Kubernetes数据持久化之Secret与ConfigMap

ConfigMap和Secret是Kubernetes中两种特殊类型的存储卷,ConfigMap这种资源对象主要用于提供配置数据以定制程序行为,不过一些敏感的配置信息,比如像用户名、密码、密钥等通常都是由Secret这种资源对象来进行配置的,他们将相应的配置信息保存于对象中,而后在Pod资源上以存储卷的形式将其挂载并获取相应配置,以实现配置与镜像文件的解耦。

一、Secret资源对象

1) Secret概述

Secret资源对象存储数据的方式是以键值对的方式进行存储的,在Pod资源进行Secret的方式是通过环境变量或存储卷的方式进行访问数据,解决了密码、token、密钥等敏感数据的配置问题,而不需要将这些敏感数据暴露到镜像或者Pod的spec字段中。另外,Secret对象的数据存储和打印格式为Base64编码的字符串,因此用户在创建Secret对象时,也需要提供该类型的编码格式的数据。在容器中以环境变量或存储卷的方式访问时,会自动解码为明文格式。需要注意的是,如果是在Master节点上,Secret对象以非加密的格式存储在etcd中,所以需要对etcd的管理和权限进行严格控制。

2)Secret资源的类型

Secret有四种类型:
1)Service Account :用来访问Kubernetes API,由Kubernetes自动创建,并且会自动挂载到Pod的/run/secrets/kubernetes.io/serviceaccount目录中;
2)Opaque :base64编码格式的Secret,用来存储密码、密钥、信息、证书等,类型标识符为generic;
3)kubernetes.io/dockerconfigjson :用来存储私有docker registry的认证信息,类型标识为docker-registry;
4)kubernetes.io/tls:用于为SSL通信模式存储证书和私钥文件,命令式创建类型标识为tls;

3)创建Secret的方式

假设存储的数据是:
username:root
password:123.com
以下的存储方式都是存储该信息!

1)使用--from-literal(文字)的方式

[[email protected] ~]# kubectl create secret generic mysecret01 --from-literal=username=root --from-literal=password=123.com
#创建一个secret资源对象,名称为mysecret01,采用的加密方式是generic(通用的、一般的加密方式)
#注意:这种方式每一条只能保存一条信息
[[email protected] ~]# kubectl get secrets mysecret01
NAME         TYPE     DATA   AGE
mysecret01   Opaque   2      25s
[[email protected] ~]# kubectl describe secrets mysecret01     #查看该资源的详细信息
Name:         mysecret01
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque                         #不透明的,看不到的

Data
====
password:  7 bytes                     #只能查看键的名称,无法查看到键对应的值
username:  4 bytes
[[email protected] ~]# kubectl get secrets mysecret01 -o yaml
#将该资源以yaml文件的方式进行显示
apiVersion: v1
data:
  password: MTIzLmNvbQ==                       #键对应的值都是乱码,加密使用的是base64编码格式
  username: cm9vdA==
kind: Secret
metadata:
  creationTimestamp: "2020-02-14T10:08:21Z"
  name: mysecret01
  namespace: default
  resourceVersion: "2474"
  selfLink: /api/v1/namespaces/default/secrets/mysecret01
  uid: 1aee0635-7bfb-4e8a-a21e-be993e534156
type: Opaque
[[email protected] ~]# echo -n cm9vdAo= | base64 --d              #将乱码解码后的结果
root
[[email protected] ~]# echo -n MTIzLmNvbQ== | base64 --d
123.com

2)使用--from-file(文件)的方式

这种方式更第一种方式差不多,可能稍微显得麻烦一些!

[[email protected] ~]# echo root > username
[[email protected] ~]# echo 123.com > password
#需要先将要存储的键值对写入到文件中,并且每个文件只能写入一个值
[[email protected] ~]# kubectl create secret generic mysecret02 --from-file=username --from-file=password
[[email protected] ~]# rm -rf username password
#即使文件删除之后,该资源键对应的值依然也是存在的
[[email protected] ~]# kubectl get secrets mysecret02
NAME         TYPE     DATA   AGE
mysecret02   Opaque   2      58s
[[email protected] ~]# kubectl describe secrets mysecret02
Name:         mysecret02
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
password:  8 bytes
username:  5 bytes

3)通过 --from-env-file(环境变量)的方式

这种方式可以在同一个文件中写入多个键值对,推荐使用!

[[email protected] ~]# tee  env.txt <<EOF            #将多个需要存储的键值写入同一个文件中
 username=root
 password=123.com
 EOF
[[email protected] ~]# kubectl create secret generic mysecret03 --from-env-file=env.txt
secret/mysecret03 created
[[email protected] ~]# kubectl get secrets mysecret03
NAME         TYPE     DATA   AGE
mysecret03   Opaque   2      19s
[[email protected] ~]# kubectl describe secrets mysecret03
Name:         mysecret03
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
username:  4 bytes
password:  7 bytes

4)通过yaml文件的方式

 [[email protected] ~]# echo root | base64                  #需要将键对应的值进行加密
cm9vdAo=
[[email protected] ~]# echo 123.com | base64
MTIzLmNvbQo=
[[email protected] ~]# vim secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: mysecret04
data:
  username: cm9vdAo=                            #将加密后的值写到配置文件中
  password: MTIzLmNvbQo=
[[email protected] ~]# kubectl apply -f secret.yaml
[[email protected] ~]# kubectl get secrets mysecret04
NAME         TYPE     DATA   AGE
mysecret04   Opaque   2      118s
[[email protected] ~]# kubectl describe secrets mysecret04
Name:         mysecret04
Namespace:    default
Labels:       <none>
Annotations:
Type:         Opaque

Data
====
password:  8 bytes
username:  5 bytes

4)Secret资源的使用方式

1)以volume挂载的方式使用

[[email protected] ~]# vim secret-pod01.yaml
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: busybox
    args:
      - /bin/sh
      - -c
      - sleep 3000000                  #以上字段仅仅是创建一个容器
    volumeMounts:
    - name: secret-test
      mountPath: "/etc/secret-test"                  #指定容器中的目录
      readOnly: true                                         #以只读的方式挂载
  volumes:
  - name: secret-test
    secret:
      secretName: mysecret04          #指定的是已有的secret资源的名称
[[email protected] ~]# kubectl apply -f secret-pod01.yaml
[[email protected] ~]# kubectl exec -it mypod /bin/sh        #进入容器
/ # cat -n /etc/secret-test/username /etc/secret-test/password     #查看对应的目录是否存在数据
     1  root
     2  123.com
#而且是已经解密后的数据
/ # echo 12324235532 > /etc/secret-test/username
/bin/sh: can‘t create /etc/secret-test/username: Read-only file system

现在,我们可以验证一下,如果此时更改secret04的内容,那么容器内对应的挂载目录下的内容是否更改?

[[email protected] ~]# echo zhangsan | base64
emhhbmdzYW4K
[[email protected] ~]# echo 123456 | base64
MTIzNDU2Cg==
[[email protected] ~]# vim secret.yaml
apiVersion: v1
kind: Secret
metadata:
  name: mysecret04
data:
  username: emhhbmdzYW4K
  password: MTIzNDU2Cg==
[[email protected] ~]# kubectl apply -f secret.yaml
[[email protected] ~]# kubectl exec -it mypod /bin/sh
/ # cat -n /etc/secret-test/username /etc/secret-test/password
     1  zhangsan
     2  123456
#再次查看容器中数据,发现已经发生了变化!    

注意:如果采用volume挂载的方式调用secert存储的值,容器内的值会随着secert存储的值发生改变而变化!

2)用环境变量的方式运行

[[email protected] ~]# vim secret-pod02.yaml
apiVersion: v1
kind: Pod
metadata:
  name: mypod2
