美文网首页
k8s如何访问 pod 元数据

k8s如何访问 pod 元数据

作者: 阿兵云原生 | 来源:发表于2023-07-17 22:55 被阅读0次

如何访问 pod 元数据

我们在 pod 中运行容器的时候,是否也会有想要获取当前 pod 的环境信息呢?咱们写的 yaml 清单写的很简单,实际上部署之后, k8s 会给我们补充在 yaml 清单中没有写的字段,那么我们的 pod 环境信息和容器的元数据如何传递到容器中呢?是不是也是通过获取这些 k8s 默认给我填写的字段呢?

有 3 种方式:

  • 通过环境变量的方式
  • 通过 Downward Api 的方式
  • 通过和 ApiServer 交互的方式

通过环境变量的方式

通过环境变量的方式获取 pod 的信息,还是比较简单的,还记得我们之前将卷中的数据转成环境变量传入到容器中的方式吗?

本次我们也是使用类似的方式来传递数据,应该说比之前的还要简单,不过我们本次传递的是环境信息,例如 pod 的 IP,pod 的 名称,命名空间,pod 所属的服务账号,节点的名称,CPU / 内存的请求 / 限制大小等等

我们任意看一下 pod 的 yaml 清单信息

[图片上传失败...(image-c583e6-1689691899710)]

[图片上传失败...(image-e9c644-1689691899710)]

[图片上传失败...(image-9c6415-1689691899710)]

上述 yaml 清单信息中,每一个字段我们都可以用来传递到容器中作为环境变量,我们可以来尝试写一个

  • 写一个 yaml 清单,创建名称为 my-downward 的 pod
  • 容器里面的使用 busybox 作为基础镜像,由于容器需要运行在 pod 中,因此我们需要运行一个程序在容器中,例如 sleep 8888888 或者其他的任意一个可以长期运行的程序

[图片上传失败...(image-313a56-1689691899710)]

apiVersion: v1
kind: Pod
metadata:
  name: my-downward
spec:
  containers:
  - name: my-downward
    image: busybox
    command: ["sleep","8888888"]
    env:
    - name: XMT_POD_NAME
      valueFrom:
        fieldRef:
          fieldPath: metadata.name
    - name: XMT_NAMESPACE
      valueFrom:
        fieldRef:
          fieldPath: metadata.namespace
    - name: XMT_NODENAME
      valueFrom:
        fieldRef:
          fieldPath: spec.nodeName
    - name: XMT_SERVICE_ACCOUNT
      valueFrom:
        fieldRef:
          fieldPath: spec.serviceAccountName
    - name: XMT_REQUEST_CPU
      valueFrom:
        resourceFieldRef:
          resource: requests.cpu
          divisor: 1m
    - name: XMT_LIMITS_MEMORY
      valueFrom:
        resourceFieldRef:
          resource: limits.memory
          divisor: 1Ki

上述自己配置了多个 XMT_* 的环境变量,来源都是在 pod 中的对应配置,kubectl create 上述 yaml 文件后,可以查看效果如下

[图片上传失败...(image-15a79b-1689691899710)]

环境变量如上所示,当我们容器里面需要使用该环境变量的时候,就可以随取随用了,很方便

可以看到容器中的环境变量和 yaml 清单上的 env 一一对应

[图片上传失败...(image-676135-1689691899710)]

通过 Downward Api 卷的方式

当然,我们也可以使用第二种方式,那就是通过 Downward Api 卷的方式,具体的操作方式和上述环境变量的方式类似,但是使用卷的方式,会在指定的路径下生成文件

Downward Api 看上去会不会想起 Restful Api,是不是都是通过访问接口的方式获取数据呢?

并不是这样的, Downward Api 实际上是将 pod 的定义和状态信息,作为容器的环境变量或者文件的方式,来给容器传递数据的,如图

[图片上传失败...(image-e82265-1689691899710)]

Downward Api 卷的方式可以这么写:

apiVersion: v1
kind: Pod
metadata:
  name: my-downward-vv
  labels:
    xmtconf: dev
spec:
  containers:
  - name: my-downward-vv
    image: busybox
    command: ["sleep","8888888"]
    volumeMounts:
    - name: my-downward-vv
      mountPath: /etc/myvv
  volumes:
  - name: my-downward-vv
    downwardAPI:
      items:
      - path: "xmtPodName"
        fieldRef:
          fieldPath: metadata.name
      - path: "xmtNamespace"
        fieldRef:
          fieldPath: metadata.namespace
      - path: "xmtLabels"
        fieldRef:
          fieldPath: metadata.labels

看这个 yaml 还是比较简单的,和写挂载的方式类似的,此处使用 downwardAPI 下的 items,来传递每一个数据,数据的来源写法和上述的环境变量类似

[图片上传失败...(image-8712d-1689691899710)]

我们可以看到,Downward Api 挂载数据,具体的文件里面会以键值对的方式来呈现,也会以文本的形式来呈现

我们来将 pod 的标签修改成 prod,验证容器里面对应的文件是否会对应修改?

kubectl label pod my-downward-vv xmtconf=prod --overwrite

[图片上传失败...(image-788f11-1689691899710)]

进入容器中查看 /etc/myvv/xmtLabels 文件是否有变化

[图片上传失败...(image-57a1e2-1689691899710)]

通过上述效果,可以看出,当使用 Downward Api 卷的时候,对应的环境变量会以文件的形式存在于我们指定的目录下

若我们在程序运行中修改了环境变量对应的值,那么卷中的文件内容也会相应修改

如何与 APiServer 进行交互?

既然可以用第三种方式与 ApiServer 的方式,咋还使用环境变量和 Downward Api 的方式呢?

