容器化运维工具(2)Kubernetes 详细教程(含图解)
一、Kubernetes 简介
Kubernetes(简称 K8s)是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。它旨在提供一个跨主机集群的容器调度、编排、高可用及自动化的平台,让开发者可以更专注于应用程序的开发,而无需过多关注底层基础设施的管理。
Kubernetes 具有强大的自愈能力、弹性伸缩、服务发现与负载均衡等特性,能够有效保障应用在复杂环境中的稳定运行。
图解 1:Kubernetes 作用示意
二、Kubernetes 核心组件
Kubernetes 集群由控制平面组件和节点组件组成,各组件协同工作以实现集群的各项功能。
(一)控制平面组件
- kube-apiserver:所有操作的统一入口,提供 RESTful API,是集群中各个组件之间通信的枢纽。
- etcd:集群数据的存储中心,保存着集群的所有状态信息。
- kube-scheduler:负责 Pod 的调度,根据预定的调度策略为 Pod 选择合适的节点。
- kube-controller-manager:运行各种控制器进程,如节点控制器、副本控制器等,确保集群的状态与期望状态一致。
- cloud-controller-manager:与云服务提供商集成,用于管理云服务相关的资源。
(二)节点组件
- kubelet:运行在每个节点上,确保容器按照 Pod 规范运行,负责与控制平面通信,汇报节点和容器的状态。
- kube-proxy:维护节点网络规则,实现 Pod 之间以及 Pod 与外部网络的通信。
- 容器运行时:负责运行容器,如 containerd、CRI-O 等,是 Kubernetes 与容器交互的接口。
图解 2:Kubernetes 核心组件架构
三、Kubernetes 安装方式
(一)使用 kubeadm 安装 Kubernetes 集群
前置条件
- 至少 2 台 Ubuntu/CentOS 服务器(1 台 master,1 台或多台 node)
- 每台服务器至少 2GB 内存,2 个 CPU
- 服务器之间可以相互通信
- 禁用 swap
- 安装容器运行时(如 containerd)
在所有节点上执行
1. 禁用 swap:
sudo swapoff -a
# 永久禁用 swap(重启生效)
sudo sed -i '/swap/s/^/#/' /etc/fstab
2. 安装 containerd:
sudo apt-get update && sudo apt-get install -y containerd
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml
sudo systemctl restart containerd
3. 安装 kubeadm、kubelet 和 kubectl:
sudo apt-get update && sudo apt-get install -y apt-transport-https ca-certificates curl
sudo curl -fsSLo /usr/share/keyrings/kubernetes-archive-keyring.gpg https://packages.cloud.google.com/apt/doc/apt-key.gpg
echo "deb [signed-by=/usr/share/keyrings/kubernetes-archive-keyring.gpg] https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
在 master 节点上执行
1. 初始化集群:
sudo kubeadm init --pod-network-cidr=10.244.0.0/16
2. 配置 kubectl
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
3. 安装网络插件(这里使用 flannel):
kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/v0.17.0/Documentation/kube-flannel.yml
在 worker 节点上执行
使用 kubeadm init 输出的 kubeadm join 命令,例如:
sudo kubeadm join 192.168.1.100:6443 --token abcdef.0123456789abcdef \--discovery-token-ca-cert-hash sha256:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef
如果忘记了 join 命令,可以在 master 节点上执行:
kubeadm token create --print-join-command
图解 3:kubeadm 安装集群流程
(二)安装 Minikube(单节点测试环境)
1. 安装 Minikube:
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
2. 启动 Minikube:
minikube start
3. 验证集群状态:
minikube status
图解 4:Minikube 安装流程
四、kubectl 常用命令
kubectl 是 Kubernetes 的命令行工具,用于与 Kubernetes 集群进行交互。
1. 查看集群信息:
kubectl cluster-info
2. 查看节点:
kubectl get nodes
kubectl get nodes -o wide
3. 查看命名空间:
kubectl get namespaces
4. 查看所有资源:
kubectl get all --all-namespaces
5. 查看 Pod:
kubectl get pods
kubectl get pods -n <namespace>
6. 查看 Deployment:
kubectl get deployments
7. 查看 Service:
kubectl get services
8. 查看日志:
kubectl logs <pod-name>
kubectl logs -f <pod-name> # 实时查看日志
9. 进入 Pod:
kubectl exec -it <pod-name> -- /bin/bash
10. 描述资源:
kubectl describe pod <pod-name>
kubectl describe deployment <deployment-name>
11. 创建资源:
kubectl create -f <yaml-file>
12. 应用资源配置:
kubectl apply -f <yaml-file>
13. 删除资源:
kubectl delete pod <pod-name>
kubectl delete -f <yaml-file>
图解 5:kubectl 命令分类
五、核心资源对象
(一)Pod
Pod 是 Kubernetes 最小的部署单元,包含一个或多个容器,这些容器共享网络和存储资源。
创建 pod.yaml:
apiVersion: v1
kind: Pod
metadata:name: my-podlabels:app: my-app
spec:containers:- name: my-containerimage: nginx:alpineports:- containerPort: 80resources:requests:memory: "64Mi"cpu: "250m"limits:memory: "128Mi"cpu: "500m"
应用配置:
kubectl apply -f pod.yaml
图解 6:Pod 结构示意
(二)Deployment
Deployment 用于管理 Pod 的创建和扩展,确保指定数量的 Pod 副本运行,并支持滚动更新和回滚。
创建 deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:name: my-deployment
spec:replicas: 3selector:matchLabels:app: my-apptemplate:metadata:labels:app: my-appspec:containers:- name: my-containerimage: nginx:alpineports:- containerPort: 80
应用配置:
kubectl apply -f deployment.yaml
图解 7:Deployment 与 Pod 关系
(三)Service
Service 为 Pod 提供稳定的网络访问点,实现 Pod 之间的通信,即使 Pod 发生重建,Service 也能通过标签选择器找到新的 Pod。
创建 service.yaml:
apiVersion: v1
kind: Service
metadata:name: my-service
spec:selector:app: my-appports:- port: 80targetPort: 80type: NodePort
应用配置:
kubectl apply -f service.yaml
图解 8:Service 工作原理
(四)ConfigMap 和 Secret
ConfigMap 用于存储非敏感的配置信息,Secret 用于存储敏感信息,如密码、密钥等。
创建 configmap.yaml:
apiVersion: v1
kind: ConfigMap
metadata:name: my-config
data:app.properties: |environment=productionlog_level=infomax_connections: "100"
创建 secret.yaml:
apiVersion: v1
kind: Secret
metadata:name: my-secret
type: Opaque
data:username: YWRtaW4= # base64 编码的 "admin"password: cGFzc3dvcmQ= # base64 编码的 "password"
应用配置:
kubectl apply -f configmap.yaml
kubectl apply -f secret.yaml
在 Pod 中使用:
apiVersion: v1
kind: Pod
metadata:name: app-pod
spec:containers:- name: app-containerimage: my-app-imageenv:- name: DB_USERNAMEvalueFrom:secretKeyRef:name: my-secretkey: username- name: LOG_LEVELvalueFrom:configMapKeyRef:name: my-configkey: log_levelvolumeMounts:- name: config-volumemountPath: /etc/configvolumes:- name: config-volumeconfigMap:name: my-config
图解 9:ConfigMap 和 Secret 在 Pod 中的使用
六、存储配置
(一)PersistentVolume 和 PersistentVolumeClaim
PersistentVolume(PV)是集群中的一块存储,由管理员配置;PersistentVolumeClaim(PVC)是用户对存储的请求,PVC 可以绑定到 PV 上,实现存储的动态分配。
创建 pv.yaml:
apiVersion: v1
kind: PersistentVolume
metadata:name: my-pv
spec:capacity:storage: 10GiaccessModes:- ReadWriteOncepersistentVolumeReclaimPolicy: RetainhostPath:path: /data/my-pv
创建 pvc.yaml:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: my-pvc
spec:accessModes:- ReadWriteOnceresources:requests:storage: 5Gi
在 Pod 中使用:
apiVersion: v1
kind: Pod
metadata:name: pv-pod
spec:containers:- name: pv-containerimage: nginxvolumeMounts:- name: pv-storagemountPath: /datavolumes:- name: pv-storagepersistentVolumeClaim:claimName: my-pvc
图解 10:PV、PVC 与 Pod 关系
七、实际应用部署案例
部署一个完整的 Web 应用(前端 + 后端 + 数据库):
1. 创建 mysql-secret.yaml(存储 MySQL 密码):
apiVersion: v1
kind: Secret
metadata:name: mysql-secret
type: Opaque
data:root-password: cGFzc3dvcmQxMjM= # base64编码的"password123"
2. 创建 mysql-pv.yaml:
apiVersion: v1
kind: PersistentVolume
metadata:name: mysql-pv
spec:capacity:storage: 20GiaccessModes:- ReadWriteOncepersistentVolumeReclaimPolicy: RetainhostPath:path: /data/mysql-pv
3. 创建 mysql-pvc.yaml:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: mysql-pvc
spec:accessModes:- ReadWriteOnceresources:requests:storage: 10Gi
4. 创建 mysql-deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:name: mysql
spec:replicas: 1selector:matchLabels:app: mysqltemplate:metadata:labels:app: mysqlspec:containers:- name: mysqlimage: mysql:5.7env:- name: MYSQL_ROOT_PASSWORDvalueFrom:secretKeyRef:name: mysql-secretkey: root-password- name: MYSQL_DATABASEvalue: myappdbports:- containerPort: 3306volumeMounts:- name: mysql-storagemountPath: /var/lib/mysqlvolumes:- name: mysql-storagepersistentVolumeClaim:claimName: mysql-pvc
---
apiVersion: v1
kind: Service
metadata:name: mysql-service
spec:selector:app: mysqlports:- port: 3306targetPort: 3306clusterIP: None # Headless service
5. 创建 backend-deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:name: backend
spec:replicas: 2selector:matchLabels:app: backendtemplate:metadata:labels:app: backendspec:containers:- name: backendimage: my-backend-image:latestenv:- name: DB_HOSTvalue: mysql-service- name: DB_USERvalue: root- name: DB_PASSWORDvalueFrom:secretKeyRef:name: mysql-secretkey: root-passwordports:- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:name: backend-service
spec:selector:app: backendports:- port: 8080targetPort: 8080
6. 创建 frontend-deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:name: frontend
spec:replicas: 2selector:matchLabels:app: frontendtemplate:metadata:labels:app: frontendspec:containers:- name: frontendimage: my-frontend-image:latestports:- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:name: frontend-service
spec:selector:app: frontendports:- port: 80targetPort: 80type: LoadBalancer
7. 应用所有配置:
kubectl apply -f mysql-secret.yaml
kubectl apply -f mysql-pv.yaml
kubectl apply -f mysql-pvc.yaml
kubectl apply -f mysql-deployment.yaml
kubectl apply -f backend-deployment.yaml
kubectl apply -f frontend-deployment.yaml
图解 11:完整 Web 应用部署架构
图解 12:Kubernetes 多环境部署架构图
八、Kubernetes 常见问题及解决方法
(一)节点状态为 NotReady
- 问题现象:执行 kubectl get nodes 显示节点状态为 NotReady。
- 可能原因:网络插件未安装或运行异常、kubelet 服务未启动、节点资源不足。
- 解决方法:
- 检查网络插件状态,如 flannel 插件:kubectl get pods -n kube-system | grep flannel。
- 重启 kubelet 服务:sudo systemctl restart kubelet。
- 检查节点资源使用情况,确保内存和 CPU 未耗尽。
(二)Pod 处于 Pending 状态
- 问题现象:Pod 长时间处于 Pending 状态,不调度到节点。
- 可能原因:节点资源不足、节点亲和性设置不当、没有满足条件的节点。
- 解决方法:
- 查看 Pod 事件:kubectl describe pod <pod-name> 寻找具体原因。
- 检查节点资源是否充足:kubectl top nodes。
- 调整 Pod 的资源请求或节点亲和性配置。
(三)Service 无法访问 Pod
- 问题现象:通过 Service 无法访问后端 Pod。
- 可能原因:Service 选择器与 Pod 标签不匹配、Pod 未就绪、网络策略限制。
- 解决方法:
- 检查 Service 选择器和 Pod 标签是否一致:kubectl get service <service-name> -o yaml 和 kubectl get pods --show-labels。
- 查看 Pod 状态是否为 Running 且就绪:kubectl get pods。
- 检查是否有网络策略阻止访问:kubectl get networkpolicy。
九、总结
Kubernetes 作为容器编排领域的主流工具,为大规模容器化应用的管理提供了强大的支持。本文详细介绍了 Kubernetes 的核心组件、安装方式、kubectl 命令、核心资源对象、存储配置、实际应用部署案例以及常见问题解决方法,并通过 Mermaid 图解直观展示了相关概念和架构。
掌握 Kubernetes 需要不断实践,在实际使用中深入理解其设计理念和工作原理,才能更好地应对复杂的容器管理场景,充分发挥其自动化、高可用、可扩展的优势,为应用的稳定运行提供有力保障。