基础知识讲解

基础知识讲解

Kubernetes(简称 K8s)是一个开源的容器编排引擎,用于自动化容器化应用程序的部署、扩展和管理。它的核心设计理念是声明式 API:你告诉 K8s “我期望集群是什么状态”,K8s 的内部机制会自动不断调整,直到实际状态与你的期望状态一致。

1. 核心概念:什么是 Pod?

Pod 是 K8s 中最小的可部署和管理的基本计算单元,而不是直接管理容器(如 Docker 容器)。

  • 包含关系:你可以把 Pod 想象成一个“豆荚”,而容器是里面的“豆子”。一个 Pod 可以包含一个或多个紧密相关的容器。
  • 资源共享:同一个 Pod 内的所有容器共享同一个网络命名空间(即拥有相同的 IP 地址和端口空间,可以通过 localhost 互相通信)以及相同的存储卷(Volumes)。
  • 生命周期:Pod 是短暂的、随时可以被替换的。如果一个节点宕机,K8s 会在其他健康的节点上创建一个一模一样的新 Pod 来替代它,而不是去“修复”原来的 Pod。

2. K8s 核心组件架构

K8s 采用的是典型的主从架构(Master-Worker)。集群被分为控制平面(Control Plane/Master)数据平面(Worker Node)

控制平面组件 (Master Node - 负责集群的大脑和管理)

这是集群的控制中心,通常为了高可用会部署在多个节点上。

  • kube-apiserver:集群的网关和“大脑”。它是所有组件互相对话的唯一桥梁,也是你通过 kubectl 敲命令时直接对话的组件。它负责请求的认证、授权和路由。

  • etcd:集群的“记忆库”。一个高可用的键值对数据库,保存了整个集群的所有配置数据和状态信息。(注意:为了安全,只有 apiserver 有权限直接读写 etcd)。

  • kube-scheduler:集群的“调度员”。当有一个新 Pod 需要创建时,它负责根据节点的 CPU、内存资源情况以及特定的调度规则,决定把这个 Pod 分配到哪个 Worker 节点上运行。

  • kube-controller-manager:集群的“大管家”。它是一个后台进程集合,不断对比 etcd 中的“期望状态”和集群的“实际状态”。如果发现 Pod 挂了,它会立刻触发重建流程,确保副本数量始终符合预期。

工作节点组件 (Worker Node - 负责干活和运行应用)

这是实际运行业务容器的节点。

  • kubelet:每个节点上的“工头”和 Agent。它直接向 apiserver 汇报当前节点的状态,并接收来自 apiserver 的指令。它负责与底层的容器运行时交互,确保 Pod 和里面的容器按照预期健康运行。

  • kube-proxy:节点上的“网络交警”。它负责维护节点上的网络规则(通常使用 iptables 或 IPVS),实现 K8s 中的 Service 概念,把请求正确地负载均衡并转发到对应的 Pod 上。

  • Container Runtime (容器运行时):真正负责拉取镜像、启动和停止容器的底层软件(如 containerdCRI-O,正如我们前面讨论的,现在已不再直接依赖 Docker 引擎)。

3. 运行原理

为了把这些组件串联起来,我们可以看看当你在终端敲下 kubectl apply -f pod.yaml 后,K8s 内部到底发生了什么:

  1. 用户提交请求kubectl 将 yaml 文件的内容转化为 REST API 请求,发送给 Master 节点的 kube-apiserver

  2. 记录期望状态:apiserver 验证请求合法后,将这个“需要新建一个 Pod”的记录存储到数据库 etcd 中,并返回成功给用户。

  3. 调度器分配kube-scheduler 监测到有一个处于待调度(Pending)状态的 Pod,经过一系列算法计算,决定将其分配给节点 Node-A,并将这个决定告诉 apiserver,记录在 etcd 中。

  4. 工头接活:Node-A 上的 kubelet 监听到 apiserver 说“有一个 Pod 分配给我了”,于是它开始干活。

  5. 启动容器kubelet 调用本机的 Container Runtime(如 containerd),执行拉取镜像、创建网络空间、启动容器等具体动作。

  6. 网络就绪:节点上的 kube-proxy 发现有新的 Pod 启动,自动更新本机的网络路由规则,确保外界或其他服务可以访问到这个新 Pod。

  7. 持续监控:容器启动后,kubelet 会持续监控它的状态并定期向 apiserver 汇报。如果容器意外崩溃,kube-controller-manager 会察觉到异常,并命令 kubelet 将其重启。

