温馨提示:所有文章中所提及的Docker相关的案例的安装包和工具,都可以在我的网盘中直接下载并跟着实操:
链接:pan.baidu.com/s/1pgboR8O5...
提取码:30in
13. Docker容器编排
编排功能,是复杂系统是否具有灵活可操作性的关键。特别在Docker应用场景中,编排意味着用户可以灵活地对各种容器资源实现定义和管理。例如:在基于微服务架构的应用系统一般都包含若干个微服务,每个微服务一般都会集群部署多个实例,如果每个微服务都要手动启动与停止,那么效率非常低、工作量也非常大。或是有一些微服务和应用之间有部署的先后关系,当前一个有依赖性的服务还没有完成部署时,另一个有依赖性的服务先完成了部署就会导致部署失败。那么使用 Docker Compose可以轻松、高效地管理和编排多个容器。
Docker Compose 作为Docker官方编排工具,其重要性不言而喻,它可以让用户通过编写一个简单的模板文件(yaml格式),然后使用一个命令即可创建并启动配置文件中所配置的所有服务,实现快速地创建和管理基于Docker容器的应用集群。
13.1 Docker-Compose安装
-
下载Compose二进制安装包(可以使用我们下载好的):
下载地址:github.com/docker/comp...,我们下载Linux版本
-
上传这些二进制文件到执行路径到
/usr/local/bin/
目录下,并添加执行权限即可shell#进入/usr/local/bin目录 cd /usr/local/bin #修改文件名字 mv docker-compose-linux-x86_64 docker-compose #添加执行权 chmod +x docker-compose
-
测试安装结果
shell#打印docker-compose版本号 docker-compose --version
13.2 Docker-Compose模板文件
模板文件是使用Compose的核心,涉及的指令也比较多,但大部分的指令与docker命令创建或启动容器时所填写的参数类似。默认的模板文件名称为docker-compose.yml ,格式为YAML 格式,目前最新的版本为v3
版本v1的Compose文件结构十分简单,每个顶级元素为服务名,次级元素为服务容器的配置信息,例如:
yaml
tomcat:
image: my_tomcat:9
ports:
- "8080:8080"
volumes:
- "/mydata/tomcat"
版本v2和版本v3扩展了Compose的语法,同时尽量保持跟旧版本的兼容,除了可以声明网络和存储外,最大的不同一个是添加了版本信息,另一个是需要将所有的服务放到services元素下面,例如我们将上面的例子改为版本v3:
yaml
version:"3"
services:
tomcat:
image: my_tocamt:9
ports:
- "8080:8080"
volumes:
- "/mydata/tomcat"
注意:每个服务的编排都必须通过image指令指定镜像 或 build指令通过Dockerfile构建镜像,如果使用build指令,在Dockerfile中设置的一系列指令,例如CMD,EXPOSE都会自动被执行,无需再次设置
Compose模板文件常用指令列表参考如下表格内容:(这里只列出一些我认为很常用的)
指令 | 功能 |
---|---|
image | 指定镜像名或镜像id,如果镜像在本地不存在,会尝试去拉取这个镜像 |
ports | 暴露容器的端口,可指定多个。 |
volumes | 数据卷或数据目录的挂载设置,可指定多个 |
build | 指定Dockerfile所在路径,会自动构建这个镜像,并使用这个镜像 |
container_name | 指定容器名称,默认将会使用"项目名称服务名称序号"的格式,如果我们自己指定了容器名,该服务将无法进行集群扩展,因为Docker不允许多个容器实例名重复 |
command | 覆盖容器启动后默认执行的命令 |
depends_on | 指定多个服务之间的依赖关系,启动时,会先启动被依赖服务 |
dns | 自定义DNS服务器,可以指定多个 |
dns_serach | 配置DNS搜索域,可以指定多个 |
dockerfile | 指定额外的编译镜像的Dockerfile文件,该指令不能跟image同时使用 |
entrypoint | 覆盖容器中默认的入口命令,也会取消镜像中指定的入口命令和默认启动命令 |
pid | 跟宿主机共享进程命名空间,打开该选项容器之间,以及容器额宿主机之间可以通过进程ID来互相访问和操作 |
expose | 指定容器暴露的端口 |
extends | 基于其他模板文件进行扩展,可以有多个yaml文件,他们之间可以有继承关系 |
restart | 指定重启策略,可以为no(不重启),always(总是),on-failure(失败时),unless-stopped(停止时) |
ulimits | 指定容器的限制值,例如,指定最大进程数 |
network_mode | 设置网络模式,bridger、host、none、containner |
networks | 指定加入的网络名 |
environment | 设置环境变量 |
13.3 Docker-Compose命令
Docker-Compose 的命令与docker命令极为相似, 用法上没有太大区别,其基本格式是docker-compose 命令 参数
,下面列出一些常用命令:
查看帮助命令:
shell
docker-compose --help
效验和查看Compose文件的配置信息
shell
docker-compose config
创建并启动容器
shell
docker-compose up -d --scale 服务名=数字
d表示后台运行,scale是表示对应的服务同时启动几个容器
停止容器,但不删除
shell
docker-compose stop
启动容器
shell
docker-compose start
停止并删除容器
shell
docker-compose down
13.4 Docker-Compose部署
我们以之前的SpirngBoot项目部署例子来进行改造实验,目前我们需要在同一个宿主机中实现的一个MySQL数据库和两个SpirngBoot程序的实例部署:
-
创建用于存储yml文件的目录
shell#进入到/mydata目录 cd /mydata #创建compose目录 mkdir compose
-
编写docker-compose.yml文件
yaml#在/mydata/compose目录下编写 vim docker-compose.yml version: "3" services: mysql: container_name: my_mysql image: mysql privileged: true restart: always volumes: - "/mydata/mysql/data:/var/lib/mysql" - "/mydata/mysql/conf:/etc/mysql/conf.d" - "/mydata/mysql/logs:/var/log/mysql" ports: - "3306:3306" expose: - "3306" environment: - MYSQL_ROOT_PASSWORD=123456 networks: - my_network springboot: image: springboot_jxc ports: - "80-81:80" depends_on: - mysql restart: always networks: - my_network networks: my_network:
以上配置文件注释版讲解:
yaml#指定yaml版本v3 version: "3" #服务配置 services: #第一个服务mysql mysql: #容器名,如果指定了,就不能部署多个容器 container_name: my_mysql #镜像名 image: mysql #为了防止出现Centos7安全Selinux禁止了一些安全权限 privileged: true #自动重启容器 restart: always #数据挂载 volumes: - "/mydata/mysql/data:/var/lib/mysql" - "/mydata/mysql/conf:/etc/mysql/conf.d" - "/mydata/mysql/logs:/var/log/mysql" #映射端口 ports: - "3306:3306" #暴露端口 expose: - "3306" #环境配置 environment: - MYSQL_ROOT_PASSWORD=123456 #加入的自定义网络 networks: - my_network #第二个服务springboot springboot: #镜像名,我们之前自己通过Dockerfile制作的JXC项目的镜像 image: springboot_jxc #映射端口,"80-81:80"这种写法会在启动多个实例的时候,自动为我们分配端口在80-81这个区间的容器映射 ports: - "80-81:80" #依赖某个服务 depends_on: - mysql #自动重启 restart: always #加入的自定义网络 networks: - my_network #自定义网络配置 networks: #自定义网络名 my_network:
-
启动服务
shell#在/mydata/compose目录下执行 docker-compose up -d --scale springboot=2 -d:后台启动容器 --scale:启动多个实例
-
进行访问测试
在Windows浏览器中分别访问
80
和81
两个端口号的实例,访问如下地址,访问后如出现如下登录页面,则部署成功,登录账号:admin
,登录密码:admin123
urlhttp://192.168.177.128:80 http://192.168.177.128:81
-
关闭服务,并删除容器
shell#在/mydata/compose目录下执行 docker-compose down
14. Docker容器管理
目前,已经有若干开源项目试图实现强大和便捷的Docker管理工具,包括Portainer、Panamax、Seagull等。本例,我们以Portainer为例为大家讲解如何安装使用Docker的容器管理工具。
Portainer是一个Docker官方推荐的轻量级的docker管理工具,它具有可视化ui界面,只需简单的TCP连接就能实现对Docker容器的全面管理和监控。官方网站为:portainer.io,该项目最早于2013年12月发起,主要基于HTML/JS语言实现。
14.1 Portainer安装
-
下载Portainer镜像
bash#我们可以在Docker Hub中找到MySQL镜像 https://hub.docker.com/r/portainer/portainer #拉取portainer镜像,默认拉取的版本是latest的 docker pull portainer/portainer-ce
-
创建数据卷
shelldocker volume create portainer_data
-
启动容器
shelldocker run --name portainer -p 9000:9000 \ -v /var/run/docker.sock:/var/run/docker.sock \ -v portainer_data:/data \ -d portainer/portainer-ce #以上命令解析 --name:容器的名称 -p:端口映射 -v:目录挂载 -v /var/run/docker.sock:/var/run/docker.sock 将宿主机的/var/run/docker.sock目录挂载到容器中的/var/run/docker.sock目录中(该目录是docker的套接字目录,主要就是发送指令给docker的守护进程的) -v portainer_data:/data 将宿主机的portainer_data数据卷挂载到容器中的/data目录(这是portainer容器默认的数据目录) -d:后台启动
-
创建管理员账号
容器启动完毕之后,我们可以在Windows浏览器中输入以下地址访问管理平台
urlhttp://192.168.177.128:9000
我们需要管理员账号的创建,如果5分钟不创建该账号,Portainner会出于安全考虑而自动关闭容器,常见完毕之后就会进入下面的页面,那么整个Portainer就安装完毕了
14.2 Portainer本地连接
Portainer安装完毕之后,我们就可以开始进行使用了,Portainer支持很多种管理和监控方式,这里我们以Local
和Remote
两种方式为例。Local
指的是管理当前安装Portainer宿主机的Docker环境,而Remote
指的是管理其他宿主机的Docker环境。
-
访问本地Docker
选择
Local
->点击Connect
即可进行连接。连接后就会进入如下列表界面,该列表会显示出所有正处于Portainner管理的机器信息
-
管理本地Docker
在列表中,点击
local
本地机器,就可以进入当前机器的管理页面,该页面可对当前选定机器的栈,容器,镜像,数据卷,网络进行管理
14.3 Portainer远程连接
Portainer连接其他机器需要使用tcp协议,端口号默认为2375。我们以192.168.177.129机器node2为例来进行演示
-
在node2机器中修改docker.service文件,开放2375端口
shell#打开node2的docker.service文件 vim /usr/lib/systemd/system/docker.service #找到ExecStart字段修改如下 ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375 -H unix://var/run/docker.sock #重启daemon systemctl daemon-reload #重启docker服务 systemctl restart docker
-
添加远程机器管理
回到Portainer页面,在左侧导航栏选择
Endpoint
,在打开的页面中选择Add endpoint
选项在弹出页面中选择Docker,并填写机器名
remote
和机器地址192.168.177.129:2375
,之后点击下方Add endpoint
按钮进行添加 -
查看添加的远程机器
添加完毕后,点击左侧导航栏选择
Home
,就可以看到如下页面,出现remote
说明node2机器的Docker也被Portainner进行管理了点击
remote
机器就可以查看node2机器中Docker的栈,容器,镜像,数据卷,网络情况了,至此我们就完成了对远程Docker机器的连接
14.4 Portainner镜像管理
我们以本地node1上的Docker为例,演示Portainner对镜像的操作
-
进入镜像管理页面
选择左侧导航栏的
Home
按钮,进入以下主机列表页面,然后选择local
本地机器之后检查左侧导航栏Home下的机器是否正确切换到
LOCAL
字样,我们可以选择左侧导航栏的Images
或是点击当前列表页中的Images图标进入镜像管理页面 -
单个镜像删除
我们在镜像列表页选择需要删除的惊险,点击
Remove
即可进行删除,例如这里我们删除hello-world:latest
,如下图所示 -
多个镜像删除
如果我们需要删除的镜像包含多个tags标签,那么直接点解
Remove
删除按钮是不被允许的,例如我们这里的Tomcat镜像,有3个Tags,那么我们需要点击该镜像,进入到如下页面进行逐一删除 -
从DockerHub拉取镜像
要拉取镜像,我需要在该页面的上方选择Registry仓库,填写要拉取的镜像,然后点击
Pull the image
拉取镜像 -
从私有仓库拉取镜像
这里我们以阿里云为例,从私有仓库拉取镜像。找到左侧导航栏,选择
Registrles
,然后点击Add registry
添加注册仓库登录自己的阿里云镜像仓库,地址
https://cr.console.aliyun.com/cn-hangzhou/instances
,找到自己的镜像仓库,查看自己仓库的信息回到Portainner页面,填写如下仓库信息,然后添加该仓库
添加完自己的镜像仓库后,点击左侧导航栏选择
images
,在该页面的上方选择Registry仓库,填写要拉取的镜像,然后点击Pull the image
拉取镜像 -
镜像的导出
在镜像页面,选择需要导出的镜像,点击
Export
按钮,例如这里我们导出hello-world:latest
,导出后浏览器会自动进行下载 -
镜像的导入
我们把之前导出的镜像进行导入,再导入之前,先将
hello-world:latest
镜像手动删除掉。然后点击Import
按钮找到之前导出的镜像进行导入即可 -
使用Dockerfile构建镜像
在镜像页面,选择
Build a new image
来构建镜像,再弹出的新页面中,编写构建镜像的镜像名和Dockerfile文件在使用Portainner进行Dockerfile构建镜像时,Portainner官方文档专门有说明,Dockerfile里的
ADD
COPY
指令不允许使用相对路径
,而应该采用URL远程资源地址
进行资源的下载。这里我们制作一个包含JDK17的centos7镜像,填下内容如下DockerfileFROM centos:7 MAINTAINER gucaini ADD https://download.oracle.com/java/17/archive/jdk-17.0.6_linux-x64_bin.tar.gz /usr/local/java ENV JAVA_HOME=/usr/local/java/jdk-17.0.6 ENV PATH=$JAVA_HOME/bin:$PATH CMD ["java","-version"]
填写完毕之后点击下方
Build the image
,进行构建,构建结果,可以通过切换到Output
页面来查看
14.5 Portainner容器管理
我们以本地node1上的Docker为例,演示Portainner对容器的操作
-
进入容器管理页
选择左侧导航栏的
Containers
进入容器管理页进入容器管理页后,会出现容器的操作功能按钮以及当前宿主机中的Docker容器列表,其中容器的操作功能按钮各个功能含义如下:
按钮键 功能含义 Start 启动一个停止中的容器 Stop 停止一个正在运行的容器 Kill 与Stop的作用相似,区别在于Stop是优雅关闭容器,而Kill是强制关闭 Restart 重启一个容器 Pause 暂停一个容器中的所有进程 Resume 恢复一个容器中的所有进程 Remove 删除一个容器 Add container 添加一个新的容器 Docker容器列表中每一个属性的作用及含义如下:
列表属性 功能含义 Name 容器名 State 容器的运行状态,Running是正在运行,Stop是停止 Quick actions 可以查看容器的日志、容器的详情、容器的运行情况、进入容器命令行 Stack 堆栈名称,这里指的是使用类似Docker-Compose容器编排来创建容器时的堆栈名称 Image 镜像名 Created 容器创建的时间 Published Ports 端口映射列表 Ownership 容器的所有权 -
创建一个容器
这里以启动一个MySQL容器为例,我们在容器列表页点击
Add container
,首先填写容器名my_mysql
,选择镜像仓库服务器DockerHub
,填写镜像名mysql:latest
,如下:接下来,我们添加端口映射,选择
publish a new network port
,然后填写宿主机和容器的端口映射配置3306:3306
,如下图:在下方容器设置中,找到
Volumes
标签页配置数据挂载,点击map additional volume
添加一组新的数据挂载配置项,其中Volume
配置的是数据卷挂载,Bind
配置的是目录挂载,这里使用Bind
目录挂载,分别填下如下挂载路径shell/mydata/mysql/data:/var/lib/mysql /mydata/mysql/conf:/etc/mysql/conf.d /mydata/mysql/logs:/var/log/mysql
在下方容器设置中,找到
Env
标签页配置环境变量,点击add environment variable
添加一组新的环境变量配置项,其中name
配置的是环境变量的名字,value
配置的是环境变量的值,填下如下内容:shellMYSQL_ROOT_PASSWORD=123456
接着找到
Restart policy
标签页配置重启策略,点击Always
,设置为总是自动重启,如下图:再接着找到
Runtime & Resource
标签页配置运行时资源,打开Privileged mode
特权模式,如下图:最后点击页面中的
Deploy the container
按钮进行容器的创建容器创建成功后,会自动跳转到容器列表页进行展示,如下图:
-
使用Compose容器编排来创建容器
在Portainner中,可以非常方便的使用容器堆栈的方式来创建容器,它相当于
Docker-Compose
容器编排。这里仍然SpringBoot程序部署为例,在左侧导航栏中找到Stacks
按钮进入堆栈列表,填写堆栈名称,以及编写docker-compose.yml文件,如下图:yamlversion: "3" services: mysql: container_name: my_mysql image: mysql privileged: true restart: always volumes: - "/mydata/mysql/data:/var/lib/mysql" - "/mydata/mysql/conf:/etc/mysql/conf.d" - "/mydata/mysql/logs:/var/log/mysql" ports: - "3306:3306" expose: - "3306" environment: - MYSQL_ROOT_PASSWORD=123456 networks: - my_network springboot: image: springboot_jxc deploy: replicas: 2 ports: - "80-81:80" depends_on: - mysql restart: always networks: - my_network networks: my_network:
编写完毕之后,点击
Deploy the stack
按钮进行容器的创建,如下图:部署完毕之后,我们可以通过列表查看详情,至此完成了Compose的部署:
进行访问测试:
在Windows浏览器中分别访问
80
和81
两个端口号的实例,访问如下地址,访问后如出现如下登录页面,则部署成功,登录账号:admin
,登录密码:admin123
urlhttp://192.168.177.128:80 http://192.168.177.128:81