天天看點

kubelet配置cni插件_七,網絡插件calico

K8S網絡設計原則:

1.每個Pod都擁有一個獨立IP位址,Pod内所有容器共享一個網絡命名空間

2.叢集内所有Pod都在一個直接連通的扁平網絡中,可通過IP直接通路

所有容器之間無需NAT就可以直接互相通路

所有Node和所有容器之間無需NAT就可以直接互相通路

容器自己看到的IP跟其他容器看到的一樣

3.Service cluster IP可在叢集内部通路,外部請求需要通過NodePort、LoadBalance或者Ingress來通路

Container Network Interface (CNI)是目前CNCF主推的網絡模型,它由兩部分組成:

CNI Plugin負責給容器配置網絡,它包括兩個基本的接口

配置網絡: AddNetwork(net *NetworkConfig, rt *RuntimeConf) (types.Result, error)

清理網絡: DelNetwork(net *NetworkConfig, rt *RuntimeConf) error

IPAM Plugin負責給容器配置設定IP位址

Kubernetes Pod的網絡是這樣建立的:

0.每個Pod除了建立時指定的容器外,都有一個kubelet啟動時指定的基礎容器,比如:google_container/pause-amd64:v3.1

1.首先 kubelet建立基礎容器生成network namespace

2.然後 kubelet調用網絡CNI driver,由它根據配置調用具體的CNI 插件

3.然後 CNI 插件給基礎容器配置網絡

4.最後 Pod 中其他的容器共享使用基礎容器的網絡

本文檔基于CNI driver 調用calico 插件來配置kubernetes的網絡,常用CNI插件有 flannel calico weave等等,這些插件各有優勢,也在互相借鑒學習優點,比如:在所有node節點都在一個二層網絡時候,flannel提供hostgw實作,避免vxlan實作的udp封裝開銷,估計是目前最高效的;calico也針對L3 Fabric,推出了IPinIP的選項,利用了GRE隧道封裝;是以這些插件都能适合很多實際應用場景,這裡選擇calico,主要考慮它支援 kubernetes network policy。

**安裝calicoctl**

随便一台節點安裝即可,這裡使用master01節點安裝。

wget https://github.com/projectcalico/calico/releases/download/v3.1.3/release-v3.1.3.tgz

tar -xf release-v3.1.3.tgz

cp release-v3.1.3/bin/calicoctl /usr/local/bin

chmod +x /usr/local/bin/calicoctl

**建立calicoctl配置檔案**

~~~

mkdir /etc/calico

vim /etc/calico/calicoctl.cfg

apiVersion: v1

kind: calicoApiConfig

metadata:

spec:

datastoreType: "etcdv2"

etcdEndpoints: "https://192.168.50.101:2379,https://192.168.50.102:2379,https://192.168.50.1:2379"

etcdKeyFile: "/etc/kubernetes/ssl/calico-key.pem"

etcdCertFile: "/etc/kubernetes/ssl/calico.pem"

etcdCACertFile: "/etc/kubernetes/ssl/calico.pem"

~~~

**拷貝所需yaml檔案**

官方安裝包裡提供的calico.yaml包含了所有所需角色,rabc.yaml為認證授權檔案,隻需要運作這2個yaml即可。

~~~

cd && mkdir calico

cp release-v3.1.3/k8s-manifests/rbac.yaml /root/calico

cp release-v3.1.3/k8s-manifests/hosted/calico.yaml /root/calico

cd calico

~~~

**修改calico.yaml**

`vim calico.yaml `

有3個地方需要改動:

1,ConfigMap對象下修改etcd_endpoints位址

