在这里插入图片描述

Service 官网文档-service

什么是service

Service 定义了这样一种抽象:逻辑上的一组 Pod,一种可以访问它们的策略 。pod重新部署之后ip就会变,所以一般通过service来访问pod。将service和pod通过某种方式绑定,就可以通过service访问pod了。同时也可以简单看作service做了一个负载均衡。就像springcloud中Eureka服务发现,通过名字就可以与真实的服务绑定。k8s中其实endpoints主要定义了真实服务(pod)的访问地址,service给出自己的name,其他资源对象就可以通过service的name来访问真实的服务(pod)。

spec (ServiceSpec)

spec 定义 Service 的行为。https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status

selector (map[string]string)

将 Service 流量路由到具有与此 selector 匹配的标签键值对的 Pod。

ports ([]ServicePort)

ports.port (int32),必需

Service 将公开的端口。

ports.targetPort (IntOrString)

在 Service 所针对的 Pod 上要访问的端口号或名称。 编号必须在 1 到 65535 的范围内。

ports.protocol (string)

此端口的 IP 协议。支持 “TCP”、“UDP” 和 “SCTP”。默认为 TCP。

ports.name (string)
  • Service 中此端口的名称。
  • 这必须是 DNS_LABEL。
  • ServiceSpec 中的所有端口的名称都必须唯一。
  • 在考虑 Service 的端点时,这一字段值必须与 EndpointPort 中的 name 字段相同。 如果此服务上仅定义一个 ServicePort,则为此字段为可选。
ports.nodePort (int32)

当类型为 NodePort 或 LoadBalancer 时,Service 公开在节点上的端口, 通常由系统分配。
如果指定了一个在范围内且未使用的值,则将使用该值,否则操作将失败。
如果在创建的 Service 需要该端口时未指定该字段,则会分配端口。
如果在创建不需要该端口的 Service时指定了该字段,则会创建失败。
当更新 Service 时,如果不再需要此字段(例如,将类型从 NodePort 更改为 ClusterIP),这个字段将被擦除。 更多信息

type (string)

  • type 确定 Service 的公开方式。
  • 默认为 ClusterIP。
  • 有效选项为 ExternalName、ClusterIP、NodePort 和 LoadBalancer。
  • “ClusterIP” 为端点分配一个集群内部 IP 地址用于负载均衡。 Endpoints 由 selector 确定,如果未设置 selector,则需要通过手动构造 Endpoints 或 EndpointSlice 的对象来确定。 如果 clusterIP 为 “None”,则不分配虚拟 IP,并且 Endpoints 作为一组端点而不是虚拟 IP 发布。
  • “NodePort” 建立在 ClusterIP 之上,并在每个节点上分配一个端口,该端口路由到与 clusterIP 相同的 Endpoints。
  • “LoadBalancer” 基于 NodePort 构建并创建一个外部负载均衡器(如果当前云支持),该负载均衡器路由到与 clusterIP 相同的 Endpoints。
  • “externalName” 将此 Service 别名为指定的 externalName。其他几个字段不适用于 ExternalName Service。
  • 更多信息

clusterIP (string)

  • clusterIP 是服务的 IP 地址,通常是随机分配的。 如果地址是手动指定的,在范围内(根据系统配置),且没有被使用,它将被分配给服务,否则创建服务将失败。
  • clusterIP 一般不会被更改,除非 type 被更改为 ExternalName (ExternalName 需要 clusterIP 为空)或 type 已经是 ExternalName 时,可以更改 clusterIP(在这种情况下,可以选择指定此字段)。 可选值 “None”、空字符串 (“”) 或有效的 IP 地址。 clusterIP 为 “None” 时会生成“无头服务”(无虚拟 IP),这在首选直接 Endpoint 连接且不需要代理时很有用。 仅适用于 ClusterIP、NodePort、和 LoadBalancer 类型的服务。 如果在创建 ExternalName 类型的 Service 时指定了 clusterIP,则创建将失败。 更新 Service type 为 ExternalName 时,clusterIP 会被移除。 更多信息: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies

externalIPs ([]string)

externalIPs 是一个 IP 列表,集群中的节点会为此 Service 接收针对这些 IP 地址的流量。
这些 IP 不被 Kubernetes 管理。用户需要确保流量可以到达具有此 IP 的节点。
一个常见的例子是不属于 Kubernetes 系统的外部负载均衡器。

