VirtualServer and cert-manager incompatible? #2520
-
Hi, After having spent the last few days diving into a lot of documentation, logs, etc, I can only conclude that the To get a secure VirtualServer resource, with a valid TLS certiciate from Let'sEncrypt, I would define something like this: apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: cafe-tls
spec:
dnsNames:
- cafe.example.com
issuerRef:
group: cert-manager.io
kind: ClusterIssuer
name: letsencrypt-prod
secretName: cafe-tls
---
apiVersion: k8s.nginx.org/v1
kind: VirtualServer
metadata:
name: cafe
spec:
host: cafe.example.com
tls:
secret: cafe-tls
upstreams:
- name: tea
service: tea-svc
port: 80
routes:
- path: /tea
action:
pass: tea Deploying the certificate will result in cert-manager creating an ingress to solve let'sencrypt's HTTP01 challenges (potentially sensitive values masked out): apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/whitelist-source-range: 0.0.0.0/0,::/0
labels:
acme.cert-manager.io/http-domain: "<masked>"
acme.cert-manager.io/http-token: "<masked>"
acme.cert-manager.io/http01-solver: "true"
name: cm-acme-http-solver-f2gxv
namespace: cafe
ownerReferences:
- apiVersion: acme.cert-manager.io/v1
blockOwnerDeletion: true
controller: true
kind: Challenge
name: cafe-tls-ztb6n-<masked>-<masked>
spec:
rules:
- host: cafe.example.com
http:
paths:
- backend:
service:
name: cm-acme-http-solver-nrthr
port:
number: 8089
path: /.well-known/acme-challenge/<masked>
pathType: ImplementationSpecific The challenge will never be validated however, because as soon as cert-manager creates the ingress, the following can be seen in the logs of the ingress controller:
When I delete the At first I thought, OK, I can just modify our deployment pipeline to first deploy the certificate resource, and deploy the VirtualServer resource after the certificate was successfully validated, but then I thought about certificate renewal. Let'sencrypt issues certs with a 3-month validity, and cert-manager will take care of renewing the certificate shortly beforehand, but if that happens, it will need to create an ingress resource again, and we would be back in the same situation (because the VritualServer resource still exists). For ingresses, this problem does not exist, because one can add annotations to have cert-manager automatically create the certificate for them, and another annotation to instruct cert-manager to edit the existing ingress in-place instead of creating a new one. This would look like so: apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: cafe-ingress
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod #Instructs cert-manager to create the certificate resource itself
acme.cert-manager.io/http01-edit-in-place: "true" #Instructs cert-manager to edit this ingress resource (ingress/cafe-ingress) in-place to validate the letsencrypt challenge, instead of creating a new ingress resource
spec:
tls:
- hosts:
- cafe.example.com
secretName: cafe-secret
rules:
- host: cafe.example.com
http:
paths:
- path: /tea
pathType: Prefix
backend:
service:
name: tea-svc
port:
number: 80 I doubt I'm the first person running into this, as using VirtualServer resources with cert-manager Certificate resources should be pretty basic thing to do to anyone using this ingress controller, so am I missing something? I found some issues which were more or less related:
In general, going to this ingress controller from the Kubernetes nginx one, seems like a downgrade, as these issues were not a problem with that one, even without using the |
Beta Was this translation helpful? Give feedback.
Replies: 7 comments 12 replies
-
the cert-manager project works with the ingress resource as expected. |
Beta Was this translation helpful? Give feedback.
-
Initial support for VirtualServer was added in https://github.com/nginxinc/kubernetes-ingress/releases/tag/v2.2.0 |
Beta Was this translation helpful? Give feedback.
-
@brianehlert I tried implementing this support for virual servers but ran into a problem. The kuberentes tooling does not seem to recognize these new properties and produces following errors error validating "/home/vsts/work/r1/a/KubernetesManifests/common-virtual-server.yaml": error validating data: ValidationError(VirtualServer.spec.tls): unknown field "cert-manager" in org.nginx.k8s.v1.VirtualServer.spec.tls; if you choose to ignore these errors, turn validation off with --validate=false
error validating "/home/vsts/work/r1/a/KubernetesManifests/keycloak.yaml": error validating data: ValidationError(VirtualServer.spec.tls): unknown field "cert-manager" in org.nginx.k8s.v1.VirtualServer.spec.tls; if you choose to ignore these errors, turn validation off with --validate=false I first updated our nginx image from 2.1.0 to 2.3.0 like the docs required. The config used based on the docs and the example: apiVersion: k8s.nginx.org/v1
kind: VirtualServer
metadata:
name: keycloak
spec:
host: keycloak.${HOSTNAME}$
tls:
secret: keycloak-tls-secret
cert-manager:
cluster-issuer: ${CertManagerClusterIssuerName}$
upstreams:
- name: keycloak
service: keycloak
port: 8080
buffer-size: 14k
routes:
- path: /auth
action:
pass: keycloak If I try locally and use the --validate=false flag the apply works and the virtual server resource is accepted with a status of valid. |
Beta Was this translation helpful? Give feedback.
-
@Joren-Thijs-KasparSolutions did you make sure to install/update the latest CRDs for NGINX Ingress controller? That looks to be the case as the field is not recognized and should be resolved with ensuring our latest CRDs are installed into the k8 cluster. |
Beta Was this translation helpful? Give feedback.
-
Hi I also tried to use cert-manager with a VirtualServer and was not able to get the certificate issued without manually adding the "challenge" service to the VirtualServers This is my VirtualServer without the manual addition of the cert-manager/let's encrypt specific routes/upstreams apiVersion: k8s.nginx.org/v1
kind: VirtualServer
metadata:
name: cafe
spec:
host: cafe.example.com
tls:
secret: certman-cafe-secret
cert-manager:
cluster-issuer: letsencrypt-staging-nginxinc
common-name: cafe.example.com
upstreams:
- name: tea
service: tea-svc
port: 80
- name: coffee
service: coffee-svc
port: 80
routes:
- path: /tea
action:
proxy:
upstream: tea
rewritePath: /
- path: /coffee
action:
proxy:
upstream: coffee
rewritePath: /
- action:
return:
body: |
Hello World
code: 200
type: text/plain
path: / |
Beta Was this translation helpful? Give feedback.
-
I don't know if this is useful, but I was able to get cert manager with DNS01 challenge using VirtualServer working. This was with externalDNS as well on GKE w WorkloadIdentity to grant access to CloudDNS: https://faun.pub/extending-gke-with-nginx-ic-2ae86a96de18 |
Beta Was this translation helpful? Give feedback.
-
я убедился что nginx ing ingress полное дерьмо |
Beta Was this translation helpful? Give feedback.
Initial support for VirtualServer was added in https://github.com/nginxinc/kubernetes-ingress/releases/tag/v2.2.0