Kubernetes ConfigMap vs Secret

Stella981
• 阅读 663

场景对比

  • Secret:当你想要存储一些敏感数据时使用Secret,例如(passwords, OAuth tokens, ssh keys, credentials等)
  • ConfigMap : 当需要存储一些非敏感配置数据时可以使用ConfigMap,例如应用程序的ini,json等配置文件。

ConfigMap:

创建ConfigMap

kind: ConfigMap
apiVersion: v1
metadata:
  name: example-config
  namespace: default
data:
  example.property.1: hello        #key-value形式,key规则必须满足dns域名规则。value为字符串。
  example.property.2: world
  example.property.file: |-        #配置文件使用方式,直接把文件内容放入value即可
    property.1=value-1
    property.2=value-2
    property.3=value-3

使用方式:

1.填充环境变量

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: gcr.io/google_containers/busybox
      command: [ "/bin/sh", "-c", "env" ]
      env:
        - name: SPECIAL_LEVEL_KEY
          valueFrom:
            configMapKeyRef:
              name: example-config     #需要使用的ConfigMap名称,必须已经存在
              key: example.property.1  #对应ConfigMap data 的key
  restartPolicy: Never

设置结果

SPECIAL_LEVEL_KEY=hello

2.设置容器启动命令行参数

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: gcr.io/google_containers/busybox
      command: [ "/bin/sh", "-c", "echo $(SPECIAL_LEVEL_KEY) $(SPECIAL_TYPE_KEY)" ]
      env:
        - name: SPECIAL_LEVEL_KEY
          valueFrom:
            configMapKeyRef:
              name: example-config
              key: example.property.1
        - name: SPECIAL_TYPE_KEY
          valueFrom:
            configMapKeyRef:
              name: example-config
              key: example.property.2
  restartPolicy: Never

运行结果:

hello world

3.挂载ConfigMap到文件

apiVersion: v1
kind: Pod
metadata:
  name: dapi-test-pod
spec:
  containers:
    - name: test-container
      image: gcr.io/google_containers/busybox
      command: [ "/bin/sh","-c","ls -l /etc/config/path/" ]
      volumeMounts:
      - name: config-volume
        mountPath: /etc/config
  volumes:
    - name: config-volume
      configMap:
        name: example-config
        items:
        - key: example.property.1
          path: path/one/example.property.1
        - key: example.property.2
          path: path/two/example.property.2
        - key: example.property.file
          path: path/file/example.property.file
  restartPolicy: Never

创建的文件如下:

└── path
    ├── file
    │   └── example.property.file
    ├── one
    │   └── example.property.1
    └── two
        └── example.property.2
        
#cat example.property.1          hello
#cat example.property.2          world
#cat example.property.file  
    property.1=value-1
    property.2=value-2
    property.3=value-3    

注意:

  • ConfigMap必须在使用之前被创建,如果引用了一个不存在的configMap,将会导致Pod无法启动
  • ConfigMap只能被相同namespace内的应用使用。
3.1挂载ConfigMap到单个文件:

假设我的项目结构如下(项目路径为/usr/local):

.
├── Dockerfile
├── Makefile
├── app.conf
├── controllers
│   └── pod.go
└── main.go

我只想把app.conf文件从ConfigMap挂载进来,其他文件保持不变,现在应该怎么做呢? 好,我们开始。

假设我的ConfigMap如下:

apiVersion: v1
kind: ConfigMap
metadata:
  name: test-cfgmap
data:
  app.conf: file data
  • 第一种方式:

可以使用下面的定义文件使用ConfigMap:

apiVersion: v1
kind: Pod
metadata:
  name: test-pd-plus-cfgmap
spec:
  containers:
  - image: ubuntu
    name: bash
    volumeMounts:
    - mountPath: /usr/local/app.conf
      name: cfgmap
      subPath: app.conf
  volumes:
  - name: cfgmap
    configMap:
      name: test-cfgmap

注意,这种方式使用ConfigMap, ConfigMap的key、 volumeMounts.mountPath和volumeMounts.subPath名称一定要保持一致,否则会挂载不成功。

  • 第二种方式:

    apiVersion: v1 kind: Pod metadata: name: test-pd-plus-cfgmap spec: containers:

    • image: ubuntu name: bash volumeMounts:
      • mountPath: /usr/local/app.conf name: cfgmap subPath: app.conf volumes:
    • name: cfgmap configMap: name: test-cfgmap items:
      • key: app.conf path: app.conf

注意,这种方式使用ConfigMap,就不再要求 ConfigMap的key跟挂载的文件名必须一致,但需要在items指定key和path对应关系。

  • 其它方式:

当然,如果你愿意,你也可以挂载ConfigMap到一个其它路径,然后通过软连接的方式链接到你需要的文件。

实际使用例子(Redis配置):

例如当我们需要按照如下配置来启动Redis

maxmemory 2mb
maxmemory-policy allkeys-lru

首先,让我们来创建一个ConfigMap:

apiVersion: v1
data:
  redis-config: |
    maxmemory 2mb
    maxmemory-policy allkeys-lru
