D25 kubernetes Service资源对象{简介/定义/类型/Endpoint对象}
1、Service概述
Service是kubernetes中的一种资源对象,用于定义一组pod的网络访问规则,它为pod提供了一个稳定的统一访问入口,允许客户端始终使用同一个ip地址进行访问,避免了直接使用podip地址导致的不稳定性
- Service主要有以下两种功能:
负载均衡:当多个pod提供服务时,Service通过负载均衡算法将请求分发到这些pod上,从而实现应用的负载均衡
服务发现:Service提供了一种服务发现机制,自动维护后端podip的变化,从而保障客户端访问应用程序不受后端pod变化的影响
2、Service定义
- 假设集群中有一组由Deployment管理的pod,这些pod在tcp的80端口上提供服务,pod标签为app=ningx,如下所示:
[root@k8s-master k8s]# kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
pod-nginx 1/1 Running 0 7s app=pod-nginx
- 为了将这组pod对外,创建一个Service资源,配置如下:
[root@k8s-master k8s]# cat service.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
ports:
# 端口映射列表
- port: 80
# 端口映射协议,支持TCP、UDP、和SCTP,默认为TCP
protocol: TCP
# 目标端口,既容器中应用程序监听的端口
targetPort: 80
# 标签选择器(Label Selector),用于定义Service应该将流量转发到哪个pod上。这里表示只有带有app=nginx标签的pod才会被改Service转发流量
selector:
app: pod-nginx
- 创建Service资源
[root@k8s-master k8s]# kubectl apply -f service.yaml
service/nginx created
- 查看Service资源
[root@k8s-master k8s]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 29d
nginx ClusterIP 10.99.169.247 <none> 180/TCP 27s
NAME:名称
TYPE:公开类型,默认为ClusterIP
CLUSTER-IP:集群IP地址,也成为虚拟IP地址
EXTERNAL-IP:外部IP地址。当使用loadbalance或externalname类型时,才会显示外部ip地址,否则会显示为none或pending
PORT(S):公开端口和协议
AGE:创建时间
综上所述,该Service分配的虚拟IP地址为10.99.169.247,监听tcp协议的180端口,该Service可以在集群中的任意pod或节点上通过地址10.99.169.247:180访问这组pod。
- 如果pod在多个端口上提供服务,可以为每个端口定义一个端口映射规则,并为每个规则制定一个唯一的名称,以便对他们进行区分。配置实例如下
[root@k8s-master k8s]# cat service-pods.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
- name: https
port: 443
protocol: TCP
targetPort: 443
selector:
app: pod-nginx
在上述实例中,定义了两个端口映射规则。其中,第一个规则将180端口映射到pod的80端口,第二个规则将443端口映射到目标pod上的443端口
- 在Service对象的PORT(S)列也会显示这两个规则公开的端口
[root@k8s-master k8s]# kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 29d
nginx ClusterIP 10.99.169.247 <none> 180/TCP 66m
- Service的虚拟IP地址是从kubernetes集群的Service网络的CIDR地址范围(在kubeadm init命令中指定)中分配的。如果想查看该CIDR地址范围,可以使用以下命令:
[root@k8s-master k8s]# kubectl cluster-info dump | grep -i service-cluster-ip-range
"--service-cluster-ip-range=10.96.0.0/12",
"--service-cluster-ip-range=10.96.0.0/12",
3、Service公开类型
- Service的公开类型定义了Service如何对外部网络公开,支持四种公开类型
ClusterIP:默认类型。Service会被分配一个虚拟IP地址。集群中的应用程序可以通过IP地址访问Service
NodePort:在每个节点上开放一个固定端口,并将该端口映射到Service上。这允许集群外部的用户可以用过节点IP地址和固定端口访问Service
LoadBalance:在底层云提供商创建一个负载均衡器,并将外部流量转发集群中的Service
ExternalName:将Service的名称映射到指定的外部域名
3.1 ClusterIP
- ClusterIP适用于应用程序仅需要在集群内部访问的场景
假设集群中部署了一个搜索接口服务,并且该服务仅有集群中的其他应用程序调用。在这种情况下,我们可以使用Service ClusterIP类型来公开相关pod - Service ClusterIP类型的配置示例如下
[root@k8s-master k8s]# cat service-clusterip.yaml
apiVersion: v1
kind: Service
metadata:
name: search-api
spec:
type: ClusterIP
ports:
- port: 80
protocol: TCP
targetPort: 8080
selector:
app: search-api
上述实例中定义了一个ClusterIP类型的Service,集群中的其他应用程序可以通过访问该Service的虚拟IP地址来访问搜索接口服务
3.2 NodePort
- NodePort类型适用于应用程序需要集群外部访问的场景
假设集群中部署了一个网站,该网站对集群外部的用户提供了访问权限。在这种情况下,我们可以使用nodeport Service来公开相关的pod - Service NodePort类型的配置示例如下
[root@k8s-master k8s]# cat service-nodeport.yaml
apiVersion: v1
kind: Service
metadata:
name: portal
spec:
type: NodePort
ports:
- port: 80
protocol: TCP
targetPort: 80
selector:
app: portal
- 创建 Service
[root@k8s-master k8s]# kubectl apply -f service-nodeport.yaml
service/portal created
- 查看Service
[root@k8s-master k8s]# kubectl get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
portal NodePort 10.103.236.157 <none> 80:32491/TCP 57s
PORT(S) 的值显示为80:32491,其中冒号左侧是访问虚拟IP地址对应的端口,右侧表示节点开放的固定端口(既nodeport端口)。用户通过任意node节点的IP地址和32491端口来访问网站,如http://172.16.99.71:32491
默认情况下,kubernetes为nodeport类型的Service分配一个固定端口。该端口取值范围为3000~32767。我们可以通过nodeport字段指定端口,如指定30002端口,配置示例如下
apiVersion: v1
kind: Service
metadata:
name: portal
spec:
type: NodePort
ports:
- port: 80
protocol: TCP
targetPort: 80
nodePort: 30002
selector:
app: portal
3.3、LoadBalance
LoadBalance类型是针对云提供商(如阿里云、aws、azure)涉及的一种类型。当创建一个LoadBalance类型的Service时,云提供商的控制器从kubernetes API中感知到该Service,然后调用云提供商API来创建一个负载均衡器,并将节点IP地址和nodeport端口作为后端添加到该负载均衡其中,这意味着用户可以通过访问云厂商的负载均衡器访问集群中的Service
- Service LoadBalance类型的配置示例如下:
[root@k8s-master k8s]# cat service-loadbalance.yaml
apiVersion: v1
kind: Service
metadata:
name: portal
spec:
type: LoadBalancer
ports:
- port: 80
protocol: TCP
targetPort: 80
nodePort: 30002
selector:
app: portal
创建Loadbalancer类型的Service资源后,Service对象的External-IP列将显示云厂商分配的负载均衡器IP地址。通过该IP地址,应用程序只能访问Service名称,从而访问应用程序
需要注意的是,使用Loadbalancer类型的前提是云厂商的控制器已经被部署在集群中。可以从云厂商获取有关控制器的详细内容
3.4 ExternalName
ExternalName是一个特殊的类型,与其他类型不同的是。它不提供负载均衡和服务发现功能,而是专用于将Service的名称映射到指定的外部域名上。因此不需要为ExternalName类型Service定义selector字段,也不会为他分配虚拟IP地址。应用程序只能通过Service名称访问该外部域名。
ExternalName类型只有在集群中需要使用Service名称来访问外部域名时才会被用到,Service ExternalName类型的配置示例如下
apiVersion: v1
kind: Service
metadata:
name: syj
spec:
type: ExternalName
externalName: test.syj.cn
通过这样的配置,集群中的应用程序可以通过Service名称syj.default.svc.cluster.local来访问外部域名test.syj.cn
4、Endpoints对象
当创建一个Service时,kubernetes会根据Service创建一个Endpoints对象,该对象负责维护与Service相关的后端pod信息,并确保Service可以被正确的转发到后端pod。
- 查看Endpoints对象
[root@k8s-master k8s]# kubectl get endpoints
NAME ENDPOINTS AGE
kubernetes 172.16.99.71:6443 29d
nginx 10.244.85.200:80 22h
pod-readiness <none> 29d
portal <none> 13m
search-api <none> 33m
Name:显示的名称与Service名称相对应
ENDPOINTS:显示了关联的pod IP地址和端口,其中超出三个显示为省略号
Endpoints对象还可以手动创建,自定义关联的IP地址和端口,以满足特定网络代理需求。例如,通过Service代理集群外部的MySQL服务,配置示例如下
[root@k8s-master k8s]# cat service-mysql-proxy.yaml
apiVersion: v1
kind: Endpoints
metadata:
name: mysql-proxy
subsets:
- addresses:
- ip: 172.16.99.70
ports:
- port: 3306
protocol: TCP
---
apiVersion: v1
kind: Service
metadata:
name: mysql-proxy
spec:
ports:
- port: 3306
targetPort: 3306
上述示例首先定义了一个名为mysql-proxy的Endpoints资源,其中subsets(子集)字段包含了一个MySQL服务的IP地址和端口,然后定义了一个名为mysql-proxy的Service资源,将访问3306端口的流量转发到目标端口3306.这里不需要定义selector字段,表明Service不是通过标签选择器来发现pod的
- 创建资源
[root@k8s-master k8s]# kubectl apply -f service-mysql-proxy.yaml
endpoints/mysql-proxy created
service/mysql-proxy unchanged
- 查看Service和Endpoints
[root@k8s-master k8s]# kubectl get service,endpoints mysql-proxy
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/mysql-proxy ClusterIP 10.98.237.25 <none> 3306/TCP 39s
NAME ENDPOINTS AGE
endpoints/mysql-proxy 172.16.99.70:3306 19s
集群中的应用程序可以通过Service的虚拟IP地址10.98.237.25和3306端口来访问外部的MySQL服务
分类:
kubernetes
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通