最近在公司尝试将测试环境 docker 化,由于组件比较多,考虑引入容器编排方案。首先尝试使用 docker-compose 来管理各个组件实例。可以跑通基本逻辑,但是目前没有服务发现框架,只能使用 docker 内置网络中的 DNS 发现其它服务,这限定了测试环境只能跑在单机环境上,时间久了各种 OOM。最近看到 docker 新版本附带的 swarm mode,尝试搭建了一套多机 docker 环境,感觉很满足当前的需求,并且对代码基本零侵入。简单的记录了一下搭建过程以及一些注意事项。
docker swarm init
创建 swarm 集群,命令会返回加入集群的命令 Swarm initialized: current node (c8dzd8xek2c9csoxj27ycl1nh) is now a manager. To add a worker to this swarm, run the following command: docker swarm join / --token SWMTKN-1-07bc8loetz13sy5eqv2t1uycqfr9dqabsd7x08gr22w7gj79fc-eiz5ljflasv65rnoq36aj2mfc / 192.168.65.2:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
docker swarm join-token worker
查询 docker swarm join / --token SWMTKN-1-07bc8loetz13sy5eqv2t1uycqfr9dqabsd7x08gr22w7gj79fc-eiz5ljflasv65rnoq36aj2mfc / 192.168.65.2:2377
docker info
可以看到 swarm 集群的信息 Swarm: active NodeID: c8dzd8xek2c9csoxj27ycl1nh Is Manager: true ClusterID: cj75fozp5effsiyuuq2dixv95 Managers: 1 Nodes: 2 Orchestration: Task History Retention Limit: 5 Raft: Snapshot Interval: 10000 Heartbeat Tick: 1 Election Tick: 3 Dispatcher: Heartbeat Period: 5 seconds CA Configuration: Expiry Duration: 3 months Node Address: 192.168.65.2
docker swarm leave
可以让当前节点离开集群,如果是管理节点,需要增加 --force
参数 docker service create --replicas 1 --name redis docker-registry-cn.easemob.com/redis
创建 redis 服务, replicas
参数指定该服务中的 task 数量 docker login
,然后创建服务时,增加 --with-registry-auth
参数将认证信息发送到 worker 节点 docker service ls
查看所有服务状态 ID NAME REPLICAS IMAGE COMMAND 0nqfp11n2xgb redis 1/1 docker-registry-cn.easemob.com/redis
docker service ps redis
查看 redis 服务状态 ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR 3qpkmxptn8o336h161183a0vz redis.1 docker-registry-cn.easemob.com/redis moby Running Running 17 hours ago
docker service update redis
更新服务。例如可以用 docker service update redis --publish-add 6379:6379
发布 redis 服务到 swarm 集群 6379 端口上(也可以在创建服务时使用 –publish 参数发布),在 swarm 任意节点上运行 redis-cli
都可以连接到 redis 服务 docker service rm redis
可以删除服务 ➜ ~ docker service update --publish-add 6379:6379 redis1 redis1 ➜ ~ telnet localhost 6379 Trying ::1... Connected to localhost. Escape character is '^]'. set test aaa +OK
--network
参数连接到 overlay 网络上。通过内建的 DNS 服务,可以通过 service name 解析出 task IP ➜ ~ docker network create --driver overlay --subnet 10.0.10.0/24 sandbox e7q4c68ybbw7xhrkb0at47k00 ➜ ~ docker service create --with-registry-auth --replicas 1 --network sandbox --name redis1 docker-registry-cn.easemob.com/redis 0dfqszxp925id4ma9blolyjmz ➜ ~ docker service create --with-registry-auth --replicas 1 --network sandbox --name redis2 docker-registry-cn.easemob.com/redis c3khd0snpu13ixx8popuoludx ➜ ~ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4c92e01d25fd docker-registry-cn.easemob.com/redis:latest "/entrypoint.sh redis" 12 seconds ago Up 9 seconds 6379/tcp redis2.1.4qbw5c0hawat5rr50hgzpxj7l c60b4659e768 docker-registry-cn.easemob.com/redis:latest "/entrypoint.sh redis" 6 minutes ago Up 6 minutes 6379/tcp redis1.1.4pvn93a6i2n5teou41mddmlxr ➜ ~ docker exec -it c60b4659e768 /bin/bash root@c60b4659e768:/data# ping redis2 PING redis2 (10.0.10.4): 56 data bytes 64 bytes from 10.0.10.4: icmp_seq=0 ttl=64 time=0.109 ms
Have fun