Cert manager doesn't get the challenge done - cloudflare

I'm setting up a k3s cluster for local development.
To be clear, I do not have a public IP address.
At this moment I'm looking for a solution to get the certificate process automated (via cert-manager).
In order to get this to work I've did the following:
Deployed k3s
Deployed cert-manager
Deployed traefik
Purchased a domain
Created a cloudflare account and added the domain there
Created an API token to do the acme challenge (based on https://cert-manager.io/docs/configuration/acme/dns01/cloudflare/)
Created a simple test website
When a add the test website I get the following error:
Found no Zones for domain _acme-challenge.. (neither in
the sub-domain noir in the SLD) please make sure your domain-entries
in the config are correct and the API is correctly setup with
Zone.read rights.
I have the following configuration:
ClusterIssuer
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt
spec:
acme:
email: my#emailaddress.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt
solvers:
- dns01:
cloudflare:
email: my#emailaddress.com
apiKeySecretRef:
name: cloudflare-api-key-secret
key: api-key
Test website
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test-ingress
namespace: test
annotations:
kubernetes.io/ingress.class: "traefik"
cert-manager.io/cluster-issuer: letsencrypt
spec:
rules:
- host: test.<mydomain>
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: nginx-svc
port:
number: 80
tls:
- secretName: test.<mydomain>

Related

ArgoCD with nginx ingress and cert manager not working

I am trying to expose ArgoCD using ingress and cert-manager in GKE cluster(version 1.21.5-gke.1302) but the certificate is not issued.
Steps to reproduce:
Install cert-manager applying this yaml
Install nginx ingress-controller with helm running:
helm install my-release nginx-stable/nginx-ingress
Create clusterIssuer applying the following:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-cluster-issuer
spec:
acme:
email: example#email.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-cluster-issuer-key
solvers:
- http01:
ingress:
class: nginx
Applied ingress using this guide and the file:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: argocd-server-ingress
namespace: argocd
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: "true"
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
# If you encounter a redirect loop or are getting a 307 response code
# then you need to force the nginx ingress to connect to the backend using HTTPS.
#
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
spec:
rules:
- host: argocd.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: argocd-server
port:
name: https
tls:
- hosts:
- argocd.example.com
secretName: argocd-secret # do not change, this is provided by Argo CD
Map the ip of ingress-controller to your host name.
Expected behaviour: I was expecting a certificate to be created successfully and have access to the app.
Current status:
Certificate describe gives me this:
Conditions:
Last Transition Time: 2022-01-18T14:10:14Z
Message: Existing issued Secret is not up to date for spec: [spec.dnsNames]
Observed Generation: 3
Reason: SecretMismatch
Status: False
Type: Ready
Last Transition Time: 2022-01-18T14:10:14Z
Message: Issuing certificate as Secret was previously issued by Issuer.cert-manager.io/
Observed Generation: 1
Reason: IncorrectIssuer
Status: True
Type: Issuing
Next Private Key Secret Name: argocd-secret-ccjtv
Not After: 2023-01-18T13:39:24Z
Not Before: 2022-01-18T13:39:24Z
Renewal Time: 2022-09-18T21:39:24Z
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Requested 16m cert-manager Created new CertificateRequest resource "argocd-secret-qm469"
Normal Requested 15m cert-manager Created new CertificateRequest resource "argocd-secret-9ctn4"
Normal Reused 7m19s (x2 over 45h) cert-manager Reusing private key stored in existing Secret resource "argocd-secret"
Finally I can access the provided url by the challenge but status is pending with reason:
Waiting for HTTP-01 challenge propagation: failed to perform self check GET request
Does anyone have any idea what might be wrong? It would be highly appreciated.
Thanks!
Looks like you have a different name for cluster issue in your ingress rule for ArgoCD.
From your example in the ClusterIssuer manifest:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-cluster-issuer
And from ingress rule
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
I think you need to specify:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-cluster-issuer
spec:
acme:
email: example#email.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: argocd-secret # HERE use secrets created by ArgoCD
solvers:
- http01:
ingress:
class: nginx

Kubernetes cert-manager certificate is created but can not get vertified

I am working on a DO kubernetes cluster and install ingress nginx and argocd on it, All seems fine and I can easily use the ingress as long as they are accessing the services via http.
I have also installed certmanager and here are the main files regarding my ingress, certificate and issuer:
Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: rancher-demo
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
certmanager.k8s.io/cluster-issuer: "letsencrypt-production"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
tls:
- hosts:
- {sub-domain}
secretName: ssl-cert-production
rules:
- host: {sub-domain}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: rancher-demo
port:
number: 80
Issuer
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-production
namespace: default
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: {my-email}
privateKeySecretRef:
name: letsencrypt-production
solvers:
- selector: {}
http01:
ingress:
class: nginx
Certificate
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: ssl-cert-production
namespace: default
spec:
secretName: ssl-cert-production
issuerRef:
name: letsencrypt-production
kind: ClusterIssuer
commonName: {sub-domain}
dnsNames:
- {sub-domain}
I went through some other samples on github and questions on stackoverflow and unfortunetly I can not figure out where I am doing it wrong.
Thank you in advance for your attentions
I finally managed to fix the issue, what I have done was as follow:
creating a new kubernete instance
installing cert-manager manaully
installing ingress-nginx manaully
creating the issuer (waiting for it to complete)
creating deployment and cluster
creating ingress config for my application
creating the certificate (waiting for it to complete)
I was working on ArgoCD and had to first do these setups myself before handling CD with Argo. It was my own fault that I did not properly go through their documentations. The order is important, but the way I sat up Argo, it was provisioing everything in parallel so for example certificate was being provision before ingress be up or issuer be in place
Also for anyone who is interested in a detailed version please checkout the github repo I created below:
https://github.com/mehdiamenein/cert-manager-nginx-ingress-do
I hope this can be helpful to someone else as well :)
Huge thanks to marcel.dempers for his wonderful video https://www.youtube.com/watch?v=hoLUigg4V18
and many thanks to #justin and #harsh-manvar for their comments

