Kubernetes-Service

Kubernetes-Service

Service作用

在k8s中,pod是不稳定的,它们随时可能会被销毁重启。当Pod重启时,它的IP地址会改变。那么客户端如何找到它呢?我们就需要一个稳定的入口,这就是service,它提供了一个稳定的虚拟IP和DNS名称,service通过标签选择器找到对应的pod,即使pod的IP变了也没关系。

底层原理,kube-proxy监听API server,配置IP tables或ipvs规则来转发流量,能实现4层的负载均衡

总结,service是连接后端pod的稳定抽象

kube-proxy三种代理模式

  • userspace模式
  • iptables模式
  • ipvs模式

kubernetes集群中有三层网络,一类是真实存在的,例如Node Network、Pod Network,提供真实IP地址;一类是虚拟的,例如Cluster Network或Service Network,提供虚拟IP地址,不会出现在接口上,仅会出现在Service当中

kube-proxy始终watch(监控)API server上关于Service相关的资源变动状态,一旦获取相关信息kube-proxy都要把相关信息转化为当前节点之上的,能够实现Service资源调度到特定Pod之上的规则,进而实现访问Service就能够获取Pod所提供的服务

userspace模式

userspace 模式是 kube-proxy 使用的第一代模式,该模式在 kubernetes v1.0 版本开始支持使用(早期)
在这里插入图片描述

流程是客户端发送流量,内核的iptables规则将流量转发到kube-proxy 监听的端口,kube-proxy在用户空间做负载均衡选择,再通过内核,转发给后端的Pod(也就是kube-proxy自己参与到转发流量)

这个模式的特点是 简单、负载均衡算法可控,但是,缺点也很明显,每个请求都需要经过用户态,性能差,延迟高,当前基本淘汰,生产环境中不会使用

iptables模式

iptables 模式是 kube-proxy使用的第二代模式,该模式在 kubernetes v1.1版本开始支持,从v1.2 版本 开始成为 kube-proxy 的默认模式(主流),最常用的一种

在这里插入图片描述

iptables 模式的负载均衡模式是通过底层 netfilter/iptables 规则来实现的,通过 informer 机制 监听 接口实时跟踪 Service 和 Endpoint 的变更事件,并触发对 iptables 规则的同步更新,也就是说,kube-proxy不再参与转发,仅仅只负载生成iptables 规则

该模式的特点是 简单、性能比userspace 高很多、纯内核转发、稳定,也有缺点,规则是线性的,当service多时,规则数量巨大,扩展性差(大规模集群效率下降)

ipvs模式

ipvs 模式被 kube-proxy采纳为第三代模式,模式在 kubernetes v1.8 版本开始引入,在 v1.9 版本中处 于 beta 阶段,在 v1.11 版本中正式开始使用(是iptables模式的高性能模式,底层还是iptables在干活)

在这里插入图片描述

ipvs(iP Virtual Server)实现了传输层负载均衡,也就是4层交换,作为 Linux 内核的一部分。ipvs运行在 主机上,在真实服务器前充当负载均衡器。ipvs 可以将基于 TCP和 UDP 的服务请求转发到真实服务器 上,并使真实服务器上的服务在单个IP 地址上显示为虚拟服务

ipvs适合大规模集群,当service多时,iptables规则数量会巨大,ipvs优势更明显

ipvs和iptables对比

iptables是转发规则系统,线性规则,service多时性能下降

ipvs是哈希表+连接跟踪,专业4层负载均衡器(内核级负载均衡器),内核支持不全,低版本内核不能使用,需要升级到4.0 or 5.0以上

使用iptables和ipvs的时机

  • 内核1.10版本之前使用iptables(1.1版本之前使用UserSpace进行转发)
  • 内核1.11版本之后同时支持iptables与ipvs,默认使用ipvs,如果ipvs模块没有加载时,会自动降级至iptables

Service类型

  • ClusterIP:只能在机群内部访问,集群外部无法直接访问
  • NodePort:在每个节点上开放一个静态端口,允许外部流量通过NodePort进入集群内部(NodePort 端口范围30000-32767
  • LoadBalancer:请求云服务商提供一个负载均衡器,将流量分发到Node
  • ExternalName:把集群外部的服务引入到集群内部中来,即实现了集群内部pod和集群外部的服务进行通信

Service参数

  • port:访问service使用的端口
  • targetPort:Pod中容器端口
  • nodePort:通过Node实现外网用户访问k8s集群内service(30000-32767)
    在这里插入图片描述

Service创建

Service的创建在工作中有两种方式,一是命令行创建,二是通过资源清单文件YAML文件创建

ClusterIP

ClusterlP根据是否生成ClusterlP又可分为普通Service和Headless Service

  • 普通Service:为Kubernetes的Service分配一个集群内部可访问的固定虚拟IP(Cluster IP),实现集群内的访问
  • Headless Service:该服务不会分配ClusterIP,也不通过kube-proxy做反向代理和负载均衡。而是通过DNS提供稳定的网络 ID来访问,DNS会将headless service的后端直接解析为pod IP列表

完整k8s资源域名:pod名称+service名称+命令空间+类型+cluster+local.(不要忘记.,这是根)
在这里插入图片描述

普通Service
命令行创建

先创建一个deployment类型的应用

[root@master ~ 21:45:13]# cd service_dir/
[root@master service_dir 21:45:19]# vim nginx_deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-service1
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@master service_dir 21:47:12]# kubectl apply -f nginx_deploy.yaml
deployment.apps/nginx-service1 created

