secret類型創建Pod使用以及ServiceAccount關聯Secret

昨日考題

創建Secret名為cka1127-secret,內含有password字段,值為cka1127,然後在名為cka1127-01的Pod1裡使用ENV進行調用,名為cka1127-02的Pod2裡使用Volume掛載在/data 下;

注意:提交評論:包含命令和yaml,以及注意點。可分多次評論。

昨日答案

創建secret方式一cka1127-secret.yaml可以是以下這樣:

<code>apiVersion: v1
kind: Secret
metadata:
name: cka1127-secret
type: Opaque
stringData:
cka1127-password: cka1127/<code>

創建

<code>[root@liabio test]# kubectl apply -f  cka-1127-secret.yaml 
secret/cka1127-secret created/<code>

創建secret方式二

<code>kubectl create secret generic cka1127-secret --from-literal=password=cka1127/<code>

名為cka1127-01的Pod yaml

<code>apiVersion: v1
kind: Pod
metadata:
name: cka1127-01
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: pwd
mountPath: /data/password

readOnly: true
volumes:
- name: pwd
secret:
secretName: cka1127-secret/<code>

名為cka1127-02的Pod yaml

<code>apiVersion: v1
kind: Pod
metadata:
name: cka1127-02
spec:
containers:
- image: nginx
name: nginx
env:
- name: PASSWORD
valueFrom:
secretKeyRef:
name: cka1127-secret
key: password/<code>

volume形式驗證,保證/data/password/下有password文件,文件內容為明文cka1127

<code>[root@liabio ~]# kubectl exec -ti cka1127-01 sh
#
# ls -l /data/password
total 0
lrwxrwxrwx 1 root root 15 Nov 28 00:40 password -> ..data/password
# cat /data/password/password
cka1127#
# /<code>

環境變量形式驗證,保證env能查到name為PASSWORD的環境變量;

<code>[root@liabio test]# kubectl exec -ti cka1127-02  bash
root@cka1127-02:/#
root@cka1127-02:/# echo $PASSWORD
cka1127
root@cka1127-02:/#/<code>

昨日解析


secret官方文檔:https://kubernetes.io/docs/concepts/configuration/secret/

secret簡介

Kubernetes中的Secret資源可以用來存儲密碼、Token、秘鑰等敏感數據, 將這些敏感信息保存在Secret中,相對於暴露到Pod、鏡像中更加的安全和靈活。

你可能會覺得,secret一般不會用到,實際上在創建Pod時,Kubernetes會自動創建包含用於訪問API的憑據的secret(由kube-controller-manager的service account token controller控制),並且它會自動修改Pod以使用這種類型的secret(這個由Admission Controller來控制)。

k8s每個namespace都會有一個Service Account,當我們創建namespace時,service account controller會監聽namespace的創建,會在該namespace中創建一個名為default的Service Account,同時service account token controller會監聽Service Account的創建,創建對應的secret,並將這個secret綁定到Service Account。

<code>[root@liabio test]# kubectl create ns cka
namespace/cka created
[root@liabio test]#
[root@liabio test]# kubectl get sa -n cka
NAME SECRETS AGE
default 1 11s
[root@liabio test]# kubectl get secrets -n cka
NAME TYPE DATA AGE
default-token-r77xn kubernetes.io/service-account-token 3 18s
[root@liabio test]# /<code>
每日一題||secret類型創建Pod使用以及ServiceAccount關聯Secret

當我們創建Pod時,如果未指定Service Account,則默認會在同一命令空間namespace中自動為其分配Service Account。則可以看到該spec.serviceAccountName字段已被自動設置。

每日一題||secret類型創建Pod使用以及ServiceAccount關聯Secret

您可以使用自動添加的Service Account憑據從Pod內部訪問API,Service Account的API權限取決於所使用的授權插件和策略。

有關Service Account如何工作的更多信息,請參見文檔:https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/

Secret的類型

--type指定創建的秘密類型,Kubernetes內置了三種類型的Secret

kubernetes.io/service-account-token Secret

上面我們已經講到,為了能從Pod內部訪問Kubernetes API,Kubernetes提供了Service Account資源。 Service Account會自動創建和掛載訪問Kubernetes API的Secret,會掛載到Pod的 /var/run/secrets/kubernetes.io/serviceaccount目錄中。 namespace創建時自動創建的Service Account用到的Secret就是這種類型的。