基础命令

1. 基础服务管理

启动 K8s 相关基础组件:

systemctl start docker
systemctl start kubelet

2. 查看与检索类命令 (Get)

这是最常用的资源查询命令,默认查询 default 名称空间,可通过 -n 指定名称空间,或 -A (--all-namespaces) 查询所有。

Node & Pod 查询

目标命令说明
Nodekubectl get nodes获取节点和服务版本信息
kubectl get nodes -o wide获取节点附加信息(如 IP、系统版本等)
Podkubectl get pod获取 default 名称空间的 Pod
kubectl get pod -o wide获取 Pod 附加信息(如 IP 及所在节点)
kubectl get pod -n kube-system获取指定名称空间 (kube-system) 的 Pod
kubectl get pod -n kube-system <podName>获取指定名称空间中的指定 Pod
kubectl get pod -A获取所有名称空间的 Pod
输出格式kubectl get pods -o yaml以 YAML 格式显示 Pod 详细信息
kubectl get pods -o json以 JSON 格式显示 Pod 详细信息
标签筛选kubectl get pod -A --show-labels查看所有 Pod 的标签信息
kubectl get pod -A --selector="k8s-app=kube-dns"根据 Selector 标签查询特定 Pod

其他核心资源查询

可以利用简写快速查询各类资源(以下命令均以查全局 -A 为例,可按需替换为 -n <名称空间>):

资源全称简写对应查询命令
Namespaces (名称空间)nskubectl get ns
Services (服务)svckubectl get svc -A
ComponentStatuses (组件状态)cskubectl get cs
ConfigMaps (配置字典)cmkubectl get cm -A
ServiceAccounts (服务账户)sakubectl get sa -A
DaemonSetsdskubectl get ds -A
Deploymentsdeploykubectl get deploy -A
ReplicaSetsrskubectl get rs -A
StatefulSetsstskubectl get sts -A
Jobsjobskubectl get jobs -A
Ingressesingkubectl get ing -A

3. 详细信息与描述 (Describe)

当需要排查 Pod 为什么没启动、或者查看资源的详细事件(Events)时使用。

# 查看 Pod 描述信息
kubectl describe pod <podName>
kubectl describe pod -n kube-system kube-apiserver-k8s-master

# 查看指定名称空间中 Deploy 的描述信息
kubectl describe deploy -n kube-system coredns

# 查看 Node 节点的描述信息
kubectl describe node <nodeName>

4. 资源监控与集群信息 (Top & Cluster-info)

(注:top 命令需要集群已安装 heapster 或 metrics-server 插件支持)

集群状态

# 查看集群基础信息
kubectl cluster-info
kubectl cluster-info dump

# 查看各组件状态信息(需指定 master 机器 IP 及端口号)
kubectl -s https://172.16.1.110:6443 get componentstatuses

资源占用 (Top)

# 查看节点或 Pod 的资源实时使用情况(CPU/内存)
kubectl top node
kubectl top pod

# 结合 Linux 命令实现高级过滤:同时查看多个指定的 Pod 资源使用情况
kubectl top pod | grep -E "aa|bb|cc"

# 高级过滤:同时查看同一台 Node 节点上所有 Pod 的资源使用情况
kubectl top pod | grep -E `kubectl get pod -o wide | grep <节点名称> | awk '{print $1}' | xargs echo | sed 's/ /|/g'`