[root@master service_dir 21:47:39]# kubectl get pods -o wide
NAME                              READY   STATUS    RESTARTS   AGE   IP               NODE    NOMINATED NODE   READINESS GATES
nginx-service1-5b6d5cd699-g6q5t   1/1     Running   0          25s   10.244.166.151   node1   <none>           <none>
nginx-service1-5b6d5cd699-mdxf9   1/1     Running   0          25s   10.244.104.31    node2   <none>           <none>

[root@master service_dir 21:47:44]# kubectl get deployments.apps 
NAME             READY   UP-TO-DATE   AVAILABLE   AGE
nginx-service1   2/2     2            2           46s

创建clusterIP类型service与Deployment类型应用关联

[root@master service_dir 21:48:04]# kubectl expose deployment nginx-service1 --type=ClusterIP --target-port=80 --port=80
service/nginx-service1 exposed

解释:

expose 创建service

deployment.apps 控制器类型

nginx-server1 应用名称,也是service名称

–type=ClusterIP 指定service类型

–target-port=80 指定Pod中容器端口

–port=80 指定service端口

[root@master service_dir 21:49:09]# kubectl get svc
NAME             TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes       ClusterIP   10.96.0.1       <none>        443/TCP   38d
nginx-service1   ClusterIP   10.97.114.112   <none>        80/TCP    5m14s

查看详细描述

[root@master service_dir 21:54:23]# kubectl describe service nginx-service1 
Name:              nginx-service1
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=nginx
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.97.114.112
IPs:               10.97.114.112
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.104.31:80,10.244.166.151:80
Session Affinity:  None
Events:            <none>

访问clusterIP 就可以看到网页内容

[root@master service_dir 21:55:19]# curl http://10.97.114.112
<!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>

验证负载均衡功能

[root@master service_dir 21:56:12]# kubectl get pods
NAME                              READY   STATUS    RESTARTS   AGE
nginx-service1-5b6d5cd699-g6q5t   1/1     Running   0          8m55s
nginx-service1-5b6d5cd699-mdxf9   1/1     Running   0          8m55s

修改nginx-service1-5b6d5cd699-g6q5t 的网页内容为web1

修改nginx-service1-5b6d5cd699-mdxf9 的网页内容为web2

[root@master service_dir 21:58:21]# kubectl exec -it nginx-service1-5b6d5cd699-g6q5t -- /bin/sh
/ # cd /usr/share/nginx/html/
/usr/share/nginx/html # ls
50x.html    index.html
/usr/share/nginx/html # echo "web1" > index.html 
/usr/share/nginx/html # cat index.html 
web1
/usr/share/nginx/html # exit

[root@master service_dir 21:59:53]# kubectl exec -it nginx-service1-5b6d5cd699-mdxf9 -- /bin/sh
/ # cd /usr/share/nginx/html/
/usr/share/nginx/html # ls
50x.html    index.html
/usr/share/nginx/html # echo "web2" > index.html 
/usr/share/nginx/html # cat index.html 
web2
/usr/share/nginx/html # exit

验证网页显示

[root@master service_dir 22:00:34]# curl http://10.97.114.112
web2
[root@master service_dir 22:00:57]# curl http://10.97.114.112
web1
[root@master service_dir 22:00:58]# curl http://10.97.114.112
web2
[root@master service_dir 22:00:59]# curl http://10.97.114.112
web1
yaml声明式创建

编写yaml文件

[root@master service_dir 22:00:59]# vim nginx_deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-service1
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
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  type: ClusterIP
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  selector:
    app: nginx

应用yaml

[root@master service_dir 22:02:38]# kubectl apply -f nginx_deploy.yaml 
deployment.apps/nginx-service1 unchanged
service/nginx-svc created

[root@master service_dir 22:08:32]# kubectl get svc,pods
NAME                 TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1        <none>        443/TCP   38d
service/nginx-service1   ClusterIP   10.97.114.112    <none>        80/TCP    18m
service/nginx-svc    ClusterIP   10.103.205.240   <none>        80/TCP    69s

