Docker网络解决方案-Calico部署记录

本文涉及的产品
公网NAT网关,每月750个小时 15CU
简介:

Calico简单简介

1
2
Calico是一个纯三层的协议,为OpenStack虚机和Docker容器提供多主机间通信。Calico不使用重叠网络比如flannel和libnetwork重叠网络驱动,
它是一个纯三层的方法,使用虚拟路由代替虚拟交换,每一台虚拟路由通过BGP协议传播可达信息(路由)到剩余数据中心。

Calico 架构

1
Calico 是一个三层的数据中心网络方案,而且方便集成 OpenStack 这种 IaaS 云架构,能够提供高效可控的 VM、容器、裸机之间的通信。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
结合上面这张图,我们来过一遍 Calico 的核心组件:
 
Felix,Calico agent,跑在每台需要运行 workload 的节点上,主要负责配置路由及 ACLs 等信息来确保 endpoint 的连通状态;
 
etcd,分布式键值存储,主要负责网络元数据一致性,确保 Calico 网络状态的准确性;
 
BGP Client(BIRD), 主要负责把 Felix 写入 kernel 的路由信息分发到当前 Calico 网络,确保 workload 间的通信的有效性;
 
BGP Route Reflector(BIRD), 大规模部署时使用,摒弃所有节点互联的 mesh 模式,通过一个或者多个BGP Route Reflector来完成集中式的路由分发;
 
通过将整个互联网的可扩展 IP 网络原则压缩到数据中心级别,Calico 在每一个计算节点利用Linux kernel实现了一个高效的vRouter来负责数据转发而每个vRouter通过BGP
协议负责把自己上运行的 workload 的路由信息像整个 Calico 网络内传播 - 小规模部署可以直接互联,大规模下可通过指定的
BGP route reflector 来完成。
 
这样保证最终所有的 workload 之间的数据流量都是通过 IP 包的方式完成互联的。

Calico原理

1
Calico 节点组网可以直接利用数据中心的网络结构(支持 L2 或者 L3),不需要额外的 NAT,隧道或者 VXLAN overlay network。

1
2
如上图所示,这样保证这个方案的简单可控,而且没有封包解包,节约 CPU 计算资源的同时,提高了整个网络的性能。
此外,Calico 基于 iptables 还提供了丰富而灵活的网络 policy, 保证通过各个节点上的 ACLs 来提供 workload 的多租户隔离、安全组以及其他可达性限制等功能。

calico网络通信模型

1
2
3
4
5
calico是纯三层的SDN 实现,它基于BPG 协议和Linux自身的路由转发机制,不依赖特殊硬件,容器通信也不依赖iptables NAT或Tunnel 等技术。
能够方便的部署在物理服务器、虚拟机(如 OpenStack)或者容器环境下。同时calico自带的基于iptables的ACL管理组件非常灵活,能够满足比较复杂的安全隔离需求。
 
在主机网络拓扑的组织上,calico的理念与weave类似,都是在主机上启动虚拟机路由器,将每个主机作为路由器使用,组成互联互通的网络拓扑。当安装了calico的主机组成集群后,
其拓扑如下图所示:

1
2
3
4
每个主机上都部署了calico /node 作为虚拟路由器,并且可以通过calico将宿主机组织成任意的拓扑集群。当集群中的容器需要与外界通信时,
就可以通过BGP协议将网关物理路由器加入到集群中,使外界可以直接访问容器IP,而不需要做任何NAT之类的复杂操作。
 
当容器通过calico进行跨主机通信时,其网络通信模型如下图所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
从上图可以看出,当容器创建时,calico为容器生成veth pair,一端作为容器网卡加入到容器的网络命名空间,并设置IP和掩码,一端直接暴露在宿主机上,
并通过设置路由规则,将容器IP暴露到宿主机的通信路由上。于此同时,calico为每个主机分配了一段子网作为容器可分配的IP范围,这样就可以根据子网的
CIDR为每个主机生成比较固定的路由规则。
 
当容器需要跨主机通信时,主要经过下面的简单步骤:
1)容器流量通过veth pair到达宿主机的网络命名空间上。
2)根据容器要访问的IP所在的子网CIDR和主机上的路由规则,找到下一跳要到达的宿主机IP。
3)流量到达下一跳的宿主机后,根据当前宿主机上的路由规则,直接到达对端容器的veth pair插在宿主机的一端,最终进入容器。
 
