ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Kubernetes 1.31+Containerd一键部署实操指南

Kubernetes 1.31+Containerd一键部署实操指南 1. 先聊清楚为什么这套方案值得直接抄过去两年我部署过不下二十套Kubernetes集群从裸机二进制编译到Ansible批量安装从单控制面测试环境到多Master生产集群都折腾过。说实话每次新环境部署最花时间的不是Kubernetes本身而是环境初始化那一堆零碎事。版本不匹配、cgroup驱动不一致、镜像拉不下来、内核参数没开全任何一个点都能卡住大半天。这也是我后来把整套流程收敛成一套Kubernetes 1.31 Containerd的一键式脚本的重要原因。进入正题之前先说清楚这套方案能做什么在一台全新的Linux服务器上通过执行一个脚本自动完成主机初始化、Containerd安装配置、Kubernetes组件安装、kubeadm init集群初始化、网络插件安装最后得到一个可以正常调度Pod的K8s集群。整个过程不需要手工干预即使你对Kubernetes部署不太熟照着跑一遍也能成功。我写这篇部署手册就是想把踩过的坑、试对的路都沉淀下来让后面的人少走弯路。而且这套方案里的“一键式脚本”不是那种黑盒脚本每一段都有明确注释和设计逻辑。如果你以后要部署生产集群也可以直接在这个基础上扩展高可用、多Worker节点、持久化存储这些能力。读懂一份脚本背后的取舍比背一百条部署命令有价值得多。2. 环境准备硬性要求与踩坑高发区2.1 主机、系统、硬件的最低要求如果只是本地测试、学习、跑CI/CD验证配置不需要太高但也不能太寒酸。我实测跑通Kubernetes 1.31 Containerd的最低配置如下配置项最低要求推荐配置说明CPU2核4核或以上kubeadm init会对节点做资源检查低于2核一般也能过但Pod调度容易被资源限制卡住内存2GB4GB或以上2GB能跑起来但系统组件经常被OOM Killer盯上磁盘20GB40GB或以上镜像缓存、容器日志增长很快20GB属于勉强能用操作系统Ubuntu 20.04 / CentOS 7.9 / Rocky 9Ubuntu 22.04 LTS内核要求3.10以上建议用较新的长期支持版本这里多说一句操作系统选型。CentOS 7虽然网上老教程最多但官方已经EOL很多软件源也迁移了新装环境我不推荐。Ubuntu 22.04和Rocky 9是我现在用得比较多的两个选择。尤其是Ubuntu 22.04软件源新、内核版本高、兼容性好后面拉镜像、装依赖都省心。如果你手头的机器是CentOS 7.9脚本也能跑但要提前配好阿里云或者腾讯云的EPEL源不然很多依赖包装不上。还有一点容易忽略所有节点的主机名不能重复且必须能够互相解析。我在脚本里面直接写入了 /etc/hosts 的方式比较粗暴但有效。如果你有内网DNS可以跳过这一步但测试环境用hosts文件最稳。2.2 内核参数与模块不起眼的设置决定成败Kubernetes集群的数据包转发依赖Linux内核的四个关键行为IPv4流量转发桥接设备上的iptables规则生效IPv6桥接流量转发连接跟踪conntrack模块加载具体来说/etc/modules-load.d/k8s.conf 这个文件需要写入overlay br_netfilteroverlay是容器镜像分层存储的基础驱动br_netfilter负责让桥接流量也能走iptables规则。这两个模块不加载后面的网络插件装完节点照样NotReady。sysctl配置里面最重要的是这几项net.bridge.bridge-nf-call-iptables 1 net.bridge.bridge-nf-call-ip6tables 1 net.ipv4.ip_forward 1bridge-nf-call-iptables 必须开启否则Kubernetes的Service转发规则在节点间通信时完全不生效。ip_forward则是所有容器网络模式的基础。这三个参数我在实际部署中见过太多次没配导致集群各种诡异网络故障的案例了。还有一个非常容易被忽视的问题部分云主机默认不会加载 br_netfilter 模块或者加载失败。如果你执行之后发现 /proc/sys/net/bridge 目录不存在大概率就是模块没加载上。这时候先用 modprobe br_netfilter 手动加载再排查为什么开机没加载成功。2.3 为什么必须关swap以及怎么关Kubernetes的kubelet在设计上默认要求节点关闭swap原因很简单容器内存隔离依赖cgroup的内存控制而swap的存在会绕过cgroup的限额控制导致内存使用统计失真进而影响调度决策和OOM判断。比如某个Pod被设置了内存上限500MB写着写着把内存写到swap里了物理内存占用不高cgroup统计也不准确但实际上系统已经快被拖垮了。以前kubeadm init直接在预检阶段就强制swap必须关闭。从版本1.22开始它允许以风险自负的方式开启swap但默认行为依然是关闭。我个人的建议测试环境可以开生产环境老老实实关掉。Kubernetes的调度和内存管理在swap开启的情况下行为很难预测没必要为了省那点内存去踩这个坑。关闭swap的方式swapoff -a sed -i /swap/d /etc/fstab注意 fstab 里的swap条目必须同步注释掉或者删除否则重启后swap又自动挂载了kubelet可能直接拒绝启动。这个我在CentOS 7上面踩过一次重启之后集群整个挂掉。2.4 Containerd安装与核心配置修改三步走Containerd是现在Kubernetes默认的容器运行时它天然实现了CRI接口不需要任何额外转换就能被kubelet直接调用。安装方式有两种一种是直接用发行版软件源安装另一种是从GitHub Release下载二进制包。对于大多数场景我推荐直接用软件源装因为依赖处理更干净升级路径也清晰。装好Containerd之后最重要的一步是生成并修改默认配置containerd config default | tee /etc/containerd/config.toml这里要改动三个核心点缺一个后面都会出问题第一Sandbox镜像地址。默认配置里 sandbox_image 指向的是 k8s.gcr.io 域名下的 pause 镜像这个镜像在国内根本拉不动。需要改成国内镜像源比如sandbox_image registry.aliyuncs.com/google_containers/pause:3.10这是整套部署里最关键的一处修改kubelet初始化时需要Sandbox镜像来启动Pod的基础容器这个镜像拉不下来Pod永远起不来。第二SystemdCgroup 必须打开。修改 [plugins.io.containerd.grpc.v1.cri.containerd.runtimes.runc.options] 下面的 SystemdCgroup从 false 改成 true。这一点要结合后面的kubelet配置一起理解使用systemd作为init系统的机器上cgroup driver必须是systemd否则同一个Pod里的进程可能被两个cgroup管理器分别管理资源统计会出现分歧严重的时候Pod直接被杀掉或者重启。第三镜像加速器。如果拉取Docker Hub镜像速度不理想可以在 [plugins.io.containerd.grpc.v1.cri.registry.mirrors] 下面配置加速器地址[plugins.io.containerd.grpc.v1.cri.registry.mirrors] [plugins.io.containerd.grpc.v1.cri.registry.mirrors.docker.io] endpoint [https://docker.m.daocloud.io]配置完成之后重启containerdsystemctl restart containerd这里有个容易踩的细节改了配置之后必须重启containerd而且建议顺手执行 systemctl daemon-reload。有一些情况下containerd进程内存里已经加载了旧配置不重启不会发现新配置。另外改完配置可以用 crictl 检查Sandbox镜像是否可拉取提前暴露问题。2.5 kubeadm/kubelet/kubectl版本锁定接下来是安装Kubernetes的三个核心二进制组件kubeadm管理集群生命周期负责初始化、升级、Token管理等kubelet节点上的核心agent负责Pod生命周期管理跟CRI打交道kubectl命令行管理工具安装方式大家都比较熟悉先从软件源注册开始然后直接安装。CentOS系和Ubuntu系的命令略有差异但核心逻辑一致。让我特别提醒的一点是这三个组件的版本必须严格一致而且和要初始化的Kubernetes版本也要严格匹配。说白了就是安装1.31.0就三个都装1.31.0千万不要混装。我见过太多人kubeadm是1.31kubelet装成1.29init的时候报一堆版本错误。安装完成后还有一个我强烈建议做的操作——版本锁定apt-mark hold kubeadm kubelet kubectl或者CentOS系的yum install -y kubeadm-1.31.0 kubelet-1.31.0 kubectl-1.31.0为什么要锁版本Kubernetes的升级从来不是无脑点一下就能完成的每个minor版本升级都有对应的升级文档和步骤小版本间的升级也可能引入配置变更。一旦软件源中版本更新被自动pull上来会造成集群各节点组件版本不一致排查起来极其痛苦。测试玩一玩无所谓如果是要持续运行的集群或者研究环境锁版本是基本操作。3. 一键式脚本核心实现从手工到“无脑”的关键3.1 脚本设计思路为什么我不建议“全塞一个大脚本”很多人一听说“一键式脚本”就想着把所有命令堆到一个install.sh里跑完结束。这种做法最简单但维护性极差一旦某一步失败整个脚本从头再来排错成本极高。我把整个过程拆成了两段01-init-env.sh主机系统基础环境初始化02-install-k8s.sh安装组件并初始化集群两个脚本可以连续执行也可以分开执行。实际使用中我发现拆成两段的好处是第一次跑的时候环境初始化部分可能有网络延迟、软件源未更新之类的偶发失败只需要重跑第一段就行后面kubeadm init前还可以人工再确认一次。每段脚本内部还划分了函数块比如 init_system_env、install_containerd、config_containerd、install_k8s_components、init_cluster。每个函数执行前打印当前状态失败后直接退出并给出错误码这样即使出了问题也能快速定位到具体函数。3.2 第一阶段环境初始化脚本逐步拆解01-init-env.sh 做了四件事关闭swap、加载内核模块、设置sysctl参数、安装基础工具curl、wget、vim、net-tools等。#!/bin/bash set -e echo 关闭swap swapoff -a sed -i /swap/d /etc/fstab echo 加载内核模块 cat EOF | tee /etc/modules-load.d/k8s.conf overlay br_netfilter EOF modprobe overlay modprobe br_netfilter echo 配置sysctl文件 cat EOF | tee /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-iptables 1 net.bridge.bridge-nf-call-ip6tables 1 net.ipv4.ip_forward 1 EOF sysctl --system echo 安装基础工具 if command -v apt-get /dev/null; then apt-get update apt-get install -y curl wget vim net-tools elif command -v yum /dev/null; then yum install -y curl wget vim net-tools fi echo 完成环境初始化这一段里有一个我特别要提醒的细节sysctl --system 不是唯一的生效方式它的作用是加载 /etc/sysctl.d/ 目录下的所有.conf文件。如果你改了配置但没有执行这一步配置只是写入了文件当前运行中的内核不会立即生效要等重启后才生效。为了让配置不重启就生效我习惯立刻执行 sysctl --system。最后检查一下lsmod | grep br_netfilter sysctl net.bridge.bridge-nf-call-iptables看到加载信息和1返回值就说明环境初始化成功。3.3 第二阶段Install脚本中的Containerd配置逻辑02-install-k8s.sh 的重点在于Containerd的安装和配置。直接看脚本#!/bin/bash set -e INSTALL_VERSION1.31.0 echo 安装 containerd # 这里按发行版区分安装containerd if command -v apt-get /dev/null; then apt-get install -y containerd elif command -v yum /dev/null; then yum install -y containerd fi echo 生成containerd默认配置 mkdir -p /etc/containerd containerd config default | tee /etc/containerd/config.toml echo 修改Sandbox镜像地址 sed -i s#sandbox_image registry.k8s.io/pause:3.10#sandbox_image registry.aliyuncs.com/google_containers/pause:3.10# /etc/containerd/config.toml echo 开启SystemdCgroup sed -i s/SystemdCgroup false/SystemdCgroup true/g /etc/containerd/config.toml echo 配置镜像加速器 cat /etc/containerd/config.toml EOF [plugins.io.containerd.grpc.v1.cri.registry.mirrors.docker.io] endpoint [https://docker.m.daocloud.io] EOF echo 重启containerd systemctl restart containerd systemctl enable containerd这里我用了sed直接替换没有依赖python或者其他工具减少依赖。不过sed替换有一个前提默认配置文件里的格式是固定的如果安装的Containerd版本格式有变化sed可能匹配不到。所以在脚本执行完之后一定要手工grep验证一下grep -n sandbox_image /etc/containerd/config.toml grep -n SystemdCgroup /etc/containerd/config.toml3.4 kubeadm init参数选择与多节点扩展装完Containerd接下来就是安装kubeadm/kubelet/kubectl。这部分不同发行版差异较大我直接用函数封装了安装逻辑。核心命令case $(. /etc/os-release; echo $ID) in ubuntu|debian) apt-get update apt-get install -y apt-transport-https ca-certificates curl gpg curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.31/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg echo deb [signed-by/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.31/deb/ / | tee /etc/apt/sources.list.d/kubernetes.list apt-get update apt-get install -y kubelet$INSTALL_VERSION-* kubeadm$INSTALL_VERSION-* kubectl$INSTALL_VERSION-* apt-mark hold kubelet kubeadm kubectl ;; centos|rhel|rocky) cat EOF | tee /etc/yum.repos.d/kubernetes.repo [kubernetes] nameKubernetes baseurlhttps://pkgs.k8s.io/core:/stable:/v1.31/rpm/ enabled1 gpgcheck1 gpgkeyhttps://pkgs.k8s.io/core:/stable:/v1.31/rpm/repodata/repomd.xml.key EOF yum install -y kubelet-$INSTALL_VERSION kubeadm-$INSTALL_VERSION kubectl-$INSTALL_VERSION yum install -y kubelet kubeadm kubectl --disableexcludeskubernetes ;; esac systemctl enable kubelet systemctl start kubelet注意Ubuntu安装时kubelet的版本号后面带 * 通配符这是因为Debian源里的包版本会带构建号CentOS系则用 --disableexcludeskubernetes 确保不会因排除规则导致依赖缺失。装好之后先别急着init检查一下版本kubelet --version kubeadm version -o short kubectl version --client三个版本输出一致再继续。然后初始化集群脚本里我做的参数选择如下kubeadm init \ --kubernetes-versionv1.31.0 \ --image-repositoryregistry.aliyuncs.com/google_containers \ --pod-network-cidr10.244.0.0/16 \ --apiserver-advertise-address0.0.0.0几个参数的解释--image-repository用国内能访问的镜像仓库地址替换默认的registry.k8s.io这直接关系到能否顺利拉取组件镜像--pod-network-cidr10.244.0.0/16必须和后面选的CNI插件网段匹配。Flannel默认就是这个网段开着不动最省心。如果你用Calico网段可以自定义为19.168.0.0/16之类的--apiserver-advertise-address默认监听所有接口单节点环境直接0.0.0.0如果是多控制面再指定为具体的VIP或内网IP初始化完成后kubeadm会输出一段join token。把这个token保存下来Worker节点加入集群就靠它了。脚本最后我还做了一步常规操作export KUBECONFIG/etc/kubernetes/admin.conf echo export KUBECONFIG/etc/kubernetes/admin.conf ~/.bashrc不设置KUBECONFIG的话每次kubectl都要加 --kubeconfig太麻烦了。4. 初始化集群、装网络插件与验证4.1 kubeadm init执行全流程与日志判断脚本执行完成后控制台会看到一串输出。重点看最后一部分如果一切正常会有类似下面的内容Your Kubernetes control-plane has initialized successfully! To start using your cluster, you need to run the following as a regular user: mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config You can now join any number of control-plane nodes by copying certificate authorities and service account signing keys... Then you can join any number of worker nodes by running the following on each as root: kubeadm join 192.168.1.10:6443 --token abc123...如果你在这一步看到了错误信息别慌。kubeadm init 的报错信息虽然看着多但核心排查点就两个日志和preflight检查。常见的一种情况是preflight检查里的Container Runtime未发现这时候先执行 crictl info 看Containerd的gRPC接口是否正常响应再执行 crictl ps 看看有没有输出。如果crictl报错大概率是containerd服务没起来或者socket路径不对。新版containerd的socket路径是 unix:///run/containerd/containerd.sockkubeadm 默认会去这个路径探测。初始化成功之后立刻执行下面这组命令mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config注意如果不用root用户操作这步必须在root之外的管理员用户下执行因为admin.conf的权限在root用户下其他用户直接kubectl会提示权限不够。如果你直接全程用root跑也要配置好KUBECONFIG环境变量。然后查看节点状态kubectl get nodes看到控制平面节点的STATUS为 NotReady 是正常的因为此时还没安装CNI网络插件。接下来装网络插件。4.2 CNI选择Flannel和Calico怎么选网络插件是Kubernetes集群里最容易出问题的组件之一它在集群里负责给每个Pod分配IP、打通跨节点通信、实现Service到Pod的路由转发。在单节点测试环境Flannel是完全够用的。它的优点是配置简单、资源占用低、跟kubeadm配合几乎零成本。缺点是功能相对单一不支持NetworkPolicy对于需要精细化流量管控的场景有些力不从心。Calico的功能更全面除了Pod网络互通还支持NetworkPolicy、BGP路由、多租户安全策略。但相应地它的架构复杂一些组件更多调试起来也更有挑战性。如果你的集群要跑生产业务或者需要做网络安全隔离直接上Calico。安装Flannel很简单kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml如果网络原因导致GitHub访问不稳定先把yaml文件下载到本地再applywget https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml kubectl apply -f kube-flannel.yml如果是Calico最新的安装命令kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.28/manifests/tigera-operator.yaml注意Calico的安装需要先去它的官网定制一个custom-resources.yaml里面包含Pod网段定义直接用默认的也行但必须跟 kubeadm init 时的 --pod-network-cidr 保持一致。实际部署中我强烈建议测试环境先用Flannel等跑通之后再把网络组件换个方案练手。别一开始就用Calico如果对它的多组件架构不熟出了问题排查面比较大。4.3 集群状态验证与节点Ready检查网络插件装完之后等个一两分钟再次查看节点状态kubectl get nodes -o wide如果 STATUS 变为了 Ready说明控制平面已经正常。接着查看所有Pod的运行状态kubectl get pods -A正常情况下kube-system命名空间下的组件Pod应该都是Running状态。如果有Pending或者CrashLoopBackOff就要去排查对应的Pod日志。最常见的问题是镜像拉不下来这时候去检查sandbox_image的配置是否生效以及镜像加速器是否可用。还有一个我每次都能靠它快速定位问题的命令组合kubectl describe pod pod-name -n kube-system journalctl -u kubelet -fdescribe里能看到Pod的事件列表主要是调度、镜像拉取、容器启动三方面的记录。kubelet日志能看到节点级别的问题比如cgroup驱动不匹配、证书过期等。这两个配合使用百分之八十的问题都能定位到。最后验证一个Pod能不能正常调度kubectl run nginx-test --imagenginx kubectl get pods -o wide等待Pod变为Running集群的基本调度链路就验证通过了。这里要说一句如果你在拉测试用的镜像时发现特别慢说明containerd的镜像加速器配置没生效回到2.4节检查一下。5. 常见问题与排查技巧实录5.1 问题速查表高频坑Top 8我在不同的环境上跑这套脚本积累了一批高频故障。直接整理成速查表遇到问题时对号入座现象大概率原因解决办法kubeadm init报错container runtime is not runningcontainerd服务挂了/未启动systemctl status containerd查看服务状态重新启动containerdkubelet一直重启日志报cgroup driver不匹配SystemdCgroup没有改成true修改/etc/containerd/config.tomlSystemdCgroup true重启containerd和kubelet节点NotReadycoredns一直PendingCNI网络插件没装/网段不一致安装Flannel或Calico确认--pod-network-cidr与CNI配置一致Pod一直ImagePullBackOffSandbox镜像无法拉取检查/etc/containerd/config.toml中的sandbox_image改用国内镜像源后重启containerdkubelet启动失败日志提示找不到kubeconfigkubelet服务启动顺序问题systemctl enable kubelet 并确保 /etc/kubernetes/kubelet.conf 存在重启之后节点NotReadyswap重新挂载/containerd未开机自启检查fstab中swap配置执行systemctl enable containerdWorker节点join超时6443端口被防火墙拦截放行6443端口iptables -A INPUT -p tcp --dport 6443 -j ACCEPTcontainerd安装版本太旧系统软件源里containerd版本老旧使用Docker官方源安装containerd或直接下载二进制包5.2 从Docker迁移到Containerd具体操作与清理要点如果你以前是用Docker作为Kubernetes运行时现在想切换到Containerd这里有一个容易踩坑的地方——环境里已经跑过Docker和kubeadm残留的配置和状态会跟新环境打架。这时候直接跑安装脚本大概率会失败需要先清理再重新部署。完整的迁移步骤把旧的Kubernetes集群重置掉kubeadm reset -f清理旧CNI配置rm -rf /etc/cni/net.d卸载Docker如果不需要再用了apt-get remove -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin删除旧的数据目录rm -rf /var/lib/docker rm -rf /var/lib/containerd重新安装Containerd然后按2.4节的方式修改配置再执行kubeadm init。这里有个核心逻辑的问题需要理解Kubernetes通过CRI接口操作容器运行时Docker本身并不直接支持CRI它需要dockershim这个适配层。Kubernetes 1.24版本起硬生生把dockershim从代码里删掉了所以新版本集群再想用Docker只能通过cri-dockerd这样的独立适配器。但Containerd天生就实现了CRI不需要加适配层这也是现在部署Kubernetes默认用Containerd而不是Docker的根本原因。从资源占用、升级维护、兼容性几个维度看Containerd都是更优的选择。不过有一个场景要单独说如果你线上业务还在用Docker构建镜像或者依赖Docker的某些命令docker exec、docker logs等切换到Containerd之后这些日常操作要改用 nerdctl 或者 crictl 来实现。crictl 专门用于容器运行时管理crictl ps # 查看运行的容器 crictl images # 查看已有镜像 crictl logs id # 查看容器日志 crictl exec -it id sh # 进入容器而 ctr 是containerd的原生命令行工具功能更底层一般不怎么直接使用。crictl才是日常排查和运维中最常用的它和docker ps的用法几乎一致习惯成本很低。5.3 面试角度部署背后常被问到的几个原理题这套部署流程跑通之后有不少初学者喜欢去面试Kubernetes相关岗位顺便分享几个这个过程中一定能被面试官翻牌子的原理问题。第一个是“Kubernetes为什么弃用Docker”。原因就是我前面说到的CRI适配层问题。早期Kubernetes通过dockershim间接调用Docker等于每创建一个容器要经过 kubelet → dockershim → docker daemon → containerd → runc 这条链路中间多了两层跳转既浪费资源又增加故障点。Containerd实现了原生CRIkubelet可以直接通过gRPC和containerd对话链路缩短性能更好问题也更好排查。第二个是“为什么kubelet和容器运行时的cgroup driver必须一致”。因为一台机器上同时存在两个cgroup管理器的话同一个Pod内的进程可能被两套统计体系分别记录资源使用情况系统无法对资源限制达到一致结果就是Pod内存超过限制之后kubelet认为进程还在限额内但containerd那边认为已经超限两者打架很容易造成Pod被杀或者资源统计错乱。用systemd的系统默认cgroup driver就是systemd所以Containerd的SystemdCgroup也要设成true。第三个是“Sandbox pause镜像到底干嘛用的”。每个Pod在启动业务容器之前会先启动一个pause容器它负责持有这个Pod的网络命名空间、IPC命名空间、PID命名空间等基础设施。所有业务容器共享这个pause容器创建的命名空间所以即使业务容器重启Pod的IP地址也不会变。想想看如果Pod里第一个业务容器挂了后面新起一个容器IP就变了那Service怎么稳定地做负载均衡这个问题理解了整个Pod生命周期和网络模型就串起来了。这三个问题的底层逻辑实际上就是你在部署过程中遇到的那几个故障点的根源。所以我一直觉得真正把部署流程跑到底、踩过这里面一个或者几个坑的人才能真正把Kubernetes的源码设计意图理解到位。这也是我建议你一定要亲手把脚本跑一遍、出点问题再修复一遍的原因。我教徒弟的时候经常说部署Kubernetes最好的学习材料不是官方文档而是你自己环境里那堆五颜六色的报错日志。这套脚本和部署流程我还会继续更新。就我个人经验而言它已经帮我节省了至少几十个小时的重复配置时间每次要开新的测试环境都是复制一份脚本、改一下主机名和IP、执行、等结果、然后直接开始干活。希望它也能帮你把从零搭建Kubernetes这件事从“折腾半天”变成“喝杯咖啡就搞定”。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进