尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
从零搭建Kubernetes单节点集群:kubeadm实操指南
刚看完概念是不是手痒想自己搭一套Kubernetes集群上一篇我们聊了k8s是什么、能干什么这篇就直接上实操。我会带你从零开始在一台Linux机器上把一个单节点集群跑起来然后部署一个Nginx验证整个链路是否正常。整个过程我会把每一步为什么要这么做讲清楚顺便把我踩过的坑也一并交代了希望能帮你少走点弯路。先说个扎心的事实很多人学k8s理论知识背得滚瓜烂熟什么Pod、Deployment、Service张口就来但真让自己搭一套环境立马卡在第一步——装都装不起来。然后就开始怀疑人生觉得自己不适合搞云原生。其实真不是你的问题而是k8s的安装门槛确实不低。它涉及的组件太多了etcd、kube-apiserver、kube-controller-manager、kube-scheduler、kubelet、kube-proxy、容器运行时……任何一个环节配置错了整个集群都起不来。这也是为什么网上教程那么多但照着抄还是各种报错的原因。这一篇我不打算直接扔给你一串复制粘贴的命令就完事而是要把k8s集群搭建背后的逻辑和常见坑都讲清楚。你跟着操作一遍之后不仅能跑起来一个集群还能明白这东西到底是怎么运作的以后再遇到问题也有排查思路。废话不多说直接进入正题。1. 内容整体设计与思路拆解1.1 为什么从单节点集群开始在动手之前我们先聊聊这次实操的整体思路。很多人一上来就想搭一个高可用的生产级集群Master三节点、Worker五节点Etcd单独部署各种负载均衡……这个想法没错但真的很劝退。如果你只是刚学k8s连Pod和Deployment都还没搞清楚是啥一上来就直面生产环境的复杂度大概率是装到一半就崩溃然后放弃。所以我强烈建议学习阶段就用kubeadm搭一个单节点的控制平面集群。也就是一个节点既当Master又当Worker。这种方式的好处特别明显资源占用小一个2核4G的云服务器或者虚拟机就能跑起来成本可以忽略不计。步骤完整虽然是单节点但该走的流程一步都少不了kubeadm init、kubeadm join、CNI网络插件配置你都会完整经历一遍。以后再搭多节点集群无非就是把join的命令再执行一次而已。好排查出了问题就一台机器看日志、查状态都方便不会被多节点之间的网络问题绕晕。够用了单节点集群足够你学习Pod、Deployment、Service、Ingress、ConfigMap这些核心对象了。等你把这个环境玩熟了再去研究生产级的高可用方案你会发现好多概念都是相通的到时候再上手就会顺畅很多。1.2 k8s和Docker到底是什么关系每次聊k8s都绕不开这个问题k8s和Docker到底是什么关系是替代品吗很多新手都在这两个概念上犯迷糊甚至面试的时候也经常被问到所以这里必须掰开揉碎讲清楚。简单说Docker是容器运行时它负责把应用打包成镜像、创建容器、管理容器的生命周期。而k8s是容器编排平台它负责管理一堆容器——容器部署在哪台机器上、怎么保证数量、怎么发现服务、怎么扩容缩容、挂了怎么恢复这些事情都是k8s管的。用生活类比的话Docker就像是一辆辆独立的货车负责把货物应用从一个地方运到另一个地方。而k8s就像一个物流调度中心它不关心车是怎么开的但知道有多少车在路上、哪些车需要加油、哪些车坏了要拖走、哪里需要增加车辆调配。这里有个关键点需要注意k8s本身不直接运行容器它是通过容器运行时来管理容器的。Docker只是容器运行时的一种而且是早期k8s最常用的一种。但从k8s 1.24版本开始kubelet不再直接支持Docker的接口了。不过这里很容易产生误解不是说k8s不能用Docker了而是说k8s底层不再用Docker来接管容器了。现在主流的选择是containerd它本来是Docker的一部分后来独立出来了专门负责容器生命周期管理。你装了Docker之后如果没有特别配置系统里的containerd一直都在只是你没单独注意过它。在本次实操中我们用的就是containerd作为容器运行时。不用装Docker因为用不上装多了反而增加故障点。1.3 集群搭建的三种主流方式选型在选工具之前我们先看看现在搭建k8s集群的主流方式有哪些各自有什么优劣势。这张表我建议大家保存一下以后不管是自己玩还是跟同事讨论方案都用得上。工具复杂度适用场景推荐指数kubeadm中等官方推荐适合学习和生产可定制性强★★★★★minikube极低本地单机学习一键启动★★★★kind低用Docker容器模拟节点适合CI测试★★★★kOps / RKE2较高云平台生产环境一键部署★★★二进制手动部署极高深度定制学习内部原理★★这次我们选kubeadm原因很简单它是k8s社区官方推荐的集群引导工具可以把整套集群的组件通过容器的方式部署起来让节点之间通过证书和token安全地加入集群。同时它的配置是显式的你可以清楚地看到拉了哪些镜像、生成了哪些证书、写入了哪些配置。这对理解k8s原理非常有帮助。minikube和kind当然也可以完成学习目标但它们封装得太好了很多细节感觉不到。比如kubeadm会告诉你证书过期了怎么续token失效了怎么重刷这些经验在实际工作里是会碰到的。用minikube的话这些全被工具藏起来了学习效果会打折扣。2. 核心细节解析与实操要点2.1 环境规划与系统准备先说环境。我这次用的是Rocky Linux 10.2kernel版本6.8左右。Rocky Linux和RHEL高度兼容稳定可靠社区活跃度也不错用来跑k8s完全没有问题。当然你用CentOS Stream、Ubuntu Server 22.04/24.04 LTS也都可以步骤大同小异就是包管理命令稍有区别。硬件方面我建议至少1核2G如果能到2核4G会更舒服。因为单节点既要跑Master组件又要跑工作负载内存太紧的话经常OOM排查起来特别痛苦。我见过太多人用512M内存的机器装k8skubelet都起不来然后来群里问为什么。所以这一步千万别省。软件环境的准备是很多人都容易忽略但又极其关键的一步有几个基础配置必须先做好网络规划每台机器要有固定的IP主机名不能重复。这步虽然简单但很重要后面很多问题都是主机名冲突导致的。防火墙k8s集群组件之间需要互相通信端口非常复杂。学习阶段最省事的办法就是关闭防火墙。生产环境当然要放行特定端口但那是另一套体系了这里咱先降低门槛。SELinux这是RHEL系的一个大头。SELinux强制访问控制如果不对k8s放开限制你会发现各种莫名其妙的权限问题。学习阶段直接把SELinux设置为permissive模式这是kubeadm官方文档都推荐的。时间同步k8s通过证书认证节点间时间不一致会直接导致TLS握手失败kubelet连不上apiserver。swap这也是一个坑。kubelet默认不允许宿主机开swap因为k8s的内存管理机制不依赖swap开着反而可能导致内存判断不准。官方推荐关掉。说了这么多落地到命令层面其实很简单。下面是核心步骤你可以对照着执行。首先确认主机名和IP然后做hosts解析。这一步是为了让k8s各组件之间通过主机名互相访问。# 查看主机名和IP hostname ip addr # 设置主机名根据你的实际情况调整 sudo hostnamectl set-hostname k8s-master # 编辑/etc/hosts添加解析记录 sudo vim /etc/hosts # 192.168.1.100 k8s-master然后关闭防火墙和SELinux这是RHEL系必须处理的两道坎# 关闭防火墙 sudo systemctl stop firewalld sudo systemctl disable firewalld # 关闭SELinux临时永久 sudo setenforce 0 sudo sed -i s/^SELINUXenforcing/SELINUXpermissive/ /etc/selinux/config最后关闭swap并让相关内核模块开机自动加载# 关闭swap sudo swapoff -a sudo sed -i / swap / s/^/#/ /etc/fstab # 加载br_netfilter模块 cat EOF | sudo tee /etc/modules-load.d/k8s.conf overlay br_netfilter EOF sudo modprobe overlay sudo modprobe br_netfiltersysctl参数也需要配置一下让iptables能正确处理桥接流量的转发cat EOF | sudo 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 sudo sysctl --system到这里系统层面的准备工作就做完了。我特意提醒一句这两步千万别跳。很多初学者图省事直接跳到装kubeadm那一步结果后面各种报错。相信我你现在老老实实把基础配置好后面会顺很多。基础打牢了层才能垒得高。2.2 容器运行时的安装与配置容器运行时是整个k8s最底层的东西它真正负责把镜像拉下来、跑成容器。现在我们在用的AI大模型、微服务最终都要以容器的形式跑在节点上。没有它k8s就成了空中楼阁。我刚才说过我们这次选containerd作为容器运行时。在正式安装之前先讲清楚为什么。k8s从v1.24版本开始就不再直接支持Docker了这不是说Docker不能用了而是kubelet不再通过Docker来管理容器改走Container Runtime Interface标准接口直接对接containerd。这背后的原因主要是性能考虑——以前kubelet要调用DockerDocker再去调containerd中间多绕了一层链路长、不好维护。现在kubelet直连containerd响应更快、日志更清晰。安装containerd的方式有很多种用包管理器直接装是最省心的sudo yum install -y yum-utils # 添加Docker官方仓库containerd和docker在同一仓库里 sudo yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo sudo yum install -y containerd.io装完之后需要生成默认配置并修改一个关键参数# 生成默认配置 sudo mkdir -p /etc/containerd containerd config default | sudo tee /etc/containerd/config.toml然后编辑/etc/containerd/config.toml把SystemdCgroup改成true。为什么因为containerd默认使用cgroupfs来管理cgroup但systemd作为系统init进程也有自己的一套cgroup管理模式。如果两者混用会造成资源统计不准确严重的时候kubelet会直接报错。让containerd也走systemd的cgroup管理方式可以保持两边统一这也是k8s官方推荐的配置。在config.toml中找到SystemdCgroup那一行改成true[plugins.io.containerd.grpc.v1.cri.containerd.runtimes.runc] ... [plugins.io.containerd.grpc.v1.cri.containerd.runtimes.runc.options] SystemdCgroup true改完之后重启containerd并设置开机自启sudo systemctl restart containerd sudo systemctl enable containerd sudo systemctl status containerd如果你去看containerd的版本大概率会发现它跟Docker是同一个生态出来的。这就是为什么很多老手到现在还是习惯把containerd和Docker混着说——他们就是一脉相承的东西。2.3 核心组件kubeadm、kubelet、kubectl的关系接下来要装的三件套——kubeadm、kubelet、kubectl很多新手分不清谁是谁这里我们先理清楚。kubeadm它是集群的安装引导工具。负责初始化Master节点、生成证书、配置文件、拉起核心组件以及生成Worker节点加入集群的token和命令。kubelet它是节点上的agent运行在每个节点上。负责接收控制平面的指令管理本节点上的Pod生命周期。你可以把它理解为每个节点的管家随时汇报Pod状态确保Pod在期望的状态。kubectl它是操作客户端。是你和集群交互的命令行工具。你可以通过它下发Deployment、查看Pod、进入容器、看日志。如果你拿一个大型公司做类比的话kubeadm是负责从零搭建公司大楼的施工队kubelet是每层楼的物业管理员负责这层楼里每个工位是否正常使用kubectl是你平时操作OA系统用的管理后台。这三个工具一个都不能少。缺了kubeadm你没法初始化集群缺了kubelet节点根本运行不了Pod缺了kubectl你连集群状态都看不到。由于Rocky Linux 10.2比较新直接走k8s官方Yum仓库是最靠谱的路径cat EOF | sudo 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 sudo yum install -y kubelet kubeadm kubectl # 设置开机自启 sudo systemctl enable --now kubelet装完之后可以验证一下版本kubeadm version kubelet --version kubectl version --client2.4 镜像拉取失败的三个常见原因这一步我要单独拎出来说因为这是整个搭建过程中最磨人的环节没有之一。kubeadm init的流程中会去拉取一堆镜像包括kube-apiserver、kube-controller-manager、kube-scheduler、kube-proxy、etcd和pause等。这些镜像都存放在registry.k8s.io上在国内访问速度极其感人经常超时甚至直接连接失败。这也是为什么很多人初始化集群的时候会卡在拉镜像那一步然后报各种拉取超时的错。我整理了三种最常见的镜像拉取失败原因和对应的解法原因一网络访问超时这是最常见的一种情况。registry.k8s.io这个域名在国内直连基本走不通或者偶尔通但极不稳定。解法就是走镜像加速器把k8s官方镜像从镜像仓库拉下来后重新打个tag改成kubeadm默认的名称。原因二kubeadm配置了错误的pause镜像版本kubeadm init的时候会自动从registry.k8s.io拉取pause镜像如果你的版本和当前集群版本不匹配可能也会失败。pause镜像是每个Pod里都会先启动的一个占位容器它负责持有网络的namespace相当于每个Pod的基础设施。原因三版本不匹配其实这种情况也经常被忽略。比如你人在国内找的加速源只同步到某个版本的老镜像你刚装的kubeadm可能对应的版本不一样拉到一半发现版本对不上又失败了。对于网络问题的核心解法我推荐两种方式一使用国内镜像站据说阿里云、docker官方加速器都在维护先把官方镜像拉下来然后再tag成kubeadm需要的那个tag。方式二通过kubeadm init的--image-repository参数直接指定到镜像仓库地址。我们这次用方式二因为最省事sudo kubeadm init \ --apiserver-advertise-address192.168.1.100 \ --image-repositoryregistry.aliyuncs.com/google_containers \ --kubernetes-versionv1.31.0 \ --pod-network-cidr10.244.0.0/16这里我用了阿里云的k8s镜像仓库确实快了很多。另外要注意一个很像坑但其实是常识的点--pod-network-cidr10.244.0.0/16跟后面要装的Flannel网络插件是配套的Flannel会默认使用这个网段来分配PodIP。如果这里不规划好后面Pod之间通信可能对不上。2.5 CNI网络插件的选型与配置集群初始化的最后一步是要装一个CNI网络插件。CNI的全称是Container Network Interface它解决的核心问题是Pod之间怎么通信、Pod和Service之间怎么通信。想想看一个Pod是有独立IP的但这个IP很可能不在宿主机的物理网段里。那这个IP怎么转发出去怎么让其他节点上的Pod访问到怎么让外部流量进入Pod这些都是网络插件要解决的问题。主流的CNI插件有Flannel、Calico、Cilium、Weave Net等。他们的实现方式各不相同Flannel最朴素的overlay网络方案用VXLAN隧道技术封装包配置简单资源占用小学习友好但性能和功能相对基础。Calico基于BGP路由协议不使用隧道性能好支持网络策略生产环境常见。Cilium基于eBPF技术是新一代的网络方案性能最好、功能最丰富但要求内核版本较高学习曲线也比较陡。学习阶段我们选Flannel就足够了它支持Pod之间的互通也支持Service的ClusterIP转发。等以后要上生产环境了可以再换Calico或者Cilium。从官方YAML安装Flannel非常简单kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml这里有个前提——你的集群得先初始化成功PATH里才有kubectl可以用。所以流程是先执行kubeadm init初始化Master再配置kubectl最后装Flannel。3. 实操过程与核心环节实现3.1 kubeadm init初始化Master节点所有准备就绪后我们正式初始化Master节点。这一步会做很多事情生成CA证书、生成组件访问的证书、生成kubeconfig配置文件、部署控制平面组件到静态Pod中、生成Worker节点加入集群的token等等。整个过程大概需要几分钟取决于你的机器性能和网络状况。代码就参考上面的kubeadm init命令。执行成功后最后几行输出会包含类似下面的内容Your Kubernetes control-plane has been 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 worker nodes by running the following on each as root: kubeadm join 192.168.1.100:6443 --token abcdef.0123456789abcdef \ --discovery-token-ca-cert-hash sha256:xxxxxx这里有几个信息非常关键/etc/kubernetes/admin.conf是管理员用的kubeconfig文件相当于集群的管理员身份凭证。kubectl全靠这个文件来认证和连接集群。kubeadm join命令和token是给Worker节点用的如果你只是单节点学习这条命令先存着不着急执行。按照提示执行那三条命令让普通用户也能用kubectl操作集群mkdir -p $HOME/.kube sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config sudo chown $(id -u):$(id -g) $HOME/.kube/config然后验证一下集群状态。这里有一个细节需要注意在没有安装CNI网络插件之前控制平面的Pod可能还没有变成Running状态因为核心的kube-apiserver、etcd等组件虽然有IP但网络插件没就绪所以某些Pod会显示Pending或者ContainerCreating。这不一定是安装失败等接下来装好Flannel应该就好了。kubectl get nodes kubectl get pods -n kube-system如果一切正常你会看到控制平面的几个Pod慢慢变成Running状态。如果你只想让这台机器同时也作为Worker运行工作负载那还需要解除Master节点的调度限制。k8s默认不让控制平面节点跑用户应用所以需要去掉taintkubectl taint nodes --all node-role.kubernetes.io/control-plane-这里简单解释一下taint污点和toleration容忍的关系。你可以把节点想象成一张床污点就是床上贴了一个闲人免进的标签。Pod就是想来睡觉的人。大多数Pod都很识趣看到标签就不往上凑了。只有带有toleration容忍的Pod才会无视这个标签继续躺上去。我们想在自己这台单节点上跑业务Pod就得把Master节点上这个闲人免进标签撕掉。3.2 安装Flannel网络插件执行完上面的kubeadm init和kubectl配置后接下来把Flannel装上。网络插件需要在集群里创建一个DaemonSet保证每个节点上都有一个网络代理来转发流量kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/master/Documentation/kube-flannel.yml这里有个小坑想提醒你。国内有些网络环境访问GitHub的raw资源也可能会超时。如果你拉不下来可以从gitee等国内镜像仓库找或者本地下载好yaml文件再apply。如果网络没问题的话这一步其实很快。安装完成后等一两分钟再看看namespace里的情况kubectl get pods -n kube-flannel如果你看到每个节点上的flannel Pod都变成了Running状态说明网络插件工作正常了。再回过头看看核心组件kubectl get pods -n kube-system等这些Pod全部进入Running状态之后你的单节点集群就算正式建成了。3.3 验证集群连通性集群搭好了不验证一下就总觉得心里没底。其实验证非常容易跑一个简单的Pod试试就行kubectl run nginx-test --imagenginx kubectl get pods -o wide如果Pod显示Running并且分配到了一个10.244.x.x网段的IP就说明整个链路已经打通了——创建Pod、镜像拉取、容器调度、网络分配全都走通了。还可以进一步检查网络连通性。进入这个Podping一下它的IP或者从一个Pod访问另一个Pod的IP如果能通说明overlay网络工作正常。这一步我们后面部署真正业务的时候可以再详细验证。3.4 让集群更完善部署Dashboard或Ingress这个单节点集群装完之后其实可以做很多练习。如果你想要一个可视化的管理界面可以部署Kubernetes Dashboard如果你想玩域名访问可以装Ingress Controller。不过这里有一个建议刚开始学习别急着把所有东西都装上。先把Pod、Deployment、Service这些核心概念在命令行里玩熟再慢慢加别的组件。装的东西越多排查问题的范围就越大对于新手来说反而容易混乱。4. 常见问题与排查技巧实录4.1 核心排查三件套无论你遇到什么问题先记住这“排查三件套”查状态、看日志、看事件。这三个命令是排查k8s问题的基础中的基础。# 查看节点状态 kubectl get nodes # 查看Pod状态 kubectl get pods -A # 查看Pod详情看底部Events有没有报错 kubectl describe pod pod-name -n namespace # 查看容器日志 kubectl logs pod-name -n namespace80%的k8s问题都能从这三个命令的输出里找到线索。Events里如果报Failed to pull image那就是镜像拉取的问题如果报Error: ImagePullBackOff那是镜像仓库地址错误或认证失败如果报CrashLoopBackOff那是容器启动后立即退出如果一直Pending那多半是资源不足、taint未容忍或者节点NoSchedule。4.2 常见报错速查表下面我把搭建过程中最常见的一些报错整理成表格方便你对照排查报错信息原因解决方案[ERROR CRI]: container runtime is not runningcontainerd没启动或者配置错误systemctl restart containerd检查config.toml是否改对了[ERROR FileContent--proc-sys-net-bridge-bridge-nf-call-iptables]: /proc/sys/net/bridge/bridge-nf-call-iptables contents are not set to 1配置过net.bridge.bridge-nf-call-iptables失败重新执行sysctl配置确认br_netfilter模块已加载[ERROR Swap]: running with swap on is not supported没有关闭swapswapoff -a注释fstab里的swap行timed out waiting for the condition控制平面组件没起来大概率是Flannel没装或者镜像拉不下来检查CNI插件检查kube-system下的Pod日志dial tcp 192.168.1.100:6443: connect: connection refusedapiserver没起来或者防火墙拦截systemctl status kubeletcrictl ps -a看容器是否在跑node xxx is not readykubelet没就绪多半是CNI问题kubectl describe node xxx查看KubeletReady的condition消息The connection to the server 192.168.1.100:6443 was refusedkubeconfig或网络问题检查admin.conf是否正确6443端口是否开放unknown flag: --experimental-upload-certskubeadm版本命令语法不一样高版本kubeadm已经移除了该参数使用新版的命令格式这里多说一句在落地的过程中最让我意外的一次问题是明明所有配置都对了但kubelet始终起不来。后来查journalctl日志发现机器上的cgroup驱动不一致——systemd使用的是cgroup v2而containerd默认还在用cgroupfs那一套。改完config.toml里的SystemdCgroup字段重启containerd就好了。所以再次提醒安装containerd后务必检查SystemdCgroup这个参数。这个小参数能帮你省下两小时的排查时间。还有一次某台机器上kubelet一直报错找不到etcd证书我一度怀疑是初始化出了问题后来发现是机器名和/etc/hosts解析对不上导致证书生成时主机名不匹配。所以改主机名要趁早最好在一开始就把hostname和/etc/hosts做好对应关系否则后面集群初始化时一堆证书和主机名绑定的环节都会有各种奇怪问题。最后再分享一个比较尴尬的教训有一次我图省事在多个节点上用了相同的主机名结果k8s直接把两个节点当成一个节点来处理导致其中一台永远NotReady。后来我统一规范了每台机器的主机名——不要用localhost不要重复所有节点的/etc/hosts都写上所有节点的IP和主机名映射这个问题就再也没出现过了。5. 收尾给新手的额外建议最后说几点我的个人体会。第一不要害怕报错。我在前几台零售机器上搭k8s几乎每次都卡在镜像拉取上。别灰心报错恰恰是你理解k8s内部机制最好的机会。每解决一个报错你对这套系统的认识就会深一层。第二善用journalctl。kubelet的日志基本都在systemd里遇到任何诡异问题第一反应应该是journalctl -u kubelet -f --no-pager大部分情况下真正的错误信息都藏在这个日志里。别只盯着kubectl describe的输出那个颗粒度还不够细。第三把单节点集群玩出花来。别以为只有一个节点的集群没意思你可以在上面练习Deployment滚动更新、Service的ClusterIP转发、ConfigMap挂载、PV/PVC存储、Ingress域名访问甚至用Helm部署一套完整的应用栈。这些练熟了你再去面对生产环境的k8s底气会完全不一样。对你来说现在最重要的是真的动手跑一遍。照着这篇文章一台2核4G的云服务器或者虚拟机一个周末的时间你就能拥有一个属于自己的k8s集群。之后再看到别人聊Deployment、Pod调度你也知道自己手上有真实环境可以验证了。希望这篇记录对你有帮助。如果搭建过程中还有哪里卡住欢迎在评论区把报错信息贴出来我看到会尽量回复。咱们一起把k8s这头大象一步步吃掉。
RELATED

