// Wrapped — CD: helm upgrade в k3s (как make addon-wrapped, только смена образа) // // Первый install — только через DevOpsTools/K3S: make addon-wrapped // (секреты, Ingress, Postgres, MinIO). Этот pipeline лишь обновляет image.* // через helm --reuse-values, не затирая values с кластера. // // Job: отдельный Pipeline / Multibranch, Script Path = Jenkinsfile.deploy // Credentials: // k3s-kubeconfig — Secret file (kubeconfig), как у devops.org.ru // // Agent: cloud kubernetes, label docker (pod template с container docker) // // Эквивалент addon: // helm upgrade --install wrapped … -n wrapped --atomic --wait // kubectl -n wrapped rollout status deployment/wrapped pipeline { agent { label 'docker' } options { buildDiscarder(logRotator(numToKeepStr: '20')) disableConcurrentBuilds() timeout(time: 20, unit: 'MINUTES') timestamps() } parameters { string( name: 'IMAGE_REPOSITORY', defaultValue: 'inecs/wrapped', description: 'Как wrapped_image_repository в k3s addon (Hub или Harbor)' ) string( name: 'IMAGE_TAG', defaultValue: '0.1.0', description: 'Тег образа (0.1.0 / latest / short-sha после CI build)' ) choice( name: 'IMAGE_PULL_POLICY', choices: ['Always', 'IfNotPresent'], description: 'Always — как в addon (mutable tag подтягивается заново)' ) } environment { HELM_RELEASE = 'wrapped' HELM_NAMESPACE = 'wrapped' HELM_CHART = './helm/wrapped' HELM_TIMEOUT = '600s' DEPLOYMENT = 'wrapped' TZ = 'Europe/Moscow' } stages { stage('Checkout') { steps { checkout scm } } stage('Helm upgrade') { when { anyOf { branch 'main' branch 'master' } } steps { withCredentials([ file(credentialsId: 'k3s-kubeconfig', variable: 'KUBECONFIG') ]) { container('docker') { sh ''' set -eux # helm + kubectl (alpine docker:*-cli) if ! command -v helm >/dev/null 2>&1; then apk add --no-cache curl tar openssl bash >/dev/null ARCH="$(uname -m)" case "$ARCH" in x86_64) ARCH=amd64 ;; aarch64|arm64) ARCH=arm64 ;; *) echo "unsupported arch: $ARCH" >&2; exit 1 ;; esac HELM_VERSION=v3.16.4 curl -fsSL "https://get.helm.sh/helm-${HELM_VERSION}-linux-${ARCH}.tar.gz" \ | tar -xz -C /tmp install -m 0755 "/tmp/linux-${ARCH}/helm" /usr/local/bin/helm fi if ! command -v kubectl >/dev/null 2>&1; then apk add --no-cache curl >/dev/null ARCH="$(uname -m)" case "$ARCH" in x86_64) ARCH=amd64 ;; aarch64|arm64) ARCH=arm64 ;; esac KVER="$(curl -fsSL https://dl.k8s.io/release/stable.txt)" curl -fsSLo /usr/local/bin/kubectl \ "https://dl.k8s.io/release/${KVER}/bin/linux/${ARCH}/kubectl" chmod +x /usr/local/bin/kubectl fi helm version --short kubectl version --client --short || kubectl version --client # Релиз должен уже существовать (первый install — make addon-wrapped) if ! helm status "$HELM_RELEASE" -n "$HELM_NAMESPACE" >/dev/null 2>&1; then echo "Release ${HELM_RELEASE} not found in ns ${HELM_NAMESPACE}." >&2 echo "Сначала: make addon-wrapped в DevOpsTools/K3S." >&2 exit 1 fi echo "Upgrading ${HELM_RELEASE}: ${IMAGE_REPOSITORY}:${IMAGE_TAG} (${IMAGE_PULL_POLICY})" # Как addon: helm upgrade --install … --atomic --wait # --reuse-values сохраняет Ingress/секреты/DB/S3 с кластера helm upgrade "$HELM_RELEASE" "$HELM_CHART" \ --namespace "$HELM_NAMESPACE" \ --reuse-values \ --set "image.repository=${IMAGE_REPOSITORY}" \ --set "image.tag=${IMAGE_TAG}" \ --set "image.pullPolicy=${IMAGE_PULL_POLICY}" \ --atomic \ --wait \ --timeout "$HELM_TIMEOUT" kubectl -n "$HELM_NAMESPACE" rollout status "deployment/${DEPLOYMENT}" --timeout=300s kubectl -n "$HELM_NAMESPACE" get deploy,po,ing -o wide ''' } } } } } post { success { echo "✓ Helm ${HELM_RELEASE}/${HELM_NAMESPACE}: ${params.IMAGE_REPOSITORY}:${params.IMAGE_TAG}" } failure { echo "✗ Helm upgrade не удался — см. лог. Первый install только через make addon-wrapped." } } }