• Kubernetes——Service资源


    Service资源

    一、Service 资源概述

      Service 是 Kubernetes 的核心资源类型之一,通常可看作微服务的一种实现。事实上它是一种抽象:通过规则定义出由多个 Pod 对象组合而成的逻辑集合,以及访问这组 Pod 的策略。

      Service 关联 Pod 资源的规则要借助于标签选择器来完成。

      比如,由 Deployment 等控制器管理的 Pod 对象中断后,会由新建的资源对象所取代,而扩缩容后的应用则会带来 Pod 对象群体的变动,随之变化的还有 Pod 的 IP 地址访问接口等,这也是编排系统之上的应用程序必然要面临的问题。

      Service 资源基于标签选择器将一组 Pod 定义成一个逻辑组合,并通过自己的 IP 地址和端口调度代理请求至组内的 Pod 对象之上,如下图,它向客户端隐藏了真实的、处理用户请求的 Pod 资源,使得客户端的请求看上去就像是由 Service 直接处理并进行响应的一样:

      Servie 对象的 IP 地址也称为 Cluster IP ,它位于为 Kubernetes 集群配置指定专用 IP 地址的范围之内,而且是一种虚拟 IP 地址,它在 Service 对象创建后即保持不变,并且能够被同一集群中的 Pod 资源所反问。

      Service 端口用于接收客户端请求并将其转发至其后端的 Pod 中应用的相应端口之上,因此这种代理机制也被称为 "端口代理"(prot proxy)或 四层代理,它工作与 TCP/IP 协议栈的传输层。

      Service 资源会通过 API Server 持续监视着(watch)标签选择器匹配到的后端 Pod 对象,并实时跟踪各对象的变动,例如,IP地址变动、对象增加或减少等。不过,需要特别说明的是,Service 并不直接链接至 Pod 对象,它们之间还有一个中间层 —— Endpoints 资源对象,它是一个由 IP 地址和端口组成的列表,这些 IP 地址和端口则来自于由 Service 的标签选择器匹配到的 Pod 资源。这也是很多场景种会使用 "Service 的后端端点"(Endpoints)这一术语的原因。默认情况下,创建 Service 资源对象时,其关联的 Endpoints 对象会自动创建。

    二、虚拟IP和服务代理

      简单来讲,一个 Service 对象就是工作节点上的一些 iptables 或 ipvs 规则,用于将到达 Service 对象 IP 地址的流量调度转发至相应的 Endpoints 对象指向的 IP 地址和端口之上。工作于每个工作节点的 kube-proxy 组件通过 API Server 持续监控着各 Service 及与其关联的 Pod 对象,并将其创建或变动实时反映至当前工作节点上相应的 iptables 或 ipvs 规则上。客户端、Service 及其 Pod 对象的关系如下图:

      Service IP 事实上是用于生成 iptables 或 ipvs 规则时使用的 IP 地址,它仅用于实现 Kubernetes 集群网络的内部通信,并且仅能够将规则中定义的转发服务的请求作为目标地址予以响应,这也是它被称为虚拟 IP 的原因之一。

      kube-proxy 将请求代理至相应端点的方法有三种:userspace(用户空间)、iptables 和 ipvs。userspace 已经淘汰,iptables 不常用,这里不描述,只描述 iptables 代理模型。

      iptables 代理模型:

    Kubernetes 自 1.9-alpha 版本起引入了 ipvs 代理模型,且自 1.11 版本起成为默认设置。此模型中,kube-proxy 跟踪 API Server 上的 Service 和 Endpoints 对象的变动,据此来调动 netlink 接口创建 ipvs 规则,并确保与 API Server 中的变动保持同步。它与 iptables 规则的不同之处仅在于其请求流量的调度功能由 ipvs 实现,余下的其他功能仍由 iptables 完成。

      类似于 iptables 模型,ipvs 构建与 netfilter 的钩子函数之上,但它使用 hash 表作为底层数据结构并工作于内核空间,因此具有流量转发速度快、规则同步性能好的特性。另外,ipvs 支持众多调度算法,例如 rr、lc、dh、sh、sed和 nq 等。

     三、创建 Servcie 资源

      Service 资源本身并不提供任何服务,真正处理并响应客户端请求的是后端的 Pod 资源。

      创建 Service 对象的常用方法有两种:

      • 直接使用 "kubectl expose" 命令。
      • 使用资源配置文件。

      Service 资源对象配置定义文件如下:

    [root@mh-k8s-master-prd-243-24 ~]# kubectl explain service
    KIND:     Service
    VERSION:  v1
    
    DESCRIPTION:
         Service is a named abstraction of software service (for example, mysql)
         consisting of local port (for example 3306) that the proxy listens on, and
         the selector that determines which pods will answer requests sent through
         the proxy.
    
    FIELDS:
       apiVersion	<string>
         APIVersion defines the versioned schema of this representation of an
         object. Servers should convert recognized schemas to the latest internal
         value, and may reject unrecognized values. More info:
         https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
    
       kind	<string>
         Kind is a string value representing the REST resource this object
         represents. Servers may infer this from the endpoint the client submits
         requests to. Cannot be updated. In CamelCase. More info:
         https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
    
       metadata	<Object>
         Standard object's metadata. More info:
         https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata
    
       spec	<Object>
         Spec defines the behavior of a service.
         https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
    
       status	<Object>
         Most recently observed status of the service. Populated by the system.
         Read-only. More info:
         https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
    
    [root@mh-k8s-master-prd-243-24 ~]# 
    

      service.spec 嵌套字段定义如下:

    [root@mh-k8s-master-prd-243-24 ~]# kubectl explain service.spec
    KIND:     Service
    VERSION:  v1
    
    RESOURCE: spec <Object>
    
    DESCRIPTION:
         Spec defines the behavior of a service.
         https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
    
         ServiceSpec describes the attributes that a user creates on a service.
    
    FIELDS:
       clusterIP    <string>
         clusterIP is the IP address of the service and is usually assigned randomly
         by the master. If an address is specified manually and is not in use by
         others, it will be allocated to the service; otherwise, creation of the
         service will fail. This field can not be changed through updates. Valid
         values are "None", empty string (""), or a valid IP address. "None" can be
         specified for headless services when proxying is not required. Only applies
         to types ClusterIP, NodePort, and LoadBalancer. Ignored if type is
         ExternalName. More info:
         https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies
    
       externalIPs    <[]string>
         externalIPs is a list of IP addresses for which nodes in the cluster will
         also accept traffic for this service. These IPs are not managed by
         Kubernetes. The user is responsible for ensuring that traffic arrives at a
         node with this IP. A common example is external load-balancers that are not
         part of the Kubernetes system.
    
       externalName    <string>
         externalName is the external reference that kubedns or equivalent will
         return as a CNAME record for this service. No proxying will be involved.
         Must be a valid RFC-1123 hostname (https://tools.ietf.org/html/rfc1123) and
         requires Type to be ExternalName.
    
       externalTrafficPolicy    <string>
         externalTrafficPolicy denotes if this Service desires to route external
         traffic to node-local or cluster-wide endpoints. "Local" preserves the
         client source IP and avoids a second hop for LoadBalancer and Nodeport type
         services, but risks potentially imbalanced traffic spreading. "Cluster"
         obscures the client source IP and may cause a second hop to another node,
         but should have good overall load-spreading.
    
       healthCheckNodePort    <integer>
         healthCheckNodePort specifies the healthcheck nodePort for the service. If
         not specified, HealthCheckNodePort is created by the service api backend
         with the allocated nodePort. Will use user-specified nodePort value if
         specified by the client. Only effects when Type is set to LoadBalancer and
         ExternalTrafficPolicy is set to Local.
    
       ipFamily    <string>
         ipFamily specifies whether this Service has a preference for a particular
         IP family (e.g. IPv4 vs. IPv6). If a specific IP family is requested, the
         clusterIP field will be allocated from that family, if it is available in
         the cluster. If no IP family is requested, the cluster's primary IP family
         will be used. Other IP fields (loadBalancerIP, loadBalancerSourceRanges,
         externalIPs) and controllers which allocate external load-balancers should
         use the same IP family. Endpoints for this Service will be of this family.
         This field is immutable after creation. Assigning a ServiceIPFamily not
         available in the cluster (e.g. IPv6 in IPv4 only cluster) is an error
         condition and will fail during clusterIP assignment.
    
       loadBalancerIP    <string>
         Only applies to Service Type: LoadBalancer LoadBalancer will get created
         with the IP specified in this field. This feature depends on whether the
         underlying cloud-provider supports specifying the loadBalancerIP when a
         load balancer is created. This field will be ignored if the cloud-provider
         does not support the feature.
    
       loadBalancerSourceRanges    <[]string>
         If specified and supported by the platform, this will restrict traffic
         through the cloud-provider load-balancer will be restricted to the
         specified client IPs. This field will be ignored if the cloud-provider does
         not support the feature." More info:
         https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/
    
       ports    <[]Object>
         The list of ports that are exposed by this service. More info:
         https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies
    
       publishNotReadyAddresses    <boolean>
         publishNotReadyAddresses, when set to true, indicates that DNS
         implementations must publish the notReadyAddresses of subsets for the
         Endpoints associated with the Service. The default value is false. The
         primary use case for setting this field is to use a StatefulSet's Headless
         Service to propagate SRV records for its Pods without respect to their
         readiness for purpose of peer discovery.
    
       selector    <map[string]string>
         Route service traffic to pods with label keys and values matching this
         selector. If empty or not present, the service is assumed to have an
         external process managing its endpoints, which Kubernetes will not modify.
         Only applies to types ClusterIP, NodePort, and LoadBalancer. Ignored if
         type is ExternalName. More info:
         https://kubernetes.io/docs/concepts/services-networking/service/
    
       sessionAffinity    <string>
         Supports "ClientIP" and "None". Used to maintain session affinity. Enable
         client IP based session affinity. Must be ClientIP or None. Defaults to
         None. More info:
         https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies
    
       sessionAffinityConfig    <Object>
         sessionAffinityConfig contains the configurations of session affinity.
    
       topologyKeys    <[]string>
         topologyKeys is a preference-order list of topology keys which
         implementations of services should use to preferentially sort endpoints
         when accessing this Service, it can not be used at the same time as
         externalTrafficPolicy=Local. Topology keys must be valid label keys and at
         most 16 keys may be specified. Endpoints are chosen based on the first
         topology key with available backends. If this field is specified and all
         entries have no backends that match the topology of the client, the service
         has no backends for that client and connections should fail. The special
         value "*" may be used to mean "any topology". This catch-all value, if
         used, only makes sense as the last value in the list. If this is not
         specified or empty, no topology constraints will be applied.
    
       type    <string>
         type determines how the Service is exposed. Defaults to ClusterIP. Valid
         options are ExternalName, ClusterIP, NodePort, and LoadBalancer.
         "ExternalName" maps to the specified externalName. "ClusterIP" allocates a
         cluster-internal IP address for load-balancing to endpoints. Endpoints are
         determined by the selector or if that is not specified, by manual
         construction of an Endpoints object. If clusterIP is "None", no virtual IP
         is allocated and the endpoints are published as a set of endpoints rather
         than a stable IP. "NodePort" builds on ClusterIP and allocates a port on
         every node which routes to the clusterIP. "LoadBalancer" builds on NodePort
         and creates an external load-balancer (if supported in the current cloud)
         which routes to the clusterIP. More info:
         https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types
    
    [root@mh-k8s-master-prd-243-24 ~]# 

      一个简单的配置清单文件 Service 资源示例如下:

    kind: Service
    apiVersion: v1
    metadata:
      name: XXX-oms-view
      namespace: XXX-oms-view
      labels:
        XXX-env: prd
        XXX-org: XXX
    spec:
      ports:
        - protocol: TCP
          port: 80
          targetPort: 80
          nodePort: 31527
      selector:
        app: XXX-oms-view
        XXX-env: prd
        XXX-org: XXX
      clusterIP: 10.233.37.76
      type: NodePort
      sessionAffinity: None
      externalTrafficPolicy: Cluster

      Servie 资源 name: XXX-oms-view 通过标签选择器关联至标签为 "app: XXX-oms-view" 的各 Pod 对象,它会自动创建名为 XXX-oms-view 的 Endpoints 资源对象,并自动配置一个 ClusterIP,暴露的端口由 port 字段进行制定,后端各 Pod 对象的端口则由 targetPort 给出,也可以使用同 port 字段的默认值。

     四、向Service对象请求服务

      Service 资源的默认类型为 ClusterIP,它仅能够接收来自集群中的 Pod 对象中的客户端程序的访问请求。

    [root@mh-k8s-master-prd-243-24 ~]#  kubectl get svc -n kubesphere-system
    NAME                    TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)              AGE
    ks-apiserver            ClusterIP   10.233.18.170   <none>        80/TCP               69d
    ks-console              NodePort    10.233.29.142   <none>        80:30880/TCP         69d
    ks-controller-manager   ClusterIP   10.233.48.67    <none>        443/TCP              69d
    minio                   ClusterIP   10.233.61.26    <none>        9000/TCP             69d
    openldap                ClusterIP   None            <none>        389/TCP              69d
    redis                   ClusterIP   10.233.54.138   <none>        6379/TCP             69d
    redis-ha                ClusterIP   None            <none>        6379/TCP,26379/TCP   69d
    redis-ha-announce-0     ClusterIP   10.233.7.171    <none>        6379/TCP,26379/TCP   69d
    redis-ha-announce-1     ClusterIP   10.233.57.0     <none>        6379/TCP,26379/TCP   69d
    redis-ha-announce-2     ClusterIP   10.233.38.140   <none>        6379/TCP,26379/TCP   69d
    [root@mh-k8s-master-prd-243-24 ~]# curl -I http://10.255.243.24:30880
    HTTP/1.1 302 Found
    Vary: Accept-Encoding
    Location: /login
    Content-Type: text/html; charset=utf-8
    Content-Length: 43
    Date: Mon, 20 Jun 2022 09:02:26 GMT
    Connection: keep-alive
    Keep-Alive: timeout=5
    
    [root@mh-k8s-master-prd-243-24 ~]# 

    五、Service会话粘性

      Service 资源还支持 Session affinity(粘性会话或会话粘性)机制,它能够将来自同一个客户端的请求始终转发至同一个后端的 Pod 对象,这意味着它会影响调度算法的流量分发功能,进而降低其负载均衡的效果。

      因此,当客户端访问 Pod 中的应用程序时,如果有基于客户端身份保存某些私有信息,并基于这些私有信息追踪用户的活动等一类的需求时,那么应该启动 session affinity 机制。

      Session affinity 的效果仅会在一定时间期限内生效,默认值为 10800秒,超出此时长之后,客户端的再次访问会被调度算法重新调度。另外,Service 资源的 Session affinity 机制仅能基于客户端 IP 地址识别客户端身份,它会把经由同一个 NAT 服务器进行源地址转换的所有客户端识别为同一个客户端,调度粒度粗糙且效果不佳,因此实践中并不推荐使用此种方法实现粘性会话。

    [root@mh-k8s-master-prd-243-24 ~]# kubectl explain service.spec.sessionAffinity
    KIND:     Service
    VERSION:  v1
    
    FIELD:    sessionAffinity <string>
    
    DESCRIPTION:
         Supports "ClientIP" and "None". Used to maintain session affinity. Enable
         client IP based session affinity. Must be ClientIP or None. Defaults to
         None. More info:
         https://kubernetes.io/docs/concepts/services-networking/service/#virtual-ips-and-service-proxies
    [root@mh-k8s-master-prd-243-24 ~]# 
    
    [root@mh-k8s-master-prd-243-24 ~]# kubectl explain service.spec.sessionAffinityConfig
    KIND:     Service
    VERSION:  v1
    
    RESOURCE: sessionAffinityConfig <Object>
    
    DESCRIPTION:
         sessionAffinityConfig contains the configurations of session affinity.
    
         SessionAffinityConfig represents the configurations of session affinity.
    
    FIELDS:
       clientIP	<Object>
         clientIP contains the configurations of Client IP based session affinity.
    
    [root@mh-k8s-master-prd-243-24 ~]# 
  • 相关阅读:
    UMLChina-我不经意的创业故事
    oracle management server
    关于做PDF的FAQ(一)~(四)
    关于学习ASP和编程的28个观点
    JavaScript的方法和技巧
    在公告栏里加进啦Google自定义搜索引擎(附代码,和参考代码,原代码)
    来北京工作了,有写感慨
    asp.net 2.0 访问oracle
    利用SharpZipLib进行文件的压缩和解压缩
    软件工程师,请不要做浮躁的人
  • 原文地址:https://www.cnblogs.com/zuoyang/p/16393266.html
Copyright © 2020-2023  润新知