kubernetes 中的 ingress

在我之前的kubernetes中的Service中,我们可以看到如何使用Service来让我们的应用可以被集群外所访问到。但是在实际使用中,仍然存在一些问题。对于我们经常用的NodePort和LoadBalancer这两个type,LoadBalancer需要底层的infra支持,并且哪怕支持了我们也不能轻易用,因为LoadBalancer资源是有限的,而且最重要的是贵,贵,贵。而对于NodePort来说,我们需要经常更新我们的proxy设置,并且追踪哪些Port被使用了,所以也是很麻烦的。

万能的程序猿总是有解决方案,ingress应运而生。

Ingress

通过使用Service,路由的规则是直接附属到一个特定的Service上,并且生命周期和Service一样。如果说,我们能把路由规则和应用解耦,那么我们就可以随意的去更新应用而不影响访问,或者随意的去更改路由规则了。Ingress正是做这个的。

根据Kubernetes官方文档:

An Ingress is a collection of rules that allow inbound connections to reach the cluster Services.

Ingress实际上做了一个Layer 7的HTTP load balancer,并且提供了以下功能:

  • TLS(Transport Layer Security)
  • Name-based virtual hosting
  • Path-based routing
  • Custom rules

AEE4364B-EE2F-451A-8361-DF5A6AE92116

通过Ingress,用户不需要直接连接到Service,用户可以直接访问到ingress的endpoint,然后通过Ingress再转发到Service。样例Ingress配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: web-ingress
spec:
rules:
- host: blue.myweb.com
http:
paths:
- backend:
serviceName: blue-service
servicePort: 80
- host: green.myweb.com
http:
paths:
- backend:
serviceName: green-service
servicePort: 80

根据这个配置,用户访问blue.myweb.com和green.myweb.com将会访问到同一个ingress的endpoint,并且再被转发到blue-service和green-service中。这个就是之前说的Name-based virtual hosting

我们也可以用Fan Out Ingress rules,比如我们访问myweb.com/blue和myweb.com/green,然后这些也会被转发到blue-service和green-service:

6E68B099-8D89-40B4-9744-475C4E1E61B0

Ingress这个Resource其实并不做转发,而是由Ingress Controller来做的。

Ingress Controller

Ingress Controller其实就是一个监听master node上API Server对Ingress Resource的改变然后改变这个Layer 7 Load Balancer的Controller。Kubernetes有好多种不同的Ingress Controllers,比如说GCE L7 Load Balancer和Nginx Ingress Controller。当然,如果我们需要的话也可以写一个自己的。

需要保证Ingress Controller被启用,Ingress才可以使用。

创建一个Ingress Resource

我们可以通过kubectl create来创建一个ingress资源,比如假设我们有一个叫做myweb-ingress.yaml的文件,内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: web-ingress
spec:
rules:
- host: blue.myweb.com
http:
paths:
- backend:
serviceName: blue-service
servicePort: 80
- host: green.myweb.com
http:
paths:
- backend:
serviceName: green-service
servicePort: 80

我们可以通过:

1
$ kubectl create -f myweb-ingress.yaml

来创建这个ingress的资源。然后只要修改我们的域名dns,指向ingress的endpoint即可(在本机上可以通过修改/etc/hosts来达成目的)。