How can I use Cert manager letsencrypt-prod in my kubernetes service?

I have 4 yaml file
Deployment.yaml
Service.yaml
Ingress.yaml
issuer.yaml
I want to use letsencrypt-prod for my service for certification . But it doesn't work.
When I use to be sure ingress is working or issuer is working both of them are done!
kubectl get ing
kubectl get issuer
But when I run:
kubectl get cert
Cert is not readt during 2 days . Like below:
it creates problem like below. certification is not binding mandrakee.xyz.Mandrakee.xyz looks still not secure! how can I make my website secyre via cert manager?
Deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: echo-deployment
spec:
replicas: 1
selector:
matchLabels:
app: echo-server
template:
metadata:
labels:
app: echo-server
spec:
containers:
- name: httpapi-host
image: jmalloc/echo-server
imagePullPolicy: Always
resources:
requests:
memory: "128Mi"
cpu: "500m"
ports:
- containerPort: 80
Service.yaml:
apiVersion: v1
kind: Service
metadata:
name: echo-service
spec:
ports:
- name: http-port
port: 80
targetPort: 8080
selector:
app: echo-server
Ingress.yaml:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: ambassador
cert-manager.io/issuer: letsencrypt-prod
name: test-ingress
spec:
tls:
- hosts:
- mandrakee.xyz
secretName: letsencrypt-prod
rules:
- host: mandrakee.xyz
http:
paths:
- backend:
service:
name: echo-service
port:
number: 80
path: /
pathType: Prefix
issuer.yaml:
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: letsencrypt-prod
spec:
acme:
email: ykaratoprak#sphereinc.com
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- dns01:
digitalocean:
tokenSecretRef:
name: digitalocean-dns
key: ce28952b5b4e33ea7d98de190f3148a7cc82d31f030bde966ad13b22c1abc524
If you have setup your issuer correctly, which you have assured us, you will see in your namespace a pod belonging to cert manager. This creates a pod that will validate that the server requesting the certificate resolves to the DNS record.
In your case, you would need to point your DNS towards your ingress.
If this is done successfully, then the next stage of debugging is to validate that both 443 and 80 can be resolved. The Validation Pod created by Cert Manager uses port 80 to validate the communication. A common mistake people make is assuming that they will only use port 443 for ssl and disable 80 for security reasons to find out later that letsencrypt can't validate the hostname without port 80.
Otherwise, the common scenario is that cert-manager is installed in the namespace cert-manager and so you should check the logs of the manager. This will provided a limited amount of logs and can be sometimes cryptic to finding the remedy to your issues.
To find the direct error, the pod spawned by cert-manager in the namespace you have deployed the ingress is a good place to focus.
A test I would run is to setup the ingress with both 80 and 443, if you use your domain from your browser you should get some invalid kubernetes generic certificates response on the port 443 and just "Not Found" on port 80. If this is successful, it rules out the limitation I have mentioned before.

