精读笔记 · 第33章 Kubernetes 容器编排工具
精读笔记 · 第33章 Kubernetes 容器编排工具
精读整理自 RHCE9 随堂讲义(原文字版 约 200 页大章)|同名视频(第02套 K8S 章节) 关联知识文件:
分章笔记/01-Linux/02-08-自动化运维(K8S);前置:第32章 Docker
一、Kubernetes 核心概念
| 概念 | 要点 |
|---|---|
| Master | 核心/管理节点:资源调度、控制副本、统一访问集群入口 |
| Node | 运行 Pod 的服务节点,被 Master 管理,汇报容器状态并管理生命周期 |
| Node IP | 节点物理网卡 IP,真实网络,服务器间直接通信 |
| Pod | “豆荚”,k8s 最小创建/调度/管理单位;一个或多个紧耦合容器组合,同宿主机、共享网络命名空间/IP/端口,可用 localhost 通信;Pod 是集群里的“应用” |
| pause 容器 | 每个 Pod 内置一个 pause 容器作为网络接入点,其他容器以容器映射模式接入;Node 宕机则该 Node 上 Pod 全部被重新调度 |
| Pod IP | docker0 网桥网段分配的虚拟二层地址,跨 Node 通信经虚拟二层网络+物理网卡流出 |
| Pod Volume | 对应 Docker Volume,解决容器间共享数据与外部存储 |
| Namespace | 逻辑划分资源对象(项目/用户),实现多租户/虚拟集群 |
| RC/ReplicaSet | 确保指定 Pod 副本数恒定;弹性伸缩/动态扩容/滚动升级核心;由 selector+replicas+template 三要素组成 |
| Deployment | 更高级对象,管理 ReplicaSet 与 Pod,官方建议用 Deployment 而非直接 RS;最常用资源 |
| Service | Pod 逻辑集合+访问策略=真实服务抽象,统一访问入口、服务代理与发现(微服务) |
| Cluster IP | Service 的虚拟 IP,与 Pod 不同网段,集群内部访问 |
| Label | 任意 API 对象的标识:K/V 键值对;控制器通过 Label Selector 过滤被控对象;命令行过滤用 -l app=nginx(key=value 用等号) |
| Event | 与资源对象关联的事件记录:最早/最后时间、重复次数、发起者、原因——排障第一参考 |
二、架构与组件
- Master 组件:
kube-apiserver:集群统一入口(REST API);kube-controller-manager:一系列控制器集合(RC/Deployment/Node/Namespace/Service/Endpoints/ServiceAccount/PV/DaemonSet/Job/PodAutoscaler 等控制器,各司其职保证期望状态);kube-scheduler:负责任务/资源调度。
- etcd:分布式键值数据库,保存 Pod、Service 等集群状态数据,可部署在 master/node,生产推荐独立部署。
- Node 组件:
kubelet(接 API Server 请求,启停/监控容器并汇报)、kube-proxy(获取 Service 信息创建代理,实现请求路由转发)、docker(容器引擎;k8s 还支持 rocket)、flanneld网络插件。 - 常用镜像仓库:docker.io/library、daocloud.io/library、mirrorgooglecontainers(docker hub k8s 镜像)、aliyun google-containers。
三、集群部署方式
- 四种方式:① minikube(本地单点体验/开发,不可生产);② kubeadm(init/join 快速部署,官方推荐);③ yum(版本低 1.5);④ 二进制包(从官方下载逐组件手动部署,可完全掌控)。
- 二进制方式目标任务(v1.13+Docker 19.09 示例):规划架构→部署 Etcd 集群→Node 装 Docker→部署 Flannel→Master 部署 apiserver/scheduler/controller-manager→Node 部署 kubelet/kube-proxy→查看集群状态→跑测试示例→部署 Dashboard(可选)。
- 规划要点:主机名互解析(/etc/hosts);关防火墙与 SELinux;机器内存 ≥3G;apiserver 高可用可用 LVS/Nginx stream 4 层反代(upstream 两个 master:6443)。
- Etcd:用 cfssl 生成自签证书(ca-config.json/ca-csr.json/server-csr.json →
cfssl gencert ... | cfssljson -bare);配置 /opt/etcd/cfg/etcd(ETCD_NAME/DATA_DIR/LISTEN_PEER_URLS 2380/LISTEN_CLIENT_URLS 2379/INITIAL_CLUSTER…每节点改自己 IP);systemd 管理;etcdctl --endpoints=... cluster-health验证。 - Flannel:往 etcd 写入子网、启动 flanneld;注意
--iface指定物理网卡、--ip-masq、--mtu=1450;确保 docker0 与 flannel.1 同网段、跨节点互通。
- kubeadm 方式(v1.19.1 示例)步骤:
- 准备:/etc/hosts 互解析、关 firewalld/SELinux、所有节点
yum install -y kubelet kubeadm kubectl ipvsadm(可装固定版本kubelet-1.19.1)。 - 内核与转发:加载
ip_vs ip_vs_rr ip_vs_wrr ip_vs_sh nf_conntrack_ipv4(写入 /etc/rc.local 开机加载);/etc/sysctl.d/k8s.conf配net.bridge.bridge-nf-call-iptables=1、vm.swappiness=0,sysctl --system;报错先modprobe br_netfilter。 - 关闭 Swap(1.8 起强制):
swapoff -a并注释 /etc/fstab 中 swap 行;或 kubelet 加--fail-swap-on=false。 - 配置 kubelet:按 docker 的 Cgroup Driver 设
/etc/sysconfig/kubelet的KUBELET_EXTRA_ARGS="--cgroup-driver=cgroupfs --pod-infra-container-image=...pause:3.2"(pause 镜像要能拉到,国内用 aliyun google_containers 源)。 - Master 初始化:
kubeadm init --kubernetes-version=v1.19.1 --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=<master IP>;kubeadm init 前 kubelet 因缺 ca.crt 反复重启属正常,init 生成 CA 后自动解决。 - 网络插件 Flannel:
kubectl apply -f kube-flannel.yml;注意把 namespace 改 kube-system(或不改),给 flannel 加node.kubernetes.io/not-ready:NoSchedule污点容忍(节点未 Ready 前不接受调度,而没网络插件节点又 Ready 不了——先容忍再起来);kubectl get pods -n kube-system全 Running 且kubectl get nodesReady 即成功。 - Node 加入:master 上执行 kubeadm init 后返回的
kubeadm join <apiserver>:6443 --token ... --discovery-token-ca-cert-hash sha256:...;报错开sysctl -w net.ipv4.ip_forward=1。 - Token 过期重来:
kubeadm token create --print-join-command(一步到位);ca hash 用openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | openssl dgst -sha256 -hex。 - 重置/移除节点:master 上
kubectl drain 节点 --delete-local-data --force --ignore-daemonsets→kubectl delete node 节点→节点上kubeadm reset;master reset 后还要rm -rf /var/lib/cni/ $HOME/.kube/config;只初始化出错时kubeadm reset后重来即可。
- 准备:/etc/hosts 互解析、关 firewalld/SELinux、所有节点
- 常见错误整理:服务器时间不一致报错;pause 镜像拉取失败(按提示镜像名重新打 tag,再 reset 重初始化);异常 Pod 用
kubectl delete pod xxx -n kube-system让它重建;journalctl -xefu kubelet查 kubelet 日志。
四、kubectl 与发布第一个应用
- 理念:K8s 不推荐命令行直接跑容器,而是“把定义写进 YAML →
kubectl create/apply -f”,文件可版本控制、可审计、可描述复杂结构。 - 创建流程模板:有镜像→(考虑要不要副本:不做副本=裸 Pod;做副本用 Deployment/RC/DaemonSet)→做副本还要 Service 才能访问。
- 首个 Pod 示例 pod.yml:
apiVersion: v1、kind: Pod、metadata{name: website, labels{app: website}}、spec.containers[{name, image: daocloud.io/library/nginx, ports[{containerPort: 80}]}]。 - 常用命令:
kubectl apply -f xxx.yaml(可加 --validate 看报错)、kubectl create -f、kubectl delete -f / delete pod 名 / --all、kubectl get pods [-o wide | -o yaml | -l app=x]、kubectl describe pod/node(重点看 Events)、kubectl exec -it pod /bin/bash。 - create vs apply:create 修改 yml 必须删了重建;apply 可直接改 yml 再 apply(声明式)。
- 发布流程小例:
kubectl apply -f namespace.yml创建 ns(ns-monitor),kubectl get namespace;发布 nginx pod → get pods 见 READY 1/1 →-o wide看跑在哪个 Node → 容器内 curl 验证。 - Pod 生命周期状态:Pending(对象已建但容器未就绪,如调度不成功)、Running(已调度且至少一个容器运行)、Succeeded(全部正常退出,一次性任务)、Failed(有容器非 0 退出,查 Events/日志)、Unknown(kubelet 汇报异常,主从通信问题);Conditions 细分:PodScheduled/Ready/Initialized/Unschedulable。
- 其他常见状态:CrashLoopBackOff(容器反复退出重启)、ErrImagePull/ImagePullBackOff(镜像拉取失败/重试)、CreateContainerConfigError、RunContainerError、ContainerCreating、PodInitializing、NetworkPluginNotReady 等。
- get deployments 列字段:READY(Running 数)/UP-TO-DATE(与最新模板一致数)/AVAILABLE(Running+最新+Ready,用户期望终态)/AGE。
五、YAML 语法
- 规则:大小写敏感;缩进表层级;不能用 Tab 只能用空格;同级左对齐即可;
#注释。 - 两种结构:Maps(字典
key: value,value 可嵌套 Map/List);Lists(数组,-开头与父元素缩进);多个文档用---分隔。 - 好处:便捷(不用堆命令参数)、可维护(源码管理)、灵活(复杂结构)。
六、Pod API 属性详解
- 视角:Pod=“机器/虚拟机”,容器=机器里的“用户程序”;调度、网络、存储、安全相关属性基本是 Pod 级。
- 容器级可选属性:name/image/command/args/workingDir/ports/env/resources/volumeMounts/livenessProbe/readinessProbe/lifecycle/imagePullPolicy/securityContext/stdin/tty 等。
- 手动调度:
nodeName: k8s-node1(直接绑定节点,可“骗过”调度器,多用于调试);nodeSelector: {kubernetes.io/hostname: node2}(按节点标签选择)。 - 生命周期钩子 lifecycle:
postStart(容器启动后执行,不保证先于 ENTRYPOINT 完成,失败则 Pod 报启动失败)、preStop(被杀前执行,同步阻塞杀死流程,可实现优雅退出,如 nginx -s quit)。 - 恢复策略
restartPolicy:Always(默认,异常必重建)、OnFailure(仅异常重启)、Never;注意 K8s 没有 Docker 的 stop 语义,“重启”实际是删除重建容器;Pod 恢复永远在当前节点,Pod 一旦绑定 Node 不会自己换节点。 - 探针(健康检查):exec 型
livenessProbe.exec.command: [cat /tmp/healthy](文件消失→探测失败→容器被杀重启,RESTARTS+1 而 Pod 保持 Running);httpGet 型httpGet: {port: http, path: /index.html}+initialDelaySeconds/periodSeconds(删掉 index.html → 容器被 kill 重建,文件“又回来了”)。 - 资源:CPU/Memory 可设 limits/requests。
七、Projected Volume 与 Downward API
- Projected Volume(v1.11+):不是存数据/交换数据,而是“把预先定义的数据投射进容器”,共四种:Secret、ConfigMap、Downward API、ServiceAccount。
- Downward API:容器内获取 Pod 基本信息,两种方式:
- 环境变量(单值):
env: - name: POD_IP valueFrom: fieldRef: fieldPath: status.podIP;metadata.name/namespace 属元数据用 metadata 取,podIP 属状态数据用 status 取。 - Volume 挂载(labels/annotations 生成文件):
volumes: - name: podinfo downwardAPI: items: - path: "labels" fieldRef: fieldPath: metadata.labels→ 挂到 /etc/podinfo/labels。
- 环境变量(单值):
- 支持字段:spec.nodeName、status.hostIP、metadata.name/namespace/uid、status.podIP、spec.serviceAccountName、metadata.labels[KEY]、metadata.annotations[KEY] 及整体 labels/annotations。
- 提示:Secret/ConfigMap/Downward API 虽也能用环境变量注入,但环境变量不会自动更新,建议用 Volume 文件方式。
八、ServiceAccount
- 定义:User Account 给人(kubectl,默认 admin);Service Account 给 Pod 里的进程,让进程带着身份访问 apiserver(默认 default)。
- 区别:User 跨 namespace,SA 只在本 namespace;每个 namespace 自动创建 default SA;Token controller 为 SA 自动建 Secret。
- Admission Controller 行为:Pod 默认自动设 serviceAccount=default;校验 SA 存在否则拒绝;未指定 imagePullSecrets 时继承 SA 的;每个容器自动挂载该 SA 的 token 与 ca.crt 到 /run/secrets/kubernetes.io/serviceaccount。
- 示例:
kubectl create serviceaccount mysa→ describe sa 见自动 secret(mysa-token-xxx)→ pod 的serviceAccountName: mysa→ 容器以 mysa token 与 apiserver 交互;可用kubectl get pod -o jsonpath="{.spec.volumes}"查看挂载的 token secret。
九、RBAC(基于角色的访问控制)
- 授权模式共 6 种:ABAC、RBAC、Webhook、Node、AlwaysDeny、AlwaysAllow;1.6 起默认 RBAC(
--authorization-mode=RBAC),1.8 起稳定。 - 对象:Role(单 namespace 内权限集合:允许的 verb 如 get/list/watch/delete/create + 资源如 pod/service);ClusterRole(全集群范围);RoleBinding(把 Role 绑给用户/SA);ClusterRoleBinding(绑 ClusterRole);Secret 存敏感信息。
- 授权两步:定义角色 → 绑定主体。
- 完整实验(创建用户 soso 并授权):
- 证书:
openssl genrsa -out soso.key 2048→openssl req -new -key soso.key -out soso.csr -subj "/CN=soso"→openssl x509 -req -in soso.csr -CA /etc/kubernetes/pki/ca.crt -CAkey .../ca.key -CAcreateserial -out soso.crt -days 365。 - 登记用户并设上下文:
kubectl config set-credentials soso --client-certificate=soso.crt --client-key=soso.key --embed-certs=true→kubectl config set-context soso@kubernetes --cluster=kubernetes --user=soso→use-context soso@kubernetes切换(current-context 查看)。 - 未授权测试:
kubectl get pod报 Forbidden(User "soso" cannot list pods)。 - 建角色与绑定(切回管理员):
kubectl create role myrole --verb=get,list,watch --resource=pod,svc;kubectl create rolebinding myrole-binding --role=myrole --user=soso。 - 再切 soso 验证 default 空间可 get pod/svc,访问其它空间/资源仍被拒。
- 集群级授权:
kubectl create clusterrole 名 --verb=... --resource=...(可访问全部 namespace 资源),用 ClusterRoleBinding 绑定后可看 kube-system 的 pod。
- 证书:
十、Deployment 详解与滚动更新
- 创建流程:用户 kubectl 创建 Deployment → Deployment 创建 ReplicaSet → RS 创建 Pod;命名规则:子对象名=父对象名+随机串。
- YAML 骨架(apps/v1):
apiVersion: apps/v1 # 版本不写死,随集群版本/资源类型变,可用 kubectl api-versions 查
kind: Deployment
metadata: {name: nginx-deployment}
spec:
selector: {matchLabels: {app: nginx}} # Label Selector,管理它关心的 Pod
replicas: 2 # 期望副本数
template: # Pod 模板,与被控 Pod 定义一致
metadata: {labels: {app: nginx}}
spec:
containers: [{name: nginx, image: nginx:1.7.9, ports: [{containerPort: 80}]}]- 控制器模式:Deployment=“上半部分期望状态定义 + 下半部分被控对象模板”,kube-controller-manager 中一系列控制器各自循环确保实际状态=期望状态(多了删、少了建)。
- 常见操作:
kubectl get deployments / get pods -l app=nginx;扩容:改 replicas: 4 再kubectl apply -f deployment.yaml --record(记录变更命令);kubectl edit deployment dep01在线改副本;升级镜像:新 deployment 换 image(如 nginx:1.14→1.16)触发滚动更新——新 RS 0→1→2…旧 RS 3→2→1→0 交替(Events 里可见 ScalingReplicaSet),期间旧版本在线、服务不中断,新版本有问题则滚动停止便于介入。 - 回滚:
kubectl rollout history deployment/dep02(--record 才能看到变更原因);kubectl rollout undo deployment/dep02(回上一版);--to-revision=3回指定版;kubectl rollout status deployment/dep02看结果。 - 扩展了解:金丝雀发布(Canary)与蓝绿发布(Blue-Green)。
十一、Service 与对外暴露
- Service 三端口(最易混):
port:Service 暴露在 ClusterIP 上的端口,ClusterIP:port给集群内部访问;nodePort:暴露在每个节点上的端口,nodeIP:nodePort给集群外部访问(范围 30000+);targetPort:后端 Pod 容器端口;port/nodePort 来的流量经 kube-proxy DNAT 到后端 pod 的 targetPort。
- 原理:kube-proxy 在本地 node 建 iptables/ipvs 规则(DNAT→本地随机端口→代理到真实 Pod),装 iptables 后即使服务关闭,规则仍写入生效。
- 暴露 4 种方式:① ClusterIP(默认,仅集群内);② NodePort(外网 client→nodeIP:nodePort→podIP:podPort,同时保留 ClusterIP);③ LoadBalancer(NodePort 之上请求云平台建负载均衡器,以每 Node 为后端);④ Ingress(HTTP 层路由转发机制,为服务配 HTTP 负载均衡器,暴露给集群外;完整生产还要外层负载均衡器如 HAProxy/Nginx)。
- Service YAML 示例(NodePort):
kind: Service
apiVersion: v1
metadata: {name: mysvc}
spec:
type: NodePort
ports:
- port: 8080 # ClusterIP 端口
nodePort: 30001 # Node 暴露端口
targetPort: 80 # Pod 端口
selector: {app: web} # 标签选择后端 Pod- 验证:
kubectl get svc看 CLUSTER-IP 与 8080:30001/TCP;浏览器/curl 节点IP:30001;注意 NodePort 在 node 上访问而非 master。 - RC 资源(了解,kind: ReplicationController + replicas + template):与 Pod YAML 区别只是 kind/replicas/template(Pod 名自动生成);
kubectl get rc(DESIRED/CURRENT/READY)、kubectl delete rc my-nginx会级联删除所管 Pod,想保留 Pod 用--cascade=false;删除前先删 Pod 会被 RC 立刻补建——所以复杂应用推荐 RC/Deployment 管理。 - Volume 类型补充:emptyDir(k8s 自建临时目录,等同 Docker 隐式卷,Pod 删除即失);hostPath(显式宿主机目录,如 /var/data);Pod 里卷由 volumes 定义、容器用 volumeMounts+mountPath 挂载;hostPath 实战:node 建目录写 index.html + Deployment 指定 nodeName + 挂 hostPath + NodePort Service 暴露访问。
十二、Dashboard 部署(Web UI)
- 下载官方 yaml:
wget https://raw.githubusercontent.com/kubernetes/dashboard/v2.4.0/aio/deploy/recommended.yaml;sed -i '/namespace/ s/kubernetes-dashboard/kube-system/g'。 - 预拉镜像:
docker pull kubernetesui/dashboard:v2.4.0、kubernetesui/metrics-scraper:v1.0.7(node 自动拉取也可)。 - 改 Service 为 NodePort 并指定
nodePort: 31260(targetPort 8443);kubectl apply -f recommended.yaml会创建 namespace/sa/service/secret/configmap/role(clusterrole)/rolebinding(clusterrolebinding)/deployment 等一串资源。 - 访问:
https://nodeIP:31260;5 种访问方式(NodePort/LoadBalancer/Ingress/API server/kubectl proxy),课程用 NodePort。 - 登录认证(Kubeconfig 或 Token 二选一,课程用 Token):创建 admin-user SA + ClusterRoleBinding 绑定内置 cluster-admin:
kind: ServiceAccount
metadata: {name: admin-user, namespace: kube-system}
kind: ClusterRoleBinding
roleRef: {apiGroup: rbac.authorization.k8s.io, kind: ClusterRole, name: cluster-admin}
subjects: [{kind: ServiceAccount, name: admin-user, namespace: kube-system}]- 取 Token:
kubectl -n kube-system get secret $(kubectl -n kube-system get sa admin-user -o jsonpath="{.secrets[0].name}") -o jsonpath="{.data.token}" | base64 -d。 - 界面:顶部操作区搜索/创建/退出;左导航按层级管理资源;中间主体显示资源实例(如 Pods)。
十三、PV / PVC 持久化存储
- 引入原因:Pod 由开发者维护、Volume 由存储管理员维护,二者职责耦合;PV/PVC 把职责分离。
- 概念:PV=管理员创建维护的外部存储空间,生命周期独立于 Pod;PVC=用户对 PV 的申请(只声明容量/访问模式/class,不关心底层细节)。
- NFS 实验拓扑:master 作 nfs-server(
yum install -y nfs-utils rpcbind;mkdir /nfsdata;chmod 666;/etc/exports 写/nfsdata *(rw,no_root_squash,no_all_squash,sync);先启 rpcbind 再启 nfs),node 作 nfs-client,可用mount -t nfs server:/nfsdata /test先验证。 - PV YAML 关键字段:
capacity.storage(容量)、accessModes(ReadWriteOnce 单节点读写 / ReadOnlyMany 多节点只读 / ReadWriteMany 多节点读写)、persistentVolumeReclaimPolicy(Retain 人工回收 / Recycle 自动清数据已废弃 / Delete 删除底层存储)、storageClassName(分类标签,PVC 同 class 才能匹配)、nfs{path, server}。 - PVC YAML:accessModes +
resources.requests.storage+ storageClassName;kubectl get pv/pvc查看,mypvc1 Bound 到 mypv1 即申请成功。 - Pod 使用:
volumes: - name: mydata persistentVolumeClaim: {claimName: mypvc1}+ volumeMounts;在 Pod 里写 index.html 会同时出现在 NFS /nfsdata,任意一端删文件两端消失;配合 NodePort Service 即可外网访问。 - 回收流程:删 Pod→删 PVC→PV 变 Released(Recycle 自动清数据);若策略 Retain:数据保留,PV 一直 Released 不能复用,需
kubectl delete pv再重建(只删对象、不删存储数据),状态回 Available。 - 静态供应(Static Provision):管理员提前建好 PV 等 PVC 来申请;适合 PVC 少。
- 动态供应(Dynamic Provision):没有满足条件的 PV 时由 StorageClass 自动创建 PV,减少管理员工作量;StorageClass 声明 provisioner(存储插件),reclaimPolicy 默认 Delete(支持 Delete/Retain);云上如 AWS EBS(standard=gp2、slow=io1),本地 NFS 需装 nfs-client-provisioner。
- MySQL 持久化实战五步:建 PV/PVC(1Gi/RWO/nfs path /nfsdata/mysql-pv,Retain)→ 部署 Service+Deployment(mysql:5.7.5-m15,env MYSQL_ROOT_PASSWORD,挂 /var/lib/mysql→mysql-pvc)→ 进容器建库建表插数据 →
poweroff关掉所在 node 模拟宕机 → K8s 把 MySQL 迁到另一节点(等待数分钟),数据完好(验证 select 一致)。 - 动态供应实战(v1.19 更稳,v1.22 曾有兼容问题):① 建 NFS(/opt/container_data 共享);② 定义 StorageClass
managed-nfs-storage+provisioner: fuseim.pri/ifs;③ 部署授权(RBAC:SA nfs-client-provisioner + ClusterRole 权限 + ClusterRoleBinding);④ 部署 nfs-client-provisioner Deployment(env:PROVISIONER_NAME 必须等于 StorageClass 的 provisioner 名、NFS_SERVER、NFS_PATH;挂载 NFS 根目录;镜像 lizhenliang/nfs-client-provisioner:v2.0.0);⑤ 用 StatefulSet+Service(clusterIP: None 无头服务)+volumeClaimTemplates(accessModes RWO、storageClassName: managed-nfs-storage、storage 1Gi)自动为每个副本(web-0/web-1)创建独立 PVC/PV(NFS 上生成 default-www-web-N-pvc-xxx 目录);删除 web-0 重建后数据仍在。 - Deployment 更新策略补充:
strategy.type两种——Recreate(先杀旧再建新);RollingUpdate(默认,边删边建保可用),可配maxUnavailable(可低于期望数,默认 25%)与maxSurge(可超过期望数,默认 25%)。
十四、命令速查表(一句话)
| 场景 | 写法 |
|---|---|
| 集群/节点 | kubectl get nodes [-o wide]、kubectl describe node 名、kubectl delete node 名 |
| 资源操作 | kubectl apply/create/delete -f xxx.yaml、kubectl get pods/svc/deploy/rc/pv/pvc/sc/ns |
| 细看对象 | kubectl describe pod/node 名、get -o yaml/json/jsonpath |
| 过滤 | kubectl get pods -l app=nginx -o wide |
| 进容器/日志 | kubectl exec -it pod /bin/bash、kubectl logs -f pod |
| 改副本 | 改 yaml kubectl apply 或 kubectl edit deployment 名 |
| 滚动/回滚 | kubectl rollout history/status/undo deployment 名 [--to-revision=N] |
| 权限 | kubectl create role/rolebinding/clusterrole/clusterrolebinding、config use-context |
| 建 SA/Secret 看 | kubectl create serviceaccount、kubectl get secret |
| 存储 | kubectl get pv/pvc/sc、kubectl delete pvc/pv |
| Node 加入 | kubeadm join ...;token 重建 kubeadm token create --print-join-command |
| 节点维护/重置 | kubectl drain、kubectl delete node、kubeadm reset |
十五、易错点
- Pod 是“机器”,容器是“程序”:网络/存储/调度属性写 Pod 级(spec.volumes 在 Pod,volumeMounts 在容器)。
- 清单里
-l app=nginx用等号;YAML 里键值用冒号+空格,禁止 Tab 缩进。 - create 声明式 vs apply 声明式:create 改文件要先删再建,apply 可直接覆盖。
- NodePort 三端口:port=ClusterIP 口、nodePort=节点外网口、targetPort=Pod 容器口;外部访问 nodeIP:nodePort。
- 删除 RC/Deployment 会级联删 Pod;不想要级联加
--cascade=false。 - restartPolicy=Always 时“重启”=删除重建容器;Pod 绑定 Node 后不会自动换节点(迁移由 Deployment 重建实现)。
- 健康检查失败会 kill 容器并重启(RESTARTS+1),Pod 仍可能 Running——判断依据要看 Events 与 RESTARTS。
- RBAC 默认模式:未授权用户 get pod 报 Forbidden 是正常现象,需 Role+RoleBinding(单空间)或 ClusterRole+ClusterRoleBinding(全空间)。
- SA token 自动挂载位置 /run/secrets/kubernetes.io/serviceaccount;imagePullSecrets 不指定时继承 SA 的。
- kubeadm 1.8+ 必须关 Swap(swapoff -a + 注释 fstab),否则 kubelet 起不来。
- flannel 未部署前节点不会 Ready(not-ready 污点),要先 apply 网络插件(含污点容忍)再等 Ready。
- PV 回收策略:Recycle 已废弃;Retain 保留数据但 PV 停在 Released 需重建对象复用;Delete 才删底层存储。
- PVC 与 PV 匹配条件:容量满足+accessModes 匹配+storageClassName 相同。
- NFS 动态供应里 nfs-client-provisioner 的 env PROVISIONER_NAME 必须与 StorageClass 的 provisioner 一致,否则不自动建 PV。
- NodePort 访问在 node 上测试,别在 master 上纠结。
十六、实操清单
核心概念速览 → kubeadm 部署(三节点:关 swap/装组件/init/装 flannel/join/get nodes)→ token 重建与节点 drain/delete/reset 演练 → 手写第一个 pod.yml 并 apply/describe/exec → 生命周期与常见状态观察 → namespace 增删 → YAML Maps/Lists 练习 → nodeName/nodeSelector 指定调度 → lifecycle postStart/preStop 与优雅退出 → livenessProbe exec/httpGet 探针实战 → restartPolicy 三种对比 → Downward API 环境变量与 volume 两种注入 → ServiceAccount mysa 示例 → RBAC 完整实验(soso 用户/role/rolebinding/clusterrole 提权)→ Deployment 建 nginx(replicas/selector/template)→ 扩容/滚动升级(换镜像看 RS 交替)/rollout 回滚 → RC+Service(NodePort)暴露 nginx/tomcat/jenkins(作业三连)→ 端口语义与 kube-proxy 验证 → emptyDir/hostPath 挂载实战 → Dashboard v2.4.0 部署 + admin-user token 登录 → NFS+PV/PVC 静态供应(建库写数据)→ PV 回收策略 Retain/Delete 对比 → MySQL 持久化五步(含宕机迁移验证)→ StorageClass+nfs-client-provisioner 动态供应 + StatefulSet volumeClaimTemplates 自动建 PV。
十七、本章自测
- Pod 与容器、Deployment 与 ReplicaSet、Service 与 Endpoints 的关系?
- k8s 为什么推荐 YAML 而不是命令行直接跑容器?
- kubeadm 部署的完整步骤?不关 Swap 会怎样?flannel 装好前节点为什么一直 not Ready?
- Pod 生命周期状态有哪些?RESTARTS 增加说明什么?重启与迁移有何区别?
- nodeName 与 nodeSelector 区别?postStart/preStop 执行时机与同步性?
- Downward API 两种注入方式与适用字段?为什么推荐 Volume 而不是环境变量?
- Service Account 与 User Account 区别?default SA 与自动挂载 token 机制?
- RBAC 授权四对象是什么?给用户 soso 授权 pod 只读的完整命令链?
- Deployment 滚动更新过程(新旧 RS 如何交替)?rollout undo 怎么用?
- Service 的 port/nodePort/targetPort 三者含义与访问路径?NodePort 与 LoadBalancer/Ingress 区别?
- PV/PVC 是什么?如何用 NFS 实现 MySQL 持久化并验证宕机迁移后数据一致?
- StorageClass 动态供应原理?provisioner 名字为什么必须一致?StatefulSet 的 volumeClaimTemplates 起什么作用?
