Docker Compose 和 Docker Swarm
文章目录
一:Docker Compose
官网:https://www.docker.com/
文档地址: https://docs.docker.com/ (Docker 官网文档超级详细)
仓库地址:https://hub.docker.com/
容器单独没有什么意义,有意义的是容器编排
1:简介
Compose是一个用于定义和运行多容器Docker应用程序的工具。
使用Compose,您可以使用yaml文件配置应用程序的服务。然后,使用一个命令,从配置中创建并启动所有服务
使用Compose基本上是一个三步过程:
- 使用定义应用的环境,以便可以在任何位置重现它。Dockerfile
- 定义构成应用的服务,以便它们可以在隔离的环境中一起运行。docker-compose.yml
- 运行,Docker 撰写命令将启动并运行整个应用。您也可以使用 docker-compose 二进制文件运行
它是一个容器编排助手,用于集中管理多个 Docker 容器的启动和协同工作。
可以在一个配置文件中集中定义所有容器以及它们的关系。
然后,可以使用一行命令启动所有容器,而不需要手动运行多个命令。
需要注意的是,Docker Compose 通常适用于把所有微服务部署在同一台服务器的场景
在真实的企业级项目中,往往会使用 K8S 等更专业的容器编排和自动化部署工具,更方便地在多个服务器上部署容器。
2:docker Compose安装
Install Docker Compose | Docker Documentation
官方下载地址慢,不推荐官方的下载地址,使用国内的镜像
运行以下命令下载 Docker Compose 的当前稳定版本:
curl -L https://dn-dao-github-mirror.daocloud.io/docker/compose/releases/download/1.25.5/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
将可以执行的权限应用于二进制文件
chmod +x /usr/local/bin/docker-compose
安装成功
> docker-compose version
# 如果安装成功,将会有下面的提示信息
docker-compose version 1.25.5, build 8a1c60f6
docker-py version: 4.1.0
CPython version: 3.7.5
OpenSSL version: OpenSSL 1.1.0l 10 Sep 2019
3:如何编写docker compose
和 Dockerfile 一样,直接去网上找现成的 Docker Compose file,复制粘贴过来略做修改就能使用了~
再配合以下 2 个网站,完全无需记忆 Docker Compose 的写法!
- Docker Compose file 官方文档:https://docs.docker.com/compose/compose-file/
- 搜索现成的 Docker 镜像:https://hub.docker.com/
当然,现在 AI 时代了,还有更简单的方式!让 AI 帮我们生成配置即可~
Docker Engine 与 docker-compose version 之间的有以下关系:
Compose file format | Docker Engine |
---|---|
1 | 1.9.0+ |
2.0 | 1.10.0+ |
2.1 | 1.12.0+ |
2.2, 3.0, 3.1, 3.2 | 1.13.0+ |
2.3, 3.3, 3.4, 3.5 | 17.06.0+ |
2.4 | 17.12.0+ |
3.6 | 18.02.0+ |
3.7 | 18.06.0+ |
从1.25.5版本开始,可以直接按操作系统平台下载安装包:
项目地址:https://github.com/docker/compose/releases
二:微服务部署实战
1:梳理服务部署表格
在部署微服务项目前,首先要规划好要部署哪些服务、以及各服务的关键信息,比如服务名称、版本号、占用端口号、关键配置等。
服务名称 | 英文名 | 端口号 | 版本号 | 服务类别 |
---|---|---|---|---|
数据库 | mysql | 3306 | v8 | 环境依赖 |
缓存 | redis | 6379 | v6 | 环境依赖 |
消息队列 | rabbitmq | 5672, 15672 | v3.12.6 | 环境依赖 |
注册中心 | nacos | 8848 | v2.2.0 | 环境依赖 |
网关服务 | gateway | 8101 | java 8 | 业务服务 |
用户服务 | yuoj-backend-user-service | 8102 | java 8 | 业务服务 |
题目服务 | yuoj-backend-question-service | 8103 | java 8 | 业务服务 |
判题服务 | yuoj-backend-judge-service | 8104 | java 8 | 业务服务 |
为什么这里我要划分服务类别为 “环境依赖” 和 “业务服务” 呢?
因为在启动服务时,必须要先启动环境依赖,才能启动业务服务,否则就会报类似 “无法连接数据库” 之类的错误。
2:Maven 子父模块打包
对于微服务项目,我们通常是使用 Maven 的子父模块功能进行管理的。
需要部署项目时,不用针对每个子服务单独执行 mvn package
命令进行打包,而是可以一键打包所有服务。
想要实现这个功能,需要给子父模块的依赖文件(pom.xml)进行一些配置,主要包括:
2.1:父模块配置
在父模块的 pom.xml 文件中引入 spring-boot-maven-plugin
即可
⚠️ 一定不要配置 configuration 和 repackage!
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
</plugin>
2.2:子模块配置
修改所有需要启动 Spring Boot 的服务(用户服务、题目服务、判题服务、网关服务)的子模块 pom.xml 文件。
主要是增加 executions 配置,使用 spring-boot-maven-plugin 的 repackage 命令来构建子模块
从而自动在构建时将公共模块的依赖打入 jar 包。
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<id>repackage</id>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
3:Dockerfile 编写
我们需要给每个 Spring Boot 服务(用户服务、题目服务、判题服务、网关服务)都编写一个 Dockerfile,放到每个子服务的根目录下。
以用户服务为例,示例代码如下:
# 基础镜像
FROM openjdk:8-jdk-alpine
# 指定工作目录
WORKDIR /app
# 将 jar 包添加到工作目录,比如 target/yuoj-backend-user-service-0.0.1-SNAPSHOT.jar
ADD target/yuoj-backend-user-service-0.0.1-SNAPSHOT.jar .
# 暴露端口
EXPOSE 8102
# 启动命令
ENTRYPOINT ["java","-jar","/app/yuoj-backend-user-service-0.0.1-SNAPSHOT.jar","--spring.profiles.active=prod"]
🎉 建议先在本地利用 IDEA 开发工具调通镜像构建流程,确保每个 Dockerfile 都是可以成功制作镜像的
查看容器的启动日志,发现能够启动服务、看到 Spring 图标即可:
4:env docker compose编写
之前我们已经梳理了服务部署表格,将服务划分为了 “环境依赖” 和 “业务服务”。
由于业务服务依赖 MySQL 等环境依赖,所以需要拆分 2 套 Docker Compose 的配置文件:
分别为 docker-compose.env.yml
环境配置和 docker-compose.service.yml
业务服务配置,保证先成功启动依赖,再启动服务。
Docker Compose 中的 depends_on 配置,也能决定服务的启动顺序。
但是depends_on 并不会等待服务完全就绪,只是确保它们在启动时的顺序,并不稳定。
4.1:MySQL docker Compose
我们不仅要创建一个 MySQL 服务,还要在创建服务后自动创建我们需要的库表结构。
所以需要先准备数据库 SQL 脚本文件,里面包含了建库、建表语句,我们把它放在微服务项目根目录的 mysql-init
文件夹中:
每个项目都提供了现成的建表语句,这是一个非常好的开发习惯,便于其他人快速启动你的项目。
由于要在本地启动 MySQL,还需要定义一个文件夹 .mysql-data
来存放 MySQL 的持久化数据,防止容器重启后数据丢失。
做好这两点后,就可以编写 docker-compose.env.yml
文件了,先只写一个 MySQL 服务,示例代码如下:
version: '3'
services:
mysql:
image: mysql:8 # 使用的镜像
container_name: yuoj-mysql # 启动的实例名称
environment:
MYSQL_ROOT_PASSWORD: 123456 # root 用户密码
ports:
- "3306:3306" # 端口映射
volumes:
- ./.mysql-data:/var/lib/mysql # 将数据目录挂载到本地目录以进行持久化
- ./mysql-init:/docker-entrypoint-initdb.d # 自动执行启动脚本
restart: always # 崩溃后自动重启
networks:
- mynetwork # 指定网络
networks:
mynetwork: # 自定义网络,实现网络互通和隔离
写好配置文件后,可以直接在 IDEA 里执行 Docker Compose 文件,调试 MySQL 的运行:
运行成功后,我们可以在本地成功连接数据库:
4.2:redis docker Compose
Redis 服务的定义和启动操作和 MySQL 服务几乎一致,Redis 的 Docker Compose 配置示例代码如下:
version: '3'
services:
redis:
image: redis:6 # 指定镜像是redis6
container_name: yuoj-redis # 声明容器名称
ports:
- "6379:6379" # 端口映射
networks:
- mynetwork # 指定网络
volumes:
- ./.redis-data:/data # 持久化
networks:
mynetwork: # 自定义网络,实现网络互通和隔离
然后在本地执行 Docker Compose 文件,启动 Redis 服务,并且尝试进入 Terminal 来调试 Redis:
4.3:rabbitMQ docker Compose
大体都一样,不在赘述
version: '3'
services:
rabbitmq:
image: rabbitmq:3.12.6-management # 支持管理面板的消息队列
container_name: yuoj-rabbitmq
environment:
RABBITMQ_DEFAULT_USER: guest
RABBITMQ_DEFAULT_PASS: guest # 用户名和密码
ports:
- "5672:5672"
- "15672:15672" # RabbitMQ Dashboard 端口
volumes:
- ./.rabbitmq-data:/var/lib/rabbitmq # 持久化
networks:
- mynetwork
networks:
mynetwork:
本地执行 Docker Compose 文件,启动 RabbitMQ 服务,然后可以访问 localhost:15672
查看到管理面板,就表示启动成功了
4.4:nacos docker Compose
在选择 Nacos 镜像时必须要注意,建议选择支持 linux/arm64 架构的镜像版本,比如 v2.2.0-slim
,否则后面可能会无法运行:
version: '3'
services:
nacos:
image: nacos/nacos-server:v2.2.0-slim
container_name: yuoj-nacos
ports:
- "8848:8848"
volumes:
- ./.nacos-data:/home/nacos/data
networks:
- mynetwork
environment:
- MODE=standalone # 单节点模式启动
- PREFER_HOST_MODE=hostname # 支持 hostname
- TZ=Asia/Shanghai # 控制时区
networks:
mynetwork:
然后在本地执行 Docker Compose 启动 Nacos,访问 localhost:8848/nacos
能够看到管理页面,就表示运行成功了
管理页面的账号和密码默认都是 nacos
4.5:环境compose整合
分别调试完上述服务后,我们把所有的配置拼在一起,就得到了完整的文件,文件名为 docker-compose.env.yml
。
version: '3'
services:
mysql:
image: mysql:8 # 使用的镜像
container_name: yuoj-mysql # 启动的实例名称
environment:
MYSQL_ROOT_PASSWORD: 123456 # root 用户密码
ports:
- "3306:3306" # 端口映射
volumes:
- ./.mysql-data:/var/lib/mysql # 将数据目录挂载到本地目录以进行持久化
- ./mysql-init:/docker-entrypoint-initdb.d # 启动脚本
restart: always # 崩溃后自动重启
networks:
- mynetwork # 指定网络
redis:
image: redis:6
container_name: yuoj-redis
ports:
- "6379:6379"
networks:
- mynetwork
volumes:
- ./.redis-data:/data # 持久化
rabbitmq:
image: rabbitmq:3.12.6-management # 支持管理面板的消息队列
container_name: yuoj-rabbitmq
environment:
RABBITMQ_DEFAULT_USER: guest
RABBITMQ_DEFAULT_PASS: guest
ports:
- "5672:5672"
- "15672:15672" # RabbitMQ Dashboard 端口
volumes:
- ./.rabbitmq-data:/var/lib/rabbitmq # 持久化
networks:
- mynetwork
nacos:
image: nacos/nacos-server:v2.2.0-slim
container_name: yuoj-nacos
ports:
- "8848:8848"
volumes:
- ./.nacos-data:/home/nacos/data
networks:
- mynetwork
environment:
- MODE=standalone # 单节点模式启动
- PREFER_HOST_MODE=hostname # 支持 hostname
- TZ=Asia/Shanghai # 控制时区
networks:
mynetwork:
5:service docker compose编写
示例代码如下,其中需要格外关注的配置是 build 和 depends_on:
version: '3'
services:
yuoj-backend-gateway:
container_name: yuoj-backend-gateway # 指定容器名称
build: # 服务的 Docker 构建文件位置
context: ./yuoj-backend-gateway # 指定目录
dockerfile: Dockerfile # 指定dockerfile
ports:
- "8101:8101" # 端口映射
networks:
- mynetwork # 指定网络
yuoj-backend-user-service:
container_name: yuoj-backend-user-service # 指定容器名称
build:
context: ./yuoj-backend-user-service # 指定目录
dockerfile: Dockerfile # 指定dockerfile
ports:
- "8102:8102" # 端口映射
networks:
- mynetwork # 指定网络
depends_on: # 本服务依赖的服务,控制启动先后顺序
- yuoj-backend-gateway # 用户服务依赖于网关服务
yuoj-backend-question-service:
container_name: yuoj-backend-question-service # 指定容器名称
build:
context: ./yuoj-backend-question-service # 指定目录
dockerfile: Dockerfile # 指定dockerfile
ports:
- "8103:8103" # 端口映射
networks:
- mynetwork # 指定网络
depends_on:
- yuoj-backend-user-service # 问题服务依赖于用户服务
- yuoj-backend-gateway # 问题服务依赖于网关服务
yuoj-backend-judge-service:
container_name: yuoj-backend-judge-service # 指定容器名称
build:
context: ./yuoj-backend-judge-service # 指定目录
dockerfile: Dockerfile # 指定dockerfile
ports:
- "8104:8104" # 端口映射
networks:
- mynetwork # 指定网络
depends_on:
- yuoj-backend-user-service # 判题服务依赖于用户服务
- yuoj-backend-question-service # 判题服务依赖于问题服务
- yuoj-backend-gateway # 判题服务依赖于网关服务
# 网络,不定义的话就是默认网络
networks:
mynetwork:
6:调整程序配置
编写好上述配置文件后,本地尝试运行 Docker Compose 业务服务,结果发现:报错啦!依赖服务的地址访问不通!
这是由于之前我们的项目访问依赖服务时,全部是使用了固定的 IP 地址(比如 localhost)
而容器内部的 localhost(或 127.0.0.1)通常指向容器本身,而不是宿主主机。
所以为了在容器内访问其他服务,程序中应该使用服务名称而不是 localhost。
我们给每个 Spring Boot 服务都增加一套 prod 上线配置,在配置中更改服务调用地址。
用户服务、题目服务和判题服务的 application-prod.yml
配置修改如下:
# 生产环境配置文件
spring:
# 数据库配置
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://mysql:3306/yuoj # localhost 改为 mysql
username: root
password: 123456
# Redis 配置
redis:
database: 1
host: redis # localhost 改为 redis
port: 6379
timeout: 5000
cloud:
nacos:
discovery:
server-addr: nacos:8848 # localhost 改为 nacos
rabbitmq:
host: rabbitmq # localhost 改为 rabbitmq
port: 5672
password: guest
username: guest
Gateway 网关服务的配置修改如下:
spring:
cloud:
nacos:
discovery:
server-addr: nacos:8848 # localhost 改为 nacos
gateway:
# ------> 指定网关映射 <------
routes:
- id: yuoj-backend-user-service
uri: lb://yuoj-backend-user-service
predicates:
- Path=/api/user/**
- id: yuoj-backend-question-service
uri: lb://yuoj-backend-question-service
predicates:
- Path=/api/question/**
- id: yuoj-backend-judge-service
uri: lb://yuoj-backend-judge-service
predicates:
- Path=/api/judge/**
application:
name: yuoj-backend-gateway
main:
web-application-type: reactive
server:
port: 8101
# 网关层支持swagger
knife4j:
gateway:
enabled: true
strategy: discover
discover:
enabled: true
version: swagger2
然后执行 mvn package
命令重新打包、执行 Docker Compose。
🎉 一定不要在项目中写死ip, 最好读取配置的方式,例如
/**
* 用于创建测试程序用到的交换机和队列(只用在程序启动前执行一次)
*/
@Slf4j
@Component
public class InitRabbitMqBean {
@Value("${spring.rabbitmq.host:localhost}")
private String host;
@PostConstruct
public void init() {
try {
ConnectionFactory factory = new ConnectionFactory();
factory.setHost(host);
Connection connection = factory.newConnection();
Channel channel = connection.createChannel();
String EXCHANGE_NAME = "code_exchange";
channel.exchangeDeclare(EXCHANGE_NAME, "direct");
// 创建队列,随机分配一个队列名称
String queueName = "code_queue";
channel.queueDeclare(queueName, true, false, false, null);
channel.queueBind(queueName, EXCHANGE_NAME, "my_routingKey");
log.info("消息队列启动成功");
} catch (Exception e) {
log.error("消息队列启动失败");
}
}
}
7:测试访问
修复上述问题后,所有服务都可以通过 Docker Compose 文件启动了。
然后我们访问 localhost:8101/doc.html
网关地址,能够看到 Swagger 聚合接口文档。
8:服务器部署
8.1:Docker Compose 安装
有了服务器后,直接参考 Docker Compose 官方文档来安装。
这里我们使用 Docker Compose V2 版本,相比 V1 版本统一了命令,使用更方便:
Docker Compose V2 地址:https://docs.docker.com/compose/migrate/
Docker Compose Linux 安装:https://docs.docker.com/compose/install/linux/#install-using-the-repository
安装过程很简单,跟着官方文档来就行了,主要包括以下几个步骤:
1)设定安装来源:
sudo yum install -y yum-utils
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
2)安装 Docker 和 Docker Compose:
sudo yum install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
3)启动 Docker:
sudo systemctl start docker
4)测试 Docker:
systemctl status docker
sudo docker run hello-world
8.2:同步文件
接下来,我们需要把本地折腾好的微服务项目源码上传到服务器上,可以选择用 FTP 或 SSH 连接文件手动上传文件。
8.3:获取 jar 包
光把代码上传到服务器还是不够的,因为我们构建 Docker 镜像需要 jar 包。
有 2 种方式得到 jar 包:
- 本地执行
mvn package
打好 jar 包,然后再上传 - 服务器上装 Maven,在服务器上打包
但是因为 jar 包比较大,频繁改动的话同步速度会比较慢,所以更建议第二种方式,步骤如下:
1)安装 Maven:
sudo yum install maven
2)安装好后,执行打包:
sudo mvn package
打包成功:
8.4:服务启动
8.4.1:启动环境依赖
先使用 docker compose 一行命令启动环境依赖:
# 老版本使用 "docker-compose" 替代 "docker compose"
# 如果没有权限,命令前加上 "sudo"或者编程超级用户
docker compose -f docker-compose.env.yml up
启动成功后,我们可以通过公网 IP 来尝试访问服务。
先进入到云服务商的服务器配置页,修改服务器的防火墙配置,放通以下端口:
8.4.2:后台运行进程
由于进程在前台启动会影响我们的操作,所以先按 ctrl + c
退出,加上 -d
参数让容器在后台启动:
sudo docker compose -f docker-compose.env.yml up -d
试着查看下 docker 容器的状态:
sudo docker stats
8.4.3:启动业务服务
确保环境依赖都启动成功后,接下来启动业务服务:
docker compose -f docker-compose.service.yml up
如果某个服务启动失败,可以再次单独只启动它,比如网关服务:
sudo docker compose
-f docker-compose.service.yml
up
yuoj-backend-gateway # 单独启动网关服务
8.5:测试访问
三:Docker Swarm
1:Docker Swarm简介
1.1:概述和作用
Docker Swarm是Docker官方提供的一个容器编排工具,用于管理Docker容器集群。
它提供了一组API以及命令行工具,使得用户可以轻松地创建、启动、停止以及扩展应用程序。
Docker Swarm的作用在于,它可以帮助用户管理多个Docker容器,简化应用程序的部署和管理
Docker Swarm将多个Docker主机组成一个集群,用户可以将应用程序部署到集群中,Docker Swarm会自动将应用程序部署到可用的Docker主机上
当集群中的某个Docker主机出现故障时,Docker Swarm会自动将受影响的容器重新部署到其他可用的主机上
1.2:Docker Swarm与Kubernetes
Docker Swarm和Kubernetes都是容器编排工具,它们都可以用于管理容器集群。下面是它们的比较优缺点:
Docker Swarm的优点:
- Docker Swarm功能相对简单,易于上手。
- Docker Swarm1.12后,Docker原生支持Swarm,无需再额外安装,使用更加便捷。
- Docker Swarm的性能比较高,可以快速地利用集群中的资源进行部署。
Kubernetes的优点:
- Kubernetes的功能非常强大,可以满足各种复杂的部署和管理需求。
- Kubernetes有很多插件和第三方工具,可以满足各种不同的需求。
- Kubernetes在容器编排方面的功能比Docker Swarm更加强大和灵活。
Docker Swarm的缺点:
- 相对于Kubernetes的高度可定制化,Docker Swarm的功能相对简单,可能无法满足高度定制化的需求。
- Docker Swarm并没有像Kubernetes那样支持多集群。
Kubernetes的缺点:
- Kubernetes的学习曲线较陡峭,需要更多的学习和时间投入。
- Kubernetes架构复杂,运维成本相对高一些。
1.3:安装Docker Swarm
安装 Docker Engine 取决于你的操作系统。以下是 Docker Engine 的安装步骤:
在 Linux 中安装 Docker Engine:
sudo apt-get remove
docker
docker-engine
docker.io containerd runc
安装docker Engine:
$ sudo apt-get update
$ sudo apt-get install -y apt-transport-https ca-certificates curl gnupg lsb-release
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
$ echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
$ sudo apt-get update
$ sudo apt-get install -y docker-ce docker-ce-cli containerd.io
1.4:需要关注的步骤
1.4.1:配置主节点
首先,需要选择其中一个节点作为Docker Swarm的主节点。该节点应安装Docker,并运行以下命令以初始化Swarm
docker swarm init --advertise-addr <MANAGER-IP>
🎉 在这里会生成token,可以进行抓取,token作用在日志中
1.4.2:其他节点加入
现在可以将其他节点加入到Docker Swarm中。在各个节点上,运行以下命令以加入集群:
docker swarm join --token <TOKEN> <MANAGER-IP>:2377
1.5:部署服务
一旦Docker Swarm集群已准备就绪,可以利用docker stack命令将应用程序部署到集群中。
可以使用Docker Compose YAML文件定义服务和网络,如以下示例:
version: '3'
services:
web:
image: nginx
ports:
- "80:80"
redis:
image: redis
执行以下命令以启动应用程序:
# 需要使用docker-compose.yml文件和指定的服务名称。
docker stack deploy -c <docker-compose.yml> <SERVICE-NAME>
1.6:核心概念
1.7:生命周期
2:核心使用
2.1 用法的基础知识
Docker Swarm是Docker官方提供的一个用于管理Docker集群的工具。
它可以将多个Docker主机组合为一个虚拟的Docker主机,并将容器应用程序无缝地在多个Docker主机之间分配和调度。
Docker Swarm使用了多个构建块并提供了一些重要的概念,其中包括节点角色、服务概念以及集群网络。
2.2:节点角色
Docker Swarm节点分为主节点和工作节点两种,其角色有所不同。
- 主节点:是Swarm管理者,负责配置、调度和协调服务,管理节点和排除故障等。主节点拥有Swarm集群的全图和完整的状态信息。
- 工作节点:运行容器。通过监听主节点访问请求接收服务部署信息并运行容器服务。工作节点可以是物理服务器、虚拟机等其他Docker主机。
2.3:服务概念
服务是Swarm集群的基本单位。
一个服务可以由多个副本组成。每一个副本运行在集群的不同节点上,间接提供应用程序的容错能力和可扩展性。
同时,通过对服务的定制化配置,还可以支持服务发现、负载均衡、升级和滚动回滚等操作。
2.4:创建Docker Swarm集群
2.4.1:操作步骤
创建Docker Swarm集群需要按照以下步骤操作:
-
创建一个Swarm管理节点:使用docker swarm init命令创建Swarm管理节点,并获取token。
-
加入工作节点:使用docker swarm join命令将工作节点加入到Swarm集群中,使用之前获取的token和主机IP地址加入节点。
-
用户配置网络和服务。
⚠️ Swarm集群的规模可根据需要扩展,而在扩展时,必须将新的工作节点加入到现有的Swarm集群中。
⚠️ 要加入新节点,必须在新节点上运行docker swarm join命令,并将新节点的令牌提供给Swarm管理节点。
创建Docker Swarm集群的详细步骤
- 在主节点上使用以下命令初始化Swarm:
docker swarm init --advertise-addr <MANAGER-IP> # 注意在这里的日志中抓取token
- 检查是否成功初始化Swarm集群,可通过以下命令查看状态:
docker node ls
- 在工作节点上通过以下命令加入Swarm集群:
docker swarm join --token <TOKEN> <MANAGER-IP>:2377
- 加入集群之后,可通过执行以下命令在Swarm集群上创建一个名为nginx-web服务并运行两个实例
docker service create # 声明创建服务
--name nginx-web # 服务的名称
--replicas 2 # 指定副本数为2,表示运行两个实例
-p 8080:80 # 端口映射-宿主机端口8080,容器端口80
nginx # 指定镜像
该服务将nginx容器映射到集群中的两个工作节点,并将服务的监听端口从容器的80号端口到Swarm集群中任意一个节点的8080端口进行转发。
查看服务的信息docker service inspect --pretty <service id>
- –pretty 参数可以简化输出內容
docker service ps <service id>
可以查看运行中的服务信息- 进入工作节点通过 docker ps 可以查看容器运行状态
2.4.2:弹性伸缩
更新服务的实例个数:docker service update --replicas <num> <service id/name>
添加新的 Docker 节点,执行 docker swarm join
命令可以加入集群
执行 docker swarm leave
可以退出集群,也可以带上 --force 参数强制退出集群
2.5 部署和管理应用程序
2.5.1 部署和管理应用程序
Docker Compose是一种工具,可以通过一个单独的YAML文件来定义、部署和运行由多个容器组成的应用程序。
使用Docker Compose可以简化多个Docker容器的部署,并且可以通过一个文件来定义容器之间的依赖关系。
Docker Compose允许在单个主机上运行应用程序,而Docker Stack则扩展并在Swarm集群中运行应用程序。
2.5.2 扩展应用程序
Swarm允许在多台主机之间扩展应用程序,并自动管理应用程序的多个实例。
利用Docker Compose和Docker Stack文件中所定义的服务和副本数
Swarm集群会在集群中的多个Docker宿主机上创建相应数量的“副本”容器实例。
# 需要使用docker-compose.yml文件和指定的服务名称。
docker stack deploy -c <docker-compose.yml> <SERVICE-NAME>
3:深入了解&高级部分
3.1:Docker Swarm的高级特性
3.1.1 滚动更新和回滚服务
在更新应用程序时,Swarm集群支持滚动更新和回滚服务的功能。
这意味着服务的所有实例会被逐步替换,从而可以保持应用程序的可用性。回滚操作可以撤消任何滚动更新。
使用滚动更新时,Swarm会同时启动新的副本与现有的副本一起运行。
一旦新的副本被设置为正在运行,Swarm将逐步停止现有副本。此过程将自动应用于所有Swarm服务。
3.1.2 每个部署延迟
Swarm支持一个deploy.delay选项,该选项确定在多个主机上进行部署时每个任务的最长延迟。
在部署新服务或更新现有服务时,Swarm将保持“旧”服务的状态,直到它已准备好接受请求。
如果在滚动更新服务时任何问题发生,新版本的服务可以立即回滚,从而保证了可用性。
3.1.3 保护敏感信息
Docker Secrets是Docker Swarm提供的一种安全管理敏感信息的方式,可用于安全地管理和传递密钥、密码和其他保密信息。
Docker Secrets收到Docker Swarm的保护,因此可以更安全地处理密钥和其他类型数据,从而更好地保护应用程序。
Docker Secrets是用于管理敏感信息的指令,它将加密用于生产环境的信息,并确保仅在需要时才向所需容器提供访问。
使用Docker Secrets,可以轻松地传递敏感信息,而无需在代码之外保留此类信息。
使用Docker Secrets的步骤:
- 创建要保护的数据:常用的管理密码方法包括传统的密码存储库,密钥管理服务,密码管理器,甚至包括环境变量或命令行参数
- 创建一个Secret对象
docker secret create <name> <file> # name是您要创建的受保护数据的名称,file是包含敏感信息的文件路径。
- 在服务中使用Secret
# 可以在Docker Compose文件或Docker Stack文件中定义如何在服务中使用Secret。
# 需要将Secret的名称添加到文件中的适当位置。
# 以下是使用db_password Secret的Docker Compose文件的示例
# 这段代码将db_password Secret注入到名为db的MySQL数据库容器中。
version: "3.2"
services:
db:
image: mysql
secrets:
- db_password
secrets:
db_password:
external: true
3.2: 监控Docker Swarm集群
3.2.1:日志记录系统
Docker Swarm集群提供了内置的日志记录系统来帮助诊断问题。
通过使用docker service logs命令查看服务的日志文件,可以在Swarm集群中找到各个服务的问题所在。
例如,以下命令将打印名为web服务的日志:
docker service logs web
3.2.2:监控集群
Prometheus可以用来收集和监控Swarm集群的应用程序和容器的性能指标。
Grafana是一种数据可视化工具,可以与Prometheus一起使用,动态监视Swarm集群的性能和运行情况。
要使用Prometheus和Grafana监控Swarm集群,需要在集群中安装并配置Prometheus,然后使用Grafana dashboard可视化数据。
3.3:错误排除和故障恢复
3.3.1 排查故障的方法
-
检查Swarm节点状态:运行
docker node ls
命令查看节点状态,确保所有节点正常工作。 -
检查Swarm服务状态:运行
docker service ls
命令以检查所有服务的状态,并确认它们正在集群中的工作节点上运行。 -
检查容器日志:运行
docker service logs
命令以查看服务的容器日志。 -
检查Docker Swarm事件:运行
docker service events
命令以查看集群中的所有事件,从而识别问题并解决它。
3.3.2 处理容器故障
Swarm支持健康检查和自适应调度功能,可自动检测和处理容器故障。
Swarm通常使用健康检查来检测容器的运行状况,并在必要时自动替换故障容器的实例。
健康检查的类型包括:命令、HTTP请求、TCP端口
在出现容器故障时,Swarm会从Docker Registry中检索新的镜像,并使用存在的容器映像来替换故障
3.4:可视化工具portainer
安装portainer:
- 基于docker ->
docker run
-d
-p 9000:9000
--restart=always
-v /var/run/docker.sock:/var/run/docker.sock
-v portainer_data:/data
portainer/portainer
- 基于docker swarm ->
docker service create
-p 9000:9000
--replace 1
--mount type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock
--mount type=volume,src=portainer_data,dst=/data
portainer/portainer
访问docker swarm任意节点地址都可以访问