文章目录
- 概述
- [一、完整实现步骤(含 Python Demo)](#一、完整实现步骤(含 Python Demo))
-
- [Step 1️⃣:创建 Kubernetes Secret](#Step 1️⃣:创建 Kubernetes Secret)
- [Step 2️⃣:编写 Python 应用(Flask 示例)](#Step 2️⃣:编写 Python 应用(Flask 示例))
- [Step 3️⃣:构建 Docker 镜像(Dockerfile)](#Step 3️⃣:构建 Docker 镜像(Dockerfile))
- [Step 4️⃣:部署到 Kubernetes(Deployment + Service)](#Step 4️⃣:部署到 Kubernetes(Deployment + Service))
- [Step 5:测试](#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
yaml
# rds-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: rds-secret
type: Opaque
data:
# 注意:必须是 base64 编码
username: amlhbGg= # echo -n "jialh" | base64
password: Q2ZldXIxMjM= # echo -n "Cfeur123" | base64
bash
kubectl apply -f rds-secret.yaml
Step 2️⃣:编写 Python 应用(Flask 示例)
python
# app.py
import os
import pymysql
from flask import Flask, jsonify
app = Flask(__name__)
def get_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")
if not user or not password:
raise ValueError("DB_USER or DB_PASSWORD not set!")
return pymysql.connect(
host=host,
port=port,
user=user,
password=password,
database=database,
charset='utf8mb4'
)
@app.route('/health')
def health():
try:
conn = get_db_connection()
conn.close()
return jsonify({"status": "ok", "db": "connected"})
except Exception as e:
return jsonify({"status": "error", "message": str(e)}), 500
if __name__ == '__main__':
app.run(host='0.0.0.0', port=8080)
Step 3️⃣:构建 Docker 镜像(Dockerfile)
bash
# Dockerfile
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY app.py .
CMD ["python", "app.py"]
bash
# requirements.txt
Flask==2.3.3
PyMySQL==1.1.0
构建并推送(假设镜像名为 my-registry/my-app:v1):
bash
docker build -t my-registry/my-app:v1 .
docker push my-registry/my-app:v1
Step 4️⃣:部署到 Kubernetes(Deployment + Service)
yaml
# app-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 2
selector:
matchLabels:
app: my-app
template:
metadata:
labels:
app: my-app
spec:
containers:
- name: app
image: my-registry/my-app:v1
ports:
- containerPort: 8080
env:
- name: DB_HOST
value: "rm-xxxx.mysql.rds.aliyuncs.com" # 替换为你的 RDS 内网地址
- name: DB_PORT
value: "3306"
- name: DB_NAME
value: "mydb"
- name: DB_USER
valueFrom:
secretKeyRef:
name: rds-secret
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: rds-secret
key: password
---
apiVersion: v1
kind: Service
metadata:
name: my-app-svc
spec:
selector:
app: my-app
ports:
- protocol: TCP
port: 80
targetPort: 8080
bash
kubectl apply -f app-deployment.yaml
Step 5:测试
将 Service 端口映射到本地,直接调用 /health 接口:
bash
kubectl port-forward svc/my-app-svc 8080:80
然后在另一个终端执行:
bash
curl http://localhost:8080/health
✅ 成功响应示例:
bash
{"status": "ok", "db": "connected"}
❌ 失败可能返回:
bash
{"status": "error", "message": "(1045, \"Access denied for user 'jialh'@'192.168.x.x' (using password: YES)\")"}
二、如何"随时变更"数据库密码?
场景:RDS 密码从 Cfeur123 改为 NewPass456!
步骤:
- 更新 Secret
bash
kubectl create secret generic rds-secret \
--from-literal=username=jialh \
--from-literal=password=NewPass456! \
--dry-run=client -o yaml | kubectl apply -f -
- 触发 Pod 重启(使新环境变量生效)
bash
# 方法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)\"}}}}}"