天天看点

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

~~~