1 Service相关概念
1.1 什么是Service?
在 Kubernetes 中,Service 是一种抽象的资源,它提供了稳定的访问接口,将外部或集群内部的流量路由到对应的 Pod 上。Pod 是 Kubernetes 中的基本调度单元,但它们是临时的,IP 地址和生命周期都可能发生变化。Service 为 Pod 提供一个稳定的访问方式,解决了 Pod 的动态 IP 问题。Kubernetes 的 Service 有几种不同的类型,能够帮助我们根据不同的需求将服务暴露给外部用户或者集群内部的其他服务。
1.2 Service 的核心概念
1.2.1 Pod 和 Service
每个 Pod 都会有一个 IP 地址,但当 Pod 被销毁、重建或调度到其他节点时,Pod 的 IP 地址会发生变化。所以不能直接使用 Pod IP 地址来访问服务。Service 专门用来解决这个问,它为一组 Pod 提供一个稳定的访问入口,不会随着 Pod 的变化而变化。Service 将流量路由到匹配标签的 Pod 上,并为客户端提供一个固定的 IP 地址和 DNS 名称来访问这些 Pod。Service是根据标签label来匹配Pod的
1.2.2 Service 和 Endpoints
Endpoints 是与 Service 关联的资源,它记录了与该 Service 匹配的 Pod 的 IP 地址。当 Service 创建时,Kubernetes 会根据标签选择器(selector)找到符合条件的 Pod,并自动生成 Endpoints,确保流量能够正确地路由到这些 Pod。容易混淆的几个端口的关系
1.3 Service 类型
Kubernetes 提供了几种不同的 Service 类型,适应不同的网络通信需求。每种类型都有自己的特性和应用场景。
1.3.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 会自动分配 ClusterIP
这个 Service 会将请求转发到符合条件的 Pod 上(标签为 app=my-app)。访问该服务时,Kubernetes 会自动通过虚拟 IP 地址 10.96.0.1 来路由流量。
1.3.2 NodePort
功能:NodePort 类型的 Service 将服务暴露到每个 Node 上的指定端口,外部客户端可以通过访问任意 Node 的 IP 地址和指定端口来访问该服务。用途:适用于开发和测试场景,或者希望通过某个特定端口暴露服务的场景。简单的应用也可以通过NodePort发布业务,大型业务一般通过Ingress。
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: NodePort
在这个例子中,nodePort 为 30001,可以通过集群中任意一个节点的 NodeIP:30001 访问服务。端口范围:30000-32767
1.3.3 LoadBalancer
功能:LoadBalancer 类型的 Service 会在云环境中创建一个外部负载均衡器,LoadBalancer是在NodePort基础上,将外部流量自动分发到集群中的多个 Pod 上。用途:适用于需要对外暴露服务,并且需要自动负载均衡的生产环境。
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80 # 外部访问的端口
targetPort: 8080 # Pod 上的目标端口
type: LoadBalancer
创建该 Service 后,Kubernetes 会自动请求云平台(如 AWS、阿里云,华为云)创建一个负载均衡器,将流量转发到集群中的 Pod 上。
1.3.4 ExternalName
功能:ExternalName 类型的 Service 将流量路由到外部的 DNS 名称,而不是内部的 Pod。用途:适用于需要访问集群外部服务(如外部数据库或第三方 API)的场景。
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: ExternalName
externalName: www.liyb.com # 外部服务的 DNS 名称
在这种配置下,my-service 将请求转发到 www.liyb.com,而不是集群内部的 Pod。
2 Service 工作原理
2.1 Pod 的 IP 和生命周期管理
每个 Pod 都有一个自己的 IP 地址,当 Pod 被删除或重新调度时,IP 地址会发生变化。Kubernetes 会监控这些变化,并确保流量能够正确地转发到新的 Pod 上。
2.2 Service 的创建与标签选择器
Service 通过标签选择器来匹配需要暴露的 Pod。当 Service 创建时,Kubernetes 会根据该标签选择器找到所有匹配的 Pod,并通过 Endpoints 记录它们的 IP 地址。
2.3 DNS 解析
Kubernetes 会为每个 Service 分配一个 DNS 名称,Pod 可以通过 DNS 名称访问 Service,而不需要关心具体的 IP 地址。这使得服务发现变得非常容易。DNS命名规则
<ServiceName>.<Namespace>.svc.<ClusterDomain>
- ServiceName:Service的名字。
- Namespace:Service所在的命名空间(Namespace)。
- svc:表示这是一个Kubernetes的Service。
- ClusterDomain:Kubernetes集群的域名,默认是
cluster.local
,但可以由集群管理员自定义。
3 Service常用操作
3.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
# 创建
kubectl apply -f service.yaml
3.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 nginx
3.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}]}}'
3.4 删除Service
# 命令行删除
kubectl delete svc <service-name>
kubectl delete svc nginx
# 基于yaml文件删除
kubectl delete -f service.yaml
Service为 Pod 提供了稳定的访问入口,解决了 Pod 生命周期变化带来的网络问题。在生产环境中,Service 不仅可以帮助实现服务间的可靠通信,还能为外部用户提供负载均衡和高可用的访问入口。在设计 Kubernetes 服务架构时,合理选择 Service 类型,并结合标签、DNS 和负载均衡等特性,可以极大地简化网络配置,提高系统的可扩展性和稳定性。