Search code examples
kubernetesssl-certificatekubernetes-ingressnginx-ingresskubernetes-secrets

Two TLS certificate for two Nginx Ingress controller Azure K8s cluster


I have two ingress controller one with default class nginx in default namespace, while the second ingress controller has a nginx class: nginx-devices.

Cert-manager is already installed using Helm.

I managed to get TLS certificate from Lets Encrypt for the first controller, using ClusterIssuer and ingress resource rules for routing Ingress.


apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
  # name: letsencrypt-staging
  name: letsencrypt-prod
spec:
  acme:
    email: xx
    # server: https://acme-staging-v02.api.letsencrypt.org/directory
    server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      # name: letsencrypt-staging
      name: letsencrypt-prod
    solvers:
    - http01:
        ingress:
          class: nginx

Ingress routing:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: serviceA-ingress-rules
  namespace: default
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
    ingress.kubernetes.io/rewrite-target: /
spec:
  tls:
  - hosts:
    - FirstService.cloudapp.azure.com
    secretName: tls-secret
  rules:
  - host: FirstService.cloudapp.azure.com
    http:
      paths:
      - path: /serviceA
        backend:
          serviceName: serviceA
          servicePort: 80

However, for creating the second TLS certificate for the second ingress controller, the TLS secret is not created

ClusterIssuer

# k8s/cluster-issuer.yaml

apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
  # name: letsencrypt-staging
  name: letsencrypt-prod-devices
  namespace: ingress-nginx-devices # namespace where the second ingress controller is installed
spec:
  acme:
    email: xxx
    # server: https://acme-staging-v02.api.letsencrypt.org/directory
    server: https://acme-v02.api.letsencrypt.org/directory
    privateKeySecretRef:
      # name: letsencrypt-staging
      name: letsencrypt-prod-devices
    solvers:
    - http01:
        ingress:
          class: nginx-devices # ingress class of the second ingress controller

ingress routing

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: devices-ingress-rules
  namespace: default # since all the services are in default namespace
  annotations:
    kubernetes.io/ingress.class: nginx-devices # ingress class of the second ingress controller
    cert-manager.io/cluster-issuer: "letsencrypt-prod-devices" 
    ingress.kubernetes.io/rewrite-target: /
spec:
  tls:
  - hosts:
    - secondService.cloudapp.azure.com
    secretName: tls-secret
  rules:
  - host: secondService.cloudapp.azure.com
    http:
      paths:
      - path: /serviceB
        backend:
          serviceName: serviceB
          servicePort: 80

by looking at the secret I can only see: kubectl get secrets -n ingress-nginx-devices

NAME                                          TYPE                                  DATA   AGE
default-token-xzp95                           kubernetes.io/service-account-token   3      92m
nginx-ingress-devices-backend-token-pd4vf     kubernetes.io/service-account-token   3      64m
nginx-ingress-devices-token-qvvps             kubernetes.io/service-account-token   3      64m
sh.helm.release.v1.nginx-ingress-devices.v1   helm.sh/release.v1                    1      64m

while in default namespace:

tls-secret                                          kubernetes.io/tls                     2      134m

Why the second tls-secret is not being generated ? what could go wrong here ?

Any help is appreciated :)


Solution

  • your second cluster issuer namespace is : ingress-nginx-devices ideally it should be in the default namespace as your ingress is in the default namespace.

    Keep these three in same namespace :

    1. Ingress
    2. Clusterissuer
    3. Service

    if everything will work well you will see the secret in default namespace

    also in your YAML of clusterissuer

    privateKeySecretRef:
          # name: letsencrypt-staging
          name: letsencrypt-prod-devices
    

    name of your secret is : letsencrypt-prod-devices

    but in ingress it is : tls-secret

    keep it same otherwise wont work

    here sharing a full example of clusterissuer and ingress keep in the same namespace. You can change the secret name, clusterissuer name as per need. Clusterissuer will create the secret automatically just give prover names of secret & clusterissuer in ingress (matching).

    apiVersion: cert-manager.io/v1alpha2
    kind: ClusterIssuer
    metadata:
      name: cluster-issuer-name
      namespace: development
    spec:
      acme:
        server: https://acme-v02.api.letsencrypt.org/directory
        email: harsh@example.com
        privateKeySecretRef:
          name: secret-name
        solvers:
        - http01:
            ingress:
              class: nginx-class-name
    ---
    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      annotations:
        kubernetes.io/ingress.class: nginx-class-name
        cert-manager.io/cluster-issuer: cluster-issuer-name
        nginx.ingress.kubernetes.io/rewrite-target: /
      name: example-ingress
    spec:
      rules:
      - host: sub.example.com
        http:
          paths:
          - path: /api
            backend:
              serviceName: service-name
              servicePort: 80
      tls:
      - hosts:
        - sub.example.com
        secretName: secret-name