update
parent
3989521766
commit
d38ff91d9b
|
@ -94,6 +94,6 @@ Kubernetes Handbook 开源于 2017 年 3 月并在其后不断完善,是第一
|
|||
</a>
|
||||
</p>
|
||||
|
||||
云原生社区是一个中立的云原生终端用户社区,始与作者于 2016 年成立的 Kubernetes & CloudNative 实战群,覆盖了上千名早期云原生拥护者。在此基础上于 2020 年 5 月,由 CNCF 大使、开源领域意见领袖共同发起将原社群升级为云原生社区,旨在推广云原生技术,构建开发者生态。
|
||||
云原生社区是一个中立的云原生终端用户社区,始与作者于 2016 年成立的 Kubernetes & CloudNative 实战群,覆盖了上千名早期云原生拥护者。在此基础上于 2020 年 5 月,由 CNCF 大使、开源领域意见领袖共同发起将原社群升级为云原生社区,目标成为中国最具影响力的云原生开源社区。
|
||||
|
||||
官方网站 <https://cloudnative.to>,关注云原生社区微信公众号,[申请加入社区](https://mp.weixin.qq.com/s/vWlSdzz2MNdXRr0sd2-LFg)。
|
||||
|
|
|
@ -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集群中的一台物理机或者虚拟机。
|
||||
- 集群:位于Internet防火墙后的节点,这是kubernetes管理的主要计算资源。
|
||||
- 节点:Kubernetes 集群中的一台物理机或者虚拟机。
|
||||
- 集群:位于 Internet 防火墙后的节点,这是 kubernetes 管理的主要计算资源。
|
||||
- 边界路由器:为集群强制执行防火墙策略的路由器。 这可能是由云提供商或物理硬件管理的网关。
|
||||
- 集群网络:一组逻辑或物理链接,可根据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访问。
|
||||
- 集群网络:一组逻辑或物理链接,可根据 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 访问。
|
||||
|
||||
## 什么是Ingress?
|
||||
## 什么是 Ingress?
|
||||
|
||||
通常情况下,service和pod仅可在集群内部网络中通过IP地址访问。所有到达边界路由器的流量或被丢弃或被转发到其他地方。从概念上讲,可能像下面这样:
|
||||
通常情况下,service 和 pod 仅可在集群内部网络中通过 IP 地址访问。所有到达边界路由器的流量或被丢弃或被转发到其他地方。从概念上讲,可能像下面这样:
|
||||
|
||||
```
|
||||
internet
|
||||
|
|
||||
------------
|
||||
[ Services ]
|
||||
[Services]
|
||||
```
|
||||
|
||||
Ingress是授权入站连接到达集群服务的规则集合。
|
||||
Ingress 是授权入站连接到达集群服务的规则集合。
|
||||
|
||||
```
|
||||
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
|
||||
1: apiVersion: extensions/v1beta1
|
||||
|
@ -62,42 +63,43 @@ GCE/GKE会在master节点上部署一个ingress controller。你可以在一个p
|
|||
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或者自己实现一个。
|
||||
- kubernetes当前支持并维护[GCE](https://git.k8s.io/ingress-gce/README.md)和[nginx](https://git.k8s.io/ingress-nginx/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).
|
||||
- [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/).
|
||||
为了使 Ingress 正常工作,集群中必须运行 Ingress controller。 这与其他类型的控制器不同,其他类型的控制器通常作为 `kube-controller-manager` 二进制文件的一部分运行,在集群启动时自动启动。 你需要选择最适合自己集群的 Ingress 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)
|
||||
- [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([Let’s 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
|
||||
apiVersion: extensions/v1beta1
|
||||
|
@ -110,7 +112,7 @@ spec:
|
|||
servicePort: 80
|
||||
```
|
||||
|
||||
使用`kubectl create -f`命令创建,然后查看ingress:
|
||||
使用`kubectl create -f`命令创建,然后查看 ingress:
|
||||
|
||||
```bash
|
||||
$ kubectl get ing
|
||||
|
@ -118,18 +120,18 @@ NAME RULE BACKEND ADDRESS
|
|||
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
|
||||
/ bar s2:80
|
||||
foo.bar.com -> 178.91.123.132 -> /foo s1:80
|
||||
/bar s2:80
|
||||
```
|
||||
|
||||
你需要一个这样的ingress:
|
||||
你需要一个这样的 ingress:
|
||||
|
||||
```yaml
|
||||
apiVersion: extensions/v1beta1
|
||||
|
@ -151,22 +153,22 @@ spec:
|
|||
servicePort: 80
|
||||
```
|
||||
|
||||
使用`kubectl create -f`创建完ingress后:
|
||||
使用 `kubectl create -f` 创建完 ingress 后:
|
||||
|
||||
```bash
|
||||
$ kubectl get ing
|
||||
NAME RULE BACKEND ADDRESS
|
||||
test -
|
||||
foo.bar.com
|
||||
/foo s1:80
|
||||
/bar s2:80
|
||||
foo.bar.com
|
||||
/foo s1:80
|
||||
/bar s2:80
|
||||
```
|
||||
|
||||
只要服务(s1,s2)存在,Ingress controller就会将提供一个满足该Ingress的特定loadbalancer实现。 这一步完成后,您将在Ingress的最后一列看到loadbalancer的地址。
|
||||
只要服务(s1,s2)存在,Ingress controller 就会将提供一个满足该 Ingress 的特定 loadbalancer 实现。 这一步完成后,您将在 Ingress 的最后一列看到 loadbalancer 的地址。
|
||||
|
||||
### 基于名称的虚拟主机
|
||||
|
||||
Name-based的虚拟主机在同一个IP地址下拥有多个主机名。
|
||||
Name-based 的虚拟主机在同一个 IP 地址下拥有多个主机名。
|
||||
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
下面这个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
|
||||
apiVersion: extensions/v1beta1
|
||||
|
@ -197,11 +199,11 @@ spec:
|
|||
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私钥和证书的[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
|
||||
apiVersion: v1
|
||||
|
@ -215,7 +217,7 @@ metadata:
|
|||
type: Opaque
|
||||
```
|
||||
|
||||
在Ingress中引用这个secret将通知Ingress controller使用TLS加密从将客户端到loadbalancer的channel:
|
||||
在 Ingress 中引用这个 secret 将通知 Ingress controller 使用 TLS 加密从将客户端到 loadbalancer 的 channel:
|
||||
|
||||
```yaml
|
||||
apiVersion: extensions/v1beta1
|
||||
|
@ -230,15 +232,15 @@ spec:
|
|||
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
|
||||
$ kubectl get ing
|
||||
|
@ -249,7 +251,7 @@ test - 178.91.123.132
|
|||
$ kubectl edit ing test
|
||||
```
|
||||
|
||||
这会弹出一个包含已有的yaml文件的编辑器,修改它,增加新的Host配置。
|
||||
这会弹出一个包含已有的 yaml 文件的编辑器,修改它,增加新的 Host 配置。
|
||||
|
||||
```yaml
|
||||
spec:
|
||||
|
@ -271,7 +273,7 @@ spec:
|
|||
..
|
||||
```
|
||||
|
||||
保存它会更新API server中的资源,这会触发ingress controller重新配置loadbalancer。
|
||||
保存它会更新 API server 中的资源,这会触发 ingress controller 重新配置 loadbalancer。
|
||||
|
||||
```bash
|
||||
$ kubectl get ing
|
||||
|
@ -283,32 +285,33 @@ test - 178.91.123.132
|
|||
/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模型支持(如SNI,re-encryption)
|
||||
- 通过声明来请求IP或者主机名
|
||||
- 结合L4和L7 Ingress
|
||||
- 更多的Ingress controller
|
||||
- 多样化的 HTTPS/TLS 模型支持(如 SNI,re-encryption)
|
||||
- 通过声明来请求 IP 或者主机名
|
||||
- 结合 L4 和 L7 Ingress
|
||||
- 更多的 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=NodePort](https://kubernetes.io/docs/user-guide/services/#type-nodeport)
|
||||
- 使用[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.Type=LoadBalancer](https://kubernetes.io/docs/user-guide/services/#type-loadbalancer)
|
||||
- 使用 [Service.Type=NodePort](https://kubernetes.io/docs/user-guide/services/#type-nodeport)
|
||||
- 使用 [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 实现更高级的负载平衡。
|
||||
|
||||
## 参考
|
||||
|
||||
- [Kubernetes Ingress Resource](https://kubernetes.io/docs/concepts/services-networking/ingress/)
|
||||
- [使用NGINX Plus负载均衡Kubernetes服务](http://dockone.io/article/957)
|
||||
- [使用 NGINX 和 NGINX Plus 的 Ingress Controller 进行 Kubernetes 的负载均衡](http://www.cnblogs.com/276815076/p/6407101.html)
|
||||
- [Kubernetes Ingress Resource - kubernetes.io](https://kubernetes.io/docs/concepts/services-networking/ingress/)
|
||||
- [使用 NGINX Plus 负载均衡 Kubernetes 服务 - dockone.io](http://dockone.io/article/957)
|
||||
- [使用 NGINX 和 NGINX Plus 的 Ingress Controller 进行 Kubernetes 的负载均衡 - cnblogs.com](http://www.cnblogs.com/276815076/p/6407101.html)
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Traefik Ingress Controller
|
||||
|
||||
我们在前面部署了 [Traefik](https://traefik.io) 作为Ingress Controller,如果集群外部直接访问Kubenretes内部服务的话,可以直接创建Ingress如下所示:
|
||||
我们在前面部署了 [Traefik](https://traefik.io) 作为 Ingress Controller,如果集群外部直接访问 Kubenetes 内部服务的话,可以直接创建 Ingress 如下所示:
|
||||
|
||||
```yaml
|
||||
apiVersion: extensions/v1beta1
|
||||
|
@ -21,7 +21,7 @@ spec:
|
|||
|
||||
## Traefik Ingress Controller
|
||||
|
||||
当我们处于迁移应用到kuberentes上的阶段时,可能有部分服务实例不在kubernetes上,服务的路由使用nginx配置,这时处于nginx和ingress共存的状态。参考下面的配置:
|
||||
当我们处于迁移应用到 Kubernetes 上的阶段时,可能有部分服务实例不在 Kubernetes上,服务的路由使用 Nginx 配置,这时处于 nginx 和 ingress 共存的状态。参考下面的配置:
|
||||
|
||||
```yaml
|
||||
apiVersion: extensions/v1beta1
|
||||
|
@ -43,12 +43,12 @@ spec:
|
|||
servicePort: 80
|
||||
```
|
||||
|
||||
注意**annotation**的配置:
|
||||
注意 **annotation** 的配置:
|
||||
|
||||
- `traefik.frontend.rule.type: PathPrefixStrip`:表示将截掉URL中的`path`
|
||||
- `kubernetes.io/ingress.class`:表示使用的ingress类型
|
||||
- `traefik.frontend.rule.type: PathPrefixStrip`:表示将截掉 URL 中的 `path`
|
||||
- `kubernetes.io/ingress.class`:表示使用的 ingress 类型
|
||||
|
||||
在nginx中增加配置:
|
||||
在 Nginx 中增加配置:
|
||||
|
||||
```ini
|
||||
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)。
|
||||
|
|
|
@ -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集群将不可用
|
||||
- 对外的一致暴露端口,即只能有一个外网访问IP和端口
|
||||
- 边缘节点的高可用,不能有单点故障,否则整个 kubernetes 集群将不可用
|
||||
- 对外的一致暴露端口,即只能有一个外网访问 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)
|
||||
|
||||
## 准备
|
||||
|
||||
复用kubernetes测试集群的三台主机。
|
||||
复用 Kubernetes 测试集群的三台主机,其 IP 地址如下:
|
||||
|
||||
172.20.0.113
|
||||
|
||||
172.20.0.114
|
||||
|
||||
172.20.0.115
|
||||
- 172.20.0.113
|
||||
- 172.20.0.114
|
||||
- 172.20.0.115
|
||||
|
||||
## 安装
|
||||
|
||||
使用keepalived管理VIP,VIP是使用IPVS创建的,IPVS 已经成为linux内核的模块,不需要安装
|
||||
使用 keepalived 管理 VIP,VIP 是使用 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)。
|
||||
|
||||
因为我们的测试集群一共只有三个node,所有在在三个node上都要安装keepalived和ipvsadmin。
|
||||
因为我们的测试集群一共只有三个 node,所有在在三个 node 上都要安装 keepalived 和 ipvsadmin。
|
||||
|
||||
```bash
|
||||
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的方式启动
|
||||
- 通过nodeSelector选择边缘节点
|
||||
- 通过hostPort暴露端口
|
||||
- 当前VIP漂移到了172.20.0.115上
|
||||
- Traefik根据访问的host和path配置,将流量转发到相应的service上
|
||||
- Traefik 以 DaemonSet 的方式启动
|
||||
- 通过 nodeSelector 选择边缘节点
|
||||
- 通过 hostPort 暴露端口
|
||||
- 当前 VIP 漂移到了 172.20.0.115 上
|
||||
- Traefik 根据访问的 host 和 path 配置,将流量转发到相应的 service 上
|
||||
|
||||
## 配置keepalived
|
||||
## 配置 keepalived
|
||||
|
||||
参考[基于keepalived 实现VIP转移,lvs,nginx的高可用](http://limian.blog.51cto.com/7542175/1301776),配置keepalived。
|
||||
参考[基于 keepalived 实现 VIP 转移,lvs,nginx 的高可用](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
|
||||
! 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
|
||||
chkconfig keepalived on
|
||||
```
|
||||
|
||||
**启动keepalived**
|
||||
**启动 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
|
||||
$ ip addr show eth0
|
||||
|
@ -152,13 +146,13 @@ $ ip addr show eth0
|
|||
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
|
||||
apiVersion: extensions/v1beta1
|
||||
|
@ -204,7 +198,7 @@ spec:
|
|||
edgenode: "true"
|
||||
```
|
||||
|
||||
注意,我们使用了`nodeSelector`选择边缘节点来调度traefik-ingress-lb运行在它上面,所有你需要使用:
|
||||
注意,我们使用了 `nodeSelector` 选择边缘节点来调度 traefik-ingress-lb 运行在它上面,所有你需要使用:
|
||||
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
给三个node打标签。
|
||||
给三个 node 打标签。
|
||||
|
||||
查看DaemonSet的启动情况:
|
||||
查看 DaemonSet 的启动情况:
|
||||
|
||||
```bash
|
||||
$ 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
|
||||
```
|
||||
|
||||
现在就可以在外网通过172.20.0.119:80来访问到traefik ingress了。
|
||||
现在就可以在外网通过 172.20.0.119:80 来访问到 traefik ingress 了。
|
||||
|
||||
## 使用域名访问Kubernetes中的服务
|
||||
## 使用域名访问 Kubernetes 中的服务
|
||||
|
||||
现在我们已经部署了以下服务:
|
||||
|
||||
- 三个边缘节点,使用Traefik作为Ingress controller
|
||||
- 使用keepalived做的VIP(虚拟IP)172.20.0.119
|
||||
- 三个边缘节点,使用 Traefik 作为 Ingress controller
|
||||
- 使用 keepalived 做的 VIP(虚拟 IP)172.20.0.119
|
||||
|
||||
这样在访问该IP的时候通过指定不同的`Host`来路由到kubernetes后端服务。这种方式访问每个Service时都需要指定`Host`,而同一个项目中的服务一般会在同一个Ingress中配置,使用`Path`来区分Service已经足够,这时候只要为VIP(172.20.0.119)来配置一个域名,所有的外部访问直接通过该域名来访问即可。
|
||||
这样在访问该 IP 的时候通过指定不同的 `Host` 来路由到 kubernetes 后端服务。这种方式访问每个 Service 时都需要指定 `Host`,而同一个项目中的服务一般会在同一个 Ingress 中配置,使用 `Path` 来区分 Service 已经足够,这时候只要为 VIP(172.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)
|
||||
- http://www.keepalived.org/
|
||||
- [LVS简介及使用](http://www.cnblogs.com/codebean/archive/2011/07/25/2116043.html)
|
||||
- [基于keepalived 实现VIP转移,lvs,nginx的高可用](http://limian.blog.51cto.com/7542175/1301776)
|
||||
- [kube-keepalived-vip - github.com](https://github.com/kubernetes/contrib/tree/master/keepalived-vip)
|
||||
- [keepalived 官方网站 - keepalived.org](http://www.keepalived.org/)
|
||||
- [LVS 简介及使用 - cnblogs.com](http://www.cnblogs.com/codebean/archive/2011/07/25/2116043.html)
|
||||
- [基于 keepalived 实现VIP转移,lvs,nginx 的高可用 - blog.51cto.com](https://blog.51cto.com/limian/1301776)
|
||||
|
|
Loading…
Reference in New Issue