本文目录导读:

我来详细讲解如何用脚本自动更新Kubernetes配置的几种常用方法:
使用 kubectl apply 脚本
#!/bin/bash
# 自动更新K8s配置脚本
set -e
# 配置变量
NAMESPACE="default"
CONFIG_DIR="./k8s-configs"
BACKUP_DIR="./backups/$(date +%Y%m%d_%H%M%S)"
# 创建备份目录
mkdir -p $BACKUP_DIR
# 备份现有配置
echo "备份现有配置..."
kubectl get all -n $NAMESPACE -o yaml > $BACKUP_DIR/current-state.yaml
# 更新配置
echo "应用新配置..."
for file in $CONFIG_DIR/*.yaml; do
echo "应用: $file"
kubectl apply -f $file --namespace $NAMESPACE
done
# 验证配置
echo "验证配置状态..."
kubectl rollout status deployment -n $NAMESPACE --timeout=120s
使用脚本更新特定资源
#!/bin/bash
# 更新Deployment镜像版本
update_deployment() {
local deployment=$1
local image=$2
local namespace=${3:-default}
echo "更新deployment: $deployment 使用镜像: $image"
# 记录当前版本
CURRENT_IMAGE=$(kubectl get deployment $deployment -n $namespace -o jsonpath='{.spec.template.spec.containers[0].image}')
echo "当前镜像: $CURRENT_IMAGE"
# 更新镜像
kubectl set image deployment/$deployment container=$image -n $namespace
# 检查更新状态
kubectl rollout status deployment/$deployment -n $namespace
}
# 更新ConfigMap
update_configmap() {
local configmap=$1
local config_file=$2
local namespace=${3:-default}
echo "更新ConfigMap: $configmap"
# 备份现有ConfigMap
kubectl get configmap $configmap -n $namespace -o yaml > "${configmap}_backup.yaml"
# 更新ConfigMap
kubectl create configmap $configmap --from-file=$config_file -n $namespace --dry-run=client -o yaml | kubectl apply -f -
# 重启相关Pod以应用新配置
kubectl rollout restart deployment -n $namespace -l "app=$configmap"
}
# 使用示例
update_deployment "my-app" "myregistry/myapp:v2.0"
update_configmap "app-config" "config/app.properties"
使用Python脚本更新
#!/usr/bin/env python3
import subprocess
import json
import yaml
import os
from datetime import datetime
class K8sConfigUpdater:
def __init__(self, namespace="default"):
self.namespace = namespace
self.backup_dir = f"backups/{datetime.now().strftime('%Y%m%d_%H%M%S')}"
os.makedirs(self.backup_dir, exist_ok=True)
def run_kubectl(self, cmd):
"""执行kubectl命令"""
try:
result = subprocess.run(
cmd.split(),
capture_output=True,
text=True,
check=True
)
return result.stdout
except subprocess.CalledProcessError as e:
print(f"命令执行失败: {e.stderr}")
raise
def backup_current_state(self):
"""备份当前状态"""
output_file = f"{self.backup_dir}/current_state.yaml"
cmd = f"kubectl get all -n {self.namespace} -o yaml"
with open(output_file, 'w') as f:
f.write(self.run_kubectl(cmd))
print(f"备份保存到: {output_file}")
def update_deployment_image(self, deployment, new_image):
"""更新Deployment镜像"""
cmd = f"kubectl set image deployment/{deployment} *= {new_image} -n {self.namespace}"
self.run_kubectl(cmd)
# 等待滚动更新完成
cmd = f"kubectl rollout status deployment/{deployment} -n {self.namespace}"
self.run_kubectl(cmd)
print(f"Deployment {deployment} 更新完成")
def update_configmap_from_file(self, configmap_name, config_file):
"""从文件更新ConfigMap"""
cmd = f"kubectl create configmap {configmap_name} --from-file={config_file} -n {self.namespace} --dry-run=client -o yaml"
new_config = self.run_kubectl(cmd)
# 应用新的ConfigMap
apply_cmd = f"kubectl apply -f -"
result = subprocess.run(
apply_cmd.split(),
input=new_config,
capture_output=True,
text=True,
check=True
)
print(f"ConfigMap {configmap_name} 更新完成")
# 重启相关Pod
self.restart_pods_by_label(f"app={configmap_name}")
def restart_pods_by_label(self, label):
"""根据标签重启Pod"""
cmd = f"kubectl rollout restart deployment -n {self.namespace} -l {label}"
self.run_kubectl(cmd)
print(f"已重启标签为 {label} 的Pod")
# 使用示例
if __name__ == "__main__":
updater = K8sConfigUpdater(namespace="production")
# 备份当前状态
updater.backup_current_state()
# 更新Deployment
updater.update_deployment_image("my-app", "myregistry/myapp:v3.0")
# 更新ConfigMap
updater.update_configmap_from_file("app-config", "config/app.properties")
使用Helm的脚本
#!/bin/bash
# 使用Helm更新配置
RELEASE_NAME="my-app"
CHART_PATH="./charts/my-app"
NAMESPACE="default"
# 更新Helm release
helm upgrade $RELEASE_NAME $CHART_PATH \
--namespace $NAMESPACE \
--set image.tag=v2.0 \
--set replicaCount=3 \
--values ./values/production.yaml \
--atomic \
--timeout 10m
# 验证更新状态
helm status $RELEASE_NAME -n $NAMESPACE
完整的自动化脚本示例
#!/bin/bash
# 完整自动化更新脚本
set -e
# 配置变量
NAMESPACE="default"
CONFIG_REPO="/path/to/config-repo"
BACKUP_DIR="/tmp/k8s-backups/$(date +%Y%m%d_%H%M%S)"
# 日志函数
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"
}
# 错误处理
error_handler() {
log "ERROR: 脚本执行失败,行号: $1"
log "执行回滚操作..."
./rollback.sh
exit 1
}
trap 'error_handler $LINENO' ERR
# 主要更新流程
main() {
log "开始K8s配置更新流程..."
# 1. 备份当前状态
log "备份当前配置..."
mkdir -p $BACKUP_DIR
# 备份所有资源
kubectl get all -n $NAMESPACE -o yaml > $BACKUP_DIR/all-resources.yaml
kubectl get configmap -n $NAMESPACE -o yaml > $BACKUP_DIR/configmaps.yaml
kubectl get secret -n $NAMESPACE -o yaml > $BACKUP_DIR/secrets.yaml
# 2. 拉取最新配置
log "拉取最新配置..."
cd $CONFIG_REPO
git pull origin main
# 3. 应用配置更新
log "应用配置更新..."
# 3.1 更新ConfigMaps
for config_file in configs/*.properties; do
name=$(basename $config_file .properties)
kubectl create configmap $name \
--from-file=$config_file \
-n $NAMESPACE \
--dry-run=client -o yaml | kubectl apply -f -
done
# 3.2 更新Deployments
kubectl apply -f deployments/ -n $NAMESPACE
# 3.3 更新Services
kubectl apply -f services/ -n $NAMESPACE
# 4. 灰度发布策略
log "执行灰度发布..."
# 创建新版本的Deployment
kubectl apply -f canary-deployment.yaml
# 等待新的Pod就绪
sleep 30
# 验证新版本
if kubectl rollout status deployment/my-app-canary -n $NAMESPACE; then
log "更新验证成功,继续完整部署..."
# 更新主Deployment
kubectl set image deployment/my-app my-app=myapp:new-version \
-n $NAMESPACE
# 删除canary Deployment
kubectl delete deployment my-app-canary -n $NAMESPACE
else
log "更新验证失败,执行回滚..."
kubectl delete deployment my-app-canary -n $NAMESPACE
exit 1
fi
log "配置更新完成!"
}
# 回滚函数
rollback() {
log "执行回滚..."
kubectl apply -f $BACKUP_DIR/all-resources.yaml
kubectl apply -f $BACKUP_DIR/configmaps.yaml
kubectl apply -f $BACKUP_DIR/secrets.yaml
}
# 执行更新
main
与CI/CD集成(GitLab CI示例)
# .gitlab-ci.yml
stages:
- deploy
variables:
NAMESPACE: "production"
DEPLOYMENT_NAME: "my-app"
deploy-to-k8s:
stage: deploy
image: bitnami/kubectl:latest
script:
- kubectl config set-cluster k8s --server="$KUBE_URL"
- kubectl config set credentials gitlab --token="$KUBE_TOKEN"
- kubectl config set-context default --cluster=k8s --user=gitlab --namespace=$NAMESPACE
- kubectl config use-context default
# 更新配置
- kubectl apply -f k8s/deployment.yaml
- kubectl apply -f k8s/service.yaml
# 滚动更新
- kubectl set image deployment/$DEPLOYMENT_NAME \
$DEPLOYMENT_NAME=$CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
# 监控部署状态
- kubectl rollout status deployment/$DEPLOYMENT_NAME --timeout=300s
最佳实践建议
- 始终创建备份:在更新前备份当前配置
- 使用版本控制:配置脚本应纳入Git版本管理
- 实现回滚机制:准备回滚脚本应对失败情况
- 灰度发布:对重要服务使用灰度发布策略
- 监控和告警:监控更新过程中的异常状态
- 权限控制:使用最小权限原则运行更新脚本
- 测试环境:先在测试环境验证更新脚本
这些脚本可以根据你的具体需求进行修改和扩展,记得在实际使用前在测试环境中充分测试。