You need to enable JavaScript to run this app.
导航

集群内应用互访

最近更新时间2023.06.07 20:21:51

首次发布时间2021.12.17 18:56:38

本文主要描述容器服务中同一个集群内的应用,如何相互访问,满足通信需求。

概述

集群内 Pod 的访问问题

工作负载创建完成后在多个 Pod 中运行,而 Pod 由于具备弹性伸缩属性,因此访问 Pod 会面临如下几个问题:

  • Pod 会随时被 Deployment 这样的控制器删除和重建,因此无法确定访问 Pod 的结果。
  • Pod 的 IP 地址是在 Pod 启动后才被分配,在启动前并不知道 Pod 的 IP 地址,因此无法通过 Pod 的 IP 地址进行访问。
  • 分配给 Pod 的 IP 地址是集群内部的IP地址,通常情况下均为私网 IP 地址,不能直接访问。并且,同一个工作负载下会存在多个副本的 Pod,每个 Pod 的 IP 地址也不一样。因此,直接通过 Pod 的 IP 地址访问应用,会存在单点性能和故障的问题。

通过 Service 解决 Pod 的访问问题

Kubernetes 中使用 Service 对象解决上述 Pod 访问问题。

  • 创建 Service 时,系统会为 Service 生成一个固定 IP 地址(ClusterIP),用户可以通过访问该 ClusterIP 来访问 Service。
  • Service 通过 Label 来选择 Pod,并将用户的访问流量转发给 Pod。同时 Service 还可以给 Pod 做负载均衡。
    alt

Service 的访问方式

集群内访问(ClusterIP)

集群内访问是指将工作负载暴露给同一集群内其他工作负载访问的方式,可以通过“集群内部域名”访问。

例如创建一个名为 nginx 的 Service,端口号为 8080,则集群内部访问时,直接通过 nginx:8080 就可以访问到 Service,进而访问后台 Pod。
alt

节点端口访问(NodePort)

节点访问是指在每个节点的 IP 上开放一个静态端口,通过静态端口对外暴露服务。集群内其他应用通过请求NodeIP:NodePort,即可访问服务。

alt

负载均衡(LoadBalancer)

LoadBalancer 类型的 Service 其实是 NodePort 类型的扩展,通过 LoadBalancer 访问Service,Service 再将请求转发到节点的 NodePort。实现了负载均衡,提供了更高的可靠性保障。

alt

Headless Service

在微服务相关场景,如果不需要负载均衡以及 Service IP,需要直通Pod的时候。可以通过指定 Cluster IP(spec.clusterIP)的值为"None"来创建 Headless Service。

Headless Service 不会为 Service 创建 ClusterIP,DNS 查询时会返回所有 Pod 的 DNS 记录,这样就可以访问到所有 Pod 的 IP 地址。相当于直接访问 Pod。

集群内访问(ClusterIP)和 Headless Service 的主要区别和应用场景如下。

差异项集群内访问(ClusterIP)Headless Service
ClusterIP有。无。
解析 Service 的 DNS 结果返回 Service 的 ClusterIP 地址。返回所有 Pod 的 Pod IP 地址。
其他应用访问 Service只能访问到 Service,具体的 Pod 由 iptables 决定,实现了针对 Pod 的负载均衡。能够直接访问到全部 Pod。
应用场景需要 Service 为 Pod 进行负载均衡的场景。
  • 需要直接访问所有 Pod 的场景。例如在集群中部署 Kafka,无需 Service 来代理,客户端需要能够访问所有的 Pod。
  • Client 处理负载均衡的场景。例如在集群中部署两个 MySQL,Client 负责处理负载均衡请求,此种场景下就无需 Serivce 来代理。

访问方式对比

访问方式公开内容说明
ClusterIPspec.clusterIp:spec.ports[*].port只能在集群内访问此服务。可从其spec.clusterIp端口访问。如果设置了spec.ports[*].targetPort,它将从端口路由到 targetPort。调用时获得的 ClusterIP:kubectl get services是集群内部分配给该服务的 IP。
NodePort
  • NodeIP:spec.ports[*].nodePort
  • spec.clusterIp:spec.ports[*].port
