Service 详解

1. Service 定义

在 Kubernetes 中,Service 是一种抽象,用于定义一组 Pod 的访问方式和网络策略。Service 允许将一组具有相同标签的 Pod 组合在一起,并为它们提供一个统一的访问入口,从而实现服务发现和负载均衡。

Service 的 yaml 格式的定义文件的完整内容如下:

apiVersion: v1
kind: Service
metadata:
  name: string
  namespace: string
  labels:
    - name: string 
  annotations:
    - name: string
spec:
  selector: []
  type: string	
  clusterIP: string
  sessionAffinity: string 
  ports:
    - name: string
      protocol: string 
      port: int
      targetPort: int
  nodePort: int 
status:
  loadBalancer: 
    ingress:
      ip: string
      hostname: string
YAML

对 Service 的定义文件模板的各属性的说明如下表所示:

属性名称取值类型是否必选取值说明
apiVersionstring必选v1
kindstring必选Service
metadataobject必选元数据
metadata.name string必选Service 名称,须符合 RFC 1035 规范
metadata.namespacestring必选名称空间,不指定时系统将使用名为“default”的命名空间。
metadata. labelslist自定义标签属性列表
metadata.annotationlist自定义注解属性列表
specobject必选详细描述
spec.selectorlist必选标签选择器配置,将选择具有指定标签的Pod作为管理范围
spec.typestringService 的类型,指定 Service 的访问方式,默认值为 CluterlP。
spec.clusterIPstring虚拟服务的 IP 地址,当type=ClusterIP 时,如果不指定该属性,则系统自动分配一个 Ip
spec.sessionAffinitystring是否支持Session,可选值为ClientIP,默认值为None。
ClientIP:表示将同一个客户端(根据客户端的IP地址决定)的访问请求都转发到同一个后端 Pod上
spec.portslistService 端口列表
spec.ports.namestring端口名称
spec.ports.protocolstring端口协议,支持TCP和 UDP,默认值为TCP
spec.ports.portint服务监听的端口号
spec.ports.targetPortint需要转发到后端 Pod上的端口号
spec.ports.nodePortint当spec.type=NodePort时,指定映射到宿主机的端口号
statusobject当spec.type=LoadBalancer时,设置外部负载均衡器的地址,用于公有云环境
status.loadBalancerobject外部负载均衡器
status.loadBalancer.ingressobject外部负载均衡器
status.loadBalancer.ingress.ipstring外部负载均衡器的IP地址
status.loadBalancer.ingress.hostnamestring外部负载均衡器的主机名

2. Service 基本使用示例

创建一个包含多个 nginx pod 副本的集合:

# webapp-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: webapp
spec:
  replicas: 2
  selector:
    matchLabels:
      app: webapp
  template:
    metadata:
      labels:
        app: webapp
    spec:
      containers:
      - name: webapp
        image: nginx:1.26.2
        ports:
        - containerPort: 80
YAML

创建:

kubectl apply -f webapp-deployment.yaml
ShellScript

查看 pod ip 地址:

kubectl get pod -l app=webapp -o wide

NAME                     READY   STATUS    RESTARTS   AGE   IP            NODE                NOMINATED NODE   READINESS GATES
webapp-78c9968fc-4zhsk   1/1     Running   0          30s   10.244.3.87   k8s-node-04-r-214   <none>           <none>
webapp-78c9968fc-j5vc5   1/1     Running   0          30s   10.244.5.79   k8s-node-08-u-218   <none>           <none>
ShellScript

在集群内访问该 pod:

# 在集群内创建一个服务
# ubuntu-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: ubuntu-pod
  labels:
    app: ubuntu-container
spec:
  containers:
  - name: ubuntu-container
    image: ubuntu:latest
    command: ["/bin/bash", "-c", "--"]
    args: ["while true; do sleep 30; done;"]
    resources:
      limits:
        memory: "512Mi"
        cpu: "500m"
    volumeMounts:
    - name: shared-data
      mountPath: /data
  volumes:
  - name: shared-data
    emptyDir: {}
  restartPolicy: Never

# 创建
kubectl apply -f ubuntu-pod.yaml

# 进入容器
kubectl exec -it ubuntu-pod -- /bin/bash

# 访问 nginx pod
apt update
apt install curl -y
curl 10.244.3.87:80

<!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>
ShellScript

此时我们通过 pod 的 ip + 端口可以访问到 nginx 服务,但 pod 的 ip 是动态变化的(例如发生故障后控制器重启了 pod),同时在运行的过程中 pod 副本的数量是可能变化的,因此对于客户端应用来说,要实现动态感知服务后端实例的变化,以及实现将请求发送到多个后端实例上的负载均衡机制,都会大大增加客户端系统实现的复杂度。
所以,Kubernetes 的 Service 就是用于解决这些问题的核心组件。通过 Service 的定义,可以对客户端应用屏蔽后端实例数量及 PodIP 地址的变化,通过负载均衡策略实现将请求转发到后端实例上,为客户端应用提供一个稳定的服务访问入口地址。Service 实现的是微服务架构中的几个核心功能:全自动的服务注册、服务发现、服务负载均衡等。

为上面创建的 pod 创建 service:

# Kubernetes 提供了一种快速的方法,即通过 kubectl expose 令来创建 Service
kubectl expose deployment webapp service

# 为了更精细化管理,可以通过 yaml 文件来创建 service
# webapp-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: webapp
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  selector:
    app: webapp
ShellScript

查看 service 的 ip 地址:

kubectl get svc

NAME         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)   AGE
webapp       ClusterIP   10.100.238.224   <none>        80/TCP    23s
ShellScript

在集群内访问 service:

curl 10.100.238.224:80

<!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>
ShellScript

同样可以访问到 nginx 服务,请求会被负载均衡的分发给两个 nginx 服务。同时Service 不仅具有 IP 地址,还会分配一个域名(域名解析由 CoreDNS 负责,后面详细介绍),Service 域名的格式为 <service-name>.<namespace>.svc.<clusterDomain>。示例:

curl webapp.default.svc.cluster.local:80

<!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>
ShellScript

一个 Service 对应的“后端”由 Pod 的 IP 地址和容器端口号组成,即一个完整的”IP:Port”访问地址,它在 Kubernetes 系统中被称作 Endpoint (端点)。通过查看 Service 的详细信息,可以看到其后端 Endpoint 列表:

kubectl describe service webapp

Name:                     webapp
Namespace:                default
Labels:                   <none>
Annotations:              <none>
Selector:                 app=webapp
Type:                     ClusterIP
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.100.238.224
IPs:                      10.100.238.224
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
Endpoints:                10.244.5.79:80,10.244.3.87:80
Session Affinity:         None
Internal Traffic Policy:  Cluster
Events:                   <none>
ShellScript

实际上在创建 Service 时系统自动创建了同名的 Endpoint 资源对象:

kubectl get endpoints webapp 
NAME     ENDPOINTS                       AGE
webapp   10.244.3.23:80,10.244.4.51:80   33m
ShellScript

自动关联机制:

  • Service 的 selector 字段:Service 通过 selector 中定义的标签(labels)筛选匹配的 Pod。
  • Endpoints 的自动更新:Kubernetes 的 endpoints-controller 会持续监控 Pod 的变化,将 所有匹配 Service selector 的 Pod 的 IP:Port 更新到与Service 同名 Endpoints 对象中。

3. Service 的多端口设置

Service 可以设置多个端口来提供不同的服务,示例:

apiVersion: v1
kind: Service
metadata:
  name: webapp
spec:
  ports:
  - port: 80
    targetPort: 80
    name: web
  - port: 81
    targetPort: 81
    name: management
  selector:
    app: webapp
YAML

同一个端口使用不同的协议示例:

apiVersion: v1
kind: Service
metadata:
  name: kube-dns
  namespace: kube-system
  labels:
    k8s-app: kube-dns
    kubernetes.io/cluster-service: "true"
    kubernetes.io/name: "KubeDNS"
spec:
  selector:
    k8s-app: kube-dns
  clusterIP: 169.169.0.100
  ports:
  - name: dns
    port: 53
    protocol: UDP
  - name: dns-tcp
    port: 53
    protocol: TCP
YAML

4. Service 的类型

Service 的类型如下:

  • ClusterIP:Kubernetes 默认会自动设置 Service 的虚拟 IP 地址,仅可被集群中的客户端应用访问。
  • NodePort:将 Service 的端口号映射到每个 Node 的一个端口号上,这样集群中的任意 Node 都可以作为 Service 的访问入口地址,即 NodeIP:NodePort。
  • LoadBalancer:将 Service 映射到一个已存在的负载均衡器的 IP 地址上,通常在公有云环境下使用。
  • ExternalName:将 Service 映射为一个外部域名地址,通过 externalName 字段进行设置。

4.1. ClusterIP 类型

