1854 字
9 分钟
云计算技术综合大作业
一、云计算资源
(一)计算资源
- 虚拟机资源(4台VMware虚拟机)
- 主控节点(K3s Server)
- IP:192.168.175.132
- 配置:2核CPU + 4GB内存 + 20GB存储
- 角色:运行K3s控制平面组件(API Server、Scheduler、Controller Manager)
- 工作节点(K3s Agent,3台)
- IP:192.168.175.136/137/138
- 配置:4核CPU + 8GB内存 + 50GB存储
- 角色:运行应用容器(Python服务、MySQL数据库)
- 主控节点(K3s Server)
- 容器资源(K3s集群)
- Python电商应用
- Pod数量:3个副本(可扩展至10+)
- 单Pod配置:1核CPU + 1GB内存 + 5GB存储
- 依赖:Flask框架、mysql-connector-python驱动
- MySQL数据库
- Pod数量:1个主节点
- 配置:2核CPU + 4GB内存 + 10GB持久存储
- Traefik入口控制器
- Pod数量:1个
- 配置:1核CPU + 512MB内存
- 监控系统(Prometheus+Grafana)
- Pod数量:2个
- 配置:2核CPU + 2GB内存 + 10GB存储
- Python电商应用
(二)存储资源
- 持久化存储
- MySQL数据卷
- 容量:10GB
- 类型:PersistentVolumeClaim(ReadWriteOnce)
- 用途:存储电商数据库数据
- 监控数据存储
- 容量:10GB(可选)
- 类型:本地存储或NFS共享
- MySQL数据卷
- 镜像与临时存储
- Docker Registry
- 本地镜像仓库:registry:2容器
- 存储量:根据镜像大小调整(Python镜像约200MB/个)
- 容器临时存储
- 每个Pod默认5GB(用于日志和临时文件)
- Docker Registry
(三)网络资源
- 集群网络配置
- IP地址规划
- 虚拟机内网:192.168.175.132-138(静态IP)
- Pod网络:K3s默认使用Flannel(10.42.0.0/16)
- IP地址规划
- 服务暴露方式
- NodePort:端口范围30000-32767(如电商服务端口30500)
- 负载均衡
- Traefik v2
- 功能:请求路由、SSL终止、限流
- 配置:监听80/443端口,绑定电商服务
- Traefik v2
二、详细搭建过程
(一)环境规划
首先,对四台虚拟机进行角色分配:
- 主控节点(Server):192.168.175.132
- 工作节点(Agent):192.168.175.136, 192.168.175.137, 192.168.175.138
- 主控节点将运行K3s的控制平面组件,工作节点负责运行应用程序和数据库容器。
(二)准备工作
在所有节点上执行以下操作:
- 更新系统
sudo apt update && sudo apt upgrade -y- 安装必要工具
sudo apt install -y curl apt-transport-https ca-certificates software-properties-common- 配置主机名 在每台机器上设置唯一的主机名:
# 主控节点sudo hostnamectl set-hostname k3s-server
# 工作节点1sudo hostnamectl set-hostname k3s-worker1
# 工作节点2sudo hostnamectl set-hostname k3s-worker2
# 工作节点3sudo hostnamectl set-hostname k3s-worker3- 配置hosts文件
在所有节点上编辑
/etc/hosts文件:
sudo nano /etc/hosts添加以下内容:
192.168.175.132 k3s-server192.168.175.136 k3s-worker1192.168.175.137 k3s-worker2192.168.175.138 k3s-worker3(三)安装Docker
在所有节点上安装Docker:
# 添加Docker官方GPG密钥curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# 添加Docker源echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# 安装Dockersudo apt update && sudo apt install -y docker-ce docker-ce-cli containerd.io
# 添加当前用户到docker组sudo usermod -aG docker $USER
# 重启Docker服务sudo systemctl restart docker
# 验证Docker安装docker --version(四)安装K3s主控节点
在192.168.175.132上执行以下命令:
curl -sfL https://get.k3s.io -o get_k3s.shchmod +x get_k3s.shcat get_k3s.sh
# 安装K3s主控节点sudo ./get_k3s.sh server --disable traefik --node-ip 192.168.175.132 --advertise-address 192.168.175.132
# 检查K3s服务状态sudo systemctl status k3s
# 获取节点token(用于添加工作节点)sudo cat /var/lib/rancher/k3s/server/node-token(五)安装K3s工作节点
在每台工作节点(192.168.175.136, 192.168.175.137, 192.168.175.138)上执行以下命令:
# 替换${NODE_TOKEN}为从主控节点获取的tokencurl -sfL https://get.k3s.io | K3S_URL=https://192.168.175.132:6443 K3S_TOKEN=${NODE_TOKEN} sh -s - agent --node-ip 192.168.175.XXX
# 检查K3s Agent服务状态sudo systemctl status k3s-agent(六)验证K3s集群
在主控节点上验证集群状态:
# 获取集群节点信息sudo kubectl get nodes(七)部署MySQL数据库
使用Helm在K3s集群上部署MySQL:
- 安装Helm
# 在主控节点上安装Helmcurl https://baltocdn.com/helm/signing.asc | sudo apt-key add -sudo apt-get install apt-transport-https --yesecho "deb https://baltocdn.com/helm/stable/debian/ all main" | sudo tee /etc/apt/sources.list.d/helm-stable-debian.listsudo apt-get updatesudo apt-get install helm- 添加MySQL Helm仓库并部署
# 添加Bitnami Helm仓库helm repo add bitnami https://charts.bitnami.com/bitnamihelm repo update
# 创建持久卷声明(PersistentVolumeClaim)cat > mysql-pvc.yaml << EOFapiVersion: v1kind: PersistentVolumeClaimmetadata: name: mysql-pvcspec: accessModes: - ReadWriteOnce resources: requests: storage: 10GiEOFkubectl apply -f mysql-pvc.yaml
# 使用Helm部署MySQLhelm install mysql bitnami/mysql \ --set primary.persistence.existingClaim=mysql-pvc \ --set auth.rootPassword=rootpassword \ --set auth.username=ecommerce \ --set auth.password=ecommercepassword \ --set auth.database=ecommerce_db \ --set volumePermissions.enabled=true \ --namespace mysql \ --create-namespace(八)部署电商网站应用
使用Python Flask作为示例应用:
- 创建应用部署文件
# 创建电商应用目录mkdir -p ecommerce-app && cd ecommerce-app
# 创建简单的Flask应用cat > app.py << EOFfrom flask import Flask, render_template, request, redirect, url_forimport mysql.connector
app = Flask(__name__)
# 数据库配置db_config = { 'host': 'mysql.mysql.svc.cluster.local', 'user': 'ecommerce', 'password': 'ecommercepassword', 'database': 'ecommerce_db'}
@app.route('/')def index(): return render_template('index.html')
if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)EOF
# 创建Dockerfilecat > Dockerfile << EOFFROM python:3.9-slimWORKDIR /appCOPY requirements.txt .RUN pip install --no-cache-dir -r requirements.txtCOPY . .EXPOSE 5000CMD ["python", "app.py"]EOF
# 创建requirements.txtcat > requirements.txt << EOFflaskmysql-connector-pythonEOF
# 创建templates目录和首页模板mkdir templatescat > templates/index.html << EOF<!DOCTYPE html><html><head> <title>电商网站</title></head><body> <h1>欢迎来到电商网站</h1> <p>这是一个基于K3s和Docker的高可用电商平台</p></body></html>EOF- 构建Docker镜像并推送到私有仓库
# 构建镜像docker build -t ecommerce-app:latest .
# 安装并启动本地Docker registrydocker run -d -p 5000:5000 --restart=always --name registry registry:2
# 标记并推送镜像docker tag ecommerce-app:latest localhost:5000/ecommerce-app:latestdocker push localhost:5000/ecommerce-app:latest- 创建Kubernetes部署和服务
cat > deployment.yaml << EOFapiVersion: apps/v1kind: Deploymentmetadata: name: ecommerce-app namespace: defaultspec: replicas: 3 selector: matchLabels: app: ecommerce-app template: metadata: labels: app: ecommerce-app spec: containers: - name: ecommerce-app image: localhost:5000/ecommerce-app:latest ports: - containerPort: 5000 env: - name: DB_HOST value: "mysql.mysql.svc.cluster.local" - name: DB_USER value: "ecommerce" - name: DB_PASSWORD value: "ecommercepassword" - name: DB_NAME value: "ecommerce_db"EOF
cat > service.yaml << EOFapiVersion: v1kind: Servicemetadata: name: ecommerce-service namespace: defaultspec: selector: app: ecommerce-app ports: - protocol: TCP port: 80 targetPort: 5000 type: LoadBalancerEOF
# 应用部署和服务kubectl apply -f deployment.yamlkubectl apply -f service.yaml(九)配置负载均衡和入口控制器
重新启用Traefik作为入口控制器:
# 安装Traefik入口控制器kubectl apply -fsudo kubectl create namespace traefikhelm repo add traefik https://traefik.github.io/chartshelm repo updatehelm install traefik traefik/traefik -n traefik
# 创建入口规则cat > ingress.yaml << EOFapiVersion: networking.k8s.io/v1kind: Ingressmetadata: name: ecommerce-ingress namespace: default annotations: kubernetes.io/ingress.class: "traefik"spec: rules: - host: ecommerce.example.com http: paths: - path: / pathType: Prefix backend: service: name: ecommerce-service port: number: 80EOF
# 应用入口规则sudo kubectl apply -f ingress.yaml(十)配置监控和日志系统
部署Prometheus和Grafana:
# 添加Prometheus社区Helm仓库helm repo add prometheus-community https://prometheus-community.github.io/helm-chartshelm repo update
# 部署Prometheus和Grafanahelm install prometheus prometheus-community/kube-prometheus-stack \ --namespace monitoring \ --create-namespace(十一)通过NodePort暴露Grafana服务
- 编辑Grafana服务配置
sudo kubectl -n monitoring edit service prometheus-grafana- 修改服务类型为NodePort
spec: clusterIP: 10.43.115.197 clusterIPs: - 10.43.115.197 internalTrafficPolicy: Cluster ipFamilies: - IPv4 ipFamilyPolicy: SingleStack ports: - name: http-web port: 80 protocol: TCP targetPort: 3000 nodePort: 31279 # 手动指定NodePort(30000-32767范围内) selector: app.kubernetes.io/instance: prometheus app.kubernetes.io/name: grafana sessionAffinity: None type: NodePort # 关键修改:将ClusterIP改为NodePort- 保存并验证
sudo kubectl -n monitoring get service prometheus-grafana- 访问Prometheus Web UI
# 获取节点IPip addr | grep inet | grep -v 127.0.0.1 | awk '{print $2}' | tr -d '\n'
# 访问地址http://192.168.175.132:31279(十二)通过NodePort暴露Prometheus服务
- 编辑Prometheus服务配置
sudo kubectl -n monitoring edit service prometheus-kube-prometheus-prometheus- 修改服务类型为NodePort
spec: clusterIP: 10.43.253.215 clusterIPs: - 10.43.253.215 externalTrafficPolicy: Cluster internalTrafficPolicy: Cluster ipFamilies: - IPv4 ipFamilyPolicy: SingleStack ports: - name: http-web nodePort: 32241 port: 9090 protocol: TCP targetPort: 9090 - appProtocol: http name: reloader-web nodePort: 31781 port: 8080 protocol: TCP targetPort: reloader-web selector: app.kubernetes.io/name: prometheus operator.prometheus.io/name: prometheus-kube-prometheus-prometheus sessionAffinity: None type: NodePort- 保存并验证
sudo kubectl -n monitoring get service prometheus-kube-prometheus-prometheus- 访问Prometheus Web UI
# 获取节点IPip addr | grep inet | grep -v 127.0.0.1 | grep -v inet6 | awk '{print $2}' | cut -d/ -f1
# 访问地址http://192.168.175.132:32241(十三)验证所有组件已正确部署
在主控节点上执行以下命令:
# 查看所有命名空间中的Podskubectl get pods --all-namespaces
# 查看服务kubectl get services --all-namespaces
# 查看入口kubectl get ingress --all-namespace