关于 K8s Service,你真的理解了吗?详细版了解一下

一、相关概念

1. 什么是Service?

在 Kubernetes 中,Service 是一种抽象的资源,它提供了稳定的访问接口,将外部或集群内部的流量路由到对应的 Pod 上。 Pod 是 Kubernetes 中的基本调度单元,但它们是临时的,IP 地址和生命周期都可能发生变化。Service 为 Pod 提供一个稳定的访问方式,解决了 Pod 的动态 IP 问题。

Kubernetes 的 Service 有几种不同的类型,能够帮助我们根据不同的需求将服务暴露给外部用户或者集群内部的其他服务。

2. Service的核心概念

(1) Pod 和 Service

在 Kubernetes 中,Pod 是部署应用的基本单位。每个 Pod 都会有一个 IP 地址,但这个 IP 地址只在 Pod 生命周期内有效。当 Pod 被销毁、重建或调度到其他节点时,Pod 的 IP 地址会发生变化。这使得直接依赖 Pod IP 地址来访问服务变得不可行。

Service 解决了这个问题,它为一组 Pod 提供一个稳定的访问入口,不会随着 Pod 的变化而变化。Service 将流量路由到匹配标签的 Pod 上,并为客户端提供一个固定的 IP 地址和 DNS 名称来访问这些 Pod。

(2) Service 和 Endpoints

Endpoints 是与 Service 关联的资源,它记录了与该 Service 匹配的 Pod 的 IP 地址。当 Service 创建时,Kubernetes 会根据标签选择器(selector)找到符合条件的 Pod,并自动生成 Endpoints,确保流量能够正确地路由到这些 Pod。

容易混淆的几个端口的关系:

3. Service 类型

Kubernetes 提供了几种不同的 Service 类型,适应不同的网络通信需求。每种类型都有自己的特性和应用场景。

(1) ClusterIP(默认类型)

功能:ClusterIP 类型的 Service 只能在集群内部访问,外部无法直接访问该服务。它为服务分配一个虚拟 IP 地址(ClusterIP),客户端通过该 IP 与服务进行通信。

用途:适用于集群内部的微服务通信,常见于服务间通信。

复制
apiVersion: v1 kind: Service metadata: name: my-service spec: selector: app: my-app # 选择标签为 app=my-app 的 Pod ports: - protocol: TCP port: 80 # 服务对外暴露的端口 targetPort: 8080 # 实际服务运行的 Pod 端口 clusterIP: 10.96.0.1 # Kubernetes 自动分配 ClusterIP1.2.3.4.5.6.7.8.9.10.11.12.

这个 Service 会将请求转发到符合条件的 Pod 上(标签为 app=my-app)。 访问该服务时,Kubernetes 会自动通过虚拟 IP 地址 10.96.0.1 来路由流量。

(2) NodePort

功能:NodePort 类型的 Service 将服务暴露到每个 Node 上的指定端口,外部客户端可以通过访问任意 Node 的 IP 地址和指定端口来访问该服务。

用途:适用于开发和测试场景,或者希望通过某个特定端口暴露服务的场景。

复制
apiVersion: v1 kind: Service metadata: name: my-service spec: selector: app: my-app ports: - protocol: TCP port: 80 # 外部客户端访问的端口 targetPort: 8080 # Pod 上的目标端口 nodePort: 30001 # 每个 Node 暴露的端口 type: NodePort1.2.3.4.5.6.7.8.9.10.11.12.13.

在这个例子中,nodePort 为 30001,可以通过集群中任意一个节点的 NodeIP:30001 访问服务。

(3) LoadBalancer

功能:LoadBalancer 类型的 Service 会在云环境中创建一个外部负载均衡器,将外部流量自动分发到集群中的多个 Pod 上。

用途:适用于需要对外暴露服务,并且需要自动负载均衡的生产环境。

复制
apiVersion: v1 kind: Service metadata: name: my-service spec: selector: app: my-app ports: - protocol: TCP port: 80 # 外部访问的端口 targetPort: 8080 # Pod 上的目标端口 type: LoadBalancer1.2.3.4.5.6.7.8.9.10.11.12.

创建该 Service 后,Kubernetes 会自动请求云平台(如 AWS、阿里云,华为云)创建一个负载均衡器,将流量转发到集群中的 Pod 上。

(4) ExternalName

功能:ExternalName 类型的 Service 将流量路由到外部的 DNS 名称,而不是内部的 Pod。

用途:适用于需要访问集群外部服务(如外部数据库或第三方 API)的场景。

复制
apiVersion: v1 kind: Service metadata: name: my-service spec: type: ExternalName externalName: example.com # 外部服务的 DNS 名称1.2.3.4.5.6.7.

在这种配置下,my-service 将请求转发到 example.com,而不是集群内部的 Pod。

二、Service 工作原理

1. Pod 的 IP 和生命周期管理

每个 Pod 都有一个自己的 IP 地址,当 Pod 被删除或重新调度时,IP 地址会发生变化。Kubernetes 会监控这些变化,并确保流量能够正确地转发到新的 Pod 上。

2. 标签选择器

Service 通过标签选择器来匹配需要暴露的 Pod。当 Service 创建时,Kubernetes 会根据该标签选择器找到所有匹配的 Pod,并通过 Endpoints 记录它们的 IP 地址。

3. DNS 解析

Kubernetes 会为每个 Service 分配一个 DNS 名称,Pod 可以通过 DNS 名称访问 Service,而不需要关心具体的 IP 地址。这使得服务发现变得非常容易。

三、Service常用操作

1. 创建service
复制
# 命令行创建,通过暴露deployment创建Service kubectl expose deployment <deployment-name> --type=<service-type> --port=<port> --target-port=<target-port> kubectl expose deploy nginx --port=80 --target-port=80 --type=NodePort # 基于yaml文件创建 # 创建Service资源清单 apiVersion: v1 kind: Service metadata: name: nginx spec: selector: app: nginx ports: - protocol: TCP port: 80 targetPort: 8080 nodePort: 30080 # 指定节点上的端口 type: type: NodePort # 创建 kubectl apply -f service.yaml1.2.3.4.5.6.7.8.9.10.11.12.13.14.15.16.17.18.19.20.21.22.23.
2. 查看service
复制
# 查看所有service信息 kubectl get svc kubectl get svc -o wide -n prod # 查看指定service的详细信息 kubectl get svc nginx -o yaml -n prod kubectl describe svc nginx -n prod # 查看Service的endpoint信息 kubectl get endpoints <service-name> kubectl get ep nginx1.2.3.4.5.6.7.8.9.10.11.
3. 编辑更新Service

注意:修改后,service会立即重启

复制
kubectl edit service <service-name> kubectl edit svc nginx -n prod # 更新端口 kubectl patch service my-service -p {"spec":{"ports":[{"port":80,"targetPort":8081}]}}1.2.3.4.5.6.
4. 删除Service
复制
# 命令行删除 kubectl delete svc <service-name> kubectl delete svc nginx # 基于yaml文件删除 kubectl delete -f service.yaml1.2.3.4.5.6.7.

Service为 Pod 提供了稳定的访问入口,解决了 Pod 生命周期变化带来的网络问题。通过不同类型的 Service(如 ClusterIP、NodePort、LoadBalancer 和 ExternalName),Kubernetes 可以满足各种网络通信需求。

在生产环境中,Service 不仅可以帮助实现服务间的可靠通信,还能为外部用户提供负载均衡和高可用的访问入口。

阅读剩余
THE END