从上面的通信过程来看,跨主机通信时,整个通信路径完全没有使用NAT或者UDP封装,性能上的损耗确实比较低。但正式由于calico的通信机制是完全基于三层的,这种机制也带来了一些缺陷,例如:
1)calico目前只支持TCP、UDP、ICMP、ICMPv6协议,如果使用其他四层协议(例如NetBIOS协议),建议使用weave、原生overlay等其他overlay网络实现。
2)基于三层实现通信,在二层上没有任何加密包装,因此只能在私有的可靠网络上使用。
3)流量隔离基于iptables实现,并且从etcd中获取需要生成的隔离规则,有一些性能上的隐患。

Calico实现Docker跨主机容器通信的示例配置说明

1)环境准备

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
机器信息
node-1:182.48.115.233    centos7.2    安装Docker、etcd、calicoctl
node-2:182.48.115.236    centos7.2    安装Docker、etcd、calicoctl
node-3:182.48.115.239    centos7.2    安装Docker、etcd、calicoctl
 
设置三台机器的主机名
node-1
[root@node-1 ~] # hostnamectl --static set-hostname  node-1
 
node-2
[root@node-2 ~] # hostnamectl --static set-hostname  node-2
 
node-3
[root@node-3 ~] # hostnamectl --static set-hostname  node-3
 
关闭三台主机的防火墙。若开启iptables防火墙,则需要打开2380端口通信。
[root@node-1 ~] # systemctl disable firewalld.service
[root@node-1 ~] # systemctl stop firewalld.service
 
在三台机器上都要设置hosts,均执行如下命令:
[root@node-1 ~] # vim /etc/hosts
182.48.115.233    node-1
182.48.115.236    node-2
182.48.115.239    node-3

2)安装docker环境

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
三个节点都要安装docker
[root@node-1 ~] # yum install -y docker
[root@node-1 ~] # systemctl start docker
[root@node-1 ~] # docker pull nginx
[root@node-1 ~] # docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
docker.io /nginx      latest              3448f27c273f        6 days ago          109.4 MB
  
在三个节点上配置docker网桥,三个网桥指定为不同的网络,网络配置细节如下:
node-1节点,Docker网桥网络指定为192.168.10.1 /24
[root@node-1 ~] # systemctl stop docker
[root@node-1 ~] # ip link set dev docker0 down
[root@node-1 ~] # brctl delbr docker0
[root@node-1 ~] # brctl addbr bridge0
[root@node-1 ~] # ip addr add 192.168.10.1/24 dev bridge0      //注意,这个192.168.10.1就是所建容器的网关地址。通过docker inspect container_id能查看到
[root@node-1 ~] # ip link set dev bridge0 up
[root@node-1 ~] # ip addr show bridge0
[root@node-1 ~] # vim /etc/sysconfig/docker      //即将虚拟的桥接口由默认的docker0改为bridge0
OPTIONS= '--selinux-enabled --log-driver=journald'
改为
OPTIONS= '--selinux-enabled --log-driver=journald -b=bridge0'     // 即添加-b=bridge0
    
[root@node-1 ~] # systemctl restart docker
[root@node-1 ~] # ifconfig         //发现只有bridge0虚拟网桥,没有默认的docker0网桥了。(如果还有docker0,就再次执行"ip link set dev docker0 down && brctl delbr docker0 && systemctl restart docker)
  
与上面操作同理:
node2节点的网桥网络指定为192.168.20.1 /24
node3节点的网桥网络指定为192.168.30.1 /24

3)安装并配置etcd(这里采用的是集群模式,建议做集群)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
etcd 是一个分布式一致性k- v 存储系统,可用于服务注册发现与共享配置,具有以下优点:
1)简单:相比于晦涩难懂的paxos算法,etcd基于相对简单且易实现的raft算法实现一致性,并通过gRPC提供接口调用
2)安全:支持TLS通信,并可以针对不同的用户进行对key的读写控制
3)高性能:10,000/秒的写性能
  
  
etcd是一个分布式高可用的键值(key /value )存储系统,主要用于服务注册发现与共享配置,etcd 会在集群的各个节点中复制这些数据并保证这些数据始终正确。具有以下优点:
1)简单:相比于晦涩难懂的paxos算法,etcd基于相对简单且易实现的raft算法实现一致性,并通过gRPC提供接口调用
2)安全:支持TLS通信,并可以针对不同的用户进行对key的读写控制
3)高性能:10,000/秒的写性能
  
