k8s ingress以及ingress Cintroller 理论篇及部署

概念

前言:

service的作用体现在两个方面,对集群内部,它不断跟踪pod的变化,更新endpoint中对应pod的对象,提供了ip不断变化的pod的服务发现机制,对集群外部,他类似负载均衡器,可以在集群内外部对pod进行访问。

但是,单独用service暴露服务的方式,在实际生产环境中不太合适:
ClusterIP的方式只能在集群内部访问。
NodePort方式的话,测试环境使用还行,当有几十上百的服务在集群中运行时,NodePort的端口管理是灾难。
LoadBalance方式受限于云平台,且通常在云平台部署ELB还需要额外的费用。

所幸k8s还提供了一种集群维度暴露服务的方式,也就是ingress。ingress可以简单理解为service的service,他通过独立的ingress对象来制定请求转发的规则,把请求路由到一个或多个service中。

这样就把服务与请求规则解耦了,可以从业务维度统一考虑业务的暴露,而不用为每个service单独考虑。

ingress与ingress-controller概念

要理解ingress,需要区分两个概念,ingress和ingress-controller:

ingress对象:

指的是k8s中的一个api对象,一般用yaml配置。作用是定义请求如何转发到service的规则,可以理解为配置模板。

ingress Cintroller

具体实现反向代理及负载均衡的程序,对ingress定义的规则进行解析,根据配置的规则来实现请求转发。
简单来说,ingress-controller才是负责具体转发的组件,通过各种方式将它暴露在集群入口,外部对集群的请求流量会先到ingress-controller,而ingress对象是用来告诉ingress-controller该如何转发请求,比如哪些域名哪些path要转发到哪些服务等等。

一组独立运行的一组pod资源,可以理解为应用程序,可以实现七层调度负载均衡。
若集群中存在N多个Node节点,可以通过DaemonSet 控制器运行一个为集群接入七层调度的负载均衡pod,用于转发至后端pod。
此pod监听nNodeIP+port,可以在前面搭建四层代理转发至这几台node节点,在通过这几个pod实现七层负载均衡至后端pod。

最佳实践

举个例子,现在集群有api、文件存储、前端3个service,可以通过一个ingress对象来实现图中的请求转发:

ingress 集群部署架构

ingress的两种转发模式

  1. 基于路径转发

  2. 基于server  name转发

ingress的部署模式

ingress的部署,需要考虑两个方面:

ingress-controller是作为pod来运行的,以什么方式部署比较好
ingress解决了把如何请求路由到集群内部,那它自己怎么暴露给外部比较好


下面列举一些目前常见的部署和暴露方式,具体使用哪种方式还是得根据实际需求来考虑决定。

Deployment+LoadBalancer模式的Service
如果要把ingress部署在公有云,那用这种方式比较合适。用Deployment部署ingress-controller,创建一个type为LoadBalancer的service关联这组pod。大部分公有云,都会为LoadBalancer的service自动创建一个负载均衡器,通常还绑定了公网地址。只要把域名解析指向该地址,就实现了集群服务的对外暴露。

Deployment+NodePort模式的Service
同样用deployment模式部署ingress-controller,并创建对应的服务,但是type为NodePort。这样,ingress就会暴露在集群节点ip的特定端口上。由于nodeport暴露的端口是随机端口,一般会在前面再搭建一套负载均衡器来转发请求。该方式一般用于宿主机是相对固定的环境ip地址不变的场景。
NodePort方式暴露ingress虽然简单方便,但是NodePort多了一层NAT,在请求量级很大时可能对性能会有一定影响。

DaemonSet+HostNetwork+nodeSelector
用DaemonSet结合nodeselector来部署ingress-controller到特定的node上,然后使用HostNetwork直接把该pod与宿主机node的网络打通,直接使用宿主机的80/433端口就能访问服务。这时,ingress-controller所在的node机器就很类似传统架构的边缘节点,比如机房入口的nginx服务器。该方式整个请求链路最简单,性能相对NodePort模式更好。缺点是由于直接利用宿主机节点的网络和端口,一个node只能部署一个ingress-controller pod。比较适合大并发的生产环境使用。

注意事项:使用hostnetwork DNS配置策略项必须使用:dnsPolicy: ClusterFirstWithHostNet,此项配置如果不指定,可能会导致内部svc域名无法解析。

附录:

k8s的dnsPolicy有哪几种?

在 Kubernetes 中,Pod 的 dnsPolicy 有以下几种类型:

  1. ClusterFirst(默认值):

    • 使用集群内的 DNS 解析服务(如 CoreDNS),优先解析集群内的域名。
    • 集群外的域名则通过节点的 DNS 配置解析。
  2. ClusterFirstWithHostNet

    • 类似 ClusterFirst,但专用于 Pod 使用主机网络(hostNetwork: true)的场景。
  3. Default

    • 使用节点的 DNS 配置,忽略集群的 DNS 服务。
  4. None

    • 不配置任何 DNS,需手动指定 dnsConfig

部署

使用helm安装

 修改参数

修改镜像地址,取消哈希校验

 修改版本,仓库

 固定部署节点,在deployment

 使用主机网络模式

 dns策略,使用主机dns

 设置svc网络类型

修改https为false,如果需要可以打开

为选择部署ingress的多个节点或一个节点打上标签,创建命名空间

如果主节点有污点则无法创建

 安装

 至此已经安装成功了。

使用ingress

部署ingress转发规则

复制代码
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-test
  namespace: linux40      //注意,非同一个namespace的svc,无法转发
  annotations:
    kubernetes.io/ingress.class: "nginx"  //注解
    nginx.ingress.kubernetes.io/use-regex: "true"  //开启正则
spec:
  rules:
    - host: www.magedu.com   //基于主机域名转发
      http:
        paths:
          - path: /   # 路径前缀匹配
            backend:
              serviceName: magedu-nginx-service   # 后端svc
              servicePort: 80  # svc端口
          - path: /webapp  # 多路径转发,同理多host匹配也是新增即可
            backend:
              serviceName: linux39-tomcat-app1-service
              servicePort: 80
复制代码

在新版本中。需要新增路径匹配类型参数 - pathType: Prefix 以及service

 部署查看

域名解析 

因为我们使用了hostnetwork,这个时候使用了本机ip+端口。所以应该把域名解析到部署ingress 转发规则的的主机ip

如果为nodeport或者则直接配集群任意节点即可。

 端口也被直接使用了主机端口。

三、拓展

3.1 进入ingress-controller pod,在/etc/nginx/conf.d目录下查看nginx.conf,可以查看到以下转发策略

复制代码
upstream upstream_balancer {
                server 0.0.0.1; # placeholder

                balancer_by_lua_block {
                        balancer.balance()
                }

                keepalive 32;

                keepalive_timeout  60s;
                keepalive_requests 100;

        }


server {
                server_name www.magedu.com ;

                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;

                # PEM sha: 1d79db9b8d38290f05f4c11572e7a284c02c4a4f
                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 /myapp {      # uri

                        set $namespace      "linux39";   # namespace
                        set $ingress_name   "ingress-magedu-nginx-service";
                        set $service_name   "linux39-tomcat-app1-service";    # 后端service名称
                        set $service_port   "80";
                        set $location_path  "/myapp";

                        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    "linux39-linux39-tomcat-app1-service-80";
                        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;

                }

                location / {

                        set $namespace      "linux39";
                        set $ingress_name   "ingress-magedu-nginx-service";
                        set $service_name   "magedu-nginx-service";
                        set $service_port   "80";
                        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    "linux39-magedu-nginx-service-80";
                        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;

                }

        }
复制代码
复制代码
cd /etc/ingress-controller/ssl/

$ ls
default-fake-certificate.pem

$ cat default-fake-certificate.pem
-----BEGIN CERTIFICATE-----
MIIDcDCCAligAwIBAgIRALJgcH7IPjDUE3BfuvHirsUwDQYJKoZIhvcNAQELBQAw0CalNAYr9iPhzhCYA9hiNywNgUeu+DdTjyydHYXrc59EOCRbgMzBGxFMh0tihoLS
H8uM4dx4HEDeJwwIfpbM8KLCVOw=
-----END CERTIFICATE-----

-----BEGIN RSA PRIVATE KEY-----
fq9xAoGBAIrHWRaToUOfzJg9cwNCschuQBmiRgDmY3YBS2lMhNvT0QRmfR38ObVK
iwnIR3rk1ChPJsZFEZcYM2H2KoKHFifl6Bb1ZIx7nGofFRSW28tgSVMz5g01vtYg
Wtaq+H7L/aUCRqa/mopBQu4QR2shbBLzR8+qrPmhncyNvJzJGpTO
-----END RSA PRIVATE KEY-----
复制代码

 

posted @   不会跳舞的胖子  阅读(1076)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律
点击右上角即可分享
微信分享提示