0%

从零开始搭建k8s集群环境(五)——安装Pod网络

系列目录:

接上步骤,我们已经成功初始化了 MasterNode01 节点,并将其加入到同一个集群内。但是两个节点目前均是 NotReady 状态,这是因为我们的集群还没有安装网络插件,而 k8s 不自带网络插件。

环境说明:

  • Master:VBox虚拟机/Centos_7.5-1804/192.168.56.100
  • Images:VBox虚拟机/Centos_7.5-1804/192.168.56.101
  • Node01:VBox虚拟机/Centos_7.5-1804/192.168.56.102

软件环境说明:

  • docker-ce-17.03.2
  • kubernetes-v1.9.0
  • harbor-v1.4.0

一、插件选择(翻译)

Calico

请参阅 Calico 文档以获得kubeadm quickstartkubeadm安装指南和其他资源。

注意: 为了使网络策略正确地工作,您需要在 kubeadm init 时添加参数 --pod-network-cidr=192.168.0.0/16Calico 只在 amd64 上工作。

安装命令:

1
kubectl apply -f https://docs.projectcalico.org/v3.0/getting-started/kubernetes/installation/hosted/kubeadm/1.7/calico.yaml

Canal

官方渠道设置指南在这里

注意: 为了让 Canal 正确地工作,您需要在 kubeadm init 时添加参数 --pod-network-cidr=10.244.0.0/16Canal 只在 amd64 上工作。

安装命令:

1
2
kubectl apply -f https://raw.githubusercontent.com/projectcalico/canal/master/k8s-install/1.7/rbac.yaml
kubectl apply -f https://raw.githubusercontent.com/projectcalico/canal/master/k8s-install/1.7/canal.yaml

Flannel

注意: 为了让 Flannel 正确地工作,您需要在 kubeadm init 时添加参数 --pod-network-cidr=10.244.0.0/16Flannel 可以在 amd64armarm64ppc64le 上进行工作,但要在 amd64 以外的平台上工作,您必须手动下载清单,并使用选定的平台替换 amd64。 需要运行 sysctl net.bridge.bridge-nf-call-iptables=1 将桥接的IPv4流量传递给 iptables 的链。这是一些 CNI插件 的工作要求,更多的信息请看这里。 有关 Flannel 的更多信息,请看这里

安装命令:

1
kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.10.0/Documentation/kube-flannel.yml

Romana

注意: 需要运行 sysctl net.bridge.bridge-nf-call-iptables=1 将桥接的IPv4流量传递给 iptables 的链。这是一些 CNI插件 的工作要求,更多的信息请看这里。 官方的 Romana 设置指南在这里

安装命令:

1
kubectl apply -f https://raw.githubusercontent.com/romana/romana/master/containerize/specs/romana-kubeadm.yml

Weave Net

注意: 需要运行 sysctl net.bridge.bridge-nf-call-iptables=1 将桥接的IPv4流量传递给 iptables 的链。这是一些 CNI插件 的工作要求,更多的信息请看这里Weave Net 可以在 amd64armarm64ppc64le 上运行,无需任何额外的操作。Weave Net 默认设置 hairpin 模式。这允许 pod 通过他们的服务IP地址访问自己,如果他们不知道他们的 PodIP。 官方 Weave Net 设置指南在这里

安装命令:

1
kubectl apply -f https://cloud.weave.works/k8s/net

网络模块请大家自己选择,安装其实很容易~ 我这里选用了 FlannelWeave Net 两种进行实验。

二、部署测试服务

为了验证我们安装的 Pod 网络配置,我们先部署一个镜像作为我们的测试服务,用来对 Pod 网络的验证。

镜像对应的 Dockerfile 文件内容如下:

1
2
3
4
5
6
7
8
FROM centos:latest
MAINTAINER lx0758 lx0758@qq.com

RUN rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm && yum install nginx -y && systemctl enable nginx

EXPOSE 80

ENTRYPOINT ["/usr/sbin/nginx", "-g", "daemon off;"]

为什么不直接用 Nginx 的镜像:因为我们测试需要去容器里面测试集群内的网络访问情况,Nginx 镜像一些常用的工具都没有,所以就自己做了一个镜像。

测试服务对应的 http-test.yaml 文件内容如下:

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
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: http-test-dm
spec:
replicas: 3
template:
metadata:
labels:
name: http-test-dm
spec:
containers:
- name: http-test-con
image: registry.cn-shenzhen.aliyuncs.com/lx0758-per/http-test:latest
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: http-test-ser
spec:
ports:
- port: 80
targetPort: 80
selector:
name: http-test-dm

