Kubernetes ConfigMap vs Secret

場景對比

  • 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

設置結果redis

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

運行結果:docker

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

建立的文件以下:json

└── 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

注意:ubuntu

  • ConfigMap必須在使用以前被建立,若是引用了一個不存在的configMap,將會致使Pod沒法啓動
  • ConfigMap只能被相同namespace內的應用使用。
3.1掛載ConfigMap到單個文件:

假設個人項目結構以下(項目路徑爲/usr/local):api

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

我只想把app.conf文件從ConfigMap掛載進來,其餘文件保持不變,如今應該怎麼作呢? 好,咱們開始。bash

假設個人ConfigMap以下:app

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

可使用下面的定義文件使用ConfigMap:ssh

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名稱必定要保持一致,不然會掛載不成功。google

  • 第二種方式:
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
相關文章
相關標籤/搜索