这是 Kubernetes 为 Service 设置 IP 地址的默认类型,kube-apiserver 服务的启动参数 –service-cluster-ip-range 设置了 Service 的 IP 地址范围,系统将自动从这个IP 地址池中为 Service 分配一个可用的 IP 地址。
用户也可以手动指定一个 ClusterIP 地址,可以通过 spec.clusterlP 字段进行设置,需要确保该 IP 地址在可用的 ClusterIP 地址池内,并且没有被其他 Service 使用。示例如下:

apiVersion: v1
kind: Service
metadata:
  name: webapp
spec:
  type: ClusterIP
  clusterIP: 10.100.238.224
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  selector:
    app: webapp
YAML

4.2. NodePort 类型

NodePort 类型用于将 Service 暴露到 Node 上,这样集群外的客户端可以通过 Node 的 IP 地址访问集群中的 Service。使用 NodePort 类型时,系统会在 Node 上开启一个端口号,考虑到可能会有其他应用程序已经占用了一些端口号(例如操作系统的系统服务占用的端口号),要求在部署 Kubernetes 集群时,通过 kube-apiserver 的启动参数 –service-node-port-range 指定可以分配的 NodePort 端口号范围,默认值为[30000~32767]。
在 Service 的定义中,可以在每个端口的配置中,通过字段 nodePort 指定一个值,如果不指定,Kubernetes 会基于端口号范围自动分配一个端口号。示例如下:

apiVersion: v1
kind: Service
metadata:
  name: webapp
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30000
  selector:
    app: webapp
YAML

4.3. LoadBalancer 类型

需要向云提供商申请一个独立于 k8s 的负载均衡器,如果集群运行在本地(无云厂商 LB),可以使用 MetalLB 提供 LoadBalancer 支持。

apiVersion: v1
kind: Service
metadata:
  name: my-loadbalancer-service
spec:
  type: LoadBalancer  # 指定 Service 类型为 LoadBalancer
  selector:
    app: nginx  # 选择要暴露的 Pod(匹配 Pod 的 labels)
  ports:
    - protocol: TCP
      port: 80       # Service 对外暴露的端口
      targetPort: 80 # Pod 监听的端口
  externalTrafficPolicy: Local  # (可选)流量策略
YAML

4.4. ExternalName 类型

ExternalName 类型的服务用于将集群外的服务定义为 Kubernetes 的集群的 Service,并且通过 externalName 字段指定外部服务的地址(只能使用域名不支持 IP 地址格式)。集群中的客户端应用通过访问这个 Service 就能访问外部服务了。示例:

apiVersion: v1
kind: Service
metadata:
  name: my-service
  namespace: prod
spec:
  type: ExternalName
  externalName: www.baidu.com
YAML

如果外部服务没有域名,而只有 ip+port,那我们无法指定 ExternalName,此时只能通过自建 endpoint 来实现,示例如下:

  • 第一种配置:普通 ClusterIP Service
    • Service 类型:默认 ClusterIP(未显式设置 clusterIP: None),会自动分配一个虚拟 IP。
    • DNS 解析
      • 查询 my-service 时返回 ClusterIP(如 10.96.123.456)。
      • 请求发送到 ClusterIP 后,由 kube-proxy 通过 iptables/ipvs 负载均衡到后端 IP(192.168.2.201:80)。
    • 流量路径Pod → ClusterIP (VIP) → kube-proxy 负载均衡 → 192.168.2.201
kind: Service
apiVersion: v1
metadata:
  name: my-service
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80

---
kind: Endpoints
apiVersion: v1
metadata:
  name: my-service
subsets:
  - addresses:
      - IP: 192.168.2.201
    ports:
      - port: 80
YAML
  • 第二种配置:Headless Service(clusterIP: None
    • Service 类型ClusterIP 但显式设置为 clusterIP: None(即 Headless Service)。
    • DNS 解析
      • 查询 my-service 时 直接返回后端 IP192.168.2.201),无 ClusterIP
      • 客户端直接连接后端 IP,绕过 kube-proxy 代理
    • 流量路径Pod → 192.168.2.201 (直接连接)
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: ClusterIP
  clusterIP: None  # clusterIP 设置为 None
  ports:
    - name: port
      port: 80

---
apiVersion: v1
kind: Endpoints
metadata:
  name: my-service # 名称必须和 Service 一致
subsets:
  - addresses:
      - IP: 192.168.2.201 # Service 将连接重定向到 endpoint
    ports:
      - name: port
        port: 80
YAML

5. Service 负载均衡机制

Service 负载均衡策略由 kube-proxy 的负责实现。

