一、Secret
Secret :用來保存一些敏感信息,比如數據庫的用戶名密碼或者祕鑰。
概覽
Secret是用來保存小片敏感數據的k8s資源,例如密碼,token,或者祕鑰。這類數據當然也可以存放在Pod或者鏡像中,但是放在Secret中是爲了更方便的控制如何使用數據,並減少暴露的風險。
用戶可以創建自己的secret,系統也會有自己的secret。
Pod需要先引用才能使用某個secret,Pod有2種方式來使用secret:作爲volume的一個域被一個或多個容器掛載;在拉取鏡像的時候被kubelet引用。
內建的Secrets
由ServiceAccount創建的API證書附加的祕鑰
k8s自動生成的用來訪問apiserver的Secret,所有Pod會默認使用這個Secret與apiserver通信
1. Secret類型
Secret有三種類型:
- Opaque:使用base64編碼存儲信息,可以通過base64 --decode解碼獲得原始數據,因此安全性弱。
- kubernetes.io/dockerconfigjson:用於存儲docker registry的認證信息。
- kubernetes.io/service-account-token:用於被 serviceaccount 引用。serviceaccout 創建時 Kubernetes 會默認創建對應的 secret。Pod 如果使用了 serviceaccount,對應的 secret 會自動掛載到 Pod 的 /run/secrets/kubernetes.io/serviceaccount 目錄中。
舉例:保存數據庫的用戶名和密碼
用戶名: root
密碼: 123.com
1、通過--from-literal(文字的)
[root@master secret]# kubectl create secret generic mysecret1 --from-literal=username=root --from-literal=pasword=123.com
generic:通用的,一般的加密方式
查看一下
[root@master secret]# kubectl get secrets
類型是Opaque(不透明的)
2、通過from-file(文件)
新建兩個文件並分別寫入用戶名和密碼
[root@master secret]# echo root > username
[root@master secret]# echo 123.com > password
創建一個secret
[root@master secret]# kubectl create secret generic mysecret2 --from-file=username --from-file=password
查看一下
[root@master secret]# kubectl get secrets
3、通過-- from- env-file:
創建一個文件寫入用戶名和密碼
[root@master secret]#vim env.txt
username=root
password=123.com
創建一個secret
[root@master secret]# kubectl create secret generic mysecret3 --from-env-file=env.txt
查看一下
[root@master secret]# kubectl get secrets
4、通過yaml配置文件
(1)把需要保存的數據加密(”base64“的方式)
[root@master secret]# echo root | base64
cm9vdAo=
[root@master secret]# echo 123.com | base64
MTIzLmNvbQo=
解碼:
[root@master secret]# echo -n cm9vdAo | base64 --decode root [root@master secret]# echo -n MTIzLmNvbQo | base64 --decode 123.com
(2)編寫secre4的yaml文件
[root@master secret]# vim secret4.yaml
apiVersion: v1
kind: Secret
metadata:
name: mysecret4
data:
username: cm9vdAo=
password: MTIzLmNvbQo=
執行一下
[root@master secret]# kubectl apply -f secret4.yaml
(3)查看一下
[root@master secret]# kubectl get secrets
如果來使用Secret資源
1. 以Volume掛載的方式
使用Secret
secret可以作爲數據卷掛載或者作爲環境變量暴露給Pod中的容器使用,也可以被系統中的其他資源使用。比如可以用secret導入與外部系統交互需要的證書文件等。
在Pod中以文件的形式使用secret
- 創建一個Secret,多個Pod可以引用同一個Secret
- 修改Pod的定義,在spec.volumes[]加一個volume,給這個volume起個名字,spec.volumes[].secret.secretName記錄的是要引用的Secret名字
- 在每個需要使用Secret的容器中添加一項spec.containers[].volumeMounts[],指定spec.containers[].volumeMounts[].readOnly = true,spec.containers[].volumeMounts[].mountPath要指向一個未被使用的系統路徑。
- 修改鏡像或者命令行使系統可以找到上一步指定的路徑。此時Secret中data字段的每一個key都是指定路徑下面的一個文件名
編寫pod的yaml文件
[root@master secret]# vim pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: busybox
args:
- /bin/sh
- -c
- sleep 300000
volumeMounts:
- name: secret-test
mountPath: "/etc/secret-test" #pod中的路徑
readOnly: true #是否只讀
volumes:
- name: secret-test
secret:
secretName: mysecret1
每一個被引用的Secret都要在spec.volumes中定義
如果Pod中的多個容器都要引用這個Secret那麼每一個容器定義中都要指定自己的volumeMounts,但是Pod定義中聲明一次spec.volumes就好了。
映射secret key到指定的路徑
可以控制secret key被映射到容器內的路徑,利用spec.volumes[].secret.items來修改被映射的具體路徑
執行一下
[root@master secret]# kubectl apply -f pod.yaml
Secret文件權限
可以指定secret文件的權限,類似linux系統文件權限,如果不指定默認權限是0644,等同於linux文件的-rw-r--r--權限
進入容器查看保存的數據
[root@master secret]# kubectl exec -it mypod /bin/sh
/ # cd /etc/secret-test/
/etc/secret-test # ls
pasword username
/etc/secret-test # cat username
root
/etc/secret-test # cat pasword
123.com
測試是否有隻讀權限
123.com/etc/secret-test # echo admin > username
/bin/sh: can't create username: Read-only file system
1.1 自定義存放數據的文件名的yaml文件
[root@master yaml]# vim pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: busybox
args:
- /bin/sh
- -c
- sleep 300000
volumeMounts:
- name: secret-test
mountPath: "/etc/secret-test" #pod中的路徑
readOnly: true #是否只讀
volumes:
- name: secret-test
secret:
secretName: mysecret1
items:
- key: username
path: my-group/my-username #自定義的容器中的目錄
- key: password
path: my-group/my-password #自定義的容器中的目錄
執行一下
[root@master yaml]# kubectl apply -f pod.yaml
查看一下
[root@master secret]# kubectl exec -it mypod /bin/sh
//進入容器查看
cat /etc/secret-test/my-group/my-password
123.com
cat /etc/secret-test/my-group/my-username
root
1.2 如果,現在將secret資源內保存的數據進行更新,請問,使用此數據的應用內,數據是是否也會更新?
會實時更新(這裏引用數據,是以volumes掛 載使用數據的方式)。
更新mysecret1的數據: password ---> admin YWRtaW4K (base64)
可以通過edit 命令,直接修改。
[root@master secret]# kubectl edit secrets mysecret1
查看一下
[root@master secret]# kubectl exec -it mypod /bin/sh
//進入容器查看
cat /etc/secret-test/my-group/my-password
admin
cat /etc/secret-test/my-group/my-username
root
數據已經成功更新了
2、以環境變量的方式
創建一個Secret,多個Pod可以引用同一個Secret
修改pod的定義,定義環境變量並使用env[].valueFrom.secretKeyRef指定secret和相應的key
修改鏡像或命令行,讓它們可以讀到環境變量
編寫pod的yaml文件
[root@master secret]# vim pod-env.yaml
apiVersion: v1
kind: Pod
metadata:
name: mypod2
spec:
containers:
- name: mypod
image: busybox
args:
- /bin/sh
- -c
- sleep 300000
env:
- name: SECRET_USERNAME
valueFrom:
secretKeyRef:
name: mysecret2
key: username
- name: SECRET_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret2
key: password
執行一下
[root@master secret]# kubectl apply -f pod-env.yaml
查看一下
[root@master secret]# kubectl get pod
進入容器查看保存的數據
[root@master secret]# kubectl exec -it mypod2 /bin/sh
/ # echo $SECRET_USERNAME
root
/ # echo $SECRET_PASSWORD
123.com
2.1 更新sevret文件的內容
[root@master yaml]# kubectl edit secrets mysecret2
//修改保存文件的內容
查看一下
[root@master secret]# kubectl exec -it mypod2 /bin/sh
/ # echo $SECRET_USERNAME
root
/ # echo $SECRET_PASSWORD
123.com
等待了一定時間後,可以看到這個數據並沒有沒有改變
總結
如果引用secret數據的應用, 要求會隨着secret資源對象內保存的數據的更新,而實時更新,那麼應該使用volumes掛載的方式引用資源因爲用環境變量的方式引用不會實時更新數據。
二、ConfigMap
上面提到的Secret可以爲Pod提供機密數據的存儲,而對於一些非機密敏感的數據,像一些應用的配置信息啊神馬的,則可以使用Configmap。
Configmap的創建與使用方式與Secret非常類似,不同點只在於數據以明文形式存放(不過,我覺得Secret的密文形式也並不密文,只能算得上是簡單編碼)。
和Secret資源類似,不同之處在於,secret 資源保存的是敏感信息,而Configmap保存的是以明文方式存放的數據。
username:adam
age:18
創建的四種方式
1、通過-- from- literal(文字的):
[root@master yaml]# kubectl create configmap myconfigmap1 --from-literal=username=adam --from-literal=age=18
查看一下
[root@master yaml]# kubectl get cm
[root@master yaml]# kubectl describe cm
2、通過--from-file (文件) :
[root@master yaml]# echo adam > username
[root@master yaml]# echo 18 > age
創建
[root@master yaml]# kubectl create configmap myconfigmap2 --from-file=username --from-file=age
查看一下
[root@master yaml]# kubectl describe cm
3、通過--from- env-file:
[root@master yaml]# vim env.txt
username=adam
age=18
創建
[root@master yaml]# kubectl create configmap myconfigmap3 --from-env-file=env.txt
查看一下
[root@master configmap]# kubectl describe cm
4、通過yaml配置文件:
[root@master yaml]# vim configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: myconfigmap4
data:
username: 'adam'
age: '18'
創建
[root@master yaml]# kubectl apply -f configmap.yaml
查看一下
[root@master yaml]# kubectl describe cm
如何來使用configmap資源
1. 以Volume掛載的方式
[root@master yaml]# vim v-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod1
spec:
containers:
- name: mypod
image: busybox
args:
- /bin/sh
- -c
- sleep 300000
volumeMounts:
- name: cmp-test
mountPath: "/etc/cmp-test"
readOnly: true
volumes:
- name: cmp-test
configMap:
name: myconfigmap1
執行一下
[root@master configmap]# kubectl apply -f v-pod.yaml
查看一下
[root@master configmap]# kubectl exec -it pod1 /bin/sh
//進入容器查看一下
> cat /etc/cmp-test/age
18/
> cat /etc/cmp-test/username
adam/
1.1 自定義存放數據的文件名的yaml文件
[root@master configmap]# vim v-pod2.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod3
spec:
containers:
- name: mypod
image: busybox
args:
- /bin/sh
- -c
- sleep 300000
volumeMounts:
- name: cmp-test
mountPath: "/etc/cmp-test"
readOnly: true
volumes:
- name: cmp-test
configMap:
name: myconfigmap1
items:
- key: username
path: my-group/my-username #自定義的容器中的目錄
- key: age
path: my-group/my-age #自定義的容器中的目錄
執行一下
[root@master configmap]# kubectl apply -f v-pod2.yaml
查看一下
[root@master configmap]# kubectl exec -it pod3 /bin/sh
//進入容器查看
> cat /etc/cmp-test/my-group/my-username
adam/
> cat /etc/cmp-test/my-group/my-age
18/
1.2 如果,現在將secret資源內保存的數據進行更新,請問,使用此數據的應用內,數據是是否也會更新?
[root@master configmap]# kubectl edit cm myconfigmap1
查看一下
[root@master configmap]# kubectl exec -it pod3 /bin/sh
//進入容器查看
> cat /etc/cmp-test/my-group/my-username
adam/
> cat /etc/cmp-test/my-group/my-age
10
可以看到更新成功
2.以環境變量的方式
[root@master configmap]# vim e-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: pod2
spec:
containers:
- name: mypod
image: busybox
args:
- /bin/sh
- -c
- sleep 300000
env:
- name: CONFIGMAP_NAME
valueFrom:
configMapKeyRef:
name: myconfigmap2
key: username
- name: CONFIGMAP_AGE
valueFrom:
configMapKeyRef:
name: myconfigmap2
key: age
執行一下
[root@master configmap]# kubectl apply -f e-pod.yaml
查看一下
[root@master configmap]# kubectl exec -it pod2 /bin/sh
//進入容器查看一下
> echo $CONFIGMAP_NAME
adam
> echo $CONFIGMAP_AGE
18
2.1 更新sevret文件的內容
[root@master configmap]# kubectl edit cm myconfigmap2
//修改保存文件的內容
查看一下
[root@master configmap]# kubectl exec -it pod2 /bin/sh
//進入容器查看一下
> echo $CONFIGMAP_NAME
adam
> echo $CONFIGMAP_AGE
18
等待了一定時間後,可以看到這個數據並沒有沒有改變
可以看出這個configmap和secret的更新效果基本沒有區別。
總結configmap、與secret資源有什麼相同和不同之處。
Secret 與 ConfigMap 對比
相同點:
key/value的形式
屬於某個特定的namespace
可以導出到環境變量
可以通過目錄/文件形式掛載
通過 volume 掛載的配置信息均可熱更新
不同點:
Secret 可以被 ServerAccount 關聯
Secret 可以存儲 docker register 的鑑權信息,用在 ImagePullSecret 參數中,用於拉取私有倉庫的鏡像
Secret 支持 Base64 加密
Secret 分爲 kubernetes.io/service-account-token、kubernetes.io/dockerconfigjson、Opaque 三種類型,而 Configmap 不區分類型
總結以volumes掛載、和環境變量方式引用資源的相同和不同之處。
volumes掛載(可根據更改數據更新):引用自己創建的secret(密文)或configmap(明文),掛載到容器中指定的目錄下。查看保存的文件時,根據自己所填路徑和secret或configmap創建的文件,進行查看。
環境變量(不因更改數據更新):引用自己創建的secret(密文)或configmap(明文),掛載到容器中指定的目錄下。查看保存的文件時,根據自己環境變量,進行查看。