可以看到,这个文件分别配置了 DeploymentService。运行的镜像是基于 CentOS 镜像,并在里面部署了一个 Nginx 服务器,用于模拟我们的 Http 服务。

部署完之后各项情况如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@localhost ~]# kubectl get deployment -o wide
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES SELECTOR
http-test-dm 3 3 3 3 14m http-test-con registry.cn-shenzhen.aliyuncs.com/lx0758-per/http-test:latest name=http-test-dm

[root@localhost ~]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE
http-test-dm-bcd8d9b5b-9cc99 1/1 Running 0 13m 10.244.0.30 localhost.master
http-test-dm-bcd8d9b5b-m79ql 1/1 Running 0 13m 10.244.2.15 localhost.node02
http-test-dm-bcd8d9b5b-m9dj2 1/1 Running 0 13m 10.244.1.27 localhost.node01

[root@localhost ~]# kubectl get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
http-test-ser ClusterIP 10.109.145.234 <none> 80/TCP 15m name=http-test-dm
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 1d <none>

三、安装Pod网络

注意事项

  • 每个集群只能安装一种 pod 网络,这里是为了演示才把列出来两种。
  • 两种网络都提供了阿里云镜像,如果使用阿里云镜像应该先下拉好镜像再应用yml文件。
  • 某些网络插件需要在集群 Master 初始化时传入 --pod-network-cidr 参数。
  • 网络插件是以扩展方式安装的,所以在每次 reset 之后是需要重新装载 yml 文件安装的。
  • 多网卡环境时需要对插件的安装参数做修改,让插件知道应该使用哪张网卡去和其他 Node 通信。

Flannel

安装 Flannel 很简单,在 Master 执行提供的命令就可以了。考虑到镜像下载很慢,可以使用我的阿里云镜像,在所有节点(包括 Master)把镜像先下载好再安装:

1
2
3
docker pull registry.cn-shenzhen.aliyuncs.com/lx0758/flannel:v0.10.0-amd64
docker tag registry.cn-shenzhen.aliyuncs.com/lx0758/flannel:v0.10.0-amd64 quay.io/coreos/flannel:v0.10.0-amd64
docker rmi registry.cn-shenzhen.aliyuncs.com/lx0758/flannel:v0.10.0-amd64

下载完镜像,然后再执行安装命令:

1
2
3
4
5
6
[root@localhost ~]# kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/v0.10.0/Documentation/kube-flannel.yml
clusterrole "flannel" created
clusterrolebinding "flannel" created
serviceaccount "flannel" created
configmap "kube-flannel-cfg" created
daemonset "kube-flannel-ds" created

注意镜像只有一个: ·quay.io/coreos/flannel:v0.10.0-amd64·

Weave Net

安装 ·Weave Net· 同样也很简单,在 ·Master· 执行上面提供的命令就可以了。考虑到镜像下载很慢,可以使用我的阿里云镜像,在所有节点(包括 Master)把镜像先下载好再安装:

1
2
3
4
5
6
7
docker pull registry.cn-shenzhen.aliyuncs.com/lx0758/weave-npc:2.3.0
docker tag registry.cn-shenzhen.aliyuncs.com/lx0758/weave-npc:2.3.0 weaveworks/weave-npc:2.3.0
docker rmi registry.cn-shenzhen.aliyuncs.com/lx0758/weave-npc:2.3.0

docker pull registry.cn-shenzhen.aliyuncs.com/lx0758/weave-kube:2.3.0
docker tag registry.cn-shenzhen.aliyuncs.com/lx0758/weave-kube:2.3.0 weaveworks/weave-kube:2.3.0
docker rmi registry.cn-shenzhen.aliyuncs.com/lx0758/weave-kube:2.3.0

注意镜像这里有两个: weaveworks/weave-npc:2.3.0 weaveworks/weave-kube:2.3.0

下载完镜像,然后再执行安装命令。

1
2
3
4
5
6
7
[root@localhost ~]# kubectl apply -f https://cloud.weave.works/k8s/net
serviceaccount "weave-net" created
clusterrole "weave-net" created
clusterrolebinding "weave-net" created
role "weave-net" created
rolebinding "weave-net" created
daemonset "weave-net" created

安装完成

Pod 网络安装完毕之后,在查看 k8s nodes 就全部变为可用了:

1
2
3
4
[root@localhost ~]# kubectl get nodes
NAME STATUS ROLES AGE VERSION
localhost.master Ready master 56m v1.9.0
localhost.node01 Ready <none> 55m v1.9.0

验证网络

