【K8S in Action】第八章 从应用访问pod元数据
通过环境变量或者configMap和secret卷向应用传递配置数据。这对于pod调度、 运行前预设的数据是可行的。对于那些不能预先知道的数据, 比如pod的IP、 主机名或者是pod自身的名称。经在别处定义的数据, 比如pod的标签和注解。不想在多个地方重复保留同样的数据。
通过环境变量或者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_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name 引用pod manifest中的元数据名称字段
- 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: 容器请求的内存和CPU 是 resourceFieldRef 字段
resource: requests.cpu
divisor: lm 资源相关的字段,基数单位
- name: CONTAINER MEMORY LIMIT KIBIBYTES
valueFrom:
resourceFieldRef:
resource: limits.memory
di 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卷来暴露这些标签和注解
multi
line
value
spec:
containers:
- name: main
image: busybox
command: ["sleep", "9999999"]
resources:
requests:
cpu: 15m
memory: lOOKi
limitS:
cpu: 100m
memory: 4Mi
volumeMountS: 在/etc/downward 目录下挂载这个dowanward卷
- name: downward
mountPath: /etc/downward
volumes:
- 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.memory
divisor: 1
$ kubectl exec downward cat /etc/downward/labels
foo="bar"
- 可以在pod运行时修改标签和注解。如我们所愿,当标签和注解被修改后,Kubemetes会更新存有相关信息的文件,从而使pod可以获取最新的数据。
- 在环境变量方式下,一旦标签和注解被修改,新的值将无法暴露。
当暴露容器级的元数据时,如容器可使用的资源限制或者资源请求(使用字段 resourceFieldRef), 必须指定引用资源字段对应的容器名称。因为我们对千卷的定义是基于 pod级的,而不是容器级的。
spec:
volumes:
- name: downward
downwardAPI:
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:8001
curl http://localhost:8001/apis/batch
curl 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/curl
command: ["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 46d
curl 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://kubernetes
secret卷中命名空间的文件,可以读取这个文件来获得命名空间信息
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/curl
command: ["sleep", "9999999"]
- name: ambassador
image: luksa/kubectl-proxy:l.6.2
pod包含两个容器,使用-c main选项指定
kubectl exec -it curl-with-ambassador -c main bash
curl localhost:8001
成功了
curl向在ambassador容器内运行的代理发送普通的 HTTP 请求(不包含任何授权相关的标头), 然后代理向 API 服务器发送 HTTPS 请求, 通过发送凭证来对客户端授权, 同时通过验证证书来识别服务器的身份。
四 使用客户端库与API服务器交互
可以使用一个标准的客户端库来执行简单的 HTTP 请求。
更多推荐
所有评论(0)