7

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

 3 years ago
source link: http://dockone.io/article/2434517
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

主机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。
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工作流程

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

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

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK