本文的試驗環境爲CentOS 7.3,Kubernetes集羣爲1.11.2,安裝步驟參見kubeadm安裝kubernetes V1.11.1 集羣
0. Metadata
每個Pod都有一些信息,包括但不限於以下的內容:
- Pod 名稱
- Pod IP
- Pod 所屬的命名空間
- Pod 所在的 Node
- Pod 對應的 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