kubernetes ConfigMap和Secret:配置應用程序

7.1.配置容器化應用程序

7.2.向容器傳遞命令行參數

7.2.1.待Docker中定義命令與參數

1.瞭解ENTRYPOINT與CMDlinux

  ENTRYPOINT定義容器啓動時被調用的能夠執行程序nginx

  CMD指定傳遞給ENTRYP的參數web

dockerfile 內容以下redis

FROM daocloud.io/centos:latest

ADD aaa /usr/local/aaa

CMD ["-f","/var/log/aa.log"]
ENTRYPOINT ["tail"]

當啓動鏡像時,容器啓動時執行以下命令:tail -f /var/log/aa.logdocker

或者在docker run <images> <arguments> 中指定,arguments會覆蓋CMD中內容centos

7.2.2.在kubernetes中覆蓋命令行和參數

 在k8s中定義容器時,鏡像的ENTRYPOINT和CMD均可以被覆蓋,僅需在容器定義中設置熟悉command和args的值api

對應參數以下:緩存

Docker kubernetes 描述
ENTRYPOINT command 容器中運行的可執行文件
CMD args 傳給可執行文件的參數

 

 

 

 

相關yml代碼以下:ui

kind: pod
spec:
  containers:
  - image: some/image
    command: ["/bin/command"]
    args: ["args1","args2","args3"]

  

7.3.爲容器設置環境變量

7.3.1.在容器定義中指定環境變量

與容器的命令和參數設置相同,環境變量列表沒法在pod建立後被修改。編碼

在pod的yml文件中設置容器環境變量代碼以下:

kind: pod
spec:
  containers:
  - image: luksa/fortune:env
    env:
    - name: INTERVAL
      value: "30"
    name: value-test-yh

  

7.3.2.在環境變量值中引用其餘環境變量

使用$( VAR )引用環境變量,

相關ym代碼以下:

env:
- name: FIRST_VAR
  value: "foo"
- name: SECOND_VAR
  value: "$(FIRST_VAR)bar"   //最終變量值爲foobar

 

7.4.利用ConfigMap解耦配置

7.4.1.ConfigMap介紹

kubernetes容許將配置選項分離到獨立的資源對象ConfigMap中,本質上就是一個鍵/值對映射,值能夠是短字面變量,也能夠是完整的配置文件。

應用無須直接讀取ConfigMap,甚至根本不須要知道其是否存在。

映射的內容經過環境變量或者卷文件的形式傳遞給容器,而並不是直接傳遞給容器,命令行參數的定義中也是經過$(ENV_VAR)語法變量

7.4.2.建立ConfigMap

使用kubectl creat configmap建立ConfigMap中間不用加-f。

1.使用指令建立ConfigMap

#kubectl creat configmap configmap-yaohong --from-literal=foo=bar --from-literal=sleep-interval=25

2.從文件內容建立ConfigMap條目

#kubectl create configmap my-conf-yh --from-file=config-file.conf

使用以下命令,會將文件內容存儲在自定義的條目下。與字面量使用相同

#kubectl create configmap my-conf-yh --from-file=customkey=config-file.conf 

3.從文件夾建立ConfigMap

#kubectl create configmap my-conf-yh --from-file=/path/to/dir

4.合併不一樣選項

#kubectl create configmap my-conf-yh 
  --from-file=/path/to/dir/
  --from-file=bar=foobar.conf
  --from-literal=some=thing

  

5.獲取ConfigMap

#kubectl -n <namespace> get configmap

  

7.4.3.給容器傳遞ConfigMap條目做爲環境變量

引用環境變量中的參數值給當前變量

apiVersion: v1
kind: pod
metadata:
  name: fortune-env-from-configmap
spec:
  containers:
  - image: luksa/fortune:env
    env:
    - name: INTERVAL                  //設置環境變量
      valueFrom:
        configMapkeyRef:
          name: fortune-configmap     
          key: sleep-interval         //變量的值取自fortune-configmap的slee-interval對應的值

  

7.4.4.一次性傳遞ConfigMap的全部條目做爲環境變量

apiVersion: v1
kind: pod
metadata:
  name: fortune-env-from-configmap
spec:
  containers:
  - image: luksa/fortune:env
    envFrom:
    - prefix: CONFIG_
      confgMapRef:
        name: my-confg-map    //引用my-config-map的ConfigMap並在變量前面都加上CONFIG_

  

7.4.5.使用ConfigMap卷將條目暴露爲文件

