iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 20
0
DevOps

Docker獸 究極進化 ~~ Kubernetes獸系列 第 20

Day-20 使用ConfigMap 與 Secret

前言

還記得在Day-19 Pod, ReplicaSet and deployment(下)當中有講述到configMap與Secret嗎?

我們先召喚出deployment.yaml來喚醒大家的記憶,並告訴大家如何使用它

apiVersion: apps/v1
kind: Deployment
metadata:
  name: ironman
  labels:
    name: ironman
    app: ironman
spec:
  minReadySeconds: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
  selector:
    matchLabels:
      app: ironman
  replicas: 1
  template:
    metadata:
      labels:
        app: ironman
    spec:
      containers:
       - name: ironman
         image: ghjjhg567/ironman:latest
         imagePullPolicy: Always
         ports:
           - containerPort: 8100
         resources:
           limits:
             cpu: "1"
             memory: "2Gi"
           requests:
             cpu: 500m
             memory: 256Mi
         envFrom:
           - secretRef:
               name: ironman-config
         command: ["./docker-entrypoint.sh"]
       - name: redis
         image: redis:4.0
         imagePullPolicy: Always
         ports:
           - containerPort: 6379
       - name: nginx
         image: nginx
         imagePullPolicy: Always
         ports:
           - containerPort: 80
         volumeMounts:
           - mountPath: /etc/nginx/nginx.conf
             name: nginx-conf-volume
             subPath: nginx.conf
             readOnly: true
           - mountPath: /etc/nginx/conf.d/default.conf
             subPath: default.conf
             name: nginx-route-volume
             readOnly: true
         readinessProbe:
           httpGet:
             path: /v1/hc
             port: 80
           initialDelaySeconds: 5
           periodSeconds: 10
      volumes:
        - name: nginx-conf-volume
          configMap:
            name: nginx-config
        - name: nginx-route-volume
          configMap:
            name: nginx-route-volume

在上面yaml中的secretRef與configMap就是引用已經創建好的secret與configMap來做使用,那在本篇章我們會來解說configMap與secret,以及使用的原理與原因。

What is ConfigMap ?

ConfigMap是一個API Object,主要用來將非機密性的資料儲存至Key-Value當中,使用時可以用作環境變量、命令行參數或者Volumes中的配置文件。

也因為ConfigMap是一個API Object,所以他的命名必須要符合DNS Subdomain Names。

DNS Subdomain Names

  1. 不能超過253個字元
  2. 只能包含英文字母、數字以及符號'-'與'.'
  3. 必須以字母為開頭
  4. 必須以字母為結尾

https://ithelp.ithome.com.tw/upload/images/20201005/201297377VifAxtE7D.png

Why ConfigMap ?

使用ConfigMap好處是讓你的服務能與配置數據分離,舉例來說你有著test、uat與prod三個不同環境,只需要再這三個環境的pod中匯入不同的configMap即可完成配置。這也讓我們能更簡潔地進行容器化開發與測試。

How to create ConfigMap ?

我們這邊以repository的prd.env為例子

REDIS_HOST=redis
REDIS_PORT=6379

Base on —from-literal

  • 我們先用kubectl來create configmap
$ kubectl create configmap configmap-prd --from-literal=REDIS_HOST=redis --from-literal=REDIS_PORT=6379
configmap "configmap-prd" created
  • 再來,看一下configmap吧
$ kubectl describe configmap configmap-prd
Name:         configmap-prd
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
REDIS_HOST:
----
redis
REDIS_PORT:
----
6379
Events:  <none>

Base on —from-file

  • 一樣,我們先來create configmap
$ kubectl create configmap configmap-prdd --from-file=../prd.env
configmap/configmap-prdd created
  • 再來,看一下configmap吧
$ kubectl describe configmap configmap-prdd
Name:         configmap-prdd
Namespace:    default
Labels:       <none>
Annotations:  <none>

Data
====
prd.env:
----
REDIS_HOST=redis
REDIS_PORT=6379

Events:  <none>

兩者的差距就僅是在Data儲存的方式,一個是依照data的key-value儲存,另一種是更上層有個key為file名稱,下面的key-value才是儲存file內的資料。

How to use configMap?

Import as environment variable

在pod內container中的envFrom.configMapRef填入已經創建好的configMap。

  template:
    metadata:
      labels:
        app: ironman
    spec:
      containers:
       - name: ironman
         image: ghjjhg567/ironman:latest
         imagePullPolicy: Always
         ports:
           - containerPort: 8100
         resources:
           limits:
             cpu: "1"
             memory: "2Gi"
           requests:
             cpu: 500m
             memory: 256Mi
         envFrom:
           - configMapRef:
               name: configmap-prd

