Kubernetes(k8s)入门教程 - 从零开始学习容器编排
Kubernetes(k8s)入门教程 - 从零开始学习容器编排
目录
- Kubernetes简介
- 环境搭建
- Kubernetes核心概念
- 第一个Kubernetes应用
- Pod详解
- Deployment详解
- Service详解
- ConfigMap和Secret
- Volume存储
- Namespace命名空间
- 常用命令
- 实际应用案例
- 监控和日志
- 故障排查
- 最佳实践
- 总结与进阶
1. Kubernetes简介
Kubernetes(简称k8s)是一个开源的容器编排平台,用于自动化容器的部署、扩展和管理。Kubernetes最初由Google开发,现在由Cloud Native Computing Foundation(CNCF)维护。
Kubernetes的核心功能:
- ✅ 容器编排:自动化容器的部署和管理
- ✅ 自动扩展:根据负载自动扩展或缩减应用
- ✅ 服务发现:自动发现和负载均衡服务
- ✅ 自我修复:自动重启失败的容器
- ✅ 滚动更新:零停机时间更新应用
- ✅ 存储编排:自动挂载存储系统
- ✅ 配置管理:管理应用配置和密钥
传统部署方式的问题:
- 手动部署,容易出错
- 难以扩展
- 资源利用率低
- 难以管理多个容器
Kubernetes的优势:
- 自动化部署和管理
- 弹性扩展
- 高可用性
- 资源优化
- 简化运维
控制平面(Control Plane)
- API Server:Kubernetes的入口,处理所有API请求
- etcd:分布式键值存储,保存集群状态
- Scheduler:调度器,决定Pod运行在哪个节点
- Controller Manager:运行各种控制器,维护期望状态
工作节点(Worker Node)
kubelet:节点代理,管理Pod生命周期
kube-proxy:网络代理,实现Service功能
Container Runtime:容器运行时(如Docker、containerd)
Pod:最小的部署单元,包含一个或多个容器
Deployment:管理Pod的副本和更新
Service:为Pod提供稳定的网络访问
ConfigMap:存储配置数据
Secret:存储敏感数据
Volume:存储卷
Namespace:命名空间,逻辑隔离
2. 环境搭建
- 操作系统:Linux、macOS或Windows
- 内存:至少2GB RAM(推荐4GB+)
- CPU:至少2核(推荐4核+)
- Docker:已安装Docker Desktop或Docker Engine
方式1:Minikube(推荐新手)
Minikube是在本地运行Kubernetes的最简单方式。
macOS安装:
# 使用Homebrew安装
brew install minikube
# 启动Minikube
minikube start
# 验证安装
kubectl get nodesLinux安装:
# 下载Minikube
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
# 启动Minikube
minikube start
# 验证安装
kubectl get nodesWindows安装:
# 使用Chocolatey安装
choco install minikube
# 启动Minikube
minikube start
# 验证安装
kubectl get nodes方式2:Docker Desktop(macOS/Windows)
Docker Desktop内置了Kubernetes支持。
- 安装Docker Desktop
- 打开Docker Desktop设置
- 在Kubernetes选项中启用Kubernetes
- 等待Kubernetes启动完成
方式3:kind(Kubernetes in Docker)
kind使用Docker容器运行Kubernetes集群。
# 安装kind
brew install kind # macOS
# 或下载二进制文件
# 创建集群
kind create cluster --name my-cluster
# 验证
kubectl get nodeskubectl是Kubernetes的命令行工具。
macOS安装:
brew install kubectlLinux安装:
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectlWindows安装:
# 使用Chocolatey
choco install kubernetes-cli
# 或使用Scoop
scoop install kubectl# 检查kubectl版本
kubectl version --client
# 检查集群状态
kubectl cluster-info
# 查看节点
kubectl get nodes
# 查看所有资源
kubectl get all# 查看当前上下文
kubectl config current-context
# 查看所有上下文
kubectl config get-contexts
# 切换上下文
kubectl config use-context <context-name>
# 查看配置
kubectl config view3. Kubernetes核心概念
Pod是Kubernetes中最小的部署单元,包含一个或多个紧密相关的容器。
Pod特点:
- Pod中的容器共享网络和存储
- Pod是临时性的,可以被创建和销毁
- 每个Pod都有唯一的IP地址
Deployment管理Pod的副本和更新,确保指定数量的Pod副本运行。
Deployment功能:
- 创建和管理Pod副本
- 滚动更新
- 回滚到之前的版本
- 扩缩容
Service为Pod提供稳定的网络访问,实现服务发现和负载均衡。
Service类型:
- ClusterIP:集群内部访问(默认)
- NodePort:通过节点端口访问
- LoadBalancer:云服务商的负载均衡器
- ExternalName:外部服务别名
ConfigMap存储非敏感的配置数据,可以在Pod中使用。
Secret存储敏感数据,如密码、密钥等。
Volume提供持久化存储,Pod重启后数据不丢失。
Namespace提供逻辑隔离,将资源分组管理。
4. 第一个Kubernetes应用
创建文件 nginx-pod.yaml:
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80部署Pod:
kubectl apply -f nginx-pod.yaml
# 查看Pod状态
kubectl get pods
# 查看Pod详情
kubectl describe pod nginx-pod
# 查看Pod日志
kubectl logs nginx-pod创建文件 nginx-service.yaml:
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 80
type: NodePort部署Service:
kubectl apply -f nginx-service.yaml
# 查看Service
kubectl get svc
# 获取Service的NodePort
kubectl get svc nginx-service -o jsonpath='{.spec.ports[0].nodePort}'
# 访问服务(Minikube)
minikube service nginx-service创建文件 nginx-deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80部署Deployment:
kubectl apply -f nginx-deployment.yaml
# 查看Deployment
kubectl get deployments
# 查看Pod
kubectl get pods -l app=nginx
# 扩展副本数
kubectl scale deployment nginx-deployment --replicas=5
# 更新镜像
kubectl set image deployment/nginx-deployment nginx=nginx:1.22
# 查看更新状态
kubectl rollout status deployment/nginx-deployment
# 回滚
kubectl rollout undo deployment/nginx-deployment5. Pod详解
apiVersion: v1
kind: Pod
metadata:
name: my-pod
labels:
app: myapp
version: v1
spec:
containers:
- name: container1
image: nginx:1.21
ports:
- containerPort: 80
env:
- name: ENV_VAR
value: "value"
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"apiVersion: v1
kind: Pod
metadata:
name: multi-container-pod
spec:
containers:
- name: nginx
image: nginx:1.21
ports:
- containerPort: 80
- name: redis
image: redis:6.2
ports:
- containerPort: 6379Pod的状态:
- Pending:Pod已被创建,但容器还未启动
- Running:Pod已绑定到节点,所有容器已创建
- Succeeded:所有容器成功终止
- Failed:至少一个容器失败终止
- Unknown:无法获取Pod状态
Liveness Probe(存活探针)
apiVersion: v1
kind: Pod
metadata:
name: liveness-pod
spec:
containers:
- name: nginx
image: nginx:1.21
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 30
periodSeconds: 10Readiness Probe(就绪探针)
apiVersion: v1
kind: Pod
metadata:
name: readiness-pod
spec:
containers:
- name: nginx
image: nginx:1.21
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 5Init容器在应用容器启动前运行,用于初始化工作。
apiVersion: v1
kind: Pod
metadata:
name: init-container-pod
spec:
initContainers:
- name: init
image: busybox
command: ['sh', '-c', 'echo "Initializing..."']
containers:
- name: app
image: nginx:1.216. Deployment详解
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-deployment
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: app
image: myapp:1.0
ports:
- containerPort: 8080apiVersion: apps/v1
kind: Deployment
metadata:
name: rolling-update-deployment
spec:
replicas: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: app
image: myapp:1.0# 手动扩缩容
kubectl scale deployment my-deployment --replicas=5
# 使用HPA自动扩缩容(需要metrics-server)
kubectl autoscale deployment my-deployment --min=2 --max=10 --cpu-percent=80# 更新镜像
kubectl set image deployment/my-deployment app=myapp:2.0
# 查看更新历史
kubectl rollout history deployment/my-deployment
# 回滚到上一个版本
kubectl rollout undo deployment/my-deployment
# 回滚到指定版本
kubectl rollout undo deployment/my-deployment --to-revision=2
# 查看更新状态
kubectl rollout status deployment/my-deployment7. Service详解
apiVersion: v1
kind: Service
metadata:
name: clusterip-service
spec:
type: ClusterIP
selector:
app: myapp
ports:
- protocol: TCP
port: 80
targetPort: 8080apiVersion: v1
kind: Service
metadata:
name: nodeport-service
spec:
type: NodePort
selector:
app: myapp
ports:
- protocol: TCP
port: 80
targetPort: 8080
nodePort: 30080apiVersion: v1
kind: Service
metadata:
name: loadbalancer-service
spec:
type: LoadBalancer
selector:
app: myapp
ports:
- protocol: TCP
port: 80
targetPort: 8080apiVersion: v1
kind: Service
metadata:
name: headless-service
spec:
clusterIP: None
selector:
app: myapp
ports:
- protocol: TCP
port: 80
targetPort: 8080# 查看Service的DNS名称
kubectl get svc
# 在Pod中访问Service
# Service名称: clusterip-service
# 命名空间: default
# DNS: clusterip-service.default.svc.cluster.local8. ConfigMap和Secret
从文件创建ConfigMap
# 创建配置文件
echo "server.port=8080" > app.properties
# 创建ConfigMap
kubectl create configmap app-config --from-file=app.properties
# 查看ConfigMap
kubectl get configmap app-config -o yaml从字面量创建ConfigMap
kubectl create configmap app-config \
--from-literal=server.port=8080 \
--from-literal=server.host=0.0.0.0在Pod中使用ConfigMap
apiVersion: v1
kind: Pod
metadata:
name: configmap-pod
spec:
containers:
- name: app
image: myapp:1.0
env:
- name: SERVER_PORT
valueFrom:
configMapKeyRef:
name: app-config
key: server.port
volumeMounts:
- name: config
mountPath: /etc/config
volumes:
- name: config
configMap:
name: app-config创建Secret
# 从文件创建
kubectl create secret generic my-secret \
--from-file=username=./username.txt \
--from-file=password=./password.txt
# 从字面量创建
kubectl create secret generic my-secret \
--from-literal=username=admin \
--from-literal=password=secret123
# 创建TLS Secret
kubectl create secret tls tls-secret \
--cert=tls.crt \
--key=tls.key在Pod中使用Secret
apiVersion: v1
kind: Pod
metadata:
name: secret-pod
spec:
containers:
- name: app
image: myapp:1.0
env:
- name: USERNAME
valueFrom:
secretKeyRef:
name: my-secret
key: username
- name: PASSWORD
valueFrom:
secretKeyRef:
name: my-secret
key: password
volumeMounts:
- name: secret
mountPath: /etc/secret
readOnly: true
volumes:
- name: secret
secret:
secretName: my-secret9. Volume存储
apiVersion: v1
kind: Pod
metadata:
name: emptydir-pod
spec:
containers:
- name: app
image: nginx:1.21
volumeMounts:
- name: cache
mountPath: /cache
volumes:
- name: cache
emptyDir: {}apiVersion: v1
kind: Pod
metadata:
name: hostpath-pod
spec:
containers:
- name: app
image: nginx:1.21
volumeMounts:
- name: host-storage
mountPath: /data
volumes:
- name: host-storage
hostPath:
path: /data
type: Directory创建PersistentVolume
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-volume
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
hostPath:
path: /data/pv创建PersistentVolumeClaim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-claim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi在Pod中使用PVC
apiVersion: v1
kind: Pod
metadata:
name: pvc-pod
spec:
containers:
- name: app
image: nginx:1.21
volumeMounts:
- name: pvc-storage
mountPath: /data
volumes:
- name: pvc-storage
persistentVolumeClaim:
claimName: pvc-claim10. Namespace命名空间
# 使用命令行创建
kubectl create namespace production
kubectl create namespace development
# 使用YAML创建apiVersion: v1
kind: Namespace
metadata:
name: production# 在指定命名空间创建资源
kubectl create deployment my-app --image=nginx:1.21 -n production
# 查看指定命名空间的资源
kubectl get pods -n production
# 切换默认命名空间
kubectl config set-context --current --namespace=productionapiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
namespace: production
spec:
hard:
requests.cpu: "4"
requests.memory: 8Gi
limits.cpu: "8"
limits.memory: 16Gi
persistentvolumeclaims: "4"11. 常用命令
# 查看资源
kubectl get pods
kubectl get services
kubectl get deployments
kubectl get nodes
kubectl get namespaces
# 查看详细信息
kubectl describe pod <pod-name>
kubectl describe service <service-name>
kubectl describe node <node-name>
# 查看日志
kubectl logs <pod-name>
kubectl logs -f <pod-name> # 实时日志
kubectl logs <pod-name> -c <container-name> # 多容器Pod
# 进入容器
kubectl exec -it <pod-name> -- /bin/bash
kubectl exec <pod-name> -- ls /app
# 删除资源
kubectl delete pod <pod-name>
kubectl delete service <service-name>
kubectl delete deployment <deployment-name>
kubectl delete -f <yaml-file># 应用配置
kubectl apply -f <yaml-file>
kubectl apply -f <directory>
# 创建资源
kubectl create deployment <name> --image=<image>
kubectl create service clusterip <name> --tcp=80:8080
# 编辑资源
kubectl edit deployment <name>
kubectl edit pod <name># 查看事件
kubectl get events
kubectl get events --sort-by=.metadata.creationTimestamp
# 查看资源使用情况
kubectl top nodes
kubectl top pods
# 端口转发
kubectl port-forward <pod-name> 8080:80
kubectl port-forward service/<service-name> 8080:80
# 查看API资源
kubectl api-resources
kubectl explain pod
kubectl explain pod.spec# 批量操作
kubectl get pods -o name | xargs kubectl delete
# 输出格式
kubectl get pods -o yaml
kubectl get pods -o json
kubectl get pods -o wide
kubectl get pods -o custom-columns=NAME:.metadata.name,STATUS:.status.phase
# 标签选择器
kubectl get pods -l app=nginx
kubectl get pods -l 'app in (nginx,redis)'
# 字段选择器
kubectl get pods --field-selector status.phase=Running12. 实际应用案例
完整的Web应用部署
deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 3
selector:
matchLabels:
app: web-app
template:
metadata:
labels:
app: web-app
spec:
containers:
- name: web
image: nginx:1.21
ports:
- containerPort: 80
env:
- name: ENV
value: "production"
resources:
requests:
memory: "128Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "200m"
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 5
periodSeconds: 5service.yaml:
apiVersion: v1
kind: Service
metadata:
name: web-app-service
spec:
type: NodePort
selector:
app: web-app
ports:
- protocol: TCP
port: 80
targetPort: 80
nodePort: 30080部署:
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
# 查看状态
kubectl get all -l app=web-appmysql-deployment.yaml:
apiVersion: v1
kind: Secret
metadata:
name: mysql-secret
type: Opaque
stringData:
password: mysql123
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:8.0
env:
- name: MYSQL_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mysql-secret
key: password
- name: MYSQL_DATABASE
value: mydb
ports:
- containerPort: 3306
volumeMounts:
- name: mysql-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-storage
persistentVolumeClaim:
claimName: mysql-pvc
---
apiVersion: v1
kind: Service
metadata:
name: mysql-service
spec:
selector:
app: mysql
ports:
- protocol: TCP
port: 3306
targetPort: 3306frontend-deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: frontend
spec:
replicas: 2
selector:
matchLabels:
app: frontend
template:
metadata:
labels:
app: frontend
spec:
containers:
- name: frontend
image: frontend:1.0
ports:
- containerPort: 3000
env:
- name: API_URL
value: "http://backend-service:8080"
---
apiVersion: v1
kind: Service
metadata:
name: frontend-service
spec:
type: LoadBalancer
selector:
app: frontend
ports:
- port: 80
targetPort: 3000backend-deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
spec:
replicas: 3
selector:
matchLabels:
app: backend
template:
metadata:
labels:
app: backend
spec:
containers:
- name: backend
image: backend:1.0
ports:
- containerPort: 8080
env:
- name: DB_HOST
value: "mysql-service"
- name: DB_NAME
value: "mydb"
---
apiVersion: v1
kind: Service
metadata:
name: backend-service
spec:
selector:
app: backend
ports:
- port: 8080
targetPort: 808013. 监控和日志
# Pod日志
kubectl logs <pod-name>
# 多容器Pod日志
kubectl logs <pod-name> -c <container-name>
# 实时日志
kubectl logs -f <pod-name>
# 之前容器的日志
kubectl logs <pod-name> --previous
# 所有Pod日志
kubectl logs -l app=myapp --all-containers=true# 安装metrics-server(Minikube)
minikube addons enable metrics-server
# 查看节点资源使用
kubectl top nodes
# 查看Pod资源使用
kubectl top pods
# 查看特定命名空间的资源
kubectl top pods -n production# 查看所有事件
kubectl get events
# 按时间排序
kubectl get events --sort-by=.metadata.creationTimestamp
# 查看特定资源的事件
kubectl describe pod <pod-name>14. 故障排查
# 查看Pod状态
kubectl get pods
# 查看Pod详情
kubectl describe pod <pod-name>
# 查看Pod日志
kubectl logs <pod-name>
# 进入Pod调试
kubectl exec -it <pod-name> -- /bin/bash
# 查看Pod事件
kubectl get events --field-selector involvedObject.name=<pod-name># 查看Service
kubectl get svc
kubectl describe svc <service-name>
# 查看Endpoints
kubectl get endpoints <service-name>
# 测试Service连接
kubectl run -it --rm debug --image=busybox --restart=Never -- wget -O- <service-name>:80问题1:Pod一直Pending
# 检查节点资源
kubectl describe node
# 检查PVC
kubectl get pvc
# 查看Pod事件
kubectl describe pod <pod-name>问题2:Pod一直CrashLoopBackOff
# 查看日志
kubectl logs <pod-name>
# 查看之前容器的日志
kubectl logs <pod-name> --previous
# 检查配置
kubectl describe pod <pod-name>问题3:Service无法访问
# 检查Service选择器
kubectl get svc <service-name> -o yaml
# 检查Pod标签
kubectl get pods --show-labels
# 检查Endpoints
kubectl get endpoints <service-name>15. 最佳实践
✅ 设置资源请求和限制
✅ 使用ResourceQuota限制命名空间资源
✅ 使用LimitRange设置默认限制
✅ 监控资源使用情况
✅ 使用Secret存储敏感信息
✅ 使用RBAC控制访问权限
✅ 定期更新镜像
✅ 使用网络策略限制网络访问
✅ 使用多个副本
✅ 配置健康检查
✅ 使用反亲和性分散Pod
✅ 配置PodDisruptionBudget
✅ 使用ConfigMap管理配置
✅ 使用Secret管理敏感信息
✅ 避免硬编码配置
✅ 使用环境变量或Volume挂载配置
✅ 使用Deployment管理应用
✅ 使用滚动更新策略
✅ 保留更新历史以便回滚
✅ 使用标签和选择器组织资源
16. 总结与进阶
通过本教程,你已经掌握了:
- ✅ Kubernetes核心概念
- ✅ Pod、Deployment、Service的使用
- ✅ ConfigMap和Secret管理
- ✅ Volume存储
- ✅ 常用命令和操作
- ✅ 实际应用部署
- ✅ 故障排查方法
高级特性
- StatefulSet:有状态应用
- DaemonSet:节点守护进程
- Job和CronJob:批处理任务
- Ingress:HTTP路由
网络
- NetworkPolicy:网络策略
- Service Mesh:Istio、Linkerd
- CNI插件:Calico、Flannel
存储
- StorageClass:动态存储
- CSI插件:云存储集成
安全
- RBAC:角色访问控制
- Pod Security Policy
- Network Policy
监控和可观测性
- Prometheus:指标监控
- Grafana:可视化
- ELK Stack:日志分析
CI/CD集成
- Jenkins
- GitLab CI
- GitHub Actions
- ArgoCD
- 官方文档:https://kubernetes.io/docs/
- Kubernetes中文社区:https://www.kubernetes.org.cn/
- Kubernetes实战:相关书籍和在线课程
- GitHub示例:https://github.com/kubernetes/examples
- 多练习:在本地环境多实践
- 做项目:部署实际应用
- 读源码:理解实现原理
- 参与社区:参与Kubernetes社区
结语
Kubernetes是一个功能强大的容器编排平台,掌握它对于现代DevOps和云原生开发至关重要。通过本教程的学习,相信你已经掌握了Kubernetes的基础知识。
记住:
- 多实践:理论结合实践,多部署应用
- 理解原理:理解Kubernetes的工作原理
- 关注最佳实践:遵循最佳实践
- 持续学习:Kubernetes在快速发展,持续学习新特性
祝你学习愉快,部署顺利! 🚀
本教程由Java突击队学习社区编写,如有问题欢迎反馈。