Kubernetes之十五----configMap和secre特色存儲卷詳解

1、本章簡介

ConfigMap 和 Secret 是 Kubernetes 系統上兩種特殊類型的存儲卷, ConfigMap 對象用 於爲容器中的應用提供配置數據以定製程序的行爲,不過敏感的配置信息,例如密鑰、證書 等通常由 Secret 對象來進行配置。 它們將相應的配置信息保存於對象中,而後在 Pod 資源 上以存儲卷的形式將其掛載並獲取相關的配置,以實現配置與鏡像文件的解捐。 本章將主要講解 ConfigMap與Secret 存儲卷的用法。

 

2、configMap介紹

        ConfigMap用於保存配置數據的鍵值對,可以用來保存單個屬性,也可以用來保存配置文件。ConfigMap跟secret很類似,但它可以更方便地處理不包含敏感信息的字符串。

       作爲分佈式系統的 Kubernetes 也提供了統一配置管理方案一一ConfigMap。 Kubemetes 基於 ConfigMap 對象實現了將配置文件從容器鏡像中解祠,從而增強了容器應用的可移植 性。 簡單來說,一個 ConfigMap 對象就是一系列配置數據的集合,這些數據可“注入”到 Pod 對象中,併爲容器應用所使用;注入方式有掛載爲存儲卷和傳遞爲環境變量兩種。

        ConfigMap 對象將配置數據以鍵值對的形式進行存儲,這些數據可以在 Pod 對象中使 用或者爲系統組件提供配置,例如控制器對象等。 不過,無論應用程序如何使用 ConfigMap 對象中的數據,用戶都完全可以通過在不同的環境中創建名稱相同但內容不同的 ConfigMap 對象,從而爲不同環境中同一功能的 Pod 資源提供不同的配置信息,實現應用與配置的靈活句兌。

 

3、創建ConfigMap對象和Pod環境變量並傳遞鍵值數據

3.1 通過命令進行創建configMap對象

        Kubernetes 的不少資源既可以使用 kubectl create命令創建, 也可以使用清單創建, 例如 前面講到的 namespaceo ConfigMap 是另-個兩種創建方式都比較常用的資源。 而且,通過 使用“ kubectl create configmap”命令,用戶可以根據目錄、文件或直接值創建 ConfigMap 對象。 命令的語法格式如下所示 :

kubectl create conf igrnap <map-name> <data-source> 

        其中,<map-name>即爲 ConfigMap 對象的名稱,而 <data-source>是數據源,它可以 通過直接值、文件或目錄來獲取。 無論是哪一種數據源供給方式,它都要轉換爲 ConfigMap 對象中的 Key-Value 數據,其中 Key 由用戶在命令行給出或是文件數據源的文件名 ,它僅能 由字母、數字、連接號和點號組成,而 Value 則是直接值或文件數據源的內容。

爲“ kubectl create  configmap,命令使用"--from-literal" 選項可在命令行直接給出鍵值對來創建 ConfigMap 對象,重複使用此選項則可以傳遞多個鍵值對。 命令格式如下:

創建一個名稱空間爲config以示區別和configmap

  • --from-literal=redis_host="redis.default.svc.cluster.local" 創建一個redis_hsot的名稱爲redis.default.svc.cluster.local

  • --from-literal=log_level="Info"                                       創建日誌級別

[root@master ~]# kubectl create ns config        # 創建一個名稱空間爲config,以示區別
namespace/config created
[root@master ~]# kubectl create configmap filebeat-cfg -n config --from-literal=redis_host="redis.default.svc.cluster.local" --from-literal=log_level="Info" # 創建configmap,指定redis_host名稱和日誌級別
configmap/filebeat-cfg created


[root@master ~]# kubectl get cm -n config        # 查看創建的configmap信息,在config名稱空間下
NAME           DATA   AGE
filebeat-cfg   2      51s

