基于k3s部署Nginx、MySQL、SpringBoot和Redis的詳細(xì)教程

1. 安裝k3s集群

1.1 單節(jié)點快速部署

# 使用root或sudo權(quán)限執(zhí)行
curl -sfL https://get.k3s.io | sh -

# 驗證安裝
sudo kubectl get nodes  # 輸出應(yīng)為Ready狀態(tài)
sudo systemctl status k3s

1.2 配置kubectl權(quán)限(可選)

mkdir -p ~/.kube
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown $USER ~/.kube/config
export KUBECONFIG=~/.kube/config

2. 部署MySQL數(shù)據(jù)庫

2.1 創(chuàng)建持久化存儲卷

# mysql-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mysql-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 5Gi  # 生產(chǎn)環(huán)境建議10Gi以上
kubectl apply -f mysql-pvc.yaml

2.2 創(chuàng)建數(shù)據(jù)庫密碼Secret

kubectl create secret generic mysql-secret \
  --from-literal=root_password=your_secure_password \
  --from-literal=database=springdb

2.3 部署MySQL

# mysql-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql-deployment
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: root_password
            - name: MYSQL_DATABASE
              valueFrom:
                secretKeyRef:
                  name: mysql-secret
                  key: database
          ports:
            - containerPort: 3306
          volumeMounts:
            - mountPath: /var/lib/mysql
              name: mysql-data
      volumes:
        - name: mysql-data
          persistentVolumeClaim:
            claimName: mysql-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: mysql-service
spec:
  selector:
    app: mysql
  ports:
    - port: 3306
      targetPort: 3306
  type: ClusterIP
kubectl apply -f mysql-deployment.yaml

3. 部署Redis緩存

3.1 創(chuàng)建Redis持久化存儲

# redis-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: redis-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 2Gi
kubectl apply -f redis-pvc.yaml

3.2 部署Redis

# redis-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
        - name: redis
          image: redis:7.0-alpine
          command: ["redis-server", "--appendonly yes"]  # 啟用持久化
          ports:
            - containerPort: 6379
          volumeMounts:
            - mountPath: /data
              name: redis-data
      volumes:
        - name: redis-data
          persistentVolumeClaim:
            claimName: redis-pvc
---
apiVersion: v1
kind: Service
metadata:
  name: redis-service
spec:
  selector:
    app: redis
  ports:
    - port: 6379
      targetPort: 6379
  type: ClusterIP
kubectl apply -f redis-deployment.yaml

4. 部署SpringBoot應(yīng)用

4.1 準(zhǔn)備SpringBoot Docker鏡像

  1. 示例application.properties

    spring.datasource.url=jdbc:mysql://mysql-service:3306/${MYSQL_DATABASE}
    spring.datasource.username=root
    spring.datasource.password=${MYSQL_ROOT_PASSWORD}
    spring.redis.host=redis-service
    spring.redis.port=6379
    
  2. Dockerfile

    FROM maven:3.8.6-jdk-11 AS build
    WORKDIR /app
    COPY . .
    RUN mvn clean package -DskipTests
    
    FROM openjdk:11-jre-slim
    COPY --from=build /app/target/*.jar /app.jar
    ENTRYPOINT ["java","-jar","/app.jar"]
    
  3. 構(gòu)建并推送鏡像

    docker build -t yourusername/springboot-app:v1 .
    docker push yourusername/springboot-app:v1
    

4.2 部署SpringBoot到k3s

# springboot-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: springboot-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: springboot
  template:
    metadata:
      labels:
        app: springboot
    spec:
      containers:
        - name: springboot
          image: yourusername/springboot-app:v1
          ports:
            - containerPort: 8080
          env:
            - name: MYSQL_ROOT_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: mysql-secret
                  key: root_password
            - name: MYSQL_DATABASE
              valueFrom:
                secretKeyRef:
                  name: mysql-secret
                  key: database
          livenessProbe:
            httpGet:
              path: /actuator/health
              port: 8080
            initialDelaySeconds: 30
            periodSeconds: 10
          readinessProbe:
            httpGet:
              path: /actuator/health
              port: 8080
---
apiVersion: v1
kind: Service
metadata:
  name: springboot-service
spec:
  selector:
    app: springboot
  ports:
    - port: 8080
      targetPort: 8080
  type: ClusterIP
kubectl apply -f springboot-deployment.yaml

5. 部署Nginx反向代理

5.1 創(chuàng)建Nginx配置文件

# nginx-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-config
data:
  default.conf: |
    server {
        listen 80;
        server_name localhost;

        location / {
            proxy_pass http://springboot-service:8080;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }
kubectl apply -f nginx-config.yaml

5.2 部署Nginx

# nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:alpine
          ports:
            - containerPort: 80
          volumeMounts:
            - mountPath: /etc/nginx/conf.d
              name: nginx-config
      volumes:
        - name: nginx-config
          configMap:
            name: nginx-config
---
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
    - port: 80
      targetPort: 80
  type: NodePort  # 或LoadBalancer
kubectl apply -f nginx-deployment.yaml

6. 驗證部署

6.1 檢查所有組件狀態(tài)

kubectl get pods,svc,pvc
# 輸出示例:
# NAME                                       READY   STATUS    RESTARTS   AGE
# pod/mysql-deployment-7c6d8f8b4d-abcde      1/1     Running   0          5m
# pod/redis-deployment-7d5f8d4b5f-fghij      1/1     Running   0          4m
# pod/springboot-deployment-6d5f8d4b5f-klmno 2/2     Running   0          3m
# pod/nginx-deployment-7c6d8f8b4d-pqrst      1/1     Running   0          2m

6.2 訪問SpringBoot應(yīng)用

# 獲取NodePort
NODE_PORT=$(kubectl get svc nginx-service -o jsonpath='{.spec.ports[0].nodePort}')
curl http://<節(jié)點IP>:$NODE_PORT
# 預(yù)期輸出:SpringBoot應(yīng)用的響應(yīng)(如"Hello World")

7. 擴(kuò)展與維護(hù)

7.1 橫向擴(kuò)展SpringBoot

kubectl scale deployment springboot-deployment --replicas=3

7.2 更新應(yīng)用版本

  1. 修改代碼后重新構(gòu)建鏡像:

    docker build -t yourusername/springboot-app:v2 .
    docker push yourusername/springboot-app:v2
    
  2. 滾動更新:

    kubectl set image deployment/springboot-deployment springboot=yourusername/springboot-app:v2
    

8. 關(guān)鍵配置說明

組件 核心配置項 作用說明
MySQL persistentVolumeClaim 數(shù)據(jù)持久化存儲
Redis command: ["redis-server", "--appendonly yes"] 啟用AOF持久化
SpringBoot livenessProbereadinessProbe 健康檢查確保服務(wù)可用性
Nginx proxy_pass http://springboot-service 反向代理到Java應(yīng)用

附:常見問題排查

  1. SpringBoot無法連接MySQL

    • 檢查Secret中的密碼是否匹配:

      kubectl get secret mysql-secret -o jsonpath='{.data.root_password}' | base64 -d
      
    • 查看SpringBoot日志:

      kubectl logs -f <springboot-pod>
      
  2. Nginx返回502錯誤

    • 確認(rèn)SpringBoot服務(wù)是否就緒:

      kubectl get endpoints springboot-service
      
  3. 數(shù)據(jù)持久化失敗

    • 檢查PVC綁定狀態(tài):

      kubectl get pvc
      
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容