应用场景
- 用来将非机密性的数据保存到键值对中
限制
- ConfigMap 在设计上不是用来保存大量数据的。在 ConfigMap 中保存的数据不可超过 1 MiB
configMaps实例
apiVersion: v1
kind: ConfigMap
metadata:
name: wu-config-map
namespace: default
selfLink: /api/v1/namespaces/default/configmaps/wu-config-map
uid: 9ffd24eb-5aa8-45d2-bae1-c2a98e96d721
resourceVersion: '492505667'
creationTimestamp: '2023-06-27T09:20:52Z'
managedFields:
- manager: kubectl.exe
operation: Update
apiVersion: v1
time: '2023-06-27T09:20:52Z'
fieldsType: FieldsV1
fieldsV1:
f:data:
.: {}
f:config: {}
f:metadata:
f:annotations:
.: {}
f:kubectl.kubernetes.io/last-applied-configuration: {}
data:
config: |
kafka:
addr: 'localhost:9092'
topic: '1111'
username: '222'
password: '3333'
hbase:
host: 'localhost'
port: '2181'
username: 'postgres'
password: 'vvvv'
dbname: 'mytes'
sslmode: 'disable'
redis:
db: 6
addr: '6666'
password: '7777'
postgresql:
host: ''
port: '5432'
dbname: 'ccc'
username: 'xxxxx'
password: 'yyyyy'
sslmode: 'prefer'
log-mode: "silent"
binaryData: {}
使用
- ConfigMap 使用 data 和 binaryData 字段保存用户的配置数据。
- data 和 binaryData 字段都是可选的。data 字段设计用来保存 UTF-8 字符串,而 binaryData 则被设计用来保存二进制数据作为 base64 编码的字串。
- data 或 binaryData 字段下面的每个键的名称都必须由字母数字字符或者 -、_ 或 . 组成。在 data 下保存的键名不可以与在 binaryData 下出现的键名有重叠。
- 静态 Pod 中的 spec 字段不能引用 ConfigMap 或任何其他 API 对象。
使用 ConfigMap 配置 Pod 中的容器:
- 在容器命令和参数内(在deployment的配置文件中配置)
- 容器的环境变量(在deployment的配置文件中配置)
- 在只读卷里面添加一个文件,让应用来读取(在deployment的配置文件中配置)【实例使用的方式】
- 编写代码在 Pod 中运行,使用 Kubernetes API 来读取 ConfigMap
配置deployment
该配置有修改,不一定能直接用,重点是volumes部分
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
namespace: default
status:
observedGeneration: 6
replicas: 1
updatedReplicas: 1
unavailableReplicas: 1
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/component: backend
template:
metadata:
creationTimestamp: null
labels:
app.kubernetes.io/component: backend
annotations:
kubectl.kubernetes.io/restartedAt: '2023-06-27T09:25:06Z'
spec:
volumes:
- name: wu-config-volume
configMap:
name: wu-config-map
defaultMode: 420
containers:
- name: backend
image: xxxxx/wu/backend:0.0.1
ports:
- containerPort: 8080
protocol: TCP
resources: {}
volumeMounts:
- name: wu-config-volume
mountPath: /config
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
imagePullPolicy: IfNotPresent
restartPolicy: Always
terminationGracePeriodSeconds: 30
dnsPolicy: ClusterFirst
securityContext: {}
schedulerName: default-scheduler
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 30%
maxSurge: 25%
revisionHistoryLimit: 10
progressDeadlineSeconds: 600
在 Pod 中将 ConfigMap 当做文件使用
要在一个 Pod 的存储卷中使用 ConfigMap:
- 创建一个 ConfigMap 对象或者使用现有的 ConfigMap 对象。多个 Pod 可以引用同一个 ConfigMap。
- 修改 Pod 定义,在 spec.volumes[] 下添加一个卷。 为该卷设置任意名称,之后将 spec.volumes[].configMap.name 字段设置为对你的 ConfigMap 对象的引用。
- 为每个需要该 ConfigMap 的容器添加一个 .spec.containers[].volumeMounts[]。 设置 .spec.containers[].volumeMounts[].readOnly=true 并将 .spec.containers[].volumeMounts[].mountPath 设置为一个未使用的目录名, ConfigMap 的内容将出现在该目录中。
- 更改你的镜像或者命令行,以便程序能够从该目录中查找文件。ConfigMap 中的每个 data 键会变成 mountPath 下面的一个文件名。
被挂载的 ConfigMap 内容会被自动更新
- 当卷中使用的 ConfigMap 被更新时,所投射的键最终也会被更新;从 ConfigMap 被更新的那一刻算起,到新的主键被投射到 Pod 中去
- 以环境变量方式使用的 ConfigMap 数据不会被自动更新。 更新这些数据需要重新启动 Pod。
- 使用 ConfigMap 作为 subPath 卷挂载的容器将不会收到 ConfigMap 的更新。
golang 直接读取配置
package global
import (
"fmt"
"os"
"github.com/spf13/viper"
)
var GVA_CONFIG Server // 配置文件中对应的结构体变量,提供生成其他变量的方法的参数
type Server struct {
Redis RedisConfig `mapstructure:"redis" json:"redis" yaml:"redis"`
Postgresql Postgresql `mapstructure:"postgresql" json:"postgresql" yaml:"postgresql"`
KafakConfig KafakConfig `mapstructure:"kafka" json:"kafka" yaml:"kafka"`
HbaseConfig HbaseConfig `mapstructure:"hbase" json:"hbase" yaml:"hbase"`
System SystemDto `mapstructure:"system" json:"system" yaml:"system"`
}
type HbaseConfig struct {
Host string `mapstructure:"host" json:"host" yaml:"host"`
Port string `mapstructure:"port" json:"port" yaml:"port"`
Dbname string `mapstructure:"dbname" json:"dbname" yaml:"dbname"`
}
type KafakConfig struct {
Addr string
Topic string
}
type Postgresql struct {
Host string `mapstructure:"host" json:"host" yaml:"host"`
Port string `mapstructure:"port" json:"port" yaml:"port"`
Dbname string `mapstructure:"dbname" json:"dbname" yaml:"dbname"`
Username string `mapstructure:"username" json:"username" yaml:"username"`
Password string `mapstructure:"password" json:"password" yaml:"password"`
Sslmode string `mapstructure:"sslmode" json:"sslmode" yaml:"sslmode"`
LogMode string `mapstructure:"log-mode" json:"logMode" yaml:"log-mode"` // 是否开启Gorm全局日志
}
func (m *Postgresql) Dsn() string {
return "host=" + m.Host + " user=" + m.Username + " password=" + m.Password + " dbname=" + m.Dbname + " port=" + m.Port + " sslmode=" + m.Sslmode + " TimeZone=Asia/Shanghai"
}
type RedisConfig struct {
DB int `mapstructure:"db" json:"db" yaml:"db"` // redis的哪个数据库
Addr string `mapstructure:"addr" json:"addr" yaml:"addr"` // 服务器地址:端口
Password string `mapstructure:"password" json:"password" yaml:"password"` // 密码
}
func initViper() {
GVA_VP = viper.New()
var config string
GVA_VP.SetConfigType("yaml") // 设置配置文件类型为 YAML
config = "/config/config"
GVA_VP.SetConfigFile(config)
if config == "" {
fmt.Println("Cannot find any configuration file")
return
}
if err := GVA_VP.ReadInConfig(); err != nil {
panic(err.(interface{}))
}
if err := GVA_VP.Unmarshal(&GVA_CONFIG); err != nil {
fmt.Println(err)
}
fmt.Printf("配置文件读取:%#v\n", GVA_CONFIG)
}
这样就可以和读取本地的yaml文件一样