1 Service资源的基础应用

1.1 创建Service资源

  创建Service对象的常用方法有两种:一是直接使用"kubectl expose"命令;另一种是使用资源配置文件,它与此前使用的资源清单文件配置其他资源的方法类似。

1.1.1 第一种方法:

  pod(po),service(svc),replication controller(rc),deployment(deploy),replica set(rs)

  Kubectl语法

kubectl expose (-f FILENAME | TYPE NAME) [--port=port] [--protocol=TCP|UDP] [--target-port=number-or-name] [--name=name] [--external-ip=external-ip-of-service] [--type=type]

  示例:

  为rc的nginx创建一个service,该服务位于端口80上,并连接到端口8000的容器上。

# kubectl expose rc nginx --port=80 --target-port=8000

  为deploy创建一个类型为NodePort的,对外暴露端口为80,名称为myapp的服务

# kubectl expose deployment myapp --type=”NodePort" --port=8O --name=myapp

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

1.1.2 第二种方法:

  定义Service资源对象时,spec的两个较为常用的内嵌字段分别为selector和ports,分别用于定义使用的标签选择器和要暴露的端口。

apiVersion: v1 
kind: Service
metadata:
  name: myapp-svc 
spec:
  selector: 
    app:myapp
  ports:
  - protocol: TCP
    port: 80 
    targetPort: 80

2 Service会话粘性

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

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

  Service资源通过.spec.sessionAffinity和.spec.sessionAffinityConfig两个字段配置粘性会话。spec.sessionAffinity字段用于定义要使用的粘性会话类型,它仅支持使用“None”和“ClientIp”两种属性。

  • None:不使用sessionAffinity,默认值
  • ClientIP:基于客户端IP地址识别客户端身份,把来自同一个源IP地址的请求始终调度至同一个Pod对象

  在启用粘性会话机制时,.spec.sessionAffinityConfig用于配置会话保持时长,他是一个嵌套字段,使用格式如下,可用时长范围为“1-86400”,默认为10800秒

spec:
  sessionAffinity: ClientIp 
  sessionAffinityConfig:
    clientIP:
    timeoutSeconds: <integer>

3 服务暴露

  Service的IP地址仅在集群内可达,然而,总会有些服务需要暴露到外部网络中接收各类客户端的访问,此时,就需要在集群边缘为其添加一层转发机制,已实现外部请求流量接入到集群的Service资源之上,这种操作也成为发布服务到外部网络中。

3.1 Service类型

  Kubernetes的Service共有四种类型:ClusterIP、NodePort、LoadBalancer和ExternalName。

  • ClusterIP:通过集群内部IP地址暴露服务,此地址仅在集群内部可达,而无法被集群外部的客户端访问。此为默认的Service类型
  • NodePort:这种类型建立在ClusterIP类型之上,其在每个Node节点的某静态端口暴露服务,简单来说,NodePort类型就是在工作节点的IP地址上选择一个端口用于将集群外部的用户请求转发至目标Service的ClusterIP和Port,因此,这种类型的Service既可如ClusterIP一样受到集群内部客户端Pod的访问,可会受到集群外部客户端通过套接字<NodeIP>:<NodePort>进行请求。
  • LoadBalancer:这种类型构建在NodePort类型之上,也就是通过公有云LB将NodePort暴露的<NodeIP>:<NodePort>配置在LB上,实现负载均衡
  • ExternalName:目的是让集群内的Pod资源能够访问外部的Service的一种实现方式

3.2 NodePort类型的Service资源

apiVersion: v1
kind: Service  
metadata:
  name: myapp-svc-nodeport 
spec:
  type: NodePort
  selector: 
    app:myapp
  ports:
  - protocol: TCP
    port: 80 
    targetPort: 80 
    nodePort: 32223
==============================
port: 80    #表示service端口
targetPort: 80    #表示Pod容器端口
nodePort: 32223   #表示Node节点暴露端口

3.3 LoadBalancer类型的Service资源

  NodePort类型的Service资源虽然能够于集群外部访问,但外部客户端必须得事先得知NodePort和集群中至少一个节点的IP地址,且选定的节点发生故障时,客户端还得自行选择请求访问其他节点,另外,集群节点很可能是某IaaS云环境中使用私有IP地址的VM,或者是IDC中使用的私有地址的物理机,这类地址对互联网客户端不可达,因为,一般,还应该在集群外创建一个具有公网IP地址的负载均衡器,由他接入外部客户端的请求并调度至集群节点相应的NodePort之上。

apiVersion: v1
kind: Service  
metadata:
  name: myapp-svc-lb 
spec:
  type: LoadBalancer
  selector: 
    app:myapp
  ports:
  - protocol: TCP
    port: 80 
    targetPort: 80 
    nodePort: 32223

3.4 ExternalName Service

  ExternalName类型的Service资源用于将集群外部的服务发布到集群中以供Pod中的应用程序访问,因此,它不需要使用标签选择器关联任何的Pod对象,但必须要使用spec.externalName属性定义一个CNAME记录用于返回外部真正提供服务的主机的别名,而后通过CNAME记录值获取到相关主机的IP地址。

apiVersion: v1 
kind: Service
metadata :
  name : external-redis-svc
  namespace: default 
spec:
  type: ExternalName 
  externaIName : redis.ilinux.io 
  ports:
  - protocol: TCP
    port: 6379 
    targetPort: 6379 
    nodePort: 0
    selector: {}

  待Service资源external-redis-svc创建完成后,各Pod对象即可通过external-redis-svc或其FQDN格式个名称external-redis-svc.default.svc.cluster.local访问相应的服务。

4 Headless类型的Service资源

  Service对象隐藏了各Pod资源,并负责将客户端的请求流量调度至该组Pod对象之上。不过,偶尔也会存在这样一类需求:客户端需要直接访问Service资源后端的Pod资源,这时就应该向客户端暴露每个Pod资源的IP地址,而不再是中间层Service对象的ClusterIP,这种类型的Service资源便称为Headless Service。

apiVersion: v1
kind: Service  
metadata:
  name: myapp-headless-svc 
spec:
  clusterIP: None 
  selector :
    app: myapp 
  ports :
  - port: 80 
    targetPort: 80 
    name: httpport

5 Ingress资源

5.1 创建Ingress资源

  Ingress资源是基于HTTP虚拟主机或URL的转发规则,它在资源配置清单的spec字段中嵌套了rules、backend和tls等字段进行定义。

  下面的示例中定义了一个Ingress资源,它包含了一个转发规则,把发往www.ilinux.io的请求代理给名为myapp-svc的Service资源

ap1Version: extesions/v1beta1
kind: Ingress
metadata:
  name: my-ingress 
  annotations :
    kubernetes.io/ingress.class: "nginx" 
spec:
  rules:
  - host: www.ilinux.io
    http: 
      paths:
      - backend:
          serviceName: myapp-svc 
          servicePort: 80

不积跬步,无以至千里;不积小流,无以成江海。