《深入剖析kubernetes》学习笔记(6)——Service和Ingress

37. Service, DNS和服务发现

  • Service 是由 kube-proxy 组件,加上 iptables 来共同实现的。

  • kubernetes中,service和pod都会被分配DNS名字

  • service分为两种服务模式

    • 1>ClusterIP模式,service的DNS名字为...svc.cluster.local,根据该记录解析到服务的Virtual IP
    • 2>Headless模式,即指定ClusterIP=None,service的DNS名字同上,但根据该记录解析到的是所有被代理的Pod的IP地址集合。(实际使用时,返回一个稳定可用的Pod的IP地址)
  • Service涉及的iptabels规则

    • KUBE-SERVICES或者KUBE-NODEPORTS,对应service的入口
    • KUBE-SVC-(hash),负载均衡链,与Endpoints数目一致,probability设置会影响当前规则命中率
    • KUBE-SEP-(hash),DNAT链,与Endpoints一一对应
  • DNAT操作:在路由之前,将流入 IP 包的目的地址和端口,改成–to-destination 所指定的新的目的地址和端口,例如:-A KUBE-SEP-WNBA2IHDGP2BOBGZ -p tcp -m comment --comment "default/hostnames:" -m tcp -j DNAT --to-destination 10.244.1.7:9376

  • 服务发现:pod自身的IP地址是随时会变化的,其数量也会随时增减,这不利于服务方访问POD上的服务,通过创建Service就可以通过单一稳定的访问点(Virtual IP)来访问到Pod,该地址再服务生命周期内保持不变。【服务的VIP是虚拟的,无法ping通】

38. 从外部联通Service的方法

(1) 指定Service类型为NodePort

  • 示例:
spec:
    type: NodePort
    ports:
    - nodePort: 8080
      targetPort: 80
      protocol: TCP

在所有宿主机上打开一个端口8080,将该端口的流量重定向到服务上,再有服务转发到对应Pod的80端口上。

若不显式地声明 nodePort 字段,Kubernetes 就会为你分配随机的可用端口来设置代理。这个端口的范围默认是 30000-32767

  • SNAT操作:
        client
          \ ^
           \ \
            v \
node 1 <--- node 2
 | ^    SNAT
 | |    --->
 v |
endpoint

若实际提供服务的Pod不在客户端访问的宿主机上,则IP包在离开宿主机前进行SNAT操作,即将包的源地址从客户端IP换成了此宿主机IP或者cni0的地址,避免pod在处理完数据后,直接将包返回客户端,造成返回数据的宿主机和客户端发送请求的宿主机不一致,造成客户端报错。

SNAT操作只对Service转发出的包进行,判断的依据是该IP包是否被打上"0x4000"的标记(该标记在DNAT操作之前被打上)。

  • 设置请求本地处理:

若将Service 的 spec.externalTrafficPolicy 字段设置为 local,则pod可以看到真正的外部client的地址,原理是,此时iptables规则只会将IP包转发给本宿主机的POD,若此宿主机无相应的pod,则请求会被丢弃。

    client
    ^ /  \
   / /    \
  / v      X
node 1    node 2
  ^ |
  | |
  | v
endpoint

(2) 指定Service类型为LoadBalancer

LoadBalancer 类型的 Service 被提交后,Kubernetes 就会调用 CloudProvider 在公有云上为你创建一个负载均衡服务,并且把被代理的 Pod 的 IP 地址配置给负载均衡服务做后端。

(3)指定Service类型为ExternalName

若指定externalName = my.database.example.com,则kube-dns中会添加一条CNAME记录,此时访问..svc.cluster.local的效果就和访问my.database.example.com相同了

此方法经常用于连接kubernetes集群外部的服务

(4)为Service分配公有IP

spec:
    ports:
    - protocol: TCP
      port: 80
      targetPort: 9376
    expternalIPs:
    - 80.11.12.10

此时可以通过访问80.11.12.10:80访问到被代理的pod,但此外部IP必须能够路由到一个Kubernetes节点。

总结

所谓 Service,其实就是 Kubernetes 为 Pod 分配的、固定的、基于 iptables(或者 IPVS)的访问入口。而这些访问入口代理的 Pod 信息,则来自于 Etcd,由 kube-proxy 通过控制循环来维护。

39. Ingress

  • Ingress的必要性:

    • 每一个类型为loadBalancer的Service,都会创建一个单独属于该service的负载均衡器,有独立的公有IP,成本高昂。Ingress则可以代理集群所有的service,并提供负载均衡服务。
  • Ingress就是服务的服务。

  • 使用流程:

    • 部署ingress-controller,一般用ingress-nginx
    • 使用nodeport的方式,将ingress-nginx以服务方式暴露出去
    • 部署service和ingress
    • 访问宿主机上nodeport端口,访问到ingress-controller
    • ingress对象访问到service,获得一个endpoint,将请求转发给endpoint
  • 一个 Nginx Ingress Controller 为你提供的服务,其实是一个可以根据 Ingress 对象和被代理后端 Service 的变化,来自动进行更新的 Nginx 负载均衡器。

  • 每个ingress对象对应一个nginx配置文件和一个nginx服务

  • 代码示例

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      name: cafe-ingress
    spec:
      tls:
      - hosts:
        - cafe.example.com
        secretName: cafe-secret
      rules:
      - host: cafe.example.com
        http:
          paths:
          - path: /tea
            backend:
              serviceName: tea-svc
              servicePort: 80
          - path: /coffee
            backend:
              serviceName: coffee-svc
              servicePort: 80
    
posted @ 2021-02-04 09:01  lwjj  阅读(197)  评论(0编辑  收藏  举报