大家好,我是小悟。
一、Kubernetes是啥?—— 你的“云原生老妈子”
想象一下,你是个餐馆老板(你的应用),有100个服务员(容器)。手动管理他们?你会疯掉:
- “服务员A在3号桌吐了,快换个新的!”
- “5号桌要了10份牛排,再开5个厨师容器!”
- “哎哟,收银容器又挂了,今天的钱白赚了!”
Kubernetes(简称k8s,因为K和s中间有8个字母,程序员就爱这么无聊) 就是你的超级餐厅经理:
- 🤖 自动编排:容器倒了?秒级重启!
- 📈 自动扩缩容:客流量暴涨?自动复制服务员!
- 🔄 滚动更新:换新菜单?零停机逐步更新!
- 🎯 服务发现:“牛排服务在哪?”“在10.244.2.3:8080,老板!”
- 💾 配置管理:所有服务的秘方(配置)统一管理
简单说:K8s让你像管理单机应用一样管理成百上千的容器,还不用半夜被报警电话吵醒!
二、实战开始:把你的应用丢进K8s“洗衣机”
环境准备:先搞个“游乐场”
# 1. 安装minikube(本地K8s游乐场) brew install minikube # Mac # 或 curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 sudo install minikube-linux-amd64 /usr/local/bin/minikube # 2. 启动你的“小黄鸭K8s” minikube start --driver=docker --cpus=4 --memory=8192 # 看到🐳 图标就对了,K8s喜欢鲸鱼 # 3. 安装kubectl(K8s遥控器) brew install kubectl # 验证安装 kubectl version --client # 4. 看看你的集群状态 kubectl cluster-info # 如果看到“Kubernetes control plane is running”,恭喜!
第一步:创建你的第一个Pod(K8s的最小“细胞”)
创建文件 my-first-pod.yaml:
apiVersion: v1 kind: Pod # 这是K8s的最小部署单元,就像单个细胞 metadata: name: my-nginx-pod labels: app: nginx environment: test humor-level: "high" # 对,标签可以随便写 spec: containers: - name: nginx-container image: nginx:alpine # 用alpine版本,小巧可爱 ports: - containerPort: 80 env: - name: NGINX_ENV value: "K8s_Rocks" resources: requests: memory: "64Mi" cpu: "250m" # m是千分之一核,不是米! limits: memory: "128Mi" cpu: "500m" # 健康检查,防止僵尸容器 livenessProbe: httpGet: path: / port: 80 initialDelaySeconds: 5 periodSeconds: 10
部署Pod:
# 应用配置 kubectl apply -f my-first-pod.yaml # 输出:pod/my-nginx-pod created # 查看状态 kubectl get pods # 你会看到: # NAME READY STATUS RESTARTS AGE # my-nginx-pod 1/1 Running 0 10s # 查看详细信息 kubectl describe pod my-nginx-pod # 信息多到像老妈子唠叨 # 进入Pod内部看看(像盗梦空间) kubectl exec -it my-nginx-pod -- /bin/sh # 在里面: curl localhost,看到nginx欢迎页! # 退出: exit
第二步:升级到Deployment(有了“克隆人军团”)
单个Pod太脆弱,用Deployment管理副本:
apiVersion: apps/v1 kind: Deployment # 这是Pod的“妈妈”,管理一组相同的Pod metadata: name: nginx-deployment labels: app: nginx department: "engineering-humor" spec: replicas: 3 # 要3个副本,三胞胎! selector: matchLabels: app: nginx template: # Pod模板 metadata: labels: app: nginx version: "v1.0" spec: containers: - name: nginx image: nginx:1.21-alpine ports: - containerPort: 80 # 就绪探针,确保容器真的准备好了 readinessProbe: httpGet: path: / port: 80 initialDelaySeconds: 3 periodSeconds: 5
部署并玩转它:
# 部署 kubectl apply -f deployment.yaml # 看Deployment状态 kubectl get deployments # NAME READY UP-TO-DATE AVAILABLE AGE # nginx-deployment 3/3 3 3 15s # 看它创建的Pod(三胞胎!) kubectl get pods -l app=nginx # 会看到3个名字不同的Pod # 模拟一个Pod挂了 kubectl delete pod $(kubectl get pods -l app=nginx -o jsonpath='{.items[0].metadata.name}') # 马上再看,K8s会自动重建一个! kubectl get pods -l app=nginx # 扩容到5个副本(客人多了!) kubectl scale deployment nginx-deployment --replicas=5 kubectl get pods # 现在有5个了! # 滚动更新(换新菜单) kubectl set image deployment/nginx-deployment nginx=nginx:1.22-alpine # 看魔术: kubectl rollout status deployment nginx-deployment # 每个Pod会逐个更新,服务不中断!
第三步:添加Service(给你的服务装“门牌号”)
Pod IP会变,需要稳定的访问地址:
apiVersion: v1 kind: Service # 这是服务的“前台接待” metadata: name: nginx-service spec: selector: app: nginx # 选择所有标签为app=nginx的Pod ports: - name: http port: 80 # Service端口 targetPort: 80 # Pod端口 nodePort: 30080 # 节点端口(NodePort类型时才用) type: NodePort # 三种类型:ClusterIP(默认),NodePort,LoadBalancer
创建并测试Service:
# 创建Service kubectl apply -f service.yaml # 查看Service kubectl get svc # NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE # nginx-service NodePort 10.96.123.45 <none> 80:30080/TCP 10s # 在集群内访问 minikube ssh # 进入节点 curl 10.96.123.45 # 用Cluster IP访问 # 从外部访问(NodePort方式) minikube service nginx-service --url # 会返回一个URL,浏览器打开它! # 或者直接 minikube service nginx-service
第四步:高级玩法 - ConfigMap和Ingress
ConfigMap:管理配置,不用改代码重新构建镜像
apiVersion: v1 kind: ConfigMap metadata: name: nginx-config data: nginx.conf: | server { listen 80; server_name _; location / { root /usr/share/nginx/html; index index.html; # 加个搞笑header add_header X-K8s-Humor "Containers contain containments"; } location /health { access_log off; return 200 "healthy\n"; } } index.html: | <html> <body> <h1>Running on Kubernetes!</h1> <p>Pod: ${POD_NAME}</p> <p>Node: ${NODE_NAME}</p> <p>笑话: Why do containers never get lost? They always have a pod to stay in!</p> </body> </html>
更新Deployment使用ConfigMap:
# 在Deployment的Pod模板中添加: spec: containers: - name: nginx # ... 其他配置 env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: NODE_NAME valueFrom: fieldRef: fieldPath: spec.nodeName volumeMounts: - name: config-volume mountPath: /etc/nginx/conf.d - name: html-volume mountPath: /usr/share/nginx/html volumes: - name: config-volume configMap: name: nginx-config items: - key: nginx.conf path: default.conf - name: html-volume configMap: name: nginx-config items: - key: index.html path: index.html
Ingress:7层负载均衡,给你的服务配“智能路由”
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: nginx-ingress annotations: nginx.ingress.kubernetes.io/rewrite-target: / spec: rules: - host: nginx.k8s.local # 本地测试用的域名 http: paths: - path: / pathType: Prefix backend: service: name: nginx-service port: number: 80 - host: "*.k8s.humor" # 通配符域名 http: paths: - path: /joke pathType: Prefix backend: service: name: nginx-service port: number: 80
启用Ingress并测试:
# 启用Ingress控制器(minikube中) minikube addons enable ingress # 应用Ingress配置 kubectl apply -f ingress.yaml # 获取Ingress IP kubectl get ingress # 需要等几分钟分配IP # 本地测试(修改hosts文件) # 编辑 /etc/hosts,添加: # <INGRESS_IP> nginx.k8s.local # 访问 curl http://nginx.k8s.local
第五步:监控和调试(当“老妈子”生病时)
# 查看所有资源 kubectl get all # 查看事件(K8s的“朋友圈动态”) kubectl get events --sort-by=.metadata.creationTimestamp # 查看Pod日志 kubectl logs -l app=nginx --tail=10 # 查看特定Pod kubectl logs <pod-name> -f # -f 是tail -f,实时看日志 # 资源使用情况 kubectl top pods kubectl top nodes # 进入调试模式(当Pod起不来时) kubectl describe pod <problem-pod> # 看详情 kubectl logs <problem-pod> --previous # 看之前容器的日志 # 临时运行一个调试Pod(像启动一辆侦察车) kubectl run -it --rm debug-pod --image=busybox --restart=Never -- sh # 在这个Pod里可以测试网络等 # nslookup nginx-service # 测试Service发现 # wget -qO- nginx-service # 测试访问
三、总结:K8s修炼心得
为什么需要K8s?
- 抽象基础设施:从“我的应用跑在哪台服务器”变成“我的应用需要多少资源”
- 自愈能力:节点挂了?Pod飘移到其他节点。容器崩了?自动重启
- 弹性伸缩:流量来了自动扩容,走了自动缩容,省钱!
- 声明式配置:告诉K8s“我想要什么状态”,而不是“你执行这些步骤”
- 生态丰富:监控、日志、CI/CD、服务网格…应有尽有
避坑指南
- 资源限制一定要设:不然一个Pod能吃光所有内存,然后…全村吃席
- 别把所有东西放一个Namespace:就像别把所有衣服扔一个衣柜
- 健康检查不是可选项:没有健康检查的Pod就像没装刹车的车
- 镜像标签别用latest:不然今天更新镜像,明天全员崩溃
- 备份etcd:etcd是K8s的大脑,不备份?祝你好运
收尾
学习K8s就像养了一只猫:
- 刚开始:它高冷神秘,你不知所措
- 中间:它偶尔捣乱,你熬夜debug
- 最后:你离不开它,它优雅地帮你管理一切
K8s的最大好处?你可以跟老板说:“我们的系统有自动恢复、弹性伸缩、零停机更新能力!” 然后深藏功与名,回家睡大觉。
最后的小抄:
# 常用命令三字经 kubectl get po # 查Pod kubectl get svc # 查服务 kubectl get deploy # 查部署 kubectl describe # 查详情 kubectl logs -f # 看日志 kubectl exec -it # 进容器 kubectl apply -f # 用配置 kubectl delete # 删资源 kubectl rollout restart # 重启部署 # 遇到问题三板斧 1. kubectl describe <资源> # 看事件 2. kubectl logs <pod> # 看日志 3. kubectl get events # 看集群事件
祝你在K8s的海洋里冲浪愉快,不被Pod拍死在沙滩上!🏄♂️🐳
谢谢你看我的文章,既然看到这里了,如果觉得不错,随手点个赞、转发、在看三连吧,感谢感谢。那我们,下次再见。
您的一键三连,是我更新的最大动力,谢谢
山水有相逢,来日皆可期,谢谢阅读,我们再会
我手中的金箍棒,上能通天,下能探海