Video Reference:【狂神说Java】Docker进阶篇超详细版教程通俗易懂_哔哩哔哩_bilibili

1 Docker Compose

1.1 Docker Compose 简介

Docker Compose是一个用来定义和运行复杂应用的Docker工具。一个使用Docker容器的应用,通常由多个容器组成。使用Docker Compose不再需要使用shell脚本来启动容器。 Compose 通过一个配置文件来管理多个Docker容器,在配置文件中,所有的容器通过services来定义,然后使用docker-compose脚本来启动,停止和重启应用,和应用中的服务以及所有依赖服务的容器,非常适合组合使用多个容器进行开发的场景。 Docker-compose 是 Docker 官方的开源项目,负责实现对 Docker 容器集群的快速编排 Docker-compose 是 Docker 公司推出的一个工具软件,可以管理多个 Docker 容器组成一个应用。需要定义一个YAML格式的配置文件 docker-compose.yml写好多个容器之间的调用关系。然后,只要一个命令,就能同时启动/关闭这些容器。

:::color1

docker-compose 还是非常爽的,用了以后,完全不像用 docker 启动容器 最简单的理解就是把多个docker容器的启动命令写在一个脚本里,批量启动容器(写好多个容器之间的命令关系) Docker Compose来轻松高效的管理容器。定义运行多个容器。

:::

画板

官方文档介绍 Compose是一个用于定义和运行多容器Docker应用程序的工具。使用Compose,您可以使用一个YAML文件来配置应用程序的服务。然后,使用一个命令创建并启动配置中的所有服务。要了解Compose的所有特性的更多信息,请参阅特性列表。 在所有环境中编写工作:生产、开发、测试以及CI工作流。您可以在常用用例中了解更多关于每个用例的信息。 使用Compose基本上有三个步骤:
  1. Dockerfile 定义你的应用环境,这样它就可以在任何地方被复制。
  2. docker-compose.yml 中定义组成应用程序的服务。所以它们可以在一个孤立的环境中一起运行。
  3. 运行docker compose up , docker compose up命令将启动并运行整个应用程序。你也可以使用compose standalone(docker-compose binary)运行docker-compose。
作用:批量容器编排。
Compose 是 Docker 官方的开源项目,需要独立安装! Dockerfile 让程序在任何地方运行。Docker Compose 是单个机器的容器编排工具。
Docker Compose docker-compose.yml 文件示例
  1. version: "3.9" # optional since v1.27.0
  2. services:
  3. web:
  4. build: .
  5. ports:
  6. - "8000:5000"
  7. volumes:
  8. - .:/code
  9. - logvolume01:/var/log
  10. depends_on:
  11. - redis
  12. redis:
  13. image: redis
  14. volumes:
  15. logvolume01: {}
Docker-Compose 项目是 Docker 官方的开源项目,负责实现对 Docker 容器集群的快速编排。 Docker-Compose 将所管理的容器分为三层,分别是工程/项目(project),服务(service)以及容器(container)。 Docker-Compose 运行目录下的所有文件(docker-compose.yml,extends 文件或环境变量文件等)组成一个工程,若无特殊指定工程名即为当前目录名。一个工程当中可包含多个服务,每个服务中定义了容器运行的镜像、参数、依赖。一个服务当中可包括多个容器实例。 Docker-Compose 并没有解决负载均衡的问题,因此需要借助其他工具实现服务发现及负载均衡,比如 Consul。
Docker Compose :重要的概念
  • 服务 services:容器,应用。(Web、Redis、MySQL)
  • 项目 project:一组关联的容器。博客
使用 Docker Compose 可以轻松、高效的管理容器,它是一个用于定义和运行多容器 Docker 的应用程序工具。

1.2 Docker-compose 能干嘛

Docker 建议我们每一个容器中只运行一个服务,因为docker容器本身占用资源极少,所以最好是将服务单独的分割开来,但是这样我们又面临了一个问题? 如果我们需要同时部署好多个服务,难道要每个服务单独写Dockerfile,然后再构建镜像,镜像容器,这样会很累,所以docker官方给我们提供了 docker-compose 多服务部署工具。 例如要实现一个Web微服务项目,除了Web服务容器本身,往往还需要再加上后端的数据库mysql服务容器,redis服务器,注册中心eureka,甚至还包括负载均衡容器等等。。。 Compose 允许用户通过一个单独的 docker-compose.yml 模板文件(YAML格式)来定义一组相关联的应用容器为一个项目(project) 可以很容易的用一个配置文件定义一个/一组多容器的应用,然后使用一条指令安装这个应用的所有依赖,完成构建。Docker-Compose解决了容器与容器之间如何管理编排的问题。

:::color1

Docker compose 是单机(本机)的多容器管理技术 K8s 是跨主机的集群部署工具

:::

1.3 Docker-compose 下载

1.3.1 官网

https://docs.docker.com/compose/compose-file/compose-file-v3/

1.3.2 官网下载

https://docs.docker.com/compose/install/

GitHub 项目地址:https://github.com/docker/compose ### 1.3.3 安装步骤 #查看最新版docker-compose 需要登录到GitHub项目中,然后修改下载的URL即可。
  1. $ sudo curl -L "https://github.com/docker/compose/releases/download/v1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
  2. # curl -SL https://github.com/docker/compose/releases/download/v2.7.0/docker-compose-$(uname -s)-$(uname -m) -o /usr/local/bin/docker-compose
  3. # curl -SL https://github.com/docker/compose/releases/download/v2.7.0/docker-compose-linux-x86_64 -o /usr/local/bin/docker-compose
  4. # 若无法下载,则科学上网
  5. # sudo curl -L https://get.daocloud.io/docker/compose/releases/download/1.25.1/docker-compose-`uname -s`-`uname -m` \
  6. #-o /usr/local/bin/docker-compose
  7. #下载最新版
  8. $ curl -L https://get.daocloud.io/docker/compose/releases/download/v2.10.2/docker-compose-`uname -s`-`uname -m` \
  9. > /usr/local/bin/docker-compose
  10. # 添加执行权限
  11. $ sudo chmod +x /usr/local/bin/docker-compose
  12. $ sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
  13. $ docker-compose version
  14. Docker Compose version v2.10.2

1.3.4 卸载步骤

  1. $ sudo rm -rf /usr/local/bin/docker-compose

1.4 Docker-compose 使用

官方文档地址:Get started with Docker Compose 官方使用 Python 应用计数器(涉及Redis) 通过Docker Compose上构建一个简单的python web应用程序,该应用程序使用Flask框架并在Redis中维护一个计数器,用来记录该Web应用被访问的次数。
  1. $ mkdir -pv /opt/composetest
  2. $ cd /opt/composetest
创建一个 app.py Python 文件
  1. import time
  2. import redis
  3. from flask import Flask
  4. app = Flask(__name__)
  5. cache = redis.Redis(host='redis', port=6379)
  6. def get_hit_count():
  7. retries = 5
  8. while True:
  9. try:
  10. return cache.incr('hits')
  11. except redis.exceptions.ConnectionError as exc:
  12. if retries == 0:
  13. raise exc
  14. retries -= 1
  15. time.sleep(0.5)
  16. @app.route('/')
  17. def hello():
  18. count = get_hit_count()
  19. return 'Hello World! I have been seen {} times.\n'.format(count)
在您的项目目录中创建另一个名为 requirements.txt 的文件,并将其粘贴到:
  1. cat > requirements.txt <<EOF
  2. flask
  3. redis
  4. EOF
创建 Dockerfile
  1. $ vim Dockerfile
  2. # syntax=docker/dockerfile:1
  3. FROM python:3.7-alpine
  4. WORKDIR /code
  5. ENV FLASK_APP=app.py
  6. ENV FLASK_RUN_HOST=0.0.0.0
  7. RUN apk add --no-cache gcc musl-dev linux-headers
  8. COPY requirements.txt requirements.txt
  9. RUN pip install -r requirements.txt
  10. EXPOSE 5000
  11. COPY . .
  12. CMD ["flask", "run"]
  13. #这告诉Docker:
  14. # 从Python 3.6映像开始构建映像。
  15. # 将当前目录添加.到/ code映像中的路径中。
  16. # 将工作目录设置为/code。
  17. # 安装Python依赖项。
  18. # 将容器的默认命令设置为python app.py .
定义一个 docker-compose
  1. $ vim docker-compose.yml
  2. version: "3.9"
  3. services:
  4. web:
  5. build: .
  6. #修改了 ports 宿主机的暴露端口,默认官网是8000:5000
  7. ports:
  8. - "8010:5000"
  9. redis:
  10. image: "redis:alpine"
查看目录树并运行 docker-compose
  1. $ ls -l
  2. total 16
  3. -rw-r--r-- 1 root root 514 Aug 27 11:19 app.py
  4. -rw-r--r-- 1 root root 111 Aug 27 11:24 docker-compose.yml
  5. -rw-r--r-- 1 root root 281 Aug 27 11:22 Dockerfile
  6. -rw-r--r-- 1 root root 12 Aug 27 11:21 requirements.txt
  7. $ docker-compose up

💫2 Docker进阶篇超详细版教程通俗易懂 - 图2

💫2 Docker进阶篇超详细版教程通俗易懂 - 图3

  1. $ curl 139.198.105.99:8010
  2. Hello World! I have been seen 3 times.
  1. $ docker-compose ls
  2. NAME STATUS CONFIG FILES
  3. composetest running(2) /root/docker-compose/composetest/docker-compose.yml

:::color1

  1. 应用 app.py
  2. Dockerfile 应用打包为镜像
  3. Docker-compose.yml 文件(定义整个服务,需要的环境,Web,Redis)完整的上线服务!
  4. 启动 Compose 项目(docker-compose up)

:::

