写在前面的话

至此,docker 的基础知识已经了解的差不多了,接下来就来谈谈对于 docker 容器,我们如何来管理它。

docker swarm

在学习 docker swarm 之前,得先知道容器编排工具的作用:提供了基于容器调度和集群的技术,并编排容器之间如何进行交互。

docker swarm 不是唯一的容器编排工具,但却是 docker 自带的容器编排工具。

可以看看它的主要结构(图片来自互联网):

docker swarm 以集群的形式运行,包括两个角色:Manager 和 worker。

Manager 是 swarm 的集群的核心,所以一般会有多个,而且建议是奇数个,避免出现脑裂的情况。

多个 Manager 之间通过 Raft 协议进行信息同步。

Worker 就是干活的节点,节点之间通过 GOSS 网络进行信息同步。

Service 和 Replicas:每一个应用就是一个 Service,而每一次该应用的运行就是 Replicas。

创建 docker swarm

准备 3 台虚拟机:

IP 主机名 说明
192.168.100.100 docker-node1 Manager
192.168.100.101 docker-node2 Worker
192.168.100.102 docker-node3 Worker

初始化 Manager 节点并将两个 Worker 节点加入:

node1 执行:

docker swarm init --advertise-addr=192.168.100.100

结果如图:

复制红色部分到另外两个节点执行!

node2 和 node3 执行:

docker swarm -4423bymu0axfzp7cr1df6jjq36d5errbhetzlg3zz722lzt2j5-4nopnics4j267mh1gidf8z7nm 

结果如图:

在 node1 节点上查看 Swarm 信息:

docker node ls

结果如图:

类似相关集群的命令在 Worker 节点上执行一般都会报错:

This node is not a swarm manager

常见错误:

1. 初始化或者加错了节点想退出:

docker swarm leave --force

2. node2 和 node3 加入 swarm 时候报错:

Error response from daemon: error while validating Root CA Certificate: x509: certificate has expired or is not yet valid

这种问题一般是几台服务器的时间不一致,同步下时间一般就好了:

yum -y install ntp
ntpdate -u ntp.api.bz

3. node2 和 node3 加入 swam 很久没反应,报错:

connect: no route to host

这种问题一般是防火墙原因,关闭服务器的防火墙即可:

systemctl stop firewalld.service
systemctl disable firewalld.service

操作 docker swarm

在 docker swarm 中,命令都是基于 service 运行,而且所有服务都是运行在 Manager 节点。

【1】创建运行容器:

docker service create --name demo busybox sh -c "while true;do sleep 300; done"

【2】查看运行信息:

docker service ls

结果如图:

【3】查看该容器运行在哪个节点:

docker service ps demo

结果如图:

通过 create 时候的名字查找,但这个名字并不是容器名字。

【4】将容器运行多个节点:

docker service scale demo=

查看:

docker service ps demo

结果如图:

可以看到,3个容器被平均分配到了各个节点。

【5】删除容器:

docker container rm -f a98aad768cb9

先随便删除一个容器,再查看,结果如图:

可以发现,容器在短时间内会少掉一个节点,但是随即再度恢复成 3 个节点。

docker service ps demo

查看详细信息,结果如图:

可以看到一个被 Shutdown 的容器。值得注意的是,这个容器并不存在了已经。

【6】删除整个 Service:

docker service rm demo

结果如图,啥都不剩:

实战 - docker swarm 部署 wordpress

注意:在做这个实战之前,最好将 3 个节点的 docker 都重启一下,确保每个节点都存在:docker_gwbridge 和 ingress 网络。

【1】在 Manager 节点创建 overlay 网络和 MySQL:

network create -d overlay demo

结果如图:

该创建只存在于 Manager 节点。

docker service create --name mysql -- --env MYSQL_DATABASE=wordpress --network demo --mount type=volume,source=mysql_data,destination=/var/lib/mysql mysql:5.7

和直接 docker run 有着明显的不同,-e 参数变成了 --env,-v 参数变成了 --mount。

查看创建结果:

docker service lsdocker service ps mysql

结果如图:

【2】创建 wordpress:

docker service create --name wordpress -p : --network demo -- --env WORDPRESS_DB_HOST=mysql wordpress

查看结果:

【3】访问测试:

这里使用 Manager 节点的 IP 进行访问的,你也可以使用 Worker 节点的 IP 访问,三个 IP 都是没问题的。基于这一点,就可以实现很多骚操作。

同样,可以启动多个节点:

docker service scale wordpress=

结果如图:

Routing Mesh

为啥同一 overlay 网络中的多个容器之间能够互相通信,切访问的时候每个 IP 都能访问?

