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 上工作。

安装命令:

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 上工作。

安装命令:

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 的更多信息,请看这里

安装命令:

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 设置指南在这里

安装命令:

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 设置指南在这里

安装命令:

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

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

二、部署测试服务

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

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

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 文件内容如下:

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 服务。

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

[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)把镜像先下载好再安装:

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

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

[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)把镜像先下载好再安装:

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

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

[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 就全部变为可用了:

[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 通的:

# 先找出两个在不同节点的 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 没运行:

[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相关的镜像。所以我又搞了阿里云:

#!/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 让它重启吧。。。我就是这样才运行起的。。。

[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 服务

[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 就会变成这样:

[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 文件:

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的问题