下面展示的Deployment 在节点(node)上创建 nginx pod 和 nginx container。需要注意的是,容器(container) 不会 使用该节点(node)上的 80 端口,也不会使用任何特定的 NAT 规则去路由流量到 Pod 上。 这意味着你可以使用相同的 containerPort
在同一个节点上运行多个 Nginx Pod, 并且可以从集群中任何其他的 Pod 或节点上使用为 Pod 分配的 IP 地址访问到它们。
以Nginx举例,创建Service:
kind: Deployment metadata: name: my-nginx spec: selector: matchLabels: run: my-nginx replicas: 2 template: metadata: labels: run: my-nginx spec: containers: - name: my-nginx image: nginx ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: my-nginx labels: run: my-nginx spec: ports: - name: http port: 4444 targetPort: 80 protocol: TCP selector: run: my-nginx
上述规约将创建一个 Service,该 Service 会将所有具有标签 run: my-nginx
的 Pod 的 TCP 80 端口暴露到一个抽象的 Service 端口上:
targetPort
:容器接收流量的端口;
port
: 可任意取值的抽象的 Service 端口,其他 Pod 通过该端口访问 Service
查看你的 Service 资源:
Service 和 Pod:
注:同一个 Pod 内的所有容器能通过 localhost 上的端口互相连通
一个 Service 由一组 Pod 提供支撑。
这些 Pod 通过 EndpointSlices 暴露出来。
Service Selector 将持续评估,结果被 POST 到使用标签与该 Service 连接的一个 EndpointSlice。
当 Pod 终止后,它会自动从包含该 Pod 的 EndpointSlices 中移除。
新的能够匹配上 Service Selector 的 Pod 将被自动地为该 Service 添加到 EndpointSlice 中。
检查 Endpoint,注意到 IP 地址与在第一步创建的 Pod 是相同的。
通过Cluster-IP访问Service服务:
现在,你应该能够从集群中任意节点上使用 curl 命令向 <CLUSTER-IP>:<PORT>
发送请求以访问 Nginx Service。 注意 Service IP 完全是虚拟的,它从来没有走过网络,如果对它如何工作的原理感到好奇, 可以进一步阅读服务代理的内容。
创建顺序:
Service尽量先于pod的deployment创建:这是因为如果副本的创建先于 Service,调度器可能会将所有 Pod 部署到同一台机器上,如果该机器宕机则整个 Service 都会离线。
要改正的话,我们可以先终止这 2 个 Pod,然后等待 Deployment 去重新创建它们(比如缩容到0,再恢复)。
这次 Service 会 先于 副本存在。这将实现调度器级别的 Pod 按 Service 分布(假定所有的节点都具有同样的容量),并提供正确的环境变量:
先创建pod:
先创建Service 后创建pod:
参考:
Kubernetes 网络模型: https://kubernetes.io/zh-cn/docs/concepts/services-networking/
Service连接应用:https://kubernetes.io/zh-cn/docs/tutorials/services/connect-applications-service/