通常情况下,service 和 pod 的 IP 仅可在集群内部访问。集群外部的请求需要通过负载均衡转发到 service 在 Node 上暴露的 NodePort 上,然后再由 kube-proxy 通过边缘路由器 (edge router) 将其转发给相关的 Pod 或者丢弃。而 Ingress 就是为进入集群的请求提供路由规则的集合
Ingress 可以给 service 提供集群外部访问的 URL、负载均衡、SSL 终止、HTTP 路由等。为了配置这些 Ingress 规则,集群管理员需要部署一个 Ingress controller,它监听 Ingress 和 service 的变化,并根据规则配置负载均衡并提供访问入口。

资料信息
Ingress-Nginx github 地址
Ingress-Nginx 官方网站


部署 Ingress-Nginx
1 2
| kubectl apply -f mandatory.yaml kubectl apply -f service-nodeport.yaml
|
Ingress HTTP 代理访问
deployment、Service、Ingress Yaml 文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| apiVersion: extensions/v1beta1 kind: Deployment metadata: name: nginx-dm spec: replicas: 2 template: metadata: labels: name: nginx spec: containers: - name: nginx image: wangyanglinux/myapp:v1 imagePullPolicy: IfNotPresent ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: nginx-svc spec: ports: - port: 80 targetPort: 80 protocol: TCP selector: name: nginx --- apiVersion: extensions/v1beta1 kind: Ingress metadata: name: nginx-test spec: rules: - host: www1.atguigu.com http: paths: - path: / backend: serviceName: nginx-svc servicePort: 80
|
Ingress HTTPS 代理访问
创建证书,以及 cert 存储方式
1 2
| openssl req -x509 -sha256 -nodes -days 365 -newkey rsa:2048 -keyout tls.key -out tls.crt -subj "/CN=nginxsvc/O=nginxsvc" kubectl create secret tls tls-secret --key tls.key --cert tls.crt
|
deployment、Service、Ingress Yaml 文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| apiVersion: extensions/v1beta1 kind: Ingress metadata: name: nginx-test spec: tls: - hosts: - foo.bar.com secretName: tls-secret rules: - host: foo.bar.com http: paths: - path: / backend: serviceName: nginx-svc servicePort: 80
|
Nginx 进行 BasicAuth
1 2 3
| yum -y install httpd htpasswd -c auth foo kubectl create secret generic basic-auth --from-file=auth
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| apiVersion: extensions/v1beta1 kind: Ingress metadata: name: ingress-with-auth annotations: nginx.ingress.kubernetes.io/auth-type: basic nginx.ingress.kubernetes.io/auth-secret: basic-auth nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - foo' spec: rules: - host: foo2.bar.com http: paths: - path: / backend: serviceName: nginx-svc servicePort: 80
|
Nginx 进行重写
名称 |
描述 |
值 |
nginx.ingress.kubernetes.io/rewrite-target |
必须重定向流量的目标URI |
串 |
nginx.ingress.kubernetes.io/ssl-redirect |
指示位置部分是否仅可访问SSL(当Ingress包含证书时默认为True) |
布尔 |
nginx.ingress.kubernetes.io/force-ssl-redirect |
即使Ingress未启用TLS,也强制重定向到HTTPS |
布尔 |
nginx.ingress.kubernetes.io/app-root |
定义Controller必须重定向的应用程序根,如果它在’/‘上下文中 |
串 |
nginx.ingress.kubernetes.io/use-regex |
指示Ingress上定义的路径是否使用正则表达式 |
布尔 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| apiVersion: extensions/v1beta1 kind: Ingress metadata: name: nginx-test annotations: nginx.ingress.kubernetes.io/rewrite-target: http://foo.bar.com:31795/hostname.html spec: rules: - host: foo10.bar.com http: paths: - path: / backend: serviceName: nginx-svc servicePort: 80
|
注:单个服务还可以通过设置 Service.Type=NodePort
或者 Service.Type=LoadBalancer
来对外暴露。
多服务的 Ingress
路由到多服务的 Ingress 即根据请求路径的不同转发到不同的后端服务上.
LR;1 2
| foo.bar.com -> 178.91.123.132 -> / foo s1:80 / bar s2:80
|
可以通过下面的 Ingress 来定义:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| apiVersion: extensions/v1beta1 kind: Ingress metadata: name: test spec: rules: - host: foo.bar.com http: paths: - path: /foo backend: serviceName: s1 servicePort: 80 - path: /bar backend: serviceName: s2 servicePort: 80
|
虚拟主机 Ingress
虚拟主机 Ingress 即根据名字的不同转发到不同的后端服务上,而他们共用同一个的 IP 地址,如下所示:
1 2 3
| foo.bar.com --| |-> foo.bar.com s1:80 | 178.91.123.132 | bar.foo.com --| |-> bar.foo.com s2:80
|
基于
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: test spec: rules: - host: foo.bar.com http: paths: - backend: serviceName: s1 servicePort: 80 - host: bar.foo.com http: paths: - backend: serviceName: s2 servicePort: 80
|
注:没有定义规则的后端服务称为默认后端服务,可以用来方便的处理 404 页面。
TLS Ingress
TLS Ingress 通过 Secret 获取 TLS 私钥和证书 (名为 tls.crt
和 tls.key
),来执行 TLS 终止。如果 Ingress 中的 TLS 配置部分指定了不同的主机,则它们将根据通过 SNI TLS 扩展指定的主机名(假如 Ingress controller 支持 SNI)在多个相同端口上进行复用。
定义一个包含 tls.crt
和 tls.key
的 secret:
1 2 3 4 5 6 7 8 9
| apiVersion: v1 data: tls.crt: base64 encoded cert tls.key: base64 encoded key kind: Secret metadata: name: testsecret namespace: default type: Opaque
|
Ingress 中引用 secret
1 2 3 4 5 6 7 8 9 10
| apiVersion: extensions/v1beta1 kind: Ingress metadata: name: no-rules-map spec: tls: - secretName: testsecret backend: serviceName: s1 servicePort: 80
|
注意,不同 Ingress controller 支持的 TLS 功能不尽相同。 请参阅有关 nginx,GCE 或任何其他 Ingress controller 的文档,以了解 TLS 的支持情况。
更新 Ingress
可以通过 kubectl edit ing name
的方法来更新 ingress:
1 2 3 4 5 6
| $ kubectl get ing NAME RULE BACKEND ADDRESS test - 178.91.123.132 foo.bar.com /foo s1:80 $ kubectl edit ing test
|
这会弹出一个包含已有 IngressSpec yaml 文件的编辑器,修改并保存就会将其更新到 kubernetes API server,进而触发 Ingress Controller 重新配置负载均衡:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| spec: rules: - host: foo.bar.com http: paths: - backend: serviceName: s1 servicePort: 80 path: /foo - host: bar.baz.com http: paths: - backend: serviceName: s2 servicePort: 80 path: /foo ..
|
更新后:
1 2 3 4 5 6 7
| $ kubectl get ing NAME RULE BACKEND ADDRESS test - 178.91.123.132 foo.bar.com /foo s1:80 bar.baz.com /foo s2:80
|
当然,也可以通过 kubectl replace -f new-ingress.yaml
命令来更新,其中 new-ingress.yaml 是修改过的 Ingress yaml。