ConfigMap、Secret

ConfigMap、Secret

为什么有这两个东西:

我们在kubernetes上部署应用的时候,经常会需要传一些配置给我们的应用,比如数据库地址啊,用户名密码啊之类的。我们要做到这个,有好多种方案,比如:

  • 我们可以直接在打包镜像的时候写在应用配置文件里面,但是这种方式的坏处显而易见而且非常明显。
  • 我们可以在配置文件里面通过env环境变量传入,但是这样的话我们要修改env就必须去修改yaml文件,而且需要重启所有的container才行。
  • 我们可以在应用启动的时候去数据库或者某个特定的地方拿,没问题!但是第一,实现起来麻烦;第二,如果配置的地方变了怎么办?

当然还有别的方案,但是各种方案都有各自的问题。

而且,还有一个问题就是,如果说我的一个配置,是要多个应用一起使用的,以上除了第三种方案,都没办法进行配置的共享,就是说我如果要改配置的话,那得一个一个手动改。假如我们有100个应用,就得改100份配置,以此类推……

kubernetes对这个问题提供了一个很好的解决方案,就是用ConfigMapSecret

应用场景:

镜像往往是一个应用的基础,还有很多需要自定义的参数或配置,例如资源的消耗、日志的位置级别等等,这些配置可能会有很多,因此不能放入镜像中,Kubernetes中提供了Configmap来实现向容器中提供配置文件或环境变量来实现不同配置,从而实现了镜像配置与镜像本身解耦,使容器应用做到不依赖于环境配置

Secret资源对象:

可以保存轻量的敏感信息,比如数据库的用户名和密码或者认证秘钥等。它保存的数据是以秘文的方式存放的

configMap资源对象:

和Secret一样,拥有大多数共同的特性,但是区别是,configMap保存的是一些不太重要的信息,它保存的数据是以明文的方式存放的。

当我们创建上述两种资源对象时,其实就是将这两种资源对象存储的信息写入了k8s群集中的etcd数据中心

Secret与ConfigMap的异同:

相同之处:

都是用来保存轻量级信息的,可以供其他资源对象(Deployment、RC、RS和Pod)进行挂载使用

这两种资源对象的创建方法(4种)及引用方法(2种)都是一样的,都是以键值对的方式进行存储的

不同之处:

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

Secret:

Secret:用于保存一些敏感信息,比如数据库的用户名密码或者密钥。这些数据是比较少量的,将这些信息放在 secret中比放在 pod 的定义或者 docker 镜像中来说更加安全和灵活

用户可以创建自己的secret,系统也会有自己的secret

内置 secret

[root@master ~]# kubectl  get secrets  -n  kube-system

Secret有三种类型:

Opaque:base64编码格式的Secret,用来存储密码、密钥等;但数据也通过base64 –decode解码得到原始数据,所有加密性很弱

kubernetes.io/dockerconfigjson:用来存储私有docker registry的认证信息

kubernetes.io/service-account-token: 用于被serviceaccount引用,serviceaccout创建时Kubernetes会默认创建对应的secret。Pod如果使用了serviceaccount,对应的secret会自动挂载到Pod目录/run/secrets/ kubernetes.io/serviceaccount中

举例:保存数据库的用户名和密码

用户名:root

密码:123.com

有四种方法:

1、通过- -from-literal(文字的):

也就是说需要保存什么,直接写出来就行

注意:每一个–from-literal只能保存一条信息

[root@master ~]# kubectl  create  secret generic  mysecret1  --from-literal=username=root  --from-literal=password=123.com

generic:通用的、一般的加密方式

[root@master ~]# kubectl  get secrets 
NAME                  TYPE                                  DATA   AGE
default-token-x9ptl   kubernetes.io/service-account-token   3      42d
mysecret1             Opaque(不透明的)                      2      2m13s

Opaque(不透明的):也就是说你看不到

[root@master ~]# kubectl  describe  secrets
Type:  Opaque

Data
====
password:  7 bytes
username:  4 bytes
//这里看不到真正的值是什么

2、- -from-file(文件):

同样,每一个只能保存一条信息

[root@master ~]# echo  root  >  username
[root@master ~]# echo  123.com  >  password
[root@master ~]# kubectl create secret generic mysecret2  --from-file=username  --from-file=password 
[root@master ~]# kubectl  get  secrets 
NAME                  TYPE                                  DATA   AGE
default-token-x9ptl   kubernetes.io/service-account-token   3      42d
mysecret1             Opaque                                2      28m
mysecret2             Opaque                                2      28s

既然是通过文件创建的,那么把文件删除,这个secret是否还在