Import as volume

這邊的話需要再volumes定義你在這pod中的volume並binding你的configMap,之後即可在pod中使用volumeMounts來將data mount進指定的container。

 template:
    metadata:
      labels:
        app: ironman
    spec:
      containers:
			 - name: nginx
         image: nginx
         imagePullPolicy: Always
         ports:
           - containerPort: 80
         volumeMounts:
           - mountPath: /etc/nginx/nginx.conf
             name: nginx-conf-volume
             subPath: nginx.conf
             readOnly: true
           - mountPath: /etc/nginx/conf.d/default.conf
             subPath: default.conf
             name: nginx-route-volume
             readOnly: true
         readinessProbe:
           httpGet:
             path: /v1/hc
             port: 80
           initialDelaySeconds: 5
           periodSeconds: 10
      volumes:
        - name: nginx-conf-volume
          configMap:
            name: nginx-config
        - name: nginx-route-volume
          configMap:
            name: nginx-route-volume

What is Secret and why?

Secret也是個API Object,主要用來儲存機密資料,像是帳號密碼、OAuth、SSH Certification與Token..等敏感資訊。

因為Secret是一個API Object,所以他的命名必須要符合DNS Subdomain Names。

DNS Subdomain Names

  1. 不能超過253個字元
  2. 只能包含英文字母、數字以及符號'-'與'.'
  3. 必須以字母為開頭
  4. 必須以字母為結尾

How to create Secret ?

這邊我們一樣以prd.env為例子,先假使你它們是敏感資訊

REDIS_HOST=redis
REDIS_PORT=6379

Base on yaml

  • 因為是敏感資訊,所以需要以secret轉換成base64的形式儲存
$ echo -n 'redis' | base64
cmVkaXM=
$ echo -n 6379 | base64
NjM3OQ==
  • 那接下來我們以上面的base64資訊儲存成secret

ironman-configyaml

apiVersion: v1
kind: Secret
metadata:
  name: ironman-config
type: Opaq
data:
  REDIS_HOST: MTI3LjAuMC4x
  REDIS_PORT: NjM3OQ==
  • 再來,我們create secret並且看一下它的資訊吧!
$ kubectl apply -f ironman-config.yaml
secret/ironman-config created
$ kubectl describe secret ironman-config
Name:         ironman-config
Namespace:    default
Labels:       <none>
Annotations:
Type:         Opaque

Data
====
REDIS_HOST:  5 bytes
REDIS_PORT:  4 bytes

這邊可以發現Secret的資訊並不會暴露在外頭,因為它是敏感資訊。

Base on file

  • 我們同樣能夠以file來create secret
$ kubectl create secret generic ironman-configg --from-file=../prd.env
secret/ironman-configg created
$ kubectl describe secret ironman-configg
Name:         ironman-configg
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
prd.env:  33 bytes

他這邊是把整個file給存成secret

How to use Secret?

這邊與configMap相似,只不過是關鍵字換成secret

Import as environment variable

在pod內container中的envFrom.configMapRef填入已經創建好的secret。

template:
    metadata:
      labels:
        app: ironman
    spec:
      containers:
       - name: ironman
         image: ghjjhg567/ironman:latest
         imagePullPolicy: Always
         ports:
           - containerPort: 8100
         resources:
           limits:
             cpu: "1"
             memory: "2Gi"
           requests:
             cpu: 500m
             memory: 256Mi
         envFrom:
           - secretRef:
               name: ironman-config

Import as volume

      volumes:
        - name: ironman-config
          secret:
            secretName: ironman-config

後記

這章節我們大致介紹了兩種不同形式的資料儲存格式,並且也演繹了如何create與implement ConfigMap與Secret。在下個章節我們將正式進入Service的世界,敬請期待。

https://ithelp.ithome.com.tw/upload/images/20201005/201297379aJs7umQAY.png

https://ithelp.ithome.com.tw/upload/images/20201006/201297370NhoRZphCs.png


上一篇
Day-19 學習Pod, ReplicaSet 與 Deployment (下)
下一篇
Day-21 尋覓 Service、kube-dns 與 kube-proxy
系列文
Docker獸 究極進化 ~~ Kubernetes獸30

尚未有邦友留言

立即登入留言