docs: update TECH-03 — CI/CD pipeline details, fix namespace default, add PVC health check commands, add K8s commit history
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
# 🚀 استقرار، CI/CD و زیرساخت
|
||||
|
||||
> **منابع ادغامشده:** `CICD-PIPELINE-GUIDE.md`, `DEPLOYMENT-README.md`, `INFRASTRUCTURE-GUIDE.md`, `INGRESS-NGINX-WARNING.md`, `OFFLINE-DEPLOYMENT-GUIDE.md`, `SERVER-MIRRORS-CONFIG.md`
|
||||
> **آخرین بروزرسانی:** اسفند ۱۴۰۴ (بروزرسانی: مرج پروداکشن + تنظیمات محیطی)
|
||||
> **آخرین بروزرسانی:** اسفند ۱۴۰۴ (بروزرسانی: PersistentVolume برای آپلود فایل + اصلاح namespace + حذف secretRef)
|
||||
|
||||
---
|
||||
|
||||
@@ -77,31 +77,94 @@ ENTRYPOINT ["dotnet", "CMSMicroservice.dll"]
|
||||
|
||||
### ۳.۱ Manifests ساختار
|
||||
|
||||
مانیفستهای K8s **داخل ریپوی CMS** نگهداری میشن و توسط CI/CD اعمال میشن:
|
||||
|
||||
```
|
||||
deployment/k8s-manifests/
|
||||
├── cms-deployment.yaml
|
||||
├── cms-service.yaml
|
||||
├── backoffice-deployment.yaml
|
||||
├── backoffice-service.yaml
|
||||
├── frontoffice-deployment.yaml
|
||||
├── frontoffice-service.yaml
|
||||
├── db-statefulset.yaml
|
||||
├── db-service.yaml
|
||||
├── ingress.yaml
|
||||
├── configmap.yaml
|
||||
└── secrets.yaml
|
||||
CMS/
|
||||
k8s/
|
||||
staging/
|
||||
cms-deployment.yaml ← PVC + Deployment + Service + Ingress
|
||||
production/
|
||||
cms-deployment.yaml ← PVC + Deployment + Service + Ingress
|
||||
```
|
||||
|
||||
### ۳.۲ مثال Deployment
|
||||
> ⚠️ **هر دو محیط از namespace `default` استفاده میکنن.**
|
||||
|
||||
### ۳.۲ PersistentVolume برای آپلود فایل
|
||||
|
||||
فایلهای آپلودشده (عکس محصولات، بلاگ، آواتار و ...) در `/app/Uploads` ذخیره میشن.
|
||||
برای جلوگیری از حذف فایلها با ریستارت Pod، یک **PersistentVolumeClaim** مونت شده:
|
||||
|
||||
```yaml
|
||||
# PVC — 20Gi ذخیرهسازی دائمی
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: cms-uploads-pvc
|
||||
namespace: default
|
||||
spec:
|
||||
accessModes: [ReadWriteOnce]
|
||||
resources:
|
||||
requests:
|
||||
storage: 20Gi
|
||||
```
|
||||
|
||||
```yaml
|
||||
# Volume Mount در Deployment
|
||||
volumeMounts:
|
||||
- name: cms-uploads
|
||||
mountPath: /app/Uploads
|
||||
volumes:
|
||||
- name: cms-uploads
|
||||
persistentVolumeClaim:
|
||||
claimName: cms-uploads-pvc
|
||||
```
|
||||
|
||||
| تنظیم | مقدار |
|
||||
|--------|-------|
|
||||
| **PVC Name** | `cms-uploads-pvc` |
|
||||
| **Mount Path** | `/app/Uploads` |
|
||||
| **Access Mode** | `ReadWriteOnce` |
|
||||
| **حجم** | `20Gi` |
|
||||
| **StorageClass** | `local-path` (K3s default) |
|
||||
| **Replicas** | `1` (محدودیت RWO) |
|
||||
|
||||
> 💡 **نکته مهم:** چون `ReadWriteOnce` هست، فقط **1 replica** میتونه بنویسه. برای 2+ replica نیاز به NFS/CephFS با `ReadWriteMany` هست.
|
||||
|
||||
### ۳.۳ تنظیمات محیطی (Environment Variables)
|
||||
|
||||
تنظیمات حساس (ConnectionString, Email, SMS, ZarinPal) **داخل `appsettings.{Environment}.json`** در ایمیج Docker قرار دارن.
|
||||
**هیچ K8s Secret استفاده نمیشه** — .NET خودش فایل config مربوط به environment رو میخونه.
|
||||
|
||||
| محیط | `ASPNETCORE_ENVIRONMENT` | فایل Config |
|
||||
|------|---------------------------|-------------|
|
||||
| **Staging** | `Staging` | `appsettings.Staging.json` |
|
||||
| **Production** | `Production` | `appsettings.Production.json` |
|
||||
|
||||
env varهای K8s manifest:
|
||||
|
||||
```yaml
|
||||
env:
|
||||
- name: ASPNETCORE_ENVIRONMENT
|
||||
value: "Staging" # یا "Production"
|
||||
- name: ASPNETCORE_URLS
|
||||
value: "http://+:8080"
|
||||
- name: Kestrel__EndpointDefaults__Protocols
|
||||
value: "Http1AndHttp2"
|
||||
- name: FileStorage__UploadPath
|
||||
value: "/app/Uploads"
|
||||
```
|
||||
|
||||
### ۳.۴ مثال Deployment (واقعی)
|
||||
|
||||
```yaml
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: cms
|
||||
namespace: foursat
|
||||
namespace: default
|
||||
spec:
|
||||
replicas: 2
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: cms
|
||||
@@ -109,104 +172,109 @@ spec:
|
||||
spec:
|
||||
containers:
|
||||
- name: cms
|
||||
image: foursat/cms:latest
|
||||
image: 194.5.195.53:30080/admin/cms:latest
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- containerPort: 5001
|
||||
- containerPort: 8080
|
||||
env:
|
||||
- name: ASPNETCORE_ENVIRONMENT
|
||||
value: "Staging"
|
||||
- name: FileStorage__UploadPath
|
||||
value: "/app/Uploads"
|
||||
volumeMounts:
|
||||
- name: cms-uploads
|
||||
mountPath: /app/Uploads
|
||||
resources:
|
||||
requests:
|
||||
memory: "256Mi"
|
||||
cpu: "250m"
|
||||
limits:
|
||||
memory: "512Mi"
|
||||
cpu: "500m"
|
||||
livenessProbe:
|
||||
grpc:
|
||||
port: 5001
|
||||
initialDelaySeconds: 15
|
||||
readinessProbe:
|
||||
grpc:
|
||||
port: 5001
|
||||
requests: { memory: "512Mi", cpu: "500m" }
|
||||
limits: { memory: "1Gi", cpu: "1000m" }
|
||||
volumes:
|
||||
- name: cms-uploads
|
||||
persistentVolumeClaim:
|
||||
claimName: cms-uploads-pvc
|
||||
```
|
||||
|
||||
### ۳.۳ Ingress
|
||||
### ۳.۵ Ingress
|
||||
|
||||
**Staging:**
|
||||
```yaml
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: foursat-ingress
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
rules:
|
||||
- host: foursat.ir
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
service:
|
||||
name: frontoffice
|
||||
port: { number: 5003 }
|
||||
- path: /admin
|
||||
backend:
|
||||
service:
|
||||
name: backoffice
|
||||
port: { number: 80 }
|
||||
- host: cms.se.kbs1.ir
|
||||
```
|
||||
|
||||
> ⚠️ **هشدار:** Ingress-nginx نسخههای قبل از 1.9.0 مشکل امنیتی CVE-2023-5044 دارند. حتماً بروزرسانی کنید.
|
||||
**Production:**
|
||||
```yaml
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
tls:
|
||||
- hosts: [cms.kbs1.ir, cms.kbs2.ir]
|
||||
secretName: cms-tls
|
||||
rules:
|
||||
- host: cms.kbs2.ir
|
||||
- host: cms.kbs1.ir
|
||||
```
|
||||
|
||||
> ⚠️ **هشدار:** از `spec.ingressClassName: nginx` استفاده کنید، نه `kubernetes.io/ingress.class` annotation (deprecated).
|
||||
|
||||
---
|
||||
|
||||
## ۴. CI/CD Pipeline
|
||||
|
||||
### ۴.۱ Gitea Actions Workflow
|
||||
### ۴.۱ Gitea Actions Workflows (CMS)
|
||||
|
||||
```yaml
|
||||
name: Build and Deploy
|
||||
on:
|
||||
push:
|
||||
branches: [kub-stage, production]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup .NET
|
||||
uses: actions/setup-dotnet@v4
|
||||
with:
|
||||
dotnet-version: '9.0.x'
|
||||
|
||||
- name: Restore
|
||||
run: dotnet restore
|
||||
|
||||
- name: Build
|
||||
run: dotnet build --no-restore -c Release
|
||||
|
||||
- name: Test
|
||||
run: dotnet test --no-build -c Release
|
||||
|
||||
- name: Docker Build & Push
|
||||
run: |
|
||||
docker build -t $REGISTRY/foursat/cms:${{ github.sha }} .
|
||||
docker push $REGISTRY/foursat/cms:${{ github.sha }}
|
||||
|
||||
- name: Deploy to K8s
|
||||
if: github.ref == 'refs/heads/production'
|
||||
run: |
|
||||
kubectl set image deployment/cms cms=$REGISTRY/foursat/cms:${{ github.sha }}
|
||||
فایلهای پایپلاین:
|
||||
```
|
||||
CMS/.gitea/workflows/
|
||||
├── kub-deploy.yml ← Staging (branch: kub-stage)
|
||||
├── prod-deploy.yml ← Production (branch: production)
|
||||
└── cms-stage.yml ← قدیمی (IIS روی Windows — غیرفعال)
|
||||
```
|
||||
|
||||
### ۴.۲ شاخهها
|
||||
### ۴.۲ فلوی Staging (`kub-deploy.yml`)
|
||||
|
||||
| شاخه | محیط | Deploy |
|
||||
|------|------|--------|
|
||||
| `kub-stage` | Staging (194.5.195.53) | Auto |
|
||||
| `production` | Production (45.149.79.127) | Manual trigger |
|
||||
| `main` | — | Development only |
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["Push to kub-stage"] --> B["Start Docker daemon"]
|
||||
B --> C["Clone repo"]
|
||||
C --> D["Pack & Push Proto NuGet"]
|
||||
D --> E["Docker build → tag :latest"]
|
||||
E --> F["Push to 194.5.195.53:30080"]
|
||||
F --> G["SCP manifest to server"]
|
||||
G --> H["kubectl apply -f cms-deployment.yaml"]
|
||||
H --> I["kubectl rollout restart"]
|
||||
I --> J["✅ Deployed to Staging"]
|
||||
```
|
||||
|
||||
### ۴.۳ فلوی Production (`prod-deploy.yml`)
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["Push to production"] --> B["Start Docker daemon"]
|
||||
B --> C["Clone repo"]
|
||||
C --> D["Pack & Push Proto NuGet"]
|
||||
D --> E["Docker build → tag :sha + :prod"]
|
||||
E --> F["Push to 194.5.195.53:30080"]
|
||||
F --> G["SCP manifest to server"]
|
||||
G --> H["kubectl apply -f cms-deployment.yaml"]
|
||||
H --> I["kubectl set image → sha"]
|
||||
I --> J["✅ Deployed to Production"]
|
||||
```
|
||||
|
||||
### ۴.۴ شاخهها و محیطها
|
||||
|
||||
| شاخه | محیط | سرور | Image Tag | Deploy |
|
||||
|------|------|------|-----------|--------|
|
||||
| `kub-stage` | Staging | 194.5.195.53 | `:latest` | Auto |
|
||||
| `production` | Production | 45.149.79.127 | `:sha` + `:prod` | Auto |
|
||||
|
||||
### ۴.۵ نکات مهم CI/CD
|
||||
|
||||
- **Proto NuGet:** هر deploy ابتدا proto packages رو build و به Nexus push میکنه
|
||||
- **Manifest apply:** پایپلاین مانیفست K8s رو SCP به سرور و `kubectl apply` میزنه
|
||||
→ PVC، Deployment، Service و Ingress هر بار اعمال میشه
|
||||
- **Image registry:** `194.5.195.53:30080` (داخلی Nexus) — نه `git.se.kbs1.ir`
|
||||
- **appsettings حفاظت:** `.gitattributes` با `merge=ours` مانع overwrite شدن `appsettings.Production.json` موقع merge میشه
|
||||
|
||||
---
|
||||
|
||||
@@ -328,6 +396,19 @@ flowchart TD
|
||||
| **FrontOffice** | `kub-stage` → `production` | `f02d082` | 21 فایل، 400 insertion + فیکس GwUrl به `cms.kbs2.ir` |
|
||||
| **BackOffice** | `kub-stage` → `production` | `bdea2e8` | 36 فایل، بدون conflict |
|
||||
|
||||
### ۹.۲ کامیتهای PVC و اصلاحات K8s (تیر ۱۴۰۴)
|
||||
|
||||
| commit | شرح |
|
||||
|--------|------|
|
||||
| `3153fd8` | feat: add PersistentVolume for CMS uploads + apply manifests in CI/CD |
|
||||
| `68da3f4` | fix: staging uses namespace default, not foursat |
|
||||
| `e41747a` | fix: production ingress — add cms.kbs2.ir, use ingressClassName |
|
||||
| `2d6c95e` | fix: use local registry 194.5.195.53:30080 instead of git.se.kbs1.ir |
|
||||
| `f8dc4ab` | fix: staging ASPNETCORE_ENVIRONMENT=Staging, remove secretKeyRef |
|
||||
| `de83c31` | fix: production uses namespace default + remove foursat namespace references |
|
||||
|
||||
> همه کامیتها به هر دو شاخه `kub-stage` و `production` push شدهاند.
|
||||
|
||||
**تنظیمات محیطی Production (`appsettings.Production.json`):**
|
||||
|
||||
| تنظیم | مقدار |
|
||||
@@ -340,10 +421,14 @@ flowchart TD
|
||||
| `ConnectionStrings.Default` | `Server=mssql-svc;Database=KBS` |
|
||||
|
||||
```bash
|
||||
# k8s-health-check.sh
|
||||
kubectl get pods -n foursat
|
||||
kubectl top pods -n foursat
|
||||
kubectl logs deployment/cms -n foursat --tail=50
|
||||
# k8s-health-check.sh (namespace = default)
|
||||
kubectl get pods
|
||||
kubectl top pods
|
||||
kubectl logs deployment/cms --tail=50
|
||||
|
||||
# بررسی PVC
|
||||
kubectl get pvc cms-uploads-pvc
|
||||
kubectl exec deployment/cms -- ls /app/Uploads | wc -l
|
||||
|
||||
# تست سرویسها
|
||||
grpcurl -plaintext localhost:5001 list # لیست سرویسها
|
||||
|
||||
Reference in New Issue
Block a user