etcd是由CoreOS开发并维护的,灵感来自于 ZooKeeper 和 Doozer,它使用Go语言编写,并通过Raft一致性算法处理日志复制以保证强一致性,有基于HTTP+JSON的API接口。
Raft是一个来自Stanford的新的一致性算法,适用于分布式系统的日志复制,Raft通过选举的方式来实现一致性,在Raft中,任何一个节点都可能成为Leader。Google的容器
集群管理系统Kubernetes、开源PaaS平台Cloud Foundry和CoreOS的Fleet都广泛使用了etcd。raft 共识算法的优点在于可以在高效的解决分布式系统中各个节点日志内容一致
性问题的同时,也使得集群具备一定的容错能力。即使集群中出现部分节点故障、网络故障等问题,仍可保证其余大多数节点正确的步进。甚至当更多的节点(一般来说超过集
群节点总数的一半)出现故障而导致集群不可用时,依然可以保证节点中的数据不会出现错误的结果。
  
----------------------------------------------------------------------------------------------------------------------------------
在三个节点机上都要安装etcd,构成etcd集群环境
(etcd下载:https: //pan .baidu.com /s/1jIsTV3C     密码:djcv)
[root@node-1 ~] # curl -L  https://github.com/coreos/etcd/releases/download/v2.3.6/etcd-v2.3.6-linux-amd64.tar.gz -o etcd-v2.3.6-linux-amd64.tar.gz
[root@node-1 ~] # tar zxvf etcd-v2.3.6-linux-amd64.tar.gz
[root@node-1 ~] # cd etcd-v2.3.6-linux-amd64/
[root@node-1 etcd-v2.3.6-linux-amd64] #
  
  
如上在三个节点机上安装好etcd后,进行etcd静态配置。
静态配置主要预先将集群的配置信息分配好,然后将集群分布启动,集群将根据配置信息组成集群。这里按如下的配置信息分别启动三个etcd。
  
在node-1上的etcd配置:
[root@node-1 ~] # ./etcd --name node1 --initial--advertise-peer-urls http://182.48.115.233:2380 \
--listen-peer-urls http: //0 .0.0.0:2380 \
--listen-client-urls http: //0 .0.0.0:2379,http: //127 .0.0.1:4001 \
--advertise-client-urls http: //0 .0.0.0:2379 \
--initial-cluster-token etcd-cluster \
--initial-cluster node1=http: //182 .48.115.233:2380,node2=http: //182 .48.115.236:2380,node3=http: //182 .48.115.239:2380\
--initial-cluster-state new
  
在node-2上的etcd配置:
[root@node-2 ~] # ./etcd --name node2 --initial--advertise-peer-urls http://182.48.115.236:2380 \
--listen-peer-urls http: //0 .0.0.0:2380 \
--listen-client-urls http: //0 .0.0.0:2379,http: //127 .0.0.1:4001 \
--advertise-client-urls http: //0 .0.0.0:2379 \
--initial-cluster-token etcd-cluster \
--initial-cluster node1=http: //182 .48.115.233:2380,node2=http: //182 .48.115.236:2380,node3=http: //182 .48.115.239:2380\
--initial-cluster-state new
  
在node-3上的etcd配置:
[root@node-3 ~] # ./etcd --name node3 --initial--advertise-peer-urls http://182.48.115.239:2380 \
--listen-peer-urls http: //0 .0.0.0:2380 \
--listen-client-urls http: //0 .0.0.0:2379,http: //127 .0.0.1:4001 \
--advertise-client-urls http: //0 .0.0.0:2379 \
--initial-cluster-token etcd-cluster \
--initial-cluster node1=http: //182 .48.115.233:2380,node2=http: //182 .48.115.236:2380,node3=http: //182 .48.115.239:2380\
--initial-cluster-state new
  
按如上配置分别启动集群,启动集群后,将会进入集群选举状态,若出现大量超时,则需要检查主机的防火墙是否关闭,或主机之间是否能通过2380端口通信,集群建立后通过以下命令检查集群状态。
  
特别注意一个细节:
上面的命令执行后会一直在前台执行中,不能关闭当前终端窗口,关闭当前窗口后,上面启动的etcd集群程序就会关闭!!
正确的做法是将其切到后台执行,在上面etcd集群程序启动后,依次:
1)按键ctrl+z   将其程序挂起,会出现一个序列号,一般为1
2)执行命令: bg  1      1就是上面挂起后出现的序列号
3)执行命令disown -a     这样就将这个程序切到后台运行了
  