正常情况下,安装 Pod 网络成功之后,各个节点的 Pod 的网络是可以 ping 通的:

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
# 先找出两个在不同节点的 Pod 分配到的 IP(没有的话部署一个)
[root@localhost ~]# kubectl get pod -o wide --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE IP NODE
default http-test-dm-bcd8d9b5b-2z57z 1/1 Running 0 8h 10.244.2.95 localhost.node01
default http-test-dm-bcd8d9b5b-7kmxq 1/1 Running 0 8m 10.244.0.38 localhost.master
ingress-nginx default-http-backend-66954f958c-nrqvr 1/1 Running 1 9h 10.244.0.31 localhost.master
ingress-nginx nginx-ingress-controller-5b7fc4c8f6-xvszd 1/1 Running 0 17m 10.0.2.15 localhost.master
kube-system etcd-localhost.master 1/1 Running 1 10h 10.0.2.15 localhost.master
kube-system kube-apiserver-localhost.master 1/1 Running 1 10h 10.0.2.15 localhost.master
kube-system kube-controller-manager-localhost.master 1/1 Running 1 10h 10.0.2.15 localhost.master
kube-system kube-dns-6f4fd4bdf-tdwrr 3/3 Running 3 9h 10.244.0.34 localhost.master
kube-system kube-flannel-ds-hxn8s 1/1 Running 1 10h 10.0.2.15 localhost.master
kube-system kube-flannel-ds-jgprt 1/1 Running 0 9h 10.0.2.15 localhost.node01
kube-system kube-proxy-qq8nh 1/1 Running 0 9h 10.0.2.15 localhost.node01
kube-system kube-proxy-x5mkg 1/1 Running 1 10h 10.0.2.15 localhost.master
kube-system kube-scheduler-localhost.master 1/1 Running 1 10h 10.0.2.15 localhost.master
kube-system kubernetes-dashboard-6b78d59ffd-4zvcg 1/1 Running 1 9h 10.244.0.35 localhost.master

# 在 Master 尝试 Ping 另一个节点内 Pod 的 IP
[root@localhost ~]# ping 10.244.2.95
PING 10.244.2.95 (10.244.2.95) 56(84) bytes of data.
64 bytes from 10.244.2.95: icmp_seq=1 ttl=63 time=2.55 ms
64 bytes from 10.244.2.95: icmp_seq=2 ttl=63 time=2.00 ms
64 bytes from 10.244.2.95: icmp_seq=3 ttl=63 time=1.50 ms
64 bytes from 10.244.2.95: icmp_seq=4 ttl=63 time=1.07 ms
--- 10.244.2.95 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 1.074/1.784/2.555/0.553 ms

# 在 Master Pod 内尝试 Ping 另一个节点内 Pod 的 IP
[root@localhost ~]# kubectl exec -ti http-test-dm-bcd8d9b5b-7kmxq bash
[root@http-test-dm-bcd8d9b5b-7kmxq /]# ping 10.244.2.95
PING 10.244.2.95 (10.244.2.95) 56(84) bytes of data.
64 bytes from 10.244.2.95: icmp_seq=1 ttl=62 time=1.60 ms
64 bytes from 10.244.2.95: icmp_seq=2 ttl=62 time=1.69 ms
64 bytes from 10.244.2.95: icmp_seq=3 ttl=62 time=1.98 ms
64 bytes from 10.244.2.95: icmp_seq=4 ttl=62 time=2.08 ms
--- 10.244.2.95 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3001ms
rtt min/avg/max/mdev = 1.600/1.842/2.089/0.204 ms

到这里可以确认,集群内所有 Pod 网络的都是互通的,说明我们的网络插件是安装正确的。

四、Pod DNS问题

上步骤我们成功安装了 Pod 网络,可是却发现 DNSPod 没运行:

1
2
3
4
5
6
7
8
9
10
11
[root@localhost ~]# kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system etcd-localhost.master 1/1 Running 0 3m
kube-system kube-apiserver-localhost.master 1/1 Running 0 2m
kube-system kube-controller-manager-localhost.master 1/1 Running 0 3m
kube-system kube-dns-6f4fd4bdf-btlhn 0/3 ContainerCreating 0 3m
kube-system kube-flannel-ds-7dqgv 1/1 Running 0 1m
kube-system kube-flannel-ds-pgxp7 1/1 Running 0 1m
kube-system kube-proxy-jfwrt 1/1 Running 0 3m
kube-system kube-proxy-mw7pz 1/1 Running 0 3m
kube-system kube-scheduler-localhost.master 1/1 Running 0 2m

在境外服务器重现之后发现是 k8s 还会去谷歌下拉 3个dns相关的镜像。所以我又搞了阿里云:

