Sealos实战:从零开始部署和管理Kubernetes集群
概述
本文档详细介绍了如何使用Sealos在多台服务器上部署和管理Kubernetes集群,包括环境准备、集群部署、应用部署、配置管理、扩容、容灾、升级和回滚等完整运维流程。我们将以三台服务器为例,展示从零开始构建到运维整个Kubernetes集群的完整过程。
1. 环境准备
1.1 服务器规划
我们使用三台服务器作为示例:
- Master节点(控制平面):192.168.1.100
- Worker节点1:192.168.1.101
- Worker节点2:192.168.1.102
1.2 前提条件
在所有服务器上准备以下环境:
- 操作系统:Ubuntu 20.04 LTS 或 CentOS 8.x
- 硬件配置:
- CPU:至少2核
- 内存:至少4GB
- 磁盘:至少40GB
- 网络配置:
- 服务器之间网络互通
- 关闭防火墙或开放必要端口
- SSH访问:确保可以从任一节点SSH到其他节点
1.3 系统准备命令
在所有节点上执行以下命令:
# 关闭防火墙(生产环境建议配置具体规则) |
2. 安装Sealos
在Master节点(192.168.1.100)上安装Sealos:
# 安装sealos |
3. 创建Clusterfile定义集群
创建一个名为Clusterfile的文件来定义集群配置:
apiVersion: apps.sealos.io/v1beta1 |
这个配置文件定义了:
- 使用Kubernetes v1.25.0版本
- 使用Calico作为CNI网络插件
- 一台Master节点和两台Worker节点
4. 部署Kubernetes集群
在Master节点上运行以下命令部署集群:
# 使用Clusterfile部署集群 |
部署完成后,Sealos会:
- 安装Kubernetes组件
- 配置etcd集群
- 初始化Master节点
- 加入Worker节点
- 配置网络插件Calico
验证集群状态:
# 如果sealos自动配置了kubectl |
预期输出:
NAME STATUS ROLES AGE VERSION |
5. 理解Pod和Node的分配机制
5.1 Node(节点)
Node是集群中的工作机器(物理机或虚拟机),负责运行Pod。在我们的例子中:
- 192.168.1.100:Master节点,具有控制平面角色
- 192.168.1.101和192.168.1.102:Worker节点,用于运行工作负载
5.2 Pod(容器组)
Pod是Kubernetes中最小的部署单元,通常包含一个或多个紧密相关的容器。
5.3 调度机制
Kubernetes调度器(kube-scheduler)负责决定Pod在哪个Node上运行。它考虑以下因素:
- 资源需求:CPU、内存等
- 节点标签(Labels)和节点选择器(Node Selector)
- 污点(Taints)和容忍度(Tolerations)
- 亲和性(Affinity)和反亲和性(Anti-Affinity)
6. 部署应用到集群
6.1 准备Docker镜像
假设我们有一个名为my-web-app:latest的Docker镜像,包含一个简单的Web应用。
首先,确保镜像在所有节点上都可用:
# 在所有节点上拉取镜像 |
6.2 创建应用部署配置
创建一个名为web-app-deployment.yaml的文件:
apiVersion: apps/v1 |
6.3 通过Sealos部署应用
使用Sealos可以创建应用包来部署应用,也可以使用kubectl直接应用YAML配置:
方法1:使用kubectl
# 应用YAML配置 |
方法2:使用Sealos应用包
首先创建应用包(Application Package):
# 创建应用包目录结构 |
7. 配置参数注入
7.1 通过ConfigMap注入配置
创建一个ConfigMap来存储配置参数:
# 创建ConfigMap |
更新Deployment以使用ConfigMap:
apiVersion: apps/v1 |
7.2 通过Secret注入敏感配置
创建一个Secret来存储敏感信息(如密码、密钥):
# 创建Secret |
更新Deployment以使用Secret:
apiVersion: apps/v1 |
8. 节点扩容
8.1 扩容Worker节点
当需要增加Worker节点来提供更多的计算资源时:
- 在新的服务器上准备环境(按照1.3节的系统准备命令)
- 使用Sealos添加节点:
# 添加新的Worker节点 |
8.2 扩容应用Pod
增加应用的副本数:
# 扩容到5个副本 |
9. 容灾策略
9.1 高可用Master节点
为避免Master节点单点故障,我们可以部署高可用集群:
# 使用三个Master节点部署高可用集群 |
9.2 备份和恢复
定期备份etcd数据和Kubernetes清单:
# 备份etcd |
9.3 健康检查和监控
配置Liveness和Readiness探针:
apiVersion: apps/v1 |
10. 应用升级和回滚
10.1 应用升级
滚动更新
使用滚动更新策略进行应用升级:
# 更新部署的镜像 |
使用Helm进行升级(可选)
如果使用Helm管理应用:
# 更新Helm Chart |
10.2 升级失败回滚
如果新版本出现问题,可以快速回滚:
# 查看升级历史 |
10.3 集群升级
升级整个Kubernetes集群:
# 使用Sealos升级集群 |
11. 实战案例总结
通过以上步骤,我们完成了一个完整的Sealos实战流程:
- 环境准备:在三台服务器上配置系统环境
- 集群部署:使用Sealos快速部署Kubernetes集群
- 应用部署:将Docker镜像部署到集群中
- 配置管理:通过ConfigMap和Secret注入配置参数
- 节点扩容:添加新的Worker节点和应用Pod
- 容灾策略:配置高可用、备份和健康检查
- 升级回滚:实现应用和集群的升级与回滚
这种基于Sealos的部署方式大大简化了Kubernetes集群的部署和管理复杂度,使得运维团队可以更专注于应用本身,而不是基础设施的复杂性。
12. Kubernetes核心概念和术语
在深入了解问题排查之前,让我们先梳理Kubernetes的层级结构和核心概念,从大到小排列:
12.1 集群(Cluster)
- 定义:由一个或多个节点组成的容器化应用平台
- 实际例子:我们前面创建的名为
my-cluster的Kubernetes集群 - 映射:一个完整的Kubernetes环境,包含控制平面和工作节点
- 对应命令:
# 查看集群信息
kubectl cluster-info
# 检查集群组件状态
kubectl get componentstatuses
# 查看集群节点
kubectl get nodes
# 查看集群版本信息
kubectl version
# 检查集群健康状况
kubectl top nodes
12.2 命名空间(Namespace)
- 定义:集群中的虚拟子分区,用于隔离资源
- 实际例子:default、kube-system、kube-public等
- 映射:类似于操作系统的文件夹,用于组织和隔离不同环境的资源
- 对应命令:
# 查看所有命名空间
kubectl get namespaces
# 创建命名空间
kubectl create namespace my-namespace
# 在指定命名空间中操作资源
kubectl get pods -n my-namespace
# 查看命名空间详细信息
kubectl describe namespace my-namespace
12.3 节点(Node)
- 定义:集群中的工作机器,可以是物理机或虚拟机
- 实际例子:我们使用的三台服务器(192.168.1.100、192.168.1.101、192.168.1.102)
- 映射:192.168.1.100(Master节点)、192.168.1.101和192.168.1.102(Worker节点)
- 对应命令:
# 查看所有节点
kubectl get nodes
# 查看节点详细信息
kubectl describe node <node-name>
# 查看节点资源使用情况
kubectl top nodes
# 标记节点不可调度
kubectl cordon <node-name>
# 标记节点可调度
kubectl uncordon <node-name>
# 安全驱逐节点上的Pod(用于维护)
kubectl drain <node-name> --ignore-daemonsets
# 查看节点事件
kubectl get events --field-selector involvedObject.kind=Node
12.4 Pod
- 定义:Kubernetes中最小的部署单元,可包含一个或多个紧密相关的容器
- 实际例子:my-web-app-7d5b9c8f4c-xyz12 这个Pod
- 映射:一个逻辑主机,包含一个或多个共享存储、网络和规格定义的容器
- 深入理解:
- Pod不是Docker Compose服务组:一个Pod通常对应一个应用实例,而不是多个相关服务
- 紧密相关容器:Pod中的多个容器需要共享存储和网络,协同完成一个任务
- 例如:主应用容器 + 日志收集容器(如Filebeat)
- 例如:主应用容器 + 代理容器(如Envoy)
- 例如:主应用容器 + Sidecar容器(如Istio Proxy)
- 共享资源:
- 网络:Pod内所有容器共享IP地址和端口空间
- 存储:Pod内所有容器可以共享存储卷
- 生命周期:Pod中的容器一起启动、停止和重启
- Docker Compose到Kubernetes的映射:
- Docker Compose中的一个服务 → Kubernetes中的一个Pod
- Docker Compose中的多个服务 → Kubernetes中的多个Pod + Service
- 对应命令:
# 查看Pod
kubectl get pods -n <namespace>
# 查看Pod详细信息
kubectl describe pod <pod-name> -n <namespace>
# 查看Pod日志
kubectl logs <pod-name> -n <namespace>
# 实时查看Pod日志
kubectl logs -f <pod-name> -n <namespace>
# 进入Pod容器
kubectl exec -it <pod-name> -n <namespace> -- bash
# 查看Pod YAML配置
kubectl get pod <pod-name> -n <namespace> -o yaml
# 删除Pod(Deployment会自动重建)
kubectl delete pod <pod-name> -n <namespace>
# 查看Pod资源使用情况
kubectl top pods -n <namespace>
12.5 容器(Container)
- 定义:运行应用的轻量级虚拟化环境
- 实际例子:my-web-app Pod中的web-container
- 映射:Docker容器,运行具体的应用程序
- 对应命令:
# 查看Pod中的容器
kubectl get pods -n <namespace> -o jsonpath='{.items[*].spec.containers[*].name}'
# 查看特定容器的日志
kubectl logs <pod-name> -c <container-name> -n <namespace>
# 进入特定容器
kubectl exec -it <pod-name> -c <container-name> -n <namespace> -- bash
# 查看容器镜像
kubectl get pods -n <namespace> -o jsonpath='{.items[*].spec.containers[*].image}'
# 查看容器资源限制
kubectl describe pod <pod-name> -n <namespace>
12.6 服务(Service)
- 定义:定义一组Pod的逻辑集合和访问策略,提供稳定的网络端点
- 实际例子:my-web-app-service,为my-web-app的Pod提供稳定的访问地址
- 映射:类似负载均衡器或代理,为一组Pod提供稳定的IP和DNS名称
- 深入理解:
- 服务发现:通过标签选择器(label selector)发现后端Pod
- 负载均衡:在后端Pod间分发流量,但不使用传统负载均衡算法
- 稳定端点:即使Pod被重新调度,Service的IP和DNS名称保持不变
- 服务类型:
- ClusterIP:仅在集群内部访问
- NodePort:在集群节点上开放端口
- LoadBalancer:创建外部负载均衡器
- ExternalName:将服务映射到外部DNS名称
- 与Docker Compose的映射:
- Docker Compose服务间的连接 → Kubernetes中使用Service
- Docker Compose的links功能 → Kubernetes中使用Service DNS名称
- 对应命令:
# 查看服务
kubectl get services -n <namespace>
# 查看服务详细信息
kubectl describe service <service-name> -n <namespace>
# 查看服务端点(后端Pod IP)
kubectl get endpoints <service-name> -n <namespace>
# 查看服务YAML配置
kubectl get service <service-name> -n <namespace> -o yaml
# 测试服务连通性
kubectl run test-pod --image=busybox --rm -it --restart=Never -- nslookup <service-name>.<namespace>.svc.cluster.local
# 端口转发到服务
kubectl port-forward service/<service-name> 8080:80 -n <namespace>
12.7 控制器(Controller)
- 定义:确保Pod按照预期状态运行的资源对象
- 实际例子:Deployment、StatefulSet、DaemonSet等
- 映射:Deployment控制器确保my-web-app始终有2个副本运行
- 深入理解:
- 控制器类型:
- Deployment:管理无状态应用,支持滚动更新和回滚
- StatefulSet:管理有状态应用,提供稳定的网络标识和持久存储
- DaemonSet:确保所有节点运行一个Pod副本
- Job/CronJob:管理一次性任务和定时任务
- Pod调度与容灾:
- 通过污点(Taints)和容忍度(Tolerations)控制Pod调度到特定节点
- 通过节点亲和性(Node Affinity)和反亲和性(Node Anti-Affinity)控制Pod部署位置
- 通过Pod反亲和性避免相同应用的Pod运行在同一节点上,实现容灾
- 与Docker Compose的映射:
- Docker Compose的replicas → Kubernetes中的Deployment replicas
- Docker Compose的restart policy → Kubernetes的Pod重启策略
- 控制器类型:
- 对应命令:
# 查看Deployment
kubectl get deployments -n <namespace>
# 查看Deployment详细信息
kubectl describe deployment <deployment-name> -n <namespace>
# 扩容Deployment
kubectl scale deployment <deployment-name> --replicas=5 -n <namespace>
# 更新Deployment镜像
kubectl set image deployment/<deployment-name> <container-name>=<new-image> -n <namespace>
# 查看Deployment升级历史
kubectl rollout history deployment <deployment-name> -n <namespace>
# 回滚Deployment
kubectl rollout undo deployment <deployment-name> -n <namespace>
# 暂停/恢复Deployment rollout
kubectl rollout pause deployment <deployment-name> -n <namespace>
kubectl rollout resume deployment <deployment-name> -n <namespace>
# 查看控制器管理的Pod
kubectl get pods -l <label-key>=<label-value> -n <namespace>
12.8 配置和存储资源
- ConfigMap:存储非敏感配置数据
- Secret:存储敏感数据如密码、密钥
- PersistentVolume/PersistentVolumeClaim:提供持久化存储
- 对应命令:
# ConfigMap命令
# 查看ConfigMap
kubectl get configmaps -n <namespace>
# 查看ConfigMap详细信息
kubectl describe configmap <configmap-name> -n <namespace>
# 创建ConfigMap
kubectl create configmap <configmap-name> --from-literal=key1=value1 --from-literal=key2=value2 -n <namespace>
# 从文件创建ConfigMap
kubectl create configmap <configmap-name> --from-file=config.properties -n <namespace>
# Secret命令
# 查看Secret
kubectl get secrets -n <namespace>
# 查看Secret详细信息
kubectl describe secret <secret-name> -n <namespace>
# 创建Secret
kubectl create secret generic <secret-name> --from-literal=key1=value1 -n <namespace>
# 从文件创建Secret
kubectl create secret generic <secret-name> --from-file=ssh-privatekey=/path/to/key -n <namespace>
# 查看Secret内容(编码后的)
kubectl get secret <secret-name> -n <namespace> -o yaml
# PersistentVolume/PersistentVolumeClaim命令
# 查看PersistentVolume
kubectl get pv
# 查看PersistentVolumeClaim
kubectl get pvc -n <namespace>
# 查看PersistentVolume详细信息
kubectl describe pv <pv-name>
# 查看PersistentVolumeClaim详细信息
kubectl describe pvc <pvc-name> -n <namespace>
13. 常见问题排查
在运维Kubernetes集群和应用时,掌握常见问题排查方法非常重要。以下是几个关键的排查入口和技巧:
13.1 从集群状态开始排查
首先检查集群整体状态:
# 检查节点状态 |
12.2 检查Pod状态和事件
Pod是最基本的部署单元,是排查问题的起点:
# 查看Pod状态 |
12.3 查看应用日志
查看应用容器的日志是排查问题的重要手段:
# 查看Pod中主容器的日志 |
12.4 进入容器调试
当需要直接进入容器内部进行调试时:
# 进入容器执行交互式命令 |
12.5 检查资源使用情况
查看Pod和节点的资源使用情况:
# 查看Pod的资源使用情况 |
12.6 检查服务和网络
排查服务访问和网络连接问题:
# 查看服务状态 |
12.7 检查配置和密钥
验证配置和密钥是否正确挂载到Pod中:
# 查看ConfigMap内容 |
12.8 排查常见问题
Pod处于Pending状态
- 检查是否有足够的资源
- 检查节点选择器和污点容忍度配置
Pod处于CrashLoopBackOff状态
- 查看容器日志
- 检查启动脚本和配置
- 检查资源限制是否过小
Pod处于ImagePullBackOff状态
- 检查镜像名称和标签是否正确
- 检查镜像仓库访问权限
服务无法访问
- 检查Service和Pod的标签选择器是否匹配
- 检查端口配置是否正确
- 验证网络策略是否有误
12.9 使用Sealos排查集群问题
# 检查Sealos集群状态 |
13. 最佳实践
- 安全:始终使用RBAC控制访问权限,定期更新证书和密钥
- 监控:部署Prometheus和Grafana等监控工具
- 日志:使用EFK(Elasticsearch, Fluentd, Kibana)收集和分析日志
- 备份:定期备份重要数据和配置
- 网络策略:配置网络策略以限制Pod间通信
- 资源管理:使用ResourceQuota和LimitRange控制资源使用
通过遵循这些最佳实践,可以构建一个安全、可靠、高效且易于维护的Kubernetes集群。