
用来调度、管理、扩缩容、自愈、滚动更新一堆容器的自动化容器编排平台。
K8s 逻辑图
┌─────────────────────────────────────────────────────────────────────┐
│ 【第一步:用户操作】 │
│ $ kubectl apply -f nginx.yaml │
└───────────────────────┬─────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 【第二步:请求到 kube-apiserver】 │
│ - 认证、鉴权、校验 YAML │
│ - 生成 Deployment 资源对象 │
│ - 写入 etcd 保存(集群唯一状态源) │
└───────────────────────┬─────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 【第三步:Deployment Controller 工作】 │
│ 发现期望副本数=3,当前=0 → 创建 ReplicaSet │
│ ReplicaSet 发现期望 Pod=3 → 开始创建 Pod 模板 │
│ Pod 被创建 → 写入 etcd,状态:Pending │
└───────────────────────┬─────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 【第四步:kube-scheduler 调度】 │
│ 监听 Pending Pod │
│ 过滤节点(资源、亲和性、污点、端口等) │
│ 打分,选一个最优 Node │
│ 给 Pod 绑定 nodeName=node01 │
│ 更新 Pod 信息 → 写入 etcd │
└───────────────────────┬─────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 【第五步:目标节点 kubelet 监听】 │
│ kubelet 监视 apiserver 中分配给自己的 Pod │
│ 发现新 Pod 需要在本机运行 │
│ 开始准备运行环境 │
└───────────────────────┬─────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 【第六步:kubelet 调用容器运行时(containerd/docker)】 │
│ 1. 拉取镜像(ImagePulling) │
│ 2. 创建 Pod 沙箱(pause 容器) │
│ 3. 配置网络(CNI 插件) │
│ 4. 创建数据卷 │
│ 5. 启动业务容器(nginx) │
└───────────────────────┬─────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 【第七步:状态上报 & 健康检查】 │
│ 容器启动成功 → kubelet 上报状态给 apiserver │
│ Pod 状态变为 Running │
│ readinessProbe / livenessProbe 开始检查 │
└───────────────────────┬─────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────┐
│ 【第八步:kube-proxy 配置 Service】 │
│ 发现新 Pod 带有标签 app=nginx │
│ 将 Pod IP 加入 Service 后端列表 │
│ 配置 iptables/ipvs 转发规则 │
│ 服务可通过 Service 域名访问:nginx-svc.default.svc.cluster.local │
└─────────────────────────────────────────────────────────────────────┘
Master 节点(大脑)
Node 节点(干活)
kubectl get nodes # 查看集群所有节点状态
核心作用:快速判断集群节点健康状态,查看节点是否Ready
深入用法:加参数 kubectl get nodes -o wide,可查看节点IP、操作系统、容器运行时(docker/containerd)
关键判断:STATUS 为 Ready 表示节点正常,NotReady 表示节点故障(需排查kubelet、容器运行时)
补充说明:NotReady,下一步用 kubectl describe node 节点名 查看故障原因(如资源不足、网络异常)
kubectl get pods -o wide # 查看所有Pod的详细信息(含运行节点、Pod IP)
核心作用:排查Pod调度情况、运行节点、网络是否正常,比单纯 kubectl get pods 更实用
重点关注字段:
STATUS:Pod状态(Running/Pending/Error等,排错核心)
NODE:Pod运行在哪个节点(方便定位节点问题)
IP:Pod的内部IP(集群内通信用,排查网络连通性)
常用扩展:kubectl get pods -n 命名空间 -o wide(指定命名空间,避免查错命名空间)
kubectl get svc # 查看所有Service(服务暴露入口)
核心作用:查看Service的类型、ClusterIP/NodePort、端口映射,判断服务是否正常暴露
重点关注字段:
TYPE:Service类型(ClusterIP/NodePort等)
CLUSTER-IP:集群内部访问地址(默认自动分配)
PORT(S):端口映射(如80:80/TCP,左边是Service端口,右边是容器端口)
深入用法:加 -o wide 可查看Service关联的Pod标签(匹配Pod的selector)
场景:Pod能正常运行,但访问不到,先查这个命令,看Service是否正常、端口是否正确
kubectl get deploy # 查看所有Deployment(控制器,管理Pod副本)
核心作用:查看Deployment的副本状态(期望vs实际)、更新状态,判断应用是否稳定
重点关注字段:
READY:实际运行的Pod副本数/期望副本数(如3/3表示正常,0/3表示异常)
UP-TO-DATE:最新版本的Pod数(滚动更新后,需等于READY数)
AVAILABLE:可用的Pod数(能提供服务的,和READY基本一致,异常时会减少)
深入用法:kubectl get deploy -o wide 可查看Deployment关联的Pod标签、镜像版本
补充说明:如果READY数不等于期望数,下一步用 kubectl describe deploy 名称 排查(如镜像拉取失败、资源不足)
kubectl describe pod Pod名称 # 查看Pod的详细事件、配置、状态(排错神器)
核心作用:排查Pod异常的根本原因,比logs更全面(logs只看容器日志,describe看整个Pod的生命周期事件)
重点看2个部分:
Events(事件):最关键!从下往上看,红色Error/Warning是故障原因(如ImagePullBackOff、资源不足)
Containers(容器):查看容器镜像、启动命令、端口、资源限制,判断是否配置错误
场景:Pod处于Pending/CrashLoopBackOff状态,先执行这个命令,90%能找到原因
补充:说排错流程时,一定要提“先describe看事件,再logs看容器日志”
kubectl logs -f Pod名称 # 实时查看Pod的容器日志(跟踪程序运行情况)
核心作用:查看容器内部程序的运行日志,排查程序本身的错误(如代码报错、配置错误)
深入用法:
-f:实时跟踪日志(类似tail -f,日常排查常用)
--tail=100:查看最近100行日志(避免日志过多刷屏)
多容器Pod:kubectl logs -f Pod名称 -c 容器名称(指定容器,否则报错)
注意点:只有Pod处于Running状态,才能查看日志;CrashLoopBackOff状态时,可加 --previous 查看上一次启动的日志
场景:Pod能启动但服务异常,用这个命令看程序报错(如端口被占用、配置文件找不到)
kubectl exec -it Pod名称 -- bash # 进入Pod容器内部,交互式操作(调试神器)
核心作用:进入容器内部,查看容器内文件、执行命令,排查容器内部环境问题
参数说明:
-i:保持标准输入打开(交互式)
-t:分配伪终端(模拟终端操作,否则无法输入命令)
--:分隔kubectl命令和容器内命令(避免命令冲突)
深入用法:
多容器Pod:kubectl exec -it Pod名称 -c 容器名称 -- bash
执行单条命令(不进入交互):kubectl exec Pod名称 -- ls /etc/nginx(查看nginx配置目录)
场景:容器启动正常,但服务访问不到,进入容器查看配置文件、测试端口连通性(如ping、curl)
补充:说调试流程时,要提到“exec进入容器,排查内部环境和配置”
kubectl get events # 查看集群所有事件(排错辅助,全局视角)
核心作用:查看集群内所有组件(apiserver、scheduler、kubelet)的事件,排查全局故障(如节点故障、调度失败、镜像拉取异常)
深入用法:
--sort-by='.lastTimestamp':按时间排序(最新事件在最后,方便查看)
-n 命名空间:查看指定命名空间的事件(生产环境常用,过滤无关事件)
grep Error:过滤错误事件(快速定位故障)
重点关注:事件类型(Normal正常、Warning警告、Error错误)、原因(如ImagePullBackOff、NodeNotReady)、涉及对象(Pod/Node/Deployment)
场景:整个集群有异常,单个Pod排查不出问题时,用这个命令看全局事件,定位是否是节点、调度器等组件故障
kubectl apply -f 配置文件.yaml # 创建/更新资源(最常用的部署命令)
核心作用:根据YAML配置文件,创建新资源(Deployment/Pod/Service),或更新已存在的资源(修改YAML后重新执行)
深入用法:
- 批量操作:kubectl apply -f 目录/(执行目录下所有YAML文件,批量部署)
- 查看执行结果:加 --record(记录操作,方便后续回滚时查看历史版本)
关键区别:apply 是“声明式部署”(只指定最终状态,K8s自动协调),比 create 更常用(create是创建,重复执行会报错)
场景:日常部署应用、更新应用配置(修改YAML后,apply即可生效,无需删除旧资源)
kubectl delete -f 配置文件.yaml # 删除YAML文件中定义的所有资源
核心作用:删除指定YAML文件中的资源(Deployment/Pod/Service等),会连带删除关联资源(如delete deploy,会删除关联的RS和Pod)
深入用法:
- 直接删除单个资源:kubectl delete pod Pod名称、kubectl delete deploy 名称
- 强制删除(Pod卡死时):kubectl delete pod Pod名称 --force --grace-period=0(跳过优雅终止,强制删除)
注意点:删除Deployment时,会删除所有关联的Pod,生产环境需谨慎,避免误删
场景:卸载应用、删除异常资源(如卡死的Pod)
kubectl scale deploy 部署名称 --replicas=3 # 扩缩容Deployment的Pod副本数
核心作用:手动调整Deployment管理的Pod副本数,实现扩缩容(应对流量高峰/低谷)
深入用法:
- 扩容:--replicas=5(增加到5个副本)
- 缩容:--replicas=1(减少到1个副本)
- 关联:扩缩容后,Deployment会自动更新RS,RS再创建/删除Pod
补充:说扩缩容时,可提“生产环境可配置HPA(自动扩缩容),根据CPU/内存使用率自动调整副本数”
场景:流量高峰时扩容,保证服务稳定;流量低谷时缩容,节省资源
kubectl rollout restart deploy 部署名称 # 重启Deployment,实现滚动更新
核心作用:重启Deployment管理的所有Pod,实现“滚动重启”(先启新Pod,再删旧Pod,业务不中断)
深入用法:
- 查看滚动更新状态:kubectl rollout status deploy 部署名称
- 回滚(重启失败时):kubectl rollout undo deploy 部署名称(回滚到上一个版本)
- 查看历史版本:kubectl rollout history deploy 部署名称
关键优势:滚动重启不会中断业务,比直接删除Pod再重建更安全(生产环境首选)
场景:应用配置更新后(如ConfigMap挂载)、容器镜像更新后,重启Pod使配置生效
# 关闭防火墙(K8s集群内部通信需要,若保留需放行所有节点端口)
systemctl stop firewalld && systemctl disable firewalld
# 关闭SELinux
setenforce 0
sed -i 's/^SELINUX=.*/SELINUX=disabled/' /etc/selinux/config
# 关闭swap(K8s强制要求)
swapoff -a
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
# 加载内核模块
cat > /etc/modules-load.d/k8s.conf << EOF
overlay
br_netfilter
EOF
modprobe overlay
modprobe br_netfilter
# 配置网络参数
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sysctl --system
# 配置全局代理(针对当前会话,永久生效需写入profile)
cat >> /etc/profile.d/proxy.sh << EOF
export HTTP_PROXY=http://127.0.0.1:20171
export HTTPS_PROXY=http://127.0.0.1:20171
export NO_PROXY=localhost,127.0.0.1,192.168.50.0/24,10.96.0.0/12,k8s-m1,k8s-m2,k8s-m3
EOF
# 赋予执行权限,立即生效
chmod +x /etc/profile.d/proxy.sh
source /etc/profile.d/proxy.sh
# 验证代理生效
echo $HTTP_PROXY
curl https://www.google.com # 正常返回HTML即生效
# 安装依赖
yum install -y yum-utils device-mapper-persistent-data lvm2
# 添加 docker 源(containerd 官方源)
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 安装 containerd
yum install -y containerd.io
# 创建默认配置
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml
# 配置 systemd cgroup(K8s 必须)
sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/' /etc/containerd/config.toml
# ==========================
# 给 containerd 配置代理(关键!)
# ==========================
mkdir -p /etc/systemd/system/containerd.service.d
cat > /etc/systemd/system/containerd.service.d/proxy.conf << EOF
[Service]
Environment="HTTP_PROXY=http://127.0.0.1:20171"
Environment="HTTPS_PROXY=http://127.0.0.1:20171"
Environment="NO_PROXY=localhost,127.0.0.1,192.168.50.0/24,10.96.0.0/12"
EOF
# 重启并开机自启
systemctl daemon-reload
systemctl enable --now containerd
systemctl restart containerd
cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=1
repo_gpgcheck=0
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF
yum install -y kubelet kubeadm kubectl --disableexcludes=kubernetes
systemctl enable --now kubelet
kubeadm init \
--apiserver-advertise-address=192.168.50.3 \
--pod-network-cidr=10.244.0.0/16 \
--kubernetes-version=1.30.0

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubeadm join 192.168.50.3:6443 --token cubrtr.yham3a3x376zi67p \
--discovery-token-ca-cert-hash sha256:3dd5b772d9a82016dbef2233eb38c6f2849938b0b37c1355470e389b33965915
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml
见 主节点【环境基础配置👆】
# 安装依赖
yum install -y yum-utils device-mapper-persistent-data lvm2
# 添加 docker 源(containerd 官方源)
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
# 安装 containerd
yum install -y containerd.io
# 创建默认配置
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml
# 配置 systemd cgroup(K8s 必须)
sed -i 's/SystemdCgroup \= false/SystemdCgroup \= true/' /etc/containerd/config.toml
# containerd 配置代理(走主节点 20171)
mkdir -p /etc/systemd/system/containerd.service.d
cat > /etc/systemd/system/containerd.service.d/proxy.conf << EOF
[Service]
Environment="HTTP_PROXY=http://192.168.50.3:20171"
Environment="HTTPS_PROXY=http://192.168.50.3:20171"
Environment="NO_PROXY=localhost,127.0.0.1,192.168.50.0/24,10.96.0.0/12"
EOF
# 重启生效
systemctl daemon-reload
systemctl restart containerd
见 主节点【安装 K8S👆】
kubeadm join 192.168.50.3:6443 --token cubrtr.yham3a3x376zi67p \
--discovery-token-ca-cert-hash sha256:3dd5b772d9a82016dbef2233eb38c6f2849938b0b37c1355470e389b33965915
kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.7.0/aio/deploy/recommended.yaml
kubectl get pods -n kubernetes-dashboard
kubectl get svc -n kubernetes-dashboard
kubectl edit svc kubernetes-dashboard -n kubernetes-dashboard
type: ClusterIP
# 改成 NodePort
type: NodePort
kubectl get svc -n kubernetes-dashboard
vi dashboard-admin.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kubernetes-dashboard
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kubernetes-dashboard
kubectl apply -f dashboard-admin.yaml
kubectl -n kubernetes-dashboard create token admin-user
https://url:nodeport # kubectl get svc -n kubernetes-dashboard
apiVersion api版本
kind 资源类型
metadata 身份信息
spec 期望状态
原理:K8s 通过探针检测 Pod 健康状态,自动重启异常 Pod,保证服务可用性
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
# 存活探针:检测Pod是否活着,死了就重启
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 30 # 启动30秒后开始检测
periodSeconds: 10 # 每10秒检测一次
timeoutSeconds: 5 # 超时5秒判定失败
# 就绪探针:检测Pod是否 ready,不ready就从Service移除
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 5
resources:
requests: # 最小资源保证(调度时的资源需求)
cpu: 100m # 0.1核
memory: 128Mi # 128MB内存
limits: # 最大资源上限
cpu: 500m # 0.5核
memory: 256Mi # 256MB内存
ConfigMap
apiVersion: v1
kind: ConfigMap # 类型是 ConfigMap
metadata:
name: nginx-index # 👈 这个名字最重要
data:
index.html: |
<h1>我是 K8s 里的自定义首页</h1>
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
# 把 ConfigMap 挂载到容器内
volumeMounts:
- name: nginx-index # 对应下面 volumes 的名字
mountPath: /usr/share/nginx/html/ # Nginx 首页目录
# 定义存储来源:ConfigMap
volumes:
- name: nginx-index # 必须和上面 volumeMounts 名字一样
configMap:
name: nginx-index # 你创建的 ConfigMap 名称
外部用户 → 域名 → Ingress → Service → Pod
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
namespace: default
annotations:
nginx.ingress.kubernetes.io/rewrite-target: / # nginx 重写(可选)
spec:
ingressClassName: nginx # 必须写!指定用 nginx ingress
rules:
- host: www.test.com # 你的域名
http:
paths:
- path: / # 访问路径
pathType: Prefix # 路径匹配规则
backend:
service:
name: my-service # 要转发到哪个 Service
port:
number: 80 # Service 端口