一、基本网络概念
- Kubernetes网络通信情景
- 容器间通信:同一个Pod内的多个容器间的通信,lo
- Pod通信:PodIP <---> PodIP
- Pod与service通信:PodIP <---> ClusterIP
- Service与集群外部客户端的通信,Ingress,NodePort等
- CNI:容器网络接口
- flannel:支持网络管理,但是不支持网络策略
- calico:支持网络管理和网络策略
- canel
- kube-router
- 解决方案:
- 虚拟网桥:叠加网络方式实现
- 多路复用:MacVLAN机制,一张网卡多个POD使用
- 硬件交换:SR-IOV,单根IO虚拟化,将一张网卡虚拟出多个物理网卡
- kubelet网络插件配置
[root@master ~]# cat /etc/cni/net.d/10-flannel.conflist
{
"name": "cbr0",
"plugins": [
{
"type": "flannel",
"delegate": {
"hairpinMode": true,
"isDefaultGateway": true
}
},
{
"type": "portmap",
"capabilities": {
"portMappings": true
}
}
]
}
二、Flannel
flannel的三种网络实现方式
-
host-gw: host Gateway,直接路由传输,各节点维护一张路由表,将自己的物理网卡作为POD的网关,所有物理机必须在同一三层网络中
-
VxLAN
- vxlan:隧道模式,在物理机与物理机直接建立基于VxLAN的隧道承载POD直接的网络报文传输
- Directrouting:如果目标POD所在节点和原POD所在节点在同一三层网络中则使用host-gw方式通信,如果不在同一三层网络中则降级为vxlan模式通信
-
UDP
1、配置参数
# kubectl get configmap kube-flannel-cfg -n kube-system -o yaml #获取flannel的配置
- Network:flannel使用的CIDR格式的网络地址,用于为Pod配置网络功能
- SubnetLen:把Network切分子网供各节点使用时,使用多长的掩码进行切分,默认24位
- SubnetMin和SubnetMax:指定子网的开始和结束
- Backend:vxlan,host-gw,udp
2、开启Directrouting功能
# vim net-conf.json
{
"Network": "10.244.0.0/16",
"backend": {
"Type": "vxlan"
"Directrouting": true
}
}
# vim kube-flannel.yml #flannel编排文件中的配置修改为如上配置
# kubectl apply -f kube-flannel.yml
# ip route show
10.244.0.0/24 via 192.168.100.51 dev eth0 #有如此路由说明修改成功
10.244.2.0/24 via 192.168.100.62 dev eth0
三、Calico
1、部署canal
使用flannel提供网管理功能,使用calico提供网络策略功能,使用k8s的etcd为calico的元数据库
# curl https://docs.projectcalico.org/manifests/canal.yaml -O
# POD_CIDR="10.244.0.0/16" ;sed -i -e "s?10.244.0.0/16?$POD_CIDR?g" canal.yaml #修改your-pod-cidr
# kubectl apply -f canal.yaml
2、创建测试规则示例
- 拒绝所有入栈流量
# kubectl create namespace dev
# kubectl create namespace prod
# vim ingress-def.yaml #未定义ingress规则则表示拒绝所以入栈
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
spec:
podSelector: {} #表示选择所有pod
policyTypes:
- Ingress #表示入栈流量限制,出栈流量不限制
# kubectl apply -f ingress-def.yaml -n dev
# kubectl get netpol -n dev
# vim pod1.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
containers:
- name: myapp
image: dongfeimg/myapp:v1
# kubectl apply -f pod1.yaml -n dev
# kubectl apply -f pod1.yaml -n prod
# kubectl get po -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod1 1/1 Running 0 42s 10.244.2.2 node02 <none> <none>
# kubectl get po -n prod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod1 1/1 Running 0 41s 10.244.1.2 node01 <none> <none>
访问10.244.2.2无法访问,访问10.244.1.2可以访问,说明规则生效
- 放开所以入栈流量
# vim ingress-def.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
spec:
podSelector: {}
ingress:
- {} #允许所有入栈流量
policyTypes:
- Ingress
- 放行特定的入栈流量
# kubectl label pods pod1 app=myapp -n dev
# vim allow-netpol-demo.yaml
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-myapp-ingress
spec:
podSelector: #选择标签为myapp的pod
matchLabels:
app: myapp
ingress:
- from: #定义客户端的ip地址段
- ipBlock:
cidr: 10.244.0.0/16
except: #在10.244.0.0/16中排除10.244.1.2/32地址
- 10.244.1.2/32
ports: #定义只开放tcp/80
- protocol: TCP
port: 80
- protocol: TCP
port: 443