自然是因为 Downward Api 的方式有所局限,局限就是 Downward Api 的方式只能获取自身 pod 的数据,如果我们想获取其他 pod 的资源信息,这个时候我们就需要和 Api Server 进行交互了

类似于这样:

[图片上传失败...(image-5e5328-1689691899710)]

那么我们来写一个 pod, 让 pod 里面的容器与 ApiServer 进行交互,此处我们需要注意两点:

  • 我们要确定 ApiServer 的位置,我们才能有机会正确访问到
  • 需要通过 ApiServer 的认证

咱们写一个 pod ,用于在这个 pod 里面使用 curl 访问 ApiServer

自己制作一个简单的带有 curl 的镜像

FROM ubuntu:latest
RUN  apt-get update -y
RUN  apt install curl -y
ENTRYPOINT ["sleep", "8888888"]

制作该镜像,推送镜像到 dockerhub

docker build -t xiaomotong888/xmtcurl .
docker push xiaomotong888/xmtcurl

写一个简单的 yaml,运行 pod

mycurl.yaml

apiVersion: v1
kind: Pod
metadata:
  name: xmt-curl
spec:
  containers:
  - name: xmt-curl
    image: xiaomotong888/xmtcurl
    command: ["sleep","8888888"]

pod 运行成功后,咱们进入到 容器里面

kubectl exec -it xmt-curl bash

咱们可以在 k8s 环境中查看一下 kubernetes 服务的 ip ,我们可以这样来访问

[图片上传失败...(image-f7e351-1689691899710)]

在容器中访问 kubernetes

[图片上传失败...(image-fdc1ea-1689691899710)]

这是因为没有证书,我们需要导入证书和 token , 这样才能正确的访问到 ApiServer,并且还需要一个重要的操作

创建一个 clusterrolebinding,需要创建了该绑定之后,才能正常的访问到 ApiServer,若没有创建该绑定,那么后面的步骤都做好了,ApiServer 也会报 403 Forbidden

kubectl create clusterrolebinding gitlab-cluster-admin --clusterrole=cluster-admin --group=system:serviceaccounts --namespace=dev

证书的位置还记的吗?

[图片上传失败...(image-b68545-1689691899710)]

之前我们查看过默认的 k8s 挂载的位置,/var/run/secrets/kubernetes.io/serviceaccount 这里面有 命名空间,证书,token

[图片上传失败...(image-d2ce09-1689691899710)]

这个时候,我们访问 k8s ApiServer 的时候,可以加上该证书

curl --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt https://kubernetes

我们可以导入一个环境变量,访问 k8s ApiServer 的时候就不需要收到导入证书了

export CURL_CA_BUNDLE=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt

https://gitee.com/common_dev/mypic20220206/raw/master/image-20220204152125059.png

可以看到效果和刚才不一样了,现在报 403 是因为没有 token ,这个时候,我们在加上 token 即可

TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)

[图片上传失败...(image-876451-1689691899710)]

这样就可以看到 apiServer 都有哪些 api 了 , 这些 api 可都是我们在写 yaml 清单时候 apiVersion 的是时候填写的

那么用一个图来结束今天的分享

[图片上传失败...(image-45914-1689691899710)]

容器里面的应用通过证书与 ApiServer 完成认证,通过 token 和 namespace 和 ApiServer 完成接口的交互

今天就到这里,学习所得,若有偏差,还请斧正

欢迎点赞,关注,收藏

朋友们,你的支持和鼓励,是我坚持分享,提高质量的动力

[图片上传失败...(image-6e2291-1689691899710)]

好了,本次就到这里

技术是开放的,我们的心态,更应是开放的。拥抱变化,向阳而生,努力向前行。

我是阿兵云原生,欢迎点赞关注收藏,下次见~

相关文章

  • k8s中service和endpoint

    K8s提供了service对象来访问pod。 为什么没有直接访问pod?一是k8s中pod不是持久性的,宕机重建将...

  • Pod内进程访问k8s服务

    Pod内进程访问k8s服务 外部服务可以通过kubeconfig访问k8s服务,那k8s集群内部服务(Pos内服务...

  • K8S 网络详解 2 kubernetes 网络实现

    K8S 的网络特征: 每个POD 一个IP (IP peer POD) 所有POD 通过IP 直接访问其他POD...

  • 2021-04-24周六

    k8s Secret作用:加密数据存在etcd里面,让Pod容器以挂载Volume方式进行访问场景:凭证基于bas...

  • k8s集群calico网络故障记录

    报错 访问k8s的dashboard界面无法访问网站,查看pod未知原因导致calico的Pod资源重新创建后无法...

  • k8s 问题解决

    core-dns 的 启动失败 重启k8s后 etcd 启动失败 k8s集群关机后重启pod访问不到外网 k8s证...

  • 高可用无单点架构之kubernetes集群

    k8s高可用无单点故障涉及那些场景 k8s 节点添加、pod添加等增删查改无单点故障 需要元数据的存储和处理能力高...

  • kubernetes service 介绍

    一、问题 首先,我们思考这样一个问题: 访问k8s集群中的pod, 客户端需要知道pod地址,需要感知pod的状态...

  • k8s之service account

    service account是k8s为pod内部的进程访问apiserver创建的一种用户。其实在pod外部也可...

  • k8s-访问外网服务的两种方式

    需求 k8s集群内的pod需要访问mysql,由于mysql的性质,不适合部署在k8s集群内,故k8s集群内的应用...

网友评论

      本文标题:k8s如何访问 pod 元数据

      本文链接:https://www.haomeiwen.com/subject/dutnudtx.html