{"action":"closed","issue":{"url":"https://api.github.com/repos/kubernetes/ingress-nginx/issues/1980","repository_url":"https://api.github.com/repos/kubernetes/ingress-nginx","labels_url":"https://api.github.com/repos/kubernetes/ingress-nginx/issues/1980/labels{/name}","comments_url":"https://api.github.com/repos/kubernetes/ingress-nginx/issues/1980/comments","events_url":"https://api.github.com/repos/kubernetes/ingress-nginx/issues/1980/events","html_url":"https://github.com/kubernetes/ingress-nginx/issues/1980","id":291631200,"number":1980,"title":"Session affinity using cookie does not work when \"path\" is not set in the Ingress - Wrong generated Nginx configuration","user":{"login":"sylmarch","id":11892658,"avatar_url":"https://avatars1.githubusercontent.com/u/11892658?v=4","gravatar_id":"","url":"https://api.github.com/users/sylmarch","html_url":"https://github.com/sylmarch","followers_url":"https://api.github.com/users/sylmarch/followers","following_url":"https://api.github.com/users/sylmarch/following{/other_user}","gists_url":"https://api.github.com/users/sylmarch/gists{/gist_id}","starred_url":"https://api.github.com/users/sylmarch/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/sylmarch/subscriptions","organizations_url":"https://api.github.com/users/sylmarch/orgs","repos_url":"https://api.github.com/users/sylmarch/repos","events_url":"https://api.github.com/users/sylmarch/events{/privacy}","received_events_url":"https://api.github.com/users/sylmarch/received_events","type":"User","site_admin":false},"labels":[{"id":475536977,"url":"https://api.github.com/repos/kubernetes/ingress-nginx/labels/help%20wanted","name":"help wanted","color":"006b75","default":true}],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":9,"created_at":"2018-01-25T16:26:55Z","updated_at":"2018-03-23T11:08:43Z","closed_at":"2018-03-23T11:08:43Z","author_association":"NONE","body":"**NGINX Ingress controller version**: 0.10.0\r\n\r\n\r\n**Kubernetes version** (use `kubectl version`):\r\nClient Version: version.Info{Major:\"1\", Minor:\"8\", GitVersion:\"v1.8.0\", GitCommit:\"6e937839ac04a38cac63e6a7a306c5d035fe7b0a\", GitTreeState:\"clean\", BuildDate:\"2017-09-28T22:57:57Z\", GoVersion:\"go1.8.3\", Compiler:\"gc\", Platform:\"linux/amd64\"}\r\nServer Version: version.Info{Major:\"1\", Minor:\"8+\", GitVersion:\"v1.8.3-rancher3\", GitCommit:\"772c4c54e1f4ae7fc6f63a8e1ecd9fe616268e16\", GitTreeState:\"clean\", BuildDate:\"2017-11-27T19:51:43Z\", GoVersion:\"go1.8.3\", Compiler:\"gc\", Platform:\"linux/amd64\"}\r\n\r\n\r\n**Environment**:\r\n\r\n- **Cloud provider or hardware configuration**: Bare metal, Kubernetes was installed using Rancher v1.6\r\n- **OS** (e.g. from /etc/os-release): CentOS 7\r\n- **Kernel** (e.g. `uname -a`):\r\n- **Install tools**:\r\n- **Others**:\r\n\r\n\r\n**What happened**:\r\nSession affinity using a cookie does not work, even if these 3 annotations is set on the ingress:\r\n-  nginx.ingress.kubernetes.io/affinity: \"cookie\"\r\n- nginx.ingress.kubernetes.io/session-cookie-name: \"route\"\r\n- nginx.ingress.kubernetes.io/session-cookie-hash: \"sha1\"\r\n\r\nI think the Nginx configuration, generated from the Ingress resource, is incorrect (see below).\r\n\r\n\r\n**What you expected to happen**:\r\nA cookie \"route\" should be set in response to the 1st request (that isn't the case).\r\nThen, all other requests should provide this cookie.\r\nThe IngressController should then forward all these requests to the same backend pod.\r\n\r\n**How to reproduce it** (as minimally and precisely as possible):\r\n\r\nHereby a complete configuration.\r\n\r\n1) create an echo service:\r\n```\r\n#######################################################################################################################\r\n# Deployment with at least 2 pods used as backend servers.\r\n#######################################################################################################################\r\napiVersion: apps/v1beta2\r\nkind: Deployment\r\nmetadata:\r\n  name: echo-server\r\nspec:\r\n  # at least 2 backends to test sticky session\r\n  replicas: 2\r\n  selector:\r\n    matchLabels:\r\n      app: echo-server\r\n  template:\r\n    metadata:\r\n      labels:\r\n        app: echo-server\r\n    spec:\r\n      containers:\r\n      - name: echo-server\r\n        image: gcr.io/google_containers/echoserver:1.8\r\n        ports:\r\n          - containerPort: 8080\r\n\r\n#######################################################################################################################\r\n# Service to access backend pods\r\n#######################################################################################################################\r\n\r\n---\r\napiVersion: v1\r\nkind: Service\r\nmetadata:\r\n  name: echo-server\r\nspec:\r\n  # service only expose internally. Using an Ingress to access it.\r\n  type: ClusterIP\r\n  ports:\r\n    - name: http\r\n      port: 8080\r\n\r\n  selector:\r\n    app: echo-server\r\n```\r\n\r\n2) create the IngressController and all other mandatory resources:\r\n```\r\n# IngressControler officiel basé sur Nginx\r\n# https://github.com/kubernetes/ingress-nginx/blob/0.10.0/deploy/README.md\r\n\r\n#######################################################################################################################\r\n# Create namespace\r\n# Source : https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/namespace.yaml\r\n#######################################################################################################################\r\napiVersion: v1\r\nkind: Namespace\r\nmetadata:\r\n  name: ingress-nginx\r\n\r\n\r\n#######################################################################################################################\r\n# Create default backend deployment and service\r\n# Source : https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/default-backend.yaml\r\n#######################################################################################################################\r\n---\r\napiVersion: extensions/v1beta1\r\nkind: Deployment\r\nmetadata:\r\n  name: default-http-backend\r\n  labels:\r\n    app: default-http-backend\r\n  namespace: ingress-nginx\r\nspec:\r\n  replicas: 1\r\n  template:\r\n    metadata:\r\n      labels:\r\n        app: default-http-backend\r\n    spec:\r\n      terminationGracePeriodSeconds: 60\r\n      containers:\r\n      - name: default-http-backend\r\n        # Any image is permissable as long as:\r\n        # 1. It serves a 404 page at /\r\n        # 2. It serves 200 on a /healthz endpoint\r\n        image: gcr.io/google_containers/defaultbackend:1.4\r\n        livenessProbe:\r\n          httpGet:\r\n            path: /healthz\r\n            port: 8080\r\n            scheme: HTTP\r\n          initialDelaySeconds: 30\r\n          timeoutSeconds: 5\r\n        ports:\r\n        - containerPort: 8080\r\n        resources:\r\n          limits:\r\n            cpu: 10m\r\n            memory: 20Mi\r\n          requests:\r\n            cpu: 10m\r\n            memory: 20Mi\r\n---\r\n\r\napiVersion: v1\r\nkind: Service\r\nmetadata:\r\n  name: default-http-backend\r\n  namespace: ingress-nginx\r\n  labels:\r\n    app: default-http-backend\r\nspec:\r\n  ports:\r\n  - port: 80\r\n    targetPort: 8080\r\n  selector:\r\n    app: default-http-backend\r\n\r\n\r\n#######################################################################################################################\r\n# Create ConfigMap with Nginx configuration.\r\n# Source : https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/configmap.yaml\r\n#######################################################################################################################\r\n---\r\nkind: ConfigMap\r\napiVersion: v1\r\nmetadata:\r\n  name: nginx-configuration\r\n  namespace: ingress-nginx\r\n  labels:\r\n    app: ingress-nginx\r\n\r\n#######################################################################################################################\r\n# Create ConfigMap with Nginx configuration for TCP services.\r\n# Source : https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/tcp-services-configmap.yaml\r\n#######################################################################################################################\r\n---\r\nkind: ConfigMap\r\napiVersion: v1\r\nmetadata:\r\n  name: tcp-services\r\n  namespace: ingress-nginx\r\n\r\n\r\n#######################################################################################################################\r\n# Create ConfigMap with Nginx configuration for UDP services.\r\n# Source : https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/udp-services-configmap.yaml\r\n#######################################################################################################################\r\n---\r\nkind: ConfigMap\r\napiVersion: v1\r\nmetadata:\r\n  name: udp-services\r\n  namespace: ingress-nginx\r\n\r\n\r\n#######################################################################################################################\r\n# Create IngressController without RBAC (= Role Based Access Control).\r\n# Source : https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/without-rbac.yaml\r\n#######################################################################################################################\r\n---\r\napiVersion: extensions/v1beta1\r\nkind: Deployment\r\nmetadata:\r\n  name: nginx-ingress-controller\r\n  namespace: ingress-nginx\r\nspec:\r\n  replicas: 1\r\n  selector:\r\n    matchLabels:\r\n      app: ingress-nginx\r\n  template:\r\n    metadata:\r\n      labels:\r\n        app: ingress-nginx\r\n      annotations:\r\n        prometheus.io/port: '10254'\r\n        prometheus.io/scrape: 'true'\r\n    spec:\r\n      initContainers:\r\n      - command:\r\n        - sh\r\n        - -c\r\n        - sysctl -w net.core.somaxconn=32768; sysctl -w net.ipv4.ip_local_port_range=\"1024 65535\"\r\n        image: alpine:3.6\r\n        imagePullPolicy: IfNotPresent\r\n        name: sysctl\r\n        securityContext:\r\n          privileged: true\r\n      containers:\r\n        - name: nginx-ingress-controller\r\n          image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.10.0\r\n          args:\r\n            - /nginx-ingress-controller\r\n            - --default-backend-service=$(POD_NAMESPACE)/default-http-backend\r\n            - --configmap=$(POD_NAMESPACE)/nginx-configuration\r\n            - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services\r\n            - --udp-services-configmap=$(POD_NAMESPACE)/udp-services\r\n            - --annotations-prefix=nginx.ingress.kubernetes.io\r\n            # only process Ingress annotated with this class\r\n            - --ingress-class=nginx\r\n          env:\r\n            - name: POD_NAME\r\n              valueFrom:\r\n                fieldRef:\r\n                  fieldPath: metadata.name\r\n            - name: POD_NAMESPACE\r\n              valueFrom:\r\n                fieldRef:\r\n                  fieldPath: metadata.namespace\r\n          ports:\r\n          - name: http\r\n            containerPort: 80\r\n          - name: https\r\n            containerPort: 443\r\n          livenessProbe:\r\n            failureThreshold: 3\r\n            httpGet:\r\n              path: /healthz\r\n              port: 10254\r\n              scheme: HTTP\r\n            initialDelaySeconds: 10\r\n            periodSeconds: 10\r\n            successThreshold: 1\r\n            timeoutSeconds: 1\r\n          readinessProbe:\r\n            failureThreshold: 3\r\n            httpGet:\r\n              path: /healthz\r\n              port: 10254\r\n              scheme: HTTP\r\n            periodSeconds: 10\r\n            successThreshold: 1\r\n            timeoutSeconds: 1\r\n\r\n\r\n#######################################################################################################################\r\n# Expose the IngressController as a \"NodePort\" service.\r\n# Statically set the published ports (notePort attributes) : 30080 for HTTP / 30443 for HTTPS.\r\n# Source : https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/provider/baremetal/service-nodeport.yaml\r\n#######################################################################################################################\r\n---\r\napiVersion: v1\r\nkind: Service\r\nmetadata:\r\n  name: ingress-nginx\r\n  namespace: ingress-nginx\r\nspec:\r\n  type: NodePort\r\n  ports:\r\n  - name: http\r\n    port: 80\r\n    targetPort: 80\r\n    # publish HTTP on port 30080\r\n    nodePort: 30080\r\n    protocol: TCP\r\n  - name: https\r\n    port: 443\r\n    targetPort: 443\r\n    # publish HTTPS on port 30443\r\n    nodePort: 30443\r\n    protocol: TCP\r\n  selector:\r\n    app: ingress-nginx\r\n```\r\n\r\n3) create the Ingress to access the echo-service through this IngressController:\r\n```\r\n#######################################################################################################################\r\n# Ingress to access echo service.\r\n#######################################################################################################################\r\napiVersion: extensions/v1beta1\r\nkind: Ingress\r\nmetadata:\r\n  name: echo-server\r\n  annotations:\r\n    # define the class so that this Ingress is only proceed by the IngressController named \"nginx-ingress-controller\".\r\n    kubernetes.io/ingress.class: \"nginx\"\r\n    # define sticky session annotations as describe here:\r\n    # https://github.com/kubernetes/ingress-nginx/tree/master/docs/examples/affinity/cookie\r\n    nginx.ingress.kubernetes.io/affinity: \"cookie\"\r\n    nginx.ingress.kubernetes.io/session-cookie-name: \"route\"\r\n    nginx.ingress.kubernetes.io/session-cookie-hash: \"sha1\"\r\n\r\nspec:\r\n  rules:\r\n    - host: echo-server\r\n      http:\r\n        paths:\r\n        - backend:\r\n            serviceName: echo-server\r\n            servicePort: 8080\r\n```\r\n\r\n4) Declare \"echo-server\" in your /etc/hosts file. The IP address should be one of your node:\r\n```\r\n11.22.33.44  echo-server\r\n```\r\n\r\n5) In your browser, open a web developer console to see request and response headers.\r\n\r\n6) Access the URL `http://echo-server:30080` and check the headers :\r\n- There is no \"Set-Cookie\" header in the response\r\n- There is no \"Cookie\" header in the request\r\n\r\n\r\n**Anything else we need to know**:\r\nYou can retrieve the generated Nginx configuration like this:\r\n\r\n1) Find your IngressController pod:\r\n```\r\n$ kubectl get po -n ingress-nginx\r\nNAME                                       READY     STATUS    RESTARTS   AGE\r\ndefault-http-backend-66b447d9cf-tswgb      1/1       Running   0          30m\r\nnginx-ingress-controller-8fcd569fc-r5sk4   1/1       Running   0          30m\r\n```\r\n\r\n2) Dump the nginx configuration on your computer:\r\n```\r\n$ kubectl exec nginx-ingress-controller-8fcd569fc-r5sk4 -n ingress-nginx -- cat /etc/nginx/nginx.conf > /tmp/nginx.conf\r\n```\r\n\r\n3) In the /tmp/nginx.conf you can see the following upstream servers:\r\n```\r\n    upstream sticky-default-echo-server-8080 {\r\n        sticky hash=sha1 name=route  httponly;\r\n\r\n        keepalive 32;\r\n\r\n        server 10.42.210.114:8080 max_fails=0 fail_timeout=0;\r\n        server 10.42.31.243:8080 max_fails=0 fail_timeout=0;\r\n\r\n    }\r\n\r\n    upstream default-echo-server-8080 {\r\n\r\n        # Load balance algorithm; empty for round robin, which is the default\r\n        least_conn;\r\n\r\n        keepalive 32;\r\n\r\n        server 10.42.210.114:8080 max_fails=0 fail_timeout=0;\r\n        server 10.42.31.243:8080 max_fails=0 fail_timeout=0;\r\n\r\n    }\r\n```\r\nBut no configuration uses the \"sticky-default-echo-server-8080\" in the server section:\r\n```\r\n    ## start server echo-server\r\n    server {\r\n        server_name echo-server ;\r\n\r\n        listen 80;\r\n\r\n        listen [::]:80;\r\n\r\n        set $proxy_upstream_name \"-\";\r\n\r\n        location / {\r\n            port_in_redirect off;\r\n\r\n            set $proxy_upstream_name \"default-echo-server-8080\";\r\n\r\n            set $namespace      \"default\";\r\n            set $ingress_name   \"echo-server\";\r\n            set $service_name   \"\";\r\n\r\n            client_max_body_size                    \"1m\";\r\n\r\n            proxy_set_header Host                   $host;\r\n\r\n            # Pass the extracted client certificate to the backend\r\n\r\n            proxy_set_header ssl-client-cert        \"\";\r\n            proxy_set_header ssl-client-verify      \"\";\r\n            proxy_set_header ssl-client-dn          \"\";\r\n\r\n            # Allow websocket connections\r\n            proxy_set_header                        Upgrade           $http_upgrade;\r\n            proxy_set_header                        Connection        $connection_upgrade;\r\n\r\n            proxy_set_header X-Real-IP              $the_real_ip;\r\n\r\n            proxy_set_header X-Forwarded-For        $the_real_ip;\r\n\r\n            proxy_set_header X-Forwarded-Host       $host;\r\n            proxy_set_header X-Forwarded-Port       $pass_port;\r\n            proxy_set_header X-Forwarded-Proto      $pass_access_scheme;\r\n            proxy_set_header X-Original-URI         $request_uri;\r\n            proxy_set_header X-Scheme               $pass_access_scheme;\r\n\r\n            # Pass the original X-Forwarded-For\r\n            proxy_set_header X-Original-Forwarded-For $http_x_forwarded_for;\r\n\r\n            # mitigate HTTPoxy Vulnerability\r\n            # https://www.nginx.com/blog/mitigating-the-httpoxy-vulnerability-with-nginx/\r\n            proxy_set_header Proxy                  \"\";\r\n\r\n            # Custom headers to proxied server\r\n\r\n            proxy_connect_timeout                   5s;\r\n            proxy_send_timeout                      60s;\r\n            proxy_read_timeout                      60s;\r\n\r\n            proxy_buffering                         off;\r\n            proxy_buffer_size                       \"4k\";\r\n            proxy_buffers                           4 \"4k\";\r\n            proxy_request_buffering                 \"on\";\r\n\r\n            proxy_http_version                      1.1;\r\n\r\n            proxy_cookie_domain                     off;\r\n            proxy_cookie_path                       off;\r\n\r\n            # In case of errors try the next upstream server before returning an error\r\n            proxy_next_upstream                     error timeout invalid_header http_502 http_503 http_504;\r\n\r\n            proxy_pass http://default-echo-server-8080;\r\n\r\n            proxy_redirect                          off;\r\n\r\n        }\r\n\r\n    }\r\n    ## end server echo-server\r\n```\r\n\r\nI never use Nginx but I think the issue is here."}}
{"actor":{"display_login":"aledbf"}}