spec:
  containers:
  - name: mypod
    image: busybox
    args:
      - /bin/sh
      - -c
      - sleep 3000000
    env:                                   #设置环境变量
      - name: SECRET_USERNAME               #指容器中的变量名称
        valueFrom:
          secretKeyRef:
            name: mysecret02                 #调用的是mysecret02
            key: username                       #对应的是mysecret02中username对应的值
      - name: SECRET_PASSWORD     #同上
        valueFrom:
          secretKeyRef:
            name: mysecret02
            key: password
[[email protected] ~]# kubectl apply -f secret-pod02.yaml
[[email protected] ~]# kubectl exec -it mypod2 /bin/sh
/ # echo ${SECRET_USERNAME}
root
/ # echo ${SECRET_PASSWORD}
123.com
#进入容器之后,查看变量对应的值

注意:如果采用变量的方式调用secert存储的值,容器内的变量值并不会随着secert存储的值发生改变,除非重新生成pod。

二、ConfigMap资源对象

1)ConfigMap概述

我们知道,在几乎所有的应用开发中,都会涉及到配置文件的变更,比如说在web的程序中,需要连接数据库,缓存甚至是队列等等。而我们的一个应用程序从写第一行代码开始,要经历开发环境、测试环境、预发布环境只到最终的线上环境。而每一个环境都要定义其独立的各种配置。如果我们不能很好的管理这些配置文件,你的运维工作将顿时变的无比的繁琐。为此业内的一些大公司专门开发了自己的一套配置管理中心,如360的Qcon,百度的disconf等。kubernetes也提供了自己的一套方案,即ConfigMap。kubernetes通过ConfigMap来实现对容器中应用的配置管理。

2)ConfigMap的创建方式

其实configMap和secert资源对象的创建方式完全一样!

1)通过--from-literal的方式

[[email protected] ~]# kubectl create configmap configmap01 --from-literal=username=root --from-literal=password=123.com
#创建一个configmap资源,名称为configmap01
[[email protected] ~]# kubectl describe configmaps configmap01
Name:         configmap01
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data      #可以很明确的看出存储的键对应的值,所以一般用于存储配置文件信息
====
password:
----
123.com
username:
----
root
Events:  <none>

2)通过--from-file的方式

[[email protected] ~]# echo root > username
[[email protected] ~]# echo 123.com > password
[[email protected] ~]# kubectl create configmap configmap02 --from-file=username --from-file=password
configmap/configmap02 created
[[email protected] ~]# kubectl describe configmaps configmap02
Name:         configmap02
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
password:
----
123.com

username:
----
root

Events:  <none>

3)通过--from-env-file的方式

[[email protected] ~]# tee 123.txt <<EOF
> username=root
> password=123.com
> EOF
[[email protected] ~]# kubectl create configmap configmap03 --from-env-file=123.txt
configmap/configmap03 created
[[email protected] ~]# kubectl describe configmaps configmap03
Name:         configmap03
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
username:
----
root
password:
----
123.com
Events:  <none>

4)通过yaml文件的方式

[[email protected] ~]# vim configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: configmap04
data:
  username: root                       #configmap使用yaml文件进行创建时,键对应的值无需事先加密
  password: 123.com                     #对应的值如果是数字,则需要单引号引起
[[email protected] ~]# kubectl apply -f configmap.yaml
[[email protected] ~]# kubectl describe configmaps configmap04
Name:         configmap04
Namespace:    default
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"v1","data":{"password":"123.com","username":"root"},"kind":"ConfigMap","metadata":{"annotations":{},"name":"configmap04","n...

Data
====
password:
----
123.com
username:
----
root
Events:  <none>

3)ConfigMap的使用方式

1)以volume挂载的方式使用

[[email protected] ~]# vim configmap-pod01.yaml
apiVersion: v1
kind: Pod
metadata:
  name: configmap-pod01
spec:
  containers:
  - name: configmap-pod01
    image: busybox
    args:
      - /bin/sh
      - -c
      - sleep 3000000
    volumeMounts:
    - name: configmap-test
      mountPath: "/etc/configmap-test"
      readOnly: true
  volumes:
  - name: configmap-test
    configMap:
      name: configmap01
