《kubernetes-1.8.0》19-examples-secrets
《kubernetes 1.8.0 測試環境安裝部署》
時間:2017-12-15
一、基礎知識:
secrets
是用來儲存類似于密碼、token、key等敏感資訊的。将這些敏感資訊放在
secrets
裡比直接放在
pod
或者
docker鏡像
中更安全和靈活。
建立:使用者能夠建立
secrets
,同時系統也會自動建立一些
secrets
(内建secrets)
使用:一個
secrets
能夠被兩種方式使用: 通過
volume
挂載到一個或者多個容器中,或者在
kubelet pull docker
鏡像的時候使用(需要login的docker倉庫)
Build-in Secrets
(内建secrets):
這個主要是關聯
Service Account
使用,當建立一個
SA
的時候将自動關聯一個
secrets
,如果想通過某個
sa
賬戶通路
apiserver
可通過該
secrets
進行驗證;
二、建立自定義secrets:
用 kubectl create secret
建立 secrets
:
kubectl create secret
secrets
要是一些pod需要通路資料庫,使用者名和密碼儲存在本機的
./username.txt
和
./password.txt
檔案中
建立所需的檔案:
$ mkdir ~/secret-examle
$ cd ~/secret-examle
$ echo -n "admin" > ./username.txt
$ echo -n "1f2d1e2e67df" > ./password.txt
使用
kubectl create secret
打包這些檔案到
secrets
$ kubectl create secret generic db-user-pass --from-file=./username.txt --from-file=./password.txt
secret "db-user-pass" created
-
:表明從本地檔案,目錄,或者鍵值對建立,還可以使用generic
以及docker-registry
tls
- docker-registry:Create a secret for use with a Docker registry
- tls:Create a TLS secret
檢視:
[[email protected] secret-examle]# kubectl get secrets
NAME TYPE DATA AGE
...
db-user-pass Opaque 15s
...
[[email protected] secret-examle]# kubectl describe secrets db-user-pass
Name: db-user-pass
Namespace: default
Labels: <none>
Annotations: <none>
Type: Opaque
Data
====
password.txt: bytes
username.txt: bytes
- 從檢視的結果可以發現不管是get還是describe都沒顯示檔案的内容,保護secrets意外暴露或者通過終端日志暴露
手工建立一個secrets
能夠通過yaml或者json檔案建立secrets
先擷取username和password的base64編碼:
$ echo -n "admin" | base64
YWRtaW4=
$ echo -n "1f2d1e2e67df" | base64
MWYyZDFlMmU2N2Rm
建立secrets的yaml:
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm
- data部分的value為base64加密過的資料
- Opaque:base64編碼格式的Secret,用來存儲密碼、密鑰等;
應用yaml:
$ kubectl create -f ./secret.yaml
secret "mysecret" created
檢視:
[[email protected] secret-examle]# kubectl get secret mysecret -o yaml
apiVersion: v1
data:
password: MWYyZDFlMmU2N2Rm
username: YWRtaW4=
kind: Secret
metadata:
creationTimestamp: --T06::Z
name: mysecret
namespace: default
resourceVersion: "3418648"
selfLink: /api/v1/namespaces/default/secrets/mysecret
uid: c9804b-e164---bc80ed
type: Opaque
decode:
$ echo "MWYyZDFlMmU2N2Rm" | base64 --decode
f2d1e2e67df
secrets能夠被以data volume的方式挂載或者以環境變量的方式暴露在pod中的container。也可以用在系統的其他方面,比如可以儲存用于系統其他部分的互動證書;
以檔案的方式在pod中使用secrets:
- 建立secrets或者使用現有的,多個pods可以關聯同一個secrets
- 修改pod的配置,在
部分添加,名字任意,配置spec.volumes[]
為 對應spec.volumes[].secret.secretName
對象的名字secrets
- 在每個需要
的secrets
添加container
部分, 注明spec.containers[].volumeMounts[]
以及注明spec.containers[].volumeMounts[].readOnly = true
到一個想防止secrets以及未使用的目錄名.spec.containers[].volumeMounts[].mountPath
- 修改鏡像或者指令行,使得程式能夠去挂載點下找對應的檔案,在secrets的data下的每個key都被映射成一個挂載點下的一個檔案名。
例子1:挂載secrets到一個volume:
mysecret.yaml
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
- 所有用到的secrets 放在
spec.volumes
- 如果在pod中有多個container,則每個container需要各自的
,而每個secrets隻需要一個volumeMounts
spec.volumes
應用并檢視:
[root@node- secret-examle]# kubectl create -f mysecret.yaml
pod "mypod" created
[root@node- secret-examle]# kubectl exec mypod ls /etc/foo/
password username
[root@node- secret-examle]# kubectl exec mypod cat /etc/foo/password
f2d1e2e67df
[root@node- secret-examle]# kubectl exec mypod cat /etc/foo/username
admin
将secrets的key映射至指定路徑:
mysecret.yaml
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
-
:這個key将被存放在username
目錄下/etc/foo/my-group/my-username
-
:這個key将不會被映射password
- 一旦聲明了
部分,所有想要被映射的key都必須列出來,否則将不比被挂載到指定的目錄下spec.volumes[].secret.items
應用并檢視:
[root@node- secret-examle]# kubectl delete pod mypod
pod "mypod" deleted
##terminating後
[root@node- secret-examle]# kubectl create -f mysecret.yaml
pod "mypod" created
[root@node- secret-examle]# kubectl exec mypod ls /etc/foo/
my-group
[root@node- secret-examle]# kubectl exec mypod cat /etc/foo/my-group/my-username
admin
設定secrets檔案的權限
可以單獨設定secrets的權限mode bit,如果沒有特别設定,預設權限為0644,json不支援八進制,是以用256 表示 0400.511表示 0777以此類推;
mysecret.yaml
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
- defaultMode: 256 :表示設定挂載點下所有檔案權限為
0400
應用并檢視:
[[email protected] secret-examle]# kubectl exec -ti mypod -- ls -l /etc/foo/
total
lrwxrwxrwx root root Dec : password -> ..data/password
lrwxrwxrwx root root Dec : username -> ..data/username
[[email protected] secret-examle]# kubectl exec -ti mypod -- ls -l /etc/foo/..data/username
-r-------- 1 root root 5 Dec 15 09:06 /etc/foo/..data/username
- 注意這邊挂載點目錄下的檔案為符号連結,真實檔案在挂載點下的
下..data/
mysecret.yaml
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
- mode: 511:設定單個secrets檔案的權限為 0700
檢視:
[root@node- secret-examle]# kubectl exec -ti mypod -- ls -l /etc/foo/..data/my-group/my-username
-rwxrwxrwx root root Dec : /etc/foo/..data/my-group/my-username
以環境變量的方式在pod中使用secrets:
通過修改
env[].valueFrom.secretKeyRef
将secrets映射至pod中的環境變量
mysecret.yaml
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
-
:變量名env.name
-
:secret名env[].valueFrom.secretKeyRef.name
-
:secret的data中的哪個keyenv[].valueFrom.secretKeyRef.name
應用并檢視:
[root@node- secret-examle]# kubectl exec -ti secret-env-pod bash
root@secret-env-pod:/data# echo $SECRET_USERNAME
admin
root@secret-env-pod:/data# echo $SECRET_PASSWORD
f2d1e2e67df
建立用來imagepull的 secrets:
- 用kubelet指令建立
$ kubectl create secret docker-registry myregistrykey \
--docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER \
--docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL
secret "myregistrykey" created.
- 用yaml檔案建立
首先本地用docker login進行登入,登入成功後,将在目前使用者的宿主目錄下建立
~/.docker/config.json
用base64将
~/.docker/config.json
加密
[root@node- secret-examle]# cat ~/.docker/config.json | base64 -w 0
ewoJImFJImF1dGgiOiAiWVdSdGFXNDZRV3hoWkdsdV.....S4wLWNlIChsaW51eCkiCgl9Cn0=
編輯yaml檔案
myregistrykey.yaml
apiVersion: v1
kind: Secret
metadata:
name: myregistrykey
namespace: default
data:
.dockerconfigjson: ewoJImFJImF1dGgiOiAiWVdSdGFXNDZRV3hoWkdsdV.....S4wLWNlIChsaW51eCkiCgl9Cn0=
type: kubernetes.io/dockerconfigjson
-
:将base64加密後的那串東西填到這裡.dockerconfigjson
- type: kubernetes.io/dockerconfigjson
建立并檢視:
[[email protected] secret-examle]# kubectl create -f myregistrykey.yaml
secret "myregistrykey" created
[[email protected] secret-examle]# kubectl describe secret myregistrykey
Name: myregistrykey
Namespace: default
Labels: <none>
Annotations: <none>
Type: kubernetes.io/dockerconfigjson
Data
====
.dockerconfigjson: 155 bytes
建立一個pod測試
foo.yaml
apiVersion: v1
kind: Pod
metadata:
name: foo
namespace: default
spec:
containers:
- name: foo
image: /elk/elasticsearch:v5
imagePullSecrets:
- name: myregistrykey
-
:根據自己的環境修改image: 172.18.169.134/elk/elasticsearch:v5.6.4
前提條件是做了私有倉庫,并設定項目為私有,即必須通過登入才能夠pull;
應用yaml并檢視:
[[email protected] secret-examle]# kubectl describe pod foo
Name: foo
Namespace: default
Node: node.131/
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 6s default-scheduler Successfully assigned foo to node.131
Normal SuccessfulMountVolume 6s kubelet, node.131 MountVolume.SetUp succeeded for volume "default-token-t8j7k"
Normal Pulling 5s kubelet, node.131 pulling image "172.18.169.134/elk/elasticsearch:v5.6.4"
Normal Pulled 5s kubelet, node.131 Successfully pulled image "172.18.169.134/elk/elasticsearch:v5.6.4"
Normal Created 5s kubelet, node.131 Created container
Normal Started 5s kubelet, node.131 Started container
其他一些細節:
* secrets 必須在所應用的pod之前先建立
* secrets 必須和所應用的pod在同一個namespace
* secrets 大小必須效益1MB
用例:帶有ssh key的pod
建立一個secret 包含本機的ssh key:
[[email protected] secret-examle]# kubectl create secret generic ssh-key-secret --from-file=ssh-privatekey=/root/.ssh/id_rsa --from-file=ssh-publickey=/root/.ssh/id_rsa.pub
secret "ssh-key-secret" created
- 注意,測試環境滿搞搞,正式環境不推薦,将暴露登陸資訊至群集中
建立pod
secret-test-pod.yaml
kind: Pod
apiVersion: v1
metadata:
name: secret-test-pod
labels:
name: secret-test
spec:
volumes:
- name: secret-volume
secret:
secretName: ssh-key-secret
containers:
- name: ssh-test-container
image: redis
volumeMounts:
- name: secret-volume
readOnly: true
mountPath: "/etc/secret-volume"
應用并測試:
[root@node- secret-examle]# kubectl exec secret-test-pod cat /etc/secret-volume/ssh-publickey
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDOB8IMzTYPcRb9h2pVoMNBI2Fy5EYPjXOEg11FyI1ffeo+C... root@node-
[root@node- secret-examle]# kubectl exec secret-test-pod cat /etc/secret-volume/ssh-privatekey
-----BEGIN RSA PRIVATE KEY-----
MIIEpQIBAAKCAQEAzgfCDM02D3EW/YdqVaDDQSNhcuRGD41zhINdRciNX33qPglK
Npks8CIresIAbPdBDc4P6FO0MncuVAoXZVOE4xOUYTcmnXkncwHp6amATMtJNFTc
OSzejJIokVQn9e7nmREU2bCTSUtlnR6804XNm78Tmh9P7dyI863OWEVdGdBKZFFz
G...
後續這個container可以用這個建立與主控端的ssh連結
用例:使用區分正式環境和測試環境認證資訊的pod
這個例子說明了其中一個pod使用正式的認證資訊,另一個pod使用測試環境的認證資訊:
$ kubectl create secret generic prod-db-secret --from-literal=username=produser --from-literal=password=Y4nys7f11
secret "prod-db-secret" created
$ kubectl create secret generic test-db-secret --from-literal=username=testuser --from-literal=password=iluvtests
secret "test-db-secret" created
建立pod:
apiVersion: v1
kind: List
items:
- kind: Pod
apiVersion: v1
metadata:
name: prod-db-client-pod
labels:
name: prod-db-client
spec:
volumes:
- name: secret-volume
secret:
secretName: prod-db-secret
containers:
- name: db-client-container
image: myClientImage
volumeMounts:
- name: secret-volume
readOnly: true
mountPath: "/etc/secret-volume"
- kind: Pod
apiVersion: v1
metadata:
name: test-db-client-pod
labels:
name: test-db-client
spec:
volumes:
- name: secret-volume
secret:
secretName: test-db-secret
containers:
- name: db-client-container
image: myClientImage
volumeMounts:
- name: secret-volume
readOnly: true
mountPath: "/etc/secret-volume"
- 有兩個pod,用不同的使用者名密碼通路資料庫
- 太麻煩了這裡就不做了 ^ ^
預期的效果是:
兩個不同的pod将擁有兩個不同的secrets file(内容):
/etc/secret-volume/username
/etc/secret-volume/password
用例:建立隐藏的secret volume(.file)
kind: Secret
apiVersion: v1
metadata:
name: dotfile-secret
data:
.secret-file: dmFsdWUtMg0KDQo=
---
kind: Pod
apiVersion: v1
metadata:
name: secret-dotfiles-pod
spec:
volumes:
- name: secret-volume
secret:
secretName: dotfile-secret
containers:
- name: dotfile-test-container
image: gcr.io/google_containers/busybox
command:
- ls
- "-l"
- "/etc/secret-volume"
volumeMounts:
- name: secret-volume
readOnly: true
mountPath: "/etc/secret-volume"
- 關鍵就在
,用.secret-file
開頭的方式建立secret的keyname,後續被挂載的時候也将被挂載成’.’開頭的檔案。。.
- 貌似用ls看不了,用ls -a 一樣可以看到。。算是隐藏吧
- 挺無聊的,也不做了 ^ ^
最後再生産環境需要注意apiserver通路權限對secrets的控制,
watch
和
list
将能夠看到
secret
的值,擁有
get
請求就可以利用secret進行相關的使用了。
至此secrets 部分算是寫完了。。
本系列其他内容:
- 01-環境準備
- 02-etcd群集搭建
- 03-kubectl管理工具
- 04-master搭建
- 05-node節點搭建
- 06-addon-calico
- 07-addon-kubedns
- 08-addon-dashboard
- 09-addon-kube-prometheus
- 10-addon-EFK
- 11-addon-Harbor
- 12-addon-ingress-nginx
- 13-addon-traefik
參考資料:
https://kubernetes.io/docs/concepts/configuration/secret/