27、K8S-资源对象-Service【IPVS代理模式】
1、基础知识
1.1、知识点回顾
1.2、关键点
ipvs会在每个节点上创建一个名为kube-ipvs0的虚拟接口,并将集群所有Service对象的ClusterIP和ExternalIP都配置在该接口; - 所以每增加一个ClusterIP 或者 EternalIP,就相当于为 kube-ipvs0 关联了一个地址罢了。 kube-proxy为每个service生成一个虚拟服务器( IPVS Virtual Server)的定义。
1.3、基本流程
所以当前节点接收到外部流量后,如果该数据包是交给当前节点上的clusterIP,则会直接将数据包交 给kube-ipvs0,而这个接口是内核虚拟出来的,而kube-proxy定义的VS直接关联到kube-ipvs0上。 如果是本地节点pod发送的请求,基本上属于本地通信,效率是非常高的。 默认情况下,这里的ipvs使用的是nat转发模型,而且支持更多的后端调度算法。仅仅在涉及到源地址转换的场景中,会涉及到极少量的iptables规则(应该不会超过20条)
2、环境准备
# 有安装kube-proxy的主机,都需要安装 yum install ipset ipvsadm -y #加载模块到内核 modprobe ip_vs modprobe ip_vs_rr modprobe ip_vs_wrr modprobe ip_vs_sh modprobe nf_conntrack # 在/etc/modules-load.d/k8s.conf中加入ipvs相关模块,使其开机自动加载到内核。 cat >> /etc/modules-load.d/k8s.conf << 'EOF' ip_vs ip_vs_rr ip_vs_wrr ip_vs_sh nf_conntrack EOF
3、模式解析
3.1、从哪里修改代理模式
对于k8s来说,默认情况下,支持的规则是 iptables,我们可以通过多种方式对我们的代理模式进行更改,
因为这些规则都是基于kube-proxy来定制的,所以,我们如果要更改代理模式的话,就需要调整kubeproxy的属性。
3.2、查看kube-proxy的所有属性信息
master1 ~]# kubectl -n kube-system get configmaps NAME DATA AGE coredns 1 6d13h extension-apiserver-authentication 6 6d13h kube-flannel-cfg 2 6d13h kube-proxy 2 6d13h kube-root-ca.crt 1 6d13h kubeadm-config 1 6d13h kubelet-config 1 6d13h master1 ~]# kubectl -n kube-system describe configmap kube-proxy ... iptables: localhostNodePorts: null masqueradeAll: false # 这个属性打开的话,会对所有的请求都进行源地址转换 masqueradeBit: null minSyncPeriod: 0s syncPeriod: 0s ipvs: # 调度算法,默认是randomrobin excludeCIDRs: null minSyncPeriod: 0s scheduler: "" strictARP: false syncPeriod: 0s tcpFinTimeout: 0s tcpTimeout: 0s udpTimeout: 0s kind: KubeProxyConfiguration metricsBindAddress: "" mode: "" # 默认没有指定,就是使用 iptables 规则 ...
3.3、kube-proxy修改ipvs代理模式的方法
3.3.1、方法1:资源清单的修改方法
# 初始化集群的时候配置好 --- apiVersion: kubeproxy.config.k8s.io/v1alpha1 kind: KubeProxyConfiguration featureGates: SupportIPVSProxyMode: true mode: ipvs
3.3.2、方法2:configmap修改方法
master1 ~]# kubectl -n kube-system get cm | grep proxy kube-proxy 2 6d15h # 修改模式mode ipvs master1 ~]# kubectl -n kube-system edit configmap kube-proxy apiVersion: v1 data: config.conf: |- ... kind: KubeProxyConfiguration metricsBindAddress: "" mode: "ipvs" # 通过标签批量删除pod master1 ~]# kubectl -n kube-system delete pod -l k8s-app=kube-proxy # 重新启动成功 master1 ~]# kubectl -n kube-system get pods | grep proxy kube-proxy-bwvs4 1/1 Running 0 41s kube-proxy-cmbgp 1/1 Running 0 41s kube-proxy-kdxbd 1/1 Running 0 41s kube-proxy-mkgjg 1/1 Running 0 41s kube-proxy-vrljp 1/1 Running 0 40s # 随机抽一个pod查看日志 master1 ~]# kubectl -n kube-system logs -f kube-proxy-bwvs4 ... I0323 03:24:40.713799 1 proxier.go:462] "IPVS scheduler not specified, use rr by default" # 默认使用rr调试模式 ... # 在master或node查看LVS的调度情况 [root@node1 ~]# ipvsadm -Ln IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 172.17.0.1:30001 rr -> 10.244.4.29:8000 Masq 1 0 0 TCP 172.17.0.1:30443 rr -> 10.244.4.8:8443 Masq 1 0 0
4、实践
4.1、实践1-验证IPVS是否成功
4.1.1、定义资源配置清单
cat > service-ipvs.yml<<'EOF' apiVersion: v1 kind: Pod metadata: name: nginx-test labels: app: my-nginx spec: containers: - name: nginx image: 192.168.10.33:80/k8s/my_nginx:v1 --- kind: Service apiVersion: v1 metadata: name: service-test1 spec: type: NodePort selector: app: my-nginx ports: - name: http protocol: TCP port: 80 targetPort: 80 nodePort: 30089 EOF
4.1.2、应用资清配置清单
master1 ]# kubectl apply -f service-ipvs.yml pod/nginx-test created service/service-test1 created master1 service]# kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES nginx-test 1/1 Running 0 87s 10.244.3.214 node1 <none> <none> master1 ]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service-test1 NodePort 10.106.71.137 <none> 80:30089/TCP 9s
4.1.3、查看ipvsadm规则
master1 ]# ipvsadm -Ln TCP 10.106.71.137:80 rr # 集群的IP地址 -> 10.244.3.214:80 Masq 1 0 0 # pod的IP地址
4.1.4、查看iptables规则
# 查看ipvsadm规则 node1 ~]# iptables -t nat -S KUBE-NODE-PORT -N KUBE-NODE-PORT -A KUBE-NODE-PORT -p tcp -m comment --comment "Kubernetes nodeport TCP port for masquerade purpose" -m set --match-set KUBE-NODE-PORT-TCP dst -j KUBE-MARK-MASQ node2 ~]# iptables -t nat -S KUBE-NODE-PORT -N KUBE-NODE-PORT -A KUBE-NODE-PORT -p tcp -m comment --comment "Kubernetes nodeport TCP port for masquerade purpose" -m set --match-set KUBE-NODE-PORT-TCP dst -j KUBE-MARK-MASQ 总结: 所有的规则自动转换成 ipvsadm了,iptables规则没有生成了。