k8s如何訪問 pod 元數(shù)據(jù)
如何訪問 pod 元數(shù)據(jù)
我們?cè)?pod 中運(yùn)行容器的時(shí)候,是否也會(huì)有想要獲取當(dāng)前 pod 的環(huán)境信息呢?咱們寫的 yaml 清單寫的很簡(jiǎn)單,實(shí)際上部署之后, k8s 會(huì)給我們補(bǔ)充在 yaml 清單中沒有寫的字段,那么我們的 pod 環(huán)境信息和容器的元數(shù)據(jù)如何傳遞到容器中呢?是不是也是通過獲取這些 k8s 默認(rèn)給我填寫的字段呢?
有 3 種方式:
通過環(huán)境變量的方式
通過 ?Downward Api 的方式
通過和 ApiServer 交互的方式
通過環(huán)境變量的方式
通過環(huán)境變量的方式獲取 pod 的信息,還是比較簡(jiǎn)單的,還記得我們之前將卷中的數(shù)據(jù)轉(zhuǎn)成環(huán)境變量傳入到容器中的方式嗎?
本次我們也是使用類似的方式來傳遞數(shù)據(jù),應(yīng)該說比之前的還要簡(jiǎn)單,不過我們本次傳遞的是環(huán)境信息,例如 pod 的 IP,pod 的 名稱,命名空間,pod 所屬的服務(wù)賬號(hào),節(jié)點(diǎn)的名稱,CPU / 內(nèi)存的請(qǐng)求 / 限制大小等等
來我們?nèi)我饪匆幌?pod 的 yaml 清單信息



上述 yaml 清單信息中,每一個(gè)字段我們都可以用來傳遞到容器中作為環(huán)境變量,我們可以來嘗試寫一個(gè)
寫一個(gè) yaml 清單,創(chuàng)建名稱為 my-downward 的 pod
容器里面的使用 busybox 作為基礎(chǔ)鏡像,由于容器需要運(yùn)行在 pod 中,因此我們需要運(yùn)行一個(gè)程序在容器中,例如 sleep 8888888 或者其他的任意一個(gè)可以長(zhǎng)期運(yùn)行的程序

apiVersion:?v1
kind:?Pod
metadata:
??name:?my-downward
spec:
??containers:
??-?name:?my-downward
????image:?busybox
????command:?["sleep","8888888"]
????env:
????-?name:?XMT_POD_NAME
??????valueFrom:
????????fieldRef:
??????????fieldPath:?metadata.name
????-?name:?XMT_NAMESPACE
??????valueFrom:
????????fieldRef:
??????????fieldPath:?metadata.namespace
????-?name:?XMT_NODENAME
??????valueFrom:
????????fieldRef:
??????????fieldPath:?spec.nodeName
????-?name:?XMT_SERVICE_ACCOUNT
??????valueFrom:
????????fieldRef:
??????????fieldPath:?spec.serviceAccountName
????-?name:?XMT_REQUEST_CPU
??????valueFrom:
????????resourceFieldRef:
??????????resource:?requests.cpu
??????????divisor:?1m
????-?name:?XMT_LIMITS_MEMORY
??????valueFrom:
????????resourceFieldRef:
??????????resource:?limits.memory
??????????divisor:?1Ki
上述自己配置了多個(gè) XMT_* 的環(huán)境變量,來源都是在 pod 中的對(duì)應(yīng)配置,kubectl create 上述 yaml 文件后,可以查看效果如下

環(huán)境變量如上所示,當(dāng)我們?nèi)萜骼锩嫘枰褂迷摥h(huán)境變量的時(shí)候,就可以隨取隨用了,很方便
可以看到容器中的環(huán)境變量和 yaml 清單上的 env 一一對(duì)應(yīng)

通過 Downward Api 卷的方式
當(dāng)然,我們也可以使用第二種方式,那就是通過 Downward Api 卷的方式,具體的操作方式和上述環(huán)境變量的方式類似,但是使用卷的方式,會(huì)在指定的路徑下生成文件
Downward Api 看上去會(huì)不會(huì)想起 Restful Api,是不是都是通過訪問接口的方式獲取數(shù)據(jù)呢?
并不是這樣的, Downward Api 實(shí)際上是將 pod 的定義和狀態(tài)信息,作為容器的環(huán)境變量或者文件的方式,來給容器傳遞數(shù)據(jù)的,如圖

Downward Api 卷的方式可以這么寫:
apiVersion:?v1
kind:?Pod
metadata:
??name:?my-downward-vv
??labels:
????xmtconf:?dev
spec:
??containers:
??-?name:?my-downward-vv
????image:?busybox
????command:?["sleep","8888888"]
????volumeMounts:
????-?name:?my-downward-vv
??????mountPath:?/etc/myvv
??volumes:
??-?name:?my-downward-vv
????downwardAPI:
??????items:
??????-?path:?"xmtPodName"
????????fieldRef:
??????????fieldPath:?metadata.name
??????-?path:?"xmtNamespace"
????????fieldRef:
??????????fieldPath:?metadata.namespace
??????-?path:?"xmtLabels"
????????fieldRef:
??????????fieldPath:?metadata.labels
看這個(gè) yaml 還是比較簡(jiǎn)單的,和寫掛載的方式類似的,此處使用 downwardAPI 下的 items,來傳遞每一個(gè)數(shù)據(jù),數(shù)據(jù)的來源寫法和上述的環(huán)境變量類似

