系列目录:
接上步骤,我们已经成功初始化了 Master
和 Node01
节点,并将其加入到同一个集群内。但是两个节点目前均是 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 quickstart 、kubeadm安装指南 和其他资源。
注意:
为了使网络策略正确地工作,您需要在 kubeadm init
时添加参数 --pod-network-cidr=192.168.0.0/16
。
Calico
只在 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/16
。
Canal
只在 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/16
。
Flannel
可以在 amd64
、arm
、arm64
和 ppc64le
上进行工作,但要在 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
可以在 amd64
、arm
、arm64
和 ppc64le
上运行,无需任何额外的操作。Weave Net
默认设置 hairpin
模式。这允许 pod
通过他们的服务IP地址访问自己,如果他们不知道他们的 PodIP
。
官方 Weave Net
设置指南在这里 。
安装命令:
1 kubectl apply -f https://cloud.weave.works/k8s/net
网络模块请大家自己选择,安装其实很容易~
我这里选用了 Flannel
和 Weave 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
可以看到,这个文件分别配置了 Deployment
和 Service
。运行的镜像是基于 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
网络,可是却发现 DNS
的 Pod
没运行:
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
Master
的 Pods
就会变成这样:
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 ···
六、参考文献
Using kubeadm to Create a Cluster - Kubernetes
docker Calico, Flannel, Weave and Docker Overlay
关于多网卡机器安装flannel的问题