Service
This commit is contained in:
@ -236,7 +236,8 @@ module.exports = {
|
||||
title: '服务发现、负载均衡、网络',
|
||||
collapsable: false,
|
||||
children: [
|
||||
// 'k8s-intermediate/service/service',
|
||||
'k8s-intermediate/service/service',
|
||||
'k8s-intermediate/service/service-details',
|
||||
// 'k8s-intermediate/service/dns',
|
||||
// 'k8s-intermediate/service/connecting',
|
||||
'k8s-intermediate/service/ingress',
|
||||
|
||||
Binary file not shown.
@ -41,7 +41,8 @@ description: Kubernetes 免费中文教程
|
||||
* [控制器 - Job](/learning/k8s-intermediate/workload/wl-job/) <Badge text="正在撰写" type="warn"/>
|
||||
* [控制器 - CronJob](/learning/k8s-intermediate/workload/wl-cronjob/) <Badge text="正在撰写" type="warn"/>
|
||||
* 服务发现、负载均衡、网络
|
||||
* [Service](/learning/k8s-intermediate/service/service.html) <Badge text="正在撰写" type="warn"/>
|
||||
* [Service 概述](/learning/k8s-intermediate/service/service.html)
|
||||
* [Service 详细描述](/learning/k8s-intermediate/service/service-details.html)
|
||||
* [Service/Pod 的 DNS](/learning/k8s-intermediate/service/dns.html) <Badge text="正在撰写" type="warn"/>
|
||||
* [Service 连接应用程序](/learning/k8s-intermediate/service/connecting.html) <Badge text="正在撰写" type="warn"/>
|
||||
* [Ingress 通过互联网访问您的应用](/learning/k8s-intermediate/service/ingress.html)
|
||||
|
||||
111
learning/k8s-intermediate/service/service-details.md
Normal file
111
learning/k8s-intermediate/service/service-details.md
Normal file
@ -0,0 +1,111 @@
|
||||
---
|
||||
layout: LearningLayout
|
||||
description: 本文介绍了 Kubernetes 中服务发现的机制,以及如何使用服务发现
|
||||
---
|
||||
|
||||
# Service 详细描述
|
||||
|
||||
参考文档:Kubernetes 官网文档:[Service](https://kubernetes.io/docs/concepts/services-networking/service/)
|
||||
|
||||
## 创建 Service
|
||||
|
||||
Kubernetes Servies 是一个 RESTFul 接口对象,可通过 yaml 文件创建。
|
||||
|
||||
例如,假设您有一组 Pod:
|
||||
* 每个 Pod 都监听 9376 TCP 端口
|
||||
* 每个 Pod 都有标签 app=MyApp
|
||||
|
||||
``` yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: my-service
|
||||
spec:
|
||||
selector:
|
||||
app: MyApp
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 80
|
||||
targetPort: 9376
|
||||
```
|
||||
|
||||
上述 YAML 文件可用来创建一个 Service:
|
||||
* 名字为 `my-service`
|
||||
* 目标端口未 TCP 9376
|
||||
* 选取所有包含标签 app=MyApp 的 Pod
|
||||
|
||||
关于 Service,您还需要了解:
|
||||
|
||||
* Kubernetes 将为该 Service 分配一个 IP 地址(ClusterIP 或 集群内 IP),供 Service Proxy 使用(参考[虚拟 IP 和 Service proxy](#虚拟-ip-和-service-proxy))
|
||||
* Kubernetes 将不断扫描符合该 selector 的 Pod,并将最新的结果更新到与 Service 同名 `my-service` 的 Endpoint 对象中。
|
||||
::: tip
|
||||
Service 从自己的 IP 地址和 `port` 端口接收请求,并将请求映射到符合条件的 Pod 的 `targetPort`。为了方便,默认 `targetPort` 的取值 与 `port` 字段相同
|
||||
:::
|
||||
* Pod 的定义中,Port 可能被赋予了一个名字,您可以在 Service 的 `targetPort` 字段引用这些名字,而不是直接写端口号。这种做法可以使得您在将来修改后端程序监听的端口号,而无需影响到前端程序。
|
||||
* Service 的默认传输协议是 TCP,您也可以使用其他 [支持的传输协议](#支持的传输协议)。
|
||||
* Kubernetes Service 中,可以定义多个端口,不同的端口可以使用相同或不同的传输协议。
|
||||
|
||||
## 创建 Service(无 label selector) <Badge text="Kuboard 暂不支持" type="warn"/>
|
||||
|
||||
Service 通常用于提供对 Kubernetes Pod 的访问,但是您也可以将其用于任何其他形式的后端。例如:
|
||||
|
||||
* 您想要在生产环境中使用一个 Kubernetes 外部的数据库集群,在测试环境中使用 Kubernetes 内部的 数据库
|
||||
* 您想要将 Service 指向另一个名称空间中的 Service,或者另一个 Kubernetes 集群中的 Service
|
||||
* 您正在将您的程序迁移到 Kubernetes,但是根据您的迁移路径,您只将一部分后端程序运行在 Kubernetes 中
|
||||
|
||||
在上述这些情况下,您可以定义一个没有 Pod Selector 的 Service。例如:
|
||||
|
||||
``` yaml
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: my-service
|
||||
spec:
|
||||
ports:
|
||||
- protocol: TCP
|
||||
port: 80
|
||||
targetPort: 9376
|
||||
```
|
||||
|
||||
因为该 Service 没有 selector,相应的 Endpoint 对象就无法自动创建。您可以手动创建一个 Endpoint 对象,以便将该 Service 映射到后端服务真实的 IP 地址和端口:
|
||||
|
||||
``` yaml
|
||||
apiVersion: v1
|
||||
kind: Endpoints
|
||||
metadata:
|
||||
name: my-service
|
||||
subsets:
|
||||
- addresses:
|
||||
- ip: 192.0.2.42
|
||||
ports:
|
||||
- port: 9376
|
||||
```
|
||||
|
||||
::: tip
|
||||
* Endpoint 中的 IP 地址不可以是 loopback(127.0.0.0/8 IPv4 或 ::1/128 IPv6),或 link-local(169.254.0.0/16 IPv4、224.0.0.0/24 IPv4 或 fe80::/64 IPv6)
|
||||
* Endpoint 中的 IP 地址不可以是集群中其他 Service 的 ClusterIP
|
||||
:::
|
||||
|
||||
对于 Service 的访问者来说,Service 是否有 label selector 都是一样的。在上述例子中,Service 将请求路由到 Endpoint 192.0.2.42:9376 (TCP)。
|
||||
|
||||
ExternalName Service 是一类特殊的没有 label selector 的 Service,该类 Service 使用 DNS 名字。参考 [ExternalName](#externalname)
|
||||
|
||||
|
||||
An ExternalName Service is a special case of Service that does not have selectors and uses DNS names instead. For more information, see the ExternalName section later in this document
|
||||
|
||||
## 虚拟 IP 和 Service proxy
|
||||
|
||||
正在撰写,最后更新时间:2019年9月17日 22:55
|
||||
|
||||
## 支持的传输协议
|
||||
|
||||
|
||||
## Service 类型
|
||||
|
||||
### ClusterIP
|
||||
|
||||
### NodePort
|
||||
|
||||
### LoadBalancer
|
||||
|
||||
### ExternalName
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 204 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 61 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 64 KiB |
@ -3,6 +3,55 @@ layout: LearningLayout
|
||||
description: 本文介绍了 Kubernetes 中服务发现的机制,以及如何使用服务发现
|
||||
---
|
||||
|
||||
# Service
|
||||
# Service 概述
|
||||
|
||||
正在撰写...
|
||||
参考文档:Kubernetes 官网文档:[Service](https://kubernetes.io/docs/concepts/services-networking/service/)
|
||||
|
||||
## 为何需要 Service
|
||||
|
||||
Kubernetes 中 Pod 是随时可以消亡的(节点故障、容器内应用程序错误等原因)。如果使用 [Deployment](learning/k8s-intermediate/workload/wl-deployment/) 运行您的应用程序,Deployment 将会在 Pod 消亡后再创建一个新的 Pod 以维持所需要的副本数。每一个 Pod 有自己的 IP 地址,然而,对于 Deployment 而言,对应 Pod 集合是动态变化的。
|
||||
|
||||
这个现象导致了如下问题:
|
||||
* 如果某些 Pod(假设是 'backends')为另外一些 Pod(假设是 'frontends')提供接口,在 'backends' 中的 Pod 集合不断变化(IP 地址也跟着变化)的情况下,'frontends' 中的 Pod 如何才能知道应该将请求发送到哪个 IP 地址?
|
||||
|
||||
Service 存在的意义,就是为了解决这个问题。
|
||||
|
||||
## Service
|
||||
|
||||
Kubernetes 中 Service 是一个 API 对象,通过 kubectl + YAML 或者 Kuboard,定义一个 Service,可以将符合 Service 指定条件的 Pod 作为可通过网络访问的服务提供给服务调用者。
|
||||
|
||||
Service 是 Kubernetes 中的一种服务发现机制:
|
||||
* Pod 有自己的 IP 地址
|
||||
* Service 被赋予一个唯一的 dns name
|
||||
* Service 通过 label selector 选定一组 Pod
|
||||
* Service 实现负载均衡,可将请求均衡分发到选定这一组 Pod 中
|
||||
|
||||
例如,假设有一个无状态的图像处理后端程序运行了 3 个 Pod 副本。这些副本是相互可替代的(前端程序调用其中任何一个都可以)。在后端程序的副本集中的 Pod 经常变化(销毁、重建、扩容、缩容等)的情况下,前端程序不应该关注这些变化。
|
||||
|
||||
Kubernetes 通过引入 Service 的概念,将前端与后端解耦。
|
||||
|
||||
## 在 Kuboard 中使用 Service
|
||||
|
||||
从 Kuboard 工作负载编辑器的视角来看,Service 与其他重要的 Kubernetes 对象之间的关系如下图所示:
|
||||
|
||||
<p>
|
||||
<img src="./service.assets/image-20190917210501081.png" style="max-width: 600px;"/>
|
||||
</p>
|
||||
|
||||
图中,Service 先连线到 Controller,Controller 在连线到容器组,这种表示方式只是概念上的,期望用户在使用 Kubernetes 的时候总是通过 Controller 创建 Pod,然后再通过 Service 暴露为网络服务,通过 Ingress 对集群外提供互联网访问。
|
||||
|
||||
事实上,Service 与 Controller 并没有直接联系,Service 通过 label selector 选择符合条件的 Pod,并将选中的 Pod 作为网络服务的提供者。从这个意义上来讲,您可以有很多中方式去定义 Service 的 label selector,然而,最佳的实践是,在 Service 中使用与 Controller 中相同的 label selector。如上图所示。
|
||||
|
||||
::: tip
|
||||
使用 Kubernetes 的最佳实践:
|
||||
* Service 与 Controller 同名
|
||||
* Service 与 Controller 使用相同的 label selector
|
||||
|
||||
在 Kuboard 中创建工作负载时,工作负载的名字(服务名称字段)将作为 Deployment(StatefulSet/DaemonSet)的名字,也将作为 Service、Ingress 的名字
|
||||
:::
|
||||
|
||||
在 Kuboard 工作负载编辑器中,Service 如下图所示:
|
||||
|
||||

|
||||
...
|
||||

|
||||
|
||||
@ -133,7 +133,8 @@ Kuboard 为 Kubernetes 初学者设计了如下学习路径:
|
||||
* [控制器 - Job](/learning/k8s-intermediate/workload/wl-job/) <Badge text="正在撰写" type="warn"/>
|
||||
* [控制器 - CronJob](/learning/k8s-intermediate/workload/wl-cronjob/) <Badge text="正在撰写" type="warn"/>
|
||||
* 服务发现、负载均衡、网络
|
||||
* [Service](/learning/k8s-intermediate/service/service.html) <Badge text="正在撰写" type="warn"/>
|
||||
* [Service 概述](/learning/k8s-intermediate/service/service.html)
|
||||
* [Service 详细描述](/learning/k8s-intermediate/service/service-details.html)
|
||||
* [Service/Pod 的 DNS](/learning/k8s-intermediate/service/dns.html) <Badge text="正在撰写" type="warn"/>
|
||||
* [Service 连接应用程序](/learning/k8s-intermediate/service/connecting.html) <Badge text="正在撰写" type="warn"/>
|
||||
* [Ingress 通过互联网访问您的应用](/learning/k8s-intermediate/service/ingress.html)
|
||||
|
||||
Reference in New Issue
Block a user