簡介
ConfigMap是用來存儲一些非安全的配置信息,如果涉及到一些安全相關的數據的話用ConfigMap就非常不妥了,
因爲ConfigMap明文存儲的,這個時候j就應該使用Secret
-
Secret 對象類型用來保存敏感信息,例如密碼、OAuth 令牌和 ssh key。
-
敏感信息放在 secret 中比放在 Pod 的定義或者容器鏡像中來說更加安全和靈活。
-
Pod 可以用兩種方式使用 secret:
- 作爲 volume 中的文件被掛載到 pod 中的一個或者多個容器裏。
- 當 kubelet 爲 pod 拉取鏡像時使用(倉庫認證信息)。
-
Secret的類型:
- Service Account:Kubernetes 自動創建包含訪問 API 憑據的 secret,並自動修改pod 以使用此類型的 secret。
- Opaque:使用base64編碼存儲信息,可以通過base64 --decode解碼獲得原始數據,因此安全性弱。
- kubernetes.io/dockerconfigjson:用於存儲docker registry的認證信息。
Service Account
[root@server2 manifest]# kubectl get secrets
NAME TYPE DATA AGE
basic-auth Opaque 1 7h52m
default-token-j7pl7 kubernetes.io/service-account-token 3 12d /其實就是個token
tls-secret kubernetes.io/tls 2 26h
運行在pod裏的進程需要調用Kubernetes API
以及非Kubernetes API
的其它服務。Service Account它並不是給kubernetes集羣的用戶使用的,而是給pod裏面的進程使用的,它爲pod提供必要的身份認證,讓它可以通過apiserver
獲取信息。
- 每個namespace下有一個名爲
default
的默認的ServiceAccount
對象:
[root@server2 manifest]# kubectl get sa --all-namespaces
NAMESPACE NAME SECRETS AGE
default default 1 12d
ingress-nginx default 1 29h
ingress-nginx ingress-nginx 1 29h
ingress-nginx ingress-nginx-admission 1 29h
kube-node-lease default 1 12d
kube-public default 1 12d
kube-system attachdetach-controller 1 12d
[root@server2 manifest]# kubectl describe sa default
Name: default
Namespace: default
Labels: <none>
Annotations: <none>
Image pull secrets: <none>
Mountable secrets: default-token-j7pl7 /可以掛載的secret
Tokens: default-token-j7pl7 /token就是一個secret
Events: <none>
- serviceaccout 創建時 Kubernetes 會默認創建對應的 secret。對應的 secret 會自動掛載到Pod 的 /run/secrets/kubernetes.io/serviceaccount 目錄中。
# 進入pod中查看secret的掛載信息。
[root@server2 manifest]# kubectl exec my-nginx-7f45d597d5-n7jft -- ls /var/run/secrets/kubernetes.io/serviceaccount
ca.crt
namespace
token /裏面有證書,命名空間和token等信息。
- ServiceAccount裏有一個名爲Tokens的可以作爲Volume一樣被Mount到Pod裏的Secret,當Pod啓動時這個Secret會被自動Mount到Pod的指定目錄下,用來協助完成Pod中的進程訪問API Server時的身份鑑權過程。
[root@server2 manifest]# kubectl describe pod my-nginx-7f45d597d5-n7jft
Mounts:
/etc/nginx/conf.d from config-volume (rw)
/var/run/secrets/kubernetes.io/serviceaccount from default-token-j7pl7 (ro)
//secret掛載到了這裏
default-token-j7pl7: //secret 就是 sa 裏面的一個token
Type: Secret (a volume populated by a Secret)
SecretName: default-token-j7pl7
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Opaque Secret
Opaque使用base64編碼存儲信息,其value爲base64編碼後的值。我們需要自行創建。
我們在做ingress的 basic-auth 其實就是一個opaque 類型的secret:
[root@server2 manifest]# kubectl get secrets
NAME TYPE DATA AGE
basic-auth Opaque 1 7h52m //這個
default-token-j7pl7 kubernetes.io/service-account-token 3 12d
tls-secret kubernetes.io/tls 2 26h
命令行創建secret:
[root@server2 ~]# kubectl create secret generic dev-db-secret --from-literal=username=devuser --from-literal=password=S\!B\\*d\$zDsb
secret/dev-db-secret created
[root@server2 ~]# kubectl get secrets
NAME TYPE DATA AGE
dev-db-secret Opaque 2 2s
注意如果密碼具有特殊字符,則需要使用 \ 字符對其進行轉義
在文件中創建secret:
[root@server2 ~]# echo -n 'admin' > ./username.txt
[root@server2 ~]# echo -n 'westos' > ./password.txt
[root@server2 ~]# kubectl create secret generic db-user-pass --from-file=./username.txt --from-file=./password.txt
kubesecret/db-user-pass created
[root@server2 ~]# kubectl get secrets
NAME TYPE DATA AGE
db-user-pass Opaque 2 4s
默認情況下 kubectl get和kubectl describe 爲了安全是不會顯示密碼的內容,可以通過以下方式查看:
[root@server2 ~]# kubectl get secrets dev-db-secret -o yaml
apiVersion: v1
data:
password: UyFCXCpkJHpEc2I=
username: ZGV2dXNlcg==
kind: Secret
metadata:
creationTimestamp: "2020-07-01T09:12:14Z"
managedFields:
- apiVersion: v1
fieldsType: FieldsV1
fieldsV1:
f:data:
.: {}
f:password: {}
f:username: {}
f:type: {}
manager: kubectl
operation: Update
time: "2020-07-01T09:12:14Z"
name: dev-db-secret
namespace: default
resourceVersion: "478900"
selfLink: /api/v1/namespaces/default/secrets/dev-db-secret
uid: e08f8d85-c4ac-4e82-a177-ab70a0e55c1e
type: Opaque
[root@server2 ~]# echo UyFCXCpkJHpEc2I= |base64 -d
S!B\*d$zDsb
[root@server2 ~]# echo ZGV2dXNlcg== |base64 -d
devuser //進行轉換就出來了
yaml清單secret
[root@server2 ~]# echo admin |base64
YWRtaW4K
[root@server2 ~]# echo caoaoyuan |base64
Y2FvYW95dWFuCg==
[root@server2 ~]# vim mysecret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: Y2FvYW95dWFuCg==
[root@server2 cm]# kubectl apply -f mysecret.yaml
kubec gsecret/mysecret created
[root@server2 cm]# kubectl get secrets
NAME TYPE DATA AGE
basic-auth Opaque 1 8h
db-user-pass Opaque 2 10m
default-token-j7pl7 kubernetes.io/service-account-token 3 12d
dev-db-secret Opaque 2 9m10s
mysecret Opaque 2 6s //這個
將Secret掛載到Volume中:
[root@server2 cm]# vim mysecret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: Y2FvYW95dWFuCg==
---
apiVersion: v1
kind: Pod
metadata:
name: mysecret
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: secrets
mountPath: "/secret" /掛接到這個位置,pod會自動創建
readOnly: true
volumes:
- name: secrets
secret:
secretName: mysecret
[root@server2 cm]# kubectl apply -f mysecret.yaml
secret/mysecret unchanged
pod/mysecret created
[root@server2 cm]# kubectl exec mysecret -- ls /secret
password
username
[root@server2 cm]# kubectl exec mysecret -- cat /secret/password
caoaoyuan
[root@server2 cm]# kubectl exec mysecret -- cat /secret/username
admin
就掛接進去了。
向指定路徑映射 secret 密鑰:
[root@server2 cm]# vim mysecret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: Y2FvYW95dWFuCg==
---
apiVersion: v1
kind: Pod
metadata:
name: mysecret
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: secrets
mountPath: "/secret"
readOnly: true
volumes:
- name: secrets
secret:
secretName: mysecret
items:
- key: username /選擇mysecret中的username這個key
path: my-group/my-username /將它掛載道這個位置
[root@server2 cm]# kubectl apply -f mysecret.yaml
secret/mysecret created
pod/mysecret created
[root@server2 cm]# kubectl exec mysecret -- ls /secret/
my-group
[root@server2 cm]# kubectl exec mysecret -- ls /secret/my-group
my-username
[root@server2 cm]# kubectl exec mysecret -- cat /secret/my-group/my-username
admin
可以看出值有指定的數據掛接到了這裏。
將Secret設置爲環境變量:
[root@server2 cm]# vim mysecret.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: Y2FvYW95dWFuCg==
---
apiVersion: v1
kind: Pod
metadata:
name: secret-env
spec:
containers:
- name: nginx
image: nginx
env:
- name: SECRET_USERNAME /自己定義名稱
valueFrom:
secretKeyRef:
name: mysecret /調用secret的值
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: password
[root@server2 cm]# kubectl apply -f mysecret.yaml
secret/mysecret unchanged
pod/secret-env created
[root@server2 cm]# kubectl exec secret-env -- env
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=secret-env
SECRET_PASSWORD=caoaoyuan
SECRET_USERNAME=admin
KUBERNETES_SERVICE_PORT_HTTPS=443
HOME=/root
環境變量讀取Secret很方便,但是無法支撐Secret動態更新。
kubernetes.io/dockerconfigjson
kubernetes.io/dockerconfigjson 類型的secret 用於存儲 docker registry 的認證信息.
我們目前用的私有倉庫是harbor倉庫,我們現在有一個未公開的倉庫,裏面又一個鏡像:
現在我們去拉取:
[root@server3 ~]# docker pull reg.caoaoyuan.org/caoaoyuan/game2048
Using default tag: latest
Error response from daemon: pull access denied for reg.caoaoyuan.org/caoaoyuan/game2048, r
是被拒絕的我們值有登陸進去才能拉取:
[root@server3 ~]# docker login reg.caoaoyuan.org
Username: admin
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store
Login Succeeded
[root@server3 ~]# docker pull reg.caoaoyuan.org/caoaoyuan/game2048
Using default tag: latest
latest: Pulling from caoaoyuan/game2048
534e72e7cedc: Pull complete
f62e2f6dfeef: Pull complete
fe7db6293242: Pull complete
3f120f6a2bf8: Pull complete
4ba4e6930ea5: Pull complete
Digest: sha256:8a34fb9cb168c420604b6e5d32ca6d412cb0d533a826b313b190535c03fe9390
Status: Downloaded newer image for reg.caoaoyuan.org/caoaoyuan/game2048:latest
reg.caoaoyuan.org/caoaoyuan/game2048:latest
而我們登陸的信息保存在用戶主目錄下的 .docker 下:
[root@server3 ~]# cd .docker/
[root@server3 .docker]# cat config.json
{
"auths": {
"reg.caoaoyuan.org": {
"auth": "YWRtaW46Y2FvYW95dWFu"
}
},
"HttpHeaders": {
"User-Agent": "Docker-Client/19.03.11 (linux)"
}
[root@server3 .docker]# docker rmi reg.caoaoyuan.org/caoaoyuan/game2048:latest
// 先刪除鏡像
[root@server3 .docker]# docker logout //退出
[root@server3 .docker]# cat config.json
{
"auths": {},
"HttpHeaders": {
"User-Agent": "Docker-Client/19.03.11 (linux)"
}
這種方式是一種不安全且不夠靈活的方式,我們可以通過kubernetes.io/dockerconfigjson 類型的secret 來實現簡化
手動創建:
[root@server2 cm]# kubectl create secret docker-registry myregistrykey \ /secret 名稱
--docker-server=reg.caoaoyuan.org \ /倉庫地址
--docker-username=admin --docker-password=caoaoyuan \ /倉庫的用戶密碼
[email protected] /用戶郵箱
secret/myregistrykey created
[root@server2 cm]# kubectl get secrets
NAME TYPE DATA AGE
basic-auth Opaque 1 9h
db-user-pass Opaque 2 98m
default-token-j7pl7 kubernetes.io/service-account-token 3 13d
dev-db-secret Opaque 2 97m
myregistrykey kubernetes.io/dockerconfigjson 1 94s
使用:
[root@server2 cm]# cat pod.yml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: game2048
image: reg.caoaoyuan.org/caoaoyuan/game2048
imagePullSecrets:
- name: myregistrykey
secret/myregistrykey created
[root@server2 cm]# kubectl apply -f pod.yml
pod/mypod created
[root@server2 cm]# kubectl get pod
NAME READY STATUS RESTARTS AGE
my-nginx-7f45d597d5-n7jft 1/1 Running 0 4h19m
mypod 1/1 Running 0 9s
/注意這時我們並沒有docker login。