← Lesson 0013 讲了网络和负载均衡。Kubernetes 把容器编排、负载均衡、服务发现、自愈全部内置了——这就是为什么它是云原生的操作系统。
你手动管 Docker:docker run、docker stop、配端口、设重启策略。管 3 个容器还行。管 50 个呢?跨 5 台机器呢?
Kubernetes = 容器操作系统。你声明「我要 3 个 nginx 副本,CPU 不超过 500m,挂了自动重启」,K8s 自己去调度、监控、修复。
Control Plane (Master) Worker Nodes
┌──────────────────────┐ ┌──────────────────┐
│ API Server │ │ kubelet │
│ Scheduler │ │ container runtime│
│ Controller Manager │ │ kube-proxy │
│ etcd (数据库) │ │ Pod Pod Pod │
└──────────────────────┘ └──────────────────┘
你只跟 API Server 打交道(通过 kubectl)。Scheduler 决定 Pod 放哪个 Node。Controller Manager 持续对比「实际状态」和「期望状态」。
Pod 是 K8s 的最小单元,包含一个或多个共享网络和存储的容器。
# pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: my-app
labels:
app: web # 标签——Service 靠这个找 Pod
spec:
containers:
- name: app
image: nginx:alpine
ports:
- containerPort: 80
kubectl apply -f pod.yaml # 创建
kubectl get pods # 列出
kubectl describe pod my-app # 详细信息(排错用)
kubectl logs my-app # 看日志
kubectl exec -it my-app -- sh # 进去
kubectl delete pod my-app # 删除
Deployment 声明「我要 N 个一模一样的 Pod」,K8s 保证实际数量 = 期望数量。
# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-deploy
spec:
replicas: 3 # 3 个副本
selector:
matchLabels:
app: web
template: # Pod 模板
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
kubectl apply -f deployment.yaml
kubectl get deployments
kubectl get pods # 看到 3 个 Pod
# 滚动更新
kubectl set image deployment/web-deploy nginx=nginx:1.25
kubectl rollout status deployment/web-deploy
# 回滚
kubectl rollout undo deployment/web-deploy
# 扩缩容
kubectl scale deployment/web-deploy --replicas=5
Pod 的 IP 是临时的(Pod 重建 IP 就变了)。Service 提供固定的 Cluster IP + DNS 名,自动负载均衡到健康的 Pod。
# service.yaml
apiVersion: v1
kind: Service
metadata:
name: web-svc
spec:
selector:
app: web # 选中带 app=web 标签的 Pod
ports:
- port: 80 # Service 的端口
targetPort: 80 # Pod 的端口
type: ClusterIP # 仅集群内部可访问(默认)
| Service Type | 效果 | 什么时候用 |
|---|---|---|
ClusterIP | 集群内部访问 | 服务间通信(默认) |
NodePort | 每个 Node 开一个端口(30000-32767) | 调试 / 简单暴露 |
LoadBalancer | 云服务商创建外部 LB | 生产对外暴露 |
kubectl get namespaces
kubectl create namespace staging
kubectl apply -f deployment.yaml -n staging
# 不同 namespace 的资源互相隔离,同名不冲突
# 装 minikube(推荐)或 kind
# minikube:
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
minikube start
# kind (Kubernetes in Docker):
# 你已经有 Docker,kind 更快
# curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-linux-amd64
# chmod +x ./kind && sudo mv ./kind /usr/local/bin/kind
# kind create cluster
# 验证
kubectl cluster-info
kubectl get nodes
如果你有 minikube/kind,跑这个:
# 创建 Deployment + Service
kubectl create deployment nginx --image=nginx:alpine --replicas=3 --port=80
kubectl expose deployment nginx --type=NodePort --port=80
# 查看
kubectl get all
# NAME READY STATUS RESTARTS AGE
# pod/nginx-xxx-xxx 1/1 Running 0 10s
# pod/nginx-xxx-yyy 1/1 Running 0 10s
# pod/nginx-xxx-zzz 1/1 Running 0 10s
# service/nginx TYPE:NodePort PORT(S):80:3xxxx/TCP
# 访问
minikube service nginx --url # minikube
# 或 kubectl port-forward svc/nginx 8080:80 # 通用方式
curl http://localhost:8080
Lesson 0015:K8s 网络与配置 →——Ingress、ConfigMap、Secret、Volume、PVC。