流程:
  1. 创建网络
  2. 执行 docker-compose up
  3. 启动服务 docker-compose.yml
  1. [+] Running 3/3
  2. Network composetest_default Created 0.1s
  3. Container composetest-redis-1 Created 0.3s
  4. Container composetest-web-1 Created 0.3s
  5. #composetest-web-1 格式:
  6. #1.文件夹名 composetest
  7. #2.docker-compose.yml 中定义了 services(服务):
  8. $ cat docker-compose.yml
  9. version: "3"
  10. services:
  11. web:
  12. build: .
  13. ports:
  14. - "8010:5000"
  15. redis:
  16. image: "redis:alpine"
  17. #查看composetest项目的镜像
  18. $ docker images
  19. REPOSITORY TAG IMAGE ID CREATED SIZE
  20. composetest_web latest 1677ee6e9825 About an hour ago 185MB
  21. redis alpine 3900abf41552 9 months ago 32.4MB
  22. python 3.7-alpine a1034fd13493 9 months ago 41.8MB
  23. #查看composetest项目创建的容器
  24. $ docker ps | grep composetest
  25. 71321dce9704 redis:alpine "docker-entrypoint.s…" 55 minutes ago Up 55 minutes 6379/tcp composetest-redis-1
  26. 598c5b5f7b00 composetest_web "flask run" 55 minutes ago Up 55 minutes 0.0.0.0:8010->5000/tcp, :::8010->5000/tcp composetest-web-1
默认的服务名 服务名_服务名-num
  • num:副本数量
集群状态。服务都不可能只有一个运行实例。弹性动态扩缩容
  1. #3.网络规则
  2. $ docker network ls
  3. NETWORK ID NAME DRIVER SCOPE
  4. cf80f623fe5f composetest_default bridge local
  5. #Docker Compose在项目中的内容都在同一个网络下。可以通过域名访问。
  6. #Docker 在每一个项目中都会维护一个各自的网络。
  7. $ docker network inspect composetest_default

💫2 Docker进阶篇超详细版教程通俗易懂 - 图4

如果在同一个网络下,我们可以直接通过主机名(域名)的方式进行访问。
  1. #停止 docker-compose 服务
  2. #需要在docker-compose 的项目目录下执行
  3. $ docker-compose down
  4. 或者使用 Ctrl + C终止服务

💫2 Docker进阶篇超详细版教程通俗易懂 - 图5

:::color1

在没有使用 docker-compose 之前,都是单个 docker run 启动容器,如果启动多个容器,那么操作起来十分麻烦 使用 docker-compose 之后,通过 docker-compose 编写的 yaml 配置文件,只需要docker-compose up 就可以一键启动多个容器,十分的方便。以及一键停止服务。 需要注意的是:docker compose 是用于单个机器上的容器编排工具,而 Docker Swarm 和 主流的K8s 则是集群级别的容器编排工具(通俗的说就是多台机器上的容器编排工具)

:::

Docker 小结: 1、Docker 镜像;docker run —> 容器 2、Dockerfile 构建镜像(服务打包) 3、docker-compose 启动项目(编排、多个微服务 / 环境) 4、Docker 网络!

1.5 Yaml 规则

docker-compose.yml 文件

Docker-compose.yml 官方文档:Compose file version 3 reference

Docker-compose 版本和 Docker 引擎是对应,并且是向下兼容的特性。
Compose file format Docker Engine release
Compose specification 19.03.0+
3.8 19.03.0+
3.7 18.06.0+
3.6 18.02.0+
3.5 17.12.0+
3.4 17.09.0+
3.3 17.06.0+
3.2 17.04.0+
3.1 1.13.1+
3.0 1.13.0+
2.4 17.12.0+
2.3 17.06.0+
2.2 1.13.0+
2.1 1.12.0+
2.0 1.10.0+
  1. #docker-compose.yml只有3层
  2. version: '' #版本
  3. services: #服务
  4. 服务名1: web
  5. #服务配置
  6. image: nginx
  7. container_name: nginx01
  8. build: .
  9. networks:
  10. 服务名2: redis
  11. ......
  12. 服务名3: mysql
  13. ......
  14. #其他配置: 网络/卷挂载/全局规则
  15. networks:
  16. volumes:
  17. configs:

:::color1

只要多写,多看,Docker-compose.yml 配置! 1、官网文档: 2、开源项目:

:::

小总结:
  1. version: '3.7' # 指定 compose 文件的版本
  2. services: # 定义所有的 service 信息, services 下面的第一级别的 key 既是一个 service 的名称
  3. aaa: #服务aaa
  4. build: # 与image二选一,指定包含构建上下文的路径, 或作为一个对象,该对象具有 context 和指定的 dockerfile 文件以及 args 参数值
  5. context: . # context: 指定 Dockerfile 文件所在的路径
  6. dockerfile: Dockerfile # dockerfile: 指定 context 指定的目录下面的 Dockerfile 的名称(默认为 Dockerfile)
  7. args: # args: Dockerfile 在 build 过程中需要的参数 (等同于 docker container build --build-arg 的作用)
  8. JAR_FILE: service.jar
  9. cache_from: # v3.2中新增的参数, 指定缓存的镜像列表 (等同于 docker container build --cache_from 的作用)
  10. labels: # v3.3中新增的参数, 设置镜像的元数据 (等同于 docker container build --labels 的作用)
  11. shm_size: # v3.5中新增的参数, 设置容器 /dev/shm 分区的大小 (等同于 docker container build --shm-size 的作用)
  12. #ports:
  13. # - "80:80"
  14. # - "443:443"
  15. ports: # 建立宿主机与容器间的端口映射关系,上面是短语法写法,下面是长语法写法
  16. - target: 80 # 容器端口
  17. published: 80 # 宿主机端口
  18. protocol: tcp # 协议类型
  19. mode: host # host在每个节点上发布主机端口,ingress 对于集群模式端口进行负载均衡
  20. - target: 443
  21. published: 443
  22. protocol: tcp
  23. mode: host
  24. command: # 覆盖容器启动后默认执行的命令, 支持 shell 格式和 [] 格式
  25. configs: # 不知道怎么用
  26. cgroup_parent: # 为容器指定父 cgroup 组,意味着将继承该组的资源限制。
  27. container_name: # 指定容器的名称 (等同于 docker run --name 的作用)
  28. deploy: # v3 版本以上, 指定与部署和运行服务相关的配置, deploy 部分是 docker stack 使用的, docker stack 依赖 docker swarm
  29. endpoint_mode: vip # v3.3 版本中新增的功能, 指定服务暴露的方式
  30. # vip # Docker 为该服务分配了一个虚拟 IP(VIP), 作为客户端的访问服务的地址
  31. # dnsrr # DNS轮询, Docker 为该服务设置 DNS 条目, 使得服务名称的 DNS 查询返回一个 IP 地址列表, 客户端直接访问其中的一个地址
  32. labels: # 指定服务的标签,这些标签仅在服务上设置
  33. mode: replicated # 指定 deploy 的模式
  34. # global # 每个集群节点都只有一个容器
  35. # replicated # 用户可以指定集群中容器的数量(默认)
  36. placement:
  37. constraints:
  38. - node.role==manager # 不知道怎么用
  39. replicas: 1 # deploy 的 mode 为 replicated 时, 指定容器副本的数量
  40. resources: # 资源限制
  41. limits: # 设置容器的资源限制
  42. cpus: "0.5" # 设置该容器最多只能使用 50% 的 CPU
  43. memory: 50M # 设置该容器最多只能使用 50M 的内存空间
  44. reservations: # 设置为容器预留的系统资源(随时可用)
  45. cpus: "0.2" # 为该容器保留 20% 的 CPU
  46. memory: 20M # 为该容器保留 20M 的内存空间
  47. restart_policy: # 定义容器重启策略, 用于代替 restart 参数
  48. condition: on-failure # 定义容器重启策略(接受三个参数)
  49. # none: # 不尝试重启
  50. # on-failure: # 只有当容器内部应用程序出现问题才会重启
  51. # any : # 无论如何都会尝试重启(默认)
  52. delay: 10s # 尝试重启的间隔时间(默认为 0s)
  53. max_attempts: 6 # 尝试重启次数(默认一直尝试重启)
  54. window: 120s # 检查重启是否成功之前的等待时间(即如果容器启动了, 隔多少秒之后去检测容器是否正常, 默认 0s)
  55. update_config: # 用于配置滚动更新配置
  56. parallelism: 1 # 一次性更新的容器数量
  57. delay: 10s # 更新一组容器之间的间隔时间
  58. order: stop-first # v3.4 版本中新增的参数, 回滚期间的操作顺序
  59. # stop-first #旧任务在启动新任务之前停止(默认)
  60. # start-first #首先启动新任务, 并且正在运行的任务暂时重叠
  61. failure_action: continue # 定义更新失败的策略
  62. # continue # 继续更新
  63. # rollback # 回滚更新
  64. # pause # 暂停更新(默认)
  65. # monitor # 每次更新后的持续时间以监视更新是否失败(单位: ns|us|ms|s|m|h) (默认为0)
  66. max_failure_ratio: 0 # 回滚期间容忍的失败率(默认值为0)
  67. rollback_config: # v3.7 版本中新增的参数, 用于定义在 update_config 更新失败的回滚策略
  68. parallelism: 1 # 一次回滚的容器数, 如果设置为0, 则所有容器同时回滚
  69. delay: 0 # 每个组回滚之间的时间间隔(默认为0)
  70. failure_action: continue # 定义回滚失败的策略
  71. # continue # 继续回滚
  72. # pause # 暂停回滚
  73. monitor: 10s # 每次回滚任务后的持续时间以监视失败(单位: ns|us|ms|s|m|h) (默认为0)
  74. max_failure_ratio: 0 # 回滚期间容忍的失败率(默认值0)
  75. order: stop-first # 回滚期间的操作顺序
  76. # stop-first # 旧任务在启动新任务之前停止(默认)
  77. # start-first # 首先启动新任务, 并且正在运行的任务暂时重叠
  78. devices: # 指定设备映射列表 (等同于 docker run --device 的作用)
  79. depends_on: #依赖容器
  80. - db
  81. - redis
  82. dns: # 设置 DNS 地址(等同于 docker run --dns 的作用)
  83. dns_search: # 设置 DNS 搜索域(等同于 docker run --dns-search 的作用)
  84. tmpfs: # v2 版本以上, 挂载目录到容器中, 作为容器的临时文件系统(等同于 docker run --tmpfs 的作用, 在使用 swarm 部署时将忽略该选项)
  85. entrypoint: # 覆盖容器的默认 entrypoint 指令 (等同于 docker run --entrypoint 的作用)
  86. env_file: # 从指定文件中读取变量设置为容器中的环境变量, 可以是单个值或者一个文件列表, 如果多个文件中的变量重名则后面的变量覆盖前面的变量, environment 的值覆盖 env_file 的值
  87. RACK_ENV=development
  88. volumes: # 定义容器和宿主机的数据卷映射关系
  89. - "/u01:/u01" # 映射容器内的 /u01 到宿主机的 /u01目录
  90. environment: # 设置环境变量, environment 的值可以覆盖 env_file 的值 (等同于 docker run --env 的作用)
  91. - TZ=Asia/Shanghai
  92. - PORT_TO_EXPOSE=80
  93. - LOG_PATH=/opt/proj/logs
  94. - PROFILES_ACTIVE=prod
  95. expose: # 暴露端口, 但是不能和宿主机建立映射关系, 类似于 Dockerfile 的 EXPOSE 指令
  96. external_links: # 连接不在 docker-compose.yml 中定义的容器或者不在 compose 管理的容器(docker run 启动的容器, 在 v3 版本中使用 swarm 部署时将忽略该选项)
  97. extra_hosts: # 添加 host 记录到容器中的 /etc/hosts 中 (等同于 docker run --add-host 的作用)
  98. healthcheck: # v2.1 以上版本, 定义容器健康状态检查, 类似于 Dockerfile 的 HEALTHCHECK 指令
  99. test: NONE # 检查容器检查状态的命令, 该选项必须是一个字符串或者列表, 第一项必须是 NONE, CMD 或 CMD-SHELL, 如果其是一个字符串则相当于 CMD-SHELL 加该字符串
  100. # NONE # 禁用容器的健康状态检测
  101. # CMD # test: ["CMD", "curl", "-f", "http://localhost"]
  102. # CMD-SHELL # test: ["CMD-SHELL", "curl -f http://localhost || exit 1"] 或者 test: curl -f https://localhost || exit 1
  103. interval: 1m30s # 每次检查之间的间隔时间
  104. timeout: 10s # 运行命令的超时时间
  105. retries: 3 # 重试次数
  106. start_period: 40s # v3.4 以上新增的选项, 定义容器启动时间间隔
  107. disable: true # true 或 false, 表示是否禁用健康状态检测和 test: NONE 相同
  108. image: # 指定 docker 镜像, 可以是远程仓库镜像、本地镜像
  109. init: # v3.7 中新增的参数, true 或 false 表示是否在容器中运行一个 init, 它接收信号并传递给进程
  110. isolation: # 隔离容器技术, 在 Linux 中仅支持 default 值
  111. labels: # 使用 Docker 标签将元数据添加到容器, 与 Dockerfile 中的 LABELS 类似
  112. links: # 链接到其它服务中的容器, 该选项是 docker 历史遗留的选项, 目前已被用户自定义网络名称空间取代, 最终有可能被废弃 (在使用 swarm 部署时将忽略该选项)
  113. logging: # 设置容器日志服务
  114. driver: # 指定日志记录驱动程序, 默认 json-file (等同于 docker run --log-driver 的作用)
  115. options: # 指定日志的相关参数 (等同于 docker run --log-opt 的作用)
  116. max-size: # 设置单个日志文件的大小, 当到达这个值后会进行日志滚动操作
  117. max-file: # 日志文件保留的数量
  118. network_mode: # 指定网络模式 (等同于 docker run --net 的作用, 在使用 swarm 部署时将忽略该选项)
  119. networks: # 将容器加入指定网络 (等同于 docker network connect 的作用), networks 可以位于 compose 文件顶级键和 services 键的二级键
  120. aliases: # 同一网络上的容器可以使用服务名称或别名连接到其中一个服务的容器
  121. ipv4_address # IP V4 格式
  122. ipv6_address # IP V6 格式
示例:
  1. version: '3.7' # 版本必须3.0及以上,否则无法使用docker-stack 运行
  2. services: # 定义 service 信息
  3. emcs-nginx:
  4. image: "nginx:latest" # 使用指定的 docker 镜像
  5. #ports:
  6. # - "80:80"
  7. # - "443:443"
  8. ports: # 建立宿主机与容器间的端口映射关系,上面是短语法写法,下面是长语法写法
  9. - target: 80 # 容器端口
  10. published: 80 # 宿主机端口
  11. protocol: tcp # 协议类型
  12. mode: host # host在每个节点上发布主机端口,ingress 对于集群模式端口进行负载均衡
  13. - target: 443
  14. published: 443
  15. protocol: tcp
  16. mode: host
  17. volumes: # 定义容器和宿主机的数据卷映射关系
  18. - "/u01:/u01" # 映射容器内的 /u01 到宿主机的 /u01目录
  19. environment: # 设置环境变量
  20. TZ: Asia/Shanghai # 设置时区为上海
  21. deploy: # 指定与部署和运行服务相关的配置, deploy部分是docker stack使用的, docker stack依赖docker swarm
  22. mode: replicated # 指定模式:global每个集群节点都只有一个容器,
  23. # replicated用户可以指定集群中容器的数量(默认)
  24. replicas: 1 # deploy的mode为 replicated 时, 指定容器副本的数量
  25. update_config: # 用于配置滚动更新的配置
  26. parallelism: 1 # 一次性更新的容器数量
  27. delay: 10s # 更新一组容器之间的间隔10s
  28. order: stop-first # 指定回滚期间的操作顺序:stop-first旧任务在启动新任务之前停止(默认),
  29. # start-first首先启动新任务, 并且正在运行的任务暂时重叠
  30. restart_policy: # 定义容器重启策略, 用于代替 restart 参数
  31. condition: on-failure # 定义容器重启策略(接受三个参数):
  32. # none不尝试重启;any无论如何都会尝试重启(默认)
  33. # on-failure只有当容器内部应用程序出现问题才会重启
  34. emcs-front: # 第二个服务
  35. image: "***/front"
  36. volumes:
  37. - "/u01/log:/u01/log"
  38. environment:
  39. TZ: Asia/Shanghai
  40. deploy:
  41. mode: replicated
  42. replicas: 1
  43. update_config:
  44. parallelism: 1
  45. delay: 20s
  46. order: stop-first
  47. restart_policy:
  48. condition: on-failure

1.6 使用 Compose 一键部署 WordPress 博客

:::color1

传统方式部署博客:
  • 下载程序,安装数据库,配置……
  • compose 应用 => 一键启动
1、下载项目( docker-compose.yml ) 2、如果需要文件。Dockerfile 3、文件准备齐全(直接 docker-compose up 一键启动项目!)

:::

官方文档:https://docs.docker.com/samples/wordpress/

  1. #创建一个项目的文件夹(这就是项目名project)
  2. $ mkdir /opt/my_wordpress ; cd /opt/my_wordpress
  3. $ vim docker-compose.yml
  4. version: "3.9"
  5. services:
  6. db:
  7. # We use a mariadb image which supports both amd64 & arm64 architecture
  8. image: mariadb:10.6.4-focal
  9. # If you really want to use MySQL, uncomment the following line
  10. #image: mysql:8.0.27
  11. command: '--default-authentication-plugin=mysql_native_password'
  12. volumes:
  13. - db_data:/var/lib/mysql
  14. restart: always
  15. environment:
  16. - MYSQL_ROOT_PASSWORD=somewordpress
  17. - MYSQL_DATABASE=wordpress
  18. - MYSQL_USER=wordpress
  19. - MYSQL_PASSWORD=wordpress
  20. expose:
  21. - 3306
  22. - 33060
  23. wordpress:
  24. image: wordpress:latest
  25. ports:
  26. - 80:80
  27. volumes:
  28. - wordpress_data:/var/www/html
  29. restart: always
  30. environment:
  31. - WORDPRESS_DB_HOST=db
  32. - WORDPRESS_DB_USER=wordpress
  33. - WORDPRESS_DB_PASSWORD=wordpress
  34. - WORDPRESS_DB_NAME=wordpress
  35. volumes:
  36. db_data: {}
  37. wordpress_data: {}
  38. #启动项目
  39. #-d 后台运行
  40. #不加 -d 就是默认前台启动
  41. $ docker-compose up -d
  42. $ docker ps
  43. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  44. 70d3fc3fbb45 wordpress:latest "docker-entrypoint.s…" About a minute ago Up About a minute 0.0.0.0:80->80/tcp, :::80->80/tcp my_wordpress-wordpress-1
  45. 459eccc745ed mariadb:10.6.4-focal "docker-entrypoint.s…" About a minute ago Up About a minute 3306/tcp, 33060/tcp my_wordpress-db-1
  46. $ docker port my_wordpress-wordpress-1
  47. 80/tcp -> 0.0.0.0:80
  48. 80/tcp -> :::80

💫2 Docker进阶篇超详细版教程通俗易懂 - 图6

http://:80 后续的操作就是 WordPress 根据引导进行部署即可

💫2 Docker进阶篇超详细版教程通俗易懂 - 图7

💫2 Docker进阶篇超详细版教程通俗易懂 - 图8

💫2 Docker进阶篇超详细版教程通俗易懂 - 图9

这样 博客就搭建完成了

:::color1

目前的IT主流的技术:Linux + Docker + Kubernetes(掌握) 掌握的技术:Docker 基础、原理、网络、服务、集群、错误排查、日志

:::

另一个可用的 WordPress 的 docker-compose.yml 文件:

  1. version: "3.3"
  2. services:
  3. db:
  4. image: mysql:5.7
  5. volumes:
  6. - db_data:/var/lib/mysql
  7. restart: always
  8. environment:
  9. MYSQL_ROOT_PASSWORD: somewordpress
  10. MYSQL_DATABASE: wordpress
  11. MYSQL_USER: wordpress
  12. MYSQL_PASSWORD: wordpress
  13. wordpress:
  14. depends_on:
  15. - db
  16. image: wordpress:latest
  17. volumes:
  18. - wordpress_data:/var/www/html
  19. ports:
  20. - "8000:80"
  21. restart: always
  22. environment:
  23. WORDPRESS_DB_HOST: db
  24. WORDPRESS_DB_USER: wordpress
  25. WORDPRESS_DB_PASSWORD: wordpress
  26. WORDPRESS_DB_NAME: wordpress
  27. volumes:
  28. db_data: {}
  29. wordpress_data: {}

1.7 实战

:::color1

  1. 编写项目微服务
  2. <font style="color:#000000;">dockerfile</font> 构建相应的应用镜像
  3. <font style="color:#000000;">docker-compose.yml</font>编排项目
  4. 打包上传到服务器 <font style="color:#000000;">docker-compose up -d</font> 即可

:::

1.7.1 使用 IDEA 创建项目

💫2 Docker进阶篇超详细版教程通俗易懂 - 图10

💫2 Docker进阶篇超详细版教程通俗易懂 - 图11

1.7.2 配置IDEA项目的应用

💫2 Docker进阶篇超详细版教程通俗易懂 - 图12

相关的配置文件内容 范例:HelloController 示例
  1. package com.example.demo.controller;
  2. import org.springframework.beans.factory.annotation.Autowired;
  3. import org.springframework.data.redis.core.RedisTemplate;
  4. import org.springframework.web.bind.annotation.GetMapping;
  5. import org.springframework.web.bind.annotation.RestController;
  6. @RestController
  7. public class HelloController {
  8. @Autowired
  9. RedisTemplate redisTemplate;
  10. @GetMapping("/hello")
  11. public String hello() {
  12. Long view = redisTemplate.opsForValue().increment("views");
  13. return "Hello, kubesphere, Thank you! views:"+view;
  14. }
  15. }
范例:application.properties 示例
  1. package com.example.demo;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. @SpringBootApplication
  5. public class DemoApplication {
  6. public static void main(String[] args) {
  7. SpringApplication.run(DemoApplication.class, args);
  8. }
  9. }
范例:Dockerfile 示例
  1. #配置基础镜像
  2. FROM java:8
  3. #拷贝jar包到容器内
  4. ADD *.jar /app.jar
  5. #执行命令
  6. CMD ["--server.port=8080"]
  7. #提示指定的暴露端口
  8. EXPOSE 8080
  9. #执行命令
  10. ENTRYPOINT ["java", "-jar", "/app.jar"]
范例:docker-compose.yml 示例
  1. version: "3"
  2. services:
  3. web:
  4. build: .
  5. image: web:1.0
  6. ports:
  7. - 8080:8080
  8. depends_on:
  9. - redis
  10. redis:
  11. image: "redis:alpine"
服务器上操作
  1. $ mkdir /opt/my_compose ; cd /opt/my_compose
  2. #将文件进行上传
  3. $ ls -l /opt/my_compose
  4. total 25020
  5. -rw-r--r-- 1 root root 25609796 Aug 27 14:15 demo-0.0.1-SNAPSHOT.jar
  6. -rw-r--r-- 1 root root 192 Aug 27 14:16 docker-compose.yml
  7. -rw-r--r-- 1 root root 213 Aug 27 14:16 Dockerfile
  8. $ docker-compose up -d
  9. $ docker ps
  10. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  11. 39f4c347a2da web:1.0 "java -jar /app.jar …" 52 seconds ago Up 50 seconds 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp my_compose-web-1
  12. 6d8ec9e73e2a redis:alpine "docker-entrypoint.s…" 52 seconds ago Up 51 seconds 6379/tcp my_compose-redis-1
  13. $ docker network ls
  14. NETWORK ID NAME DRIVER SCOPE
  15. 978e62f6ef2c my_compose_default bridge local

💫2 Docker进阶篇超详细版教程通俗易懂 - 图13

:::color1

未来项目只要有 docker-compose.yml 文件。按照这个规则,启动编排容器即可!

:::

范例:进行测试
  1. $ curl 10.0.0.101:8080/hello
  2. Hello, kubesphere, Thank you! views:1
  3. $ curl 10.0.0.101:8080/hello
  4. Hello, kubesphere, Thank you! views:2
假设项目要重新部署打包
  1. docker-compose up --build
  2. #重新构建镜像

1.8 Docker-compose 常用的命令

:::warning

Compose 常用命令
  • docker-compose -h —-> 查看帮助
  • docker-compose up —-> 启动所有docker-compose服务
  • <font style="color:#000000;">docker-compose up -d ---> 启动服务 docker-compose 服务,并后台运行</font>
  • <font style="color:#000000;">docker-compose down ---> 停止并删除容器、网络、卷、镜像</font>
  • docker-compose up —build —-> 重新构建项目镜像
  • docker-compose exec yml里面的服务id —-> 进入容器实例内部 docker-compose exec <font style="color:#000000;">docker-compose.yml文件中写的服务id</font> /bin/bash
  • docker-compose ps —-> 展示当前 docker-compose 编排过的运行的所有容器
  • docker-compose top —-> 展示当前 docker-compose 编排过的容器进程
  • docker-compose logs yml里面的服务id —-> 检查容器输出日志
  • <font style="color:#000000;">docker-compose config ---> 检查配置</font>
  • <font style="color:#000000;">docker-compose config -q ---> 检查配置,有问题才有输出</font>
  • docker-compose restart —-> 重启服务
  • docker-compose start —-> 启动服务
  • docker-compose stop —-> 停止服务

:::

1.9 小总结:

工程Project,服务Services,容器Container 项目 docker-compose :三层:
  • 工程:project
  • 服务:services
  • 容器:运行实例!

2 Docker Swarm

集群方式的部署。4台服务器(性能配置:2C4G)可以使用云服务器或者是虚拟机即可。 服务器准备完毕后!3 主 3 从 的集群环境。

2.1 4台机器环境配置

我们使用的是(entOS 7 (64-bit) 目前,CentOS仅发行版本中的内核支持Docker。 Docker运行在CentOS 7 上,要求系统为64位、系统内核版本为3.10以上。 尽量使用阿里云进行实验,其内部网络通信十分的快速。 集群规划
角色 操作系统 主机名 IP地址(尽量使用非10网段) 配置参数
Swarm Manager CentOS 7.9.2009 docker-master 10.0.0.101 1C2G
Swarm Node CentOS 7.9.2009 docker-node1 10.0.0.102 1C2G
Swarm Node CentOS 7.9.2009 docker-node2 10.0.0.103 1C2G
Swarm Node CentOS 7.9.2009 docker-node3 10.0.0.104 1C2G

查看自己的内核

uname -r 命令用于打印当前系统相关信息(内核版本号、硬件架构、主机名称和操作系统类型等)。
  1. $ uname -r
  2. 3.10.0-1160.el7.x86_64

查看版本信息

cat /etc/os-release
  1. $ cat /etc/os-release
  2. NAME="CentOS Linux"
  3. VERSION="7 (Core)"
  4. ID="centos"
  5. ID_LIKE="rhel fedora"
  6. VERSION_ID="7"
  7. PRETTY_NAME="CentOS Linux 7 (Core)"
  8. ANSI_COLOR="0;31"
  9. CPE_NAME="cpe:/o:centos:centos:7"
  10. HOME_URL="https://www.centos.org/"
  11. BUG_REPORT_URL="https://bugs.centos.org/"
  12. CENTOS_MANTISBT_PROJECT="CentOS-7"
  13. CENTOS_MANTISBT_PROJECT_VERSION="7"
  14. REDHAT_SUPPORT_PRODUCT="centos"
  15. REDHAT_SUPPORT_PRODUCT_VERSION="7"
关闭防火墙以及SElinux功能
  1. systemctl disable --now firewalld
  2. #对于此测试,您需要两个可以相互通信的不同 Docker 主机。每个主机必须在两个 Docker 主机之间打开以下端口:
  3. TCP 端口 2377
  4. TCP UDP 端口 7946
  5. UDP 端口 4789
  6. #设置此设置的一种简单方法是拥有两个 VM(本地或 AWS 等云提供商),每个 VM 都已安装并运行 Docker。
  7. #如果您使用的是 AWS 或类似的云计算平台,最简单的配置是使用安全组,
  8. #该安全组打开两台主机之间的所有传入端口以及来自客户端 IP 地址的 SSH 端口。
  9. #若不关闭防火墙,则需要放通相关的端口
  10. firewall-cmd --zone=public --add-port=2377/tcp --permanent
  11. firewall-cmd --zone=public --add-port=7946/tcp --permanent
  12. firewall-cmd --zone=public --add-port=7946/udp --permanent
  13. firewall-cmd --zone=public --add-port=4789/tcp --permanent
  14. firewall-cmd --zone=public --add-port=4789/udp --permanent
  15. firewall-cmd --reload
  16. setenforce 0
  17. sed -i -r '/^SELINUX=/s@(.*)=(.*)@\1=disabled@g' /etc/selinux/config

2.2 安装步骤

1、官网安装参考手册: https://docs.docker.cam/enginelinstall/centos/ 2、确定你是CentOS7及以上版本,我们已经做过了 3、yum安装gcc相关环境(需要确保虚拟机可以上外网)
  1. curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
  2. yum install -y gcc gcc-c++
4、卸载旧版本
  1. $ sudo yum remove docker \
  2. docker-client \
  3. docker-client-latest \
  4. docker-common \
  5. docker-latest \
  6. docker-latest-logrotate \
  7. docker-logrotate \
  8. docker-engine
5、安装需要的软件包
  1. $ sudo yum install -y yum-utils
6、设置镜像仓库
  1. #设置镜像的仓库,默认是国外的
  2. $ sudo yum-config-manager \
  3. --add-repo \
  4. https://download.docker.com/linux/centos/docker-ce.repo
  5. #推荐使用阿里云的,速度快
  6. $ sudo yum-config-manager \
  7. --add-repo \
  8. https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
7、更新yum软件包的索引
  1. #更新yum软件包的索引
  2. $ yum makecache fast
8、安装 Docker-CE
  1. #5.安装Docker相关的 Docker-ce社区版,ee则是企业版
  2. $ sudo yum install -y \
  3. docker-ce docker-ce-cli containerd.io docker-compose-plugin
9、启动 Docker
  1. #启动Docker
  2. $ systemctl enable --now docker
10、测试命令
  1. #查看Docker的信息
  2. $ docker version
  3. #判断Docker是否安装成功
  4. #运行helloworld
  5. $ sudo docker run hello-world
  6. #查看镜像
  7. $ docker images
11、卸载 Docker
  1. $ systemctl stop docker
  2. $ sudo yum remove -y \
  3. docker-ce docker-ce-cli containerd.io docker-compose-plugin
  4. $ rm -rf /var/lib/docker

2.3 配置 Docker 镜像加速器

  1. sudo mkdir -p /etc/docker
  2. sudo tee /etc/docker/daemon.json <<-'EOF'
  3. {
  4. "registry-mirrors": ["https://po13h3y1.mirror.aliyuncs.com","http://hub-mirror.c.163.com","https://mirror.ccs.tencentyun.com","http://f1361db2.m.daocloud.io"]
  5. }
  6. EOF
  7. sudo systemctl daemon-reload
  8. sudo systemctl restart docker

2.4 Docker Swarm 介绍

官方文档:https://docs.docker.com/engine/swarm/

Docker Engine 1.12 引入了集群模式,允许你创建一个或多个Docker引擎的集群,称为群。集群由一个或多个节点组成:集群模式下运行Docker Engine 1.12或更高版本的物理或虚拟机。 有两种类型的节点 : managersworkers.

💫2 Docker进阶篇超详细版教程通俗易懂 - 图14

If you haven’t already, read through the swarm mode overview and key concepts. Docker Swarm是管理跨节点容器的编排工具,相较于Docker Compose而言,Compose只能编排单节点上的容器[ Docker Compose v3 版本则可以将容器分配到不同 Docker Host 主机上,其基于Docker Swarm ],Swarm将一群Docker节点虚拟化为一个主机,使得用户只要在单一主机上操作就能完成对整个容器集群的管理工作。如果下载的是最新版的Docker,那么Swarm就已经被包含在内了,无需再安装。 Docker Swarm架构包含两种角色,manager和node,前者是Swarm Daemon工作的节点,包含了调度器、路由、服务发现等功能,负责接收客户端的集群管理请求,然后调度Node进行具体的容器工作,比如容器的创建、扩容与销毁等。 manager 本身也是一个node。

💫2 Docker进阶篇超详细版教程通俗易懂 - 图15

通常情况下,为了集群的高可用,manager个数 >=3 的奇数,node的个数则是不限制。

2.4.1 Docker Swarm 几个关键信息

  1. Swarm
集群的管理和编排是使用嵌入docker引擎的SwarmKit,可以在docker初始化时启动swarm模式或者加入已存在的swarm
  1. Node
一个节点是docker引擎集群的一个实例。您还可以将其视为Docker节点。您可以在单个物理计算机或云服务器上运行一个或多个节点,但生产群集部署通常包括分布在多个物理和云计算机上的Docker节点。 要将应用程序部署到swarm,请将服务定义提交给 管理器节点。管理器节点将称为任务的工作单元分派 给工作节点。 Manager节点还执行维护所需群集状态所需的编排和集群管理功能。Manager节点选择单个领导者来执行编排任务。 工作节点接收并执行从管理器节点分派的任务。默认情况下,管理器节点还将服务作为工作节点运行,但您可以将它们配置为仅运行管理器任务并且是仅管理器节点。代理程序在每个工作程序节点上运行,并报告分配给它的任务。工作节点向管理器节点通知其分配的任务的当前状态,以便管理器可以维持每个工作者的期望状态。
  1. Service
一个服务是任务的定义,管理机或工作节点上执行。它是群体系统的中心结构,是用户与群体交互的主要根源。创建服务时,你需要指定要使用的容器镜像。
  1. Task
任务是在docekr容器中执行的命令,Manager节点根据指定数量的任务副本分配任务给worker节点

2.4.2 Docker Swarm 的命令使用方法

docker swarm:集群管理,子命令有init, join, leave, update。(docker swarm —help查看帮助) docker node:节点管理,子命令有accept, promote, demote, inspect, update, tasks, ls, rm。(docker node —help查看帮助) docker service:服务创建,子命令有create, inspect, update, remove, tasks。(docker service—help查看帮助)

2.4.3 总结

node是加入到swarm集群中的一个docker引擎实体,可以在一台物理机上运行多个node,node分为:
  • manager nodes,也就是管理节点
  • worker nodes,也就是工作节点
1)manager node管理节点:执行集群的管理功能,维护集群的状态,选举一个leader节点去执行调度任务。 2)worker node工作节点:接收和执行任务。参与容器集群负载调度,仅用于承载task。 3)service服务:一个服务是工作节点上执行任务的定义。创建一个服务,指定了容器所使用的镜像和容器运行的命令。
  • service是运行在worker nodes上的task的描述,service的描述包括使用哪个docker 镜像,以及在使用该镜像的容器中执行什么命令。
