這篇文章教你看明白 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:5001,192.168.1.10:5001 我們把他們稱爲 Endpoint,就是所謂的具體的服務,比如 order 訂單服務。

pod nginx-ingress
nginx-ingress也是一種代理,是一個pod,外部的數據統一經過(必經)這個pod,然後通過該pod內部的nginx方向代理到各個服務(Endpoint)。nginx-ingress是ingress控制器插件的一種,這些插件有很多,比如istio-ingressgateway。

1、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.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.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服務了。

2、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。

3、nginx-ingress對外提供服務
一般來講,pod直接對外提供服務就只有兩種方式:

create一個service,該service暴漏nodePort
forward 映射
我們一般採用第一種。

nginx-ingress也是一個pod,所以,爲了能使外部通過該pod代理訪問,還需要nginx-ingress對外提供一個nodePort的service。這個service這裏也不再寫了。

4、nginx-ingress工作流程

我們可以看到,因爲 nginx-ingress 這個pod做了所有service的代理,在高併發情況下將承受巨大壓力,我們可以增加多個pod實例。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章