前言
大家好,我是秋意零。
在上一篇中,我們介紹了 Pod 的生命周期以及區(qū)分 Pod 字段的層次級(jí)別,相信你對(duì)此有了充分的認(rèn)識(shí)。
今天,我們還會(huì)接著以 Pod 展開(kāi),說(shuō)說(shuō)它的 “服務(wù)對(duì)象”,一聽(tīng)就知道是對(duì) Pod 提供服務(wù)的對(duì)象,接下來(lái)就一起來(lái)看看, “服務(wù)對(duì)象” 是否有趣吧??!
哦!對(duì)了最近搞了一個(gè)扣扣群,旨在技術(shù)交流、博客互助,希望各位大佬多多支持!在我主頁(yè)推廣區(qū)域,如圖:
文章底部推廣區(qū)域,如圖:
?? 簡(jiǎn)介
- ?? 個(gè)人主頁(yè): 秋意零
- ?? 個(gè)人介紹:在校期間參與眾多云計(jì)算相關(guān)比賽,如:?? “省賽”、“國(guó)賽”,并斬獲多項(xiàng)獎(jiǎng)項(xiàng)榮譽(yù)證書(shū)
- ?? 目前狀況:24 屆畢業(yè)生,拿到一家私有云(IAAS)公司 offer,暑假開(kāi)始實(shí)習(xí)
- ?? 賬號(hào):各個(gè)平臺(tái), 秋意零 賬號(hào)創(chuàng)作者、 云社區(qū) 創(chuàng)建者
- ??歡迎大家:歡迎大家一起學(xué)習(xí)云計(jì)算,走向年薪 30 萬(wàn)
系列文章目錄
【探索Kubernetes|容器基礎(chǔ)進(jìn)階篇 系列1】容器的本質(zhì)是進(jìn)程
【探索 Kubernetes|容器基礎(chǔ)進(jìn)階篇 系列 2】容器資源限制利器
【探索 Kubernetes|容器基礎(chǔ)進(jìn)階篇 系列 3】容器進(jìn)程的文件系統(tǒng)
【探索 Kubernetes|容器基礎(chǔ)進(jìn)階篇 系列 4】理解現(xiàn)代云原生時(shí)代的引擎
【探索 Kubernetes|集群搭建篇 系列 5】簡(jiǎn)化 Kubernetes 的部署,深入解析其工作流程
更多點(diǎn)擊專欄查看:深入探索 Kubernetes
正文開(kāi)始:
- 快速上船,馬上開(kāi)始掌舵了(Kubernetes),距離開(kāi)船還有 3s,2s,1s…
一、Pod 服務(wù)對(duì)象
早在 【探索 Kubernetes|容器基礎(chǔ)進(jìn)階篇 系列 4】理解現(xiàn)代云原生時(shí)代的引擎 (七、Kubernetes 全景圖) 這篇中,就簡(jiǎn)單介紹過(guò) “服務(wù)對(duì)象” ;而下圖中,所說(shuō)的 “編排對(duì)象” 將在后面詳細(xì)展開(kāi)。如下圖所示:
首先,需要聲明的是,目前介紹的 “服務(wù)對(duì)象”,僅僅是通過(guò) Pod 的 Volume 字段來(lái)展開(kāi)說(shuō)明的。為什么呢?
- 像 Secret、ConfigMap、Downward API、ServiceAccountToken 這四種 Projected Volume 是今天主角,也就是通過(guò) Volume 字段掛載(投射)進(jìn) Pod 從而進(jìn)行服務(wù)的。這種 Volume,存在的意義不是為了存放容器里的數(shù)據(jù),也不是用來(lái)進(jìn)行容器和宿主機(jī)之間的數(shù)據(jù)交換。這些特殊 Volume 的作用,是為容器提供預(yù)先定義好的數(shù)據(jù)。所以,從容器的角度來(lái)看,這些 Volume 里的信息就是仿佛是被 Kubernetes“投射”(Project)進(jìn)入容器當(dāng)中的。這正是 Projected Volume 的含義。
- 而像 Service、Horizontal Pod Autoscaler 就是通過(guò)其它指標(biāo)字段對(duì) Pod 進(jìn)行服務(wù)的。
二、Secret
Sercret 是將 Pod 要訪問(wèn)的加密數(shù)據(jù),存在在 Etcd 數(shù)據(jù)庫(kù)中。之后,Pod 通過(guò)掛載 Volume 卷的方式,訪問(wèn)到這些 Secret 里存放的信息。
Secret 使用方法:
想象一個(gè)這樣的場(chǎng)景,使用 Kubernetes 部署一個(gè) Mysql 服務(wù),Mysql 容器初始化時(shí)需要指定 root 密碼,因?yàn)槲覀円话闶褂?YAML 方式部署,這樣方便管理容器服務(wù)對(duì)象。這時(shí)我們需要在 YAML 文件中通過(guò)環(huán)境變量的方式,初始化 Mysql 用戶和密碼,但是這樣就容易暴露這樣的明文用戶和密碼信息。這時(shí)就需要使用 Secret 映射給這個(gè) Mysql 使用對(duì)應(yīng)的認(rèn)證信息。
1.首先需要給明文用戶和密碼加密
因?yàn)槲覀?Secret 也是 YAML 方式部署,不過(guò)在企業(yè)中,這種信息一般是管理人員為運(yùn)維人員創(chuàng)建。運(yùn)維人員使用這樣一個(gè) Secret 即可。
這里使用 base64 方式轉(zhuǎn)碼,并不安全,因?yàn)?base64 僅僅是經(jīng)過(guò)了轉(zhuǎn)碼,而并沒(méi)有被加密。在真正的生產(chǎn)環(huán)境中,你需要在 Kubernetes 中開(kāi)啟 Secret 的加密插件,增強(qiáng)數(shù)據(jù)的安全性。
# 加密方式
[root@master01 ~]# echo -n "root" | base64
cm9vdA==
[root@master01 ~]# echo -n "000000" | base64
MDAwMDAw
# 解密方式
[root@master01 ~]# echo -n "cm9vdA==" | base64 -d
admin
[root@master01 ~]# echo -n "MDAwMDAw" | base64 -d
000000
2.創(chuàng)建 Secret
將加密過(guò)后的用戶和密碼信息,填寫(xiě)到 Secret 中。data 字段下,以 Key-Value 的格式保存了兩份 Secret 數(shù)據(jù)。其中,“user” 就是第一份數(shù)據(jù)的 Key,“pass” 是第二份數(shù)據(jù)的 Key。
user 是用戶 key 而 cm9vdA== 是用戶 value(用戶名)
pass 是用戶 key 而 MDAwMDAw 是用戶 value(用戶密碼)
[root@master01 yaml]# cat > secret-my.yaml << EOF
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque # 默認(rèn)類型
data:
user: cm9vdA==
pass: MDAwMDAw
EOF
# 部署 Secret
[root@master01 yaml]# kubectl apply -f secret-my.yaml
secret/mysecret created
# 記住 Secret 的名稱(這里叫:mysecret),待會(huì)會(huì)使用。
[root@master01 yaml]# kubectl get secret
NAME TYPE DATA AGE
mysecret Opaque 2 9s
3.創(chuàng)建 Pod(Mysql)
可以使用 kubectl create secret generic
命令創(chuàng)建或者 YAML
文件創(chuàng)建。
- 3.1.將 Secret 導(dǎo)入到環(huán)境變量中
apiVersion: v1
kind: Pod
metadata:
name: mysql-pod
spec:
containers:
- name: mysql-container
image: mysql:5.7
imagePullPolicy: IfNotPresent
ports:
- containerPort: 3306
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysecret
key: pass
進(jìn)入容器驗(yàn)證,環(huán)境變量是否和 Secret 中保存的值一致。
[root@master01 yaml]# kubectl exec -it mysql-pod -- /bin/bash
root@mysql-pod:/# env |grep MYSQL_ROOT_PASSWORD
MYSQL_ROOT_PASSWORD=000000
- 3.2.將 Secret 掛載到 projected Voluem 中
apiVersion: v1
kind: Pod
metadata:
name: busybox-pod
spec:
containers:
- name: busybox-container
image: busybox
imagePullPolicy: IfNotPresent
args:
- sleep
- "3600"
volumeMounts:
- name: busybox-secrets
mountPath: /var/secrets/busybox
readOnly: true
volumes:
- name: busybox-secrets
projected:
sources:
- secret:
name: mysecret
進(jìn)入容器驗(yàn)證,掛載的目錄的值是否和 Secret 中保存的值一致。
- 注意:使用 Voluem 掛載方式時(shí),是將 Secret 中的 key 作為目錄名稱,value 作為目錄中的值 。
[root@master01 yaml]# kubectl exec -it busybox-pod -- /bin/sh
# 查看使用 Secret 掛載進(jìn)容器中的目錄
/ # ls /var/secrets/busybox
pass user
# 查看值
/ # cat /var/secrets/busybox/user
admin
/ # cat /var/secrets/busybox/pass
000000/ #
小結(jié)
通過(guò)掛載方式進(jìn)入到容器里的 Secret,一旦其對(duì)應(yīng)的 Etcd 里的數(shù)據(jù)被更新,這些 Volume 里的文件內(nèi)容,同樣也會(huì)被更新。其實(shí),這是 kubelet 組件在定時(shí)維護(hù)這些 Volume。
不過(guò),這個(gè)更新會(huì)有一定延時(shí)。所以在編寫(xiě)應(yīng)用程序時(shí),在發(fā)起數(shù)據(jù)庫(kù)連接的代碼處寫(xiě)好重試和超時(shí)的邏輯,絕對(duì)是個(gè)好習(xí)慣。
三、ConfigMap
ConfigMap 與 Secret 類似,區(qū)別就是 ConfigMap 保存的是不需要加密的、應(yīng)用所需的配置文件信息。
ConfigMap 的用法幾乎與 Secret 完全相同,可以使用 kubectl create configmap
從文件或者目錄創(chuàng)建 ConfigMap,也可以直接編寫(xiě) ConfigMap 對(duì)象的 YAML 文件。
[root@master01 yaml]# cat test-db.text
database.host=localhost
database.port=3306
database.username=admin
database.password=secret
# 從 test-db.text 文件中,創(chuàng)建 configmap。
[root@master01 yaml]# kubectl create configmap my-config --from-file=test-db.text
configmap/my-config created
查看 configmap 中 data 數(shù)據(jù)信息,可以看到是和 test-db.text 配置文件中一致的,后期也是可以通過(guò)環(huán)境變量和 Voluem 卷的方式使用(同上述 Secret)。
[root@master01 yaml]# kubectl get configmap my-config -o yaml
例:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container
image: my-image
env:
- name: DATABASE_HOST
valueFrom:
configMapKeyRef:
name: my-config
key: database.host
- name: DATABASE_PORT
valueFrom:
configMapKeyRef:
name: my-config
key: database.port
- name: DATABASE_USERNAME
valueFrom:
configMapKeyRef:
name: my-config
key: database.username
- name: DATABASE_PASSWORD
valueFrom:
configMapKeyRef:
name: my-config
key: database.password
四、Downward API
Downward API 是一種特性,它允許容器在運(yùn)行時(shí)獲取關(guān)于自身和它所在 Pod 的一些元數(shù)據(jù)信息。這些信息可以作為環(huán)境變量或卷掛載提供給容器使用。
如果按照 Downward(下載)這個(gè)單詞意思理解就是: 將 Pod 或容器自身的元數(shù)據(jù)信息下載到是運(yùn)行狀態(tài)的容器中使用。
Downward API 提供了以下作用:
總的來(lái)說(shuō),Downward API 提供了一種在容器運(yùn)行時(shí)獲取 Pod 和容器自身元數(shù)據(jù)的機(jī)制,使容器能夠動(dòng)態(tài)獲取并使用這些信息。這對(duì)于編寫(xiě)靈活且適應(yīng)性強(qiáng)的應(yīng)用程序非常有用,并能夠在 Kubernetes 環(huán)境中提供更多的自動(dòng)化和配置選項(xiàng)。
可用字段
只有部分 Kubernetes API 字段可以通過(guò) Downward API 使用。
- fieldRef:傳遞 Pod 級(jí)字段的信息
- resourceFieldRef:傳遞 Container 級(jí)字段的信息
1.可通過(guò) fieldRef
獲得的信息
-
metadata.name
:Pod 的名稱 -
metadata.namespace
:Pod 的命名空間 -
metadata.uid
:Pod 的唯一 ID - …
2.可通過(guò) resourceFieldRef
獲得的信息
-
limits.cpu
:容器的 CPU 限制值 -
requests.cpu
:容器的 CPU 請(qǐng)求值 -
requests.memory
:容器的內(nèi)存請(qǐng)求值 -
limits.memory
:容器的內(nèi)存限制值 - …
Kubernetes 官網(wǎng):更多可用字段信息
舉個(gè)例子:
我們定義了一個(gè) Pod 名為 projected-buxybox,并創(chuàng)建了一個(gè)名為 app 的容器。我們使用了一個(gè) Projected Volume,并將其掛載到了 /etc/config 目錄下。 并使用 fieldRef 來(lái)獲取 Pod 的元數(shù)據(jù)信息,使用 resourceFieldRef 來(lái)獲取容器的元數(shù)據(jù)信息。
-
items.path
:定義元數(shù)據(jù)信息的目錄是什么。 -
fieldRef.fieldPath
:定義 Pod 元數(shù)據(jù)信息的值是什么。 -
resourceFieldRef.resource
:定義 容器 元數(shù)據(jù)信息的值是什么。
apiVersion: v1
kind: Pod
metadata:
name: projected-buxybox
spec:
containers:
- name: app
image: busybox
imagePullPolicy: IfNotPresent
args:
- sleep
- "3600"
resources:
limits:
cpu: "2"
requests:
cpu: "1"
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
projected:
sources:
- downwardAPI:
items:
- path: "pod_name"
fieldRef:
fieldPath: metadata.name
- path: "pod_namespace"
fieldRef:
fieldPath: metadata.namespace
- path: "cpu_limits"
resourceFieldRef:
containerName: app
resource: limits.cpu
- path: "cpu_request"
resourceFieldRef:
containerName: app
resource: requests.cpu
驗(yàn)證:部署 Pod ,并查看 /etc/config 目錄下,獲取的值是否正確。
[root@master01 yaml]# kubectl apply -f projected-buxybox-pod.yaml
[root@master01 yaml]# kubectl get -f projected-buxybox-pod.yaml
NAME READY STATUS RESTARTS AGE
projected-buxybox 1/1 Running 0 3m11s
[root@master01 yaml]# kubectl exec -it projected-buxybox -- /bin/sh
/ # ls /etc/config/
cpu_limits cpu_request pod_name pod_namespace
/ # cat /etc/config/cpu_limits
2
/ # cat /etc/config/cpu_request
1
/ # cat /etc/config/pod_name
projected-buxybox
/ # cat /etc/config/pod_namespace
default
小結(jié)
注意:Downward API 能夠獲取到的信息,一定是 Pod 里的容器進(jìn)程啟動(dòng)之前就能夠確定下來(lái)的信息。而如果你想要獲取 Pod 容器運(yùn)行后才會(huì)出現(xiàn)的信息,比如,容器進(jìn)程的 PID,那就肯定不能使用 Downward API 了,而應(yīng)該考慮在 Pod 里定義一個(gè) sidecar 容器。
Secret、ConfigMap,以及 Downward API 這三種 Projected Volume 定義的信息,大多還可以通過(guò)環(huán)境變量的方式出現(xiàn)在容器里。但是,通過(guò)環(huán)境變量獲取這些信息的方式,不具備自動(dòng)更新的能力。所以,一般情況下,我都建議你使用 Volume 文件的方式獲取這些信息。
五、ServiceAccountToken
如果我有一個(gè) Pod,而且在 Pod 中安裝 Kubernetes 的 Clinet,想實(shí)現(xiàn)可以從容器里直接訪問(wèn)并且操作這個(gè) Kubernetes 的 API ?這種方式是可行的,不過(guò),你首先要解決 API Server 的授權(quán)問(wèn)題,這就需要 ServiceAccount 服務(wù)對(duì)象了。
1.Service Account 是什么?
- Service Account(服務(wù)賬號(hào))是 Kubernetes 中用于身份驗(yàn)證和授權(quán)的實(shí)體,進(jìn)行權(quán)限分配的對(duì)象。它是為 Pod 提供訪問(wèn) Kubernetes API 的身份憑據(jù)。每個(gè) Service Account 都有一個(gè)唯一的名稱和對(duì)應(yīng)的身份令牌(Token)。
- Service Account 可以與 Pod 關(guān)聯(lián),使 Pod 具有與 Kubernetes API 進(jìn)行交互的權(quán)限。它允許 Pod 在運(yùn)行時(shí)進(jìn)行身份驗(yàn)證,并根據(jù)其配置的權(quán)限來(lái)執(zhí)行操作,例如創(chuàng)建、更新或刪除資源。
比如,Service Account A,可以只被允許對(duì) Kubernetes API 進(jìn)行 GET 操作,而 Service Account B,則可以有 Kubernetes API 的所有操作權(quán)限。
2.ServiceAccountToken 是什么?
像上述這樣的權(quán)限分配操作,實(shí)際上是通過(guò)一種它所綁定的一個(gè) ServiceAccountToken。任何運(yùn)行在 Kubernetes 集群上的應(yīng)用,都必須使用這個(gè) ServiceAccountToken 里保存的授權(quán)信息,也就是 Token,才能訪問(wèn) kube-apiserver。
另外,為了方便使用,Kubernetes 已經(jīng)為你提供了一個(gè)默認(rèn)“服務(wù)賬戶”(default Service Account)。如圖:
并且,任何一個(gè)運(yùn)行在 Kubernetes 里的 Pod,都可以直接使用這個(gè)默認(rèn)的 Service Account,而無(wú)需顯示地聲明掛載它,因?yàn)槭悄J(rèn)自動(dòng)掛載(可以設(shè)置不掛載,默認(rèn)掛載)靠 Projected Volume 機(jī)制實(shí)現(xiàn)。
你可以查看任意一個(gè)運(yùn)行中的 Pod,你會(huì)發(fā)現(xiàn)一個(gè) 類型為 Projected 并且包含來(lái)自多個(gè)源的注入數(shù)據(jù)的卷(Service Account 的身份令牌),然后自動(dòng)掛載在每個(gè)容器的一個(gè)固定目錄上 /var/run/secrets/kubernetes.io/serviceaccount
,容器可以通過(guò)該路徑訪問(wèn)令牌,并將其用于與 Kubernetes API 的安全通信。
這里提供了兩種查看方式,如下圖:
kubectl describe pod mysql-pod
下圖我們可以看到,這個(gè) Projected 包含來(lái)自多個(gè)源的注入數(shù)據(jù)的卷,使用了 ServiceAccountToken、ConfigMap、DownwardAPI。
kubectl get pod -o yaml mysql-pod
所以 Pod 中的容器應(yīng)用,就可以直接使用這個(gè)目錄下的授權(quán)信息和文件與 kube-apiserver 訪問(wèn), Projected 目錄下的內(nèi)容,如圖所示:
這種把 Kubernetes 客戶端以容器的方式運(yùn)行在集群里,然后使用 default Service Account 自動(dòng)授權(quán)的方式,被稱作 “InClusterConfig”(內(nèi)部集群配置),也是我最推薦的進(jìn)行 Kubernetes API 編程的授權(quán)方式。
除了默認(rèn)的 ServiceAccount 還可以自定義 ServiceAccount 來(lái)對(duì)應(yīng)不同的權(quán)限設(shè)置。這樣 Pod 在使用這個(gè) Service Account 對(duì)應(yīng)的 ServiceAccountToken 時(shí)權(quán)限就更加靈活。
總結(jié)
今天,介紹了 Pod 的 Volume 的 Projected 服務(wù)對(duì)象。
你還應(yīng)該認(rèn)真體會(huì)一下 Kubernetes “一切皆對(duì)象” 的設(shè)計(jì)思想:比如,應(yīng)用是 Pod 對(duì)象,應(yīng)用的配置是 ConfigMap 對(duì)象,應(yīng)用要訪問(wèn)的密碼則是 Secret 對(duì)象。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-487774.html
最后:技術(shù)交流、博客互助,點(diǎn)擊下方或主頁(yè)推廣加入哦?。?br>文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-487774.html
到了這里,關(guān)于【探索 Kubernetes|作業(yè)管理篇 系列 9】Pod 的服務(wù)對(duì)象的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!