SSL Certificates on Kubernetes Using ACME

I have been following this tutorial: https://cert-manager.io/docs/ , and after I have installed my cert manager and made sure they are running with kubectl get pods --namespace cert-manager,
cert-manager-5597cff495-l5hjs 1/1 Running 0 91m
cert-manager-cainjector-bd5f9c764-xrb2t 1/1 Running 0 91m
cert-manager-webhook-5f57f59fbc-q5rqs 1/1 Running 0 91m
I then configured my cert-manager using ACME issuer by following this tutorial https://cert-manager.io/docs/configuration/acme/ .
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
# You must replace this email address with your own.
# Let's Encrypt will use this to contact you about expiring
# certificates, and issues related to your account.
email: aidenhsy#gmail.com
server: https://acme-staging-v02.api.letsencrypt.org/directory
privateKeySecretRef:
# Secret resource that will be used to store the account's private key.
name: letsencrypt-staging
# Add a single challenge solver, HTTP01 using nginx
solvers:
- http01:
ingress:
class: nginx
Here is my full ingress config file:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: ingress-srv
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/use-regex: 'true'
spec:
rules:
- host: www.hyhaus.xyz
http:
paths:
- path: /api/?(.*)
backend:
serviceName: devback-srv
servicePort: 4000
- path: /?(.*)
backend:
serviceName: devfront-srv
servicePort: 3000
---
apiVersion: v1
kind: Service
metadata:
annotations:
service.beta.kubernetes.io/do-loadbalancer-enable-proxy-protocol: 'true'
service.beta.kubernetes.io/do-loadbalancer-hostname: 'www.hyhaus.xyz'
labels:
helm.sh/chart: ingress-nginx-2.0.3
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/version: 0.32.0
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/component: controller
name: ingress-nginx-controller
namespace: ingress-nginx
spec:
type: LoadBalancer
externalTrafficPolicy: Local
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
- name: https
port: 443
protocol: TCP
targetPort: https
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/component: controller
---
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
spec:
acme:
# You must replace this email address with your own.
# Let's Encrypt will use this to contact you about expiring
# certificates, and issues related to your account.
email: aidenhsy#gmail.com
server: https://acme-staging-v02.api.letsencrypt.org/directory
privateKeySecretRef:
# Secret resource that will be used to store the account's private key.
name: letsencrypt-staging
# Add a single challenge solver, HTTP01 using nginx
solvers:
- http01:
ingress:
class: nginx
However when I browse to my site, the browser warns: security certificate is not trusted by your computer's operating system. And when I took a look a my certificate, it shows self-assigned, which is not really what I want. Am I doing something wrong here?
This is a certificate placeholder provided by nginx ingress controller. When you see it, it means there is no other (dedicated) certificate for the endpoint.
Now the first reason why this happened is that your Ingress doesn't have necessary data. Update it with this:
metadata:
annotations:
# which issuer to use
cert-manager.io/cluster-issuer: "letsencrypt-staging"
spec:
tls: # placing a host in TLS config indicates that a certificate should be created
- hosts:
- example.org
- www.example.org
- xyz.example.org
secretName: myingress-cert # cert-manager will store the created certificate in this secret
Documentation for ingress objects is here.
If the above didn't help, try the troubleshooting steps offered by the documentation. In my experience checking CertificateRequest and Certificate resources was enough in most cases to determine the problem.
$ kubectl get certificate
$ kubectl describe certificate <certificate-name>
$ kubectl get certificaterequest
$ kubectl describe certificaterequest <CertificateRequest name>
Remember that these objects are namespaced, meaning that they'll be in the same namespace as the ingress object.
To secure Ingress, First you have to add ClusterIssuer to your Ingress resources and cert-manager will then pick it up and create the Certificate resource for you .
Kind : ingress metadata: annotations : cert-manager.io/cluster-issuer: nameOfClusterIssuer .
Second you have to add tls <= this indicates the creation of certificate(key/cert pair) by Cert-manager via The ClusterIssuer.
Third you have to add secretName: myingress <= here the cert manager will store the tls secrets ( after creating key/cert pair and store them for you)..