[root@master ~]# kubectl get cm -n config  -o yaml   # 查看configmap詳細信息
apiVersion: v1
items:
- apiVersion: v1
  data:
    log_level: Info                             # 日誌級別
    redis_host: redis.default.svc.cluster.local  # redis_host名稱
  kind: ConfigMap
  metadata:
    creationTimestamp: "2020-08-04T01:40:14Z"
    name: filebeat-cfg
    namespace: config
    resourceVersion: "168207"
    selfLink: /api/v1/namespaces/config/configmaps/filebeat-cfg
    uid: 2d4517ac-6442-483d-a8d6-60d797fd2a1b
kind: List
metadata:
  resourceVersion: ""
  selfLink: ""

注意:此類方式提供的數據量有限, 一般是在僅通過有限的幾個數據項即可爲Pod資源提供足夠的配置信息時使用。

  

3.2 定義Pod 環境變量並傳遞ConfigMap對象鍵值數據

3.2.1 查看yaml文件幫助

查看kuberbetes幫助文檔,然後再創建yaml配置文件

[root@master configmap]# kubectl explain pods.spec.containers               # 可以查看幫助裏邊的env變量信息
   env	<[]Object>
     List of environment variables to set in the container. Cannot be updated.
     
[root@master configmap]# kubectl explain pods.spec.containers.env.valueFrom  # 然後再env環境變量下也可以引用
KIND:     Pod
VERSION:  v1

RESOURCE: valueFrom <Object>

DESCRIPTION:
     Source for the environment variable's value. Cannot be used if value is not
     empty.

     EnvVarSource represents a source for the value of an EnvVar.

FIELDS:
   configMapKeyRef	<Object>                              # 引用此變量
     Selects a key of a ConfigMap.

   fieldRef	<Object>
     Selects a field of the pod: supports metadata.name, metadata.namespace,
     metadata.labels, metadata.annotations, spec.nodeName,
     spec.serviceAccountName, status.hostIP, status.podIP.

   resourceFieldRef	<Object>
     Selects a resource of the container: only resources limits and requests
     (limits.cpu, limits.memory, limits.ephemeral-storage, requests.cpu,
     requests.memory and requests.ephemeral-storage) are currently supported.

   secretKeyRef	<Object>                                    # 引用此變量
     Selects a key of a secret in the pod's namespace
[root@master configmap]# kubectl explain pods.spec.containers.env.valueFrom.configMapKeyRef # 下面更詳細的引用
KIND:     Pod
VERSION:  v1

RESOURCE: configMapKeyRef <Object>

DESCRIPTION:
     Selects a key of a ConfigMap.

     Selects a key from a ConfigMap.

FIELDS:
   key	<string> -required-                                    # 引用文件的鍵
     The key to select.

   name	<string>                                               # 應用文件的名稱
     Name of the referent. More info:
     https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names

   optional	<boolean>
     Specify whether the ConfigMap or its key must be defined

 

3.2.2 向Pod 環境變量傳遞ConfigMap對象鍵值數據

        Pod 資源的環境變量值的獲得方式之一包括引用 ConfigMap 對 象中的數據,這一點通過在 env 字段中爲 valueFrom 內configMapKeyRef對象即可實現, 其使用格式如下 :

        其中, 字段 name 的值爲要引用的 ConfigMap 對象的名稱字段 key 可用於指定要引用 ConfigMap 對象中某鍵的鍵名。 此類環境變量的使用方式與直接定義的環境變量並無區別,它們可被用於容器的啓動腳本或直接傳遞給容器應用等。 

1、創建yaml文件

[root@master ~]# mkdir configmap
[root@master ~]# cd configmap/
[root@master configmap]# cat pod-cfg.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: pod-cfg-demo
  namespace: config
