53.k8s的service应用管理-5
文章目录
第5部:kubernetes核心概念Service
service作用
使用kubernetes集群运行工作负载时,由于Pod经常处于用后即焚状态,Pod经常被重新生成,因此 Pod对应的IP地址也会经常变化,导致无法直接访问Pod提供的服务,Kuberetes中使用了Service来解决 这一问题,即在Pod前面使用Service对Pod进行代理,无论Pod怎样变化,只要有Label,就可以让 Service能够联系上Pod,把Pod lP地址添加到Service对应的端点列表(Endpoints)实现对Pod IP跟踪, 进而实现通过Service访问Pod目的。
- 通过service为pod客户端提供访问pod方法,即可客户端访问pod入口
- 通过标签动态感知podIP地址变化等
- 防止pod失联
- 定义访问pod访问策略
- 通过label-selector相关联
- 通过Service实现Pod的负载均衡(TCP/UDP4层)
- 底层实现由kube-proxy通过userspace、iptables、ipvs三种代理模式
kube-proxy三种代理模式
- kubernetes集群中有三层网络,一类是真实存在的,例如Node Network、Pod Network,提供真 实IP地址;一类是虚拟的,例如ClusterNetwork或Service Network,提供虚拟IP地址,不会出现在 接口上,仅会出现在Service当中
- kube-proxy始终watch(监控)kube-apiserver上关于Service相关的资源变动状态,一旦获取相关信 息kube:proxy都要把相关信息转化为当前节点之上的,能够实现Service资源调度到特定Pod之上 的规则,进而实现访问Service就能够获取Pod所提供的服务
- kube-proxy三种代理模式:userspace模式、iptables模式、ipvs模式
userspace模式
userspace 模式是 kube-proxy 使用的第一代模式,该模式在 kubernetes v1.0 版本开始支持使用。
userspace 模式的实现原理图示如下:

kube-proxy会为每个 Service 随机监听一个端口(proxyport),并增加一条 iptables规则。所以通过 ClusterlP:Port 访问 Service 的报文都redirect 到 proxy port,kube-proxy 从它监听的 proxy port 收到 报文以后,走 round robin(默认)或是 session affinity(会话亲和力,即同client IP 都走同一链路给同pod 服务),分发给对应的 pod。
由于 userspace 模式会造成所有报文都走一遍用户态(也就是Service 请求会先从用户空间进入内核 iptables,然后再回到用户空间,由kube-proxy 完成后端 Endpoints 的选择和代理工作),需要在内核 空间和用户空间转换,流量从用户空间进出内核会带来性能损耗,所以这种模式效率低、性能不高,不 推荐使用。

iptables模式
iptables 模式是 kube-proxy使用的第二代模式,该模式在 kubernetes v1.1版本开始支持,从v1.2 版本 开始成为 kube-proxy 的默认模式。
iptables 模式的负载均衡模式是通过底层 netfilter/iptables 规则来实现的,通过 informer 机制 Watch 接口实时跟踪 Service 和 Endpoint 的变更事件,并触发对 iptables 规则的同步更新。
iptables 模式的实现原理图示如下:

通过图示可以发现在 iptables模式下,kube proxy只是作为 controller,而不是server,真正服务的是 内核的 netfilter,体现在用户态 的是 iptables。所以整体的效率会比 userspace 模式高。

ipvs模式
ipvs 模式被 kube-proxy采纳为第三代模式,模式在 kubernetes v1.8 版本开始引入,在 v1.9 版本中处 于 beta 阶段,在 v1.11 版本中正式开始使用。
ipvs(iP Virtual Server)实现了传输层负载均衡,也就是4层交换,作为 Linux 内核的一部分。ipvs运行在 主机上,在真实服务器前充当负载均衡器。ipvs 可以将基于 TCP和 UDP 的服务请求转发到真实服务器 上,并使真实服务器上的服务在单个IP 地址上显示为虚拟服务。
ipvs 模式的实现原理图示如下:


ipvs 和 iptables 都是基于 netfilter 的,那么ipvs 模式有哪些更好的性能呢?
- ipvs 为大型集群提供了更好的可拓展性和性能
- ipvs 支持比 iptables 更复杂的负载均衡算法(包括:最小负载、最少连接、加权等)
- ipvs 支持服务器健康检查和连接重试等功能
- 可以动态修改 ipset的集合,即使iptables 的规则正在使用这个集合
ipvs 依赖于 iptables。ipvs 会使用 iptables 进行包过滤、airpin-masquerade tricks(地址伪装)、SNAT 等功能,但是使用的是 iptables 的扩展ipset,并不是直接调用 iptables 来生成规则链。通过 ipset 来存 储需要 DROP或 masquerade 的流量的源或目标地址,用于确保iptables 规则的数量是恒定的,这样我 们就不需要关心有多少 Service 或是 Pod 了。
使用 ipset 相较于 iptables有什么优点呢?iptables 是线性的数据结构,而ipset引入了带索引的数据结 构,当规则很多的时候,ipset 依然可以很高效的查找和匹配。可以将 ipset 简单理解为一个IP(段)的集 合,这个集合的内容可以是IP 地址、IP 网段、端口等,iptables 可以直接添加规则对这个“可变的集合进 行操作”,这样就可以大大减少iptables规则的数量,从而减少性能损耗。
举一个例子,如果我们要禁止成千上万个IP访问我们的服务器,如果使用 iptables 就需要一条一条的添 加规则,这样会在 iptables 中生成大量的规则:如果用ipset 就只需要将相关的IP 地址(网段)加入到 ipset 集合中,然后只需要设置少量的 iptables 规则就可以实现这个目标。
下面的表格是ipvs模式下维护的ipset表集合:

iptables与ipvs对比
- iptables
- 工作在内核空间
- 优点
- 灵活,功能强大(可以在数据包不同阶段对包进行操作)
- 缺点
- 表中规则过多时,响应变慢,即规则遍历匹配和更新,呈线性延时
- ipvs
- 工作在内核空间
- 优点
- 转发效率高
- 调度算法丰富:rr,wrr,lc,wlc,ip hash等
- 缺点
- 内核支持不全,低版本内核不能使用,需要升级到4.0或5.0以上。
- 使用iptables与ipvs时机
- 1.10版本之前使用iptables(1.1版本之前使用UserSpace进行转发)
- 1.11版本之后同时支持iptables与ipvs,默认使用ipvs,如果ipvs模块没有加载时,会自动降级至iptables
service类型
- ClusterIP
- 默认,分配一个集群内部可以访问的虚拟IP
- NodePort
- 在每个Node上分配一个端口作为外部访问入口
- nodePort端口范围为:30000-32767
- LoadBalancer
- 工作在特定的Cloud Provider上,例如Google Cloud,AWS,OpenStack
- ExternalName
- 表示把集群外部的服务引入到集群内部中来,即实现了集群内部pod和集群外部的服务进行通信
service参数
- port 访问service使用的端口
- targetPort Pod中容器端口
- nodePort 通过Node实现外网用户访问k8s集群内service(30000-32767)
service创建
Service的创建在工作中有两种方式,一是命令行创建,二是通过资源清单文件YAML文件创建。
1:ClusterIP类型
ClusterlP根据是否生成ClusterlP又可分为普通Service和Headless Service。
service两类:
- 普通service: 为Kubernetes的Service分配一个集群内部可访问的固定虚拟IP(Cluster IP),实现集群内的访问,。
- Headless Service
该服务不会分配Cluster Ip,也**不通过kube-proxy做反向代理和负载均衡。**而是通过DNS提供稳定的网络 ID来访问,DNS会将headless service的后端直接解析为pod IP列表。

