Kubernetes元数据访问与API访问

Pod 内的应用可通过 Kubernetes API Server 查询其他 Pod 的元数据,需满足以下条件:

  • 权限配置:为 Pod 所在的 ServiceAccount 授予 get/list Pod 的权限(如绑定 view 角色)。
  • 访问 API Server:通过环境变量或 kubeconfig 获取 API Server 地址和认证信息(如 ServiceAccount 的 Token)。
  1. 创建带权限的 ServiceAccount

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: pod-reader
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: pod-reader
    rules:
    - apiGroups: [""]
      resources: ["pods"]
      verbs: ["get", "list"]
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: pod-reader-binding
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: Role
      name: pod-reader
    subjects:
    - kind: ServiceAccount
      name: pod-reader
      namespace: default
    
  2. 在 Pod 中使用该 ServiceAccount

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-client
    spec:
      serviceAccountName: pod-reader
      containers:
      - name: curl
        image: curlimages/curl
        command: ["sh", "-c", "sleep infinity"]
    
  3. 在 Pod 内通过 API 访问其他 Pod
    进入容器后,执行以下命令查询(需替换 $NAMESPACE$POD_NAME):

    curl -k https://kubernetes.default.svc.cluster.local/api/v1/namespaces/$NAMESPACE/pods/$POD_NAME -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)"
    

若 Pod 属于同一 Service,可通过以下方式获取同服务内的其他 Pod 信息:

  • 环境变量:Kubernetes 会为每个 Service 生成以服务名开头的环境变量,列出 Pod 的 IP 和端口(仅支持旧版 DNS 模式)。

  • DNS 解析:通过 $(服务名).$(命名空间).svc.cluster.local 的 DNS 域名解析到 Service 的 Cluster IP,再通过 Service 访问后端 Pod(需配合 headless Service 直接解析到 Pod IP)。

    apiVersion: v1
    kind: Service
    metadata:
      name: my-service
    spec:
      clusterIP: None  # Headless Service,不分配 Cluster IP,直接返回 Pod IP
      selector:
        app: my-app
    

    Pod 内可通过 DNS 解析获取同服务内的 Pod 列表:

    nslookup my-service.default.svc.cluster.local
    

若仅需获取 当前 Pod 自身 的元数据(如名称、IP、标签等),可通过 Downward API 注入:

  • 环境变量方式

    containers:
    - name: app
      image: my-image
      env:
      - name: POD_NAME
        valueFrom:
          fieldRef:
            fieldPath: metadata.name
      - name: POD_IP
        valueFrom:
          fieldRef:
            fieldPath: status.podIP
    
  • Volume 挂载方式

    volumes:
    - name: pod-info
      downwardAPI:
        items:
        - path: "name"
          fieldRef:
            fieldPath: metadata.name
        - path: "ip"
          fieldRef:
            fieldPath: status.podIP
    

使用 kubectl 命令查看声明式 API:

  • 列出所有 API 资源:使用kubectl api-resources命令可以列出 Kubernetes 集群中的所有 API 资源,显示资源的名称、API 组、资源类型等信息。
  • 列出所有 API 版本kubectl api-versions命令可列出 Kubernetes 集群中可用的 API 版本,显示所有 API 组和版本的信息。
  • 查看特定资源的详细信息:通过kubectl explain <api-resource>命令查看特定资源的详细信息和结构,将<api-resource>替换为具体的 API 资源名称,如kubectl explain pod可查看 Pod 资源的详细信息。

通过 Swagger-UI 可视化查看 Kubernetes 接口文档:

  • 创建反向代理:打开一个 SSH 连接到 K8S 集群,执行kubectl proxy --port=8080命令。
  • 获取 API 文档信息:再打开一个 SSH 连接,执行curl localhost:8080/openapi/v2 > k8s-swagger.json命令,将 K8S 的 API 文档信息输出到k8s-swagger.json文件中。
  • 运行容器:执行docker run --rm -d -p 80:8080 -e SWAGGER_JSON=/k8s-swagger.json -v $(pwd)/k8s-swagger.json:/k8s-swagger.json swaggerapi/swagger-ui命令。此时,在浏览器上输入http://ip(IP 为运行容器的主机 IP),即可看到可视化的 API 文档界面。

使用 Curl 从 Kubernetes API 服务器获取信息:

~/.kube/config 文件中提取信息。~/.kube/config 文件包含了与 Kubernetes 集群进行通信所需的配置信息。我们需要从中提取以下信息:

  • API 服务器地址:Kubernetes API 服务器的 URL。

  • 客户端证书:用于身份验证的客户端证书。

  • 客户端私钥:与客户端证书对应的私钥。

  • CA 证书:用于验证 API 服务器证书的 CA 证书。

    # 提取 API 服务器地址
    API_SERVER=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')
    
    # 提取客户端证书
    CLIENT_CERT_DATA=$(kubectl config view --minify -o jsonpath='{.users[0].user.client-certificate-data}')
    echo $CLIENT_CERT_DATA | base64 -d > client.crt
    
    # 提取客户端私钥
    CLIENT_KEY_DATA=$(kubectl config view --minify -o jsonpath='{.users[0].user.client-key-data}')
    echo $CLIENT_KEY_DATA | base64 -d > client.key
    
    # 提取 CA 证书
    CA_CERT_DATA=$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.certificate-authority-data}')
    echo $CA_CERT_DATA | base64 -d > ca.crt
    
  • 使用以下 curl 命令获取所有命名空间中的 Pod 信息:

    curl --cacert ca.crt --cert client.crt --key client.key $API_SERVER/api/v1/pods
    
  • 使用以下 curl 命令获取所有命名空间的信息:

    curl --cacert ca.crt --cert client.crt --key client.key $API_SERVER/api/v1/namespaces
    

posted @ 2022-04-29 17:12  wanghongwei-dev  阅读(152)  评论(0)    收藏  举报