4)task任务:一个任务包含了一个容器及其运行的命令。task是service的执行实体,task启动docker容器并在容器中执行任务。

2.5 搭建 Swarm 集群

  1. $ docker network ls
  2. NETWORK ID NAME DRIVER SCOPE
  3. f8457b0dde69 bridge bridge local
  4. 7e2416a3754e host host local
  5. efedf7a831e1 none null local
  6. #配置内核参数
  7. $ cat >> /etc/sysctl.conf <<EOF
  8. net.bridge.bridge-nf-call-ip6tables=1
  9. net.bridge.bridge-nf-call-iptables=1
  10. net.bridge.bridge-nf-call-arptables=1
  11. net.ipv4.ip_forward=1
  12. EOF
  13. $ sysctl -p
  14. $ systemctl restart network
  15. #查看Swarm 帮助
  16. $ docker swarm --help
  17. Usage: docker swarm COMMAND
  18. Manage Swarm
  19. Commands:
  20. ca Display and rotate the root CA
  21. init Initialize a swarm
  22. join Join a swarm as a node and/or manager
  23. join-token Manage join tokens
  24. leave Leave the swarm
  25. unlock Unlock swarm
  26. unlock-key Manage the unlock key
  27. update Update the swarm
  28. Run 'docker swarm COMMAND --help' for more information on a command.
  29. $ docker swarm init --help
  30. Usage: docker swarm init [OPTIONS]
  31. Initialize a swarm
  32. Options:
  33. --advertise-addr string Advertised address (format: <ip|interface>[:port])
  34. --autolock Enable manager autolocking (requiring an unlock key to start a stopped manager)
  35. --availability string Availability of the node ("active"|"pause"|"drain") (default "active")
  36. --cert-expiry duration Validity period for node certificates (ns|us|ms|s|m|h) (default 2160h0m0s)
  37. --data-path-addr string Address or interface to use for data path traffic (format: <ip|interface>)
  38. --data-path-port uint32 Port number to use for data path traffic (1024 - 49151). If no value is set or
  39. is set to 0, the default port (4789) is used.
  40. --default-addr-pool ipNetSlice default address pool in CIDR format (default [])
  41. --default-addr-pool-mask-length uint32 default address pool subnet mask length (default 24)
  42. --dispatcher-heartbeat duration Dispatcher heartbeat period (ns|us|ms|s|m|h) (default 5s)
  43. --external-ca external-ca Specifications of one or more certificate signing endpoints
  44. --force-new-cluster Force create a new cluster from current state
  45. --listen-addr node-addr Listen address (format: <ip|interface>[:port]) (default 0.0.0.0:2377)
  46. --max-snapshots uint Number of additional Raft snapshots to retain
  47. --snapshot-interval uint Number of log entries between Raft snapshots (default 10000)
  48. --task-history-limit int Task history retention limit (default 5)
  49. #查看容器网络
  50. $ docker network ls
  51. NETWORK ID NAME DRIVER SCOPE
  52. 0419346c0041 bridge bridge local
  53. 7e2416a3754e host host local
  54. lx0i51ag13ge ingress overlay swarm
  55. efedf7a831e1 none null local
范例:初始化 Docker Swarm 集群
  1. # --autolock 启用管理器自动锁定(需要解锁钥匙才能启动已停止的管理器)
  2. $ docker swarm init --advertise-addr 10.0.0.101 --autolock=false
  3. Swarm initialized: current node (99uy33e0bqj9vpsgff5m8dhdo) is now a manager.
  4. To add a worker to this swarm, run the following command:
  5. docker swarm join --token SWMTKN-1-20u795dhecf4hyuc8rqgmlhcb6d3rvwpn8a3rk3p3jsfilhvrq-c0shttrcji8oh9kqecq547zgl 10.0.0.101:2377
  6. To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
#初始化节点 docker swarm init #docker swarm join 加入一个 Node 节点!
  1. #docker-node1节点加入到 docker swarm 集群
  2. docker-node1 $ docker swarm join --token SWMTKN-1-20u795dhecf4hyuc8rqgmlhcb6d3rvwpn8a3rk3p3jsfilhvrq-c0shttrcji8oh9kqecq547zgl 10.0.0.101:2377
  3. This node joined a swarm as a worker.
  1. #获取令牌(Master)
  2. docker swarm join-token manager
  3. #获取令牌(Worker)
  4. docker swarm join-token worker
#docker node ls 查看 Docker Swarm 集群节点情况
  1. #只有 Manager 节点才能运行该命令
  2. $ docker node ls
  3. ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
  4. 99uy33e0bqj9vpsgff5m8dhdo * docker-master Ready Active Leader 20.10.17
  5. kizhvl3j9pyp35ac8b9olbyij docker-node1 Ready Active 20.10.17
  6. #普通节点运行会报错
  7. $ docker node ls
  8. Error response from daemon: This node is not a swarm manager. Worker nodes can't be used to view or modify cluster state. Please run this command on a manager node or promote the current node to a manager.
#docker swarm join 加入一个 Node 节点!
  1. #在 Docker Swarm Manager 节点生成一串 Worker 令牌
  2. $ docker swarm join-token worker
  3. To add a worker to this swarm, run the following command:
  4. docker swarm join --token SWMTKN-1-20u795dhecf4hyuc8rqgmlhcb6d3rvwpn8a3rk3p3jsfilhvrq-c0shttrcji8oh9kqecq547zgl 10.0.0.101:2377
  5. #docker-node2节点加入到 docker swarm 集群
  6. docker-node2 $ docker swarm join --token SWMTKN-1-20u795dhecf4hyuc8rqgmlhcb6d3rvwpn8a3rk3p3jsfilhvrq-c0shttrcji8oh9kqecq547zgl 10.0.0.101:2377
  7. #查看 Docker Swarm 集群节点情况
  8. $ docker node ls
  9. ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
  10. 99uy33e0bqj9vpsgff5m8dhdo * docker-master Ready Active Leader 20.10.17
  11. kizhvl3j9pyp35ac8b9olbyij docker-node1 Ready Active 20.10.17
  12. m23f84nx9fjjsplo3yjpqu61n docker-node2 Ready Active 20.10.17
