?? 歡迎大家來到景天科技苑??
🎈🎈 養成好習慣,先贊后看哦~🎈🎈
🏆 作者簡介:景天科技苑
🏆《頭銜》:大廠架構師,華為云開發者社區專家博主,阿里云開發者社區專家博主,CSDN全棧領域優質創作者,掘金優秀博主,51CTO博客專家等。
🏆《博客》:Python全棧,前后端開發,小程序開發,人工智能,js逆向,App逆向,網絡系統安全,數據分析,Django,fastapi,flask等框架,云原生k8s,linux,shell腳本等實操經驗,網站搭建,數據庫等分享。所屬的專欄:云原生K8S,零基礎到進階實戰
景天的主頁:景天科技苑
文章目錄
- 1.Secret概述
- 1.1 Secret是什么?
- 1.2 使用Secret
- 1、通過環境變量引入Secret
- 2、通過volume掛載Secret
1.Secret概述
1.1 Secret是什么?
前面我們一起探討了k8s的Configmap一般是用來存放明文數據的,如配置文件,
對于一些敏感數據,如密碼、私鑰等數據時,要用secret類型。
Secret解決了密碼、token、秘鑰等敏感數據的配置問題,而不需要把這些敏感數據暴露到鏡像或者Pod Spec中。
Secret可以以Volume或者環境變量的方式使用。
要使用 secret,pod 需要引用 secret。Pod 可以用兩種方式使用 secret:
作為 volume 中的文件被掛載到 pod 中的一個或者多個容器里,
或者當 kubelet 為 pod 拉取鏡像時使用。
secret可選參數有三種:
- generic: 通用類型,通常用于存儲密碼數據。
- tls:此類型僅用于存儲私鑰和證書。
- docker-registry: 若要保存docker倉庫的認證信息的話,就必須使用此種類型來創建。
Secret類型有三種:
-
Service Account:用于被 serviceaccount 引用。
serviceaccout 創建時 Kubernetes 會默認創建對應的 secret。
Pod 如果使用了 serviceaccount,對應的 secret 會自動掛載到 Pod 的 /run/secrets/kubernetes.io/serviceaccount 目錄中。 -
Opaque:base64編碼格式的Secret,用來存儲密碼、秘鑰等。可以通過base64 --decode解碼獲得原始數據,因此安全性弱
-
kubernetes.io/dockerconfigjson:用來存儲私有docker registry的認證信息。
1.2 使用Secret
1、通過環境變量引入Secret
#把mysql的root用戶的password創建成secret
[root@master01 secret ]#kubectl create secret generic mysql-password --from-literal=password=Jxxxxxxx3x
secret/mysql-password created
[root@master01 secret ]#kubectl get secret
NAME TYPE DATA AGE
default-token-xc8dr kubernetes.io/service-account-token 3 12d
mysql-password Opaque 1 19s
nfs-provisioner-token-8mxt9 kubernetes.io/service-account-token 3 4d22h
[root@master01 secret ]#kubectl describe secret mysql-password
Name: mysql-password
Namespace: default
Labels: <none>
Annotations: <none>Type: OpaqueData
====
password: 14 bytes
#password的值是加密的,
#但secret的加密是一種偽加密,它僅僅是將數據做了base64的編碼.
#創建pod,引用secret
[root@master01 secret ]#vim pod-secret.yaml
apiVersion: v1
kind: Pod
metadata:name: pod-secretlabels:app: myapp
spec:containers:- name: myappimage: ikubernetes/myapp:v1imagePullPolicy: IfNotPresentports:- name: httpcontainerPort: 80env:- name: MYSQL_ROOT_PASSWORD #它是Pod啟動成功后,Pod中容器的環境變量名.valueFrom:secretKeyRef:name: mysql-password #這是secret的對象名key: password #它是secret中的key名
[root@master01 secret ]#kubectl apply -f pod-secret.yaml
pod/pod-secret created
[root@master01 secret ]#kubectl exec -it pod-secret -- /bin/sh
/ # printenv
MYAPP_SVC_PORT_80_TCP_ADDR=10.98.57.156
KUBERNETES_SERVICE_PORT=443
KUBERNETES_PORT=tcp://192.168.0.1:443
MYAPP_SVC_PORT_80_TCP_PORT=80
HOSTNAME=pod-secret
SHLVL=1
MYAPP_SVC_PORT_80_TCP_PROTO=tcp
HOME=/root
MYSQL_ROOT_PASSWORD=Jxxxxxxxx3x 這就是傳遞進來的變量
MYAPP_SVC_PORT_80_TCP=tcp://10.98.57.156:80
TERM=xterm
NGINX_VERSION=1.12.2
KUBERNETES_PORT_443_TCP_ADDR=192.168.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
MYAPP_SVC_SERVICE_HOST=10.98.57.156
KUBERNETES_PORT_443_TCP=tcp://192.168.0.1:443
KUBERNETES_SERVICE_PORT_HTTPS=443
PWD=/
KUBERNETES_SERVICE_HOST=192.168.0.1
MYAPP_SVC_SERVICE_PORT=80
MYAPP_SVC_PORT=tcp://10.98.57.156:80
傳遞到pod里面后,自動解密了
2、通過volume掛載Secret
1)創建Secret
手動加密,基于base64加密
[root@xianchaomaster1 ~]# echo -n 'admin' | base64
YWRtaW4=
echo -n 'jingtian123456f' | base64
解碼:
echo amluZ3RpYW4xMjM0NTZm|base64 -d
2)創建yaml文件
[root@master01 secret ]#vim secret.yaml
apiVersion: v1
kind: Secret
metadata:name: mysecret
type: Opaque
data:username: YWRtaW4=password: amluZ3RpYW4xMjM0NTZm
[root@master01 secret ]#kubectl apply -f secret.yaml
secret/mysecret created
[root@master01 secret ]#
[root@master01 secret ]#kubectl get secret
NAME TYPE DATA AGE
default-token-xc8dr kubernetes.io/service-account-token 3 12d
mysecret Opaque 2 7s
mysql-password Opaque 1 14m
nfs-provisioner-token-8mxt9 kubernetes.io/service-account-token 3 4d23h
[root@master01 secret ]#kubectl describe secret mysecret
Name: mysecret
Namespace: default
Labels: <none>
Annotations: <none>Type: OpaqueData
====
password: 15 bytes
username: 5 bytes
3)將Secret掛載到Volume中
[root@master01 secret ]#vim pod_secret_volume.yaml
apiVersion: v1
kind: Pod
metadata:name: pod-secret-volume
spec:containers:- name: myappimage: registry.cn-beijing.aliyuncs.com/google_registry/myapp:v1volumeMounts:- name: secret-volumemountPath: /etc/secretreadOnly: truevolumes:- name: secret-volumesecret:secretName: mysecret
[root@master01 secret ]#kubectl apply -f pod_secret_volume.yaml
pod/pod-secret-volume created
[root@master01 secret ]#kubectl get pods
NAME READY STATUS RESTARTS AGE
mysql-pod 0/1 Completed 0 88m
mysql-pod-envfrom 0/1 Completed 0 76m
mysql-pod-volume 0/1 Completed 0 65m
nfs-provisioner-847fb5b8f5-lzvcf 1/1 Running 7 (6h38m ago) 3d7h
pod-pvc 1/1 Running 1 (7h38m ago) 3d5h
pod-secret 1/1 Running 0 11m
pod-secret-volume 1/1 Running 0 15s
test-hostpath 2/2 Running 6 (7h38m ago) 4d5h
test-nfs-volume 1/1 Running 3 (7h38m ago) 4d3h
web-0 1/1 Running 1 (7h38m ago) 2d22h
web-1 1/1 Running 1 (7h38m ago) 2d22h
web-2 1/1 Running 1 (7h38m ago) 2d22h
web-3 1/1 Running 1 (7h38m ago) 2d22h
進去容器查看
[root@master01 secret ]#kubectl exec -it pod-secret-volume -- /bin/sh/ # ls /etc/secret/
password username
[root@master01 secret ]#kubectl exec -it pod-secret-volume -- /bin/sh
/ # cat /etc/sec
secret/ securetty
/ # cat /etc/secret/username
admin/ # / # cat /etc/secret/password
jingtian123456f/ #
#由上可見,以卷的方式掛載到pod ,在pod中的secret信息實際已經被解密。
Secret 的類型
創建 Secret 時,你可以使用 Secret 資源的 type 字段,或者與其等價的 kubectl 命令行參數(如果有的話)為其設置類型。
Secret 類型有助于對 Secret 數據進行編程處理。
Kubernetes 提供若干種內置的類型,用于一些常見的使用場景。
針對這些類型,Kubernetes 所執行的合法性檢查操作以及對其所實施的限制各不相同。
內置類型 用法
Opaque 用戶定義的任意數據
kubernetes.io/service-account-token 服務賬號令牌
kubernetes.io/dockercfg ~/.dockercfg 文件的序列化形式
kubernetes.io/dockerconfigjson ~/.docker/config.json 文件的序列化形式
kubernetes.io/basic-auth 用于基本身份認證的憑據
kubernetes.io/ssh-auth 用于 SSH 身份認證的憑據
kubernetes.io/tls 用于 TLS 客戶端或者服務器端的數據
bootstrap.kubernetes.io/token 啟動引導令牌數據
docker私有倉庫,加了https認證后拉取鏡像:
imagePullSecret資源將Secret提供的密碼傳遞給kubelet從而在拉取鏡像前完成必要的認證過程,
簡單說就是你的鏡像倉庫是私有的,每次拉取是需要認證的。
創建docker-registry類型的Secret對象,并在定義pod資源時明確通過"imagePullSecrets"字段來申明使用哪個私鑰去認證;
創建docker-registry類型的Secret對象,然后把它添加到某個ServiceAccount對象中,
使用了這個ServiceAccount對象創建出來的pod就自然而然通過認證獲取到鏡像;
配置過程
這里創建Secret對象有兩種方式,各有千秋。
方式一:通過命令行直接創建Secret
kubectl create secret docker-registry video-docker-redistry-key \--docker-server=10.3.9.107:5000 \--docker-username='gsafety' \--docker-password='123456'
查看key
# kubectl get secret
NAME TYPE DATA AGE
default-token-d9phm kubernetes.io/service-account-token 3 19h
video-docker-redistry-key kubernetes.io/dockerconfigjson 1 2s
最后在yaml文件中使用這個創建出來的Secret:
apiVersion: v1
kind: Pod
metadata:name: foonamespace: awesomeapps
spec:containers:- name: fooimage: janedoe/awesomeapp:v1imagePullSecrets:- name: xxx-key
方式二:通過現存的docker認證文件來創建Secret,首先使用docker login 登錄到某個倉庫,會在本地保存認證信息
[root@master01 ~ ]#kubectl create secret generic harborsecret --from-file=.dockerconfigjson=/root/.docker/config.json --type=kubernetes.io/dockerconfigjson
secret/harborsecret created
或者:
#Create a new secret named my-secret from ~/.docker/config.jsonkubectl create secret docker-registry my-secret --from-file=.dockerconfigjson=path/to/.docker/config.json
[root@master01 ~ ]#kubectl create secret docker-registry my-secret --from-file=.dockerconfigjson=/root/.docker/config.json
secret/my-secret created
注意:config.json文件需要在主機上通過docker login 的方式登錄后,才會生成。
這種方式有一個好處,就是如果有多個鏡像倉庫,都先存在于一個config.json文件中,然后通過命令打入Secret。
[root@master01 ~ ]#kubectl get secret harborsecret -oyaml
apiVersion: v1
data:.dockerconfigjson: ewoJImF1dGhzIjogewoJCSJyZXBvc2l0b3J5Lmd1b2tpbmdoay5jb20iOiB7CgkJCSJhdXRoIjogIllXUnRhVzQ2VkdacGFHSXRjSEp2WkhWamRFQXlNREl5IgoJCX0KCX0KfQ==
kind: Secret
metadata:creationTimestamp: "2022-11-07T05:52:41Z"name: harborsecretnamespace: defaultresourceVersion: "2355"uid: 14503d3d-3992-4d31-9b1d-ff4049990d51
type: kubernetes.io/dockerconfigjson