7

I have a NGINX Ingress in my GKE. I want make my URL secure. But I unfortunately I am unable to achieve that via cert-manager. I see an option to create Managed Certificates. But I am not sure if there is an annotation that allow me to use google managed certificate in NGINX Ingress. Controller.

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: ingress-https
  namespace: non-default
  annotations:
    kubernetes.io/ingress.allow-http: "false"
    kubernetes.io/ingress.class: "nginx"
    networking.gke.io/managed-certificates: "managed-certificate"
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
    cert-manager.io/issuer: "letsencrypt-production"
spec:
  tls:
    - hosts:
        - example.com
      secretName: selfsigned-cert-tls
  rules:
    - host: example.com
      http:
        paths:
          - path: "/"
            backend:
              serviceName: hello-service
              servicePort: hello-port
          - path: "/kube"
            backend:
              serviceName: hello-kubernetes
              servicePort: 80

When I create a certificate with cert-manager, certificate status is showing "Kubernetes Ingress Controller Fake Certificate"

Ram
  • 655
  • 2
  • 7
  • 27
  • Nginx Ingress when deployed uses default TLS certificates which is giving you "Kubernetes Ingress Controller Fake Certificate" Depending upon how you have installed via helm or manifests , please provide your certificates in the options given here HELM : https://docs.nginx.com/nginx-ingress-controller/installation/installation-with-helm/#configuration Manifests : https://github.com/nginxinc/kubernetes-ingress/blob/master/deployments/common/default-server-secret.yaml Since you might have already deployed you can edit the secret also directly with the cert and key – Tarun Khosla Jul 20 '20 at 09:50
  • if you are following here https://cloud.google.com/kubernetes-engine/docs/how-to/managed-certs , make sure your cluster version is 1.16.5-gke.1 or higher. or using correct apiVersion – Tarun Khosla Jul 20 '20 at 09:55
  • How did you deploy the cert-manager? Because it will give you a valid Let's encrypt certificate. – Mr.KoopaKiller Jul 20 '20 at 09:58
  • Google managed certificates are different than cert-manager generated certificates. When using cert manager certificates, which will work with nginx ingress controllers, you need to define the `tls` section of your ingress spec which maps host names to secret names and cert-manager will use the specified secret name to store the generated SSL certificate. Since you have done that, I suspect an issue with your cert-manager installation (or perhaps you haven't installed it at all, this is not installed out of box in GKE clusters). – Paul Wheeler Dec 09 '20 at 21:47
  • 2
    That said, I share your original question. If you stripped out all the cert-manager cruft, is it possible to use Google Managed Certificates with an nginx kubernetes ingress controller (as opposed to the documented method specifying a global static IP). – Paul Wheeler Dec 09 '20 at 21:49
  • 1
    @PaulWheeler Currently no: See: https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-multi-ssl#specifying_certificates_for_your_ingress – Aalex Gabi Dec 29 '20 at 16:46
  • @AalexGabi is technically correct, but people have gotten traefik working behind the GCE ingress: https://github.com/kubernetes/ingress-gce/issues/369#issuecomment-743012823 – Bryan Larsen Mar 11 '21 at 21:56
  • But I couldn't get traefik to work that way. But I used the same mechanism for nginx and got it to work. So I posted an answer. – Bryan Larsen Mar 12 '21 at 15:02

1 Answers1

6

Using cert-manager is easier, but if you cannot use cert-manager for some reason, you can try this solution. It sets up both a GCE ingress and an nginx ingress. The GCE ingress is public, terminates the SSL but forwards to the private nginx ingress to do the routing.

helm3 install -f nginx-values.yaml ingress-nginx ingress-nginx/ingress-nginx
#nginx-values.yaml

controller:
  service:
    type: NodePort
    annotations:
      cloud.google.com/backend-config: '{"default": "backendconfig"}'
  admissionWebhooks:
    enabled: false
defaultBackend:
  enabled: true

And then create a BackendConfig and an Ingress to set up a LoadBalancer that'll talk to the nginx NodePort service.

apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
  name: backendconfig
spec:
  timeoutSec: 300
  healthCheck:
    requestPath: /healthz
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: ingress
  annotations:
    networking.gke.io/managed-certificates: foo,bar
spec:
  backend:
    serviceName: ingress-nginx-controller
    servicePort: 80

And then you can create a ManagedCertificate and an Ingress for foo and bar, and they'll share the same LoadBalancer.

apiVersion: networking.gke.io/v1
kind: ManagedCertificate
metadata:
  name: foo
spec:
  domains:
    - foo.example.com
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: foo
  annotations:
    kubernetes.io/ingress.class: nginx
spec:
  rules:
  - host: foo.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          serviceName: foo
          servicePort: 5000

Remember that every time you create a new ManagedCertificate / Ingress pair, you'll have to modify the gce ingress manifest with the name of the cert in the networking.gke.io/managed-certificates annotation.

Bryan Larsen
  • 9,468
  • 8
  • 56
  • 46