然后关闭当前程序运行的终端窗口,然后 ps  -ef| grep  etcd,会发现etcd的集群程序还在运行中:
[root@node-1 ~] # ps -ef|grep etcd
root     13138     1  1 14:33 ?        00:00:07 . /etcd  -name node1 --initial--advertise-peer-urls http: //182 .48.115.233:2380 --listen-peer-urls http: //0 .0.0.0:2380 --listen-client-urls http: //0 .0.0.0:2379,http: //127 .0.0.1:4001 --advertise-client-urls http: //0 .0.0.0:2379 --initial-cluster-token etcd-cluster --initial-cluster node1=http: //182 .48.115.233:2380,node2=http: //182 .48.115.236:2380,node3=http: //182 .48.115.239:2380 --initial-cluster-state new
root     13226 13186  0 14:40 pts /1     00:00:00  grep  --color=auto etcd
[root@node-1 ~] # lsof -i:2380
COMMAND   PID USER   FD   TYPE  DEVICE SIZE /OFF  NODE NAME
etcd    13138 root    5u  IPv6 1827574      0t0  TCP *:2380 (LISTEN)
etcd    13138 root    8u  IPv6 1831276      0t0  TCP node-1:2380->node-3:60886 (ESTABLISHED)
etcd    13138 root   11u  IPv4 1827581      0t0  TCP node-1:49991->node-2:2380 (ESTABLISHED)
  
以上配置项说明( /root/etcd-v2 .3.6-linux-amd64 /etcd  --help 查看帮助信息):
--name    etcd集群中的节点名,这里可以随意,可区分且不重复就行
---listen-peer-urls     监听的用于节点之间通信的url,可监听多个,集群内部将通过这些url进行数据交互(如选举,数据同步等)
---initial--advertise-peer-urls     建议用于节点之间通信的url,节点间将以该值进行通信。
---listen-client-urls     监听的用于客户端通信的url,同样可以监听多个。
---advertise-client-urls    建议使用的客户端通信url,该值用于etcd代理或etcd成员与etcd节点通信。
---initial-cluster-token etcd-cluster-1   节点的token值,设置该值后集群将生成唯一 id ,并为每个节点也生成唯一 id ,当使用相同配置文件再启动一个集群时,只要该token值不一样,etcd集群就不会相互影响。
---initial-cluster   也就是集群中所有的initial--advertise-peer-urls 的合集
---initial-cluster-state new    新建集群的标志
  
查看集群成员(在三个节点机任意一个上面查看都可以,因为做的是集群环境):
[root@node-1 etcd-v2.3.6-linux-amd64] # ./etcdctl  member list                                        //如下,发现node1节点目前是leader
4590a741acf3f320: name=node1 peerURLs=http: //182 .48.115.233:2380 clientURLs=http: //0 .0.0.0:2379 isLeader= true
5e984e2093d56d63: name=node3 peerURLs=http: //182 .48.115.239:2380 clientURLs=http: //0 .0.0.0:2379 isLeader= false
951afc93e5278fdc: name=node2 peerURLs=http: //182 .48.115.236:2380 clientURLs=http: //0 .0.0.0:2379 isLeader= false
  
检查集群健康状态(在三个节点中的任意一个上面都可以查看)
[root@node-1 etcd-v2.3.6-linux-amd64] # ./etcdctl cluster-health
member 4590a741acf3f320 is healthy: got healthy result from http: //0 .0.0.0:2379
member 5e984e2093d56d63 is healthy: got healthy result from http: //0 .0.0.0:2379
member 951afc93e5278fdc is healthy: got healthy result from http: //0 .0.0.0:2379
cluster is healthy
  
如上集群搭建成功。