NAME                                  READY   STATUS    RESTARTS   AGE
pod/nginx-service1-5b6d5cd699-g6q5t   1/1     Running   0          21m
pod/nginx-service1-5b6d5cd699-mdxf9   1/1     Running   0          21m
[root@master service_dir 22:09:15]# kubectl describe service 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.103.205.240
IPs:               10.103.205.240
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.104.31:80,10.244.166.151:80
Session Affinity:  None
Events:            <none>
[root@master service_dir 22:10:10]# kubectl get endpoints
NAME                                          ENDPOINTS                            AGE
k8s-sigs.io-nfs-subdir-external-provisioner   <none>                               31d
kubernetes                                    192.168.108.128:6443                 38d
nginx-svc                                     10.244.104.31:80,10.244.166.151:80   2m41s
[root@master service_dir 22:10:14]# curl http://10.103.205.240
web1
[root@master service_dir 22:11:02]# curl http://10.103.205.240
web2
[root@master service_dir 22:11:23]# curl http://10.103.205.240
web1
[root@master service_dir 22:11:24]# curl http://10.103.205.240
web2
Headless Service

也叫无头服务

  • 普通的clusterIP service是service name解析为cluster ip,然后cluster ip对应到后面pod ip
  • headless service是指service name直接解析为后面的pod ip(也就是没有创建虚拟ip)

创建deployment控制器以及 无头服务 的yaml

[root@master service_dir 22:14:32]# cat nginx_deploy_headless.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-service1
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
---
apiVersion: v1
kind: Service
metadata:
  name: headless-svc
spec:
  type: ClusterIP		#ClusterIP类型也是默认类型
  clusterIP: None		#None代表无头服务
  ports:				#指定service端口及容器端口
    - port: 80			#service ip中的端口
      targetPort: 80	#pod端口
      protocol: TCP
  selector:				#指定后端pod标签
    app: nginx

应用yaml

[root@master service_dir 22:17:38]# kubectl apply -f nginx_deploy_headless.yaml 
deployment.apps/nginx-service1 created
service/headless-svc created

[root@master service_dir 22:17:58]# kubectl get svc
NAME           TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
headless-svc   ClusterIP   None         <none>        80/TCP    76s
kubernetes     ClusterIP   10.96.0.1    <none>        443/TCP   38d

[root@master service_dir 22:19:14]# kubectl get pod -o wide
NAME                              READY   STATUS    RESTARTS   AGE   IP               NODE    NOMINATED NODE   READINESS GATES
nginx-service1-5b6d5cd699-cr58p   1/1     Running   0          87s   10.244.166.152   node1   <none>           <none>
nginx-service1-5b6d5cd699-ttzdp   1/1     Running   0          87s   10.244.104.32    node2   <none>           <none>

[root@master service_dir 22:19:25]# kubectl get endpoints
NAME                                          ENDPOINTS                            AGE
headless-svc                                  10.244.104.32:80,10.244.166.152:80   92s
k8s-sigs.io-nfs-subdir-external-provisioner   <none>                               31d
kubernetes                                    192.168.108.128:6443                 38d

DNS

DNS服务监视Kubernetes APl,为每一个Service创建DNS记录用于域名解析

headless service需要DNS来解决访问问题

DNS记录格式为:pod名称+service名称+命令空间+类型+cluster+local.

查看kube-dns服务的IP

[root@master service_dir 22:19:30]# kubectl get pod -o wide -n kube-system | grep dns
coredns-66f779496c-nzpjw                   1/1     Running   1 (38d ago)   38d     10.244.219.70     master   <none>           <none>
coredns-66f779496c-wzrkp                   1/1     Running   1 (38d ago)   38d     10.244.219.69     master   <none>           <none>
[root@master service_dir 22:22:39]# kubectl get svc -n kube-system | grep dns
kube-dns                                            ClusterIP   10.96.0.10    <none>        53/UDP,53/TCP,9153/TCP         38d

在集群主机通过DNS服务地址查找无头服务的dns解析

[root@master service_dir 22:24:31]# dig -t a headless-svc.default.svc.cluster.local. @10.96.0.10

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.16 <<>> -t a headless-svc.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: 32286
;; 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:
;headless-svc.default.svc.cluster.local.	IN A

;; ANSWER SECTION:
headless-svc.default.svc.cluster.local.	30 IN A	10.244.104.32
headless-svc.default.svc.cluster.local.	30 IN A	10.244.166.152

;; Query time: 0 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: 六 221 22:25:22 CST 2026
;; MSG SIZE  rcvd: 175

在集群内创建pod进行解析

[root@master service_dir 22:25:22]# 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://headless-svc.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>

NodePort

在这里插入图片描述

创建yaml

[root@master service_dir 22:27:40]# cat nginx_nodePort.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-app
  labels:
    app: nginx
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
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-nodeport
spec:
  type: NodePort
  ports:
    - port: 8060
      targetPort: 80
      nodePort: 31111   #范围30000-32767
      protocol: TCP
  selector:
    app: nginx

应用yaml

[root@master service_dir 22:31:13]# kubectl apply -f nginx_nodePort.yaml
deployment.apps/nginx-app created
service/nginx-nodeport created\

