基础知识讲解
基础知识讲解
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 (容器运行时):真正负责拉取镜像、启动和停止容器的底层软件(如
containerd、CRI-O,正如我们前面讨论的,现在已不再直接依赖 Docker 引擎)。
3. 运行原理
为了把这些组件串联起来,我们可以看看当你在终端敲下 kubectl apply -f pod.yaml 后,K8s 内部到底发生了什么:
-
用户提交请求:
kubectl将 yaml 文件的内容转化为 REST API 请求,发送给 Master 节点的 kube-apiserver。 -
记录期望状态:apiserver 验证请求合法后,将这个“需要新建一个 Pod”的记录存储到数据库 etcd 中,并返回成功给用户。
-
调度器分配:kube-scheduler 监测到有一个处于待调度(Pending)状态的 Pod,经过一系列算法计算,决定将其分配给节点 Node-A,并将这个决定告诉 apiserver,记录在 etcd 中。
-
工头接活:Node-A 上的 kubelet 监听到 apiserver 说“有一个 Pod 分配给我了”,于是它开始干活。
-
启动容器:kubelet 调用本机的 Container Runtime(如 containerd),执行拉取镜像、创建网络空间、启动容器等具体动作。
-
网络就绪:节点上的 kube-proxy 发现有新的 Pod 启动,自动更新本机的网络路由规则,确保外界或其他服务可以访问到这个新 Pod。
-
持续监控:容器启动后,kubelet 会持续监控它的状态并定期向 apiserver 汇报。如果容器意外崩溃,kube-controller-manager 会察觉到异常,并命令 kubelet 将其重启。
基础命令
1. 基础服务管理
启动 K8s 相关基础组件:
systemctl start docker
systemctl start kubelet
2. 查看与检索类命令 (Get)
这是最常用的资源查询命令,默认查询 default 名称空间,可通过 -n 指定名称空间,或 -A (--all-namespaces) 查询所有。
Node & Pod 查询
| 目标 | 命令 | 说明 |
|---|---|---|
| Node | kubectl get nodes | 获取节点和服务版本信息 |
kubectl get nodes -o wide | 获取节点附加信息(如 IP、系统版本等) | |
| Pod | kubectl 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 (名称空间) | ns | kubectl get ns |
| Services (服务) | svc | kubectl get svc -A |
| ComponentStatuses (组件状态) | cs | kubectl get cs |
| ConfigMaps (配置字典) | cm | kubectl get cm -A |
| ServiceAccounts (服务账户) | sa | kubectl get sa -A |
| DaemonSets | ds | kubectl get ds -A |
| Deployments | deploy | kubectl get deploy -A |
| ReplicaSets | rs | kubectl get rs -A |
| StatefulSets | sts | kubectl get sts -A |
| Jobs | jobs | kubectl get jobs -A |
| Ingresses | ing | kubectl 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 小时)。
解决办法:
-
在 Master 节点生成一个新的 Token:
kubeadm token create -
获取 CA 证书哈希值:
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex | sed 's/^.* //' -
(最省事的方法)直接在 Worker 节点执行
kubeadm reset,然后拿着刚刚新生成的 Token 和 Hash 执行kubeadm join重新将节点加入集群。