深入理解K8S (一) Service

下面展示的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/

分享你的喜爱

留下评论

您的电子邮箱地址不会被公开。 必填项已用 * 标注