Minikube 部署 Laravel + Vue 微服务集群与持续集成方案
项目架构概述
这个方案将使用 Minikube 在本地 Kubernetes 环境中部署一个包含 Laravel 后端和 Vue 前端的微服务架构,并实现持续集成流程。
主要组件
- 前端服务: Vue.js 应用
- 后端服务: Laravel API
- 数据库服务: MySQL
- 缓存服务: Redis
- 消息队列: RabbitMQ (可选)
- CI/CD 流水线: GitHub Actions/Jenkins
环境准备
1. 安装必要工具
# 安装 Minikube
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube
# 安装 kubectl
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/kubectl
# 启动 Minikube
minikube start --driver=docker --cpus=4 --memory=8192
2. 启用必要插件
minikube addons enable ingress
minikube addons enable metrics-server
微服务部署
1. 创建命名空间
# namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: laravel-vue-app
2. MySQL 部署
# mysql-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: mysql
namespace: laravel-vue-app
spec:
replicas: 1
selector:
matchLabels:
app: mysql
template:
metadata:
labels:
app: mysql
spec:
containers:
- name: mysql
image: mysql:5.7
env:
- name: MYSQL_ROOT_PASSWORD
value: yourpassword
- name: MYSQL_DATABASE
value: laravel
ports:
- containerPort: 3306
volumeMounts:
- name: mysql-persistent-storage
mountPath: /var/lib/mysql
volumes:
- name: mysql-persistent-storage
persistentVolumeClaim:
claimName: mysql-pv-claim
---
# mysql-service.yaml
apiVersion: v1
kind: Service
metadata:
name: mysql
namespace: laravel-vue-app
spec:
ports:
- port: 3306
selector:
app: mysql
---
# mysql-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
namespace: laravel-vue-app
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
3. Redis 部署
# redis-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
namespace: laravel-vue-app
spec:
replicas: 1
selector:
matchLabels:
app: redis
template:
metadata:
labels:
app: redis
spec:
containers:
- name: redis
image: redis:alpine
ports:
- containerPort: 6379
---
# redis-service.yaml
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: laravel-vue-app
spec:
ports:
- port: 6379
selector:
app: redis
4. Laravel 后端部署
# laravel-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: laravel-backend
namespace: laravel-vue-app
spec:
replicas: 3
selector:
matchLabels:
app: laravel-backend
template:
metadata:
labels:
app: laravel-backend
spec:
containers:
- name: laravel-app
image: your-registry/laravel-app:latest
env:
- name: DB_HOST
value: mysql
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: laravel-secrets
key: db-password
- name: REDIS_HOST
value: redis
ports:
- containerPort: 9000
livenessProbe:
httpGet:
path: /api/health
port: 9000
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /api/health
port: 9000
initialDelaySeconds: 5
periodSeconds: 5
---
# laravel-service.yaml
apiVersion: v1
kind: Service
metadata:
name: laravel-backend
namespace: laravel-vue-app
spec:
ports:
- port: 9000
selector:
app: laravel-backend
5. Vue 前端部署
# vue-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: vue-frontend
namespace: laravel-vue-app
spec:
replicas: 3
selector:
matchLabels:
app: vue-frontend
template:
metadata:
labels:
app: vue-frontend
spec:
containers:
- name: vue-app
image: your-registry/vue-app:latest
env:
- name: VUE_APP_API_URL
value: http://laravel-backend:9000
ports:
- containerPort: 8080
livenessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
---
# vue-service.yaml
apiVersion: v1
kind: Service
metadata:
name: vue-frontend
namespace: laravel-vue-app
spec:
ports:
- port: 80
targetPort: 8080
selector:
app: vue-frontend
---
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: laravel-vue-ingress
namespace: laravel-vue-app
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: laravel-vue.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: vue-frontend
port:
number: 80
- path: /api
pathType: Prefix
backend:
service:
name: laravel-backend
port:
number: 9000
持续集成流程
GitHub Actions 示例
# .github/workflows/ci-cd.yaml
name: CI/CD Pipeline
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build-test-backend:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.1'
extensions: mbstring, ctype, fileinfo, tokenizer, mysql, pdo, xml, gd
coverage: pcov
- name: Install dependencies
run: composer install --prefer-dist --no-progress
- name: Copy .env
run: cp .env.example .env
- name: Generate key
run: php artisan key:generate
- name: Run tests
run: php artisan test
- name: Build Docker image
run: docker build -t your-registry/laravel-app:${{ github.sha }} -f Dockerfile.backend .
- name: Login to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_TOKEN }}
- name: Push Docker image
run: docker push your-registry/laravel-app:${{ github.sha }}
build-test-frontend:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Set up Node.js
uses: actions/setup-node@v2
with:
node-version: '16'
- name: Install dependencies
run: npm install
- name: Run tests
run: npm run test:unit
- name: Build production
run: npm run build
- name: Build Docker image
run: docker build -t your-registry/vue-app:${{ github.sha }} -f Dockerfile.frontend .
- name: Login to Docker Hub
uses: docker/login-action@v1
with:
username: ${{ secrets.DOCKER_HUB_USERNAME }}
password: ${{ secrets.DOCKER_HUB_TOKEN }}
- name: Push Docker image
run: docker push your-registry/vue-app:${{ github.sha }}
deploy:
needs: [build-test-backend, build-test-frontend]
runs-on: ubuntu-latest
steps:
- name: Install kubectl
uses: azure/setup-kubectl@v1
- name: Configure kubectl
run: |
mkdir -p ~/.kube
echo "${{ secrets.KUBE_CONFIG }}" > ~/.kube/config
- name: Deploy to Kubernetes
run: |
kubectl set image deployment/laravel-backend laravel-app=your-registry/laravel-app:${{ github.sha }} -n laravel-vue-app
kubectl set image deployment/vue-frontend vue-app=your-registry/vue-app:${{ github.sha }} -n laravel-vue-app
Dockerfile 示例
Laravel Dockerfile
# Dockerfile.backend
FROM php:8.1-fpm
# Install dependencies
RUN apt-get update && apt-get install -y \
build-essential \
libpng-dev \
libjpeg62-turbo-dev \
libfreetype6-dev \
locales \
zip \
jpegoptim optipng pngquant gifsicle \
vim \
unzip \
git \
curl \
libzip-dev \
libonig-dev \
libpq-dev
# Clear cache
RUN apt-get clean && rm -rf /var/lib/apt/lists/*
# Install extensions
RUN docker-php-ext-install pdo_mysql mbstring zip exif pcntl
RUN docker-php-ext-configure gd --with-freetype --with-jpeg
RUN docker-php-ext-install gd
# Install composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
# Set working directory
WORKDIR /var/www
# Copy existing application directory contents
COPY . /var/www
# Install dependencies
RUN composer install
# Expose port 9000 and start php-fpm server
EXPOSE 9000
CMD ["php-fpm"]
Vue Dockerfile
# Dockerfile.frontend
FROM node:16 as build-stage
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
FROM nginx:stable-alpine as production-stage
COPY --from=build-stage /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
部署与应用访问
- 应用所有 Kubernetes 配置:
kubectl apply -f namespace.yaml
kubectl apply -f mysql-pvc.yaml
kubectl apply -f mysql-deployment.yaml
kubectl apply -f mysql-service.yaml
kubectl apply -f redis-deployment.yaml
kubectl apply -f redis-service.yaml
kubectl apply -f laravel-deployment.yaml
kubectl apply -f laravel-service.yaml
kubectl apply -f vue-deployment.yaml
kubectl apply -f vue-service.yaml
kubectl apply -f ingress.yaml
- 获取 Minikube IP 并配置 hosts:
minikube ip
# 将返回的IP添加到你的hosts文件
# 例如: 192.168.49.2 laravel-vue.local
- 访问应用:
- 前端: http://laravel-vue.local
- API: http://laravel-vue.local/api
扩展建议
- Horizontal Pod Autoscaler (HPA): 为 Laravel 和 Vue 服务添加自动扩展
- 监控: 集成 Prometheus 和 Grafana
- 日志: 使用 ELK 或 Loki 进行日志收集
- 服务网格: 考虑使用 Istio 或 Linkerd 进行服务网格管理
- 数据库高可用: 考虑使用 MySQL 集群或云数据库服务
这个方案提供了一个完整的本地开发环境,可以轻松扩展到生产环境。
No Comments