apiVersion: v1
kind: pod
metadata:
  name: configmap-volume-yh
spec:
  containers:
  - image: nginx:aplin
    name: web-server
    volumeMounts:
    ...
    - name: config
defaultMode: "6600" //設置文件的權限爲rw-rw mountPath: /etc/nginx/con.conf
subPath: my.conf //subPath字段能夠用於掛載卷中某個獨立的文件或者文件夾,並且不覆蓋該卷下其餘文件 ... volume: ... - name: config configMap: name: fortune-config //引用fortune-config configMap的卷,而後掛載在/etc/nginx/conf.d

  能夠使用以下命令查看到/etc/nginx/conf.d文件下面包含fortune-config

#kubectl exec config-volume-yh -c web-server ls /etc/nginx/conf.d

   

7.5.使用Secert給容器傳遞敏感數據

7.5.1.介紹Secert

Secret結構和ConfigMap相似,均是鍵/值對的映射。

使用方法也和ConfigMap同樣,能夠:

  1.將Secret條目做爲環境變量傳遞給容器,

  2.將Secret條目暴露爲卷中文件

 ConfigMap存儲非敏感的文本配置數據,採用Secret存儲天生敏感的數據

7.5.2.默認令牌Secret

1.查看secret

# kubectl get secrets 
NAME                  TYPE                                  DATA   AGE
default-token-x9cjb   kubernetes.io/service-account-token   3      78d

2.描述secret

# kubectl describe secrets default-token-x9cjb 
Name:         default-token-x9cjb
Namespace:    default
Labels:       <none>
Annotations:  kubernetes.io/service-account.name: default
              kubernetes.io/service-account.uid: 64a41a09-98ce-11e9-9fa5-fa163e6fdb6b

Type:  kubernetes.io/service-account-token

Data
====
token:      eyJhbGciOiJSUzI1NiIsImtpZCI6IiJ9.eyJpc3MiOiJrdWJlcm5lduaW8vc2VydmljZTxCv6HdtP-ZW3ZC2IKKR5YBhaokFIl35mix79pU4Ia2pJ_fuPTBGNyrCHyNQYH4ex5DhND3_b2puQmn8RSErQ
ca.crt:     1298 bytes
namespace:  7 bytes

 

7.5.3.建立Secret

1.建立一個名爲https-yh的generic secret

#kubectl create secret generic https-yh --from-file=https.key  --from-file=https.cert  --from-file=foo

 

2.建立一個secret.yaml文件,內容用base64編碼

$ echo -n 'admin' | base64
YWRtaW4=
$ echo -n '1f2d1e2e67df' | base64
MWYyZDFlMmU2N2Rm

 

yaml文件內容:

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

 

建立:

$ kubectl create -f ./secret.yaml
secret "mysecret" created

 

解析Secret中內容

複製代碼
$ kubectl get secret mysecret -o yaml
apiVersion: v1
data:
  username: YWRtaW4=
  password: MWYyZDFlMmU2N2Rm
kind: Secret
metadata:
  creationTimestamp: 2016-01-22T18:41:56Z
  name: mysecret
  namespace: default
  resourceVersion: "164619"
  selfLink: /api/v1/namespaces/default/secrets/mysecret
  uid: cfee02d6-c137-11e5-8d73-42010af00002
type: Opaque
複製代碼

 

base64解碼:

$ echo 'MWYyZDFlMmU2N2Rm' | base64 --decode
1f2d1e2e67df

  

7.5.4.對比ConfigMap與Secret

Secret的條目內容會進行Base64格式編碼,而ConfigMap直接以純文本展現。

1.爲二進制數據建立Secret

  Base64能夠將二進制數據轉換爲純文本,並以YAML或Json格式進行展現

  但要注意Secret的大小限制是1MB

2.stringDate字段介紹

  Secret能夠經過StringDate字段設置條目的純文本

kind: Secret
apiVersion: v1
stringDate:
  foo: plain txt
date:
  https.cert: HGIOPUPSDF63456BJ3BBJL34563456BLKJBK634563456BLBKJBLKJ63456BLK3456LK
  http.key: OHOPGPIU42342345OIVBGOI3456345OVB6O3456BIPO435B6IPU345UI

  

7.5.5.在pod中使用Secret

secret能夠做爲數據卷掛載或者做爲環境變量暴露給Pod中的容器使用,也能夠被系統中的其餘資源使用。好比能夠用secret導入與外部系統交互須要的證書文件等。

