Skip to content

1.部署环境准备

swarm 至少需要三个节点 所以需要准备三台机器

  • 练习环境

https://labs.play-with-docker.com/

bash
#修改主机名
hostnamectl set-hostname manager-01
#修改主机名
hostnamectl set-hostname manager-01
主机ip地址说明
manager-01192.168.177.130swarm-manager节点
work-01192.168.177.131swarm-work01节点
work-02192.168.177.129swarm-work02节点

docker版本:20.10.13

文档,https://docs.docker.com/engine/swarm/

容错节点

管理节点以奇数形式存在,保证管理节点高可用

Swarm manager nodesRepartition (on 3 Availability zones)
31-1-1
52-2-1
73-2-2
93-3-3
Swarm SizeMajorityFault Tolerance
110
220
321
431
532
642
743
853
954

2.初始化管理节点

#advertise-addr 来指定其他节点连接m0时的地址
#来指定其他节点连接m0时的地址 来指定其他节点连接m0时的地址
#来指定其他节点连接m0时的地址

docker swarm init --advertise-addr 192.168.177.130:2377 --listen-addr
192.168.177.130:2377

#查看节点信息
docker node ls

#查看网络信息 docker-swarm 初始化时会创建一个类型为overlay的网络
docker network ls
#advertise-addr 来指定其他节点连接m0时的地址
#来指定其他节点连接m0时的地址 来指定其他节点连接m0时的地址
#来指定其他节点连接m0时的地址

docker swarm init --advertise-addr 192.168.177.130:2377 --listen-addr
192.168.177.130:2377

#查看节点信息
docker node ls

#查看网络信息 docker-swarm 初始化时会创建一个类型为overlay的网络
docker network ls

2.1添加manager节点

添加manager 节点 –token 会失效 时效为24小时 以后添加节点时 执行 docker swarm join-token 获取最新的token

#在manager节点执行。可以作为manager节点加入集群
docker swarm join-token -q manager
#在manager节点执行。可以作为manager节点加入集群
docker swarm join-token -q manager

2.2添加worker节点

节点 –token 会失效 时效为24小时 以后添加节点时 执行 docker swarm join-token 获取最新的token

#在manager节点执行。可以作为worker节点加入集群
docker swarm join-token -q worker
#在manager节点执行。可以作为worker节点加入集群
docker swarm join-token -q worker

MANAGER STATUS列说明:

Leader 意味着该节点是使得群的所有群管理和编排决策的主要管理器节点。

:Reachable 意味着节点是管理者节点正在参与Raft共识。如果领导节点不可用,则该节点有资格被选为新领导者。

:Unavailable 意味着节点是不能与其他管理器通信的管理器。如果管理器节点不可用,您应该将新的管理器节点加入群集,或者将工作器节点升级为管理器。

AVAILABILITY列说明:

Active 意味着调度程序可以将任务分配给节点。

Pause 意味着调度程序不会将新任务分配给节点,但现有任务仍在运行。

Drain 意味着调度程序不会向节点分配新任务。调度程序关闭所有现有任务并在可用节点上调度它们

2.3.节点权限提升降低

#将worker节点提升为manager节点,在manager节点执行如下命令:
docker node promote hostname
docker node ls

#将manager节点降低为worker节点,在manager节点执行如下命令:
docker node demote hostname
docker node ls


#manager节点只用于管理集群,不希望部署服务。
docker node update --availability drain hostname

[root@k8s-node01 ~]# docker node update  --help

Usage:  docker node update [OPTIONS] NODE

Update a node

Options:
      --availability string   Availability of the node ("active", "pause", "drain")
      --label-add list        Add or update a node label ("key=value")
      --label-rm list         Remove a node label if exists
      --role string           Role of the node ("worker", "manager")
#将worker节点提升为manager节点,在manager节点执行如下命令:
docker node promote hostname
docker node ls

#将manager节点降低为worker节点,在manager节点执行如下命令:
docker node demote hostname
docker node ls


#manager节点只用于管理集群,不希望部署服务。
docker node update --availability drain hostname

[root@k8s-node01 ~]# docker node update  --help

Usage:  docker node update [OPTIONS] NODE

Update a node

Options:
      --availability string   Availability of the node ("active", "pause", "drain")
      --label-add list        Add or update a node label ("key=value")
      --label-rm list         Remove a node label if exists
      --role string           Role of the node ("worker", "manager")

2.4脱离集群

各个节点离开集群(必须先是node节点离开集群,然后manager节点才能离开集群)

#想要那个节点脱离集群就在那个节点下执行以下命令
docker swarm leave
#想要那个节点脱离集群就在那个节点下执行以下命令
docker swarm leave

2.5删除已经脱离集群的节点

#删除已经脱离集群的work-02节点 ,,如果是多个manager节点中的其中一个节点需要先将节点降为worker节点才能删除
docker node rm work-02

#manager节点只能强制退出 manager退出后意味着整个swarm不复存在。
docker swarm leave --force
#删除已经脱离集群的work-02节点 ,,如果是多个manager节点中的其中一个节点需要先将节点降为worker节点才能删除
docker node rm work-02

#manager节点只能强制退出 manager退出后意味着整个swarm不复存在。
docker swarm leave --force

3.图形界面

 docker run -itd --name visualizer -p 8099:8080 -e HOST=192.168.59.16 -e PORT=8080 -v /var/run/docker.sock:/var/run/docker.sock dockersamples/visualizer:latest
 
 
 #或者使用以下命令  可以通过集群中所有ip+port进行访问
 docker service create \
--name=viz \
--publish=8080:8080/tcp \
--constraint=node.role==manager \
--mount=type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \
dockersamples/visualizer
 docker run -itd --name visualizer -p 8099:8080 -e HOST=192.168.59.16 -e PORT=8080 -v /var/run/docker.sock:/var/run/docker.sock dockersamples/visualizer:latest
 
 
 #或者使用以下命令  可以通过集群中所有ip+port进行访问
 docker service create \
--name=viz \
--publish=8080:8080/tcp \
--constraint=node.role==manager \
--mount=type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \
dockersamples/visualizer
  • weavescope

4.stack命令

#在manager节点中创建docker-compose.yml文件。执行如下命令:
docker stack deploy nginx-stack --compose-file=docker-compose.yml 或者是
docker stack deploy nginx-stack -c docker-compose.yml
#查看stack服务运行情况。执行如下命令:
docker stack services nginx-stack
#查看5个容器运行在哪个节点中。执行如下命令:
docker service ls #查看到NAME中的服务名为:nginx-stack_nginx-web
docker service ps nginx-stack_nginx-web
#在manager节点中创建docker-compose.yml文件。执行如下命令:
docker stack deploy nginx-stack --compose-file=docker-compose.yml 或者是
docker stack deploy nginx-stack -c docker-compose.yml
#查看stack服务运行情况。执行如下命令:
docker stack services nginx-stack
#查看5个容器运行在哪个节点中。执行如下命令:
docker service ls #查看到NAME中的服务名为:nginx-stack_nginx-web
docker service ps nginx-stack_nginx-web

5.常用命令

# 创建服务
docker service create \  
  --image nginx \
  --replicas 2 \
  nginx 

# 更新服务
docker service update \  
  --image nginx:alpine \
  nginx 

# 删除服务
docker service rm nginx

# 减少服务实例(这比直接删除服务要好)
docker service scale nginx=0

# 增加服务实例
docker service scale nginx=5

# 查看所有服务
docker service ls

# 查看服务的容器状态
docker service ps nginx

# 查看服务的详细信息。
docker service inspect nginx  



实现零宕机部署也非常简单。这样也可以方便地实现持续部署:

# 构建新镜像
docker build -t hub.docker.com/image . 

# 将新镜像上传到Docker仓库
docker push hub.docker.com/image

# 更新服务的镜像
docker service update --image hub.docker.com/image service
# 创建服务
docker service create \  
  --image nginx \
  --replicas 2 \
  nginx 