ClusterIP Service
命令创建Service
创建deployment类型的应用
[root@docker-master service-dir]# vim nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: c1
image: nginx:1.26-alpine
ports:
- containerPort: 80
应用YAML文件
[root@docker-master service-dir]# kubectl apply -f nginx-deployment.yaml
deployment.apps/nginx-deploy created
验证
[root@docker-master service-dir]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deploy-5b6d5cd699-gcsm9 1/1 Running 0 18s 10.244.248.177 docker-node2 <none> <none>
nginx-deploy-5b6d5cd699-pkc5l 1/1 Running 0 18s 10.244.148.212 docker-node1 <none> <none>
[root@docker-master service-dir]# kubectl get deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deploy 2/2 2 2 41s
创建clusterIP类型service与Deployment类型应用关联
[root@docker-master service-dir]# kubectl expose deployment nginx-deploy --type=ClusterIP --target-port=80 --port=80
service/nginx-deploy exposed
说明
expose #创建service
deployment.apps #控制器类型
nginx-deploy #应用名称,也是service名称
--type=ClusterIP #指定service类型
--target-port=80 #指定Pod中容器端口
--port=80 #指定service端口
[root@docker-master service-dir]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 8d
nginx-deploy ClusterIP 10.99.127.250 <none> 80/TCP 16s
查看详情描述
[root@docker-master service-dir]# kubectl describe svc nginx-deploy
Name: nginx-deploy
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=nginx
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.99.127.250
IPs: 10.99.127.250
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.148.212:80,10.244.248.177:80
Session Affinity: None
Events: <none>
访问clusterIP就可以看到网页内容
[root@docker-master service-dir]# curl http://10.99.127.250
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
验证负载均衡功能
查看pod
[root@docker-master service-dir]# kubectl get pod
NAME READY STATUS RESTARTS AGE
nginx-deploy-5b6d5cd699-gcsm9 1/1 Running 0 5m58s
nginx-deploy-5b6d5cd699-pkc5l 1/1 Running 0 5m58s
修改nginx-deploy-5b6d5cd699-gcsm9网页内容为:this is web1
[root@docker-master service-dir]# kubectl exec -it nginx-deploy-5b6d5cd699-gcsm9 /bin/sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # cd /usr/share/nginx/html
/usr/share/nginx/html # echo "this is web1" > index.html
/usr/share/nginx/html #
修改nginx-deploy-5b6d5cd699-pkc5l网页内容为:this is web2
[root@docker-master service-dir]# kubectl exec -it nginx-deploy-5b6d5cd699-pkc5l /bin/sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
/ # cd /usr/share/nginx/html
/usr/share/nginx/html # echo "this is web2" > index.html
/usr/share/nginx/html #
验证网页显示
[root@docker-master service-dir]# curl http://10.99.127.250
this is web2
[root@docker-master service-dir]# curl http://10.99.127.250
this is web1
通过YAML文件创建service
编写YAML文件
[root@docker-master service-dir]# vim nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deploy
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: c1
image: nginx:1.26-alpine
ports:
- containerPort: 80
--- # 添加以下内容
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
type: ClusterIP
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
app: nginx
应用YAML
[root@docker-master service-dir]# kubectl delete svc nginx-deploy
service "nginx-deploy" deleted
[root@docker-master service-dir]# kubectl apply -f nginx-deployment.yaml
deployment.apps/nginx-deploy created
service/nginx-svc created
验证
[root@docker-master service-dir]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-deploy-5b6d5cd699-79d7n 1/1 Running 0 21s 10.244.148.206 docker-node1 <none> <none>
nginx-deploy-5b6d5cd699-h9r9z 1/1 Running 0 21s 10.244.248.178 docker-node2 <none> <none>
[root@docker-master service-dir]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 8d
nginx-svc ClusterIP 10.102.193.213 <none> 80/TCP 36s
[root@docker-master service-dir]# kubectl describe svc nginx-svc
Name: nginx-svc
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=nginx
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.102.193.213
IPs: 10.102.193.213
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.148.206:80,10.244.248.178:80
Session Affinity: None
Events: <none>
[root@docker-master service-dir]# kubectl get endpoints
NAME ENDPOINTS AGE
k8s-sigs.io-nfs-subdir-external-provisioner <none> 22h
kubernetes 192.168.108.30:6443 8d
nginx-svc 10.244.148.206:80,10.244.248.178:80 6m32s
[root@docker-master service-dir]# curl http://10.102.193.213
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
headless service
- 普通的clusterIP service是service name解析为cluster ip,然后cluster ip对应到后面pod ip。
- headless service是指service name直接解析为后面的pod ip
创建headless service的YAML文件
[root@docker-master service-dir]# vim nginx-headless.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-headless
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: c1
image: nginx:1.26-alpine
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-headless
spec:
type: ClusterIP #ClusterIP类型也是默认类型
clusterIP: None #None代表无头服务
ports: #指定service端口及容器端口
- port: 80 #service ip中的端口
targetPort: 80 #pod端口
protocol: TCP
selector: #指定后端pod标签
app: nginx
应用YAML文件
[root@docker-master service-dir]# kubectl apply -f nginx-headless.yaml
deployment.apps/nginx-headless unchanged
service/nginx-headless unchanged
查看
[root@docker-master service-dir]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 8d
nginx-headless ClusterIP None <none> 80/TCP 54s
[root@docker-master service-dir]# kubectl get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-headless-5b6d5cd699-c74cd 1/1 Running 0 67s 10.244.248.186 docker-node2 <none> <none>
nginx-headless-5b6d5cd699-cz4fz 1/1 Running 0 67s 10.244.148.214 docker-node1 <none> <none>
[root@docker-master service-dir]# kubectl get endpoints
NAME ENDPOINTS AGE
k8s-sigs.io-nfs-subdir-external-provisioner <none> 22h
kubernetes 192.168.108.30:6443 8d
nginx-headless 10.244.148.214:80,10.244.248.186:80 83s
DNS
DNS服务监视Kubernetes APl,为每一个Service创建DNS记录用于域名解析
headless service需要DNS来解决访问问题
DNS记录格式为:…svc.cluster.local.
查看kube-dns服务的IP
[root@docker-master service-dir]# kubectl get pod -o wide -n kube-system | grep dns
coredns-66f779496c-4bt9n 1/1 Running 13 (4h32m ago) 8d 10.244.219.106 master <none> <none>
coredns-66f779496c-nnkcw 1/1 Running 13 (4h32m ago) 8d 10.244.219.104 master <none> <none>
[root@docker-master service-dir]# kubectl get svc -n kube-system | grep dns
kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 8d
在集群主机通过DNS服务地址查找无头服务的dns解析
[root@docker-master service-dir]# dig -t a nginx-headless.default.svc.cluster.local. @10.96.0.10
; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.16 <<>> -t a nginx-headless.default.svc.cluster.local. @10.96.0.10
;; global options: +cmd
;; Got answer:
;; WARNING: .local is reserved for Multicast DNS
;; You are currently testing what happens when an mDNS query is leaked to DNS
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 30160
;; flags: qr aa rd; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;nginx-headless.default.svc.cluster.local. IN A
;; ANSWER SECTION:
nginx-headless.default.svc.cluster.local. 30 IN A 10.244.148.214
nginx-headless.default.svc.cluster.local. 30 IN A 10.244.248.186
;; Query time: 5 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: 四 1月 22 13:58:15 CST 2026
;; MSG SIZE rcvd: 181
在集群内创建pod进行解析
[root@docker-master service-dir]# kubectl run -it centos --image=centos:7 --image-pull-policy=IfNotPresent
If you don't see a command prompt, try pressing enter.
[root@centos /]# curl http://nginx-headless.default.svc.cluster.local.
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
2:NodePort类型
创建YAML文件
[root@docker-master service-dir]# vim nginx-nodeport.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-nodeport
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: c1
image: nginx:1.26-alpine
ports:
- containerPort: 80 # 容器端口
---
apiVersion: v1
kind: Service
metadata:
name: nginx-nodeport
spec:
type: NodePort
ports:
- port: 8060 # Service端口,内部集群访问端口
targetPort: 80 # Pod端口
nodePort: 31111 # node节点端口,外部访问集群的端口 范围30000-32767
protocol: TCP
selector:
app: nginx
应用YAML文件
[root@docker-master service-dir]# kubectl apply -f nginx-nodeport.yaml
deployment.apps/nginx-nodeport created
service/nginx-nodeport created
查看
[root@docker-master service-dir]# kubectl get svc,pod
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 8d
service/nginx-nodeport NodePort 10.108.158.161 <none> 8060:31111/TCP 64s
NAME READY STATUS RESTARTS AGE
pod/nginx-nodeport-5b6d5cd699-k4sfz 1/1 Running 0 64s
pod/nginx-nodeport-5b6d5cd699-p6plj 1/1 Running 0 64s
[root@docker-master service-dir]# kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-nodeport 2/2 2 2 80s
直接使用浏览器访问
http://192.168.108.30:31111/