4)启动Calico服务(这是安装最新版的做法,新版和老版的命令已有所改变)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
首先在三个节点机上下载calico的命令管理工具calicoctl(百度云下载地址:https: //pan .baidu.com /s/1pKKTGbL      密码:r7sm)
[root@node-1 ~] # wget http://www.projectcalico.org/builds/calicoctl
[root@node-1 ~] # chmod +x calicoctl
[root@node-1 ~] # mv calicoctl /usr/local/bin/
[root@node-1 ~] # calicoctl --help                  //查看帮助信息
 
启动Calico服务
在Docker环境中Calico服务是做为容器来运行的,使用host的网络配置。所有容器配置使用Calico服务,做为calico节点互相通信。
Calico在每个主机上通过一个自己的container与其他主机或者网络通讯,即calico-node的container,这个container里面包含了Bird路由管理、Felix协议等。
 
千万别忘了在三个节点上都要下载calico的node镜像
(可以先在一个节点上下载镜像,然后将镜像通过docker save导出保存到本地,再将镜像拷贝到其他节点上通过docker load导入,这样对于其他节点来说,比使用docker pull要快)
[root@node-1 ~] # docker pull calico/node
[root@node-1 ~] # docker pull calico/node-libnetwork
[root@node-1 ~] # docker images
REPOSITORY                         TAG                 IMAGE ID            CREATED             SIZE
docker.io /calico/node               latest              1e0928760e74        11 hours ago        255.2 MB
docker.io /nginx                     latest              3448f27c273f        6 days ago          109.4 MB
docker.io /calico/node-libnetwork    latest              84d99cab9fc4        7 months ago        70.2 MB
 
 
下面分别在三个节点上,以Docker方式启动calico-node(这个命令会执行一段时间,耐心等待......)
node-1
[root@node-1 ~] # calicoctl node run --ip=182.48.115.233
Running  command  to load modules: modprobe -a xt_set ip6_tables
Enabling IPv4 forwarding
.......
Using node name: node-1
Starting libnetwork service
Calico node started successfully
 
node-2
[root@node-2 ~] # calicoctl node run --ip=182.48.115.236
 
node-3
[root@node-3 ~] # calicoctl node run --ip=182.48.115.239
 
可以在三个节点上查看calico-node启动情况
[root@node-1 ~] # docker ps
CONTAINER ID        IMAGE                        COMMAND             CREATED             STATUS              PORTS               NAMES
2ac613b1af9a        quay.io /calico/node :latest    "start_runit"        22 seconds ago      Up 17 seconds                           calico-node
[root@node-1 ~] # ps -ef|grep calico
root     14339 14336  0 15:43 ?        00:00:00 svlogd -tt  /var/log/calico/bird6
root     14340 14336  0 15:43 ?        00:00:00 bird6 -R -s  /var/run/calico/bird6 .ctl -d -c  /etc/calico/confd/config/bird6 .cfg
root     14341 14337  0 15:43 ?        00:00:00 svlogd  /var/log/calico/confd
root     14342 14337  0 15:43 ?        00:00:00 confd -confdir= /etc/calico/confd  -interval=5 - watch  -no-discover --log-level=debug -node=http: //127 .0.0.1:2379 -client-key= -client-cert= -client-ca-keys=
root     14343 14334  0 15:43 ?        00:00:00 svlogd  /var/log/calico/felix
root     14344 14334  2 15:43 ?        00:00:03 calico-felix
root     14346 14338  0 15:43 ?        00:00:00 svlogd  /var/log/calico/libnetwork
root     14349 14335  0 15:43 ?        00:00:00 svlogd -tt  /var/log/calico/bird
root     14350 14335  0 15:43 ?        00:00:00 bird -R -s  /var/run/calico/bird .ctl -d -c  /etc/calico/confd/config/bird .cfg
root     14597 13854  0 15:45 pts /2     00:00:00  grep  --color=auto calico
 
查看节点状态信息(在三个节点上都可以查看)
[root@node-1 ~] # calicoctl node status
Calico process is running.
 
IPv4 BGP status
+----------------+-------------------+-------+----------+-------------+
|  PEER ADDRESS  |     PEER TYPE     | STATE |  SINCE   |    INFO     |
+----------------+-------------------+-------+----------+-------------+
| 182.48.115.236 | node-to-node mesh | up    | 07:47:20 | Established |
| 182.48.115.239 | node-to-node mesh | up    | 07:52:55 | Established |
+----------------+-------------------+-------+----------+-------------+
 
IPv6 BGP status
No IPv6 peers found.
 
[root@node-2 ~] # calicoctl node status
Calico process is running.
 
IPv4 BGP status
+----------------+-------------------+-------+----------+-------------+
|  PEER ADDRESS  |     PEER TYPE     | STATE |  SINCE   |    INFO     |
+----------------+-------------------+-------+----------+-------------+
| 182.48.115.233 | node-to-node mesh | up    | 07:46:19 | Established |
| 182.48.115.239 | node-to-node mesh | up    | 07:51:54 | Established |
+----------------+-------------------+-------+----------+-------------+
 
IPv6 BGP status
No IPv6 peers found.
 
[root@node-3 ~] # calicoctl node status
Calico process is running.
 
IPv4 BGP status
+----------------+-------------------+-------+----------+-------------+
|  PEER ADDRESS  |     PEER TYPE     | STATE |  SINCE   |    INFO     |
+----------------+-------------------+-------+----------+-------------+
| 182.48.115.233 | node-to-node mesh | up    | 09:51:54 | Established |
| 182.48.115.236 | node-to-node mesh | up    | 09:51:54 | Established |
+----------------+-------------------+-------+----------+-------------+
 
IPv6 BGP status
No IPv6 peers found.
 
 
使用calicoctl创建ipPool
在启动别的容器之前,我们需要配置一个IP地址池带有ipip和nat-outgoing选项。所以带有有效配置的容器就可以访问互联网,在每个节点上运行下面的命令:
 
先查看calico的ip池(任意一个节点上都能查看)
[root@node-1 ~] # calicoctl get ipPool
CIDR                      
192.168.0.0 /16            
fd80:24e2:f998:72d6:: /64  
 
[root@node-1 ~] # calicoctl get ippool -o wide
CIDR                       NAT    IPIP   
192.168.0.0 /16              true    false  
fd80:24e2:f998:72d6:: /64    true    false  
 
上面查出的192.168.0.0 /16 是calico默认的网络。
可以使用命令 "calicoctl delete ippool 192.168.0.0/16" 删除calico默认的网络,这是非必要操作,可以保留calico默认的网络!
 
现在开始在三个节点机器上使用calicoctl创建ipPool
创建ip pool首先定义一个资源文件ipPool.yaml,如下:
 
node-1节点机器上
[root@node-1 ~] # vim ipPool.yaml
apiVersion: v1
kind: ipPool
metadata:
   cidr: 192.168.10.1 /24
spec:
   ipip:
     enabled:  true
   nat-outgoing:  true
   disabled:  false
 
[root@node-1 ~] # calicoctl create -f ipPool.yaml
Successfully created 1  'ipPool'  resource(s)
 
[root@node-1 ~] # calicoctl get ippool -o wide
CIDR                       NAT    IPIP   
192.168.0.0 /16              true    false  
192.168.10.1 /24             true    true              // 两个 true ,说明使用了IPIP
fd80:24e2:f998:72d6:: /64    true    false
 
--------------------------------------------------------------------------------
上面在创建ipPool的时候,使用了IPIP。也可以选择不使用IPIP,如下:(这里我选择的是使用IPIP)
[root@node-1 ~] # vim ipPool.yaml
apiVersion: v1
kind: ipPool
metadata:
   cidr: 192.168.10.1 /24
spec:
   ipip:
     enabled:  false
   nat-outgoing:  true
   disabled:  false
-------------------------------------------------------------------------------
 
同理,node-2节点机器上
[root@node-2 ~] # vim ipPool.yaml
apiVersion: v1
kind: ipPool
metadata:
   cidr: 192.168.20.1 /24
spec:
   ipip:
     enabled:  true
   nat-outgoing:  true
   disabled:  false
[root@node-2 ~] # calicoctl create -f ipPool.yaml
Successfully created 1  'ipPool'  resource(s)
[root@node-2 ~] # calicoctl get ippool -o wide
CIDR                       NAT    IPIP   
192.168.0.0 /16              true    false  
192.168.10.1 /24             true    true   
192.168.20.1 /24             true    true   
fd80:24e2:f998:72d6:: /64    true    false 
 
node-3节点机器上
[root@node-3 ~] # vim ipPool.yaml
apiVersion: v1
kind: ipPool
metadata:
   cidr: 192.168.30.1 /24
spec:
   ipip:
     enabled:  true
   nat-outgoing:  true
   disabled:  false
[root@node-3 ~] # calicoctl create -f ipPool.yaml
Successfully created 1  'ipPool'  resource(s)
[root@node-3 ~] # calicoctl get ippool -o wide
CIDR                       NAT    IPIP   
192.168.0.0 /16              true    false  
192.168.10.1 /24             true    true   
192.168.20.1 /24             true    true   
192.168.30.1 /24             true    true   
fd80:24e2:f998:72d6:: /64    true    false 
 
由上面可以看出,当三个节点都创建了ipPool后,再次查看calico的ip池,就会发现三个节点的Docker网桥网络ip都显示出来了

3)容器网络配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
在3个节点上启动容器
 