这就是 Routing Mesh,其主要的两种体现:Internal 和 Ingress。

Internal:容器与容器之间访问通过 overlay 网络

【1】通过创建两个容器进行测试,分别是 busybox 和 jwilder/whoami:

# 创建测试 overlay 网络
docker network create -d overlay ov-demo1

# 创建两个容器
docker service create --name busybox --network ov-demo1 busybox sh -c "while true;do sleep 3000;done"
docker service create --name whoami --network ov-demo1 -p 8000:8000 -d jwilder/whoami

# 将 whoami 创建成多个节点
docker service scale whoami=3

【2】进入 busybox 测试:

docker exec -it 1e68d97b6cda sh

结果如图:

记住上面这个 IP。然后去查看几个 whoami 容器的 IP,都不是这个 IP。

那这个 IP 是啥?

学过 LVS 的就知道有个东西叫做 VIP,也就是虚拟 IP,而这里的原理就是 LVS 实现,而这个 IP 就是 VIP,所有才会有访问哪个 IP 都行的结果,而且负载均衡

Ingress: 如果服务有绑定端口,则可以通过任意节点的这个端口访问。

原理在于:当访问指定端口的时候,请求被 gwbridge 转发带 ingress-sbox 的 namespace 中,然后让 LVS 调度给了任意一台机器。

docker swarm 中的 docker-compose.yml

上面学习的 docker swarm 虽然很爽,但是还是没有摆脱手动写很长的命令的束缚。所以有了接下来的专门用于 docker swarm 的 docker-compose.yml。

具体可以参照官方文档:

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

这里以部署 wordpress 为例的 docker-compose.yml:

version: '3'

services:

  web:
    image: wordpress
    ports:
      - 8888:80
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_PASSWORD: 123456
    networks:
      - ov-test
    depends_on:
      - db
    deploy:
      mode: replicated
      replicas: 3
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
      update_config:
        parallelism: 2
        delay: 10s

  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: 123456
      MYSQL_DATABASE: wordpress
    volumes:
      - mysql_test_data:/var/lib/mysql
    networks:
      - ov-test
    deploy:
      mode: global
      placement:
        constraints:
          - node.role == manager

volumes:
  mysql_test_data:

networks:
  ov-test:
    driver: overlay

相比于之前 docker-comse 时写的文件,这里主要多了 deploy 项,具体可以根据官方文档学习。

删除掉之前建立的所有容器,运行该配置文件,启动服务:

docker stack deploy wordpess --compose-file=docker-compose.yml

结果如图:

可以发现,在 docker swarm 中管理 docker compose 服务,不是使用 docker service 命令,而是换成了 docker stack 命令进行管理。

查看容器的相关信息:

# 查看 docker  stack 运行情况
docker stack ls

# 查看运行状态
docker stack services wordpess

# 也可以用 service 查看
docker service ls

# 查看更详细的信息
docker stack ps wordpess

结果如图:

访问测试:

删除服务:

docker stack rm wordpess

实战 - docker swarm 中的复杂项目实战

这是一个投票系统,工作原理如下图:

docker-compose 文件:

version: '

services:

    redis:
        image: redis:alpine
        ports:
            - "
        networks:
            - frontend
        deploy:
            replicas:
            update_config:
                parallelism:
                delay: 10s
            restart_policy:
                condition: on-failure

    db:
        image: postgres:9.4
        volumes:
            - db-data:/var/lib/postgresql/data
        networks:
            - backend
        deploy:
            placement:
                constraints: [node.role == manager]

    vote:
        image: dockersamples/exampleenvotingapp_vote:before
        ports:
            - :
        networks:
            - frontend
        depends_on:
            - redis
        deploy:
            replicas:
            update_config:
                parallelism:
            restart_policy:
                condition: on-failure

    result:
        image: dockersamples/exampleenvotingapp_result:before
        ports:
            - :
        networks:
            - backend
        depends_on:
            - db
        deploy:
            replicas:
            update_config:
                parallelism:
                delay: 10s
            restart_policy:
                condition: on-failure

    worker:
        image: dockersamples/exampleenvotingapp_worker
        networks:
            - frontend
            - backend
        labels: [APP=VOTING]
        deploy:
            placement:
                constraints: [node.role == manager]
            restart_policy:
                condition: on-failure
                delay: 10s
                max_attempts:     

    visualizer:
        image: dockersamples/visualizer:stable
        ports:
            - :
        stop_grace_period: 1m30s
        volumes:
            - "/var/run/docker.sock:/var/run/docker.sock"
        deploy:
            placement:
                constraints: [node.role == manager]

networks:
    frontend:
    backend:

volumes:
    db-data:

由于这个项目会去下载几个镜像,特别慢,有兴趣的可以自己尝试一下。

docker 中的密码管理

在实际生产中,很多时候数据库的密码不适合直接以明文的形式写出来,比如写在 docker-compose.yml 文件中,所以这就需要对密码进行处理。

对于 docker 中的密码,有两点需要明确:

1. 密码存在 Manager 节点的 Raft database 中,能够同步到其它节点。

2. Secert 在容器内部是以文件的形式保存的。

【1】创建 secert:

方法 1:从文件创建,创建一个 passwd 的文件,内容是密码:admin123

# 创建密码
docker secret create pass-demo passwd

# 查看
docker secret ls

结果如图:

方法 2:从用户输入创建:

echo "admin123" | docker secret create pass-demo1 -

注意最后的 - 符号,结果如图:

【2】删除密码:

docker secret rm pass-demo1

【3】给创建的容器指定密码:

docker service create --name demo --secret pass-demo busybox sh -c "while true;do sleep 300;done"

找到容器的节点,进入容器查看密码:

docker exec -it e80ae4cfdf15 sh

结果如图:

【4】如何使用这个文件,以 MySQL 为例:

docker service create --name mysql --secret pass-demo -e MYSQL_ROOT_PASSWORD_FILE=/run/secrets/pass-demo -d mysql

MySQL 镜像有个环境变量是可以指定密码文件的,但是这个特性是 MySQL 8 才具有的。结果如图:

【5】如何在 docker-compose.yml 中使用:

version: '3.7'

services:

  web:
    image: wordpress
    ports:
      - :
    secrets:
      - my-password
    environment:
      WORDPRESS_DB_HOST: mysql
      WORDPRESS_DB_PASSWORD_FILE: /run/secrets/my-password
    networks:
      - demo
    depends_on:
      - mysql
    deploy:
      mode: replicated
      replicas:
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts:
      update_config:
        parallelism:
        delay: 10s

  mysql:
    image: mysql:5.7
    secrets:
      - my-password
    environment:
      MYSQL_ROOT_PASSWORD_FILE: /run/secret/my-password
      MYSQL_DATABASE: wordpress
    volumes:
      - mysql-data:/var/lib/mysql
    networks:
      - demo
    deploy:
      mode: global
      placement:
        constraints:
          - node.role == manager

volumes:
  mysql-data:

networks:
  demo:
    driver: overlay

secrets:
  my-password:
    file: ./password

有几个地方值得注意:

1. 配置密码的时候指定的是文件。

2. 多了一个顶层配置,secerts

3. docker-compose.yml 版本是当前最新的,否则可能不支持该语法。

服务更新

服务搭建起来了,那如何在不停止服务的情况下灰度更新它?docker swarm 提供了自己方法。

这里以 Flask 项目为例:

【1】在三个节点的新建目录,app.py 和 Dockerfil:

mkdir docker-update
cd docker-update

app.py:

from flask import Flask
app = Flask(__name__)
@app.route('/')
def hello():
    return "Hello Flask version 1.0\n"
if __name__=="__main__":
    app.run(host=)

Dockerfile:

FROM python:2.7
COPY app.py /app/
RUN pip install flask
WORKDIR /app/
EXPOSE
CMD ["python", "app.py"]

【2】将 3 个节点构建成镜像:

docker build -t dylan/flask-test:v1. .

【3】将 3 个节点 app.py 里面的 1.0 换成 2.0,重新构建镜像:

docker build -t dylan/flask-test:v2. .

【4】部署 1.0 版本:

docker service create --name flask --publish : --network demo dylan/flask-test:v1.

【5】找到对应的节点访问测试:

sh -c "while true;do curl 127.0.0.1:9999&&sleep 1;done"

结果如图:

【6】在线升级:

# 扩展节点
docker service scale flask=

# 更新
docker service update --image dylan/flask-test:v2. flask

结果如图:

再看看访问的效果:

可以看出在升级过程中,有段时间是双版本并行的,更新完成后都是新的了。这就实现了业务的不中断。

写到这里,docker swarm 的知识差不多了,如果想更深入的学习,可以自己再去研究。

小结

docker swarm 给我们打开了容器编排的大门,但是最终目标还是 K8S,如果感兴趣,可以关注后面的 K8S 内容。