[root@master service_dir 22:31:51]# kubectl get svc,pods
NAME                     TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)          AGE
service/kubernetes       ClusterIP   10.96.0.1      <none>        443/TCP          38d
service/nginx-nodeport   NodePort    10.111.10.70   <none>        8060:31111/TCP   36s

NAME                             READY   STATUS    RESTARTS   AGE
pod/nginx-app-5b6d5cd699-kswqn   1/1     Running   0          36s
pod/nginx-app-5b6d5cd699-mgr4k   1/1     Running   0          36s

[root@master service_dir 22:31:54]# kubectl get deployments
NAME        READY   UP-TO-DATE   AVAILABLE   AGE
nginx-app   2/2     2            2           60s

使用浏览器访问nodeIP

http://192.168.108.128:31111/
在这里插入图片描述

http://192.168.108.136:31111/
在这里插入图片描述

LoadBalancer

用于集群外访问过程

  • 用户
  • 域名
  • 云服务商提供LB服务
  • NodeIP:Port(service IP)
  • Pod IP:Port
    在这里插入图片描述
MetalLB

自建kubernetes的loadbalancer类型服务方案

MetalLB可以为kubernetes集群中的Service提供网络负载均衡功能

MetalLB两大功能为:

  • 地址分配,类似于DHCP
  • 外部通告,一旦MetalLB为服务分配了外部IP地址,它就需要使群集之外的网络意识到该IP在群集 中"存在"。(MetalLB使用标准路由协议来实现此目的:ARP,NDP或BGP)

参考文档:https://metallb.universe.tf/installation/
在这里插入图片描述

下载资源清单

v0.12

[root@master service_dir 22:53:13]# cd load_dir/
[root@master load_dir 22:53:33]# cd metallb
[root@master metallb 22:54:55]# wget https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/namespace.yaml
--2026-02-21 22:55:35--  https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/namespace.yaml
正在解析主机 raw.githubusercontent.com (raw.githubusercontent.com)... 198.18.0.6
正在连接 raw.githubusercontent.com (raw.githubusercontent.com)|198.18.0.6|:443... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:91 [text/plain]
正在保存至: “namespace.yaml”

100%[==========================================================================================>] 91          --.-K/s 用时 0s      

2026-02-21 22:55:36 (6.38 MB/s) - 已保存 “namespace.yaml.1” [91/91])

[root@master metallb 22:55:36]# wget https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/metallb.yaml
--2026-02-21 22:56:04--  https://raw.githubusercontent.com/metallb/metallb/v0.12.1/manifests/metallb.yaml
正在解析主机 raw.githubusercontent.com (raw.githubusercontent.com)... 198.18.0.6
正在连接 raw.githubusercontent.com (raw.githubusercontent.com)|198.18.0.6|:443... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:9383 (9.2K) [text/plain]
正在保存至: “metallb.yaml.1”

100%[==========================================================================================>] 9,383       --.-K/s 用时 0.01s   

2026-02-21 22:56:04 (654 KB/s) - 已保存 “metallb.yaml” [9383/9383])

应用yaml

[root@master metallb 22:56:43]# kubectl apply -f namespace.yaml 
namespace/metallb-system configured
[root@master metallb 22:57:28]# kubectl apply -f metallb.yaml 
serviceaccount/controller unchanged
serviceaccount/speaker unchanged
clusterrole.rbac.authorization.k8s.io/metallb-system:controller configured
clusterrole.rbac.authorization.k8s.io/metallb-system:speaker configured
role.rbac.authorization.k8s.io/config-watcher created
role.rbac.authorization.k8s.io/pod-lister configured
role.rbac.authorization.k8s.io/controller configured
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:controller unchanged
clusterrolebinding.rbac.authorization.k8s.io/metallb-system:speaker unchanged
rolebinding.rbac.authorization.k8s.io/config-watcher created
rolebinding.rbac.authorization.k8s.io/pod-lister configured
rolebinding.rbac.authorization.k8s.io/controller configured
daemonset.apps/speaker configured
deployment.apps/controller configured
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@master metallb 22:58:08]# kubectl get ns
NAME                   STATUS   AGE
default                Active   38d
ingress-nginx          Active   26d
kube-node-lease        Active   38d
kube-public            Active   38d
kube-system            Active   38d
kubernetes-dashboard   Active   38d
metallb-system         Active   26d
monitoring             Active   26d

[root@master metallb 22:58:25]# kubectl get pod -n metallb-system 
NAME                         READY   STATUS    RESTARTS   AGE
controller-8d6664589-pgwkz   1/1     Running   0          55s
speaker-9kg5q                1/1     Running   0          53s
speaker-p5tvl                1/1     Running   0          43s

可以给metallb做资源配置

[root@master metallb 22:58:36]# kubectl get configmaps -n metallb-system 
NAME                DATA   AGE
kube-root-ca.crt    1      26d

准备metalLB 配置文件

[root@master metallb 23:00:16]# vim metallb-conf.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: config			# 必须是config名称,负责无法获取地址
  namespace: metallb-system