[[email protected] ~]# kubectl apply -f configmap-pod01.yaml
[[email protected] ~]# kubectl exec -it configmap-pod01 /bin/sh
/ # cat -n /etc/configmap-test/username /etc/configmap-test/password
     1  root
     2  123.com

ConfigMap资源采用volume挂载的方式,与Secret资源采用volume挂载的方式几乎是一样的,会随着源数据的变化而变化!

2)用环境变量的方式运行

[[email protected] ~]# vim configmap-pod02.yaml
apiVersion: v1
kind: Pod
metadata:
  name: configmap-pod02
spec:
  containers:
  - name: configmap-pod02
    image: busybox
    args:
      - /bin/sh
      - -c
      - sleep 3000000
    env:
      - name: CONFIGMAP_USERNAME
        valueFrom:
          configMapKeyRef:
            name: configmap04
            key: username                   #调用的是configmap04中username的值
      - name: CONFIGMAP_PASSWORD
        valueFrom:
          configMapKeyRef:
            name: configmap04
            key: password
[[email protected] ~]# kubectl apply -f configmap-pod02.yaml
[[email protected] ~]# kubectl exec -it configmap-pod02 /bin/sh
/ # echo ${CONFIGMAP_USERNAME}
root
/ # echo ${CONFIGMAP_PASSWORD}
123.com

ConfigMap资源采用环境变量的方式,与Secret资源采用变量变量的方式几乎是一样的,不会随着源数据的变化!

三、Secret与ConfigMap的异同点

1)相同点

都是用来保存轻量级信息的,可以供其他资源对象(Deployment、RC、RS和POd)进行挂载使用。
这两种资源对象的创建方法(4种)及引用方法(2种)都是一样的,都是以键值对的方式进行存储的。

2)不同点

Secret是用来保存敏感信息的,而configMap是用来保存一些不太重要的数据的,具体表现在当我们执行“kubectl describe ....”命令时,Secret这种类型的资源对象时查看不到其具体的信息的,而configMap是可以查看到其保存的具体内容的。

3)注意事项

1)Secret、ConfigMap必须在Pod之前创建;
2)只有与当前Secret、ConfigMap在同一个namespace内的pod才能使用这个Secret、ConfigMap,换句话说,Secret、ConfigMap不能跨命名空间调用。

——————————本文到此结束,感谢阅读————————————

原文地址:https://blog.51cto.com/14157628/2471181

时间: 2024-10-08 10:46:48

Kubernetes数据持久化之Secret与ConfigMap的相关文章

k8s数据持久化之Secret

一.Secret资源对象:解决了密码.token.密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者Pod Spec中.Secret可以以Volume或者环境变量的方式使用.用来保存一些敏感信息,比如数据库的用户名密码或者密钥.Secret有三种类型:1.Service Account:用来访问Kubernetes API,由Kubernetes自动创建,并且会自动挂载到Pod的/run/secrets/kubernetes.io/serviceaccount目录中.2.Opaque

Kubernetes数据持久化方案

