docker高级
文章目录
- 1.Docker Compose
- 1.1 介绍
- 1.2 compose文件
- 1.3 常用命令
- 1.4 安装
- 1.5 项目说明和构建
- 1.5.1 手工启动
- 1.5.2 compose 编排启动
- 1.5.3 完善 compose.yml
- 1.5.4 加入前端容器
- 2.UI管理平台
- 2.1 portainer
- 3.镜像发布
- 3.1 阿里云
- 3.2 Docker Registry
- 3.2.1 介绍
- 3.2.2 安装
- 3.2.3 测试
- 3.2.4 https 问题
- 方法1.配置 Docker 客户端允许 HTTP 连接
- 方法2.使用 HTTPS 配置 Registry(推荐)
- 5.Docker Swarm
- 5.1 简介
- 5.1.1 节点
- 5.1.2 服务、任务、容器
- 1.2 swarm集群
- 5.3 节点维护
- 5.3.1 退群进群
- worker 节点
- manager 节点
- 5.3.2 更改角色 (升级降级)
- 5.3.3 节点标签
- 5.4.1 开启 autolock
- 5.4.2 状况模拟
- 5.5 创建服务
- 5.6 服务的负载均衡
- 1.7 扩容缩容与可用性
- 1.7.1 扩容缩容
- 5.7.2 availability 可用性
- 1.8 全局模式部署
1.Docker Compose
1.1 介绍
对于现在应用来说,大多都是通过很多的微服务互相协同组成的一个完整应用。
例如订单管理、用户管理、品类管理、缓存服务、数据库服务等,它们构成了一个电商平台的应用。
部署和管理大量的服务容器是一件非常繁琐的事情,而 Docker Compose 就是解决这类问题的。
Docker Compose 是一个需要在 Docker 主机上进行安装的 Docker 容器编排外部工具。
其并不是通过脚本或各种冗长的 Docker 命令来将应用组件组织起来的,而是通过一个声明式的配置文件描述整个应用,然后通过一条命令完成应用部署的。
部署成功后,还可通过一系列简单命令实现对其完整生命周期的管理。
1.2 compose文件
Docker Compose 使用 YAML 文件来定义服务,官方推荐的默认文件名为 compose.yml 但同时也支持 docker-compose.yml。
由于一个 compose 文件中定义的是一个项目的所有服务,所以一般为在创建 compose 文件之前先新建一个目录,目录名称一般为项目名称,然后再将项目所需的所有镜像、微服务的 Dockerfile放入该目录,并在该目录中新建 compose 文件。
compose 文件中包含6个顶级属性:version、services、networks、volumes、configs 与 secrets,它们下面还包含很多属性。
官方:https://docs.docker.com/reference/compose-file/
1.3 常用命令
官方:https://docs.docker.com/reference/cli/docker/compose/
-
docker-compose pull
拉取 compose 中服务依赖的全部镜像或指定镜像,通过在命令后添加服务名称来指定。
-
docker-compose config
检査 compose 文件是否正确,可添加选项-q,表示只有存在问题时才有输出。
-
docker-compose up
启动 compose 中的所有容器,-d 选项表示后台启动。
-
docker-compose down
停止并移除 compose 中的所有容器、网络
-
docker-compose logs
查看 comopse 中所有服务或指定服务的运行日志,通过在命令后添加服务名称来指定。
默认情况下,将对不同的服务日志使用不同的颜色来区分。 -
docker-compose ps
列出 compose 中所有服务或指定服务,通过在命令后添加服务名称来指定。
-
docker-compose top
列出 compose 中当前正在运行的所有服务或指定服务,通过在命令后添加服务名称来指定。
-
docker-compose images
列出 compose 中所有服务或指定服务对应的镜像,通过在命令后添加服务名称来指定。 -
docker-compose port
列出指定服务容器的指定端口所映射的宿主机端口。
-
docker-compose run
用于在已经运行的服务中启动一个新的容器。与 docker-compose up 命令不同,docker-compose run 命令可以单独启动一个容器,而不是启动所有定义的服务。 -
docker-compose exec
进入指定服务容器,通过在命令后添加服务名称来指定。
-
docker-compose pause
暂停 compose 中所有服务容器或指定服务容器,通过在命令后添加服务名称来指定。 -
docker-compose unpause
恢复 compose 中处于暂停状态的所有服务容器或指定服务容器,通过在命令后添加服务名称来指定。 -
docker-compose stop
在不移除容器的情况下停止运行容器。可以通过docker compose start 重新启动容器。 -
docker-compose start
启动服务或现有容器。
-
docker-compose restart
重新启动所有已停止和正在运行的服务,或仅重新启动指定的服务。
-
docker-compose kill
通过发送 SIGKILL 信号强制运行的容器停止,可以选择性地传递该信号。
-
docker-compose rm
移除已停止的服务容器。
1.4 安装
官方:https://docs.docker.com/compose/install/standalone/
# 下载
curl -SL https://github.com/docker/compose/releases/download/v2.32.4/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
#切换目录
cd /usr/local/bin
# 更改名称
mv docker-compose-linux-x86_64 docker-compose
# 给docker-compose可执行权限
chmod +x /usr/local/bin/docker-compose# 创建软连接
ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose# 查看版本
docker-compose --version
1.5 项目说明和构建
说明:同02进阶中的shopms项目,只构建后台java项目即可,此处略
1.5.1 手工启动
手工构建:
- 运行 mysql 容器,恢复数据
- java项目用Dockerfile构建镜像,再运行容器
1.5.2 compose 编排启动
创建目录 /shopapp,在其中编写 compose.yml
用 services 定义若干个服务:
继续定义:
services:app:build: ./app #指定 app 服务的镜像./app 中的 Dockerfile 来生成的。./app 表示当前工作目录下的 app 文件夹container_name: shopapp #指定容器的名称为 shopapp。ports:- 9090:9090 #将容器的端口 9090 映射到宿主机的端口 9090。depends_on: - db #指定 app 服务依赖于 db 服务。db:image: mysql:5.7 #指定 db 服务使用 mysql:5.7 镜像environment:MYSQL_ROOT_PASSWORD: 123456 #设置 MySQL 数据库的环境变量,指定 root 用户的密码为 123456ports:- 3306:3306 #将容器的端口 3306 映射到宿主机的端口 3306。volumes:#将宿主机的 ./db/conf 目录挂载到容器的 /etc/mysql/conf.d 目录。- ./db/conf:/etc/mysql/conf.d#将宿主机的 ./db/data 目录挂载到容器的 /var/lib/mysql 目录。- ./db/data:/var/lib/mysql
检查 compose.yml 语法:
docker-compose config -q
启动:
docker-compose up -d
停止:
docker-compose down
查看容器、镜像:
查看网络:
postman测试api请求:
如果数据库访问失败,检查springboot配置文件,如下:
注意:application.yml
1.5.3 完善 compose.yml
如果修改了compose文件名,如compose2.yml,启动用: docker-compose -f compose2.yml up -d
1.5.4 加入前端容器
2.UI管理平台
希望查看运行中的容器所占用的系统情况,可以使用命令:
docker stats
但是不够直观,可以安装带有UI界面的管理平台,帮助用户进行管理。
2.1 portainer
官网:https://www.portainer.io/
linux安装portainer:https://docs.portainer.io/start/install-ce/server/docker/linux
先拉取镜像:
docker pull portainer/portainer-ce
数据卷:
docker volume create portainer_data
查找位置:
docker volume inspect portainer_data
运行容器:
docker run -d -p 8000:8000 -p 9443:9443 -p 9000:9000 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest
网页访问:
http://192.168.9.3:9000
用 9443 端口也可访问,注意是 https 的协议:
https://192.168.9.3:9443
3.镜像发布
3.1 阿里云
登录 https://www.aliyun.com/ (账号需经过实名认证)
容器镜像服务:
其中的“实例”指的就是镜像仓库,进入个人版实例:
设置“访问凭证”,相当于是登录镜像中心的密码
设置“命名空间”,名字要求全网唯一(可以创建多个)
创建“镜像仓库”,仓库名称相当于镜像名
根据操作指南,测试 push 镜像,先登录(docker login)
把镜像按照要求重新打标签(docker tag)
推送到镜像中心(docker push)
在“镜像版本中”可以看到刚才推送的镜像(digest码一致):
把之前的镜像删除,测试pull :
其他,登出:
docker logout registtry.cn-hangzhou.aliyuncs.com
3.2 Docker Registry
3.2.1 介绍
搭建 Docker 镜像中心最常用的技术是 Docker Registry,尤其是 Docker Distribution,它是 Docker 官方提供的开源镜像仓库。
https://hubgw.docker.com/_/registry
3.2.2 安装
提问deepseek:在 centos7中已经装了docker了,现在要安装 Docker Registry ,并且用 htpasswd 进行验证,怎么做
步骤1.安装 htpasswd
是 Apache 提供的工具,用于创建和管理用户认证文件,如果系统中没有安装,可以通过以下命令安装:
yum install -y httpd-tools
步骤2.创建一个目录来存储认证文件,并生成 htpasswd文件:
# 创建认证文件目录
mkdir -p /opt/docker-registry/auth# 生成 htpasswd 文件(例如用户名为 tom)
htpasswd -Bc /opt/docker-registry/auth/htpasswd tom
- -B:使用 bcrypt 加密密码(推荐)。
- -c:创建新文件(如果文件已存在,不要使用
-c
,否则会覆盖文件)。
如果需要添加更多用户,可以运行:
# anotheruser为用户名
htpasswd -B /opt/docker-registry/auth/htpasswd anotheruser
步骤3.拉取镜像、运行容器:
docker pull registry
docker run -d \--name registry \-p 5000:5000 \-v /var/lib/registry:/var/lib/registry \-v /etc/docker/registry-auth:/auth \-e "REGISTRY_AUTH=htpasswd" \-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \-e "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd" \registry
-v /opt/docker-registry/auth:/auth
:将本地的auth
目录挂载到容器中。-v /opt/docker-registry/data:/var/lib/registry
:将本地的data
目录挂载到容器中,用于存储镜像数据。-e REGISTRY_AUTH=htpasswd
:启用htpasswd
身份验证。-e REGISTRY_AUTH_HTPASSWD_REALM
:认证域的名称(可以自定义)。-e REGISTRY_AUTH_HTPASSWD_PATH
:指定htpasswd
文件的路径。
3.2.3 测试
1.登录 Registry:
docker login localhost:5000
2.推送镜像:
标记一个本地镜像:
docker tag my-image localhost:5000/my-image
推送镜像到 Registry:
docker push localhost:5000/my-image
3.拉取镜像
docker pull localhost:5000/my-image
其他:验证身份验证
如果未登录或登录失败,尝试推送或拉取镜像时会收到以下错误:
unauthorized: authentication required
3.2.4 https 问题
远程登录报错,Docker 客户端默认尝试通过 HTTPS 连接 Registry,而 Docker Registry 是通过 HTTP 运行的。
方法1.配置 Docker 客户端允许 HTTP 连接
在 Docker 客户端机器上,编辑 Docker 的配置文件 /etc/docker/daemon.json
(如果文件不存在,可以创建它)
重启 docker服务,再次测试登录
systemctl restart docker
方法2.使用 HTTPS 配置 Registry(推荐)
步骤1.在Rigistry端进行操作
从 Go 1.15 开始,Go 语言(Docker 是用 Go 编写的)不再支持仅依赖 CN 字段的证书,必须使用 SAN 字段。要解决这个问题,你需要重新生成 TLS 证书,并在证书中包含 SAN 字段。
# 创建目录,用于存放证书等文件
mkdir -p /opt/docker-registry/certs# 切换目录
cd /opt/docker-registry/certs# 创建 openssl.cnf 文件
cat > openssl.cnf <<EOF
[req]
default_bits = 4096
prompt = no
default_md = sha256
distinguished_name = dn[dn]
CN = 192.168.9.4[v3_ext]
authorityKeyIdentifier=keyid,issuer:always
basicConstraints=CA:FALSE
keyUsage=digitalSignature,nonRepudiation,keyEncipherment
extendedKeyUsage=serverAuth
subjectAltName=@alt_names[alt_names]
IP.1 = 192.168.9.4
EOF
CN
:Common Name,填写 Registry 的 IP 或域名。subjectAltName
:在[alt_names]
部分定义 SAN,支持 IP 或域名。
生成私钥和证书,使用 OpenSSL 生成私钥和证书:
openssl req -newkey rsa:4096 -nodes -sha256 \-keyout domain.key \-out domain.csr \-config openssl.cnf# 如果有 CA 证书:
#openssl x509 -req -days 365 -sha256 \
# -in domain.csr \
# -CAcreateserial \
# -CA ca.crt -CAkey ca.key \
# -out domain.crt \
# -extensions v3_ext \
# -extfile openssl.cnf# 如果没有 CA 证书:
openssl req -x509 -newkey rsa:4096 -nodes -sha256 \-keyout domain.key \-out domain.crt \-days 365 \-config openssl.cnf \-extensions v3_ext
生成的 domain.key
和 domain.crt
文件将用于配置 Registry。
步骤2.删除之前的容器,配置 Docker Registry 使用 TLS,重新启动 Registry 容器,并挂载证书文件:
docker run -d \-p 5000:5000 \--name registry \-v /opt/docker-registry/auth:/auth \-v /opt/docker-registry/data:/var/lib/registry \-v /opt/docker-registry/certs:/certs \-e REGISTRY_AUTH=htpasswd \-e REGISTRY_AUTH_HTPASSWD_REALM="Registry Realm" \-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \registry
步骤3.在客户端机器上信任证书。将生成的 domain.crt
文件复制到客户端机器,并将其添加到系统的受信任证书列表中。
在 Registry 端把认证文件发送到客户端:
# 在客户端运行mkdir -p /etc/docker/certs.d/192.168.9.4:5000cp domain.crt /etc/docker/certs.d/192.168.9.4:5000/ca.crt
- Docker 客户端会检查
/etc/docker/certs.d/<registry-domain>:<port>/
目录下的ca.crt
文件。 - 如果 Registry 使用域名而不是 IP 地址,请将
192.168.9.4
替换为域名。
在客户端机器上重启 Docker 服务以加载新证书:
systemctl restart docker
再次尝试登录:
docker login https://192.168.9.4:5000
需要选择一个镜像进行标记
myapp 1.0 989d89d63bca About a minute ago 642MB
docker tag 989d89d63bca 192.168.9.4:5000/myapp:1.0
**docker tag
**用于为本地镜像创建一个新的标签(tag)
989d89d63bca
这是本地镜像的唯一标识符(镜像 ID)。每个 Docker 镜像都有一个唯一的 ID,可以通过docker images
命令查看。192.168.9.4:5000/myapp:1.0
这是目标镜像的完整名称,包括:192.168.9.4:5000
:这是远程 Docker Registry 的地址和端口。192.168.9.4
是私有 Registry 的 IP 地址,5000
是其服务端口。myapp
:这是镜像的名称。1.0
:这是镜像的版本标签(tag),用于区分不同版本的镜像。
推送镜像到 Registry
docker push 192.168.9.4:5000/myapp:1.0
这是私有 Docker Registry 的地址和端口:
192.168.9.4
是私有 Registry 的 IP 地址。5000
是私有 Registry 的服务端口(默认情况下,Docker Registry 使用 5000 端口)。
#推送的镜像位置 目录名就是镜像名称
#/opt/docker-registry/data/docker/registry/v2/repositories
一个新的标签(tag)
989d89d63bca
这是本地镜像的唯一标识符(镜像 ID)。每个 Docker 镜像都有一个唯一的 ID,可以通过docker images
命令查看。192.168.9.4:5000/myapp:1.0
这是目标镜像的完整名称,包括:192.168.9.4:5000
:这是远程 Docker Registry 的地址和端口。192.168.9.4
是私有 Registry 的 IP 地址,5000
是其服务端口。myapp
:这是镜像的名称。1.0
:这是镜像的版本标签(tag),用于区分不同版本的镜像。
推送镜像到 Registry
docker push 192.168.9.4:5000/myapp:1.0
这是私有 Docker Registry 的地址和端口:
192.168.9.4
是私有 Registry 的 IP 地址。5000
是私有 Registry 的服务端口(默认情况下,Docker Registry 使用 5000 端口)。
#推送的镜像位置 目录名就是镜像名称
#/opt/docker-registry/data/docker/registry/v2/repositories
5.Docker Swarm
5.1 简介
Docker Swarm 是由 Docker 公司推出的 Docker 的原生集群管理系统,它将一个 Docker主机池变成了一个单独的虚拟主机,用户只需通过简单的 API 即可实现与 Docker 集群的通信。
Docker swarm 使用 GO 语言开发,从 Docker 1.12.0版本开始,Docker swarm 已经内置于Docker引擎中,无需再专门的进行安装配置。
官网: https://docs.docker.com/engine/swarm/
5.1.1 节点
在 Docker Swarm 中,Manager 节点是集群的核心管理组件,负责维护集群状态、调度任务、处理 API 请求以及确保集群的高可用性。Manager 节点通过 Raft 一致性算法实现分布式一致性,确保集群的稳定运行。
Manager 节点的作用
- 集群管理:
- Manager 节点负责管理整个 Swarm 集群,包括节点的加入、离开、状态监控等。
- 它维护集群的全局状态,并确保所有节点的一致性。
- 任务调度:
- Manager 节点根据服务的定义和资源需求,将任务(Tasks)调度到合适的 Worker 节点上运行。
- 调度策略包括节点资源、约束条件(constraints)和偏好(preferences)等。
- 高可用性:
- Manager 节点通过 Raft 一致性算法实现高可用性。
- 多个 Manager 节点组成一个高可用集群,确保即使某个 Manager 节点失效,集群仍能正常运行。
- API 服务:
- Manager 节点提供 Docker API 服务,用于接收用户的管理请求(如创建服务、更新配置等)。
- 所有对 Swarm 集群的操作(如
docker service create
)都通过 Manager 节点执行。
- 维护集群状态:
- Manager 节点维护集群的全局状态,包括服务、网络、卷、配置和密钥等信息。
- 这些状态信息通过 Raft 日志在多个 Manager 节点之间同步。
- Leader 选举:
- 在多个 Manager 节点中,会选举出一个 Leader 节点,负责处理集群的管理任务。
- 如果 Leader 节点失效,剩余的 Manager 节点会重新选举一个新的 Leader。
- 安全性:
- Manager 节点负责管理 Swarm 集群的安全配置,如 TLS 证书、加密密钥等。
- 它还控制节点的加入和权限管理。
在 Docker Swarm 中,Worker 节点是 Swarm 集群的重要组成部分,主要负责运行和管理由 Swarm 调度的容器化任务(Tasks)。Worker 节点不参与 Swarm 集群的管理和决策,而是专注于执行实际的工作负载。
Worker 节点的作用
- 运行服务任务:
- Worker 节点负责运行由 Swarm Manager 节点调度的服务任务(Tasks)。
- 每个任务通常对应一个容器实例。
- 负载均衡:
- Worker 节点通过 Swarm 的内置负载均衡机制,确保服务的高可用性和性能。
- Swarm 会自动将任务分配到可用的 Worker 节点上。
- 扩展性和弹性:
- Worker 节点可以根据需要动态扩展或缩减,以应对工作负载的变化。
- 如果某个 Worker 节点失效,Swarm 会将该节点上的任务重新调度到其他健康的 Worker 节点上。
- 资源提供:
- Worker 节点提供计算、存储和网络资源,用于运行容器化应用。
- 与 Manager 节点协作:
- Worker 节点从 Manager 节点接收任务指令,并定期向 Manager 节点报告状态。
- Worker 节点不参与集群管理决策(如 Leader 选举、服务调度策略等)。
5.1.2 服务、任务、容器
- Service(服务)
-
定义:
- Service 是 Swarm 中部署和管理的核心单元,代表一个长期运行的应用或微服务。
- 它定义了应用的镜像、副本数量、网络配置、存储卷、环境变量等。
-
特点:
-
Service 是面向用户的抽象,用户通过创建和管理 Service 来部署应用。
-
Service 可以指定副本数量(Replicated Mode)或全局模式(Global Mode)。
-
Replicated Mode:指定固定数量的任务副本。
-
Global Mode:在每个符合条件的节点上运行一个任务。
-
-
- Task(任务)
-
定义:
- Task 是 Service 的具体实例化单位,代表一个容器化的任务。
- 每个 Task 对应一个容器,由 Swarm Manager 调度到某个节点上运行。
-
特点:
- Task 是 Swarm 调度的最小单位。
- 每个 Task 包含容器的配置信息(如镜像、网络、存储卷等)。
- Task 的状态由 Swarm Manager 监控和管理(如运行中、失败、完成等)。
-
示例:
- 如果一个 Service 定义了 3 个副本,Swarm 会创建 3 个 Task,每个 Task 对应一个容器。
- Container(容器)
- 定义:
- Container 是 Task 的实际运行实例,是 Docker 容器化的具体表现。
- 它是基于镜像创建的运行时环境,包含应用代码、依赖和配置。
- 特点:
- Container 是 Task 的具体实现,由 Task 定义其配置。
- 每个 Container 在某个节点上运行,由 Docker 引擎管理。
- 示例:
- 如果一个 Task 被调度到某个节点上,Docker 会在该节点上启动一个对应的容器。
三者的关系
- 层次结构:
- Service > Task > Container
- 一个 Service 包含多个 Task,每个 Task 对应一个 Container。
- 创建流程:
- 用户创建一个 Service,并指定副本数量。
- Swarm Manager 根据 Service 的定义,创建相应数量的 Task。
- 每个 Task 被调度到某个节点上,并由 Docker 引擎启动对应的 Container。
- 状态管理:
- Swarm Manager 监控 Service、Task 和 Container 的状态。
- 如果某个 Container 失效,Swarm 会重新调度对应的 Task,并在其他节点上启动新的 Container。
1.2 swarm集群
现要搭建一个 docker swarm 集群,包含5个swarm 节点。这5个swarm 节点的IP与暂时的角色分配如下(注意,是暂时的):
hostname | ip | role | required |
---|---|---|---|
docker1 | 192.168.9.3 | manager | 2核2G |
docker2 | 192.168.9.4 | manager | 2核2G |
docker3 | 192.168.9.5 | manager | 2核2G |
docker4 | 192.168.9.6 | worker | 1核1G |
docker5 | 192.168.9.7 | worker | 1核1G |
先了解以下命令:
docker1:
初始化swarm,默认自己会成为 manager 节点。
#在 docker1 初始化 swarm
docker swarm init
注:用 docker info 查看信息
docker4:
把 docker4 作为 worker节点加入swarm
# To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-5pj3mb6esgm13y7u2dvyre7jyaw2an7g628yg9nkgynp55ewhd-15di9u6twoea9ghapqmk99ozt 192.168.9.3:2377
docker2 和 docker3:
把 docker2和docker3 作为 manager 节点加入 swarm
# 在docker1上
# To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
docker swarm join-token manager
# 在docker2 和 docker3 上
docker swarm join --token SWMTKN-1-5pj3mb6esgm13y7u2dvyre7jyaw2an7g628yg9nkgynp55ewhd-0b465wi3hij8yqjea9qoqybm1 192.168.9.3:2377
查看命令说明
docker5:
把 docker5 作为 worker节点加入swarm
同理,也可以在docker1 运行:
# 在docker1上用该命令
docker swarm join-token worker
# 在docker5上
docker swarm join --token SWMTKN-1-5pj3mb6esgm13y7u2dvyre7jyaw2an7g628yg9nkgynp55ewhd-15di9u6twoea9ghapqmk99ozt 192.168.9.3:2377
查看节点信息:
docker node ls
5.3 节点维护
5.3.1 退群进群
worker 节点
worker 节点退群,以docker5 为例
# 在docker5上
docker swarm leave
在其他主机如docker1,查看节点信息(发现 docker5 的状态为 down)
docker5 重新加入 swarm
在docker1,查看节点信息,发现有两个 docker5 节点,但是ID不同。
这也就说明节点其实是逻辑概念,某台docker主机上可以存在若干节点。
要删除down节点,可以:docker node rm
再次查看节点
manager 节点
manager 节点退群,以docker3 为例:
这个错误表明你正在尝试从 Docker Swarm 集群中的一个 Manager 节点上执行 docker swarm leave
命令,而该节点当前是 Swarm 集群的管理者之一。由于 Manager 节点在 Swarm 中负责维护集群状态和一致性(通过 Raft 算法),直接离开可能会导致集群失去法定人数(quorum),从而无法正常工作。
错误原因
- Manager 节点的重要性:
- Swarm 集群需要多数(quorum)的 Manager 节点在线才能正常工作。如果过多的 Manager 节点离开,集群将无法达成共识,导致无法管理服务。
- 例如,如果你有 3 个 Manager 节点,至少需要 2 个在线才能维持集群的正常运行。
- 直接离开的后果:
- 如果你从一个 Manager 节点上直接执行
docker swarm leave
,可能会导致集群失去 quorum,从而无法继续运行。
- 如果你从一个 Manager 节点上直接执行
解决方法
方法 1:降级 Manager 节点
如果你希望该节点离开 Swarm 集群,但不影响集群的正常运行,可以先将该节点从 Manager 降级为 Worker 节点,然后再离开。
解决方法
方法 1:降级 Manager 节点
如果你希望该节点离开 Swarm 集群,但不影响集群的正常运行,可以先将该节点从 Manager 降级为 Worker 节点,然后再离开。
-
降级节点:
docker node demote <NODE-ID>
- 将
<NODE-ID>
替换为你要降级的节点的 ID(可以通过docker node ls
查看)。
- 将
-
离开 Swarm:
docker swarm leave
如果你确定要强制该节点离开 Swarm 集群,可以使用 --force
参数。但请注意,这可能会导致集群失去 quorum,从而无法正常工作。
-
强制离开:
docker swarm leave --force
-
如果集群因此失去 quorum,你需要手动恢复集群:
-
在剩余的 Manager 节点上执行以下命令,强制重新初始化集群:
docker swarm init --force-new-cluster
-
这将使当前节点成为新的 Swarm 集群的 Leader,并尝试恢复集群状态。
方法 3:恢复集群
-
如果集群已经失去 quorum 且无法正常工作,可以尝试以下步骤恢复:
-
在剩余的 Manager 节点上执行:
docker swarm init --force-new-cluster
- 这会强制重新初始化 Swarm 集群,并使当前节点成为新的 Leader。
-
重新加入其他节点:
- 使用
docker swarm join-token
获取新的加入令牌,然后让其他节点重新加入集群。
- 使用
测试方法1
把 docker3 降级
此时 docker3 已经从 manager 变为了 worker,从docker1 查看信息如下:
也可以在 docker1 把 docker3 提升为 manager:
5.3.2 更改角色 (升级降级)
在 manager 节点上可以更新节点信息
docker3 降级为 worker:
docker node update --role worker docker3
docker3 升级为 manager:
docker node update --role manager docker3
5.3.3 节点标签
可以给节点添加、更改、删除标签
docker node update --label-add author="tom" --label-add desc="just a test " docker3
#删除
docker node update --label-rm author docker3
1.4 manager 自动锁定
在 manager 集群中,swarm 通过 Raft 日志方式维护了 manager 集群中数据的一致性。即在 manager 集群中每个节点通过 manager 间通信方式维护着自己的 Raft 日志。
但在通信过程中存在有一种风险:Raft 日志攻击者会通过 Raft日志数据的传递来访问篡改 manager 节点中的配置或数据。为了防止被攻击,swarm 开启了一种集群自动锁定功能,为 manager 间的通信启用了 TLS 加密。用于加密和解密的公钥与私钥,全部都维护在各个节点的 Docker 内存中。
开启了自动锁定后,一旦节点的 Docker 重启,则密钥丢失,那么集群就会出问题。
swarm 中通过 autolock 标志来设置集群的自动锁定功能:为 true 则开启自动锁定,为 false 则关闭自动锁定。
5.4.1 开启 autolock
在初始化时可以用 --autolock=true 开启自动锁定:
如果已经初始化过了,但未开启自动锁定,可以通过 docker swarm update 命令进行更新开启自动锁定
用 docker info 查询,之前的案例中,autolock 并未开启:
在任意一台 manager 执行 update 都可开启 autolock:
docker swarm update --autolock=true
此时 docker info:
如果 unlock-key 忘记了,可用以下命令查询:
5.4.2 状况模拟
假设 docker3 宕机了:
在其他 manager 查看节点信息:
假设 docker3 故障排除又开机了:
发现它不会自动成为 manager 节点,因为自动锁定的问题,需要对其进行解锁
此时用 docker info 查看也会发现 swarm 已锁定:
解锁:
注:在生产环境中会开启自动锁定,但为了学习方便,还是不开启自动锁定了。
(docker swarm update --autolock=false)
5.5 创建服务
在 Docker Swarm 中创建服务非常简单,下面以部署 tomcat 服务为例,详细讲解如何创建和管理服务。
使用 docker service create
命令创建 Tomcat 服务。
docker service create --name tomcat -p 8081:8080 --replicas 3 tomcat:8.5.32
参数说明:
--name tomcat
:指定服务名称为tomcat
。-p 8081:8080
:将宿主机的 8080 端口映射到容器的 8081 端口。- 也可以写成
--publish published=8080,target=8081
- 也可以写成
--replicas 3
:指定运行 3 个副本(即 3 个 Tomcat 容器)。tomcat:8.5.32
:使用官方 Tomcat 8.5.32 镜像。--limit-cpu 0.5
:表示限制容器最多可以使用 0.5 个 CPU 核心 的计算资源(1 个 CPU 核心的 50% 的计算能力)。--limit-memory 512m
:限制容器最多可以使用 512 MB 的内存
查看服务情况:
查看日志:
也可以查询某个节点上的任务:
docker node ps docker1
访问对应主机的tomcat服务:(docker3、docker2、docker5)
5.6 服务的负载均衡
此时服务中的任务是启动在 docker2、docker3、docker5上的
分别进入容器内,添加 test.html 页面,内容不同
测试访问 docker2 这台服务器对应的网址,会发现以下效果:
原因:
当一个 service 包含多个 task 时,用户对 service 的访问最终会通过负载均衡方式转发给各个 task 处理。
这个负载均衡为随机策略,且无法通过修改 service 的属性方式进行变更。
但由于该负载均衡为三层负载均衡,所以其可以通过第三方实现负载均衡策略的变更,例如通过 Nginx、HAProxy等。
其他:
也可以用 whoami 镜像测试负载均衡
# 每台都拉取镜像
docker pull containous/whoami# 创建服务
docker service create --name whoami --replicas 5 -p 80:80 containous/whoami# 访问测试
curl 192.168.9.3
1.7 扩容缩容与可用性
1.7.1 扩容缩容
5.7.2 availability 可用性
任务数可以大于节点数:
此时如果再扩容到10个任务,会每个节点分摊2个。
假设其中docker4 机器性能较差,不想让其参与扩容,则可以将其暂停,暂停只会影响扩容,不会影响其对外提供服务。
更新节点可用性状态命令:docker node update --availability
此时扩容至10个:
恢复 docker4 的可用性为 active:
测试可用性为 drain(排空、放干) ,此时所有节点都为 active,任务数为10:
更改 docker4 的可用性为 drain:
此时总任务数还是维持10个,但是 docker4不参与服务了
1.8 全局模式部署
service 以副本任务 task 的形式部署在 swarm 集群节点上。
根据 task 数量与节点数量的关系,常见的 service 部署模式有两种:replicated 模式与 global 模式。
默认使用的是副本模式,现测试全局模式。
先把 docker5 leave swarm(为了后面的测试)
创建服务,mode 为 global:
# 全局模式不能使用 --replicas 选项
docker service create --name tomcat -p 8081:8080 --mode global tomcat:8.5.32
此时把 docker5 加入swarm:(先在manager节点查询worker的token)
再查看服务情况:
相关文章:

