K8s之Service详解(Detailed Explanation of K8s Service)

K8s之Service详解

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 和负载均衡等特性,可以极大地简化网络配置,提高系统的可扩展性和稳定性。

3.5 Service的使用场景和优势

Service的主要优势在于其稳定性和负载均衡能力。由于Pod的IP地址不是固定的,直接通过Pod IP访问应用是不稳定的。Service提供了一个统一的入口地址,客户端通过访问Service的入口地址即可访问到后端的Pod服务。此外,Service还支持多种负载分发策略,如轮询、随机等,确保请求能够均匀地分发到各个后端Pod上‌。

相关推荐
5xidixi10 分钟前
HTTP(1)
网络·网络协议·http
张文君1 小时前
docker直接运行arm下的docker
arm开发·docker·容器
doubt。2 小时前
2.[网鼎杯 2020 朱雀组]phpweb
网络·安全·web安全·网络安全·php·代码复审
lingllllove2 小时前
使用 HTTP::Server::Simple 实现轻量级 HTTP 服务器
服务器·网络协议·http
weixin_307779133 小时前
AWS EMR使用Apache Kylin快速分析大数据
大数据·数据仓库·云计算·aws·kylin
一只码代码的章鱼3 小时前
计算机网络 笔记 传输层
网络·网络协议·tcp/ip·计算机网络
月上柳青3 小时前
docker gitlab arm64 版本安装部署
docker·容器·gitlab
别致的影分身3 小时前
Linux网络 HTTP cookie 与 session
网络·网络协议·http
神秘剑客_CN4 小时前
使用windows笔记本让服务器上网
运维·服务器·windows