0 0 Share PDF

How to configure a default TLS certificate for the Kubernetes Nginx ingress controller

Article ID: KB000858

Issue

The example in the documentation at docs.docker.com does not indicate how to set a default certificate for ingress. Instead, it will use a self generated certificate as explained at the Kubernetes nginx ingress project documentation.

Providing a specific certificate can be useful for monitoring the health of the ingress.

Resolution

Note: these instructions are provided as an example only. Kubernetes ingress nginx is not supported by Docker.

You can specify a default SSL certificate for the ingress controller.

For that, you need to modify the configuration of the controller with a new param : --default-ssl-certificate=$(POD_NAMESPACE)/<nameofyoursecret>

Steps to make the changes :

  1. Create a secret containing the certificate inside the namespace used for the ingress (ingress-nginx) named default-ssl-certificate :

    apiVersion: v1
    data:
      tls.crt: base64 encoded cert
      tls.key: base64 encoded key
    kind: Secret
    metadata:
      name: default-ssl-certificate
      namespace: ingress-nginx
    type: Opaque
    

    Full documentation : https://kubernetes.io/docs/concepts/services-networking/ingress/#tls

  2. Delete the ingress-nginx configuration previously created (delete all components from your cluster).

  3. Create the new ingress with this config file :

    apiVersion: apps/v1beta2
    kind: Deployment
    metadata:
      name: default-http-backend
      labels:
        app: default-http-backend
      namespace: ingress-nginx
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: default-http-backend
      template:
        metadata:
          labels:
            app: default-http-backend
          annotations:
            seccomp.security.alpha.kubernetes.io/pod: docker/default
        spec:
          terminationGracePeriodSeconds: 60
          containers:
          - name: default-http-backend
            # Any image is permissable as long as:
            # 1. It serves a 404 page at /
            # 2. It serves 200 on a /healthz endpoint
            image: gcr.io/google_containers/defaultbackend:1.4
            livenessProbe:
              httpGet:
                path: /healthz
                port: 8080
                scheme: HTTP
              initialDelaySeconds: 30
              timeoutSeconds: 5
            ports:
            - containerPort: 8080
            resources:
              limits:
                cpu: 10m
                memory: 20Mi
              requests:
                cpu: 10m
                memory: 20Mi
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: default-http-backend
      namespace: ingress-nginx
      labels:
        app: default-http-backend
    spec:
      ports:
      - port: 80
        targetPort: 8080
      selector:
        app: default-http-backend
    ---
    kind: ConfigMap
    apiVersion: v1
    metadata:
      name: nginx-configuration
      namespace: ingress-nginx
      labels:
        app: ingress-nginx
    ---
    kind: ConfigMap
    apiVersion: v1
    metadata:
      name: tcp-services
      namespace: ingress-nginx
    ---
    kind: ConfigMap
    apiVersion: v1
    metadata:
      name: udp-services
      namespace: ingress-nginx
    ---
    apiVersion: apps/v1beta2
    kind: Deployment
    metadata:
      name: nginx-ingress-controller
      namespace: ingress-nginx
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: ingress-nginx
      template:
        metadata:
          labels:
            app: ingress-nginx
          annotations:
            prometheus.io/port: '10254'
            prometheus.io/scrape: 'true'
            seccomp.security.alpha.kubernetes.io/pod: docker/default
        spec:
          initContainers:
          - command:
            - sh
            - -c
            - sysctl -w net.core.somaxconn=32768; sysctl -w net.ipv4.ip_local_port_range="1024 65535"
            image: alpine:3.6
            imagePullPolicy: IfNotPresent
            name: sysctl
            securityContext:
              privileged: true
          containers:
            - name: nginx-ingress-controller
              image: quay.io/kubernetes-ingress-controller/nginx-ingress-controller:0.17.1
              args:
                - /nginx-ingress-controller
                - --default-backend-service=$(POD_NAMESPACE)/default-http-backend
                - --default-ssl-certificate=$(POD_NAMESPACE)/default-ssl-certificate
                - --configmap=$(POD_NAMESPACE)/nginx-configuration
                - --tcp-services-configmap=$(POD_NAMESPACE)/tcp-services
                - --udp-services-configmap=$(POD_NAMESPACE)/udp-services
                - --annotations-prefix=nginx.ingress.kubernetes.io
              env:
                - name: POD_NAME
                  valueFrom:
                    fieldRef:
                      fieldPath: metadata.name
                - name: POD_NAMESPACE
                  valueFrom:
                    fieldRef:
                      fieldPath: metadata.namespace
              ports:
              - name: http
                containerPort: 80
              - name: https
                containerPort: 443
              livenessProbe:
                failureThreshold: 3
                httpGet:
                  path: /healthz
                  port: 10254
                  scheme: HTTP
                initialDelaySeconds: 10
                periodSeconds: 10
                successThreshold: 1
                timeoutSeconds: 1
              readinessProbe:
                failureThreshold: 3
                httpGet:
                  path: /healthz
                  port: 10254
                  scheme: HTTP
                periodSeconds: 10
                successThreshold: 1
                timeoutSeconds: 1
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: ingress-nginx
      namespace: ingress-nginx
    spec:
      type: NodePort
      ports:
      - name: http
        port: 80
        targetPort: 80
        protocol: TCP
      - name: https
        port: 443
        targetPort: 443
        protocol: TCP
      selector:
        app: ingress-nginx
    
  4. You should now be able to access the default backend with https and with the certificate you provided.

    The /healthz endpoint is also available with https and this certificate to monitor the ingress.

References