synchronization
All checks were successful
continuous-integration/drone Build is passing

This commit is contained in:
2025-08-25 13:02:18 +08:00
commit f1ecb4ed07
37 changed files with 1644 additions and 0 deletions

23
chart/.helmignore Normal file
View File

@@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/

24
chart/Chart.yaml Normal file
View File

@@ -0,0 +1,24 @@
apiVersion: v2
name: blog-chart
description: A Helm chart for Kubernetes
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
# Versions are expected to follow Semantic Versioning (https://semver.org/)
version: 0.1.0
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application. Versions are not expected to
# follow Semantic Versioning. They should reflect the version the application is using.
# It is recommended to use it with quotes.
appVersion: "1.16.0"

17
chart/README.md Normal file
View File

@@ -0,0 +1,17 @@
> 本文作者:丁辉
# Helm部署
开始部署
```bash
helm install blog ./chart \
--namespace blog --create-namespace
```
卸载
```bash
helm uninstall blog -n blog
```

View File

@@ -0,0 +1,7 @@
Please visit this URL after startup:
{{ if .Values.ingress.host }}
https://{{ .Values.ingress.host }}
{{ end }}

View File

@@ -0,0 +1,17 @@
{{/*
Startup parameter
*/}}
{{- define "argument" -}}
progressDeadlineSeconds: 200
replicas: 1
revisionHistoryLimit: 1
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
{{- end }}
{{- define "imagePullPolicy" -}}
imagePullPolicy: IfNotPresent
{{- end }}

View File

@@ -0,0 +1,87 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Values.deployment.blog.name }}
labels:
app: {{ .Values.deployment.blog.labels.app }}
spec:
{{- include "argument" . | nindent 2 }}
selector:
matchLabels:
app: {{ .Values.deployment.blog.labels.app }}
template:
metadata:
labels:
app: {{ .Values.deployment.blog.labels.app }}
spec:
{{- if .Values.global.enabled }}
volumes:
- name: data
persistentVolumeClaim:
claimName: blog-pvc
{{- end }}
containers:
- name: {{ .Values.deployment.blog.name }}
image: {{ .Values.deployment.blog.image }}:{{ .Values.deployment.blog.tag }}
{{- include "imagePullPolicy" . | nindent 8 }}
ports:
- containerPort: {{ .Values.blog.targetPort }}
protocol: TCP
{{- if .Values.global.enabled }}
volumeMounts:
{{- range .Values.deployment.blog.volumeMounts }}
- name: {{ .name }}
mountPath: {{ .mountPath }}
{{- end }}
{{- end }}
readinessProbe:
failureThreshold: 3
initialDelaySeconds: 5
periodSeconds: 3
successThreshold: 1
tcpSocket:
port: {{ .Values.blog.targetPort }}
timeoutSeconds: 10
resources:
limits:
memory: {{ .Values.deployment.blog.limits.memory }}
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ .Values.deployment.blog_gateway.name }}
labels:
app: {{ .Values.deployment.blog_gateway.labels.app }}
spec:
{{- include "argument" . | nindent 2 }}
selector:
matchLabels:
app: {{ .Values.deployment.blog_gateway.labels.app }}
template:
metadata:
labels:
app: {{ .Values.deployment.blog_gateway.labels.app }}
spec:
containers:
- name: {{ .Values.deployment.blog_gateway.name }}
image: {{ .Values.deployment.blog_gateway.image }}:{{ .Values.deployment.blog_gateway.tag }}
{{- include "imagePullPolicy" . | nindent 8 }}
env:
{{- range .Values.deployment.blog_gateway.env }}
- name: {{ .name }}
value: {{ .value }}
{{- end }}
ports:
- containerPort: {{ .Values.blog_gateway.targetPort }}
protocol: TCP
readinessProbe:
failureThreshold: 3
initialDelaySeconds: 5
periodSeconds: 3
successThreshold: 1
tcpSocket:
port: {{ .Values.blog_gateway.targetPort }}
timeoutSeconds: 10
resources:
limits:
memory: {{ .Values.deployment.blog_gateway.limits.memory }}

View File

@@ -0,0 +1,36 @@
{{- if .Values.ingress.enabled -}}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
{{- if .Values.ingress.redirection.enabled}}
annotations:
kubernetes.io/tls-acme: "true"
nginx.ingress.kubernetes.io/permanent-redirect-code: "301"
#kubernetes.io/ingress.class: "nginx"
ingress.kubernetes.io/ssl-redirect: "true"
ingress.kubernetes.io/secure-backends: "true"
ingress.kubernetes.io/force-ssl-redirect: "true"
{{- end }}
name: {{ .Values.ingress.name }}
spec:
ingressClassName: nginx
rules:
- host: {{ .Values.ingress.host }}
http:
paths:
- pathType: Prefix
backend:
service:
name: {{ .Values.ingress.service.name }}
port:
number: {{ .Values.ingress.service.port.number }}
path: /
{{- if .Values.ingress.tls.enabled}}
tls:
- hosts:
{{- range $.Values.ingress.tls.hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .Values.ingress.tls.secretName }}
{{- end }}
{{- end }}

18
chart/templates/pvc.yaml Normal file
View File