我們可以看到,Downward Api 掛載數(shù)據(jù),具體的文件里面會(huì)以鍵值對(duì)的方式來呈現(xiàn),也會(huì)以文本的形式來呈現(xiàn)
我們來將 pod 的標(biāo)簽修改成 prod,驗(yàn)證容器里面對(duì)應(yīng)的文件是否會(huì)對(duì)應(yīng)修改?
kubectl?label?pod?my-downward-vv?xmtconf=prod?--overwrite

進(jìn)入容器中查看 /etc/myvv/xmtLabels
文件是否有變化

通過上述效果,可以看出,當(dāng)使用 Downward Api 卷的時(shí)候,對(duì)應(yīng)的環(huán)境變量會(huì)以文件的形式存在于我們指定的目錄下
若我們?cè)诔绦蜻\(yùn)行中修改了環(huán)境變量對(duì)應(yīng)的值,那么卷中的文件內(nèi)容也會(huì)相應(yīng)修改
如何與 APiServer 進(jìn)行交互?
既然可以用第三種方式與 ApiServer 的方式,咋還使用環(huán)境變量和 Downward Api 的方式呢?
自然是因?yàn)?Downward Api 的方式有所局限,局限就是 Downward Api 的方式只能獲取自身 pod 的數(shù)據(jù),如果我們想獲取其他 pod 的資源信息,這個(gè)時(shí)候我們就需要和 Api Server 進(jìn)行交互了
類似于這樣:

那么我們來寫一個(gè) pod, 讓 pod 里面的容器與 ApiServer 進(jìn)行交互,此處我們需要注意兩點(diǎn):
我們要確定 ApiServer 的位置,我們才能有機(jī)會(huì)正確訪問到
需要通過 ApiServer 的認(rèn)證
咱們寫一個(gè) pod ,用于在這個(gè) pod 里面使用 curl 訪問 ApiServer
自己制作一個(gè)簡(jiǎn)單的帶有 curl 的鏡像
FROM?ubuntu:latest
RUN??apt-get?update?-y
RUN??apt?install?curl?-y
ENTRYPOINT?["sleep",?"8888888"]
制作該鏡像,推送鏡像到 dockerhub
docker?build?-t?xiaomotong888/xmtcurl?.
docker?push?xiaomotong888/xmtcurl
寫一個(gè)簡(jiǎn)單的 yaml,運(yùn)行 pod
mycurl.yaml
apiVersion:?v1
kind:?Pod
metadata:
??name:?xmt-curl
spec:
??containers:
??-?name:?xmt-curl
????image:?xiaomotong888/xmtcurl
????command:?["sleep","8888888"]
pod 運(yùn)行成功后,咱們進(jìn)入到 容器里面
kubectl?exec?-it?xmt-curl?bash
咱們可以在 k8s 環(huán)境中查看一下 kubernetes 服務(wù)的 ip ,我們可以這樣來訪問

在容器中訪問 kubernetes

這是因?yàn)闆]有證書,我們需要導(dǎo)入證書和 token , 這樣才能正確的訪問到 ApiServer,并且還需要一個(gè)重要的操作
創(chuàng)建一個(gè) ?clusterrolebinding,需要?jiǎng)?chuàng)建了該綁定之后,才能正常的訪問到 ApiServer,若沒有創(chuàng)建該綁定,那么后面的步驟都做好了,ApiServer 也會(huì)報(bào) 403 ?Forbidden
kubectl?create?clusterrolebinding?gitlab-cluster-admin?--clusterrole=cluster-admin?--group=system:serviceaccounts?--namespace=dev
證書的位置還記的嗎?

之前我們查看過默認(rèn)的 k8s 掛載的位置,/var/run/secrets/kubernetes.io/serviceaccount
這里面有 命名空間,證書,token

這個(gè)時(shí)候,我們?cè)L問 k8s ApiServer 的時(shí)候,可以加上該證書
curl?--cacert?/var/run/secrets/kubernetes.io/serviceaccount/ca.crt?https://kubernetes
我們可以導(dǎo)入一個(gè)環(huán)境變量,訪問 k8s ApiServer 的時(shí)候就不需要收到導(dǎo)入證書了
export?CURL_CA_BUNDLE=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
https://gitee.com/common_dev/mypic20220206/raw/master/image-20220204152125059.png
可以看到效果和剛才不一樣了,現(xiàn)在報(bào) 403 是因?yàn)闆]有 token ,這個(gè)時(shí)候,我們?cè)诩由?token 即可
TOKEN=$(cat?/var/run/secrets/kubernetes.io/serviceaccount/token)

這樣就可以看到 apiServer 都有哪些 api 了 , 這些 api 可都是我們?cè)趯?yaml 清單時(shí)候 apiVersion 的是時(shí)候填寫的
那么用一個(gè)圖來結(jié)束今天的分享

容器里面的應(yīng)用通過證書與 ApiServer 完成認(rèn)證,通過 token 和 namespace 和 ApiServer 完成接口的交互
今天就到這里,學(xué)習(xí)所得,若有偏差,還請(qǐng)斧正
歡迎點(diǎn)贊,關(guān)注,收藏
朋友們,你的支持和鼓勵(lì),是我堅(jiān)持分享,提高質(zhì)量的動(dòng)力

好了,本次就到這里
技術(shù)是開放的,我們的心態(tài),更應(yīng)是開放的。擁抱變化,向陽而生,努力向前行。
我是阿兵云原生,歡迎點(diǎn)贊關(guān)注收藏,下次見~