Как посмотреть состояние сертификата?
# kubectl -n default describe certificate example-com
...
Status:
Acme:
Authorizations:
Account: https://acme-v01.api.letsencrypt.org/acme/reg/22442061
Domain: example.com
Uri: https://acme-v01.api.letsencrypt.org/acme/challenge/qJA9MGCZnUnVjAgxhoxONvDnKAsPatRILJ4n0lJ7MMY/4062050823
Account: https://acme-v01.api.letsencrypt.org/acme/reg/22442061
Domain: admin.example.com
Uri: https://acme-v01.api.letsencrypt.org/acme/challenge/pW2tFKLBDTll2Gx8UBqmEl846x5W-YpBs8a4HqstJK8/4062050808
Account: https://acme-v01.api.letsencrypt.org/acme/reg/22442061
Domain: www.example.com
Uri: https://acme-v01.api.letsencrypt.org/acme/challenge/LaZJMM9_OKcTYbEThjT3oLtwgpkNfbHVdl8Dz-yypx8/4062050792
Conditions:
Last Transition Time: 2018-04-02T18:01:04Z
Message: Certificate issued successfully
Reason: CertIssueSuccess
Status: True
Type: Ready
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal PrepareCertificate 1m cert-manager-controller Preparing certificate with issuer
Normal PresentChallenge 1m cert-manager-controller Presenting http-01 challenge for domain example.com
Normal PresentChallenge 1m cert-manager-controller Presenting http-01 challenge for domain www.example.com
Normal PresentChallenge 1m cert-manager-controller Presenting http-01 challenge for domain admin.example.com
Normal SelfCheck 1m cert-manager-controller Performing self-check for domain admin.example.com
Normal SelfCheck 1m cert-manager-controller Performing self-check for domain example.com
Normal SelfCheck 1m cert-manager-controller Performing self-check for domain www.example.com
Normal ObtainAuthorization 55s cert-manager-controller Obtained authorization for domain example.com
Normal ObtainAuthorization 54s cert-manager-controller Obtained authorization for domain admin.example.com
Normal ObtainAuthorization 53s cert-manager-controller Obtained authorization for domain www.example.com
Как получить список сертификатов?
# kubectl get certificate --all-namespaces
NAMESPACE NAME AGE
default example-com 13m
Какие виды сертификатов поддерживаются?
На данный момент модуль устанавливает два ClusterIssuer’а:
- letsencrypt
- letsencrypt-staging
Работает ли старая аннотация tls-acme?
Да, работает! Специальный компонент (cert-manager-ingress-shim
) видит эти аннотации и на их основании автоматически создает ресурсы Certificate
(в тех же namespace, что и Ingress-ресурсы с аннотациями).
Важно! При использовании аннотации, Certificate создается “прилинкованным” к существующему Ingress-ресурсу, и для прохождения challenge НЕ создается отдельный Ingress, а вносятся дополнительные записи в существующий. Это означает, что если на основном Ingress’е настроена аутентификация или whitelist — ничего не выйдет. Лучше не использовать аннотацию и переходить на Certificate.
Важно! При переходе с аннотации на Certificate нужно удалить Certificate который был создан по аннотации. Иначе, по обоим Certificate будет обновляться один Secret и это может привести к достижению лимита запросов Let’s Encrypt.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
kubernetes.io/tls-acme: "true" # вот она, аннотация!
name: example-com
namespace: default
spec:
ingressClassName: nginx
rules:
- host: example.com
http:
paths:
- backend:
service:
name: site
port:
number: 80
path: /
pathType: ImplementationSpecific
- host: www.example.com # дополнительный домен
http:
paths:
- backend:
service:
name: site
port:
number: 80
path: /
pathType: ImplementationSpecific
- host: admin.example.com # еще один дополнительный домен
http:
paths:
- backend:
service:
name: site
port:
number: 80
path: /
pathType: ImplementationSpecific
tls:
- hosts:
- example.com
- www.example.com # дополнительный домен
- admin.example.com # еще один дополнительный домен
secretName: example-com-tls # так будут называться и certificate и secret
Ошибка: CAA record does not match issuer
Если cert-manager
не может заказать сертификаты с ошибкой:
CAA record does not match issuer
То необходимо проверить CAA (Certificate Authority Authorization)
DNS запись у домена, для которого заказывается сертификат.
Если вы хотите использовать Let’s Encrypt сертификаты, то у домена должна быть CAA запись: issue "letsencrypt.org"
.
Подробнее про CAA можно почитать тут и тут.
Интеграция с Vault
Вы можете использовать данную инструкцию для выпуска сертификатов с помощью Vault.
После конфигурации PKI и включения авторизации в Kubernetes, вам нужно:
-
Создать service account и скопировать ссылку на его секрет:
kubectl create serviceaccount issuer ISSUER_SECRET_REF=$(kubectl get serviceaccount issuer -o json | jq -r ".secrets[].name")
-
Создать Issuer:
kubectl apply -f - <<EOF apiVersion: cert-manager.io/v1 kind: Issuer metadata: name: vault-issuer namespace: default spec: vault: # если Vault разворачивался по вышеуказанной инструкции, в это месте в инструкции опечатка server: http://vault.default.svc.cluster.local:8200 # указывается на этапе конфигурации PKI path: pki/sign/example-dot-com auth: kubernetes: mountPath: /v1/auth/kubernetes role: issuer secretRef: name: $ISSUER_SECRET_REF key: token EOF
-
Создать ресурс Certificate, для получения TLS сертификата подписанного Vault CA:
kubectl apply -f - <<EOF apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: example-com namespace: default spec: secretName: example-com-tls issuerRef: name: vault-issuer # домены указываются на этапе конфигурации PKI в Vault commonName: www.example.com dnsNames: - www.example.com EOF
Как защитить учетные данные cert-manager?
Если вы не хотите хранить учетные данные конфигурации Deckhouse (например, по соображениям безопасности), вы можете создать свой собственный ClusterIssuer / Issuer. Например, вы можете создать свой ClusterIssuer для сервиса route53 следующим образом:
-
Создайте секрет с учетными данными:
kubectl apply -f - <<EOF apiVersion: v1 kind: Secret type: Opaque metadata: name: route53 namespace: default data: secret-access-key: {{ "MY-AWS-ACCESS-KEY-TOKEN" | b64enc | quote }} EOF
-
Создайте простой ClusterIssuer со ссылкой на этот секрет:
kubectl apply -f - <<EOF apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: route53 namespace: default spec: acme: server: https://acme-v02.api.letsencrypt.org/directory privateKeySecretRef: name: route53-tls-key solvers: - dns01: route53: region: us-east-1 accessKeyID: {{ "MY-AWS-ACCESS-KEY-ID" }} secretAccessKeySecretRef: name: route53 key: secret-access-key EOF
-
Закажите сертификаты как обычно, используя созданный ClusterIssuer:
kubectl apply -f - <<EOF apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: example-com namespace: default spec: secretName: example-com-tls issuerRef: name: route53 commonName: www.example.com dnsNames: - www.example.com EOF