文章目录
k8s之configmap
什么是 ConfigMap?
ConfigMap 是 Kubernetes 中用于存储非机密配置数据的 API 对象。它允许你将配置信息与容器镜像解耦,使应用程序更加灵活和可移植。ConfigMap 以键值对的形式存储数据,可以被 Pod 以多种方式消费。
为什么需要 ConfigMap?
在传统的应用部署中,配置通常硬编码在应用程序中或通过环境变量传递。这种方式存在以下问题:
- 配置与代码耦合:修改配置需要重新构建镜像
- 环境差异:不同环境需要不同的配置
- 安全性:敏感配置可能暴露在镜像中
- 维护困难:配置分散在各个地方,难以统一管理
ConfigMap 解决了这些问题,提供了一种集中化、声明式的配置管理方案。
ConfigMap 的创建方式
- 通过 kubectl 命令行创建
bash
# 从字面值创建
kubectl create configmap app-config \
--from-literal=database.host=mysql.example.com \
--from-literal=database.port=3306
# 从文件创建
kubectl create configmap app-config --from-file=config.properties
# 从目录创建
kubectl create configmap app-config --from-file=config-dir/
- 通过 YAML 文件创建
yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: default
data:
# 简单的键值对
database.host: "mysql.example.com"
database.port: "3306"
# 多行配置文件
app.properties: |
server.port=8080
logging.level.root=INFO
spring.datasource.url=jdbc:mysql://mysql:3306/mydb
# JSON 格式配置
config.json: |
{
"server": {
"port": 8080,
"host": "0.0.0.0"
},
"database": {
"host": "mysql.example.com",
"port": 3306
}
}
ConfigMap 的使用方式
- 作为环境变量
yaml
apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: myapp:latest
env:
# 引用单个键
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: app-config
key: database.host
# 引用所有键作为环境变量
envFrom:
- configMapRef:
name: app-config
- 作为命令行参数
yaml
apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: myapp:latest
command: ["/bin/sh"]
args: ["-c", "echo $(DB_HOST):$(DB_PORT)"]
env:
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: app-config
key: database.host
- name: DB_PORT
valueFrom:
configMapKeyRef:
name: app-config
key: database.port
- 作为卷挂载
yaml
apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app
image: myapp:latest
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: app-config
# 可选:指定特定的键和文件名
items:
- key: app.properties
path: application.properties
- key: config.json
path: config.json
实际应用场景
场景1:Web 应用配置
apiVersion: v1
kind: ConfigMap
metadata:
name: webapp-config
data:
nginx.conf: |
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://backend:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
app.env: |
NODE_ENV=production
PORT=8080
LOG_LEVEL=info
REDIS_URL=redis://redis:6379
场景2:数据库配置
yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: db-config
data:
mysql.cnf: |
[mysqld]
max_connections=200
innodb_buffer_pool_size=1G
slow_query_log=1
long_query_time=2
init.sql: |
CREATE DATABASE IF NOT EXISTS myapp;
USE myapp;
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) NOT NULL,
email VARCHAR(100) NOT NULL
);
ConfigMap 最佳实践
- 命名规范
bash
# 好的命名方式
kubectl create configmap app-database-config
kubectl create configmap frontend-nginx-config
kubectl create configmap backend-app-config
# 避免的命名方式
kubectl create configmap config
kubectl create configmap data
- 环境分离
yaml
# 开发环境
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: development
data:
database.host: "dev-mysql.internal"
log.level: "debug"
---
# 生产环境
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
namespace: production
data:
database.host: "prod-mysql.internal"
log.level: "warn"
使用 namespace 来区分开发和生产环境是 Kubernetes 中常见和推荐的做法。这是最常见的方式,适用于同一个集群内的环境分离:主要用于小型团队。
缺点:
安全风险:生产和开发环境在同一个集群,存在潜在的安全风险
资源竞争:可能存在资源争用的情况
故障影响:集群级别的故障会影响所有环境
更严格的环境分离方式,每个环境使用独立的集群。主要用于中大型团队,并且对安全和隔离性要求比较高场景。
实际生产中,很多公司采用混合策略:
bash
# 集群规划示例
# dev-cluster: 开发和测试环境
# - namespace: development
# - namespace: testing
# - namespace: integration
# prod-cluster: 预生产和生产环境
# - namespace: staging
# - namespace: production
注意事项和限制
- 大小限制
ConfigMap 的总大小不能超过 1MB
单个键的值不能超过 1MB - 安全考虑
ConfigMap 中的数据是明文存储的 - ConfigMap 更新不会自动触发 Pod 重启,需要手动重启
参考
推荐:【k8s教程】薪享宏福Kubernetes v1.29 |2024最新版!B站最强!百万播放汪洋授课,轻松拿捏k8s
参考URL: https://www.bilibili.com/video/BV1PbeueyE8V