5. 故障排查与交互 (Logs & Exec)

用于查看服务打印的日志或直接进入容器内部执行命令。

# 持续追踪并查看指定 Pod 的最后 500 行日志
kubectl logs -f --tail 500 -n kube-system kube-apiserver-k8s-master

# 查看运行中 Pod 的环境变量
kubectl exec <podName> env

# 交互模式:进入 Pod 容器内部 (通常是 bash 或 sh)
kubectl exec -it <podName> -n <namespace> -- /bin/bash

6. 资源的创建、更新与删除 (Apply & Delete)

结合图片中常见的生命周期管理命令补充:

# 声明式创建或更新资源 (推荐,基于 yaml 文件)
kubectl apply -f xxx.yaml

# 创建资源
kubectl create -f xxx.yaml

# 删除指定的 Pod (K8s 会根据副本控制器自动重建)
kubectl delete pod <podName> -n <namespace>

# 根据 yaml 文件清理删除对应资源
kubectl delete -f xxx.yaml

# 强制删除一直处于 Terminating 状态的 Pod
kubectl delete pod <podName> -n <namespace> --force --grace-period=0

7. 进阶管理 (Scale & Rollout)

用于控制副本数量和服务版本迭代(图片涉及部分):

# 扩缩容:将指定的 Deployment 副本数调整为 3
kubectl scale deployment <deploymentName> --replicas=3 -n <namespace>

# 查看滚动更新状态
kubectl rollout status deployment <deploymentName> -n <namespace>

# 重启 Deployment (触发滚动更新,常用于重新拉取镜像或刷新配置)
kubectl rollout restart deployment <deploymentName> -n <namespace>

# 回滚到上一个版本
kubectl rollout undo deployment <deploymentName> -n <namespace>

证书续签

K8s 集群通过 kubeadm 安装时,默认生成的证书有效期通常为 1 年。证书过期会导致集群组件无法通信,kubectl 执行时会报错(如 x509: certificate has expired)。

检查证书状态

# 查看各个证书的过期时间及剩余有效时间 (Master 节点执行)
kubeadm certs check-expiration

续签证书

# 一键续签所有由 kubeadm 管理的控制面证书 (有效期顺延 1 年)
kubeadm certs renew all

# (可选) 如果只想续签单个组件的证书,可以指定名称,例如:
kubeadm certs renew apiserver

使新证书生效 (重启静态 Pod)

证书续签后,需要重启控制平面的核心组件(API Server, Controller Manager, Scheduler, etcd)才能加载新证书。

# 方法一:直接重启 kubelet 服务(推荐,会自动重建静态 Pod)
systemctl restart kubelet

# 方法二:临时移出并移回 manifests 配置文件来触发 Pod 重启
# mv /etc/kubernetes/manifests/*.yaml /tmp/
# 等待几秒钟
# mv /tmp/*.yaml /etc/kubernetes/manifests/

更新本地 kubeconfig 配置 (重要)

由于管理证书(admin.conf)也更新了,必须替换掉当前用户 ~/.kube/config 中的旧配置,否则 kubectl 依然无法访问集群。

# 1. 备份旧的配置文件
mv ~/.kube/config ~/.kube/config.bak

# 2. 拷贝新生成的 admin.conf 到用户目录
cp -i /etc/kubernetes/admin.conf ~/.kube/config

# 3. 赋予正确的所属权限
chown $(id -u):$(id -g) ~/.kube/config

验证续签结果

# 确认能否正常获取集群节点信息,且没有报错
kubectl get nodes

# 再次检查证书有效期,确认是否已延长
kubeadm certs check-expiration

工作节点证书过期处理 (手动分发/物理拷贝法)

物理拷贝法

适用场景:二进制部署的 K8s 集群,或不依赖 K8s 原生 CSR 审批,习惯集中管控配置的场景。

