一篇文章看明白nginx-ingress控制器


主机Nginx

一般Nginx做主机反向代理(网关)有以下配置:
upstream order{
server 192.168.1.10:5001;
server 192.168.1.11:5001;
}

server {
listen 80;
server_name  order.example.com;
access_log     /var/log/nginx/order.example.com-access.log;
error_log     /var/log/nginx/order.example.com-error.log;
location / {
    proxy_pass_header Server;
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Scheme $scheme;
    proxy_pass http://order;
}


其中192.168.1.10:5001192.168.1.10:5001我们把他们称为Endpoint,就是所谓的具体的服务,比如order订单服务。

Pod nginx-ingress

nginx-ingress也是一种代理,是一个Pod,外部的数据统一经过(必经)这个Pod,然后通过该Pod内部的Nginx方向代理到各个服务(Endpoint)。nginx-ingress是Ingress控制器插件的一种,这些插件有很多,比如istio-ingressgateway。

Pod

nginx-ingress Pod有两个功能,Controller和Nginx:
  • Controller:和Kubernetes API通讯实时更新Nginx配置(就是ingress yaml资源了)
  • Nginx:正常的反向代理


与主机Nginx的区别是,该Pod nginx-ingress是运行在Pod里。主机在定义反向代理配置文件时,需要监听一个对外开放的端口,比如上边的80端口。那么Pod中的Nginx端口是如何配置的呢?

我们在GitHub上找到了nginx-ingress的deployment.yaml:

https://raw.githubusercontent. ... .yaml

其中一段:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-ingress-controller
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
replicas: 1
selector:
matchLabels:
  app.kubernetes.io/name: ingress-nginx
  app.kubernetes.io/part-of: ingress-nginx
template:
metadata:
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
  annotations:
    prometheus.io/port: "10254"
    prometheus.io/scrape: "true"
spec:
  # wait up to five minutes for the drain of connections
  terminationGracePeriodSeconds: 300
  serviceAccountName: nginx-ingress-serviceaccount
  containers:
    - name: nginx-ingress-controller
      image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.26.1
      ...
      ...
      ...
      ports:
        - name: http
          containerPort: 80
        - name: https
          containerPort: 443

我们看到:
- name: http
containerPort: 80
- name: https
containerPort: 443

默认对外监听了两个端口80和443,也就是说,有这两个端口对外就可以Web服务了。

Ingress资源

Ingress资源通过yaml进行管理的,比如以下:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: order
spec: 
rules:
- host: order.example.com
http:
  paths: /
  backend: 
    serviceName: order
    servicePort: 80

以上我们定义了一个单一规则的Ingress,该Pod(nginx-ingress)接收到外部所有的请求,将被发送到内部order服务的80端口上。接下来我们看Pod(nginx-ingress)如何把Ingress资源转化为该Pod中的Nginx反向代理配置文件。
upstream order{
server order:80;
}

server {
listen 80;
server_name  order.example.com;
...
...
location / {
    proxy_pass_header Server;
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Scheme $scheme;
    proxy_pass http://order; # 对应ingress 资源 name: order
}


当然Ingress如果包含https,那么会转化Nginx对应的443端口及证书的配置文件内容,这里就不写了。


那么,单一个规则的Ingress资源代理多个服务(比如order服务,product服务)或者多个Ingress资源文件如何转化为Nginx配置? 猜测,其实就是转化成了多个。
upstream order{
server order:80;


当然,被转化的nginx配置文件要比这些复杂的多,据说还是用lua脚本写的,灵活如openresty。

nginx-ingress对外提供服务

一般来讲,Pod直接对外提供服务就只有两种方式:
  • create一个service,该service暴漏nodePort
  • forward映射


我们一般采用第一种。

nginx-ingress也是一个Pod,所以,为了能使外部通过该Pod代理访问,还需要nginx-ingress对外提供一个nodePort的Service。这个Service这里也不再写了。

nginx-ingress工作流程

16d9afd9301961e2~tplv-t2oaga2asx-watermark.image_.png

我们可以看到,因为nginx-ingress这个Pod做了所有Service的代理,在高并发情况下将承受巨大压力,我们可以增加多个Pod实例。

链接:https://juejin.cn/post/6844903957479817230,作者:dakesolo

0 个评论

要回复文章请先登录注册