# 写给小白的 kubectl 入门

## 前言

意外又看到不少正在学 Kubernetes 新手。想想本人写过各种自己懂或不懂、信或不信的原理、机制、方法和工具等等各种东西，唯独没写过 kubectl，其实这东西也是值得一写的——比如说去年我才从一线同学的操作里学会用 `-A` 代替 `--all-namespaces`。理顺 kubectl 的用法，也会对 Kubernetes 的知识体系以及运维工作有很大的帮助。

对 Kubernetes 稍有了解的读者应该都知道声明式 API 的说法，kubectl 就是一个这种 API 的客户端，所以 kubectl 的主要功能就是用来操作对象的。

## 开局两张图

下图是个常见的使用方式：

> ![](https://cdn.hashnode.com/res/hashnode/image/upload/v1745916448878/cc8d1b0b-e094-4cd5-9024-836ec6640352.png align="center")
> 
> 其实本来想写主谓宾定状补的，后来想想还得复习一下，算了算了。

一般的 kubectl 使用都是这么个顺序，参数是可以调整位置的，暂且如此就可以了。

用一个思维导图来归纳一下：

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1745916455962/006246dc-37db-4b98-a2d4-c7e3ccc9cb49.png align="center")

## 动作

在 kubectl 中被称为 `command` 也就是命令。使用 `kubectl --help` 能看到可用的命令列表：

```plaintext
$ kubectl --help
kubectl controls the Kubernetes cluster manager.

 Find more information at: https://kubernetes.io/docs/reference/kubectl/overview/

Basic Commands (Beginner):
  create        Create a resource from a file or from stdin.
...
  run           在集群中运行一个指定的镜像
...

Basic Commands (Intermediate):
  explain       查看资源的文档
  get           显示一个或更多 resources
...
Deploy Commands:
  rollout       Manage the rollout of a resource
...
```

可以看到 kubectl 的命令行帮助非常不错，不仅有功能说明、分类，还有难度标识，甚至有部分的中文说明，kubectl 的每个命令都可以用 `--help` 查看进一步的帮助说明。

这里列出了很多可用的命令，按照操作能力，主流命令基本可以分为增删改查（CRUD）四种。

### C

新建命令用于在集群中创建对象，最常用的新建命令应该是 `create`、`run` 了，`create` 能够创建多种对象，而 `run` 则主要用来创建 Pod。这两个命令都需要在命令行中使用参数的方式来表达待创建的对象的字段内容，其表达力非常粗糙和有限，并且带有明显的命令式 API 风味，在我的日常工作中已经很少用到这样的命令了。

但是这种命令往往有个妙用，`--dry-run=client`（旧版本中是 `--dry-run`），可以在不产生实际操作的情况下，测试命令的输出，加上 `-o yaml`，可以帮助输出 YAML 文档。

### R

`get` 是最常用的查询指令，用于获取对象列表和基本信息，而 `describe` 则用于获取一个对象的详细信息。另外一个常用的读取指令就是 Debug 常用的日志查看指令：`kubectl logs`。

### U

最重要的更新命令可以说是 `apply`，`edit` 了，`patch`、`label`、`annotation`、`scale` 等命令也算常用。

`apply` 是把 yaml 提交给 Kubernetes 集群的最常用方式，而 `edit` `patch` 都是用于修改线上负载的常用手段。`label` 和 `annotation` 命令则是用于修改对象元数据的，例如标签和注解。

### D

这个没什么好说——`delete`

### 获取帮助

kubectl 的所有命令、子命令都支持 `--help` 参数，可以用这种方式获取帮助。

`kubectl options` 命令能够获取 kubectl 的所有全局参数。

### 常用参数

`-f`：很多指令（不只是 `apply` 和 `create`）都可以用 `-f <文件名>` 的方式进行输入，如果使用管道操作，则可以用参数 `-f -` 接收 STDIN 的输入。

`-l`：可以使用各种对象上的标签对操作范围进行过滤，例如 `-l app=hello`

`-o`：指定输出格式，这个参数相对复杂，最常用的是 `yaml` 或者 `json` 用于输出机器报文，还可以用 JSON Path 或者 Go Template 对结果进行处理。

## 对象

对象通常是类型+名称的一个组合，可以用 kubectl 获得当前集群支持的对象类型：

![](https://cdn.hashnode.com/res/hashnode/image/upload/v1745916477219/e26ba9d8-ff53-4fd1-bf52-07c7abe1383e.png align="center")

如上图，输出内容包含几个列：名称、简称、API 群组、是否归属命名空间以及对象的 Kind 属性。例如常用的 `Deployment`：

* 名称：Deployment
    
* 简称：Deploy
    
* API 群组：apps
    
* 归属命名空间：是
    
* Kind：Deployment
    

使用命令 `kubectl get deploy`，就能获得当前命名空间中的 `Deployment` 对象列表，如果在尾巴上加入 Deployment 的名称，就能得到符合名称要求的 Deployment 对象，

## Schema

前面提到的 `-f` 参数，或者是 `get -o yaml`，都要用到具体的对象数据结构，这个结构到底是哪里规定的呢？基本结构可以分为三个部分，以一个 Namespace 为例：

```yaml
apiVersion: v1
kind: Namespace
metadata:
  name: default
spec:
  finalizers:
  - kubernetes
```

一般会分为四个基础字段：`apiVersion`、`kind`、`metadata`、`status` 以及 `spec`。

* apiVersion：格式为 `<apiGroup>/<apiVersion>`，一个对象的 API Group，可以用前文提到的 `api-resources` 命令查到，而版本则可以通过 `kubectl api-versions` 查询得到。
    
* kind：对应 `api-resources` 命令输出的字段。
    
* metadata：元数据，其中包括标签、注解、名称等字段，如果对象是属于命名空间的，也会把命名空间写在这里。
    
* status：这个字段的内容通常是由 Kubenretes 自动填写的。经常会被省略掉。
    
* spec：具体的对象内容，可以由几个途径获取其定义结构
    
    * 部分资源可以使用 `kubectl explain <对象类别>` 获得解释
        
    * 如果该资源在集群中有对象存在，可以使用 `kubectl get <对象类别> <对象名称> -o yaml` 的方式获得原文，向其致敬。
        
    * 如果前两种方法都没有，就需要去查看 Kubernetes 或者第三方的 API Reference 了。
        

## 最后

看了上面的解释，是不是对 Kubernetes 的控制台操作有点底了？
