Ingress - nicoleShuaihui/k8s GitHub Wiki

Ingress

1. Service基本操作

  • Loadbalancer。即通过LoadBalancer类型的K8s Service对外暴露服务。
  • Ingress。七层HTTP代理。

Ingress是Kubernetes对7层反向代理的抽象。Kubernetes的Ingress有多种实现方式,最常见的是nginx。我们也可以通过与nginx类比,来理解Ingress。

1. Ingress基本操作

1)创建Ingress

创建文件ingress.yml,内容如下:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: 【你的环境名字】
  namespace: 【你的环境名】
spec:
  rules:
  - host: 【你的环境名】.super-front.com
    http:
      paths:
      - backend:
          serviceName: super-front
          servicePort: 【你的super-front的Service端口】
        path: /

通过kubectl命令创建ingress:

kubectl apply -f ./ingress.yml

修改我们本地机器的hosts文件,添加如下的一行DNS配置。

172.30.10.41 【你的环境名】.super-front.com

例如我的windows系统,hosts文件在C:\Windows\System32\drivers\etc下。

打开浏览器,尝试访问【你的环境名】.my-super-app.com。可以访问到吗?

2)查看Ingress

kubectl命令查看ingress:

# kubectl get ing -n pg-allen
NAME       HOSTS                       ADDRESS   PORTS   AGE
pg-allen   pg-allen.my-super-app.com             80      6m48s

3)配置TLS

首先,需要一份TLS证书。下面以域名pg-allen.super-front.com为例。

创建秘钥:

openssl genrsa -out test-ingress.key 2048

创建证书请求(CSR):

openssl req -new -key test-ingress.key -out test-ingress.csr \
        -subj "/CN=pg-allen.super-front.com"

创建证书:

openssl x509 -req -days 365 -in test-ingress.csr -signkey test-ingress.key \
        -out test-ingress.crt

至此,我们获得了秘钥test-ingress.key和证书test-ingress.crt

然后,我们需创建Secret:

# kubectl -n pg-allen create secret tls pg-allen-super-front-com --cert ./test-ingress.crt --key ./test-ingress.key
secret/pg-allen-super-front-com created

查看配置的Secret,确认下:

# kubectl -n pg-allen get secret pg-allen-super-front-com -o yaml
apiVersion: v1
data:
  tls.crt: 【Base64编码的证书信息】
  tls.key: 【Base64编码的秘钥信息】
kind: Secret
metadata:
  creationTimestamp: "2020-04-11T03:11:21Z"
  name: pg-allen-super-front-com
  namespace: pg-allen
  resourceVersion: "357747872"
  selfLink: /api/v1/namespaces/pg-allen/secrets/pg-allen-super-front-com
  uid: 1e6909f5-7ba2-11ea-a111-0050568156a5
type: kubernetes.io/tls

注意:Secret的Type必须是kubernetes.io/tls,才能被Ingress所使用。

修改Ingress:

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: pg-allen
  namespace: pg-allen
spec:
  tls:
  - hosts:
    - pg-allen.super-front.com
    secretName: pg-allen-super-front-com
  rules:
  - host: pg-allen.super-front.com
    http:
      paths:
      - backend:
          serviceName: super-front
          servicePort: 18080
        path: /

尝试访问https://pg-allen-super-front-com,能否正常访问?(如果浏览器提示CA根不受信任,可忽略)

4)nginx-ingress-controller原理初探

为了理解ingress的原理,我们进入ingress-controller内部一探究竟。

在线下集群多个节点上,运行着nginx-ingress-controller

# kubectl get po --all-namespaces -owide |grep ingress-controller 
ingress-nginx       nginx-ingress-controller-p9x9w                       1/1     Running                0          32d     172.30.10.41     172.30.10.41    <none>           <none>
ingress-nginx       nginx-ingress-controller-skf48                       1/1     Running                0          36d     172.30.10.69     172.30.10.69    <none>           <none>
... ...

我们进入其中一个ingress-controller pod内:

# kubectl exec -it nginx-ingress-controller-p9x9w  -n ingress-nginx bash

在ingress-controller pod内/etc/nginx目录下,我们看到nginx.conf文件。

在这个文件,可找到了pg-allen.super-front.com相关的配置:

        ## start server pg-allen.super-front.com
        server {
                server_name pg-allen.super-front.com ;      # Ingress的host

                listen 80;

                listen [::]:80;

                set $proxy_upstream_name "-";
                set $pass_access_scheme $scheme;
                set $pass_server_port $server_port;
                set $best_http_host $http_host;
                set $pass_port $pass_server_port;

                listen 443  ssl http2;

                listen [::]:443  ssl http2;

                # PEM sha: e2ec5127f5690d9b5be7d4c964745c25cac69e4b
                ssl_certificate                         /etc/ingress-controller/ssl/default-fake-certificate.pem;
                ssl_certificate_key                     /etc/ingress-controller/ssl/default-fake-certificate.pem;

                ssl_certificate_by_lua_block {
                        certificate.call()
                }

                location / {

                        set $namespace      "pg-allen";
                        set $ingress_name   "pg-allen";
                        set $service_name   "super-front";
                        set $service_port   "18080";
                        set $location_path  "/";

                        rewrite_by_lua_block {
                                lua_ingress.rewrite({
                                        force_ssl_redirect = true,
                                        use_port_in_redirects = false,
                                })
                                balancer.rewrite()
                                plugins.run()
                        }

                        header_filter_by_lua_block {

                                plugins.run()
                        }
                        body_filter_by_lua_block {

                        }

                        log_by_lua_block {

                                balancer.log()

                                monitor.call()

                                plugins.run()
                        }

                        if ($scheme = https) {
                                more_set_headers                        "Strict-Transport-Security: max-age=15724800; includeSubDomains";
                        }

                        port_in_redirect off;

                        set $balancer_ewma_score -1;
                        set $proxy_upstream_name    "pg-allen-super-front-18080";
                        set $proxy_host             $proxy_upstream_name;

                        set $proxy_alternative_upstream_name "";

                        client_max_body_size                    1m;

                        proxy_set_header Host                   $best_http_host;

                        # Pass the extracted client certificate to the backend

                        # Allow websocket connections
                        proxy_set_header                        Upgrade           $http_upgrade;

                        proxy_set_header                        Connection        $connection_upgrade;

                        proxy_set_header X-Request-ID           $req_id;
                        proxy_set_header X-Real-IP              $the_real_ip;

                        proxy_set_header X-Forwarded-For        $the_real_ip;

                        proxy_set_header X-Forwarded-Host       $best_http_host;
                        proxy_set_header X-Forwarded-Port       $pass_port;
                        proxy_set_header X-Forwarded-Proto      $pass_access_scheme;

                        proxy_set_header X-Original-URI         $request_uri;

                        proxy_set_header X-Scheme               $pass_access_scheme;

                        # Pass the original X-Forwarded-For
                        proxy_set_header X-Original-Forwarded-For $http_x_forwarded_for;

                        # mitigate HTTPoxy Vulnerability
                        # https://www.nginx.com/blog/mitigating-the-httpoxy-vulnerability-with-nginx/
                        proxy_set_header Proxy                  "";

                        # Custom headers to proxied server

                        proxy_connect_timeout                   5s;
                        proxy_send_timeout                      60s;
                        proxy_read_timeout                      60s;

                        proxy_buffering                         off;
                        proxy_buffer_size                       4k;
                        proxy_buffers                           4 4k;
                        proxy_request_buffering                 on;

                        proxy_http_version                      1.1;

                        proxy_cookie_domain                     off;
                        proxy_cookie_path                       off;

                        # In case of errors try the next upstream server before returning an error
                        proxy_next_upstream                     error timeout;
                        proxy_next_upstream_timeout             0;
                        proxy_next_upstream_tries               3;

                        proxy_pass http://upstream_balancer;

                        proxy_redirect                          off;

                }

        }
        ## end server pg-allen.super-front.com

ingress-controller将我们的ingress配置,转成了nginx(确切是openresty)的配置。

处理过程:外部访问——》nginx-ingress-controller(nginx转发)——》k8s Service()——》pod(转发完成)

⚠️ **GitHub.com Fallback** ⚠️