pull/450/head
Jimmy Song 2021-07-08 19:08:34 +08:00
parent 3989521766
commit d38ff91d9b
No known key found for this signature in database
GPG Key ID: CBA666E6EF8B2C3A
4 changed files with 131 additions and 134 deletions

View File

@ -94,6 +94,6 @@ Kubernetes Handbook 开源于 2017 年 3 月并在其后不断完善,是第一
</a> </a>
</p> </p>
云原生社区是一个中立的云原生终端用户社区,始与作者于 2016 年成立的 Kubernetes & CloudNative 实战群,覆盖了上千名早期云原生拥护者。在此基础上于 2020 年 5 月,由 CNCF 大使、开源领域意见领袖共同发起将原社群升级为云原生社区,旨在推广云原生技术,构建开发者生态 云原生社区是一个中立的云原生终端用户社区,始与作者于 2016 年成立的 Kubernetes & CloudNative 实战群,覆盖了上千名早期云原生拥护者。在此基础上于 2020 年 5 月,由 CNCF 大使、开源领域意见领袖共同发起将原社群升级为云原生社区,目标成为中国最具影响力的云原生开源社区
官方网站 <https://cloudnative.to>,关注云原生社区微信公众号,[申请加入社区](https://mp.weixin.qq.com/s/vWlSdzz2MNdXRr0sd2-LFg)。 官方网站 <https://cloudnative.to>,关注云原生社区微信公众号,[申请加入社区](https://mp.weixin.qq.com/s/vWlSdzz2MNdXRr0sd2-LFg)。

View File

@ -1,51 +1,52 @@
# Ingress解析 # Ingress 解析
Ingress 是从Kubernetes集群外部访问集群内部服务的入口这篇文章部分译自Kubernetes官方文档[Ingress Resource](https://kubernetes.io/docs/concepts/services-networking/ingress/),后面的章节会讲到使用[Traefik](https://github.com/containous/traefik)来做Ingress controller文章末尾给出了几个相关链接。 Ingress 是从 Kubernetes 集群外部访问集群内部服务的入口,这篇文章部分译自 Kubernetes 官方文档 [Ingress Resource](https://kubernetes.io/docs/concepts/services-networking/ingress/),后面的章节会讲到使用 [Traefik](https://github.com/containous/traefik) 来做 Ingress controller文章末尾给出了几个相关链接。
**术语** **术语 **
在本篇文章中你将会看到一些在其他地方被交叉使用的术语,为了防止产生歧义,我们首先来澄清下。 在本篇文章中你将会看到一些在其他地方被交叉使用的术语,为了防止产生歧义,我们首先来澄清下。
- 节点Kubernetes集群中的一台物理机或者虚拟机。 - 节点Kubernetes 集群中的一台物理机或者虚拟机。
- 集群位于Internet防火墙后的节点这是kubernetes管理的主要计算资源。 - 集群:位于 Internet 防火墙后的节点,这是 kubernetes 管理的主要计算资源。
- 边界路由器:为集群强制执行防火墙策略的路由器。 这可能是由云提供商或物理硬件管理的网关。 - 边界路由器:为集群强制执行防火墙策略的路由器。 这可能是由云提供商或物理硬件管理的网关。
- 集群网络一组逻辑或物理链接可根据Kubernetes[网络模型](https://kubernetes.io/docs/admin/networking/)实现群集内的通信。 集群网络的实现包括Overlay模型的 [flannel](https://github.com/coreos/flannel#flannel) 和基于SDN的OVS。 - 集群网络:一组逻辑或物理链接,可根据 Kubernetes [网络模型](https://kubernetes.io/docs/admin/networking/) 实现群集内的通信。 集群网络的实现包括 Overlay 模型的 [flannel](https://github.com/coreos/flannel#flannel) 和基于 SDN OVS。
- 服务使用标签选择器标识一组pod成为的Kubernetes[服务](https://kubernetes.io/docs/user-guide/services/)。 除非另有说明否则服务假定在集群网络内仅可通过虚拟IP访问。 - 服务:使用标签选择器标识一组 pod 成为的 Kubernetes [服务](https://kubernetes.io/docs/user-guide/services/)。 除非另有说明,否则服务假定在集群网络内仅可通过虚拟 IP 访问。
## 什么是Ingress ## 什么是 Ingress
通常情况下service和pod仅可在集群内部网络中通过IP地址访问。所有到达边界路由器的流量或被丢弃或被转发到其他地方。从概念上讲可能像下面这样 通常情况下service pod 仅可在集群内部网络中通过 IP 地址访问。所有到达边界路由器的流量或被丢弃或被转发到其他地方。从概念上讲,可能像下面这样:
``` ```
internet internet
| |
------------ ------------
[ Services ] [Services]
``` ```
Ingress是授权入站连接到达集群服务的规则集合。 Ingress 是授权入站连接到达集群服务的规则集合。
``` ```
internet internet
| |
[ Ingress ] [Ingress]
--|-----|-- --|-----|--
[ Services ] [Services]
``` ```
你可以给Ingress配置提供外部可访问的URL、负载均衡、SSL、基于名称的虚拟主机等。用户通过POST Ingress资源到API server的方式来请求ingress。 [Ingress controller](https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-controllers)负责实现Ingress通常使用负载平衡器它还可以配置边界路由和其他前端这有助于以HA方式处理流量。 你可以给 Ingress 配置提供外部可访问的 URL、负载均衡、SSL、基于名称的虚拟主机等。用户通过 POST Ingress 资源到 API server 的方式来请求 ingress。 [Ingress controller](https://kubernetes.io/docs/concepts/services-networking/ingress/#ingress-controllers) 负责实现 Ingress通常使用负载均衡器它还可以配置边界路由和其他前端这有助于以高可用的方式处理流量。
## 先决条件 ## 先决条件
在使用Ingress resource之前有必要先了解下面几件事情。Ingress是beta版本的resource在kubernetes1.1之前还没有。你需要一个`Ingress Controller`来实现`Ingress`,单纯的创建一个`Ingress`没有任何意义 在使用 Ingress 资源之前,有必要先了解下面几件事情
GCE/GKE会在master节点上部署一个ingress controller。你可以在一个pod中部署任意个自定义的ingress controller。你必须正确地annotate每个ingress比如 [运行多个ingress controller](https://git.k8s.io/ingress#running-multiple-ingress-controllers) 和 关闭glbc。 - Ingress 资源对象在 Kubernetes 1.1 之前还没有。
- 你需要一个 `Ingress Controller` 来实现 `Ingress`,单纯的创建一个 `Ingress` 没有任何意义。
- GCE/GKE 会在 master 节点上部署一个 ingress controller。你可以在一个 pod 中部署任意个自定义的 ingress controller。你必须正确地注解每个 ingress比如运行多个 ingress controller 和关闭 glbc。
- 在非 GCE/GKE 的环境中,你需要在 pod 中 部署一个 controller例如 [Nginx Ingress Controller](https://github.com/kubernetes/ingress-nginx/blob/master/README.md)。
确定你已经阅读了Ingress controller的 beta版本限制。在非GCE/GKE的环境中你需要在pod中[部署一个controller](https://git.k8s.io/ingress-nginx/README.md)。 ## Ingress 资源
## Ingress Resource 最简化的 Ingress 配置如下。
最简化的Ingress配置
```yaml ```yaml
1: apiVersion: extensions/v1beta1 1: apiVersion: extensions/v1beta1
@ -62,42 +63,43 @@ GCE/GKE会在master节点上部署一个ingress controller。你可以在一个p
12: servicePort: 80 12: servicePort: 80
``` ```
*如果你没有配置Ingress controller就将其POST到API server不会有任何用处* 如果你没有配置 Ingress controller 就将其 POST 到 API server 不会有任何用处。
**配置说明** **配置说明**
**1-4行**跟Kubernetes的其他配置一样ingress的配置也需要`apiVersion``kind`和`metadata`字段。配置文件的详细说明请查看[部署应用](https://kubernetes.io/docs/user-guide/deploying-applications), [配置容器](https://kubernetes.io/docs/user-guide/configuring-containers)和使用resources **1-4 **:跟 Kubernetes 的其他配置一样ingress 的配置也需要 `apiVersion``kind` `metadata` 字段。配置文件的详细说明请查看 [部署应用](https://kubernetes.io/docs/user-guide/deploying-applications)[配置容器](https://kubernetes.io/docs/user-guide/configuring-containers) 和使用资源
**5-7行**: Ingress spec 中包含配置一个loadbalancer或proxy server的所有信息。最重要的是它包含了一个匹配所有入站请求的规则列表。目前ingress只支持http规则。 **5-7 **: Ingress spec 中包含配置一个 loadbalancer proxy server 的所有信息。最重要的是,它包含了一个匹配所有入站请求的规则列表。目前 ingress 只支持 http 规则。
**8-9行**每条http规则包含以下信息一个`host`配置项比如for.bar.com在这个例子中默认是*`path`列表(比如:/testpath每个path都关联一个`backend`(比如test:80)。在loadbalancer将流量转发到backend之前所有的入站请求都要先匹配host和path。 **8-9 **:每条 http 规则包含以下信息:一个 `host` 配置项(比如 for.bar.com在这个例子中默认是 *`path` 列表(比如:/testpath每个 path 都关联一个 `backend`(比如 test:80)。在 loadbalancer 将流量转发到 backend 之前,所有的入站请求都要先匹配 host path。
**10-12行**:正如 [services doc](https://kubernetes.io/docs/user-guide/services)中描述的那样backend是一个`service:port`的组合。Ingress的流量被转发到它所匹配的backend。 **10-12 **:正如 [services doc](https://kubernetes.io/docs/user-guide/services) 中描述的那样backend 是一个 `service:port` 的组合。Ingress 的流量被转发到它所匹配的 backend。
**全局参数**为了简单起见Ingress示例中没有全局参数请参阅资源完整定义的[api参考](https://releases.k8s.io/master/staging/src/k8s.io/api/extensions/v1beta1/types.go)。 在所有请求都不能跟spec中的path匹配的情况下请求被发送到Ingress controller的默认后端可以指定全局缺省backend。 **全局参数**为了简单起见Ingress 示例中没有全局参数,请参阅资源完整定义的 [API 参考](https://releases.k8s.io/master/staging/src/k8s.io/api/extensions/v1beta1/types.go)。 在所有请求都不能跟 spec 中的 path 匹配的情况下,请求被发送到 Ingress controller 的默认后端,可以指定全局缺省 backend。
## Ingress controllers ## Ingress controller
为了使Ingress正常工作集群中必须运行Ingress controller。 这与其他类型的控制器不同,其他类型的控制器通常作为`kube-controller-manager`二进制文件的一部分运行,在集群启动时自动启动。 你需要选择最适合自己集群的Ingress controller或者自己实现一个。 为了使 Ingress 正常工作,集群中必须运行 Ingress controller。 这与其他类型的控制器不同,其他类型的控制器通常作为 `kube-controller-manager` 二进制文件的一部分运行,在集群启动时自动启动。 你需要选择最适合自己集群的 Ingress controller 或者自己实现一个。
- kubernetes当前支持并维护[GCE](https://git.k8s.io/ingress-gce/README.md)和[nginx](https://git.k8s.io/ingress-nginx/README.md)两种controller. - Kubernetes 当前支持并维护 [GCE](https://github.com/kubernetes/ingress-gce/blob/master/README.md) 和 [nginx](https://github.com/kubernetes/ingress-nginx/blob/master/README.md) 两种 controller
- F5公司[支持并维护](https://support.f5.com/csp/article/K86859508) [F5 BIG-IP Controller for Kubernetes](http://clouddocs.f5.com/products/connectors/k8s-bigip-ctlr/latest). - F5公司[支持并维护](https://support.f5.com/csp/article/K86859508) [F5 BIG-IP Controller for Kubernetes](http://clouddocs.f5.com/products/connectors/k8s-bigip-ctlr/latest)
- [Kong](https://konghq.com/) 同时支持并维护[社区版](https://discuss.konghq.com/c/kubernetes)与[企业版](https://konghq.com/api-customer-success/)的 [Kong Ingress Controller for Kubernetes](https://konghq.com/blog/kubernetes-ingress-controller-for-kong/). - [Kong](https://konghq.com/) 同时支持并维护 [社区版](https://discuss.konghq.com/c/kubernetes) [企业版](https://konghq.com/api-customer-success/) 的 [Kong Ingress Controller for Kubernetes](https://konghq.com/blog/kubernetes-ingress-controller-for-kong/)
- [Traefik](https://github.com/containous/traefik) 是功能齐全的 ingress controller[Lets Encrypt](https://letsencrypt.org/), secrets, http2, websocket…, Containous 也对其提供商业支持。 - [Traefik](https://github.com/containous/traefik) 是功能齐全的 ingress controller[Lets Encrypt](https://letsencrypt.org/), secrets, http2, websocket…, Containous 也对其提供商业支持。
- [Istio](https://istio.io) 使用CRD Gateway来[控制Ingress流量](https://istio.io/docs/tasks/traffic-management/ingress/)。 - [Istio](https://istio.io) 使用 CRD Gateway [控制 Ingress 流量](https://istio.io/docs/tasks/traffic-management/ingress/)。
## 在你开始前 ## 在你开始前
以下文档描述了Ingress资源中公开的一组跨平台功能。 理想情况下所有的Ingress controller都应该符合这个规范但是我们还没有实现。 GCE和nginx控制器的文档分别在[这里](https://git.k8s.io/ingress-gce/README.md)和[这里](https://git.k8s.io/ingress-nginx/README.md)。如果您使用F5 BIG-IP controller, 请参看[这里](http://clouddocs.f5.com/containers/latest/kubernetes/kctlr-k8s-ingress-ctlr.html). 以下文档描述了 Ingress 资源中公开的一组跨平台功能。 理想情况下,所有的 Ingress controller 都应该符合这个规范,但是我们还没有实现。 GCE 和 Nginx 控制器的文档分别在 [这里](https://github.com/kubernetes/ingress-gce/blob/master/README.md) 和 [这里](https://github.com/kubernetes/ingress-nginx/blob/master/README.md)。如果您使用 F5 BIG-IP controller请参看 [这里](http://clouddocs.f5.com/containers/latest/kubernetes/kctlr-k8s-ingress-ctlr.html)。
**确保您查看控制器特定的文档,以便您了解每个文档的注意事项。** **确保您查看控制器特定的文档,以便您了解每个文档的注意事项。**
## Ingress类型 ## Ingress 类型
### 单Service Ingress ### 单 Service Ingress
Kubernetes中已经存在一些概念可以暴露单个service查看[替代方案](https://kubernetes.io/docs/concepts/services-networking/ingress/#alternatives)但是你仍然可以通过Ingress来实现通过指定一个没有rule的默认backend的方式。 Kubernetes 中已经存在一些概念可以暴露单个 service查看 [替代方案](https://kubernetes.io/docs/concepts/services-networking/ingress/#alternatives)),但是你仍然可以通过 Ingress 来实现,通过指定一个没有 rule 的默认 backend 的方式。
ingress.yaml定义文件 ingress.yaml 定义文件:
```yaml ```yaml
apiVersion: extensions/v1beta1 apiVersion: extensions/v1beta1
@ -110,7 +112,7 @@ spec:
servicePort: 80 servicePort: 80
``` ```
使用`kubectl create -f`命令创建然后查看ingress 使用`kubectl create -f`命令创建,然后查看 ingress
```bash ```bash
$ kubectl get ing $ kubectl get ing
@ -118,18 +120,18 @@ NAME RULE BACKEND ADDRESS
test-ingress - testsvc:80 107.178.254.228 test-ingress - testsvc:80 107.178.254.228
``` ```
`107.178.254.228`就是Ingress controller为了实现Ingress而分配的IP地址。`RULE`列表示所有发送给该IP的流量都被转发到了`BACKEND`所列的Kubernetes service上。 `107.178.254.228` 就是 Ingress controller 为了实现 Ingress 而分配的 IP 地址。`RULE` 列表示所有发送给该 IP 的流量都被转发到了 `BACKEND` 所列的 Kubernetes service 上。
### 简单展开 ### 简单展开
如前面描述的那样kubernetes pod中的IP只在集群网络内部可见我们需要在边界设置一个东西让它能够接收ingress的流量并将它们转发到正确的端点上。这个东西一般是高可用的loadbalancer。使用Ingress能够允许你将loadbalancer的个数降低到最少例如假如你想要创建这样的一个设置 如前面描述的那样kubernetes pod 中的 IP 只在集群网络内部可见,我们需要在边界设置一个东西,让它能够接收 ingress 的流量并将它们转发到正确的端点上。这个东西一般是高可用的 loadbalancer。使用 Ingress 能够允许你将 loadbalancer 的个数降低到最少,例如,假如你想要创建这样的一个设置:
``` ```
foo.bar.com -> 178.91.123.132 -> / foo s1:80 foo.bar.com -> 178.91.123.132 -> /foo s1:80
/ bar s2:80 /bar s2:80
``` ```
你需要一个这样的ingress 你需要一个这样的 ingress
```yaml ```yaml
apiVersion: extensions/v1beta1 apiVersion: extensions/v1beta1
@ -151,7 +153,7 @@ spec:
servicePort: 80 servicePort: 80
``` ```
使用`kubectl create -f`创建完ingress后 使用 `kubectl create -f` 创建完 ingress 后:
```bash ```bash
$ kubectl get ing $ kubectl get ing
@ -162,11 +164,11 @@ test -
/bar s2:80 /bar s2:80
``` ```
只要服务s1s2存在Ingress controller就会将提供一个满足该Ingress的特定loadbalancer实现。 这一步完成后您将在Ingress的最后一列看到loadbalancer的地址。 只要服务s1s2存在Ingress controller 就会将提供一个满足该 Ingress 的特定 loadbalancer 实现。 这一步完成后,您将在 Ingress 的最后一列看到 loadbalancer 的地址。
### 基于名称的虚拟主机 ### 基于名称的虚拟主机
Name-based的虚拟主机在同一个IP地址下拥有多个主机名。 Name-based 的虚拟主机在同一个 IP 地址下拥有多个主机名。
``` ```
foo.bar.com --| |-> foo.bar.com s1:80 foo.bar.com --| |-> foo.bar.com s1:80
@ -174,7 +176,7 @@ foo.bar.com --| |-> foo.bar.com s1:80
bar.foo.com --| |-> bar.foo.com s2:80 bar.foo.com --| |-> bar.foo.com s2:80
``` ```
下面这个ingress说明基于[Host header](https://tools.ietf.org/html/rfc7230#section-5.4)的后端loadbalancer的路由请求 下面这个 ingress 说明基于 [Host header](https://tools.ietf.org/html/rfc7230#section-5.4) 的后端 loadbalancer 的路由请求:
```yaml ```yaml
apiVersion: extensions/v1beta1 apiVersion: extensions/v1beta1
@ -197,11 +199,11 @@ spec:
servicePort: 80 servicePort: 80
``` ```
**默认backend**一个没有rule的ingress如前面章节中所示所有流量都将发送到一个默认backend。你可以用该技巧通知loadbalancer如何找到你网站的404页面通过制定一些列rule和一个默认backend的方式。如果请求header中的host不能跟ingress中的host匹配并且/或请求的URL不能与任何一个path匹配则流量将路由到你的默认backend。 **默认 backend**:一个没有 rule ingress如前面章节中所示所有流量都将发送到一个默认 backend。你可以用该技巧通知 loadbalancer 如何找到你网站的 404 页面,通过制定一些列 rule 和一个默认 backend 的方式。如果请求 header 中的 host 不能跟 ingress 中的 host 匹配,并且 / 或请求的 URL 不能与任何一个 path 匹配,则流量将路由到你的默认 backend。
### TLS ### TLS
你可以通过指定包含TLS私钥和证书的[secret](https://kubernetes.io/docs/user-guide/secrets)来加密Ingress。 目前Ingress仅支持单个TLS端口443并假定TLS termination。 如果Ingress中的TLS配置部分指定了不同的主机则它们将根据通过SNI TLS扩展指定的主机名假如Ingress controller支持SNI在多个相同端口上进行复用。 TLS secret中必须包含名为`tls.crt`和`tls.key`的密钥这里面包含了用于TLS的证书和私钥例如 你可以通过指定包含 TLS 私钥和证书的 [secret](https://kubernetes.io/docs/user-guide/secrets) 来加密 Ingress。 目前Ingress 仅支持单个 TLS 端口 443并假定 TLS termination。 如果 Ingress 中的 TLS 配置部分指定了不同的主机,则它们将根据通过 SNI TLS 扩展指定的主机名(假如 Ingress controller 支持 SNI在多个相同端口上进行复用。 TLS secret 中必须包含名为 `tls.crt` `tls.key` 的密钥,这里面包含了用于 TLS 的证书和私钥,例如:
```yaml ```yaml
apiVersion: v1 apiVersion: v1
@ -215,7 +217,7 @@ metadata:
type: Opaque type: Opaque
``` ```
在Ingress中引用这个secret将通知Ingress controller使用TLS加密从将客户端到loadbalancer的channel Ingress 中引用这个 secret 将通知 Ingress controller 使用 TLS 加密从将客户端到 loadbalancer channel
```yaml ```yaml
apiVersion: extensions/v1beta1 apiVersion: extensions/v1beta1
@ -230,15 +232,15 @@ spec:
servicePort: 80 servicePort: 80
``` ```
请注意各种Ingress controller支持的TLS功能之间存在差距。 请参阅有关[nginx](https://git.k8s.io/ingress-nginx/README.md#https)[GCE](https://git.k8s.io/ingress-gce/README.md#frontend-https)或任何其他平台特定Ingress controller的文档以了解TLS在你的环境中的工作原理。 请注意,各种 Ingress controller 支持的 TLS 功能之间存在差距。 请参阅有关 [nginx](https://git.k8s.io/ingress-nginx/README.md#https)[GCE](https://git.k8s.io/ingress-gce/README.md#frontend-https) 或任何其他平台特定 Ingress controller 的文档,以了解 TLS 在你的环境中的工作原理。
Ingress controller启动时附带一些适用于所有Ingress的负载平衡策略设置例如负载均衡算法后端权重方案等。更高级的负载平衡概念例如持久会话动态权重尚未在Ingress中公开。 你仍然可以通过service loadbalancer获取这些功能。 随着时间的推移我们计划将适用于跨平台的负载平衡模式加入到Ingress资源中。 Ingress controller 启动时附带一些适用于所有 Ingress 的负载平衡策略设置,例如负载均衡算法,后端权重方案等。更高级的负载平衡概念(例如持久会话,动态权重)尚未在 Ingress 中公开。 你仍然可以通过 service loadbalancer 获取这些功能。 随着时间的推移,我们计划将适用于跨平台的负载平衡模式加入到 Ingress 资源中。
还值得注意的是尽管健康检查不直接通过Ingress公开但Kubernetes中存在并行概念例如[准备探查](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/),可以使你达成相同的最终结果。 请查看特定控制器的文档,以了解他们如何处理健康检查([nginx](https://git.k8s.io/ingress-nginx/README.md)[GCE](https://git.k8s.io/ingress-gce/README.md#health-checks))。 还值得注意的是,尽管健康检查不直接通过 Ingress 公开,但 Kubernetes 中存在并行概念,例如 [准备探查](https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-probes/),可以使你达成相同的最终结果。 请查看特定控制器的文档,以了解他们如何处理健康检查([nginx](https://git.k8s.io/ingress-nginx/README.md)[GCE](https://git.k8s.io/ingress-gce/README.md#health-checks))。
## 更新Ingress ## 更新 Ingress
假如你想要向已有的ingress中增加一个新的Host你可以编辑和更新该ingress 假如你想要向已有的 ingress 中增加一个新的 Host你可以编辑和更新该 ingress
```bash ```bash
$ kubectl get ing $ kubectl get ing
@ -249,7 +251,7 @@ test - 178.91.123.132
$ kubectl edit ing test $ kubectl edit ing test
``` ```
这会弹出一个包含已有的yaml文件的编辑器修改它增加新的Host配置。 这会弹出一个包含已有的 yaml 文件的编辑器,修改它,增加新的 Host 配置。
```yaml ```yaml
spec: spec:
@ -271,7 +273,7 @@ spec:
.. ..
``` ```
保存它会更新API server中的资源这会触发ingress controller重新配置loadbalancer。 保存它会更新 API server 中的资源,这会触发 ingress controller 重新配置 loadbalancer。
```bash ```bash
$ kubectl get ing $ kubectl get ing
@ -283,32 +285,33 @@ test - 178.91.123.132
/foo s2:80 /foo s2:80
``` ```
在一个修改过的ingress yaml文件上调用`kubectl replace -f`命令一样可以达到同样的效果。 在一个修改过的 ingress yaml 文件上调用`kubectl replace -f` 命令一样可以达到同样的效果。
## 跨可用域故障 ## 跨可用域故障
在不同云供应商之间,跨故障域的流量传播技术有所不同。 有关详细信息请查看相关Ingress controller的文档。 有关在federation集群中部署Ingress的详细信息请参阅federation文档。 在不同云供应商之间,跨故障域的流量传播技术有所不同。 有关详细信息,请查看相关 Ingress controller 的文档。 有关在 federation 集群中部署 Ingress 的详细信息,请参阅 federation 文档。
## 未来计划 ## 未来计划
- 多样化的HTTPS/TLS模型支持如SNIre-encryption - 多样化的 HTTPS/TLS 模型支持(如 SNIre-encryption
- 通过声明来请求IP或者主机名 - 通过声明来请求 IP 或者主机名
- 结合L4和L7 Ingress - 结合 L4 L7 Ingress
- 更多的Ingress controller - 更多的 Ingress controller
请跟踪[L7和Ingress的proposal](https://github.com/kubernetes/kubernetes/pull/12827),了解有关资源演进的更多细节,以及[Ingress repository](https://github.com/kubernetes/ingress/tree/master)了解有关各种Ingress controller演进的更多详细信息。 请跟踪 [L7 Ingress proposal](https://github.com/kubernetes/kubernetes/pull/12827),了解有关资源演进的更多细节,以及 [Ingress repository](https://github.com/kubernetes/ingress/tree/master),了解有关各种 Ingress controller 演进的更多详细信息。
## 替代方案 ## 替代方案
你可以通过很多种方式暴露service而不必直接使用ingress 你可以通过很多种方式暴露 service 而不必直接使用 ingress
- 使用[Service.Type=LoadBalancer](https://kubernetes.io/docs/user-guide/services/#type-loadbalancer) - 使用 [Service.Type=LoadBalancer](https://kubernetes.io/docs/user-guide/services/#type-loadbalancer)
- 使用[Service.Type=NodePort](https://kubernetes.io/docs/user-guide/services/#type-nodeport) - 使用 [Service.Type=NodePort](https://kubernetes.io/docs/user-guide/services/#type-nodeport)
- 使用[Port Proxy](https://git.k8s.io/contrib/for-demos/proxy-to-service) - 使用 [Port Proxy](https://git.k8s.io/contrib/for-demos/proxy-to-service)
- 部署一个[Service loadbalancer](https://github.com/kubernetes/contrib/tree/master/service-loadbalancer) 这允许你在多个service之间共享单个IP并通过Service Annotations实现更高级的负载平衡。 - 部署一个 [Service loadbalancer](https://github.com/kubernetes/contrib/tree/master/service-loadbalancer) 这允许你在多个 service 之间共享单个 IP并通过 Service Annotations 实现更高级的负载平衡。
## 参考 ## 参考
- [Kubernetes Ingress Resource](https://kubernetes.io/docs/concepts/services-networking/ingress/) - [Kubernetes Ingress Resource - kubernetes.io](https://kubernetes.io/docs/concepts/services-networking/ingress/)
- [使用NGINX Plus负载均衡Kubernetes服务](http://dockone.io/article/957) - [使用 NGINX Plus 负载均衡 Kubernetes 服务 - dockone.io](http://dockone.io/article/957)
- [使用 NGINX 和 NGINX Plus 的 Ingress Controller 进行 Kubernetes 的负载均衡](http://www.cnblogs.com/276815076/p/6407101.html) - [使用 NGINX 和 NGINX Plus 的 Ingress Controller 进行 Kubernetes 的负载均衡 - cnblogs.com](http://www.cnblogs.com/276815076/p/6407101.html)

View File

@ -1,6 +1,6 @@
# Traefik Ingress Controller # Traefik Ingress Controller
我们在前面部署了 [Traefik](https://traefik.io) 作为Ingress Controller如果集群外部直接访问Kubenretes内部服务的话可以直接创建Ingress如下所示 我们在前面部署了 [Traefik](https://traefik.io) 作为 Ingress Controller如果集群外部直接访问 Kubenetes 内部服务的话,可以直接创建 Ingress 如下所示:
```yaml ```yaml
apiVersion: extensions/v1beta1 apiVersion: extensions/v1beta1
@ -21,7 +21,7 @@ spec:
## Traefik Ingress Controller ## Traefik Ingress Controller
当我们处于迁移应用到kuberentes上的阶段时可能有部分服务实例不在kubernetes上服务的路由使用nginx配置这时处于nginx和ingress共存的状态。参考下面的配置: 当我们处于迁移应用到 Kubernetes 上的阶段时,可能有部分服务实例不在 Kubernetes上服务的路由使用 Nginx 配置,这时处于 nginx 和 ingress 共存的状态。参考下面的配置:
```yaml ```yaml
apiVersion: extensions/v1beta1 apiVersion: extensions/v1beta1
@ -43,12 +43,12 @@ spec:
servicePort: 80 servicePort: 80
``` ```
注意**annotation**的配置: 注意 **annotation** 的配置:
- `traefik.frontend.rule.type: PathPrefixStrip`表示将截掉URL中的`path` - `traefik.frontend.rule.type: PathPrefixStrip`:表示将截掉 URL 中的 `path`
- `kubernetes.io/ingress.class`表示使用的ingress类型 - `kubernetes.io/ingress.class`:表示使用的 ingress 类型
nginx中增加配置: Nginx 中增加配置:
```ini ```ini
upstream docGenerate { upstream docGenerate {
@ -57,4 +57,4 @@ upstream docGenerate {
} }
``` ```
172.20.0.119是我们的边缘节点的VIP见[边缘节点配置](../practice/edge-node-configuration.md)。 172.20.0.119 是我们的边缘节点的 VIP见[边缘节点配置](../practice/edge-node-configuration.md)。

View File

@ -1,47 +1,43 @@
# 边缘节点配置 # 边缘节点配置
## 前言 为了配置 kubernetes 中的 traefik ingress 的高可用,对于 kubernetes 集群以外只暴露一个访问入口,需要使用 keepalived 排除单点问题。本文参考了 [kube-keepalived-vip](https://github.com/kubernetes/contrib/tree/master/keepalived-vip),但并没有使用容器方式安装,而是直接在 node 节点上安装。
为了配置kubernetes中的traefik ingress的高可用对于kubernetes集群以外只暴露一个访问入口需要使用keepalived排除单点问题。本文参考了[kube-keepalived-vip](https://github.com/kubernetes/contrib/tree/master/keepalived-vip)但并没有使用容器方式安装而是直接在node节点上安装。
## 定义 ## 定义
首先解释下什么叫边缘节点Edge Node所谓的边缘节点即集群内部用来向集群外暴露服务能力的节点集群外部的服务通过该节点来调用集群内部的服务边缘节点是集群内外交流的一个Endpoint。 首先解释下什么叫边缘节点Edge Node所谓的边缘节点即集群内部用来向集群外暴露服务能力的节点集群外部的服务通过该节点来调用集群内部的服务边缘节点是集群内外交流的一个 Endpoint。
**边缘节点要考虑两个问题** **边缘节点要考虑两个问题**
- 边缘节点的高可用不能有单点故障否则整个kubernetes集群将不可用 - 边缘节点的高可用,不能有单点故障,否则整个 kubernetes 集群将不可用
- 对外的一致暴露端口即只能有一个外网访问IP和端口 - 对外的一致暴露端口,即只能有一个外网访问 IP 和端口
## 架构 ## 架构
为了满足边缘节点的以上需求,我们使用[keepalived](http://www.keepalived.org/)来实现。 为了满足边缘节点的以上需求,我们使用 [keepalived](http://www.keepalived.org/) 来实现。
在Kubernetes中添加了service的同时在DNS中增加一个记录这条记录需要跟ingress中的`host`字段相同IP地址即VIP的地址本示例中是`172.20.0.119`这样集群外部就可以通过service的DNS名称来访问服务了。 Kubernetes 中添加了 service 的同时,在 DNS 中增加一个记录,这条记录需要跟 ingress 中的 `host` 字段相同IP 地址即 VIP 的地址,本示例中是 `172.20.0.119`,这样集群外部就可以通过 service DNS 名称来访问服务了。
选择Kubernetes的三个node作为边缘节点并安装keepalived下图展示了边缘节点的配置同时展示了向Kubernetes中添加服务的过程。 选择 Kubernetes 的三个 node 作为边缘节点,并安装 keepalived下图展示了边缘节点的配置同时展示了向 Kubernetes 中添加服务的过程。
![边缘节点架构](../images/kubernetes-edge-node-architecture.png) ![边缘节点架构](../images/kubernetes-edge-node-architecture.png)
## 准备 ## 准备
复用kubernetes测试集群的三台主机。 复用 Kubernetes 测试集群的三台主机,其 IP 地址如下:
172.20.0.113 - 172.20.0.113
- 172.20.0.114
172.20.0.114 - 172.20.0.115
172.20.0.115
## 安装 ## 安装
使用keepalived管理VIPVIP是使用IPVS创建的IPVS 已经成为linux内核的模块不需要安装 使用 keepalived 管理 VIPVIP 是使用 IPVS 创建的IPVS 已经成为 linux 内核的模块,不需要安装
LVS的工作原理请参考http://www.cnblogs.com/codebean/archive/2011/07/25/2116043.html LVS 的工作原理请参考:[http://www.cnblogs.com/codebean/archive/2011/07/25/2116043.html](https://www.cnblogs.com/codebean/archive/2011/07/25/2116043.html)
不使用镜像方式安装了直接手动安装指定三个节点为边缘节点Edge node 不使用镜像方式安装了直接手动安装指定三个节点为边缘节点Edge node
因为我们的测试集群一共只有三个node所有在在三个node上都要安装keepalived和ipvsadmin。 因为我们的测试集群一共只有三个 node所有在在三个 node 上都要安装 keepalived ipvsadmin。
```bash ```bash
yum install keepalived ipvsadm yum install keepalived ipvsadm
@ -49,21 +45,19 @@ yum install keepalived ipvsadm
## 配置说明 ## 配置说明
需要对原先的traefik ingress进行改造从以Deployment方式启动改成DeamonSet。还需要指定一个与node在同一网段的IP地址作为VIP我们指定成172.20.0.119配置keepalived前需要先保证这个IP没有被分配。。 需要对原先的 traefik ingress 进行改造,从以 Deployment 方式启动改成 DeamonSet。还需要指定一个与 node 在同一网段的 IP 地址作为 VIP我们指定成 172.20.0.119,配置 keepalived 前需要先保证这个 IP 没有被分配。。
- Traefik以DaemonSet的方式启动 - Traefik DaemonSet 的方式启动
- 通过nodeSelector选择边缘节点 - 通过 nodeSelector 选择边缘节点
- 通过hostPort暴露端口 - 通过 hostPort 暴露端口
- 当前VIP漂移到了172.20.0.115上 - 当前 VIP 漂移到了 172.20.0.115
- Traefik根据访问的host和path配置将流量转发到相应的service上 - Traefik 根据访问的 host path 配置,将流量转发到相应的 service
## 配置keepalived ## 配置 keepalived
参考[基于keepalived 实现VIP转移lvsnginx的高可用](http://limian.blog.51cto.com/7542175/1301776)配置keepalived。 参考[基于 keepalived 实现 VIP 转移lvsnginx 的高可用](http://limian.blog.51cto.com/7542175/1301776)keepalived 的配置参考其[官方配置文档](http://keepalived.org/pdf/UserGuide.pdf)
keepalived的官方配置文档见http://keepalived.org/pdf/UserGuide.pdf 配置文件 `/etc/keepalived/keepalived.conf` 文件内容如下:
配置文件`/etc/keepalived/keepalived.conf`文件内容如下:
```ini ```ini
! Configuration File for keepalived ! Configuration File for keepalived
@ -122,25 +116,25 @@ virtual_server 172.20.0.119 80{
} }
``` ```
`Realserver`的IP和端口即traefik供外网访问的IP和端口。 `Realserver` IP 和端口即 traefik 供外网访问的 IP 和端口。
将以上配置分别拷贝到另外两台node的`/etc/keepalived`目录下。 将以上配置分别拷贝到另外两台 node `/etc/keepalived` 目录下。
我们使用转发效率最高的`lb_kind DR`直接路由方式转发使用TCP_CHECK来检测real_server的health。 我们使用转发效率最高的 `lb_kind DR` 直接路由方式转发,使用 TCP_CHECK 来检测 real_server health。
设置keepalived为开机自启动 设置 keepalived 为开机自启动:
```bash ```bash
chkconfig keepalived on chkconfig keepalived on
``` ```
**启动keepalived** **启动 keepalived**
``` ```
systemctl start keepalived systemctl start keepalived
``` ```
三台node都启动了keepalived后观察eth0的IP会在三台node的某一台上发现一个VIP是172.20.0.119。 三台 node 都启动了 keepalived 后,观察 eth0 IP会在三台 node 的某一台上发现一个 VIP 172.20.0.119。
```bash ```bash
$ ip addr show eth0 $ ip addr show eth0
@ -152,13 +146,13 @@ $ ip addr show eth0
valid_lft forever preferred_lft forever valid_lft forever preferred_lft forever
``` ```
关掉拥有这个VIP主机上的keepalived观察VIP是否漂移到了另外两台主机的其中之一上。 关掉拥有这个 VIP 主机上的 keepalived观察 VIP 是否漂移到了另外两台主机的其中之一上。
## 改造Traefik ## 改造 Traefik
在这之前我们启动的traefik使用的是deployment只启动了一个pod无法保证高可用即需要将pod固定在某一台主机上这样才能对外提供一个唯一的访问地址现在使用了keepalived就可以通过VIP来访问traefik同时启动多个traefik的pod保证高可用。 在这之前我们启动的 traefik 使用的是 deployment只启动了一个 pod无法保证高可用即需要将 pod 固定在某一台主机上,这样才能对外提供一个唯一的访问地址),现在使用了 keepalived 就可以通过 VIP 来访问 traefik同时启动多个 traefik pod 保证高可用。
配置文件`traefik.yaml`内容如下: 配置文件 `traefik.yaml` 内容如下:
```yaml ```yaml
apiVersion: extensions/v1beta1 apiVersion: extensions/v1beta1
@ -204,7 +198,7 @@ spec:
edgenode: "true" edgenode: "true"
``` ```
注意,我们使用了`nodeSelector`选择边缘节点来调度traefik-ingress-lb运行在它上面所有你需要使用 注意,我们使用了 `nodeSelector` 选择边缘节点来调度 traefik-ingress-lb 运行在它上面,所有你需要使用:
``` ```
kubectl label nodes 172.20.0.113 edgenode=true kubectl label nodes 172.20.0.113 edgenode=true
@ -212,9 +206,9 @@ kubectl label nodes 172.20.0.114 edgenode=true
kubectl label nodes 172.20.0.115 edgenode=true kubectl label nodes 172.20.0.115 edgenode=true
``` ```
给三个node打标签。 给三个 node 打标签。
查看DaemonSet的启动情况 查看 DaemonSet 的启动情况:
```bash ```bash
$ kubectl -n kube-system get ds $ kubectl -n kube-system get ds
@ -222,16 +216,16 @@ NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE
traefik-ingress-lb 3 3 3 3 3 edgenode=true 2h traefik-ingress-lb 3 3 3 3 3 edgenode=true 2h
``` ```
现在就可以在外网通过172.20.0.119:80来访问到traefik ingress了。 现在就可以在外网通过 172.20.0.119:80 来访问到 traefik ingress 了。
## 使用域名访问Kubernetes中的服务 ## 使用域名访问 Kubernetes 中的服务
现在我们已经部署了以下服务: 现在我们已经部署了以下服务:
- 三个边缘节点使用Traefik作为Ingress controller - 三个边缘节点,使用 Traefik 作为 Ingress controller
- 使用keepalived做的VIP虚拟IP172.20.0.119 - 使用 keepalived 做的 VIP虚拟 IP172.20.0.119
这样在访问该IP的时候通过指定不同的`Host`来路由到kubernetes后端服务。这种方式访问每个Service时都需要指定`Host`而同一个项目中的服务一般会在同一个Ingress中配置使用`Path`来区分Service已经足够这时候只要为VIP172.20.0.119)来配置一个域名,所有的外部访问直接通过该域名来访问即可。 这样在访问该 IP 的时候通过指定不同的 `Host` 来路由到 kubernetes 后端服务。这种方式访问每个 Service 时都需要指定 `Host`,而同一个项目中的服务一般会在同一个 Ingress 中配置,使用 `Path` 来区分 Service 已经足够,这时候只要为 VIP172.20.0.119)来配置一个域名,所有的外部访问直接通过该域名来访问即可。
如下图所示: 如下图所示:
@ -239,7 +233,7 @@ traefik-ingress-lb 3 3 3 3 3 edge
## 参考 ## 参考
- [kube-keepalived-vip](https://github.com/kubernetes/contrib/tree/master/keepalived-vip) - [kube-keepalived-vip - github.com](https://github.com/kubernetes/contrib/tree/master/keepalived-vip)
- http://www.keepalived.org/ - [keepalived 官方网站 - keepalived.org](http://www.keepalived.org/)
- [LVS简介及使用](http://www.cnblogs.com/codebean/archive/2011/07/25/2116043.html) - [LVS 简介及使用 - cnblogs.com](http://www.cnblogs.com/codebean/archive/2011/07/25/2116043.html)
- [基于keepalived 实现VIP转移lvsnginx的高可用](http://limian.blog.51cto.com/7542175/1301776) - [基于 keepalived 实现VIP转移lvsnginx 的高可用 - blog.51cto.com](https://blog.51cto.com/limian/1301776)