# 更新服务
docker service update \  
  --image nginx:alpine \
  nginx 

# 删除服务
docker service rm nginx

# 减少服务实例(这比直接删除服务要好)
docker service scale nginx=0

# 增加服务实例
docker service scale nginx=5

# 查看所有服务
docker service ls

# 查看服务的容器状态
docker service ps nginx

# 查看服务的详细信息。
docker service inspect nginx  



实现零宕机部署也非常简单。这样也可以方便地实现持续部署:

# 构建新镜像
docker build -t hub.docker.com/image . 

# 将新镜像上传到Docker仓库
docker push hub.docker.com/image

# 更新服务的镜像
docker service update --image hub.docker.com/image service

swarm

命令描述
docker swarm join初始化一个 swarm 群集
docker swarm join加入群集作为节点或管理器
docker swarm join-token管理用于加入群集的令牌
docker swarm leave离开 swarm 群集
docker swarm update更新 swarm 群集
docker swarm unlock解锁 swarm 群集
docker swarm unlock-key管理解锁钥匙

node

命令描述
docker node demote从 swarm 群集管理器中降级一个或多个节点
docker node inspect显示一个或多个节点的详细信息
docker node ls列出 swarm 群集中的节点
docker node promote将一个或多个节点推入到群集管理器中
docker node ps列出在一个或多个节点上运行的任务,默认为当前节点
docker node rm从 swarm 群集删除一个或多个节点
docker node update更新一个节点

service

命令描述
docker service create创建服务
docker service inspect显示一个或多个服务的详细信息
docker service logs获取服务的日志
docker service ls列出服务
docker service rm删除一个或多个服务
docker service scale设置服务的实例数量
docker service update更新服务
docker service rollback恢复服务至update之前的配置

stack

命令描述
docker stack deploy部署新的堆栈或更新现有堆栈
docker stack ls列出现有堆栈
docker stack ps列出堆栈中的任务
docker stack rm删除一个或多个堆栈
docker stack services列出堆栈中的服务

6.清理任务

Docker Swarm 的 global mode 为所有的 Docker 节点启动一个清理服务副本, 实现新节点加入时自动启动与配置更新时自动同步到所有节点

创建 docker-compose.yml 文件, 内容如下

# docker-compose 文件版本, 需与 docker engine 兼容, 否则启动失败
# https://docs.docker.com/compose/compose-file/#compose-and-docker-compatibility-matrix
version: "3.8"

# 配置时区为宿主机时区
x-bind-timezone:
  - &bind-localtime
    type: bind
    source: /etc/localtime
    target: /etc/localtime
    read_only: true
  - &bind-timezone
    type: bind
    source: /etc/timezone
    target: /etc/timezone
    read_only: true

services:
  docker-prune:
    # 请将镜像 tag 修改为宿主机的 docker 版本
    image: docker:19.03.13
    # https://docs.docker.com/engine/swarm/services/#create-services-using-templates
    hostname: "docker-prune-{{.Node.Hostname}}"
    entrypoint: docker-entrypoint.sh
    volumes:
      # 保持时区与宿主机一致(北京时间)
      - *bind-localtime
      - *bind-timezone
      - type: bind
        source: /var/run/docker.sock
        target: /var/run/docker.sock
    configs:
      - source: docker-entrypoint
        target: /usr/local/bin/docker-entrypoint.sh
        # 赋予执行权限
        mode: 0555
      - source: run
        target: /usr/local/bin/run.sh
        # 赋予执行权限
        mode: 0555
    environment:
      # cron 表达式, 必配 https://crontab.guru/
      CRON: "0 3 * * *"
      # 清理匹配到的镜像, 选配
      # 一般用于在自己或公司名下的项目镜像
      # 因为该类镜像会频繁的发布与更新, 而更新后上个版本理论上可以删除
      # 如果不配置或者为空则忽略该步骤
      PRUNE_IMAGE_BY_GREP: abc
    deploy:
      # global 模式, 在所有的 docker 节点上都会启动一份副本, 以达到 docker 节点新增时自动启动
      mode: global
