本文的試驗環境為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