如果从节点的外部 IP 在 NodePort 上访问此服务,它将把请求路由到spec.clusterIp:spec.ports[*].port,然后将请求路由到spec.ports[*].targetPort(如果已设置)。也可以使用与 ClusterIP 相同的方式访问此服务。NodeIP 是节点的外部 IP 地址。无法从访问服务<ClusterIP>:spec.ports[*].nodePort

LoadBalancer

  • spec.loadBalancerIp:spec.ports[*].port
  • <NodeIP>:spec.ports[*].nodePort
  • spec.clusterIp:spec.ports[*].port

可以从负载均衡器的 IP 地址访问此服务,该服务会将请求路由到 NodePort,后者又将请求路由到 ClusterIP 端口。用户可以像访问 NodePort 或 ClusterIP 服务一样访问此服务。

使用提示

  • 除非绝对必要,否则不要为 Pod 指定 hostPort。将 Pod 绑定到 hostPort 时,因为每个<hostIP, hostPort, protocol>组合必须是唯一,因此 hostPort 会限制 Pod 可以调度的位置数。 如果没有明确指定 hostIP 和 Protocol,Kubernetes 将使用0.0.0.0作为默认的 hostIP,TCP 作为默认的 Protocol。
  • 如果只需要访问端口以进行调试,则可以使用 apiserver proxy 或 kubectl port-forward。
  • 如果明确需要在节点上公开 Pod 的端口,请在使用 hostPort 之前考虑使用 NodePort 服务。
  • 避免使用 hostNetwork,原因与 hostPort 相同。
  • 不需要 kube-proxy 负载均衡时,使用无头服务 headless-services(ClusterIP 被设置为 None)以便于服务发现。

注意事项

如果需要跨 VPC 访问工作负载,则需要通过对等连接等手段打通不同 VPC 网络。

配置集群内访问(ClusterIP)

配置前检查

  • 创建完成集群、节点,保证集群、节点工作正常。详细操作,请参见 创建集群
  • 将应用镜像上传至镜像仓库。详细操作,请参见 推送和拉取镜像

配置步骤

以无状态负载(Deployment)为例。详细的操作步骤和参数说明,请参见 集群内访问(ClusterIP)

  1. 进入容器服务操作界面,选择 集群 > 工作负载 > 无状态工作负载,创建负载。

  2. 选择新创建好的工作负载,在 访问方式 页签中。选择 服务,单击 创建服务
    alt

  3. 进入服务配置页面,配置服务的基本信息。
    alt

    配置项配置说明
    名称配置服务的名称。
    命名空间配置服务的命名空间。本示例默认与 Deployment 所属命名空间相同。
    标签单击 添加标签 图标,配置服务的标签。标签能够为服务定义不同的属性,方便批量筛选等需求。
    注解对应 Kubernetes 中的 Annotation。单击 添加注解,为服务添加注解并配置键值对。
  4. 配置访问类型,本例中选择 集群内访问(ClusterIP)

  5. 配置 端口映射。分别配置 Service 的端口、容器的端口和协议。
    alt

    配置项配置说明
    名称配置服务端口到容器端口映射的名称。
    服务端口配置 Service 对外提供服务的端口。同一种协议的服务端口不允许重复。
    协议根据业务的协议类型,选择端口协议。当前支持 TCP 协议和 UDP 协议。
    容器端口配置容器的端口,该端口为工作负载对外提供服务的端口。例如 nginx 默认使用 80 端口。
  6. 配置标签选择器。Service 使用标签进行流量转发。

  7. (可选)配置会话保持,配置超时时间,超时后依配置项处理。

  8. 单击 确定,完成配置。

检查结果

登录集群中的其他节点,使用集群 IP + 服务端口号的访问暴露的工作负载,发现访问成功(本例以 nginx 为例)。
alt

配置节点端口访问(NodePort)

配置前检查

  • 创建完成集群、节点,保证集群、节点工作正常。详细操作,请参见 创建集群
  • 将应用镜像上传至镜像仓库。详细操作,请参见 推送和拉取镜像

配置步骤

