Metadata獲取的三種方式

本文的試驗環境為CentOS 7.3,Kubernetes集群為1.11.2,安裝步驟參見kubeadm安裝kubernetes V1.11.1 集群

0. Metadata

每個Pod都有一些信息,包括但不限於以下的內容:

Pod 名稱Pod IPPod 所屬的命名空間Pod 所在的 NodePod 對應的 service account每個容器的CPU、內存請求每個容器的CPU、內存上限Pod 的標籤Pod 的 annotations

這些信息都可以通過kubectl命令獲取,但是有的情況下,我們需要從應用內獲取,例如獲取當前Pod的地址、主機名等一些信息,這就要求我們必須知道如何在應用內獲取Pod的metadata,本文介紹三種應用內獲取Pod的metadata的方式,供大家參考。

1. 通過環境變量暴露Metadata

apiVersion: v1 kind: Pod metadata: name: downward spec: containers: - name: main image: docker.io/busybox command: ["sleep", "99999"] resources: requests: cpu: 15m memory: 100Ki limits: cpu: 100m memory: 4Mi 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_REQUEST_MILLICORES valueFrom: resourceFieldRef: resource: requests.cpu divisor: 1m - name: CONTAINER_MEMORY_LIMIT_KIBIBYTES valueFrom: resourceFieldRef: resource: limits.memory divisor: 1Ki

在設置資源請求情況的變量時,會設置一個除數,所以環境變量最後顯示計算後的結果。CPU的除數可以是1或者1m,內存的除數可以是1、1k、1Ki、1M、1Mi。

可以看到實際執行的情況

2. 以文件的形式傳遞參數

通過定義downwardAPI卷,可以將環境變量以配置文件的方式暴露給容器的應用。

apiVersion: v1 kind: Pod metadata: name: downward labels: foo: bar annotations: key1: value1 key2: | multi line value spec: containers: - name: main image: busybox command: ["sleep", "9999999"] resources: requests: cpu: 15m memory: 100Ki limits: cpu: 100m memory: 4Mi volumeMounts: - name: downward mountPath: /etc/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: "containerCpuRequestMilliCores" resourceFieldRef: containerName: main resource: requests.cpu divisor: 1m - path: "containerMemoryLimitBytes" resourceFieldRef: containerName: main resource: limits.memory divisor: 1

創建Pod後可以查看掛載的文件。

$ kubectl exec downward ls -lL /etc/downward

利用環境變量的方式無法將labels和annotations導入為環境變量,使用掛載文件的方式就可以,我們因此可以查看Pod具有的labels和annotations。當labels和annotations在Pod運行期間被修改後,修改也可以反映到文件上。這也就是為什麼不能用作環境變量的原因。

$ kubectl exec downward cat /etc/downward/labels $ kubectl exec downward cat /etc/downward/annotations

在獲取容器的資源請求數據時,我們必須指定容器的名稱。不管一個Pod中有一個還是多個容器,我們都需要明確指定容器的名稱。利用這種方式,如果一個Pod含有多個容器,我們可以將其他容器的資源使用情況傳遞到另外一個容器中。

3. 容器外通過API server獲取metadata

上面介紹的兩種方法可以獲取Pod的相關信息,但是這些信息並不是完整的,如果我們需要更多的信息,就需要用到API server。

$ kubectl cluster-info #查看API Server的位置 $ curl http://ip:port/ #查看API列表,如果是https就不行了 [root@devops-101 ~]# kubectl cluster-info Kubernetes master is running at https://192.168.0.101:6443 KubeDNS is running at https://192.168.0.101:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

對於https的情況,可以設置代理,通過代理來訪問,具體如下:

[root@devops-101 ~]#kubectl proxyk Starting to serve on 127.0.0.1:8001 # 換一個終端窗口 [root@devops-101 ~]# curl http://localhost:8001 { "paths": [ "/api", "/api/v1", "/apis", "/apis/", "/apis/admissionregistration.k8s.io", "/apis/admissionregistration.k8s.io/v1beta1", "/apis/apiextensions.k8s.io", "/apis/apiextensions.k8s.io/v1beta1", ...

能夠看到一個列表,通過API的路徑,可以訪問我們想要找到的任何資源。例如查找一個deployment。

[root@devops-101 ~]# curl http://localhost:8001/apis/apps/v1/deployments { "kind": "DeploymentList", "apiVersion": "apps/v1", "metadata": { "selfLink": "/apis/apps/v1/deployments", "resourceVersion": "326381" }, ...

4. 容器內訪問 API Server

容器內訪問API server需要認證,並且需要通過環境變量獲取API Server的地址和端口。

地址的獲取方式如下:

root@curl:/# env | grep KUBERNETES_SERVICE KUBERNETES_SERVICE_PORT=443 KUBERNETES_SERVICE_HOST=10.0.0.1 KUBERNETES_SERVICE_PORT_HTTPS=443

認證主要通過ca.cert及用戶名,ca.cert文件默認掛載在/var/run/secrets/kubernetes.io/serviceaccount/。

具體方法:

[root@devops-101 ~]# kubectl exec -it img-curl /bin/sh / # TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) / # curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt -H "Authorization: Bearer $TOKEN" https://kubernetes { "paths": [ "/api", "/api/v1", "/apis", "/apis/", "/apis/admissionregistration.k8s.io", "/apis/admissionregistration.k8s.io/v1beta1", "/apis/apiextensions.k8s.io",

如果遇到了下圖中的錯誤,需要創建RBAC的角色綁定並且重新執行一下上面的命令。

接下來就可以在Pod的容器中查看metadata的信息,如下查看當前命名空間所有運行的Pods

有了訪問API server的能力,就為我們定義容器內應用的行為提供了無限的想象力,我們可以通過curl來訪問API server,同時也有很多語言的客戶端庫,讓我們方便的在自己的應用中調用API server

Java clientNode.jsPHP