每日一題||secret類型創建Pod使用以及ServiceAccount關聯Secret

Opaque Secret

Opaque類型的Secret是一個map結構(key-value),其中vlaue要求以base64格式編碼,以下示例中基本都為Opaque類型的Secret。

kubernetes.io/dockerconfigjson Secret

kubernetes.io/dockercfg類型的Secret用於存放私有Docker Registry的認證信息。 當Kubernetes在創建Pod並且需要從私有Docker Registry pull鏡像時,需要使用認證信息,就會用到kubernetes.io/dockercfg類型的Secret。

<code>kubectl create secret docker-registry cka-regsecret \\
--docker-server=coderaction \\
--docker-username=admin \\
--docker-password=123456 \\
[email protected]/<code>
每日一題||secret類型創建Pod使用以及ServiceAccount關聯Secret

在創建Pod時需要在Pod的spec中按如下形式使用:

<code>apiVersion: v1
kind: Pod
metadata:
name: cka-private-reg
spec:
containers:
- name: cka-private-reg-container
image: nginx
imagePullSecrets:
- name: cka-regsecret/<code>

可以參考官方文檔:https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod

給分區默認的ServiceAccount添加imagePullSecrets,以至於創建的所有Pod可以自動添加spec.imagePullSecrets,詳情參考官方文檔:https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#add-imagepullsecrets-to-a-service-account

secret創建

kubectl創建secret

kubectl創建seccret官方文檔:https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#-em-secret-em-

格式:

<code>kubectl create secret generic NAME [--type=string] [--from-file=[key=]source] [--from-literal=key1=value1] [--dry-run]/<code>

--from-literal:指定要插入的鍵和文字值(即mykey = somevalue),value為明文值,創建後會被base64編碼;--from-file:可以使用密鑰文件的文件路徑指定密鑰文件,在這種情況下,將為它們指定默認名稱;或者可以選擇使用指定目錄,這樣將迭代該目錄中的每個有效文件密鑰。--type:創建的秘密類型,上面已經介紹過三種類型;--dry-run:如果為true,則僅打印將要向APIServer發送創建的對象,而不發送它。默認false;

使用--from-file創建

<code>[root@liabio cka]# echo -n 'admin' > ./username
[root@liabio cka]# echo -n 'test123' > ./password
[root@liabio cka]# echo -n 'shanghai' > ./city
[root@liabio cka]# ll
total 12
-rw-r--r-- 1 root root 9 Nov 28 20:44 city
-rw-r--r-- 1 root root 8 Nov 28 20:43 password
-rw-r--r-- 1 root root 6 Nov 28 20:43 username
[root@liabio cka]# kubectl create secret generic test-cka1127-01 --from-file=./username --from-file=./password
secret/test-cka1127-01 created
[root@liabio cka]# kubectl create secret generic test-cka1127-02 --from-file=./
secret/test-cka1127-02 created
[root@liabio cka]# /<code>

以指定目錄創建的secret,查看到目錄下所有文件都被加到data下:

<code>kubectl get secrets test-cka1127-02 -oyaml/<code>
<code>apiVersion: v1
data:
city: c2hhbmdoYWkK
password: dGVzdDEyMwo=
username: YWRtaW4K
kind: Secret
metadata:
creationTimestamp: "2019-11-28T12:44:57Z"
name: test-cka1127-02
namespace: default
resourceVersion: "14636360"
selfLink: /api/v1/namespaces/default/secrets/test-cka1127-02
uid: 4a3a1a5d-09e6-4bf9-bbe3-3300db1ddf7a
type: Opaque/<code>

指定username和password創建的secret:

<code>kubectl get secrets test-cka1127-01 -oyaml/<code>
<code>apiVersion: v1
data:
password: dGVzdDEyMwo=
username: YWRtaW4K
kind: Secret
metadata:
creationTimestamp: "2019-11-28T12:44:47Z"

name: test-cka1127-01
namespace: default
resourceVersion: "14636347"
selfLink: /api/v1/namespaces/default/secrets/test-cka1127-01
uid: 766516a2-34be-4a18-b4e2-83751a6cd2b7
type: Opaque/<code>

默認情況下,kubectl describe 命令能避免顯示文件的內容。這可以防止將 secret 中的內容暴露給從終端日誌記錄中刻意尋找它們的人。

