在 Kubernetes 中,通过 Service 可以实现四层(L4)负载均衡,将流量分发至后端的 Pod。四层负载主要用于传输层(TCP/UDP),而不像七层负载均衡(HTTP/HTTPS)那样进行应用层的流量处理。以下是几种方式来实现服务端口的暴露:
1. ClusterIP
- 特点:默认类型,仅在集群内部暴露服务。
- 用途:适合内部通信,无法直接从外部访问。
- 实现方式:Service 会分配一个虚拟 IP,集群中的 Pod 通过这个 IP 访问目标服务。
- 配置示例:
apiVersion: v1 kind: Service metadata: name: my-service spec: selector: app: my-app ports: - protocol: TCP port: 80 targetPort: 8080 type: ClusterIP
2. NodePort
- 特点:将服务暴露在每个节点的指定端口上,外部可以通过节点 IP 访问服务。
- 用途:适合集群外部直接访问的服务,端口范围通常为 30000-32767。
- 实现方式:集群内的每个节点都会监听一个端口,并将流量转发到 Service。
- 配置示例:
apiVersion: v1 kind: Service metadata: name: my-service spec: type: NodePort selector: app: my-app ports: - port: 80 targetPort: 8080 nodePort: 30080 # 可指定,也可让系统自动分配
3. LoadBalancer
- 特点:在支持 LoadBalancer 的云平台(如 AWS、GCP)上,通过云提供商的负载均衡服务将流量分发到 Service。
- 用途:适合外部流量需要访问集群内部服务的情况。
- 实现方式:Kubernetes 通过云提供商 API 创建外部负载均衡器,并将流量导向集群节点的 NodePort。
- 配置示例:
apiVersion: v1 kind: Service metadata: name: my-service spec: type: LoadBalancer selector: app: my-app ports: - port: 80 targetPort: 8080
4. ExternalName
- 特点:服务的类型为
ExternalName
时,Service 不会创建代理,而是通过 DNS 解析外部域名。 - 用途:适合通过 Kubernetes 内部名称访问外部服务。
- 配置示例:
apiVersion: v1 kind: Service metadata: name: my-service spec: type: ExternalName externalName: example.com
在生产环境中,NodePort 和 LoadBalancer 是最常用的两种外部暴露服务的方法。
在 Kubernetes 的 Service 配置中,targetPort
指定的是容器端口(即实际运行在 Pod 内的应用程序端口),它将 Kubernetes Service 转发的流量发送到对应的容器端口。以下是关于每个字段的详细说明:
- port:这是 Service 的端口,对外暴露的入口端口。用户访问 Service 时使用该端口。
- targetPort:这是容器端口,即 Service 接收到的流量最终转发到 Pod 内部的端口(通常是容器的应用端口)。
- nodePort(仅 NodePort 类型的 Service): 在 Kubernetes 集群中的每个节点上开放的端口,允许外部流量通过节点 IP + 该端口访问 Service。
例如,以下配置中 targetPort: 8080
表示容器端口:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: NodePort
selector:
app: my-app
ports:
- port: 80 # Service 的入口端口
targetPort: 8080 # 容器端口
nodePort: 30080 # 节点端口
在这个例子中:
port: 80
是服务端口(Service 的入口端口)。targetPort: 8080
是容器端口(应用程序运行的端口)。nodePort: 30080
是节点端口(外部流量可以通过该端口访问节点并转发到 Service)。
命令行模式
可以通过 kubectl expose
命令来创建上述 NodePort
类型的 Service 配置。以下是具体的命令:
kubectl expose deployment my-app \
--type=NodePort \
--name=my-service \
--port=80 \
--target-port=8080 \
--node-port=30080
命令参数说明
deployment my-app
:指定要暴露的 Deployment 名称(假设已存在一个名为my-app
的 Deployment)。--type=NodePort
:将 Service 类型设置为NodePort
,以便外部流量可以通过节点端口访问。--name=my-service
:定义 Service 的名称。--port=80
:设置 Service 的入口端口。--target-port=8080
:将 Service 接收的流量转发到容器中的端口 8080。--node-port=30080
:在每个节点上暴露端口 30080(此参数为可选,若不指定则系统自动分配)。
验证 Service
执行完创建命令后,可以通过以下命令查看 Service 的配置:
kubectl get service my-service
这将显示 Service 的详细信息,包括 ClusterIP
、NodePort
等。