# 在此处配置使用的网络, 如果不配置, docker 会创建一个默认网络 docker-prune_default
# 建议先创建一个外部网络, 然后使用改网络
#    networks:
#      swarm_webnet:
#
#networks:
#  swarm_webnet:
#    # 是否为外部网络
#    external: true

configs:
  docker-entrypoint:
    file: ./docker-entrypoint.sh
  run:
    file: ./run.sh
# docker-compose 文件版本, 需与 docker engine 兼容, 否则启动失败
# https://docs.docker.com/compose/compose-file/#compose-and-docker-compatibility-matrix
version: "3.8"

# 配置时区为宿主机时区
x-bind-timezone:
  - &bind-localtime
    type: bind
    source: /etc/localtime
    target: /etc/localtime
    read_only: true
  - &bind-timezone
    type: bind
    source: /etc/timezone
    target: /etc/timezone
    read_only: true

services:
  docker-prune:
    # 请将镜像 tag 修改为宿主机的 docker 版本
    image: docker:19.03.13
    # https://docs.docker.com/engine/swarm/services/#create-services-using-templates
    hostname: "docker-prune-{{.Node.Hostname}}"
    entrypoint: docker-entrypoint.sh
    volumes:
      # 保持时区与宿主机一致(北京时间)
      - *bind-localtime
      - *bind-timezone
      - type: bind
        source: /var/run/docker.sock
        target: /var/run/docker.sock
    configs:
      - source: docker-entrypoint
        target: /usr/local/bin/docker-entrypoint.sh
        # 赋予执行权限
        mode: 0555
      - source: run
        target: /usr/local/bin/run.sh
        # 赋予执行权限
        mode: 0555
    environment:
      # cron 表达式, 必配 https://crontab.guru/
      CRON: "0 3 * * *"
      # 清理匹配到的镜像, 选配
      # 一般用于在自己或公司名下的项目镜像
      # 因为该类镜像会频繁的发布与更新, 而更新后上个版本理论上可以删除
      # 如果不配置或者为空则忽略该步骤
      PRUNE_IMAGE_BY_GREP: abc
    deploy:
      # global 模式, 在所有的 docker 节点上都会启动一份副本, 以达到 docker 节点新增时自动启动
      mode: global
# 在此处配置使用的网络, 如果不配置, docker 会创建一个默认网络 docker-prune_default
# 建议先创建一个外部网络, 然后使用改网络
#    networks:
#      swarm_webnet:
#
#networks:
#  swarm_webnet:
#    # 是否为外部网络
#    external: true

configs:
  docker-entrypoint:
    file: ./docker-entrypoint.sh
  run:
    file: ./run.sh

其中会用到两个脚本, 需与 docker-compose.yml 在同一文件夹中

  • docker-entrypoint.sh
#!/bin/sh

# https://blog.knoldus.com/running-a-cron-job-in-docker-container/

# Start the run once job.
echo "Docker container has been started"

touch /var/log/cron.log

# Setup a cron schedule
echo "${CRON} run.sh >> /var/log/cron.log 2>&1
# This extra line makes it a valid cron" >scheduler.txt

# 配置定时任务
crontab scheduler.txt
# 后台启动定时任务
crond
# 查看定时任务执行日志
tail -f /var/log/cron.log
#!/bin/sh

# https://blog.knoldus.com/running-a-cron-job-in-docker-container/

# Start the run once job.
echo "Docker container has been started"

touch /var/log/cron.log

# Setup a cron schedule
echo "${CRON} run.sh >> /var/log/cron.log 2>&1
# This extra line makes it a valid cron" >scheduler.txt

# 配置定时任务
crontab scheduler.txt
# 后台启动定时任务
crond
# 查看定时任务执行日志
tail -f /var/log/cron.log
  • run.sh
bash
#!/bin/sh

# 清理容器
echo -e "\n清理容器 begin"
docker container prune --force
echo "清理容器 end"

# 清理镜像
echo -e "\n清理悬空镜像 begin"
docker image prune --force
echo "清理悬空镜像 end"

# 清理匹配到的镜像
if [ "${PRUNE_IMAGE_BY_GREP}" != "" ]; then
  # 如果镜像被使用, 则删除失败
  echo -e "\n清理匹配到的镜像 begin"
  docker images | grep "${PRUNE_IMAGE_BY_GREP}" | awk '{print $3 }' | xargs docker rmi
  echo "清理项目镜像 end"
fi
#!/bin/sh

# 清理容器
echo -e "\n清理容器 begin"
docker container prune --force
echo "清理容器 end"

# 清理镜像
echo -e "\n清理悬空镜像 begin"
docker image prune --force
echo "清理悬空镜像 end"

# 清理匹配到的镜像
if [ "${PRUNE_IMAGE_BY_GREP}" != "" ]; then
  # 如果镜像被使用, 则删除失败
  echo -e "\n清理匹配到的镜像 begin"
  docker images | grep "${PRUNE_IMAGE_BY_GREP}" | awk '{print $3 }' | xargs docker rmi
  echo "清理项目镜像 end"
fi
bash
#启动
docker stack deploy --compose-file docker-compose.yml docker-prune

#删除
docker stack rm docker-prune


#更新
# 先停止, 再启动, 因为使用到了 docker config, 无法直接更新
docker stack rm docker-prune && docker stack deploy --compose-file docker-compose.yml docker-prune
#启动
docker stack deploy --compose-file docker-compose.yml docker-prune

#删除
docker stack rm docker-prune


#更新
# 先停止, 再启动, 因为使用到了 docker config, 无法直接更新
docker stack rm docker-prune && docker stack deploy --compose-file docker-compose.yml docker-prune

7.集群服务管理

7.1创建服务

