通过环境变量或者configMap和secret卷向应用传递配置数据。这对于pod调度、 运行前预设的数据是可行的。
对于那些不能预先知道的数据, 比如pod的IP、 主机名或者是pod自身的名称。经在别处定义的数据, 比如pod的标签和注解。不想在多个地方重
复保留同样的数据。
通过Downward API传递元数据
1 了解可用的元数据
Downward API 允许我们通过环境变量或者文件(在downwardA釭卷中)的传递pod的元数据。这种方式主要是将在pod的定义和状态中取得的数据作为环境变量和文件的值, 如图所示
• pod的名称
• pod的IP
• pod所在的命名空间
• pod运行节点的名称
• pod运行所归属的服务账户的名称
• 每个容器请求的CPU和内存的使用量
• 每个容器可以使用的CPU和内存的限制
• pod的标签
• pod的注解
2 通过环境变量暴露元数据
通过环境变量的方式将pod和容器的元数据传递到容器中。
pod的名称 、IP和命名空间可以通过POD_NAME、 POD_IP和POD_NAMESPACE 这几个环境变量分别暴露。
apiVersion: vl
kind: Pod
metadata: name: downward
spec: containers: - name: main image: busybox command: ["sleep", "9999999") resources:requests: cpu: 15m memory: lOOKi limitS:cpu: 100m memory: 4Mi env: - name: POD_NAMEvalueFrom:fieldRef: fieldPath: metadata.name 引用pod manifest中的元数据名称字段 - name: POD_NAMESPACEvalueFrom: fieldRef: fieldPath: metadata.namespace- name: POD IP valueFrom:fieldRef: fieldPath: status.podIP - name: NODE NAMEvalueFrom:fieldRef: fieldPath: spec.nodeName - name: SERVICE ACCOUNTvalueFrom: fieldRef: fieldPath: spec.serviceAccountName- name: CONTAINER CPU REQUEST MILLICORESvalueFrom:resourceFieldRef: 容器请求的内存和CPU 是 resourceFieldRef 字段resource: requests.cpu divisor: lm 资源相关的字段,基数单位- name: CONTAINER MEMORY LIMIT KIBIBYTESvalueFrom:resourceFieldRef: resource: limits.memorydi visor: lKi看看容器中出环境变量
kubect1 exec downward env
3 通过downwardAPI卷来传递元数据
如果更倾向于使用文件的方式而不是环境变量的方式暴露元数据,可以定义一个downwardAPI卷并挂载到容器中。必须使用downwardAPI卷来暴露pod标签或注解。
apiVersion: vl
kind: Pod
metadata:name: downward labels: foo: bar annotations:keyl: valuel key2: | 通过downwardAPI卷来暴露这些标签和注解multiline value
spec: containers: - name: mainimage: busyboxcommand: ["sleep", "9999999"]resources:requests: cpu: 15m memory: lOOKi limitS:cpu: 100m memory: 4Mi volumeMountS: 在/etc/downward 目录下挂载这个dowanward卷- name: downwardmountPath: /etc/downwardvolumes: - name: downward 通过将卷的名字设定为downward来定义—个dowanwardAPI卷downwardAPI:items: - path: "podName" pod的名称(来自manifest文件中 的metadate.name字段)将被写入fieldRef:fieldPath: metadata.name - path: "podNamespace"fieldRef:fieldPath: metadata.namespace- path: "labels" pod的标签将被保存到/etc/dowanward/labels文件中 fieldRef:fieldPath: metadata.labels- path:"annotations" pod的注解将被保存到/etc/dowanward/annotations 文件中fieldRef:fieldPath: metadata.annotations - path: "containerCpuRequestMilliCores"resourceFieldRef:containerName: main resource: requests.cpu divisor: lm - path: "containerMemoryLimitBytes"resourceFieldRef: containerName: main resource: limits.memorydivisor: 1 $ kubectl exec downward cat /etc/downward/labels
foo="bar"
- 可以在pod运行时修改标签和注解。如我们所愿,当标签和注解被修改后,Kubemetes会更新存有相关信息的文件,从而使pod可以获取最新的数据。
- 在环境变量方式下,一旦标签和注解被修改,新的值将无法暴露。
当暴露容器级的元数据时,如容器可使用的资源限制或者资源请求(使用字段 resourceFieldRef), 必须指定引用资源字段对应的容器名称。因为我们对千卷的定义是基于 pod级的,而不是容器级的。
spec: volumes: - name: downwarddownwardAPI:items: - path: "containCpuRequestMilliCores"resourceFieldRef: containerName: main 必须指定容器名称resource: requests.cpu divisor: lm
二、 与Kubernetes API服务器交互
通过服务相关的环境变量或者 DNS 来获取服务和 pod的信息, 但如果应用需要获取其他资源的信息或者获取最新的信息, 就需要直接与API 服务器进行交互。
2.1 Kubernetes REST API
可以通过运行kubectl cluster-info 命令来得到服务器的 URL。kubectl proxy命令启动了一个代理服务来接收来自你本机的 HTTP 连接并转发至 API 服务器, 同时处理身份认证。
$ kubect1 cluster-info
Kubernetes master is running at https://192.168.99.100:8443$ kubect1 proxy
Starting to serve on 127.0.0.1:8001curl http://localhost:8001/apis/batchcurl http://localhost:8001/apis/batch/vl通过名称恢复一个指定命名空间下的资源 (name:my-job;namespace:dfault)
curl http://localhost:8001/apis/batch/vl/namespaces/default/jobs/my-job
与这个Job资源的完整的 JSON 定义信息一致
kubetcl get job my-job -o json
通过在 /apis/batch/vl/jobs路径运行一个GET请求,列举集群中所有的Job实例。
2.2 从pod内部与API服务器进行交互
apiVersion: vl
kind: Pod
metadata:name: curl
spec: containers: - name: main image: tutum/curlcommand: ["sleep", "9999999"]在完成pod的创建后,在容器中运行kubectl exec来启动一个bashshell
kubectl exec -it curl bash
- 确定API 服务器的位置
- 确保是与 API 服务器进行交互,而不是一个冒名者
- 通过服务器的认证,否则将不能查看任何内容以及进行任何操作
确定API 服务器的位置
Kubemetes API服务器的 IP 地址和端口:名为kubernetes的服务在默认的命名空间被自动暴露。每个服务都被配置了对应的环境变量, 在容器内通过查询KUBERNETES_SERVICE_HOST 和 KUBERNETES_SERVICE_PORT 这两个环境变量就可以获取 API 服务器的 IP 地址和端口。
同样, 每个服务都可以获得一个 DNS 入口,curl 指向 https://kubemetes
kubectl get SVC
NAME CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes 10.0.0.1 <none> 443/TCP 46dcurl https://kubernetes
验证服务器身份
在讨论 Secret 时, 我们看到一个名为 defalut-token-xyz的 Secret 被自动创建,并挂载到每个容器的 /var/run/secrets/kubemetes.io/serviceaccount
目录下。curl允许使用-cacert选项来指定CA 证书。
在容器内执行
curl --cacert /var/run/secrets/kubernetes.io/serviceaccountca.ert https://kubernetes
Unauthorized 设置CURL_CA_BUNDLE环境变量来简化操作,不用每次指定 cacert export CURL_CA_BUNDLE=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
获得API服务器授权
凭证可以使用之前提到的default-token Secret来产生, 同时凭证可以被存放在secret卷的token文件中。
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
Authorization字段向 API 服务器传递了凭证
curl -H "Authorization: Bearer $TOKEN" https://kubernetessecret卷中命名空间的文件,可以读取这个文件来获得命名空间信息
NS=$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)
curl -H "Authorization: Bearer $TOKEN" https://kubernetes/api/vl/namespaces/$NS/pods
三、通过 ambassador 容器简化与 API 服务器的交互
可以在主容器运行的同时, 启动一个ambassador容器,并在其中运行kubecctl proxy命令, 通过它来实现与API服务器的交互。保证安全性的前提下有办法简化通信的方式。
apiVersion: vl
kind: Pod
metadata:name: curl
spec: containers: - name: main image: tutum/curlcommand: ["sleep", "9999999"]- name: ambassador image: luksa/kubectl-proxy:l.6.2pod包含两个容器,使用-c main选项指定kubectl exec -it curl-with-ambassador -c main bashcurl localhost:8001成功了
curl向在ambassador容器内运行的代理发送普通的 HTTP 请求(不包含任何授权相关的标头), 然后代理向 API 服务器发送 HTTPS 请求, 通过发送凭证来对客户端授权, 同时通过验证证书来识别服务器的身份。
四 使用客户端库与API服务器交互
可以使用一个标准的客户端库来执行简单的 HTTP 请求。