• 裸金属和NGINX Ingress


     首先,目前常用的Ingress-Nginx-Controller有两个。一个是K8S官方开源的Ingress-Nginx-Controller,另一个是nginx官方开源的Ingress-Nginx-Controller。我们使用的是K8S官方的版本。

      这两个Controller大致的区别如下:

      1)K8S官方的Controller也是采用Go语言开发的,集成了Lua实现的OpenResty;而Nginx官方的Ccontroller是集成了Nginx;

      2)两者对Nginx的配置不同,并且使用的nginx.conf配置模板也是不一样的,Nginx官方的采用两个模板文件以include的方式配置upstream;K8S官方版本采用Lua动态配置upstream,所以不需要reload。

      所以,在pod频繁变更的场景下,采用K8S官方版本不需要reload,影响会更小。 

      接下来,我们来看K8S官方的Ingress-Nginx-Controller是如何实现Metrics监控数据采集上报的。

    ingress-Nginx-Controller的配置分为两部分nginx.conf 和内存

    内存中的可以通过curl http://127.0.0.1:10246/configuration/backends访问

    ingress-nginx/rootfs/etc/nginx/template/nginx.tmpl:1392:            opentracing off;
    root@ubuntu:~/nginx_ingress# kubectl exec -it ingress-nginx-controller-7478b9dbb5-6qk65 -n ingress-nginx --  curl http://127.0.0.1:10246/configuration/backends
    [{"name":"default-apache-svc-80","service":{"metadata":{"creationTimestamp":null},"spec":{"ports":[{"protocol":"TCP","port":80,"targetPort":80}],"selector":{"app":"apache-app"},"clusterIP":"10.111.63.105","type":"ClusterIP","sessionAffinity":"None"},"status":{"loadBalancer":{}}},"port":80,"sslPassthrough":false,"endpoints":[{"address":"10.244.243.197","port":"80"},{"address":"10.244.41.61","port":"80"}],"sessionAffinityConfig":{"name":"","mode":"","cookieSessionAffinity":{"name":""}},"upstreamHashByConfig":{"upstream-hash-by-subset-size":3},"noServer":false,"trafficShapingPolicy":{"weight":0,"header":"","headerValue":"","headerPattern":"","cookie":""}},{"name":"default-nginx-svc-80","service":{"metadata":{"creationTimestamp":null},"spec":{"ports":[{"protocol":"TCP","port":80,"targetPort":80}],"selector":{"app":"nginx-app"},"clusterIP":"10.103.182.145","type":"ClusterIP","sessionAffinity":"None"},"status":{"loadBalancer":{}}},"port":80,"sslPassthrough":false,"endpoints":[{"address":"10.244.243.195","port":"80"},{"address":"10.244.41.58","port":"80"}],"sessionAffinityConfig":{"name":"","mode":"","cookieSessionAffinity":{"name":""}},"upstreamHashByConfig":{"upstream-hash-by-subset-size":3},"noServer":false,"trafficShapingPolicy":{"weight":0,"header":"","headerValue":"","headerPattern":"","cookie":""}},{"name":"default-web2-8097","service":{"metadata":{"creationTimestamp":null},"spec":{"ports":[{"protocol":"TCP","port":8097,"targetPort":80}],"selector":{"run":"web2"},"clusterIP":"10.99.87.66","type":"ClusterIP","sessionAffinity":"None"},"status":{"loadBalancer":{}}},"port":8097,"sslPassthrough":false,"endpoints":[{"address":"10.244.41.59","port":"80"}],"sessionAffinityConfig":{"name":"","mode":"","cookieSessionAffinity":{"name":""}},"upstreamHashByConfig":{"upstream-hash-by-subset-size":3},"noServer":false,"trafficShapingPolicy":{"weight":0,"header":"","headerValue":"","headerPattern":"","cookie":""}},{"name":"default-web3-8097","service":{"metadata":{"creationTimestamp":null},"spec":{"ports":[{"protocol":"TCP","port":8097,"targetPort":80}],"selector":{"run":"web3"},"clusterIP":"10.107.70.171","type":"ClusterIP","sessionAffinity":"None"},"status":{"loadBalancer":{}}},"port":8097,"sslPassthrough":false,"endpoints":[{"address":"10.244.41.55","port":"80"}],"sessionAffinityConfig":{"name":"","mode":"","cookieSessionAffinity":{"name":""}},"upstreamHashByConfig":{"upstream-hash-by-subset-size":3},"noServer":false,"trafficShapingPolicy":{"weight":0,"header":"","headerValue":"","headerPattern":"","cookie":""}},{"name":"upstream-default-backend","port":0,"sslPassthrough":false,"endpoints":[{"address":"127.0.0.1","port":"8181"}],"sessionAffinityConfig":{"name":"","mode":"","cookieSessionAffinity":{"name":""}},"upstreamHashByConfig":{},"noServer":false,"trafficShapingPolicy":{"weight":0,"header":"","headerValue":"","headerPattern":"","cookie":""}}]
    root@ubuntu:~/nginx_ingress# kubectl exec -it ingress-nginx-controller-7478b9dbb5-6qk65 -n ingress-nginx --  sh
    /etc/nginx $ ls
    fastcgi.conf            fastcgi_params.default  koi-win                 mime.types.default      nginx.conf              owasp-modsecurity-crs   template                win-utf
    fastcgi.conf.default    geoip                   lua                     modsecurity             nginx.conf.default      scgi_params             uwsgi_params
    fastcgi_params          koi-utf                 mime.types              modules                 opentracing.json        scgi_params.default     uwsgi_params.default
    /etc/nginx $ ps -elf 
    PID   USER     TIME  COMMAND
        1 www-data  0:00 /usr/bin/dumb-init -- /nginx-ingress-controller --publish-service=ingress-nginx/ingress-nginx-controller --election-id=ingress-controller-leader --ingress-class=nginx --configmap=ingress-nginx/ingress-nginx-controller --validating-web
        6 www-data 25:35 /nginx-ingress-controller --publish-service=ingress-nginx/ingress-nginx-controller --election-id=ingress-controller-leader --ingress-class=nginx --configmap=ingress-nginx/ingress-nginx-controller --validating-webhook=:8443 --validatin
       47 www-data  0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /etc/nginx/nginx.conf
       51 www-data  3:23 nginx: worker process
       52 www-data  3:12 nginx: worker process
       53 www-data  2:36 nginx: worker process
       54 www-data  2:38 nginx: worker process
       55 www-data  2:54 nginx: worker process
       56 www-data  3:15 nginx: worker process
       64 www-data  2:38 nginx: worker process
      102 www-data  2:39 nginx: worker process
      148 www-data  2:56 nginx: worker process
      192 www-data  2:38 nginx: worker process
      232 www-data  2:37 nginx: worker process
      268 www-data  2:54 nginx: worker process
      289 www-data  3:10 nginx: worker process
      324 www-data  2:55 nginx: worker process
      366 www-data  2:36 nginx: worker process
      418 www-data  2:38 nginx: worker process
      443 www-data  2:37 nginx: worker process
      479 www-data  2:38 nginx: worker process
      517 www-data  2:39 nginx: worker process
      541 www-data  2:38 nginx: worker process
      571 www-data  3:08 nginx: worker process
      596 www-data  2:41 nginx: worker process
      619 www-data  2:39 nginx: worker process
      647 www-data  2:39 nginx: worker process
      653 www-data  3:09 nginx: worker process
      684 www-data  2:41 nginx: worker process
      709 www-data  2:40 nginx: worker process
      737 www-data  2:41 nginx: worker process
      771 www-data  2:37 nginx: worker process
      808 www-data  2:38 nginx: worker process
      847 www-data  2:54 nginx: worker process
      882 www-data  3:11 nginx: worker process
      937 www-data  2:39 nginx: worker process
      996 www-data  2:38 nginx: worker process
    root@ubuntu:~/karmada/pkg#  kubectl get ingress -o wide
    NAME              CLASS    HOSTS                                    ADDRESS   PORTS   AGE
    example-ingress   <none>   ubuntu.com                                         80      18d
    micro-ingress     <none>   nginx.mydomain.com,apache.mydomain.com             80      18d
    web-ingress       <none>   web.mydomain.com                                   80      18d
    web-ingress-lb    <none>   web3.mydomain.com,web2.mydomain.com                80      18d
    root@cloud:~# kubectl get svc -n ingress-nginx
    NAME                                 TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)                      AGE
    ingress-nginx-controller             LoadBalancer   10.109.135.148   <pending>     80:31324/TCP,443:31274/TCP   18d
    ingress-nginx-controller-admission   ClusterIP      10.107.93.85     <none>        443/TCP                      18d
    root@cloud:~# curl -I -H "Host: web2.mydomain.com"  http://10.109.135.148
    HTTP/1.1 200 OK
    Date: Tue, 24 Aug 2021 09:58:54 GMT
    Content-Type: text/html
    Content-Length: 612
    Connection: keep-alive
    Last-Modified: Tue, 06 Jul 2021 14:59:17 GMT
    ETag: "60e46fc5-264"
    Accept-Ranges: bytes
    
    root@cloud:~#
    root@cloud:~# kubectl describe svc  ingress-nginx-controller    -n ingress-nginx | more
    Name:                     ingress-nginx-controller
    Namespace:                ingress-nginx
    Labels:                   app.kubernetes.io/component=controller
                              app.kubernetes.io/instance=ingress-nginx
                              app.kubernetes.io/managed-by=Helm
                              app.kubernetes.io/name=ingress-nginx
                              app.kubernetes.io/version=0.44.0
                              helm.sh/chart=ingress-nginx-3.23.0
    Annotations:              <none>
    Selector:                 app.kubernetes.io/component=controller,app.kubernetes.io/instance=ingress-nginx,app.kubernetes.io/name=ingress-nginx
    Type:                     LoadBalancer
    IP:                       10.109.135.148
    Port:                     http  80/TCP
    TargetPort:               http/TCP
    NodePort:                 http  31324/TCP
    Endpoints:                10.244.41.54:80
    Port:                     https  443/TCP
    TargetPort:               https/TCP
    NodePort:                 https  31274/TCP
    Endpoints:                10.244.41.54:443
    Session Affinity:         None
    External Traffic Policy:  Local
    HealthCheck NodePort:     32469
    Events:                   <none>
    root@cloud:~# kubectl get pod  -n ingress-nginx
    NAME                                        READY   STATUS    RESTARTS   AGE
    ingress-nginx-controller-7478b9dbb5-6qk65   1/1     Running   6          18d
    root@cloud:~# kubectl get pod  -n ingress-nginx -o wide
    NAME                                        READY   STATUS    RESTARTS   AGE   IP             NODE    NOMINATED NODE   READINESS GATES
    ingress-nginx-controller-7478b9dbb5-6qk65   1/1     Running   6          18d   10.244.41.54   cloud   <none>           <none>
    root@cloud:~# curl -I -H "Host: web2.mydomain.com"  http://10.244.41.54
    HTTP/1.1 200 OK
    Date: Tue, 24 Aug 2021 10:03:08 GMT
    Content-Type: text/html
    Content-Length: 612
    Connection: keep-alive
    Last-Modified: Tue, 06 Jul 2021 14:59:17 GMT
    ETag: "60e46fc5-264"
    Accept-Ranges: bytes
    
    root@cloud:~# 

     

    root@ubuntu:~# kubectl get pods -A  -o wide | grep nginx
    default          nginx-app-56b5bb67cc-mkfct                  1/1     Running            3          15d     10.244.41.58     cloud    <none>           <none>
    default          nginx-app-56b5bb67cc-s9jtk                  1/1     Running            0          19d     10.244.243.195   ubuntu   <none>           <none>
    default          nginx-karmada-f89759699-qcztn               1/1     Running            0          18h     10.244.41.51     cloud    <none>           <none>
    default          nginx-karmada-f89759699-vn47h               1/1     Running            0          18h     10.244.41.52     cloud    <none>           <none>
    ingress-nginx    ingress-nginx-controller-7478b9dbb5-6qk65   1/1     Running            6          19d     10.244.41.54     cloud    <none>           <none>
    root@ubuntu:~# netstat -pan | grep 10254
    root@ubuntu:~# kubectl exec -it ingress-nginx-controller-7478b9dbb5-6qk65 -n ingress-nginx -- sh
    /etc/nginx $ netstat -pan | grep 10254
    netstat: can't scan /proc - are you root?
    tcp        0      0 :::10254                :::*                    LISTEN      -
    tcp        0      0 ::ffff:10.244.41.54:10254 ::ffff:10.10.16.47:51780 TIME_WAIT   -
    tcp        0      0 ::ffff:10.244.41.54:10254 ::ffff:10.10.16.47:64858 TIME_WAIT   -
    tcp        0      0 ::ffff:10.244.41.54:10254 ::ffff:10.10.16.47:60173 TIME_WAIT   -
    tcp        0      0 ::ffff:10.244.41.54:10254 ::ffff:10.10.16.47:22861 TIME_WAIT   -
    tcp        0      0 ::ffff:10.244.41.54:10254 ::ffff:10.10.16.47:7885 TIME_WAIT   -
    tcp        0      0 ::ffff:10.244.41.54:10254 ::ffff:10.10.16.47:20247 TIME_WAIT   -
    tcp        0      0 ::ffff:10.244.41.54:10254 ::ffff:10.10.16.47:8397 TIME_WAIT   -
    tcp        0      0 ::ffff:10.244.41.54:10254 ::ffff:10.10.16.47:16263 TIME_WAIT   -
    tcp        0      0 ::ffff:10.244.41.54:10254 ::ffff:10.10.16.47:49831 TIME_WAIT   -
    tcp        0      0 ::ffff:10.244.41.54:10254 ::ffff:10.10.16.47:21393 TIME_WAIT   -
    tcp        0      0 ::ffff:10.244.41.54:10254 ::ffff:10.10.16.47:46450 TIME_WAIT   -
    tcp        0      0 ::ffff:10.244.41.54:10254 ::ffff:10.10.16.47:25988 TIME_WAIT   -
    /etc/nginx $ 

     

     

     curl http://127.0.0.1:10246/configuration/backends -o backend.json 

    updateCh

     ingress/controller/nginx.go

            for {
                    select {
                    case err := <-n.ngxErrCh:
                            if n.isShuttingDown {
                                    return
                            }
    
                            // if the nginx master process dies, the workers continue to process requests
                            // until the failure of the configured livenessProbe and restart of the pod.
                            if process.IsRespawnIfRequired(err) {
                                    return
                            }
    
                    case event := <-n.updateCh.Out():
                            if n.isShuttingDown {
                                    break
                            }
    
                            if evt, ok := event.(store.Event); ok {
                                    klog.V(3).InfoS("Event received", "type", evt.Type, "object", evt.Obj)
                                    if evt.Type == store.ConfigurationEvent {
                                            // TODO: is this necessary? Consider removing this special case
                                            n.syncQueue.EnqueueTask(task.GetDummyObject("configmap-change"))
                                            continue
                                    }
    
                                    n.syncQueue.EnqueueSkippableTask(evt.Obj)
                            } else {
                                    klog.Warningf("Unexpected event type received %T", event)
                            }
                    case <-n.stopCh:
                            return
                    }
            }

    syncQueue

    // Start starts the loop to keep the status in sync
    func (s statusSync) Run(stopCh chan struct{}) {
            go s.syncQueue.Run(time.Second, stopCh)
    
            // trigger initial sync
            s.syncQueue.EnqueueTask(task.GetDummyObject("sync status"))
    
            // when this instance is the leader we need to enqueue
            // an item to trigger the update of the Ingress status.
            wait.PollUntil(time.Duration(UpdateInterval)*time.Second, func() (bool, error) {
                    s.syncQueue.EnqueueTask(task.GetDummyObject("sync status"))
                    return false, nil
            }, stopCh)
    }

    reload

    // OnUpdate is called by the synchronization loop whenever configuration
    // changes were detected. The received backend Configuration is merged with the
    // configuration ConfigMap before generating the final configuration file.
    // Returns nil in case the backend was successfully reloaded.
    func (n *NGINXController) OnUpdate(ingressCfg ingress.Configuration) error {
            cfg := n.store.GetBackendConfiguration()
            cfg.Resolver = n.resolver
    
            content, err := n.generateTemplate(cfg, ingressCfg)
            if err != nil {
                    return err
            }
    
            err = createOpentracingCfg(cfg)
            if err != nil {
                    return err
            }
    
            err = n.testTemplate(content)
            if err != nil {
                    return err
            }
    
            if klog.V(2).Enabled() {
                    src, _ := ioutil.ReadFile(cfgPath)
                    if !bytes.Equal(src, content) {
                            tmpfile, err := ioutil.TempFile("", "new-nginx-cfg")
                            if err != nil {
                                    return err
                            }
                            defer tmpfile.Close()
                            err = ioutil.WriteFile(tmpfile.Name(), content, file.ReadWriteByUser)
                            if err != nil {
                                    return err
                            }
    
                            diffOutput, err := exec.Command("diff", "-I", "'# Configuration.*'", "-u", cfgPath, tmpfile.Name()).CombinedOutput()
                            if err != nil {
                                    if exitError, ok := err.(*exec.ExitError); ok {
                                            ws := exitError.Sys().(syscall.WaitStatus)
                                            if ws.ExitStatus() == 2 {
                                                    klog.Warningf("Failed to executing diff command: %v", err)
                                            }
                                    }
                            }
    
                            klog.InfoS("NGINX configuration change", "diff", string(diffOutput))
    
                            // we do not defer the deletion of temp files in order
                            // to keep them around for inspection in case of error
                            os.Remove(tmpfile.Name())
                    }
            }
    
            err = ioutil.WriteFile(cfgPath, content, file.ReadWriteByUser)
            if err != nil {
                    return err
            }
    
            o, err := n.command.ExecCommand("-s", "reload").CombinedOutput()
            if err != nil {
                    return fmt.Errorf("%v
    %v", err, string(o))
            }
    
            return nil
    }

    syncIngress

    // syncIngress collects all the pieces required to assemble the NGINX
    // configuration file and passes the resulting data structures to the backend
    // (OnUpdate) when a reload is deemed necessary.
    func (n *NGINXController) syncIngress(interface{}) error {
    
        // 获取最新配置信息
        ....
        // 构造 nginx 配置
        pcfg := &ingress.Configuration{
            Backends:              upstreams,
            Servers:               servers,
            PassthroughBackends:   passUpstreams,
            BackendConfigChecksum: n.store.GetBackendConfiguration().Checksum,
        }
        ...
        // 不能避免 reload,就执行 reload 更新配置
        if !n.IsDynamicConfigurationEnough(pcfg) {
            ...
            err := n.OnUpdate(*pcfg)
            ...
        }
        ...
        // 动态更新配置
        err := wait.ExponentialBackoff(retry, func() (bool, error) {
            err := configureDynamically(pcfg, n.cfg.ListenPorts.Status, n.cfg.DynamicCertificatesEnabled)
            ...
        })
        ...
    }

     

     nginx_request_exporter 通过 syslog 协议 收集并分析 Nginx 的 access log 来统计 HTTP 请求相关的一些指标;nginx-prometheus-shiny-exporter 和 nginx_request_exporter 类似,也是使用 syslog 协议来收集 access log

     nginx ingress controller configmap annotation template

     --election-id=ingress-controller-leader --ingress-class=nginx --configmap=ingress-nginx/ingress-nginx-controller --validating-webhook=:8443 

     

     

     template

     

     

     

     

     

     

     

     

    lua模块和c块有冲突,这些配置写在共享内存中

     

    lua写,不需要做reload

     

     

    Bare-metal considerations¶

    Porter-面向裸金属环境的 Kubernetes 开源负载均衡器

    Ingress-Nginx-Controller的Metrics监控源码改造简析

    通过traceID实例讲解 Nginx Ingress 参数配置 

    kubernetes云原生纪元:领悟Ingress Nginx template (中)

    kubernetes云原生纪元:领悟 Ingress Nginx(上)

    kubernetes云原生纪元:领悟 Ingress Nginx(下)

  • 相关阅读:
    2022年官网下安装Redis最全版与官网查阅方法
    vSphere 高级特性FT配置与管理
    光纤交换机长距离级联设置
    vSphere中Storage vMotion的流程详解
    vSphere HA 原理与配置
    vSphere 计算vMotion的迁移原理
    存储网络交换机SNS2124联链路未配置TRUNK导致性能问题
    Windows 远程时提示CredSSP 加密数据库修正 问题的简单处理.
    vSphere vSwitch网络属性配置详解
    什么是virtual Machine
  • 原文地址:https://www.cnblogs.com/dream397/p/15180869.html
Copyright © 2020-2023  润新知