http://192.168.108.31:31111/

http://192.168.108.32:31111/

3:LoadBalancer
是一个插件
集群外访问过程
- 用户
- 域名
- 云服务提供商提供LB服务
- NodeIP:Port(service IP)
- Pod IP:端口

MetalLB
自建kubernetes的loadbalancer类型服务方案
MetalLB可以为kubernetes集群中的Service提供网络负载均衡功能
MetalLB两大功能为:
- 地址分配,类似于DHCP
- 外部通告,一旦MetalLB为服务分配了外部IP地址,它就需要使群集之外的网络意识到该IP在群集 中"存在"。MetalLB使用标准路由协议来实现此目的:ARP,NDP或BGP。
参考文档:https://metallb.universe.tf/installation/
下载资源清单文件
v0.12
[root@docker-master load-dir]# wget https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/namespace.yaml
--2026-01-22 15:00:38-- https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/namespace.yaml
正在解析主机 raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.111.133, 185.199.108.133, 185.199.109.133, ...
正在连接 raw.githubusercontent.com (raw.githubusercontent.com)|185.199.111.133|:443... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:91 [text/plain]
正在保存至: “namespace.yaml”
100%[========================================================================>] 91 --.-K/s 用时 0s
2026-01-22 15:00:39 (9.14 MB/s) - 已保存 “namespace.yaml” [91/91])
[root@docker-master load-dir]# wget https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/metallb.yaml
--2026-01-22 15:01:03-- https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/metallb.yaml
正在解析主机 raw.githubusercontent.com (raw.githubusercontent.com)... 185.199.110.133, 185.199.111.133, 185.199.108.133, ...
正在连接 raw.githubusercontent.com (raw.githubusercontent.com)|185.199.110.133|:443... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:9383 (9.2K) [text/plain]
正在保存至: “metallb.yaml”
100%[========================================================================>] 9,383 --.-K/s 用时 0.01s
2026-01-22 15:01:04 (850 KB/s) - 已保存 “metallb.yaml” [9383/9383])
应用文件
[root@docker-master load-dir]# kubectl apply -f namespace.yaml
namespace/metallb-system created
[root@docker-master load-dir]# kubectl apply -f metallb.yaml
serviceaccount/controller created
serviceaccount/speaker created
clusterrole.rbac.authorization.k8s.io/metallb-system:controller created
clusterrole.rbac.authorization.k8s.io/metallb-system:speaker created
role.rbac.authorization.k8s.io/config-watcher created
role.rbac.authorization.k8s.io/pod-lister created
role.rbac.authorization.k8s.io/controller created
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:controller created
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:speaker created
rolebinding.rbac.authorization.k8s.io/config-watcher created
rolebinding.rbac.authorization.k8s.io/pod-lister created
rolebinding.rbac.authorization.k8s.io/controller created
daemonset.apps/speaker created
deployment.apps/controller created
resource mapping not found for name: "controller" namespace: "" from "metallb.yaml": no matches for kind "PodSecurityPolicy" in version "policy/v1beta1"
ensure CRDs are installed first
resource mapping not found for name: "speaker" namespace: "" from "metallb.yaml": no matches for kind "PodSecurityPolicy" in version "policy/v1beta1"
ensure CRDs are installed first
查看
[root@docker-master load-dir]# kubectl get ns
NAME STATUS AGE
default Active 9d
kube-node-lease Active 9d
kube-public Active 9d
kube-system Active 9d
kubernetes-dashboard Active 8d
metallb-system Active 67m
[root@docker-master load-dir]# kubectl get pod -n metallb-system
NAME READY STATUS RESTARTS AGE
controller-8d6664589-7dvg2 1/1 Running 0 6m38s
speaker-njbtc 1/1 Running 0 6m38s
speaker-qf5vw 1/1 Running 0 6m38s
问题解决:如果出现pod中有失败状态,可以在node节点中直接导入镜像文件(metallb_controller.tar 和metallb_speaker.tar),解决镜像下载问题
可以给metallb做资源配置
[root@docker-master load-dir]# kubectl get configmap -n metallb-system
NAME DATA AGE
kube-root-ca.crt 1 68m
准备metalLB配置文件
[root@docker-master load-dir]# vim metallb-conf.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: config #必须是config名称,否则无法获取地址
namespace: metallb-system
data:
config: |
address-pools:
- name: default
protocal: layer2
addresses:
- 192.168.108.180-192.168.108.200 #与集群节点服务器处于同一网段
应用yaml文件
[root@docker-master load-dir]# kubectl apply -f metallb-conf.yaml
configmap/config created
查看
[root@docker-master load-dir]# kubectl get configmap -n metallb-system
NAME DATA AGE
config 1 59s
kube-root-ca.crt 1 71m
[root@docker-master load-dir]# kubectl describe cm config -n metallb-system
Name: config
Namespace: metallb-system
Labels: <none>
Annotations: <none>
Data
====
config:
----
address-pools:
- name: default
protocol: layer2
addresses:
- 192.168.108.180-192.168.108.200 #与集群节点服务器处于同一网段
BinaryData
====
Events: <none>
创建nginx应用资源
[root@docker-master load-dir]# vim nginx-metallb.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: metallb-system
name: nginx-metallb
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: c1
image: nginx:1.26-alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
应用yaml文件
[root@docker-master load-dir]# kubectl apply -f nginx-metallb.yaml
deployment.apps/nginx-metallb created
查看
[root@docker-master load-dir]# kubectl get deploy -n metallb-system
NAME READY UP-TO-DATE AVAILABLE AGE
controller 1/1 1 1 13m
nginx-metallb 2/2 2 2 45s
[root@docker-master load-dir]# kubectl get pod -n metallb-system
NAME READY STATUS RESTARTS AGE
controller-8d6664589-7dvg2 1/1 Running 0 13m
nginx-metallb-5b6d5cd699-9wdbj 1/1 Running 0 61s
nginx-metallb-5b6d5cd699-ctzm7 1/1 Running 0 61s
speaker-njbtc 1/1 Running 0 13m
speaker-qf5vw 1/1 Running 0 13m
创建service资源
[root@docker-master load-dir]# vim lb-service.yaml
apiVersion: v1
kind: Service
metadata:
name: lb
namespace: metallb-system
spec:
type: LoadBalancer
ports:
- targetPort: 80
port: 80
protocol: TCP
selector:
app: nginx
应用yaml
[root@docker-master load-dir]# kubectl apply -f lb-service.yaml
service/lb created
查看
[root@docker-master load-dir]# kubectl get svc -n metallb-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
lb LoadBalancer 10.98.239.164 192.168.108.180 80:31601/TCP 2m2s
访问地址:http://192.168.108.180/

