大家好,我是小悟。
一、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拍死在沙滩上!🏄♂️🐳
谢谢你看我的文章,既然看到这里了,如果觉得不错,随手点个赞、转发、在看三连吧,感谢感谢。那我们,下次再见。
您的一键三连,是我更新的最大动力,谢谢
山水有相逢,来日皆可期,谢谢阅读,我们再会
我手中的金箍棒,上能通天,下能探海