sessionAffinity (string)

支持 “ClientIP” 和 “None”。用于维护会话亲和性。 启用基于客户端 IP 的会话亲和性。必须是 ClientIP 或 None。默认为 None。 更多信息: https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies

loadBalancerIP (string)

仅适用于服务类型: LoadBalancer。此功能取决于底层云提供商是否支持负载均衡器。 如果云提供商不支持该功能,该字段将被忽略。 已弃用: 该字段信息不足,且其含义因实现而异,而且不支持双栈。 从 Kubernetes v1.24 开始,鼓励用户在可用时使用特定于实现的注释。在未来的 API 版本中可能会删除此字段。

service如何选择pod

  1. Service 所针对的 Pod 集合通常是通过选择算符来确定的
  2. 不带选择算符的服务

定义 Service

例如,假定有一组 Pod,它们对外暴露了 9376 端口,同时还被打上 app=MyApp 标签:

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  selector: #将 Service 流量路由到具有与此 selector 匹配的标签键值对的 Pod。
    app.kubernetes.io/name: MyApp #代理的是label为该key:value的pod
  ports:
    - protocol: TCP #pod的端口使用tcp协议
      port: 80 #通过该端口访问该service
      targetPort: 9376 #被代理的端口,也就是pod上开放的端口
  1. 创建一个名称为 “my-service” 的 Service 对象
  2. 它会将请求代理到使用 TCP 端口 9376,并且具有标签 app.kubernetes.io/name=MyApp 的 Pod 上。

Pod 中的端口定义是有名字的,你可以在 Service 的 targetPort 属性中引用这些名称。
在新版本中更改 Pod 中后端软件公开的端口号,而不会破坏客户端。

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app.kubernetes.io/name: proxy
spec:
  containers:
  - name: nginx
    image: nginx:stable
    ports:
      - containerPort: 80
        name: http-web-svc

---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app.kubernetes.io/name: proxy
  ports:
  - name: name-of-service-port
    protocol: TCP
    port: 80
    targetPort: http-web-svc
    

不带选择算符的服务

apiVersion: v1
kind: Service
metadata:
  name: my-service
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376

由于此服务没有选择算符,因此不会自动创建相应的 Endpoints 对象。 你可以通过手动添加 Endpoints 对象,将服务手动映射到运行该服务的网络地址和端口:( 请求将被路由到用户定义的 Endpoint)

apiVersion: v1
kind: Endpoints
metadata:
  # 这里的 name 要与 Service 的名字相同
  name: my-service
subsets:
  - addresses:
      - ip: 192.0.2.42
    ports:
      - port: 9376

端点 IPs 必须不可以 是:本地回路(IPv4 的 127.0.0.0/8, IPv6 的 ::1/128) 或本地链接(IPv4 的 169.254.0.0/16 和 224.0.0.0/24,IPv6 的 fe80::/64)。
端点 IP 地址不能是其他 Kubernetes 服务的集群 IP,因为 kube-proxy 不支持将虚拟 IP 作为目标。

status(ServiceStatus)

最近观察到的 Service 状态。由系统填充。只读。 更多信息

Endpoints 官文-Endpoints

什么是endpoints

  • pod和service之间的关联关系,是通过endpoint实现的。 Endpoints表示了一个Service对应的所有Pod副本的访问地址的集合,也就是官网说的

Endpoints 是实现实际服务的端点的集合

而Endpoints Controller负责生成和维护所有Endpoints对象的控制器。它负责监听Service和对应的Pod副本的变化。

  • 对于pod,endpoint是集群自动创建的,用于将service和pod关联起来;而对于外部服务(部署在集群外边的数据库之类的),我们可以人工的创建endpoint和service。使其能够更规范的和pod进行通信。
  • Endpoint存储在etcd中,它是根据service配置文件中的selector描述产生的。
  • 一个service由一组Pod组成,这些Pod通过Endpoints暴露出来,

subsets ([]EndpointSubset)

subsets.addresses ([]EndpointAddress) EndpointAddress 是描述单个 IP 地址的元组。

提供标记为就绪的相关端口的 IP 地址。 这些端点应该被认为是负载均衡器和客户端可以安全使用的。

