kubernetes核心概念 Service
iptables 规则将数据包的目标 IP 地址从 Service 的 ClusterIP 转换为后端 Pod 的 IP 地址。:指定查询的记录类型为 A 记录(Address Record),A 记录用于将域名解析为 IPv4 地址。无头服务允许用户直接与 Pod 通信,避免了负载均衡器的介入,适合需要自定义网络策略的场景。客户端通过 DNS 查询无头服务的名称时,会返回所有匹配 Pod 的 I
总结:
- Service类型决定了客户访问Service的方法
- Kube-proxy工作模式是service实现代理时的底层实现方式
- service作用
使用kubernetes集群运行工作负载时,由于Pod经常处于用后即焚状态,Pod经常被重新生成,因此Pod对应的IP地址也会经常变化,导致无法直接访问Pod提供的服务,
Kubernetes中使用了Service来解决这一问题,即在Pod前面使用Service对Pod进行代理,无论Pod怎样变化 ,只要有Label,就可以让Service能够联系上Pod,把PodIP地址添加到Service对应的端点列表(Endpoints)实现对Pod IP跟踪,进而实现通过Service访问Pod目的。
- 通过service为pod客户端提供访问pod方法,即客户端访问pod入口
- 通过标签动态感知pod IP地址变化等
- 防止pod失联
- 定义访问pod访问策略
- 通过label-selector相关联
- 通过Service实现Pod的负载均衡(TCP/UDP 4层)
- 底层实现由kube-proxy通过userspace、iptables、ipvs三种代理模式完成
举例:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx1
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.20
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: test-svc
spec:
type: NodePort
selector:
app: nginx
ports:
- protocol: TCP
port: 1000
targetPort: 80
nodePort: 32034
- kube-proxy三种代理模式(service的实现方式)
- 中的 kube-proxy 是一个网络代理,负责为集群中的服务提供网络转发。
- userspace、iptables 和 ipvs。下面用通俗的例子来解释这三种模式。
- Userspace 模式
- kube-proxy)负责把你的订单(网络请求)交给厨师(后端 Pod)。服务员需要亲自跑到厨房,把订单交给厨师,然后再把做好的菜端给你。这个过程比较慢,因为服务员需要来回跑动。
- userspace 模式下,kube-proxy 在用户空间处理网络请求,数据包需要从内核空间传到用户空间,再由 kube-proxy 转发到后端 Pod。这种模式效率较低,因为数据包需要在用户空间和内核空间之间来回传递。

- iptables 模式
- iptables)。你点餐后,订单通过传送带直接送到厨师那里,厨师做好菜后也通过传送带直接送到你桌上。服务员只需要确保传送带正常工作。
- iptables 模式下,kube-proxy 通过配置 iptables 规则来实现网络转发。数据包直接在内核空间处理,不需要经过用户空间,效率更高。kube-proxy 只需要负责更新 iptables 规则,不需要亲自处理每个数据包。

- ipvs 模式[华王1]
- ipvs)。这个系统可以根据厨师的工作负载,自动把订单分配给最空闲的厨师,确保每道菜都能快速做好并送到你桌上。
- ipvs 模式下,kube-proxy 使用 Linux 内核的 IP Virtual Server(IPVS)功能来实现负载均衡。IPVS 提供了更高效的负载均衡算法,能够根据后端 Pod 的负载情况动态调整流量分配。这种模式性能最好,适合大规模集群。

- Userspace 模式:服务员亲自跑腿,效率低。
- iptables 模式:使用传送带自动送餐,效率较高。
- ipvs 模式:引入智能调度系统,效率最高,适合大规模集群。
- iptables 和 ipvs 是更常用的模式,尤其是 ipvs,因为它提供了更好的性能和可扩展性。
注:使用iptables与ipvs时机:
1.10版本之前使用iptables(1.1版本之前使用UserSpace进行转发)
1.11版本之后同时支持iptables与ipvs,默认使用ipvs,如果ipvs模块没有加载时,会自动降级至iptables
修改kube-proxy的工作模式
# 查看configmap
[root@master01 ~]# kubectl -n kube-system describe cm kube-proxy | grep mode

修改configmap
[root@master01 ~]#kubectl -n kube-system edit cm kube-proxy
mode: "ipvs"

重启damonset控制器
[root@master01 ~]# kubectl -n kube-system rollout restart daemonset kube-proxy
再次查看configmap
[root@master01 ~]# kubectl -n kube-system describe cm kube-proxy | grep mode