spec:
  containers:
  - name: filebeat
    image: ikubernetes/filebeat:5.6.5-alpine
    env:
    - name: REDIS_HOST        # 定義鏡像中redis_host的環境變量名稱要大寫
      valueFrom:              # 用來給REDIS_HOST來傳值的
        configMapKeyRef:
          name: filebeat-cfg  # 引用上面創建好的configMap的值
          key: redis_host     # 引用上面創建到redis_host的鍵(創建configMap時的值)
    - name: LOG_LEVEL         # 定義log_level日誌級別的環境變量時要大寫
      valueFrom:
        configMapKeyRef:
          name: filebeat-cfg  # 也是引用上面的值,與REDIS_HOST值類似
          key: log_level      # configMap資源中的鍵

注意:創建引用了 ConfigMap 資源的 Pod 對象時 , 被引用的資源必須事先存在, 否則將無 法啓動相應的容器,直到被依賴的資源創建完成爲止。不過, 那些未引 用不存在的 ConfigMap 資源的容器將不受 此 影 響 。另外 , ConfigMap 是名稱空 間 級別的資源, 它必須與引用它的 Pod 資源在同 一 空間 中 。

 

2、執行yaml文件並創建pod,查看驗證結果

[root@master configmap]# kubectl apply -f pod-cfg.yaml   # 創建變量名並引用
pod/pod-cfg-demo created 
[root@master configmap]# kubectl get pods -n config  # 查看此時的pod已經運行
NAME           READY   STATUS    RESTARTS   AGE
pod-cfg-demo   1/1     Running   0          40s

 

3、查看此時的環境變量信息

[root@master configmap]# kubectl exec -it pod-cfg-demo  -n config  -- /bin/sh  # 進入pod中查看此時的環境變量
/ # printenv 
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT=443
LOG_LEVEL=Info                                          # 日誌級別是Info
HOSTNAME=pod-cfg-demo
SHLVL=1
HOME=/root
TERM=xterm
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT_HTTPS=443
PWD=/
KUBERNETES_SERVICE_HOST=10.96.0.1
REDIS_HOST=redis.default.svc.cluster.local               # 引用的環境變量
FILEBEAT_VERSION=5.6.5

  

4、此時修改configmap裏邊的環境變量值,雖然用命令查看此時的環境變量被修改了,實際在pod環境變量並沒有被修改。

[root@master ~]# kubectl edit cm filebeat-cfg  -n config 
apiVersion: v1
data:
  log_level: Notice                                               # 將Info改爲Notice
  redis_host: redis.default.svc.cluster.local
[root@master ~]# kubectl get cm filebeat-cfg -n config -o yaml # 用命令查看此時的環境變量已經被修改 apiVersion: v1 data: log_level: Notice # 此時修改完環境變量,並查看此時的環境變量已經被修改 redis_host: redis.default.svc.cluster.local

  

5、查看pod的環境變量信息未被修改

[root@master configmap]# kubectl exec -it pod-cfg-demo  -n config  -- /bin/sh
/ # printenv                             # 再次查看環境變量
KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT=443
LOG_LEVEL=Info              # 但是在pod中查看此時的日誌級別還是未修改的

 

4、ConfigMap 存儲卷

 存儲卷原理:若ConfigMap 對象中的鍵值來源於較長的文件內容,那麼使用環境變量將其導人會使 得變量值佔據過多的內存空間而且不易處理。 此類數據通常用於爲容器應用提供配置文件, 因此將其內容直接作爲文件進行引用方爲較好的選擇。 其實現方式是,在定義 Pod 資源時, 將此類 ConfigMap 對象配置爲 ConfigMap 類型的存儲卷,而後由容器將其掛載至特定的掛 載點後直接進行訪問。

 

1、定義兩個configMap文件

爲“ kubectl create configmap ,命令使用“--from-file” 選項即可基於文件內容來創建ConfigMap對象, 它的命令格式如下。 可以重複多次使用"--from-file"選項傳遞多個文件內容:

kubectl create configmap <co口figmap_name> --from-file工<path-to-file>

  

1、創建訪問頁面路徑

[root@master configmap]# cat server.conf                   # 定義訪問頁面路徑
server {
    	server_name www.peng.com;
    	listen 80;
    	location / {
           root "/usr/share/nginx/html";
    	}
}

