第56节 service
❤️💕💕新时代拥抱云原生,云原生具有环境统一、按需付费、即开即用、稳定性强特点。Myblog:http://nsddd.top
[TOC]
Service 对象
Service Selector
Kubernetes 允许将 Pod 对象通过标签(Label)进行标记,并通过 Service Selector 定义基于 Pod 标签的过滤规则,以便选择服务的上游应用实例
Service Selector
对象是 Kubernetes 中的一个资源对象,用于定义服务的选择器。选择器是一组用于选择后端 Pod 的标签。当一个 Service 对象被创建时,可以指定相关联的 Selector 对象。这个 Selector 可以是一个简单的标签选择器,也可以是一个更复杂的表达式,如 matchExpressions
。
Service Selector
对象的定义可以在创建 Service 对象时直接指定,也可以使用 kubectl label
命令进行设置。例如,可以使用以下命令创建一个 Service Selector 对象:
kubectl label pods <pod-name> app=my-app
这个命令会将 Pod 对象的标签设置为 app=my-app
。然后,可以使用以下命令创建一个 Service 对象,并将其关联到这个 Pod:
kubectl expose pod <pod-name> --port=<port> --target-port=<target-port> --selector=app=my-app
在这个命令中,--selector
参数指定了一个标签选择器,用于选择与之关联的 Pod。在这个例子中,选择器是 app=my-app
。
要查看 Service Selector 对象的详细信息,可以使用以下命令:
kubectl describe service <service-name> --namespace=<namespace>
这个命令会显示与 Service 对象相关联的 Endpoint 和 Selector 对象。其中,Selector 对象列出了与 Service 相关联的 Pod 的标签选择器。
Ports
Ports 属性中定义了服务的端口、协议目标端口等信息
Service
对象是 Kubernetes 中的一个资源对象,用于定义一个服务。服务是一组 Pod 的抽象,这些 Pod
可以被其他容器或外部用户访问。Service
对象可以定义一个稳定的 DNS 名称和 IP 地址,以及一个负载均衡器,用于将请求分发给后端 Pod。
Service
对象中的 Ports
对象用于定义服务的端口信息。一个 Service
对象可以包含多个 Ports
对象,每个 Ports
对象定义了一个服务端口和其对应的目标端口。例如,下面的 Service
对象定义了两个端口:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
ports:
- name: http
port: 80
targetPort: 8080
- name: https
port: 443
targetPort: 8443
上面的 Service
对象定义了两个端口:http
和 https
。http
端口映射到后端 Pod 的 8080
端口,https
端口映射到后端 Pod 的 8443
端口。
要创建一个 Service
对象,可以使用以下命令:
kubectl expose deployment <deployment-name> --type=ClusterIP --name=<service-name> --port=<port> --target-port=<target-port>
其中,<deployment-name>
为部署的名称,<service-name>
为服务的名称,<port>
为服务的端口,<target-port>
为后端 Pod 的端口。
要查看 Service
和 Ports
对象的详细信息,可以使用以下命令:
kubectl describe service <service-name> --namespace=<namespace>
这个命令会显示与 Service
对象相关联的 Ports
对象和 Endpoint
对象。其中,Ports
对象列出了服务的端口信息,Endpoint
对象列出了与服务相关联的后端 Pod 的网络地址和端口信息。
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
#如果设置了PublishNotReadyAdddress为 true,则无论Pod是否就绪都会被加入endpoint readyAddress list 中
#publishNotReadyAddresses: true
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
Endpoint 对象
Endpoint
对象是 Kubernetes 中的一个资源对象,用于存储一个服务的网络地址和端口信息。这个对象可以通过 kubectl
命令行工具或 Kubernetes API 进行创建和管理。
Endpoint
对象可以与 Service
对象关联,表示服务的后端地址和端口信息。Endpoint
对象中的地址和端口信息可以手动配置,也可以通过 EndpointSlices
对象自动管理。
在创建 Service
对象时,Kubernetes 会自动创建相应的 Endpoint
对象,并将其与 Service
对象关联。如果需要手动配置 Endpoint
对象,可以使用以下命令:
kubectl create endpoint <endpoint-name> --namespace=<namespace> --addresses=<ip1>,<ip2>,... --ports=<port1>,<port2>,...
其中,<endpoint-name>
为 Endpoint
对象的名称,<namespace>
为命名空间名称,<ip1>,<ip2>,...
为后端服务的 IP 地址,<port1>,<port2>,...
为后端服务的端口号。
要查看 Endpoint
对象的详细信息,可以使用以下命令:
kubectl describe endpoints <endpoint-name> --namespace=<namespace>
当 Service 的 selector 不为空时,Kubernetes Endpoint Controller 会侦听服务创建事件,创建与 Service 同名的 Endpoint 对象
selector 能够选取的所有 PodIP
都会被配置到 addresses
属性中
- 如果此时 selector 所对应的 filter 查询不到对应的 Pod,则 addresses 列表为空
- 默认配置下,如果此时对应的 Pod 为 not ready 状态,则对应的 PodIP 只会出现在 subsets 的
notReadyAddresses
属性中,这意味着对应的 Pod 还没准备好提供服务,不能作为流量转发的目标。 - 如果设置了
PublishNotReadyAdddress
为 true,则无论 Pod 是否就绪都会被加入 readyAddress list 中
apiVersion: v1
kind: Endpoints
metadata:
name: service-without-selector
subsets:
- addresses:
- ip: 220.181.38.148
ports:
- name: http
port: 80
protocol: TCP
如果 service 对象过多的话, Endpoint 对象不好管理,社区提出了 EndpointSlice 对象。
EndpointSlice 对象
EndpointSlice 对象用于管理服务的端点。它们提供了一种比传统的 Endpoint 对象更可扩展和高效的管理端点信息的方式。在 Kubernetes 中,EndpointSlice 对象表示与服务关联的端点的子集。这个子集是由一组选择器定义的,这些选择器根据特定的标签或 IP 地址等标准过滤端点。这允许更细粒度地控制哪些端点包含在 EndpointSlice 中。
Endpoint slices 由 Kubernetes 自动创建和管理,因此无需手动创建它们。可以使用 kubectl 命令行工具或 Kubernetes API 查询 Endpoint slices,就像其他 Kubernetes 资源一样。Endpoint slices 被设计为比传统的 Endpoint 资源更可扩展,因为它们可以处理更多的端点而不影响性能。它们也更高效,因为它们只存储与服务相关的端点信息。
- 当某个 Service 对应的 backend Pod 较多时,Endpoint 对象就会因保存的地址信息过多而变得异常庞大
- Pod 状态的变更会引起 Endpoint 的变更,Endpoint 的变更会被推送至所有节点,从而导致持续占用大量网络带宽
- EndpointSlice 对象,用于对 Pod 较多的 Endpoint 进行切片,切片大小可以自定义
不定义 selector 的 service
Service 可以定义 selector,也可以不定义 selector。这个命令会显示与
Service
对象相关联的Ports
对象和Endpoint
对象。在 headless 服务中,Endpoint 对象列出了与之关联的 Pod 的网络地址和端口信息,而不是 IP 地址。apiVersion: v1 kind: Service metadata: name: my-headless-service spec: clusterIP: None ports: - name: http port: 80 targetPort: 8080 - name: https port: 443 targetPort: 8443
在这个 Service 对象中,clusterIP 属性被设置为 None,表示这个服务没有任何 IP 地址。然后,可以使用这个服务的 DNS 名称来访问与之关联的 Pod。
用户创建了 Service
但不定义 Selector
- Endpoint Controller 不会为该
Service
自动创建Endpoint
- 用户可以手动创建 Endpoint 对象,并设置任意 IP 地址到
Address
属性 - 访问该服务的请求会被转发至目标地址
通过该类型服务,可以为集群外的一组 Endpoint 创建服务
Service Endpoint Pod 的关系
📜 对上面的解释:
可以看到 Endpoint 链接了 Service 和 Pod
Service
、Endpoint
和 Pod
是 Kubernetes 中三个重要的概念。Service
定义了一个服务,可以将请求负载均衡到多个 Pod
上。Endpoint
定义了 Service
的后端 Pod
的地址和端口信息。Pod
是 Kubernetes 中最基本的部署单元,是一个或多个容器的集合。在 Kubernetes 中,Service
和 Endpoint
对象通常是通过 Pod
对象来定义的。Service
和 Endpoint
对象是通过 selector
属性与 Pod
对象关联的,selector
属性定义了一组标签,这些标签用于选择与 Service
和 Endpoint
相关联的 Pod
。
一个 Service
对象可以与多个 Endpoint
对象关联,每个 Endpoint
对象定义了一个后端 Pod
的地址和端口信息。当一个 Service
对象收到请求时,它会将请求负载均衡到与之关联的 Endpoint
对象上。Endpoint
对象中的地址和端口信息可以手动配置,也可以由 Kubernetes 自动管理。
Service
、Endpoint
和 Pod
之间的关系如下:
Service
对象定义了一个服务,包括服务的 IP 地址和端口信息。Endpoint
对象定义了一个服务的后端Pod
的地址和端口信息。Pod
对象是 Kubernetes 中最基本的部署单元,是一个或多个容器的集合。Service
和Endpoint
对象通常是通过selector
属性与Pod
对象关联的,selector
属性定义了一组标签,这些标签用于选择与Service
和Endpoint
相关联的Pod
。- 当一个
Service
对象收到请求时,它会将请求负载均衡到与之关联的Endpoint
对象上。 Endpoint
对象中的地址和端口信息可以手动配置,也可以由 Kubernetes 自动管理。
Service 的类型
类型 | 描述 |
---|---|
ClusterIP | 在集群内部的 IP 地址上暴露服务。这个地址只能在集群内部访问。 |
NodePort | 在每个节点的 IP 地址上暴露服务。这个地址可以从集群外部访问。 |
LoadBalancer | 在外部负载均衡器的 IP 地址上暴露服务。这个地址可以从集群外部访问。 |
ExternalName | 通过 CNAME 记录暴露服务。这个地址可以从集群内部和外部访问。 |
- clusterIP
- Service 的默认类型, 服务被发布至仅集群内部可见的虚拟 IP 地址上。
- 在 API Server 启动时,需要通过
service-cluster-ip-range
参数配置虚拟 IP 地址段,API Server
中有用于分配 IP 地址和端口的组件,当该组件捕获 Service 对象并创建事件时,会从配置的虚拟 IP 地址段中取一个有效的 IP 地址,分配给该 Service 对象。
- nodePort
- 在 API Server 启动时,需要通过 node-port-range 参数配置 nodePort 的范围, 同样的,API Server 组件会捕获 Service 对象并创建事件,即从配置好的 nodePort 范围取一个有效端口,分配给该 Service。
- 每个节点的 kube-proxy 会尝试在服务分配的 nodePort 上建立侦听器接收请求,并转发给服务对应的后端 Pod 实例。
- LoadBalancer
- 企业数据中心一 般会采购一些负载均衡器,作为外网请求进入数据中心内部的统一流量入口。
- 针对不同的基础架构云平台,Kubernertes Cloud Manager 提供支持不同供应商 API 的 Service Controller。如果需要在 Openstack 云平台上搭建 Kubernetes 集群,那么只需提供一份 openstack.rc, Openstack Service Controller 即可通过调用 LBaaS API 完成负载均衡配置。
- Headless Service
- Headless 服务是用户将 clusterIP 显示定义为 None 的服务。
- 无头的服务意味着 Kubernetes 不会为该服务分配统一入口,包括 clusterIP, nodePort 等
- ExternalName:为一个服务创建别名
ExternalName demo:
访问该 service 的情况会被转发到指定域名。
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: prod
spec:
type: ExternalName
externalName: tencent.com
包含关系:
在 Kubernetes 中,ClusterIP
是一种服务类型,用于在集群内部的 IP 地址上暴露服务。这个地址只能在集群内部访问。NodePort
和 LoadBalancer
是 Kubernetes 中的另外两种服务类型,它们都可以在集群外部访问服务。NodePort
在每个节点的 IP 地址上暴露服务,而 LoadBalancer
在外部负载均衡器的 IP 地址上暴露服务。
因此,ClusterIP
是 NodePort
和 LoadBalancer
的子集。也就是说,如果你创建了一个 ClusterIP
服务,那么你可以通过 NodePort
或 LoadBalancer
访问这个服务。但是,如果你创建了一个 NodePort
或 LoadBalancer
服务,那么你不能通过 ClusterIP
访问这个服务,因为 ClusterIP
只在集群内部暴露服务。
Service Topology
Service Topology
是 Kubernetes 中的一个资源对象,用于定义服务的拓扑结构。拓扑结构是一组用于选择后端 Pod 的拓扑域。当一个 Service 对象被创建时,可以指定相关联的 Service Topology
对象。这个 Service Topology
可以是一个简单的标签选择器,也可以是一个更复杂的表达式,如 matchExpressions
。Service Topology
对象定义了服务的拓扑结构,可以实现更高效的负载均衡和故障转移。要使用 Service Topology
,需要将 Kubernetes 版本升级到 1.16
或更高版本。
要创建一个 Service Topology
对象,可以使用以下命令:
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: my-app
topologyKeys:
- "kubernetes.io/hostname"
ports:
- name: http
port: 80
targetPort: 8080
在这个 Service
对象中,topologyKeys
属性被设置为 kubernetes.io/hostname
,表示使用 hostname
作为拓扑域。然后,在 Endpoint
对象中,每个 Pod
的 hostname
属性会被用作拓扑域。
要查看 Service Topology
对象的详细信息,可以使用以下命令:
kubectl describe service <service-name> --namespace=<namespace>
这个命令会显示与 Service
对象相关联的 Service Topology
对象和 Endpoint
对象。其中,Service Topology
对象列出了服务的拓扑信息。
细节部分:
- 一个网络调用的延迟受客户端和服务器所处位置的影响,两者是否在同一节点、同一机架、同一可用区、同一数据中心,都会影响参与数据传输的设备数量
- 在分布式系统中,为保证系统的高可用,往往需要控制应用的错误域(Failure Domain),比如通过反亲和性配置,将一个应用的多个副本部署在不同机架,甚至不同的数据中心
- Kubernetes 提供通用标签来标记节点所处的物理位置,如:
topology.kubernetes.io/ zone: us-west2-a
failure-domain. beta.kubernetes.io/ region: us-west
failure-domain.tess.io/ network-device: us-west05-ra053
failure-domain.tess.io/rack: us_westO2_02-314_19_12
kubernetes.io/hostname: node-1
- Service 引入了 topologyKeys 属性,可以通过如下设置来控制流量
- 当
topologyKeys
设置为["kubernetes.io/hostname"]
时,调用服务的客户端所在节点上如 果有服务实例正在运行,则该实例处理请求,否则,调用失败。 - 当
topologyKeys
设置为["kubernetes.io/hostname" , "topology.kubernetes.io/zone", "topology. kubernetes.io/region"]
时,若同一节点有对应的服务实例,则请求会优先转发至该实例。否则,顺序查找当前 zone 及当前 region 是否有服务实例,并将请求按顺序转发。 - 当
topologyKeys
设置为["topology.kubernetes.io/ zone", "*"]
时,请求会被优先转发至当前 zone 的服务实例。如果当前 zone 不存在服务实例,则请求会被转发至任意服务实例。
- 当
该 Service 的访问只会转发到 client 所在 node 上的 Pod:
apiVersion: v1
kind: Service
metadata:
name: nodelocal
spec:
ports:
- port: 80
protocol: TCP
name: http
selector:
app: nginx
topologyKeys:
- "kubernetes.io/hostname"
该 Service 的访问会按照优先级转发:
apiVersion: v1
kind: Service
metadata:
name: prefer-nodelocal
spec:
ports:
- port: 80
protocol: TCP
name: http
selector:
app: nginx
topologyKeys:
- "kubernetes.io/hostname"
- "topology.kubernetes.io/zone"
- "topology.kubernetes.io/region"
- "*"
END 链接
✴️版权声明 © :本书所有内容遵循CC-BY-SA 3.0协议(署名-相同方式共享)©