以无状态负载(Deployment)为例。详细的操作步骤和参数说明,请参见 节点端口访问(NodePort)

  1. 进入容器服务操作界面,选择 集群 > 工作负载 > 无状态工作负载,创建负载。

  2. 选择新创建好的工作负载,在 访问方式 页签中。选择 服务,单击 创建服务

  3. 进入服务配置页面,配置服务的基本信息。

    配置项配置说明
    名称配置服务的名称。
    命名空间配置服务的命名空间。本示例默认与 Deployment 所属命名空间相同。
    标签单击 添加标签 图标,配置服务的标签。标签能够为服务定义不同的属性,方便批量筛选等需求。
    注解对应 Kubernetes 中的 Annotation。单击 添加注解,为服务添加注解并配置键值对。
  4. 配置访问类型,本例中选择 节点端口访问(NodePort)

  5. 配置端口映射。分别配置节点的端口、Service 的端口、容器的端口和协议。
    alt

    配置项配置说明
    名称配置服务端口到容器端口映射的名称。
    服务端口配置 Service 对外提供服务的端口。同一种协议的服务端口不允许重复。
    协议根据业务的协议类型,选择端口协议。当前支持 TCP 协议和 UDP 协议。
    节点端口即 NodePort,可以填写具体的端口,也可以不填写。不填写具体值时系统自动分配端口。
    容器端口配置容器的端口,该端口为工作负载对外提供服务的端口。例如 nginx 默认使用 80 端口。
  6. 配置标签选择器。通过标签与工作负载相关联。

  7. (可选)配置会话保持,配置超时时间,超时后依配置项处理。

  8. 单击 确定,完成配置。

检查结果

登录集群中的其他节点,使用节点 IP+节点端口号的访问暴露的工作负载,发现访问成功(本例以 nginx 为例)。
alt

配置均衡负载(LoadBalancer)

配置前检查

  • 创建完成集群、节点,保证集群、节点工作正常。详细操作,请参见 创建集群
  • 将应用镜像上传至镜像仓库。详细操作,请参见 推送和拉取镜像

配置步骤

以无状态负载(Deployment)为例。详细的操作步骤和参数说明,请参见 负载均衡(LoadBalancer)

  1. 进入容器服务操作界面,选择 集群 > 工作负载 > 无状态工作负载,创建负载。

  2. 选择新创建好的工作负载,在 访问方式 页签中。选择 服务,单击 创建服务

  3. 进入服务配置页面,配置服务的基本信息。

    配置项配置说明
    名称配置服务的名称。
    命名空间配置服务的命名空间。本示例默认与 Deployment 所属命名空间相同。
    标签单击 添加标签 图标,配置服务的标签。标签能够为服务定义不同的属性,方便批量筛选等需求。
    注解对应 Kubernetes 中的 Annotation。单击 添加注解,为服务添加注解并配置键值对。
  4. 配置访问类型,本例中选择 负载均衡(LoadBalancer)

  5. (可选)配置直通 Pod 模式。该模式是指 CLB 和 Pod 直接连接,不经过 Kube-proxy 的处理,能够利用 CLB 的健康检查等高级能力(仅 VPC-CNI 网络支持该配置项)。

  6. 配置 负载均衡器。在下拉菜单中选择 私网访问自动创建。子网、实例规格按实际需求选择。
    alt

  7. 配置监听器调度算法,支持 加权轮询(WRR)加权最小连接数(WLC)源地址哈希(SH)

    算法说明
    加权轮询(WRR)基于权重值进行流量的分发,权重值越高的后端服务器,被轮询到的次数(概率)越高。
    加权最小连接数(WLC)优先将流量分发给当前连接数与权重比值最小的后端。
    源地址哈希(SH)基于源 IP 地址的一致性哈希,相同源地址的请求会调度到相同的后端服务器。
  8. (可选)按需选择是否启用健康检查。本示例不设置健康检查。

  9. 配置端口映射。

    配置项配置说明
    名称配置端口映射的名称。
    服务端口配置 Service 对外提供服务的端口,同一种协议的服务端口不允许重复。
    协议根据业务的协议类型,选择端口协议。当前支持 TCP 协议和 UDP 协议
    容器端口配置容器的端口,该端口为工作负载对外提供服务的端口。例如 Nginx 的端口为 80 端口。
  10. 配置标签选择器。通过标签与工作负载相关联。

  11. (可选)配置会话保持,配置超时时间,超时后依配置项处理。

  12. 单击 确定,完成配置。

检查结果

登录集群中的其他节点,使用LoadBalancer 外部端点 IP + 端口号的访问暴露的工作负载。
alt
访问成功后如下所示(本例以 nginx 为例)。
alt