文章目录
- 概述
- 一、完整实现步骤(含 Python Demo)
- Step 1️⃣:创建 Kubernetes Secret
- Step 2️⃣:编写 Python 应用(Flask 示例)
- Step 3️⃣:构建 Docker 镜像(Dockerfile)
- Step 4️⃣:部署到 Kubernetes(Deployment + Service)
- Step 5:测试
- 二、如何“随时变更”数据库密码?
概述
在 Kubernetes 中,将数据库账号密码等敏感配置与代码解耦,并支持动态更新,是标准的安全和运维实践。我将通过(Python 应用 + 阿里云 RDS + 账号 jialh / 密码 Cfeur123)来设计一个完整可运行的 Python Demo。
✅ 推荐方案:使用 Kubernetes Secret + 环境变量注入
这是最简单、安全、且满足“随时变更配置”的方式:
- 敏感信息存入 Secret
- Pod 通过环境变量读取
- 更新 Secret 后,滚动重启 Pod 即可生效(或配合 ConfigMap Reloader 实现热更新,但对 DB 密码通常不需要)
💡 注意:Kubernetes 的 Secret 不会自动热更新到已运行的 Pod 环境变量中(这是设计行为)。但你可以通过 滚动更新
Deployment 实现“配置变更生效”,这在生产中是标准做法。
一、完整实现步骤(含 Python Demo)
Step 1️⃣:创建 Kubernetes Secret
# rds-secret.yamlapiVersion:v1kind:Secretmetadata:name:rds-secrettype:Opaquedata:# 注意:必须是 base64 编码username:amlhbGg=# echo -n "jialh" | base64password:Q2ZldXIxMjM=# echo -n "Cfeur123" | base64kubectl apply -f rds-secret.yamlStep 2️⃣:编写 Python 应用(Flask 示例)
# app.pyimportosimportpymysqlfromflaskimportFlask,jsonify app=Flask(__name__)defget_db_connection():host=os.getenv("DB_HOST","localhost")port=int(os.getenv("DB_PORT","3306"))user=os.getenv("DB_USER")password=os.getenv("DB_PASSWORD")database=os.getenv("DB_NAME","test")ifnotuserornotpassword:raiseValueError("DB_USER or DB_PASSWORD not set!")returnpymysql.connect(host=host,port=port,user=user,password=password,database=database,charset='utf8mb4')@app.route('/health')defhealth():try:conn=get_db_connection()conn.close()returnjsonify({"status":"ok","db":"connected"})exceptExceptionase:returnjsonify({"status":"error","message":str(e)}),500if__name__=='__main__':app.run(host='0.0.0.0',port=8080)Step 3️⃣:构建 Docker 镜像(Dockerfile)
# DockerfileFROM python:3.9-slim WORKDIR /app COPY requirements.txt.RUN pipinstall--no-cache-dir -r requirements.txt COPY app.py.CMD["python","app.py"]# requirements.txtFlask==2.3.3PyMySQL==1.1.0构建并推送(假设镜像名为 my-registry/my-app:v1):
docker build -t my-registry/my-app:v1.docker push my-registry/my-app:v1Step 4️⃣:部署到 Kubernetes(Deployment + Service)
# app-deployment.yamlapiVersion:apps/v1kind:Deploymentmetadata:name:my-appspec:replicas:2selector:matchLabels:app:my-apptemplate:metadata:labels:app:my-appspec:containers:-name:appimage:my-registry/my-app:v1ports:-containerPort:8080env:-name:DB_HOSTvalue:"rm-xxxx.mysql.rds.aliyuncs.com"# 替换为你的 RDS 内网地址-name:DB_PORTvalue:"3306"-name:DB_NAMEvalue:"mydb"-name:DB_USERvalueFrom:secretKeyRef:name:rds-secretkey:username-name:DB_PASSWORDvalueFrom:secretKeyRef:name:rds-secretkey:password---apiVersion:v1kind:Servicemetadata:name:my-app-svcspec:selector:app:my-appports:-protocol:TCPport:80targetPort:8080kubectl apply -f app-deployment.yamlStep 5:测试
将 Service 端口映射到本地,直接调用 /health 接口:
kubectl port-forward svc/my-app-svc8080:80然后在另一个终端执行:
curlhttp://localhost:8080/health✅ 成功响应示例:
{"status":"ok","db":"connected"}❌ 失败可能返回:
{"status":"error","message":"(1045,\"Access denied for user 'jialh'@'192.168.x.x' (using password: YES)\")"}二、如何“随时变更”数据库密码?
场景:RDS 密码从 Cfeur123 改为 NewPass456!
步骤:
- 更新 Secret
kubectl create secret generic rds-secret\--from-literal=username=jialh\--from-literal=password=NewPass456!\--dry-run=client -o yaml|kubectl apply -f -- 触发 Pod 重启(使新环境变量生效)
# 方法1:滚动重启(推荐)kubectl rollout restart deployment/my-app# 方法2:修改 Deployment 注解(也会触发滚动更新)kubectl patch deployment my-app -p"{\"spec\":{\"template\":{\"metadata\":{\"annotations\":{\"restartedAt\":\"$(date+%Y-%m-%dT%H:%M:%S%z)\"}}}}}"