Service 的工作原理和 LVS、Nginx 差不多,Kubernetes 会给它分配一个静态 IP 地址,然后它再去自动管理、维护后面动态变化的 Pod 集合,当客户端访问 Service,它就根据某种策略,把流量转发给后面的某个 Pod。

Service:微服务架构的应对之道_service

Service 使用了 iptables 技术,每个节点上的 kube-proxy 组件自动维护 iptables 规则,客户不再关心 Pod 的具体地址,只要访问 Service 的固定 IP 地址,Service 就会根据 iptables 规则转发请求给它管理的多个 Pod,是典型的负载均衡架构。

因为在 Kubernetes 里提供服务的是 Pod,而 Pod 又可以用 Deployment/DaemonSet 对象来部署,所以 kubectl expose  支持从多种对象创建服务,Pod、Deployment、DaemonSet 都可以。

使用 kubectl expose 指令时还需要用参数 --port 和 --target-port 分别指定映射端口和容器端口,而 Service 自己的 IP 地址和后端 Pod 的 IP 地址可以自动生成,用法上和 Docker 的命令行参数 -p 很类似,只是略微麻烦一点。

为了让你看清楚 Service 与它引用的 Pod 的关系,需要重点关注的是 selector、targetPort 与 Pod 的关联:

Service:微服务架构的应对之道_Pod_02

 Service 对象的域名完全形式是“对象. 名字空间.svc.cluster.local”,但很多时候也可以省略后面的部分,直接写“对象. 名字空间”甚至“对象名”就足够了,默认会使用对象所在的名字空间(比如这里就是 default)。

Service 对象有一个关键字段“type”,表示 Service 是哪种类型的负载均衡。前面我们看到的用法都是对集群内部 Pod 的负载均衡,所以这个字段的值就是默认的“ClusterIP”,Service 的静态 IP 地址只能在集群内访问。除了“ClusterIP”,Service 还支持其他三种类型,分别是“ExternalName”“LoadBalancer”“NodePort”。