docker高级
文章目录 1.Docker Compose1.1 介绍1.2 compose文件1.3 常用命令1.4 安装1.5 项目说明和构建1.5.1 手工启动1.5.2 compose 编排启动1.5.3 完善 compose.yml1.5.4 加入前端容器 2.UI管理平台2.1 portainer 3.镜像发布3.1 阿里云3.2 Docker Registry3.2.1 介绍3.2.2 安装3.2.3 测…...
Redis Stream基本使用及应用场景
一、概念 Redis Streams是Redis5.0提供的一种消息队列机制,支持多播的可持久化的消息队列,用户实现发布订阅的功能,借鉴了kafka设计。 二、常用命令 命令名称描述XADD key ID field value [field value ...]添加一条消息 key:St…...

DAY40|动态规划Part08|LeetCode: 121. 买卖股票的最佳时机 、 122.买卖股票的最佳时机II 、 123.买卖股票的最佳时机III
目录 LeetCode:121. 买卖股票的最佳时机 暴力解法 贪心法 动态规划法 LeetCode:122.买卖股票的最佳时机II 基本思路 LeetCode: 买卖股票的最佳时机III、IV 基本思路 C代码 LeetCode:121. 买卖股票的最佳时机 力扣题目链接 文字讲解:121. 买卖股票的最佳时…...
【安装及调试旧版Chrome + 多版本环境测试全攻略】
👨💻 安装及调试旧版Chrome 多版本环境测试全攻略 🌐 (新手友好版 | 覆盖安装/运行/调试全流程) 🕰️ 【背景篇】为什么我们需要旧版浏览器测试? 🌍 🌐 浏览器世界的“…...