subsets.addresses.ip (string), 必需
  • 端点的 IP。
  • 不可以是本地回路(127.0.0.0/8)、链路本地(169.254.0.0/16)或链路本地多播(224.0.0.0/24)地址。 IPv6 也被接受,但并非在所有平台上都完全支持。 此外,诸如 kube-proxy 等某些 Kubernetes 组件还没有准备好支持 IPv6。
subsets.addresses.hostname (string)

端点主机名称。

subsets.addresses.nodeName (string)

可选:承载此端点的节点。此字段可用于确定一个节点的本地端点。

subsets.addresses.targetRef (ObjectReference)

对提供端点的对象的引用。

subsets.notReadyAddresses ([]EndpointAddress)

提供相关端口但由于尚未完成启动、最近未通过就绪态检查或最近未通过活跃性检查而被标记为当前未就绪的 IP 地址。

subsets.notReadyAddresses.ip (string), 必需

端点的 IP。不可以是本地环路(127.0.0.0/8)、链路本地(169.254.0.0/16)或链路本地多播(224.0.0.0/24)地址。 IPv6 也被接受,但并非在所有平台上都完全支持。 此外,诸如 kube-proxy 等某些 Kubernetes 组件还没有准备好支持 IPv6。

subsets.notReadyAddresses.hostname (string)

端点主机名称。

subsets.notReadyAddresses.nodeName (string)

可选:承载此端点的节点。此字段可用于确定节点的本地端点。

subsets.notReadyAddresses.targetRef (ObjectReference)

对提供端点的对象的引用。

subsets.ports ([]EndpointPort)

相关 IP 地址上可用的端口号。

subsets.ports.port (int32), 必需

端点的端口号。

subsets.ports.protocol (string)

此端口的 IP 协议。必须是 UDP、TCP 或 SCTP。默认值为 TCP。

subsets.ports.name (string)

端口的名称。此字段必须与相应 ServicePort 中的 name 字段匹配。必须是 DNS_LABEL。 仅当定义了一个端口时才可选。

subsets.ports.appProtocol (string)

