本文目录导读:

- 核心思路
- 方案一:基础Shell脚本(适用于简单应用或测试环境)
- 方案二:使用Helm的自动化脚本(生产环境推荐)
- 方案三:Python脚本(适用于复杂的多步骤操作)
- 方案四:GitLab CI/CD集成(最实用的自动化方式)
- 关键注意事项
是的,实用脚本完全可以自动部署Kubernetes应用,通过编写Shell、Python或使用Helm等工具,可以大幅简化从代码到集群的运行过程。
我将为你提供几种不同层次的自动部署脚本方案,从简单的kubectl应用到复杂的CI/CD集成。
核心思路
自动部署的本质是:使用脚本封装并顺序执行 kubectl apply、helm install/upgrade 等命令,并加入错误处理、等待就绪和回滚逻辑。
基础Shell脚本(适用于简单应用或测试环境)
这个脚本直接使用 kubectl 操作YAML文件。
#!/bin/bash
# deploy.sh - 部署一个简单的Kubernetes应用
set -euo pipefail # 遇到错误立即退出,未定义变量报错,管道失败也退出
# 配置区域
NAMESPACE="my-app"
DEPLOY_DIR="./k8s-manifests" # k8s配置清单目录
APP_NAME="my-application"
DOCKER_IMAGE="myregistry.com/${APP_NAME}:${BUILD_TAG:-latest}"
echo "=== 开始部署 ${APP_NAME} 到命名空间 ${NAMESPACE} ==="
# 1. 检查kubectl连接
kubectl cluster-info > /dev/null 2>&1 || { echo "错误:无法连接到Kubernetes集群"; exit 1; }
# 2. 创建命名空间(如果不存在)
kubectl get namespace ${NAMESPACE} > /dev/null 2>&1 || kubectl create namespace ${NAMESPACE}
# 3. (可选)使用sed替换镜像标签,确保使用最新版本
if [ -f "${DEPLOY_DIR}/deployment.yaml" ]; then
echo "更新镜像标签为: ${DOCKER_IMAGE}"
sed -i "s|image: .*${APP_NAME}.*|image: ${DOCKER_IMAGE}|g" ${DEPLOY_DIR}/deployment.yaml
fi
# 4. 应用所有配置清单(按顺序:先ConfigMap/Secret,再Deployment/Service)
echo "应用Kubernetes清单..."
kubectl apply -f ${DEPLOY_DIR}/namespace.yaml 2>/dev/null || true
kubectl apply -f ${DEPLOY_DIR}/configmap.yaml
kubectl apply -f ${DEPLOY_DIR}/secret.yaml
kubectl apply -f ${DEPLOY_DIR}/deployment.yaml
kubectl apply -f ${DEPLOY_DIR}/service.yaml
kubectl apply -f ${DEPLOY_DIR}/ingress.yaml
# 5. 等待Deployment就绪(超时300秒)
echo "等待Deployment ${APP_NAME} 就绪..."
kubectl rollout status deployment/${APP_NAME} -n ${NAMESPACE} --timeout=300s
if [ $? -eq 0 ]; then
echo "✓ 部署成功!"
# 输出service地址(如果有)
SERVICE_IP=$(kubectl get svc ${APP_NAME} -n ${NAMESPACE} -o jsonpath='{.status.loadBalancer.ingress[0].ip}' 2>/dev/null)
echo "服务地址: ${SERVICE_IP:-N/A}"
else
echo "✗ 部署失败,开始回滚..."
kubectl rollout undo deployment/${APP_NAME} -n ${NAMESPACE}
exit 1
fi
使用方法:
export BUILD_TAG=v1.2.3 chmod +x deploy.sh ./deploy.sh
使用Helm的自动化脚本(生产环境推荐)
Helm是Kubernetes的包管理器,能管理复杂的应用依赖和版本。
helm-deploy.sh:
#!/bin/bash
set -euo pipefail
RELEASE_NAME="my-app-release"
NAMESPACE="production"
CHART_PATH="./charts/my-app"
VALUES_FILE="./environments/production/values.yaml"
DOCKER_TAG="${BUILD_TAG:-latest}"
echo "=== Helm 自动部署开始 ==="
# 1. 验证Helm是否安装
helm version --short > /dev/null 2>&1 || { echo "请先安装Helm"; exit 1; }
# 2. 添加/更新依赖仓库
helm dependency update ${CHART_PATH}
# 3. 部署或升级应用 (--install 表示如果不存在则安装)
echo "部署 ${RELEASE_NAME} (镜像标签: ${DOCKER_TAG})"
helm upgrade --install ${RELEASE_NAME} ${CHART_PATH} \
--namespace ${NAMESPACE} \
--create-namespace \
--values ${VALUES_FILE} \
--set image.tag=${DOCKER_TAG} \
--wait \
--timeout 10m0s \
--atomic # 如果失败自动回滚
if [ $? -eq 0 ]; then
echo "✓ Helm部署成功!"
helm status ${RELEASE_NAME} -n ${NAMESPACE}
else
echo "✗ 部署失败,使用以下命令查看详情:"
echo " helm status ${RELEASE_NAME} -n ${NAMESPACE}"
exit 1
fi
Python脚本(适用于复杂的多步骤操作)
Python脚本可以处理更复杂的逻辑,比如动态生成配置、API调用等。
#!/usr/bin/env python3
# deploy.py - 使用Python Kubernetes客户端
import os
import sys
import time
import yaml
from kubernetes import client, config, utils
from kubernetes.client.rest import ApiException
def deploy_application(namespace, app_name, image_tag):
# 加载kubeconfig(默认~/.kube/config)
config.load_kube_config()
apps_v1 = client.AppsV1Api()
core_v1 = client.CoreV1Api()
# 1. 创建命名空间
try:
namespace_body = client.V1Namespace(metadata=client.V1ObjectMeta(name=namespace))
core_v1.create_namespace(namespace_body)
print(f"命名空间 {namespace} 已创建")
except ApiException as e:
if e.status == 409:
print(f"命名空间 {namespace} 已存在")
else:
raise
# 2. 读取并模板化Deployment YAML
with open('deployment.yaml', 'r') as f:
dep_yaml = f.read().replace('${DOCKER_TAG}', image_tag)
dep_config = yaml.safe_load(dep_yaml)
dep_config['metadata']['namespace'] = namespace
# 3. 创建或更新Deployment
try:
existing_dep = apps_v1.read_namespaced_deployment(name=app_name, namespace=namespace)
# 更新
apps_v1.patch_namespaced_deployment(name=app_name, namespace=namespace, body=dep_config)
print("Deployment已更新")
except ApiException as e:
if e.status == 404:
# 创建
apps_v1.create_namespaced_deployment(namespace=namespace, body=dep_config)
print("Deployment已创建")
else:
raise
# 4. 等待就绪
print("等待Deployment就绪...")
for _ in range(60): # 最多等5分钟
time.sleep(5)
dep = apps_v1.read_namespaced_deployment(name=app_name, namespace=namespace)
ready = dep.status.ready_replicas or 0
desired = dep.spec.replicas
print(f" 就绪副本: {ready}/{desired}")
if ready == desired:
print("✓ 部署完成!")
return True
print("✗ 部署超时")
return False
if __name__ == "__main__":
image_tag = os.environ.get('BUILD_TAG', 'latest')
deploy_application(namespace='my-app', app_name='nginx', image_tag=image_tag)
运行:
python3 deploy.py
GitLab CI/CD集成(最实用的自动化方式)
在实际团队中,通常会结合CI/CD工具实现自动化。
# .gitlab-ci.yml 示例
deploy-k8s:
stage: deploy
image: bitnami/kubectl:latest
script:
# 登录到私有镜像仓库
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
# 替换YAML中的镜像标签为本次构建的标签
- sed -i "s|image:.*|image: \$CI_REGISTRY_IMAGE:\$CI_COMMIT_SHORT_SHA|g" k8s/deployment.yaml
# 使用kubectl部署
- kubectl config set-cluster k8s --server="$K8S_SERVER"
- kubectl config set-credentials gitlab --token="$K8S_TOKEN"
- kubectl --namespace production apply -f k8s/
# 等待就绪并回滚
- kubectl rollout status deployment/my-app -n production --timeout=300s || kubectl rollout undo deployment/my-app -n production
only:
- main
关键注意事项
| 注意点 | 说明 |
|---|---|
| 幂等性 | 脚本应设计为多次执行结果一致(使用 kubectl apply 而非 create) |
| 版本控制 | 所有YAML文件和脚本都应纳入Git管理 |
| 回滚机制 | 部署失败时应自动回滚(如 kubectl rollout undo) |
| 健康检查 | 务必在脚本中等待Deployment就绪(rollout status) |
| 安全配置 | kubeconfig文件、API Token等敏感信息应通过环境变量或KMS管理 |
| 环境隔离 | 开发/测试/生产环境的脚本应有参数区分 |
- 快速试用:用方案一的Shell脚本即可
- 生产环境:强烈建议使用Helm(方案二)+ CI/CD(方案四)
- 复杂逻辑:Python脚本(方案三)可以处理更复杂的场景
实用脚本不仅能自动部署,还能通过 --atomic、回滚、健康检查等手段保证部署的可靠性和安全性,希望这些示例能直接应用到你的项目中!