Kubernetes(十五)Configmap和Secret

一    背景引出

前面我们学习了一些'常用的资源对象'的使用,但是'单纯依靠'这些资源对象,还'不足以'满足我们的日常需求

一个'重要的需求'就是'应用的配置管理'、'敏感信息的存储和使用(passwd、token)'、'容器运行资源的配置'、'安全管控'、'身份认证'等等

二    ConfigMap

对于'应用的可变配置'在 Kubernetes 中是通过一个 'ConfigMap 资源对象'来实现的

我们知道'许多应用'经常会有从'配置文件'、'命令行参数'或者'环境变量中'读取一些'配置信息'的需求

这些配置信息我们肯定'不会直接写死到应用程序'中去的,比如你一个应用连接一个 redis 服务,下一次想更换一个了的,还得'重新去修改代码',重新'制作一个镜像',这肯定是'不可取'的

++++++++++++++++ '分割线' ++++++++++++++++ 

而ConfigMap 就给我们提供了'向容器中注入配置信息的能力',不仅可以用来保存'单个属性',还可以用来保存'整个配置文件',

应用场景举例: 比如我们可以用来'配置一个 redis 服务'的访问地址,也可以用来保存'整个 redis' 的配置文件

Configmap官网资料

(1)帮助文档理解

(1)命令行创建

备注: 这是'最常用'的方式

①  基于目录创建

查看

将 '/tmp/' 目录下的'所有文件-->普通文件',也就是 'hpa-mem.yaml' 和 'hpa-mem-demo.yml' 打包到 'configmap1' ConfigMap 中

②    基于文件

基于'单个'文件或'多个'文件创建 ConfigMap

++++++++++++++++ '这个不再演示' ++++++++++++++++ 

你可以'定义'在 ConfigMap 的 data 部分出现键名,而'不是按默认行为'使用文件名

kubectl create configmap 'configmap_name'  --from-file='<my-key-name>=<path-to-file>'

③    基于字面量

注意的是如果文件里面的'配置信息很大'的话,'describe' 的时候可能'不会显示对应的值'

④    从环境文件创建 ConfigMap

(2)yaml创建

kind: ConfigMap
apiVersion: v1
metadata:
  name: cm-demo
  namespace: default
data:                       '核心是这个字段'
  data.1: hello
  data.2: world
  config: |
    property.1=1
    property.2=2
    property.3=3
'yaml的一些高级语法在k8s中的体现'

使用竖线符'|'来表示该语法,每行的'缩进和行尾空白'都会被去掉,而'额外的缩进'会被保留

使用右尖括号' > '来表示该语法,--'和保留换行不同的是'-->只有'空白行'才会被'识别为换行',原来的'换行符'都会被转换成'空格',而'行首缩进'会被去除

参考博客

参考博客

维基百科

(3)ConfigMap的使用

Pod的'使用方式':

1. 将ConfigMap中的数据'设置为容器的环境变量'

2. 将ConfigMap中的数据设置为'命令行参数'

3. 使用'Volume'将ConfigMap作为'文件或目录挂载(mount)'

4. 编写'代码'在 Pod 中运行,使用'Kubernetes API 来读取' ConfigMap

⑤     环境变量使用

资源清单

需求: 将 ConfigMap 中的'所有键值对配置'为容器'环境变量'

备注: Kubernetes 'v1.6 和更高版本'支持此功能

kubectl create configmap cm2 --from-literal=JAVA_HOME=/usr/bin/java --from-literal=MAVEN_HOME=/usr/bin/maven
apiVersion: v1
kind: Pod
metadata:
  name: busybox
spec:
  containers:
  - name: busybox
    image: busybox
    command: ['/bin/sh','-c','env']
    envFrom:
      - configMapRef:
          name: cm2

⑥  作为命令行参数

apiVersion: v1
kind: Pod
metadata:
  name: testcm2-pod
spec:
  containers:
    - name: testcm2
      image: busybox
      command: [ "/bin/sh", "-c", "echo $(DB_HOST) $(DB_PORT)" ]
      env:
        - name: DB_HOST
          valueFrom:
            configMapKeyRef:
              name: cm-demo3
              key: db.host
        - name: DB_PORT
          valueFrom:
            configMapKeyRef:
              name: cm-demo3
              key: db.port