相关推荐

Python循环与异常处理深度指南,避开这些坑

Python循环与异常处理深度指南,避开这些坑

开头Python的for循环和while循环,看起来就两行语法,但真要在项目里写出清晰、高效、不出bug的循环代码,里面门道不少。尤其是循环和异常处理搭配使用时,很多人会踩到变量作用域、无限循环、异常吞掉等让人头疼的坑。这篇博文不讲那…

📅 2026/9/16 3:37:07
Kubernetes集群搭建实战:从架构原理到kubeadm部署与故障排查

Kubernetes集群搭建实战:从架构原理到kubeadm部署与故障排查

k8s(二):从架构到上线,手把手搭一套生产可用集群第二篇来了。上一篇我们把k8s是什么、解决什么问题、和docker到底什么关系聊清楚了,这一篇直接动手:从架构理解到集群搭建,再到故障排查&#xf…

📅 2026/9/16 3:37:07
C++错误处理新范式:std::variant与std::expected深度解析

C++错误处理新范式:std::variant与std::expected深度解析

1. 为什么C需要两种“错误处理利器”1.1 错误处理的老问题:异常还是返回值?在C社区混久了,你会发现每次聊到错误处理,都能吵上十分钟。一部分人坚持异常(exception)才是正道,理由是它能把错误处…

