1. 程式人生 > >Kubernetes學習筆記(七):訪問Pod元資料與Kubernetes API

Kubernetes學習筆記(七):訪問Pod元資料與Kubernetes API

## Downward API 我們已經瞭解到,使用ConfigMap和Secret嚮應用傳遞配置資料,這對於執行前預設的資料是可行的。但是對於那些不能預先知道的,就需要使用Downward API。 Downward API允許我們通過環境變數或者卷的方式嚮應用傳遞元資料。可傳遞的資料包括:Pod的IP、名稱、標籤、註解、所在命令空間、執行的節點名稱、執行所屬的ServiceAccountName,每個容器請求的CPU和記憶體使用量以及限制。 ### 通過環境變數暴露元資料 `env.valueFrom`下引用Pod的欄位使用`fieldRef`,引用容器的cpu和記憶體使用`resourceFieldRef`。 對於暴露資源的請求和使用顯示的環境變數,我們通常會設定一個基數單位。實際的資源請求值和使用限制值除以這個基數單位,所得結果通過環境變數暴露出去。 ``` # downward-env.yaml apiVersion: v1 kind: Pod metadata: name: downward-env spec: containers: - name: alpine image: alpine command: ["sleep","999999"] resources: requests: cpu: 15m memory: 100Ki limits: cpu: 500m memory: 100Mi env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: POD_NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace - name: POD_IP valueFrom: fieldRef: fieldPath: status.podIP - name: NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName - name: SERVICE_ACCOUNT valueFrom: fieldRef: fieldPath: spec.serviceAccountName - name: CONTAINER_CPU_REQ_MILLICORES valueFrom: resourceFieldRef: resource: requests.cpu divisor: 1m - name: CONTAINER_MEMORY_LIMIT_KIBIBYTES valueFrom: resourceFieldRef: resource: limits.memory divisor: 1Ki ``` 檢視一下環境變數 ``` -> [[email protected]] [~] k create -f downward-env.yaml pod/downward-env created -> [[email protected]] [~] k exec downward-env env PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=downward-env POD_NAME=downward-env POD_NAMESPACE=default POD_IP=10.244.1.24 NODE_NAME=kube1.vm SERVICE_ACCOUNT=default CONTAINER_CPU_REQ_MILLICORES=15 CONTAINER_MEMORY_LIMIT_KIBIBYTES=102400 ``` ### 通過Downward卷傳遞元資料 使用downward卷的方式傳遞元資料,當Pod的標籤和註解修改後,Kubernetes會更新存有相關資訊的檔案。而環境變數方式下,新值無法暴露。 該描述檔案定義了一個downward型別的卷,掛載到容器的/tmp/downward。卷中包含的內容是用downwardAPI.items定義的。 ``` # downward-volume.yaml apiVersion: v1 kind: Pod metadata: name: downward-volume labels: foo: bar annotations: key1: value1 key2: | multi line value spec: containers: - name: alpine image: alpine command: ["sleep","999999"] resources: requests: cpu: 15m memory: 100Ki limits: cpu: 500m memory: 100Mi volumeMounts: - name: downward mountPath: /tmp/downward volumes: - name: downward downwardAPI: items: - path: "podName" fieldRef: fieldPath: metadata.name - path: "podNamespace" fieldRef: fieldPath: metadata.namespace - path: "labels" fieldRef: fieldPath: metadata.labels - path: "annotations" fieldRef: fieldPath: metadata.annotations - path: "containerCpuReqMillicores" resourceFieldRef: containerName: alpine resource: requests.cpu divisor: 1m - path: "containerMemoryLimitBytes" resourceFieldRef: containerName: alpine resource: limits.memory divisor: 1 ``` 建立檢視 ``` -> [[email protected]] [~] k create -f downward-volume.yaml pod/downward-volume created -> [[email protected]] [~] k exec downward-volume ls /tmp/downward annotations containerCpuReqMillicores containerMemoryLimitBytes labels podName podNamespace ``` ## 與Kubernetes API伺服器互動 DownwardAPI可以獲得當前Pod的部分元資料,但是無法獲得到其他的Pod的,以及一些叢集中的其他資源資訊。 ### Kubernetes REST API 先來檢視叢集資訊,找到API伺服器地址。然後 curl -k https://192.168.199.117:6443 ,當然結果也是訪問受限的。 ``` -> [[email protected]] [~] k cluster-info Kubernetes master is running at https://192.168.199.117:6443 KubeDNS is running at https://192.168.199.117:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy ``` 所以我們通過 kubectl proxy 訪問API伺服器。kubectl proxy啟動一個代理,接收來自本機的HTTP請求並驗證身份,轉發到API伺服器。 ``` -> [[email protected]] [~] k proxy Starting to serve on 127.0.0.1:8001 ``` 新開一個視窗,訪問根路徑實時 ``` -> [[email protected]] [~] curl http://localhost:8001/ { "paths": [ "/api", "/api/v1", "/apis", "/apis/", ............ ``` ### 從pod內部與API伺服器互動 確定API伺服器的地址 ``` -> [[email protected]] [~] k get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 443/TCP 2d1h ``` 或者從任意Pod查詢服務的環境變數 ``` -> [[email protected]] [~] k exec myalpine env|grep KUBERNETES_SERVICE KUBERNETES_SERVICE_PORT=443 KUBERNETES_SERVICE_PORT_HTTPS=443 KUBERNETES_SERVICE_HOST=10.96.0.1 ``` 用一個有curl的映象啟動一個Pod 首先驗證伺服器身份,定義CURL_CA_BUNDLE環境變數,省去每次都要 curl --cacert 指定證書 ``` export CURL_CA_BUNDLE=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt ``` 其次獲得伺服器授權:定義TOKEN ``` export TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) ``` 繞過RBAC,賦予所有服務賬戶(也可以說所有pod)的叢集管理員許可權。 ``` -> [[email protected]] [~] k create clusterrolebinding permissive-binding --clusterrole=cluster-admin --group=system:serviceaccounts clusterrolebinding.rbac.authorization.k8s.io/permissive-binding created ``` 訪問API伺服器 ``` $ curl -H "Authorization: Bearer $TOKEN" https://kubernetes/ { "paths": [ "/api", "/api/v1", ........... ``` 獲取當前執行Pod所在的名稱空間 ``` export NS=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace) ``` 列出當前名稱空間的Pods ``` $ curl -H "Authorization: Bearer $TOKEN" https://kubernetes/api/v1/namespaces/$NS/pods { "kind": "PodList", "apiVersion": "v1", "metadata": { "selfLink": "/api/v1/namespaces/default/pods", "resourceVersion": "454829" .......... ``` ### 簡化與API伺服器的互動 在Pod中,除了主容器外另起一個執行kubectl proxy的容器,這樣主容器就可以通過http://127.0.0.1:8001/訪問API伺服器了。 先構建映象,準備kubectl-proxy.sh和Dockerfile。 ``` # kubectl-proxy.sh #!/bin/sh API_SERVER="https://$KUBERNETES_SERVICE_HOST:$KUBERNETES_SERVICE_PORT" CA_CRT="/var/run/secrets/kubernetes.io/serviceaccount/ca.crt" TOKEN="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" /kubectl proxy --server="$API_SERVER" --certificate-authority="$CA_CRT" --token="$TOKEN" --accept-paths='^.*' ``` myalpine就是一個安裝了curl的自制映象 ``` # Dockerfile FROM registry.cn-hangzhou.aliyuncs.com/orzi/myalpine RUN curl -LO https://storage.googleapis.com/kubernetes-release/release/v1.18.0/bin/linux/amd64/kubectl && chmod +x ./kubectl && mv ./kubectl / COPY kubectl-proxy.sh /kubectl-proxy.sh ENTRYPOINT ["/kubectl-proxy.sh"] ``` 構建、推送 ``` docker build -t registry.cn-hangzhou.aliyuncs.com/orzi/myalpine:kubeproxy . docker push registry.cn-hangzhou.aliyuncs.com/orzi/myalpine:kubeproxy ``` 描述檔案 ``` # mykubeproxy.yaml apiVersion: v1 kind: Pod metadata: name: mykubeproxy spec: containers: - name: myalpine image: registry.cn-hangzhou.aliyuncs.com/orzi/myalpine command: ["sleep","999999"] - name: mykubeproxy image: registry.cn-hangzhou.aliyuncs.com/orzi/myalpine:kubeproxy ``` 建立、檢視 ``` -> [[email protected]] [~] k create -f mykubeproxy.yaml pod/mykubeproxy created -> [[email protected]] [~] k exec -it mykubeproxy -c myalpine sh $ curl http://127.0.0.1:8001 { "paths": [ "/api", "/api/v1", "/apis", ....... ``` ## 小結 - **Downward API允許我們將不能預先知道的Pod元資料通過環境變數或者卷的方式傳遞給應用。** - Downward API可傳遞的資料包括:Pod的IP、名稱、標籤、註解、所在名稱空間、執行的節點名稱、執行所屬的ServiceAccountName,每個容器請求的CPU和記憶體的使用量和限制。 - `env.valueFrom`下引用Pod的欄位使用`fieldRef`,引用容器的cpu和記憶體使用`resourceFieldRef`。 - 對於暴露資源的請求和使用顯示的環境變數,我們通常會設定一個基數單位。實際的資源請求值和使用限制值除以這個基數單位,所得結果通過環境變數暴露出去。 - **使用downward卷的方式傳遞元資料,當Pod的標籤和註解修改後,Kubernetes會更新存有相關資訊的檔案。而環境變數方式下,新值無法暴露。** - 可以通過執行kubectl proxy後,在節點上訪問API伺服器。也可以在Pod中另起一個專門執行kubectl proxy的容器,在主容器中