Docker 提供了 docker stack 命令集,用来在 docker swarm 中部署服务及更新服务,我们可以提前将服务的定义写入一个 docker-compose.yml 文件,然后交由 docker stack deploy` 命令去执行:

# ./docker-compose.yml

version: '3.6'

services:
  nginx:
    image: nginx:1.17.6-alpine
    ports:
      - "80:80"
    networks:
      - swarm_net
    deploy:
      mode: replicated
      replicas: 5
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 120s
      update_config:
        parallelism: 2
        delay: 5s


networks:
  swarm_net:
    driver: overlay
# ./docker-compose.yml

version: '3.6'

services:
  nginx:
    image: nginx:1.17.6-alpine
    ports:
      - "80:80"
    networks:
      - swarm_net
    deploy:
      mode: replicated
      replicas: 5
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
        window: 120s
      update_config:
        parallelism: 2
        delay: 5s


networks:
  swarm_net:
    driver: overlay
# ./deploy-nginx-service.yml

---
- name: Deploy services to docker swarm cluster
  gather_facts: no
  hosts: leader
  vars:
    src_docker_compose: ./docker-compose.yml
    dest_docker_compose: ~/docker-compose.yml

    stack_name: first_stack
  tasks:
    - name: Upload docker compose file
      template:
        src: "{{ src_docker_compose }}"
        dest: "{{ dest_docker_compose }}"

    - name: Deploy services
      shell: docker stack deploy --with-registry-auth --prune --compose-file {{ dest_docker_compose }} {{ stack_name }}

    - name: Pause for 10 seconds to wait for services being running
      pause:
        seconds: 10

    - name: Ensure services deployed
      shell: docker service ls
      register: service_output

    - name: Output service list
      debug:
        msg: "{{ service_output.stdout_lines }}"

    - name: Show stacks
      shell: docker stack ls
# ./deploy-nginx-service.yml

---
- name: Deploy services to docker swarm cluster
  gather_facts: no
  hosts: leader
  vars:
    src_docker_compose: ./docker-compose.yml
    dest_docker_compose: ~/docker-compose.yml

    stack_name: first_stack
  tasks:
    - name: Upload docker compose file
      template:
        src: "{{ src_docker_compose }}"
        dest: "{{ dest_docker_compose }}"

    - name: Deploy services
      shell: docker stack deploy --with-registry-auth --prune --compose-file {{ dest_docker_compose }} {{ stack_name }}

    - name: Pause for 10 seconds to wait for services being running
      pause:
        seconds: 10

    - name: Ensure services deployed
      shell: docker service ls
      register: service_output

    - name: Output service list
      debug:
        msg: "{{ service_output.stdout_lines }}"

    - name: Show stacks
      shell: docker stack ls
bash
ansible-playbook -i hosts.ini -v ./deploy-nginx-service.yml
ansible-playbook -i hosts.ini -v ./deploy-nginx-service.yml

Manager节点创建服务

#使用Manager节点创建服务
docker service create --replicas 1 --name myhello -p 8000:8000 --constraint 'node.role==manager' kentalk/helloword

#使用Manager节点扩缩容服务
docker service scale myhello=3 --constraint 'node.role==manager'
#使用Manager节点创建服务
docker service create --replicas 1 --name myhello -p 8000:8000 --constraint 'node.role==manager' kentalk/helloword

#使用Manager节点扩缩容服务
docker service scale myhello=3 --constraint 'node.role==manager'

Worker节点部署服务

#work节点创建服务
docker service create --replicas 1 --name myhello -p 8000:8000 --constraint 'node.role==worker' kentalk/helloworld

#扩容
docker service scale myhello=3 --constraint 'node.role==worker'
#work节点创建服务
docker service create --replicas 1 --name myhello -p 8000:8000 --constraint 'node.role==worker' kentalk/helloworld

#扩容
docker service scale myhello=3 --constraint 'node.role==worker'
docker service create --replicas 1 --name web01 nginx
docker service create --replicas 1 --name web01 nginx

7.2显示服务详细信息

docker service inspect --pretty web01


#返回json格式
docker service inspect web01
docker service inspect --pretty web01


#返回json格式
docker service inspect web01

7.3扩容和缩容

docker service scale web01=3
docker service scale web01=3

7.4查看服务任务

#查看所有service
docker service ls


#查看web01
docker service ps web01

#查看运行状态的service
docker service ps -f 'desired-state=running' web01
#查看所有service
docker service ls


#查看web01
docker service ps web01

#查看运行状态的service
docker service ps -f 'desired-state=running' web01

7.5滚动更新服务

#创建
docker service create \
--replicas 3 \
--name redis \
--update-delay 10s \
redis:3.0.6


#更新
docker service update --image redis:3.0.7 redis
#创建
docker service create \
--replicas 3 \
--name redis \
--update-delay 10s \
redis:3.0.6


#更新
docker service update --image redis:3.0.7 redis

7.6创建服务时设定更新策略

docker service create \
--name my_web
--replicas 10 \
--update-delay 10s \
--update-parallelism 2 \
--update-failure-action continue \
nginx:1.12
docker service create \
--name my_web
--replicas 10 \
--update-delay 10s \
--update-parallelism 2 \
--update-failure-action continue \
nginx:1.12

7.7创建服务时设定回滚策略

docker service create \
--name my_web \
--replicas 10 \
--rollback-parallelism 2 \
--rollback-monitor 20s \
--rollback-max-failure-ratio .2 \
nginx:1.12
docker service create \
--name my_web \
--replicas 10 \
--rollback-parallelism 2 \
--rollback-monitor 20s \
--rollback-max-failure-ratio .2 \
nginx:1.12

7.8服务更新

docker service update --image nginx:1.13 my_web
docker service update --image nginx:1.13 my_web

7.9手动回滚

docker service update --rollback my_web
docker service update --rollback my_web

8.0角色切换

#升级前
[root@k8s-master01 docker-swarm]# docker node ls 
ID                            HOSTNAME       STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
lla0kao0df1ehymdwo2vzdmb3 *   k8s-master01   Ready     Active         Leader           19.03.15
91hhnuxxgfg7tuyorz9v5lhgn     k8s-node01     Ready     Active                          19.03.15
l5o7592d6wv53sfi7ufvj4o9y     k8s-node02     Ready     Active                          19.03.15
#升级前
[root@k8s-master01 docker-swarm]# docker node ls 
ID                            HOSTNAME       STATUS    AVAILABILITY   MANAGER STATUS   ENGINE VERSION
lla0kao0df1ehymdwo2vzdmb3 *   k8s-master01   Ready     Active         Leader           19.03.15
91hhnuxxgfg7tuyorz9v5lhgn     k8s-node01     Ready     Active                          19.03.15
l5o7592d6wv53sfi7ufvj4o9y     k8s-node02     Ready     Active                          19.03.15

8.swarm集群数据管理

1.volume方式管理数据

​ volume模式:在宿主机上创建一个volume,默认目录为(/var/lib/docker/volume/your_custom_volume/_data),然后把容器的某个目录映射到宿主机的volume上,即使容器挂了,数据还会依然保留在宿主机的volume上

bash
docker service create --replicas 1 --mount type=volume,src=nginx_data,dst=/usr/share/nginx/html --name www_web01 nginx:1.12
docker service create --replicas 1 --mount type=volume,src=nginx_data,dst=/usr/share/nginx/html --name www_web01 nginx:1.12
  • 查看服务
docker service inspect www_web01
docker service inspect www_web01
  • 查看数据卷
docker volume inspect nginx_data
docker volume inspect nginx_data

2.bind mount方式管理数据

bind mount模式:将宿主机某个目录映射到docker容器,很适合于网站,同时把宿主机的这个目录作为git版本目录,每次update代码的时候,容器就会更新。

创建数据目录

在mananger、worker01、worker02上创建web网站目录:

mkdir -p /data/wwwroot

docker service create --replicas 1--mount type=bind,src=/data/wwwroot,dst=/usr/share/nginx/html --name www_web02 nginx:1.12
mkdir -p /data/wwwroot

docker service create --replicas 1--mount type=bind,src=/data/wwwroot,dst=/usr/share/nginx/html --name www_web02 nginx:1.12

3.NFS方式管理数据

前面两种方式都是单机docker上数据共享方式,要是在集群中,这个就不适用了,我们必须使用共享存储或网络存储了

#随便找个节点进行安装
yum install nfs-utils -y
#随便找个节点进行安装
yum install nfs-utils -y
docker service create \
--mount 'type=volume,src=nfs-vol,dst=/usr/share/nginx/html, \
volume-driver=local,volume-opt=type=nfs,\
volume-opt=device=:/data/container_data,"volume-opt=o=addr=10.11.97.187,vers=4,soft,timeo=180,bg,tcp,rw"' \
--name www_web03_nfs nginx:1.12
docker service create \
--mount 'type=volume,src=nfs-vol,dst=/usr/share/nginx/html, \
volume-driver=local,volume-opt=type=nfs,\
volume-opt=device=:/data/container_data,"volume-opt=o=addr=10.11.97.187,vers=4,soft,timeo=180,bg,tcp,rw"' \
--name www_web03_nfs nginx:1.12

9.swarm集群发布

https 😕/docs.docker.com/engine/swarm/ingress/#/configure-an-external-load-balancer

服务发现: Swarm模式内置DNS组件,自动为每个服务分配DNS记录,然后服务的DNS名称在集群内的服务直接分发请求。

负载均衡:在Swarm集群中创建服务时, Ingress网络会自动为其分配一个虚拟IP(VIP),在DNS解析时返回VIP,流入该VIP的流量将自动发送(IPVS)该服务的所以健康任 务(容器)

1.创建服务

在每个节点上创建服务,使用ingress暴露publish port:

docker service create --replicas=3 --name web01 -p 88:80 nginx:1.12
docker service create --replicas=3 --name web01 -p 88:80 nginx:1.12

2.查看容器分布节点

[root@k8s-node01 ~]# docker service ls 
ID             NAME      MODE         REPLICAS   IMAGE        PORTS
tjl6o6v4rcfz   web01     replicated   3/3        nginx:1.12   *:88->80/tcp

[root@k8s-node01 ~]# docker service ps web01
ID             NAME      IMAGE        NODE           DESIRED STATE   CURRENT STATE           ERROR     PORTS
tmxw2pvfgtnu   web01.1   nginx:1.12   k8s-node01     Running         Running 9 minutes ago             
i6kmtbpgybfj   web01.2   nginx:1.12   k8s-node02     Running         Running 9 minutes ago             
w0b3hauyt73k   web01.3   nginx:1.12   k8s-master01   Running         Running 9 minutes ago
[root@k8s-node01 ~]# docker service ls 
ID             NAME      MODE         REPLICAS   IMAGE        PORTS
tjl6o6v4rcfz   web01     replicated   3/3        nginx:1.12   *:88->80/tcp

[root@k8s-node01 ~]# docker service ps web01
ID             NAME      IMAGE        NODE           DESIRED STATE   CURRENT STATE           ERROR     PORTS
tmxw2pvfgtnu   web01.1   nginx:1.12   k8s-node01     Running         Running 9 minutes ago             
i6kmtbpgybfj   web01.2   nginx:1.12   k8s-node02     Running         Running 9 minutes ago             
w0b3hauyt73k   web01.3   nginx:1.12   k8s-master01   Running         Running 9 minutes ago

如果你关掉某个节点上web01的服务,swarm会再次启动一个服务,以达到原来task的个数。在真实环境中,我们可以在swarm集群中的每个节点启动指定个数的tasks,然后在前端使用负载均衡设备,比如HA或Nginx都行,直接通过负载均衡的方式做到高可用

3.查看network

[root@k8s-node01 ~]# docker network ls
NETWORK ID     NAME              DRIVER    SCOPE
b9704956f6d1   bridge            bridge    local
e4cd8283fbd1   docker_gwbridge   bridge    local
a8ce4375181a   host              host      local
ldcaqwsczce8   ingress           overlay   swarm
9eb3e46dd217   none              null      local
[root@k8s-node01 ~]# docker network ls
NETWORK ID     NAME              DRIVER    SCOPE
b9704956f6d1   bridge            bridge    local
e4cd8283fbd1   docker_gwbridge   bridge    local
a8ce4375181a   host              host      local
ldcaqwsczce8   ingress           overlay   swarm
9eb3e46dd217   none              null      local

查看ingress网络

docker network inspect ld
docker network inspect ld

可以看出ingress,模拟出了一个vxlan,驱动类型为overlay,网段为:10.255.0.0/16,网关为10.255.0.1,vxlan有4096个接口

10.swarm集群高可用架构实现

11.Swarm配置文件管理

1、 生成一个基本的Nginx配置文件
# cat site.conf

server {

  listen 80;

  server_name localhost;

location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}

 

2、 将site.conf保存到docker配置中

# docker config create site.conf site.conf
# docker config ls


3、 创建一个Nginx并应用这个配置
# docker service create \
--name nginx \
--config source=site.conf,target=/etc/nginx/conf.d/site.conf \
--publish 8080:80 \
nginx
1、 生成一个基本的Nginx配置文件
# cat site.conf

server {

  listen 80;

  server_name localhost;

location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}

 

2、 将site.conf保存到docker配置中

# docker config create site.conf site.conf
# docker config ls


3、 创建一个Nginx并应用这个配置
# docker service create \
--name nginx \
--config source=site.conf,target=/etc/nginx/conf.d/site.conf \
--publish 8080:80 \
nginx

12.备份监控

https://gdevillele.github.io/engine/swarm/admin_guide/#/recover-from-disaster

https://www.digitalocean.com/community/tutorials/how-to-create-a-cluster-of-docker-containers-with-docker-swarm-and-digitalocean-on-ubuntu-16-04