1 configmap

Tip
  • 就是为了配置与代码分离
  • 不同的pod 里某些东西可能使用相同的配置, 这样只要写一次, pod里直接用就行
  • secret && configmap 可以理解为2中特殊类型的存储卷
  • configmap存放的时候明文数据
  • 简称 cm

configmap

k explain cm

1.1 创建

1.1.1 基于目录或文件

环境准备
cat >game.properties <<EOF
enemies=aliens
lives=3
enemies.cheat=true
enemies.cheat.level=noGoodRotten
secret.code.passphrase=UUDDLRLRBABAS
secret.code.allowed=true
secret.code.lives=30
EOF
cat >ui.properties<<EOF
color.good=purple
color.bad=yellow
allow.textmode=true
how.nice.to.look=fairlyNice
EOF

tree
.
└── cfg
    ├── game.properties
    └── ui.properties
创建
# 基于目录,就是目录下的所有文件
k create cm game-all-config --from-file=./cfg/
# 基于文件 ,默认是default 命名空间, -n 指定
k create cm ui-config --from-file=./cfg/ui.properties -n test
# 默认是用文件名作为key, 可以指定
k create cm ui-config-with-key --from-file=ui=./cfg/ui.properties
# 基于多个文件
k create cm game-all-config-with-multi \
    --from-file=./cfg/ui.properties \
    --from-file=./cfg/game.properties
查看
k get cm #(1)
执行结果
NAME                  DATA    AGE
game-all-config        2      113s
查看某歌配置
k describe cm game-all-config
k get cm game-all-config  -o yaml # 查看(2)
执行结果
apiVersion: v1
data:
  game.properties: |
    enemies=aliens
    lives=3
    enemies.cheat=true
    enemies.cheat.level=noGoodRotten
    secret.code.passphrase=UUDDLRLRBABAS
    secret.code.allowed=true
    secret.code.lives=30
  ui.properties: |
    color.good=purple
    color.bad=yellow
    allow.textmode=true
    how.nice.to.look=fairlyNice
kind: ConfigMap
metadata:
  creationTimestamp: "2023-07-17T08:16:36Z"
  name: game-config
  namespace: default
  resourceVersion: "906578"
  uid: a8341d85-c916-40cd-bb5e-0ef334cc31f6

1.1.2 基于文件以env形式

Tip
  • Env 文件包含环境变量列表
    • Env 文件中的每一行必须为 VAR=VAL 格式。
    • 以#开头的行(即注释)将被忽略。
    • 空行将被忽略。
    • 引号不会被特殊处理(即它们将成为 ConfigMap 值的一部分)
环境准备
cat >game-env-file.properties<<EOF
enemies=aliens
lives=3
allowed="true"
EOF
创建
#从 k8s 1.23 版本开始,kubectl 支持多次指定 --from-env-file 参数来从多个数据源创建
k create cm game-env-file \
    --from-env-file=./cfg/game-env-file.properties
查看
k get cm game-env-file -o yaml
执行结果
apiVersion: v1
data:
  allowed: '"true"'
  enemies: aliens
  lives: "3"
kind: ConfigMap
metadata:
  creationTimestamp: "2023-07-17T08:43:55Z"
  name: game-env-file
  namespace: default
  resourceVersion: "908873"
  uid: 5f8c87a6-9af0-4b7b-8ed3-9018667c338f

注意 allowed: ‘“true”’ 的true
数字会用双引号

1.1.3 基于字面值

k create cm mysql-config \
    --from-literal=mysql.user=root \
    --from-literal=mysql.port=3306

1.1.4 基于yaml文件

mysql-cm.yaml
apiVersion: v1
kind: ConfigMap
immutable: true
metadata:
  name: mysql-config2
  namespace: default
data: #同命令创建的 --from-literal=database=test --from-literal=port=3306
  database: "test"
  port: "3306"
  1. immutable: true 设置成不可变
这样你无法通过`k edit cm` 修改
无法通过修改yaml文件,然后apply -f 或 k replace -f
可以用`k replace --force -f`
  1. 数字必须用引号括起来!!!
k create -f mysql-cm.yaml

1.2 使用

Tip

ConfigMap 位于确定的命名空间中. 每个 ConfigMap 只能被同一命名空间中的 Pod 引用

1.2.1 valueFrom

Tip

适用于使用几个环境变量, 直接注入,如果你后续修改了configmap, 是不会同步到pod里的

pod-cm-valuefrom.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: special-config
  namespace: default
data:
  hello: world
  python: good
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: cm-mysql
  namespace: default
data:
  mysql_port: "3306"
---
apiVersion: v1
kind: Pod
metadata:
  name: pod-cm-valuefrom
spec:
  containers:
    - name: test-container
      image: busybox
      imagePullPolicy: IfNotPresent
      command: [ "/bin/sh", "-c", "env" ]
      env:
        - name: tom
          value: cat # env环境变量,我们当然可以直接赋值
        - name: WELCOME
          valueFrom: # 使用来自cm的key
            configMapKeyRef:
              # 指定 包含你要赋给 WELCOME 值 的ConfigMap
              name: special-config
              # 指定与取值相关的键名
              key: hello
        - name: MYSQL_PORT
          valueFrom:
            configMapKeyRef:
              name: cm-mysql
              key: mysql-port
              optional: false  #(1)
  restartPolicy: Never
  1. optional: false 默认是false
    • false:
      • 指定的configmap不存在,则pod无法启动
      • 指定的key不存在, pod 也无法启动
    • true: 表示如果指定的configmap或key 不存在, 可以启动pod,只不过就是没有用到,key无效
k create -f pod-cm-valuefrom.yaml
# 打印 env 环境变量 ,可以看到 WELCOME = world, MYSQL_PORT等
k logs pod-cm-valuefrom

