
— 特色专栏 —
MySQL / PostgreSQL / MongoDB
ElasticSearch / Hadoop / Redis
Kubernetes / Docker / DevOps
Nginx / Git / Tools / OpenStack
大家好,我是民工哥!
谁再说搞不懂 k8s 四种 Service 类型!就把这个给他甩过去。

Kubernetes(简称k8s) 是一个开源的容器编排平台,用于自动化应用程序的部署、扩展和管理。它最初由谷歌设计,并基于谷歌内部多年运行容器化工作负载的经验(即Borg系统)开发而成,后来捐赠给云原生计算基金会(CNCF)进行维护和推广。Kubernetes 已经成为容器编排领域的事实标准,广泛应用于云原生应用开发和微服务架构中。
在 Kubernetes 中,Service 是一种抽象概念,用于将一组运行在 Pods 上的应用程序暴露为网络服务。Kubernetes 提供了四种主要的 Service 类型,每种类型适用于不同的使用场景。

k8s 四种 Service 类型:ClusterIP、NodePort、LoadBalancer、ExternalName,今天一次性给你们讲清楚。
它是 Kubernetes Service的默认类型,也就是说如果不指定 type,Kubernetes 会默认创建 ClusterIP 类型的 Service。
仅在集群内部可访问,提供一个集群内部的虚拟 IP 地址(ClusterIP)。适用于集群内部的服务发现和通信,例如微服务之间的调用。

简单易用,默认类型,无需额外配置。它提供稳定的虚拟 IP 和 DNS 名称,便于服务发现。且负载均衡和故障转移由 Kubernetes 自动处理。
10.96.0.0/12)。selector 字段选择一组 Pod 作为后端。Kubernetes 会自动创建与 Service 同名的 Endpoints 对象,其中包含所有匹配 selector 的 Pod 的 IP 和端口。如果 Pod 发生变化(例如扩容或重启),Endpoints 会自动更新。kube-proxy 组件会监听 Service 和 Endpoints 的变化,并在节点上配置 iptables 或 IPVS 规则,将流量从 ClusterIP 转发到后端 Pod。编写 Service 定义文件:
type: ClusterIP(默认值,可省略)。selector 以匹配目标 Pod 的标签。ports,包括 port(Service 的端口)和 targetPort(Pod 的端口)。应用 YAML 文件
kubectl apply -f your-service.yaml
示例 YAML 文件
apiVersion: v1
kind:Service
metadata:
name:my-clusterip-service
spec:
type:ClusterIP#可省略,默认就是 ClusterIP
selector:
app:my-app#匹配 Pod 的标签
ports:
-protocol:TCP
port:80 #Service 的端口,集群内的其他 Pod 通过该端口访问服务。
targetPort:8080#Pod 的端口,Service 将流量转发到该端口。
创建 Service
kubectl expose deployment my-deployment \
--type=ClusterIP \
--name=my-clusterip-service \
--port=80 \
--target-port=8080
验证 Service
kubectl get svc my-clusterip-service
验证 ClusterIP 服务
获取 ClusterIP 地址:
kubectl get svc my-clusterip-service
输出示例:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-clusterip-service ClusterIP 10.96.123.45 <none> 80/TCP 10s
从集群内部访问服务
假设有一个 Pod 运行在集群中,可以通过 ClusterIP 地址访问服务:
curl http://10.96.123.45:80
检查 Service 详情
kubectl describe svc my-clusterip-service
如果需要手动指定 ClusterIP,可以在 YAML 文件中添加 clusterIP 字段:
apiVersion: v1
kind:Service
metadata:
name:my-clusterip-service
spec:
type:ClusterIP
clusterIP:10.96.0.100#手动指定 ClusterIP
selector:
app:my-app
ports:
-protocol:TCP
port:80
targetPort:8080
注意:指定的 ClusterIP 必须在 Kubernetes 配置的地址范围内,且不能与其他服务冲突。
Service 可以暴露多个端口,每个端口可以映射到后端 Pod 的不同端口。
spec:
ports:
-name:http
protocol:TCP
port:80
targetPort:8080
-name:https
protocol:TCP
port:443
targetPort:8443
Kubernetes Service 的 NodePort 类型 是一种用于将服务暴露到集群外部的 Service 类型。在每个节点上开放一个静态端口(NodePort),允许通过 <NodeIP>:<NodePort> 的方式从集群外部访问服务。NodePort 会在 ClusterIP 的基础上额外暴露一个端口。

NodePort 的端口范围默认是 30000-32767,也可以通过手工配置调整。由于每个服务占用一个节点端口,会导致端口资源有限,手动管理端口可能会导致冲突。总体性能和可用性不如 LoadBalancer。
30000-32767,但可以手动指定。kube-proxy 组件会监听 Service 和 Endpoints 的变化,并通过 iptables 或 IPVS 规则将流量从 NodePort 转发到后端 Pod。在 Kubernetes 中,配置 NodePort 类型的服务可以通过 YAML 文件或 kubectl 命令行工具完成。
编写 Service 定义文件:
type: NodePort。selector 以匹配目标 Pod 的标签。ports,包括 targetPort(Pod 的端口)和 nodePort。应用 YAML 文件:
kubectl apply -f your-service.yaml
apiVersion: v1
kind:Service
metadata:
name:my-nodeport-service
spec:
type:NodePort#指定服务类型为 NodePort
selector: #用于匹配目标 Pod 的标签
app:my-app#匹配 Pod 的标签
ports:
-protocol:TCP
port:80 #Service 的端口,客户端通过该端口访问服务
targetPort:8080#Pod 的端口,Service 将流量转发到该端口
nodePort:30007#可选,指定节点端口(范围 30000-32767)
创建 Service:
kubectl expose deployment my-deployment \
--type=NodePort \
--name=my-nodeport-service \
--port=80 \
--target-port=8080 \
--node-port=30007
参数详解
expose deployment:#基于现有的 Deployment 创建 Service。
--type=NodePort:#指定服务类型为 NodePort。
--name:#指定 Service 的名称。
--port:#Service 的端口。
--target-port:#Pod 的端口。
--node-port:#指定节点端口(可选)。
验证 Service:
kubectl get svc my-nodeport-service
验证 NodePort 服务
获取节点 IP 地址:
kubectl get nodes -o wide
访问服务:使用节点 IP 和 NodePort 访问服务。
http://<Node-IP>:30007
检查 Service 详情:
kubectl describe svc my-nodeport-service
Kubernetes Service 的 LoadBalancer 类型 是一种用于将服务暴露到集群外部的 Service 类型,在 NodePort 的基础上,通过云服务商(如 AWS、GCP、Azure)的负载均衡器(Load Balancer)将外部流量导入到服务。提供一个外部可访问的 IP 地址,通常用于生产环境。

裸机环境或本地 Kubernetes 集群(如 Minikube)通常无法使用。
在支持 LoadBalancer 的云环境中,Kubernetes 会自动创建和管理负载均衡器,无需手动配置。
创建 LoadBalancer 类型的 Service。
以下是一个简单的 LoadBalancer 服务配置示例:
apiVersion: v1
kind:Service
metadata:
name:my-service
spec:
type:LoadBalancer#指定服务类型为 LoadBalancer
selector: #选择要暴露的 Pod,标签 app: my-app 用于匹配目标 Pod
app:my-app
ports:
-protocol:TCP
port:80 #服务暴露的端口(外部访问的端口)
targetPort:8080#Pod 中应用监听的端口
将上述配置保存为 service.yaml 文件,然后使用 kubectl 命令应用配置:
kubectl apply -f service.yaml
应用配置后,Kubernetes 会请求云服务提供商创建一个外部负载均衡器,并分配一个外部 IP 地址。可以通过以下命令查看服务状态:
kubectl get svc my-service
输出示例:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
my-service LoadBalancer 10.96.0.1 203.0.113.1 80:30007/TCP 10s
EXTERNAL-IP #表示负载均衡器的外部 IP 地址,外部用户可以通过该地址访问服务。
PORT(S) #显示服务端口和映射的节点端口。
一旦 EXTERNAL-IP 可用,外部用户可以通过以下方式访问服务:
http://<EXTERNAL-IP>:80
例如,如果 EXTERNAL-IP 是 203.0.113.1,则访问地址为:
http://203.0.113.1
配置注意事项
LoadBalancer 类型服务依赖于云服务提供商的负载均衡器。如果在本地或不支持 LoadBalancer 的环境中运行(如 Minikube),可以使用 NodePort 或 Ingress,或者安装 MetalLB 等解决方案。EXTERNAL-IP 映射到一个域名,方便用户访问。如果需要暴露 HTTPS 服务,可以修改 Service 配置并使用 Ingress 控制器管理 SSL 证书。例如:
apiVersion: v1
kind:Service
metadata:
name:my-https-service
spec:
type:LoadBalancer
selector:
app:my-app
ports:
-protocol:TCP
port:443
targetPort:8443
然后使用 Ingress 控制器(如 NGINX Ingress 或 Traefik)管理 SSL 证书和域名。
如果在本地环境(如 Minikube 或裸机 Kubernetes 集群)中运行,可以使用 MetalLB) 模拟 LoadBalancer 类型服务。
kubectl apply -f https://raw.githubusercontent.com/metallb/metallb/v0.13.13/config/manifests/metallb-native.yaml
配置 IP 地址池:创建一个 ConfigMap 来定义 MetalLB 可分配的 IP 地址范围:
apiVersion: metallb.io/v1beta1
kind: IPAddressPool
metadata:
name: my-ip-pool
namespace: metallb-system
spec:
addresses:
- 192.168.1.240-192.168.1.250
应用配置:
kubectl apply -f metallb-config.yaml
Kubernetes Service 的 ExternalName 类型是一种特殊的 Service 类型,用于将集群内部的服务映射到集群外部的 DNS 名称,而不是将流量路由到集群内的 Pod。
简单易用,无需创建实际的 Service 或 Pod,隐藏外部服务的复杂性,提供统一的 DNS 访问方式。仅支持 DNS 名称,无法映射到 IP 地址。也不提供负载均衡或故障转移。
ExternalName 类型的 Service 通过 DNS 解析将请求转发到指定的外部域名。ClusterIP、NodePort 或 LoadBalancer 类型不同,ExternalName 不会创建代理或负载均衡器,也不会分配集群 IP。externalName 字段,Kubernetes 会自动将 Service 的 DNS 名称解析为指定的外部域名。ExternalName 类型 Service 进行过渡。以下是一个 ExternalName 类型 Service 的示例:
apiVersion: v1
kind:Service
metadata:
name:external-db#访问方式
spec:
type:ExternalName
externalName:my-external-db.example.com#指定外部服务的 DNS 名称
curl http://external-db:5432
Service 类型 | 访问方式 | 适用场景 |
|---|---|---|
ClusterIP | 仅集群内部 | 内部服务通信 |
NodePort | 集群外部通过 <NodeIP>:<NodePort> | 开发和测试环境 |
LoadBalancer | 集群外部通过负载均衡器 IP | 生产环境,需要外部负载均衡 |
ExternalName | 通过 DNS CNAME 映射到外部服务 | 访问集群外部服务 |
在 Kubernetes 中,四种 Service 类型(ClusterIP、NodePort、LoadBalancer、ExternalName)没有绝对的“好用类型”,而是根据具体o业务场景需求来选择最合适的类型。
👍 如果你喜欢这篇文章,请点赞并分享给你的朋友!