K8s四层负载均衡-service
Kubernetes 的 四层负载均衡 其实就是通过 Service 在 TCP/UDP 层(L4)来做的,工作在 OSI 第四层(传输层),不解析 HTTP 协议内容,而是直接根据 IP + 端口 转发流量。
一、Service 的类型和四层关系
K8s 中四层负载均衡主要用以下 Service 类型:
类型 说明 典型场景 ClusterIP(默认) 只在集群内部提供访问,L4 负载到后端 Pod 集群内部通信 NodePort 暴露到每个 Node 节点的固定端口,外部可访问,L4 负载 小规模测试或简单对外服务 LoadBalancer 依赖云厂商的 L4 LB(如 AWS ELB、阿里云 SLB),直接获取外网 IP 公网服务 ExternalName DNS 级别转发,不是真正的负载均衡 特殊场景
二、创建 Service 资源创建 Service 资源
kubectl explain service
1、ClusterIP类型
vim pod_test.yamlapiVersion: apps/v1 kind: Deployment metadata:name: my-nginx spec:selector:matchLabels:run: my-nginxreplicas: 2template:metadata:labels:run: my-nginxspec:containers:- name: my-nginximage: nginximagePullPolicy: IfNotPresentports:- containerPort: 80kubectl apply -f pod_test.yaml kubectl get pods -l run=my-nginx -o wide
现在看到的ip是随机分配的,删除pod重新生成后ip会改变
创建 Service
apiVersion: v1 kind: Service metadata:name: my-nginxlabels:run: my-nginx spec:type: ClusterIPports:- port: 80protocol: TCPtargetPort: 80selector:run: my-nginxkubectl apply -f service_test.yaml kubectl get svc -l run=my-nginx
port: 80
→ Service 暴露的端口,集群内访问ServiceIP:80
。
protocol: TCP
→ 使用 TCP 协议(默认)。
targetPort: 80
→ Pod 内容器监听的端口(对应 Deployment 中的containerPort: 80
)Service 会把流量转发给所有带
run=my-nginx
标签的 Pod。这和你的 Deployment 模板里
labels: run: my-nginx
一一对应。所以,这个 Service 会把流量均衡分发到你 Deployment 创建的那两个 nginx Pod 上。
2、NodePort类型
vim pod_nodeport.yamlapiVersion: apps/v1 kind: Deployment metadata:name: my-nginx-nodeport spec:replicas: 2selector:matchLabels:run: my-nginx-nodeporttemplate:metadata:labels:run: my-nginx-nodeportspec:containers:- name: my-nginx-nodeport-containerimage: nginximagePullPolicy: IfNotPresentports:- containerPort: 80kubectl apply -f pod_nodeport.yaml kubectl get pods -l run=my-nginx-nodeport
创建service
vim service_nodeport.yamlapiVersion: v1 kind: Service metadata:name: my-nginx-nodeportlabels:run: my-nginx-nodeport spec:type: NodePortselector:run: my-nginx-nodeportports:- port: 80protocol: TCPtargetPort: 80nodePort: 30380kubectl apply -f service_nodeport.yaml kubectl get svc -l run=my-nginx-nodeport
然后根据ip加端口就可以访问了
3、ExternalName类型
vim client.yamlapiVersion: apps/v1 kind: Deployment metadata:name: client spec:replicas: 1selector:matchLabels:app: busyboxtemplate:metadata:labels:app: busyboxspec:containers:- name: busyboximage: busyboxcommand: ["/bin/sh", "-c", "sleep 36000"]kubectl apply -f client.yaml
vim client_svc.yamlapiVersion: v1 kind: Service metadata:name: client-svc spec:type: ExternalNameexternalName: nginx-svc.nginx-ns.svc.cluster.localports:- name: httpport: 80targetPort: 80
kubectl get podskubectl apply -f client_svc.yamlkubectl create ns nginx-nsvim cat server_nginx.yamlapiVersion: apps/v1 kind: Deployment metadata:name: nginxnamespace: nginx-ns spec:replicas: 1selector:matchLabels:app: nginxtemplate:metadata:labels:app: nginxspec:containers:- name: nginximage: nginximagePullPolicy: IfNotPresentkubectl apply -f server_nginx.yaml kubectl get pods -n nginx-ns
vim nginx_svc.yamlapiVersion: v1 kind: Service metadata:name: nginx-svcnamespace: nginx-ns spec:selector:app: nginxports:- name: httpprotocol: TCPport: 80targetPort: 80kubectl apply -f nginx_svc.yaml
进入容器访问
wget -q -O - client-svc.default.svc.cluster.localwget -q -O - nginx-svc.nginx-ns.svc.cluster.local看到结果一样
###有待补充。。。。