k8s中的服务通过secret访问数据库的实际案例

文章目录

  • 概述
  • [一、完整实现步骤(含 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)\"}}}}}"
相关推荐
陌上丨3 小时前
Redis的Key和Value的设计原则有哪些?
数据库·redis·缓存
AI_56783 小时前
AWS EC2新手入门:6步带你从零启动实例
大数据·数据库·人工智能·机器学习·aws
ccecw3 小时前
Mysql ONLY_FULL_GROUP_BY模式详解、group by非查询字段报错
数据库·mysql
JH30733 小时前
达梦数据库与MySQL的核心差异解析:从特性到实践
数据库·mysql
数据知道3 小时前
PostgreSQL 核心原理:如何利用多核 CPU 加速大数据量扫描(并行查询)
数据库·postgresql
麦聪聊数据5 小时前
Web 原生架构如何重塑企业级数据库协作流?
数据库·sql·低代码·架构
未来之窗软件服务5 小时前
数据库优化提速(四)新加坡房产系统开发数据库表结构—仙盟创梦IDE
数据库·数据库优化·计算机软考
主机哥哥5 小时前
阿里云OpenClaw部署全攻略,五种方案助你快速部署!
服务器·阿里云·负载均衡
陈桴浮海6 小时前
Kustomize实战:从0到1实现K8s多环境配置管理与资源部署
云原生·容器·kubernetes
Goat恶霸詹姆斯6 小时前
mysql常用语句
数据库·mysql·oracle