使用集群节点IP也可以访问,此时端口号为31601



新版本MetalLB
v0.15
前面v0.12的配置从头到尾全部删完
1:修改kube-proxy配置文件
[root@docker-master load-dir]# kubectl edit configmap -n kube-system kube-proxy
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: "ipvs" #检查模式
ipvs:
strictARP: true #设置为true
2:使用YAML文件创建资源(打开魔法)
[root@docker-master load-dir]# kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.15.2/config/manifests/metallb-native.yaml
namespace/metallb-system created
customresourcedefinition.apiextensions.k8s.io/bfdprofiles.metallb.io created
customresourcedefinition.apiextensions.k8s.io/bgpadvertisements.metallb.io created
customresourcedefinition.apiextensions.k8s.io/bgppeers.metallb.io created
customresourcedefinition.apiextensions.k8s.io/communities.metallb.io created
customresourcedefinition.apiextensions.k8s.io/ipaddresspools.metallb.io created
customresourcedefinition.apiextensions.k8s.io/l2advertisements.metallb.io created
customresourcedefinition.apiextensions.k8s.io/servicebgpstatuses.metallb.io created
customresourcedefinition.apiextensions.k8s.io/servicel2statuses.metallb.io created
serviceaccount/controller created
serviceaccount/speaker created
role.rbac.authorization.k8s.io/controller created
role.rbac.authorization.k8s.io/pod-lister created
clusterrole.rbac.authorization.k8s.io/metallb-system:controller created
clusterrole.rbac.authorization.k8s.io/metallb-system:speaker created
rolebinding.rbac.authorization.k8s.io/controller created
rolebinding.rbac.authorization.k8s.io/pod-lister created
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:controller created
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:speaker created
configmap/metallb-excludel2 created
secret/metallb-webhook-cert created
service/metallb-webhook-service created
deployment.apps/controller created
daemonset.apps/speaker created
validatingwebhookconfiguration.admissionregistration.k8s.io/metallb-webhook-configuration created
同时也可以把YAML下载
[root@docker-master load-dir]# wget https://raw.githubusercontent.com/metallb/metallb/v0.15.2/config/manifests/metallb-native.yaml
--2026-01-22 16:56:54-- https://raw.githubusercontent.com/metallb/metallb/v0.15.2/config/manifests/metallb-native.yaml
正在解析主机 raw.githubusercontent.com (raw.githubusercontent.com)... 198.18.0.9
正在连接 raw.githubusercontent.com (raw.githubusercontent.com)|198.18.0.9|:443... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:74628 (73K) [text/plain]
正在保存至: “metallb-native.yaml”
100%[========================================================================>] 74,628 144KB/s 用时 0.5s
2026-01-22 16:56:56 (144 KB/s) - 已保存 “metallb-native.yaml” [74628/74628])
3:查看创建资源
[root@docker-master load-dir]# kubectl get all -n metallb-system
NAME READY STATUS RESTARTS AGE
pod/controller-8666ddd68b-c85wt 1/1 Running 0 84s
pod/speaker-6bsbw 1/1 Running 0 84s
pod/speaker-9h7xt 0/1 Running 0 84s
pod/speaker-mr526 1/1 Running 0 84s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/metallb-webhook-service ClusterIP 10.101.14.65 <none> 443/TCP 84s
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
daemonset.apps/speaker 3 3 2 3 2 kubernetes.io/os=linux 84s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/controller 1/1 1 1 84s
NAME DESIRED CURRENT READY AGE
replicaset.apps/controller-8666ddd68b 1 1 1 84s
打开官网配置

