GitLab CI'da Kubernetes sertifika hatası: sorun kodda değil
GitLab CI'da kubectl x509 ya da süresi dolmuş sertifika hatası verdiğinde sorunu koddan ayırıp kubeconfig, CA ve kimlik bilgilerine indirmek.
Dün çalışan deploy işi bugün kırmızı. Kodda değişiklik yok ya da değişiklik masum. Log'un sonunda şu satırlardan biri var:
Unable to connect to the server: x509: certificate signed by unknown authority
Unable to connect to the server: x509: certificate has expired or is not yet valid
error: You must be logged in to the server (Unauthorized)
Bu hataların ortak noktası şu: pipeline, Kubernetes API'sine güvenli bağlantı kuramıyor. Uygulama kodu bu aşamaya hiç gelmiyor. Bu yüzden ilk iş, sorunu koddan ayırmaktır.
1. Sorunu ayırın
Pipeline'a deploy'dan önce tek satırlık bir kontrol adımı ekleyin:
k8s-check:
stage: .pre
image: bitnami/kubectl:latest
script:
- kubectl version
- kubectl auth can-i get pods -n "$KUBE_NAMESPACE"
Bu adım da kırılıyorsa sorun kesin olarak bağlantı ve kimlik tarafındadır.
2. Hatayı okuyun
| Hata | En olası neden |
|---|---|
signed by unknown authority |
kubeconfig'teki CA (certificate-authority-data) sunucunun sertifikasıyla eşleşmiyor ya da hiç yok |
certificate has expired |
İstemci sertifikası ya da API sunucu sertifikası süresi dolmuş |
certificate is valid for …, not … |
server: adresi sertifikanın SAN listesinde yok (IP yerine DNS adı ya da tersi) |
Unauthorized |
Token iptal edilmiş, süresi dolmuş ya da yanlış kullanıcı |
3. kubeconfig'i doğru taşıyın
En sık rastlanan hata, kubeconfig'i normal bir değişken olarak tanımlayıp içeriğini ortam değişkeni sanmaktır. GitLab'da kubeconfig'i File tipinde bir CI/CD değişkeni olarak saklayın. Değişken, dosyanın yolunu verir:
deploy:
script:
- export KUBECONFIG="$KUBECONFIG_FILE"
- kubectl config view --minify # hangi küme ve kullanıcıyla bağlanıldığını görün
- kubectl apply -f k8s/
kubectl config view --minify çıktısında server: adresinin doğru küme olduğunu ve beklenen kullanıcının kullanıldığını kontrol edin.
4. Sertifika sürelerini kontrol edin
Birçok dağıtımda istemci sertifikaları sınırlı süreyle (çoğunlukla bir yıl) üretilir ve yenilenmesi gerekir. Kubeconfig'teki istemci sertifikasının bitiş tarihini görmek için:
kubectl config view --raw --minify \
-o jsonpath='{.users[0].user.client-certificate-data}' \
| base64 -d | openssl x509 -noout -enddate
Küme tarafında sertifikalar yenilendiyse, CI değişkenindeki kubeconfig de güncellenmelidir. Aksi hâlde pipeline eski bilgilerle bağlanmaya devam eder.
5. Kalıcı çözüm
- CI için kişisel kubeconfig yerine, yalnızca deploy yetkisi olan bir ServiceAccount kullanın.
- Kubeconfig'in nereden geldiğini ve ne zaman yenileneceğini dokümante edin.
- Sertifika bitiş tarihleri için izleme sistemine bir uyarı ekleyin. Sürpriz, bir sonraki deploy günü yaşanmasın.
Ders
Kırmızı pipeline her zaman kötü kod demek değildir. Önce bir bakalım: hata hangi katmanda? Bağlantı, kimlik ve sertifika sağlam değilse, kodun ne yaptığının önemi yoktur.