CI/CD: serverplus Kubernetes klasteriga deploy
G'oya
Klasterga kirish (kubeconfig) CI sirlariga joylanadi, pipeline esa har bir push'da kubectl apply'ni ishga tushiradi. Quyida — buni serverplus'dagi Kubernetes klasteri uchun GitLab CI va GitHub Actions'da qanday tashkil qilish va admin-huquqni tarqatmasdan xavfsiz bajarish.
CI sirlariga nima joylaymiz
- Klaster kubeconfig'i — ideal holda admin emas, cheklangan (ServiceAccount'dan, quyida qarang). base64'ga kodlab, maskalangan CI o'zgaruvchisi sifatida saqlaymiz (
KUBE_CONFIG). - application credential id/secret — faqat pipeline OpenStack infratuzilmasining o'ziga tegsa (masalan, Terraform orqali).
# get kubeconfig and encode it for the CI secret
openstack coe cluster config my-cluster
base64 -w0 ./config # result -> KUBE_CONFIG variablekubeconfig'ni hech qachon repozitoriyga joylamang. Faqat maskalangan CI sirlari. Bitta kubeconfig fayli — bu klasterga to'liq kirish.
Cheklangan kirish (ServiceAccount + RBAC)
admin-kubeconfig o'rniga faqat bitta namespace'da huquqli servis-akkaunt yarating:
kubectl create namespace app
kubectl -n app create serviceaccount deployer
kubectl -n app create rolebinding deployer-edit \
--clusterrole=edit --serviceaccount=app:deployer
# short-lived token for this account
kubectl -n app create token deployer --duration=24hUshbu token va klaster manzili asosida CI uchun alohida kubeconfig yig'iladi — u faqat app namespace'ini o'zgartira oladi.
GitLab CI
.gitlab-ci.yml — main'ga push'da deploy:
deploy:
stage: deploy
image: bitnami/kubectl:latest
script:
- echo "$KUBE_CONFIG" | base64 -d > kubeconfig
- export KUBECONFIG=$PWD/kubeconfig
- kubectl -n app apply -f k8s/
- kubectl -n app rollout status deployment/web
rules:
- if: $CI_COMMIT_BRANCH == "main"KUBE_CONFIG Settings → CI/CD → Variables'da masked o'zgaruvchi sifatida beriladi (kubeconfig'dan base64).
GitHub Actions
.github/workflows/deploy.yml:
name: deploy
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: kubeconfig
run: |
echo "${{ secrets.KUBE_CONFIG }}" | base64 -d > kubeconfig
echo "KUBECONFIG=$PWD/kubeconfig" >> $GITHUB_ENV
- name: deploy
run: |
kubectl -n app apply -f k8s/
kubectl -n app rollout status deployment/webKUBE_CONFIG Settings → Secrets and variables → Actions'ga qo'shiladi.
Obraz yig'ish va xususiy registry
Odatiy to'liq tsikl: obrazni yig'ish, registry'ga push qilish, deploy'ni yangilash.
docker build -t registry.example/web:$TAG .
docker push registry.example/web:$TAG
kubectl -n app set image deployment/web web=registry.example/web:$TAGRegistry xususiy bo'lsa, klasterga imagePullSecret qo'shing va uni deploy manifestida ko'rsating.
Xavfsizlik
- admin-kubeconfig emas. Bitta namespace'da
editrolli alohida ServiceAccount (RBAC) — runner buzilsa ham butun klasterga kirish bermaydi. - Faqat maskalangan CI sirlari, muhitlar uchun alohida ma'lumotlar (stage/prod) va ularni yangilash.
- Deploy'ni kim ishga tushirishini cheklang: protected branches va protected environments.
Ko'p beriladigan savollar
kubectl: connection refused / timeout (pipeline'dan). kubeconfig'da control plane'ning tashqi manzili (floating IP) bo'lishi kerak, ichki 10.x emas. CI runner shu manzilga tarmoq orqali kira olishi kerak.
«forbidden» xatosi. Servis-akkauntga RBAC'da huquq yetmayapti — rolebinding va namespace'ni tekshiring.
x509 sertifikat xatosi. Eskirgan kubeconfig (klaster qayta yaratilgan). Qaytadan yarating: openstack coe cluster config my-cluster --force.