Aws-cert-manager: различия между версиями
Sirmax (обсуждение | вклад) |
Sirmax (обсуждение | вклад) |
||
| Строка 129: | Строка 129: | ||
NAME READY SECRET ISSUER STATUS AGE |
NAME READY SECRET ISSUER STATUS AGE |
||
mpp-staging-tls True mpp-staging-tls letsencrypt-http-cert-issuer Certificate is up to date and has not expired 6d20h |
mpp-staging-tls True mpp-staging-tls letsencrypt-http-cert-issuer Certificate is up to date and has not expired 6d20h |
||
| + | </PRE> |
||
| + | Объект <code> Certificate</code> содержит в себе те же метки что и <code>Ingress</code> |
||
| + | <PRE> |
||
| + | kubectl -n mpp-staging get certificates mpp-staging-tls -o yaml |
||
| + | </PRE> |
||
| + | <PRE> |
||
| + | apiVersion: cert-manager.io/v1 |
||
| + | kind: Certificate |
||
| + | metadata: |
||
| + | creationTimestamp: "2025-06-01T18:25:43Z" |
||
| + | generation: 2 |
||
| + | labels: |
||
| + | app.kubernetes.io/managed-by: Helm |
||
| + | application: mpp-ingress |
||
| + | component: mpp-ingress |
||
| + | name: mpp-staging-tls |
||
| + | namespace: mpp-staging |
||
| + | ownerReferences: |
||
| + | - apiVersion: networking.k8s.io/v1 |
||
| + | blockOwnerDeletion: true |
||
| + | controller: true |
||
| + | kind: Ingress |
||
| + | name: mpp-ingress |
||
| + | uid: e600fec5-935b-4156-ab32-bf1ae73a92eb |
||
| + | resourceVersion: "2606170" |
||
| + | uid: daa30a3b-7e10-477f-9c14-61832fb3d284 |
||
| + | spec: |
||
| + | dnsNames: |
||
| + | - be.staging.arturhaunt.ninja |
||
| + | - login.staging.arturhaunt.ninja |
||
| + | - log.staging.arturhaunt.ninja |
||
| + | - content.staging.arturhaunt.ninja |
||
| + | - fe.staging.arturhaunt.ninja |
||
| + | - ca.staging.arturhaunt.ninja |
||
| + | - shootin.staging.arturhaunt.ninja |
||
| + | - seeble.staging.rankparrot.com |
||
| + | - seeble2.staging.rankparrot.com |
||
| + | issuerRef: |
||
| + | group: cert-manager.io |
||
| + | kind: ClusterIssuer |
||
| + | name: letsencrypt-http-cert-issuer |
||
| + | secretName: mpp-staging-tls |
||
| + | usages: |
||
| + | - digital signature |
||
| + | - key encipherment |
||
| + | status: |
||
| + | conditions: |
||
| + | - lastTransitionTime: "2025-06-08T14:20:10Z" |
||
| + | message: Certificate is up to date and has not expired |
||
| + | observedGeneration: 2 |
||
| + | reason: Ready |
||
| + | status: "True" |
||
| + | type: Ready |
||
| + | notAfter: "2025-09-06T13:21:39Z" |
||
| + | notBefore: "2025-06-08T13:21:40Z" |
||
| + | renewalTime: "2025-08-07T13:21:39Z" |
||
| + | revision: 1 |
||
</PRE> |
</PRE> |
||
Версия 17:16, 8 июня 2025
Для Ingress требуется автоматически выписывать сертефикаты для доменов которые "Хостятся" на нем
Предварительные требования
Требуется доступ (ручной или автоматический) к управлению зоной DNS для того что бы направить нужные домены на соответвующий Ingress
Возможные варианты решения
- Использовать независимое от cloud-провайдера решение, Let's encrypt.
- В завимсимости от того где лежит DNS-зона и как ей можно управлять, может требовать или не требовать ручной правкии зоны.
- В случае если зона хостится на AWS Route53 возможно применить например такую автоматизацию обновления зоны
- К плюсам можно отнести то что решение будет работать на любом клауде, не привязано к провайдеру.
- Список возможных Issuers досаточно широк (https://cert-manager.io/docs/configuration/issuers/), для тестирования можно например использовать локально развернутый Hashicorp Vault
- Использовать сертефикаты от AWS (это пока не реализовано)
cert-manager
Для решения этой задачи существует cert-manager
Примерный принцип работы (насколько я его понимаю)
- Установка в том чимсле создания
Custom Resource Definition(далееCRD) - Cоздается ресусурс типа
IssuerилиClusterIssuer— описывает, откуда брать сертификаты- Разница в том что
Issuerдоступен только внутри namespace, в моем случае когда все сертефикаты нужны для нескольких копий приложения ("окружений"), напримерdev.domain.tld,staging.domain.tld,qa.domain.tldнужно будет изменитьClusterIssuerнаIssuer. Пока окружение одно это не важно, но как только их несколько то не хочется иметь один сертефикат на всех с длинным списком Altnames (но это требует проверки)
- Разница в том что
- После создания Certificate-ресурса —
cert-managerследит за ним и выполняет выпуск согласно настройкам ресурса, результат сохраняет вSecret
cert-manager автоматически:
- делает HTTP или DNS-проверку чтобы подтвердить владение доменом (в этом случае HTTP так как у него нет доступа к управлению ресурсами зоны!) Как именно определено в поле
solvers - получает сертификат от CA, определенного в поле
acme - сохраняет в
SecretTODO - Мониторит и продлевает его до истечения срока действия.
Установка
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm \ install cert-manager jetstack/cert-manager \ --namespace cert-manager \ --create-namespace \ --set installCRDs=true
Пример ClusterIssuer
Достаточно простой объект
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-http-cert-issuer
spec:
acme:
email: sirmax123@gmail.com
privateKeySecretRef:
name: letsencrypt-http
server: https://acme-v02.api.letsencrypt.org/directory
solvers:
- http01:
ingress:
class: nginx
- имя можно выбрать произвольное
email: sirmax123@gmail.comраньше был нужен что б Let's Encrypt мог прислать оповещение, но он уже давно это отключил и сецчас это просто ненужное но обязательное поле.solversспособ подтверждения владения доменом- имя секрета в котором содержится ключ аккаунта, он создается автоматически если его нет. В целом его можно пересоздать, но тогда можно уперется в число запросов новых аккаунтов, потребуется повторная валидация домена и может еще что то, так что лучше его не удалять.
|
Генерация сертефикатов
Аннотация Ingress
Для того что бы включить генерацию сертефикатов требуется указать аннотацию у Ingress, в которой указать имя желаемого Issuer / ClusterIssuer
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-http-cert-issuer
При этом cert-manager проверить есть ли объект типа Certificate и если нет создаст его на основе значения
в секции .spec.tls.mpp-staging-tls объекта Ingress
Например, для такого Ingress:
tls:
- hosts:
- be.staging.mydomain.tld
- login.staging.mydomain.tld
- log.staging.mydomain.tld
- content.staging.mydomain.tld
- fe.staging.mydomain.tld
- ca.staging.mydomain.tld
- shootin.mydomain.tld
- seeble.staging.myseconddomain.tld
- seeble2.staging.myseconddomain.tld
secretName: mpp-staging-tls
будет создан объект типа Certificate (в том же namespace где находится Ingress)
kubectl -n mpp-staging get Certificate NAME READY SECRET AGE mpp-staging-tls True mpp-staging-tls 6d20h
|
Это может выглядеть как парадокс "курицы и яйца" - секркт должен быть на момент выпуска сертефиката, |
Объект Certificate
Объект создается в том же namespace что и Ingress
kubectl -n mpp-staging get certificates mpp-staging-tls -o wide NAME READY SECRET ISSUER STATUS AGE mpp-staging-tls True mpp-staging-tls letsencrypt-http-cert-issuer Certificate is up to date and has not expired 6d20h
Объект Certificate содержит в себе те же метки что и Ingress
kubectl -n mpp-staging get certificates mpp-staging-tls -o yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
creationTimestamp: "2025-06-01T18:25:43Z"
generation: 2
labels:
app.kubernetes.io/managed-by: Helm
application: mpp-ingress
component: mpp-ingress
name: mpp-staging-tls
namespace: mpp-staging
ownerReferences:
- apiVersion: networking.k8s.io/v1
blockOwnerDeletion: true
controller: true
kind: Ingress
name: mpp-ingress
uid: e600fec5-935b-4156-ab32-bf1ae73a92eb
resourceVersion: "2606170"
uid: daa30a3b-7e10-477f-9c14-61832fb3d284
spec:
dnsNames:
- be.staging.arturhaunt.ninja
- login.staging.arturhaunt.ninja
- log.staging.arturhaunt.ninja
- content.staging.arturhaunt.ninja
- fe.staging.arturhaunt.ninja
- ca.staging.arturhaunt.ninja
- shootin.staging.arturhaunt.ninja
- seeble.staging.rankparrot.com
- seeble2.staging.rankparrot.com
issuerRef:
group: cert-manager.io
kind: ClusterIssuer
name: letsencrypt-http-cert-issuer
secretName: mpp-staging-tls
usages:
- digital signature
- key encipherment
status:
conditions:
- lastTransitionTime: "2025-06-08T14:20:10Z"
message: Certificate is up to date and has not expired
observedGeneration: 2
reason: Ready
status: "True"
type: Ready
notAfter: "2025-09-06T13:21:39Z"
notBefore: "2025-06-08T13:21:40Z"
renewalTime: "2025-08-07T13:21:39Z"
revision: 1