在开始介绍k8s持久化存储前,我们有必要了解一下k8s的emptydir和hostpath.configmap以及secret的机制和用途. 1.EmptydirEmptyDir是一个空目录,他的生命周期和所属的 Pod 是完全一致的,EmptyDir主要作用可以在同一 Pod 内的不同容器之间共享工作过程中产生的文件.如果Pod配置了emptyDir类型Volume, Pod 被分配到Node上时候,会创建emptyDir,只要Pod运行在Node上,emptyDir都会存在(容器挂掉不会导致

Kubernetes数据持久化之Storage Class(存储类)自动创PV

通过博文Kubernetes的存储之Volume可以了解到Kubernets实现数据持久化的流程为:搭建NFS底层存储-->创建PV-->创建PVC-->创建pod最终将pod中的container实现数据的持久化! 从上述流程中,看似没有什么问题,但是仔细研究就会发现:PVC在向PV申请存储空间时,是根据指定PV的名称.访问模式.容量大小来决定具体向哪个PV申请空间的. 打比方说:如果PV的容量是20G,定义的访问模式是WRO(只允许以读写的方式挂载到单个节点),而PVC申请的存储空间

Kubernetes数据持久化之Storage Class(存储类)及自动创建PV

通过博文Kubernetes的存储之Volume可以了解到Kubernets实现数据持久化的流程为:搭建NFS底层存储-->创建PV-->创建PVC-->创建pod最终将pod中的container实现数据的持久化! 从上述流程中,看似没有什么问题,但是仔细研究就会发现:PVC在向PV申请存储空间时,是根据指定PV的名称.访问模式.容量大小来决定具体向哪个PV申请空间的. 打比方说:如果PV的容量是20G,定义的访问模式是WRO(只允许以读写的方式挂载到单个节点),而PVC申请的存储空间

Kubernetes进阶之secret及configmap配置管理

Kubernetes进阶之secret及configmap配置管理 目录: 一 从外部访问应用最佳方式 二 配置管理 三 数据卷与数据持久卷 四 再谈有状态应用部署 五 K8S 安全机制 二.配置管理Pod使用secret两种方式: ? 变量注入 (就是我们在写yaml的时候直接让它以变量的方式注入进去,注入pod中,去引用这个变量,去做相关的处理)? 挂载(直接从volume的形式挂载到我们指定的目录下)Configmap与Secret类似,区别在于ConfigMap保存的是不需要加密配置信息

kubernetes的应用数据持久化

1.无状态应用与有状态应用 应用的有状态和无状态是根据应用是否有持久化保存数据的需求而言的,即持久化保存数据的应用为有状态的应用,反之则为无状态的应用.常见的系统往往是有状态的应用,比如对于微博和微信这类应用,所有用户发布的内容和留言都是要保存记录的.但是一个系统往往是由众多微服务或更小的应用模块构成的.有的微服务或模块其实并没有数据持久化的需求.例如,搭建一个Wordpress博客系统需要部署一个前端的PHP应用,以及一个后端的MySQL数据库.虽然整个博客系统有持久化的需求,是一个有状态的系

2个Kubernetes使用同一个Ceph存储达到Kubernetes间持久化数据迁移

2个Kubernetes使用同一个Ceph存储达到Kubernetes间持久化数据迁移 [TOC] 当前最新Kubernetes稳定版为1.14.现在为止,还没有不同Kubernetes间持久化存储迁移的方案.但根据Kubernetes pv/pvc绑定流程和原理,只要 "存储"-->"PV"-->"PVC" 的绑定关系相同,即可保证不同间Kubernetes可挂载相同的存储,并且里面是相同数据. 1. 环境 原来我的Kubernet

数据持久化、单例、重载【添加对不可访问的成员的操作】、魔术方法、类常量、static关键字对self的补充【静态延迟绑定实现$this的效果】、参数类型约束【参数前加类名】、遍历【iterator接口】、快速排序

1.数据持久化过程[传输(例如表单提交或php交互mysql)和保存过程] 使用的是字符串形式的流数据. 数据流就是为了传输[按照序列的形式进行传输] [http://baike.baidu.com/link?url=0MtUQMhFzc_EwJc09rXZV8KlfOL4jis6XNbRfmGA3rQhDcGwOp8togLVQjXBV34M] 所以将其他类型数据转化为字符串的过程也是序列化的过程 [这个概念和图片.视频的流媒体的区别?] [注意点] 另外mysql中sql语句中的某些关键词为

Kubernetes Harbor等资源--secret和ServiceAccount配置

Kubernetes Harbor等资源--secret和ServiceAccount配置 ![]来啦,老弟########## 用途 secret对象类型主要目的是保存和处理敏感信息/私密数据.将这些信息放在secret对象中比 直接放在pod或docker image中更安全,也更方便使用.在一个已经创建好的secrets对象有两种方式被pod对象使用,其一,在container中的volume对象里以file的形式被使用,其二,在pull images时被kubelet使用. ######