1
2
3
4
5
6
7
8
9
10
11
#!/usr/bin/env bash
images=(
k8s-dns-sidecar-amd64:1.14.7
k8s-dns-kube-dns-amd64:1.14.7
k8s-dns-dnsmasq-nanny-amd64:1.14.7
)
for imageName in ${images[@]} ; do
docker pull registry.cn-shenzhen.aliyuncs.com/lx0758/$imageName
docker tag registry.cn-shenzhen.aliyuncs.com/lx0758/$imageName gcr.io/google_containers/$imageName
docker rmi registry.cn-shenzhen.aliyuncs.com/lx0758/$imageName
done

上面3个镜像只需要在 Master 机器上面安装即可。

pull 之后,貌似 dns 就运行起了。。。 额。。。如果始终运行不起,那你就 kubectl delete pod {pods} -n kube-system 杀掉 Pod 让它重启吧。。。我就是这样才运行起的。。。

1
2
3
4
5
6
7
8
9
[root@xg-6xyun-cn ~]# kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system etcd-xg-6xyun-cn 1/1 Running 0 8m
kube-system kube-apiserver-xg-6xyun-cn 1/1 Running 0 8m
kube-system kube-controller-manager-xg-6xyun-cn 1/1 Running 0 9m
kube-system kube-dns-6f4fd4bdf-8k446 3/3 Running 0 9m
kube-system kube-flannel-ds-wp4z7 1/1 Running 0 8m
kube-system kube-proxy-vwxbt 1/1 Running 0 9m
kube-system kube-scheduler-xg-6xyun-cn 1/1 Running 0 8m

验证 DNS 服务

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
[root@localhost ~]# kubectl exec -ti http-test-dm-bcd8d9b5b-2z5dz bash
[root@http-test-dm-bcd8d9b5b-2z5dz /]# curl 10.96.148.108
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
[root@http-test-dm-bcd8d9b5b-2z5dz /]# curl http-test-ser
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>

五、问题汇总

kubeadm init 没加 --pod-network-cidr

MasterPods 就会变成这样:

1
2
3
4
5
6
7
8
9
10
11
[root@localhost ~]# kubectl get pods --all-namespaces
NAMESPACE NAME READY STATUS RESTARTS AGE
kube-system etcd-localhost.master 1/1 Running 3 49m
kube-system kube-apiserver-localhost.master 1/1 Running 3 49m
kube-system kube-controller-manager-localhost.master 1/1 Running 3 49m
kube-system kube-dns-6f4fd4bdf-rpgw4 0/3 ContainerCreating 0 1h
kube-system kube-flannel-ds-dskzt 0/1 CrashLoopBackOff 22 49m
kube-system kube-flannel-ds-xj9l8 0/1 Error 2 2m
kube-system kube-proxy-n2hc8 1/1 Running 0 2m
kube-system kube-proxy-xdtcx 1/1 Running 3 1h
kube-system kube-scheduler-localhost.master 1/1 Running 3 49m

所以。。。重新初始化吧~

Flannel 多网卡环境 Pod 无法互访

这么问题我搞了半天,其实就是需要对 网络插件指定网卡,不然它也不知道用哪个网卡和其他节点通信呐~ 由于 Flannel 使用默认路由的网卡接口,导致适用了外网网卡,致使pod之间无法访问。 所以需要指定使用相应网卡。在 command 参数增加 --iface=eth1 即可,修改 yaml 文件:

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
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: kube-flannel-ds
namespace: kube-system
labels:
tier: node
app: flannel
spec:
template:
metadata:
labels:
tier: node
app: flannel
spec:
hostNetwork: true
nodeSelector:
beta.kubernetes.io/arch: amd64
tolerations:
- key: node-role.kubernetes.io/master
operator: Exists
effect: NoSchedule
serviceAccountName: flannel
initContainers:
- name: install-cni
image: quay.io/coreos/flannel:v0.10.0-amd64
command:
- cp
args:
- -f
- /etc/kube-flannel/cni-conf.json
- /etc/cni/net.d/10-flannel.conflist
volumeMounts:
- name: cni
mountPath: /etc/cni/net.d
- name: flannel-cfg
mountPath: /etc/kube-flannel/
containers:
- name: kube-flannel
image: quay.io/coreos/flannel:v0.10.0-amd64
command:
- /opt/bin/flanneld
args:
- --ip-masq
- --kube-subnet-mgr
# 这里就是重点了
- --iface=eth1
···

六、参考文献

  1. Using kubeadm to Create a Cluster - Kubernetes
  2. docker Calico, Flannel, Weave and Docker Overlay
  3. 关于多网卡机器安装flannel的问题
  • 本文作者: 6x
  • 本文链接: https://6xyun.cn/article/57
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-ND 许可协议。转载请注明出处!