Waiting on certificate issuance from order status "pending"

I'm running into an issue handling tls certificates with cert-manager, I'm following the documentation and added some extras to work with Traefik as an ingress.
Currently, I have this YAML files:
cluster-issuer.yaml
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
name: letsencrypt-staging
namespace: secure-alexguedescom
spec:
acme:
email: user#gmail.com
server: https://acme-staging-v02.api.letsencrypt.org/directory
privateKeySecretRef:
# Secret resource used to store the account's private key.
name: letsencrypt-staging
# Add a single challenge solver, HTTP01 using nginx
solvers:
- selector: {}
http01:
ingress:
class: traefik-cert-manager
traefik-ingress.yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
# add an annotation indicating the issuer to use.
cert-manager.io/cluster-issuer: letsencrypt-staging
name: secure-alexguedescom-ingress-http
namespace: secure-alexguedescom
spec:
rules:
- host: secure.alexguedes.com
http:
paths:
- backend:
serviceName: secure-alexguedescom-nginx
servicePort: 80
path: /
tls:
- hosts:
- secure.alexguedes.com
secretName: secure-alexguedescom-cert
cert-staging.yaml
apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
name: secure-alexguedescom-cert
namespace: secure-alexguedescom
spec:
commonName: secure.alexguedes.com
secretName: letsencrypt-staging
dnsNames:
- secure.alexguedes.com
issuerRef:
name: letsencrypt-staging
kind: ClusterIssuer
Inspecting the certs I have this error message:
Message: Issuing certificate as Secret does not contain a certificate
Reason: MissingData
Also inspecting the certificaterequest I have this log messages:
Status:
Conditions:
Last Transition Time: 2020-08-16T00:32:01Z
Message: Waiting on certificate issuance from order secure-alexguedescom/secure-alexguedescom-cert-q8w5p-1982372682: "pending"
Reason: Pending
Status: False
Type: Ready
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal OrderCreated 11m cert-manager Created Order resource secure-alexguedescom/secure-alexguedescom-cert-q8w5p-1982372682
Normal OrderPending 11m cert-manager Waiting on certificate issuance from order secure-alexguedescom/secure-alexguedescom-cert-q8w5p-1982372682: ""
I'm not sure which piece is wrong, using Helm v2 with Tiller and k8s v1.7
Any ideas?
Thanks in advance
The typical problem with letsencrypt certs is the letsencrypt itself not being able to validate who you are and that you own the domain. In this case, alexguedes.com.
With cert-manager you can do Domain Validation and HTTP Validation. Based on the posted ClusterIssuer you are doing HTTP Validation. So you need to make sure that secure.alexguedes.com resolves to a globally available IP address and that Traefik port 443 is listening on that IP address.