本文介绍如何使用 Service 暴露应用、实现负载均衡和服务发现,并管理相关标签。
📌 核心概念:Kubernetes Service
什么是 Service?
Pod 是有生命周期的,当节点故障或被替换时,其上的 Pod 会随之消亡,并由 ReplicaSet 等控制器创建新 Pod 来替换。这些新 Pod 会分配新的 IP 地址。Service 正是为了解决由此产生的服务发现与稳定访问端点问题而设计的抽象层。
Service 的核心作用:
-
定义一组 Pod 的逻辑集合
-
为这组 Pod 提供统一的访问入口(端点)
-
实现负载均衡
-
提供服务发现机制
通过 Service,即使后端 Pod 发生变更,前端应用也无需关心具体的 Pod IP,实现了前后端之间的松耦合。
Service 的类型
在定义 Service 时,可以通过 spec.type 字段指定不同的暴露方式:
| ClusterIP (默认) | 在集群内部 IP 上暴露服务,仅限集群内部访问 | 内部微服务间通信 |
| NodePort | 通过 NAT 在每个节点的相同端口上暴露服务,可通过 节点IP:节点端口 从外部访问 | 开发测试、简单外部访问 |
| LoadBalancer | 利用云平台的负载均衡器分配外部 IP,自动将流量导向 Service | 生产环境,云平台支持时 |
| ExternalName | 将 Service 映射到外部域名(CNAME 记录),无代理 | 集成外部服务 |
NodePort 是 ClusterIP 的超集,LoadBalancer 是 NodePort 的超集。
🏷️ 服务与标签(Labels)
Service 通过 标签选择器(Label Selector) 来匹配一组 Pod。标签是附加到对象(如 Pod)上的键值对,用于逻辑分组。
标签的常见用途:
-
标识环境(如 env=prod、env=dev)
-
标注版本(如 version=v1.2.0)
-
按功能分类(如 tier=frontend、component=redis)
标签可以在创建对象时指定,也可以后续动态添加、修改。
🛠️ 实践操作
步骤 1:创建 Service(NodePort 类型)
使用 kubectl expose 命令为 Deployment 创建 Service:
kubectl expose deployment/kubernetes-bootcamp –type="NodePort" –port 8080
此命令会创建一个名为 kubernetes-bootcamp 的 Service,类型为 NodePort,容器端口为 8080。
ccc@cccs-MBP ~ % kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 20h
ccc@cccs-MBP ~ % kubectl expose deployment/kubernetes-bootcamp –type="NodePort" –port 8080
service/kubernetes-bootcamp exposed
ccc@cccs-MBP ~ % kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 20h
kubernetes-bootcamp NodePort 10.99.224.218 <none> 8080:30848/TCP 8s
ccc@cccs-MBP ~ %
查看 Service 详情:
kubectl describe services/kubernetes-bootcamp
输出会显示 Service 的集群 IP、内部端口以及节点端口(NodePort,范围通常为 30000-32767)。
ccc@cccs-MBP ~ % kubectl describe services/kubernetes-bootcamp
Name: kubernetes-bootcamp
Namespace: default
Labels: app=kubernetes-bootcamp
Annotations: <none>
Selector: app=kubernetes-bootcamp
Type: NodePort
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.99.224.218
IPs: 10.99.224.218
LoadBalancer Ingress: localhost
Port: <unset> 8080/TCP
TargetPort: 8080/TCP
NodePort: <unset> 30848/TCP
Endpoints: 10.1.0.17:8080
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
ccc@cccs-MBP ~ %
设置环境变量并测试访问:
# 提取节点端口号
export NODE_PORT=$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}')
echo "NodePort: $NODE_PORT"
# 在Docker Desktop中可以直接localhost或127.0.0.1
curl http://localhost:$NODE_PORT
ccc@cccs-MBP ~ % export NODE_PORT=$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}')
echo "NodePort: $NODE_PORT"
NodePort: 30848
ccc@cccs-MBP ~ % curl http://localhost:30848
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-75c5d958ff-flfdd | v=1
ccc@cccs-MBP ~ %
步骤 2:使用标签进行查询和管理
查看 Deployment 自动创建的标签:
kubectl describe deployment kubernetes-bootcamp
通常会自动生成 app=kubernetes-bootcamp 标签。
使用标签筛选 Pod 和 Service:
# 查看带有特定标签的 Pod
kubectl get pods -l app=kubernetes-bootcamp
# 查看带有特定标签的 Service
kubectl get services -l app=kubernetes-bootcamp
为 Pod 添加新标签:
# 获取 Pod 名称
export POD_NAME=$(kubectl get pods -o go-template –template '{{range .items}}{{.metadata.name}}{{"\\n"}}{{end}}')
# 添加版本标签
kubectl label pods $POD_NAME version=v1
# 验证标签
kubectl describe pods $POD_NAME
# 按新标签查询
kubectl get pods -l version=v1
ccc@cccs-MBP ~ % export POD_NAME="$(kubectl get pods -o go-template –template '{{range .items}}{{.metadata.name}}{{"\\n"}}{{end}}')"
echo "Name of the Pod: $POD_NAME"
Name of the Pod: kubernetes-bootcamp-75c5d958ff-flfdd
ccc@cccs-MBP ~ % kubectl label pods "$POD_NAME" version=v1
pod/kubernetes-bootcamp-75c5d958ff-flfdd labeled
ccc@cccs-MBP ~ % kubectl describe pods "$POD_NAME"
Name: kubernetes-bootcamp-75c5d958ff-flfdd
Namespace: default
Priority: 0
Service Account: default
Node: docker-desktop/192.168.65.4
Start Time: Fri, 30 Jan 2026 09:18:24 +0800
Labels: app=kubernetes-bootcamp
pod-template-hash=75c5d958ff
version=v1
Annotations: <none>
Status: Running
IP: 10.1.0.17
IPs:
IP: 10.1.0.17
Controlled By: ReplicaSet/kubernetes-bootcamp-75c5d958ff
Containers:
kubernetes-bootcamp:
Container ID: docker://42746c7a21be846354d7c4f0f33a364efcfd9cc4f5353907c1b9912e106beeb0
Image: gcr.io/google-samples/kubernetes-bootcamp:v1
Image ID: docker-pullable://gcr.io/google-samples/kubernetes-bootcamp@sha256:0d6b8ee63bb57c5f5b6156f446b3bc3b3c143d233037f3a2f00e279c8fcc64af
Port: <none>
Host Port: <none>
State: Running
Started: Fri, 30 Jan 2026 09:18:25 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-s64m8 (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
kube-api-access-s64m8:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events: <none>
ccc@cccs-MBP ~ % kubectl get pods -l version=v1
NAME READY STATUS RESTARTS AGE
kubernetes-bootcamp-75c5d958ff-flfdd 1/1 Running 0 132m
ccc@cccs-MBP ~ %
步骤 3:删除 Service
通过标签删除 Service:
kubectl delete service -l app=kubernetes-bootcamp
验证删除结果:
kubectl get services
注意:删除 Service 仅移除了访问入口,不会删除 Pod。应用仍可在集群内部运行,可通过进入 Pod 内部验证:
kubectl exec -ti $POD_NAME — curl http://localhost:8080
若要完全关闭应用,需要删除对应的 Deployment。
📊 总结
| 创建 NodePort Service | kubectl expose deployment/<名称> –type=NodePort –port <端口> | 暴露应用到集群外部 |
| 查看 Service 详情 | kubectl describe services/<名称> | 查看 IP、端口、选择器等详细信息 |
| 按标签筛选对象 | kubectl get pods -l <键>=<值> | 查询带有特定标签的 Pod/Service |
| 添加标签 | kubectl label pods <名称> <键>=<值> | 为已有对象添加或更新标签 |
| 删除 Service | kubectl delete service -l <键>=<值> | 通过标签删除 Service(不影响 Pod) |
🔍 补充说明
-
无选择器的 Service:可以创建不定义 selector 的 Service,此时不会自动创建 Endpoints,需手动关联特定端点。
-
ExternalName 类型:仅用于 DNS 映射,不进行流量代理,适合集成外部服务。
-
负载均衡:Service 默认在匹配的 Pod 间进行会话无关的轮询负载均衡。
网硕互联帮助中心




评论前必须登录!
注册