[root@master ~]# rm  -rf  username  password 
[root@master ~]# kubectl  get  secrets 
NAME                  TYPE                                  DATA   AGE
default-token-x9ptl   kubernetes.io/service-account-token   3      42d
mysecret1             Opaque                                2      29m
mysecret2             Opaque                                2      92s
//它确实还会存在

3、通过- -from-env-file:

这种方法可以把用户名和密码写在一个文件里面,这样就比前两种方便

[root@master ~]# vim  env.txt
username=root
password=123.com
[root@master ~]# kubectl  create  secret generic mysecret3  --from-env-file=env.txt
[root@master ~]# kubectl  get secrets 
NAME                  TYPE                                  DATA   AGE
default-token-x9ptl   kubernetes.io/service-account-token   3      42d
mysecret1             Opaque                                2      34m
mysecret2             Opaque                                2      6m27s
mysecret3             Opaque                                2      16s
[root@master ~]# kubectl  describe secrets
Data
====
password:  7 bytes
username:  4 bytes

4、通过yaml配置文件

先看一下yaml怎么写

[root@master ~]# kubectl  get secrets  mysecret1  -o  yaml
apiVersion: v1
data:
  password: MTIzLmNvbQ==
  username: cm9vdA==
kind: Secret
metadata:
  creationTimestamp: "2020-02-14T02:01:34Z"
  name: mysecret1
  namespace: default
  resourceVersion: "13766"
  selfLink: /api/v1/namespaces/default/secrets/mysecret1
  uid: ffce8c7a-2dfc-4958-9e3b-0fcb50d00cca
type: Opaque

可以看到数据是被加密后写入yaml文件里的,所以我们写的时候不能直接写数据,而是要加密一下

把保存的数据加密:

通过base64方式:

[root@master ~]# echo  root  |  base64
cm9vdAo=
[root@master ~]# echo  123.com  |  base64
MTIzLmNvbQo=

创建secret资源对象:

[root@master ~]# vim  secret4.yaml
apiVersion: v1
kind: Secret
metadata:
  name: mysecret4
data:
  username: cm9vdAo=
  password: MTIzLmNvbQo=
[root@master ~]# kubectl  apply  -f  secret4.yaml
[root@master ~]# kubectl get secrets 
NAME                  TYPE                                  DATA   AGE
default-token-x9ptl   kubernetes.io/service-account-token   3      42d
mysecret1             Opaque                                2      42m
mysecret2             Opaque                                2      14m
mysecret3             Opaque                                2      8m
mysecret4             Opaque                                2      18s

这种方法虽然说我们看不到真正的数据是什么,但是这种方式也是不安全的,每一次编码后的数据是一样的,是由规律的,同样它是可以被解码的

解码:

[root@master ~]# echo  -n  cm9vdAo  |  base64  --decode
root

如何来使用Secret资源:

Secret 可以作为数据卷被挂载,或作为环境变量 暴露出来以供 pod 中的容器使用。它们也可以被系统的其他部分使用,而不直接暴露在 pod 内

两种方法:

1、以Volume挂载的方式

//创建Pod来引用secret
[root@master ~]# vim  pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers: 
  - name: mypod
    image:  busybox
    args:
      - /bin/sh
      - -c
      - sleep 300000
    volumeMounts:
    - name: secret-test
      mountPath:  "/etc/secret-test"
      readOnly:  true  //是否只读,也就是说对于/etc/secret-test只有只读的权限,不能修改
  volumes:
  - name: secret-test
    secret:
      secretName: mysecret1
[root@master ~]# kubectl  apply  -f  pod.yaml
[root@master ~]# kubectl  get pod
NAME    READY   STATUS    RESTARTS   AGE
mypod   1/1     Running   0          2m4s

进入容器查看是否有我们保存的数据

[root@master ~]# kubectl  exec  -it  mypod  /bin/sh
/ # cd  /etc/secret-test
/etc/secret-test # cat username
root
/etc/secret-test # cat  password
123.com
/etc/secret-test # echo  admin  >  username
/bin/sh: can't create username: Read-only file system
//这个文件也是不能修改的,因为是只读文件

还可以自定义存放数据的文件名:

//在volumes字段下追加items字段:
  volumes:
  - name: secret-test 
    secret:
      secretName: mysecret1
      items:
      - key:  username
        path: my-group/my-username
      - key:  password
        path: my-group/my-password
