容器编排:就是针对容器生命周期的管理,对容器的生命周期进行更快速方便的方式进行管理。
实例:一个java程序,依赖了mysql,redis,要想把 java 程序运行起来,则必须要先启动 mysql、redis。那么这三者这件就存在了依赖关联。
容器编排存在的意义:
- 依赖管理,当一个容器必须在另一个容器运行完成后,才能运行时,就需要进行依赖管理
- 副本数控制,容器有时候也需要集群,快速的对容器集群进行弹性伸缩
- 配置共享,通过配置文件统一描述需要运行的服务相关信息,自动化的解析配置内容,并构建对应的服务
容器编排的出现,就是让开发者可以更简单的使用容器,省去频繁的写各种命令,docker 容器编排的出现,就类似 shell 脚本,一键搞定!
容器编排,主要有两种模式:
- 基于Docker Compose(单机)
- 基于Swarm(集群)
Docker Compose 是单机环境下的容器编排。
有的时候我们会需要涉及到在一台机器部署多个容器,那么此时再手动的每次输入相关的一堆配置命令再来启动容器,还是产生了很多无意义的重复性劳动。针对单机的多容器部署的情况,Docker 为我们提供了一个单机版本的服务编排工具 docker-compose
Docker-Compose 可以高效便捷的管理单机上运行的所有容器,它通过 yaml 配置文件的方式完成之前执行 docker run 命令所设置的所有参数,你可以先针对单机上的所有容器进行相关配置,配置完成后即可使用 docker-compose 对单机多容器进行高效的管理
docker compose 容器编排,就是基于docker-compose.yml
配置文件进行的容器编排。只要学会如何编写这个配置文件,就会用这个玩意了。
注意:需要注意的是,docker-compose 与docker有版本对应关系,因此在使用docker-compose时需要选择与已安装的docker版本相对应的docker-compose版本,否则可能会出现不兼容或无法正常工作的问题。但是!我在官网一致没有找到 docker 和 docker-compose 的对应关系表啊,有知道的小伙伴能评论发我一下吗??我只找到个 docker compose 发行版本,依赖的 docker 需要升级的版本,docker compose 发行版本地址:https://docs.docker.com/compose/release-notes。如下图所示:
因为 docker 使用的是最新版本:24.0.6
,所以 docker compose 也使用了最新版本2.21.0
还有一个对应关系表,在这里,也没有太看懂。地址:
- https://docs.docker.com/compose/compose-file/compose-file-v2
- https://docs.docker.com/compose/compose-file/compose-file-v3
Docker Compose 下载地址:https://github.com/docker/compose/releases/download/v2.21.0/docker-compose-linux-x86_64
# step 1:下载 docker compose 最新版本
curl -L "https://github.com/docker/compose/releases/download/v2.21.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# $(uname -s) 系统内核,即:linux
# $(uname -m) 系统架构,即:x86_64
# step 2:将可执行权限应用于二进制文件
sudo chmod +x /usr/local/bin/docker-compose
# step 3:创建软链
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
# step 4:测试是否安装成功
docker-compose --version
# docker 启动 nginx命令:
docker run -d --restart=always --network xxx -v /www/abc:/usr/share/nginx/html -e APP_ENV=dev -p 80:80 --name nginx-compose nginx
# 命令解释:
# -d 后台运行
# --restart=always 出现异常后总是自动重启
# --network xxx 自定义网络
# -v /www/abc:/usr/share/nginx/html 将[本地目录/www/abc]与[容器目录/usr/share/nginx/html] 进行数据卷绑定
# -e APP_ENV=dev 添加环境变量
# -p 80:80 端口映射
# --name 容器名称
# nginx 镜像名
上述命令,就可以在 docker 中启动一个 nginx 容器了。
- 在不使用来回复制、粘贴的方式,如何将这条命令复用呢?
- 这个命令还不算太长,如果命令更长的怎么办呢?
这样就需要用到 docker compose 了。
创建一个
/opt/docker/nginx
文件夹,在nginx文件夹下创建一个docker-compose.yml
文件,进入文件,就可以编写 docker compose了
参考官网进行编写docker compose即可。因为docker compose的配置项太多了。截至
2023-09-14
,使用的docker 24.0.6
和docker compose 2.21.0
,所以此处直接使用 Compose V3版本。地址:https://docs.docker.com/compose/compose-file/compose-file-v3
配置超级多,根本记不住。所以参考官网来写就好了。
如果是一个普通的镜像,更多的关注【服务services】、【网络networks】、【数据卷volumes】这三个配置项就可以了
# docker 启动 nginx命令:
docker run -d --restart=always --network xxx -v /www/abc:/usr/share/nginx/html -e APP_ENV=dev -p 80:80 --name nginx-compose nginx
上面的命令,转成 nginx compose 如下:
version: "3.8"
services:
nginx-demo-compose:
contianer_name: "nginx-compose"
image: nginx
restart: always
networks: nginx_net
volumes:
- /www/abc:/usr/share/nginx/html
environment:
- APP_ENV=dev
ports:
- 80:80
networks:
nginx_net:
ipam:
driver: default
config:
- subnet: "172.16.238.0/24"
命令 | 说明 |
---|---|
build | 先构建完镜像,然后构建一个docker服务(如果开始就已经是个镜像了,则会跳过,命令不生效) |
config | 规范、验证并查看 compose 文件,验证通过后,控制台会返回 compose 文件内容 |
cp | 在容器和本地文件系统之间复制文件/文件夹 |
create | 为 compose 中的 service 服务创建容器。 |
down | 停止并删除容器、网络 |
events | 从容器接收实时事件 |
exec | 在运行中的容器中执行命令 |
images | 列出创建的容器使用的镜像 |
kill | 强制停止服务容器 |
logs | 查看容器的日志输出 |
ls | 列出正在运行的 compose 项目 |
pause | 暂停 service 服务 |
port | 输出端口绑定的公共端口 |
ps | 列出容器 |
pull | 拉取 service 服务镜像 |
push | 推送 service 服务镜像 |
restart | 重启 service 服务容器 |
rm | 删除停止的服务容器 |
run | 在服务上运行一次性命令 |
start | 启动服务 |
stop | 停止服务 |
top | 显示正在运行的进程 |
unpause | 取消暂停服务 |
up | 创建并启动一个容器 |
version | 显示 Docker Compose 版本信息 |
wait | 等待阻塞直到第一个服务容器停止 |
提示: 更详细命令说明,使用
docker compose [命令] --help
了解。比如:docker compose up --help
扩缩容命令:
命令 | 说明 |
---|---|
docker compose up --scale 服务名=num | 扩容/缩容,服务名为compose文件服务名,num 为数量 |
# 进入/opt/docker/nginx 目录,在docker-compose.yml同级下,执行如下命令
docker compose config
进入
/opt/docker/nginx
目录下,在docker-compose.yml
同级目录下,开始操作
# step 1:创建服务(此处也可以启动compose中的特定服务:docker compose create 服务名)
docker compose create
# step 2:查看服务是否创建成功
docker compose ps -a
# step 3:后台启动容器
docker compose up -d
如图所示:
扩缩容命令,如下:
docker compose up -d --scale 服务名=num
扩缩容注意:
- 需要删除 container_name (docker 不允许多个容器具有相同的名称)
- 修改 port 端口映射(一个服务只能一个端口,会提示端口占用问题)
修改后的 docker-compose.yaml 如下:
version: "3.8"
services:
nginx-demo:
image: nginx
restart: always
networks:
- nginx_net
volumes:
- /www/abc:/usr/share/nginx/html
environment:
- APP_ENV=dev
ports:
- 80 # 此处80代表容器中的80端口,映射到本地的随机端口
networks:
nginx_net:
ipam:
driver: default
config:
- subnet: "172.16.238.0/24"
修改配置信息后,执行
docker compose up -d
,便会重新读取compose配置,启动容器
Swarm 也是需要提前安装好 Docker Compose !!!
Swarm 是 Docker 公司推出的用来管理 docker 集群的平台,几乎全部用GO语言来完成的开发的, 它是将一群 Docker 宿主机变成一个单一的虚拟主机,Swarm 使用标准的 Docker API 接口作为其前端的访问入口,换言之,各种形式的DockerClient(compose, docker-py 等) 均可以直接与 Swarm 通信,甚至 Docker 本身都可以很容易的与 Swarm 集成,这大大方便了用户将原本基于单节点的系统移植到 Swarm 上,同时Swarm 内置了对 Docker 网络插件的支持,用户也很容易的部署跨主机的容器集群服务。
Docker Swarm 和 Docker Compose 一样,都是 Docker 官方容器编排项目,但不同的是,Docker Compose 是一个在单个服务器或主机上创建多个容器的工具,而 Docker Swarm 则可以在多个服务器或主机上创建容器集群服务,对于微服务的部署,显然 Docker Swarm 会更加适合。
从 Docker 1.12.0 版本开始,Docker Swarm 已经包含在 Docker 引擎中(docker swarm),并且已经内置了服务发现工具,所以 swarm 我们无需手动安装。
Swarm deamon只是一个调度器(Scheduler) + 路由器(router),Swarm自己不运行容器,它只是接受Docker客户端发来的请求,调度适合的节点来运行容器,这就意味着,即使Swarm由于某些原因挂掉了,集群中的节点也会照常运行,放Swarm重新恢复运行之后,他会收集重建集群信息。https://github.com/docker/swarm
k8s 的出现早于 swarm,所以 swarm 的诞生,就是为了与 k8s 竞争,k8s 已经很成熟了,所以目前市场上用的 k8s 的还是挺多的,swarm 相对来说用的还不是提多。
运行 Docker 的主机可以主动初始化一个 Swarm 集群或者加入一个已存在的 Swarm 集群,这样这个运行 Docker 的主机就成为一个 Swarm 集群的节点 (node) 。
Swarm节点分为管理 (manager) 节点和工作 (worker) 节点。
管理节点用于 Swarm 集群的管理,docker swarm 命令基本只能在管理节点执行(节点退出集群命令 docker swarm leave 可以在工作节点执行)。一个 Swarm 集群可以有多个管理节点,但只有一个管理节点可以成为 leader,leader 通过 raft 协议实现。通常,第一个启用docker swarm的节点将成为leader,后来加入的都是follower。当前的leader如果挂掉,剩余的节点将重新选举出一个新的leader。每一个manager都有一个完整的当前集群状态的副本,可以保证manager的高可用。
工作节点是任务执行节点,管理节点将服务 (service) 下发至工作节点执行。管理节点默认也作为工作节点。你也可以通过配置让服务只运行在管理节点。worker节点之间,通过control plane进行通信,这种通信使用gossip协议,并且是异步的。
来自 Docker 官网的这张图片形象的展示了集群中管理节点与工作节点的关系。
三台机器如下:每台机器都安装好 docker
和 docker-compose
IP | 角色 |
---|---|
192.168.204.101 | manager 管理节点 |
192.168.204.102 | worker 工作节点 |
192.168.204.103 | worker 工作节点 |
# 查看docker swarm 命令
docker swarm --help
[root@localhost ~]# docker swarm --help
Usage: docker swarm COMMAND
Manage Swarm
Commands:
init Initialize a swarm
join Join a swarm as a node and/or manager
Run 'docker swarm COMMAND --help' for more information on a command.
# 查看 swarm 集群状态
docker info
# 查看 swarm 集群节点信息
docker node ls
# 登录管理节点,并执行如下命令
docker swarm init --advertise-addr 192.168.204.101
# 返回如下信息
[root@localhost ~]# docker swarm init --advertise-addr 192.168.204.101
Swarm initialized: current node (2tlpn6ywqh9kms9ymgndpoinc) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-3gcmbp3voxo05kw0q4lfe972a1uy7bbch59aabu55i3dnb2eeo-3a26jdpdkmdmvjuj54ki9c14h 192.168.204.101:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
复制初始化集群返回的命令,分别在 两个work 节点执行,将work节点加入 swarm 集群。
记得:关闭防火墙,或者开放端口 2377!!!
先关闭防火墙:systemctl stop firewalld
然后永久关闭防火墙:systemctl disable firewalld
# 加入swarm集群命令
docker swarm join --token SWMTKN-1-3gcmbp3voxo05kw0q4lfe972a1uy7bbch59aabu55i3dnb2eeo-3a26jdpdkmdmvjuj54ki9c14h 192.168.204.101:2377
加入成功如图所示:
进入 manager 管理节点,通过
docker node ls
查看集群节点信息。work 节点无法查看哦!
在管理节点,通过命令 docker service 部署服务,通过
docker service --help
查看详细命令
命令 | 说明 |
---|---|
create | 创建一个新的服务 |
inspect | 展示一个/多个服务的详细信息 |
logs | 查看服务/任务的日志 |
ls | 显示所有service服务 |
ps | 显示一个/多个服务的所有task |
rm | 删除一个/多个服务 |
rollback | 恢复service服务的配置信息 |
scale | 弹性扩缩容service服务 |
update | 更新service服务 |
在管理节点,通过命令 docker service 部署服务,此处来部署一个 nginx 服务
# 部署一个nginx服务
docker service create --replicas 1 -p 80:80 --name nginx_swarm nginx
# --replicas 1 一个副本
# -p 80:80 端口映射
# --name 自定义名称
# manager管理节点, 查看所有service服务
docker service ls
# 在 manager 和 work 节点,都执行 docker ps 命令,查看服务是否启动成功
docker ps
# 访问服务
curl 192.168.204.101
如果要想在管理端去访问 curl 192.168.204.202 和 192.168.204.203,也显示服务正常。
需要先扩容至副本数为 3,即可。
提示:另一种情况:副本数为3后,现在指定节点203退出swarm集群,此时 3 个副本就会重新分配(比如:201机器2个副本,202机器1个副本,如果此时203节点重新加入后,即使203这个节点上没有这个副本,集群会帮我们自动分发服务,你同样还是可以访问curl 192.168.204.203 成功)
以下命令,在
manager 管理节点
执行操作
# 副本数扩容(nginx_swarm:服务名)
docker service update --replicas 3 nginx_swarm
错误提示:error creating external connectivity network: Failed to Setup IP tables: U
解决方案:关闭防火墙后,需要重启 docker 服务
命令:service docker restart
修改 --replicas 的个数即可。
# 哪个节点要离开集群,在指定节点执行如下命令
docker swarm leave
以下命令,在
manager 管理节点
执行操作
# 删除节点(nodeId 通过 docker node ls 查看)
docker node rm [nodeId]
在要加入集群的节点执行如下命令:
# 再次执行刚才的,加入swarm集群命令即可
docker swarm join --token SWMTKN-1-3gcmbp3voxo05kw0q4lfe972a1uy7bbch59aabu55i3dnb2eeo-3a26jdpdkmdmvjuj54ki9c14h 192.168.204.101:2377
本文结束,谢谢