Docker入门
1.Docker的基本组成
- 镜像(image):我们把应用程序和配置依赖打包好形成一个可交付的运行环境,这个打包好的运行环境就是image镜像文件
- 容器(container):容器是用镜像创建的运行实例。容器是镜像运行时的实体。容器为镜像提供了一个标准的和隔离的运行环境,它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台
- 仓库(repository):仓库(Repository)是集中存放镜像文件的场所。仓库分为公开仓库(Public)和私有仓库(Private)两种形式。最大的公开仓库是 Docker Hub存放了数量庞大的镜像供用户下载。国内的公开仓库包括阿里云 、网易云等
2.安装
- 前提条件
目前,CentOS 仅发行版本中的内核支持 Docker。Docker 运行在CentOS 7 (64-bit)上,要求系统为64位、Linux系统内核版本为 3.8以上,这里选用Centos7.x,也就是说,Docker必须安装在Linux中。
使用如下命令查看自己的内核内核版本号、硬件架构、主机名称和操作系统类型等:
uname -r
- 卸载旧版本(没安装过,可跳过此步骤)
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
yum安装gcc相关
yum -y install gcc
yum -y install gcc-c++
使用如下命令查看是否安装成功,或者是否已经安装过,安装过就无需再次安装:
whereis gcc
whereis g++
-
设置存储库
yum install -y yum-utils
-
设置stable镜像仓库(此处不同于官网,此处使用阿里云镜像,官方的访问较慢)
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
-
更新yum软件包索引,使下次yum操作更快
yum makecache fast
-
安装DOCKER CE
yum -y install docker-ce docker-ce-cli containerd.io
-
启动docker
systemctl start docker
-
测试是否安装成功
docker version
3.配置阿里云镜像加速
- 登录阿里云控制台
此处的命令就是图片中的命令:
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://dj3h28do.mirror.aliyuncs.com"]
}
EOF
systemctl daemon-reload
systemctl restart docker
4.Docker常用命令
-
帮助启动类命令
启动docker: systemctl start docker 停止docker: systemctl stop docker 重启docker: systemctl restart docker 查看docker状态: systemctl status docker 设置docker开机启动: systemctl enable docker 查看docker概要信息: docker info 查看docker总体帮助文档: docker --help 查看docker命令帮助文档: docker 具体命令 --help
-
镜像命令
-
列出本地主机上的镜像
docker images
可选参数:
-a :列出本地所有的镜像(含历史映像层)
-q :只显示镜像ID。
-
搜索镜像
docker search 镜像名称
可选参数:
–limit : 只列出N个镜像,默认25个
-
-
下载镜像
docker pull 镜像名字
可选参数:
:版本号:指定镜像版本下载,不添加此参数下载的将会是最新版
例://下载redis版本为6.0.1的镜像文件 docker pull redis:6.0.1 //下载最新版redis镜像文件 docker pull redis
-
查看镜像/容器/数据卷所占的空间
docker system df
-
删除镜像
docker rmi -f 镜像名字或者镜像ID
例:
//删除单个镜像 docker rmi -f feb5d9fea6a5 //删除多个镜像 docker rmi -f feb5d9fea6a5 f9b990972689 //删除全部镜像 docker rmi -f $(docker images -qa)
-
在本地生成新的镜像
docker commit -m="提交的描述信息" -a="作者" 即将提交的容器ID 要创建的目标镜像名:版本号
例:(此处以,拉取下来不含有vim命令的ubuntu镜像作为示例,通过以下命令给他添加vim命令后生成一个包含vim命令的新镜像)
//更新包管理工具 apt-get update //安装vim工具 apt-get -y install vim -----------以上两步在ubuntu中操作,下面的在linux中操作----------- docker commit -m="this add vim images" -a="wangfei" 4b31d27087a1 myUbuntu:1.0
-
容器命令
注:有镜像才能创建容器,所以执行容器命令时必须先下载镜像
-
新建容器
docker run 参数 镜像名称:版本号
运行容器的时候,需要指定版本号,不指定版本号,会使用默认的latest为默认版本,如果没有默认版本,运行run命令,会从仓库,拉取latest版本的容器,并创建实例;如果docker没有该镜像,那么docker先去拉取镜像,然后再创建镜像的实例,并启动
新建交互式容器(需要命令行交互的容器,比如centos,ubuntu,等):
必须使用-it参数
新建守护式容器(比如redis,mysql,等,不需要命令行交互的容器):
必须使用-d参数可选参数:
–name=容器新名字 :为容器指定一个名称;
-d: 后台运行容器并返回容器ID,也即启动守护式容器(后台运行);
-i:以交互模式运行容器,通常与 -t 同时使用;
-t:为容器重新分配一个伪输入终端,通常与 -i 同时使用;也即启动交互式容器(前台有伪终端,等待交互);
-P: 随机端口映射,大写P
-p: 指定端口映射,映射容器与宿主机之间的端口,小写p
-v :指定卷的目录,通过指定宿主机和容器之间的目录,从而备份容器运行后产生的数据,相当于对运行的容器数据做了一个备份,备份到宿主机当中,并且实现数据共享例如:tomcat下的logs目录,在tomcat启动的时候,会产生日志,如果需要查看日志,就需要进去docker容器中的运行的tomcat实例中的logs目录下,查看日志信息;镜像实例,都是相互沙箱隔离的;使用该命令,可以把tomcat的目录,建立成共享目录,这样,在docker下,也可以查看该目录
说明:docker -p port1:port2 port1 宿主机端口,也就是你服务器对外提供(映射)的访问端口 port2 容器内部端口 -p 的作用就是容器内部端口和容器外部端口进行映射,内外端口有映射才能访问。 如果关闭防火墙,相当于对外暴露所有端口。
例:
/** 参数说明: -i: 交互式操作。 -t: 终端。 ubuntu : ubuntu镜像。 /bin/bash:放在镜像名后的是命令,这里我 们希望有个交互式 Shell,因此用的是 /bin/bash。 要退出终端,直接输入 exit **/ docker run -it --name=myo1 ubuntu:latest /bin/bash 或者: docker run -it --name=myo1 ubuntu /bin/bash //不使用--name,系统将会随机分配 docker run -it ubuntu /bin/bash //启动redis这种守护式容器 docker run -d redis //通过映射宿主机与容器之间的目录,备份运行,或数据共享 docker run -d -p 5000:5000 -v /zzyyuse/myregistry/:/tmp/registry --privileged=true registry
2.列出当前所有正在运行的容器
docker ps
参数说明:
不加参数就会显示出正在运行的容器
-a :列出当前所有正在运行的容器+历史上运行过的
-l :显示最近创建的容器。
-n:显示最近n个创建的容器。
-q :静默模式,只显示容器编号。
3.退出当前容器(针对于命令行交互的容器,比如上文中的ubuntu 操作系统)
exit:这种退出方式会导致当前容器停止
ctrl+p+q:ctrl+p+q退出,容器不停止
退出后再次进入当前容器:
docker exec -it 容器ID /bin/bash
4.启动已停止运行的容器
docker start 容器ID或者容器名
5.重启容器
docker restart 容器ID或者容器名
6.停止容器
docker stop 容器ID或者容器名
7.强制停止容器
docker kill 容器ID或容器名
8.删除已停止的指定容器
docker rm 容器ID
删除已停止的全部容器
docker rm $(docker ps -qf status=exited)
9.一次性删除全部容器实例
docker rm -f $(docker ps -a -q)
或者
docker ps -a -q | xargs docker rm
10.查看容器日志
docker logs 容器ID
11.查看容器内运行的进程
docker top 容器ID
12.查看容器内部细节
docker inspect 容器ID
13.从容器拷贝文件到主机
·docker cp 容器ID:容器内路径 目的主机路径
例:
docker cp 4b31d27087a1:/a.txt /usr/local/
14.导入和导出容器
将容器导出为tar文件
·docker export 容器ID > 文件名.tar
例:
docker export 4b31d27087a1 > abc.tar
将tar文件导入为镜像(与上述命令作用相反)
·cat 文件名.tar | docker import - 镜像用户/镜像名:镜像版本号
例:
cat abc.tar | docker import - mytest/ubuntu:1.0
导入效果:
5.将本地镜像推送到阿里云
点击个人示例,进入命名空间,新建命名空间
点击镜像仓库,创建镜像仓库
复制如下命令,推送本地镜像到阿里云
例:
docker login --username=wangfeiadmin registry.cn-hangzhou.aliyuncs.com
--输入密码
docker tag c904de3e2025 registry.cn-hangzhou.aliyuncs.com/wf-dockeer-test/myubuntu:1.0
docker push registry.cn-hangzhou.aliyuncs.com/wf-dockeer-test/myubuntu:1.0
--等待推送完成
6.从阿里云拉取镜像
复制阿里云控制台命令,和推送在一个地方
docker pull registry.cn-hangzhou.aliyuncs.com/wf-dockeer-test/myubuntu:1.0
7. 将本地镜像推送到本地私服库
1.下载镜像Registry
docker pull Registry
2.运行私有库
默认情况,仓库被创建在/var/lib/registry目录下
//此处的-v是指定卷的目录
//宿主机目录为/zzyyuse/myregistry/
//容器内目录为/tmp/registry,如果没有该目录则会创建
//--privileged=true的作用是扩大容器的权限解决挂载目录没有权限的问题
//建议自行用容器卷映射,方便宿主机联调
docker run -d -p 5000:5000 -v /zzyyuse/myregistry/:/tmp/registry --privileged=true registry
3.在本地生成新的镜像
docker commit -m="vim cmd add" -a="wf" 4b31d27087a1 test_ubuntu:1.1
4.验证私有服务器存在哪些镜像
curl -XGET http://服务器IP:5000/v2/_catalog
6.将本地镜像修改成符合私服规范的Tag
//这里的test_ubuntu:1.1 为本地即将推送的镜像名称及版本号
//123.56.103.93为服务器IP,5000为映射的端口号
//private_test_ubuntu:1.1为上传后的镜像名称及版本号
docker tag test_ubuntu:1.1 123.56.103.93:5000/private_test_ubuntu:1.1
7.修改配置/etc/docker/daemon.json配置,使之支持http上传,
docker默认不允许http方式推送镜像,通过配置选项来取消这个限制
注:修改完后如果不生效,建议重启docker
vim /etc/docker/daemon.json
在daemon.json添加如下配置: “insecure-registries”: [“服务器IP:映射的端口号”],注意是添加,所以第一行后面需要添加一个逗号
{
"registry-mirrors": ["https://dj3h28do.mirror.aliyuncs.com"],
"insecure-registries": ["123.56.103.93:5000"]
}
重启docker
systemctl restart docker
重启私有仓库
docker run -d -p 5000:5000 -v /zzyyuse/myregistry/:/tmp/registry --privileged=true registry
8.推送本地镜像到本地私有库
//此处的123.56.103.93:5000/private_test_ubuntu:1.1就是上述步骤6中修改后的TAG,
docker push 123.56.103.93:5000/private_test_ubuntu:1.1
9.验证是否推送成功,同步骤4命令一样
curl -XGET http://123.56.103.93:5000/v2/_catalog
8.从私服库拉取镜像
//此处的123.56.103.93:5000/private_test_ubuntu:1.1就是上述步骤6中修改后的TAG,
docker pull 123.56.103.93:5000/private_test_ubuntu:1.1
运行
docker run -it 123.56.103.93:5000/private_test_ubuntu:1.1 /bin/bash
9.0容器卷
卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过Union File System提供一些用于持续存储或共享数据的特性:
卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷,可以通过容器卷实现,容器数据备份,容器数据与主机共享
-
运行一个带有容器卷存储功能的容器实例(可参见,将本地镜像推送到本地私服库下的步骤2)
docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录 镜像名
-
作用
在实际开发中我们 将运用与运行的环境打包镜像,run后形成容器实例运行 ,但是我们对数据的要求希望是持久化的,Docker容器产生的数据,如果不备份,那么当容器实例删除后,容器内的数据自然也就没有了。为了能保存数据在docker中我们使用卷。 特点: 1:数据卷可在容器之间共享或重用数据 2:卷中的更改可以直接实时生效 3:数据卷中的更改不会包含在镜像的更新中 4:数据卷的生命周期一直持续到没有容器使用它为止
-
容器与主机数据共享
启动容器
//这种运行方式,默认就是 :rw 容器实例内部不被限制,可以读,也可以写
docker run -it --privileged=true -v /tmp/host_data_two:/tmp/docker_data_two ubuntu /bin/bash
//如果使用这种方式的话,在容器路径后增加 :ro 那么就是容器实例内部被限制,只支持读取,不支持写入
//这种方式限制的只是容器内部,和主机无关,所以此时如果宿主机写入内容,可以同步给容器内,容器可以读取到。
docker run -it --privileged=true -v /tmp/host_data_two:/tmp/docker_data_two:ro ubuntu /bin/bash
进入容器与主机绑定的目录/tmp/docker_data_two
cd /tmp/docker_data_two
在容器的/tmp/docker_data_two目录下新建文件ccc.txt
touch ccc.txt
退出容器,切换到主机的/tmp/host_data_two目录下
cd /tmp/host_data_two
此时刚才在容器中创建的ccc.txt就出现在了主机的/tmp/host_data_two目录下
此时,我们使用vim命令对ccc.txt文件进行编辑
vim ccc.txt
再次进入容器的/tmp/docker_data_two目录下,查看ccc.txt,就会查看到在主机当中编辑的内容
10.多容器之间卷的继承和共享
通过参数 --volumes-from可以实现,多个容器之间卷的共享
docker run -it --privileged=true -v /tmp/host_extends:/docker_extends --name=u1 ubuntu
在容器u1中/docker_extends目录下创建`test_exends.txt文件
启动容器u2,并通过 --volumes-from参数,继承u1
docker run -it --privileged=true --volumes-from u1 --name=u2 ubuntu
此时切换到u2的/docker_extends目录下查看,就会看到在u1中创建的`test_exends.txt文件
11安装及运行mysql
12安装及运行redis
13搭建mysql主从复制
14搭建redis集群
15DockerFile解析
-
Dockerfile内容基础知识
1:每条保留字指令都必须为大写字母且后面要跟随至少一个参数 2:指令按照从上到下,顺序执行 3:#表示注释 4:每条指令都会创建一个新的镜像层并对镜像进行提交
-
Docker执行Dockerfile的大致流程
1.docker从基础镜像运行一个容器 2.执行一条指令并对容器作出修改 3.执行类似docker commit的操作提交一个新的镜像层 4.docker再基于刚提交的镜像运行一个新容器 5.执行dockerfile中的下一条指令直到所有指令都执行完成
-
DockerFile常用保留字指令
RUN yum -y install vim RUN ["可执行文件","参数1","参数2"] 例: RUN ["./test.php","dev","offline"] 等价于 ./test.php dev offline FROM:基础镜像,当前新镜像是基于哪个镜像的,指定一个已经存在的镜像作为模板,第一条必须是from MAINTAINER:镜像维护者的姓名和邮箱地址 RUN:容器构建时需要运行的命令 EXPOSE:当前容器对外暴露出的端口 WORKDIR:指定在创建容器后,终端默认登陆的进来工作目录,一个落脚点 USER:指定该镜像以什么样的用户权限去执行,如果都不指定,默认是root ENV:用来在构建镜像过程中设置环境变量 ADD:将宿主机目录下的文件拷贝进镜像且会自动处理URL和解压tar压缩包 COPY:类似ADD,拷贝文件和目录到镜像中。 将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置 VOLUME:容器数据卷,用于数据保存和持久化工作,相当于命令 -v CMD:指定容器启动后的要干的事情 注意:Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效,CMD 会被 docker run 之后的参数替换 它和前面RUN命令的区别: CMD是在docker run 时运行。 RUN是在 docker build时运行。 ENTRYPOINT:也是用来指定一个容器启动时要运行的命令,类似于 CMD 指令,但是ENTRYPOINT不会被docker run后面的命令覆盖. ENTRYPOINT可以和CMD一起用,一般是变参才会使用 CMD ,联用之后这里的 CMD 等于是在给 ENTRYPOINT 传参。 当指定了ENTRYPOINT后,CMD的含义就发生了变化,不再是直接运行其命令而是将CMD的内容作为参数传递给ENTRYPOINT指令,他两个组合会变成 <ENTRYPOINT>“<CMD>”
#声明当前镜像基于centos
FROM centos
#作者及邮箱
MAINTAINER wf<3218839619@qq.com>
#声明一个变量
ENV MYPATH /usr/local
#进入该镜像后,进入的目录为/usr/local
WORKDIR $MYPATH
#安装vim编辑器
RUN yum -y install vim
#安装ifconfig命令查看网络IP
RUN yum -y install net-tools
#安装java8及lib库
RUN yum -y install glibc.i686
#创建一个文件夹
RUN mkdir /usr/local/java
#ADD 是相对路径jar,把jdk-8u333-linux-x64.tar.gz添加到容器中,安装包必须要和Dockerfile文件在同一位置
ADD jdk-8u333-linux-x64.tar.gz /usr/local/java/
#配置java环境变量,声明变量
ENV JAVA_HOME /usr/local/java/jdk1.8.0_171
ENV JRE_HOME $JAVA_HOME/jre
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib:$CLASSPATH
ENV PATH $JAVA_HOME/bin:$PATH
#暴露端口
EXPOSE 80
# 这里的echo 相当于java中的 System.out.println(""),输出到控制台的信息
CMD echo $MYPATH
CMD echo "----------success----------"
CMD /bin/bash
16部署微服务项目
17Docker网络
docker启动后,会产生一个名为docker0的虚拟网桥
-
作用
容器间的互联和通信以及端口映射
容器IP变动时候可以通过服务名直接网络通信而不受到影响 -
基本常用命令
docker network ls: 查看网络
docker network inspectXXX网络名字 :查看网络源数据
docker network rm XXX网络名字 :删除网络
docker network create 网络名称 :创建网络
bridge模式:使用–network bridge指定,默认使用docker0
host模式:使用–network host指定
none模式:使用–network none指定
container模式:使用–network container:NAME或者容器ID指定
自定义网络
自定义桥接网络,自定义网络默认使用的是桥接网络bridge模式
docker network create wf_network
启动容器使用自定义网络
docker run -d -p 8081:8080 --network wf_network --name tomcat81 tomcat
docker run -d -p 8082:8080 --network wf_network --name tomcat82 tomcat
在docker-compoe中使用自定义网络
networks:
wf_network:
external: true
##18Docker-compose容器编排
-
.下载
curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
-
赋予读写权限
chmod +x /usr/local/bin/docker-compose
-
检查是否安装成功(出现版本号,说明安装成功)
docker-compose --version
-
卸载docker-compose
rm /usr/local/bin/docker-compose
Compose使用的三个步骤
1.编写Dockerfile定义各个微服务应用并构建出对应的镜像文件
2.使用 docker-compose.yml 定义一个完整业务单元,安排好整体应用中的各个容器服务。
3.最后,执行docker-compose u命令 来启动并运行整个应用程序,完成一键部署上线
Compose常用命令
docker-compose -h :查看帮助
docker-compose up :启动所有docker-compose服务
docker-compose up -d :启动所有docker-compose服务并后台运行
docker-compose down :停止并删除容器、网络、卷、镜像。
docker-compose exec yml里面的服务id :进入容器实例内部 docker-compose exec docker-compose.yml文件中写的服务id /bin/bash
docker-compose ps : 展示当前docker-compose编排过的运行的所有容器
docker-compose top :展示当前docker-compose编排过的容器进程
docker-compose logs yml里面的服务id : 查看容器输出日志
docker-compose config :检查配置
docker-compose config -q :检查配置,有问题才有输出
docker-compose restart :重启服务
docker-compose start : 启动服务
docker-compose stop : 停止服务
#docker-compose文件的版本,目前使用的是官网提供的最新版本3
version: "3"
#关于服务容器实例的配置
services:
#---------------第一个容器服务的配置-----------------------
microService: #自定义的服务名,可随意
image: docket-test:1.1 #需要启动的docker容器名称及版本号
container_name: ms01 #容器运行后的名称,相当于 --name命令
build:#构建指定目录下的Dockerfile
context: .
dockerfile: Dockerfile
ports: #启动后的端口映射
- "6001:6001"
volumes:#容器数据卷的映射配置,相当于参数命令 -v
- /home/myfile/microService:/data #容器数据卷的映射路径
networks: #自定义的网络配置相当于参数 --network
- wf_net #自定义的网络,通过 docker network create命令创建
depends_on: #image配置项启动前需要先启动的容器实例,也就是docket-test启动前
- redis #需要先启动 redis 和mysql,此处使用的是下面自定义的容器服务名
- mysql
#---------------第二个容器服务的配置-----------------------
redis: #自定义的服务名,可随意
image: redis:6.0.8 #需要启动的docker容器名称及版本号
ports:
- "6379:6379" #启动后的端口映射
volumes: #容器数据卷的映射配置,相当于参数命令 -v
- /home/redis/redis.conf:/etc/redis/redis.conf
- /home/redis/data:/data
networks: #自定义的网络配置相当于参数 --network
- wf_net
command: redis-server /etc/redis/redis.conf # 使用redis.conf运行redis
#---------------第三个容器服务的配置-----------------------
mysql:#自定义的服务名,可随意
image: mysql:5.7 #需要启动的docker容器名称及版本号
environment:#环境配置
MYSQL_ROOT_PASSWORD: 'root' #root用户的密码
MYSQL_ALLOW_EMPTY_PASSWORD: 'no' #是否允许空密码
MYSQL_DATABASE: 'docker-test'
MYSQL_USER: 'wangfei' #对mysql再配置一个用户名
MYSQL_PASSWORD: 'wf123'#对mysql再配置一个m
ports: #启动后的端口映射
- "3306:3306"
volumes: #容器数据卷的映射配置,相当于参数命令 -v
- /app/mysql/db:/var/lib/mysql
- /app/mysql/conf/my.cnf:/etc/my.cnf
- /app/mysql/init:/docker-entrypoint-initdb.d
networks: #自定义的网络配置相当于参数 --network
- wf_net
command: --default-authentication-plugin=mysql_native_password #解决外部无法访问
networks: #网络配置,此处相当于再此处创建网络
wf_net: #相当于通过 docker network create命令创建一个wf_net网络
-
检查docker-compose.yml语法是否正确
docker-compose config -q
-
使用docker-compose up -d,在docker-compose.yml文件的同一目录下执行,
启动docker-compose.yml文件中定义的服务,并后台运行docker-compose up -d