端口的应用程序协议。此字段遵循标准的 Kubernetes 标签语法。 未加前缀的名称保留给 IANA 标准服务名称(遵循 RFC-6335 和 https://www.iana.org/assignments/service-names)。 非标准协议应使用带前缀名称,如 mycompany.com/my-custom-protocol。

Ingress 官网文档-ingress

什么是ingress?

Ingress 是对集群中服务的外部访问进行管理(将集群的服务暴露给集群外访问,就像nginx)的 API 对象,典型的访问方式是 HTTP。

用于配置 Ingress 的主机规则列表。如果未指定或没有规则匹配,则所有流量都将发送到默认后端。

Ingress 不会公开任意端口或协议。 将 HTTP 和 HTTPS 以外的服务公开到 Internet 时,通常使用 Service.Type=NodePort 或 Service.Type=LoadBalancer 类型的 Service。

IngressSpec(代表ingress中自己的spec字段的内容)

defaultBackend (IngressBackend)

ingressClassName (string)

  • 没有指定类的新 Ingress 资源将被分配到此默认类。也就是ingress和ingressClass有绑定关系,同时也是和ingress控制器也有绑定关系
  • 当存在多个默认 Ingress Class 时,新的 Ingress 如果没有指定 ingressClassName 则不会被允许创建。解决这个问题只需确保集群中最多只能有一个 IngressClass 被标记为默认。

rules ([]IngressRule)(文档中在字段后面加上类型的,应该是代码中的样子)

rules.host (string)
  1. 不允许 IP。当前 IngressRuleValue 只能应用于父 Ingress Spec 中的 IP。

  2. 由于不允许使用端口,因此不理会 “:” 分隔符。 当前 Ingress 的端口隐式为:

:80 用于 http
:443 用于 https
这两种情况在未来都可能发生变化

rules.http (HTTPIngressRuleValue)

HTTPIngressRuleValue 是指向后端的 http 选择算符列表。例如 http:/// ? -> 后端, 其中 url 的部分对应于 RFC 3986,此资源将用于匹配最后一个 “/” 之后和第一个 “?” 之前的所有内容或 “#”。

rules.http.paths ([]HTTPIngressPath),必需

将请求映射到后端的路径集合。
将路径与后端关联。与路径匹配的传入 URL 将转发到后端。

rules.http.paths.backend (IngressBackend),必需

backend 定义将流量转发到的引用服务端点。
IngressBackend
描述给定服务和端口的所有端点。

service (IngressServiceBackend)

IngressServiceBackend 需要端口名或端口号。
IngressServiceBackend 引用一个 Kubernetes Service 作为后端。
service 引用一个 Service 作为后端。此字段是一个与 resource 互斥的设置。

service.name (string),必需

name 是引用的服务。服务必须与 Ingress 对象位于同一命名空间中。

service.port (ServiceBackendPort)

ServiceBackendPort 是被引用的服务的端口。

service.port.name (string)

name 是服务上的端口名称。此字段是一个与 number 互斥的设置。

service.port.number (int32)

number 是服务上的数字形式端口号(例如 80)。此字段是一个与 name 互斥的设置。

rules.http.paths.pathType (string),必需

决定如何解释 path 匹配

  • Exact:与 URL 路径完全匹配。

  • Prefix:根据按 “/” 拆分的 URL 路径前缀进行匹配。
    匹配是按路径元素逐个元素完成。路径元素引用的是路径中由“/”分隔符拆分的标签列表。 如果每个 p 都是请求路径 p 的元素前缀,则请求与路径 p 匹配。 请注意,如果路径的最后一个元素是请求路径中的最后一个元素的子字符串,则匹配不成功 (例如 /foo/bar 匹配 /foo/bar/baz,但不匹配 /foo/barbaz)。

  • ImplementationSpecific:路径匹配的解释取决于 IngressClass。 实现可以将其视为单独的路径类型,也可以将其视为前缀或确切的路径类型。 实现需要支持所有路径类型。

rules.http.paths.path (string)

path 要与传入请求的路径进行匹配。 目前,它可以包含 RFC 3986 定义的 URL 的常规 “路径” 部分所不允许的字符。 路径必须以 “/” 开头,并且在 pathType 值为 “Exact” 或 “Prefix” 时必须存在。

status (IngressStatus)

status 是 Ingress 的当前状态。 更多信息

IngressClass 官文-ingressClass

什么是ingressClass

IngressClass 代表 Ingress 的类,被 Ingress 的规约引用。

spec (IngressClassSpec)

spec 是 IngressClass 的期望状态。更多信息

controller (string)

  • controller 是指应该处理此类的控制器名称
    这允许由同一控制器控制不同“口味”。例如,对于同一个实现的控制器你可能有不同的参数。 此字段应该指定为长度不超过 250 个字符的域前缀路径,例如 “acme.io/ingress-controller”。 该字段是不可变的。

parameters (IngressClassParametersReference)

parameters 是指向控制器中包含额外配置的自定义资源的链接。 如果控制器不需要额外的属性,这是可选的。
IngressClassParametersReference 标识一个 API 对象。这可以用来指定一个集群或者命名空间范围的资源

parameters.kind (string),必需

kind 是被引用资源的类型。

parameters.name (string),必需

name 是被引用资源的名称。

parameters.apiGroup (string)

apiGroup 是被引用资源的组。 如果未指定 apiGroup,则被指定的 kind 必须在核心 API 组中。 对于任何其他第三方类型,apiGroup 是必需的。

parameters.namespace (string)

namespace 是被引用资源的命名空间。 当范围被设置为 “namespace” 时,此字段是必需的; 当范围被设置为 “Cluster” 时,此字段必须不设置。

parameters.scope (string)

scope 表示是否引用集群或者命名空间范围的资源。 这可以设置为“集群”(默认)或者“命名空间”。

Ingress 控制器 官文-Ingress 控制器

  • 为了让 Ingress 资源工作,集群必须有一个正在运行的 Ingress 控制器。

  • 必须拥有一个 Ingress 控制器 才能满足 Ingress 的要求。 仅创建 Ingress 资源本身没有任何效果。就像只有nginx配置文件没有nginx服务是不行的。

  • 与作为 kube-controller-manager 可执行文件的一部分运行的其他类型的控制器不同, Ingress 控制器不是随集群自动启动的。 基于此页面,你可选择最适合你的集群的 ingress 控制器实现。

  • Kubernetes 作为一个项目,目前支持和维护 AWS、 GCE 和 Nginx Ingress 控制器。

参考资料

k8s的service和endpoint
ingress,ingressController,ingressClass
service详解

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