相关文章:Docker 三剑客之 Docker Swarm

这一篇主要是对 Docker Swarm 的完善,增加基于 overlay 组网通信,以便 Docker 容器可以跨主机访问。

不同主机间的容器之间通信方式,大概有三种:

  • 使用端口映射:直接把容器的服务端口映射到主机上,主机直接通过映射出来的端口通信。
  • 把容器放到主机所在的网段:修改 docker 的 ip 分配网段和主机一致,还要修改主机的网络结构。
  • 第三方项目:flannel,weave 或者 pipework 等,这些方案一般都是通过 SDN 搭建 overlay 网络达到容器通信的。

在使用 overlay 组网通信之前,我们先安装 Docker,以及 Docker Machine(Linux 下):

$ sudo curl -L https://github.com/docker/machine/releases/download/v0.13.0/docker-machine-`uname -s`-`uname -m` > /usr/local/bin/docker-machine
$ sudo chmod +x /usr/local/bin/docker-machine

使用脚本一键安装(Docker 镜像加速地址可以更换):

#!/bin/bash

set -e

create_kv() {
echo Creating kvstore machine.
docker-machine create -d virtualbox \
--engine-opt="registry-mirror=https://kvo9moak.mirror.aliyuncs.com" \
kvstore
docker $(docker-machine config kvstore) run -d \
-p "8500:8500" \
progrium/consul --server -bootstrap-expect 1
} create_master() {
echo Creating cluster master
kvip=$(docker-machine ip kvstore) docker-machine create -d virtualbox \
--swarm --swarm-master \
--swarm-discovery="consul://${kvip}:8500" \
--engine-opt="cluster-store=consul://${kvip}:8500" \
--engine-opt="cluster-advertise=eth1:2376" \
--engine-opt="registry-mirror=https://kvo9moak.mirror.aliyuncs.com" \
swarm-manager
} create_nodes(){
kvip=$(docker-machine ip kvstore)
echo Creating cluster nodes
for i in 1 2; do
docker-machine create -d virtualbox \
--swarm \
--swarm-discovery="consul://${kvip}:8500" \
--engine-opt="cluster-store=consul://${kvip}:8500" \
--engine-opt="cluster-advertise=eth1:2376" \
--engine-opt="registry-mirror=https://kvo9moak.mirror.aliyuncs.com" \
swarm-node${i}
done
} teardown(){
docker-machine rm kvstore -y
docker-machine rm -y swarm-manager
for i in 1 2; do
docker-machine rm -y swarm-node${i}
done
} case $1 in
up)
create_kv
create_master
create_nodes
;;
down)
teardown
;;
*)
echo "Unknow command..."
exit 1
;;
esac

运行./cluster.sh up,就能自动生成四台主机:

  • 一台 kvstore 运行 consul 服务。
  • 一台 swarm master 机器,运行 swarm manager 服务。
  • 两台 swarm node 机器,都是运行了 swarm node 服务和 docker daemon 服务。

查看四台主机的具体信息:

$ docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
kvstore - virtualbox Running tcp://192.168.99.100:2376 v18.03.1-ce
swarm-manager * (swarm) virtualbox Running tcp://192.168.99.101:2376 swarm-manager (master) v18.03.1-ce
swarm-node1 - virtualbox Running tcp://192.168.99.102:2376 swarm-manager v18.03.1-ce
swarm-node2 - virtualbox Running tcp://192.168.99.103:2376 swarm-manager v18.03.1-ce

接下来验证集群是否正确安装?在主机上运行下面命令(主机,不是 Docker 主机):

