← 返回上一页

tech

kubectl get 命令的完整执行流程

以 kubectl get nodes 为例,说明命令从参数解析、读取 kubeconfig、构造 URL 到请求 API Server 并打印结果的完整过程。

以命令:kubectl get nodes 为例,它的执行过程可以概括为:

解析命令
  -> 补全并校验参数
  -> 读取 kubeconfig
  -> 解析资源类型
  -> 构造 URL
  -> 发送 HTTP 请求
  -> 接收并解码响应
  -> 格式化输出

1. 解析命令和参数

kubectl 首先识别 get 子命令,并解析资源类型、资源名称、namespace、selector、输出格式等参数。

例如:

kubectl get nodes
kubectl get pods -n default
kubectl get nodes -o yaml

解析完成后,kubectl 会补全当前 namespace、输出格式等运行参数,并校验参数组合是否合法。

2. 读取 kubeconfig

kubectl 通常从以下位置读取 kubeconfig:

  • –kubeconfig 指定的文件
  • KUBECONFIG 环境变量指定的文件
  • $HOME/.kube/config

Windows 默认位置一般是:C:\Users\<用户名>\.kube\config

Linux 或 macOS 默认位置:~/.kube/config

kubeconfig 不是 Kubernetes 项目源码的一部分,通常由 kubeadm、minikube、kind、云平台工具或集群管理员生成。

其中最重要的配置包括:

clusters:
  - name: demo
    cluster:
      server: https://127.0.0.1:6443

users:
  - name: admin
    user:
      token: ...

contexts:
  - name: demo-context
    context:
      cluster: demo
      user: admin
      namespace: default

clusters 表示可以连接的 Kubernetes 集群列表。server 是 API Server 地址,也就是 kubectl 的请求入口。

kubeconfig 还包含认证信息、CA 证书、客户端证书、当前 context 和默认 namespace。

3. 解析资源类型

对于:kubectl get nodes

nodes 是用户输入的 REST Resource,RESTMapper 会通过 Kubernetes Discovery 信息将它解析为:

Resource: nodes
Kind:     Node
Group:    core
Version:  v1
Scope:    Cluster

这里:

Node  是 Kubernetes Kind
nodes 是 API 请求使用的 Resource

RESTMapper 负责确定:

  • 资源对应的 Kind
  • API Group 和 Version
  • REST Resource 名称
  • 是否属于 namespace
  • 应该使用 /api 还是 /apis

4. 构造 API 请求 URL

Node 属于核心 API 组 core/v1(group == ""。为了兼容早期 API,这些资源继续保留在“默认组”中,因此核心组的 Group 表示为空字符串),并且是集群级资源,因此请求路径为:/api/v1/nodes

假设 kubeconfig 中的 API Server 是:https://127.0.0.1:6443

最终 URL 为:https://127.0.0.1:6443/api/v1/nodes

如果查询 namespace 级资源,例如:kubectl get pods -n default

URL 通常为:https://127.0.0.1:6443/api/v1/namespaces/default/pods

如果资源属于非核心 API 组,例如 Deployment:/apis/apps/v1/namespaces/default/deployments

如果带 selector,还会追加查询参数:/api/v1/nodes?labelSelector=kubernetes.io/os=linux

5. 通过 REST Client 发送请求

kubectl 不直接操作 TCP,也不直接访问 etcd。它会使用 client-go 的 REST Client 构造 HTTP Request,再交给 Go 的 http.Client 发送。

请求发送过程中会处理:

  • TLS 和 CA 证书校验
  • 客户端证书认证
  • Bearer Token 或其他认证方式
  • User-Agent
  • Proxy
  • Exec/Auth 插件
  • 请求限流和部分重试

最终发送的是类似请求:

GET /api/v1/nodes HTTP/1.1
Host: 127.0.0.1:6443
Accept: application/json
Authorization: Bearer <token>

6. API Server 处理请求

API Server 是 kubectl 的统一入口。它负责:

  1. 认证请求用户
  2. 授权用户是否可以执行操作
  3. 校验请求路径和参数
  4. 从 etcd 读取数据
  5. 返回资源对象

例如:kubectl get nodes

API Server 会从 etcd 获取 Node 对象,并返回一个 NodeList。

kubectl 不会直接连接以下组件:

  • etcd:由 API Server 访问,用于保存集群状态
  • kube-scheduler:监听 API Server,负责为 Pod 选择节点
  • kube-controller-manager:监听 API Server,负责维持资源的期望状态
  • kubelet:在节点上执行 Pod,并通过 API Server 汇报状态

组件关系可以简化为:

kubectl
   |
   v
kube-apiserver
   |
   +-- etcd
   +-- kube-scheduler
   +-- kube-controller-manager
   +-- kubelet

kubectl 只需要知道 API Server 的地址和认证信息。

7. 接收和解码响应

API Server 返回 HTTP 响应,例如:

HTTP/1.1 200 OK
Content-Type: application/json

响应 body 可能是:

{
  "kind": "NodeList",
  "apiVersion": "v1",
  "items": []
}

client-go 会:

  1. 读取响应 body
  2. 检查 HTTP 状态码
  3. 根据 Content-Type 选择解码器
  4. 将 JSON 或 Protobuf 解码为 Kubernetes 对象
  5. 将错误状态转换为 Kubernetes API 错误

例如:

401 -> 认证失败
403 -> 没有权限
404 -> 资源不存在
500 -> API Server 内部错误

8. 格式化并打印结果

解码后的对象返回给 kubectl,kubectl 根据输出参数选择打印方式:

kubectl get nodes

使用默认表格输出。

kubectl get nodes -o wide

输出更多列。

kubectl get nodes -o yaml
kubectl get nodes -o json

输出完整 YAML 或 JSON。

最终流程就是:

kubectl get nodes
  -> 读取 kubeconfig
  -> 获取 API Server 地址和认证信息
  -> RESTMapper 将 nodes 解析为 core/v1 Node
  -> 构造 /api/v1/nodes
  -> 发送 GET 请求
  -> API Server 认证、授权并从 etcd 读取数据
  -> 返回 NodeList
  -> client-go 解码
  -> kubectl 格式化并打印