当 Worker 节点的 kubelet 证书过期,导致节点离线时,可以在 Master 节点(或证书签发机)统一生成新证书并远程拷贝过去覆盖。

Master 节点:重新生成 Worker 节点证书

(假设你使用的是二进制部署常用的 cfssl 等工具,或者重新生成了 kubelet.kubeconfig 等配置)

Master 节点:通过远程软件/命令发送给 Worker 节点

使用 scp 或自动化运维工具(如 Ansible),将生成好的新证书或配置文件强行推送到瘫痪的 Worker 节点对应的目录。

# 示例:通过 scp 将新证书覆盖到 Worker 节点 (假设 Worker IP 为 192.168.1.100)
scp /path/to/new/kubelet-client.pem root@192.168.1.100:/var/lib/kubelet/pki/
scp /path/to/new/kubelet-client-key.pem root@192.168.1.100:/var/lib/kubelet/pki/

# 或者拷贝新的 kubeconfig 文件
scp /path/to/new/kubelet.kubeconfig root@192.168.1.100:/etc/kubernetes/

验证节点恢复

回到 Master 节点查看节点状态,等待其变为 Ready。

kubectl get nodes

K8s原生机制

适用场景:使用 kubeadm 搭建的集群,利用 K8s 自带的 TLS Bootstrapping 机制,由 Worker 节点向 Master 重新申请证书。

当 Worker 节点的证书完全过期,导致节点离线(NotReady)时,原有的自动轮换机制会失效。需要手动清理旧证书,并让 Master 重新审批下发新证书。

Worker 节点:清理过期证书

登录到出问题的 Worker 节点,删除过期的配置文件和客户端证书,迫使 kubelet 重新发起证书申请(注意千万不要删除 ca.crt 根证书)。

# 1. 停止 kubelet 服务
systemctl stop kubelet

# 2. 备份并移除旧的 kubelet 配置文件
mv /etc/kubernetes/kubelet.conf /etc/kubernetes/kubelet.conf.bak

# 3. 删除过期的 kubelet 客户端证书 (保留 ca.crt)
rm -f /var/lib/kubelet/pki/kubelet-client-current.pem
rm -f /var/lib/kubelet/pki/kubelet-client-*.pem

# 4. 重新启动 kubelet 
# 此时 kubelet 会找不到有效证书,从而使用 bootstrap-kubelet.conf 重新向 Master 发起申请
systemctl start kubelet

Master 节点:审批证书请求 (CSR)

回到 Master 节点,查看 Worker 节点发来的“远程发证”请求,并手动批准。

# 1. 查看集群中的证书签名请求 (CSR)
kubectl get csr
# 你会看到一个状态为 "Pending" (待审批) 的请求,名称类似 node-csr-xxxxxx

# 2. 手动批准该证书请求 (将 <csr-name> 替换为实际的 Pending 名称)
kubectl certificate approve <csr-name>

# 3. 再次查看 CSR 状态,确认状态已变为 "Approved,Issued" (已批准并下发)
kubectl get csr

验证节点恢复

证书下发后,Worker 节点的 kubelet 会自动拉取证书并恢复正常运行。

# 在 Master 节点检查节点状态,等待其状态变为 Ready
kubectl get nodes

常见踩坑记录(Token 过期问题): 如果在 Worker 节点重启 kubelet 后,Master 上执行 kubectl get csr 没有看到任何 Pending 的请求,通常是因为 Worker 节点上 /etc/kubernetes/bootstrap-kubelet.conf 里记录的 Bootstrap Token 也早就过期了(Token 默认有效期只有 24 小时)。

解决办法:

  1. 在 Master 节点生成一个新的 Token:kubeadm token create

  2. 获取 CA 证书哈希值:openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //'

  3. (最省事的方法)直接在 Worker 节点执行 kubeadm reset,然后拿着刚刚新生成的 Token 和 Hash 执行 kubeadm join 重新将节点加入集群。