⑦  将 ConfigMap 数据添加到一个卷中

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: busybox
      command: [ "/bin/sh", "-c", "ls /etc/config/" ] '查看是否挂载-->生成两个文件(以configmap的key为文件名)'
      volumeMounts:               
      - name: config-volume       '容器中使用哪个volume,进行挂载'
        mountPath: /etc/config    '容器中的挂载点'
  volumes:
    - name: config-volume
      configMap:
        name: cm1                 '使用configmap类型的cm1作为volume'
  restartPolicy: Never

⑧  将 ConfigMap 数据添加到数据卷中的特定路径

使用 'path 字段'为特定的 ConfigMap 项目'指定预期的文件路径' 

在这里'SPECIAL_LEVEL' 将挂载在 'config-volume' 数据卷中 '/etc/config/keys 目录下'

++++++++++++++++++ '注意事项' ++++++++++++++++++ 

使用 ConfigMap 作为 'subPath' 的数据卷将'不会收到' ConfigMap 更新
apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: busybox
      command: [ "/bin/sh","-c","cat /etc/config/keys" ]
      volumeMounts:
      - name: config-volume
        mountPath: /etc/config  -->'挂载后-->/etc/config/${path}'
  volumes:
    - name: config-volume
      configMap:
        name: special-config
        items:
        - key: SPECIAL_LEVEL    -->'使用configmap中的哪个key'
          path: keys

⑨  热更新

之有当 ConfigMap 以'数据卷的形式挂载'进 Pod 的时,才支持'热更新' -->'subPath'不支持

细节: '更新' ConfigMap或'删掉重建'ConfigMap,Pod 内挂载的'配置信息会热更新',这时可以增加一些'监测配置文件'变更的脚本,然后'重加载'对应服务就可以实现'应用的热更新'

核心: 让系统'感知配置文件'的'变化',让应用程序重'新加载配置'文件生效 -->'md5sum模拟'

++++++++++++++++++  '分割线'  ++++++++++++++++++

配置文件的热更新'不等于'应用的热更新

ConfigMap可以通过'目录'或'文件'的方式进行挂载

⑩  限制事项

1) 在 Pod 规范中'引用之前',必须'先创建一个 ConfigMap'-->'除非将 ConfigMap 标记为"可选"';如果引用的 ConfigMap '不存在',则 Pod '将不会启动';同样引用 ConfigMap 中'不存在的键'也会阻止 Pod 启动。

如果你使用 envFrom 基于 ConfigMap 定义环境变量,那么无效的键将被忽略。 可以启动 Pod,但无效名称将记录在事件日志中(InvalidVariableNames)。 日志消息列出了每个跳过的键。

2)ConfigMap 位于'特定的名字空间'中,每个 ConfigMap 只能被'同一名字空间中的 Pod 引用'

3)你不能将 ConfigMap 用于' 静态 Pod '

4)ConfigMap '文件大小限制'为 1MB-->'ETCD 的要求'

三    Secret

官网文档

(1)概念引入

(2) Secret的类型

强调: pod对于kube-apiservre也是一个'client',要访问资源'也需要通过认证'-->'通过'kubernetes.io/service-account-token

(3)Opaque

特点:Opaque 类型的数据是一个 'map 类型',要求 value 必须是 'base64 编码'格式

+++++++++++++++++++​ '分割线' +++++++++++++++++++​ 

建一个'用户名为 admin','密码为 123456' 的 Secret 对象,首先我们需要先把用户名和密码'做 base64 编码'
echo -n 表示'不换行输出',添加了-n选项以后,'文本直接连着命令提示符'输出了,并没有换行

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque              '重点'
data:
  username: YWRtaW4=      'base64编码'
  password: MTIzNDU2
用 'describe' 命令查看到的 Data '不会直接显示'出来 -->可以'get -o yaml'形式获取

(4)kubernetes.io/service-account-token

Service Account 是属于某个'具体的Namespace',给'Pod 里的进程'使用的

每个ServiceAccount下面都会拥有一个'加密过的secret作为Token'. 该token也叫service-account-token,该token才是'真正在API Server验证'(authentication)环节起作用的

当用户在该namespace下'创建pod'的时候都会'默认使用'这个service account

1) 每个Namespace下有一个'名为default'的默认的Service Account'sa'对象

2) 这个ServiceAccount下面都会拥有一个'加密过的secret'作为Token,可以'当作Volume'一样被Mount到Pod里

3)当Pod 启动时,这个'Secret会自动被Mount'到Pod的'指定目录下',用来'协助完成'Pod中的进程'访问API Server'时的'身份鉴权'过程

