Pod 访问问题

Pod 被创建之后,该如何访问呢?直接访问 Pod 会有以下几个问题:

为了以一种固定的方式访问 Pod,Kubernetes 提供了一种负载均衡和服务发现的机制: Service。Service 创建后会提供一个固定的虚拟 IP(以 ClusterIP 类型的 Service 为例), 这样,用户无需关心 Pod 在哪个节点,通过固定 Service IP 即可实现对 Pod 地访问,并且 Service 可以对访问进行负载均衡。

示例:创建一个 Service

apiVersion: v1
kind: Service
metadata:
  name: nginx        # Service的名称
spec:
  selector:          # Label Selector,选择包含app=nginx标签的Pod
    app: nginx
  ports:
  - name: service0
    targetPort: 80   # Pod的端口
    port: 8080       # Service对外暴露的端口
    protocol: TCP    # 转发协议类型,支持TCP和UDP
  type: ClusterIP    # Service的类型

使用 ServiceName 访问 Service

使用 IP 直连有一个问题,如果 Service 被删除,相应的 Cluster IP 也会被回收。域名发现

为此 Kubernetes 结合 DNS 的。CoreDNS 安装成功后会成为 DNS 服务器,当创建 Service 后,CoreDNS 会将 Service 的名称与 IP 记录起来,这样 Pod 就可以通过向 CoreDNS 查询 Service 的名称获得 Service 的 IP 地址。

coreDNS 提供格式如 <service-name>.<namespace-name>.svs.cluster.local 的服务,访问该地址,集群内的域名解析解析服务器会返回该服务所对应的 A 记录。实际使用中,同一个命名空间下可以省略<namespace>.svc.cluster.local,直接使用 ServiceName 即可。

例如上面创建的名为 nginx 的 Service,直接通过 nginx:8080 就可以访问到 Service,进而访问 Pod, 这样无需感知具体 Service 的 IP 地址。

Service 类型

Service 的类型除了 ClusterIP 还有 NodePort、LoadBalancer 和 Headless Service,这几种类型的 Service 有着不同的用途。

NodePort 类型的 Service

NodePort 类型的 Service 可以让 Kubernetes 集群每个节点上保留一个相同的端口, 外部访问连接首先访问节点 IP:Port,然后将这些连接转发给服务对应的 Pod。如下图所示。

下面是一个创建 NodePort 类型的 Service。创建完成后,可以通过节点的 IP:Port访问到后台 Pod