[root@master configmap]# cp server.conf server1.conf
[root@master configmap]# cat server1.conf 
server {
    	server_name www.ilinux.io;
    	listen 80;
    	location / {
    	    root "/html/ilinux";
    	}
}

 

2、通過訪問頁面文件創建configMap,並驗證信息

  •  --from-file=./server.conf          指定的是相對路徑的文件名稱
  • --from-file=server-second.conf=./server1.conf     定義第二個文件的名稱信息爲server-second.conf
[root@master configmap]# kubectl create configmap nginx-cfg --from-file=./server.conf  --from-file=server-second.conf=./server1.conf  -n config    # 其中server-second.conf是自定義創建的文件名 
configmap/nginx-cfg created    

[root@master configmap]# kubectl get cm -n config  # 查看此時創建好的configmap信息
NAME           DATA   AGE
filebeat-cfg   2      72m
nginx-cfg      2      30s
[root@master configmap]# kubectl get cm  nginx-cfg -n config -o yaml
apiVersion: v1
data:
  server.conf: "server {\n    \tserver_name www.peng.com;\n   \tlisten 80; \tlocation 
  / {\n    \t\t  \  root \"/usr/share/nginx/html\";\n    \t}\n}\n"  # 查看此時創建的myserver.conf配置文件
  server-second.conf: "server {\n    \tserver_name www.ilinux.io;\n   \tlisten 80;  \tlocation 
  / {\n    \t\t   root \"/html/ilinux\";\n    \t}\n}\n"             # 查看此時創建的第二個配置文件
kind: ConfigMap
metadata:
  creationTimestamp: "2020-08-04T02:52:22Z"
  name: nginx-cfg           # configmap名稱
  namespace: config
  resourceVersion: "175017"
  selfLink: /api/v1/namespaces/config/configmaps/nginx-cfg
  uid: c67ad90a-e873-477e-b76f-8b1e6dbe406b

  

2、掛載整個存儲卷

       關聯爲 Pod 資源的存儲卷時, ConfigMap 對象中的每個鍵都對應地表現爲一個文件, 鍵名轉爲文件名而鍵值則爲相應文件的內容即便是通過直接值創建的鍵值數據,也一樣表現爲文件視圖。 掛載於容器上之後, 由鍵值數據表現出的文件位於掛載點目錄中,容器中 的進程可直接讀取這些文件的內容。 配置Pod 資源時, 基於存儲卷的方式引用 ConfigMap 對象的方法非常簡單,僅需要指 明存儲卷名稱及要引用的 ConfigMap 對象名稱即可。 下面是於配置文件 myapp-pod.yaml 中定義的 Pod 資源,創建的 ConfigMap 對象 nginx-cfg,容器myapp將其掛載至應用程序 Nginx 加載配置文件模塊的目錄/etc/ nginx/conf.d 中, 具體如下 :

 

1、定義一個myapp-pod.yaml文件,將configmap中的nginx-cfg掛載只應用容器中

[root@master configmap]# cat myapp-pod.yaml 
apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  namespace: config
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    volumeMounts:
    - name: config                # 指定掛載的存儲卷的名稱,與volumes上的名稱一致
      mountPath: /etc/nginx/conf.d/
  volumes:
  - name: config                 # 存儲卷名稱
    configMap:
      name: nginx-cfg            # 與前面創建的configmap的nginx-cfg進行關聯
      items:                     # 引用哪個鍵
      - key: server.conf         # 指定配置文件必須是相對路徑才能被調用
        path: server-first.conf 
      - key: server-second.conf  # key值爲上面創建的configmap對應的值
        path: server-second.conf  # path路徑對應的是configmap對應的配置文件

configMap 存儲卷的 items 字段的值是一個對象列表,可嵌套使用的字段有三個,具體 如下。

key <string>: 要引用的鍵名稱,必選字段。 

path<string>: 對應的鍵於掛載點目錄中生成的文件的相對路徑,可以不同於鍵名稱, 必選字段。

mode <integer> : 文件的權限模型,可用範圍爲 0 到 0777。

上面的配置示例中, server.-firstconf 映射成了server.conf 文件,而 server-second.conf則保持了與鍵名同名,並明確指定使用 0644 的權限,從而達成了僅裝載部分 文件至容器之目的。

 

2、創建yaml文件,並查看效果

[root@master configmap]# kubectl apply -f myapp-pod.yaml 
pod/myapp-pod created

[root@master configmap]# kubectl get pods -n config
NAME           READY   STATUS    RESTARTS   AGE
nginx-pod      1/1     Running   0          12m                    # 此時查看到新的pod已經創建成功
pod-cfg-demo   1/1     Running   1          7h2m
[root@master configmap]# kubectl describe pods nginx-pod -n config # 查看此時的pod運行狀態信息,已經是運行狀態 .............中間省略了 Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled <unknown> default-scheduler Successfully assigned config/nginx-pod to node2 Normal Pulled 13m kubelet, node2 Container image "nginx:1.14.1-alpine" already present on machine Normal Created 13m kubelet, node2 Created container myapp Normal Started 13m kubelet, node2 Started container myapp

 

3、進入到容器內部查看此時的配置文件是否存在,和監聽的端口是否打開

[root@master configmap]# kubectl  exec -it nginx-pod  -n config  -- /bin/sh  # 連接到nginx-pod容器中,查看此時nginx的配置文件信息
/ # cd /etc/nginx/conf.d  # 切換到訪問頁面下
/etc/nginx/conf.d # ls    # 此時可以看到有兩個配置文件信息
server-first.conf   server-second.conf
/etc/nginx/conf.d # cat server-first.conf   # 查看此時的配置文件信息
server {
    	server_name www.peng.com;
  	listen 80;
    	location / {
              root "/html/peng";
    	}
}
/etc/nginx/conf.d # cat server-second.conf   # 查看此時的配置文件信息
server {
    	server_name www.ilinux.io;
	listen 80;
    	location / {
    	      root "/html/ilinux";
    	}
}
/etc/nginx/conf.d # netstat -nl              # 查看此時的端口號80也已經被監聽
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN  

  

4、如果想要修改監聽的端口號怎麼辦?我們只需要修改nginx-cfg資源裏的信息,而不能修改配置文件,因爲你已經創建好了pod的容器

[root@master configmap]# kubectl edit cm nginx-cfg -n config   # 修改nginx-cfg的配置信息即可
.......此處省略無關信息
apiVersion: v1
data:
  server-second.conf: "server {\n    \tserver_name www.ilinux.io;\n\tlisten 80;\n
    \   \tlocation / {\n    \t      root \"/html/ilinux\";\n    \t}\n}\n"
  server.conf: "server {\n    \tserver_name www.peng.com;\n  \tlisten 8080;\n    \tlocation               # 將server.conf中80改爲8080即可
    / {\n              root \"/html/peng\";\n    \t}\n}\n"

  

5、此時可以看到修改後的端口監聽狀態已經成爲8080,並創建兩個訪問頁面進行測試,如果端口沒有監聽,就需要手動重新加載

[root@master configmap]# kubectl edit cm nginx-cfg -n config   # 修改nginx-cfg的配置信息即可
}/etc/nginx/conf.d # cat server-first.conf 
server {
    	server_name www.peng.com;
  	listen 8080;
    	location / {
              root "/html/peng";
    	}
}
/etc/nginx/conf.d # netstat -nlt          # 查看此時的端口號是否正常
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      
/etc/nginx/conf.d # nginx -s reload       # 如果沒監聽成功,我們就需要手動重新進行加載
2020/08/04 09:30:35 [notice] 26#26: signal process started
/etc/nginx/conf.d # netstat -nlt          # 查看此時的端口號已經被重新加載成功爲8080端口
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN 
/etc/nginx/conf.d # mkdir /html/peng -p                           # 創建訪問頁面目錄
/etc/nginx/conf.d # mkdir /html/ilinux -p                        # 創建訪問頁面目錄
/etc/nginx/conf.d # echo welcome to shanghai > /html/peng/index.html  # 創建訪問頁面
/etc/nginx/conf.d # echo welcome to shanghai-1 > /html/ilinux/index.html # 創建訪問頁面
/etc/nginx/conf.d # exit

  

6、查看pod的IP地址,並寫入到hosts文件中,進行域名解析並訪問

[root@master configmap]# kubectl get pods -o wide -n config  # 查看此時創建的pod  IP地址
NAME           READY   STATUS    RESTARTS   AGE     IP            NODE    NOMINATED NODE   READINESS GATES
nginx-pod      1/1     Running   1          3h55m   10.244.2.70   node2   <none>           <none>
pod-cfg-demo   1/1     Running   2          10h     10.244.2.71   node2   <none>           <none>

[root@master configmap]# cat /etc/hosts   # 進行域名解析
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.7.101 master
192.168.7.102 node1
192.168.7.103 node2
192.168.7.104 nfs
10.244.2.70 www.peng.com                  # 在master節點上進行域名解析
10.244.2.70 www.ilinux.io                 # 在master節點上進行域名解析

[root@master configmap]# curl www.peng.com        # 訪問網頁
welcome to shanghai-1
[root@master configmap]# curl www.ilinux.io:8080  # 訪問網頁
welcome to shanghai

  

 5、Secret 資源

Secret資源的功能類似於ConfigMap,但它專用於存放敏感數據,例如密碼、數字證書、私鑰、令牌和SSH key 等。

 

1、Secret概述

        Secret 對象存儲數據的方式及使用方式類似於 ConfigMap 對象,以鍵值方式存儲數據, 在 Pod 資源中通過環境變量或存儲捲進行數據訪問。 不同的是, Secret 對象僅會被分發至調 用了此對象的 Pod 資源所在的工作節點,且只能由節點將其存儲於內存中。 另外, Secret 對 象的數據的存儲及打印格式爲 Base64 編碼的字符串,因此用戶在創建 Secret 對象時也要提 供此種編碼格式的數據。 不過,在容器中以環境變量或存儲卷的方式訪問時,它們會被自動 解碼爲明文格式。 

        需要注意的是,在 Master 節點上, S巳cret 對象以非加密的格式存儲於 etcd中,因此 管理員必須加以精心管控以確保敏感數據的機密性,必須確保 etcd 集羣節點間以及與 API Server 的安全通信,etcd 服務的訪問授權,還包括用戶訪問 API Server 時的授權,因爲擁有 創建 Pod 資源的用戶都可以使用 Secret 資源並能夠通過 Pod 中的容器訪問其數據。 

        Secret 對象主要有兩種用途, 一是作爲存儲卷注入到 Pod 上由容器應用程序所使用, 二是用於 kubelet 爲 Pod 裏的容器拉取鏡像時向私有倉庫提供認證信息。 不過,後面使用 ServiceAccount 資源自建的 Secret 對象是一種更具安全性的方式。

 Secret 資源主要由四種類型組成,具體如下。

  •  Opaque:自定義數據內容; base64 編碼,用來存儲密碼、密鑰、信息、證書等數據,類型標識符爲 generic。 
  •  kubernetes.io/service-account-token : Service Account 的認證信息,可在創建 Service Accout 時由 Kubernetes 自動創建。 
  • kubernetes.io/dockerconfiεjson :用來存儲 Docker 鏡像倉庫的認證信息,類型標識爲docker-registry。
  •  kubernetes.io/tls : 用於爲 SSL 通信模式存儲證書和私鑰文件,命令式創建時類型標 識爲 tls。

       注意:base編碼並非加密機制,其編碼的數據可使用“ base64 …decode”一類的命令進 行解碼。

 

2、創建Secret資源

   手動創建Secret對象的方式有兩種:通過kubectl create命令和使用Secret配置文件。

2.1 命令式創建 

 1、創建secret

        不少場景中, Pod 中的應用需要通過用戶名和密碼訪問其他服務,例如訪問數據庫系統等。 創建此類的 Secret 對象,可以使用“ kubectl create secret generic <SECRET_NAME> --from-literal=key=value'’命令直接進行創建,不過爲用戶認證之需進行創建時, 其使用的 鍵名通常是 username 和 password。

[root@master configmap]# kubectl create secret generic mysql-root-password -n config --from-literal=password=centos         # 創建secret,名稱爲mysql-root-password,--from-literal=password密碼爲centos
secret/mysql-root-password created

 

2、查看創建的secret資源信息,此時查看的密碼是通過base64進行加密的,但是通過base64可以進行破解。

[root@master configmap]# kubectl get secret  mysql-root-password -n config -o yaml          # 查看secret的具體信息
apiVersion: v1
data:
  password: Y2VudG9z                                                                        # 創建的密碼必須事base64編碼密鑰
kind: Secret
metadata:
  creationTimestamp: "2020-08-04T14:31:43Z"
  name: mysql-root-password
  namespace: config
  resourceVersion: "230246"
  selfLink: /api/v1/namespaces/config/secrets/mysql-root-password
  uid: 0a4a4a2e-9c2b-411c-85eb-fb89b23f6daa
type: Opaque 
[root@master configmap]# echo Y2VudG9z | base64 -d                                          # 將base64編碼進行解密,可以查看到此時的密碼就是centos
centos[root@master configmap]# 
[root@master configmap]# kubectl get secret -n config                                       # 查看創建的secret信息
NAME                  TYPE                                  DATA   AGE
default-token-qmgzk   kubernetes.io/service-account-token   3      13h
mysql-root-password   Opaque                                1      40m

 

2.2 通過secret向pod注入環境變量 

1、創建Pod,與前面創建的secret進行關聯

[root@master configmap]# cat  mysql-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: mysql
  namespace: config
spec:
  containers:
  - name: mysql
    image: mysql:5.6
    env:
    - name: MYSQL_ROOT_PASSWORD  # 鏡像定義的環境變量名
      valueFrom:
        secretKeyRef:
          key: password             # 密碼的鍵,對應的密碼就是上面創建的centos
          name: mysql-root-password # 創建的secret名稱

  

2、執行yaml文件,創建pod,並查看pod的詳細信息

[root@master configmap]# kubectl apply -f mysql-pod.yaml   # 創建pod資源
pod/mysql-pod created
[root@master configmap]# kubectl get pods -n config     # 查看此時的pod運行狀態
NAME           READY   STATUS    RESTARTS   AGE
mysql-pod      1/1     Running   0          17m
nginx-pod      1/1     Running   1          6h3m
pod-cfg-demo   1/1     Running   2          12h

 

3、進入到pod容器中,查看此時的信息,此方法不是保存密鑰的妥當方法,裏面可以看到登錄數據庫的密碼

[root@master configmap]# kubectl exec -it mysql-pod -n config -- /bin/sh
# mysql -pcentos            # 登錄到數據庫中
Warning: Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.6.49 MySQL Community Server (GPL)

Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> exit
Bye
# printenv                 # 可以使用printenv進行查看環境變量值
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://10.96.0.1:443
HOSTNAME=mysql-pod
MYSQL_MAJOR=5.6
HOME=/root
MYSQL_ROOT_PASSWORD=centos
TERM=xterm
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
MYSQL_VERSION=5.6.49-1debian9
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_SERVICE_PORT_HTTPS=443
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
GOSU_VERSION=1.12
KUBERNETES_SERVICE_HOST=10.96.0.1

  

3、Secret 存儲卷

       類似於 Pod 消費 ConfigMap 對象的方式, Secret 對象可以注入爲環境變量,也可以存儲爲卷形式掛載使用。 不過,容器應用通常會在發生錯誤時將所有環境變量保存於日誌信息 中,甚至有些應用在啓動時即會將運行環境打印到日誌中;另外,容器應用調用第三方程序爲子進程時,這些子進程能夠繼承並使用父進程的所有環境變量。 有鑑於此,使用環境變量引用 Secret 對象中的敏感信息實在算不上明智之舉。

        在 Pod 中使用 Secret 存儲卷的方式,除了其類型及引用標識要替換爲 Secret 及 secretName 之外,幾乎完全類似於 Config Map 存儲卷,包括支持使用掛載整個存儲卷、只掛載存儲卷 中的指定鍵值以及獨立掛載存儲卷中的鍵等使用方式。 

 

3.1 基於存儲卷創建Secret

 1、創建tls.key和tls.crt密鑰文件

[root@master configmap]# openssl genrsa -out tls.key 2048
Generating RSA private key, 2048 bit long modulus
..............+++
.......+++
e is 65537 (0x10001)
[root@master configmap]# openssl req -new -x509 -key tls.key -out tls.crt -subj /C=CN/ST=Beijing/L=Beijing/O=DevOps/CN=myapp.peng.com
[root@master configmap]# ll
total 32
-rw-r--r-- 1 root root  413 Aug  4 17:02 myapp-pod.yaml
-rw-r--r-- 1 root root  652 Aug  4 22:31 my-pod.yaml
-rw-r--r-- 1 root root  276 Aug  4 22:49 mysql-pod.yaml
-rw-r--r-- 1 root root  407 Aug  4 10:12 pod-cfg.yaml
-rw-r--r-- 1 root root  112 Aug  4 16:07 server1.conf
-rw-r--r-- 1 root root  114 Aug  4 16:48 server.conf
-rw-r--r-- 1 root root 1285 Aug  5 21:37 tls.crt         # 查看生成的tls.crt文件
-rw-r--r-- 1 root root 1675 Aug  5 21:37 tls.key         # 查看此時生成的tls.key文件  

 

2、基於上面創建的tls.key和tls.crt文件創建 tls類型的secret文件

[root@master configmap]# kubectl  create  secret tls  mysql-cert  --cert=./tls.crt  --key=./tls.key  -n config
secret/mysql-cert created
[root@master configmap]# kubectl get secrets -n config        #   查看此時創建的secret狀態
NAME                  TYPE                                  DATA   AGE
default-token-qmgzk   kubernetes.io/service-account-token   3      36h
mysql-cert            kubernetes.io/tls                     2      4m16s
mysql-root-password   Opaque                                1      23h

 

3、將上面資源清單文件中定義的資源創建於 Kubernetes 系統上,而後再查看容器掛載點 目錄中的文件,以確認其掛載是否成功完成,將創建的secret的tls.crt和ltls.key映射爲兩個文件

[root@master configmap]# cat  my-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
  namespace: config
spec:
  containers:
  - name: myapp
    image: ikubernetes/myapp:v1
    volumeMounts:
    - name: config
      mountPath: /etc/nginx/conf.d/
    - name: tls                     # tls存儲卷
      mountPath: /etc/nginx/certs/  # 存儲卷掛載目錄
  volumes:
  - name: config
    configMap:
      name: nginx-cfg
      items:
      - key: server.conf
        path: server-first.conf
      - key: server-second.conf
        path: server-second.conf
  - name: tls                  # 創建第二個volume
    secret:
      secretName: mysql-cert   # secret創建的名稱
      items:
        - key: tls.crt         # 定義tls.crt名稱
          path: myapp.crt      # 映射爲此名稱
        - key: tls.key         # 第二個tls.key的名稱
          path: myapp.key      # 映射的名稱
          mode: 0600           # 文件權限改爲0600

 

4、創建pod,並查看容器內部的密鑰文件

[root@master configmap]# kubectl apply -f my-pod.yaml   # 創建pod
pod/my-pod created
[root@master configmap]# kubectl exec -it my-pod -n config -- /bin/sh  # 到容器內部查看加密文件
/ # cd  /etc/nginx/certs
/etc/nginx/certs # ls
myapp.crt  myapp.key
/etc/nginx/certs # exit

  

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章