这里就和之前版本有区别
4:不需要创建configmap资源对象,而是直接使用IPAddressPool资源
[root@docker-master load-dir]# vim ipaddresspool.yaml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: first-pool
namespace: metallb-system
spec:
addresses:
- 192.168.108.220-192.168.108.230 # 修改 分配地址池范围
应用YAML
[root@docker-master load-dir]# kubectl apply -f ipaddresspool.yaml
ipaddresspool.metallb.io/first-pool created
5:查看创建资源
[root@docker-master load-dir]# kubectl get ipaddresspool -n metallb-system
NAME AUTO ASSIGN AVOID BUGGY IPS ADDRESSES
first-pool true false ["192.168.108.220-192.168.108.230"]
6:创建nginx应用资源
[root@docker-master load-dir]# vim nginx-metallb.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: metallb-system
name: nginx-metallb
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: c1
image: nginx:1.26-alpine
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
应用yaml文件
[root@docker-master load-dir]# kubectl apply -f nginx-metallb.yaml
deployment.apps/nginx-metallb created
查看
[root@docker-master load-dir]# kubectl get deploy -n metallb-system
NAME READY UP-TO-DATE AVAILABLE AGE
controller 1/1 1 1 4m43s
nginx-metallb 2/2 2 2 18s
[root@docker-master load-dir]# kubectl get pod -n metallb-system
NAME READY STATUS RESTARTS AGE
controller-8666ddd68b-c85wt 1/1 Running 0 5m1s
nginx-metallb-5b6d5cd699-9lwz9 1/1 Running 0 36s
nginx-metallb-5b6d5cd699-rb2hk 1/1 Running 0 36s
speaker-6bsbw 1/1 Running 0 5m1s
speaker-9h7xt 1/1 Running 0 5m1s
speaker-mr526 1/1 Running 0 5m1s
7:创建service资源
[root@docker-master load-dir]# cat lb-service.yaml
apiVersion: v1
kind: Service
metadata:
name: lb
namespace: metallb-system
spec:
type: LoadBalancer
ports:
- targetPort: 80
port: 80
protocol: TCP
selector:
app: nginx
应用yaml
[root@docker-master load-dir]# kubectl apply -f lb-service.yaml
service/lb created
查看到分配的地址是:192.168.18.200
[root@docker-master load-dir]# kubectl get svc -n metallb-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
lb LoadBalancer 10.97.216.14 192.168.108.220 80:30191/TCP 22s
metallb-webhook-service ClusterIP 10.101.14.65 <none> 443/TCP 6m2s
验证查看网站
http://192.168.108.220/