在Pod中以文件的形式使用secret

  1. 建立一個Secret,多個Pod能夠引用同一個Secret
  2. 修改Pod的定義,在spec.volumes[]加一個volume,給這個volume起個名字,spec.volumes[].secret.secretName記錄的是要引用的Secret名字
  3. 在每一個須要使用Secret的容器中添加一項spec.containers[].volumeMounts[],指定spec.containers[].volumeMounts[].readOnly = truespec.containers[].volumeMounts[].mountPath要指向一個未被使用的系統路徑。
  4. 修改鏡像或者命令行使系統能夠找到上一步指定的路徑。此時Secret中data字段的每個key都是指定路徑下面的一個文件名

下面是一個Pod中引用Secret的列子:

複製代碼
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: redis
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true
  volumes:
  - name: foo
    secret:
      secretName: mysecret
複製代碼

 

每個被引用的Secret都要在spec.volumes中定義

若是Pod中的多個容器都要引用這個Secret那麼每個容器定義中都要指定本身的volumeMounts,可是Pod定義中聲明一次spec.volumes就行了。

映射secret key到指定的路徑

能夠控制secret key被映射到容器內的路徑,利用spec.volumes[].secret.items來修改被映射的具體路徑

複製代碼
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: redis
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true
  volumes:
  - name: foo
    secret:
      secretName: mysecret
      items:
      - key: username
        path: my-group/my-username
複製代碼

 

發生了什麼呢?

  • username被映射到了文件/etc/foo/my-group/my-username而不是/etc/foo/username
  • password沒有變

Secret文件權限

能夠指定secret文件的權限,相似linux系統文件權限,若是不指定默認權限是0644,等同於linux文件的-rw-r--r--權限

設置默認權限位

複製代碼
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: redis
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
  volumes:
  - name: foo
    secret:
      secretName: mysecret
      defaultMode: 256
複製代碼

 

上述文件表示將secret掛載到容器的/etc/foo路徑,每個key衍生出的文件,權限位都將是0400

因爲JSON不支持八進制數字,所以用十進制數256表示0400,若是用yaml格式的文件那麼就很天然的使用八進制了

同理能夠單獨指定某個key的權限

複製代碼
apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: redis
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
  volumes:
  - name: foo
    secret:
      secretName: mysecret
      items:
      - key: username
        path: my-group/my-username
        mode: 511
複製代碼

 

從volume中讀取secret的值

值得注意的一點是,以文件的形式掛載到容器中的secret,他們的值已是通過base64解碼的了,能夠直接讀出來使用。

複製代碼
$ ls /etc/foo/
username
password
$ cat /etc/foo/username
admin
$ cat /etc/foo/password
1f2d1e2e67df
複製代碼

 

被掛載的secret內容自動更新

也就是若是修改一個Secret的內容,那麼掛載了該Secret的容器中也將會取到更新後的值,可是這個時間間隔是由kubelet的同步時間決定的。最長的時間將是一個同步週期加上緩存生命週期(period+ttl)

特例:以subPath形式掛載到容器中的secret將不會自動更新

以環境變量的形式使用Secret

  1. 建立一個Secret,多個Pod能夠引用同一個Secret
  2. 修改pod的定義,定義環境變量並使用env[].valueFrom.secretKeyRef指定secret和相應的key
  3. 修改鏡像或命令行,讓它們能夠讀到環境變量
複製代碼
apiVersion: v1
kind: Pod
metadata:
  name: secret-env-pod
spec:
  containers:
  - name: mycontainer
    image: redis
    env:
      - name: SECRET_USERNAME
        valueFrom:
          secretKeyRef:
            name: mysecret
            key: username
      - name: SECRET_PASSWORD
        valueFrom:
          secretKeyRef:
            name: mysecret
            key: password
  restartPolicy: Never
複製代碼

 

容器中讀取環境變量,已是base64解碼後的值了:

$ echo $SECRET_USERNAME
admin
$ echo $SECRET_PASSWORD
1f2d1e2e67df

 

使用imagePullSecrets

建立一個專門用來訪問鏡像倉庫的secret,當建立Pod的時候由kubelet訪問鏡像倉庫並拉取鏡像,具體描述文檔在 這裏

設置自動導入的imagePullSecrets

能夠手動建立一個,而後在serviceAccount中引用它。全部通過這個serviceAccount建立的Pod都會默認使用關聯的imagePullSecrets來拉取鏡像,

相關文章
相關標籤/搜索