Kubernetes 配置【Secret、ConfigMap】

52 阅读5分钟

云原生 从docker、Jenkins、Kubernetes从入门到精通系列

配置的最佳实战:

  • 云原生 应用12要素 中,提出了配置分离。点击这里
  • 在推送到集群之前,配置文件应存储在版本控制中。 这允许您在必要时快速回滚配置更改。 它还有助于集群重新创建和恢复。
  • 使用 YAML 而不是 JSON 编写配置文件。虽然这些格式几乎可以在所有场景中互换使用,但 YAML 往往更加用户友好。
  • 建议相关对象分组到一个文件。比如 guestbook-all-in-one.yaml
  • 除非必要,否则不指定默认值:简单的最小配置会降低错误的可能性。
  • 将对象描述放在注释中,以便更好地进行内省。

1、Secret

使用命令解释kubectl explain secret,secret的相关参数与使用说明

  • Secret 对象类型用来保存敏感信息,例如密码、OAuth 令牌和 SSH 密钥。 将这些信息放在 secret 中比放在 Pod 的定义或者 容器镜像 中来说更加安全和灵活。
  • Secret 是一种包含少量敏感信息例如密码、令牌或密钥的对象。用户可以创建 Secret,同时系统也创建了一些 Secret。
1、Secret种类

1620443365394.png

  • 细分类型

1620444574342.png

2、Pod如何引用

要使用 Secret,Pod 需要引用 Secret。 Pod 可以用三种方式之一来使用 Secret:

Secret 对象的名称必须是合法的 DNS 子域名。 在为创建 Secret 编写配置文件时,你可以设置 data 与/或 stringData 字段。 datastringData 字段都是可选的。data 字段中所有键值都必须是 base64 编码的字符串。如果不希望执行这种 base64 字符串的转换操作,你可以选择设置 stringData 字段,其中可以使用任何字符串作为其取值。

3、实战
1、创建Secret

1、generic 类型

## 命令行
#### 1、使用基本字符串 【因为有特殊字符,所以需要使用单引号包一下】
kubectl create secret generic dev-db-secret   --from-literal=username=devuser   --from-literal=password='S!B*d$zDsb='
 
 #使用以下命令查看yaml文件
 --dry-run=client -oyaml

## 参照以下yaml

apiVersion: v1
kind: Secret
metadata:
  name: dev-db-secret  
data:
  password: UyFCXCpkJHpEc2I9  ## base64编码了一下
  username: ZGV2dXNlcg==
  
#### 2、使用文件内容
echo -n 'admin' > ./username.txt
echo -n '1f2d1e2e67df' > ./password.txt

kubectl create secret generic db-user-pass \
  --from-file=./username.txt \
  --from-file=./password.txt

# 默认密钥名称是文件名。 你可以选择使用 --from-file=[key=]source 来设置密钥名称。如下
kubectl create secret generic db-user-pass-02 \
  --from-file=un=./username.txt \
  --from-file=pd=./password.txt
## 使用yaml
dev-db-secret yaml内容如下

1620444050943.png

  • 获取Secret内容
kubectl get secret dev-db-secret -o jsonpath='{.data}'
2、使用Secret

1、环境变量引用

vi快捷键dG全部删除

# secret保存在集群的etcd里面
apiVersion: v1
kind: Pod
metadata:
  name: "pod-secret"
  namespace: default
  labels:
    app: "pod-secret"
spec:
  containers:
  - name: pod-secret
    image: "busybox"
    command: ["/bin/sh","-c","sleep 3600"]  ## echo $My_USR
    resources:
       limits:
         cpu: 10m #  1核代表1000m
       requests:
         cpu: 5m
    env:
    - name: MY_USR  # 容器里的环境变量名字
      valueFrom:
        secretKeyRef: # secret的内容
          name:  dev-db-secret #指定secret名字
          key: username  # 自动base64解码
    - name: POD_NAME
      valueFrom:
        fieldRef: # 属性引用
          fieldPath: metadata.name  # 取出资源对象信息
    - name: POD_LIMIT_MEM
      valueFrom:
        resourceFieldRef:
          containerName: pod-secret  # 取出指定容器的相关资源值
          resource: limits.cpu