'ca.crt和token'就是提供给'开发者访问'apiservre的 -->利用'pod自带的'

'默认default的sa'没有对应的权限'比如get pods',除非'sa关联的secret'或者说'sevice accout有这个权限'就可以访问pod了

++++++++++++++++++ '另外一种方式'  ++++++++++++++++++ 

kubeconfig -->集群内'不管pod还是节点'和集群外都可以访问

(5)kubernetes.io/dockerconfigjson

说明:如果'yaml文件的话',需要提前把'核心数据'进行'base64编码',每次都都要'手工操作',比较'麻烦' -->'自动帮我们做base64编码'

++++++++++++++++ '下面方式' ++++++++++++++++

如果非'80'端口或者'https-->默认是443可以省略'的形式,仓库地址需要加'port'

备注: 可以'加上-->可选'--type=kubernetes.io/dockerconfigjson

'利用docker login'生成的'.dockercfg'文件生成secret

kubectl create secret docker-registry myregistrykey   --from-file="~/.dockercfg"

(6)Secret使用

1)以'环境变量'的形式

2)以'volume'的形式挂载

①    环境变量

创建Secret保存'mysql镜像'启动所需的'参数'

1)'创建Secret'-->属于'ns'的

kubectl create secret generic mysql-secret --from-literal=MYSQL_ROOT_PASSWORD='$!B@12zDhh' -n default

备注: 密码'格式不对'也可能无法创建成功

---

apiVersion: v1
kind: Pod
metadata:
  labels:
    name: java
  name: mysql
  namespace: default
spec:
  containers:
  - image: mysql:5.7.30
    name: mysql-server
    imagePullPolicy: IfNotPresent
    env:
    - name: MYSQL_ROOT_PASSWORD    '这个名字必须是固定的,mysql启动会找这个环境变量'
      valueFrom:
        secretKeyRef:
          key: MYSQL_ROOT_PASSWORD
          name: mysql-secret

---

kubectl apply -f mysql-secret.yml

测试ok 

②  Volume 挂载

1)创建一个'包含 SSH 密钥'的 Secret

kubectl create secret generic ssh-key-secret \
  --from-file=ssh-privatekey=/root/.ssh/.ssh/id_rsa \
  --from-file=ssh-publickey=/root/.ssh/id_rsa.pub

2)创建一个 Pod,令其'引用包含 SSH 密钥的 Secret',并通过'存储卷来使用'它

apiVersion: v1
kind: Pod
metadata:
  name: secret-test-pod
  labels:
    name: secret-test
spec:
  volumes:                        'pod中声明使用volum的类型'
  - name: secret-volume
    secret:
      secretName: ssh-key-secret
  containers:
  - name: ssh-test-container
    image: mySshImage
    volumeMounts:                 'containers使用volume'
    - name: secret-volume
      readOnly: true
      mountPath: "/etc/secret-volume"

③   imagePullSecrets

ImagePullSecrets 与 Secrets '不同',因为 Secrets 可以'挂载到 Pod 中',但是 'ImagePullSecrets 只能由 Kubelet 访问'
apiVersion: v1
kind: Pod
metadata:
  name: foo
spec:
  containers:
  - name: foo
    image: harbor.wzj.com/test:v1
  imagePullSecrets:         '说明: 这里只是认证-->必须保证该secret是对harbor.wzj.com的认证才能拉取' --> '针对pod里面所有的容器的'
  - name: myregistry
备注: 除了设置 Pod.spec.imagePullSecrets 这种方式来'获取私有镜像'之外,我们还可以通过在 'ServiceAccount' 中设置 'imagePullSecrets',然后就会自动为'使用该 sa 的 Pod 注入' imagePullSecrets 信息

④   tls

后续补充: ingress'这块'做一个'认证'

⑤    热更新和不可变

特点:  一旦一个 Secret 或 ConfigMap 被'标记为不可变','撤销'此操作或者'更改' data 字段的内容都是'不可能的', '只能删除'并'重新创建'这个 Secret;现有的 Pod 将维持对已删除 Secret 的挂载点 - 建议重新创建这些 Pod

三    Secret 和 ConfigMap这两种资源对象的异同点

四    Secret最佳实践

五    Secret扩展

FEATURE STATE: Kubernetes 'v1.13 [beta]'

你可以为 Secret 数据开启'静态加密', 这样 Secret 数据就'不会以明文形式'存储到etcd 中

静态加密

Valut加密

 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值