#docker swarm join 加入一个 Manager 节点!
  1. #在 Docker Swarm Manager 节点生成一串 Manager 令牌
  2. $ docker swarm join-token manager
  3. To add a manager to this swarm, run the following command:
  4. docker swarm join --token SWMTKN-1-20u795dhecf4hyuc8rqgmlhcb6d3rvwpn8a3rk3p3jsfilhvrq-el7umy9l5k946v874i5g33tn4 10.0.0.101:2377
  5. #docker-node3节点加入到 docker swarm 集群
  6. docker-node3 $ docker swarm join --token SWMTKN-1-20u795dhecf4hyuc8rqgmlhcb6d3rvwpn8a3rk3p3jsfilhvrq-el7umy9l5k946v874i5g33tn4 10.0.0.101:2377
  7. #查看 Docker Swarm 集群节点情况(docker-master | docker-node3均可以运行)
  8. $ docker node ls
  9. ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
  10. 99uy33e0bqj9vpsgff5m8dhdo docker-master Ready Active Leader 20.10.17
  11. kizhvl3j9pyp35ac8b9olbyij docker-node1 Ready Active 20.10.17
  12. m23f84nx9fjjsplo3yjpqu61n docker-node2 Ready Active 20.10.17
  13. 23pzy3giz3swnx4z41iipgxn6 * docker-node3 Ready Active Reachable 20.10.17
这就将 Docker Swarm 集群搭建完毕了
  1. #两台Manager节点和两个Worker节点
  2. #集群其实至少要三台Manager节点(要确保大多数的情况),即奇数个Manager节点
  3. $ docker node ls
  4. ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
  5. 99uy33e0bqj9vpsgff5m8dhdo * docker-master Ready Active Leader 20.10.17
  6. kizhvl3j9pyp35ac8b9olbyij docker-node1 Ready Active 20.10.17
  7. m23f84nx9fjjsplo3yjpqu61n docker-node2 Ready Active 20.10.17
  8. 23pzy3giz3swnx4z41iipgxn6 docker-node3 Ready Active Reachable 20.10.17

2.5.1 部署 Docker Swarm 健康服务

Visualizer非常直观地显示了Swarm集群中,服务器的状态和服务器上面运行容器的状态。Visualizer会占用8080、5000端口,应该规划好,避免使用这两个端口。
  1. #拉取镜像
  2. docker pull dockersamples/visualizer
  3. #部署监控服务 (#端口不能冲突)
  4. docker service create --name viz \
  5. --publish 8080:8080/tcp \
  6. --constraint=node.role==manager \
  7. --mount=type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \
  8. dockersamples/visualizer

💫2 Docker进阶篇超详细版教程通俗易懂 - 图16

2.5.2 部署 Portainer 图形化集群管理工具

Portainer 是一款轻量级的应用,它提供了图形化界面,用于方便的管理Docker环境,包括单机环境和集群环境(毫不犹豫直接使用 K8S)。用于监控和统计

Portainer 官方站点

官网:https://www.portainer.io/ 安装文档:Install Portainer with Docker on Linux - Portainer Documentation + Rancher (CI/CD使用) + Portainer 先执行使用 Docker图形化界面管理工具!提供一个后台面板供我们操作! bash $ docker volume create portainer_data $ docker service create -p 8000:8000 -p 9443:9443 \ --name portainer \ --constraint=node.role==manager \ --mount=type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \ --mount src=portainer_data,dst=/data \ portainer/portainer-ce:2.9.3 #访问测试: #外网:http://IP地址:9443 $ curl -k https://localhost:9443 可以查看相关的Docker面板情况 💫2 Docker进阶篇超详细版教程通俗易懂 - 图17 ## 2.6 Raft 协议 当 Docker Engine 以 swarm 模式运行时,管理器节点实现 Raft 共识算法来管理全局集群状态。 为什么原因Docker群模式是使用一个共识算法,以确保那些负责在集群中的管理和调度任务的所有经理节点,都存储相同一致的状态。 在整个集群中具有相同的一致状态意味着在发生故障时,任何 Manager 节点都可以接收任务并将服务恢复到稳定状态。例如,如果集群中负责调度任务的Leader Manager意外终止,任何其他 Manager 都可以接手调度的任务并重新平衡任务以匹配所需的状态。 使用共识算法在分布式系统中复制日志的系统确实需要特别小心。它们通过要求大多数节点就值达成一致来确保集群状态在出现故障时保持一致。 Raft 最多可以容忍(N-1)/2失败,并且需要大多数或法定人数的 (N/2)+1成员就提议给集群的值达成一致。这意味着在运行 Raft 的 5 个 Manager 的集群中,如果 3 个节点不可用,系统将无法处理更多请求以安排额外的任务。现有任务继续运行,但如果管理器集不健康,则调度程序无法重新平衡任务以应对故障。 群体模式下共识算法的实现意味着它具有分布式系统固有的特性:
  1. 容错系统中的值达成一致。
  2. 通过领导人选举过程相互排斥
  3. 集群成员管理
  4. 全局一致的对象排序和 CAS(比较和交换)

目前实验环境:两台Manager节点和两个Worker节点:假设一个节点挂了!其他节点是否可以用! Raft 协议:保证大多数节点存活才可以用,只要>1,集群则至少大于 3台。 实验:Raft 一致性算法 1、将 docker-master 机器停止,宕机!双主,另外一个主节点也不能使用了!
  1. #docker-master机器停止docker服务
  2. $ systemctl stop docker
  3. Warning: Stopping docker.service, but it can still be activated by:
  4. docker.socket
  5. docker-node3 $ docker node ls
  6. Error response from daemon: rpc error: code = DeadlineExceeded desc = context deadline exceede

💫2 Docker进阶篇超详细版教程通俗易懂 - 图18

2、将实验环境设置为 三主一从
  1. #docker-master机器开启docker服务
  2. $ systemctl start docker
  3. #可以看到docker-master节点状态是Reachable
  4. #而docker-node3节点状态是Leader
  5. $ docker node ls
  6. ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
  7. 99uy33e0bqj9vpsgff5m8dhdo * docker-master Ready Active Reachable 20.10.17
  8. kizhvl3j9pyp35ac8b9olbyij docker-node1 Ready Active 20.10.17
  9. m23f84nx9fjjsplo3yjpqu61n docker-node2 Ready Active 20.10.17
  10. 23pzy3giz3swnx4z41iipgxn6 docker-node3 Ready Active Leader 20.10.17
  11. #现在将docker-node2节点设置为Manager节点
  12. docker-node2 $ docker swarm leave
  13. Node left the swarm.
  14. $ docker node ls
  15. ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
  16. 99uy33e0bqj9vpsgff5m8dhdo docker-master Ready Active Reachable 20.10.17
  17. kizhvl3j9pyp35ac8b9olbyij docker-node1 Ready Active 20.10.17
  18. #docker-node2在集群中状态是 Down
  19. m23f84nx9fjjsplo3yjpqu61n docker-node2 Down Active 20.10.17
  20. 23pzy3giz3swnx4z41iipgxn6 * docker-node3 Ready Active Leader 20.10.17
  21. #删除该Down状态的节点信息
  22. $ docker node rm m23f84nx9fjjsplo3yjpqu61n
  23. m23f84nx9fjjsplo3yjpqu61n
  24. #在Manager节点上生成加入集群的Manager令牌
  25. $ docker swarm join-token manager
  26. To add a manager to this swarm, run the following command:
  27. docker swarm join --token SWMTKN-1-20u795dhecf4hyuc8rqgmlhcb6d3rvwpn8a3rk3p3jsfilhvrq-el7umy9l5k946v874i5g33tn4 10.0.0.104:2377
  28. #docker-node2以 Manager 身份加入到集群中
  29. docker-node2 $ docker swarm join --token SWMTKN-1-20u795dhecf4hyuc8rqgmlhcb6d3rvwpn8a3rk3p3jsfilhvrq-el7umy9l5k946v874i5g33tn4 10.0.0.104:2377
  30. #再次查看Docker Swarm 节点状态
  31. $ docker node ls
  32. ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
  33. 99uy33e0bqj9vpsgff5m8dhdo docker-master Ready Active Reachable 20.10.17
  34. kizhvl3j9pyp35ac8b9olbyij docker-node1 Ready Active 20.10.17
  35. rd9mtj5uqlqzh0wdjjqjc8v4m docker-node2 Ready Active Reachable 20.10.17
  36. 23pzy3giz3swnx4z41iipgxn6 * docker-node3 Ready Active Leader 20.10.17
  37. #现在就是三主一从的环境
注意的是:Worker 就是工作节点,无法执行管理节点的操作。目前3台机器已经设置成管理节点了。

💫2 Docker进阶篇超详细版教程通俗易懂 - 图19

再次测试 Raft 协议的情况
  1. #docker-master机器停止docker服务
  2. $ systemctl stop docker
  3. Warning: Stopping docker.service, but it can still be activated by:
  4. docker.socket
  5. #管理节点的操作依旧可以使用
  6. docker-node3 $ docker node ls
  7. ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
  8. 99uy33e0bqj9vpsgff5m8dhdo docker-master Ready Active Unreachable 20.10.17
  9. kizhvl3j9pyp35ac8b9olbyij docker-node1 Ready Active 20.10.17
  10. rd9mtj5uqlqzh0wdjjqjc8v4m docker-node2 Ready Active Reachable 20.10.17
  11. 23pzy3giz3swnx4z41iipgxn6 * docker-node3 Ready Active Leader 20.10.17
  12. #docker-node2机器停止docker服务
  13. docker-node2 $ systemctl stop docker
  14. Warning: Stopping docker.service, but it can still be activated by:
  15. docker.socket
  16. docker-node3 $ docker node ls
  17. Error response from daemon: rpc error: code = DeadlineExceeded desc = context deadline exceeded
集群可用!3个主节点。必须要管理节点>1台管理节点的存活
  1. #重新恢复Docker Swarm 的集群状态
  2. $ systemctl restart docker

2.7 Docker Swarm 体会