5.1. kube-proxy 的代理模式

  • iptables 模式(仅适用于 Linux 系统)
    • 通过 Linux 内核的 iptables 规则链匹配目标 Pod IP,随机选择后端。集群规模大时效率不高。
  • ipvs 模式(仅适用于 Linux 系统)
    • 使用内核的 IPVS(LVS)模块,支持更丰富的算法(如轮询、最少连接)。转发效率高,适合大规模集群或高并发场景。
  • kernelspace 模式(适用于 windows 系统)

5.2. 负载均衡算法

确认当前的 kube-proxy 模式

# 查看 Pod YAML 文件
kubectl get pods -n kube-system -l k8s-app=kube-proxy -o yaml | grep -i "mode"
# 输出可能为:
## mode: "iptables"(默认模式,使用 iptables 规则)
## mode: "ipvs"(高性能模式,支持更多负载均衡算法)

# 检查 kube-proxy 的启动参数
kubectl get pods -n kube-system -l k8s-app=kube-proxy -o yaml | grep -i "\-\-proxy-mode"
# 如果输出类似:- --proxy-mode=ipvs 则说明 kube-proxy 运行在 ipvs 模式;如果没有 --proxy-mode 参数,则默认是 iptables 模式。

# 检查 kube-proxy ConfigMap
kubectl get configmap kube-proxy -n kube-system -o yaml | grep -i "mode"
# 如果输出类似:mode: "ipvs" 则说明 kube-proxy 运行在 ipvs 模式;如果没有 mode 字段,则默认是 iptables 模式。


# 注意:当 kube-proxy 以 ipvs 代理模式启动时,kube-proxy 将验证节点上是否安装了 IPVS 模块,如果未安装,则 kube-proxy 将回退到 iptables 代理模式
Bash

修改负载均衡算法

  • 如果 kube-proxy 使用 iptables 模式
    • 默认使用 随机(random) 负载均衡策略。
    • 无法直接修改算法,因为 iptables 本身不提供多种负载均衡策略。
  • 如果 kube-proxy 使用 ipvs 模式
    • ipvs 支持多种负载均衡算法,可以通过修改 kube-proxy 的 ConfigMap 来调整,示例如下:
# 编辑 kube-proxy ConfigMap
kubectl edit configmap kube-proxy -n kube-system

# 修改 ipvs 相关配置
ipvs:
  scheduler: "rr"  # 可选算法:rr|wrr|lc|wlc|lblc|lblcr|dh|sh|sed|nq
  strictARP: true  # 如果使用 MetalLB,建议启用
  
# 修改后重启 kube-proxy Pod
kubectl rollout restart daemonset kube-proxy -n kube-system
Bash

5.3. 会话保持机制

Service 支持通过设置 sessionAffinity 来实现基于客户端 IP 地址的会话保持机制,即首次将某个客户端来源IP地址发起的请求转发到后端的某个 Pod 上,之后从相同的客户端 IP 地址发起的请求都将被转发到相同的后端 Pod 上,配置参数为 spec.sessionAffinity,示例:

apiVersion: v1
kind: Service
metadata:
  name: webapp
spec:
  sessionAffinity: ClientIP
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  selector:
    app: webapp
YAML

同时,用户可以设置会话保持的最长时间,在此时间之后重置客户端来源 IP 地址的保持规则,配置参数为 spec.sessionAffinityConfig.clientIP.timeoutSeconds。例如下面的服务将会话保持时间设置为 10800s(3h):

apiVersion: v1
kind: Service
metadata:
  name: webapp
spec:
  sessionAffinity: ClientIP
  sessionAffinityConfig:
    clientIP:
      timeoutSeconds: 10800
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  selector:
    app: webapp
YAML

注意:使用了会话保持机制,则不再有负载均衡的效果。

