资讯详情

资讯详情

阿里云与K8s零基础入门:从服务器选型到容器编排实战

做了五六年运维经常在后台收到私信问阿里云和K8s到底怎么入门很多人买了服务器却不知道怎么规划也有人啃了一堆概念还是写不出第一条命令。这次我把整个自学过程里能用得上的东西整理成一套可执行路径从阿里云服务器选型和基础环境初始化到K8s核心对象怎么理解再到带注释命令逐条跑通最后用一个贴近真实工作的练习项目把整条链路串起来。这套流程我自己带过几个零基础的新同事实操按顺序走基本一两个周末就能看到成果。1. 学习路线设计先别碰集群把这三件事做扎实1.1 零基础最容易踩的坑顺序反了我在带新人时发现一个普遍问题一上来就跟着教程敲kubeadm init结果网络插件、容器运行时、证书过期各种报错满天飞两小时过去连集群都起不来挫败感极强。问题不在于K8s本身有多难而是前置基础没打好。零基础学K8s我的建议是严格按下面这条顺序走先买一台阿里云ECS把Linux基本功过一遍文件操作、权限、systemd、网络基础再用这台机器跑容器搞懂镜像和容器的关系把docker run和containerd的命令摸熟之后才轮到K8s先理解Pod、Deployment、Service这3个核心对象再考虑怎么把集群建起来这个顺序背后有个很现实的逻辑K8s的报错信息基本都是层层嵌套的。比如你创建一个Pod一直ContainerCreating可能是因为镜像拉不下来可能是因为节点资源不够也可能是因为网络插件没装好。如果看不懂容器层面的日志就算把K8s文档背下来也定位不了问题。1.2 阿里云环境规划入门用轻量服务器就够很多人纠结要不要一开始就上高配ECS我的建议是入门阶段用轻量应用服务器或者最低配的ECS就够了。以阿里云为例入门阶段2核4G的配置就能跑起一个单节点K8s集群。按量付费或者包年包月都行第一个月先按量付费练完就释放成本控制在几十块以内。等你真正确定要长期学习再换成包年包月。这里有一个很重要但容易忽略的点地域选择。建议选离你物理位置近的节点比如你在杭州就选华东1不是为了玄学提速而是后续拉镜像、排网络问题的时候ping值低会让你更快判断是网络问题还是配置问题。另外入门阶段千万不要开通公网带宽很大的实例1M到3M足够SSH连接和拉取镜像用了省钱且够用。提示新用户买ECS时注意看“固定带宽”和“按使用流量”的计费区别。入门学习阶段建议直接固定带宽1M或3M别选按流量计费容易因为中文文档里的一个wget命令把自己流量费搞超。1.3 环境初始化三件套先装好拿到一台全新的阿里云ECS后先别急着装K8s把下面这三件事做完后面能省很多事。# 1. 更新系统软件包 sudo apt update sudo apt upgrade -y # Debian/Ubuntu 系 # 如果用的是 CentOS / Alibaba Cloud Linux则用 # sudo yum update -y # 2. 创建普通用户并加入 sudo 组不建议一直用 root 操作 sudo useradd -m k8suser # 创建用户 k8suser sudo usermod -aG sudo k8suser # 加入 sudo 组CentOS 系是 wheel 组 sudo passwd k8suser # 设置密码 # 3. 配置 SSH 密钥登录强烈建议比密码登录安全得多 ssh-keygen -t rsa -b 4096 -f ~/.ssh/aliyun_k8s # 本地生成密钥对 ssh-copy-id -i ~/.ssh/aliyun_k8s.pub k8suser你的服务器公网IP这三步看起来基础但直接影响后续所有操作。用普通用户 sudo 而不是 root 直连是因为K8s社区和阿里云推荐的运维惯例都是最小权限原则——你以后在公司维护生产集群也一定是这种模式现在就养成习惯后面不会踩权限的坑。1.4 网络与安全组这是阿里云特有的坑K8s对网络要求非常严格而云服务器和本地虚拟机的最大区别就是有一层安全组。很多人在本地用 VMware 练得好好的一到阿里云就各种集群组件通信失败十有八九是安全组没放行。入门阶段你至少需要放行这几个端口22端口SSH连接用6443端口K8s API Server 通信2379-2380端口etcd 通信单节点可先不开10250端口kubelet 通信30000-32767端口段NodePort 服务暴露用在阿里云控制台找到你的 ECS 实例 → 安全组 → 配置规则添加入方向规则时记得选“自定义TCP”端口范围按上面的段填授权对象写0.0.0.0/0。如果你觉得全开网段不安全也可以限定你当前办公网络的IP但学习阶段为了方便建议直接全开同时用SSH密钥登录来兜底安全这块。注意安全组规则是阿里云这层做的过滤和服务器内部防火墙iptables/firewalld是两层体系。我见过有人只在安全组放行了端口但系统内部 firewalld 还开着结果端口通不了。建议学习阶段直接把 firewalld 停掉并禁用开机自启减少一层变量。2. K8s 核心对象拆解用生活化方式理解 Pod、Deployment、Service2.1 Pod最小的“进程盒子”K8s最基础的对象是Pod但很多人一开始会把它和容器混为一谈。我常用的一个类比是容器是一个个集装箱Pod是一艘专门绑运这些集装箱的小船。Pod里可以装一个容器也可以装多个紧密协作的容器比如一个跑业务进程一个负责收集日志它们共享网络命名空间和存储卷。在真实运维中你得习惯这个观念Pod是K8s管理的最小单位而不是容器。所以排查问题的时候先看Pod状态再看容器日志。下面的命令是入门阶段每天都会用到的# 查看命名空间下所有 Pod 及其状态 kubectl get pods -n your-namespace # 查看某个 Pod 的详细信息重点看 Events 字段 kubectl describe pod pod-name -n your-namespace # 进入 Pod 里的容器执行命令用于排查运行中的进程问题 kubectl exec -it pod-name -n your-namespace -- /bin/sh # 实时查看 Pod 日志加 -f 是跟随输出 kubectl logs -f pod-name -n your-namespace很多新手遇到Pod起不来第一反应就是删掉重建。但kubectl describe里Events那一段其实已经把原因写得很清楚了——镜像不存在、端口冲突、资源不足都会直接显示。学会看describe是K8s运维的基本功比盲目删Pod高到不知道哪里去了。2.2 Deployment你的“自动修复管家”Deployment可以理解为对Pod做了一层自动化管理。你告诉它“我要跑3个副本”它会始终保持这3个副本存在其中任何一个挂了它都会自动拉起新的。这就解决了单个容器生命周期管理的核心问题。我让新手做的第一个练习不是创建Pod而是创建Deployment因为这才是生产中真正在用的方式# 创建一个名为 myapp 的 Deployment镜像用 nginx副本数 3 kubectl create deployment myapp --imagenginx:1.25 --replicas3 -n your-namespace # 查看 Deployment 状态 kubectl get deployment myapp -n your-namespace # 修改副本数到 5弹性伸缩的雏形 kubectl scale deployment myapp --replicas5 -n your-namespace # 滚动更新镜像版本 kubectl set image deployment/myapp nginxnginx:1.26 -n your-namespace # 查看滚动更新过程中的状态 kubectl rollout status deployment/myapp -n your-namespace这套操作下来你就已经接触到了K8s最核心的运维场景保证副本数量、发布新版本、回滚异常版本。零基础阶段不需要马上理解控制器原理先用命令把体验打通后面再看理论会顺畅很多。2.3 Service给Pod一个稳定的“门牌号”Pod在K8s里是“朝生暮死”的IP地址随时会变。Service的作用就是给这一组Pod提供一个稳定的访问入口虚拟IP DNS客户端只管访问Service不用关心后端Pod的IP变化。这一层逻辑初看有点绕但很重要。你可以这样理解Deployment管“有多少个Pod活着”Service管“怎样能找到这些Pod”。两个对象配合才构成一个对外提供服务的完整应用。# 将 Deployment 暴露为 Service类型 ClusterIP仅集群内可访问 kubectl expose deployment myapp --port80 --target-port80 -n your-namespace # 如果希望外部直接访问可以把类型换成 NodePort会分配一个 30000-32767 的端口 kubectl get service myapp -n your-namespace # 查看 Service 详细信息其中 ENDPOINTS 列就是后端 Pod 的 IP 列表 kubectl describe service myapp -n your-namespace在阿里云上外部访问一般不会直接用NodePort要自己处理一堆端口限制而是用SLB负载均衡器配合Ingress或者LoadBalancer类型的Service。但入门阶段我建议先把NodePort跑通理解数据流转路径再去接触SLB、Ingress这些偏阿里云生态的组件。2.4 命名空间多环境隔离的起点命名空间Namespace是一个很容易被忽略但生产环境里特别重要的概念。它可以把集群划分成多个虚拟的独立空间——比如 dev、prod 各一个 namespace彼此资源隔离、互不干扰。# 创建命名空间 kubectl create namespace dev # 查看所有命名空间 kubectl get namespaces # 后续所有操作都带 -n 指定命名空间 kubectl get pods -n dev很多新手习惯所有资源都丢在 default 命名空间里本地练没问题但一到生产环境就会乱了套。从第一天开始就养成带-n参数的习惯后面接手任何真实项目都会轻松很多。3. 带注释命令实操用 Minikube 在阿里云上快速拉起单节点集群3.1 工具选型为什么不直接上 kubeadm零基础阶段直接使用kubeadm在阿里云上搭建集群是一个很容易让人放弃的操作——它涉及的组件太多任何一个细节出错都会导致初始化失败。我建议先用 Minikube 作为学习工具它底层把复杂的技术细节帮你屏蔽了但操作体验和真实K8s集群几乎一样kubectl命令完全通用。等你在Minikube上把核心对象、常用命令都熟练了再去用kubeadm搭真实的多节点集群会发现轻松很多因为大多数排查思路你已经训练过了。3.2 Minikube 安装与启动阿里云 ECS 实测版# 1. 安装 Minikube注意下载阿里云镜像加速否则会卡到怀疑人生 curl -Lo minikube https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/releases/v1.31.2/minikube-linux-amd64 sudo install minikube /usr/local/bin/ # 2. 安装 kubectl同样使用阿里云镜像 curl -Lo kubectl https://kubernetes.oss-cn-hangzhou.aliyuncs.com/release/v1.28.2/bin/linux/amd64/kubectl sudo install kubectl /usr/local/bin/ # 3. 安装 dockerMinikube 在 Linux 下默认用 docker 驱动 sudo apt install -y docker.io # Ubuntu 系 sudo systemctl enable --now docker # 4. 启动 Minikube使用国内镜像源是关键 minikube start \ --driverdocker \ --image-mirror-countrycn \ --image-repositoryregistry.cn-hangzhou.aliyuncs.com/google_containers \ --cpus2 \ --memory2048这条启动命令里的参数都是有讲究的--driverdocker表示用 Docker 来承载K8s节点这是单节点学习最稳妥的方式--image-mirror-countrycn和--image-repository是给国内网络环境准备的否则K8s核心组件镜像拉取会一直超时--cpus2和--memory2048是给Minikube分配的资源上限和你ECS本身配置要匹配3.3 启动失败排查实录阿里云上的高概率坑我在阿里云上帮人搭环境时遇到最多的报错是Exiting due to DRV_AS_ROOT: The docker driver should not be used with root privileges.这是因为你用了 root 用户执行。Minikube 官方不建议直接在 root 下用 docker 驱动解决办法是切回普通用户并把该用户加入 docker 组sudo usermod -aG docker k8suser # 退出当前 SSH 重新登录让组权限生效 exit # 再重新登录后不要加 sudo直接执行 minikube status第二个常见问题是Exiting due to PROVIDER_DOCKER_NEW_NETWORK: Invalid network plugin这是Docker网络和你ECS网络环境冲突。先执行docker network prune清理一下再重启 Docker 服务最后重新minikube start。如果还不行检查一下ECS是不是开了多块网卡强制指定网络试试。3.4 集群可用性验证跑通第一个工作负载Minikube 启动成功后别急着庆祝先用下面的命令确认集群真的“健康”# 查看节点状态Ready 表示节点正常 kubectl get nodes # 查看集群核心组件状态 kubectl get pods -n kube-system # 创建一个测试 Podnginx 启动成功后通过端口转发访问它 kubectl create deployment test-web --imagenginx:1.25 --replicas1 kubectl expose deployment test-web --typeNodePort --port80 kubectl get svc test-web # 找到 30000-32767 段的端口访问 http://你的服务器公网IP:那个端口到这里“在阿里云上有一个能跑工作负载的K8s集群”这个目标就算达成了。对这个阶段来说重要的不是集群本身而是你亲手验证了从“部署应用”到“对外暴露服务”的完整链路。4. 可落地练习项目一给博客应用容器化并发布到 K8s4.1 项目设计为什么要做博客应用学习K8s最忌讳的是“只跑 hello-world”。我设计的第一个练习项目是把自己的静态博客容器化并部署到K8s这是个非常适合零基础的项目它不涉及复杂业务逻辑但恰好覆盖了镜像构建、Deployment编排、Service暴露、存储卷挂载这几个最常用的运维场景。我从 Hugo 开始因为静态站点生成器只需要一条命令就能产出完整的HTML文件后续直接在 Dockerfile 里用 Nginx 托管这些静态文件即可。4.2 编写带注释的 Dockerfile# 第一阶段构建静态站点 FROM golang:1.21 AS builder # 安装 Hugo RUN apt-get update apt-get install -y hugo # 把博客源码复制进容器 WORKDIR /app COPY . . # 生成静态文件到 public 目录 RUN hugo --minify # 第二阶段用 Nginx 托管静态文件镜像体积更小 FROM nginx:1.25-alpine # 把第一阶段生成的静态文件复制到 Nginx 的站点根目录 COPY --frombuilder /app/public /usr/share/nginx/html # 暴露 80 端口 EXPOSE 80这里用了多阶段构建第一阶段的Golang环境只是为了生成静态文件最终镜像只包含Nginx和HTML体积从几百MB缩到几十MB。这个习惯在真实运维里非常受用——镜像越小拉取越快攻击面也越小。4.3 容器镜像构建与推到阿里云容器镜像服务K8s节点拉取镜像时需要一个镜像仓库。你可以用 Docker Hub国内速度不稳定也可以直接用阿里云容器镜像服务ACR个人版免费额度对学习完全够用。# 1. 登录阿里云容器镜像服务按控制台提示操作 docker login --username你的用户名 registry.cn-hangzhou.aliyuncs.com # 2. 给本地镜像打标签格式是仓库地址/命名空间/仓库名:版本号 docker tag my-blog:v1 registry.cn-hangzhou.aliyuncs.com/my-namespace/my-blog:v1 # 3. 推送镜像到阿里云镜像仓库 docker push registry.cn-hangzhou.aliyuncs.com/my-namespace/my-blog:v1 # 4. 在服务器上拉取验证看能否从远成拉取成功 docker pull registry.cn-hangzhou.aliyuncs.com/my-namespace/my-blog:v1把镜像推到阿里云镜像仓库还有一个额外好处K8s节点如果是同地域的ECS拉取速度会非常快基本秒级。4.4 编写 K8s 部署清单YAML 文件带注释这里不推荐用kubectl create deployment那种命令行方式因为YAML文件可以版本化管理、可复现这才是真实工作中该有的姿势。# deployment.yaml apiVersion: apps/v1 kind: Deployment metadata: name: blog-deployment namespace: dev labels: app: my-blog spec: # 副本数这里是单节点 Minikube所以只跑 1 个 replicas: 1 selector: matchLabels: app: my-blog template: metadata: labels: app: my-blog spec: containers: - name: blog-container image: registry.cn-hangzhou.aliyuncs.com/my-namespace/my-blog:v1 imagePullPolicy: IfNotPresent ports: - containerPort: 80 resources: # 预留资源生产环境必填防止内存泄漏拖垮节点 requests: cpu: 100m memory: 128Mi limits: cpu: 500m memory: 512Mi# service.yaml apiVersion: v1 kind: Service metadata: name: blog-service namespace: dev spec: type: NodePort selector: app: my-blog ports: - port: 80 targetPort: 80 # 不指定 nodePort 的话系统会在 30000-32767 之间自动分配应用这两份清单并验证访问# 创建命名空间如果还没有 kubectl create namespace dev # 应用 Deployment 和 Service kubectl apply -f deployment.yaml kubectl apply -f service.yaml # 查看状态等待 READY 显示 1/1 kubectl get deployment -n dev kubectl get pods -n dev # 查看自动分配的 NodePort kubectl get svc -n dev把输出的PORT(S)列里80:31xxx/TCP这样的端口记下来浏览器访问http://你的服务器公网IP:31xxx如果能看到你的博客页面恭喜你的第一个完整K8s应用已经运行起来了。5. 学习K8s必须避开的业务“陷阱”与常见问题速查5.1 容器崩溃循环CrashLoopBackOff这是新手最高频的报错没有之一。原因一般是容器启动后立刻退出或者启动后因健康检查失败被Kill掉。排查步骤记住这个顺序# 1. 先看当前状态 kubectl get pods -n dev # 2. 看日志这是最重要的证据 kubectl logs pod-name -n dev --tail100 # 3. 如果 Pod 之前正常过看前一个容器的日志 kubectl logs pod-name -n dev --previous # 4. 看事件确认到底卡在哪一步 kubectl describe pod pod-name -n dev常见原因启动命令写错、依赖的数据库还没就绪、镜像本身有问题。这里提醒一个很容易忽略的如果日志里显示exec user process caused: exec format error大概率是镜像架构和ECS架构不一致比如在ARM Mac上构建的镜像推到AMD64服务器上跑。5.2 镜像拉取失败ImagePullBackOff阿里云ECS上遇到ImagePullBackOff先检查几件事镜像名称是否写错尤其是镜像仓库地址里得区分registry.cn-hangzhou.aliyuncs.com和 Docker Hub 官方地址镜像是否为私有仓库如果是私有的需要在Deployment中配置imagePullSecretsDNS解析问题尝试在ECS上手动docker pull验证对于Minikube环境镜像拉取失败可以先手动拉好镜像再启动或者配置registry-mirrors指向阿里云的镜像加速器。5.3 存储卷权限问题当你在K8s里挂载了 hostPath 或 CephFS 这类存储时经常遇到“Permission denied”。这不是K8s配置问题而是宿主机目录的属主、属组和容器内进程UID不匹配导致的。解决思路很直接# 临时验证手动进入容器看用户ID kubectl exec -it pod-name -n dev -- id # 在宿主机调整目录权限让容器内用户能访问 sudo chown -R 1000:1000 /data/blog很多业务容器的官方镜像默认以UID 1000运行而宿主机目录是root创建的基本必踩这个坑。5.4 阿里云安全组导致访问超时这个问题的坑在于K8s集群里一切正常Pod是RunningService也有Endpoints但浏览器就是打不开页面。排查思路ECS安全组是否放行了对应的NodePort端口段服务器内部防火墙是否拦截学习阶段建议直接放行端口是否真的监听在0.0.0.0上ss -lntp | grep 端口如果是用了LoadBalancer类型的Service检查SLB配置我见过最夸张的一次是用户在阿里云控制台的安全组里只放行了80端口NodePort开在30000多段外部一直访问超时查了半天才发现是安全组的问题。所以这里再次强调安全组是云环境特有的第一道关卡排查网络问题永远先看它。5.5 集群资源不足导致Pod调度失败单节点Minikube资源本身就有限一旦部署了很多测试应用很容易出现0/1 nodes are available: insufficient memory的调度失败。这时不是去清理业务而是先学会看资源水位# 查看节点资源使用情况 kubectl top nodes # 查看各 Pod 资源占用 kubectl top pods -n dev # 清理不再使用的资源 kubectl delete deployment 未使用的deployment -n dev背后的道理是K8s的调度器是根据Pod的requests字段判断节点剩余可分配资源的。有时候节点实际内存还有很多空余但因为你先前的Deployment设置了过高的requests导致新Pod无法调度。这也是为什么我前面在YAML里特意写了resources字段的原因——学会管理资源水位是每个K8s运维的必修课。5.6 常见问题速查表报错现象大概率原因第一步排查命令Pod一直Pending资源不足或调度约束不满足kubectl describe pod pod-nameCrashLoopBackOff启动命令错误或健康检查失败kubectl logs pod-name --previousImagePullBackOff镜像拉取失败手动docker pull验证ContainerCreatingCNI网络或存储卷挂载问题kubectl describe pod pod-nameService无法访问安全组/防火墙/Selector不匹配kubectl get endpoints svc-name命令提示not foundkubectl版本与集群版本差异kubectl version6. 进阶路径从“会敲命令”到“会运维”的落地练习6.1 加入阿里云生态组件从 K8s 到云原生当你把上面这套流程吃透以后可以尝试把阿里云的各种托管组件融入到K8s工作流中这些才是实际工作中真正会遇到的场景用阿里云SLB替代NodePort把Service类型改成LoadBalancer给集群配置一个阿里云日志服务SLS的采集器让Pod日志自动收集到日志平台用阿里云容器镜像服务的触发器实现镜像推送后自动更新Deployment练习方式保持现有的博客项目把Service从NodePort改成LoadBalancerapiVersion: v1 kind: Service metadata: name: blog-service-lb namespace: dev spec: type: LoadBalancer selector: app: my-blog ports: - port: 80 targetPort: 80应用之后kubectl get svc blog-service-lb -n dev会显示一个EXTERNAL-IP大概率是你阿里云账号下自动创建的SLB实例的公网IP。这个操作背后的逻辑很重要云厂商通过Cloud Controller Manager把云上的负载均衡资源动态关联到K8s的Service上这也是“云原生”最直白的一个体现。6.2 模拟真实故障演练才是最好的学习光学会敲命令是不够的你得练就一套“条件反射式”的排查流程。我建议你做几个简单的故障演练自己先把博客应用的副本数缩到0然后再手动扩回来观察kubectl get events -n dev --sort-by.metadata.creationTimestamp里的调度记录kill掉一个Pod看看Deployment多久能拉一个新的起来kubectl delete pod pod-name -n dev同时开另一个终端kubectl get pods -n dev -w观察状态变化改错镜像版本号观察滚动更新的回滚过程练习kubectl rollout undo deployment/blog-deployment -n dev手动把Pod里的Nginx进程杀掉kubectl exec -it pod-name -n dev -- kill 1看K8s会怎么处理这组练习全部做下来基本就把K8s的自动恢复机制吃透了——你会发现Deployment控制器比你想象中顽强得多它会让你的应用始终保持期望的状态。6.3 下一步掌握 helm 和 CI/CD当你建立了“用YAML描述应用状态”的感觉后可以去接触Helm了。Helm的作用是帮你把一堆分散的YAML文件打包成可复用、可配置的“安装包”你只需要改一个values.yaml就能完成不同环境dev/prod的部署差异。然后是CI/CD。一个简单的自动化流程就是代码推送到Git仓库 → 触发构建镜像 → 推送到ACR → 触发K8s滚动更新。阿里云的云效平台对新手比较友好或者你可以用GitHub Actions对接阿里云ACR把镜像推送和部署命令全部自动化。这个阶段里运维的核心角色已经从“手动敲命令”变成了“设计和维护一套自动化流程”职业边界一下子拓宽了。6.4 关于“运维岗位”的一点个人观察最后说点题外话。我在实际维护项目时最大的感受是K8s本身并不是难点难点在于你能不能快速理解业务需求然后把它翻译成合适的资源和编排方式。工具学起来是线性的但你处理问题的思路需要大量的踩坑和复盘才能建立。所以不要追求把所有组件都搞懂再动手更有效的方式是带着一个真实目标比如“把博客项目跑起来”遇到什么问题就查什么问题在解决一个个问题的过程中把K8s的知识体系自然搭建起来。这个项目跑通一次之后你会发现再去看那些系统性的书籍和文档吸收速度比之前快好几倍。工具永远只是入口真正让你值钱的是面对不确定问题时快速定位和解决的能力。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →