zoukankan      html  css  js  c++  java
  • Nginx Ingress Controller

    官方文档:https://kubernetes.github.io/ingress-nginx/deploy/#bare-metal

    There are three ways to customize NGINX:

    1. ConfigMap: using a Configmap to set global configurations in NGINX.
    2. Annotations: use this if you want a specific configuration for a particular Ingress rule.
    3. Custom template: when more specific settings are required, like open_file_cache, adjust listen options as rcvbuf or when is not possible to change the configuration through the ConfigMap.

    Ingress-Controller配置说明


    1. 外部NG

    2. 内部NG

    污点容忍

    在污点容忍时,要注意预留一台无污点的机器地,因为在部署ingress-controller时需要执行二个脚本,用来生成key,如果没有无污点的机器(Job: ingress-nginx-admission-patch && Job: ingress-nginx-admission-create)报错

    1. 节点标签
      # be-nginx 标签
      kubernetes.io/env: prod
          kubernetes.io/ingress: prod-internal
      
      ---------------------------------------------------
      
      # fe-nginx 标签
      kubernetes.io/env: prod
          kubernetes.io/ingress: prod
    2. 污点容忍
      # be-nginx 污点配置
      <root@PROD-K8S-CP1 /var/log/kubernetes># kubectl taint node prod-be-k8s-wn1 ingress=prod-internal:NoExecute
      <root@PROD-K8S-CP1 /var/log/kubernetes># kubectl taint node prod-be-k8s-wn2 ingress=prod-internal:NoExecute
      
      ------------------------------------------------------------------------------------------
      
      # fe-nginx 污点配置
      <root@PROD-K8S-CP1 /var/log/kubernetes># kubectl taint node prod-fe-k8s-wn1 ingress=prod:NoExecute
      <root@PROD-K8S-CP1 /var/log/kubernetes># kubectl taint node prod-fe-k8s-wn2 ingress=prod:NoExecute

    prod-ingress

    1. 具体配置
      apiVersion: v1
      kind: Namespace
      metadata:
        name: ingress-nginx
        labels:
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
      
      ---
      # Source: ingress-nginx/templates/controller-serviceaccount.yaml
      apiVersion: v1
      kind: ServiceAccount
      metadata:
        labels:
          helm.sh/chart: ingress-nginx-2.9.0
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/version: 0.33.0
          app.kubernetes.io/managed-by: Helm
          app.kubernetes.io/component: controller
        name: ingress-nginx
        namespace: ingress-nginx
      ---
      # Source: ingress-nginx/templates/admission-webhooks/job-patch/serviceaccount.yaml
      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: ingress-nginx-admission
        annotations:
          helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
          helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
        labels:
          helm.sh/chart: ingress-nginx-2.9.0
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/version: 0.33.0
          app.kubernetes.io/managed-by: Helm
          app.kubernetes.io/component: admission-webhook
        namespace: ingress-nginx
      ---
      # Source: ingress-nginx/templates/controller-configmap.yaml
      apiVersion: v1
      kind: ConfigMap
      metadata:
        labels:
          helm.sh/chart: ingress-nginx-2.9.0
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/version: 0.33.0
          app.kubernetes.io/managed-by: Helm
          app.kubernetes.io/component: controller
        name: prod-ingress-template
        #name: ingress-nginx-controller
        namespace: ingress-nginx
      data:
      ---
      # Source: ingress-nginx/templates/clusterrole.yaml
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRole
      metadata:
        labels:
          helm.sh/chart: ingress-nginx-2.9.0
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/version: 0.33.0
          app.kubernetes.io/managed-by: Helm
        name: ingress-nginx
        namespace: ingress-nginx
      rules:
        - apiGroups:
            - ''
          resources:
            - configmaps
            - endpoints
            - nodes
            - pods
            - secrets
          verbs:
            - list
            - watch
        - apiGroups:
            - ''
          resources:
            - nodes
          verbs:
            - get
        - apiGroups:
            - ''
          resources:
            - services
          verbs:
            - get
            - list
            - update
            - watch
        - apiGroups:
            - extensions
            - networking.k8s.io   # k8s 1.14+
          resources:
            - ingresses
          verbs:
            - get
            - list
            - watch
        - apiGroups:
            - ''
          resources:
            - events
          verbs:
            - create
            - patch
        - apiGroups:
            - extensions
            - networking.k8s.io   # k8s 1.14+
          resources:
            - ingresses/status
          verbs:
            - update
        - apiGroups:
            - networking.k8s.io   # k8s 1.14+
          resources:
            - ingressclasses
          verbs:
            - get
            - list
            - watch
      ---
      # Source: ingress-nginx/templates/clusterrolebinding.yaml
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRoleBinding
      metadata:
        labels:
          helm.sh/chart: ingress-nginx-2.9.0
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/version: 0.33.0
          app.kubernetes.io/managed-by: Helm
        name: ingress-nginx
        namespace: ingress-nginx
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: ingress-nginx
      subjects:
        - kind: ServiceAccount
          name: ingress-nginx
          namespace: ingress-nginx
      ---
      # Source: ingress-nginx/templates/controller-role.yaml
      apiVersion: rbac.authorization.k8s.io/v1
      kind: Role
      metadata:
        labels:
          helm.sh/chart: ingress-nginx-2.9.0
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/version: 0.33.0
          app.kubernetes.io/managed-by: Helm
          app.kubernetes.io/component: controller
        name: ingress-nginx
        namespace: ingress-nginx
      rules:
        - apiGroups:
            - ''
          resources:
            - namespaces
          verbs:
            - get
        - apiGroups:
            - ''
          resources:
            - configmaps
            - pods
            - secrets
            - endpoints
          verbs:
            - get
            - list
            - watch
        - apiGroups:
            - ''
          resources:
            - services
          verbs:
            - get
            - list
            - update
            - watch
        - apiGroups:
            - extensions
            - networking.k8s.io   # k8s 1.14+
          resources:
            - ingresses
          verbs:
            - get
            - list
            - watch
        - apiGroups:
            - extensions
            - networking.k8s.io   # k8s 1.14+
          resources:
            - ingresses/status
          verbs:
            - update
        - apiGroups:
            - networking.k8s.io   # k8s 1.14+
          resources:
            - ingressclasses
          verbs:
            - get
            - list
            - watch
        - apiGroups:
            - ''
          resources:
            - configmaps
          resourceNames:
            - ingress-controller-leader-prod
          verbs:
            - get
            - update
        - apiGroups:
            - ''
          resources:
            - configmaps
          verbs:
            - create
        - apiGroups:
            - ''
          resources:
            - endpoints
          verbs:
            - create
            - get
            - update
        - apiGroups:
            - ''
          resources:
            - events
          verbs:
            - create
            - patch
      ---
      # Source: ingress-nginx/templates/controller-rolebinding.yaml
      apiVersion: rbac.authorization.k8s.io/v1
      kind: RoleBinding
      metadata:
        labels:
          helm.sh/chart: ingress-nginx-2.9.0
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/version: 0.33.0
          app.kubernetes.io/managed-by: Helm
          app.kubernetes.io/component: controller
        name: ingress-nginx
        namespace: ingress-nginx
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: Role
        name: ingress-nginx
      subjects:
        - kind: ServiceAccount
          name: ingress-nginx
          namespace: ingress-nginx
      ---
      # Source: ingress-nginx/templates/controller-service-webhook.yaml
      apiVersion: v1
      kind: Service
      metadata:
        labels:
          helm.sh/chart: ingress-nginx-2.9.0
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/version: 0.33.0
          app.kubernetes.io/managed-by: Helm
          app.kubernetes.io/component: controller
        name: ingress-nginx-controller-admission
        namespace: ingress-nginx
      spec:
        type: ClusterIP
        ports:
          - name: https-webhook
            port: 443
            targetPort: webhook
        selector:
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/component: controller
      ---
      # Source: ingress-nginx/templates/controller-service.yaml
      apiVersion: v1
      kind: Service
      metadata:
        labels:
          helm.sh/chart: ingress-nginx-2.9.0
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/version: 0.33.0
          app.kubernetes.io/managed-by: Helm
          app.kubernetes.io/component: controller
        name: prod-ingress
        namespace: ingress-nginx
      spec:
        type: ClusterIP
        ports:
          - name: http
            port: 80
            protocol: TCP
            targetPort: http
          - name: https
            port: 443
            protocol: TCP
            targetPort: https
        selector:
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/component: controller
      ---
      # Source: ingress-nginx/templates/controller-deployment.yaml
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        labels:
          helm.sh/chart: ingress-nginx-2.9.0
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/version: 0.33.0
          app.kubernetes.io/managed-by: Helm
          app.kubernetes.io/component: controller
        #name: ingress-nginx-controller
        name: prod-ingress
        namespace: ingress-nginx
      spec:
        selector:
          matchLabels:
            app.kubernetes.io/name: ingress-nginx
            app.kubernetes.io/instance: ingress-nginx
            app.kubernetes.io/component: controller
        revisionHistoryLimit: 10
        minReadySeconds: 0
        template:
          metadata:
            labels:
              app.kubernetes.io/name: ingress-nginx
              app.kubernetes.io/instance: ingress-nginx
              app.kubernetes.io/component: controller
          spec:
            dnsPolicy: ClusterFirst
            containers:
              - name: pord-ingress
                image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.33.0
                imagePullPolicy: IfNotPresent
                lifecycle:
                  preStop:
                    exec:
                      command:
                        - /wait-shutdown
                args:
                  - /nginx-ingress-controller
                  - --election-id=ingress-controller-leader
                  - --ingress-class=prod
                  - --configmap=ingress-nginx/prod-ingress-template
                  - --validating-webhook=:8443
                  - --validating-webhook-certificate=/usr/local/certificates/cert
                  - --validating-webhook-key=/usr/local/certificates/key
                securityContext:
                  capabilities:
                    drop:
                      - ALL
                    add:
                      - NET_BIND_SERVICE
                  runAsUser: 101
                  allowPrivilegeEscalation: true
                env:
                  - name: POD_NAME
                    valueFrom:
                      fieldRef:
                        fieldPath: metadata.name
                  - name: POD_NAMESPACE
                    valueFrom:
                      fieldRef:
                        fieldPath: metadata.namespace
                livenessProbe:
                  httpGet:
                    path: /healthz
                    port: 10254
                    scheme: HTTP
                  initialDelaySeconds: 10
                  periodSeconds: 10
                  timeoutSeconds: 1
                  successThreshold: 1
                  failureThreshold: 3
                readinessProbe:
                  httpGet:
                    path: /healthz
                    port: 10254
                    scheme: HTTP
                  initialDelaySeconds: 10
                  periodSeconds: 10
                  timeoutSeconds: 1
                  successThreshold: 1
                  failureThreshold: 3
                ports:
                  - name: http
                    containerPort: 80
                    protocol: TCP
                  - name: https
                    containerPort: 443
                    protocol: TCP
                  - name: webhook
                    containerPort: 8443
                    protocol: TCP
                volumeMounts:
                  - name: webhook-cert
                    mountPath: /usr/local/certificates/
                    readOnly: true
                  - name: localtime
                    mountPath: /etc/localtime
                resources:
                  requests:
                    cpu: 100m
                    memory: 512Mi
                  limits:
                    cpu: 2
                    memory: 3000Mi
            nodeSelector:
              kubernetes.io/os: linux
            affinity:
              nodeAffinity:
                requiredDuringSchedulingIgnoredDuringExecution:
                  nodeSelectorTerms:
                    - matchExpressions:
                        - key: kubernetes.io/ingress
                          operator: In
                          values:
                            - prod
              podAntiAffinity:
                requiredDuringSchedulingIgnoredDuringExecution:
                  - labelSelector:
                      matchExpressions:
                        - key: kubernetes.io/env
                          operator: In
                          values:
                            - prod
                    topologyKey: kubernetes.io/hostname
            tolerations:
              - key: ingress
                value: prod
                effect: NoExecute
            hostNetwork: true
            serviceAccountName: ingress-nginx
            terminationGracePeriodSeconds: 60
            volumes:
              - name: webhook-cert
                secret:
                  secretName: ingress-nginx-admission
              - name: localtime
                hostPath:
                  path: /etc/localtime
                  type: ""
      ---
      # Source: ingress-nginx/templates/admission-webhooks/validating-webhook.yaml
      # before changing this value, check the required kubernetes version
      # https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#prerequisites
      apiVersion: admissionregistration.k8s.io/v1beta1
      kind: ValidatingWebhookConfiguration
      metadata:
        labels:
          helm.sh/chart: ingress-nginx-2.9.0
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/version: 0.33.0
          app.kubernetes.io/managed-by: Helm
          app.kubernetes.io/component: admission-webhook
        name: ingress-nginx-admission
        namespace: ingress-nginx
      webhooks:
        - name: validate.nginx.ingress.kubernetes.io
          rules:
            - apiGroups:
                - extensions
                - networking.k8s.io
              apiVersions:
                - v1beta1
              operations:
                - CREATE
                - UPDATE
              resources:
                - ingresses
          failurePolicy: Fail
          sideEffects: None
          admissionReviewVersions:
            - v1
            - v1beta1
          clientConfig:
            service:
              namespace: ingress-nginx
              name: ingress-nginx-controller-admission
              path: /extensions/v1beta1/ingresses
      ---
      # Source: ingress-nginx/templates/admission-webhooks/job-patch/clusterrole.yaml
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRole
      metadata:
        name: ingress-nginx-admission
        annotations:
          helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
          helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
        labels:
          helm.sh/chart: ingress-nginx-2.9.0
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/version: 0.33.0
          app.kubernetes.io/managed-by: Helm
          app.kubernetes.io/component: admission-webhook
        namespace: ingress-nginx
      rules:
        - apiGroups:
            - admissionregistration.k8s.io
          resources:
            - validatingwebhookconfigurations
          verbs:
            - get
            - update
      ---
      # Source: ingress-nginx/templates/admission-webhooks/job-patch/clusterrolebinding.yaml
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRoleBinding
      metadata:
        name: ingress-nginx-admission
        annotations:
          helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
          helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
        labels:
          helm.sh/chart: ingress-nginx-2.9.0
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/version: 0.33.0
          app.kubernetes.io/managed-by: Helm
          app.kubernetes.io/component: admission-webhook
        namespace: ingress-nginx
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: ingress-nginx-admission
      subjects:
        - kind: ServiceAccount
          name: ingress-nginx-admission
          namespace: ingress-nginx
      ---
      # Source: ingress-nginx/templates/admission-webhooks/job-patch/job-createSecret.yaml
      apiVersion: batch/v1
      kind: Job
      metadata:
        name: ingress-nginx-admission-create
        annotations:
          helm.sh/hook: pre-install,pre-upgrade
          helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
        labels:
          helm.sh/chart: ingress-nginx-2.9.0
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/version: 0.33.0
          app.kubernetes.io/managed-by: Helm
          app.kubernetes.io/component: admission-webhook
        namespace: ingress-nginx
      spec:
        template:
          metadata:
            name: ingress-nginx-admission-create
            labels:
              helm.sh/chart: ingress-nginx-2.9.0
              app.kubernetes.io/name: ingress-nginx
              app.kubernetes.io/instance: ingress-nginx
              app.kubernetes.io/version: 0.33.0
              app.kubernetes.io/managed-by: Helm
              app.kubernetes.io/component: admission-webhook
          spec:
            containers:
              - name: create
                image: docker.io/jettech/kube-webhook-certgen:v1.2.0
                imagePullPolicy: IfNotPresent
                args:
                  - create
                  - --host=ingress-nginx-controller-admission,ingress-nginx-controller-admission.ingress-nginx.svc
                  - --namespace=ingress-nginx
                  - --secret-name=ingress-nginx-admission
            restartPolicy: OnFailure
            serviceAccountName: ingress-nginx-admission
            securityContext:
              runAsNonRoot: true
              runAsUser: 2000
      ---
      # Source: ingress-nginx/templates/admission-webhooks/job-patch/job-patchWebhook.yaml
      apiVersion: batch/v1
      kind: Job
      metadata:
        name: ingress-nginx-admission-patch
        annotations:
          helm.sh/hook: post-install,post-upgrade
          helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
        labels:
          helm.sh/chart: ingress-nginx-2.9.0
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/version: 0.33.0
          app.kubernetes.io/managed-by: Helm
          app.kubernetes.io/component: admission-webhook
        namespace: ingress-nginx
      spec:
        template:
          metadata:
            name: ingress-nginx-admission-patch
            labels:
              helm.sh/chart: ingress-nginx-2.9.0
              app.kubernetes.io/name: ingress-nginx
              app.kubernetes.io/instance: ingress-nginx
              app.kubernetes.io/version: 0.33.0
              app.kubernetes.io/managed-by: Helm
              app.kubernetes.io/component: admission-webhook
          spec:
            containers:
              - name: patch
                image: docker.io/jettech/kube-webhook-certgen:v1.2.0
                imagePullPolicy: IfNotPresent
                args:
                  - patch
                  - --webhook-name=ingress-nginx-admission
                  - --namespace=ingress-nginx
                  - --patch-mutating=false
                  - --secret-name=ingress-nginx-admission
                  - --patch-failure-policy=Fail
            restartPolicy: OnFailure
            serviceAccountName: ingress-nginx-admission
            securityContext:
              runAsNonRoot: true
              runAsUser: 2000
      ---
      # Source: ingress-nginx/templates/admission-webhooks/job-patch/role.yaml
      apiVersion: rbac.authorization.k8s.io/v1
      kind: Role
      metadata:
        name: ingress-nginx-admission
        annotations:
          helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
          helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
        labels:
          helm.sh/chart: ingress-nginx-2.9.0
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/version: 0.33.0
          app.kubernetes.io/managed-by: Helm
          app.kubernetes.io/component: admission-webhook
        namespace: ingress-nginx
      rules:
        - apiGroups:
            - ''
          resources:
            - secrets
          verbs:
            - get
            - create
      ---
      # Source: ingress-nginx/templates/admission-webhooks/job-patch/rolebinding.yaml
      apiVersion: rbac.authorization.k8s.io/v1
      kind: RoleBinding
      metadata:
        name: ingress-nginx-admission
        annotations:
          helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
          helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
        labels:
          helm.sh/chart: ingress-nginx-2.9.0
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/version: 0.33.0
          app.kubernetes.io/managed-by: Helm
          app.kubernetes.io/component: admission-webhook
        namespace: ingress-nginx
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: Role
        name: ingress-nginx-admission
      subjects:
        - kind: ServiceAccount
          name: ingress-nginx-admission
          namespace: ingress-nginx
      View Code
    2. 滚动更新、副本集
      spec:
        replicas: 2
      ....
        strategy:
          type: RollingUpdate
          rollingUpdate:
            maxUnavailable: 1
            maxSurge: 25%

    prod-internal-ingress

    1. 具体配置
      apiVersion: v1
      kind: Namespace
      metadata:
        name: ingress-nginx
        labels:
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
      
      ---
      # Source: ingress-nginx/templates/controller-serviceaccount.yaml
      apiVersion: v1
      kind: ServiceAccount
      metadata:
        labels:
          helm.sh/chart: ingress-nginx-2.9.0
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/version: 0.33.0
          app.kubernetes.io/managed-by: Helm
          app.kubernetes.io/component: controller
        name: ingress-nginx
        namespace: ingress-nginx
      ---
      # Source: ingress-nginx/templates/admission-webhooks/job-patch/serviceaccount.yaml
      apiVersion: v1
      kind: ServiceAccount
      metadata:
        name: ingress-nginx-admission
        annotations:
          helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
          helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
        labels:
          helm.sh/chart: ingress-nginx-2.9.0
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/version: 0.33.0
          app.kubernetes.io/managed-by: Helm
          app.kubernetes.io/component: admission-webhook
        namespace: ingress-nginx
      ---
      # Source: ingress-nginx/templates/controller-configmap.yaml
      apiVersion: v1
      kind: ConfigMap
      metadata:
        labels:
          helm.sh/chart: ingress-nginx-2.9.0
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/version: 0.33.0
          app.kubernetes.io/managed-by: Helm
          app.kubernetes.io/component: controller
        name: prod-internal-ingress-template
        #name: ingress-nginx-controller
        namespace: ingress-nginx
      data:
      ---
      # Source: ingress-nginx/templates/clusterrole.yaml
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRole
      metadata:
        labels:
          helm.sh/chart: ingress-nginx-2.9.0
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/version: 0.33.0
          app.kubernetes.io/managed-by: Helm
        name: ingress-nginx
        namespace: ingress-nginx
      rules:
        - apiGroups:
            - ''
          resources:
            - configmaps
            - endpoints
            - nodes
            - pods
            - secrets
          verbs:
            - list
            - watch
        - apiGroups:
            - ''
          resources:
            - nodes
          verbs:
            - get
        - apiGroups:
            - ''
          resources:
            - services
          verbs:
            - get
            - list
            - update
            - watch
        - apiGroups:
            - extensions
            - networking.k8s.io   # k8s 1.14+
          resources:
            - ingresses
          verbs:
            - get
            - list
            - watch
        - apiGroups:
            - ''
          resources:
            - events
          verbs:
            - create
            - patch
        - apiGroups:
            - extensions
            - networking.k8s.io   # k8s 1.14+
          resources:
            - ingresses/status
          verbs:
            - update
        - apiGroups:
            - networking.k8s.io   # k8s 1.14+
          resources:
            - ingressclasses
          verbs:
            - get
            - list
            - watch
      ---
      # Source: ingress-nginx/templates/clusterrolebinding.yaml
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRoleBinding
      metadata:
        labels:
          helm.sh/chart: ingress-nginx-2.9.0
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/version: 0.33.0
          app.kubernetes.io/managed-by: Helm
        name: ingress-nginx
        namespace: ingress-nginx
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: ingress-nginx
      subjects:
        - kind: ServiceAccount
          name: ingress-nginx
          namespace: ingress-nginx
      ---
      # Source: ingress-nginx/templates/controller-role.yaml
      apiVersion: rbac.authorization.k8s.io/v1
      kind: Role
      metadata:
        labels:
          helm.sh/chart: ingress-nginx-2.9.0
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/version: 0.33.0
          app.kubernetes.io/managed-by: Helm
          app.kubernetes.io/component: controller
        name: ingress-nginx
        namespace: ingress-nginx
      rules:
        - apiGroups:
            - ''
          resources:
            - namespaces
          verbs:
            - get
        - apiGroups:
            - ''
          resources:
            - configmaps
            - pods
            - secrets
            - endpoints
          verbs:
            - get
            - list
            - watch
        - apiGroups:
            - ''
          resources:
            - services
          verbs:
            - get
            - list
            - update
            - watch
        - apiGroups:
            - extensions
            - networking.k8s.io   # k8s 1.14+
          resources:
            - ingresses
          verbs:
            - get
            - list
            - watch
        - apiGroups:
            - extensions
            - networking.k8s.io   # k8s 1.14+
          resources:
            - ingresses/status
          verbs:
            - update
        - apiGroups:
            - networking.k8s.io   # k8s 1.14+
          resources:
            - ingressclasses
          verbs:
            - get
            - list
            - watch
        - apiGroups:
            - ''
          resources:
            - configmaps
          resourceNames:
            - ingress-controller-leader-prod
            - ingress-controller-leader-prod-internal
          verbs:
            - get
            - update
        - apiGroups:
            - ''
          resources:
            - configmaps
          verbs:
            - create
        - apiGroups:
            - ''
          resources:
            - endpoints
          verbs:
            - create
            - get
            - update
        - apiGroups:
            - ''
          resources:
            - events
          verbs:
            - create
            - patch
      ---
      # Source: ingress-nginx/templates/controller-rolebinding.yaml
      apiVersion: rbac.authorization.k8s.io/v1
      kind: RoleBinding
      metadata:
        labels:
          helm.sh/chart: ingress-nginx-2.9.0
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/version: 0.33.0
          app.kubernetes.io/managed-by: Helm
          app.kubernetes.io/component: controller
        name: ingress-nginx
        namespace: ingress-nginx
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: Role
        name: ingress-nginx
      subjects:
        - kind: ServiceAccount
          name: ingress-nginx
          namespace: ingress-nginx
      ---
      # Source: ingress-nginx/templates/controller-service-webhook.yaml
      apiVersion: v1
      kind: Service
      metadata:
        labels:
          helm.sh/chart: ingress-nginx-2.9.0
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/version: 0.33.0
          app.kubernetes.io/managed-by: Helm
          app.kubernetes.io/component: controller
        name: ingress-nginx-controller-admission
        namespace: ingress-nginx
      spec:
        type: ClusterIP
        ports:
          - name: https-webhook
            port: 443
            targetPort: webhook
        selector:
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/component: controller
      ---
      # Source: ingress-nginx/templates/controller-service.yaml
      apiVersion: v1
      kind: Service
      metadata:
        labels:
          helm.sh/chart: ingress-nginx-2.9.0
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/version: 0.33.0
          app.kubernetes.io/managed-by: Helm
          app.kubernetes.io/component: controller
        name: prod-internal-ingress
        namespace: ingress-nginx
      spec:
        type: ClusterIP
        ports:
          - name: http
            port: 80
            protocol: TCP
            targetPort: http
          - name: https
            port: 443
            protocol: TCP
            targetPort: https
        selector:
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/component: controller
      ---
      # Source: ingress-nginx/templates/controller-deployment.yaml
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        labels:
          helm.sh/chart: ingress-nginx-2.9.0
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/version: 0.33.0
          app.kubernetes.io/managed-by: Helm
          app.kubernetes.io/component: controller
        #name: ingress-nginx-controller
        name: prod-internal-ingress
        namespace: ingress-nginx
      spec:
        selector:
          matchLabels:
            app.kubernetes.io/name: ingress-nginx
            app.kubernetes.io/instance: ingress-nginx
            app.kubernetes.io/component: controller
        revisionHistoryLimit: 10
        minReadySeconds: 0
        template:
          metadata:
            labels:
              app.kubernetes.io/name: ingress-nginx
              app.kubernetes.io/instance: ingress-nginx
              app.kubernetes.io/component: controller
          spec:
            dnsPolicy: ClusterFirst
            containers:
              - name: prod-internal-ingress
                image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.33.0
                imagePullPolicy: IfNotPresent
                lifecycle:
                  preStop:
                    exec:
                      command:
                        - /wait-shutdown
                args:
                  - /nginx-ingress-controller
                  - --election-id=ingress-controller-leader
                  - --ingress-class=prod-internal
                  - --configmap=ingress-nginx/prod-internal-ingress-template
                  - --validating-webhook=:8443
                  - --validating-webhook-certificate=/usr/local/certificates/cert
                  - --validating-webhook-key=/usr/local/certificates/key
                securityContext:
                  capabilities:
                    drop:
                      - ALL
                    add:
                      - NET_BIND_SERVICE
                  runAsUser: 101
                  allowPrivilegeEscalation: true
                env:
                  - name: POD_NAME
                    valueFrom:
                      fieldRef:
                        fieldPath: metadata.name
                  - name: POD_NAMESPACE
                    valueFrom:
                      fieldRef:
                        fieldPath: metadata.namespace
                livenessProbe:
                  httpGet:
                    path: /healthz
                    port: 10254
                    scheme: HTTP
                  initialDelaySeconds: 10
                  periodSeconds: 10
                  timeoutSeconds: 1
                  successThreshold: 1
                  failureThreshold: 3
                readinessProbe:
                  httpGet:
                    path: /healthz
                    port: 10254
                    scheme: HTTP
                  initialDelaySeconds: 10
                  periodSeconds: 10
                  timeoutSeconds: 1
                  successThreshold: 1
                  failureThreshold: 3
                ports:
                  - name: http
                    containerPort: 80
                    protocol: TCP
                  - name: https
                    containerPort: 443
                    protocol: TCP
                  - name: webhook
                    containerPort: 8443
                    protocol: TCP
                volumeMounts:
                  - name: webhook-cert
                    mountPath: /usr/local/certificates/
                    readOnly: true
                  - name: localtime
                    mountPath: /etc/localtime
                resources:
                  requests:
                    cpu: 100m
                    memory: 512Mi
                  limits:
                    cpu: 2
                    memory: 3000Mi
            nodeSelector:
              kubernetes.io/os: linux
            affinity:
              nodeAffinity:
                requiredDuringSchedulingIgnoredDuringExecution:
                  nodeSelectorTerms:
                    - matchExpressions:
                        - key: kubernetes.io/ingress
                          operator: In
                          values:
                            - prod-internal
              podAntiAffinity:
                requiredDuringSchedulingIgnoredDuringExecution:
                  - labelSelector:
                      matchExpressions:
                        - key: kubernetes.io/env
                          operator: In
                          values:
                            - prod
                    topologyKey: kubernetes.io/hostname
            tolerations:
              - key: ingress
                value: prod-internal
                effect: NoExecute
            hostNetwork: true
            serviceAccountName: ingress-nginx
            terminationGracePeriodSeconds: 60
            volumes:
              - name: webhook-cert
                secret:
                  secretName: ingress-nginx-admission
              - name: localtime
                hostPath:
                  path: /etc/localtime
                  type: ""
      ---
      # Source: ingress-nginx/templates/admission-webhooks/validating-webhook.yaml
      # before changing this value, check the required kubernetes version
      # https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/#prerequisites
      apiVersion: admissionregistration.k8s.io/v1beta1
      kind: ValidatingWebhookConfiguration
      metadata:
        labels:
          helm.sh/chart: ingress-nginx-2.9.0
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/version: 0.33.0
          app.kubernetes.io/managed-by: Helm
          app.kubernetes.io/component: admission-webhook
        name: ingress-nginx-admission
        namespace: ingress-nginx
      webhooks:
        - name: validate.nginx.ingress.kubernetes.io
          rules:
            - apiGroups:
                - extensions
                - networking.k8s.io
              apiVersions:
                - v1beta1
              operations:
                - CREATE
                - UPDATE
              resources:
                - ingresses
          failurePolicy: Fail
          sideEffects: None
          admissionReviewVersions:
            - v1
            - v1beta1
          clientConfig:
            service:
              namespace: ingress-nginx
              name: ingress-nginx-controller-admission
              path: /extensions/v1beta1/ingresses
      ---
      # Source: ingress-nginx/templates/admission-webhooks/job-patch/clusterrole.yaml
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRole
      metadata:
        name: ingress-nginx-admission
        annotations:
          helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
          helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
        labels:
          helm.sh/chart: ingress-nginx-2.9.0
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/version: 0.33.0
          app.kubernetes.io/managed-by: Helm
          app.kubernetes.io/component: admission-webhook
        namespace: ingress-nginx
      rules:
        - apiGroups:
            - admissionregistration.k8s.io
          resources:
            - validatingwebhookconfigurations
          verbs:
            - get
            - update
      ---
      # Source: ingress-nginx/templates/admission-webhooks/job-patch/clusterrolebinding.yaml
      apiVersion: rbac.authorization.k8s.io/v1
      kind: ClusterRoleBinding
      metadata:
        name: ingress-nginx-admission
        annotations:
          helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
          helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
        labels:
          helm.sh/chart: ingress-nginx-2.9.0
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/version: 0.33.0
          app.kubernetes.io/managed-by: Helm
          app.kubernetes.io/component: admission-webhook
        namespace: ingress-nginx
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: ClusterRole
        name: ingress-nginx-admission
      subjects:
        - kind: ServiceAccount
          name: ingress-nginx-admission
          namespace: ingress-nginx
      ---
      # Source: ingress-nginx/templates/admission-webhooks/job-patch/job-createSecret.yaml
      apiVersion: batch/v1
      kind: Job
      metadata:
        name: ingress-nginx-admission-create
        annotations:
          helm.sh/hook: pre-install,pre-upgrade
          helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
        labels:
          helm.sh/chart: ingress-nginx-2.9.0
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/version: 0.33.0
          app.kubernetes.io/managed-by: Helm
          app.kubernetes.io/component: admission-webhook
        namespace: ingress-nginx
      spec:
        template:
          metadata:
            name: ingress-nginx-admission-create
            labels:
              helm.sh/chart: ingress-nginx-2.9.0
              app.kubernetes.io/name: ingress-nginx
              app.kubernetes.io/instance: ingress-nginx
              app.kubernetes.io/version: 0.33.0
              app.kubernetes.io/managed-by: Helm
              app.kubernetes.io/component: admission-webhook
          spec:
            containers:
              - name: create
                image: docker.io/jettech/kube-webhook-certgen:v1.2.0
                imagePullPolicy: IfNotPresent
                args:
                  - create
                  - --host=ingress-nginx-controller-admission,ingress-nginx-controller-admission.ingress-nginx.svc
                  - --namespace=ingress-nginx
                  - --secret-name=ingress-nginx-admission
            restartPolicy: OnFailure
            serviceAccountName: ingress-nginx-admission
            securityContext:
              runAsNonRoot: true
              runAsUser: 2000
      ---
      # Source: ingress-nginx/templates/admission-webhooks/job-patch/job-patchWebhook.yaml
      apiVersion: batch/v1
      kind: Job
      metadata:
        name: ingress-nginx-admission-patch
        annotations:
          helm.sh/hook: post-install,post-upgrade
          helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
        labels:
          helm.sh/chart: ingress-nginx-2.9.0
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/version: 0.33.0
          app.kubernetes.io/managed-by: Helm
          app.kubernetes.io/component: admission-webhook
        namespace: ingress-nginx
      spec:
        template:
          metadata:
            name: ingress-nginx-admission-patch
            labels:
              helm.sh/chart: ingress-nginx-2.9.0
              app.kubernetes.io/name: ingress-nginx
              app.kubernetes.io/instance: ingress-nginx
              app.kubernetes.io/version: 0.33.0
              app.kubernetes.io/managed-by: Helm
              app.kubernetes.io/component: admission-webhook
          spec:
            containers:
              - name: patch
                image: docker.io/jettech/kube-webhook-certgen:v1.2.0
                imagePullPolicy: IfNotPresent
                args:
                  - patch
                  - --webhook-name=ingress-nginx-admission
                  - --namespace=ingress-nginx
                  - --patch-mutating=false
                  - --secret-name=ingress-nginx-admission
                  - --patch-failure-policy=Fail
            restartPolicy: OnFailure
            serviceAccountName: ingress-nginx-admission
            securityContext:
              runAsNonRoot: true
              runAsUser: 2000
      ---
      # Source: ingress-nginx/templates/admission-webhooks/job-patch/role.yaml
      apiVersion: rbac.authorization.k8s.io/v1
      kind: Role
      metadata:
        name: ingress-nginx-admission
        annotations:
          helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
          helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
        labels:
          helm.sh/chart: ingress-nginx-2.9.0
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/version: 0.33.0
          app.kubernetes.io/managed-by: Helm
          app.kubernetes.io/component: admission-webhook
        namespace: ingress-nginx
      rules:
        - apiGroups:
            - ''
          resources:
            - secrets
          verbs:
            - get
            - create
      ---
      # Source: ingress-nginx/templates/admission-webhooks/job-patch/rolebinding.yaml
      apiVersion: rbac.authorization.k8s.io/v1
      kind: RoleBinding
      metadata:
        name: ingress-nginx-admission
        annotations:
          helm.sh/hook: pre-install,pre-upgrade,post-install,post-upgrade
          helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
        labels:
          helm.sh/chart: ingress-nginx-2.9.0
          app.kubernetes.io/name: ingress-nginx
          app.kubernetes.io/instance: ingress-nginx
          app.kubernetes.io/version: 0.33.0
          app.kubernetes.io/managed-by: Helm
          app.kubernetes.io/component: admission-webhook
        namespace: ingress-nginx
      roleRef:
        apiGroup: rbac.authorization.k8s.io
        kind: Role
        name: ingress-nginx-admission
      subjects:
        - kind: ServiceAccount
          name: ingress-nginx-admission
          namespace: ingress-nginx
      View Code
    2. 滚动更新、副本集
      spec:
        replicas: 2
      ....
        strategy:
          type: RollingUpdate
          rollingUpdate:
            maxUnavailable: 1
            maxSurge: 25%

    日志输出

    1. 编辑prod-ingress-template ConfigMap (lens),调整nginx日志输出格式
      log-format-upstream: >-
          $realip_remote_addr [$time_local] $server_name "$request" $request_time
          $status $body_bytes_sent "$http_referer" "$http_user_agent"
          "$http_x_forwarded_for" $proxy_upstream_name $upstream_addr
          "$upstream_response_time" "$upstream_status"
        map-hash-bucket-size: '256'
        nginx-status-ipv4-whitelist: all
        use-forwarded-headers: 'true'
    2. 创建ingresss的模板文件
      apiVersion: v1
      kind: ConfigMap
      metadata:
        name: nginx-tmpl
        namespace: ingress-nginx
      data:
        nginx.tmpl: |
          {{ $all := . }}
       
              {{ $servers := .Servers }}
       
              {{ $cfg := .Cfg }}
       
              {{ $IsIPV6Enabled := .IsIPV6Enabled }}
       
              {{ $healthzURI := .HealthzURI }}
       
              {{ $backends := .Backends }}
       
              {{ $proxyHeaders := .ProxySetHeaders }}
       
              {{ $addHeaders := .AddHeaders }}
       
       
              # Configuration checksum: {{ $all.Cfg.Checksum }}
       
       
              # setup custom paths that do not require root access
       
              pid {{ .PID }};
       
       
              {{ if $cfg.UseGeoIP2 }}
       
              load_module /etc/nginx/modules/ngx_http_geoip2_module.so;
       
              {{ end }}
       
       
              {{ if (shouldLoadModSecurityModule $cfg $servers) }}
       
              load_module /etc/nginx/modules/ngx_http_modsecurity_module.so;
       
              {{ end }}
       
       
              {{ if (shouldLoadOpentracingModule $cfg $servers) }}
       
              load_module /etc/nginx/modules/ngx_http_opentracing_module.so;
       
              {{ end }}
       
       
              daemon off;
       
       
              worker_processes {{ $cfg.WorkerProcesses }};
       
              {{ if gt (len $cfg.WorkerCPUAffinity) 0 }}
       
              worker_cpu_affinity {{ $cfg.WorkerCPUAffinity }};
       
              {{ end }}
       
       
              worker_rlimit_nofile {{ $cfg.MaxWorkerOpenFiles }};
       
       
              {{/* http://nginx.org/en/docs/ngx_core_module.html#worker_shutdown_timeout
              */}}
       
              {{/* avoid waiting too long during a reload */}}
       
              worker_shutdown_timeout {{ $cfg.WorkerShutdownTimeout }} ;
       
       
              {{ if not (empty $cfg.MainSnippet) }}
       
              {{ $cfg.MainSnippet }}
       
              {{ end }}
       
       
              events {
                  multi_accept        {{ if $cfg.EnableMultiAccept }}on{{ else }}off{{ end }};
                  worker_connections  {{ $cfg.MaxWorkerConnections }};
                  use                 epoll;
              }
       
       
              http {
                  lua_package_path "/etc/nginx/lua/?.lua;;";
       
                  {{ buildLuaSharedDictionaries $cfg $servers }}
       
                  init_by_lua_block {
                      collectgarbage("collect")
       
                      -- init modules
                      local ok, res
       
                      ok, res = pcall(require, "lua_ingress")
                      if not ok then
                        error("require failed: " .. tostring(res))
                      else
                        lua_ingress = res
                        lua_ingress.set_config({{ configForLua $all }})
                      end
       
                      ok, res = pcall(require, "configuration")
                      if not ok then
                        error("require failed: " .. tostring(res))
                      else
                        configuration = res
                      end
       
                      ok, res = pcall(require, "balancer")
                      if not ok then
                        error("require failed: " .. tostring(res))
                      else
                        balancer = res
                      end
       
                      {{ if $all.EnableMetrics }}
                      ok, res = pcall(require, "monitor")
                      if not ok then
                        error("require failed: " .. tostring(res))
                      else
                        monitor = res
                      end
                      {{ end }}
       
                      ok, res = pcall(require, "certificate")
                      if not ok then
                        error("require failed: " .. tostring(res))
                      else
                        certificate = res
                        certificate.is_ocsp_stapling_enabled = {{ $cfg.EnableOCSP }}
                      end
       
                      ok, res = pcall(require, "plugins")
                      if not ok then
                        error("require failed: " .. tostring(res))
                      else
                        plugins = res
                      end
                      -- load all plugins that'll be used here
                      plugins.init({ {{ range  $idx, $plugin := $cfg.Plugins }}{{ if $idx }},{{ end }}{{ $plugin | quote }}{{ end }} })
                  }
       
                  init_worker_by_lua_block {
                      lua_ingress.init_worker()
                      balancer.init_worker()
                      {{ if $all.EnableMetrics }}
                      monitor.init_worker()
                      {{ end }}
       
                      plugins.run()
                  }
       
                  {{/* Enable the real_ip module only if we use either X-Forwarded headers or Proxy Protocol. */}}
                  {{/* we use the value of the real IP for the geo_ip module */}}
                  {{ if or $cfg.UseForwardedHeaders $cfg.UseProxyProtocol }}
                  {{ if $cfg.UseProxyProtocol }}
                  real_ip_header      proxy_protocol;
                  {{ else }}
                  real_ip_header      {{ $cfg.ForwardedForHeader }};
                  {{ end }}
       
                  real_ip_recursive   on;
                  {{ range $trusted_ip := $cfg.ProxyRealIPCIDR }}
                  set_real_ip_from    {{ $trusted_ip }};
                  {{ end }}
                  {{ end }}
       
                  {{ if $all.Cfg.EnableModsecurity }}
                  modsecurity on;
       
                  modsecurity_rules_file /etc/nginx/modsecurity/modsecurity.conf;
       
                  {{ if $all.Cfg.EnableOWASPCoreRules }}
                  modsecurity_rules_file /etc/nginx/owasp-modsecurity-crs/nginx-modsecurity.conf;
                  {{ else if (not (empty $all.Cfg.ModsecuritySnippet)) }}
                  modsecurity_rules '
                    {{ $all.Cfg.ModsecuritySnippet }}
                  ';
                  {{ end }}
       
                  {{ end }}
       
                  {{ if $cfg.UseGeoIP }}
                  {{/* databases used to determine the country depending on the client IP address */}}
                  {{/* http://nginx.org/en/docs/http/ngx_http_geoip_module.html */}}
                  {{/* this is require to calculate traffic for individual country using GeoIP in the status page */}}
                  geoip_country       /etc/nginx/geoip/GeoIP.dat;
                  geoip_city          /etc/nginx/geoip/GeoLiteCity.dat;
                  geoip_org           /etc/nginx/geoip/GeoIPASNum.dat;
                  geoip_proxy_recursive on;
                  {{ end }}
       
                  {{ if $cfg.UseGeoIP2 }}
                  # https://github.com/leev/ngx_http_geoip2_module#example-usage
       
                  {{ range $index, $file := $all.MaxmindEditionFiles }}
                  {{ if eq $file "GeoLite2-City.mmdb" }}
                  geoip2 /etc/nginx/geoip/GeoLite2-City.mmdb {
                      $geoip2_city_country_code source=$remote_addr country iso_code;
                      $geoip2_city_country_name source=$remote_addr country names en;
                      $geoip2_city source=$remote_addr city names en;
                      $geoip2_postal_code source=$remote_addr postal code;
                      $geoip2_dma_code source=$remote_addr location metro_code;
                      $geoip2_latitude source=$remote_addr location latitude;
                      $geoip2_longitude source=$remote_addr location longitude;
                      $geoip2_time_zone source=$remote_addr location time_zone;
                      $geoip2_region_code source=$remote_addr subdivisions 0 iso_code;
                      $geoip2_region_name source=$remote_addr subdivisions 0 names en;
                  }
                  {{ end }}
       
                  {{ if eq $file "GeoIP2-City.mmdb" }}
                  geoip2 /etc/nginx/geoip/GeoIP2-City.mmdb {
                      $geoip2_city_country_code source=$remote_addr country iso_code;
                      $geoip2_city_country_name source=$remote_addr country names en;
                      $geoip2_city source=$remote_addr city names en;
                      $geoip2_postal_code source=$remote_addr postal code;
                      $geoip2_dma_code source=$remote_addr location metro_code;
                      $geoip2_latitude source=$remote_addr location latitude;
                      $geoip2_longitude source=$remote_addr location longitude;
                      $geoip2_time_zone source=$remote_addr location time_zone;
                      $geoip2_region_code source=$remote_addr subdivisions 0 iso_code;
                      $geoip2_region_name source=$remote_addr subdivisions 0 names en;
                  }
                  {{ end }}
       
                  {{ if eq $file "GeoLite2-ASN.mmdb" }}
                  geoip2 /etc/nginx/geoip/GeoLite2-ASN.mmdb {
                      $geoip2_asn source=$remote_addr autonomous_system_number;
                      $geoip2_org source=$remote_addr autonomous_system_organization;
                  }
                  {{ end }}
       
                  {{ if eq $file "GeoIP2-ASN.mmdb" }}
                  geoip2 /etc/nginx/geoip/GeoIP2-ASN.mmdb {
                      $geoip2_asn source=$remote_addr autonomous_system_number;
                      $geoip2_org source=$remote_addr autonomous_system_organization;
                  }
                  {{ end }}
       
                  {{ if eq $file "GeoIP2-ISP.mmdb" }}
                  geoip2 /etc/nginx/geoip/GeoIP2-ISP.mmdb {
                      $geoip2_isp isp;
                      $geoip2_isp_org organization;
                  }
                  {{ end }}
       
                  {{ if eq $file "GeoIP2-Connection-Type.mmdb" }}
                  geoip2 /etc/nginx/geoip/GeoIP2-Connection-Type.mmdb {
                      $geoip2_connection_type connection_type;
                  }
                  {{ end }}
       
                  {{ if eq $file "GeoIP2-Anonymous-IP.mmdb" }}
                  geoip2 /etc/nginx/geoip/GeoIP2-Anonymous-IP.mmdb {
                      $geoip2_is_anon source=$remote_addr is_anonymous;
                      $geoip2_is_hosting_provider source=$remote_addr is_hosting_provider;
                      $geoip2_is_public_proxy source=$remote_addr is_public_proxy;
                  }
                  {{ end }}
       
                  {{ end }}
       
                  {{ end }}
       
                  aio                 threads;
                  aio_write           on;
       
                  tcp_nopush          on;
                  tcp_nodelay         on;
       
                  log_subrequest      on;
       
                  reset_timedout_connection on;
       
                  keepalive_timeout  {{ $cfg.KeepAlive }}s;
                  keepalive_requests {{ $cfg.KeepAliveRequests }};
       
                  client_body_temp_path           /tmp/client-body;
                  fastcgi_temp_path               /tmp/fastcgi-temp;
                  proxy_temp_path                 /tmp/proxy-temp;
                  ajp_temp_path                   /tmp/ajp-temp;
       
                  client_header_buffer_size       {{ $cfg.ClientHeaderBufferSize }};
                  client_header_timeout           {{ $cfg.ClientHeaderTimeout }}s;
                  large_client_header_buffers     {{ $cfg.LargeClientHeaderBuffers }};
                  client_body_buffer_size         {{ $cfg.ClientBodyBufferSize }};
                  client_body_timeout             {{ $cfg.ClientBodyTimeout }}s;
       
                  http2_max_field_size            {{ $cfg.HTTP2MaxFieldSize }};
                  http2_max_header_size           {{ $cfg.HTTP2MaxHeaderSize }};
                  http2_max_requests              {{ $cfg.HTTP2MaxRequests }};
                  http2_max_concurrent_streams    {{ $cfg.HTTP2MaxConcurrentStreams }};
       
                  types_hash_max_size             2048;
                  server_names_hash_max_size      {{ $cfg.ServerNameHashMaxSize }};
                  server_names_hash_bucket_size   {{ $cfg.ServerNameHashBucketSize }};
                  map_hash_bucket_size            {{ $cfg.MapHashBucketSize }};
       
                  proxy_headers_hash_max_size     {{ $cfg.ProxyHeadersHashMaxSize }};
                  proxy_headers_hash_bucket_size  {{ $cfg.ProxyHeadersHashBucketSize }};
       
                  variables_hash_bucket_size      {{ $cfg.VariablesHashBucketSize }};
                  variables_hash_max_size         {{ $cfg.VariablesHashMaxSize }};
       
                  underscores_in_headers          {{ if $cfg.EnableUnderscoresInHeaders }}on{{ else }}off{{ end }};
                  ignore_invalid_headers          {{ if $cfg.IgnoreInvalidHeaders }}on{{ else }}off{{ end }};
       
                  limit_req_status                {{ $cfg.LimitReqStatusCode }};
                  limit_conn_status               {{ $cfg.LimitConnStatusCode }};
       
                  {{ buildOpentracing $cfg $servers }}
       
                  include /etc/nginx/mime.types;
                  default_type text/html;
       
                  {{ if $cfg.EnableBrotli }}
                  brotli on;
                  brotli_comp_level {{ $cfg.BrotliLevel }};
                  brotli_types {{ $cfg.BrotliTypes }};
                  {{ end }}
       
                  #{{ if $cfg.UseGzip }}
                  #gzip on;
                  #gzip_comp_level {{ $cfg.GzipLevel }};
                  #gzip_http_version 1.1;
                  #gzip_min_length {{ $cfg.GzipMinLength}};
                  #gzip_types {{ $cfg.GzipTypes }};
                  #gzip_proxied any;
                  #gzip_vary on;
                  #{{ end }}
       
                  # Custom headers for response
                  {{ range $k, $v := $addHeaders }}
                  more_set_headers {{ printf "%s: %s" $k $v | quote }};
                  {{ end }}
       
                  server_tokens {{ if $cfg.ShowServerTokens }}on{{ else }}off{{ end }};
                  {{ if not $cfg.ShowServerTokens }}
                  more_clear_headers Server;
                  {{ end }}
       
                  # disable warnings
                  uninitialized_variable_warn off;
       
                  # Additional available variables:
                  # $namespace
                  # $ingress_name
                  # $service_name
                  # $service_port
                  log_format upstreaminfo {{ if $cfg.LogFormatEscapeJSON }}escape=json {{ end }}'{{ $cfg.LogFormatUpstream }}';
       
                  {{/* map urls that should not appear in access.log */}}
                  {{/* http://nginx.org/en/docs/http/ngx_http_log_module.html#access_log */}}
                  map $request_uri $loggable {
                      {{ range $reqUri := $cfg.SkipAccessLogURLs }}
                      {{ $reqUri }} 0;{{ end }}
                      default 1;
                  }
       
                  {{ if $cfg.EnableSyslog }}
                  error_log syslog:server={{ $cfg.SyslogHost }}:{{ $cfg.SyslogPort }} {{ $cfg.ErrorLogLevel }};
                  {{ else }}
                  error_log  {{ $cfg.ErrorLogPath }} {{ $cfg.ErrorLogLevel }};
                  {{ end }}
       
                  {{ buildResolvers $cfg.Resolver $cfg.DisableIpv6DNS }}
       
                  # See https://www.nginx.com/blog/websocket-nginx
                  map $http_upgrade $connection_upgrade {
                      default          upgrade;
                      {{ if (gt $cfg.UpstreamKeepaliveConnections 0) }}
                      # See http://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive
                      ''               '';
                      {{ else }}
                      ''               close;
                      {{ end }}
                  }
       
                  # Reverse proxies can detect if a client provides a X-Request-ID header, and pass it on to the backend server.
                  # If no such header is provided, it can provide a random value.
                  map $http_x_request_id $req_id {
                      default   $http_x_request_id;
                      {{ if $cfg.GenerateRequestID }}
                      ""        $request_id;
                      {{ end }}
                  }
       
                  {{ if and $cfg.UseForwardedHeaders $cfg.ComputeFullForwardedFor }}
                  # We can't use $proxy_add_x_forwarded_for because the realip module
                  # replaces the remote_addr too soon
                  map $http_x_forwarded_for $full_x_forwarded_for {
                      {{ if $all.Cfg.UseProxyProtocol }}
                      default          "$http_x_forwarded_for, $proxy_protocol_addr";
                      ''               "$proxy_protocol_addr";
                      {{ else }}
                      default          "$http_x_forwarded_for, $realip_remote_addr";
                      ''               "$realip_remote_addr";
                      {{ end}}
                  }
       
                  map $http_x_forwarded_proto $full_x_forwarded_proto {
                      default $http_x_forwarded_proto;
                      "" $scheme;
                  }
       
                  {{ end }}
       
                  # Create a variable that contains the literal $ character.
                  # This works because the geo module will not resolve variables.
                  geo $literal_dollar {
                      default "$";
                  }
       
                  server_name_in_redirect off;
                  port_in_redirect        off;
       
                  ssl_protocols {{ $cfg.SSLProtocols }};
       
                  ssl_early_data {{ if $cfg.SSLEarlyData }}on{{ else }}off{{ end }};
       
                  # turn on session caching to drastically improve performance
                  {{ if $cfg.SSLSessionCache }}
                  ssl_session_cache builtin:1000 shared:SSL:{{ $cfg.SSLSessionCacheSize }};
                  ssl_session_timeout {{ $cfg.SSLSessionTimeout }};
                  {{ end }}
       
                  # allow configuring ssl session tickets
                  ssl_session_tickets {{ if $cfg.SSLSessionTickets }}on{{ else }}off{{ end }};
       
                  {{ if not (empty $cfg.SSLSessionTicketKey ) }}
                  ssl_session_ticket_key /etc/nginx/tickets.key;
                  {{ end }}
       
                  # slightly reduce the time-to-first-byte
                  ssl_buffer_size {{ $cfg.SSLBufferSize }};
       
                  {{ if not (empty $cfg.SSLCiphers) }}
                  # allow configuring custom ssl ciphers
                  ssl_ciphers '{{ $cfg.SSLCiphers }}';
                  ssl_prefer_server_ciphers on;
                  {{ end }}
       
                  {{ if not (empty $cfg.SSLDHParam) }}
                  # allow custom DH file http://nginx.org/en/docs/http/ngx_http_ssl_module.html#ssl_dhparam
                  ssl_dhparam {{ $cfg.SSLDHParam }};
                  {{ end }}
       
                  ssl_ecdh_curve {{ $cfg.SSLECDHCurve }};
       
                  # PEM sha: {{ $cfg.DefaultSSLCertificate.PemSHA }}
                  ssl_certificate     {{ $cfg.DefaultSSLCertificate.PemFileName }};
                  ssl_certificate_key {{ $cfg.DefaultSSLCertificate.PemFileName }};
       
                  {{ if gt (len $cfg.CustomHTTPErrors) 0 }}
                  proxy_intercept_errors on;
                  {{ end }}
       
                  {{ range $errCode := $cfg.CustomHTTPErrors }}
                  error_page {{ $errCode }} = @custom_upstream-default-backend_{{ $errCode }};{{ end }}
       
                  proxy_ssl_session_reuse on;
       
                  {{ if $cfg.AllowBackendServerHeader }}
                  proxy_pass_header Server;
                  {{ end }}
       
                  {{ range $header := $cfg.HideHeaders }}proxy_hide_header {{ $header }};
                  {{ end }}
       
                  {{ if not (empty $cfg.HTTPSnippet) }}
                  # Custom code snippet configured in the configuration configmap
                  {{ $cfg.HTTPSnippet }}
                  {{ end }}
       
                  upstream upstream_balancer {
                      ### Attention!!!
                      #
                      # We no longer create "upstream" section for every backend.
                      # Backends are handled dynamically using Lua. If you would like to debug
                      # and see what backends ingress-nginx has in its memory you can
                      # install our kubectl plugin https://kubernetes.github.io/ingress-nginx/kubectl-plugin.
                      # Once you have the plugin you can use "kubectl ingress-nginx backends" command to
                      # inspect current backends.
                      #
                      ###
       
                      server 0.0.0.1; # placeholder
       
                      balancer_by_lua_block {
                        balancer.balance()
                      }
       
                      {{ if (gt $cfg.UpstreamKeepaliveConnections 0) }}
                      keepalive {{ $cfg.UpstreamKeepaliveConnections }};
       
                      keepalive_timeout  {{ $cfg.UpstreamKeepaliveTimeout }}s;
                      keepalive_requests {{ $cfg.UpstreamKeepaliveRequests }};
                      {{ end }}
                  }
       
                  {{ range $rl := (filterRateLimits $servers ) }}
                  # Ratelimit {{ $rl.Name }}
                  geo $remote_addr $whitelist_{{ $rl.ID }} {
                      default 0;
                      {{ range $ip := $rl.Whitelist }}
                      {{ $ip }} 1;{{ end }}
                  }
       
                  # Ratelimit {{ $rl.Name }}
                  map $whitelist_{{ $rl.ID }} $limit_{{ $rl.ID }} {
                      0 {{ $cfg.LimitConnZoneVariable }};
                      1 "";
                  }
                  {{ end }}
       
                  {{/* build all the required rate limit zones. Each annotation requires a dedicated zone */}}
                  {{/* 1MB -> 16 thousand 64-byte states or about 8 thousand 128-byte states */}}
                  {{ range $zone := (buildRateLimitZones $servers) }}
                  {{ $zone }}
                  {{ end }}
       
                  # Cache for internal auth checks
                  proxy_cache_path /tmp/nginx-cache-auth levels=1:2 keys_zone=auth_cache:10m max_size=128m inactive=30m use_temp_path=off;
       
                  # Global filters
                  {{ range $ip := $cfg.BlockCIDRs }}deny {{ trimSpace $ip }};
                  {{ end }}
       
                  {{ if gt (len $cfg.BlockUserAgents) 0 }}
                  map $http_user_agent $block_ua {
                      default 0;
       
                      {{ range $ua := $cfg.BlockUserAgents }}{{ trimSpace $ua }} 1;
                      {{ end }}
                  }
                  {{ end }}
       
                  {{ if gt (len $cfg.BlockReferers) 0 }}
                  map $http_referer $block_ref {
                      default 0;
       
                      {{ range $ref := $cfg.BlockReferers }}{{ trimSpace $ref }} 1;
                      {{ end }}
                  }
                  {{ end }}
       
                  {{/* Build server redirects (from/to www) */}}
                  {{ range $redirect := .RedirectServers }}
                  ## start server {{ $redirect.From }}
                  server {
                      server_name {{ $redirect.From }};
       
                      {{ buildHTTPListener  $all $redirect.From }}
                      {{ buildHTTPSListener $all $redirect.From }}
       
                      ssl_certificate_by_lua_block {
                          certificate.call()
                      }
       
                      {{ if gt (len $cfg.BlockUserAgents) 0 }}
                      if ($block_ua) {
                         return 403;
                      }
                      {{ end }}
                      {{ if gt (len $cfg.BlockReferers) 0 }}
                      if ($block_ref) {
                         return 403;
                      }
                      {{ end }}
       
                      {{ if ne $all.ListenPorts.HTTPS 443 }}
                      {{ $redirect_port := (printf ":%v" $all.ListenPorts.HTTPS) }}
                      return {{ $all.Cfg.HTTPRedirectCode }} $scheme://{{ $redirect.To }}{{ $redirect_port }}$request_uri;
                      {{ else }}
                      return {{ $all.Cfg.HTTPRedirectCode }} $scheme://{{ $redirect.To }}$request_uri;
                      {{ end }}
                  }
                  ## end server {{ $redirect.From }}
                  {{ end }}
       
                  {{ range $server := $servers }}
       
                  ## start server {{ $server.Hostname }}
                  server {
                      server_name {{ $server.Hostname }} {{range $server.Aliases }}{{ . }} {{ end }};
       
                      {{ if gt (len $cfg.BlockUserAgents) 0 }}
                      if ($block_ua) {
                         return 403;
                      }
                      {{ end }}
                      {{ if gt (len $cfg.BlockReferers) 0 }}
                      if ($block_ref) {
                         return 403;
                      }
                      {{ end }}
       
                      {{ if $cfg.DisableAccessLog }}
                      access_log off;
                      {{ else }}
                      {{ if $cfg.EnableSyslog }}
                      access_log syslog:server={{ $cfg.SyslogHost }}:{{ $cfg.SyslogPort }} upstreaminfo if=$loggable;
                      {{ else }}
                      access_log /var/log/nginx/{{ $server.Hostname }}.log upstreaminfo {{ $cfg.AccessLogParams }} if=$loggable;
                      {{ end }}
                      {{ end }}
       
                      {{ template "SERVER" serverConfig $all $server }}
       
                      {{ if not (empty $cfg.ServerSnippet) }}
                      # Custom code snippet configured in the configuration configmap
                      {{ $cfg.ServerSnippet }}
                      {{ end }}
       
                      {{ template "CUSTOM_ERRORS" (buildCustomErrorDeps "upstream-default-backend" $cfg.CustomHTTPErrors $all.EnableMetrics) }}
                  }
                  ## end server {{ $server.Hostname }}
       
                  {{ end }}
       
                  # backend for when default-backend-service is not configured or it does not have endpoints
                  server {
                      listen {{ $all.ListenPorts.Default }} default_server {{ if $all.Cfg.ReusePort }}reuseport{{ end }} backlog={{ $all.BacklogSize }};
                      {{ if $IsIPV6Enabled }}listen [::]:{{ $all.ListenPorts.Default }} default_server {{ if $all.Cfg.ReusePort }}reuseport{{ end }} backlog={{ $all.BacklogSize }};{{ end }}
                      set $proxy_upstream_name "internal";
       
                      location / {
                        return 404;
                      }
                  }
       
                  # default server, used for NGINX healthcheck and access to nginx stats
                  server {
                      listen 127.0.0.1:{{ .StatusPort }};
                      set $proxy_upstream_name "internal";
       
                      keepalive_timeout 0;
                      gzip off;
       
                      access_log off;
       
                      {{ if $cfg.EnableOpentracing }}
                      opentracing off;
                      {{ end }}
       
                      location {{ $healthzURI }} {
                          return 200;
                      }
       
                      location /is-dynamic-lb-initialized {
                          content_by_lua_block {
                              local configuration = require("configuration")
                              local backend_data = configuration.get_backends_data()
                              if not backend_data then
                                  ngx.exit(ngx.HTTP_INTERNAL_SERVER_ERROR)
                                  return
                              end
       
                              ngx.say("OK")
                              ngx.exit(ngx.HTTP_OK)
                          }
                      }
       
                      location {{ .StatusPath }} {
                          stub_status on;
                      }
       
                      location /configuration {
                          client_max_body_size                    {{ luaConfigurationRequestBodySize $cfg }}m;
                          client_body_buffer_size                 {{ luaConfigurationRequestBodySize $cfg }}m;
                          proxy_buffering                         off;
       
                          content_by_lua_block {
                            configuration.call()
                          }
                      }
       
                      location / {
                          content_by_lua_block {
                              ngx.exit(ngx.HTTP_NOT_FOUND)
                          }
                      }
                  }
              }
       
       
              stream {
                  lua_package_path "/etc/nginx/lua/?.lua;/etc/nginx/lua/vendor/?.lua;;";
       
                  lua_shared_dict tcp_udp_configuration_data 5M;
       
                  init_by_lua_block {
                      collectgarbage("collect")
       
                      -- init modules
                      local ok, res
       
                      ok, res = pcall(require, "configuration")
                      if not ok then
                        error("require failed: " .. tostring(res))
                      else
                        configuration = res
                      end
       
                      ok, res = pcall(require, "tcp_udp_configuration")
                      if not ok then
                        error("require failed: " .. tostring(res))
                      else
                        tcp_udp_configuration = res
                      end
       
                      ok, res = pcall(require, "tcp_udp_balancer")
                      if not ok then
                        error("require failed: " .. tostring(res))
                      else
                        tcp_udp_balancer = res
                      end
                  }
       
                  init_worker_by_lua_block {
                      tcp_udp_balancer.init_worker()
                  }
       
                  lua_add_variable $proxy_upstream_name;
       
                  log_format log_stream '{{ $cfg.LogFormatStream }}';
       
                  {{ if $cfg.DisableAccessLog }}
                  access_log off;
                  {{ else }}
                  access_log {{ or $cfg.StreamAccessLogPath $cfg.AccessLogPath }} log_stream {{ $cfg.AccessLogParams }};
                  {{ end }}
       
                  error_log  {{ $cfg.ErrorLogPath }};
       
                  upstream upstream_balancer {
                      server 0.0.0.1:1234; # placeholder
       
                      balancer_by_lua_block {
                        tcp_udp_balancer.balance()
                      }
                  }
       
                  server {
                      listen 127.0.0.1:{{ .StreamPort }};
       
                      access_log off;
       
                      content_by_lua_block {
                        tcp_udp_configuration.call()
                      }
                  }
       
                  # TCP services
                  {{ range $tcpServer := .TCPBackends }}
                  server {
                      preread_by_lua_block {
                          ngx.var.proxy_upstream_name="tcp-{{ $tcpServer.Backend.Namespace }}-{{ $tcpServer.Backend.Name }}-{{ $tcpServer.Backend.Port }}";
                      }
       
                      {{ range $address := $all.Cfg.BindAddressIpv4 }}
                      listen                  {{ $address }}:{{ $tcpServer.Port }}{{ if $tcpServer.Backend.ProxyProtocol.Decode }} proxy_protocol{{ end }};
                      {{ else }}
                      listen                  {{ $tcpServer.Port }}{{ if $tcpServer.Backend.ProxyProtocol.Decode }} proxy_protocol{{ end }};
                      {{ end }}
                      {{ if $IsIPV6Enabled }}
                      {{ range $address := $all.Cfg.BindAddressIpv6 }}
                      listen                  {{ $address }}:{{ $tcpServer.Port }}{{ if $tcpServer.Backend.ProxyProtocol.Decode }} proxy_protocol{{ end }};
                      {{ else }}
                      listen                  [::]:{{ $tcpServer.Port }}{{ if $tcpServer.Backend.ProxyProtocol.Decode }} proxy_protocol{{ end }};
                      {{ end }}
                      {{ end }}
                      proxy_timeout           {{ $cfg.ProxyStreamTimeout }};
                      proxy_pass              upstream_balancer;
                      {{ if $tcpServer.Backend.ProxyProtocol.Encode }}
                      proxy_protocol          on;
                      {{ end }}
                  }
                  {{ end }}
       
                  # UDP services
                  {{ range $udpServer := .UDPBackends }}
                  server {
                      preread_by_lua_block {
                          ngx.var.proxy_upstream_name="udp-{{ $udpServer.Backend.Namespace }}-{{ $udpServer.Backend.Name }}-{{ $udpServer.Backend.Port }}";
                      }
       
                      {{ range $address := $all.Cfg.BindAddressIpv4 }}
                      listen                  {{ $address }}:{{ $udpServer.Port }} udp;
                      {{ else }}
                      listen                  {{ $udpServer.Port }} udp;
                      {{ end }}
                      {{ if $IsIPV6Enabled }}
                      {{ range $address := $all.Cfg.BindAddressIpv6 }}
                      listen                  {{ $address }}:{{ $udpServer.Port }} udp;
                      {{ else }}
                      listen                  [::]:{{ $udpServer.Port }} udp;
                      {{ end }}
                      {{ end }}
                      proxy_responses         {{ $cfg.ProxyStreamResponses }};
                      proxy_timeout           {{ $cfg.ProxyStreamTimeout }};
                      proxy_pass              upstream_balancer;
                  }
                  {{ end }}
              }
       
       
              {{/* definition of templates to avoid repetitions */}}
       
              {{ define "CUSTOM_ERRORS" }}
                      {{ $enableMetrics := .EnableMetrics }}
                      {{ $upstreamName := .UpstreamName }}
                      {{ range $errCode := .ErrorCodes }}
                      location @custom_{{ $upstreamName }}_{{ $errCode }} {
                          internal;
       
                          proxy_intercept_errors off;
       
                          proxy_set_header       X-Code             {{ $errCode }};
                          proxy_set_header       X-Format           $http_accept;
                          proxy_set_header       X-Original-URI     $request_uri;
                          proxy_set_header       X-Namespace        $namespace;
                          proxy_set_header       X-Ingress-Name     $ingress_name;
                          proxy_set_header       X-Service-Name     $service_name;
                          proxy_set_header       X-Service-Port     $service_port;
                          proxy_set_header       X-Request-ID       $req_id;
                          proxy_set_header       Host               $best_http_host;
       
                          set $proxy_upstream_name {{ $upstreamName | quote }};
       
                          rewrite                (.*) / break;
                          proxy_pass            http://upstream_balancer;
                          log_by_lua_block {
                              {{ if $enableMetrics }}
                              monitor.call()
                              {{ end }}
                          }
                      }
                      {{ end }}
              {{ end }}
       
       
              {{/* CORS support from
              https://michielkalkman.com/snippets/nginx-cors-open-configuration.html */}}
       
              {{ define "CORS" }}
                   {{ $cors := .CorsConfig }}
                   # Cors Preflight methods needs additional options and different Return Code
                   if ($request_method = 'OPTIONS') {
                      more_set_headers 'Access-Control-Allow-Origin: {{ $cors.CorsAllowOrigin }}';
                      {{ if $cors.CorsAllowCredentials }} more_set_headers 'Access-Control-Allow-Credentials: {{ $cors.CorsAllowCredentials }}'; {{ end }}
                      more_set_headers 'Access-Control-Allow-Methods: {{ $cors.CorsAllowMethods }}';
                      more_set_headers 'Access-Control-Allow-Headers: {{ $cors.CorsAllowHeaders }}';
                      more_set_headers 'Access-Control-Max-Age: {{ $cors.CorsMaxAge }}';
                      more_set_headers 'Content-Type: text/plain charset=UTF-8';
                      more_set_headers 'Content-Length: 0';
                      return 204;
                   }
       
                      more_set_headers 'Access-Control-Allow-Origin: {{ $cors.CorsAllowOrigin }}';
                      {{ if $cors.CorsAllowCredentials }} more_set_headers 'Access-Control-Allow-Credentials: {{ $cors.CorsAllowCredentials }}'; {{ end }}
                      more_set_headers 'Access-Control-Allow-Methods: {{ $cors.CorsAllowMethods }}';
                      more_set_headers 'Access-Control-Allow-Headers: {{ $cors.CorsAllowHeaders }}';
       
              {{ end }}
       
       
              {{/* definition of server-template to avoid repetitions with server-alias
              */}}
       
              {{ define "SERVER" }}
                      {{ $all := .First }}
                      {{ $server := .Second }}
       
                      {{ buildHTTPListener  $all $server.Hostname }}
                      {{ buildHTTPSListener $all $server.Hostname }}
       
                      set $proxy_upstream_name "-";
       
                      ssl_certificate_by_lua_block {
                          certificate.call()
                      }
       
                      {{ if not (empty $server.AuthTLSError) }}
                      # {{ $server.AuthTLSError }}
                      return 403;
                      {{ else }}
       
                      {{ if not (empty $server.CertificateAuth.CAFileName) }}
                      # PEM sha: {{ $server.CertificateAuth.CASHA }}
                      ssl_client_certificate                  {{ $server.CertificateAuth.CAFileName }};
                      ssl_verify_client                       {{ $server.CertificateAuth.VerifyClient }};
                      ssl_verify_depth                        {{ $server.CertificateAuth.ValidationDepth }};
       
                      {{ if not (empty $server.CertificateAuth.CRLFileName) }}
                      # PEM sha: {{ $server.CertificateAuth.CRLSHA }}
                      ssl_crl                                 {{ $server.CertificateAuth.CRLFileName }};
                      {{ end }}
       
                      {{ if not (empty $server.CertificateAuth.ErrorPage)}}
                      error_page 495 496 = {{ $server.CertificateAuth.ErrorPage }};
                      {{ end }}
                      {{ end }}
       
                      {{ if not (empty $server.ProxySSL.CAFileName) }}
                      # PEM sha: {{ $server.ProxySSL.CASHA }}
                      proxy_ssl_trusted_certificate           {{ $server.ProxySSL.CAFileName }};
                      proxy_ssl_ciphers                       {{ $server.ProxySSL.Ciphers }};
                      proxy_ssl_protocols                     {{ $server.ProxySSL.Protocols }};
                      proxy_ssl_verify                        {{ $server.ProxySSL.Verify }};
                      proxy_ssl_verify_depth                  {{ $server.ProxySSL.VerifyDepth }};
                      {{ if not (empty $server.ProxySSL.ProxySSLName) }}
                      proxy_ssl_name                           {{ $server.ProxySSL.ProxySSLName }};
                      {{ end }}
                      {{ end }}
       
                      {{ if not (empty $server.ProxySSL.PemFileName) }}
                      proxy_ssl_certificate                   {{ $server.ProxySSL.PemFileName }};
                      proxy_ssl_certificate_key               {{ $server.ProxySSL.PemFileName }};
                      {{ end }}
       
                      {{ if not (empty $server.SSLCiphers) }}
                      ssl_ciphers                             {{ $server.SSLCiphers }};
                      {{ end }}
       
                      {{ if not (empty $server.SSLPreferServerCiphers) }}
                      ssl_prefer_server_ciphers               {{ $server.SSLPreferServerCiphers }};
                      {{ end }}
       
                      {{ if not (empty $server.ServerSnippet) }}
                      {{ $server.ServerSnippet }}
                      {{ end }}
       
                      {{ range $errorLocation := (buildCustomErrorLocationsPerServer $server) }}
                      {{ template "CUSTOM_ERRORS" (buildCustomErrorDeps $errorLocation.UpstreamName $errorLocation.Codes $all.EnableMetrics) }}
                      {{ end }}
       
                      {{ buildMirrorLocations $server.Locations }}
       
                      {{ $enforceRegex := enforceRegexModifier $server.Locations }}
                      {{ range $location := $server.Locations }}
                      {{ $path := buildLocation $location $enforceRegex }}
                      {{ $proxySetHeader := proxySetHeader $location }}
                      {{ $authPath := buildAuthLocation $location $all.Cfg.GlobalExternalAuth.URL }}
                      {{ $applyGlobalAuth := shouldApplyGlobalAuth $location $all.Cfg.GlobalExternalAuth.URL }}
       
                      {{ $externalAuth := $location.ExternalAuth }}
                      {{ if eq $applyGlobalAuth true }}
                      {{ $externalAuth = $all.Cfg.GlobalExternalAuth }}
                      {{ end }}
       
                      {{ if not (empty $location.Rewrite.AppRoot) }}
                      if ($uri = /) {
                          return 302 $scheme://$http_host{{ $location.Rewrite.AppRoot }};
                      }
                      {{ end }}
       
                      {{ if $authPath }}
                      location = {{ $authPath }} {
                          internal;
       
                          {{ if $all.Cfg.EnableOpentracing }}
                          opentracing on;
                          opentracing_propagate_context;
                          {{ end }}
       
                          {{ if $externalAuth.AuthCacheKey }}
                          set $tmp_cache_key '{{ $server.Hostname }}{{ $authPath }}{{ $externalAuth.AuthCacheKey }}';
                          set $cache_key '';
       
                          rewrite_by_lua_block {
                              ngx.var.cache_key = ngx.encode_base64(ngx.sha1_bin(ngx.var.tmp_cache_key))
                          }
       
                          proxy_cache auth_cache;
       
                          {{- range $dur := $externalAuth.AuthCacheDuration }}
                          proxy_cache_valid {{ $dur }};
                          {{- end }}
       
                          proxy_cache_key "$cache_key";
                          {{ end }}
       
                          # ngx_auth_request module overrides variables in the parent request,
                          # therefore we have to explicitly set this variable again so that when the parent request
                          # resumes it has the correct value set for this variable so that Lua can pick backend correctly
                          set $proxy_upstream_name {{ buildUpstreamName $location | quote }};
       
                          proxy_pass_request_body     off;
                          proxy_set_header            Content-Length          "";
                          proxy_set_header            X-Forwarded-Proto       "";
                          proxy_set_header            X-Request-ID            $req_id;
       
                          {{ if $externalAuth.Method }}
                          proxy_method                {{ $externalAuth.Method }};
                          proxy_set_header            X-Original-URI          $request_uri;
                          proxy_set_header            X-Scheme                $pass_access_scheme;
                          {{ end }}
       
                          proxy_set_header            Host                    {{ $externalAuth.Host }};
                          proxy_set_header            X-Original-URL          $scheme://$http_host$request_uri;
                          proxy_set_header            X-Original-Method       $request_method;
                          proxy_set_header            X-Sent-From             "nginx-ingress-controller";
                          proxy_set_header            X-Real-IP               $remote_addr;
                          {{ if and $all.Cfg.UseForwardedHeaders $all.Cfg.ComputeFullForwardedFor }}
                          proxy_set_header            X-Forwarded-For        $full_x_forwarded_for;
                          {{ else }}
                          proxy_set_header            X-Forwarded-For        $remote_addr;
                          {{ end }}
       
                          {{ if $externalAuth.RequestRedirect }}
                          proxy_set_header            X-Auth-Request-Redirect {{ $externalAuth.RequestRedirect }};
                          {{ else }}
                          proxy_set_header            X-Auth-Request-Redirect $request_uri;
                          {{ end }}
       
                          {{ if $externalAuth.AuthCacheKey }}
                          proxy_buffering                         "on";
                          {{ else }}
                          proxy_buffering                         {{ $location.Proxy.ProxyBuffering }};
                          {{ end }}
                          proxy_buffer_size                       {{ $location.Proxy.BufferSize }};
                          proxy_buffers                           {{ $location.Proxy.BuffersNumber }} {{ $location.Proxy.BufferSize }};
                          proxy_request_buffering                 {{ $location.Proxy.RequestBuffering }};
                          proxy_http_version                      {{ $location.Proxy.ProxyHTTPVersion }};
       
                          proxy_ssl_server_name       on;
                          proxy_pass_request_headers  on;
                          {{ if isValidByteSize $location.Proxy.BodySize true }}
                          client_max_body_size        {{ $location.Proxy.BodySize }};
                          {{ end }}
                          {{ if isValidByteSize $location.ClientBodyBufferSize false }}
                          client_body_buffer_size     {{ $location.ClientBodyBufferSize }};
                          {{ end }}
       
                          # Pass the extracted client certificate to the auth provider
                          {{ if not (empty $server.CertificateAuth.CAFileName) }}
                          {{ if $server.CertificateAuth.PassCertToUpstream }}
                          proxy_set_header ssl-client-cert        $ssl_client_escaped_cert;
                          {{ end }}
                          proxy_set_header ssl-client-verify      $ssl_client_verify;
                          proxy_set_header ssl-client-subject-dn  $ssl_client_s_dn;
                          proxy_set_header ssl-client-issuer-dn   $ssl_client_i_dn;
                          {{ end }}
       
                          {{- range $line := buildAuthProxySetHeaders $externalAuth.ProxySetHeaders}}
                          {{ $line }}
                          {{- end }}
       
                          {{ if not (empty $externalAuth.AuthSnippet) }}
                          {{ $externalAuth.AuthSnippet }}
                          {{ end }}
       
                          set $target {{ $externalAuth.URL }};
                          proxy_pass $target;
                      }
                      {{ end }}
       
                      {{ if isLocationAllowed $location }}
                      {{ if $externalAuth.SigninURL }}
                      location {{ buildAuthSignURLLocation $location.Path $externalAuth.SigninURL }} {
                          internal;
       
                          add_header Set-Cookie $auth_cookie;
       
                          return 302 {{ buildAuthSignURL $externalAuth.SigninURL }};
                      }
                      {{ end }}
                      {{ end }}
       
                      location {{ $path }} {
                          {{ $ing := (getIngressInformation $location.Ingress $server.Hostname $location.Path) }}
                          set $namespace      {{ $ing.Namespace | quote}};
                          set $ingress_name   {{ $ing.Rule | quote }};
                          set $service_name   {{ $ing.Service | quote }};
                          set $service_port   {{ $ing.ServicePort | quote }};
                          set $location_path  {{ $location.Path | escapeLiteralDollar | quote }};
       
                          {{ buildOpentracingForLocation $all.Cfg.EnableOpentracing $location }}
       
                          {{ if $location.Mirror.Source }}
                          mirror {{ $location.Mirror.Source }};
                          mirror_request_body {{ $location.Mirror.RequestBody }};
                          {{ end }}
       
                          rewrite_by_lua_block {
                              lua_ingress.rewrite({{ locationConfigForLua $location $all }})
                              balancer.rewrite()
                              plugins.run()
                          }
       
                          # be careful with `access_by_lua_block` and `satisfy any` directives as satisfy any
                          # will always succeed when there's `access_by_lua_block` that does not have any lua code doing `ngx.exit(ngx.DECLINED)`
                          # other authentication method such as basic auth or external auth useless - all requests will be allowed.
                          #access_by_lua_block {
                          #}
       
                          header_filter_by_lua_block {
                              lua_ingress.header()
                              plugins.run()
                          }
       
                          body_filter_by_lua_block {
                          }
       
                          log_by_lua_block {
                              balancer.log()
                              {{ if $all.EnableMetrics }}
                              monitor.call()
                              {{ end }}
       
                              plugins.run()
                          }
       
                          {{ if not $location.Logs.Access }}
                          access_log off;
                          {{ end }}
       
                          {{ if $location.Logs.Rewrite }}
                          rewrite_log on;
                          {{ end }}
       
                          {{ if $location.HTTP2PushPreload }}
                          http2_push_preload on;
                          {{ end }}
       
                          port_in_redirect {{ if $location.UsePortInRedirects }}on{{ else }}off{{ end }};
       
                          set $balancer_ewma_score -1;
                          set $proxy_upstream_name {{ buildUpstreamName $location | quote }};
                          set $proxy_host          $proxy_upstream_name;
                          set $pass_access_scheme  $scheme;
       
                          {{ if $all.Cfg.UseProxyProtocol }}
                          set $pass_server_port    $proxy_protocol_server_port;
                          {{ else }}
                          set $pass_server_port    $server_port;
                          {{ end }}
       
                          set $best_http_host      $http_host;
                          set $pass_port           $pass_server_port;
       
                          set $proxy_alternative_upstream_name "";
       
                          {{ buildModSecurityForLocation $all.Cfg $location }}
       
                          {{ if isLocationAllowed $location }}
                          {{ if gt (len $location.Whitelist.CIDR) 0 }}
                          {{ range $ip := $location.Whitelist.CIDR }}
                          allow {{ $ip }};{{ end }}
                          deny all;
                          {{ end }}
       
                          {{ if not (isLocationInLocationList $location $all.Cfg.NoAuthLocations) }}
                          {{ if $authPath }}
                          # this location requires authentication
                          auth_request        {{ $authPath }};
                          auth_request_set    $auth_cookie $upstream_http_set_cookie;
                          add_header          Set-Cookie $auth_cookie;
                          {{- range $line := buildAuthResponseHeaders $externalAuth.ResponseHeaders }}
                          {{ $line }}
                          {{- end }}
                          {{ end }}
       
                          {{ if $externalAuth.SigninURL }}
                          set_escape_uri $escaped_request_uri $request_uri;
                          error_page 401 = {{ buildAuthSignURLLocation $location.Path $externalAuth.SigninURL }};
                          {{ end }}
       
                          {{ if $location.BasicDigestAuth.Secured }}
                          {{ if eq $location.BasicDigestAuth.Type "basic" }}
                          auth_basic {{ $location.BasicDigestAuth.Realm | quote }};
                          auth_basic_user_file {{ $location.BasicDigestAuth.File }};
                          {{ else }}
                          auth_digest {{ $location.BasicDigestAuth.Realm | quote }};
                          auth_digest_user_file {{ $location.BasicDigestAuth.File }};
                          {{ end }}
                          proxy_set_header Authorization "";
                          {{ end }}
                          {{ end }}
       
                          {{/* if the location contains a rate limit annotation, create one */}}
                          {{ $limits := buildRateLimit $location }}
                          {{ range $limit := $limits }}
                          {{ $limit }}{{ end }}
       
                          {{ if $location.CorsConfig.CorsEnabled }}
                          {{ template "CORS" $location }}
                          {{ end }}
       
                          {{ buildInfluxDB $location.InfluxDB }}
       
                          {{ if isValidByteSize $location.Proxy.BodySize true }}
                          client_max_body_size                    {{ $location.Proxy.BodySize }};
                          {{ end }}
                          {{ if isValidByteSize $location.ClientBodyBufferSize false }}
                          client_body_buffer_size                 {{ $location.ClientBodyBufferSize }};
                          {{ end }}
       
                          {{/* By default use vhost as Host to upstream, but allow overrides */}}
                          {{ if not (eq $proxySetHeader "grpc_set_header") }}
                          {{ if not (empty $location.UpstreamVhost) }}
                          {{ $proxySetHeader }} Host                   {{ $location.UpstreamVhost | quote }};
                          {{ else }}
                          {{ $proxySetHeader }} Host                   $best_http_host;
                          {{ end }}
                          {{ end }}
       
                          # Pass the extracted client certificate to the backend
                          {{ if not (empty $server.CertificateAuth.CAFileName) }}
                          {{ if $server.CertificateAuth.PassCertToUpstream }}
                          {{ $proxySetHeader }} ssl-client-cert        $ssl_client_escaped_cert;
                          {{ end }}
                          {{ $proxySetHeader }} ssl-client-verify      $ssl_client_verify;
                          {{ $proxySetHeader }} ssl-client-subject-dn  $ssl_client_s_dn;
                          {{ $proxySetHeader }} ssl-client-issuer-dn   $ssl_client_i_dn;
                          {{ end }}
       
                          # Allow websocket connections
                          {{ $proxySetHeader }}                        Upgrade           $http_upgrade;
                          {{ if $location.Connection.Enabled}}
                          {{ $proxySetHeader }}                        Connection        {{ $location.Connection.Header }};
                          {{ else }}
                          {{ $proxySetHeader }}                        Connection        $connection_upgrade;
                          {{ end }}
       
                          {{ $proxySetHeader }} X-Request-ID           $req_id;
                          {{ $proxySetHeader }} X-Real-IP              $remote_addr;
                          {{ if and $all.Cfg.UseForwardedHeaders $all.Cfg.ComputeFullForwardedFor }}
                          {{ $proxySetHeader }} X-Forwarded-For        $full_x_forwarded_for;
                          {{ $proxySetHeader }} X-Forwarded-Proto      $full_x_forwarded_proto;
                          {{ else }}
                          {{ $proxySetHeader }} X-Forwarded-For        $remote_addr;
                          {{ end }}
                          {{ $proxySetHeader }} X-Forwarded-Host       $best_http_host;
                          {{ $proxySetHeader }} X-Forwarded-Port       $pass_port;
                          {{ $proxySetHeader }} X-Forwarded-Proto      $pass_access_scheme;
                          {{ if $all.Cfg.ProxyAddOriginalURIHeader }}
                          {{ $proxySetHeader }} X-Original-URI         $request_uri;
                          {{ end }}
                          {{ $proxySetHeader }} X-Scheme               $pass_access_scheme;
       
                          # Pass the original X-Forwarded-For
                          {{ $proxySetHeader }} X-Original-Forwarded-For {{ buildForwardedFor $all.Cfg.ForwardedForHeader }};
       
                          # mitigate HTTPoxy Vulnerability
                          # https://www.nginx.com/blog/mitigating-the-httpoxy-vulnerability-with-nginx/
                          {{ $proxySetHeader }} Proxy                  "";
       
                          # Custom headers to proxied server
                          {{ range $k, $v := $all.ProxySetHeaders }}
                          {{ $proxySetHeader }} {{ $k }}                    {{ $v | quote }};
                          {{ end }}
       
                          proxy_connect_timeout                   {{ $location.Proxy.ConnectTimeout }}s;
                          proxy_send_timeout                      {{ $location.Proxy.SendTimeout }}s;
                          proxy_read_timeout                      {{ $location.Proxy.ReadTimeout }}s;
       
                          proxy_buffering                         {{ $location.Proxy.ProxyBuffering }};
                          proxy_buffer_size                       {{ $location.Proxy.BufferSize }};
                          proxy_buffers                           {{ $location.Proxy.BuffersNumber }} {{ $location.Proxy.BufferSize }};
                          {{ if isValidByteSize $location.Proxy.ProxyMaxTempFileSize true }}
                          proxy_max_temp_file_size                {{ $location.Proxy.ProxyMaxTempFileSize }};
                          {{ end }}
                          proxy_request_buffering                 {{ $location.Proxy.RequestBuffering }};
                          proxy_http_version                      {{ $location.Proxy.ProxyHTTPVersion }};
       
                          proxy_cookie_domain                     {{ $location.Proxy.CookieDomain }};
                          proxy_cookie_path                       {{ $location.Proxy.CookiePath }};
       
                          # In case of errors try the next upstream server before returning an error
                          proxy_next_upstream                     {{ buildNextUpstream $location.Proxy.NextUpstream $all.Cfg.RetryNonIdempotent }};
                          proxy_next_upstream_timeout             {{ $location.Proxy.NextUpstreamTimeout }};
                          proxy_next_upstream_tries               {{ $location.Proxy.NextUpstreamTries }};
       
                          {{/* Add any additional configuration defined */}}
                          {{ $location.ConfigurationSnippet }}
       
                          {{ if not (empty $all.Cfg.LocationSnippet) }}
                          # Custom code snippet configured in the configuration configmap
                          {{ $all.Cfg.LocationSnippet }}
                          {{ end }}
       
                          {{/* if we are sending the request to a custom default backend, we add the required headers */}}
                          {{ if (hasPrefix $location.Backend "custom-default-backend-") }}
                          proxy_set_header       X-Code             503;
                          proxy_set_header       X-Format           $http_accept;
                          proxy_set_header       X-Namespace        $namespace;
                          proxy_set_header       X-Ingress-Name     $ingress_name;
                          proxy_set_header       X-Service-Name     $service_name;
                          proxy_set_header       X-Service-Port     $service_port;
                          proxy_set_header       X-Request-ID       $req_id;
                          {{ end }}
       
                          {{ if $location.Satisfy }}
                          satisfy {{ $location.Satisfy }};
                          {{ end }}
       
                          {{/* if a location-specific error override is set, add the proxy_intercept here */}}
                          {{ if $location.CustomHTTPErrors }}
                          # Custom error pages per ingress
                          proxy_intercept_errors on;
                          {{ end }}
       
                          {{ range $errCode := $location.CustomHTTPErrors }}
                          error_page {{ $errCode }} = @custom_{{ $location.DefaultBackendUpstreamName }}_{{ $errCode }};{{ end }}
       
                          {{ if (eq $location.BackendProtocol "FCGI") }}
                          include /etc/nginx/fastcgi_params;
                          {{ end }}
                          {{- if $location.FastCGI.Index -}}
                          fastcgi_index {{ $location.FastCGI.Index | quote }};
                          {{- end -}}
                          {{ range $k, $v := $location.FastCGI.Params }}
                          fastcgi_param {{ $k }} {{ $v | quote }};
                          {{ end }}
       
                          {{ if not (empty $location.Redirect.URL) }}
                          return {{ $location.Redirect.Code }} {{ $location.Redirect.URL }};
                          {{ end }}
       
                          {{ buildProxyPass $server.Hostname $all.Backends $location }}
                          {{ if (or (eq $location.Proxy.ProxyRedirectFrom "default") (eq $location.Proxy.ProxyRedirectFrom "off")) }}
                          proxy_redirect                          {{ $location.Proxy.ProxyRedirectFrom }};
                          {{ else if not (eq $location.Proxy.ProxyRedirectTo "off") }}
                          proxy_redirect                          {{ $location.Proxy.ProxyRedirectFrom }} {{ $location.Proxy.ProxyRedirectTo }};
                          {{ end }}
                          {{ else }}
                          # Location denied. Reason: {{ $location.Denied | quote }}
                          return 503;
                          {{ end }}
                          {{ if not (empty $location.ProxySSL.CAFileName) }}
                          # PEM sha: {{ $location.ProxySSL.CASHA }}
                          proxy_ssl_trusted_certificate           {{ $location.ProxySSL.CAFileName }};
                          proxy_ssl_ciphers                       {{ $location.ProxySSL.Ciphers }};
                          proxy_ssl_protocols                     {{ $location.ProxySSL.Protocols }};
                          proxy_ssl_verify                        {{ $location.ProxySSL.Verify }};
                          proxy_ssl_verify_depth                  {{ $location.ProxySSL.VerifyDepth }};
                          {{ end }}
       
                          {{ if not (empty $location.ProxySSL.ProxySSLName) }}
                          proxy_ssl_name                           {{ $location.ProxySSL.ProxySSLName }};
                          {{ end }}
       
                          {{ if not (empty $location.ProxySSL.PemFileName) }}
                          proxy_ssl_certificate                   {{ $location.ProxySSL.PemFileName }};
                          proxy_ssl_certificate_key               {{ $location.ProxySSL.PemFileName }};
                          {{ end }}
                      }
                      {{ end }}
                      {{ end }}
       
                      {{ if eq $server.Hostname "_" }}
                      # health checks in cloud providers require the use of port {{ $all.ListenPorts.HTTP }}
                      location {{ $all.HealthzURI }} {
                          {{ if $all.Cfg.EnableOpentracing }}
                          opentracing off;
                          {{ end }}
       
                          access_log off;
                          return 200;
                      }
       
                      # this is required to avoid error if nginx is being monitored
                      # with an external software (like sysdig)
                      location /nginx_status {
                          {{ if $all.Cfg.EnableOpentracing }}
                          opentracing off;
                          {{ end }}
       
                          {{ range $v := $all.NginxStatusIpv4Whitelist }}
                          allow {{ $v }};
                          {{ end }}
                          {{ if $all.IsIPV6Enabled -}}
                          {{ range $v := $all.NginxStatusIpv6Whitelist }}
                          allow {{ $v }};
                          {{ end }}
                          {{ end -}}
                          deny all;
       
                          access_log off;
                          stub_status on;
                      }
       
                      {{ end }}
       
              {{ end }}
      
      # 创建命令如下
      <root@PROD-K8S-CP1 ~># kubectl apply -f ingress-configmap.yaml 
      configmap/nginx-tmpl created
    3. ingress节点上,创建对应的用户及目录
      <root@PROD-FE-K8S-WN1 ~># mkdir /var/log/nginx
      <root@PROD-FE-K8S-WN1 ~># groupadd -g 101 www-data
      <root@PROD-FE-K8S-WN1 ~># useradd -u 101 -g 101 -G www-data www-data
      <root@PROD-FE-K8S-WN1 ~># id www-data
      uid=101(www-data) gid=101(www-data) groups=101(www-data)
      <root@PROD-FE-K8S-WN1 ~># chown -R www-data:www-data /var/log/nginx/
      
      # 快捷方式
      mkdir /var/log/nginx
      groupadd -g 101 www-data
      useradd -u 101 -g 101 -G www-data www-data
      chown -R www-data:www-data /var/log/nginx/
      id www-data
    4. 创建好的ConfigMap 及  hostPath 映射到ingress中
          spec:
            volumes:
              - name: webhook-cert
                secret:
                  secretName: ingress-nginx-admission
                  defaultMode: 420
              - name: nginx-tmpl
                configMap:
                  name: nginx-tmpl
                  defaultMode: 420
              - name: nginxlog
                hostPath:
                  path: /var/log/nginx
                  type: Directory
      ...
                volumeMounts:
                  - name: webhook-cert
                    readOnly: true
                    mountPath: /usr/local/certificates/
                  - name: nginx-tmpl
                    readOnly: true
                    mountPath: /etc/nginx/template
                  - name: nginxlog
                    mountPath: /var/log/nginx
    5. 修改时区
            volumes:
      ....
              - name: localtime
                hostPath:
                  path: /etc/localtime
                  type: ""
      ----------------------------------------------
                volumeMounts:
      ...
                  - name: localtime
                    mountPath: /etc/localtime
  • 相关阅读:
    03-三维空间刚体运动-基础知识体系
    特征值和特征向量
    齐次坐标和一般坐标
    c++中 重载 覆盖 隐藏的区别 附加 mutable笔记
    快速学习理解网络协议4
    快速学习理解网络协议3
    快速学习理解网络协议2
    快速学习理解网络协议1
    c++的直接初始化与复制初始化 未完成!!!!!!!!!!!!
    高性能网络编程(二)
  • 原文地址:https://www.cnblogs.com/apink/p/15183133.html
Copyright © 2011-2022 走看看