【09】循序渐进学 docker:docker swarm的更多相关文章

  1. 小白学Docker之Swarm

    承接上篇文章:小白学Docker之Compose,自学网站来源于https://docs.docker.com/get-started 系列文章: 小白学Docker之基础篇 小白学Docker之Co ...

  2. docker kubernetes Swarm容器编排k8s CICD部署

    1docker版本 docker 17.09 https://docs.docker.com/ appledeAir:~ apple$ docker version Client: Docker En ...

  3. 【Docker】 Swarm简单介绍

    [Swarm] Swarm是Docker官方提供的一款集群管理工具,其主要作用是把若干台Docker主机抽象为一个整体,并且通过一个入口统一管理这些Docker主机上的各种Docker资源.Swarm ...

  4. Docker And Swarm Mode(一)

    (一)节点的创建和配置 前言  虽然工作中一直在用Docker和Docker Swarm,但是总感觉有点陌生,总想自己亲手来写写和配置Docker 容器相关的事情,这篇文章主要是参考了Los Tech ...

  5. Docker - 使用 swarm 部署 services

    前言 经过之前一段时间学习与思考,我们已经大概明确了一些感念: Docker image/container,  service and node 简单来说,swarm允许我们以节点(node)的方式 ...

  6. 新一代Java程序员必学的Docker容器化技术基础篇

    Docker概述 **本人博客网站 **IT小神 www.itxiaoshen.com Docker文档官网 Docker是一个用于开发.发布和运行应用程序的开放平台.Docker使您能够将应用程序与 ...

  7. Docker - Docker基础讲义

    Docker Docker - 官网 Docker - Hub GitHub - Docker Docker中文社区 虚拟化技术 硬件级虚拟化(hardware-level-virtualizatio ...

  8. Docker: docker container常用命令实战

    容器管理,容器常用选项 选项 描述 -i, –interactive 交互式 -t, –tty 分配一个伪终端 -d, –detach 运行容器到后台 -e, –env 设置环境变量 -p, –pub ...

  9. Docker: docker image常用命令实战

    #docker列出镜像[root@192 ~]# docker imagesREPOSITORY TAG IMAGE ID CREATED SIZEnginx latest 881bd08c0b08 ...

  10. docker: docker安装和镜像下载

    1 安装docker的apt源 apt-get install apt-transport-https ca-certificates curl software-properties-common ...

随机推荐

  1. 【UVA11212 算法竞赛入门经典】 Editing a Book 【IDA*】

    题意 你有一篇由n(2<=n<=9)个自然段组成的文章,希望将它们排列成1,2,···,n.可以用剪切和粘贴来完成任务.每次可以剪切一段连续的自然段,粘贴时按照顺序粘贴.注意剪贴板只有一个 ...

  2. 小程序动态生成二维码,生成image图片

    前端: <image src="{{img_usrl}}" style="width:100%;height:104px;" bindlongtap=&q ...

  3. Git,GitHub以及GitLab的区别

    Git - 版本控制工具 Github - 一个网站,提供给用户空间创建git仓储,保存用户的一些数据文档或者代码等 GitLab - 基于Git的项目管理软件 Git分布式版本控制系统 Git是一款 ...

  4. xargs在linux中的使用详解-乾颐堂

    xargs在linux中是个很有用的命令,它经常和其他命令组合起来使用,非常的灵活. xargs是给命令传递参数的一个过滤器,也是组合多个命令的一个工具.它把一个数据流分割为一些足够小的块,以方便过滤 ...

  5. css确定取消 悬浮底部样式 和 金额 后缀

    .blockquote-bottom { width: 100%; position: fixed; margin: 0; bottom: 0; left: 0; text-align: center ...

  6. Yii项目开发总结

    学习Yii很久了,一直做的是小案例,自以为学的还不错.直到最近用Yii开发了一个非常简单的CMS,一路下来,磕磕绊绊,才知自己不足.加上最近正学习着偏架构方面的知识.特此总结一下.小白经验,大神轻拍, ...

  7. sql server锁检测

    有时候系统运行老感觉效率不高,并且有时候sql还有超时的报错,但是并发量并不高.通过排查定位sql是否有执行效率问题 -- 开事务, 以保持锁 BEGIN TRAN -- 更新 update tabl ...

  8. 设计模式16:Mediator 中介者模式(行为型模式)

    Mediator 中介者模式(行为型模式) 依赖关系的转化 动机(Motivation) 在软件构建过程中,经常出现多个对象互相关联交互的情况,对象之间经常会维持一种复杂的应用关系,如果遇到一些需求的 ...

  9. Linq实战 之 Linq to Sql及Entity Framework操作详解

    Linq实战 之 Linq to Sql及Entity Framework操作详解 一:linq to db的框架 1. linq to sql 2. linq to ado.net entity f ...

  10. java-03 变量与运算符

    1.java中的变量与常量 1.1 变量的定义: 变量,顾名思义就是会变的量,这种思想来源于数学,指的是一个不确定的量或者随时会改变的量. 在我们进行编程的过程中,有一些东西是会随着实际情况而发生变化 ...