Kubernetes实战:你的分布式系统“保姆”养成记

大家好,我是小悟。

一、Kubernetes是啥?------ 你的"云原生老妈子"

想象一下,你是个餐馆老板(你的应用),有100个服务员(容器)。手动管理他们?你会疯掉:

  • "服务员A在3号桌吐了,快换个新的!"
  • "5号桌要了10份牛排,再开5个厨师容器!"
  • "哎哟,收银容器又挂了,今天的钱白赚了!"

Kubernetes(简称k8s,因为K和s中间有8个字母,程序员就爱这么无聊) 就是你的超级餐厅经理:

  • 🤖 自动编排:容器倒了?秒级重启!
  • 📈 自动扩缩容:客流量暴涨?自动复制服务员!
  • 🔄 滚动更新:换新菜单?零停机逐步更新!
  • 🎯 服务发现:"牛排服务在哪?""在10.244.2.3:8080,老板!"
  • 💾 配置管理:所有服务的秘方(配置)统一管理

简单说:K8s让你像管理单机应用一样管理成百上千的容器,还不用半夜被报警电话吵醒!


二、实战开始:把你的应用丢进K8s"洗衣机"

环境准备:先搞个"游乐场"

bash 复制代码
# 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

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:

perl 复制代码
# 应用配置
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管理副本:

yaml 复制代码
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

部署并玩转它:

ini 复制代码
# 部署
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会变,需要稳定的访问地址:

yaml 复制代码
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:

csharp 复制代码
# 创建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:管理配置,不用改代码重新构建镜像

bash 复制代码
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

yaml 复制代码
# 在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层负载均衡,给你的服务配"智能路由"

yaml 复制代码
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并测试:

bash 复制代码
# 启用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

第五步:监控和调试(当"老妈子"生病时)

ini 复制代码
# 查看所有资源
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?

  1. 抽象基础设施:从"我的应用跑在哪台服务器"变成"我的应用需要多少资源"
  2. 自愈能力:节点挂了?Pod飘移到其他节点。容器崩了?自动重启
  3. 弹性伸缩:流量来了自动扩容,走了自动缩容,省钱!
  4. 声明式配置:告诉K8s"我想要什么状态",而不是"你执行这些步骤"
  5. 生态丰富:监控、日志、CI/CD、服务网格...应有尽有

避坑指南

  1. 资源限制一定要设:不然一个Pod能吃光所有内存,然后...全村吃席
  2. 别把所有东西放一个Namespace:就像别把所有衣服扔一个衣柜
  3. 健康检查不是可选项:没有健康检查的Pod就像没装刹车的车
  4. 镜像标签别用latest:不然今天更新镜像,明天全员崩溃
  5. 备份etcd:etcd是K8s的大脑,不备份?祝你好运

收尾

学习K8s就像养了一只猫:

  • 刚开始:它高冷神秘,你不知所措
  • 中间:它偶尔捣乱,你熬夜debug
  • 最后:你离不开它,它优雅地帮你管理一切

K8s的最大好处?你可以跟老板说:"我们的系统有自动恢复、弹性伸缩、零停机更新能力!" 然后深藏功与名,回家睡大觉。


最后的小抄:

csharp 复制代码
# 常用命令三字经
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拍死在沙滩上!🏄‍♂️🐳

谢谢你看我的文章,既然看到这里了,如果觉得不错,随手点个赞、转发、在看三连吧,感谢感谢。那我们,下次再见。

您的一键三连,是我更新的最大动力,谢谢

山水有相逢,来日皆可期,谢谢阅读,我们再会

我手中的金箍棒,上能通天,下能探海

相关推荐
啊哈灵机一动1 小时前
玩转 ESP32-S3 N16R8:PlatformIO 配置 PSRAM 并验证使用
后端
小周在成长1 小时前
Java 构造器(Constructor)完全指南
后端
刃神太酷啦1 小时前
C++的IO流和C++的类型转换----《Hello C++ Wrold!》(29)--(C/C++)
java·c语言·开发语言·c++·qt·算法·leetcode
稚辉君.MCA_P8_Java1 小时前
Gemini永久会员 哈希表(Hash Table)高效的数据结构
java·数据结构·后端·算法·架构
一只乔哇噻1 小时前
java后端工程师+AI大模型进修ing(研一版‖day58)
java·开发语言
lichong9511 小时前
Android 弹出进度条对话框 避免用户点击界面交互
java·前端·javascript
Geek__19921 小时前
杂记:记录一次Sqlite的使用问题
java·oracle·sqlite
summer__77771 小时前
【期末复习01】-算法题ProgramDesign
java·算法
x***38161 小时前
比较Spring AOP和AspectJ
java·后端·spring