1. 程式人生 > 實用技巧 >K8S Secrete詳解2

K8S Secrete詳解2

k8s通過secret管理敏感資訊

應用啟動過程中可能需要一些敏感資訊,比如訪問資料庫的使用者名稱密碼或者祕鑰。將這些資訊直接儲存在容器映象中顯然不妥,Kubernetes 提供的解決方案是 Secret。

Secret 會以密文的方式儲存資料,避免了直接在配置檔案中儲存敏感資訊。Secret 會以 Volume 的形式被 mount 到 Pod,容器可通過檔案的方式使用 Secret 中的敏感資料;此外,容器也可以環境變數的方式使用這些資料。

Secret 可通過命令列或 YAML 建立。比如希望 Secret 中包含如下資訊:

  1. 使用者名稱admin

  2. 密碼123456

1.建立 Secret方式

有四種方法建立 Secret:

1.1 通過--from-literal

kubectl create secret generic mysecret --from-literal=username=admin --from-literal=password=123456

每個--from-literal對應一個資訊條目。

1.2 通過--from-file

echo -n admin > ./username
echo -n 123456 > ./password
kubectl create secret generic mysecret --from-file=./username --from-file=./password

每個檔案內容對應一個資訊條目。

1.3通過--from-env-file

cat << EOF > env.txt
username=admin
password=123456
EOF
kubectl create secret generic mysecret --from-env-file=env.txt

檔案env.txt中每行 Key=Value 對應一個資訊條目。

1.4通過 YAML 配置檔案:

檔案中的敏感資料必須是通過 base64 編碼後的結果。

執行kubectl apply建立 Secret:

2.檢視secret

2.1通過kubectl get secret
檢視存在的 secret

顯示有兩個資料條目

2.2通過kubectl describe secret檢視條目的 Key

2.3通過kubectl edit secret mysecret檢視vlaue

2.4通過base64將value反解碼

3.vloume方式secret的使用

Pod 可以通過 Volume 或者環境變數的方式使用 Secret,先學習 Volume 方式。

Pod 的配置檔案如下所示:

① 定義 volumefoo,來源為 secretmysecret

② 將foomount 到容器路徑/etc/foo,可指定讀寫許可權為readOnly

建立 Pod 並在容器中讀取 Secret:

可以看到,Kubernetes 會在指定的路徑/etc/foo下為每條敏感資料建立一個檔案,檔名就是資料條目的 Key,這裡是/etc/foo/username/etc/foo/password,Value 則以明文存放在檔案中。

我們也可以自定義存放資料的檔名,比如將配置檔案改為:

這時資料將分別存放在/etc/foo/my-group/my-username/etc/foo/my-group/my-password中。

以 Volume 方式使用的 Secret 支援動態更新:Secret 更新後,容器中的資料也會更新。

將 password 更新為abcdef,base64 編碼為YWJjZGVm

4.環境變數中使用secret

通過 Volume 使用 Secret,容器必須從檔案讀取資料,會稍顯麻煩,Kubernetes 還支援通過環境變數使用 Secre

建立 Pod 並讀取 Secret。

通過環境變數SECRET_USERNAMESECRET_PASSWORD成功讀取到 Secret 的資料。

需要注意的是,環境變數讀取 Secret 很方便,但無法支撐 Secret 動態更新。

Secret 可以為 Pod 提供密碼、Token、私鑰等敏感資料;對於一些非敏感資料,比如應用的配置資訊,則可以用 ConfigMap

k8s管理機密資訊

一、啟動應用安全資訊的保護:

Secret介紹:

應用啟動過程中可能需要一些敏感資訊,比如訪問資料庫的使用者名稱密碼或者祕鑰。將這些資訊直接儲存在容器映象中顯然不妥,Kubernetes 提供的解決方案是 Secret。 Secret 會以密文的方式儲存資料,避免了直接在配置檔案中儲存敏感資訊。Secret 會以 Volume 的形式被 mount 到 Pod,容器可通過檔案的方式使用 Secret 中的敏感資料;此外,容器也可以環境變數的方式使用這些資料。 Secret 可通過命令列或 YAML 建立。比如希望 Secret 中包含如下資訊:
  1. 使用者名稱admin
  2. 密碼123456

建立 Secret

四種方法建立 Secret:

1. 通過--from-literal

kubectl create secret generic mysecret --from-literal=username=admin --from-literal=password=123 kubectl get secret
[root@cicd ~]# kubectl get secret
NAME                  TYPE                                  DATA      AGE
default-token-g44kp   kubernetes.io/service-account-token   3         3d
mysecret              Opaque                            2         9s
每個--from-literal對應一個資訊條目。

