Kubernetes:我怎么知道我在哪个节点上?

Kubernetes: How do I know what node I'm on?

如果我通过 ssh 进入 Kubernetes 节点,我如何找出该节点的 UUID,以便我可以查询主节点 API 以获取该节点的特定信息?

到目前为止已经试过了

root     13020  2.5  1.0 410112 41660 ?        Ssl  Jan25  26:04 /usr/bin/kubelet --logtostderr=true --v=0 --api_servers=http://10.32.140.181:8080 --address=0.0.0.0 --port=10250 --allow_privileged=false --maximum-dead-containers=1 --max-pods=14

[achang@p3dlwsbkn50d51 ~]$ curl -Gs http://localhost:10255/pods/
404 page not found

有许多不同的 ID 和名称与 kubernetes 节点相关联,这取决于您要查找的是哪个。如果你想查询 API 服务器的节点信息,你很可能正在寻找节点名称。节点名称通常与主机名相同,但如果不是,找到它的最简单方法是在 kubelet 中查询 运行 pods,然后查看它们 运行 在哪个节点上:

$ curl -Gs http://localhost:10255/pods/ | grep -o '"nodeName":"[^"]*"' | head -n 1
"nodeName":"e2e-test-stclair-minion-8o3b"

其他ID可以通过查询节点规格找到:

$ curl -Gs http://localhost:10255/spec/ | grep -oE '(machine_|system_uu|boot_)id":.*'
machine_id": "",
system_uuid": "CB7FAAA0-3A53-5FE4-4285-D33D03FEBA6C",
boot_id": "8b89b8f5-5fbb-4cc0-82e4-7c57ec11f656",

最后,externalIDproviderID可以从API服务器查询到:

$ kubectl get nodes e2e-test-stclair-minion-8o3b -o=jsonpath="externalID:{.spec.externalID}; providerID:{.spec.providerID}"

编辑:

如果上述方法失败并且您可以访问 api 服务器,您可以只查找与所需节点的主机名匹配的节点:

$ NODEHOST="your-host"
$ kubectl get nodes | grep "hostname=$NODEHOST"

在kubectl中添加wide output选项可以获得节点名:

// List all pods in plain-text output format and includes additional information (such as node name). $ kubectl get pods -o wide

更多选项:https://kubernetes.io/docs/user-guide/kubectl-overview/

kubelet 是每个节点中的实体 运行,就像 "host agent" 一样,kube-api-server 与之交互以获取节点特定信息并执行节点特定任务。

Kubelet 有关于节点名称的信息。通常,节点名称在启动 kubelet 时使用“--hostname-override”选项给出。

因此,如果设置了 --hostname-override,则以下命令将给出节点名称。

ps-eaf | grep kubelet | tr ' ' '\n' | grep "--hostname-override" | awk -F= ' { 打印 $2 } '

否则,必须有 kubelet API 来提供此信息,但 kubelet API 没有记录,因此最好不要在 Whosebug 中建议它们

我发现当前的 kubernetes 节点(我检查了 minikube、gke 节点池)有文件 /etc/machine-id,其中 cat /etc/machine-id 对于每个 kubernetes 节点都是唯一的,并且与对应的 kubectl get nodes -o json | jq -r .items[].status.nodeInfo.machineID 匹配。

因为不需要API调用,我觉得这种方式更容易和shell或者容器结合。

现在,如果您打算稍后通过环境变量使用它们,最好在部署期间公开它们。

示例:

apiVersion: v1
kind: Pod
metadata:
  name: dapi-envars-fieldref
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      command: [ "sh", "-c"]
      args:
      - while true; do
          echo -en '\n';
          printenv MY_NODE_NAME MY_POD_NAME MY_POD_NAMESPACE;
          printenv MY_POD_IP MY_POD_SERVICE_ACCOUNT;
          sleep 10;
        done;
      env:
        - name: MY_NODE_NAME
          valueFrom:
            fieldRef:
              fieldPath: spec.nodeName
        - name: MY_POD_NAME
          valueFrom:
            fieldRef:
              fieldPath: metadata.name
        - name: MY_POD_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        - name: MY_POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        - name: MY_POD_SERVICE_ACCOUNT
          valueFrom:
            fieldRef:
              fieldPath: spec.serviceAccountName
  restartPolicy: Never

参考

https://kubernetes.io/docs/tasks/inject-data-application/environment-variable-expose-pod-information/