------------node-1节点上创建容器--------------
[root@node-1 ~] # docker run -itd --name=my-test1 docker.io/nginx
0f09da38cb1a9b0155bcb1ed9fe8192676355e06ed474d411fc31f1207a20a63
[root@node-1 ~] # docker exec -ti my-test1 /bin/bash                   //登陆my-test1容器,发现容器ip是安装指定的docker网桥网络分配的
root@0f09da38cb1a:/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
     link /loopback  00:00:00:00:00:00 brd 00:00:00:00:00:00
     inet 127.0.0.1 /8  scope host lo
        valid_lft forever preferred_lft forever
     inet6 ::1 /128  scope host
        valid_lft forever preferred_lft forever
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default
     link /ipip  0.0.0.0 brd 0.0.0.0
2964: eth0@if2965: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
     link /ether  02:42:c0:a8:0a:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
     inet 192.168.10.2 /24  scope global eth0
        valid_lft forever preferred_lft forever
     inet6 fe80::42:c0ff:fea8:a02 /64  scope link
        valid_lft forever preferred_lft forever
 
 
------------node-2节点上创建容器--------------
[root@node-2 ~] # docker run -itd  --name=my-test2 docker.io/nginx
707a1e64a3072b1c49dad3009e63b7307ab725fa43147c1ad3c809f5214c761b
[root@node-2 ~] # docker exec -ti my-test2 /bin/bash
root@707a1e64a307:/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
     link /loopback  00:00:00:00:00:00 brd 00:00:00:00:00:00
     inet 127.0.0.1 /8  scope host lo
        valid_lft forever preferred_lft forever
     inet6 ::1 /128  scope host
        valid_lft forever preferred_lft forever
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default qlen 1
     link /ipip  0.0.0.0 brd 0.0.0.0
