定义

将运行在一组 Pods 上的应用程序公开为网络服务的抽象概念。

在 Kubernetes 中,你无需对你的应用程序进行任何修改即可通过 Service 来实现服务发现机制。Kubernetes 将为每个 Pods 提供自己的 IP 地址,并通过 Service 整合一组 Pod 统一对外提供服务, 并且在它们之间进行负载均衡。

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

创建 Service 时 ControllerManager 会通过 selector 筛选 Pod 并创建 Endpoint(如果无 selector 则需手动创建 Endpoint 提供给 Service)。

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

kube-proxy

既然 Services 只是抽象概念,那么就会有其他组件来负责实现它的功能,kube-proxy 就将负责实现 Service 的工作,kube-proxy 被运行在 kubernetes 每个 Node 上为 Services 提供简单的 TCP, UDP和 SCTP 流量转发,将对 Service 的访问请求转发到对应的目标(Endpoints),他有三种工作模式:

  • userspace

    简单来说就是反向代理,通过 kube-proxy 代理中转,转发过程中会涉及到 Linux 用户态与内核态的转化,导致效率不高。

    https://d33wubrfki0l68.cloudfront.net/e351b830334b8622a700a8da6568cb081c464a9b/13020/images/docs/services-userspace-overview.svg

  • iptables

    通过监听 Services 和 Endpoint 的修改来更新 Node 上的 iptables 规则,将转发工作完全交给内核来做,避免状态转换引发的性能问题。在 Kubernetes v1.2 以后默认采用该方案。

    https://d33wubrfki0l68.cloudfront.net/27b2978647a8d7bdc2a96b213f0c0d3242ef9ce0/e8c9b/images/docs/services-iptables-overview.svg

  • IPVS(IP Virtual Server)

    类似与 iptables 模式,在性能方面有所优化,将原有的存储结构由线性表改为了 Hash 表,避免了当 iptables 规则庞大时检索与修改的成本过高。

    当 kube-proxy 以 IPVS 代理模式启动时,它将验证 IPVS 内核模块是否可用。 如果未检测到 IPVS 内核模块,则 kube-proxy 将退回到以 iptables 代理模式运行。

    https://d33wubrfki0l68.cloudfront.net/2d3d2b521cf7f9ff83238218dac1c019c270b1ed/9ac5c/images/docs/services-ipvs-overview.svg

服务发现

  • 环境变量

    当 Pod 运行在 Node 上,kubelet 会为每个活跃的 Service 添加一组环境变量,格式为 {SVCNAME}_SERVICE_HOST{SVCNAME}_SERVICE_PORT ,例如:

    REDIS_MASTER_SERVICE_HOST=10.0.0.11
    REDIS_MASTER_SERVICE_PORT=6379
    REDIS_MASTER_PORT=tcp://10.0.0.11:6379
    REDIS_MASTER_PORT_6379_TCP=tcp://10.0.0.11:6379
    REDIS_MASTER_PORT_6379_TCP_PROTO=tcp
    REDIS_MASTER_PORT_6379_TCP_PORT=6379
    REDIS_MASTER_PORT_6379_TCP_ADDR=10.0.0.11
    
  • DNS

    集群的 DNS 服务器(例如 CoreDNS)监视 Kubernetes API 中的新服务,并为每个服务创建一组 DNS 记录。 如果在整个集群中都启用了 DNS,则所有 Pod 都应该能够通过其 DNS 名称自动解析服务。

References

https://cloud.tencent.com/developer/article/1832918

https://kubernetes.io/zh-cn/docs/concepts/services-networking/service/