[root@master ~]# kubectl  apply  -f  pod.yaml 
pod/mypod created
[root@master ~]# kubectl  exec  -it  mypod  /bin/sh
/ # cd  /etc/secret-test/
/etc/secret-test # ls
my-group
/etc/secret-test # cd  my-group/
/etc/secret-test/..2020_02_17_01_40_09.035305611/my-group # ls
my-username     my-password
/etc/secret-test/..2020_02_17_01_40_09.035305611/my-group # cat my-username 
root
/etc/secret-test/..2020_02_17_01_40_09.035305611/my-group # cat  my-password 
123.com

2、以环境变量的方式

[root@master ~]# cp  pod.yaml   pod-env.yaml 
[root@master ~]# vim  pod-env.yaml
apiVersion: v1
kind: Pod
metadata:
  name: mypod2
spec:
  containers:
  - name: mypod2
    image: busybox
    args:
      - /bin/sh
      - -c
      - sleep 300000
    env:
      - name: SECRET_USERNAME
        valueFrom:
          secretKeyRef:  //翻译过来就是机密键引用,提取mysecret2里面的数据到SECRET_USERNAME
            name: mysecret2
            key: username
      - name: SECRET_PASSWORD
        valueFrom:
          secretKeyRef: //与上面同理
            name: mysecret2
            key: password
[root@master ~]# kubectl  apply  -f  pod-env.yaml
[root@master ~]# kubectl  get pod
NAME     READY   STATUS    RESTARTS   AGE
mypod    1/1     Running   0          18m
mypod2   1/1     Running   0          79s

同样,进入pod查看

[root@master ~]# kubectl exec  -it  mypod2  /bin/sh
/ # echo $SECRET_USERNAME
root
/ # echo  $SECRET_PASSWORD
123.com

如果现在将secret资源内保存的数据进行更新,使用此数据的应用内,数据是否也会更新

更新mysecret1的数据:把password----->123.com---->admin

[root@master ~]# echo  admin  |  base64
YWRtaW4K
[root@master ~]# kubectl get secrets zhbsecret2 -o yaml
//可以通过edit命令直接修改:
[root@master ~]# kubectl edit  secrets  zhbsecret2
data:
  username: cm9vdAo=
  password: YWRtaW4K  //更改
[root@master ~]# kubectl  exec  -it  mypod  /bin/sh
/ # cd  /etc/secret-test/my-group/
/etc/secret-test/..2020_02_17_01_57_25.223684048/my-group # cat my-password 
admin
//可以看到已经跟着改变了

注意:

这里引用数据是以volumes挂载使用数据的方式,才会实时更新

那么,以环境变量的方式引用的数据,是否会实时更新?

[root@master ~]# kubectl  edit  secrets  mysecret4
data:
  username: cm9vdAo=
  password: YWRtaW4K
[root@master ~]# kubectl  exec  -it  mypod2  /bin/sh
/ # echo  $SECRET_PASSWORD
123.com
//没有变化

总结:

如果引用secret数据的应用,要求会随着secret资源对象内保存的数据的更新而实时更新,那么应该使用volumes挂载的方式引用资源。因为用环境变量的方式引用不会实时更新数据

ConfigMap:

和Secret资源类似,不同之处在于,secret资源保存的是敏感信息,而configmap保存的方式是以明文的方式存放的数据

什么是ConfigMap:

ConfigMap对像是一系列配置的集合,k8s会将这一集合注入到对应的Pod对像中,并为容器成功启动使用。注入的方式一般有两种,一种是挂载存储卷,一种是传递变量。ConfigMap被引用之前必须存在,属于名称空间级别,不能跨名称空间使用,内容明文显示。ConfigMap内容修改后,对应的pod必须重启或者重新加载配置

创建ConfigMap的4种方式:

username:adam

age:18

和secretc创建的方式一模一样

1、通过- -from-literal(文字的):

[root@master ~]# kubectl  create  configmap  myconfigmap1  --from-literal=username=adam  --from-literal=age=18
configmap/myconfigmap1 created
[root@master ~]# kubectl get configmaps 
NAME           DATA   AGE
myconfigmap1   2      32s
[root@master ~]# kubectl describe configmaps
Data
====
age:
----
18
username:
----
adam

2、- -from-file(文件):

[root@master ~]# touch  adam  >  username
[root@master ~]# touch  18  >  age
[root@master ~]# kubectl  create  configmap  myconfigmap2  --from-file=username  --from-file=age 
configmap/myconfigmap2 created
[root@master ~]# kubectl  get configmaps 
NAME           DATA   AGE
myconfigmap1   2      4m23s
myconfigmap2   2      63s

3、通过- -from-env-file:

[root@master ~]# vim  env.txt
username=adam
age=18
[root@master ~]# kubectl  create  configmap  myconfigmap3  --from-env-file=env.txt 
configmap/myconfigmap3 created
[root@master ~]# kubectl  get configmaps 
NAME           DATA   AGE
myconfigmap1   2      16m
myconfigmap2   2      5m18s
myconfigmap3   2      8m56s

4、通过yaml配置文件

[root@master ~]# vim  configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: myconfigmap4
data:
  username: adam
  age:  "18"
[root@master ~]# kubectl  apply  -f  configmap.yaml 
configmap/myconfigmap4 created
[root@master ~]# kubectl  get configmaps 
NAME           DATA   AGE
myconfigmap1   2      16m
myconfigmap2   2      5m18s
myconfigmap3   2      8m56s
myconfigmap4   2      4m8s
使用configmap:

和secret一样,有两种方法

第一种方法是:

以volumes挂载的方式引用资源

[root@master ~]# vim  v-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod1
spec:
  containers:
  - name: pod1
    image:  busybox
    args:
      - bin/sh
      - -c
      - sleep 300000
    volumeMounts:
    - name: cmp-test
      mountPath:  "/etc/cmp-test"
      readOnly: true
  volumes:
  - name: cmp-test
    configMap:
      name: myconfigmap1
[root@master ~]# kubectl  apply  -f  v-pod.yaml 
pod/pod1 created

第二种方式:

以环境变量的方式引用资源

[root@master ~]# vim  e-pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod2
spec:
  containers:
  - name: pod2
    image:  busybox
    args:
      - bin/sh
      - -c
      - sleep 300000
    env:
      - name: CONFIGMAP_NAME
        valueFrom:
          configMapKeyRef:
            name: myconfigmap2
            key:  username
      - name: CONFIGMAP_AGE
        valueFrom:
          configMapKeyRef:
            name: myconfigmap2
            key:  age
[root@master ~]# kubectl  apply  -f  e-pod.yaml 
pod/pod2 created
[root@master ~]# kubectl   get  pod
NAME      READY   STATUS    RESTARTS   AGE
pod1      1/1     Running   0          5m34s
pod2      1/1     Running   0          48s

如果现在将confgimap资源内保存的数据进行更新,使用此数据的应用内,数据是否也会更新

[root@master ~]# kubectl  edit  configmaps  myconfigmap1
data:
  age: "18"
  username: root
[root@master ~]# kubectl  exec  -it  pod1  /bin/sh
/ # cd  /etc/cmp-test/
/etc/cmp-test # cat username 
root
//这里会跟着更新,如果操作过快,它会反应不过来,你就话看不到改变,稍微等一下就行了

那么,以环境变量的方式引用的数据,是否会实时更新?

[root@master ~]# kubectl  exec  -it  pod2  /bin/sh
/ # echo  $CONFIGMAP_AGE
18
/ # echo  $CONFIGMAP_NAME
adam
/ # exit
[root@master ~]# kubectl  edit  configmaps  myconfigmap2
data:
  age: |
    18
  username: |
    root
[root@master ~]# kubectl  describe  configmaps  myconfigmap2
Data
====
age:
----
18

username:
----
root
[root@master ~]# kubectl  exec  -it  pod2  /bin/sh
/ # echo  $CONFIGMAP_NAME
adam
//和secret一样,是不会更新的

小结

Secret:

用于存放一些敏感信息,比如数据库的用户名密码、密钥等,以密文的方式保存

创建Secret资源对象的四种方式:

  • –from-literal(文字的):需要保存什么内容直接写出来,一次只能保存一条
  • –from-file(文件):把需要保存的内容写到文件里面,通过–from-file指定这个文件。一次只能保存一条
  • –from-env-file(环境变量):把想要保存的内容都写入一个文件里面,通过–from-env-file指定
  • 通过yaml配置文件:在data字段写入要保存的内容,注意是以密文的格式写入(使用base64的方式加密就行)

引用Secret资源的两种方法:

  • Volumes挂载的方式:
  • 环境变量的方式:
ConfigMap:

和Secret一样,拥有大多数共同的特性,但是区别是,configMap保存的是一些不太重要的信息,它保存的数据是以明文的方式存放的,使用describe来查看是,能看到真正的信息

创建ConfigMap资源对象的四种方式和引用ConfigMap的两种方式一摸一样

–from-literal(文字的)

–from-file(文件)

–from-env-file(环境变量)

通过yaml配置文件

Volumes挂载的方式:

环境变量的方式:


如果引用secret、CongigMap数据的应用,要求会随着secret、ConfigMap资源对象内保存的数据的更新而实时更新,那么应该使用volumes挂载的方式引用资源。因为用环境变量的方式引用不会实时更新数据

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值