Kubernetes Service 支持的不同访问方式。
Kubernetes 中可以通过不同方式发布 Service,通过 ServiceType
字段指定,该字段的默认值是 ClusterIP
,可选值有
ClusterIP: 默认值。通过集群内部的一个 IP 地址暴露 Service,只在集群内部可以访问
NodePort: 通过每一个节点上的的静态端口(NodePort)暴露 Service,同时自动创建 ClusterIP 类型的访问方式
LoadBalancer: 通过云服务供应商(AWS、Azure、GCE 等)的负载均衡器在集群外部暴露 Service,同时自动创建 NodePort 和 ClusterIP 类型的访问方式
ExternalName
是一种特定类型的服务(Service),允许你为Kubernetes集群之外的外部服务创建别名(CNAME)。通常情况下,它用于将Kubernetes Service映射到一个域名(DNS名称),从而可以使用更友好、易读的名称与外部服务进行通信。
ExternalName
服务类型主要用于当你需要连接到位于Kubernetes集群之外的外部服务,而该外部服务没有直接可访问的IP地址或端口时。通过使用ExternalName
服务,你可以创建一个虚拟的DNS条目,将其指向外部服务的地址。
如使用 ExternalName 类型的 Service,CoreDNS 版本不能低于 1.7
ClusterIP 是 ServiceType 的默认值。
对于 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 地址上。
例如,
--nodeport-address=127.0.0.0/8
,则 kube-proxy 只将阶段端口绑定到 loopback 地址上。--nodeport-address
的默认值是一个空列表。则 kube-proxy 将节点端口绑定到该节点所有的网络 IP 地址上。您可以通过 nodePort
字段指定节点端口号(必须在 --service-node-port-range
指定的范围内)。Kubernetes 在创建 Service 时将使用该节点端口,如果该端口已被占用,则创建 Service 将不能成功。在这种情况下,您必须自己规划好端口使用,以避免端口冲突。
使用 NodePort,您可以:
NodePort 类型的 Service 可通过如下方式访问:
在支持外部负载均衡器的云环境中(例如 GCE、AWS、Azure 等),将 .spec.type
字段设置为 LoadBalancer
,Kubernetes 将为该Service 自动创建一个负载均衡器。负载均衡器的创建操作异步完成,您可能要稍等片刻才能真正完成创建,负载均衡器的信息将被回写到 Service 的 .status.loadBalancer
字段。如下所示:
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 类型的 Service 映射到一个外部的 DNS name,而不是一个 pod label selector。可通过 spec.externalName
字段指定外部 DNS name。
下面的例子中,名称空间 prod
中的 Service my-service
将映射到 my.database.example.com
:
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
对应的数据库迁移到集群内部来,您可以按如下步骤进行:
ps:
- ExternalName 可接受一个ipv4地址型的字符串作为
.spec.externalName
的值,但是这个字符串将被认为是一个由数字组成的 DNS name,而不是一个 IP 地址。- 如果要 hardcode 一个 IP 地址,请考虑使用 headless Service
如果有外部 IP 路由到 Kubernetes 集群的一个或多个节点,Kubernetes Service 可以通过这些 externalIPs
进行访问。externalIP
需要由集群管理员在 Kubernetes 之外配置。
在 Service 的定义中, externalIPs
可以和任何类型的 .spec.type
一通使用。在下面的例子中,客户端可通过 80.11.12.10:80
(externalIP:port) 访问my-service
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