skip to Main Content

I was under the impression that the main point of cluster-issuer is that its namespaced and doesn’t have to be recreated across different resources, in general there could be one main cluster-issuer that will manage all ingresses across the cluster.

From what I am seeing the cluster-issuer can only create one secret and if its in use by one ingress the second wont wont be created properly cause its already taken.

Is there anyway to create one cluster-issuer to manage all ingresses across the cluster?

Code included below

Cluster-issuer.yaml

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-grafana
  namespace: cert-manager
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: [email protected]
    privateKeySecretRef:
      name: letsencrypt-grafana
    solvers:
    - selector:
        dnsZones:
          - "foo.com"
      dns01:
        route53:
          region: eu-central-1
          hostedZoneID: foo
          accessKeyID: foo
          secretAccessKeySecretRef:
            name: aws-route53-creds
            key: password.txt

Ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: grafana-ingress
  namespace: loki
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-grafana
    kubernetes.io/tls-acme: "true"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
    nginx.ingress.kubernetes.io/proxy-body-size:  "125m"
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  tls:
  - hosts:
    - grafana.foo.com
    secretName: letsencrypt-grafana # < cert-manager will store the created certificate in this secret.
  rules:
  - host: grafana.foo.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: loki-grafana
            port:
              number: 80

2

Answers


  1. Chosen as BEST ANSWER

    @Harsh Manvar while I do appreciate your anwser I found something that is a better suit for my needs.

    Cert-manager documentation contains multiple options to sync secrets across namespaces

    The one I chose was reflector. The steps to install are included in the documentation but just for the sake of service i'll post here aswell

    Requirements: Helm

    Installation:

    helm repo add emberstack https://emberstack.github.io/helm-charts
    helm repo update
    helm upgrade --install reflector emberstack/reflector
    

    Setup:

    Add the following annotation to your secret reflector.v1.k8s.emberstack.com/reflection-allowed: "true", it should look like the following

    apiVersion: v1
    kind: Secret
    metadata:
     name: source-secret
     annotations:
       reflector.v1.k8s.emberstack.com/reflection-allowed: "true"
    

    Done! Your secret should be replicated within all namespaces. For multiple ingress configurations within the same namespace you could edit your ingress.yaml like this

    Ingress.yaml

    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: jenkins-ingress
      namespace: jenkins
      annotations:
        cert-manager.io/cluster-issuer: letsencrypt-global
        kubernetes.io/tls-acme: "true"
        nginx.ingress.kubernetes.io/ssl-redirect: "true"
        nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
        nginx.ingress.kubernetes.io/proxy-body-size:  "125m"
        nginx.ingress.kubernetes.io/rewrite-target: /
    spec:
      ingressClassName: nginx
      tls:
      - hosts:
        - jenkins.foo.com
        - nginx.foo.com
        secretName: letsencrypt-global # < cert-manager will store the created certificate in this secret.
      rules:
      - host: jenkins.foo.com
        http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: jenkins
                port:
                  number: 80
      - host: nginx.foo.com
        http:
          paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nginx
                port:
                  number: 80
    

  2. i would recommend creating the wildcard certificate using issuer/clusterissuer.

    So you will be having the single secret with wildcard cert so you can use that across all ingress.

    As you are already using DNS verification it will work well, as wildcard not supports the HTTP

    apiVersion: cert-manager.io/v1
    kind: Issuer
    metadata:
      name: letsencrypt-prod
    spec:
      acme:
        email: [email protected]
        server: https://acme-v02.api.letsencrypt.org/directory
        privateKeySecretRef:
          name: letsencrypt-prod
        solvers:
        - selector:
            dnsZones:
              - "devops.example.in"
          dns01:
            route53:
              region: us-east-1
              hostedZoneID: Z0152EXAMPLE
              accessKeyID: AKIA5EXAMPLE
              secretAccessKeySecretRef:
                name: route53-secret
                key: secret-access-key
    ---
    apiVersion: cert-manager.io/v1alpha2
    kind: Certificate
    metadata:
      name: le-crt
    spec:
      secretName: tls-secret
      issuerRef: 
        kind: Issuer
        name: letsencrypt-prod
      commonName: "*.devops.example.in"
      dnsNames:
        - "*.devops.example.in"
    

    Read my full article : https://medium.com/@harsh.manvar111/wild-card-certificate-using-cert-manager-in-kubernetes-3406b042d5a2

    Ingress & secret example

    apiVersion: extensions/v1beta1
    kind: Ingress
    metadata:
      annotations:
        kubernetes.io/ingress.class: nginx
        nginx.ingress.kubernetes.io/ssl-redirect: "false"
        certmanager.k8s.io/issuer: "letsencrypt-prod"
        certmanager.k8s.io/acme-challenge-type: dns01
        certmanager.k8s.io/acme-dns01-provider: route53
      name: ingress-resource-tls
      namespace: default
    spec:
      rules:
      - host: "hello.devops.example.in"
        http:
          paths:
          - backend:
              serviceName: hello-app
              servicePort: 8080
            path: /
            pathType: ImplementationSpecific
      tls:
      - hosts:
        - "hello.devops.example.in"
        secretName: tls-secret
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search