$ eval $(docker-machine env --swarm swarm-manager)
$ docker info
Containers: 6
Running: 6
Paused: 0
Stopped: 0
Images: 5
Server Version: swarm/1.2.8
Role: primary
Strategy: spread
Filters: health, port, containerslots, dependency, affinity, constraint, whitelist
Nodes: 3
swarm-manager: 192.168.99.101:2376
└ ID: K6WX:ZYFT:UEHA:KM66:BYHD:ROBF:Z5KG:UHNE:U37V:4KX2:S5SV:YSCA|192.168.99.101:2376
└ Status: Healthy
└ Containers: 2 (2 Running, 0 Paused, 0 Stopped)
└ Reserved CPUs: 0 / 1
└ Reserved Memory: 0 B / 1.021 GiB
└ Labels: kernelversion=4.9.93-boot2docker, operatingsystem=Boot2Docker 18.03.1-ce (TCL 8.2.1); HEAD : cb77972 - Thu Apr 26 16:40:36 UTC 2018, ostype=linux, provider=virtualbox, storagedriver=aufs
└ UpdatedAt: 2018-05-08T10:20:39Z
└ ServerVersion: 18.03.1-ce
swarm-node1: 192.168.99.102:2376
└ ID: RPRC:AVBX:7CBJ:HUTI:HI3B:RI6B:QI6O:M2UQ:ZT2I:HZ6J:33BL:HY76|192.168.99.102:2376
└ Status: Healthy
└ Containers: 2 (2 Running, 0 Paused, 0 Stopped)
└ Reserved CPUs: 0 / 1
└ Reserved Memory: 0 B / 1.021 GiB
└ Labels: kernelversion=4.9.93-boot2docker, operatingsystem=Boot2Docker 18.03.1-ce (TCL 8.2.1); HEAD : cb77972 - Thu Apr 26 16:40:36 UTC 2018, ostype=linux, provider=virtualbox, storagedriver=aufs
└ UpdatedAt: 2018-05-08T10:21:09Z
└ ServerVersion: 18.03.1-ce
swarm-node2: 192.168.99.103:2376
└ ID: MKQ2:Y7EO:CKOJ:MGFH:B77S:3EWX:7YJT:2MBQ:CJSN:XENJ:BSKO:RAZP|192.168.99.103:2376
└ Status: Healthy
└ Containers: 2 (2 Running, 0 Paused, 0 Stopped)
└ Reserved CPUs: 0 / 1
└ Reserved Memory: 0 B / 1.021 GiB
└ Labels: kernelversion=4.9.93-boot2docker, operatingsystem=Boot2Docker 18.03.1-ce (TCL 8.2.1); HEAD : cb77972 - Thu Apr 26 16:40:36 UTC 2018, ostype=linux, provider=virtualbox, storagedriver=aufs
└ UpdatedAt: 2018-05-08T10:21:06Z
└ ServerVersion: 18.03.1-ce
Plugins:
Volume:
Network:
Log:
Swarm:
NodeID:
Is Manager: false
Node Address:
Kernel Version: 4.9.93-boot2docker
Operating System: linux
Architecture: amd64
CPUs: 3
Total Memory: 3.063GiB
Name: 85be09a37044
Docker Root Dir:
Debug Mode (client): false
Debug Mode (server): false
Experimental: false
Live Restore Enabled: false WARNING: No kernel memory limit support

可以看到集群的具体信息。

然后,接下来在主机上创建 overlay 网络,创建命令:

$ docker network create -d overlay net1
d6a8a22298485a044b19fcbb62033ff1b4c3d4bd6a8a2229848

然后我们查看刚创建名称为net1的 overlay 网络,命令:

$ docker network ls
NETWORK ID NAME DRIVER SCOPE
d6a8a2229848 net1 overlay global
9c7f0e793838 swarm-manager/bridge bridge local
93787d9ba7ed swarm-manager/host host local
72fd1e63889e swarm-manager/none null local
c73e00c4c76c swarm-node1/bridge bridge local
95983d8f1ef1 swarm-node1/docker_gwbridge bridge local
a8a569d55cc9 swarm-node1/host host local
e7fa8403b226 swarm-node1/none null local
7f1d219b5c08 swarm-node2/bridge bridge local
e7463ae8c579 swarm-node2/docker_gwbridge bridge local
9a1f0d2bbdf5 swarm-node2/host host local
bea626348d6d swarm-node2/none null local

接下来,我们创建两个容器(主机上执行,使用 Docker Swarm 很方便),测试使用net1网络,是否可以相互访问,创建命令:

$ docker run -d --net=net1 --name=c1 -e constraint:node==swarm-node1 busybox top
dab080b33e76af0e4c71c9365a6e57b2191b7aacd4f715ca11481403eccce12a
$ docker run -d --net=net1 --name=c2 -e constraint:node==swarm-node2 busybox top
583fde42182a7e8f27527d5c55163a32102dba566ebe1f13d1951ac214849c8d

查看刚创建的容器运行情况:

$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
583fde42182a busybox "top" 3 seconds ago Up 2 seconds swarm-node2/c2
dab080b33e76 busybox "top" 18 seconds ago Up 18 seconds swarm-node1/c1

接下来,我们查看net1网络的具体详情:

$ docker network inspect net1
[
{
"Name": "net1",
"Id": "d6a8a2229848d40ce446f8f850a0e713a6c88a9b43583cc463f437f306724f28",
"Created": "2018-05-08T09:21:42.408840755Z",
"Scope": "global",
"Driver": "overlay",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "10.0.0.0/24",
"Gateway": "10.0.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"583fde42182a7e8f27527d5c55163a32102dba566ebe1f13d1951ac214849c8d": {
"Name": "c2",
"EndpointID": "b7fcb0039ab21ff06b36ef9ba008c324fabf24badfe45dfa6a30db6763716962",
"MacAddress": "",
"IPv4Address": "10.0.0.3/24",
"IPv6Address": ""
},
"dab080b33e76af0e4c71c9365a6e57b2191b7aacd4f715ca11481403eccce12a": {
"Name": "c1",
"EndpointID": "8a80a83230edfdd9921357f08130fa19ef0b917bc4426aa49cb8083af9edb7f6",
"MacAddress": "",
"IPv4Address": "10.0.0.2/24",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]

可以看到,我们刚刚创建的两个容器信息(包含 IP 地址),也在里面。

然后我们测试下两个容器是否可以相互访问(直接 ping 容器名称,也可以访问):

$ docker exec c1 ping -c 3 10.0.0.3
PING 10.0.0.3 (10.0.0.3): 56 data bytes
64 bytes from 10.0.0.3: seq=0 ttl=64 time=0.903 ms
64 bytes from 10.0.0.3: seq=1 ttl=64 time=0.668 ms
64 bytes from 10.0.0.3: seq=2 ttl=64 time=0.754 ms --- 10.0.0.3 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.668/0.775/0.903 ms $ docker exec c2 ping -c 3 10.0.0.2
PING 10.0.0.2 (10.0.0.2): 56 data bytes
64 bytes from 10.0.0.2: seq=0 ttl=64 time=0.827 ms
64 bytes from 10.0.0.2: seq=1 ttl=64 time=0.702 ms
64 bytes from 10.0.0.2: seq=2 ttl=64 time=0.676 ms --- 10.0.0.2 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.676/0.735/0.827 ms $ docker exec c2 ping -c 3 c1
PING c1 (10.0.0.2): 56 data bytes
64 bytes from 10.0.0.2: seq=0 ttl=64 time=1.358 ms
64 bytes from 10.0.0.2: seq=1 ttl=64 time=0.663 ms
64 bytes from 10.0.0.2: seq=2 ttl=64 time=0.761 ms --- c1 ping statistics ---
3 packets transmitted, 3 packets received, 0% packet loss
round-trip min/avg/max = 0.663/0.927/1.358 ms

另附 Docker Swarm 架构图:

参考资料:

Docker 三剑客之 Docker Swarm(基于 overlay 组网通信)的更多相关文章

  1. Docker 三剑客之 Docker Swarm

    上一篇:Docker 三剑客之 Docker Compose 阅读目录: Docker Machine 创建 Docker 主机 Docker Swarm 配置集群节点 Docker Service ...

  2. Docker(五):Docker 三剑客之 Docker Machine

    上篇文章Docker(四):Docker 三剑客之 Docker Compose介绍了 Docker Compose,这篇文章我们来了解 Docker Machine . Docker Machine ...

  3. Docker三剑客之Docker Swarm

    一.什么是Docker Swarm Swarm是Docker公司推出的用来管理docker集群的平台,几乎全部用GO语言来完成的开发的,代码开源在https://github.com/docker/s ...

  4. docker——三剑客之Docker swarm

    Docker Swarm是Docker官方的三剑客项目之一,提供Docker容器集群服务,是Docker官方对容器云生态进行支持的核心方案.使用它,用户可以将多个Docker主机封装为单个大型的虚拟D ...

  5. Docker(六):Docker 三剑客之 Docker Swarm

    实践中会发现,生产环境中使用单个 Docker 节点是远远不够的,搭建 Docker 集群势在必行.然而,面对 Kubernetes, Mesos 以及 Swarm 等众多容器集群系统,我们该如何选择 ...

  6. Docker三剑客之Docker Compose

    一.什么是Docker Compose Compose 项目是Docker官方的开源项目,负责实现Docker容器集群的快速编排,开源代码在https://github.com/docker/comp ...

  7. Docker三剑客之Docker Machine

    一.什么是Docker Machine Docker Machine 是Docker官方编排项目之一,使用go语言编写的,使用不同引擎在多种平台上快速的安装Docker环境,开源地址:https:// ...

  8. docker——三剑客之Docker Machine

    Docker Machine是Docker官方三剑客项目之一,负责使用Docker的第一步,在多种平台上快速安装Docker环境.它支持多种平台,让用户在很短时间内搭建一套Docker主机集群. Ma ...

  9. Docker(四):Docker 三剑客之 Docker Compose

    前两篇文章我们介绍了 Dockerfile 的使用Docker(二):Dockerfile 使用介绍,我们知道使用一个 Dockerfile 模板文件可以定义一个单独的应用容器,如果需要定义多个容器就 ...

随机推荐

  1. Linux Debugging(七): 使用反汇编理解动态库函数调用方式GOT/PLT

    本文主要讲解动态库函数的地址是如何在运行时被定位的.首先介绍一下PIC和Relocatable的动态库的区别.然后讲解一下GOT和PLT的理论知识.GOT是Global Offset Table,是保 ...

  2. xml解析之使用dom4j的api对xml文件进行CRUD(二)

    在使用dom4j的api对xml文件进行CRUD(一)见博客http://blog.csdn.net/qq_32059827/article/details/51524330的基础上,再对做一次练习. ...

  3. Java 8新特性探究(二)类型注解和重复注解

    本文将介绍java 8的第二个特性:类型注解. 注解大家都知道,从java5开始加入这一特性,发展到现在已然是遍地开花,在很多框架中得到了广泛的使用,用来简化程序中的配置.那充满争议的类型注解究竟是什 ...

  4. C语言中,#include <>和#include ""的区别和注意点

    C语言中包含文件有两种包含符号,一个是<>尖括号,另一个是""双引号.那么这两个有什么区别呢? 首先在本地建立一个空文件,命名为stdio.h. 然后再建立一个C文件, ...

  5. 江湖问题研究-- intent传递有没有大小限制,是多少?

    出门一步,便是江湖,江湖上有许多流言. 比如这条: intent传递是有大小限制的,具体在40KB左右. 当然也有传言说是1M左右. 数百头母驴为何半夜惨叫? 小卖部安全套为何屡遭黑手? 女生宿舍内裤 ...

  6. 让Oracle 大小写敏感 表名 字段名 对像名

    一.解决方案 1.在表名.字段名.对象名上加上双引号,即可实现让oracle大小写区分. 2.但是这又引起了另一个问题:在数据库操作中,sql语句中相应的表名.字段名.对象名上一定要加双引号. 解决办 ...

  7. Ceres-Solver库入门

    示例1:求极值 首先我们以Ceres库官网中的Hello World例子来进行说明.这里例子的目的是为了计算方程取得最小值时x的值.从这个方程很容易看出来当x=10时,f(x)取得最小值0.这个方程虽 ...

  8. 【一天一道LeetCode】#35. Search Insert Position

    一天一道LeetCode系列 (一)题目 Given a sorted array and a target value, return the index if the target is foun ...

  9. XWork容器的存储结构

    我们可以看到,在Container的默认实现,ContainerImpl中有两个实例变量.factoris和factoryNamesByType. 对象制造工厂 class ContainerImpl ...

  10. Android下Json数据解析

    如从网络获取JSON 则需要创建一个工具类,该类返回一个字符串为JSON文本 package com.example.jsonapp; import java.io.InputStreamReader ...