📅 2026/9/16 3:37:07
MORE NEWS

更多资讯

📰

Win10 22H2找回小娜:虚拟机中一步步还原“你好小娜”语音唤醒

前阵子我在VMware里装了官方原版的Win10 22H2,本想着装完看一眼现在的系统什么样,结果手一滑把“你好小娜”这个话题给捞了出来。网上关于小娜的教程还停留在两年前的“点击任务栏搜索框旁边的Cortana”那一套,可实际上到了22H2的后期补丁&am…

📰

企业AI知识库搭建实战:从文档治理到向量检索调优

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

STM32标准外设库驱动SHT3X温湿度传感器:软件模拟I2C时序与CRC校验实战

简介:STM32驱动SHT3X温湿度传感器工程包,基于STM32F103C8T6微控制器,实现了对SHT30、SHT31等SHT3X系列数字温湿度传感器的数据采集,并通过串口输出当前环境温度与湿度值,适合嵌入式学习者、电子竞赛参赛者以及需要快速…

📰

ESP32音频队列溢出原理与实时流控优化实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

📰

Android Studio从零打造贪吃蛇:自定义View与状态机实战指南

简介:贪吃蛇作为经典街机游戏,本次基于Android Studio实现的版本移除了墙壁与自身碰撞限制,玩家只需专注操控贪吃蛇持续进食成长,玩法更显轻松自由。整套资源面向计算机专业学生的安卓课程设计、期末项目或自学练手场景&#xff0…

📰

Windows系统封装实战:从sysprep通用化到自定义镜像部署全流程

这几年我帮人批量装机的次数不算少,从最早的Ghost塞优盘、到后来用DISM封装WIM,再到Windows 10/11时代用sysprep走完整套自定义封装流程,算是把"Windows系统镜像"这条路摸透了。最近又一次帮朋友公司做60台办公电脑的部署&#xff…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