@@ -0,0 +1,18 @@
{{- if .Values.global.enabled -}}
apiVersion: v1
kind: List
items:
{{- range .Values.global.pvcConfigs }}
- apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ .name }}
spec:
accessModes:
- {{ .accessModes }}
storageClassName: {{ .storageClass }}
resources:
requests:
storage: {{ .storage }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,41 @@
apiVersion: v1
kind: Service
metadata:
name: {{ .Values.deployment.blog.name }}
spec:
selector:
app: {{ .Values.deployment.blog.labels.app }}
ports:
- name: {{ .Values.deployment.blog.name }}
protocol: TCP
port: {{ .Values.blog.port }}
targetPort: {{ .Values.blog.targetPort }}
type: {{ .Values.blog.type }}
---
apiVersion: v1
kind: Service
metadata:
name: {{ .Values.deployment.blog_gateway.name }}
spec:
selector:
app: {{ .Values.deployment.blog_gateway.labels.app }}
ports:
- name: {{ .Values.deployment.blog_gateway.name }}
protocol: TCP
port: {{ .Values.blog_gateway.port }}
targetPort: {{ .Values.blog_gateway.targetPort }}
type: {{ .Values.blog_gateway.type }}
---
apiVersion: v1
kind: Service
metadata:
name: {{ .Values.statefulset.blog_twikoo.name }}
spec:
selector:
app: {{ .Values.statefulset.blog_twikoo.labels.app }}
ports:
- name: {{ .Values.statefulset.blog_twikoo.name }}
protocol: TCP
port: {{ .Values.blog_twikoo.port }}
targetPort: {{ .Values.blog_twikoo.targetPort }}
type: {{ .Values.blog_twikoo.type }}

View File

@@ -0,0 +1,54 @@
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: {{ .Values.statefulset.blog_twikoo.name }}
spec:
podManagementPolicy: OrderedReady
replicas: 1
revisionHistoryLimit: 0
selector:
matchLabels:
app: {{ .Values.statefulset.blog_twikoo.labels.app }}
serviceName: {{ .Values.statefulset.blog_twikoo.name }}
minReadySeconds: 5
template:
metadata:
labels:
app: {{ .Values.statefulset.blog_twikoo.labels.app }}
spec:
terminationGracePeriodSeconds: 5
containers:
- name: {{ .Values.statefulset.blog_twikoo.name }}
image: {{ .Values.statefulset.blog_twikoo.image }}:{{ .Values.statefulset.blog_twikoo.tag }}
env:
{{- range .Values.statefulset.blog_twikoo.env }}
- name: {{ .name }}
value: "{{ .value }}"
{{- end }}
ports:
- containerPort: {{ .Values.blog_twikoo.targetPort }}
protocol: TCP
resources:
limits:
memory: {{ .Values.statefulset.blog_twikoo.limits.memory }}
livenessProbe:
failureThreshold: 3
initialDelaySeconds: 5
periodSeconds: 3
successThreshold: 1
tcpSocket:
port: {{ .Values.blog_twikoo.targetPort }}
timeoutSeconds: 20
{{- if .Values.global.enabled }}
volumeMounts:
{{- range .Values.statefulset.blog_twikoo.volumeMounts }}
- name: {{ .name }}
mountPath: {{ .mountPath }}
{{- end }}
{{- end }}
{{- if .Values.global.enabled }}
volumes:
- name: data
persistentVolumeClaim:
claimName: twikoo-pvc
{{- end }}

86
chart/values.yaml Normal file
View File

@@ -0,0 +1,86 @@
# Default values for blog.
global:
enabled: true
pvcConfigs:
- name: blog-pvc
storageClass: "" # 指定存储卷, 不指定则需要集群内存在默认的存储卷
storage: "10Gi"
accessModes: ReadWriteOnce
- name: twikoo-pvc
storageClass: "" # 指定存储卷, 不指定则需要集群内存在默认的存储卷
storage: "10Gi"
accessModes: ReadWriteOnce
deployment:
blog:
name: blog
labels:
app: blog
image: registry.cn-hangzhou.aliyuncs.com/offends/hexo
tag: hexo-async-offends
limits:
memory: 512Mi
volumeMounts:
- name: data
mountPath: /hexo/source/_posts
blog_gateway:
name: blog-gateway
labels:
app: blog-gateway
image: registry.cn-hangzhou.aliyuncs.com/offends/hexo
tag: gateway-kubernetes
limits:
memory: 512Mi
env:
- name: localhost
value: "blog.offends.cn"
statefulset:
blog_twikoo:
name: blog-twikoo
labels:
app: blog-twikoo
image: registry.cn-hangzhou.aliyuncs.com/offends/hexo
tag: twikoo
limits:
memory: 128Mi
env:
- name: TWIKOO_THROTTLE
value: "1000"
volumeMounts:
- name: data
mountPath: /app/data
blog:
port: 4000
targetPort: 4000
type: ClusterIP
blog_gateway:
port: 80
targetPort: 80
type: ClusterIP
blog_twikoo:
port: 8080
targetPort: 8080
type: ClusterIP
# kubectl create secret tls blog-tls --key nginx.key --cert nginx.pem -n blog
ingress:
enabled: true
name: blog-ingress
host: blog.offends.cn
service:
name: blog-gateway
port:
number: 80
tls:
enabled: true
hosts:
- blog.offends.cn
secretName: blog-tls
redirection: #是否开启http重定向到https
enabled: true