نسخه آنلاین در حال بارگذاری زمان... تهران: ۲۶°C
۲۸ کاربر آنلاین

PNo.30Light

نشریه تخصصی هوش مصنوعی، سیستم‌های سرور و مهندسی داده

تازه ترین‌ها
زیرساخت و سرور
زمان مطالعه: ۱۹ دقیقه ۰ بازدید

cert-manager: مدیریت گواهی TLS در Kubernetes — راهنمای کامل

نویسنده: تحریریه فنی P30Light
cert-manager: مدیریت گواهی TLS در Kubernetes — راهنمای کامل
✦ خلاصه نکات کلیدی مقاله
  • cert-manager کنترلر X.509 بومی Kubernetes است — صدور، renew خودکار و Secret برای Ingress/mTLS.
  • ClusterIssuer + Certificate CRD: Let's Encrypt، Vault، Route53 DNS-01 برای wildcard — بدون certbot دستی روی node.
  • پروژه CNCF (از Jetstack) — ۵M+ download روزانه؛ جایگزین استاندارد TLS روی K8s/OpenShift.

HTTPS دیگر luxury نیست — مرورگرها HTTP را «ناامن» می‌زنند، APIها TLS می‌خواهند، و compliance بدون encryption قبول نمی‌شود. روی Kubernetes معمولاً Ingress + TLS Secret داریم — اما certificate از کجا می‌آید؟

راه‌های بد:

  • certbot دستی روی یک node — expire می‌شود، کسی renew نمی‌کند
  • copy/paste .crt/.key — drift، audit ندارید
  • cloud LB certificate — vendor lock، per-service گران
  • self-signed — مرورگر قرمز، mTLS داخلی OK ولی public نه

cert-manager پاسخ ecosystem است:

Cloud native certificate management — X.509 certificate management for Kubernetes and OpenShift workloads.

یعنی certificate مثل هر resource دیگر Kubernetes: declarative، automated، renewed قبل از expire.

پروژه توسط Jetstack ساخته و ۲۰۲۰ به CNCF donate شد. امروز ۵M+ download روزانه و استاندارد de facto TLS روی cluster.


مشکل certificate دستی در Kubernetes

مدل شکننده:
DevOps هر ۹۰ روز → SSH به jump box → certbot
                    → kubectl create secret tls ...
                    → فراموش → سایت down در جمعه شب
مشکلپیامد
expire بدون renewoutage، SEO ضربه
Secret staleIngress از cert قدیمی serve می‌کند
wildcard با HTTP-01غیرممکن — نیاز DNS-01
multi-clustercert جدا per cluster
audit«چه کسی cert را عوض کرد؟» — نامشخص

cert-manager lifecycle را automate می‌کند: request → challenge → Secret → renew → repeat.


cert-manager چیست؟

cert-manager یک Kubernetes controller است که:

  • Certificate CRD را watch می‌کند
  • از Issuer / ClusterIssuer certificate می‌گیرد
  • کلید خصوصی + cert را در Secret ذخیره می‌کند
  • قبل از expire renew می‌کند (پیش‌فرض ~۳۰ روز قبل)
  • با Ingress، Gateway API، Service Mesh، Pod mount integrate می‌شود

Issuerهای پشتیبانی‌شده:

نوعمثال
ACME (public)Let’s Encrypt
ACME (private)Boulder، Smallstep
HashiCorpVault
Private PKICA داخلی، CyberArk
Self-signeddev/test

معماری و CRDها

نمای کلی

┌─────────────────────────────────────────────────────────┐
│                    cert-manager                          │
│  ┌─────────────┐  ┌──────────────┐  ┌─────────────────┐ │
│  │  controller │  │  cainjector  │  │   webhook       │ │
│  └──────┬──────┘  └──────────────┘  └─────────────────┘ │
└─────────┼───────────────────────────────────────────────┘
          │ reconcile

   Certificate CRD  ──►  CertificateRequest
          │                    │
          ▼                    ▼
      Issuer /            Order (ACME)
   ClusterIssuer              │
          │                    ▼
          │              Challenge (HTTP-01 / DNS-01)

   Kubernetes Secret (tls.crt + tls.key)


   Ingress / Gateway / Pod volume

CRDهای کلیدی

CRDscopeکاربرد
IssuernamespaceCA برای یک namespace
ClusterIssuerclusterCA مشترک (Let’s Encrypt prod)
Certificatenamespace«من Secret X با SAN Y می‌خواهم»
CertificateRequestinternalrequest خام — معمولاً دستی نمی‌سازید
Order / ChallengeACMEHTTP-01 یا DNS-01 flow

ویژگی‌های اصلی (از cert-manager.io)

ویژگیتوضیح
Automated issuance & renewalIngress TLS بدون cron دستی
Public & private CALet’s Encrypt تا Vault
mTLSPod-to-pod با private PKI
WildcardDNS-01 challenge
Service meshadd-on برای Istio SPIFFE
CSI driverprivate key on-node، بدون Secret

ACME challenges: HTTP-01 vs DNS-01

HTTP-01DNS-01
نیازIngress از اینترنت reachableAPI DNS (Route53، Cloudflare، …)
Wildcard*.example.com
firewall strictسختآسان‌تر
پیچیدگیکمIAM + DNS provider

برای p30light.ir پشت Cloudflare معمولاً DNS-01 با Cloudflare solver یا HTTP-01 اگر origin expose است.


نصب cert-manager

Helm (توصیه production)

از Helm docs:

helm install cert-manager oci://quay.io/jetstack/charts/cert-manager \
  --version v1.17.2 \
  --namespace cert-manager \
  --create-namespace \
  --set crds.enabled=true

تأیید:

kubectl get pods -n cert-manager
kubectl get crd | grep cert-manager

kubectl (سریع)

kubectl apply -f \
  https://github.com/cert-manager/cert-manager/releases/download/v1.17.2/cert-manager.yaml

همیشه CRDها را با نسخه cert-manager هم‌خوان نگه دارید.


ClusterIssuer: Let’s Encrypt staging

همیشه اول staging — rate limit واقعی نمی‌خورید:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-staging
spec:
  acme:
    server: https://acme-staging-v02.api.letsencrypt.org/directory
    email: [email protected]
    privateKeySecretRef:
      name: letsencrypt-staging-account-key
    solvers:
      - http01:
          ingress:
            class: nginx
kubectl apply -f clusterissuer-staging.yaml
kubectl describe clusterissuer letsencrypt-staging
# Status: Ready

Certificate + Ingress (HTTP-01)

روش ۱: Certificate CRD صریح

apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: myapp-tls
  namespace: production
spec:
  secretName: myapp-tls-secret
  issuerRef:
    name: letsencrypt-staging
    kind: ClusterIssuer
  dnsNames:
    - app.example.com
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: myapp
  namespace: production
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - app.example.com
      secretName: myapp-tls-secret
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: myapp
                port:
                  number: 80

cert-manager Certificate را watch می‌کند → Challenge → Secret پر می‌شود → Ingress TLS فعال.

روش ۲: Ingress annotation (nginx)

metadata:
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-staging
spec:
  tls:
    - hosts:
        - app.example.com
      secretName: app-example-com-tls

ساده‌تر برای app team — cert-manager Certificate را خودکار می‌سازد.


Production Issuer

پس از تست staging:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-prod
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: [email protected]
    privateKeySecretRef:
      name: letsencrypt-prod-account-key
    solvers:
      - http01:
          ingress:
            class: nginx

Certificate را به letsencrypt-prod switch کنید.


Wildcard با DNS-01 (Route53 مثال)

از Route53 docs:

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: letsencrypt-dns01
spec:
  acme:
    server: https://acme-v02.api.letsencrypt.org/directory
    email: [email protected]
    privateKeySecretRef:
      name: letsencrypt-dns01-key
    solvers:
      - dns01:
          route53:
            region: eu-central-1
            # با IRSA روی EKS — role از ServiceAccount
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: wildcard-example
  namespace: production
spec:
  secretName: wildcard-example-tls
  issuerRef:
    name: letsencrypt-dns01
    kind: ClusterIssuer
  dnsNames:
    - "*.example.com"
    - example.com

Private PKI و mTLS داخلی

برای service-to-service (نه public CA):

apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
  name: selfsigned-internal
spec:
  selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: internal-api-mtls
  namespace: backend
spec:
  secretName: internal-api-tls
  issuerRef:
    name: selfsigned-internal
    kind: ClusterIssuer
  dnsNames:
    - api.internal.svc.cluster.local
  usages:
    - server auth
    - client auth

برای production internal: Vault Issuer یا CA سازمانی.


چه زمانی cert-manager؟

✅ مناسب

  • Kubernetes/OpenShift با Ingress/Gateway زیاد
  • Let’s Encrypt automate
  • Wildcard یا multi-SAN
  • GitOps (Argo CD) — Certificate YAML در Git
  • Renew خودکار — SLA uptime
  • mTLS mesh یا internal API

❌ کمتر مناسب

وضعیتجایگزین
TLS فقط روی Cloudflare (proxy)Cloudflare Universal SSL
یک static site خارج K8sCDN cert
VM بدون K8scertbot + systemd timer
cert از vendor hardware HSMmanual process

مقایسه

معیارcertbot دستیcloud LB certcert-manager
K8s nativeجزئی
GitOps
Auto renewcron دستیvendor✅ controller
Wildcard LEDNS script✅ DNS-01
Multi-namespaceسختper-LBClusterIssuer
Audit CRD✅ events

cert-manager در stack P30Light

Internet


Cloudflare / nginx ([nginx tuning](/blog/nginx-optimization-high-traffic/))


Ingress + cert-manager Secret (TLS)


Astro static / apps on K8s

    ├── [Argo CD](/blog/argo-project-kubernetes-gitops-cicd/) sync
    └── [Kube-OVN](/blog/kube-ovn-kubernetes-cloud-native-networking/) network

Certificate manifest در همان GitOps repo — deploy و renew هم‌راستا با app.


Troubleshooting

# وضعیت Certificate
kubectl describe certificate -n production myapp-tls
kubectl get certificaterequest,order,challenge -n production

# لاگ controller
kubectl logs -n cert-manager deploy/cert-manager -f

# رویدادهای رایج
kubectl get events -n production --field-selector reason=Failed
علامتعلت محتملfix
Certificate PendingChallenge faildescribe Challenge
HTTP-01 timeoutIngress unreachableDNS/firewall
DNS-01 failIAM/API tokenRoute53/CF credentials
Secret emptyIssuer not Readydescribe ClusterIssuer
staging cert in prodwrong issuerRefswitch to prod Issuer

امنیت و best practices

  • Separate staging/prod Issuer — هرگز staging را در prod فراموش نکنید (مرورگر warning)
  • email ACME واقعی — expire notice از Let’s Encrypt
  • RBAC — فقط platform team ClusterIssuer بسازد
  • Rate limits LE — از staging برای test
  • Backup نیست — cert قابل re-issue است؛ account key Secret را backup کنید
  • Uninstall — CRDها Certificateها را پاک می‌کنند (Helm docs)

عملیات روزمره

kubectl get certificate -A
kubectl get clusterissuer
kubectl cert-manager check api --wait=2m   # اگر plugin نصب است
kubectl describe certificate myapp-tls -n production

Renew معمولاً خودکار — monitor با Prometheus metrics cert-manager.


جمع‌بندی

بدون cert-managerبا cert-manager
certbot + cronController reconcile loop
expire = outageRenew proactive
Ingress TLS دستیCertificate CRD
wildcard سختDNS-01 یک Issuer
audit ضعیفKubernetes events + Git

cert-manager برای هر cluster Kubernetes که HTTPS جدی می‌خواهد — public یا internal — almost mandatory است. یک بار ClusterIssuer درست setup کنید؛ بعد صدها Certificate از همان pattern.

قدم بعدی

  1. Helm install روی staging cluster
  2. letsencrypt-staging ClusterIssuer + یک Certificate تست
  3. Ingress با TLS — verify در مرورگر (staging warning OK)
  4. switch به letsencrypt-prod
  5. اگر wildcard لازم است — DNS-01 با provider DNS خود

منابع:


منتشر شده در P30Light — بخش زیرساخت سرور و Cloud Native.

لینک گزارش با موفقیت کپی گردید!