Docker Swarm 弹性,扩缩容,集群环境。 以后要告别 docker run ! docker-compose up 启动一个项目。单机的容器编排工具。 集群:Docker Swarm (docker service)后期的就是 Kubernetes。 docker集群 → 容器是服务 → 服务可以在容器中启动多个(副本数) Nginx 原先要配置负载均衡,需要把对应的服务写在 Nignx 的配置信息里,增加多少个,就写多少个;现在nginx不管这些了,不需要再麻烦的配置了,这就是动态扩缩容吧。
  1. #使用 docker 创建一个负载均衡服务 service
  2. $ docker service --help
  3. Usage: docker service COMMAND
  4. Manage services
  5. Commands:
  6. create Create a new service
  7. inspect Display detailed information on one or more services
  8. logs Fetch the logs of a service or task
  9. ls List services
  10. ps List the tasks of one or more services
  11. rm Remove one or more services
  12. rollback Revert changes to a service's' configuration
  13. scale Scale one or multiple replicated services
  14. update Update a service
  15. Run 'docker service COMMAND --help' for more information on a command.
  16. # docker swarm service 特性:
  17. #创建服务,动态扩展服务,动态更新服务,日志等
灰度发布,金丝雀发布!
  1. #容器启动!不具有扩缩容的能力
  2. $ docker run -it --name my-nginx nignx
  3. #服务!具有扩缩容的能力,滚动更新!
  4. $ docker service create -p 10080:80 --name my-nginx nginx
  5. tiwaj5uoanutx9gskbwwaphcd
  6. overall progress: 1 out of 1 tasks
  7. 1/1: running [==================================================>]
  8. verify: Service converged

💫2 Docker进阶篇超详细版教程通俗易懂 - 图20

  1. #docker service 需要先做swarm集群
  2. #查看docker service服务列表
  3. $ docker service ls
  4. ID NAME MODE REPLICAS IMAGE PORTS
  5. tiwaj5uoanut my-nginx replicated 1/1 nginx:latest *:10080->80/tcp
  6. #查看服务 REPLICAS 副本数
  7. #查看 my-nginx 服务在哪个节点上及状态:
  8. $ docker service ps my-nginx
  9. ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
  10. w9nlgl140jb0 my-nginx.1 nginx:latest docker-node2 Running Running about a minute ago
  11. #查看详细信息
  12. $ docker service inspect my-nginx
  13. #可以在Worker节点上查看Docker进程
  14. docker-node2 $ docker ps
  15. CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
  16. 0c7c9f65a519 nginx:latest "/docker-entrypoint.…" 5 minutes ago Up 5 minutes 80/tcp my-nginx.1.w9nlgl140jb0qkzfr0gttcv41
范例:实现动态扩缩容
  1. #方法一:使用 docker service scale 进行扩容
  2. $ docker service scale --help
  3. Usage: docker service scale SERVICE=REPLICAS [SERVICE=REPLICAS...]
  4. Scale one or multiple replicated services
  5. Options:
  6. -d, --detach Exit immediately instead of waiting for the service to converge
  7. $ docker service scale my-nginx=3
  8. my-nginx scaled to 3
  9. overall progress: 3 out of 3 tasks
  10. 1/3: running [==================================================>]
  11. 2/3: running [==================================================>]
  12. 3/3: running [==================================================>]
  13. verify: Service converged
  14. #扩容完成后,查看扩容情况
  15. $ docker service ls
  16. ID NAME MODE REPLICAS IMAGE PORTS
  17. tiwaj5uoanut my-nginx replicated 3/3 nginx:latest *:10080->80/tcp
  18. #已经创建了多个副本数
  19. $ docker service ps my-nginx
  20. ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
  21. w9nlgl140jb0 my-nginx.1 nginx:latest docker-node2 Running Running 8 minutes ago
  22. nckmn3z21ijb my-nginx.2 nginx:latest docker-master Running Running about a minute ago
  23. 6vd1emspxxtr my-nginx.3 nginx:latest docker-node3 Running Running about a minute ago
  24. #方法二:使用 docker service update --replicas [int] 进行扩容
  25. $ docker service update --replicas 5 my-nginx
  26. my-nginx
  27. overall progress: 5 out of 5 tasks
  28. 1/5: running [==================================================>]
  29. 2/5: running [==================================================>]
  30. 3/5: running [==================================================>]
  31. 4/5: running [==================================================>]
  32. 5/5: running [==================================================>]
  33. verify: Service converged
  34. #扩容完成后,查看扩容情况
  35. $ docker service ls
  36. ID NAME MODE REPLICAS IMAGE PORTS
  37. tiwaj5uoanut my-nginx replicated 5/5 nginx:latest *:10080->80/tcp
  38. $ docker service ps my-nginx
  39. ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
  40. w9nlgl140jb0 my-nginx.1 nginx:latest docker-node2 Running Running 9 minutes ago
  41. nckmn3z21ijb my-nginx.2 nginx:latest docker-master Running Running 2 minutes ago
  42. 6vd1emspxxtr my-nginx.3 nginx:latest docker-node3 Running Running 2 minutes ago
  43. w8phrrpvxrb4 my-nginx.4 nginx:latest docker-node1 Running Running 21 seconds ago
  44. tf4m0pcr5yvh my-nginx.5 nginx:latest docker-node1 Running Running 21 seconds ago
  45. #update 只能扩容。缩容是停止容器而不是rm容器
服务,集群中任意的节点都可以正常访问!
  1. $ curl 10.0.0.101:10080
  2. <!DOCTYPE html>
  3. <html>
  4. <head>
  5. <title>Welcome to nginx!</title>
  6. <style>
  7. html { color-scheme: light dark; }
  8. body { width: 35em; margin: 0 auto;
  9. font-family: Tahoma, Verdana, Arial, sans-serif; }
  10. </style>
  11. </head>
  12. <body>
  13. <h1>Welcome to nginx!</h1>
  14. <p>If you see this page, the nginx web server is successfully installed and
  15. working. Further configuration is required.</p>
  16. <p>For online documentation and support please refer to
  17. <a href="http://nginx.org/">nginx.org</a>.<br/>
  18. Commercial support is available at
  19. <a href="http://nginx.com/">nginx.com</a>.</p>
  20. <p><em>Thank you for using nginx.</em></p>
  21. </body>
  22. </html>
  23. #云服务器可以安全组放通后,可以直接使用(虚拟机可能会出现一些问题)

2.7.1 Docker Swarm 网络的坑

💫2 Docker进阶篇超详细版教程通俗易懂 - 图21

统一的判断:

  1. 服务器的防火墙有没有关闭。也可以放通相关的 Docker Swarm 集群端口
  1. #需要放通的端口有:
  2. #对于此测试,您需要两个可以相互通信的不同 Docker 主机。Docker 主机之间打开以下端口:
  3. TCP 端口 2377
  4. TCP UDP 端口 7946
  5. UDP 端口 4789
  6. #设置此设置的一种简单方法是拥有两个 VM(本地或 AWS 等云提供商),每个 VM 都已安装并运行 Docker。
  7. #如果您使用的是 AWS 或类似的云计算平台,最简单的配置是使用安全组,
  8. #该安全组打开两台主机之间的所有传入端口以及来自客户端 IP 地址的 SSH 端口。
  9. #若不关闭防火墙,则需要放通相关的端口
  10. firewall-cmd --zone=public --add-port=2377/tcp --permanent
  11. firewall-cmd --zone=public --add-port=7946/tcp --permanent
  12. firewall-cmd --zone=public --add-port=7946/udp --permanent
  13. firewall-cmd --zone=public --add-port=4789/tcp --permanent
  14. firewall-cmd --zone=public --add-port=4789/udp --permanent
  15. firewall-cmd --reload
  1. 服务器的主机名需要设置的有意义并且没有冲突
  2. 需要确认的是服务器的网段是在哪个网段。Docker Swarm 默认服务的 Overlay 网络是在 10 网段,很容易与现网的网段造成冲突。所以服务器网段尽量不要设置成 10 网段的情况,但是一般已经服务器网络无法修改,那么就需要修改 Docker Swarm 默认的 Overlay 网络。(一般以上三点就可以排查出”为什么 Docker Swarm 部署的服务,集群各节点无法正常通信的情况”)

💫2 Docker进阶篇超详细版教程通俗易懂 - 图22

:::info 南北向:主要用于访问外部网络。通过eht1网卡,走veth的docker_gwbridge网络,根据NAT把容器地址转换成主机地址,访问到外部网络。

东西向:用于集群之间的网络访问。192.168.200.10上的容器通过eht0访问overlay的网络mynet,将原始数据加一个VXLAN的头,封装成数据包,这时会原始地址就是192.168.200.10,目标IP地址192.168.200.11,通过这个管道发送到目标机器上,再通过overlay网络的mynet接收解封,发送到192.168.200.11的容器上。

集群的两个节点之间 10.0.1.8 - > 10.0.1.9 转换后两台机器 192.168.200.10 -> 192.168.200.11。

:::

2.8 概念总结

Docker Swarm :集群的管理和容器编排,Docker 可以初始化一个Swarm,其他节点可以加入。(管理节点,工作节点) Node:就是一个 Docker 节点,多个节点就组成了一个网络集群(管理节点,工作节点) Service:任务,可以在管理节点,工作节点来运行。核心!用户访问! Task:容器内的命令,细节任务!

💫2 Docker进阶篇超详细版教程通俗易懂 - 图23

Swarm 特点:
  1. Docker Engine集成集群管理
使用Docker Engine CLl创建一个Docker Engine的Swarm模式,在集群中部署应用程序服务。
  1. 去中心化设计
Swarm角色分为Manager和Worker节点,Manager节点故障不影响应用使用。
  1. 扩容缩容
可以声明每个服务运行的容器数量,通过添加或删除容器数自动调整期望的状态。
  1. 期望状态协调
Swarm Manager节点不断监视集群状态,并调整当前状态与期望状态之间的差异。例如,设置一个服务运行10个副本容器,如果两个副本的服务器节点崩溃,Manager将创建两个新的副本替代崩溃的副本。并将新的副本分配到可用的worker节点。
  1. 多主机网络
可以为服务指定overlay网络。当初始化或更新应用程序时,Swarm manager会自动为overlay网络上的容器分配IP地址。
  1. 服务发现
Swarm manager节点为集群中的每个服务分配唯一的DNS记录和负载均衡VIP。可以通过Swarm内置的DNS服务器查询集群中每个运行的容器。
  1. 负载均衡
实现服务副本负载均衡,提供入口访问。也可以将服务入口暴露给外部负载均衡器再次负载均衡。
  1. 安全传输
Swarm中的每个节点使用TLS相互验证和加密,确保安全的其他节点通信。
  1. 滚动更新
