Swarm 笔记

By | 2021年12月30日

概念

节点

运行 Docker 的主机可以主动初始化一个 Swarm 集群或者加入一个已存在的 Swarm 集群,这样这个运行 Docker 的主机就成为一个 Swarm 集群的节点 (node) 。
节点分为管理 (manager) 节点和工作 (worker) 节点。
docker swarm 命令基本只能在管理节点执行(节点退出集群命令 docker swarm leave 可以在工作节点执行)。
一个 Swarm 集群可以有多个管理节点,但只有一个管理节点可以成为 leader,leader 通过 raft 协议实现。
工作节点是任务执行节点,管理节点将服务 (service) 下发至工作节点执行。管理节点默认也作为工作节点。你也可以通过配置让服务只运行在管理节点。

服务和任务

Task 是 Swarm 中的最小的调度单位,目前来说就是一个单一的容器。
Service 是指一组 Task 的集合,Service 定义了任务的属性。服务有两种模式:
1)replicated services 按照一定规则在各个工作节点上运行指定个数的任务。
2)global services 每个工作节点上运行一个任务
两种模式通过 docker service create 的 –mode 参数指定。

常用命令

docker swarm init --advertise-addr <MANAGER-IP>  #在管理节点初始化一个 Swarm 集群
docker node ls                  #查看集群
docker node rm iue              #移除指定节点
docker service ls               #查看当前 Swarm 集群运行的服务
docker service ps nginx         #查看nginx服务的详情(加 --no-trunc 可显示全error信息等字段)
docker service logs -f nginx    #查看nginx服务的日志
docker service rm nginx         #从Swarm集群移除nginx服务
docker service update --update-parallelism 1 --update-delay 10s falstorm_fallogstash   #更新服务
docker service inspect 8se

docker swarm join-token [OPTIONS] (worker|manager)            #显示join token
docker swarm join-token manager                               #显示manager join token
docker swarm leave                                            #在worker节点上执行此命令,此worker从swarm中移除 docker swarm join --token SWMTKN-1-2maijudaypf5cg1y7cmo7yzt5cpapjfbc96bj5mxeogmjyuf1y-avqwv24g0pw7odenasc4jehu7 192.168.1.188:2377

docker stack ls
docker stack rm test

# swarm 中重启 kafka 容器(不能用 restart,否则会导致相同的容器多出来一个)
docker stop $(docker container ls | grep 'kafka' | awk '{print $1}')

使用 compose 文件

使用 docker service create 一次只能部署一个服务,使用 docker-compose.yml 我们可以一次启动多个关联的服务。
经测试,如果手工删除了 volumn 映射的目录,重启 swarm 的 service 是不会成功的,需要先重启docker才行,如:service docker restart
这里,我仅贴出一些工作中用到的compose.yml文件供参考。出于保密这些文件仅对一些敏感字眼作了修改。

falpolicy-compose.yml

version: '3.6'

services:
  falpolicy:
    image: 192.168.1.166:8083/centos7-jdk8-tomcat8-tools-falpos
    volumes:
      - "falhome:/falhome"	
    ports:
      - "8080:8080"
      - "8443:8443"
      - "2331:2331"
    networks:
      - falnet      
    depends_on:
      - falmongo
      - falsolr
    deploy:
      placement:
        constraints:
          - node.role == manager

  falsolr:
    image: 192.168.1.166:8083/solr-falsec
    volumes:
      - "solr_home:/solr_home"
    expose:
      - "8983"	
    ports:
      - "8983:8983"
    depends_on:
      - falmongo
    networks:
      - falnet
    deploy:
      placement:
        constraints:
          - node.role == manager
          
  falmongo:
    image: 192.168.1.166:8083/mongo-falsec
    volumes:
      - "mongo-data:/data/db"
      - "mongo-config:/data/configdb"
    ports:
      - "27017:27017"
    networks:
      - falnet
    deploy:
      placement:
        constraints:
          - node.role == manager

  falinfluxdb:
    image: 192.168.1.166:8083/influxdb-falsec
    volumes:
      - "influxdb:/var/lib/influxdb"
    ports:
      - "8086:8086"
    networks:
      - falnet
    deploy:
      placement:
        constraints:
          - node.role == manager
          
volumes:
  mongo-data:
  mongo-config:
  solr_home:
  falhome:
  influxdb:
  
networks:
  falnet:
    driver: overlay
    attachable: true

falstorm-compose.yml

version: '3.6'

services:
  falzookeeper:
    image: 192.168.1.166:8083/zookeeper-falsec
    volumes:
      - "zoodata:/data"
      - "zoodatalog:/datalog"
      - "zoologs:/logs"
    networks:
      - falnet
    deploy:
      placement:
        constraints:
          - node.role == worker

  falkafka:
    image: 192.168.1.166:8083/kafka-falsec
    volumes:
      - "kafka:/kafka"
    depends_on:
      - falzookeeper
    networks:
      - falnet
    ports:
      - "9092:9092"    
    deploy:
      placement:
        constraints:
          - node.role == worker
          
  fallogstash:
    image: 192.168.1.166:8083/logstash-falsec
    volumes:
      - "logstash:/logstash"
    depends_on:
      - falzookeeper
      - falkafka
    networks:
      - logstash
#    environment:
      #default is 127.0.0.1
#      KAFKA_SERVER: "127.0.0.1"
#      KAFKA_PORT: "9092"
    deploy:
      placement:
        constraints:
          - node.role == worker
          
  falstorm:
    image: 192.168.1.166:8083/storm-falsec
    volumes:
      - "storm-data:/data"
      - "storm-logs:/logs"
#      - "storm-falhome:/falhome"
    depends_on:
      - falzookeeper
      - falinfluxdb
      - falkafka
      - fallogstash
      - falmongo
    networks:
      - falnet
#    command: storm jar /falhome/topology/falstorm-log.jar com.falsec.storm.FalStormLogApplication
    deploy:
      placement:
        constraints:
          - node.role == worker

volumes:
  influxdb:
  zoodata:
  zoodatalog:
  zoologs:
  kafka:
  logstash:
  storm-data:
  storm-logs:
  
networks:
  falnet:
    external: true
    name: falpolicy_falnet
  #need to expose the 514 port directly on the host
  #otherwise the source ip will be docker bridge ip
  logstash:
    external: true
    name: host
  • external :If set to true, specifies that this volume has been created outside of Compose. docker-compose up does not attempt to create it, and raises an error if it doesn’t exist.

docker stack deploy 尝试 pull 镜像导致一起起不来

现象:容器起不来,查看日志没有输出任何日志。

overlay 网络

介绍

overlay 网络驱动程序在多个 Docker 守护进程主机之间创建一个分布式网络。这个网络在允许容器连接并进行安全通信的主机专用网络之上(overlay 覆盖在上面)。Docker 透明地处理每个 Docker 守护进程与目标容器之间的数据包的路由。
我们可以将 swarm 服务和独立容器连接到同一个 overlay 网络。当初始化swarm集群或将一个Docker主机加入已经存在的swarm集群时,Docker主机上会创建两个新网络:

  • 一个称为 ingress 的 overlay 网络,用来处理与 swarm 服务相关的控制和数据流。当创建的 swarm 服务没有连接到用户自定义的 overlay 网络时,这个服务会默认连接到 ingress 网络。
  • 一个称为 docker_gwbridge 的bridge 网络,用来将单个的 Docker 守护进程连接到 swarm 中的其他守护进程。

连接到同一 overlay 网络的 swarm 服务可以有效地将所有端口暴露给对方。要使端口可以在服务之外访问,必须在 Surround with spacesdocker service update命令中使用 -p 标志发布该端口,如 -p 8080:80。

要创建可以用于 swarm 服务和独立容器跟其他 Docker 守护进程中运行的独立容器通信的 overlay 网络,需要添加 –attachable 标志docker network create -d overlay --attachable my-attachable-overlay

防火墙端口开放

当我们使用swarm overlay网络在多台服务器上部署service,如果服务器启用了防火墙(firewalld、iptables等),那么需要开启下面几个端口才能访问overlay网络上的每个主机:

  • TCP 端口 2377:用于集群管理通信
  • TCP 和 UDP 端口 7946:用于节点之间通信
  • UDP 端口 4789:overlay 网络流量

以firewalld为例,开放端口命令如下

sudo firewall-cmd --zone=public --add-port=2377/tcp --permanent
sudo firewall-cmd --zone=public --add-port=7946/tcp --permanent
sudo firewall-cmd --zone=public --add-port=7946/udp --permanent
sudo firewall-cmd --zone=public --add-port=4789/udp --permanent
sudo firewall-cmd --reload

部署伸缩

当业务处于高峰期时,我们需要扩展服务运行的容器数量。
docker service scale nginx=5
当业务平稳时,我们需要减少服务运行的容器数量。
docker service scale nginx=2

实践

Allow HTTP connection to falnas private docker registry

  • Turn off https for docker

Edit the “daemon.json” file, whose default location is /etc/docker/daemon.json on Linux or C:\ProgramData\docker\config\daemon.json on Windows Server.

{
    "insecure-registries" : ["192.168.1.166:8083"]
}
  • Restart Docker for the changes to take effect.systemctl restart docker

Docker login to 192.168.1.166:8083

#用户名docker   密码china.123
docker login http://192.168.1.166:8083

Create docker swarm

docker swarm init --advertise-addr <MANAGER-IP>
如果要将其他机器上的worker节点加入进来,可以在那台机器上执行此命令:
docker swarm join --token SWMTKN-1-2maijudaypf5cg1y7cmo7yzt5cpapjfbc96bj5mxeogmjyuf1y-avqwv24g0pw7odenasc4jehu7 192.168.1.200:2377
注意:必须开放相关防火墙端口,开发时可以先禁用 firewalld,否则会报错:Error while dialing dial tcp xxx.xxx.xxx.xxx: connect: no route to host。一切顺利的话,执行 docker node ls查看新加入的node节点的STATUS为”Ready”并且MANAGER STATUS为空,不能是Reachable,说明可以使用了。

参考文档:https://docs.docker.com/engine/swarm/swarm-tutorial/create-swarm

Run the following compose file

docker stack deploy -c /home/admin/dev/compose/test-compose.yml --with-registry-auth falpolicy
docker stack deploy -c /home/admin/dev/compose/falstorm-compose.yml --with-registry-auth falstorm

注:使用 –with-registry-auth 需要先 “docker login http://192.168.1.166:8083”。
如果修改了 falstorm-compose.yml,目前是先执行docker stack rm falstorm,再重启部署的。

运维人员在客户现场部署时,需要将application.properites文件中127.0.0.1地址改为服务器地址,以便外部服务器可以访问,文件位于
/var/lib/docker/volumes/falpolicy_falhome/_data/falpolicy/config/application.properties,然后修改falpolicy.server.access.host键的值为 host 主机的IP即可。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注