特殊字符,例如$,,*,和!需要逃逸。在大多數常見的shell中,最簡單的轉義密碼方法是用單引號(')引起來。例如,如果您的實際密碼是S!B*d$zDsb,則應以這種方式執行命令:

kubectl create secret generic dev-db-secret

--from-literal=username=devuser --from-literal=password='S!B*d$zDsb' 您無需從文件(--from-file)中轉義密碼中的特殊字符。

手動創建秘密

還可以先在文件中以json或yaml格式創建一個Secret,然後創建該對象。該secret包含兩種:data和是stringData是。data字段用於存儲使用base64編碼的任意數據。提供stringData字段是為了方便起見,它允許提供未編碼的字符串。

例如,要使用data將兩個字符串存儲在Secret中,請按如下所示將它們轉換為base64:

<code>echo -n 'admin' | base64
YWRtaW4=
echo -n '1f2d1e2e67df' | base64
MWYyZDFlMmU2N2Rm/<code>

注意:在轉base64編碼時,一定記得加-n參數,否則可能會遇到坑。

然後創建以下yaml,最終kubectl apply

<code>apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
username: YWRtaW4=
password: MWYyZDFlMmU2N2Rm/<code>

如果用以下yaml創建,注意到用了stringData,user的值為coderaction明文。

<code>apiVersion: v1
kind: Secret
metadata:
name: cka1127-secret-02
type: Opaque
stringData:
user: coderaction/<code>

執行kubectl apply後查看:

<code>apiVersion: v1
data:
user: Y29kZXJhY3Rpb24=
kind: Secret
metadata:
name: cka1127-secret-02
type: Opaque/<code>

Y29kZXJhY3Rpb24=解碼為coderaction

<code>[root@liabio cka]# echo Y29kZXJhY3Rpb24= | base64 -d
coderaction/<code>

data和stringData的鍵必須由字母數字字符“-”,“ _”或“。”組成。

編碼注意:secret數據的序列化JSON和YAML值被編碼為base64字符串。換行符在這些字符串中無效,因此必須省略。base64在Darwin/macOS上使用該實用程序時,用戶應避免使用該-b選項來分隔長行。相反,如果選項不可用,Linux用戶應將選項添加-w 0到base64命令或管道中。base64 | tr -d 'n'-w

從生成器創建秘密

從1.14開始,Kubectl支持使用Kustomize管理對象。使用此新功能,您還可以從生成器創建一個Secret,然後將其應用於在Apiserver上創建對象。

使用Secret

將secret所有內容掛載為Pod裡的文件

<code>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/<code>

這樣Pod中的/etc/foo目錄下會生成mysecret中的所有映射文件。

將密鑰投影到特定路徑

我們還可以控制secret映射到卷中的路徑。您可以使用.spec.volumes[].secret.items更改每個鍵的目標路徑:

<code>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/<code>

這樣Pod中username存儲在/etc/foo/my-group/my-username文件而非/etc/foo/username;而且沒有password的映射文件。

secret文件權限

<code>apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mypod
image: nginx
volumeMounts:
- name: foo
mountPath: "/etc/foo"
volumes:
- name: foo
secret:
secretName: cka1127-secret
defaultMode: 256/<code>

然後,Secret將被掛載到/etc/foo並且由Secret卷掛載創建的所有文件權限為0400;

請注意,JSON規範不支持八進制表示法,因此對於0400權限,請使用值256。如果您使用yaml而不是json描述Pod,則可以使用八進制表示法以更自然的方式指定權限。

也可以像前面的示例一樣使用映射,併為不同的文件指定不同的權限,如下所示:

<code>apiVersion: v1
kind: Pod
metadata:
name: mypod-1
spec:
containers:
- name: mypod
image: nginx
volumeMounts:
- name: foo
mountPath: "/etc/foo"
volumes:
- name: foo
secret:
secretName: cka1127-secret-02
items:
- key: user
path: my-group/my-username
mode: 511/<code>

mode值511為十進制,在這種情況下,生成的文件的/etc/foo/my-group/my-username許可權值為八進制0777。由於JSON的限制,您必須以十進制表示法指定mode。

請注意,如果稍後閱讀此權限值,則可能會以十進制表示法顯示。

環境變量

Pod中通過環境變量引用Secret和題目答案一樣,不做累述;


分享到:


相關文章: