Kubernetes Ingress 只是 Kubernetes 中的一个普通资源对象,需要一个对应的 Ingress 控制器来解析 Ingress 的规则,暴露服务到外部,比如 ingress-nginx,本质上来说它只是一个 Nginx Pod,然后将请求重定向到其他内部(ClusterIP)服务去,这个 Pod 本身也是通过 Kubernetes 服务暴露出去,常见的方式是通过 LoadBalancer 来实现的。同样本文我们希望用一个简单清晰的概述,让你来了解 Kubernetes Ingress 背后的东西,让你更容易理解使用的 Ingress。
我们可以使用 Ingress 来使内部服务暴露到集群外部去,它为你节省了宝贵的静态 IP,因为你不需要声明多个 LoadBalancer 服务了,此次,它还可以进行更多的额外配置。下面我们通过一个简单的示例来对 Ingress 进行一些说明吧。
简单 HTTP server
首先,我们先回到容器、Kubernetes 之前的时代。
之前我们更多会使用一个(Nginx)HTTP server 来托管我们的服务,它可以通过 HTTP 协议接收到一个特定文件路径的请求,然后在文件系统中检查这个文件路径,如果存在则就返回即可。
例如,在 Nginx 中,我们可以通过下面的配置来实现这个功能。
location /folder {
root /var/www/;
index index.html;
}
除了上面提到的功能之外,我们可以当 HTTP server 接收到请求后,将该请求重定向到另一个服务器(意味着它作为代理)去,然后将该服务器的响应重定向到客户端去。对于客户端来说,什么都没有改变,接收到的结果仍然还是请求的文件(如果存在的话)。
同样如果在 Nginx 中,重定向可以配置成下面的样子:
location /folder {
proxy_pass http://second-nginx-server:8000;
}
简单的 Kubernetes 示例
使用 ClusterIP 服务
使用 LoadBalancer 服务
手动配置 Nginx 代理服务
11.22.33.44
的负载均衡器,对于不同的 http 请求路径我们用黄色来进行标记,他们的目标是一致的,只是包含的不同的请求 URL。
location /folder {
proxy_pass http://service-nginx:3001;
}
location /other {
proxy_pass http://service-python:3002;
}
使用 Kubernetes Ingress
安装 Ingress 控制器
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-.24.1/deploy/mandatory.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-.24.1/deploy/provider/cloud-generic.yaml
使用下面的命令,可以看到安装在命名空间 ingress-nginx 中的 k8s 资源。
kubectl exec
进入该 pod,里面包含一个预配置的 Nginx 服务器。其中的 nginx.conf
文件就包含各种代理重定向设置和其他相关配置。
Ingress 配置示例
我们所使用的 Ingress yaml 例子可以是这样的。
# just example, not tested
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
namespace: default
name: test-ingress
spec:
rules:
- http:
paths:
- path: /folder
backend:
serviceName: service-nginx
servicePort: 3001
- http:
paths:
- path: /other
backend:
serviceName: service-python
servicePort: 3002
kubectl create -f ingress.yaml
来创建这个资源对象即可,创建完成后这个 Ingress 对象会被上面安装的 Ingress 控制器转换为对应的 Nginx 配置。配置 Ingress Nginx
kind: Ingress
metadata:
name: ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/proxy-connect-timeout: '30'
nginx.ingress.kubernetes.io/proxy-send-timeout: '500'
nginx.ingress.kubernetes.io/proxy-read-timeout: '500'
nginx.ingress.kubernetes.io/send-timeout: "500"
nginx.ingress.kubernetes.io/enable-cors: "true"
nginx.ingress.kubernetes.io/cors-allow-methods: "*"
nginx.ingress.kubernetes.io/cors-allow-origin: "*"
...
此外也可以做更细粒度的规则配置,如下所示:
nginx.ingress.kubernetes.io/configuration-snippet: |
if ($host = 'www.qikqiak.com' ) {
rewrite ^ https://qikqiak.com$request_uri permanent;
}
查看 ingress-nginx 日志
要排查问题,通过查看 Ingress 控制器的日志非常有帮助。
使用 Curl 测试
如果我们想测试 Ingress 重定向规则,好使用 curl -v [yourhost.com](http://yourhost.com)
来代替浏览器,可以避免缓存等带来的问题。
重定向规则
在本文的示例中我们使用 /folder
和 /other/directory
等路径来重定向到不同的服务,此外我们也可以通过主机名来区分请求,比如将 api.myurl.com 和 site.myurl.com 重定向到不同的内部 ClusterIP 服务去。
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: simple-fanout-example
spec:
rules:
- host: api.myurl.com
http:
paths:
- path: /foo
backend:
serviceName: service1
servicePort: 4200
- path: /bar
backend:
serviceName: service2
servicePort: 8080
- host: website.myurl.com
http:
paths:
- path: /
backend:
serviceName: service3
servicePort: 3333
SSL/HTTPS
可能我们想让网站使用安全的 HTTPS 服务,Kubernetes Ingress 也提供了简单的 TLS 校验,这意味着它会处理所有的 SSL 通信、解密/校验 SSL 请求,然后将这些解密后的请求发送到内部服务去。
如果你的多个内部服务使用相同(可能是通配符)的 SSL 证书,这样我们就只需要在 Ingress 上配置一次,而不需要在内部服务上去配置,Ingress 可以使用配置的 TLS Kubernetes Secret 来配置 SSL 证书。
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: tls-example-ingress
spec:
tls:
- hosts:
- sslexample.foo.com
secretName: testsecret-tls
rules:
- host: sslexample.foo.com
http:
paths:
- path: /
backend:
serviceName: service1
servicePort: 80
总结
原文链接:https://codeburst.io/kubernetes-ingress-simply-visually-explained-d9cad44e4419