15: eth0@if16: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
     link /ether  02:42:c0:a8:14:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
     inet 192.168.20.2 /24  scope global eth0
        valid_lft forever preferred_lft forever
     inet6 fe80::42:c0ff:fea8:1402 /64  scope link
        valid_lft forever preferred_lft forever
 
------------node-3节点上创建容器--------------
[root@node-3 ~] # docker run -itd --name=my-test3 docker.io/nginx
d52d18d9e1eb0e309ece7cc20c76654c195db5aee609cb3a2075dfcb1aff2425
[root@node-3 ~] # docker exec -ti my-test3 /bin/bash
root@d52d18d9e1eb:/ # ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default
     link /loopback  00:00:00:00:00:00 brd 00:00:00:00:00:00
     inet 127.0.0.1 /8  scope host lo
        valid_lft forever preferred_lft forever
     inet6 ::1 /128  scope host
        valid_lft forever preferred_lft forever
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN group default
     link /ipip  0.0.0.0 brd 0.0.0.0
39: eth0@if40: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
     link /ether  02:42:c0:a8:1e:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
     inet 192.168.30.2 /24  scope global eth0
        valid_lft forever preferred_lft forever
     inet6 fe80::42:c0ff:fea8:1e02 /64  scope link
        valid_lft forever preferred_lft forever
root@d52d18d9e1eb:/ # ping 192.168.10.2
PING 192.168.10.2 (192.168.10.2): 56 data bytes
64 bytes from 192.168.10.2: icmp_seq=0 ttl=62  time =0.799 ms
^C--- 192.168.10.2  ping  statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min /avg/max/stddev  = 0.799 /0 .799 /0 .799 /0 .000 ms
root@d52d18d9e1eb:/ # ping 192.168.20.2
PING 192.168.20.2 (192.168.20.2): 56 data bytes
64 bytes from 192.168.20.2: icmp_seq=0 ttl=62  time =1.021 ms
^C--- 192.168.20.2  ping  statistics ---
1 packets transmitted, 1 packets received, 0% packet loss
round-trip min /avg/max/stddev  = 1.021 /1 .021 /1 .021 /0 .000 ms
 
可以发现,在三个节点上创建的容器都是按照指定的docker网桥网络分配的ip,并且各节点机上的容器间的ip是可以相互 ping 通的!
除此之外:
1)容器可以访问外网(默认采用的是bridge网桥模式,只要宿主机能访问外网,容器也就可以)。
2)宿主机可以 ping 通任意一个节点上的容器ip
3)容器可以 ping 通任意一个节点ip
***************当你发现自己的才华撑不起野心时,就请安静下来学习吧***************