2. 通過--from-file

echo -n admin > ./username echo -n 123 > ./password kubectl create secret generic yoursecret --from-file=./username --from-file=./password 每個檔案內容對應一個資訊條目。
[root@cicd yml]# cat username 
admin[root@cicd yml]# cat password 
123[root@cicd yml]#

3. 通過--from-env-file

cat << EOF > env.txt username=admin password=123456 EOF kubectl create secret generic mysecret--from-env-file=env.txt 檔案env.txt中每行 Key=Value 對應一個資訊條目。

4. 通過 YAML 配置檔案:

檔案中的敏感資料必須是通過 base64 編碼後的結果。
echo -n admin | base64

 YWRtaW4=

echo -n 123 | base64

YWJj
 然後編寫以下檔案,新增關鍵引數。

[root@cicd yml]# cat secret.yml apiVersion: v1 kind: Secret metadata: name: yoursecret data: username: YWRtaW4= password: YWJj

data的資料以key:value的形式寫入。

執行kubectl apply建立 Secret


然後通過 base64 將 Value 反編碼:
[root@cicd yml]# echo -n YWRtaW4=|  base64 --decode      #-n 不換行
admin[root@cicd yml]# echo -n YWJj |  base64 --decode
abc[root@cicd yml]#

二、secret在pod中的應用:

volume 方式使用 Secret

Pod 可以通過 Volume 或者環境變數的方式使用 Secret,先學習 Volume 方式。 (1)Pod 的配置檔案如下所示:   cat pod2.yml

① 定義 volumefoo,來源為yoursecret ② 將foomount 到容器路徑/etc/foo,可指定讀寫許可權為readOnly 3.定義pod名稱 4. 掛載的目錄名與宿主機對映的目錄同名。

建立 Pod 並在容器中讀取 Secret:

[root@cicd yml]# kubectl get pod
NAME       READY     STATUS              RESTARTS   AGE
mypod-c3   1/1       Running             3          2h
mypod-c4   1/1       Running             2          1h
mypod3     0/1       ContainerCreating   0          42s

可以看到mypod3正在建立,這一狀態的原因有2;

一是因為延遲,等會就行

二是因為報錯,執行

[root@cicd yml]# kubectldescribepod mypod3
進入mypod3檢視詳細狀態資訊,如果報錯根據報錯做出反應。

建立完後,我們進入mypod3驗證:

[root@cicd yml]# kubectl exec -it mypod3 sh

可以看到,Kubernetes 會在指定的路徑/etc/foo下為每條敏感資料建立一個檔案檔名就是資料條目的 Key,這裡是/etc/foo/username和/etc/foo/password,Value 則以明文存放在檔案中。 (2)我們也可以自定義存放資料的檔名,比如將配置檔案改為:

這時資料將分別存放在/etc/foo/my-group/my-username和/etc/foo/my-group/my-password中。 執行建立mypod4: [root@cicd yml]# kubectl exec -it mypod4 sh
error: unable to upgrade connection: container not found ("mypod")
如果報此錯,則是因為建立的pod不成功,即error或者正在建立中。 建立完畢後,我們進入mypod4的/etc/foo路徑檢視。

Volume 方式使用的 Secret 支援動態更新:Secret 更新後,容器中的資料也會更新。 將 password 更新為 mdzz,base64 編碼為YWJjZGVm
[root@cicd yml]# echo -n mdzz | base64
bWR6eg==
更新 Secret。

重新執行secret.yml檔案

幾秒鐘後出現此報錯: cat: can't open 'my-password': No such file or directory
sh: getcwd: No such file or directory
這是因為改變的密碼正在生效,重新進入/etc/foo發現新的 password 已經同步好了。
/etc/foo/..2019_06_24_09_42_04.419998613/my-group # cat my-password 
mdzz/etc/foo/..2019_06_24_09_42_04.419998613/my-group # 

環境變數方式使用 Secret

通過 Volume 使用 Secret,容器必須從檔案讀取資料,會稍顯麻煩,Kubernetes 還支援通過環境變數使用 Secret。 Pod 配置檔案示例如下:

注意上圖裡的key:username和key:password是對應secret.yml檔案裡的

所以一定要注意書寫,不然是無法通過環境變數方式使用secret的。

然後建立 Pod。 [root@cicd yml]# kubectl apply -f pod4.yml
pod "mypod5" created

