k8s 网络代理(kube-proxy
)在每个节点上运行。网络代理反映了每个节点上 Kubernetes API 中定义的服务,并且可以执行简单的 TCP、UDP 和 SCTP 流转发,或者在一组后端进行 循环 TCP、UDP 和 SCTP 转发。但是,必须要有一个插件,才可以实现相应的通信功能,它的作用是使发往 Service 的流量(通过ClusterIP和端口)负载均衡到正确的后端Pod。
kube-proxy的理解
kube-proxy通过网络插件,实现网络请求转发,网络插件就是CNI接口的具体实现,其中iptables性能没有ipvs效果好,因为ipvs的时间复杂度是o1,而iptables需要循环遍历,容器越多,节点越多iptables性能就会下降
配置参数列表
https://kubernetes.io/zh-cn/docs/reference/command-line-tools-reference/kube-proxy/
一份kube-proxy的配置文件
apiVersion: kubeproxy.config.k8s.io/v1alpha1
bindAddress: 0.0.0.0
clientConnection:
acceptContentTypes: ""
burst: 0
contentType: ""
kubeconfig: /var/lib/kube-proxy/kubeconfig.conf
qps: 0
clusterCIDR: 10.100.0.0/16
configSyncPeriod: 0s
conntrack:
maxPerCore: null
min: null
tcpCloseWaitTimeout: null
tcpEstablishedTimeout: null
detectLocalMode: ""
enableProfiling: false
featureGates:
SupportIPVSProxyMode: true
healthzBindAddress: ""
hostnameOverride: ""
iptables:
masqueradeAll: false
masqueradeBit: null
minSyncPeriod: 0s
syncPeriod: 0s
ipvs:
excludeCIDRs: null
minSyncPeriod: 0s
scheduler: ""
strictARP: false
syncPeriod: 0s
tcpFinTimeout: 0s
tcpTimeout: 0s
udpTimeout: 0s
kind: KubeProxyConfiguration
metricsBindAddress: ""
mode: iptables
nodePortAddresses: null
oomScoreAdj: null
portRange: ""
showHiddenMetricsForVersion: ""
udpIdleTimeout: 0s
winkernel:
enableDSR: false
networkName: ""
sourceVip: ""
简单说明这份配置文件
配置文件中表明了kubeproxy支持iptables、ipvs、Winkernel、Conntrack四种模式,也可能支持其他模式,但是我不清楚,配置文件中明确使用模式为iptables(这是因为我的集群版本是1.18,无法使用ipvs)
CNI(容器网络接口)
网络不通,一切为零,容器想要正常运行,那么网络是必不可少的,部分容器具备网络系统,例如,Docker有内置的网络系统,但是并不是所有的容器都有这样的网络系统,如果k8s想要做到包容万象,那么使用一套标准行为规范的容器网络协议是很有必要的,k8s使用的是CNI接口层,CNI(Conteinre Network Interface) 是 google 和 CoreOS 主导制定的容器网络标准,它本身并不是实现或者代码,可以理解成一个协议。这个标准是在 rkt 网络提议的基础上发展起来的,综合考虑了灵活性、扩展性、ip 分配、多网卡等因素
CNI接口都规定了什么?
查看源代码
https://github.com/containernetworking/cni/blob/main/libcni/api.go
CNI的规范真的简单
- 给我一个路径,让我识别到CNI配置列表(支持多个网络插件,上图代码100行),上图中131、132两行为必填参数
- 当需要使用插件时,比如新增网络、删除网络等,执行101行代码,
- 插件自己处理网络分配,完成业务
CNI的简单规范,使得插件支持百花齐放,每种插件都有不同的特点
一份简单的calico插件清单
网络插件配置目录在/etc/cni/net.d/
网络插件的具体二进制文件在 /opt/cni/bin
目录下
10-calico.conflist
内容如下
{
"name": "k8s-pod-network", # 必填
"cniVersion": "0.3.1", # 必填
"plugins": [
{
"type": "calico", # 插件的具体类型
"log_level": "info", # 日志等级配置
"log_file_path": "/var/log/calico/cni/cni.log", # 日志目录配置
"datastore_type": "kubernetes",
"nodename": "k8s-master-1",
"mtu": 0,
"ipam": {
"type": "calico-ipam"
},
"policy": {
"type": "k8s"
},
"kubernetes": {
"kubeconfig": "/etc/cni/net.d/calico-kubeconfig" # 插件使用的k8s配置
}
},
{
"type": "portmap",
"snat": true,
"capabilities": {"portMappings": true}
},
{
"type": "bandwidth",
"capabilities": {"bandwidth": true}
}
]
}
calico-kubeconfig
配置如下
# Kubeconfig file for Calico CNI plugin.
apiVersion: v1
kind: Config
clusters:
- name: local
cluster:
server: https://[10.200.0.1]:443
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUN5RENDQWJDZ0F3SUJBZ0lCQURBTkJna3Foa2lHOXcwQkFRc0ZBREFWTVJNd0VRWURWUVFERXdwcmRXSmwKY201bGRHVnpNQjRYRFRJeU1EY3hNekEwTkRBME5Wb1hEVE15TURjeE1EQTBOREEwTlZvd0ZURVRNQkVHQTFVRQpBeE1LYTNWaVpYSnVaWFJsY3pDQ0FTSXdEUVlKS29aSWh2Y05BUUVCQlFBRGdnRVBBRENDQVFvQ2dnRUJBTlJRCmxsWkZndzFVaFN5TFJIYk01UnpNYXN2eTNKL1ZOK1lISE5DT1lqeDJNODNCOFZzc09jaGw4S1hOdjJKckMrL3EKUVRNcXl4U0hhNHltZWg3SXI3d2dUTjFJTTNqdEdyZk5ONHhJQ1k2ZTlMWnVuSlB6V3FHQTdnOXF2M0ViN29FMAplQyt3MEtaRGcwazB1VGx4bUhTWFp0a1Z3eEtCSkdmV2xabDdZVDdXK2lXT0h6SVdpVTM2bWRUdGVJclhqbksxClBKeFl1VWE5TEVRSWltSGVBMk9zVk01YjMxbE9mVDVsdVptWWRjYWxZYUNmMlEwMWtJa2NBQmtnTHRSbFhQTXUKNk5MN2dqRFFueTVGbjlmUWRCN0tyWEFsVWEwS2hrMitiM2VhdGNZVmw2TG1DbTFTTkhQUjhLclM3bDdPUU9IVAo3MThtZ0luUENkVWNUNFI2dUVVQ0F3RUFBYU1qTUNFd0RnWURWUjBQQVFIL0JBUURBZ0trTUE4R0ExVWRFd0VCCi93UUZNQU1CQWY4d0RRWUpLb1pJaHZjTkFRRUxCUUFEZ2dFQkFENllXaWJIdkVmS09IZGxFVllTZS9TbjVFc0gKWDVyOGhuOHZFQ3l5bVR0bEk1N0JrY1VJL3pTWXJCMjdZRXVlbm54N2dneFJ3OTJVbzNBUUdSV2llVUVWVjlBNwpteFg2ZDNDWnNCNnExM1lLUnFMTXdnb2RaaGh1bVpoY0dyOHhubE1xS3hFdkZRcFlLbkVUdzRoWXlnZmZsUkRhCnNMaXM2WHNlczI3VjZhbVhVTDhpUFM5bTk1OEdJa3lWaEF3K25ZbVRJTHdieHBoTEZtKzJBK3hlRkdWbnJMWHkKMjNZUFVLdGI5THd3M29GQUFNa3VBOTFPc0p0VndLTDN3VHR4anU3TGhjZFpTYnpJbmZSNi9RWThnbE9JS3MzcQpJdXpMOU1ESHVIMW40TEcwamZwUGVqMnhqZUdhOUdyWHNEQVVlaU1URE1YOUxUMjVHdXo2NkwzdEN6az0KLS0tLS1FTkQgQ0VSVElGSUNBVEUtLS0tLQo=
users:
- name: calico
user:
token: eyJhbGciOiJSUzI1NiIsImtpZCI6Im5QbGNTbk5tR0p6U19VM0EydWdqUnZ3RzVCLVNVemNCeFlUZ3hwcFlOREEifQ.eyJpc3MiOiJrdWJlcm5ldGVzL3NlcnZpY2VhY2NvdW50Iiwia3ViZXJuZXRlcy5pby9zZXJ2aWNlYWNjb3VudC9uYW1lc3BhY2UiOiJrdWJlLXN5c3RlbSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VjcmV0Lm5hbWUiOiJjYWxpY28tbm9kZS10b2tlbi1sanR2YyIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQc2VydmljZS1hY2NvdW50Lm5hbWUiOiJjYWxpY28tbm9kZSIsImt1YmVybmV0ZXMuaW8vc2VydmljZWFjY291bnQvc2VydmljZS1hY2NvdW50LnVpZCI6IjRmMDJjOWJiLWZmZTUtNDRjOS05N2I4LTBlMTVmM2Q0MzllMSIsInN1YiI6InN5c3RlbTpzZXJ2aWNlYWNjb3VudDprdWJlLXN5c3RlbTpjYWxpY28tbm9kZSJ9.st-Pfb7ujDk8tegiIsYfhhH4FhQBQCLbYcFVa0IqDDBN0kCgb6nINLAP0g1G4INwxRwZ5DJ3XfHNxTLEKjgLLfTbqjq3r1AhvNV98fbS89p5TPvZS8ydaHQxhnLuaPPc8cU_4zKcmq1QxR2fyHNNyGmvkI09Mb3e-ob9a_9cBiDzw6MPeHG1I1YH-L8KQfzo-CdPpZcIm430HbRaTgI6XvjzaLVewfqGR3UlucgBLSR8HC2r1cRWtXwPiquGpdtFhrimKhpveZNNkUrB7ef6dDFTX1z0KiIB8ogReXyHF3yPtpG1dX63ESKtw9bB5lQAp1kwMtxpkMR-yOB4Ja9_5A
contexts:
- name: calico-context
context:
cluster: local
user: calico
current-context: calico-context
查看k8s支持网络插件二进制文件
查看calico的yml,发现calico是使用ds模式,将二进制文件挂载到每个node的目录中,因此,每个节点的kube-proxy,均可以使用calico的网络,实现pod之间的网络转发通信
https://docs.projectcalico.org/manifests/calico.yaml
kube-proxy总结
- 负责转发网络请求
- 内部使用CNI容器网络接口与网络组件进行通信
- CNI的插件具有很多种类,且特性各不相同
- 网络插件配置目录在
/etc/cni/net.d/
- 网络插件的具体二进制文件在
/opt/cni/bin
目录下 - calico是通过ds模式,挂载master的二进制文件和相关网络配置信息,然后分发到各个node