本文转自散尽浮华博客园博客,原文链接:http://www.cnblogs.com/kevingrace/p/6864804.html,如需转载请自行联系原作者
相关实践学习
基于ACK Serverless轻松部署企业级Stable Diffusion
本实验指导您在容器服务Serverless版(以下简称 ACK Serverless )中,通过Knative部署满足企业级弹性需求的Stable Diffusion服务。同时通过对该服务进行压测实验,体验ACK Serverless 弹性能力。
相关文章
|
1月前
|
消息中间件 数据可视化 Kafka
docker arm架构部署kafka要点
本内容介绍了基于 Docker 的容器化解决方案,包含以下部分: 1. **Docker 容器管理**:通过 Portainer 可视化管理工具实现对主节点和代理节点的统一管理。 2. **Kafka 可视化工具**:部署 Kafka-UI 以图形化方式监控和管理 Kafka 集群,支持动态配置功能, 3. **Kafka 安装与配置**:基于 Bitnami Kafka 镜像,提供完整的 Kafka 集群配置示例,涵盖 KRaft 模式、性能调优参数及数据持久化设置,适用于高可用生产环境。 以上方案适合 ARM64 架构,为用户提供了一站式的容器化管理和消息队列解决方案。
|
12天前
|
Docker 容器
Docker网关冲突导致容器启动网络异常解决方案
当执行`docker-compose up`命令时,服务器网络可能因Docker创建新网桥导致IP段冲突而中断。原因是Docker默认的docker0网卡(172.17.0.1/16)与宿主机网络地址段重叠,引发路由异常。解决方法为修改docker0地址段,通过配置`/etc/docker/daemon.json`调整为非冲突段(如192.168.200.1/24),并重启服务。同时,在`docker-compose.yml`中指定网络模式为`bridge`,最后通过检查docker0地址、网络接口列表及测试容器启动验证修复效果。
|
4月前
|
消息中间件 监控 RocketMQ
Docker部署RocketMQ5.2.0集群
本文详细介绍了如何使用Docker和Docker Compose部署RocketMQ 5.2.0集群。通过创建配置文件、启动集群和验证容器状态,您可以快速搭建起一个RocketMQ集群环境。希望本文能够帮助您更好地理解和应用RocketMQ,提高消息中间件的部署和管理效率。
535 91
|
2月前
|
Ubuntu 安全 Docker
Ubuntu下部署及操作Docker技巧
以上就是在Ubuntu下部署及操作Docker的具体步骤。但这只是冰山一角,Docker的魅力远不仅如此。你可以将其视为存放各种工具的小箱子,随时随地取用,极大地提升工作效率。你也可以私人订制,适应不同的开发环境,就像一个拥有各种口味冰淇淋的冰箱,满足各种各样的需求。好了,现在你已经掌握了基本的Docker运用技巧,快去尝试使用吧!记住,沉浸在探索中,你会找到无尽的乐趣和满满的收获。
155 23
|
4月前
|
存储 NoSQL Redis
Docker 部署 Redis
在使用 Docker 部署 Redis 时,为实现数据持久化,需正确挂载容器内的数据目录到宿主机。推荐命令如下: ``` docker run -d --name redis -v /mnt/data/redis:/data -p 6379:6379 redis ``` 该命令将宿主机的 `/mnt/data/redis` 目录挂载到容器的 `/data` 目录,确保 Redis 数据持久化。此路径更通用,适合大多数场景。避免使用不匹配的挂载路径,如 `/var/lib/redis` 或 `/mnt/data/redis` 到非默认目录,以防止数据无法正确持久化。
|
5月前
|
存储 关系型数据库 MySQL
美团面试:MySQL为什么 不用 Docker部署?
45岁老架构师尼恩在读者交流群中分享了关于“MySQL为什么不推荐使用Docker部署”的深入分析。通过系统化的梳理,尼恩帮助读者理解为何大型MySQL数据库通常不使用Docker部署,主要涉及性能、管理复杂度和稳定性等方面的考量。文章详细解释了有状态容器的特点、Docker的资源隔离问题以及磁盘IO性能损耗,并提供了小型MySQL使用Docker的最佳实践。此外,尼恩还介绍了Share Nothing架构的优势及其应用场景,强调了配置管理和数据持久化的挑战。最后,尼恩建议读者参考《尼恩Java面试宝典PDF》以提升技术能力,更好地应对面试中的难题。
|
3月前
|
安全 API 算法框架/工具
大模型文件Docker镜像化部署技术详解
大模型文件Docker镜像化部署技术详解
379 2
|
3月前
|
JSON 运维 Ubuntu
在Docker上部署Ollama+AnythingLLM完成本地LLM Agent部署
通过以上步骤,您可以成功在Docker上部署Ollama和AnythingLLM,实现本地LLM Agent的功能。在部署过程中,确保环境和配置正确,以避免不必要的问题。希望本文能够帮助您顺利完成部署,并在本地环境中高效地使用LLM模型。
1158 8
|
4月前
|
人工智能 文字识别 安全
Stirling-PDF:51.4K Star!用Docker部署私有PDF工作站,支持50多种PDF操作,从此告别在线工具
Stirling-PDF 是一款基于 Docker 的本地化 PDF 编辑工具,支持 50 多种 PDF 操作,包括合并、拆分、转换、压缩等,同时提供多语言支持和企业级功能,满足个人和企业用户的多样化需求。
322 6
Stirling-PDF:51.4K Star!用Docker部署私有PDF工作站,支持50多种PDF操作,从此告别在线工具
|
4月前
|
JavaScript 前端开发 Docker
如何通过pm2以cluster模式多进程部署next.js(包括docker下的部署)
通过这些步骤,可以确保您的Next.js应用在多核服务器上高效运行,并且在Docker环境中实现高效的容器化管理。
438 44
下一篇
oss创建bucket