通過環境變數SECRET_USERNAME和SECRET_PASSWORD成功讀取到 Secret 的資料。
[root@cicd yml]# kubectl get pod
NAME      READY     STATUS    RESTARTS   AGE
mypod5    1/1       Running   0          56s
[root@cicd yml]# kubectl exec-it mypod5 sh
/ # echo $SECRET_USERNAME
admin
/ # echo $SECRET_PASSWORD
mdzz

需要注意的是,環境變數讀取 Secret 很方便,但無法支撐 Secret 動態更新Secret 可以為 Pod 提供密碼、Token、私鑰等敏感資料思維導圖之kubernetes

              k8s

               docker

108、如何使用 Secret? (Swarm15)

參考https://www.cnblogs.com/CloudMan6/p/8068057.html 我們經常要想容器傳遞敏感資訊,最常見的就是密碼。比如: docker run -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql 在啟動Mysql容器時,我們通過環境變數 MYSQL_ROOT_PASSWORD設定mysql的管理員密碼。不過密碼是以明文的形式寫在了dockerrun命令中,有潛在的安全隱患。 為了解決這個問題,dockerswarm提供了secret機制,允許將敏感資訊加密後儲存到secret中,使用者可以指定哪些容器可以使用此secret。 如果使用secret啟動Mysql容器,方法是: root@host03:~# echo 'my-secret-pw' | docker secret create my_secret_data1 - # 建立一個secret z04oyb43x6brtvpdel6bqc7rv root@host03:~# docker secret ls # 檢視secret列表 IDNAMEDRIVERCREATEDUPDATED z04oyb43x6brtvpdel6bqc7rvmy_secret_data17 seconds ago7 seconds ago root@host03:~# docker secret inspect my_secret_data1 # 檢視secret詳細資訊 [ { "ID": "z04oyb43x6brtvpdel6bqc7rv", "Version": { "Index": 13493 }, "CreatedAt": "2019-05-16T02:05:11.083477558Z", "UpdatedAt": "2019-05-16T02:05:11.083477558Z", "Spec": { "Name": "my_secret_data1", "Labels": {} } } ] root@host03:~# docker service create --name mysql --secret source=my_secret_data1,target=mysql_root_password -e MYSQL_ROOT_PASSWORD_FILE="/run/secrets/mysql_root_password" mysql 4epm4b3arpzetqra3vuveqgq5 overall progress: 1 out of 1 tasks 1/1: running[==================================================>] verify: Service converged root@host03:~# docker service ps mysql IDNAMEIMAGENODEDESIRED STATECURRENT STATEERRORPORTS 8icyti1vg03nmysql.1mysql:latesthost02RunningRunning 5 minutes ago root@host02:~# docker ps CONTAINER IDIMAGECOMMANDCREATEDSTATUSPORTSNAMES 74ae17815637mysql:latest"docker-entrypoint.s…"57 seconds agoUp 56 seconds3306/tcp, 33060/tcpmysql.1.8icyti1vg03nlmp87zna0vw4g root@host02:~# docker exec mysql.1.8icyti1vg03nlmp87zna0vw4g cat /run/secrets/mysql_root_password # 在容器中可以看到未加密的密碼 my-secret-pw docker service create --name mysql \ --secret source=my_secret_data1,target=mysql_root_password \ # source指定容器使用secret後,secret會被解密並存放到容器中 /run/secret/<filename>,其中filename由tatget指定 -e MYSQL_ROOT_PASSWORD_FILE="/run/secrets/mysql_root_password" \ # 環境變數 MYSQL_ROOT_PASSWORD_FILE從容器中指定的檔案/run/secret/<filename>中獲得(明文) mysql 這裡可能會有兩個問題: 1、在第一步建立secret時,不是也使用明文了嗎?這跟在環境變數中直接指定密碼有什麼不同? 在我們的例子中建立secret和使用secret是分開完成的,其好處是將密碼和容器解耦。secret可以有專人(比如管理員)負責,而執行容器的使用者只需要使用secret但並不需要知道secret的內容。也就是說例子中的兩個步驟可以由不同的人在不同的時間完成。 2、secret是以檔案形式mount到容器中,容器怎麼知道去哪裡讀取呢? 這需要image的支援,如果image希望他部署出來的容器能夠從secret中讀取資料,那麼此image就應該提供一種方式,讓使用者能夠制定secret的位置。最常用的方法就是通過環境變數,Docker的很多官方image都採用這種方式,比如Mysql映象同事提供了MYSQL_ROOT_PASSWORD和 MYSQL_ROOT_PASSWORD_FILE兩個環境變數。