I am unable to issue a working certificate for my ingress host in k8s. I use a ClusterIssuer to issue certificates and the same ClusterIssuer has issued certificates in the past for my ingress hosts under my domain name *xyz.com. But all of a sudden neither i can issue new Certificate with state 'True' for my host names nor a proper certificate secret (kubernetes.io/tls) gets created (but instead an Opaque secret gets created).
**strong text**
**kubectl describe certificate ingress-cert -n abc**
Name: ingress-cert
Namespace: abc
Labels: <none>
Annotations: <none>
API Version: cert-manager.io/v1beta1
Kind: Certificate
Metadata:
Creation Timestamp: 2021-09-08T07:48:32Z
Generation: 1
Owner References:
API Version: extensions/v1beta1
Block Owner Deletion: true
Controller: true
Kind: Ingress
Name: test-ingress
UID: c03ffec0-df4f-4dbb-8efe-4f3550b9dcc1
Resource Version: 146643826
Self Link: /apis/cert-manager.io/v1beta1/namespaces/abc/certificates/ingress-cert
UID: 90905ab7-22d2-458c-b956-7100c4c77a8d
Spec:
Dns Names:
abc.xyz.com
Issuer Ref:
Group: cert-manager.io
Kind: ClusterIssuer
Name: letsencrypt
Secret Name: ingress-cert
Status:
Conditions:
Last Transition Time: 2021-09-08T07:48:33Z
Message: Issuing certificate as Secret does not exist
Reason: DoesNotExist
Status: False
Type: Ready
Last Transition Time: 2021-09-08T07:48:33Z
Message: Issuing certificate as Secret does not exist
Reason: DoesNotExist
Status: True
Type: Issuing
Next Private Key Secret Name: ingress-cert-gdq7g
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Issuing 11m cert-manager Issuing certificate as Secret does not exist
Normal Generated 11m cert-manager Stored new private key in temporary Secret resource "ingress-cert-gdq7g"
Normal Requested 11m cert-manager Created new CertificateRequest resource "ingress-cert-dp6sp"
I checked the certificate request and it contains no events. Also i can see no challenges. I have added the logs below. Any help would be appreciated
kubectl describe certificaterequest ingress-cert-dp6sp -n abc
Namespace: abc
Labels: <none>
Annotations: cert-manager.io/certificate-name: ingress-cert
cert-manager.io/certificate-revision: 1
cert-manager.io/private-key-secret-name: ingress-cert-gdq7g
API Version: cert-manager.io/v1beta1
Kind: CertificateRequest
Metadata:
Creation Timestamp: 2021-09-08T07:48:33Z
Generate Name: ingress-cert-
Generation: 1
Owner References:
API Version: cert-manager.io/v1alpha2
Block Owner Deletion: true
Controller: true
Kind: Certificate
Name: ingress-cert
UID: 90905ab7-22d2-458c-b956-7100c4c77a8d
Resource Version: 146643832
Self Link: /apis/cert-manager.io/v1beta1/namespaces/abc/certificaterequests/ingress-cert-dp6sp
UID: fef72617-fc1d-4384-9f4b-a7e4502582d8
Spec:
Issuer Ref:
Group: cert-manager.io
Kind: ClusterIssuer
Name: letsencrypt
Request: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURSBSRVFVRVNULS0tLS0KTUlJQ2Z6Q0NBV2NDQVFBd0FEQ0NBU0l3RFFZSktvWklodmNOQVFFQkJRQURnZ0VQQURDQ0FRb0NnZ0VCQUxMNgphTGhZNjhuNnhmMUprYlF5ek9OV1J4dGtLOXJrbjh5WUtMd2l4ZEFMVUl0TERra0t6Uksyb3loZzRMMThSQmQvCkNJaGJ5RXBYNnlRditKclRTOC84T1A0MWdwTUxBLzROdVhXWWtyeWhtZFdNaFlqa21OOFpiTUk1SlZZcVV2cVkKRWQ1b2cydmVmSjU1QlJPRExsd0o3YjBZa3hXckUwMGJxQ1ExWER6ZzFhM08yQ2JWd1NQT29WV2x6Uy9CdzRYVgpMeVdMS3E4QU52b2dZMUxXRU8xcG9YelRObm9LK2U2YVZueDJvQ1ZLdGxPaG1iYXRHYXNSaTJKL1FKK0dOWHovCnFzNXVBSlhzYVErUzlxOHIvbmVMOXNPYnN2OWd1QmxCK09yQVg2eHhkNHZUdUIwVENFU00zWis2c2MwMFNYRXAKNk01RlY3dkFFeDQyTWpuejVoa0NBd0VBQWFBNk1EZ0dDU3FHU0liM0RRRUpEakVyTUNrd0p3WURWUjBSQkNBdwpIb0ljY25kemMyZHdMbU5zYjNWa1oyRjBaUzV0YVdOeWIyWnBiaTVrWlRBTkJna3Foa2lHOXcwQkFRc0ZBQU9DCkFRRUFTQ0cwTXVHMjZRbVFlTlBFdmphNHZqUUZOVFVINWVuMkxDcXloY2ZuWmxocWpMbnJqZURuL2JTV1hwdVIKTnhXTnkxS0EwSzhtMG0rekNPbWluZlJRS1k2eHkvZU1WYkw4dTgrTGxscDEvRHl3UGxvREE2TkpVOTFPaDM3TgpDQ0E4NWphLy9FYVVvK0p5aHBzaTZuS1d4UXRpYXdmYXhuNUN4SENPWGF5Qzg0Q0IzdGZ2WWp6YUF3Ykx4akxYCmxvd09LUHNxSE51ZktFM0NtcjZmWGgramd5VWhxamYwOUJHeGxCWEFsSVNBNkN5dzZ2UmpWamFBOW82TmhaTXUKbmdheWZON00zUzBBYnAzVFFCZW8xYzc3QlFGaGZlSUE5Sk51SWtFd3EvNXppYVY1RDErNUxSSnR5ZkVpdnJLTwpmVjQ5WkpCL1BGOTdiejhJNnYvVW9CSkc2Zz09Ci0tLS0tRU5EIENFUlRJRklDQVRFIFJFUVVFU1QtLS0tLQo=
Status:
Conditions:
Last Transition Time: 2021-09-08T07:48:33Z
Message: Waiting on certificate issuance from order abc/ingress-cert-dp6sp-3843501305: ""
Reason: Pending
Status: False
Type: Ready
Events: <none>
Here is the ingress.yaml
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
name: test-ingress
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: 20m
kubernetes.io/ingress.class: "nginx"
cert-manager.io/cluster-issuer: "letsencrypt"
spec:
rules:
- host: abc.xyz.com
http:
paths:
- path: /static
backend:
serviceName: app-service
servicePort: 80
- path: /
backend:
serviceName: app-service
servicePort: 8000
tls:
- hosts:
- abc.xyz.com
secretName: ingress-cert
Here is the clusterissuer:
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
name: letsencrypt
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: example#user.de
privateKeySecretRef:
name: letsencrypt-key
solvers:
- http01:
ingress:
class: nginx
Works only with Nginx Ingress Controller
I was using ClusterIssuer but I changed it to Issuer and it works.
-- Install cert-manager (Installed version 1.6.1) and be sure that the three pods are running
-- Create an Issuer by appling this yml be sure that the issuer is running.
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: letsencrypt-nginx
namespace: default
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: example#example.com
privateKeySecretRef:
name: letsencrypt-nginx-private-key
solvers:
- http01:
ingress:
class: nginx
-- Add this to your ingress annotations
cert-manager.io/issuer: letsencrypt-nginx
-- Add the secretName to your ingress spec.tls.hosts
spec:
tls:
- hosts:
- yourdomain.com
secretName: letsencrypt-nginx
Notice that the Nginx Ingress Controller is able to generate the Certificate CRD automatically via a special annotation: cert-manager.io/issuer. This saves work and time, because you don't have to create and maintain a separate manifest for certificates as well (only the Issuer manifest is required). For other ingresses you may need to provide the Certificate CRD as well.
Ideally your ingress pointing to the secret which is storing the secret or SSL/TLS key cert.
kind: Ingress
apiVersion: extensions/v1beta1
metadata:
name: test-ingress
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: 20m
kubernetes.io/ingress.class: "nginx"
cert-manager.io/cluster-issuer: "letsencrypt"
spec:
rules:
- host: abc.xyz.com
http:
paths:
- path: /static
backend:
serviceName: app-service
servicePort: 80
- path: /
backend:
serviceName: app-service
servicePort: 8000
tls:
- hosts:
- abc.xyz.com
secretName: letsencrypt-key
Your cluster issue storing the key
privateKeySecretRef:
name: letsencrypt-key
You have to use this secret and attach this to ingress.
If secret already storing cert with a domain
test.example.com and you are trying to get a new cert with hello.example.com
in this case using cluster issuer will overwrite the secret and might loss old cert stored inside secret.
You can create the multiple clusterissuer,
One storing and connect to single ingress, first.example.com
Second cluster issuer with different key name
privateKeySecretRef:
name: letsencrypt-key
and new key or secret will get attached to the ingress.
Related
I have an issue with Certificate from Let's Encrypt in Kubernetes in Azure AKS.
It seems to be valid in k8s, but web browsers shows "Kubernetes Ingress Controller Fake Certificate". Following steps from https://cert-manager.io/docs/troubleshooting/ to describe my state:
kubectl get certificates --all-namespaces
NAMESPACE NAME READY SECRET AGE
gap tls-secret True tls-secret 5h29m
kubectl get CertificateRequests --all-namespaces
NAMESPACE NAME APPROVED DENIED READY ISSUER REQUESTOR AGE
gap tls-secret-h8xvm True True letsencrypt-prod system:serviceaccount:ingress-basic:cert-manager 5h31m
kubectl get clusterissuer --all-namespaces
NAME READY AGE
letsencrypt-prod True 5h45m
kubectl describe clusterissuer letsencrypt-prod
...
Spec:
Acme:
Email: aaa#company.com
Preferred Chain:
Private Key Secret Ref:
Name: letsencrypt-prod
Server: https://acme-v02.api.letsencrypt.org/directory
Solvers:
http01:
Ingress:
Class: nginx
Pod Template:
Metadata:
Spec:
Node Selector:
kubernetes.io/os: linux
Status:
Acme:
Last Registered Email: aaa#company.com
Uri: https://acme-v02.api.letsencrypt.org/acme/acct/XXXXXXXX
Conditions:
Last Transition Time: 2022-09-07T15:05:07Z
Message: The ACME account was registered with the ACME server
Observed Generation: 1
Reason: ACMEAccountRegistered
Status: True
Type: Ready
Events: <none>
kubectl get order --all-namespaces
NAMESPACE NAME STATE AGE
gap tls-secret-h8xvm-907122039 valid 5h38m
kubectl describe order -n gap tls-secret-h8xvm-907122039
Spec:
Dns Names:
my.app.com
Issuer Ref:
Group: cert-manager.io
Kind: ClusterIssuer
Name: letsencrypt-prod
Request: XXXXXXXXX
Status:
Authorizations:
Challenges:
Token: XXXXXXXXXXX
Type: http-01
URL: https://acme-v02.api.letsencrypt.org/acme/chall-v3/XXX/YYY
Identifier: dev01.got-dev.ligenius.app
Initial State: valid
URL: https://acme-v02.api.letsencrypt.org/acme/authz-v3/XXX
Wildcard: false
Certificate: XXXXXXX
Finalize URL: https://acme-v02.api.letsencrypt.org/acme/finalize/YYY/ZZZ
State: valid
URL: https://acme-v02.api.letsencrypt.org/acme/order/YYY/ZZZ
Events: <none>
kubectl get challenges --all-namespaces
No resources found
Is it ok that challenge doesn't exist?
Update 1
Ingress definition
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: XXX-chart
labels:
helm.sh/chart: xxx-chart-0.1.0
app.kubernetes.io/name: xxx-chart
app.kubernetes.io/instance: RELEASE-NAME
app.kubernetes.io/version: "1.16.0"
app.kubernetes.io/managed-by: Helm
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- "my.app.com"
secretName: tls-secret
rules:
- host: "my.app.com"
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: "yyy-svc"
port:
number: 80
- ... more path definition
curl -k https://my.app.com/
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>nginx</center>
</body>
</html>
It looks like ingress nginx return default 404 page, but it shouldn't matter for certificate instalation. The yyy-svc and other services are up and running.
Kubernetes server 1.22.6
ingress-nginx/controller v1.3.1
cert-manager v1.9.1
Any thought what is misconfigured?
Earlier it worked for cert-manager v0.16.1, after upgrade to 1.9.1 and solving https://github.com/cert-manager/cert-manager/issues/3501 it doesn't work anymore.
I found the issue. In Ingress the annotation: kubernetes.io/ingress.class: nginx was missing. I removed it some time ago because of some changes in cluster and now it's needed again.
I followed this instruction to set up a cert manager on my EKS cluster https://cert-manager.io/docs/tutorials/acme/ingress/.
here is my ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: test
annotations:
kubernetes.io/ingress.class: "nginx"
cert-manager.io/issuer: "letsencrypt-staging"
spec:
tls:
- hosts:
- '*.test.com'
secretName: test-tls
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: test-service
port:
number: 80
Here is the issuer. I just copied the config from the instruction
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: letsencrypt-staging
spec:
acme:
server: https://acme-staging-v02.api.letsencrypt.org/directory
email: info#test.com
privateKeySecretRef:
name: letsencrypt-staging
solvers:
- http01:
ingress:
class: nginx
After deployment, I found the certificate ready state is false
kubectl get certificate
NAME READY SECRET AGE
test-tls False test-tls 2m45s
Then I followed this to troubleshoot https://cert-manager.io/docs/faq/troubleshooting/
I ran kubectl describe certificaterequest <request name>, found error Waiting on certificate issuance from order test-tls-xxx: "pending"
then ran kubectl describe order test-tls-xxx, found error
Warning Solver 20m cert-manager Failed to determine a valid solver configuration for the set of domains on the Order: no configured challenge solvers can be used for this challenge.
Any idea why it couldn't determine a valid solver? how do I test if solver is working?
It's not working due you are using the staging URL in cluster issuer to verify the image.
Please try with the Production URL.
here a simple and proper example of Clusterissuer and ingress YAML (do note you were trying with staging API https://acme-staging-v02.api.letsencrypt.org/directory if possible use the production server address so it works properly with all browsers)
Example:
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
Note : When you are trying again please try deleting the old objects like ingress, Clusterissuer first.
Issuer vs ClusterIssuer
An Issuer is a namespaced resource, and it is not possible to issue
certificates from an Issuer in a different namespace. This means you
will need to create an Issuer in each namespace you wish to obtain
Certificates in.
If you want to create a single Issuer that can be consumed in multiple
namespaces, you should consider creating a ClusterIssuer resource.
This is almost identical to the Issuer resource, however is
non-namespaced so it can be used to issue Certificates across all
namespaces.
Ref : https://cert-manager.io/docs/concepts/issuer/
Wildcard cert
You can use as per requirement, if you are using issuer you can update the ingress annotation line like
cert-manager.io/issuer: issuer-name
If you are trying to get the wildcard * certificate you won't be able to get it using HTTP auth method
solvers:
- http01:
ingress:
class: nginx-class-name
instead of this you have to use the DNS-auth method for wildcard cert.
solvers:
- dns01:
cloudDNS:
project: my-project
serviceAccountSecretRef:
name: prod-clouddns-svc-acct-secret
key: service-account.json
Read more at : https://cert-manager.io/docs/configuration/acme/dns01/
Ref article to get the wildcard cert : https://medium.com/#harsh.manvar111/wild-card-certificate-using-cert-manager-in-kubernetes-3406b042d5a2
I am trying to deploy ingress-routes in Kubernetes following these guides:
https://cert-manager.io/docs/tutorials/acme/ingress/
https://learn.microsoft.com/en-us/azure/aks/ingress-static-ip
I have deployed a cluster-issuer:
apiVersion: cert-manager.io/v1alpha2
kind: ClusterIssuer
metadata:
name: letsencrypt
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: <Myemail>
privateKeySecretRef:
name: letsencrypt
solvers:
- http01:
ingress:
class: nginx
podTemplate:
spec:
nodeSelector:
"kubernetes.io/os": linux
Then I have deployed ingress:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: airflow-ingress
namespace: airflow6
annotations:
kubernetes.io/ingress.class: nginx
certmanager.k8s.io/cluster-issuer: letsencryp
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
tls:
- hosts:
- <MYhost>
secretName: tls-secret1
rules:
- host: <MYhost>
http:
paths:
- path: /
backend:
serviceName: airflow-web
servicePort: 8080
Then if I try to get the certificate:
kubectl describe certificate tls-secret1 --namespace airflow6
Error from server (NotFound): certificates.cert-manager.io "tls-secret1" not found
I have tried to deploy my own certificate:
apiVersion: cert-manager.io/v1alpha2
kind: Certificate
metadata:
name: tls-secret1
namespace: airflow6
spec:
secretName: tls-secret1
dnsNames:
- <MYhost>
issuerRef:
name: letsencrypt
# We can reference ClusterIssuers by changing the kind here.
# The default value is Issuer (i.e. a locally namespaced Issuer)
kind: ClusterIssuer
group: cert-manager.io
Then run the same command:
kubectl describe certificate tls-secret1 --namespace airflow6
Name: tls-secret1
Namespace: airflow6
Labels: <none>
Annotations: API Version: cert-manager.io/v1beta1
Kind: Certificate
Metadata:
Creation Timestamp: 2020-10-12T10:50:25Z
Generation: 1
Resource Version: 9408916
Self Link: /apis/cert-manager.io/v1beta1/namespaces/airflow6/certificates/quickstart-example-tls
UID: 5c4f06e2-bb61-4eed-8999-58540d4055ce
Spec:
Dns Names:
<Myhost>
Issuer Ref:
Group: cert-manager.io
Kind: ClusterIssuer
Name: letsencrypt
Secret Name: tls-secret1
Status:
Conditions:
Last Transition Time: 2020-10-12T10:50:25Z
Message: Issuing certificate as Secret does not exist
Reason: DoesNotExist
Status: True
Type: Issuing
Last Transition Time: 2020-10-12T10:50:25Z
Message: Issuing certificate as Secret does not exist
Reason: DoesNotExist
Status: False
Type: Ready
Next Private Key Secret Name: tls-secret1
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Issuing 3m8s cert-manager Issuing certificate as Secret does not exist
Normal Requested 3m8s cert-manager Created new CertificateRequest resource "quickstart-example-tls-hl7vk"
Normal Requested <invalid> cert-manager Created new CertificateRequest resource "quickstart-example-tls-vqmbh"
Normal Generated <invalid> (x3 over 3m8s) cert-manager Stored new private key in temporary Secret resource "quickstart-example-tls-fgvn6"
Normal Requested <invalid> cert-manager Created new CertificateRequest resource "quickstart-example-tls-5gg9l"
I don't know if I need to create a secret like this:
apiVersion: v1
kind: Secret
name: example-tls
namespace: foo
data:
tls.crt: <base64 encoded cert>
tls.key: <base64 encoded key>
type: kubernetes.io/tls
But I really don't know what I have to put in tls.crt and tls.key.
In all the guides I have read I saw that when the ingress-routes is deployed automatically a certificate is created but for me is not working, what I am going wrong?
no you are not supposed to create the TLS secret on your own, it's like when you put the secret name in the ingress rule's tls section, then while doing the DNS verification, the secret will be created by issuer itself for the respective namespace in which the ingress rule has been created.
To cross-check on configs created or to create new one, you can refer this
Then you can follow this stack overflow post, it will help you likely
I have it working on one site application I already set up and now I am just trying to replicate the exact same thing for a different site/domain in another namespace.
So staging.correct.com is my working https domain
and staging.example.com is my not working https domain (http works - just not https)
When I do the following it shows 3 certs, the working one for correct and then 2 for the example.com when it should only have one for example:
kubectl get -A certificate
correct staging-correct-com True staging-correct-com-tls 10d
example staging-example-com False staging-example-com-tls 16h
example staging-example-website-com False staging-example-com-tls 17h
When I do:
kubectl get -A certificaterequests
It shows 2 certificate requests for the example
example staging-example-com-nl46v False 15h
example staging-example-website-com-plhqb False 15h
When I do:
kubectl get ingressroute -A
NAMESPACE NAME AGE
correct correct-ingress-route 10d
correct correct-secure-ingress-route 6d22h
kube-system traefik-dashboard 26d
example example-website-ingress-route 15h
example example-website-secure-ingress-route 15h
routing dashboard 29d
routing traefik-dashboard 6d21h
When I do:
kubectl get secrets -A (just showing the relevant ones)
correct default-token-bphcm kubernetes.io/service-account-token
correct staging-correct-com-tls kubernetes.io/tls
example default-token-wx9tx kubernetes.io/service-account-token
example staging-example-com-tls Opaque
example staging-example-com-wf224 Opaque
example staging-example-website-com-rzrvw Opaque
Logs from cert manager pod:
1 ingress.go:91] cert-manager/controller/challenges/http01/selfCheck/http01/ensureIngress "msg"="found one existing HTTP01 solver ingress" "dnsName"="staging.example.com" "related_resource_kind"="Ingress" "related_resource_name"="cm-acme-http-solver-bqjsj" "related_resource_namespace”=“example” "related_resource_version"="v1beta1" "resource_kind"="Challenge" "resource_name"="staging-example-com-ltjl6-1661100417-771202110" "resource_namespace”=“example” "resource_version"="v1" "type"="HTTP-01"
When I do:
kubectl get challenge -A
example staging-example-com-nl46v-1661100417-2848337980 staging.example.com 15h
example staging-example-website-com-plhqb-26564845-3987262508 pending staging.example.com
When I do: kubectl get order -A
NAMESPACE NAME STATE AGE
example staging-example-com-nl46v-1661100417 pending 17h
example staging-example-website-com-plhqb-26564845 pending 17h
My yml files:
My ingress route:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
namespace: example
name: example-website-ingress-route
annotations:
kubernetes.io/ingress.class: "traefik"
cert-manager.io/issuer: example-issuer-staging
traefik.ingress.kubernetes.io/router.entrypoints: web
traefik.frontend.redirect.entryPoint: https
spec:
entryPoints:
- web
routes:
- match: Host(`staging.example.com`)
middlewares:
- name: https-only
kind: Rule
services:
- name: example-website
namespace: example
port: 80
my issuer:
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: example-issuer-staging
namespace: example
spec:
acme:
# The ACME server URL
server: https://acme-v02.api.letsencrypt.org/directory
# Email address used for ACME registration
email: example#example.com
# Name of a secret used to store the ACME account private key
privateKeySecretRef:
name: staging-example-com-tls
# Enable the HTTP-01 challenge provider
solvers:
# An empty 'selector' means that this solver matches all domains
- http01:
ingress:
class: traefik
my middleware:
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: https-only
namespace: example
spec:
redirectScheme:
scheme: https
permanent: true
my secure ingress route:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
namespace: example
name: example-website-secure-ingress-route
annotations:
kubernetes.io/ingress.class: "traefik"
cert-manager.io/issuer: example-issuer-staging
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.frontend.redirect.entryPoint: https
spec:
entryPoints:
- websecure
routes:
- match: Host(`staging.example.com`)
kind: Rule
services:
- name: example-website
namespace: example
port: 80
tls:
domains:
- main: staging.example.com
options:
namespace: example
secretName: staging-example-com-tls
my service:
apiVersion: v1
kind: Service
metadata:
namespace: example
name: 'example-website'
spec:
type: ClusterIP
ports:
- protocol: TCP
name: http
port: 80
targetPort: 80
- protocol: TCP
name: https
port: 443
targetPort: 80
selector:
app: 'example-website'
my solver:
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: staging-example-com
namespace: example
spec:
secretName: staging-example-com-tls
issuerRef:
name: example-issuer-staging
kind: Issuer
commonName: staging.example.com
dnsNames:
- staging.example.com
my app:
apiVersion: apps/v1
kind: ReplicaSet
metadata:
namespace: example
name: 'example-website'
labels:
app: 'example-website'
tier: 'frontend'
spec:
replicas: 1
selector:
matchLabels:
app: 'example-website'
template:
metadata:
labels:
app: 'example-website'
spec:
containers:
- name: example-website-container
image: richarvey/nginx-php-fpm:1.10.3
imagePullPolicy: Always
env:
- name: SSH_KEY
value: 'secret'
- name: GIT_REPO
value: 'url of source code for site'
- name: GIT_EMAIL
value: 'example#example.com'
- name: GIT_NAME
value: 'example'
ports:
- containerPort: 80
How can I delete all these secrets, orders, certificates and stuff in the example namespace and try again? Does cert-manager let you do this without restarting them continuously?
EDIT:
I deleted the namespace and redeployed, then:
kubectl describe certificates staging-example-com -n example
Spec:
Common Name: staging.example.com
Dns Names:
staging.example.com
Issuer Ref:
Kind: Issuer
Name: example-issuer-staging
Secret Name: staging-example-com-tls
Status:
Conditions:
Last Transition Time: 2020-09-26T21:25:06Z
Message: Issuing certificate as Secret does not contain a certificate
Reason: MissingData
Status: False
Type: Ready
Last Transition Time: 2020-09-26T21:25:07Z
Message: Issuing certificate as Secret does not exist
Reason: DoesNotExist
Status: True
Type: Issuing
Next Private Key Secret Name: staging-example-com-gnbl4
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Issuing 3m10s cert-manager Issuing certificate as Secret does not exist
Normal Reused 3m10s cert-manager Reusing private key stored in existing Secret resource "staging-example-com-tls"
Normal Requested 3m9s cert-manager Created new CertificateRequest resource "staging-example-com-qrtfx"
So then I did:
kubectl describe certificaterequest staging-example-com-qrtfx -n example
Status:
Conditions:
Last Transition Time: 2020-09-26T21:25:10Z
Message: Waiting on certificate issuance from order example/staging-example-com-qrtfx-1661100417: "pending"
Reason: Pending
Status: False
Type: Ready
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal OrderCreated 8m17s cert-manager Created Order resource example/staging-example-com-qrtfx-1661100417
Normal OrderPending 8m17s cert-manager Waiting on certificate issuance from order example/staging-example-com-qrtfx-1661100417: ""
So I did:
kubectl describe challenges staging-example-com-qrtfx-1661100417 -n example
Status:
Presented: true
Processing: true
Reason: Waiting for HTTP-01 challenge propagation: wrong status code '404', expected '200'
State: pending
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Started 11m cert-manager Challenge scheduled for processing
Normal Presented 11m cert-manager Presented challenge using HTTP-01 challenge mechanism
I figured it out. The issue seems to be that IngressRoute (which is used in traefik) does not work with cert mananger. I just deployed this file, then the http check was confirmed, then I could delete it again. Hope this helps others with same issue.
Seems cert manager does support IngressRoute which is in Traefik? I opened the issue here so let's see what they say: https://github.com/jetstack/cert-manager/issues/3325
kubectl apply -f example-ingress.yml
File:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
namespace: example
name: example-ingress
annotations:
kubernetes.io/ingress.class: "traefik"
cert-manager.io/issuer: example-issuer-staging
spec:
rules:
- host: staging.example.com
http:
paths:
- path: /
backend:
serviceName: example-website
servicePort: 80
tls:
- hosts:
- staging.example.com
secretName: staging-example-com-tls
I am struggling to get cert-manager to issue certificates from let's encrypt which I can use with my ingress in Google Cloud Kubernetes.
I have a cluster running with a deployment, service and ingress in the default namespace. I also registered a domain at namecheap and added an A record to the IP address from my ingress. Now I can access the website with http and everything is fine. Now I want to move to https and things do not work.
I have installed cert-manager:
kubectl create namespace cert-manager
kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v0.13.1/cert-manager.yaml
I verified that cert-manager is running:
kubectl get pods --namespace cert-manager
NAME READY STATUS RESTARTS AGE
cert-manager-5655447474-kw9k7 1/1 Running 0 99m
cert-manager-cainjector-59c9dfd4f7-fjzbf 1/1 Running 0 99m
cert-manager-webhook-865b8fb666-7kmx2 1/1 Running 0 99m
Now I created a ClusterIssuer kubectl apply -f letsencrypt-prod.yaml in the default namespace:
apiVersion: certmanager.k8s.io/v1alpha1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: 'my#email.com'
privateKeySecretRef:
name: letsencrypt-prod
http01: {}
And added a certificate with kubectl apply -f certificate.yaml:
apiVersion: certmanager.k8s.io/v1alpha1
kind: Certificate
metadata:
name: my-certs
spec:
secretName: my-certs
issuerRef:
name: letsencrypt-prod
kind: ClusterIssuer
commonName: "www.mydomain.de"
dnsNames:
- "www.mydomain.de"
acme:
config:
- dns01:
provider: cloud-dns
domains:
- "www.mydomain.de"
This is my ingress:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
annotations:
kubernetes.io/ingress.global-static-ip-name: "my-ip"
spec:
rules:
- host: www.mydomain.de
http:
paths:
- backend:
serviceName: my-service
servicePort: 80
tls:
- hosts:
- www.mydomain.de
secretName: my-certs
Now when I run kubectl describe certificate my-certs there are no events:
kubectl describe certificate my-certs
Name: my-certs
Namespace: default
Labels: <none>
Annotations: kubectl.kubernetes.io/last-applied-configuration:
{"apiVersion":"certmanager.k8s.io/v1alpha1","kind":"Certificate","metadata":{"annotations":{},"name":"my-certs","namespace":"default"},"sp...
API Version: certmanager.k8s.io/v1alpha1
Kind: Certificate
Metadata:
Creation Timestamp: 2020-02-23T13:30:15Z
Generation: 1
Resource Version: 787204
Self Link: /apis/certmanager.k8s.io/v1alpha1/namespaces/default/certificates/my-certs
UID: a027a698-5640-11ea-bce8-42010a9c00dc
Spec:
Acme:
Config:
Dns 01:
Provider: cloud-dns
Domains:
www.mydomain.de
Common Name: www.mydomain.de
Dns Names:
www.mydomain.de
Issuer Ref:
Kind: ClusterIssuer
Name: letsencrypt-prod
Secret Name: my-certs
Events: <none>
And in Google Cloud Console I see the message "Could not find TLS certificates. Continuing setup for the load balancer to serve HTTP" for the ingress.
What is wrong here or what am I missing?
Instead of creating the certificate resource manually you can add below annotation to the ingress resource:
cert-manager.io/issuer: "letsencrypt-prod"
Cert-manager will read the annotation and use them to create a certificate.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: my-ingress
annotations:
kubernetes.io/ingress.global-static-ip-name: "my-ip"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
rules:
- host: www.mydomain.de
http:
paths:
- backend:
serviceName: my-service
servicePort: 80
tls:
- hosts:
- www.mydomain.de
secretName: my-certs
After this check if a secret and certificate with name my-certs got created or not.
Also check the related issue