5.4. Service 的流量策略

  • 外部流量策略(externalTrafficPolicy
    • 控制从集群外部(如 NodePort 或 LoadBalancer 类型 Service)进入的流量如何路由到 Pod。
    • 可选值:
      • Cluster(默认):流量可能被转发到任意节点的 Pod(即使 Pod 不在该节点上)。
      • Local:流量仅转发到接收流量的节点上运行的 Pod(若无本地 Pod,连接丢弃)。
    • 配置示例:
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  type: LoadBalancer
  externalTrafficPolicy: Local  # 设置为 Local 策略
  selector:
    app: my-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
YAML
  • 内部流量策略(internalTrafficPolicy
    • 控制集群内部(如其他 Pod)通过 Service 访问时的流量路由行为(Kubernetes 1.22+ 支持)。
    • 可选值:
      • Cluster(默认):流量可能被转发到任意节点的 Pod。
      • Local:流量仅转发到发起源所在节点上的 Pod(若无本地 Pod,连接失败)。
    • 配置示例:
apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  internalTrafficPolicy: Local  # 内部流量仅本地路由
  selector:
    app: my-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080
YAML

在 v1.22 版本引入了 ProxyTerminatingEndpoints 字段,ProxyTerminatingEndpoints 是一个与 Service 流量处理相关的特性,主要用于控制 处于终止状态(Terminating)的 Pod 是否继续接收流量。

当 Pod 被删除时,它会进入 Terminating 状态,Pod 从 Service 的 Endpoints 列表中移除(默认行为),但在某些场景下(如滚动更新或缩容),立即切断流量可能导致请求失败,尤其是长连接请求(如 WebSocket)。

  • ProxyTerminatingEndpoints 的作用
    • 功能:允许 kube-proxy 继续将流量转发给处于 Terminating 状态的 Pod,直到它们完全终止(前提是 Pod 仍能处理请求)。
    • 目的
      • 避免因 Pod 终止导致的请求中断。
      • 支持优雅终止(如完成正在处理的请求)。

6. Headless Service

Headless Service 是指服务没有入口访问地址(无 ClusterIP 地址),kube-proxy 不会为其创建负载转发规则,如果 Headless Service 设置了标签选择器,Kubernetes 将根据标签选择器查询后端 Pod 列表,自动创建 Endpoints 列表,将服务名(DNS城名)的解析机制设置为:当客户端访问该服务名时,得到的是全部 Endpoints 列表,而不是一个单独的 IP 地址。示例如下:

# headless-service-test.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.26.2
        ports:
        - containerPort: 80

---
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
  clusterIP: None
  selector:
    app: nginx
YAML

创建示例:

kubectl apply -f headless-service-test.yaml
ShellScript

查看创建的 pod ip:

kubectl get pods -l app=nginx -o wide

NAME                     READY   STATUS    RESTARTS   AGE     IP            NODE                NOMINATED NODE   READINESS GATES
nginx-567cbc4d7c-5bs62   1/1     Running   0          2m25s   10.244.5.80   k8s-node-08-u-218   <none>           <none>
nginx-567cbc4d7c-dwff7   1/1     Running   0          2m25s   10.244.2.83   k8s-node-01-c-211   <none>           <none>
nginx-567cbc4d7c-sfnrd   1/1     Running   0          2m25s   10.244.3.89   k8s-node-04-r-214   <none>           <none>
ShellScript

查看 Headless Service 详细信息:

kubectl describe svc nginx

Name:                     nginx
Namespace:                default
Labels:                   app=nginx
Annotations:              <none>
Selector:                 app=nginx
Type:                     ClusterIP
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       None
IPs:                      None
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
Endpoints:                10.244.5.80:80,10.244.2.83:80,10.244.3.89:80
Session Affinity:         None
Internal Traffic Policy:  Cluster
Events:                   <none>
ShellScript

可以使用 nslookup 工具解析 ip 地址:

# 创建一个 ubuntu 系统 pod,并进入 pod
kubectl exec -it ubuntu-pod -- bash

# 解析 headless server 将会返回全部的 endpoint 的 ip 地址
nslookup nginx.default.svc.cluster.local

Server:		10.96.0.10
Address:	10.96.0.10#53

Name:	nginx.default.svc.cluster.local
Address: 10.244.5.80
Name:	nginx.default.svc.cluster.local
Address: 10.244.2.83
Name:	nginx.default.svc.cluster.local
Address: 10.244.3.89
ShellScript

7. 了解拓展

statefulSet 创建的 Pod 有 DNS 地址,通过解析 Pod 的 DNS 可以返回 Pod 的 IP 地址而 deployment 创建的 Pod 没有 DNS,则无法解析。我们可以通过设置 hostname 和 subdomain 字段来自定义一个域名。示例如下:

# headless-service-test.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      hostname: nginx-01
      subdomain: nginx
      containers:
      - name: nginx
        image: nginx:1.26.2
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
  clusterIP: None
  selector:
    app: nginx
YAML
nslookup nginx-01.nginx.default.svc.cluster.local

Server:		10.96.0.10
Address:	10.96.0.10#53

Name:	nginx-01.nginx.default.svc.cluster.local
Address: 10.244.5.84
ShellScript

官方参考文档:https://kubernetes.io/zh-cn/docs/concepts/services-networking/dns-pod-service

上一篇
下一篇