kind: ConfigMap
metadata:
  name: example-redis-config
  namespace: default

下面我们来创建一个Pod来使用它:

apiVersion: v1
kind: Pod
metadata:
  name: redis
spec:
  containers:
  - name: redis
    image: kubernetes/redis:v1
    env:
    - name: MASTER
      value: "true"
    ports:
    - containerPort: 6379
    volumeMounts:
    - mountPath: /redis-master
      name: config
  volumes:
    - name: config
      configMap:
        name: example-redis-config
        items:
        - key: redis-config
          path: redis.conf     #指定生成的配置文件名称

当我们创建完Pod后,进入它: 生成的配置文件如下:

redis-master
`-- redis.conf -> ..data/redis.conf

我们发现在redis-master 目录下生成了一个文件redis.conf ,对应我们上面path定义的文件名。输出一下redis.conf内容:

maxmemory 2mb
maxmemory-policy allkeys-lru

下面我们看一下redis的配置:

$ kubectl exec -it redis redis-cli
127.0.0.1:6379> CONFIG GET maxmemory
1) "maxmemory"
2) "2097152"
127.0.0.1:6379> CONFIG GET maxmemory-policy
1) "maxmemory-policy"
2) "allkeys-lru"

符合我们的预期。

注意: 虽然使用configMap可以很方便的把我们配置文件放入到容器中,但一定注意配置文件的大小,(尽量控制在1M以内)更不能滥用ConfigMap,否则可能会给apiserver和etcd造成较大压力,影响整个集群。

Secret:

当需要使用一些敏感的配置,比如密码,证书等信息时,建议使用Secret。

创建Secret

apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  username: YWRtaW4=     
  password: MWYyZDFlMmU2N2Rm

注意: Secret 的value必须经过base64, 以上明文为: username: admin password: 1f2d1e2e67df ,可以直接使用 echo -n "1f2d1e2e67df" | base64 进行base64,或者到这里可以进行base64加密解密

使用方式:

1.挂载到文件

apiVersion: v1
kind: Pod
metadata:
  name: mypod
  namespace: default
spec:
  containers:
  - image: redis
    name: mypod
    volumeMounts:
    - mountPath: /etc/foo
      name: foo
      readOnly: true
  volumes:
  - name: foo
    secret:
      defaultMode: 420      #0644默认文件权限,由于json文件不支持八进制,使用json时应使用十进制
      secretName: mysecret

运行结果:在/etc/foo/目录下生成两个文件username和password

foo/
|-- password -> ..data/password
`-- username -> ..data/username
#cat username       admin
#cat password      1f2d1e2e67df

注意: 自动更新: 当Secrets被更新时,已经挂载的pod不会立即更新,而要等待kubelete检查周期,kubelet会定期检查secret变化并更新它。

2.通过环境变量使用

apiVersion: v1
kind: Pod
metadata:
  name: secret-env-pod
spec:
  containers:
    - name: mycontainer
      image: redis
      env:
        - name: SECRET_USERNAME
          valueFrom:
            secretKeyRef:
              name: mysecret   #指定secret名称
              key: username    #要使用的key
        - name: SECRET_PASSWORD
          valueFrom:
            secretKeyRef:
              name: mysecret
              key: password


$ echo $SECRET_USERNAME
admin
$ echo $SECRET_PASSWORD
1f2d1e2e67df

3.拉取镜像

apiVersion: v1
kind: Secret
metadata:
  name: image-test-secret
  namespace: default
type: kubernetes.io/dockerconfigjson
data:
  .dockerconfigjson: ew0KCSJhdXRocyI6IHsNCgkJImltYWdlLXRlc3QiOiB7DQoJCQkiYXV0aCI6ICJjbTl2ZERweWIyOTAiLA0KCQkJImVtYWlsIjogIiINCgkJfQ0KCX0NCn0=

加密部分的明文为:

{
    "auths": {
        "image-test": {
            "auth": "cm9vdDpyb290",   #  密文为"root:rootbase64"的结果
            "email": ""
        }
    }
}

部署文件使用如下:

apiVersion: v1
kind: Pod
metadata:
  name: foo
  namespace: default
spec:
  containers:
    - name: foo
      image: janedoe/awesomeapp:v1
  imagePullSecrets:
    - name: image-test-secret

实际使用例子(挂载证书文件):

kind: Secret
apiVersion: v1
metadata:
  name: client-certs
  namespace: default
data:
  ca.pem: *** #实际使用请替换成经过base64加密后的内容
  kubernetes.pem: ***
  kubernetes-key.pem: ***

使用deployment部署:

apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: redis
spec:
  replicas: 1
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
      - name: redis
        image: redis
        ports:
          - containerPort: 8080
        volumeMounts:
        - mountPath: /etc/kubernetes/certs
          name: my-certs
      volumes:
        - name: my-certs
          secret:
            secretName: client-certs
            items:
            - key: ca.pem
              path: ca.pem
            - key: kubernetes.pem
              path: kubernetes.pem
            - key: kubernetes-key.pem
              path: kubernetes-key.pem
      imagePullSecrets:
        - name: image-test-secret
点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这