使用命令kubectl get pod -A查看刚刚创建的容器,并获取容器名pod-secret
使用命令kubectl exec -it pod-secret -- /bin/sh进入容器;
使用命令echo $MY_USR可查看变量信息。

环境变量引用的方式不会被自动更新!!

2、卷挂载

# secret保存在集群的etcd里面
# kubectl create secret
apiVersion: v1
kind: Pod
metadata:
  name: "pod-secret-volume"
  namespace: default
  labels:
    app: "pod-secret-volume"
spec:
  volumes: # 指定挂载详情
  - name: app
    secret:
      defaultMode: 0777 # 修改默认的权限模式
      secretName: db-user-pass  # secret里面所有的key全部挂出来,
      items:
      - key: password.txt  # db-user-pass里面的password.txt这个key的内容挂出来
        path: pwd.md # 默认secret里面数据的key是作为文件名的。 path就是相当于我们自己指定一个文件名

  containers:
  - name: pod-secret-volume
    image: "busybox"
    command: ["/bin/sh","-c","sleep 3600"]  ## echo $My_USR
    resources:
       limits:
         cpu: 10m #  1核代表1000m
       requests:
         cpu: 5m
    volumeMounts:
    - name: app
      mountPath: /app  # 容器内的app文件夹是集群中 secret名叫db-user-pass的内容
      readOnly: false

使用命令kubectl get pod -A查看刚刚创建的容器,并获取容器名pod-secret-volume
使用命令kubectl exec -it pod-secret-volume -- /bin/sh进入容器;
使用命令ls /app/可查看相应挂载文件信息。

image.png

挂载方式的secret 在secret变化的时候会自动更新 (子路径引用除外)

如果secret以挂载的方式给容器

  • secret里面的所有key都是文件名。内容就是文件内容。
  • 挂载的方式会自动更新文件内容
  • 反向更新,默认是只读模式,如果要编辑,则需要指定 defaultMode字段。0777。并且添加redeOnly=false
    • pod安全性。超级权限穿透。
    • pod里面fsGroup,runAsUser

2、ConfigMap

使用命令解释kubectl explain cm,查看相关命令
使用命令解释kubectl create cm --help,查看帮助

  • ConfigMap保存的内容就是普通的明文文本,不会编码;
  • ConfigMap 来将你的配置数据和应用程序代码分开;
  • ConfigMap 是一种 API 对象,用来将非机密性的数据保存到键值对中。使用时, Pods 可以将其用作环境变量、命令行参数或者存储卷中的配置文件。
apiVersion: v1
kind: ConfigMap
metadata:
  name: game-demo
data:
  # 类属性键;每一个键都映射到一个简单的值
  player_initial_lives: "3"
  ui_properties_file_name: "user-interface.properties"

  # 类文件键
  game.properties: |
    enemy.types=aliens,monsters
    player.maximum-lives=5    
  user-interface.properties: |
    color.good=purple
    color.bad=yellow
    allow.textmode=true

你可以使用四种方式来使用 ConfigMap 配置 Pod 中的容器:

  1. 在容器命令和参数内
  2. 容器的环境变量
  3. 在只读卷里面添加一个文件,让应用来读取
  4. 编写代码在 Pod 中运行,使用 Kubernetes API 来读取 ConfigMap
apiVersion: v1
kind: Pod
metadata:
  name: "cm-pod"
  namespace: default
  labels:
    app: "cm-pod"
spec:
  volumes:
  - name: my-cm
    configMap:
      name: game-demo # 指定cm的名字
      # items:
      #  -
  containers:
  - name: cm-pod
    image: "busybox"
    command: ["/bin/sh","-c","sleep 3600"]
    env:
    - name: PLAY_LIVES  # 请注意这里和 ConfigMap 中的键名是不一样的
      valueFrom:
        configMapKeyRef:  #来自于cm
          name: game-demo  # 这个值来自 ConfigMap
          key: player_initial_lives # 需要取值的键
    volumeMounts:
    - name: my-cm
      mountPath: /app  # 容器内的app文件夹是集群中 secret名叫db-user-pass的内容

ConfigMap的修改,可以触发挂载文件的自动更新

CM和Secret使用子路径的话是无法热更新的。