Kubernetes 中的 Service 是将运行在一个或一组 Pod 上的网络应用程序公开为网络服务的方法,用来解决上述 Pod 访问问题。Service 拥有一个固定 IP 地址,不仅可以通过访问 Service 来访问工作负载,而且可以通过 Service 的 Label 选择 Pod,并将用户的访问流量转发给 Pod。更多详细介绍参见:Kubernetes 官网文档。
工作负载创建完成后,其在多个 Pod 中运行,而 Pod 由于具备弹性伸缩属性,因此访问 Pod 会面临如下几个问题:
Service 包含多种类型,适应于不同的场景。包括:集群内访问(ClusterIP)、节点端口访问(NodePort)。
集群内访问(ClusterIP):集群内访问(ClusterIP)是指将工作负载暴露给同一集群内其他工作负载访问的方式,可以通过 集群内部域名 访问。例如:创建一个名为 nginx 的 Service,端口号为 80,则集群内部访问时,直接通过 nginx:80 就可以访问到 Service,进而访问后台 Pod。
在微服务相关场景,如果不需要负载均衡以及 Service IP,需要直通 Pod 的时候,可以配置 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 进行负载均衡的场景。 |
|
节点端口访问(NodePort):节点端口访问(NodePort)是指在每个节点的 IP 上开放一个静态端口,通过静态端口对外暴露服务。其他应用通过请求Node_IP:Node_Port
,即可访问服务。节点的 IP 地址可以分配私网地址,也可以分配公网地址。因此,通过节点访问方式,可以对内或对外暴露服务。
配置项 | 说明 |
---|---|
名称 | 自定义服务名称,同一个命名空间下,名称必须唯一。 |
命名空间 | 选择服务所属的命名空间。建议选择您自定义的命名空间,或系统默认创建的 default 命名空间。 |
标签 | 单击 添加标签 图标,配置服务的标签。标签能够为服务定义不同的属性,方便批量筛选等需求。 |
注解 | 对应 Kubernetes 中的 Annotation。单击 添加注解,为服务添加注解并配置键值对。 |
访问类型 | 按需选择提供服务的访问类型,包括:集群内访问(ClusterIP)、节点端口访问(NodePort)。 |
设置为 Headless Service | 访问类型为集群内访问(ClusterIP)时需要配置,默认不勾选。 |
端口映射 | 配置端口映射规则:
|
标签选择器 | Service 通过标签选择器与后端容器组绑定:
|
会话保持 | 默认不配置。启用后 Service 将来自同一个 IP 地址的访问请求转发到同一台后端服务器上。 说明
|
服务创建完成后,将返回资源管理页面。单击资源列表顶部操作按钮或右侧操作列...
中的操作按钮,可执行对应管理操作。详细说明如下:
操作 | 说明 |
---|---|
使用 Yaml 创建 | 使用 Yaml 创建资源,推荐直接粘贴已经根据业务需求配置的 Yaml 内容。相较于使用控制台创建资源,使用 Yaml 方式支持的参数更全面。 |
更新 | 通过控制台方式更新 Service 配置。 |
编辑 Yaml | 编辑已经创建 Service 的文件,更新配置信息。 |
导出 | 导出当前 Service 的 Yaml 文件。 |
删除 | 删除目标 Service 。 |
创建服务的 Yaml 测试示例如下,具体参数和配置以实际使用场景中各云厂商的定义为准。
apiVersion: v1 kind: Service metadata: name: my-svc # adjust name for your service namespace: default # specify your namespace to apply service spec: selector: app: nginx # change label selector to match your backend pod ports: - protocol: TCP name: http port: 30080 # choose an unique port on each node to avoid port conflict targetPort: 80 type: NodePort