diff --git a/k8s/00-namespace.yaml b/k8s/00-namespace.yaml new file mode 100644 index 0000000..9c75aaf --- /dev/null +++ b/k8s/00-namespace.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: pengzhan-dev + labels: + app.kubernetes.io/name: pengzhan-dev diff --git a/k8s/01-secret.yaml b/k8s/01-secret.yaml new file mode 100644 index 0000000..7ddd4d8 --- /dev/null +++ b/k8s/01-secret.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Secret +metadata: + name: pengzhan-secrets + namespace: pengzhan-dev +type: Opaque +stringData: + ADMIN_SECRET: "admin" diff --git a/k8s/02-pvc.yaml b/k8s/02-pvc.yaml new file mode 100644 index 0000000..7952c22 --- /dev/null +++ b/k8s/02-pvc.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: pengzhan-content-pvc + namespace: pengzhan-dev +spec: + accessModes: + - ReadWriteOnce + storageClassName: local-path + resources: + requests: + storage: 5Gi diff --git a/k8s/03-deployment.yaml b/k8s/03-deployment.yaml new file mode 100644 index 0000000..97417b8 --- /dev/null +++ b/k8s/03-deployment.yaml @@ -0,0 +1,87 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: pengzhan-web + namespace: pengzhan-dev + labels: + app: pengzhan-web +spec: + replicas: 1 + revisionHistoryLimit: 5 + strategy: + type: RollingUpdate + rollingUpdate: + maxSurge: 1 + maxUnavailable: 0 + selector: + matchLabels: + app: pengzhan-web + template: + metadata: + labels: + app: pengzhan-web + spec: + securityContext: + fsGroup: 1000 + fsGroupChangePolicy: "OnRootMismatch" + initContainers: + - name: init-content-perms + image: busybox:1.36 + imagePullPolicy: IfNotPresent + command: ["sh", "-c"] + args: + - | + mkdir -p /app/content/data + chown -R 1000:1000 /app/content || true + volumeMounts: + - name: content-data + mountPath: /app/content + containers: + - name: pengzhan-web + image: git.pengzhan.dev/haopengzhan/pengzhan.dev:latest + imagePullPolicy: Always + ports: + - containerPort: 3000 + name: http + env: + - name: NODE_ENV + value: "production" + - name: PORT + value: "3000" + - name: CONTENT_DIR + value: "/app/content" + - name: ADMIN_SECRET + valueFrom: + secretKeyRef: + name: pengzhan-secrets + key: ADMIN_SECRET + volumeMounts: + - name: content-data + mountPath: /app/content + livenessProbe: + httpGet: + path: / + port: 3000 + initialDelaySeconds: 15 + periodSeconds: 30 + timeoutSeconds: 5 + failureThreshold: 3 + readinessProbe: + httpGet: + path: / + port: 3000 + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 2 + resources: + requests: + cpu: 50m + memory: 128Mi + limits: + cpu: 500m + memory: 512Mi + volumes: + - name: content-data + persistentVolumeClaim: + claimName: pengzhan-content-pvc diff --git a/k8s/04-service.yaml b/k8s/04-service.yaml new file mode 100644 index 0000000..0ea87aa --- /dev/null +++ b/k8s/04-service.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: pengzhan-web + namespace: pengzhan-dev + labels: + app: pengzhan-web +spec: + type: ClusterIP + selector: + app: pengzhan-web + ports: + - name: http + port: 80 + targetPort: 3000 diff --git a/k8s/05-ingress.yaml b/k8s/05-ingress.yaml new file mode 100644 index 0000000..d1be3bd --- /dev/null +++ b/k8s/05-ingress.yaml @@ -0,0 +1,24 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: pengzhan-ingress + namespace: pengzhan-dev + annotations: + cert-manager.io/cluster-issuer: letsencrypt-prod +spec: + ingressClassName: traefik + rules: + - host: pengzhan.dev + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: pengzhan-web + port: + number: 80 + tls: + - hosts: + - pengzhan.dev + secretName: pengzhan-dev-tls