![](https://box.kancloud.cn/85028e92f7d6e8a6bbb005455f8b735e_800x507.png)

2,ConfigMap對象下修改證書路徑,打開原檔案後面預設的注釋行即可。

![](https://box.kancloud.cn/3558b1390101fdc75c67f525bab2642a_800x505.png)

3,在secret裡添加base64編碼格式證書

![](https://box.kancloud.cn/699b02c534144f971e7386e07ccf70d8_800x272.jpg)

~~~

cat /etc/kubernetes/ssl/calico-key.pem | base64 | tr -d '\n'

cat /etc/kubernetes/ssl/calico.pem | base64 | tr -d '\n'

cat /etc/kubernetes/ssl/ca.pem | base64 | tr -d '\n'

~~~

![](https://box.kancloud.cn/745e87286897c7c16d0e2479d64c7a8f_800x338.png)

額外2個可選修改的參數:

![](https://box.kancloud.cn/45153642403208cee0986508992fb7cd_800x64.jpg)

**CALICO_IPV4POOL_CIDR**: Calico IPAM的IP位址池,Pod的IP位址将從該池中進行配置設定,修改為你期望的位址,建議和實體位址劃分開,我這裡使用172.30網段和實體機位址區分開。

**CALICO_IPV4POOL_IPIP**:是否啟用IPIP模式,啟用IPIP模式時,Calico将在node上建立一個tunl0的虛拟隧道,雲環境使用此模式。

不使用IPIP模式時,設定為"off",此時将使用BGP模式。IPIP是一種将各Node的路由之間做一個tunnel,再把兩個網絡連接配接起來的模式,啟用IPIP模式時,Calico将在各Node上建立一個名為"tunl0"的虛拟網絡接口。

**啟動calico服務**

提前在每個節點下載下傳好所需鏡像

quay.io/calico/kube-controllers:v3.1.3

quay.io/calico/node:v3.1.3

quay.io/calico/cni:v3.1.3

~~~

kubectl apply -f calico.yaml

kubectl apply -f rbac.yaml

~~~

**檢視服務運作狀态**

~~~

kubectl get pod -n kube-system

NAME READY STATUS RESTARTS AGE

calico-kube-controllers-98989846-gq7hw 1/1 Running 0 52m

calico-node-8c95z 2/2 Running 0 52m

calico-node-gbzld 2/2 Running 0 52m

calico-node-vs5lc 2/2 Running 0 52m

~~~

等待全部Running後在進行後續操作

**修改kubelet配置檔案**

~~~

vim /etc/kubernetes/kubelet

KUBELET_ARGS= 添加 --network-plugin=cni

systemctl restart kubelet #修改後注意重新開機kubelet

~~~

**使用calicoctl檢視服務狀态**

~~~

calicoctl node status

Calico process is running.

IPv4 BGP status

+----------------+-------------------+-------+----------+-------------+

| PEER ADDRESS | PEER TYPE | STATE | SINCE | INFO |

+----------------+-------------------+-------+----------+-------------+

| 192.168.50.102 | node-to-node mesh | up | 06:30:56 | Established |

| 192.168.50.1 | node-to-node mesh | up | 06:36:46 | Established |

+----------------+-------------------+-------+----------+-------------+

IPv6 BGP status

No IPv6 peers found.

~~~

**網卡上生成tunl0并擷取172.30網段ip**

~~~

ifconfig

tunl0: flags=193 mtu 1440

inet 172.30.241.64 netmask 255.255.255.255

tunnel txqueuelen 1 (IPIP Tunnel)

RX packets 0 bytes 0 (0.0 B)

RX errors 0 dropped 0 overruns 0 frame 0

TX packets 0 bytes 0 (0.0 B)

TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

~~~

**每個節點都生成了去向其他節點的路由**

~~~

route -n

Kernel IP routing table

Destination Gateway Genmask Flags Metric Ref Use Iface

0.0.0.0 192.168.50.253 0.0.0.0 UG 0 0 0 eth0

169.254.0.0 0.0.0.0 255.255.0.0 U 1002 0 0 eth0

172.17.0.0 0.0.0.0 255.255.0.0 U 0 0 0 docker0

172.30.59.192 192.168.50.102 255.255.255.192 UG 0 0 0 tunl0

172.30.196.128 192.168.50.1 255.255.255.192 UG 0 0 0 tunl0

172.30.241.64 0.0.0.0 255.255.255.192 U 0 0 0 *

172.30.241.65 0.0.0.0 255.255.255.255 UH 0 0 0 cali0d46f3216c3

192.168.50.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0

~~~

**calico 3.x 版本預設使用 etcd v3存儲,在etcd節點檢視calico相關記錄**

~~~

# 檢視所有calico相關資料

etcdssl get /calico --prefix --keys-only=true

# 檢視 calico網絡為各節點配置設定的網段

etcdssl get /calico/ipam/v2/host --prefix --keys-only=true

~~~

為什麼前邊yaml中很多參數都沒填?install-cni容器啟動時會執行/install-cni.sh腳本,腳本會将預設的設定替換成正确的設定,其中證書部分就是從secret中提取出來的,具體腳本内的操作進入容器檢視,生成cni的位置/etc/cni/net.d;

![](https://box.kancloud.cn/237694b33ac509e4f52e4e8dbdd74905_1349x504.png)

BGP 協定是通過TCP 連接配接來建立鄰居的,是以可以用netstat 指令驗證 BGP Peer

~~~

netstat -antlp|grep ESTABLISHED|grep 179

tcp 0 0 192.168.50.101:179 192.168.50.102:59753 ESTABLISHED 15306/bird

tcp 0 0 192.168.50.101:37892 192.168.50.1:179 ESTABLISHED 15306/bird

~~~

**驗證calico網絡可用性**

建立一個pod

~~~

vim pod.yaml

apiVersion: v1

kind: Pod

metadata:

name: centos

namespace: default

spec:

containers:

- image: centos

command:

- sleep

- "360000"

imagePullPolicy: IfNotPresent

name: centos

restartPolicy: Always

~~~

建立一個deploy

~~~

vim nginx.yaml

apiVersion: extensions/v1beta1

kind: Deployment

metadata:

name: nginx-deploy

spec:

replicas: 2

template:

metadata:

labels:

run: my-nginx

spec:

containers:

- name: my-nginx

image: nginx:latest

ports:

- containerPort: 80

---

apiVersion: v1

kind: Service

metadata:

name: nginx-svc

spec:

ports:

- port: 8888

targetPort: 80

selector:

run: my-nginx

~~~

檢視pod已經配置設定到172.30.x.x網段的ip

~~~

kubectl apply -f nginx.yaml -f pod.yaml

kubectl get pod -o wide

NAME READY STATUS RESTARTS AGE IP NODE

centos 1/1 Running 0 17s 172.30.196.129 172.16.60.1

nginx-deploy-64669f548f-brg6f 1/1 Running 0 17s 172.30.59.193 172.16.60.102

nginx-deploy-64669f548f-gmllr 1/1 Running 0 17s 172.30.241.65 172.16.60.101

~~~

進入容器,ping其他pod的ip是通的

~~~

kubectl exec -it centos /bin/sh

[[email protected] /]# ping 172.30.241.65

PING 172.30.241.65 (172.30.241.65) 56(84) bytes of data.

64 bytes from 172.30.241.65: icmp_seq=1 ttl=62 time=0.384 ms

64 bytes from 172.30.241.65: icmp_seq=2 ttl=62 time=0.330 ms

64 bytes from 172.30.241.65: icmp_seq=3 ttl=62 time=0.322 ms

~~~

從實體節點ping pod的ip也是通的

~~~

ping 172.30.59.193

PING 172.30.59.193 (172.30.59.193) 56(84) bytes of data.

64 bytes from 172.30.59.193: icmp_seq=1 ttl=63 time=0.433 ms

64 bytes from 172.30.59.193: icmp_seq=2 ttl=63 time=0.293 ms

~~~