4:ExternalName
作用:
- 把集群外部的服务引入到集群内部中来,实现了集群内部pod和集群外部的服务进行通信
- ExternalName类型的服务适用于外部服务使用域名的方式,缺点是不能指定端口
- 还有一点要注意:集群内的Pod会继承Node上的DNS解析规则。所以只要Node可以访问的服务, Pod中也可以访问到,这就实现了集群内服务访问集群外服务
公网域名引入
查看dns资源
[root@docker-master ~]# kubectl get svc -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 9d
查看公网域名解析
[root@docker-master ~]# dig -t a www.baidu.com @10.96.0.10
; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.16 <<>> -t a www.baidu.com @10.96.0.10
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4601
;; flags: qr rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;www.baidu.com. IN A
;; ANSWER SECTION:
www.baidu.com. 5 IN CNAME www.a.shifen.com.
www.a.shifen.com. 5 IN A 180.101.51.73
www.a.shifen.com. 5 IN A 180.101.49.44
;; Query time: 114 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: 五 1月 23 09:10:28 CST 2026
;; MSG SIZE rcvd: 149
创建YAML
[root@docker-master service-dir]# cat externalname.yaml
apiVersion: v1
kind: Service
metadata:
name: baidu-external
spec:
type: ExternalName
externalName: www.baidu.com
应用YAM
[root@docker-master service-dir]# kubectl apply -f externalname.yaml
service/baidu-external created
查看创建资源
[root@docker-master service-dir]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
baidu-external ExternalName <none> www.baidu.com <none> 8s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 9d
查看本地域名解析
[root@docker-master service-dir]# dig -t a baidu-external.default.svc.cluster.local. @10.96.0.10
; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.16 <<>> -t a baidu-external.default.svc.cluster.local. @10.96.0.10
;; global options: +cmd
;; Got answer:
;; WARNING: .local is reserved for Multicast DNS
;; You are currently testing what happens when an mDNS query is leaked to DNS
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 9606
;; flags: qr aa rd; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;baidu-external.default.svc.cluster.local. IN A
;; ANSWER SECTION:
baidu-external.default.svc.cluster.local. 5 IN CNAME www.baidu.com.
www.baidu.com. 5 IN CNAME www.a.shifen.com.
www.a.shifen.com. 5 IN A 180.101.51.73
www.a.shifen.com. 5 IN A 180.101.49.44
;; Query time: 112 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: 五 1月 23 09:20:51 CST 2026
;; MSG SIZE rcvd: 243
开启测试Pod来解析域名
[root@docker-master service-dir]# kubectl run -it expod --image=busybox:1.28
If you don't see a command prompt, try pressing enter.
/ # nslookup www.baidu.com
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: www.baidu.com
Address 1: 240e:e9:6002:1ac:0:ff:b07e:36c5
Address 2: 240e:e9:6002:1fd:0:ff:b0e1:fe69
Address 3: 180.101.51.73
Address 4: 180.101.49.44
/ # nslookup baidu-external.default.svc.cluster.local.
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: baidu-external.default.svc.cluster.local.
Address 1: 240e:e9:6002:1fd:0:ff:b0e1:fe69
Address 2: 240e:e9:6002:1ac:0:ff:b07e:36c5
Address 3: 180.101.49.44
Address 4: 180.101.51.73
不同命名空间访问
案例:实现ns1和ns2两个命名空间之间服务的访问
1:创建ns1命名空间和相关deployment,pod,service
[root@docker-master service-dir]# vim pod-ns1.yaml
# 创建命名空间
apiVersion: v1
kind: Namespace
metadata:
name: ns1
---
# 应用资源
apiVersion: apps/v1
kind: Deployment
metadata:
name: pod-ns1
namespace: ns1
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: c1
image: nginx:1.26-alpine
ports:
- containerPort: 80
---
# 端口暴露
apiVersion: v1
kind: Service
metadata:
name: svc1 #服务名称
namespace: ns1 #属于ns1命名空间
spec:
type: ClusterIP
clusterIP: None #无头服务
selector:
app: nginx
ports:
- port: 80
targetPort: 80
---
# 跨命名空间
apiVersion: v1
kind: Service
metadata:
name: external-svc1
namespace: ns1
spec:
type: ExternalName
externalName: sv2.ns2.svc.cluster.local. #将ns2空间的svc2服务引入到ns1空间
2:应用YAML
[root@docker-master service-dir]# kubectl apply -f pod-ns1.yaml
namespace/ns1 created
deployment.apps/pod-ns1 created
service/svc1 created
service/external-svc1 created
3:查看命名空间ns1中的资源
[root@docker-master service-dir]# kubectl get svc,pod -n ns1
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/external-svc1 ExternalName <none> sv2.ns2.svc.cluster.local. <none> 35s
service/svc1 ClusterIP None <none> 80/TCP 35s
NAME READY STATUS RESTARTS AGE
pod/pod-ns1-5b6d5cd699-rgqzf 1/1 Running 0 35s
4:使用dns:10.96.0.10解析域名,可以直接看到pod的ip
[root@docker-master service-dir]# kubectl get svc -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 9d
metrics-server ClusterIP 10.111.168.59 <none> 443/TCP 8d
[root@docker-master service-dir]# dig -t a svc1.ns1.svc.cluster.local. @10.96.0.10
; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.16 <<>> -t a svc1.ns1.svc.cluster.local. @10.96.0.10
;; global options: +cmd
;; Got answer:
;; WARNING: .local is reserved for Multicast DNS
;; You are currently testing what happens when an mDNS query is leaked to DNS
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 60531
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;svc1.ns1.svc.cluster.local. IN A
;; ANSWER SECTION:
svc1.ns1.svc.cluster.local. 30 IN A 10.244.148.233
;; Query time: 0 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: 五 1月 23 10:08:54 CST 2026
;; MSG SIZE rcvd: 97
[root@docker-master service-dir]# kubectl get pod -n ns1 -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-ns1-5b6d5cd699-rgqzf 1/1 Running 0 98s 10.244.148.233 docker-node1 <none> <none>
5:创建ns2命名空间和相关deployment,pod,service
[root@docker-master service-dir]# cat pod-ns2.yaml
# 创建命名空间
apiVersion: v1
kind: Namespace
metadata:
name: ns2
---
# 应用资源
apiVersion: apps/v1
kind: Deployment
metadata:
name: pod-ns2
namespace: ns2
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: c1
image: nginx:1.26-alpine
ports:
- containerPort: 80
---
# 端口暴露
apiVersion: v1
kind: Service
metadata:
name: svc2
namespace: ns2
spec:
type: ClusterIP
clusterIP: None
selector:
app: nginx
ports:
- port: 80
targetPort: 80
---
# 跨命名空间
apiVersion: v1
kind: Service
metadata:
name: external-svc1
namespace: ns2
spec:
type: ExternalName
externalName: sv1.ns1.svc.cluster.local.
6:应用YAML
[root@docker-master service-dir]# kubectl apply -f pod-ns2.yaml
namespace/ns2 created
deployment.apps/pod-ns2 created
service/svc2 created
service/external-svc1 created
[root@docker-master service-dir]# kubectl get svc,pod -n ns2
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/external-svc1 ExternalName <none> sv1.ns1.svc.cluster.local. <none> 8s
service/svc2 ClusterIP None <none> 80/TCP 8s
NAME READY STATUS RESTARTS AGE
pod/pod-ns2-5b6d5cd699-czlhm 1/1 Running 0 8s
7:使用dns解析pod的ip
[root@docker-master service-dir]# dig -t a svc2.ns2.svc.cluster.local. @10.96.0.10
; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.16 <<>> -t a svc2.ns2.svc.cluster.local. @10.96.0.10
;; global options: +cmd
;; Got answer:
;; WARNING: .local is reserved for Multicast DNS
;; You are currently testing what happens when an mDNS query is leaked to DNS
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 54146
;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;svc2.ns2.svc.cluster.local. IN A
;; ANSWER SECTION:
svc2.ns2.svc.cluster.local. 30 IN A 10.244.148.237
;; Query time: 0 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: 五 1月 23 10:10:02 CST 2026
;; MSG SIZE rcvd: 97
[root@docker-master service-dir]# kubectl get pod -n ns2 -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-ns2-5b6d5cd699-czlhm 1/1 Running 0 34s 10.244.148.237 docker-node1 <none> <none>
在pod中使用域名进行访问
进入ns2中的pod,使用nslookup对ns1中的pod进行域名解析
[root@docker-master service-dir]# kubectl exec -it pod-ns2-5b6d5cd699-czlhm -n ns2 -- /bin/sh
/ # nslookup sv2
Server: 10.96.0.10
Address: 10.96.0.10:53
** server can't find sv2.cluster.local: NXDOMAIN
** server can't find sv2.ns2.svc.cluster.local: NXDOMAIN
** server can't find sv2.svc.cluster.local: NXDOMAIN
** server can't find sv2.ns2.svc.cluster.local: NXDOMAIN
** server can't find sv2.svc.cluster.local: NXDOMAIN
** server can't find sv2.cluster.local: NXDOMAIN
/ # nslookup svc1.ns1.svc.cluster.local.
Server: 10.96.0.10
Address: 10.96.0.10:53
Name: svc1.ns1.svc.cluster.local
Address: 10.244.148.233
如果ns1中pod的ip发生变化,那么是否还能够域名正常解析
先查看ns1中pod的ip
[root@docker-master service-dir]# kubectl get pod -n ns1 -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-ns1-5b6d5cd699-rgqzf 1/1 Running 0 8m50s 10.244.148.233 docker-node1 <none> <none>
再删除pod,并查看ip变化为10.244.104.7
[root@docker-master service-dir]# kubectl delete pod pod-ns1-5b6d5cd699-rgqzf -n ns1
pod "pod-ns1-5b6d5cd699-rgqzf" deleted
[root@docker-master service-dir]# kubectl get pod -n ns1 -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-ns1-5b6d5cd699-d9kxv 1/1 Running 0 15s 10.244.248.131 docker-node2 <none> <none>
再次进入到ns2中pod,对ns1中pod进行域名解析
[root@docker-master service-dir]# kubectl exec -it pod-ns2-5b6d5cd699-czlhm -n ns2 -- /bin/sh
/ # nslookup svc1.ns1.svc.cluster.local.
Server: 10.96.0.10
Address: 10.96.0.10:53
Name: svc1.ns1.svc.cluster.local
Address: 10.244.248.131 #发现依然能完成解析
sessionAffinity
会话粘黏
设置sessionAffinity为clientip(类似nginx的ip_hash算法、lvs的sh算法)
创建nginx资源使用clusterip访问
[root@docker-master service-dir]# vim nginx-session.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-session
spec:
selector:
matchLabels:
app: nginx
replicas: 2
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: c1
image: nginx:1.26-alpine
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
type: ClusterIP
selector:
app: nginx
ports:
- port: 80
targetPort: 80
应用YAML
[root@docker-master service-dir]# kubectl apply -f nginx-session.yaml
deployment.apps/nginx-session created
service/nginx-svc unchanged
查看资源
[root@docker-master service-dir]# kubectl get pod,svc
NAME READY STATUS RESTARTS AGE
pod/nginx-session-5b6d5cd699-fqfpm 1/1 Running 0 13s
pod/nginx-session-5b6d5cd699-lc86m 1/1 Running 0 13s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 9d
service/nginx-svc ClusterIP 10.110.140.73 <none> 80/TCP 68s
更新两个pod中首页内容作为鉴别区分
修改第1个pod首页内容为web1
[root@docker-master service-dir]# kubectl exec -it pod/nginx-session-5b6d5cd699-fqfpm -- /bin/sh
/ # cd /usr/share/nginx/html
/usr/share/nginx/html # echo "web1" > index.html
/usr/share/nginx/html #
修改第2个pod首页内容为web2
[root@docker-master service-dir]# kubectl exec -it pod/nginx-session-5b6d5cd699-lc86m -- /bin/sh
/ # cd /usr/share/nginx/html
/usr/share/nginx/html # echo web2 > index.html
可以直接观测到访问clusterip使用了负载均衡
[root@docker-master service-dir]# curl http://10.110.140.73
web2
[root@docker-master service-dir]# curl http://10.110.140.73
web1
粘黏的功能就是更改Session Affinity选项
[root@docker-master service-dir]# kubectl describe svc nginx-svc
Name: nginx-svc
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=nginx
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.110.140.73
IPs: 10.110.140.73
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.148.236:80,10.244.248.188:80
Session Affinity: None
Events: <none>
[root@docker-master service-dir]# kubectl patch svc nginx-svc -p '{"spec":{"sessionAffinity":"ClientIP"}}'
service/nginx-svc patched
再次查看更改结果
[root@docker-master service-dir]# kubectl describe svc nginx-svc
Name: nginx-svc
Namespace: default
Labels: <none>
Annotations: <none>
Selector: app=nginx
Type: ClusterIP
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.110.140.73
IPs: 10.110.140.73
Port: <unset> 80/TCP
TargetPort: 80/TCP
Endpoints: 10.244.148.236:80,10.244.248.188:80
Session Affinity: ClientIP
Events: <none>
验证访问粘黏,第1次访问哪个pod,后面就一直访问这个pod,直到失效时间
sessionAffinity机制默认失效时间为10800秒(3小时)
[root@docker-master service-dir]# curl http://10.110.140.73
web2
[root@docker-master service-dir]# curl http://10.110.140.73
web2
[root@docker-master service-dir]# curl http://10.110.140.73
web2
更多推荐

所有评论(0)