data:
  config: |
    address-pools:
      - name: default
        protocol: layer2
        addresses:
          - 192.168.108.200-192.168.108.210		#与集群节点服务器处于同一网段

应用yaml

[root@master metallb 23:02:38]# kubectl apply -f metallb-conf.yaml 
configmap/config created

[root@master metallb 23:02:48]# kubectl get configmaps -n metallb-system 
NAME                DATA   AGE
config              1      15s
kube-root-ca.crt    1      26d

[root@master metallb 23:03:03]# 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.200-192.168.108.210


BinaryData
====

Events:  <none>

创建nginx应用资源

[root@master metallb 23:06:40]# cat nginx_metallb.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  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
            
[root@master metallb 23:07:29]# kubectl apply -f nginx_metallb.yaml
deployment.apps/nginx-metallb created

[root@master metallb 23:08:25]# kubectl get deployment
NAME            READY   UP-TO-DATE   AVAILABLE   AGE
nginx-metallb   2/2     2            2           54s

[root@master metallb 23:08:33]# kubectl get pod
NAME                             READY   STATUS    RESTARTS   AGE
nginx-metallb-5b6d5cd699-jtsst   1/1     Running   0          106s
nginx-metallb-5b6d5cd699-sb7xh   1/1     Running   0          106s

创建service 资源

[root@master metallb 23:09:49]# cat nginx_lb-svc.yaml 
apiVersion: v1
kind: Service
metadata:
  name: nginx-metallb
spec:
  type: LoadBalancer
  ports:
    - port: 80
      protocol: TCP
      targetPort: 80
  selector:
    app: nginx

应用yaml

[root@master metallb 23:10:20]# kubectl apply -f nginx_lb-svc.yaml 
service/nginx-metallb created

[root@master metallb 23:10:28]# kubectl get svc
NAME            TYPE           CLUSTER-IP     EXTERNAL-IP       PORT(S)        AGE
kubernetes      ClusterIP      10.96.0.1      <none>            443/TCP        38d
nginx-metallb   LoadBalancer   10.99.23.219   192.168.108.201   80:31139/TCP   10s

访问地址:http://192.168.108.201/
在这里插入图片描述

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

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

新版本MetalLB

v0.15

修改kube-proxy配置文件

[root@master metallb 23:10:38]# kubectl edit configmaps -n kube-system kube-proxy
ipvs:
... ...
  strictARP: true		#设置为true
... ...
kind: KubeProxyConfiguration
... ...
mode: ipvs				#设置模式

使用yaml文件创建资源(使用神奇妙妙工具)

[root@master metallb 23:22:58]# cd ..
[root@master load_dir 23:23:04]# cd metallb_new/
[root@master metallb_new 23:23:24]# 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 unchanged
customresourcedefinition.apiextensions.k8s.io/bgpadvertisements.metallb.io unchanged
customresourcedefinition.apiextensions.k8s.io/bgppeers.metallb.io unchanged
customresourcedefinition.apiextensions.k8s.io/communities.metallb.io unchanged
customresourcedefinition.apiextensions.k8s.io/ipaddresspools.metallb.io unchanged
customresourcedefinition.apiextensions.k8s.io/l2advertisements.metallb.io unchanged
customresourcedefinition.apiextensions.k8s.io/servicebgpstatuses.metallb.io unchanged
customresourcedefinition.apiextensions.k8s.io/servicel2statuses.metallb.io unchanged
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 configured

也可以把yaml文件下载下来

[root@master metallb_new 23:23:24]# wget https://raw.githubusercontent.com/metallb/metallb/v0.15.2/config/manifests/metallb-native.yaml

查看

[root@master metallb_new 23:24:09]# kubectl get all -n metallb-system 
NAME                              READY   STATUS    RESTARTS   AGE
pod/controller-8666ddd68b-jtthk   1/1     Running   0          72s
pod/speaker-qz27r                 1/1     Running   0          72s
pod/speaker-t9vvz                 1/1     Running   0          72s
pod/speaker-wt6t5                 1/1     Running   0          72s

NAME                              TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
service/metallb-webhook-service   ClusterIP   10.100.146.183   <none>        443/TCP   72s

NAME                     DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR            AGE
daemonset.apps/speaker   3         3         3       3            3           kubernetes.io/os=linux   72s

NAME                         READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/controller   1/1     1            1           72s

NAME                                    DESIRED   CURRENT   READY   AGE
replicaset.apps/controller-8666ddd68b   1         1         1       72s

打开官网配置

参考文档:https://metallb.universe.tf/installation/
在这里插入图片描述

这里就和之前版本有区别

不需要创建configmap资源对象,而是直接使用IPAddressPool资源

[root@master metallb_new 23:27:34]# vim ipaddressPool.yaml
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
  name: first-pool
  namespace: metallb-system
spec:
  addresses:
    - 192.168.108.200-192.168.108.210		#分配地址池范围

应用yaml

[root@master metallb_new 23:28:17]# kubectl apply -f ipaddressPool.yaml 
ipaddresspool.metallb.io/first-pool created

[root@master metallb_new 23:28:30]# kubectl get ipaddresspool -n metallb-system 
NAME         AUTO ASSIGN   AVOID BUGGY IPS   ADDRESSES
first-pool   true          false             ["192.168.108.200-192.168.108.210"]

创建nginx应用资源

[root@master metallb_new 23:28:57]# cat nginx_metallb.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  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
            
[root@master metallb_new 23:29:48]# kubectl apply -f nginx_metallb.yaml 
deployment.apps/nginx-metallb created

[root@master metallb_new 23:29:55]# kubectl get deployments.apps 
NAME            READY   UP-TO-DATE   AVAILABLE   AGE
nginx-metallb   2/2     2            2           5s

[root@master metallb_new 23:30:00]# kubectl get pod
NAME                             READY   STATUS    RESTARTS   AGE
nginx-metallb-5b6d5cd699-dx8tl   1/1     Running   0          11s
nginx-metallb-5b6d5cd699-whbww   1/1     Running   0          11s

创建service资源

[root@master metallb_new 23:30:35]# cat nginx_lb-svc.yaml 
apiVersion: v1
kind: Service
metadata:
  name: nginx-metallb
spec:
  type: LoadBalancer
  ports:
    - port: 80
      protocol: TCP
      targetPort: 80
  selector:
    app: nginx
    
[root@master metallb_new 23:30:57]# kubectl apply -f nginx_lb-svc.yaml 
service/nginx-metallb created

[root@master metallb_new 23:31:06]# kubectl get svc
NAME            TYPE           CLUSTER-IP     EXTERNAL-IP       PORT(S)        AGE
kubernetes      ClusterIP      10.96.0.1      <none>            443/TCP        38d
nginx-metallb   LoadBalancer   10.98.116.37   192.168.108.201   80:30424/TCP   3s

查看网站

http://192.168.108.201/
在这里插入图片描述

ExternalName

作用:

  • 把集群外部的服务引入到集群内部中来,实现了集群内部pod和集群外部的服务进行通信
  • ExternalName类型的服务适用于外部服务使用域名的方式,缺点是不能指定端口
  • 还有一点要注意:集群内的Pod会继承Node上的DNS解析规则。所以只要Node可以访问的服务,Pod中也可以访问到,这就实现了集群内服务访问集群外服务
公网域名引入

查看dns资源

[root@master metallb_new 23:39:32]# cd ../..
[root@master service_dir 23:39:46]# kubectl get svc -n kube-system | grep dns
kube-dns                                            ClusterIP   10.96.0.10    <none>        53/UDP,53/TCP,9153/TCP         38d

查看公网域名解析

[root@master service_dir 23:41:05]# 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: 53294
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, 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	A	198.18.0.14

;; Query time: 0 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: 六 221 23:41:05 CST 2026
;; MSG SIZE  rcvd: 71

创建yaml

[root@master service_dir 23:41:05]# cat externelName.yaml 
apiVersion: v1
kind: Service
metadata:
  name: my-externalname
  namespace: default
spec:
  type: ExternalName
  externalName: www.baidu.com

应用yaml

[root@master service_dir 23:41:59]# kubectl apply -f externelName.yaml 
service/my-externalname created

[root@master service_dir 23:42:24]# kubectl get svc | grep exter
my-externalname   ExternalName   <none>       www.baidu.com   <none>    12s

查看本地域名解析

[root@master service_dir 23:42:55]# dig -t A my-externalname.default.svc.cluster.local. @10.96.0.10

; <<>> DiG 9.11.4-P2-RedHat-9.11.4-26.P2.el7_9.16 <<>> -t A my-externalname.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: 43421
;; 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:
;my-externalname.default.svc.cluster.local. IN A

;; ANSWER SECTION:
my-externalname.default.svc.cluster.local. 5 IN	CNAME www.baidu.com.
www.baidu.com.		5	IN	A	198.18.0.14

;; Query time: 3 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: 六 221 23:43:29 CST 2026
;; MSG SIZE  rcvd: 167

开启测试Pod来解析域名

[root@master service_dir 23:44:39]# 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: 198.18.0.14
/ # nslookup my-externalname.default.svc.cluster.local.
Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      my-externalname.default.svc.cluster.local.
Address 1: 198.18.0.14
不同namespace访问

案例:实现ns1和ns2两个命令空间之间服务的访问

创建ns1命名空间和相关的deployment,pod,service

[root@master service_dir 23:48:12]# cat pod-ns1.yaml 
apiVersion: v1
kind: Namespace
metadata:
  name: ns1
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-nginx
  namespace: ns1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.26-alpine
        imagePullPolicy: IfNotPresent
        ports:
          - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: svc1			#服务名称
  namespace: ns1		#属于ns1命令空间
spec:
  selector:
    app: nginx
  clusterIP: None		#无头服务
  ports:
  - port: 80
    targetPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: external-svc1
  namespace: ns1		#属于ns1命名空间
spec:
  type: ExternalName
  externalName: svc2.ns2.svc.cluster.local.		#将ns2空间的svc2服务引入ns1空间

应用yaml

[root@master service_dir 23:51:59]# kubectl apply -f pod-ns1.yaml
namespace/ns1 created
deployment.apps/deploy-nginx created
service/svc1 created
service/external-svc1 created

[root@master service_dir 23:52:06]# kubectl get pods,svc -n ns1
NAME                                READY   STATUS    RESTARTS   AGE
pod/deploy-nginx-66d785bdb5-27c8k   1/1     Running   0          16s

NAME                    TYPE           CLUSTER-IP   EXTERNAL-IP                   PORT(S)   AGE
service/external-svc1   ExternalName   <none>       svc2.ns2.svc.cluster.local.   <none>    16s
service/svc1            ClusterIP      None         <none>                        80/TCP    16s

使用dns:10.96.0.10解析域名,可以直接看到pod的ip

[root@master service_dir 23:53:12]# kubectl get svc -n kube-system | grep dns
kube-dns                                            ClusterIP   10.96.0.10    <none>        53/UDP,53/TCP,9153/TCP         38d

[root@master service_dir 23:53:33]# 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: 18110
;; 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.104.37

;; Query time: 0 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: 六 221 23:54:05 CST 2026
;; MSG SIZE  rcvd: 97

[root@master service_dir 23:54:34]# kubectl get pods -n ns1 -o wide
NAME                            READY   STATUS    RESTARTS   AGE     IP              NODE    NOMINATED NODE   READINESS GATES
deploy-nginx-66d785bdb5-27c8k   1/1     Running   0          2m37s   10.244.104.37   node2   <none>           <none>

创建ns2命名空间和相关的deployment,pod,service

[root@master service_dir 23:55:15]# cat pod-ns2.yaml 
apiVersion: v1
kind: Namespace
metadata:
  name: ns2
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy-nginx
  namespace: ns2
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.26-alpine
        imagePullPolicy: IfNotPresent
        ports:
          - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: svc2
  namespace: ns2
spec:
  selector:
    app: nginx
  clusterIP: None
  ports:
  - port: 80
    targetPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: external-svc1
  namespace: ns2
spec:
  type: ExternalName
  externalName: svc1.ns1.svc.cluster.local.

应用yaml

[root@master service_dir 23:55:52]# kubectl apply -f pod-ns2.yaml 
namespace/ns2 created
deployment.apps/deploy-nginx created
service/svc2 created
service/external-svc1 created

[root@master service_dir 23:56:15]# kubectl get pods,svc -n ns2
NAME                                READY   STATUS    RESTARTS   AGE
pod/deploy-nginx-66d785bdb5-qql7w   1/1     Running   0          14s

NAME                    TYPE           CLUSTER-IP   EXTERNAL-IP                   PORT(S)   AGE
service/external-svc1   ExternalName   <none>       svc1.ns1.svc.cluster.local.   <none>    14s
service/svc2            ClusterIP      None         <none>                        80/TCP    14s

使用dns解析pod的ip

[root@master service_dir 23:57:26]# 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: 26828
;; 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.166.144

;; Query time: 0 msec
;; SERVER: 10.96.0.10#53(10.96.0.10)
;; WHEN: 六 221 23:57:47 CST 2026
;; MSG SIZE  rcvd: 97

[root@master service_dir 23:58:19]# kubectl get pods -n ns2 -o wide
NAME                            READY   STATUS    RESTARTS   AGE     IP               NODE    NOMINATED NODE   READINESS GATES
deploy-nginx-66d785bdb5-qql7w   1/1     Running   0          2m32s   10.244.166.144   node1   <none>           <none>

在pod中使用域名进行访问

进入ns1中的pod,使用nslookup 对 ns2 中的pod进行域名解析

[root@master service_dir 00:00:37]# kubectl exec -it -n ns1 deploy-nginx-66d785bdb5-27c8k -- /bin/sh
/ # nslookup svc1
Server:		10.96.0.10
Address:	10.96.0.10:53


Name:	svc1.ns1.svc.cluster.local
Address: 10.244.104.37

/ # nslookup svc2.ns2.svc.cluster.local.
Server:		10.96.0.10
Address:	10.96.0.10:53


Name:	svc2.ns2.svc.cluster.local
Address: 10.244.166.144

如果ns2中的pod的ip发生变化,那么是否还能够域名正常解析

先看ns2中pod的ip

[root@master service_dir 00:03:27]# kubectl get pods -n ns2 -o wide
NAME                            READY   STATUS    RESTARTS   AGE     IP               NODE    NOMINATED NODE   READINESS GATES
deploy-nginx-66d785bdb5-qql7w   1/1     Running   0          7m23s   10.244.166.144   node1   <none>           <none>

在删除pod,并查看IP变化为 10.244.104.40

[root@master service_dir 00:03:38]# kubectl delete pod -n ns2 deploy-nginx-66d785bdb5-qql7w 
pod "deploy-nginx-66d785bdb5-qql7w" deleted
[root@master service_dir 00:04:19]# kubectl get pods -n ns2 -o wide
NAME                            READY   STATUS    RESTARTS   AGE   IP              NODE    NOMINATED NODE   READINESS GATES
deploy-nginx-66d785bdb5-8z78j   1/1     Running   0          3s    10.244.104.40   node2   <none>           <none>

再次进入到ns1中pod,对ns2中pod进行域名解析

[root@master service_dir 00:05:13]# kubectl exec -it -n ns1 deploy-nginx-66d785bdb5-27c8k -- /bin/sh
/ # nslookup svc2.ns2.svc.cluster.local.
Server:		10.96.0.10
Address:	10.96.0.10:53


Name:	svc2.ns2.svc.cluster.local
Address: 10.244.104.40

能够发现依然能够完成解析

sessionAffinity会话粘黏

在service做负载均衡的时候,会转发流量,会话粘黏是一种负载均衡机制,确保来自同意客户端的请求始终被转发到同一个后端Pod

工作原理:

当启用会话粘黏后,

  1. 客户端首次访问服务
  2. Service将请求转发给某个Pod
  3. Service记录客户端和Pod的对应关系
  4. 客户端的后续请求继续转发给同一个Pod

设置sessionAffinity为clientIP(类似nginx的ip_hash算法、lvs的sh算法)

创建nginx资源使用clusterIP访问

[root@master service_dir 13:11:07]# cat session-nginx-svc.yaml 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-server
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
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  type: ClusterIP
  ports:
    - port: 80
      protocol: TCP
      targetPort: 80
  selector:
    app: nginx

应用yaml

[root@master service_dir 13:14:12]# kubectl apply -f session-nginx-svc.yaml 
deployment.apps/nginx-server created
service/nginx-svc created

[root@master service_dir 13:15:43]# kubectl get pods,svc
NAME                                READY   STATUS    RESTARTS   AGE
pod/nginx-server-5b6d5cd699-hwvsv   1/1     Running   0          15s
pod/nginx-server-5b6d5cd699-vhmn7   1/1     Running   0          15s

NAME                 TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP   38d
service/nginx-svc    ClusterIP   10.101.228.13   <none>        80/TCP    15s

更新两个Pod中首页内容作为鉴别区分

修改第1个Pod首页内容为web1,修改第2个Pod首页内容为web2

[root@master service_dir 13:15:58]# kubectl exec -it nginx-server-5b6d5cd699-hwvsv -- /bin/sh
/ # cd usr/share/nginx/html/
/usr/share/nginx/html # ls
50x.html    index.html
/usr/share/nginx/html # echo "web1" > index.html 
/usr/share/nginx/html # cat index.html 
web1
/usr/share/nginx/html # exit

[root@master service_dir 13:17:58]# kubectl exec -it nginx-server-5b6d5cd699-vhmn7 -- /bin/sh
/ # cd usr/share/nginx/html/
/usr/share/nginx/html # ls
50x.html    index.html
/usr/share/nginx/html # echo "web2" > index.html 
/usr/share/nginx/html # cat index.html 
web2
/usr/share/nginx/html # exit

可以直接观测到访问clusterip使用了负载均衡

[root@master service_dir 13:18:32]# kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP   39d
nginx-svc    ClusterIP   10.101.228.13   <none>        80/TCP    3m19s
[root@master service_dir 13:19:02]# curl http://10.101.228.13
web1
[root@master service_dir 13:19:14]# curl http://10.101.228.13
web2
[root@master service_dir 13:19:14]# curl http://10.101.228.13
web1
[root@master service_dir 13:19:15]# curl http://10.101.228.13
web2

现在开始使用会话粘黏功能,粘黏的功能就是更改Session Affinity选项

[root@master service_dir 13:20:20]# 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.101.228.13
IPs:               10.101.228.13
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.104.41:80,10.244.166.158:80
Session Affinity:  None			`看这里`
Events:            <none>

修改选项

[root@master service_dir 13:21:02]# kubectl patch svc nginx-svc -p '{"spec":{"sessionAffinity":"ClientIP"}}'
service/nginx-svc patched

再次查看更改结果

[root@master service_dir 13:22:27]# 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.101.228.13
IPs:               10.101.228.13
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.104.41:80,10.244.166.158:80
Session Affinity:  ClientIP		#更改完成
Events:            <none>

验证会话粘黏,第1次访问哪个pod,后面就一直访问这个pod,直到失效时间

sessionAffinity机制默认失效时间为10800秒(3小时)

[root@master service_dir 13:27:21]# curl http://10.101.228.13
web2
[root@master service_dir 13:27:29]# curl http://10.101.228.13
web2
[root@master service_dir 13:27:30]# curl http://10.101.228.13
web2
[root@master service_dir 13:27:30]# curl http://10.101.228.13
web2

验证成功!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值