升级时,逐步将应用服务更新到节点,如果出现问题,可以将任务回滚到先前版本

2.9 工作模式

Node 节点

💫2 Docker进阶篇超详细版教程通俗易懂 - 图24

Service
当部署服务到 swarm,swarm manager接收你对服务期望状态的定义。然后它为服务在 swarm 中的节点调度一个或多个副本任务。这些任务在 swarm 的节点上彼此独立地运行。
例如假设你想负载均衡三个 HTTP 服务器实例。下面的图表展示了三个 HTTP 服务器副本。
三个 HTTP 实例中的每一个是 swarm 中的一个任务。

💫2 Docker进阶篇超详细版教程通俗易懂 - 图25

容器是一个独立的进程。在swarm模式模式中,每个task只调用一个容器。task类似于调度程序放置容器的“插槽”。一旦容器处于活动状态,调度程序就会识别出任务处于运行状态。如果容器未通过健康检查或终止,则任务终止。
任务与调度
  1. swarm manager:
  2. -- 1API:这个请求直接由Swarm managerAPI进行接收,接收命令并创建服务对象。
  3. -- 2orchestrator:为服务创建一个任务。
  4. -- 3allocater:为这个任务分配IP地址。
  5. -- 4dispatcher:将任务分配到指定的节点。
  6. -- 5scheduler:在该节点中下发指定命令。
  7. worker node:接收manager任务后去运行这个任务。
  8. -- 1container:创建相应的容器。
  9. -- 2worker:连接到调度程序以检查分配的任务
  10. -- 3executor:执行分配给工作节点的任务

💫2 Docker进阶篇超详细版教程通俗易懂 - 图26

命令 -> 管理节点 -> API -> 调度 -> 工作节点(创建 Task 容器维护创建!)
服务副本与全局服务
有两种类型的services部署,副本和全局
  • Replicated services
    可以指定运行相同任务的数量。例如,你决定部署三个 HTTP 实例的副本,每个提供相同的内容。
  • global services
    在每个节点上运行一个相同的任务。不需要预先指定任务的数量。每次增加一个节点到 swarm 中,协调器就会创建一个任务,然后调度器把任务分配给新节点。
下图表示用黄色表示拥有三个副本的 Replicated service,用灰色表示了一个global service

💫2 Docker进阶篇超详细版教程通俗易懂 - 图27

调整 Service 以什么方式运行
  1. --mode string
  2. service mode (replicated or globa1) (default "replicated")
  3. docker service create --mode replicated --name mytom tomcat:7 #默认的
  4. docker service create --mode global --name haha alpine ping baidu.com
  5. #场景?日志收集
  6. #每一个节点有自己的日志收集器,过滤。把所有日志最终再传给日志中心
  7. #服务监控,状态性能。

2.10 网络模式

Docker Swarm 常用的网络模式:
  • Overlay :传统网络架构叠加虚拟化技术模式
  • Ingress :特殊的 Overlay 网络,具有负载均衡的网络。这个网络用于将服务暴露给外部访问,docker swarm就是通过它实现的routing mesh(将外部请求路由到不同主机的容器)。
  • docker_gwbridge 为使用多主机群覆盖网络的所有容器和任务提供默认网关功能。它是在每个 Docker 主机上创建的,当 Docker 主机加入集群时创建。

docker_gwbridge 是一个本地桥接网络,在以下两种情况会自动创建:

  • 初始化或者加入一个 swarm 集群时,用来在不同 hosts 主机的不同节点间进行通信;
  • 在容器中的所有网络都不能访问外部时,Docker 会将 docker_gwbridge 网络加入到容器中,用来访问外部网络或者其他的集群节点。
  • 容器可以连接到宿主机。
名称 类型 注释
docker_gwbridge bridge none
ingress overlay none
overlay none

第一是外部如何访问部署运行在swarm集群内的服务,可以称之为 入方向 流量,在swarm里我们通过 ingress 来解决

第二是部署在swarm集群里的服务,如何对外进行访问,这部分又分为两块:

  • 第一,东西向流量 ,也就是不同swarm节点上的容器之间如何通信,swarm通过 overlay 网络来解决;
  • 第二,南北向流量 ,也就是swarm集群里的容器如何对外访问,比如互联网,这个是 Linux bridge + iptables NAT 来解决的

南北向:主要用于访问外部网络。通过eht1网卡,走veth的docker_gwbridge网络,根据NAT把容器地址转换成主机地址,访问到外部网络。

东西向:用于集群之间的网络访问。192.168.200.10上的容器通过eht0访问overlay的网络mynet,将原始数据加一个VXLAN的头,封装成数据包,这时会原始地址就是192.168.200.10,目标IP地址192.168.200.11,通过这个管道发送到目标机器上,再通过overlay网络的mynet接收解封,发送到192.168.200.11的容器上。

集群的两个节点之间 10.0.1.8 - > 10.0.1.9 转换后两台机器 192.168.200.10 -> 192.168.200.11

💫2 Docker进阶篇超详细版教程通俗易懂 - 图28

3 Docker Stack

  1. 之前学的docker-compose.yml 就是一个单机版的多应用服务启动脚本.
  2. 那么docker stack 就是个集群版本的多应用服务启动脚本,语法和compose基本相同.
  3. docker stack 是基于cluster集群模式,发布服务的一个功能。
  4. docker stack 有如下几个命令
  5. docker stack deploy 发布或者更新一个stack
  6. docker stack list 获取所有stack
  7. docker stack ps 列出stack中运行的task
  8. docker stack services 列出stack中的服务
  9. docker stack rm 移除stack
  1. #单机
  2. docker-compose up -d docker-compose.yml
  3. #集群
  4. docker stack deploy --compose-file docker-compose.yml
  5. #docker-compose.yml 文件
  6. version: '3'
  7. services:
  8. web:
  9. image: wordpress
  10. ports:
  11. - 8080:80
  12. environment:
  13. WORDPRESS_DB_HOST: mysql
  14. WORDPRESS_DB_PASSWORD: root
  15. networks:
  16. - my-network
  17. depends_on:
  18. - mysql
  19. deploy:
  20. mode: replicated
  21. replicas: 3
  22. restart_policy:
  23. condition: on-failure
  24. delay: 5s
  25. max_attempts: 3
  26. update_config:
  27. parallelism: 1
  28. delay: 10s
  29. mysql:
  30. image: mysql:5.7
  31. environment:
  32. MYSQL_ROOT_PASSWORD: root
  33. MYSQL_DATABASE: wordpress
  34. volumes:
  35. - mysql-data:/var/lib/mysql
  36. networks:
  37. - my-network
  38. deploy:
  39. mode: global
  40. placement:
  41. constraints:
  42. - node.role == manager
  43. volumes:
  44. mysql-data:
  45. networks:
  46. my-network:
  47. driver: overlay

4 Docker Secret

安全!配置密码,证书! 声明式配置中,若直接定义用户名及密码等环境变量时,会造成安全隐患;因此,引入secret,对保密数据(用户名及密码、ssh key、TLS认证信息、其他需保密数据)进行加密。

敏感数据包括密码、私钥、证书及其它所有不能以明文的形式在网络上传输,或者是不能保存在各种文件中的数据,例如Dokerfile、image等。从docker 1.13开始,可以通过secret功能集中的保存与分发这些敏感数据,一个secret只允许被授权的服务在运行的时候访问,另外只有在集群模式下才能使用secret功能。docker以加密的形式保存与传输敏感数据,并且敏感数据会以分布式的形式存储在集群中的所以manager节点上,以提高可用性。

当对一个新建立的或者是运行中的service进行某个secret的授权时,docker会在内存中模拟一个文件,然后将解密后的数据放入文件中,并mount这个文件到容器的文件系统中,默认目录是/run/secrets/。可以在任何时候对一个服务进行授权、撤销操作。

docker secret同时也可以用来管理普通的配置项,但是从Docker 17.06开始,提供了专门用于管理非敏感数据的config。两者的区别是secret用的是RAM来模拟文件系统保存敏感数据,使用敏感数据的容器是只读的。而config则直接使用普通的文件系统存储非敏感数据。

💫2 Docker进阶篇超详细版教程通俗易懂 - 图29

  1. $ docker secret --help
  2. Usage: docker secret COMMAND
  3. Manage Docker secrets
  4. Commands:
  5. create Create a secret from a file or STDIN as content
  6. inspect Display detailed information on one or more secrets
  7. ls List secrets
  8. rm Remove one or more secrets
  9. Run 'docker secret COMMAND --help' for more information on a command.

5 Docker Config

在动态的、大规模的分布式集群上,管理和分发配置文件也是很重要的工作。传统的配置文件分发方式(如配置文件放入镜像中,设置环境变量,volume 动态挂载等)都降低了镜像的通用性。 在 Docker 17.06 以上版本中,Docker 新增了 docker config 子命令来管理集群中的配置信息,以后你无需将配置文件放入镜像或挂载到容器中就可实现对服务的配置。 注意:config 仅能在 Swarm 集群中使用 可以用target指定路径,如果不指定,默认挂载到容器的根目录下
  1. $ docker config --help
  2. Usage: docker config COMMAND
  3. Manage Docker configs
  4. Commands:
  5. create Create a config from a file or STDIN
  6. inspect Display detailed information on one or more configs
  7. ls List configs
  8. rm Remove one or more configs
  9. Run 'docker config COMMAND --help' for more information on a command.

6 扩展到 Kubernetes

Go 是 Google 开发的一种编译型、并发型,并具有垃圾回收功能的编程语言。 Go 的表现力强、简洁、干净、高效。它的并发机制使它能够轻松地编写程序,从而最大限度地利用多核和网络机器,而它新颖的类型系统则使灵活的模块化程序构造成为可能。Go 快速编译成机器代码,但又具有垃圾回收的便利性和运行时反射的强大功能。它是一种快速的、静态类型化的、编译后的语言,感觉就像一种动态类型化的、解释的语言。 Go 语言是基于 Inferno 操作系统所开发的。Go 语言于 2009 年 11 月正式宣布推出,成为开放源代码项目,并在 Linux 及 Mac OS X 平台上进行了实现,后追加 Windows 系统下的实现。 Go(又称Golang)是Google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的编程语言,被称为云计算时代的C语言。

Go 语言!必须掌握!

  • 入门 → 基础语法 → 高级对象 → 操作数据库 → 框架