jina verze
This commit is contained in:
@@ -0,0 +1,19 @@
|
||||
{{- if .Values.debugHelm }}
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata: { name: debug, namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
containers:
|
||||
- name: debug
|
||||
image: nicolaka/netshoot:latest
|
||||
command: ["sh","-c","sleep infinity"]
|
||||
stdin: true
|
||||
tty: true
|
||||
securityContext:
|
||||
capabilities:
|
||||
add: ["NET_RAW","NET_ADMIN"] # for tcpdump/mtr
|
||||
restartPolicy: Never
|
||||
|
||||
{{- end }}
|
||||
@@ -0,0 +1,299 @@
|
||||
{{- if .Values.mariadbHelm }}
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata: { name: "{{ .Values.mariadbMaster }}-config", namespace: "{{ .Values.namespace }}" }
|
||||
data:
|
||||
replication.cnf: |
|
||||
[mysqld]
|
||||
skip_name_resolve=1
|
||||
server-id=1
|
||||
|
||||
# --- log ---
|
||||
log_bin=mysql-bin
|
||||
binlog_format=ROW
|
||||
binlog_expire_logs_seconds=604800
|
||||
max_binlog_total_size=32212254720
|
||||
|
||||
# --- durability ---
|
||||
innodb_flush_log_at_trx_commit=1
|
||||
sync_binlog=1
|
||||
|
||||
# --- connection / thread pool ---
|
||||
max_connections={{ .Values.profiles.mariadbMaster.maxConnections }}
|
||||
thread_handling=pool-of-threads
|
||||
thread_pool_size={{ .Values.profiles.mariadbMaster.threadPoolSize }}
|
||||
thread_pool_max_threads=128
|
||||
thread_pool_stall_limit=500
|
||||
|
||||
innodb_buffer_pool_size={{ .Values.profiles.mariadbMaster.innodbBufferPoolSize }}
|
||||
innodb_buffer_pool_instances={{ .Values.profiles.mariadbMaster.innodbBufferPoolInstances }}
|
||||
innodb_flush_method=O_DIRECT
|
||||
innodb_flush_neighbors=0
|
||||
innodb_io_capacity=2000
|
||||
innodb_io_capacity_max=4000
|
||||
innodb_log_file_size=1G
|
||||
innodb_log_buffer_size=64M
|
||||
|
||||
# --- cache ---
|
||||
query_cache_type=0
|
||||
query_cache_size=0
|
||||
table_open_cache={{ .Values.profiles.mariadbMaster.tableOpenCache }}
|
||||
table_open_cache_instances={{ .Values.profiles.mariadbMaster.tableOpenCacheInstances }}
|
||||
table_definition_cache={{ .Values.profiles.mariadbMaster.tableOpenCache }}
|
||||
open_files_limit=65535
|
||||
|
||||
# --- buffers ---
|
||||
tmp_table_size={{ .Values.profiles.mariadbMaster.tmpTableSize }}
|
||||
max_heap_table_size={{ .Values.profiles.mariadbMaster.tmpTableSize }}
|
||||
sort_buffer_size=2M
|
||||
join_buffer_size=2M
|
||||
read_buffer_size=256K
|
||||
read_rnd_buffer_size=512K
|
||||
|
||||
# --- timeouts ---
|
||||
wait_timeout=60
|
||||
interactive_timeout=300
|
||||
|
||||
max_allowed_packet=64M
|
||||
|
||||
slow_query_log=1
|
||||
long_query_time=1
|
||||
slow_query_log_file=/var/lib/mysql/slow.log
|
||||
log_error=/var/lib/mysql/error.log
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata: { name: "{{ .Values.mariadbSlave }}-config", namespace: "{{ .Values.namespace }}" }
|
||||
data:
|
||||
replication.cnf: |
|
||||
[mysqld]
|
||||
skip_name_resolve=1
|
||||
server-id=2
|
||||
read_only=1
|
||||
|
||||
# --- log ---
|
||||
relay-log=relay-log
|
||||
relay_log_purge=1
|
||||
relay_log_recovery=1
|
||||
|
||||
# --- connection / thread pool ---
|
||||
max_connections={{ .Values.profiles.mariadbSlave.maxConnections }}
|
||||
thread_handling=pool-of-threads
|
||||
thread_pool_size={{ .Values.profiles.mariadbSlave.threadPoolSize }}
|
||||
thread_pool_max_threads=32
|
||||
thread_pool_stall_limit=500
|
||||
|
||||
# --- InnoDB ---
|
||||
innodb_buffer_pool_size={{ .Values.profiles.mariadbSlave.innodbBufferPoolSize }}
|
||||
innodb_buffer_pool_instances={{ .Values.profiles.mariadbSlave.innodbBufferPoolInstances }}
|
||||
innodb_flush_method=O_DIRECT
|
||||
innodb_flush_neighbors=0
|
||||
innodb_io_capacity=1000
|
||||
innodb_io_capacity_max=2000
|
||||
innodb_log_file_size=512M
|
||||
innodb_log_buffer_size=32M
|
||||
|
||||
# --- durability (for standby recovery replica) ---
|
||||
innodb_flush_log_at_trx_commit=1
|
||||
sync_binlog=1
|
||||
|
||||
# --- cache ---
|
||||
query_cache_type=0
|
||||
query_cache_size=0
|
||||
table_open_cache={{ .Values.profiles.mariadbSlave.tableOpenCache }}
|
||||
table_open_cache_instances={{ .Values.profiles.mariadbSlave.tableOpenCacheInstances }}
|
||||
table_definition_cache={{ .Values.profiles.mariadbSlave.tableOpenCache }}
|
||||
open_files_limit=65535
|
||||
|
||||
# --- buffers ---
|
||||
tmp_table_size={{ .Values.profiles.mariadbSlave.tmpTableSize }}
|
||||
max_heap_table_size={{ .Values.profiles.mariadbSlave.tmpTableSize }}
|
||||
sort_buffer_size=1M
|
||||
join_buffer_size=1M
|
||||
read_buffer_size=256K
|
||||
read_rnd_buffer_size=512K
|
||||
|
||||
# --- timeouts ---
|
||||
wait_timeout=60
|
||||
interactive_timeout=300
|
||||
|
||||
max_allowed_packet=64M
|
||||
|
||||
# --- logs ---
|
||||
slow_query_log=0
|
||||
log_error=/var/lib/mysql/error.log
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata: { name: "{{ .Values.mariadbMaster }}-pv" }
|
||||
spec:
|
||||
capacity: { storage: 100Gi }
|
||||
volumeMode: Filesystem
|
||||
accessModes: [ ReadWriteOnce ]
|
||||
persistentVolumeReclaimPolicy: Retain
|
||||
hostPath: { path: "{{ .Values.mariadbMasterPath }}", type: DirectoryOrCreate }
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata: { name: "{{ .Values.mariadbMaster }}-pvc", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
volumeName: "{{ .Values.mariadbMaster }}-pv"
|
||||
volumeMode: Filesystem
|
||||
accessModes: [ ReadWriteOnce ]
|
||||
resources: { requests: { storage: 100Gi } }
|
||||
storageClassName: ""
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata: { name: "{{ .Values.mariadbSlave }}-pv" }
|
||||
spec:
|
||||
capacity: { storage: 100Gi }
|
||||
volumeMode: Filesystem
|
||||
accessModes: [ ReadWriteOnce ]
|
||||
persistentVolumeReclaimPolicy: Retain
|
||||
hostPath: { path: "{{ .Values.mariadbSlavePath }}", type: DirectoryOrCreate }
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata: { name: "{{ .Values.mariadbSlave }}-pvc", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
volumeName: "{{ .Values.mariadbSlave }}-pv"
|
||||
volumeMode: Filesystem
|
||||
accessModes: [ ReadWriteOnce ]
|
||||
resources: { requests: { storage: 100Gi } }
|
||||
storageClassName: ""
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata: { name: "{{ .Values.mariadbMaster }}", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
serviceName: "{{ .Values.mariadbMaster }}-headless"
|
||||
replicas: 1
|
||||
selector: { matchLabels: { app: "{{ .Values.mariadbMaster }}" } }
|
||||
template:
|
||||
metadata: { labels: { app: "{{ .Values.mariadbMaster }}" } }
|
||||
spec:
|
||||
terminationGracePeriodSeconds: 60
|
||||
containers:
|
||||
- name: "{{ .Values.mariadbMaster }}"
|
||||
image: mariadb:12.2
|
||||
resources:
|
||||
requests: { cpu: "{{ .Values.profiles.mariadbMaster.cpuRequest }}", memory: "{{ .Values.profiles.mariadbMaster.memoryRequest }}" }
|
||||
limits: { cpu: "{{ .Values.profiles.mariadbMaster.cpuLimit }}", memory: "{{ .Values.profiles.mariadbMaster.memoryLimit }}" }
|
||||
ports:
|
||||
- { containerPort: 3306 }
|
||||
env:
|
||||
- { name: MARIADB_ROOT_PASSWORD, valueFrom: { secretKeyRef: { name: "{{ .Values.mariadb }}-secret", key: root-password } } }
|
||||
readinessProbe:
|
||||
exec:
|
||||
command: ["sh","-lc",'mariadb-admin ping -h 127.0.0.1 -uroot -p"$MARIADB_ROOT_PASSWORD" --silent']
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 3
|
||||
failureThreshold: 6
|
||||
livenessProbe:
|
||||
exec:
|
||||
command: ["sh","-lc",'mariadb-admin ping -h 127.0.0.1 -uroot -p"$MARIADB_ROOT_PASSWORD" --silent']
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 3
|
||||
failureThreshold: 6
|
||||
volumeMounts:
|
||||
- { name: "{{ .Values.mariadbMaster }}-volume", mountPath: /var/lib/mysql }
|
||||
- { name: "{{ .Values.mariadbMaster }}-config-volume", mountPath: /etc/mysql/conf.d/replication.cnf, subPath: replication.cnf }
|
||||
volumes:
|
||||
- name: "{{ .Values.mariadbMaster }}-volume"
|
||||
persistentVolumeClaim: { claimName: "{{ .Values.mariadbMaster }}-pvc" }
|
||||
- name: "{{ .Values.mariadbMaster }}-config-volume"
|
||||
configMap: { name: "{{ .Values.mariadbMaster }}-config" }
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata: { name: "{{ .Values.mariadbSlave }}", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
serviceName: "{{ .Values.mariadbSlave }}-headless"
|
||||
replicas: 1
|
||||
selector: { matchLabels: { app: "{{ .Values.mariadbSlave }}" } }
|
||||
template:
|
||||
metadata: { labels: { app: "{{ .Values.mariadbSlave }}" } }
|
||||
spec:
|
||||
terminationGracePeriodSeconds: 60
|
||||
containers:
|
||||
- name: "{{ .Values.mariadbSlave }}"
|
||||
image: mariadb:12.2
|
||||
resources:
|
||||
requests: { cpu: "{{ .Values.profiles.mariadbSlave.cpuRequest }}", memory: "{{ .Values.profiles.mariadbSlave.memoryRequest }}" }
|
||||
limits: { cpu: "{{ .Values.profiles.mariadbSlave.cpuLimit }}", memory: "{{ .Values.profiles.mariadbSlave.memoryLimit }}" }
|
||||
ports:
|
||||
- { containerPort: 3306 }
|
||||
env:
|
||||
- { name: MARIADB_ROOT_PASSWORD, valueFrom: { secretKeyRef: { name: "{{ .Values.mariadb }}-secret", key: root-password } } }
|
||||
readinessProbe:
|
||||
exec:
|
||||
command: ["sh","-lc",'mariadb-admin ping -h 127.0.0.1 -uroot -p"$MARIADB_ROOT_PASSWORD" --silent']
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 3
|
||||
failureThreshold: 6
|
||||
livenessProbe:
|
||||
exec:
|
||||
command: ["sh","-lc",'mariadb-admin ping -h 127.0.0.1 -uroot -p"$MARIADB_ROOT_PASSWORD" --silent']
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 3
|
||||
failureThreshold: 6
|
||||
volumeMounts:
|
||||
- { name: "{{ .Values.mariadbSlave }}-volume", mountPath: /var/lib/mysql }
|
||||
- { name: "{{ .Values.mariadbSlave }}-config-volume", mountPath: /etc/mysql/conf.d/replication.cnf, subPath: replication.cnf }
|
||||
volumes:
|
||||
- name: "{{ .Values.mariadbSlave }}-volume"
|
||||
persistentVolumeClaim: { claimName: "{{ .Values.mariadbSlave }}-pvc" }
|
||||
- name: "{{ .Values.mariadbSlave }}-config-volume"
|
||||
configMap: { name: "{{ .Values.mariadbSlave }}-config" }
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata: { name: "{{ .Values.mariadbMaster }}", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
selector: { app: "{{ .Values.mariadbMaster }}" }
|
||||
ports: [ { name: mysql, protocol: TCP, port: 3306, targetPort: 3306 } ]
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata: { name: "{{ .Values.mariadbSlave }}", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
selector: { app: "{{ .Values.mariadbSlave }}" }
|
||||
ports: [ { name: mysql, protocol: TCP, port: 3306, targetPort: 3306 } ]
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata: { name: "{{ .Values.mariadbMaster }}-headless", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
clusterIP: None
|
||||
selector: { app: "{{ .Values.mariadbMaster }}" }
|
||||
ports:
|
||||
- { name: mysql, protocol: TCP, port: 3306, targetPort: 3306 }
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata: { name: "{{ .Values.mariadbSlave }}-headless", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
clusterIP: None
|
||||
selector: { app: "{{ .Values.mariadbSlave }}" }
|
||||
ports:
|
||||
- { name: mysql, protocol: TCP, port: 3306, targetPort: 3306 }
|
||||
|
||||
{{- end }}
|
||||
@@ -0,0 +1,128 @@
|
||||
{{- if .Values.metricHelm }}
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata: { name: "{{ .Values.metric }}-node-exporter", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
selector: { app: "{{ .Values.metric }}-node-exporter" }
|
||||
ports: [ { name: metrics, protocol: TCP, port: 9100, targetPort: 9100 } ]
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
metadata: { name: "{{ .Values.metric }}-node-exporter", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
selector:
|
||||
matchLabels: { app: "{{ .Values.metric }}-node-exporter" }
|
||||
template:
|
||||
metadata:
|
||||
labels: { app: "{{ .Values.metric }}-node-exporter" }
|
||||
spec:
|
||||
hostNetwork: true
|
||||
hostPID: true
|
||||
dnsPolicy: ClusterFirstWithHostNet
|
||||
tolerations:
|
||||
- operator: "Exists"
|
||||
containers:
|
||||
- name: "{{ .Values.metric }}-node-exporter"
|
||||
image: quay.io/prometheus/node-exporter:v1.8.2
|
||||
args:
|
||||
- --web.listen-address=:9100
|
||||
- --path.procfs=/host/proc
|
||||
- --path.sysfs=/host/sys
|
||||
- --path.rootfs=/host/root
|
||||
- --collector.textfile.directory={{ .Values.metricPromPath }}
|
||||
ports: [ { containerPort: 9100, hostPort: 9100, name: metrics } ]
|
||||
resources:
|
||||
requests: { cpu: "10m", memory: "32Mi" }
|
||||
limits: { cpu: "150m", memory: "200Mi" }
|
||||
securityContext:
|
||||
readOnlyRootFilesystem: true
|
||||
allowPrivilegeEscalation: false
|
||||
volumeMounts:
|
||||
- { name: proc, mountPath: /host/proc, readOnly: true }
|
||||
- { name: sys, mountPath: /host/sys, readOnly: true }
|
||||
- { name: root, mountPath: /host/root, readOnly: true }
|
||||
- { name: textfile, mountPath: "{{ .Values.metricPromPath }}", readOnly: true }
|
||||
volumes:
|
||||
- name: proc
|
||||
hostPath: { path: /proc, type: Directory }
|
||||
- name: sys
|
||||
hostPath: { path: /sys, type: Directory }
|
||||
- name: root
|
||||
hostPath: { path: /, type: Directory }
|
||||
- name: textfile
|
||||
hostPath: { path: "{{ .Values.metricPromPath }}", type: DirectoryOrCreate }
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata: { name: "{{ .Values.metric }}-vmagent", namespace: "{{ .Values.namespace }}" }
|
||||
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata: { name: "{{ .Values.metric }}-vmagent" }
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["nodes", "nodes/proxy", "services", "endpoints", "pods"]
|
||||
verbs: ["get", "list", "watch"]
|
||||
- apiGroups: ["discovery.k8s.io"]
|
||||
resources: ["endpointslices"]
|
||||
verbs: ["get", "list", "watch"]
|
||||
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata: { name: "{{ .Values.metric }}-vmagent" }
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: "{{ .Values.metric }}-vmagent"
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: "{{ .Values.metric }}-vmagent"
|
||||
namespace: "{{ .Values.namespace }}"
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata: { name: "{{ .Values.metric }}-vmagent", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
selector: { app: "{{ .Values.metric }}-vmagent" }
|
||||
ports: [ { name: http, protocol: TCP, port: 8429, targetPort: 8429 } ]
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata: { name: "{{ .Values.metric }}-vmagent", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels: { app: "{{ .Values.metric }}-vmagent" }
|
||||
template:
|
||||
metadata:
|
||||
labels: { app: "{{ .Values.metric }}-vmagent" }
|
||||
spec:
|
||||
serviceAccountName: "{{ .Values.metric }}-vmagent"
|
||||
containers:
|
||||
- name: "{{ .Values.metric }}-vmagent"
|
||||
image: victoriametrics/vmagent:v1.112.0
|
||||
args:
|
||||
- -promscrape.config=/etc/vmagent/vmagent.yml
|
||||
- -httpListenAddr=:8429
|
||||
- -loggerLevel=INFO
|
||||
- -remoteWrite.url={{ .Values.metricApiUrl }}
|
||||
- -remoteWrite.label=server={{ .Values.namespace }}
|
||||
ports: [ { containerPort: 8429, name: http } ]
|
||||
resources:
|
||||
requests: { cpu: "30m", memory: "128Mi" }
|
||||
limits: { cpu: "300m", memory: "512Mi" }
|
||||
volumeMounts:
|
||||
- { name: "{{ .Values.metric }}-vmagent-config-volume", mountPath: /etc/vmagent/vmagent.yml, subPath: vmagent.yml, readOnly: true }
|
||||
volumes:
|
||||
- name: "{{ .Values.metric }}-vmagent-config-volume"
|
||||
hostPath: { path: "{{ .Values.metricVmagentPath }}", type: DirectoryOrCreate }
|
||||
|
||||
{{- end }}
|
||||
@@ -0,0 +1,301 @@
|
||||
{{- if .Values.openlitespeedHelm }}
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata: { name: "{{ .Values.openlitespeed }}-vhosts-pv" }
|
||||
spec:
|
||||
capacity: { storage: 500Gi }
|
||||
volumeMode: Filesystem
|
||||
accessModes: [ ReadWriteMany ]
|
||||
persistentVolumeReclaimPolicy: Retain
|
||||
hostPath: { path: "{{ .Values.vhostsPath }}", type: DirectoryOrCreate }
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata: { name: "{{ .Values.openlitespeed }}-vhosts-pvc", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
volumeName: "{{ .Values.openlitespeed }}-vhosts-pv"
|
||||
volumeMode: Filesystem
|
||||
accessModes: [ ReadWriteMany ]
|
||||
resources: { requests: { storage: 500Gi } }
|
||||
storageClassName: ""
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata: { name: "{{ .Values.openlitespeed }}-config-pv" }
|
||||
spec:
|
||||
capacity: { storage: 1Gi }
|
||||
volumeMode: Filesystem
|
||||
accessModes: [ ReadWriteMany ]
|
||||
persistentVolumeReclaimPolicy: Retain
|
||||
hostPath: { path: "{{ .Values.openlitespeedConfigPath }}", type: DirectoryOrCreate }
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata: { name: "{{ .Values.openlitespeed }}-config-pvc", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
volumeName: "{{ .Values.openlitespeed }}-config-pv"
|
||||
volumeMode: Filesystem
|
||||
accessModes: [ ReadWriteMany ]
|
||||
resources: { requests: { storage: 1Gi } }
|
||||
storageClassName: ""
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata: { name: "{{ .Values.openlitespeed }}-admin-pv" }
|
||||
spec:
|
||||
capacity: { storage: 1Gi }
|
||||
volumeMode: Filesystem
|
||||
accessModes: [ ReadWriteMany ]
|
||||
persistentVolumeReclaimPolicy: Retain
|
||||
hostPath: { path: "{{ .Values.openlitespeedAdminPath }}", type: DirectoryOrCreate }
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata: { name: "{{ .Values.openlitespeed }}-admin-pvc", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
volumeName: "{{ .Values.openlitespeed }}-admin-pv"
|
||||
volumeMode: Filesystem
|
||||
accessModes: [ ReadWriteMany ]
|
||||
resources: { requests: { storage: 1Gi } }
|
||||
storageClassName: ""
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata: { name: "{{ .Values.openlitespeed }}-phpini-pv" }
|
||||
spec:
|
||||
capacity: { storage: 1Gi }
|
||||
volumeMode: Filesystem
|
||||
accessModes: [ ReadWriteMany ]
|
||||
persistentVolumeReclaimPolicy: Retain
|
||||
hostPath: { path: "{{ .Values.openlitespeedPhpIniPath }}", type: DirectoryOrCreate }
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata: { name: "{{ .Values.openlitespeed }}-phpini-pvc", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
volumeName: "{{ .Values.openlitespeed }}-phpini-pv"
|
||||
volumeMode: Filesystem
|
||||
accessModes: [ ReadWriteMany ]
|
||||
resources: { requests: { storage: 1Gi } }
|
||||
storageClassName: ""
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata: { name: "{{ .Values.openlitespeed }}-logs-pv" }
|
||||
spec:
|
||||
capacity: { storage: 10Gi }
|
||||
volumeMode: Filesystem
|
||||
accessModes: [ ReadWriteMany ]
|
||||
persistentVolumeReclaimPolicy: Retain
|
||||
storageClassName: ""
|
||||
hostPath: { path: "{{ .Values.openlitespeedLogsPath }}", type: DirectoryOrCreate }
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata: { name: "{{ .Values.openlitespeed }}-logs-pvc", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
volumeName: "{{ .Values.openlitespeed }}-logs-pv"
|
||||
volumeMode: Filesystem
|
||||
accessModes: [ ReadWriteMany ]
|
||||
resources: { requests: { storage: 10Gi } }
|
||||
storageClassName: ""
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata: { name: "{{ .Values.openlitespeed }}-vhost-data-pv" }
|
||||
spec:
|
||||
capacity: { storage: 5Gi }
|
||||
volumeMode: Filesystem
|
||||
accessModes: [ ReadWriteMany ]
|
||||
persistentVolumeReclaimPolicy: Retain
|
||||
hostPath: { path: "{{ .Values.openlitespeedVhostDataPath }}", type: DirectoryOrCreate }
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata: { name: "{{ .Values.openlitespeed }}-vhost-data-pvc", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
volumeName: "{{ .Values.openlitespeed }}-vhost-data-pv"
|
||||
volumeMode: Filesystem
|
||||
accessModes: [ ReadWriteMany ]
|
||||
resources: { requests: { storage: 5Gi } }
|
||||
storageClassName: ""
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata: { name: "{{ .Values.openlitespeed }}-vhost-shared-pv" }
|
||||
spec:
|
||||
capacity: { storage: 1Gi }
|
||||
volumeMode: Filesystem
|
||||
accessModes: [ ReadWriteMany ]
|
||||
persistentVolumeReclaimPolicy: Retain
|
||||
hostPath: { path: "{{ .Values.openlitespeedVhostSharedPath }}", type: DirectoryOrCreate }
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata: { name: "{{ .Values.openlitespeed }}-vhost-shared-pvc", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
volumeName: "{{ .Values.openlitespeed }}-vhost-shared-pv"
|
||||
volumeMode: Filesystem
|
||||
accessModes: [ ReadWriteMany ]
|
||||
resources: { requests: { storage: 1Gi } }
|
||||
storageClassName: ""
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata: { name: "{{ .Values.openlitespeed }}", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
replicas: 2
|
||||
strategy: { type: RollingUpdate, rollingUpdate: { maxSurge: 0, maxUnavailable: 1 } }
|
||||
selector: { matchLabels: { app: "{{ .Values.openlitespeed }}" } }
|
||||
template:
|
||||
metadata: { labels: { app: "{{ .Values.openlitespeed }}" } }
|
||||
spec:
|
||||
initContainers:
|
||||
- name: "{{ .Values.openlitespeed }}-init"
|
||||
image: litespeedtech/openlitespeed:1.8.5-lsphp85
|
||||
command: ["sh", "-c"]
|
||||
args:
|
||||
- |
|
||||
if [ ! -f /mnt/config/httpd_config.conf ]; then
|
||||
cp -a /usr/local/lsws/conf/. /mnt/config/
|
||||
fi
|
||||
if [ ! -f /mnt/admin/admin_config.conf ]; then
|
||||
cp -a /usr/local/lsws/admin/conf/. /mnt/admin/
|
||||
fi
|
||||
volumeMounts:
|
||||
- { name: "{{ .Values.openlitespeed }}-config-volume", mountPath: /mnt/config }
|
||||
- { name: "{{ .Values.openlitespeed }}-admin-volume", mountPath: /mnt/admin }
|
||||
shareProcessNamespace: true
|
||||
containers:
|
||||
- name: "{{ .Values.openlitespeed }}"
|
||||
image: litespeedtech/openlitespeed:1.8.5-lsphp85
|
||||
ports:
|
||||
- { containerPort: 80 }
|
||||
- { containerPort: 7080 }
|
||||
resources:
|
||||
requests: { cpu: "{{ .Values.profiles.openlitespeed.cpuRequest }}", memory: "{{ .Values.profiles.openlitespeed.memoryRequest }}" }
|
||||
limits: { cpu: "{{ .Values.profiles.openlitespeed.cpuLimit }}", memory: "{{ .Values.profiles.openlitespeed.memoryLimit }}" }
|
||||
readinessProbe: { tcpSocket: { port: 80 }, initialDelaySeconds: 5, periodSeconds: 5, failureThreshold: 3 }
|
||||
livenessProbe: { tcpSocket: { port: 80 }, initialDelaySeconds: 10, periodSeconds: 10, failureThreshold: 5 }
|
||||
volumeMounts:
|
||||
- { name: "{{ .Values.openlitespeed }}-vhosts-volume", mountPath: /var/www/vhosts }
|
||||
- { name: "{{ .Values.openlitespeed }}-config-volume", mountPath: /usr/local/lsws/conf }
|
||||
- { name: "{{ .Values.openlitespeed }}-admin-volume", mountPath: /usr/local/lsws/admin/conf }
|
||||
- { name: "{{ .Values.openlitespeed }}-phpini-volume", mountPath: /etc/ols-php-ini }
|
||||
- { name: "{{ .Values.openlitespeed }}-logs-volume", mountPath: /usr/local/lsws/logs }
|
||||
- { name: "{{ .Values.openlitespeed }}-cache-volume", mountPath: /usr/local/lsws/cachedata }
|
||||
- { name: "{{ .Values.openlitespeed }}-tmp-volume", mountPath: /tmp/lshttpd }
|
||||
- { name: "{{ .Values.openlitespeed }}-vhost-data-volume", mountPath: /var/www/data, readOnly: true }
|
||||
- { name: "{{ .Values.openlitespeed }}-vhost-shared-volume", mountPath: /var/www/shared, readOnly: true }
|
||||
volumes:
|
||||
- name: "{{ .Values.openlitespeed }}-vhosts-volume"
|
||||
persistentVolumeClaim: { claimName: "{{ .Values.openlitespeed }}-vhosts-pvc" }
|
||||
- name: "{{ .Values.openlitespeed }}-config-volume"
|
||||
persistentVolumeClaim: { claimName: "{{ .Values.openlitespeed }}-config-pvc" }
|
||||
- name: "{{ .Values.openlitespeed }}-admin-volume"
|
||||
persistentVolumeClaim: { claimName: "{{ .Values.openlitespeed }}-admin-pvc" }
|
||||
- name: "{{ .Values.openlitespeed }}-phpini-volume"
|
||||
persistentVolumeClaim: { claimName: "{{ .Values.openlitespeed }}-phpini-pvc" }
|
||||
- name: "{{ .Values.openlitespeed }}-logs-volume"
|
||||
persistentVolumeClaim: { claimName: "{{ .Values.openlitespeed }}-logs-pvc" }
|
||||
- name: "{{ .Values.openlitespeed }}-cache-volume"
|
||||
emptyDir: { sizeLimit: 100Gi }
|
||||
- name: "{{ .Values.openlitespeed }}-tmp-volume"
|
||||
emptyDir: { sizeLimit: 100Gi }
|
||||
- name: "{{ .Values.openlitespeed }}-vhost-data-volume"
|
||||
persistentVolumeClaim: { claimName: "{{ .Values.openlitespeed }}-vhost-data-pvc" }
|
||||
- name: "{{ .Values.openlitespeed }}-vhost-shared-volume"
|
||||
persistentVolumeClaim: { claimName: "{{ .Values.openlitespeed }}-vhost-shared-pvc" }
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata: { name: "{{ .Values.openlitespeed }}", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
selector: { app: "{{ .Values.openlitespeed }}" }
|
||||
ports:
|
||||
- { name: http, protocol: TCP, port: 80, targetPort: 80 }
|
||||
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata: { name: "{{ .Values.openlitespeed }}-ingress", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
ingressClassName: traefik
|
||||
rules:
|
||||
- http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service: { name: "{{ .Values.openlitespeed }}", port: { number: 80 } }
|
||||
|
||||
# -------------------------
|
||||
# Admin panel
|
||||
# -------------------------
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata: { name: "{{ .Values.openlitespeed }}-admin", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
selector: { app: "{{ .Values.openlitespeed }}" }
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- { name: admin, protocol: TCP, port: 7080, targetPort: 7080 }
|
||||
|
||||
---
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: MiddlewareTCP
|
||||
metadata: { name: "{{ .Values.openlitespeed }}-admin-allowlist", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
ipAllowList: { sourceRange: [ {{ .Values.openlitespeedAdminWhiteList }} ] }
|
||||
|
||||
---
|
||||
apiVersion: traefik.io/v1alpha1
|
||||
kind: IngressRouteTCP
|
||||
metadata: { name: "{{ .Values.openlitespeed }}-admin", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
entryPoints: [ "olsadmin" ]
|
||||
routes:
|
||||
- match: HostSNI(`*`)
|
||||
middlewares:
|
||||
- name: "{{ .Values.openlitespeed }}-admin-allowlist"
|
||||
services:
|
||||
- name: "{{ .Values.openlitespeed }}-admin"
|
||||
port: 7080
|
||||
tls:
|
||||
passthrough: true
|
||||
|
||||
---
|
||||
apiVersion: helm.cattle.io/v1
|
||||
kind: HelmChartConfig
|
||||
metadata: { name: traefik, namespace: kube-system }
|
||||
spec:
|
||||
valuesContent: |-
|
||||
ports:
|
||||
olsadmin:
|
||||
port: 9443
|
||||
expose:
|
||||
default: true
|
||||
exposedPort: 9443
|
||||
protocol: TCP
|
||||
additionalArguments:
|
||||
- "--entryPoints.olsadmin.address=:9443/tcp"
|
||||
|
||||
{{- end }}
|
||||
@@ -0,0 +1,188 @@
|
||||
{{- if .Values.postfixHelm }}
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata: { name: "{{ .Values.postfix }}-tls", namespace: "{{ .Values.namespace }}" }
|
||||
type: kubernetes.io/tls
|
||||
data:
|
||||
tls.crt: {{ .Values.postfixTlsCrtB64 }}
|
||||
tls.key: {{ .Values.postfixTlsKeyB64 }}
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata: { name: "{{ .Values.postfix }}-sasl", namespace: "{{ .Values.namespace }}" }
|
||||
data:
|
||||
smtpd.conf: |
|
||||
pwcheck_method: auxprop
|
||||
auxprop_plugin: sasldb
|
||||
sasldb_path: /config/sasldb2
|
||||
mech_list: PLAIN LOGIN
|
||||
default_realm: {{ .Values.postfixDefaultRealm }}
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata: { name: "{{ .Values.postfix }}-config-pv" }
|
||||
spec:
|
||||
capacity: { storage: 1Gi }
|
||||
volumeMode: Filesystem
|
||||
accessModes: [ ReadWriteOnce ]
|
||||
persistentVolumeReclaimPolicy: Retain
|
||||
hostPath: { path: "{{ .Values.postfixConfigPath }}", type: DirectoryOrCreate }
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata: { name: "{{ .Values.postfix }}-dkim-pv" }
|
||||
spec:
|
||||
capacity: { storage: 1Gi }
|
||||
volumeMode: Filesystem
|
||||
accessModes: [ ReadWriteOnce ]
|
||||
persistentVolumeReclaimPolicy: Retain
|
||||
hostPath: { path: "{{ .Values.postfixDkimPath }}", type: DirectoryOrCreate }
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata: { name: "{{ .Values.postfix }}-config-pvc", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
volumeName: "{{ .Values.postfix }}-config-pv"
|
||||
volumeMode: Filesystem
|
||||
accessModes: [ ReadWriteOnce ]
|
||||
resources: { requests: { storage: 1Gi } }
|
||||
storageClassName: ""
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata: { name: "{{ .Values.postfix }}-dkim-pvc", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
volumeName: "{{ .Values.postfix }}-dkim-pv"
|
||||
volumeMode: Filesystem
|
||||
accessModes: [ ReadWriteOnce ]
|
||||
resources: { requests: { storage: 1Gi } }
|
||||
storageClassName: ""
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata: { name: "{{ .Values.postfix }}-queue-pvc", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
accessModes: ["ReadWriteOnce"]
|
||||
resources: { requests: { storage: 5Gi } }
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata: { name: "{{ .Values.postfix }}", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
replicas: 1
|
||||
selector: { matchLabels: { app: "{{ .Values.postfix }}" } }
|
||||
template:
|
||||
metadata: { labels: { app: "{{ .Values.postfix }}" } }
|
||||
spec:
|
||||
enableServiceLinks: false
|
||||
initContainers:
|
||||
- name: "{{ .Values.postfix }}-dkim-init"
|
||||
image: boky/postfix:4.4.0-alpine
|
||||
imagePullPolicy: IfNotPresent
|
||||
command: ["/bin/sh", "-lc"]
|
||||
args:
|
||||
- |
|
||||
set -e
|
||||
if [ ! -f /dkim/opendkim.conf ]; then
|
||||
cp -a /etc/opendkim/* /dkim/
|
||||
fi
|
||||
touch /dkim/TrustedHosts /dkim/SigningTable /dkim/KeyTable
|
||||
chown opendkim:opendkim /dkim/TrustedHosts /dkim/KeyTable /dkim/SigningTable
|
||||
chmod 0644 /dkim/TrustedHosts /dkim/KeyTable /dkim/SigningTable
|
||||
printf '%s\n' 127.0.0.1 localhost 10.42.0.0/16 10.43.0.0/16 > /dkim/TrustedHosts
|
||||
|
||||
volumeMounts:
|
||||
- name: "{{ .Values.postfix }}-dkim-volume"
|
||||
mountPath: /dkim
|
||||
containers:
|
||||
- name: "{{ .Values.postfix }}"
|
||||
image: boky/postfix:4.4.0-alpine
|
||||
ports:
|
||||
- { containerPort: 25, name: smtp }
|
||||
- { containerPort: 587, name: submission }
|
||||
env:
|
||||
- { name: POSTFIX_myhostname, value: "{{ .Values.postfixHost }}" }
|
||||
- { name: POSTFIX_smtpd_banner, value: "$myhostname ESMTP" }
|
||||
- { name: POSTFIX_mynetworks, value: "127.0.0.0/8" }
|
||||
- { name: POSTFIX_inet_interfaces, value: "all" }
|
||||
|
||||
# Rules
|
||||
- { name: POSTFIX_smtpd_client_restrictions, value: "permit_mynetworks, permit_sasl_authenticated, reject" }
|
||||
- { name: POSTFIX_smtpd_relay_restrictions, value: "permit_sasl_authenticated, reject_unauth_destination" }
|
||||
- { name: POSTFIX_smtpd_sender_restrictions, value: "reject_non_fqdn_sender,reject_unknown_sender_domain,reject_sender_login_mismatch,permit_sasl_authenticated,reject_unauth_destination" }
|
||||
|
||||
# TLS
|
||||
- { name: POSTFIX_smtpd_tls_cert_file, value: "/etc/ssl/mail/tls.crt" }
|
||||
- { name: POSTFIX_smtpd_tls_key_file, value: "/etc/ssl/mail/tls.key" }
|
||||
- { name: POSTFIX_smtpd_tls_security_level, value: "may" }
|
||||
- { name: POSTFIX_smtp_tls_security_level, value: "may" }
|
||||
|
||||
# SASL (Cyrus, sasldb2)
|
||||
- { name: POSTFIX_smtpd_sasl_auth_enable, value: "yes" }
|
||||
- { name: POSTFIX_smtpd_sasl_type, value: "cyrus" }
|
||||
- { name: POSTFIX_smtpd_sasl_path, value: "smtpd" }
|
||||
- { name: POSTFIX_cyrus_sasl_config_path, value: "/etc/sasl2" }
|
||||
|
||||
# Maps (Virtual domain/alias and senders)
|
||||
- { name: POSTFIX_virtual_alias_domains, value: "lmdb:/config/{{ .Values.postfixDomainsFile }}" }
|
||||
- { name: POSTFIX_virtual_alias_maps, value: "lmdb:/config/{{ .Values.postfixAliasesFile }}" }
|
||||
- { name: POSTFIX_smtpd_sender_login_maps, value: "lmdb:/config/{{ .Values.postfixSendersFile }}" }
|
||||
|
||||
# DKIM
|
||||
- { name: DKIM_SELECTOR, value: "{{ .Values.postfixDkimSelector }}" }
|
||||
- { name: POSTFIX_smtpd_milters, value: "inet:localhost:8891" }
|
||||
- { name: POSTFIX_non_smtpd_milters, value: "$smtpd_milters" }
|
||||
- { name: POSTFIX_milter_default_action, value: "accept" }
|
||||
- { name: POSTFIX_milter_protocol, value: "6" }
|
||||
|
||||
# Other
|
||||
- { name: ALLOW_EMPTY_SENDER_DOMAINS, value: "true" }
|
||||
- { name: ALLOWED_SENDER_DOMAINS, value: "" }
|
||||
|
||||
volumeMounts:
|
||||
- { name: "{{ .Values.postfix }}-tls-volume", mountPath: /etc/ssl/mail, readOnly: true }
|
||||
- { name: "{{ .Values.postfix }}-sasl-volume", mountPath: /etc/sasl2 }
|
||||
- { name: "{{ .Values.postfix }}-config-volume", mountPath: /config }
|
||||
- { name: "{{ .Values.postfix }}-dkim-volume", mountPath: /etc/opendkim }
|
||||
- { name: "{{ .Values.postfix }}-dkim-volume", mountPath: /etc/opendkim/keys, subPath: keys }
|
||||
- { name: "{{ .Values.postfix }}-queue-volume", mountPath: /var/spool/postfix }
|
||||
volumes:
|
||||
- name: "{{ .Values.postfix }}-tls-volume"
|
||||
secret: { secretName: "{{ .Values.postfix }}-tls" }
|
||||
- name: "{{ .Values.postfix }}-sasl-volume"
|
||||
configMap: { name: "{{ .Values.postfix }}-sasl" }
|
||||
- name: "{{ .Values.postfix }}-config-volume"
|
||||
persistentVolumeClaim: { claimName: "{{ .Values.postfix }}-config-pvc" }
|
||||
- name: "{{ .Values.postfix }}-dkim-volume"
|
||||
persistentVolumeClaim: { claimName: "{{ .Values.postfix }}-dkim-pvc" }
|
||||
- name: "{{ .Values.postfix }}-queue-volume"
|
||||
persistentVolumeClaim: { claimName: "{{ .Values.postfix }}-queue-pvc" }
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata: { name: "{{ .Values.postfix }}-public", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
type: LoadBalancer
|
||||
externalTrafficPolicy: Local
|
||||
selector: { app: "{{ .Values.postfix }}" }
|
||||
ports: [ { name: smtp, port: 25, targetPort: 25 } ]
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata: { name: "{{ .Values.postfix }}", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
selector: { app: "{{ .Values.postfix }}" }
|
||||
ports: [ { name: submission, port: 587, targetPort: 587 } ]
|
||||
|
||||
{{- end }}
|
||||
@@ -0,0 +1,416 @@
|
||||
{{- if .Values.redisHelm }}
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata: { name: "{{ .Values.redis }}-config", namespace: "{{ .Values.namespace }}" }
|
||||
data:
|
||||
redis.conf: |
|
||||
bind 0.0.0.0
|
||||
port 6379
|
||||
dir /data
|
||||
|
||||
# --- ACL ---
|
||||
aclfile /data-acl/{{ .Values.redisFileUsersAcl }}
|
||||
|
||||
# --- all in one DB ---
|
||||
databases 1
|
||||
|
||||
# --- network ---
|
||||
protected-mode yes
|
||||
tcp-backlog 1024
|
||||
tcp-keepalive 300
|
||||
timeout 0
|
||||
|
||||
# --- connections ---
|
||||
maxclients {{ .Values.profiles.redis.maxClients }}
|
||||
|
||||
# --- memory (tune) ---
|
||||
maxmemory {{ .Values.profiles.redis.maxmemory }}
|
||||
maxmemory-policy allkeys-lfu
|
||||
maxmemory-samples 5
|
||||
maxmemory-eviction-tenacity 10
|
||||
maxmemory-clients 5%
|
||||
client-query-buffer-limit 256mb
|
||||
client-output-buffer-limit normal 0 0 0
|
||||
client-output-buffer-limit replica 256mb 64mb 60
|
||||
client-output-buffer-limit pubsub 32mb 8mb 60
|
||||
|
||||
# --- replication ---
|
||||
replica-serve-stale-data yes
|
||||
replica-read-only yes
|
||||
repl-backlog-size 64mb
|
||||
repl-backlog-ttl 3600
|
||||
min-replicas-to-write 0
|
||||
#min-replicas-max-lag 10
|
||||
|
||||
# --- persistence ---
|
||||
appendonly yes
|
||||
appendfsync everysec
|
||||
aof-rewrite-incremental-fsync yes
|
||||
rdb-save-incremental-fsync yes
|
||||
save ""
|
||||
|
||||
# --- log ---
|
||||
slowlog-log-slower-than 10000
|
||||
slowlog-max-len 128
|
||||
latency-monitor-threshold 0
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolume
|
||||
metadata: { name: "{{ .Values.redis }}-users-pv" }
|
||||
spec:
|
||||
capacity: { storage: 1Gi }
|
||||
volumeMode: Filesystem
|
||||
accessModes: [ ReadWriteMany ]
|
||||
persistentVolumeReclaimPolicy: Retain
|
||||
hostPath: { path: "{{ .Values.redisPath }}", type: DirectoryOrCreate }
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata: { name: "{{ .Values.redis }}-users-pvc", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
volumeName: "{{ .Values.redis }}-users-pv"
|
||||
volumeMode: Filesystem
|
||||
accessModes: [ ReadWriteMany ]
|
||||
resources: { requests: { storage: 1Gi } }
|
||||
storageClassName: ""
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata: { name: "{{ .Values.redis }}", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
serviceName: "{{ .Values.redis }}"
|
||||
replicas: 2
|
||||
selector: { matchLabels: { app: "{{ .Values.redis }}" } }
|
||||
persistentVolumeClaimRetentionPolicy: { whenDeleted: Delete, whenScaled: Retain }
|
||||
template:
|
||||
metadata: { labels: { app: "{{ .Values.redis }}" } }
|
||||
spec:
|
||||
terminationGracePeriodSeconds: 30
|
||||
initContainers:
|
||||
- name: init-redis-acl
|
||||
image: redis:8.6-alpine
|
||||
resources:
|
||||
requests: { cpu: "10m", memory: "32Mi" }
|
||||
limits: { cpu: "100m", memory: "128Mi" }
|
||||
env:
|
||||
- { name: POD_NAME, valueFrom: { fieldRef: { fieldPath: metadata.name } } }
|
||||
- { name: REDIS_PASSWORD, valueFrom: { secretKeyRef: { name: "{{ .Values.redis }}-secret", key: root-password } } }
|
||||
command: ["/bin/sh","-c"]
|
||||
args:
|
||||
- |
|
||||
set -eu
|
||||
ACL="/data-acl/{{ .Values.redisFileUsersAcl }}"
|
||||
HASH=$(printf '%s' "$REDIS_PASSWORD" | sha256sum | awk '{print $1}')
|
||||
mkdir -p /data-acl
|
||||
|
||||
if [ "$POD_NAME" = "{{ .Values.redis }}-0" ]; then
|
||||
tmp="${ACL}.tmp"
|
||||
|
||||
if [ -f "$ACL" ]; then
|
||||
awk '!(tolower($1)=="user" && $2=="default")' "$ACL" > "$tmp"
|
||||
else
|
||||
: > "$tmp"
|
||||
fi
|
||||
|
||||
# default user is used by replication auth and HAProxy health checks
|
||||
printf 'user default on sanitize-payload #%s ~* &* +@all\n' "$HASH" >> "$tmp"
|
||||
mv "$tmp" "$ACL"
|
||||
chmod 600 "$ACL"
|
||||
else
|
||||
i=0
|
||||
while [ ! -f "$ACL" ] && [ $i -lt 300 ]; do
|
||||
sleep 1
|
||||
i=$((i+1))
|
||||
done
|
||||
[ -f "$ACL" ] || exit 1
|
||||
fi
|
||||
volumeMounts:
|
||||
- { name: "{{ .Values.redis }}-users-volume", mountPath: /data-acl }
|
||||
containers:
|
||||
- name: "{{ .Values.redis }}"
|
||||
image: redis:8.6-alpine
|
||||
resources:
|
||||
requests: { cpu: "{{ .Values.profiles.redis.cpuRequest }}", memory: "{{ .Values.profiles.redis.memoryRequest }}" }
|
||||
limits: { cpu: "{{ .Values.profiles.redis.cpuLimit }}", memory: "{{ .Values.profiles.redis.memoryLimit }}" }
|
||||
ports:
|
||||
- { name: redis, containerPort: 6379 }
|
||||
env:
|
||||
- { name: POD_NAME, valueFrom: { fieldRef: { fieldPath: metadata.name } } }
|
||||
- { name: POD_IP, valueFrom: { fieldRef: { fieldPath: status.podIP } } }
|
||||
- { name: REDIS_PASSWORD, valueFrom: { secretKeyRef: { name: "{{ .Values.redis }}-secret", key: root-password } } }
|
||||
- { name: SENTINEL_HOST, value: "{{ .Values.redisSentinel }}" }
|
||||
- { name: SENTINEL_PORT, value: "26379" }
|
||||
- { name: MASTER_NAME, value: "mymaster" }
|
||||
command: ["/bin/sh","-c"]
|
||||
args:
|
||||
- |
|
||||
set -eu
|
||||
|
||||
POD_DNS_SHORT="${POD_NAME}.{{ .Values.redis }}"
|
||||
POD_DNS_FQDN="${POD_NAME}.{{ .Values.redis }}.{{ .Values.namespace }}.svc.cluster.local"
|
||||
|
||||
get_master() {
|
||||
REDISCLI_AUTH="$REDIS_PASSWORD" \
|
||||
redis-cli -h "$SENTINEL_HOST" -p "$SENTINEL_PORT" \
|
||||
SENTINEL get-master-addr-by-name "$MASTER_NAME" 2>/dev/null | tr -d '\r'
|
||||
}
|
||||
|
||||
out=""
|
||||
i=0
|
||||
while [ $i -lt 20 ]; do
|
||||
out="$(get_master || true)"
|
||||
[ -n "$out" ] && break
|
||||
i=$((i+1))
|
||||
sleep 1
|
||||
done
|
||||
|
||||
master_host="$(printf '%s\n' "$out" | sed -n '1p')"
|
||||
master_port="$(printf '%s\n' "$out" | sed -n '2p')"
|
||||
[ -n "$master_port" ] || master_port="6379"
|
||||
|
||||
is_me_master() {
|
||||
[ "$master_host" = "$POD_IP" ] || [ "$master_host" = "$POD_DNS_SHORT" ] || [ "$master_host" = "$POD_DNS_FQDN" ]
|
||||
}
|
||||
|
||||
if [ -n "$master_host" ]; then
|
||||
if is_me_master; then
|
||||
exec redis-server /etc/redis/redis.conf --masteruser default --masterauth "$REDIS_PASSWORD"
|
||||
else
|
||||
exec redis-server /etc/redis/redis.conf --replicaof "$master_host" "$master_port" --masteruser default --masterauth "$REDIS_PASSWORD"
|
||||
fi
|
||||
else
|
||||
# bootstrap if sentinel is not ready yet
|
||||
if [ "$POD_NAME" = "{{ .Values.redis }}-0" ]; then
|
||||
exec redis-server /etc/redis/redis.conf
|
||||
else
|
||||
exec redis-server /etc/redis/redis.conf --replicaof {{ .Values.redis }}-0.{{ .Values.redis }} 6379 --masteruser default --masterauth "$REDIS_PASSWORD"
|
||||
fi
|
||||
fi
|
||||
volumeMounts:
|
||||
- { name: "{{ .Values.redis }}-data-volume", mountPath: /data }
|
||||
- { name: "{{ .Values.redis }}-config-volume", mountPath: /etc/redis }
|
||||
- { name: "{{ .Values.redis }}-users-volume", mountPath: /data-acl }
|
||||
volumes:
|
||||
- name: "{{ .Values.redis }}-config-volume"
|
||||
configMap: { name: "{{ .Values.redis }}-config" }
|
||||
- name: "{{ .Values.redis }}-users-volume"
|
||||
persistentVolumeClaim: { claimName: "{{ .Values.redis }}-users-pvc" }
|
||||
volumeClaimTemplates:
|
||||
- metadata: { name: "{{ .Values.redis }}-data-volume" }
|
||||
spec:
|
||||
accessModes: [ ReadWriteOnce ]
|
||||
resources: { requests: { storage: 10Gi } }
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata: { name: "{{ .Values.redis }}", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
clusterIP: None
|
||||
selector: { app: "{{ .Values.redis }}" }
|
||||
ports:
|
||||
- { name: redis, protocol: TCP, port: 6379, targetPort: 6379 }
|
||||
|
||||
# -------------------------
|
||||
# Sentinel (1) with PVC
|
||||
# -------------------------
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata: { name: "{{ .Values.redisSentinel }}-config", namespace: "{{ .Values.namespace }}" }
|
||||
data:
|
||||
sentinel.conf.tmpl: |
|
||||
bind 0.0.0.0
|
||||
port 26379
|
||||
dir /data
|
||||
|
||||
sentinel deny-scripts-reconfig yes
|
||||
sentinel resolve-hostnames yes
|
||||
sentinel announce-hostnames yes
|
||||
|
||||
# quorum=1 (single sentinel)
|
||||
sentinel monitor mymaster {{ .Values.redis }}-0.{{ .Values.redis }} 6379 1
|
||||
sentinel down-after-milliseconds mymaster 5000
|
||||
sentinel failover-timeout mymaster 60000
|
||||
sentinel parallel-syncs mymaster 1
|
||||
|
||||
sentinel auth-user mymaster default
|
||||
sentinel auth-pass mymaster __PASSWORD__
|
||||
|
||||
requirepass __PASSWORD__
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata: { name: "{{ .Values.redisSentinel }}", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
replicas: 1
|
||||
serviceName: "{{ .Values.redisSentinel }}"
|
||||
selector: { matchLabels: { app: "{{ .Values.redisSentinel }}" } }
|
||||
persistentVolumeClaimRetentionPolicy: { whenDeleted: Delete, whenScaled: Retain }
|
||||
template:
|
||||
metadata: { labels: { app: "{{ .Values.redisSentinel }}" } }
|
||||
spec:
|
||||
containers:
|
||||
- name: "{{ .Values.redisSentinel }}"
|
||||
image: redis:8.6-alpine
|
||||
resources:
|
||||
requests: { cpu: "50m", memory: "128Mi" }
|
||||
limits: { cpu: "200m", memory: "256Mi" }
|
||||
ports:
|
||||
- { name: sentinel, containerPort: 26379 }
|
||||
env:
|
||||
- { name: REDIS_PASSWORD, valueFrom: { secretKeyRef: { name: "{{ .Values.redis }}-secret", key: root-password } } }
|
||||
command: ["/bin/sh","-c"]
|
||||
args:
|
||||
- |
|
||||
set -eu
|
||||
CONF=/data/sentinel.conf
|
||||
if [ ! -f "$CONF" ]; then
|
||||
pwd_escaped=$(printf '%s' "$REDIS_PASSWORD" | sed -e 's/[\/&]/\\&/g')
|
||||
sed "s/__PASSWORD__/${pwd_escaped}/g" /tmpl/sentinel.conf.tmpl > "$CONF"
|
||||
chmod 600 "$CONF"
|
||||
fi
|
||||
exec redis-server "$CONF" --sentinel
|
||||
volumeMounts:
|
||||
- { name: "{{ .Values.redisSentinel }}-tmpl", mountPath: /tmpl }
|
||||
- { name: "{{ .Values.redisSentinel }}-data", mountPath: /data }
|
||||
volumes:
|
||||
- name: "{{ .Values.redisSentinel }}-tmpl"
|
||||
configMap: { name: "{{ .Values.redisSentinel }}-config" }
|
||||
volumeClaimTemplates:
|
||||
- metadata: { name: "{{ .Values.redisSentinel }}-data" }
|
||||
spec:
|
||||
accessModes: [ ReadWriteOnce ]
|
||||
resources: { requests: { storage: 1Gi } }
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata: { name: "{{ .Values.redisSentinel }}", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
selector: { app: "{{ .Values.redisSentinel }}" }
|
||||
ports:
|
||||
- { name: sentinel, port: 26379, targetPort: 26379 }
|
||||
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata: { name: "{{ .Values.redisSentinel }}-allow-only-checker", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
podSelector: { matchLabels: { app: "{{ .Values.redisSentinel }}" } }
|
||||
policyTypes:
|
||||
- Ingress
|
||||
ingress:
|
||||
- from:
|
||||
- podSelector: { matchLabels: { app: "{{ .Values.redis }}" } }
|
||||
- podSelector: { matchLabels: { app: "{{ .Values.redisSentinel }}" } }
|
||||
ports:
|
||||
- { protocol: TCP, port: 26379 }
|
||||
|
||||
# -------------------------
|
||||
# HAProxy: single master endpoint
|
||||
# -------------------------
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata: { name: "{{ .Values.redis }}-haproxy-config", namespace: "{{ .Values.namespace }}" }
|
||||
data:
|
||||
haproxy.cfg: |
|
||||
global
|
||||
log stdout format raw local0
|
||||
maxconn 20000
|
||||
|
||||
resolvers kubedns
|
||||
nameserver dns1 10.43.0.10:53
|
||||
accepted_payload_size 8192
|
||||
resolve_retries 3
|
||||
timeout resolve 1s
|
||||
timeout retry 1s
|
||||
hold valid 10s
|
||||
hold obsolete 30s
|
||||
|
||||
defaults
|
||||
mode tcp
|
||||
log global
|
||||
option tcplog
|
||||
option log-health-checks
|
||||
timeout connect 5s
|
||||
timeout client 1m
|
||||
timeout server 1m
|
||||
timeout check 1s
|
||||
|
||||
frontend fe_redis_master
|
||||
bind *:6379
|
||||
default_backend be_redis_master
|
||||
|
||||
backend be_redis_master
|
||||
mode tcp
|
||||
balance first
|
||||
option tcp-check
|
||||
option srvtcpka
|
||||
timeout queue 2s
|
||||
timeout connect 2s
|
||||
timeout check 3s
|
||||
timeout server 10m
|
||||
tcp-check connect
|
||||
tcp-check send-lf "AUTH default $REDIS_PASSWORD\r\n"
|
||||
tcp-check expect string +OK
|
||||
tcp-check send INFO\ replication\r\n
|
||||
tcp-check expect string role:master
|
||||
tcp-check send QUIT\r\n
|
||||
tcp-check expect string +OK
|
||||
server redis0 {{ .Values.redis }}-0.{{ .Values.redis }}.{{ .Values.namespace }}.svc.cluster.local:6379 check resolvers kubedns resolve-prefer ipv4 init-addr libc,none inter 5s fall 2 rise 2
|
||||
server redis1 {{ .Values.redis }}-1.{{ .Values.redis }}.{{ .Values.namespace }}.svc.cluster.local:6379 check resolvers kubedns resolve-prefer ipv4 init-addr libc,none inter 5s fall 2 rise 2
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata: { name: "{{ .Values.redis }}-haproxy", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
replicas: 1
|
||||
selector: { matchLabels: { app: "{{ .Values.redis }}-haproxy" } }
|
||||
template:
|
||||
metadata:
|
||||
labels: { app: "{{ .Values.redis }}-haproxy" }
|
||||
spec:
|
||||
containers:
|
||||
- name: "{{ .Values.redis }}-haproxy"
|
||||
image: haproxy:2.9-alpine
|
||||
resources:
|
||||
requests: { cpu: "50m", memory: "64Mi" }
|
||||
limits: { cpu: "500m", memory: "256Mi" }
|
||||
ports:
|
||||
- { name: redis, containerPort: 6379 }
|
||||
env:
|
||||
- { name: REDIS_PASSWORD, valueFrom: { secretKeyRef: { name: "{{ .Values.redis }}-secret", key: root-password } } }
|
||||
command: ["/bin/sh","-c"]
|
||||
args:
|
||||
- |
|
||||
set -eu
|
||||
haproxy -c -f /usr/local/etc/haproxy/haproxy.cfg
|
||||
exec haproxy -f /usr/local/etc/haproxy/haproxy.cfg -db
|
||||
readinessProbe: { tcpSocket: { port: 6379 }, initialDelaySeconds: 1, periodSeconds: 2, failureThreshold: 3 }
|
||||
livenessProbe: { tcpSocket: { port: 6379 }, initialDelaySeconds: 10, periodSeconds: 10, failureThreshold: 3 }
|
||||
volumeMounts:
|
||||
# - { name: cfg, mountPath: /usr/local/etc/haproxy/haproxy.cfg, subPath: haproxy.cfg }
|
||||
- { name: cfg, mountPath: /usr/local/etc/haproxy }
|
||||
volumes:
|
||||
- name: cfg
|
||||
configMap: { name: "{{ .Values.redis }}-haproxy-config" }
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata: { name: "{{ .Values.redis }}-master", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
selector: { app: "{{ .Values.redis }}-haproxy" }
|
||||
ports:
|
||||
- { name: redis, port: 6379, targetPort: 6379 }
|
||||
|
||||
{{- end }}
|
||||
@@ -0,0 +1,52 @@
|
||||
{{- if .Values.workerHelm }}
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata: { name: "{{ .Values.worker }}", namespace: "{{ .Values.namespace }}" }
|
||||
spec:
|
||||
replicas: 1
|
||||
selector: { matchLabels: { app: "{{ .Values.worker }}" } }
|
||||
template:
|
||||
metadata: { labels: { app: "{{ .Values.worker }}" } }
|
||||
spec:
|
||||
containers:
|
||||
- name: "{{ .Values.worker }}"
|
||||
image: python:3.12-slim
|
||||
imagePullPolicy: IfNotPresent
|
||||
resources:
|
||||
requests: { cpu: "50m", memory: "64Mi" }
|
||||
limits: { cpu: "200m", memory: "256Mi" }
|
||||
ports:
|
||||
- { containerPort: 8080 }
|
||||
workingDir: /app/agent
|
||||
command: ["/bin/sh","-c"]
|
||||
args:
|
||||
- |
|
||||
set -e
|
||||
if [ ! -f /app/agent/worker.py ]; then
|
||||
echo "ERROR: /app/agent/worker.py not found" >&2
|
||||
ls -la /app/agent >&2 || true
|
||||
exit 1
|
||||
fi
|
||||
exec python -u /app/agent/worker.py
|
||||
env:
|
||||
- { name: WORKER_UUID, value: "{{ .Values.workerUuid }}" }
|
||||
- { name: WORKER_NAME, value: "{{ .Values.workerName }}" }
|
||||
- { name: WORKER_POOL, value: "{{ .Values.workerPool }}" }
|
||||
- { name: API_URL, value: "{{ .Values.workerApiUrl }}" }
|
||||
- { name: GETTING_PAUSE, value: "{{ .Values.workerApiGettingPause }}" }
|
||||
- { name: SENDING_PAUSE, value: "{{ .Values.workerApiSendingPause }}" }
|
||||
volumeMounts:
|
||||
- { name: "{{ .Values.worker }}-agent-volume", mountPath: /app/agent }
|
||||
- { name: "{{ .Values.worker }}-tasks-volume", mountPath: /app/tasks }
|
||||
readinessProbe: { httpGet: { path: /healthz, port: 8080 }, periodSeconds: 5, timeoutSeconds: 2 }
|
||||
livenessProbe: { httpGet: { path: /healthz, port: 8080 }, periodSeconds: 10, timeoutSeconds: 2, failureThreshold: 3 }
|
||||
startupProbe: { httpGet: { path: /healthz, port: 8080 }, periodSeconds: 2, timeoutSeconds: 2, failureThreshold: 30 }
|
||||
volumes:
|
||||
- name: "{{ .Values.worker }}-agent-volume"
|
||||
hostPath: { path: "{{ .Values.workerAgentPath }}", type: DirectoryOrCreate }
|
||||
- name: "{{ .Values.worker }}-tasks-volume"
|
||||
hostPath: { path: "{{ .Values.workerTasksPath }}", type: DirectoryOrCreate }
|
||||
|
||||
{{- end }}
|
||||
Reference in New Issue
Block a user