1.2.2 envFrom

Tip

将configmap里所有的作为环境变量,也是注入的方式, 修改configmap,同样不会同步到pod里

apiVersion: v1
kind: ConfigMap
metadata:
  name: special-config
  namespace: default
data:
  hello: world
  python: good
---
apiVersion: v1
kind: Pod
metadata:
  name: pod-cm-envfrom
spec:
  containers:
    - name: test-container
      image: busybox
      imagePullPolicy: IfNotPresent
      command: [ "/bin/sh", "-c", "env" ]
      envFrom:
1        - prefix: TEST_
          configMapRef:
            name: special-config
2            optional: true
  restartPolicy: Never
1
环境变量加上前缀
2
默认是false
false: 如果指定的configmap不存在,则pod无法启动
true: 表示如果指定的cm 不存在, 可以启动pod,只不过就是没有用到cm

1.2.3 文件挂载

my.conf
server {
    listen       8099;
    listen       [::]:8099;
    server_name  _;
    root         /usr/share/nginx/html;
    include /etc/nginx/default.d/*.conf;
    error_page 404 /404.html;
    location = /404.html {
    }
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
    }
}
# 混合 来创建一个cm
k create cm cm-nginx-8099 --from-file=my.conf  --from-literal=mysql.port=3306
apiVersion: v1
kind: Pod
metadata:
  name: cm-vol-1
  namespace: default
spec:
  containers:
  - image: nginx:alpine
    name: web-server
    volumeMounts:
    - name: vol-cm-nginx-8099 #使用的volume的名称
      mountPath: /etc/nginx/conf.d/  #挂载到容器里的哪个目录, 挂载后这个目录下原来的所有文件将被删除
      readOnly: true
    - name: vol-cm-nginx-8099 #可以挂载到多个目录 ,没有的话,会自动创建目录
      mountPath: /etc/nginx/abc/
      readOnly: true
  volumes:
  - name: vol-cm-nginx-8099  #volume的名称
    configMap: # 存储卷类型
      name: cm-nginx-8099 #cm名字
      items: #修改挂载到容器里的名称,默认是key名, 有多个key 就有多个文件 (看下面说道的 2个文件软连接 )
        - key: my.conf #cm里的key名
          path: my2.conf    # 挂载到容器里的名称 最终是在 上面设置的mountPath /etc/nginx/conf.d/my2.conf
        - key: mysql.port
          path: mysql_port
          mode: 0666 # 单独设置权限
      defaultMode: 0666  #8进制   挂载到容器里的文件的权限  记得去看软连接的原始文件的权限来验证
k exec -it configmap-volume-demo -- ls -l /etc/nginx/conf.d
lrwxrwxrwx    1 root     root  15 Jul 17 14:27 my2.conf -> ..data/my2.conf  内容就是my.conf文件内容
lrwxrwxrwx    1 root     root  17 Jul 17 14:27 mysql_port -> ..data/mysql_port 内容是3306
Important
  • 这种文件挂载的方式, 如果你的configmap修改了,pod里看到的配置也会是修改后的
  • 不过 这还不行, 你的pod里的程序必须也能够 热加载才行, (就是能监控配置文件的变化,自动重启)

2 secret

官方文档

Tip
  • 由于configmap 是明文, 因此与configmap 有着同样功能的 secret 就相应的设计出来了
  • 使用方法与 configmap 类似,在yaml文件上把configmap 改成 secret,大部分就ok了
类型 描述
Opaque 通用型Secret,用户自定义,默认类型
kubernetes.io/service-account-token 作用于ServiceAccount,包含一个令牌,用于标识API服务账户
kubernetes.io/dockercfg serialized ~/.dockercfg file
kubernetes.io/dockerconfigjson 下载私有仓库镜像使用的Secret, 和宿主机的 ~/.docker/config.json一致 ,宿主机docker login后即可产生该文件
kubernetes.io/basic-auth 用于使用基本认证(账号密码)的Secret,可以使用Opaque取代
kubernetes.io/ssh-auth 用于存储ssh密钥的Secret
kubernetes.io/tls 用于存储HTTPS域名证书文件的Secret,可以被Ingress使用
bootstrap.kubernetes.io/token 一种简单的 bearer token,用于创建新集群或将新节点添加到现有集群,在集群安装时可用于自动颁发集群的证书
kubectl create secret generic mysql-root-password \
    --from-literal=password=123456  \
    --from-literal=username=root
k get secret
我们可以看到这个 secret 的类型是 Opaque
NAME                  TYPE    DATA   AGE
mysql-root-password   Opaque  2      12s
k describe secrets  mysql-root-password
Data 里只显示几个字节!
Name:         mysql-root-password
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
password:  6 bytes
username:  4 bytes
k get secrets mysql-root-password  -o yaml
Data 显示的是加密的
apiVersion: v1
data:
  password: MTIzNDU2
  username: cm9vdA==
kind: Secret
metadata:
  creationTimestamp: "2023-07-18T01:56:16Z"
  name: mysql-root-password
  namespace: default
  resourceVersion: "941954"
  uid: 51b42a5f-02c8-4cc1-a482-2c6c0eceb3eb
type: Opaque
# 然而那这个加密仅仅是base64 可以解密
# 能够得到 密码 123456
echo MTIzNDU2 |base64 -d
#文件形式创建
cat user.txt
    root
cat pass.txt
    123456
kubectl create secret generic mysql-root-password2 --from-file=user.txt --from-file=pass.txt

3 注意

  • 我们一般是用配置文件来创建configmap
  • 前面提到过,真正的热更新,还需要程序检测自动重启的支持
  • 使用envFrom和valueFrom是无法更新环境变量的, 环境变量是启动容器就定了的.需要重启容器
Back to top