1.本机搭建K8s环境
建议直接使用 Rancher Desktop 搭建K8s环境,后续的实验也都是基于 Rancher Desktop 搭建K8s环境进行的。
1.1.基于Docker Desktop
Docker Desktop可以一键部署本地K8s环境,只需要点击确定即可。但是K8s的版本是和Docker Desktop的版本是绑定的,无法选择特定的K8s版本。

1.2.基于Rancher Desktop
Rancher Desktop 是 Rancher 推出的一款在桌面上提供容器和 Kubernetes 管理的应用。通过Rancher Desktop,可以自由选择K8s版本、配置容器运行时等。

1.3.直接使用minikube
minikube 还可以通过一个简单的start命令即可创建一个K8s集群:
1 | `minikube start --image-mirror-country='cn' --image-repository='registry.cn-hangzhou.aliyuncs.com/google_containers' ` |
minikube启动后,可以通过以下两个命令查看集群的状态。
1 | `minikube status minikube node list ` |
虽然 minikube 能够搭建 K8s 环境,但是要操作 K8s,还需要下载“kubectl”,可以通过minikube kubectl进行安装。
minikube 自带的 kubectl 有一点形式上的限制,要在前面加上 minikube 的前缀,后面再有个 –
1 | `# kubectl version minikube kubectl -- version ` |
2.创建一个Pod
通过kubectl run命令可以直接创建出一个裸Pod:
1 | `kubectl run ngx --image=nginx:alpine ` |
命令运行后,我们可以通过kubectl get pods查询当前命名空间(默认default)下的所有Pod:

上述的这种创建Pod的方式称为“命令式”,但是在实际操作中,一般都是通过Yaml进行声明,然后通过kubectl创建相应的资源对象。
首先我们通过以下命令先删除之前创建的Pod:
1 | `kubectl delete pod ngx ` |
然后创建一个yaml文件,并写入以下内容:
1 | `# ngx-pod.yml apiVersion: v1 kind: Pod metadata: name: ngx spec: containers: - image: nginx:alpine name: ngx-container ` |
在这个yaml中,kind表明资源对象的类型是Pod; apiVersion表示使用的K8s表示操作这种资源的 API 版本号;metadata表示Pod的元信息,通常我们会在metadata中放入name、labels等信息。
spec是specification,中文翻译为规格、说明书、明细单等,这里其实就是描述这个资源对象的详情或期望状态。例如,这里我们就是希望这个Pod含有1个(containers数组的个数只有1)容器,这个容器使用nginx:alpine镜像,容器的名称是ngx-container。
之后,我们通过kubectl apply创建一个Pod(kubectl create也可以,但是create只能进行创建,无法进行更新):
1 | `kubectl apply -f ngx-pod.yml ` |

kubectl apply用于通过-f参数指定的文件,创建或更新资源对象。kubectl 会智能地找出yaml文件的变更点,并对资源进行更新。
在创建资源后,我们通过kubectl get pod ngx获取当前命名空间下名为ngx的Pod信息。还可以通过下面的命令,可以列举该Pod下所有container的name:
1 | `$ kubectl get pod ngx -o jsonpath='{range .spec.containers[*]}{.name}{"\n"}{end}' ngx-container ` |
K8s对jsonpath的支持可以参看官方文档:https://kubernetes.io/zh-cn/docs/reference/kubectl/jsonpath/。
声明式创建的资源删除也很简单,也是通过kubectl delete命令,但是直接通过-f传递yaml文件名即可。
1 | `kubectl delete -f ngx-pod.yml ` |
3.Yaml模板
通过命令式创建资源简单便捷,但是通过声明式 yaml 文件更加容易对应用进行编排管理和控制。声明式 yaml 文件只用表达I want即可,剩下的K8s系统会自动帮你完成。
使用yaml创建资源固然好,但是对于yaml文件中的字段有哪些,实在是太多了不好记,apiVersion不知道当前的K8s是多少,怎么办呢?难道需要我为每一类资源的yaml文件记录个存档?
其实K8s早就有准备了,最佳实践是让K8s自己为你创建一个资源模板。还是以刚才创建Pod为例,我们只需要多加两个参数-dry-run=client和-o yaml,即在控制台看到K8s为我们生成的创建Pod的模板示例。
-dry-run=client 参数用来预览资源,并不真正将资源提交集群中。-o yaml表明将结果输出为yaml格式。
1 | `$ kubectl run ngx --image=nginx:alpine --dry-run=client -o yaml apiVersion: v1 kind: Pod metadata: creationTimestamp: null labels: run: ngx name: ngx spec: containers: - image: nginx:alpine name: ngx resources: {} dnsPolicy: ClusterFirst restartPolicy: Always status: {} ` |

由于K8s生成yaml示例中含有一些我们用不到的字段,甚至是只读字段,所以我们需要查阅对象的说明文档,添加或者删除字段来定制这个 yaml即可。当然,如果设置了只读字段,K8s也会自动忽略,不会报错。
关于K8s的各个资源的Api说明文档,可以访问官方文档:Kubernetes API | Kubernetes。例如Pod中的字段,可以在Pod | Kubernetes找到说明。
当然,我们也可以使用kubectl explain命令。kubectl explain命令可以为我们解释指定kind或kind下字段的含义,例如:
1 | `kubectl explain pod kubectl explain pod.spec.containers ` |
4.Pod 资源限制
Pod 中的资源限制有两个字段 requests 和 limit ,分别用来表明所需的最小资源以及可能占用的最大资源。类似于最小值和最大值或者是软上限和硬上限。

根据 Pod 是否设置了 requests 和 limit,K8s会提供不同的服务质量QoS:
- Best-Effort:requests 和 limit 均没有设置时,当 Pod 所在的节点被耗尽的时候,这类 Pod 会被第一个删除。
- Burstable:requests < limit 时,当 Pod 所在的节点被耗尽的时候,在所有 Best-Effort Pod 删除完毕后,会开始删除此类 Pod。
- Guaranteed:requests = limit 时,此类 Pod 的优先级最高。
5.Pod 优先级
Pod 可以通过 PriorityClass 定义 Pod 的重要性,进而影响 Pod 的调度的优先级。PriorityClass 资源对象具有一个整数类型的 value 字段,value 越大,优先级越大,表明 Pod 越重要。当存在多个 Pod 需要调度的时候,优先级大的 Pod 先会被调度;当资源不足的时候,优先级低的 Pod 可能会被删除,以便给优先级高的 Pod 腾出资源。我们可以通过 PriorityClass 来定义服务的优先级。

6.Pod的创建过程
Pod的创建过程存在3个阶段、5种状态:

- Pending:Pod正在创建中
- Running:Pod 已经绑定到了某个节点,Pod 中所有的容器都已被创建。至少有一个容器仍在运行,或者正处于启动或重启状态。
- Succeeded:Pod 中的所有容器都已成功终止,并且不会再重启。
- Failed:Pod 中的所有容器都已终止,并且至少有一个容器是因为失败终止。也就是说,容器以非 0 状态退出或者被系统终止。
- Unknown:因为某些原因无法取得 Pod 的状态。这种情况通常是因为与 Pod 所在主机通信失败。
在每个生命周期状态下,还会存在细分的状态,例如处于 Running 的 Pod,还有会有 PodScheduled、ContainersReady、Initialized、Ready 等阶段。只有在 Running 中,且 Ready 是 True 的 Pod 才可以正常地对外提供服务,其他的都不能正常工作。