- service类型
Service类型决定了访问Service的方法
3.1 service类型
- ClusterIP
- 默认,分配一个集群内部可以访问的虚拟IP
- NodePort
- 在每个Node上分配一个端口作为外部访问入口
- nodePort端口范围为:30000-32767
- LoadBalancer
- 工作在特定的Cloud Provider上,例如Google Cloud,AWS,OpenStack
ExternalName表示把集群外部的服务引入到集群内部中来,即实现了集群内部pod和集群外部的服务进行通信
3.2 Service参数
- port :访问service使用的端口
- targetPort :Pod中容器暴露端口
- nodePort: 通过Node实现外网用户访问k8s集群内service的端口 (30000-32767)
Service的创建在工作中有两种方式:
一是命令行创建
二是通过资源清单文件YAML文件创建。
4.1 ClusterIP分类
ClusterIP根据是否生成ClusterIP又可分为普通Service和Headless Service
Service两类:
- 普通Service:
为Kubernetes的Service分配一个集群内部可访问的固定虚拟IP(Cluster IP), 实现集群内的访问。
- Headless Service[华王2] (无头服务,无群集ip): 用在内部的不公开的域名访问
该服务不会分配Cluster IP, 也不通过kube-proxy做反向代理和负载均衡。而是通过DNS提供稳定的网络ID来访问,DNS会将headless service的后端直接解析为pod IP列表。

4.1.1 普通ClusterIP Service创建
4.1.1.1 命令行创建Service
创建Deployment类型的应用
[root@master01 ~]# vim nginx1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-server1
spec:
replicas: 2
selector:
matchLabels:
app: nginx1
template:
metadata:
labels:
app: nginx1
spec:
containers:
- name: c1
image: nginx:1.20
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
应用资源清单文件
[root@master01 ~]# kubectl apply -f nginx1.yaml
验证Deployment类型的创建情况
[root@master01 ~]# kubectl get deployment.apps

[root@master01 ~]# kubectl get pod -o wide

[root@master01 ~]# curl 10.244.5.7 (pod ip地址)
可查看到网页内容

创建ClusterIP类型service与Deployment类型应用关联
命令创建service
[root@master01 ~]# kubectl expose deployment.apps nginx-server1 --type=ClusterIP --target-port=80 --port=80
说明:
expose 创建service
deployment.apps 控制器类型
nginx-server1 应用名称,也是service名称
--type=ClusterIP 指定service类型
--target-port=80 指定Pod中容器端口
--port=80 指定service端口
[root@master01 ~]# kubectl get service nginx-server1

[root@master01 ~]# curl 10.103.253.214 (ClusterIP 群集IP)

4.1.1.2 通过资源清单文件创建Service
[root@master01 ~]# vim nginx-server2.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-server2
spec:
replicas: 2
selector:
matchLabels:
app: nginx2
template:
metadata:
labels:
app: nginx2
spec:
containers:
- name: nginx2
image: nginx:1.20
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-server2
spec:
type: ClusterIP
ports:
- protocol: TCP
port: 80
targetPort: 80
selector:
app: nginx2
[root@master01 ~]# kubectl delete all --all
[root@master01 ~]# kubectl apply -f nginx-server2.yaml
查看service
[root@master01 ~]# kubectl get service
查看endpoints
[root@master01 ~]# kubectl get endpoints

4.1.1.3 访问
[root@master01 ~]# curl 10.98.242.254

可看到网页内容
4.1.1.4 两个pod里做成不同的主页方便测试负载均衡
[root@master01 ~]# kubectl get pod -o wide

[root@master01 ~]# kubectl exec -it nginx-server2-5f644dc499-62xmk -- bash
root@nginx-server2-5f644dc499-62xmk:/# cd /usr/share/nginx/html/
root@nginx-server2-5f644dc499-62xmk:/usr/share/nginx/html# echo web1 > index.html
root@nginx-server2-5f644dc499-62xmk:/usr/share/nginx/html# exit
[root@master01 ~]# kubectl exec -it nginx-server2-5f644dc499-62xmk -- bash
root@nginx-server2-5f644dc499-62xmk:/# cd /usr/share/nginx/html/
root@nginx-server2-5f644dc499-62xmk:/usr/share/nginx/html# echo web2 > index.html
root@nginx-server2-5f644dc499-62xmk:/usr/share/nginx/html# exit
exit
4.1.1.5 测试
[root@master01 ~]# curl 10.98.242.254
web2
[root@master01 ~]# curl 10.98.242.254
web1
4.1.2 Headless Service
- 普通的ClusterIP service是service name解析为cluster ip,然后cluster ip对应到后面的pod ip
- Headless service是指service name 直接解析为后面的pod ip
4.1.2.1 编写用于创建Deployment控制器类型的资源清单文件
[root@master01 ~]# vim nginx-server3.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-server3
spec:
replicas: 2
selector:
matchLabels:
app: nginx3
template:
metadata:
labels:
app: nginx3
spec:
containers:
- name: nginx-smart
image: nginx:1.20
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
[root@master01 ~]# kubectl apply -f nginx-server3.yaml
4.1.2.2 通过资源清单文件创建headless Service
[root@master ~]# vim headless-service.yml
apiVersion: v1
kind: Service
metadata:
name: headless-service
namespace: default
spec:
type: ClusterIP # ClusterIP类型,也是默认类型
clusterIP: None # None就代表是无头service
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx3
4.1.2.3 应用资源清单文件创建headless Service
[root@master ~]# kubectl apply -f headless-service.yml
4.1.2.4 查看已创建的headless Service
[root@master01 ~]# kubectl get svc

