شب ۲۳: TLS در Kubernetes¶
بخش ۲۳ از مجموعهٔ آموزش Traefik در ۳۰ شب؛ هر جلسه برای ۶۰ تا ۹۰ دقیقه مطالعه، تمرین عملی، بررسی نتیجه و تمرین رفع خرابی طراحی شده است. مثالها مطابق منبع با Traefik Proxy v3.7 نوشته شدهاند؛ برای محیط عملیاتی نسخهٔ اصلاحی آزمودهشده یا digest مشخصی را ثابت کنید. تمرینها را روی میزبان یا کلاستر آزمایشگاهی اجرا کنید.
فهرست کامل دورهٔ ترافیک در ۳۰ شب
هدفهای یادگیری¶
- خاتمهٔ TLS با Kubernetes Secrets و چرخش زندهٔ آن.
- افزودن تغییرمسیرها و گزینههای امن TLS.
- درک نقش cert-manager و عیبیابی ACME.
تمرین عملی: TLS مبتنی بر Secret¶
kubectl -n apps create secret tls whoami-tls \
--cert=certs/whoami.crt --key=certs/whoami.key \
--dry-run=client -o yaml > whoami-tls.yaml
kubectl apply -f whoami-tls.yaml
apiVersion: traefik.io/v1alpha1
kind: TLSOption
metadata: {name: modern, namespace: apps}
spec:
minVersion: VersionTLS12
sniStrict: true
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata: {name: https-redirect, namespace: apps}
spec:
redirectScheme: {scheme: https, permanent: true}
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata: {name: whoami-http, namespace: apps}
spec:
entryPoints: [web]
routes:
- match: Host(`whoami.example.test`)
kind: Rule
middlewares: [{name: https-redirect}]
services: [{name: whoami, port: 80}]
---
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata: {name: whoami-https, namespace: apps}
spec:
entryPoints: [websecure]
routes:
- match: Host(`whoami.example.test`)
kind: Rule
services: [{name: whoami, port: 80}]
tls:
secretName: whoami-tls
options: {name: modern, namespace: apps}
kubectl apply -f tls-route.yaml
kubectl -n apps describe secret whoami-tls
openssl s_client -connect 127.0.0.1:443 -servername whoami.example.test \
-CAfile certs/lab-ca.crt -verify_return_error </dev/null
curl --cacert certs/lab-ca.crt --resolve whoami.example.test:443:127.0.0.1 \
https://whoami.example.test/
فایل whoami-tls.yaml را commit نکنید؛ دادهٔ کلید خصوصی آن با base64 کدگذاری شده و رمزگذاری نشده است. برای وضعیت مطلوب از روندهای sealed secret یا secret خارجی استفاده کنید.
نمونهٔ شیء cert-manager، پس از نصب و ایمنسازی جداگانهٔ cert-manager:
apiVersion: cert-manager.io/v1
kind: Certificate
metadata: {name: whoami, namespace: apps}
spec:
secretName: whoami-tls
dnsNames: [whoami.example.com]
issuerRef: {kind: ClusterIssuer, name: letsencrypt-staging}
kubectl -n apps get certificate,certificaterequest,order,challenge
kubectl -n apps describe certificate whoami
kubectl -n apps get secret whoami-tls -o jsonpath='{.metadata.resourceVersion}{"\n"}'
با اعمال TLS Secret تازهتولیدشده، گواهی آزمایشگاه را بچرخانید، resourceVersion آن را یادداشت کنید و openssl s_client را تا تغییر شمارهٔ سریال تکرار کنید. این کار بازخوانی کنترلر بدون restart شدن podها را ثابت میکند.
نکتههای عیبیابی¶
- TLS Secret رد میشود:
tls.crtیاtls.keyندارد، زنجیره نامعتبر است یا کلید با گواهی منطبق نیست. - وضعیت Certificate برابر Ready=False است: شرایط و رویدادها را بهترتیب در CertificateRequest، سپس Order و Challenge دنبال کنید.
- گواهی اشتباه است: عدم تطابق SNI با میزبان مسیر، رفتار پیشفرض TLSStore یا خطای نام و namespace مربوط به secret را بررسی کنید.
- HTTPS کار میکند اما HTTP تغییرمسیر نمیدهد: مسیریاب جداگانهٔ
webیا تغییرمسیر entrypoint بسازید.
خودآزمایی¶
- آیا base64 یک کنترل امنیتی است؟ خیر.
- چرا صدور خارجی برای چند نمونه بهتر است؟ تمام نمونهها یک Secret همگامشده را مصرف میکنند و وضعیت محلی تغییرپذیر ACME را مشترک نمیکنند.
- کدام فیلد گواهی IngressRoute را انتخاب میکند؟
spec.tls.secretName. - اثبات کنید: Secret را بچرخانید و تغییر سریال گواهی ارائهشده را بدون انتشار مجدد Traefik نشان دهید.