Service 的作用
在 如何在 Kubernetes 部署应用 中,我们讲到了如何部署应用程序,但还有几个问题没有解决:
- 服务发现:由于 Kubernetes 的调度机制,在 Kubernetes 中,Pod 的 IP 不是固定的。如果其它程序需要访问这个 Pod,要怎么知道这个 Pod 的 IP 呢?
- 负载均衡:由于 Deployment 管理着多个 Pod 的副本,如果其它程序需要访问这些 Pod,显然需要一个 proxy 为这些 Pod 做负载均衡。
- 外部路由:如果应用程序运行在 Kubernetes 外部,如何访问 Kubernetes 内部的 Pod 呢?
Kubernetes 提供了 Service 功能,用来解决这些问题。
服务发现与负载均衡
Service 通常会和 Deployment 结合在一起使用,首先通过 Deployment 部署应用程序,然后再使用 Service 为应用程序提供服务发现、负载均衡和外部路由的功能。
首先,让我们创建一个 Deployment:
接着,为这个 Deployment 创建一个 Service:
这里我们创建了一个名为nginx-service
的 Service,它监听的端口是 5000,同时它会把全部的流量都转发给它代理的所有 Pod(这些 Pod 都必须拥有app: nginx-server
这个标签)。
Service 提供了两种服务发现的方式,第一种是环境变量,第二种是 DNS。先说第一种,上面我们创建了nginx-service
这个 Service,接着如果我们再创建另外一个 Pod,那么在这个 Pod 中,可以通过环境变量知道nginx-service
的地址。
首先,创建一个新的 Pod(这个 Pod 已经安装好了curl
工具):
接着,进入这个 Pod,可以查看它的环境变量。可以看到,当 Kubernetes 创建这个 Pod 时,会自动注入这些环境变量:
因此,在curl
这个 Pod 中,可以通过访问这些环境变量,从而访问nginx-service
。
另一种服务发现的方式是 DNS 解析。例如,我们进入 curl Pod 里面,可以通过 DNS 解析,访问nginx-service
:
由于nginx-service
的 namespace 是default
,因此它的 DNS 域名是nginx-service.default
。
再说说负载均衡,我们上面创建了nginx-service
,这个 Service 会自动将接收到的流量转发给它代理的两个 Nginx Pod。
外部路由
默认情况下,Service 的类型是 ClusterIP,因此当我们创建了一个 Service 之后,这个 Service 不能被外部访问。
可以看到,nginx-service
的 IP 是10.43.169.158
,这个 IP 只能从 Kubernetes 内部才能访问。当然,除了 ClusterIP 之外,Service 还可以是其它类型:NodePort、LoadBalancer 和 ExternalName。
这里说下 NodePort 类型的 Service。Kubernetes 会为 Service 分配一个端口,并且在所以节点都打开这个端口,因此我们可以通过任意一个节点,访问到这个 Service。
例如,这里我们修改nginx-service
的类型为 NodePort:
可以看到分配的端口号为 31623:
这时候,通过集群的任何一个节点的 31623 端口,都可以访问到nginx-service
。例如,假设集群有一个节点的 IP 是172.16.1.116
,那么通过它的 31623 端口访问nginx-service
: