Search code examples
kuberneteskubernetes-helmkubernetes-ingress

How to use SSL requests from Kubernetes ingress to pods


I am making a kubernetes application deployment with gitlab kubernetes integration. I ran into an issue that after putting the pods (containers) on ssl, the browser responds with:

    Bad Request
    Your browser sent a request that this server could not understand.
    Reason: You're speaking plain HTTP to an SSL-enabled server port.
    Instead use the HTTPS scheme to access this URL, please.
    Apache/2.4.38 (Debian) Server at docker.vm Port 80

I am accessing the browser url with https://***********.eu/ and have no idea why it is redirected from https to http inside the kubernetes on the way to the pods.

My Ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  annotations:
    field.cattle.io/publicEndpoints: '[{"addresses":["******"],"port":443,"protocol":"HTTPS","serviceName":"******","ingressName":"******","hostname":"******","path":"/","allNodes":true},{"addresses":["******"],"port":443,"protocol":"HTTPS","serviceName":"******","ingressName":"******","hostname":"******","path":"/","allNodes":true}]'
    kubernetes.io/ingress.class: nginx
    kubernetes.io/tls-acme: "true"
  creationTimestamp: "2021-05-21T12:54:44Z"
  generation: 1
  labels:
    app: development
    chart: auto-deploy-app-1.0.7
    heritage: Tiller
    release: development
  managedFields:
  - apiVersion: extensions/v1beta1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .: {}
          f:kubernetes.io/ingress.class: {}
          f:kubernetes.io/tls-acme: {}
        f:labels:
          .: {}
          f:app: {}
          f:chart: {}
          f:heritage: {}
          f:release: {}
      f:spec:
        f:rules: {}
        f:tls: {}
    manager: Go-http-client
    operation: Update
    time: "2021-05-21T12:54:44Z"
  - apiVersion: networking.k8s.io/v1beta1
    fieldsType: FieldsV1
    fieldsV1:
      f:status:
        f:loadBalancer:
          f:ingress: {}
    manager: nginx-ingress-controller
    operation: Update
    time: "2021-05-21T12:55:25Z"
  - apiVersion: extensions/v1beta1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          f:field.cattle.io/publicEndpoints: {}
    manager: rancher
    operation: Update
    time: "2021-05-21T12:55:25Z"
  name: development-auto-deploy
  namespace: ******
  resourceVersion: "******"
  selfLink: /apis/networking.k8s.io/v1/namespaces/******
  uid: ******
spec:
  rules:
  - host: ******
    http:
      paths:
      - backend:
          service:
            name: development-auto-deploy
            port:
              number: 443
        path: /
        pathType: ImplementationSpecific
  - host: ******
    http:
      paths:
      - backend:
          service:
            name: development-auto-deploy
            port:
              number: 443
        path: /
        pathType: ImplementationSpecific
  tls:
  - hosts:
    - ******
    - ******
    secretName: development-auto-deploy-tls
</pre>

My Service.yaml

<pre>
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: "2021-05-21T12:54:44Z"
  labels:
    app: development
    chart: auto-deploy-app-1.0.7
    heritage: Tiller
    release: development
  managedFields:
  - apiVersion: v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:labels:
          .: {}
          f:app: {}
          f:chart: {}
          f:heritage: {}
          f:release: {}
      f:spec:
        f:ports:
          .: {}
          k:{"port":443,"protocol":"TCP"}:
            .: {}
            f:name: {}
            f:port: {}
            f:protocol: {}
            f:targetPort: {}
        f:selector:
          .: {}
          f:app: {}
          f:tier: {}
        f:sessionAffinity: {}
        f:type: {}
    manager: Go-http-client
    operation: Update
    time: "2021-05-21T12:54:44Z"
  name: development-auto-deploy
  namespace: ******
  resourceVersion: "******"
  selfLink: /api/v1/namespaces/******
  uid: ******
spec:
  clusterIP: ******
  ports:
  - name: web
    port: 443
    protocol: TCP
    targetPort: 443
  selector:
    app: development
    tier: web
  sessionAffinity: None
  type: ClusterIP
status:
  loadBalancer: {}
>

And deployment.yaml for the pod deployment:

apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    app.gitlab.com/app: *******
    app.gitlab.com/env: development
    deployment.kubernetes.io/revision: "1"
    field.cattle.io/publicEndpoints: '[{"addresses":["*******"],"port":443,"protocol":"HTTPS","serviceName":"*******","ingressName":"*******","hostname":"*******","path":"/","allNodes":true},{"addresses":["*******"],"port":443,"protocol":"HTTPS","serviceName":"*******","ingressName":"*******","hostname":"*******","path":"/","allNodes":true}]'
  creationTimestamp: "2021-05-21T12:54:44Z"
  generation: 2
  labels:
    app: development
    chart: auto-deploy-app-1.0.7
    heritage: Tiller
    release: development
    tier: web
    track: stable
  managedFields:
  - apiVersion: apps/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .: {}
          f:app.gitlab.com/app: {}
          f:app.gitlab.com/env: {}
        f:labels:
          .: {}
          f:app: {}
          f:chart: {}
          f:heritage: {}
          f:release: {}
          f:tier: {}
          f:track: {}
      f:spec:
        f:progressDeadlineSeconds: {}
        f:replicas: {}
        f:revisionHistoryLimit: {}
        f:selector:
          f:matchLabels:
            .: {}
            f:app: {}
            f:release: {}
            f:tier: {}
            f:track: {}
        f:strategy:
          f:rollingUpdate:
            .: {}
            f:maxSurge: {}
            f:maxUnavailable: {}
          f:type: {}
        f:template:
          f:metadata:
            f:annotations:
              .: {}
              f:app.gitlab.com/app: {}
              f:app.gitlab.com/env: {}
              f:checksum/application-secrets: {}
            f:labels:
              .: {}
              f:app: {}
              f:release: {}
              f:tier: {}
              f:track: {}
          f:spec:
            f:containers:
              k:{"name":"auto-deploy-app"}:
                .: {}
                f:env:
                  .: {}
                  k:{"name":"DATABASE_URL"}:
                    .: {}
                    f:name: {}
                    f:value: {}
                  k:{"name":"GITLAB_ENVIRONMENT_NAME"}:
                    .: {}
                    f:name: {}
                    f:value: {}
                  k:{"name":"GITLAB_ENVIRONMENT_URL"}:
                    .: {}
                    f:name: {}
                    f:value: {}
                f:envFrom: {}
                f:image: {}
                f:imagePullPolicy: {}
                f:livenessProbe:
                  .: {}
                  f:failureThreshold: {}
                  f:httpGet:
                    .: {}
                    f:path: {}
                    f:port: {}
                    f:scheme: {}
                  f:initialDelaySeconds: {}
                  f:periodSeconds: {}
                  f:successThreshold: {}
                  f:timeoutSeconds: {}
                f:name: {}
                f:ports:
                  .: {}
                  k:{"containerPort":443,"protocol":"TCP"}:
                    .: {}
                    f:containerPort: {}
                    f:name: {}
                    f:protocol: {}
                f:readinessProbe:
                  .: {}
                  f:failureThreshold: {}
                  f:httpGet:
                    .: {}
                    f:path: {}
                    f:port: {}
                    f:scheme: {}
                  f:initialDelaySeconds: {}
                  f:periodSeconds: {}
                  f:successThreshold: {}
                  f:timeoutSeconds: {}
                f:resources: {}
                f:terminationMessagePath: {}
                f:terminationMessagePolicy: {}
            f:dnsPolicy: {}
            f:imagePullSecrets:
              .: {}
              k:{"name":"*******"}:
                .: {}
                f:name: {}
            f:restartPolicy: {}
            f:schedulerName: {}
            f:securityContext: {}
            f:terminationGracePeriodSeconds: {}
    manager: Go-http-client
    operation: Update
    time: "2021-05-21T12:54:44Z"
  - apiVersion: apps/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          f:deployment.kubernetes.io/revision: {}
      f:status:
        f:availableReplicas: {}
        f:conditions:
          .: {}
          k:{"type":"Available"}:
            .: {}
            f:lastTransitionTime: {}
            f:lastUpdateTime: {}
            f:message: {}
            f:reason: {}
            f:status: {}
            f:type: {}
          k:{"type":"Progressing"}:
            .: {}
            f:lastTransitionTime: {}
            f:lastUpdateTime: {}
            f:message: {}
            f:reason: {}
            f:status: {}
            f:type: {}
        f:observedGeneration: {}
        f:readyReplicas: {}
        f:replicas: {}
        f:updatedReplicas: {}
    manager: kube-controller-manager
    operation: Update
    time: "2021-05-21T12:54:55Z"
  - apiVersion: apps/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          f:field.cattle.io/publicEndpoints: {}
    manager: rancher
    operation: Update
    time: "2021-05-21T12:55:25Z"
  name: development
  namespace: *******
  resourceVersion: "*******"
  selfLink: /apis/apps/v1/namespaces/*******
  uid: *******
spec:
  progressDeadlineSeconds: 600
  replicas: 1
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: development
      release: development
      tier: web
      track: stable
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      annotations:
        app.gitlab.com/app: *******
        app.gitlab.com/env: development
        checksum/application-secrets: *******
      creationTimestamp: null
      labels:
        app: development
        release: development
        tier: web
        track: stable
    spec:
      containers:
      - env:
        - name: DATABASE_URL
          value: ' '
        - name: GITLAB_ENVIRONMENT_NAME
          value: development
        - name: GITLAB_ENVIRONMENT_URL
          value: *******
        envFrom:
        - secretRef:
            name: development-secret
        image: *******
        imagePullPolicy: IfNotPresent
        livenessProbe:
          failureThreshold: 3
          httpGet:
            path: /
            port: 443
            scheme: HTTPS
          initialDelaySeconds: 15
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 15
        name: auto-deploy-app
        ports:
        - containerPort: 443
          name: web
          protocol: TCP
        readinessProbe:
          failureThreshold: 3
          httpGet:
            path: /
            port: 443
            scheme: HTTPS
          initialDelaySeconds: 5
          periodSeconds: 10
          successThreshold: 1
          timeoutSeconds: 3
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      imagePullSecrets:
      - name: *******
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
status:
  availableReplicas: 1
  conditions:
  - lastTransitionTime: "2021-05-21T12:54:55Z"
    lastUpdateTime: "2021-05-21T12:54:55Z"
    message: Deployment has minimum availability.
    reason: MinimumReplicasAvailable
    status: "True"
    type: Available
  - lastTransitionTime: "2021-05-21T12:54:44Z"
    lastUpdateTime: "2021-05-21T12:54:55Z"
    message: ReplicaSet "*******" has successfully progressed.
    reason: NewReplicaSetAvailable
    status: "True"
    type: Progressing
  observedGeneration: 2
  readyReplicas: 1
  replicas: 1
  updatedReplicas: 1

SSL is removed somewhere and kubernetes ingress calls the pods with http:// instead of https://, but I do not know how to fix it.

So the question is: How to remove SSL termination from kubernetes ingress?


Solution

  • If you want SSL termination to happen at the server instead at the ingress/LoadBalancer, you can use a something called SSL Passthrough. Load Balancer will then not terminate the SSL request at the ingress but then your server should be able to terminate those SSL request. Use these configuration in your ingress.yaml file depending upon your ingress class

       annotations:
        ingress.kubernetes.io/ssl-passthrough: "true"
        nginx.ingress.kubernetes.io/ssl-passthrough: "true"
    
    

    There is one more annotation that you can use in nginx. backend-protocol annotations is possible to indicate how NGINX should communicate with the backend service.

    nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
    

    By default NGINX uses HTTP.

    Read more about it here https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#backend-protocol