可以看到headless-service没有CLUSTER-IP,用None表示
[root@master01 ~]# kubectl get endpoints

4.1.2.5 DNS
DNS服务监视Kubernetes API,为每一个Service创建DNS记录用于域名解析
headless service需要DNS来解决访问问题
DNS记录格式为: 服务名.名称空间.svc.cluster.local.
4.1.2.5.1 查看kube-dns服务的IP (k8s群集内DNS服务,k8s内置的)
[root@master01 ~]# kubectl get svc -n kube-system

查看到coreDNS的服务地址是10.96.0.10
4.1.2.5.2 在集群主机通过DNS服务地址查找无头服务的dns解析
[root@master01 ~]# yum -y install bind-utils
[root@master01 ~]# dig[华王3] -t A[华王4] headless-service.default.svc.cluster.local. @10.96.0.10

生产环境中需要合法的域名
4.1.2.5.3 验证pod的IP
[root@master01 ~]# kubectl get pod -o wide

4.1.2.5.4 在集群中创建一个pod验证
创建一个镜像为yauritux/busybox-curl的pod,pod名称为busybox,用来解析域名
[root@master01 ~]# kubectl run busybox --image=yauritux/busybox-curl -it
/home # curl headless-service.default.svc.cluster.local.
显示网页内容

- NodePort类型(在外部使用集群节点IP访问)
创建资源清单文件
[root@master01 ~]# vim nodeport-service.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-server4
spec:
replicas: 2
selector:
matchLabels:
app: nginx-nodeport
template:
metadata:
labels:
app: nginx-nodeport
spec:
containers:
- name: nginx-nodeport
image: nginx:1.20
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: nginx-nodeport
spec:
type: NodePort
selector:
app: nginx-nodeport
ports:
- protocol: TCP
nodePort: 30001
port: 8060
targetPort: 80
应用资源清单文件
[root@master01 ~]# kubectl apply -f nodeport-service.yaml
验证service创建
[root@master01 ~]# kubectl get deployments.apps

[root@master01 ~]# kubectl get svc

[root@master01 ~]# kubectl get endpoints

访问kubernetes 任一节点ip的nodeport端口30001,均可成功访问
http://192.168.10.11:30001/



[华王1]在 iptables 模式下,数据包的处理流程如下:
- 客户端发送请求:客户端向 Service 的虚拟 IP(ClusterIP)发送请求。
- 数据包进入内核空间:数据包到达节点后,直接进入内核空间,由 iptables 规则处理。
- NAT 表处理:
-
- 数据包首先经过 nat 表的 PREROUTING 链,进行目标地址转换(DNAT)。
- iptables 规则将数据包的目标 IP 地址从 Service 的 ClusterIP 转换为后端 Pod 的 IP 地址。
- 转发到后端 Pod:数据包被转发到后端 Pod。
- 响应处理:
-
- Pod 处理完请求后,响应数据包经过 nat 表的 POSTROUTING 链,进行源地址转换(SNAT)。
- 响应数据包直接返回给客户端。
[华王2]无头服务的特点
- 没有 ClusterIP:
-
- 无头服务不分配 ClusterIP,因此没有单一的 IP 地址可供客户端访问。
- 直接解析到 Pod IP:
-
- 客户端通过 DNS 查询无头服务的名称时,会返回所有匹配 Pod 的 IP 地址列表。
- 适用于有状态应用:
-
- 无头服务为有状态应用(如数据库集群、消息队列集群)提供稳定的网络标识。
- 灵活性高:
-
- 无头服务允许用户直接与 Pod 通信,避免了负载均衡器的介入,适合需要自定义网络策略的场景。
- [华王3]dig:DNS 查询工具,用于向 DNS 服务器发送查询请求并返回结果。
[华王4]-t A:指定查询的记录类型为 A 记录(Address Record),A 记录用于将域名解析为 IPv4 地址。
更多推荐
所有评论(0)