【Linux】进程间通信——命名管道
文章目录 命名管道什么是命名管道**命名管道 vs. 无名管道**如何创建命名管道 用命名管道实现进程间通信MakefileComm.hppServer.hppClient.hppServer.cppClient.cpp 效果总结 命名管道 什么是命名管道 命名管道,也称为 FIFO(First In First Out&#…...
Qt在Linux嵌入式开发过程中复杂界面滑动时卡顿掉帧问题分析及解决方案
Qt在Linux嵌入式设备开发过程中,由于配置较低,加上没有GPU,我们有时候会遇到有些组件比较多的复杂界面,在滑动时会出现掉帧或卡顿的问题。要讲明白这个问题还得从CPU和GPU的分工说起。 一、硬件层面核心问题根源剖析 CPU&#x…...

AI学习第六天-python的基础使用-趣味图形
在 Python 编程学习过程中,turtle库是一个非常有趣且实用的工具,它可以帮助我们轻松绘制各种图形。结合for循环、random模块以及自定义方法等知识点,能够创作出丰富多彩的图案。下面就来分享一下相关的学习笔记。 一、基础知识点回顾 &…...

[VMware]卸载VMware虚拟机和Linux系统ubuntu(自记录版)
记录一下,不是教程,只是防止我做错了可以回溯一下 我打开vscode,就会跳出下图 虚拟机,Linux还是很久之前学习安装的,种途可能卸载过(不太记得了),现在尝试彻底卸载 彻底卸载VMware虚拟机的详细步骤-CSDN博客虚拟机Vmware 转移 克隆 卸载及移除Linux系统_克隆的虚拟机怎么移除-…...
J-LangChain,用Java实现LangChain编排!轻松加载PDF、切分文档、向量化存储,再到智能问答
Java如何玩转大模型编排、RAG、Agent??? 在自然语言处理(NLP)的浪潮中,LangChain作为一种强大的模型编排框架,已经在Python社区中广受欢迎。然而,对于Java开发者来说,能…...

Cuppa CMS v1.0 任意文件读取(CVE-2022-25401)
漏洞简介: Cuppa CMS v1.0 administrator/templates/default/html/windows/right.php文件存在任意文件读取漏洞 漏洞环境: 春秋云镜中的漏洞靶标,CVE编号为CVE-2022-25401 漏洞复现 弱口令行不通 直接访问administrator/templates/defau…...

可以免费无限次下载PPT的网站
前言 最近发现了一个超实用的网站,想分享给大家。 在学习和工作的过程中,想必做PPT是一件让大家都很头疼的一件事。 想下载一些PPT模板减少做PPT的工作量,但网上大多精美的PPT都是需要付费才能下载使用。 即使免费也有次数限制࿰…...

STM32中使用PWM对舵机控制
目录 1、硬件JIE 2、PWM口配置 3、角度转换 4、main函数中应用 5、工程下载连接 1、硬件介绍 单片机:STM32F1 舵机:MG995 2、PWM口配置 20毫秒的PWM脉冲占空比,对舵机控制效果较好 计算的公式: PSC、ARR值的选取…...

使用插件 `vue2-water-marker`添加全局水印
使用插件 vue2-water-marker添加全局水印 效果图 1、安装插件 npm install vue2-water-marker --save2、全局注册 // main.js import Vue from vue import Vue2WaterMarker from vue2-water-markerVue.use(Vue2WaterMarker)3、在组件中使用 <template><div id&q…...
MySQL表约束的种类与应用
在MySQL数据库中,表约束是确保数据完整性的关键。约束限制了可以在表中插入或更新的数据类型,保证数据的准确性和可靠性。了解MySQL中的各种表约束对于数据库设计和数据维护至关重要。以下是MySQL支持的主要表约束类型及其应用的详细介绍。 1. 主键约束…...
【大模型+知识图谱】大模型与知识图谱融合:技术演进、实践应用与未来挑战
【大模型+知识图谱】大模型与知识图谱融合:技术演进、实践应用与未来挑战 大模型与知识图谱融合:技术演进、实践应用与未来挑战引言:为什么需要融合?一、技术融合的三重路径1.1 知识图谱增强大模型1.2 大模型赋能知识图谱1.3 协同推理框架二、工业级应用场景落地2.1 智能问…...
MS SQL 2008 技术内幕:T-SQL 语言基础
《MS SQL 2008 技术内幕:T-SQL 语言基础》是一部全面介绍 Microsoft SQL Server 2008 中 T-SQL(Transact-SQL)语言的书籍。T-SQL 是 SQL Server 的扩展版本,增加了编程功能和数据库管理功能,使得开发者和数据库管理员能…...
MySQL-MATCH ... AGAINST工具
在MySQL中,MATCH……AGAINST是全文索引(Full-Text index)的查询语法,它允许你对文本进行高效的全文搜素,支持自然语言搜索和布尔搜索模式。以下是MATCH……AGAINST的详细用法和示例 一、全文索引的基本概念 全文索引适…...
微服务合并
有的团队为了节约机器成本、有的团队为了提升研发效率、有的团队为了降低人均服务数 微服务合并,可以从多个角度入手 代码重构融合:人工拷贝代码、解决冲突,然后分阶段实施迁移重构。代码合并打包:将多个代码仓库,拉取…...

Shell脚本基础:用Bash自动化任务
Shell脚本基础:用Bash自动化任务 在Linux运维中,手动执行重复性任务既耗时又容易出错,而Shell脚本则为自动化提供了强大支持。 从基础概念到实用案例,逐步掌握用Bash实现自动化的核心技能。Shell脚本是Linux自动化的基石…...

基于W2605C语音识别合成芯片的智能语音交互闹钟方案-AI对话享受智能生活
随着科技的飞速发展,智能家居产品正逐步渗透到我们的日常生活中,其中智能闹钟作为时间管理的得力助手,也在不断进化。基于W2605C语音识别与语音合成芯片的智能语音交互闹钟,凭借其强大的联网能力、自动校时功能、实时天气获取、以…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
HTML前端开发:JavaScript 常用事件详解
作为前端开发的核心,JavaScript 事件是用户与网页交互的基础。以下是常见事件的详细说明和用法示例: 1. onclick - 点击事件 当元素被单击时触发(左键点击) button.onclick function() {alert("按钮被点击了!&…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...

SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)
本项目是基于 STM32F103C8T6 微控制器的 SPWM(正弦脉宽调制)电源模块,能够生成可调频率和幅值的正弦波交流电源输出。该项目适用于逆变器、UPS电源、变频器等应用场景。 供电电源 输入电压采集 上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, …...

iview框架主题色的应用
1.下载 less要使用3.0.0以下的版本 npm install less2.7.3 npm install less-loader4.0.52./src/config/theme.js文件 module.exports {yellow: {theme-color: #FDCE04},blue: {theme-color: #547CE7} }在sass中使用theme配置的颜色主题,无需引入,直接可…...

基于Java+VUE+MariaDB实现(Web)仿小米商城
仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意:运行前…...
LangFlow技术架构分析
🔧 LangFlow 的可视化技术栈 前端节点编辑器 底层框架:基于 (一个现代化的 React 节点绘图库) 功能: 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...

【Post-process】【VBA】ETABS VBA FrameObj.GetNameList and write to EXCEL
ETABS API实战:导出框架元素数据到Excel 在结构工程师的日常工作中,经常需要从ETABS模型中提取框架元素信息进行后续分析。手动复制粘贴不仅耗时,还容易出错。今天我们来用简单的VBA代码实现自动化导出。 🎯 我们要实现什么? 一键点击,就能将ETABS中所有框架元素的基…...