k8s服务发现之第三弹发布Service

2024-09-06 19:25:30 浏览数 (2)

Kubernetes Service 支持的不同访问方式。

Service 类型

Kubernetes 中可以通过不同方式发布 Service,通过 ServiceType 字段指定,该字段的默认值是 ClusterIP,可选值有

  • ClusterIP: 默认值。通过集群内部的一个 IP 地址暴露 Service,只在集群内部可以访问
  • NodePort: 通过每一个节点上的的静态端口(NodePort)暴露 Service,同时自动创建 ClusterIP 类型的访问方式
    • 在集群内部通过 (Port) 访问
    • 在集群外部通过 (NodePort) 访问
  • LoadBalancer: 通过云服务供应商(AWS、Azure、GCE 等)的负载均衡器在集群外部暴露 Service,同时自动创建 NodePort 和 ClusterIP 类型的访问方式
    • 在集群内部通过 (Port) 访问
    • 在集群外部通过 (NodePort) 访问
    • 在集群外部通过 (Port) 访问
  • ExternalName 是一种特定类型的服务(Service),允许你为Kubernetes集群之外的外部服务创建别名(CNAME)。通常情况下,它用于将Kubernetes Service映射到一个域名(DNS名称),从而可以使用更友好、易读的名称与外部服务进行通信。

ExternalName服务类型主要用于当你需要连接到位于Kubernetes集群之外的外部服务,而该外部服务没有直接可访问的IP地址或端口时。通过使用ExternalName服务,你可以创建一个虚拟的DNS条目,将其指向外部服务的地址。

如使用 ExternalName 类型的 Service,CoreDNS 版本不能低于 1.7

ClusterIP

ClusterIP 是 ServiceType 的默认值。

NodePort

对于 NodePort 类型的 Service,Kubernetes 为其分配一个节点端口(对于同一 Service,在每个节点上的节点端口都相同),该端口的范围在初始化 apiserver 时可通过参数 --service-node-port-range 指定(默认是:30000-32767)。节点将该端口上的网络请求转发到对应的 Service 上。可通过 Service 的 .spec.ports[*].nodePort 字段查看该 Service 分配到的节点端口号。

在启动 kube-proxy 时使用参数 --nodeport-address 可指定阶段端口可以绑定的 IP 地址段。该参数接收以逗号分隔的 CIDR 作为参数值(例如:10.0.0.0/8,192.0.2.0/25),kube-proxy 将查找本机符合该 CIDR 的 IP 地址,并将节点端口绑定到符合的 IP 地址上。

例如,

  • 如果启动 kube-proxy 时指定了参数 --nodeport-address=127.0.0.0/8,则 kube-proxy 只将阶段端口绑定到 loopback 地址上。
  • --nodeport-address 的默认值是一个空列表。则 kube-proxy 将节点端口绑定到该节点所有的网络 IP 地址上。

您可以通过 nodePort 字段指定节点端口号(必须在 --service-node-port-range 指定的范围内)。Kubernetes 在创建 Service 时将使用该节点端口,如果该端口已被占用,则创建 Service 将不能成功。在这种情况下,您必须自己规划好端口使用,以避免端口冲突。

使用 NodePort,您可以:

  • 根据自己的需要配置负载均衡器
  • 配置 Kubernetes / 非 Kubernetes 的混合环境
  • 直接暴露一到多个节点的 IP 地址,以便客户端可访问 Kubernetes 中的 Service

NodePort 类型的 Service 可通过如下方式访问:

  • 在集群内部通过 (Port) 访问
  • 在集群外部通过 (NodePort) 访问

LoadBalancer

在支持外部负载均衡器的云环境中(例如 GCE、AWS、Azure 等),将 .spec.type 字段设置为 LoadBalancer,Kubernetes 将为该Service 自动创建一个负载均衡器。负载均衡器的创建操作异步完成,您可能要稍等片刻才能真正完成创建,负载均衡器的信息将被回写到 Service 的 .status.loadBalancer 字段。如下所示:

代码语言:javascript复制
 apiVersion: v1
 kind: Service
 metadata:
  name: my-service
 spec:
  selector:
    app: MyApp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376
  clusterIP: 10.0.171.239
  loadBalancerIP: 78.11.24.19
  type: LoadBalancer
 status:
  loadBalancer:
    ingress:
      - ip: 146.148.47.155

发生到外部负载均衡器的网络请求就像被转发到 Kubernetes 中的后端 Pod 上。负载均衡的实现细节由各云服务上确定。

由于 Kuboard 不限定 Kubernetes 是运行在裸机上、私有云上或者是公有云上,因此 Kuboard 暂不支持 LoadBalancer 类型的 Service。关于更多 LoadBalancer Service 相关的描述,请参考 Type LoadBalancer和您所使用的云供应商的文档

ExternalName

ExternalName 类型的 Service 映射到一个外部的 DNS name,而不是一个 pod label selector。可通过 spec.externalName 字段指定外部 DNS name。

下面的例子中,名称空间 prod 中的 Service my-service 将映射到 my.database.example.com

代码语言:javascript复制
 apiVersion: v1
 kind: Service
 metadata:
  name: my-service
  namespace: prod
 spec:
  type: ExternalName
  externalName: my.database.example.com

执行 nslookup my-service.prod.svc.cluster.local 指令时,集群的 DNS 服务将返回一个 CNAME 记录,其对应的值为 my.database.example.com。访问 my-service 与访问其他类型的 Service 相比,网络请求的转发发生在 DNS level,而不是使用 proxy。如果您在后续想要将 my.database.example.com 对应的数据库迁移到集群内部来,您可以按如下步骤进行:

  1. 在 Kubernetes 中部署数据库(并启动数据库的 Pod)
  2. 为 Service 添加合适的 selector 和 endpoint
  3. 修改 Service 的类型

ps:

  • ExternalName 可接受一个ipv4地址型的字符串作为.spec.externalName的值,但是这个字符串将被认为是一个由数字组成的 DNS name,而不是一个 IP 地址。
  • 如果要 hardcode 一个 IP 地址,请考虑使用 headless Service

External IP

如果有外部 IP 路由到 Kubernetes 集群的一个或多个节点,Kubernetes Service 可以通过这些 externalIPs 进行访问。externalIP 需要由集群管理员在 Kubernetes 之外配置。

在 Service 的定义中, externalIPs 可以和任何类型的 .spec.type 一通使用。在下面的例子中,客户端可通过 80.11.12.10:80 (externalIP:port) 访问my-service

代码语言:javascript复制
 apiVersion: v1
 kind: Service
 metadata:
  name: my-service
 spec:
  selector:
    app: MyApp
  ports:
    - name: http
      protocol: TCP
      port: 80
      targetPort: 9376
  externalIPs:
    - 80.11.12.10

0 人点赞