在定义了 Pod 应用之后, 多个 Pod 组成了一组服务(Service). 借助服务, 可以方便的实现服务发现, 负载均衡, 平滑升级; 让服务之间的依赖与 Pod 应用解构.
Pod 的创建销毁, 扩容缩容, 故障迁移等, 会造成 Pod 服务的 IP 地址并不是可以静态依赖的. Service 用于保证 Pod 应用动态变化对依赖者无感知.
Service 提供服务的无中断升级. 先启动一个新的 Pod 使用升级后的内容, 当新 Pod 可用后, 关闭一个老的 Pod. 依次替换所有老的 Pod 即完成无中断升级.
注意: 前提是新老服务对外提供的 API 等要保持兼容.
Service 的管理
1 | apiVersion: v1 |
定义好后, 执行应用生效, 查看服务.
1 | kubectl apply -f SERVICES.yaml |
查看 Service 后面的节点列表(Endpoints), 可以看到服务后面有哪些节点服务. 其中 SERVICE_NAME 为上面第二步获取 Service 列表中的 Service 名.
1 | kubectl get endpoints SERVICE_NAME |
查看 Service 详细信息, 可以看服务的选择器, 类型, 端口映射关系.
1 | kubectl describe service SERVICE_NAME |
删除 Service
1 | kubectl delete -f SERVICES.yaml |
Service 外部访问功能
type: ClusterIP
使用 kube-proxy 和 ClusterIP 让 Master 转发请求
http://<masterip>:8080/api/v1/proxy/namespaces/<ns>/services/SERVICE_NAME:PORT_NAME/
type: NodePort
使用 nodePort
字段指定向外网映射的端口, 不填随机 30000~32767.
http://<masterip>:nodePort/
type: LoadBalancer
使用 spec.status.loadBalancer
定义外部负载均衡 ip 地址.
CoreDNS 实现外部访问
解决使用 Service 的时候需要预知 ClusterIP 的问题.
安装
可以使用 K8s 的软件包管理工具 Helm, 也可以通过 Yaml 进行安装.
1 | wget "https://github.com/kubernetes/kubernetes/blob/master/cluster/addons/dns/coredns/coredns.yaml.base" |
其中修改下面内容:
1 | __PILLAR__DNS__DOMAIN__ 改为 Cluster 机器的 hostname, 例如: cluster.local |
部署 CoreDNS
1 | kubectl apply -f coredns.yaml.base |
客户端接入
修改所有 Node 节点的 kubelet 配置, 增加 DNS 设置: /etc/kubernetes/kubelet
1 | KUBELET_ARGS="--cluster-dns=ClusterIP --cluster-domain=cluster.local" |
其中 --cluster-dns
, --cluster-domain
和上面的配置文件 coredns.yaml
中的内容一致.
客户端测试使用
在一个 pod 中, 调用 nslookup DEPLOYMENT_NAME
查看 DNS 解析. 使用 curl http://DELOYMENT_NAME:PORT/
访问 restapi 服务.
一般集群内访问其他 Service 可以使用 ClusterIP, NodePort, DNS. 集群内服务向外部服务暴露服务, 使用 LoadBalancer 类型, Ingress 是 Service 向上的一个抽象.
总结
LoadBalancer 推荐在使用云服务的时候使用.
NodePort 提供端口数有限, 在大规模部署下有问题.
ClusterIP 明显不适用与外部调用.
Porter 适用于自己部署的机房用. (文中没有提到, 后续可能会根据了解介绍.)