Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
33a91223a3 | ||
|
|
87e7bcebcf | ||
|
|
cd8cb1f586 | ||
|
|
729e808b13 | ||
|
|
af717cc530 | ||
|
|
56c4c3871a | ||
|
|
8dd1868c25 | ||
|
|
5eaee8c7b7 | ||
|
|
7e7813bfe0 | ||
|
|
a79c695a40 | ||
|
|
29d95cd853 | ||
|
|
8a90756af0 | ||
|
|
52780edbb5 | ||
|
|
8a4849733c | ||
|
|
8e99f42815 | ||
|
|
c4b608b621 | ||
|
|
dd0f664324 | ||
|
|
04610cc6e2 | ||
|
|
aaa1e9ae7e | ||
|
|
47589988bf | ||
|
|
2a08898a23 | ||
|
|
9b0530fb70 | ||
|
|
ba1fcae807 | ||
|
|
da97f66448 | ||
|
|
2a89c89754 | ||
|
|
8e4201621d | ||
|
|
ee7a82b0b8 | ||
|
|
6da0a39428 | ||
|
|
4c744e539c | ||
|
|
e94caf8054 | ||
|
|
46bc178dab | ||
|
|
d1d28776cd | ||
|
|
1991ffc1e3 | ||
|
|
d8973e2daa | ||
|
|
f2d5b97465 | ||
|
|
ac8e5e127c | ||
|
|
52bfa88a33 | ||
|
|
089bc9bfb5 | ||
|
|
070176030c | ||
|
|
b6c671bc23 | ||
|
|
04c35083ef | ||
|
|
be9ace99bc | ||
|
|
1b41eee364 | ||
|
|
373ce77ac8 | ||
|
|
bd88daa109 | ||
|
|
1c7185aed6 | ||
|
|
6d39028e2f | ||
|
|
4159a6c045 | ||
|
|
5f0a3ca3b6 | ||
|
|
07cdc88568 | ||
|
|
b11b7c902d | ||
|
|
ff4e87aca0 | ||
|
|
01561ea2cd | ||
|
|
7db427f332 | ||
|
|
41729bf256 | ||
|
|
fe914e2de4 | ||
|
|
0348329829 | ||
|
|
e257e3895b | ||
|
|
4fe2a2b5f3 | ||
|
|
690ff2a19c | ||
|
|
99e1818572 | ||
|
|
cf88753ff5 | ||
|
|
862a7619e2 | ||
|
|
5a29dcc236 |
No files matched your search
@@ -30,9 +30,11 @@ jobs:
|
|||||||
cli_config_credentials_token: ${{ secrets.TF_API_TOKEN }}
|
cli_config_credentials_token: ${{ secrets.TF_API_TOKEN }}
|
||||||
|
|
||||||
- name: Setup kubeconfig
|
- name: Setup kubeconfig
|
||||||
|
env:
|
||||||
|
CI_KUBECONFIG: ${{ secrets.KUBECONFIG }}
|
||||||
run: |
|
run: |
|
||||||
mkdir -p ~/.kube
|
mkdir -p ~/.kube
|
||||||
echo "${{ secrets.KUBECONFIG }}" > ~/.kube/config
|
printf '%s' "$CI_KUBECONFIG" > ~/.kube/config
|
||||||
chmod 600 ~/.kube/config
|
chmod 600 ~/.kube/config
|
||||||
|
|
||||||
- name: Terraform Init
|
- name: Terraform Init
|
||||||
|
|||||||
@@ -59,3 +59,6 @@ tags
|
|||||||
[._]*.un~
|
[._]*.un~
|
||||||
|
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
|
||||||
|
# Helm charts pulled by kustomize (--enable-helm) when rendering locally
|
||||||
|
k8s-ng/**/charts/
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: furumi-player
|
||||||
|
labels:
|
||||||
|
app: furumi-player
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
strategy:
|
||||||
|
type: Recreate # the library is a hostPath on a single node
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: furumi-player
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: furumi-player
|
||||||
|
annotations:
|
||||||
|
reloader.stakater.com/auto: "true"
|
||||||
|
spec:
|
||||||
|
# The music library lives on this node's /data (LVM raid, not replicated).
|
||||||
|
nodeSelector:
|
||||||
|
kubernetes.io/hostname: music
|
||||||
|
containers:
|
||||||
|
- name: furumi-player
|
||||||
|
image: ultradesu/furumusic:latest
|
||||||
|
imagePullPolicy: Always
|
||||||
|
env:
|
||||||
|
- name: FURU_DATABASE_URL
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: furumi-creds
|
||||||
|
key: PG_STRING
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: 8000
|
||||||
|
volumeMounts:
|
||||||
|
- name: library
|
||||||
|
mountPath: /media
|
||||||
|
- name: inbox
|
||||||
|
mountPath: /inbox
|
||||||
|
volumes:
|
||||||
|
- name: library
|
||||||
|
hostPath:
|
||||||
|
path: /data/furumi/library
|
||||||
|
type: Directory
|
||||||
|
- name: inbox
|
||||||
|
hostPath:
|
||||||
|
path: /data/furumi/inbox
|
||||||
|
type: Directory
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: furumi
|
||||||
|
annotations:
|
||||||
|
cert-manager.io/cluster-issuer: letsencrypt
|
||||||
|
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||||
|
spec:
|
||||||
|
ingressClassName: traefik
|
||||||
|
rules:
|
||||||
|
- host: music.hexor.cy
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: furumi-player
|
||||||
|
port:
|
||||||
|
number: 8000
|
||||||
|
tls:
|
||||||
|
- secretName: furumi-tls
|
||||||
|
hosts:
|
||||||
|
- music.hexor.cy
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
|
||||||
|
resources:
|
||||||
|
- secrets.yaml
|
||||||
|
- deployment.yaml
|
||||||
|
- service.yaml
|
||||||
|
- servicemonitor.yaml
|
||||||
|
- ingress.yaml
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
# Read-only access to the furumi-db Secret in the psql namespace
|
||||||
|
# (see postgresql/databases/furumi.yaml for the other half).
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: db-credentials-reader
|
||||||
|
---
|
||||||
|
apiVersion: external-secrets.io/v1
|
||||||
|
kind: SecretStore
|
||||||
|
metadata:
|
||||||
|
name: psql-credentials
|
||||||
|
spec:
|
||||||
|
provider:
|
||||||
|
kubernetes:
|
||||||
|
remoteNamespace: psql
|
||||||
|
server:
|
||||||
|
caProvider:
|
||||||
|
type: ConfigMap
|
||||||
|
name: kube-root-ca.crt
|
||||||
|
key: ca.crt
|
||||||
|
auth:
|
||||||
|
serviceAccount:
|
||||||
|
name: db-credentials-reader
|
||||||
|
---
|
||||||
|
apiVersion: external-secrets.io/v1
|
||||||
|
kind: ExternalSecret
|
||||||
|
metadata:
|
||||||
|
name: furumi-creds
|
||||||
|
spec:
|
||||||
|
refreshInterval: 1h
|
||||||
|
secretStoreRef:
|
||||||
|
kind: SecretStore
|
||||||
|
name: psql-credentials
|
||||||
|
target:
|
||||||
|
name: furumi-creds
|
||||||
|
template:
|
||||||
|
data:
|
||||||
|
PG_STRING: "postgresql://{{ .username }}:{{ .password }}@main-rw.psql.svc:5432/furumi"
|
||||||
|
data:
|
||||||
|
- secretKey: username
|
||||||
|
remoteRef:
|
||||||
|
key: furumi-db
|
||||||
|
property: username
|
||||||
|
- secretKey: password
|
||||||
|
remoteRef:
|
||||||
|
key: furumi-db
|
||||||
|
property: password
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: furumi-player
|
||||||
|
labels:
|
||||||
|
app: furumi-player
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
selector:
|
||||||
|
app: furumi-player
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
protocol: TCP
|
||||||
|
port: 8000
|
||||||
|
targetPort: 8000
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
apiVersion: monitoring.coreos.com/v1
|
||||||
|
kind: ServiceMonitor
|
||||||
|
metadata:
|
||||||
|
name: furumi-player
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: furumi-player
|
||||||
|
endpoints:
|
||||||
|
- port: http
|
||||||
|
path: /metrics
|
||||||
|
interval: 30s
|
||||||
|
scrapeTimeout: 10s
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
# k8s-secrets
|
||||||
|
|
||||||
|
The `k8s-secrets` Argo CD Application reads this directory through
|
||||||
|
`core-state/values.yaml` and deploys into namespace `k8s-secret`.
|
||||||
|
|
||||||
|
External Secrets loads the `k8s/openai/creds` Vaultwarden item into
|
||||||
|
`openai-creds`. The reader at `pass.hexor.cy` can only read that Secret and is
|
||||||
|
protected by the Keycloak forward-auth proxy. Its access policy is managed in
|
||||||
|
`terraform/keycloak/terraform.tfvars`.
|
||||||
|
|
||||||
|
The Kubernetes resource names and namespace match the former deployment so
|
||||||
|
Argo CD can switch the source path without replacing the service or certificate.
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
apiVersion: external-secrets.io/v1
|
||||||
|
kind: ExternalSecret
|
||||||
|
metadata:
|
||||||
|
name: openai-creds
|
||||||
|
spec:
|
||||||
|
refreshInterval: 5m
|
||||||
|
secretStoreRef:
|
||||||
|
name: vaultwarden-login
|
||||||
|
kind: ClusterSecretStore
|
||||||
|
target:
|
||||||
|
name: openai-creds
|
||||||
|
creationPolicy: Owner
|
||||||
|
deletionPolicy: Retain
|
||||||
|
template:
|
||||||
|
type: Opaque
|
||||||
|
data:
|
||||||
|
USER: "{{ .user }}"
|
||||||
|
PASS: "{{ .pass }}"
|
||||||
|
TOTP: "{{ .totp }}"
|
||||||
|
data:
|
||||||
|
- secretKey: user
|
||||||
|
remoteRef:
|
||||||
|
key: k8s/openai/creds
|
||||||
|
property: login.username
|
||||||
|
- secretKey: pass
|
||||||
|
remoteRef:
|
||||||
|
key: k8s/openai/creds
|
||||||
|
property: login.password
|
||||||
|
- secretKey: totp
|
||||||
|
remoteRef:
|
||||||
|
key: k8s/openai/creds
|
||||||
|
property: login.totp
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
apiVersion: traefik.io/v1alpha1
|
||||||
|
kind: Middleware
|
||||||
|
metadata:
|
||||||
|
name: auth-proxy
|
||||||
|
spec:
|
||||||
|
forwardAuth:
|
||||||
|
address: http://auth-proxy.keycloak.svc:80/auth
|
||||||
|
trustForwardHeader: false
|
||||||
|
---
|
||||||
|
apiVersion: traefik.io/v1alpha1
|
||||||
|
kind: IngressRoute
|
||||||
|
metadata:
|
||||||
|
name: secret-reader
|
||||||
|
spec:
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
routes:
|
||||||
|
- match: Host(`pass.hexor.cy`)
|
||||||
|
kind: Rule
|
||||||
|
middlewares:
|
||||||
|
- name: auth-proxy
|
||||||
|
services:
|
||||||
|
- name: secret-reader
|
||||||
|
port: 80
|
||||||
|
tls:
|
||||||
|
secretName: secret-reader-tls
|
||||||
|
---
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: Certificate
|
||||||
|
metadata:
|
||||||
|
name: secret-reader-tls
|
||||||
|
spec:
|
||||||
|
secretName: secret-reader-tls
|
||||||
|
issuerRef:
|
||||||
|
name: letsencrypt
|
||||||
|
kind: ClusterIssuer
|
||||||
|
dnsNames:
|
||||||
|
- pass.hexor.cy
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
namespace: k8s-secret
|
||||||
|
resources:
|
||||||
|
- external-secret.yaml
|
||||||
|
- reader.yaml
|
||||||
|
- ingress.yaml
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: secret-reader
|
||||||
|
labels:
|
||||||
|
app: secret-reader
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: Role
|
||||||
|
metadata:
|
||||||
|
name: secret-reader
|
||||||
|
rules:
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["secrets"]
|
||||||
|
resourceNames: ["openai-creds"]
|
||||||
|
verbs: ["get"]
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: RoleBinding
|
||||||
|
metadata:
|
||||||
|
name: secret-reader
|
||||||
|
roleRef:
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
kind: Role
|
||||||
|
name: secret-reader
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: secret-reader
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: secret-reader
|
||||||
|
labels:
|
||||||
|
app: secret-reader
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: secret-reader
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: secret-reader
|
||||||
|
spec:
|
||||||
|
serviceAccountName: secret-reader
|
||||||
|
nodeSelector:
|
||||||
|
homelab.hexor.cy/pool: core
|
||||||
|
homelab.hexor.cy/exposure: external
|
||||||
|
securityContext:
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 1000
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
containers:
|
||||||
|
- name: secret-reader
|
||||||
|
image: ultradesu/k8s-secrets:0.2.2@sha256:f206942d21ca9dcd131d6e19ba26cc17671815919217aef657b30a9f85854778
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
args:
|
||||||
|
- --secrets
|
||||||
|
- openai-creds
|
||||||
|
- --namespace
|
||||||
|
- k8s-secret
|
||||||
|
- --port
|
||||||
|
- "3000"
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: 3000
|
||||||
|
env:
|
||||||
|
- name: RUST_LOG
|
||||||
|
value: info
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 50m
|
||||||
|
memory: 64Mi
|
||||||
|
limits:
|
||||||
|
cpu: 150m
|
||||||
|
memory: 128Mi
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
periodSeconds: 5
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: http
|
||||||
|
initialDelaySeconds: 10
|
||||||
|
periodSeconds: 10
|
||||||
|
securityContext:
|
||||||
|
readOnlyRootFilesystem: true
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop: ["ALL"]
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: secret-reader
|
||||||
|
labels:
|
||||||
|
app: secret-reader
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: secret-reader
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 80
|
||||||
|
targetPort: http
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: llamacpp-config
|
||||||
|
data:
|
||||||
|
LLAMA_CACHE: /models
|
||||||
|
LLAMA_ARG_HOST: 0.0.0.0
|
||||||
|
LLAMA_ARG_PORT: "8080"
|
||||||
|
# The model is chosen here: <hf-user>/<repo>:<quant>. It is downloaded into
|
||||||
|
# /models on first start; changing it restarts the pod (reloader).
|
||||||
|
#LLAMA_ARG_HF_REPO: "unsloth/Qwen3.8-27B-GGUF:UD-Q6_K"
|
||||||
|
LLAMA_ARG_HF_REPO: "unsloth/Qwen3.6-35B-A3B-GGUF:UD-Q6_K"
|
||||||
|
LLAMA_ARG_CTX_SIZE: "131072"
|
||||||
|
LLAMA_ARG_N_GPU_LAYERS: all
|
||||||
|
LLAMA_ARG_FLASH_ATTN: "on"
|
||||||
|
LLAMA_ARG_FIT: "on"
|
||||||
|
# Strix Halo: mmap-ed weights hang or corrupt on ROCm; read them directly.
|
||||||
|
LLAMA_ARG_LOAD_MODE: dio
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: llamacpp
|
||||||
|
annotations:
|
||||||
|
reloader.stakater.com/auto: "true"
|
||||||
|
labels:
|
||||||
|
app: llamacpp
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
strategy:
|
||||||
|
type: Recreate # one GPU, one pod
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: llamacpp
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: llamacpp
|
||||||
|
spec:
|
||||||
|
dnsPolicy: Default
|
||||||
|
nodeSelector:
|
||||||
|
homelab.hexor.cy/pool: core
|
||||||
|
homelab.hexor.cy/exposure: internal
|
||||||
|
workload/ai: "true"
|
||||||
|
tolerations:
|
||||||
|
- key: workload
|
||||||
|
operator: Equal
|
||||||
|
value: ai
|
||||||
|
effect: NoSchedule
|
||||||
|
containers:
|
||||||
|
- name: llamacpp
|
||||||
|
image: ghcr.io/ggml-org/llama.cpp:server-rocm-b11434
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
envFrom:
|
||||||
|
- configMapRef:
|
||||||
|
name: llamacpp-config
|
||||||
|
env:
|
||||||
|
- name: HF_TOKEN
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: llamacpp-hf-token
|
||||||
|
key: token
|
||||||
|
optional: true
|
||||||
|
# hipBLASLt gives the biggest prompt-processing gain on ROCm 7.x.
|
||||||
|
- name: ROCBLAS_USE_HIPBLASLT
|
||||||
|
value: "1"
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: 8080
|
||||||
|
protocol: TCP
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
amd.com/gpu: 1
|
||||||
|
startupProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: http
|
||||||
|
failureThreshold: 180 # first start downloads the model
|
||||||
|
periodSeconds: 10
|
||||||
|
timeoutSeconds: 5
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: http
|
||||||
|
failureThreshold: 3
|
||||||
|
periodSeconds: 10
|
||||||
|
timeoutSeconds: 5
|
||||||
|
volumeMounts:
|
||||||
|
- name: models
|
||||||
|
mountPath: /models
|
||||||
|
volumes:
|
||||||
|
- name: models
|
||||||
|
hostPath:
|
||||||
|
path: /var/lib/llamacpp/models
|
||||||
|
type: DirectoryOrCreate
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
|
||||||
|
resources:
|
||||||
|
- configmap.yaml
|
||||||
|
- deployment.yaml
|
||||||
|
- service.yaml
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: llamacpp
|
||||||
|
labels:
|
||||||
|
app: llamacpp
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
selector:
|
||||||
|
app: llamacpp
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 8080
|
||||||
|
targetPort: http
|
||||||
|
protocol: TCP
|
||||||
@@ -0,0 +1,561 @@
|
|||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: nginx-config
|
||||||
|
namespace: minecraft
|
||||||
|
data:
|
||||||
|
nginx.conf: |
|
||||||
|
user nginx;
|
||||||
|
worker_processes 1;
|
||||||
|
error_log /var/log/nginx/error.log warn;
|
||||||
|
pid /var/run/nginx.pid;
|
||||||
|
|
||||||
|
events {
|
||||||
|
worker_connections 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
http {
|
||||||
|
include /etc/nginx/mime.types;
|
||||||
|
default_type application/octet-stream;
|
||||||
|
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
|
||||||
|
# Custom 502 error page with auto-refresh
|
||||||
|
error_page 502 /502.html;
|
||||||
|
location = /502.html {
|
||||||
|
internal;
|
||||||
|
return 200 '<!DOCTYPE html><html><head><meta charset="utf-8"><title>Server Loading</title><style>body{font-family:Arial,sans-serif;text-align:center;margin-top:100px;background:#f0f0f0}h1{color:#333}p{color:#666;font-size:18px}</style></head><body><h1>Server is loading probably...</h1><p>Please wait a moment and try refreshing the page.</p><script>setTimeout(function(){window.location.reload();}, 10000);</script></body></html>';
|
||||||
|
add_header Content-Type text/html;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main location - proxy to Minecraft Dynmap
|
||||||
|
location / {
|
||||||
|
# Proxy configuration for Dynmap server
|
||||||
|
proxy_pass http://localhost:8123;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
|
||||||
|
# Inject user authentication meta tag into HTML head
|
||||||
|
sub_filter '<head>' '<head><meta name="remote-user" content="$http_x_authentik_username">';
|
||||||
|
|
||||||
|
# Replace default Dynmap title with custom server name
|
||||||
|
sub_filter 'Minecraft Dynamic Map' "Hexor's MC server";
|
||||||
|
|
||||||
|
# Inject custom script before closing body tag
|
||||||
|
sub_filter "</body>" '<script src="/clients/inject.js"></script></body>';
|
||||||
|
|
||||||
|
# Apply sub_filter replacements globally (not just once)
|
||||||
|
sub_filter_once off;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Serve inject.js and .ps1 scripts inline (no forced download)
|
||||||
|
location = /clients/inject.js {
|
||||||
|
alias /mc/clients/inject.js;
|
||||||
|
default_type application/javascript;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ ^/clients/(.+\.ps1)$ {
|
||||||
|
alias /mc/clients/$1;
|
||||||
|
default_type text/plain;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Static file serving for client downloads
|
||||||
|
location /clients/ {
|
||||||
|
alias /mc/clients/;
|
||||||
|
sendfile on; # Enable efficient file serving
|
||||||
|
add_header Content-Disposition "attachment"; # Force download
|
||||||
|
autoindex on; # Enable directory listing
|
||||||
|
gzip off; # Disable compression for downloads
|
||||||
|
chunked_transfer_encoding off; # Disable chunked encoding
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: client-scripts
|
||||||
|
namespace: minecraft
|
||||||
|
data:
|
||||||
|
inject.js: |
|
||||||
|
(function() {
|
||||||
|
function getUsername() {
|
||||||
|
var metas = document.querySelectorAll("meta");
|
||||||
|
for (var i = 0; i < metas.length; i++) {
|
||||||
|
if (metas[i].getAttribute("name") === "remote-user") {
|
||||||
|
return metas[i].getAttribute("content");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var jwt = document.cookie.split("; ").find(function(row) {
|
||||||
|
return row.startsWith("authentik_session=");
|
||||||
|
});
|
||||||
|
if (jwt) {
|
||||||
|
try {
|
||||||
|
var token = jwt.split("=")[1];
|
||||||
|
var payload = JSON.parse(atob(token.split(".")[1]));
|
||||||
|
return payload.sub || payload.username || "web-user";
|
||||||
|
} catch(e) {}
|
||||||
|
}
|
||||||
|
return "web-user";
|
||||||
|
}
|
||||||
|
|
||||||
|
var username = getUsername();
|
||||||
|
console.log("Username found:", username);
|
||||||
|
|
||||||
|
if (username && username !== "web-user" &&
|
||||||
|
window.location.search.indexOf("playername=") === -1) {
|
||||||
|
var currentUrl = new URL(window.location.href);
|
||||||
|
currentUrl.searchParams.set("playername", username);
|
||||||
|
console.log("Redirecting to:", currentUrl.href);
|
||||||
|
window.location.href = currentUrl.href;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", function() {
|
||||||
|
// User block
|
||||||
|
var userBlock = document.createElement("div");
|
||||||
|
userBlock.style.cssText = "background-color:#CEC6CB;color:black;padding:8px;text-align:center;font-size:medium;border-radius:4px;position:absolute;top:10px;right:150px;max-width:200px;";
|
||||||
|
userBlock.innerHTML = "Logged in as: <b>" + username + "</b>";
|
||||||
|
document.body.appendChild(userBlock);
|
||||||
|
|
||||||
|
// Info block
|
||||||
|
var infoBlock = document.createElement("p");
|
||||||
|
infoBlock.style.cssText = "background-color:#CEC6CB;color:black;padding:10px;text-align:center;font-size:large;display:inline-block;border-radius:4px;position:absolute;top:10px;left:150px;";
|
||||||
|
infoBlock.innerHTML = 'GEYMERSKIY SOYUZ Server<br>'
|
||||||
|
+ 'Get <a href="https://github.com/PrismLauncher/PrismLauncher/releases/tag/8.4">Prism Launcher</a> '
|
||||||
|
+ 'and <a href="/clients/1.12.2.zip">client.zip</a> for this server. '
|
||||||
|
+ 'Server address <b>minecraft.hexor.cy:30565</b><br>'
|
||||||
|
+ 'Requires <a href="https://www.java.com/en/download/manual.jsp">Java 8</a><br><br>'
|
||||||
|
+ '<a href="#" id="showInstallBtn" style="color:black;text-decoration:underline;">Windows Install Script</a>';
|
||||||
|
document.body.appendChild(infoBlock);
|
||||||
|
|
||||||
|
// Modal
|
||||||
|
var modal = document.createElement("div");
|
||||||
|
modal.id = "installModal";
|
||||||
|
modal.style.cssText = "display:none;position:fixed;z-index:1000;left:0;top:0;width:100%;height:100%;background-color:rgba(0,0,0,0.5);";
|
||||||
|
modal.innerHTML = '<div style="background-color:#CEC6CB;margin:15% auto;padding:10px;border-radius:4px;width:70%;max-width:500px;text-align:center;color:black;font-size:large;">'
|
||||||
|
+ '<h3 style="margin-top:0;color:black;">Windows Installation</h3>'
|
||||||
|
+ '<p style="color:black;">Copy and paste this command into PowerShell:</p>'
|
||||||
|
+ '<textarea id="scriptCommand" readonly style="width:90%;height:60px;font-family:monospace;padding:8px;border:1px solid #888;border-radius:4px;resize:none;background-color:white;color:black;"></textarea>'
|
||||||
|
+ '<br><br>'
|
||||||
|
+ '<button id="copyButton" style="background-color:#CEC6CB;color:black;padding:10px 15px;border:1px solid #888;border-radius:4px;cursor:pointer;margin-right:10px;font-size:large;">Copy</button>'
|
||||||
|
+ '<button id="closeButton" style="background-color:#CEC6CB;color:black;padding:10px 15px;border:1px solid #888;border-radius:4px;cursor:pointer;font-size:large;">Close</button>'
|
||||||
|
+ '</div>';
|
||||||
|
document.body.appendChild(modal);
|
||||||
|
|
||||||
|
// Generate PowerShell command with username
|
||||||
|
function buildPsCommand() {
|
||||||
|
var d = "$";
|
||||||
|
var q = "'";
|
||||||
|
return d + 'f="' + d + 'env:TEMP\\mc-install.ps1"; iwr -useb https://minecraft.hexor.cy/clients/win-install.ps1 -OutFile '
|
||||||
|
+ d + 'f; powershell -ExecutionPolicy Bypass -File ' + d + 'f -Username ' + q + username + q + '; Remove-Item ' + d + 'f';
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById("showInstallBtn").addEventListener("click", function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
modal.style.display = "block";
|
||||||
|
document.getElementById("scriptCommand").value = buildPsCommand();
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById("closeButton").addEventListener("click", function() {
|
||||||
|
modal.style.display = "none";
|
||||||
|
});
|
||||||
|
|
||||||
|
document.getElementById("copyButton").addEventListener("click", function() {
|
||||||
|
var textarea = document.getElementById("scriptCommand");
|
||||||
|
textarea.select();
|
||||||
|
textarea.setSelectionRange(0, 99999);
|
||||||
|
document.execCommand("copy");
|
||||||
|
var btn = document.getElementById("copyButton");
|
||||||
|
btn.style.borderColor = "#4CAF50";
|
||||||
|
setTimeout(function() { btn.style.borderColor = "#888"; }, 2000);
|
||||||
|
});
|
||||||
|
|
||||||
|
modal.addEventListener("click", function(event) {
|
||||||
|
if (event.target === modal) {
|
||||||
|
modal.style.display = "none";
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
})();
|
||||||
|
|
||||||
|
win-install.ps1: |
|
||||||
|
# Game Setup Script for PrismLauncher and Minecraft Client
|
||||||
|
# This script downloads and configures PrismLauncher with Hexor client
|
||||||
|
|
||||||
|
param(
|
||||||
|
[string]$Username = "",
|
||||||
|
[string]$InstallPath = "$env:USERPROFILE\Games\PrismLauncher"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Enable TLS 1.2 for downloads
|
||||||
|
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
||||||
|
|
||||||
|
# Function to write colored log messages
|
||||||
|
function Write-Log {
|
||||||
|
param(
|
||||||
|
[string]$Message,
|
||||||
|
[string]$Level = "INFO"
|
||||||
|
)
|
||||||
|
|
||||||
|
switch ($Level) {
|
||||||
|
"INFO" {
|
||||||
|
Write-Host "[" -NoNewline
|
||||||
|
Write-Host "INFO" -ForegroundColor Blue -NoNewline
|
||||||
|
Write-Host "] $Message"
|
||||||
|
}
|
||||||
|
"WARN" {
|
||||||
|
Write-Host "[" -NoNewline
|
||||||
|
Write-Host "WARN" -ForegroundColor Yellow -NoNewline
|
||||||
|
Write-Host "] $Message"
|
||||||
|
}
|
||||||
|
"ERROR" {
|
||||||
|
Write-Host "[" -NoNewline
|
||||||
|
Write-Host "ERROR" -ForegroundColor Red -NoNewline
|
||||||
|
Write-Host "] $Message"
|
||||||
|
}
|
||||||
|
"SUCCESS" {
|
||||||
|
Write-Host "[" -NoNewline
|
||||||
|
Write-Host "SUCCESS" -ForegroundColor Green -NoNewline
|
||||||
|
Write-Host "] $Message"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to download file with progress
|
||||||
|
function Download-File {
|
||||||
|
param(
|
||||||
|
[string]$Url,
|
||||||
|
[string]$OutputPath
|
||||||
|
)
|
||||||
|
|
||||||
|
try {
|
||||||
|
Write-Log "Downloading from: $Url"
|
||||||
|
Write-Log "Saving to: $OutputPath"
|
||||||
|
|
||||||
|
if (Test-Path $OutputPath) {
|
||||||
|
Remove-Item $OutputPath -Force
|
||||||
|
Write-Log "Removed existing file to avoid corruption" "WARN"
|
||||||
|
}
|
||||||
|
|
||||||
|
$webClient = New-Object System.Net.WebClient
|
||||||
|
$webClient.DownloadFile($Url, $OutputPath)
|
||||||
|
|
||||||
|
if (Test-Path $OutputPath) {
|
||||||
|
$fileSize = (Get-Item $OutputPath).Length
|
||||||
|
Write-Log "Download completed successfully ($fileSize bytes)" "SUCCESS"
|
||||||
|
return $true
|
||||||
|
} else {
|
||||||
|
Write-Log "Download failed - file not found" "ERROR"
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Log "Download failed: $($_.Exception.Message)" "ERROR"
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to extract ZIP archive
|
||||||
|
function Extract-Archive {
|
||||||
|
param(
|
||||||
|
[string]$ArchivePath,
|
||||||
|
[string]$DestinationPath
|
||||||
|
)
|
||||||
|
|
||||||
|
try {
|
||||||
|
Write-Log "Extracting archive: $ArchivePath"
|
||||||
|
Write-Log "Destination: $DestinationPath"
|
||||||
|
|
||||||
|
if (!(Test-Path $ArchivePath)) {
|
||||||
|
Write-Log "Archive file not found: $ArchivePath" "ERROR"
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
|
||||||
|
$fileSize = (Get-Item $ArchivePath).Length
|
||||||
|
if ($fileSize -lt 1000) {
|
||||||
|
Write-Log "Archive file too small ($fileSize bytes), probably corrupted" "ERROR"
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(Test-Path $DestinationPath)) {
|
||||||
|
New-Item -ItemType Directory -Path $DestinationPath -Force | Out-Null
|
||||||
|
}
|
||||||
|
|
||||||
|
$existingFiles = Get-ChildItem -Path $DestinationPath -File | Where-Object { $_.Extension -ne ".zip" }
|
||||||
|
$existingDirs = Get-ChildItem -Path $DestinationPath -Directory
|
||||||
|
|
||||||
|
if ($existingFiles.Count -gt 0 -or $existingDirs.Count -gt 0) {
|
||||||
|
Write-Log "Clearing existing files in destination directory" "WARN"
|
||||||
|
$existingFiles | Remove-Item -Force -ErrorAction SilentlyContinue
|
||||||
|
$existingDirs | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
|
||||||
|
Add-Type -AssemblyName System.IO.Compression.FileSystem
|
||||||
|
|
||||||
|
try {
|
||||||
|
$zip = [System.IO.Compression.ZipFile]::OpenRead($ArchivePath)
|
||||||
|
$entryCount = $zip.Entries.Count
|
||||||
|
$zip.Dispose()
|
||||||
|
Write-Log "ZIP file validated ($entryCount entries)" "SUCCESS"
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Log "ZIP file validation failed: $($_.Exception.Message)" "ERROR"
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
|
||||||
|
[System.IO.Compression.ZipFile]::ExtractToDirectory($ArchivePath, $DestinationPath)
|
||||||
|
|
||||||
|
Write-Log "Archive extracted successfully" "SUCCESS"
|
||||||
|
return $true
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Log "Archive extraction failed: $($_.Exception.Message)" "ERROR"
|
||||||
|
|
||||||
|
if (Test-Path $ArchivePath) {
|
||||||
|
Write-Log "Removing potentially corrupted archive file" "WARN"
|
||||||
|
Remove-Item $ArchivePath -Force -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to check Java installation
|
||||||
|
function Check-JavaInstallation {
|
||||||
|
try {
|
||||||
|
$javaVersion = java -version 2>&1 | Select-String "version"
|
||||||
|
if ($javaVersion) {
|
||||||
|
Write-Log "Java is installed: $($javaVersion.ToString().Trim())" "SUCCESS"
|
||||||
|
return $true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Log "Java is not installed or not in PATH" "WARN"
|
||||||
|
Write-Log "Please download Java from: https://www.java.com/en/download/manual.jsp" "WARN"
|
||||||
|
Write-Log "Look for 'Windows Offline (64-bit)' version" "WARN"
|
||||||
|
|
||||||
|
$response = Read-Host "Do you want to continue without Java? (y/n)"
|
||||||
|
if ($response -eq 'y' -or $response -eq 'Y') {
|
||||||
|
Write-Log "Continuing without Java verification" "WARN"
|
||||||
|
return $true
|
||||||
|
} else {
|
||||||
|
Write-Log "Installation cancelled. Please install Java first." "ERROR"
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to generate a random hex string (UUID-like without dashes)
|
||||||
|
function New-RandomHexId {
|
||||||
|
param([int]$Length = 32)
|
||||||
|
$bytes = New-Object byte[] ($Length / 2)
|
||||||
|
$rng = [System.Security.Cryptography.RandomNumberGenerator]::Create()
|
||||||
|
$rng.GetBytes($bytes)
|
||||||
|
$rng.Dispose()
|
||||||
|
return ($bytes | ForEach-Object { $_.ToString("x2") }) -join ''
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to create accounts.json file with offline account
|
||||||
|
function Create-AccountsFile {
|
||||||
|
param(
|
||||||
|
[string]$TargetPath,
|
||||||
|
[string]$PlayerName
|
||||||
|
)
|
||||||
|
|
||||||
|
$accountsPath = Join-Path $TargetPath "accounts.json"
|
||||||
|
$profileId = New-RandomHexId -Length 32
|
||||||
|
$clientToken = New-RandomHexId -Length 32
|
||||||
|
$iat = [int][double]::Parse((Get-Date -UFormat %s))
|
||||||
|
|
||||||
|
$accountsObj = @{
|
||||||
|
accounts = @(
|
||||||
|
@{
|
||||||
|
entitlement = @{
|
||||||
|
canPlayMinecraft = $true
|
||||||
|
ownsMinecraft = $true
|
||||||
|
}
|
||||||
|
"msa-client-id" = ""
|
||||||
|
type = "MSA"
|
||||||
|
},
|
||||||
|
@{
|
||||||
|
active = $true
|
||||||
|
entitlement = @{
|
||||||
|
canPlayMinecraft = $true
|
||||||
|
ownsMinecraft = $true
|
||||||
|
}
|
||||||
|
profile = @{
|
||||||
|
capes = @()
|
||||||
|
id = $profileId
|
||||||
|
name = $PlayerName
|
||||||
|
skin = @{
|
||||||
|
id = ""
|
||||||
|
url = ""
|
||||||
|
variant = ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
type = "Offline"
|
||||||
|
ygg = @{
|
||||||
|
extra = @{
|
||||||
|
clientToken = $clientToken
|
||||||
|
userName = $PlayerName
|
||||||
|
}
|
||||||
|
iat = $iat
|
||||||
|
token = "0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
formatVersion = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$accountsObj | ConvertTo-Json -Depth 10 | Out-File -FilePath $accountsPath -Encoding UTF8
|
||||||
|
Write-Log "Created accounts.json at: $accountsPath" "SUCCESS"
|
||||||
|
Write-Log "Player name: $PlayerName" "SUCCESS"
|
||||||
|
return $true
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Log "Failed to create accounts.json: $($_.Exception.Message)" "ERROR"
|
||||||
|
return $false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Main installation process
|
||||||
|
Write-Log "Starting PrismLauncher and Minecraft client setup"
|
||||||
|
Write-Log "Player name: $Username"
|
||||||
|
Write-Log "Installation path: $InstallPath"
|
||||||
|
|
||||||
|
# Create installation directory and clear if exists (but keep ZIP files)
|
||||||
|
if (Test-Path $InstallPath) {
|
||||||
|
Write-Log "Installation directory exists, clearing contents" "WARN"
|
||||||
|
$existingFiles = Get-ChildItem -Path $InstallPath -File | Where-Object { $_.Extension -ne ".zip" }
|
||||||
|
$existingDirs = Get-ChildItem -Path $InstallPath -Directory
|
||||||
|
|
||||||
|
$existingFiles | Remove-Item -Force -ErrorAction SilentlyContinue
|
||||||
|
$existingDirs | Remove-Item -Recurse -Force -ErrorAction SilentlyContinue
|
||||||
|
} else {
|
||||||
|
New-Item -ItemType Directory -Path $InstallPath -Force | Out-Null
|
||||||
|
Write-Log "Created installation directory: $InstallPath"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Step 1: Download PrismLauncher
|
||||||
|
Write-Log "Step 1: Downloading PrismLauncher..."
|
||||||
|
$launcherUrl = "https://github.com/PrismLauncher/PrismLauncher/releases/download/8.4/PrismLauncher-Windows-MSVC-Portable-8.4.zip"
|
||||||
|
$launcherZip = Join-Path $InstallPath "PrismLauncher-8.4.zip"
|
||||||
|
$launcherExtractPath = Join-Path $InstallPath "PrismLauncher-Windows-MSVC-Portable-8.4"
|
||||||
|
|
||||||
|
if (!(Download-File -Url $launcherUrl -OutputPath $launcherZip)) {
|
||||||
|
Write-Log "Failed to download PrismLauncher. Exiting." "ERROR"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Step 2: Extract PrismLauncher
|
||||||
|
Write-Log "Step 2: Extracting PrismLauncher..."
|
||||||
|
if (!(Extract-Archive -ArchivePath $launcherZip -DestinationPath $InstallPath)) {
|
||||||
|
Write-Log "Failed to extract PrismLauncher. Exiting." "ERROR"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Find the actual extracted directory
|
||||||
|
$extractedDirs = Get-ChildItem -Path $InstallPath -Directory | Where-Object { $_.Name -like "*PrismLauncher*" }
|
||||||
|
if ($extractedDirs.Count -gt 0) {
|
||||||
|
$launcherExtractPath = $extractedDirs[0].FullName
|
||||||
|
Write-Log "Found PrismLauncher directory: $launcherExtractPath" "SUCCESS"
|
||||||
|
} else {
|
||||||
|
Write-Log "Could not find extracted PrismLauncher directory. Checking for direct extraction..." "WARN"
|
||||||
|
$prismExe = Join-Path $InstallPath "prismlauncher.exe"
|
||||||
|
if (Test-Path $prismExe) {
|
||||||
|
$launcherExtractPath = $InstallPath
|
||||||
|
Write-Log "PrismLauncher extracted directly to: $launcherExtractPath" "SUCCESS"
|
||||||
|
} else {
|
||||||
|
Write-Log "Failed to locate PrismLauncher files. Exiting." "ERROR"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Step 3: Create accounts.json in InstallPath (only if username provided)
|
||||||
|
if ($Username -and $Username -ne "web-user") {
|
||||||
|
Write-Log "Step 3: Creating accounts configuration for $Username..."
|
||||||
|
if (!(Create-AccountsFile -TargetPath $InstallPath -PlayerName $Username)) {
|
||||||
|
Write-Log "Failed to create accounts.json. Exiting." "ERROR"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Write-Log "Step 3: No username provided, skipping accounts.json creation" "WARN"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Step 4: Check Java installation
|
||||||
|
Write-Log "Step 4: Checking Java installation..."
|
||||||
|
if (!(Check-JavaInstallation)) {
|
||||||
|
Write-Log "Java check failed. Exiting." "ERROR"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Step 5: Download Minecraft client
|
||||||
|
Write-Log "Step 5: Downloading Minecraft client..."
|
||||||
|
$minecraftUrl = "https://minecraft.hexor.cy/clients/1.12.2.zip"
|
||||||
|
$minecraftZip = Join-Path $InstallPath "minecraft-1.12.2.zip"
|
||||||
|
$instancesPath = Join-Path $launcherExtractPath "instances"
|
||||||
|
$hexorPath = Join-Path $instancesPath "Hexor"
|
||||||
|
|
||||||
|
if (!(Download-File -Url $minecraftUrl -OutputPath $minecraftZip)) {
|
||||||
|
Write-Log "Failed to download Minecraft client. Exiting." "ERROR"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Step 6: Create instances directory and extract Minecraft client
|
||||||
|
Write-Log "Step 6: Setting up Minecraft client..."
|
||||||
|
if (!(Test-Path $instancesPath)) {
|
||||||
|
New-Item -ItemType Directory -Path $instancesPath -Force | Out-Null
|
||||||
|
Write-Log "Created instances directory"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(Test-Path $hexorPath)) {
|
||||||
|
New-Item -ItemType Directory -Path $hexorPath -Force | Out-Null
|
||||||
|
Write-Log "Created Hexor instance directory"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(Extract-Archive -ArchivePath $minecraftZip -DestinationPath $hexorPath)) {
|
||||||
|
Write-Log "Failed to extract Minecraft client. Exiting." "ERROR"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
# Step 7: Cleanup temporary files
|
||||||
|
Write-Log "Step 7: Cleaning up temporary files..."
|
||||||
|
try {
|
||||||
|
Remove-Item $launcherZip -Force
|
||||||
|
Remove-Item $minecraftZip -Force
|
||||||
|
Write-Log "Temporary files cleaned up" "SUCCESS"
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Log "Could not remove temporary files: $($_.Exception.Message)" "WARN"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Final success message
|
||||||
|
Write-Log "=== INSTALLATION COMPLETED SUCCESSFULLY ===" "SUCCESS"
|
||||||
|
Write-Log "PrismLauncher location: $launcherExtractPath" "SUCCESS"
|
||||||
|
Write-Log "Executable: $(Join-Path $launcherExtractPath 'prismlauncher.exe')" "SUCCESS"
|
||||||
|
Write-Log "Minecraft client installed in: $hexorPath" "SUCCESS"
|
||||||
|
if ($Username -and $Username -ne "web-user") {
|
||||||
|
Write-Log "Player name configured: $Username" "SUCCESS"
|
||||||
|
Write-Log "Accounts file: $(Join-Path $InstallPath 'accounts.json')" "SUCCESS"
|
||||||
|
}
|
||||||
|
Write-Log ""
|
||||||
|
Write-Log "You can now run PrismLauncher and the Hexor instance should be available!"
|
||||||
|
Write-Log "If Java was not installed, please download it from: https://www.java.com/en/download/manual.jsp"
|
||||||
|
|
||||||
|
# Ask if user wants to launch the game
|
||||||
|
$launchResponse = Read-Host "Do you want to launch PrismLauncher now? (y/n)"
|
||||||
|
if ($launchResponse -eq 'y' -or $launchResponse -eq 'Y') {
|
||||||
|
$launcherExe = Join-Path $launcherExtractPath "prismlauncher.exe"
|
||||||
|
if (Test-Path $launcherExe) {
|
||||||
|
Write-Log "Launching PrismLauncher..." "INFO"
|
||||||
|
Start-Process -FilePath $launcherExe -WorkingDirectory $launcherExtractPath
|
||||||
|
} else {
|
||||||
|
Write-Log "Launcher executable not found!" "ERROR"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: minecraft
|
||||||
|
namespace: minecraft
|
||||||
|
labels:
|
||||||
|
app: minecraft
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: minecraft
|
||||||
|
replicas: 1
|
||||||
|
strategy:
|
||||||
|
type: Recreate
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: minecraft
|
||||||
|
spec:
|
||||||
|
nodeSelector:
|
||||||
|
kubernetes.io/hostname: music
|
||||||
|
volumes:
|
||||||
|
- name: storage
|
||||||
|
hostPath:
|
||||||
|
path: /data/k8s/mc-server/
|
||||||
|
type: Directory
|
||||||
|
- name: nginx-config
|
||||||
|
configMap:
|
||||||
|
name: nginx-config
|
||||||
|
- name: client-scripts
|
||||||
|
configMap:
|
||||||
|
name: client-scripts
|
||||||
|
|
||||||
|
terminationGracePeriodSeconds: 180
|
||||||
|
containers:
|
||||||
|
- name: minecraft
|
||||||
|
image: eclipse-temurin:8-jdk-ubi10-minimal@sha256:85c943a7093a276b0f6ae13dee2ffecb98e390ab6a32fc7e4b8b1fc6bb103dd7
|
||||||
|
command: ["java"]
|
||||||
|
args:
|
||||||
|
- -Xms4G
|
||||||
|
- -Xmx4G
|
||||||
|
- -XX:+UseG1GC
|
||||||
|
- -XX:+ParallelRefProcEnabled
|
||||||
|
- -XX:MaxGCPauseMillis=200
|
||||||
|
- -XX:+UnlockExperimentalVMOptions
|
||||||
|
- -XX:+DisableExplicitGC
|
||||||
|
- -XX:+AlwaysPreTouch
|
||||||
|
- -XX:G1NewSizePercent=30
|
||||||
|
- -XX:G1MaxNewSizePercent=40
|
||||||
|
- -XX:G1HeapRegionSize=8M
|
||||||
|
- -XX:G1ReservePercent=20
|
||||||
|
- -XX:G1HeapWastePercent=5
|
||||||
|
- -XX:G1MixedGCCountTarget=4
|
||||||
|
- -XX:InitiatingHeapOccupancyPercent=15
|
||||||
|
- -XX:G1MixedGCLiveThresholdPercent=90
|
||||||
|
- -XX:G1RSetUpdatingPauseTimePercent=5
|
||||||
|
- -XX:SurvivorRatio=32
|
||||||
|
- -XX:+PerfDisableSharedMem
|
||||||
|
- -XX:MaxTenuringThreshold=1
|
||||||
|
- -jar
|
||||||
|
- forge-1.12.2-14.23.5.2854.jar
|
||||||
|
- nogui
|
||||||
|
workingDir: /mc/
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
memory: "8Gi"
|
||||||
|
cpu: "2000m"
|
||||||
|
limits:
|
||||||
|
memory: "12Gi"
|
||||||
|
cpu: "4000m"
|
||||||
|
ports:
|
||||||
|
- name: game
|
||||||
|
containerPort: 25565
|
||||||
|
protocol: TCP
|
||||||
|
- name: dynmap
|
||||||
|
containerPort: 8123
|
||||||
|
protocol: TCP
|
||||||
|
- name: webstatus-mod
|
||||||
|
containerPort: 8080
|
||||||
|
protocol: TCP
|
||||||
|
startupProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: game
|
||||||
|
periodSeconds: 10
|
||||||
|
failureThreshold: 90
|
||||||
|
livenessProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: game
|
||||||
|
periodSeconds: 30
|
||||||
|
timeoutSeconds: 5
|
||||||
|
failureThreshold: 3
|
||||||
|
readinessProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: game
|
||||||
|
periodSeconds: 10
|
||||||
|
timeoutSeconds: 5
|
||||||
|
volumeMounts:
|
||||||
|
- name: storage
|
||||||
|
mountPath: /mc
|
||||||
|
- name: nginx
|
||||||
|
image: nginx@sha256:f9ea18bfa4fad859e1ed38259d711da7ccad2c3516e875cec3351a57c859f571
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
memory: "64Mi"
|
||||||
|
cpu: "50m"
|
||||||
|
limits:
|
||||||
|
memory: "256Mi"
|
||||||
|
cpu: "200m"
|
||||||
|
ports:
|
||||||
|
- containerPort: 80
|
||||||
|
volumeMounts:
|
||||||
|
- name: nginx-config
|
||||||
|
mountPath: /etc/nginx/nginx.conf
|
||||||
|
subPath: nginx.conf
|
||||||
|
- name: storage
|
||||||
|
mountPath: /mc
|
||||||
|
- name: client-scripts
|
||||||
|
mountPath: /mc/clients/win-install.ps1
|
||||||
|
subPath: win-install.ps1
|
||||||
|
- name: client-scripts
|
||||||
|
mountPath: /mc/clients/inject.js
|
||||||
|
subPath: inject.js
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: minecraft-exporter
|
||||||
|
namespace: minecraft
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: minecraft
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 19565
|
||||||
|
targetPort: 19565
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: minecraft
|
||||||
|
annotations:
|
||||||
|
cert-manager.io/cluster-issuer: letsencrypt
|
||||||
|
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||||
|
spec:
|
||||||
|
ingressClassName: traefik
|
||||||
|
rules:
|
||||||
|
- host: minecraft.hexor.cy
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: minecraft-dynmap
|
||||||
|
port:
|
||||||
|
number: 80
|
||||||
|
tls:
|
||||||
|
- secretName: minecraft-tls
|
||||||
|
hosts:
|
||||||
|
- minecraft.hexor.cy
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
namespace: minecraft
|
||||||
|
resources:
|
||||||
|
- deployments.yaml
|
||||||
|
- configmaps.yaml
|
||||||
|
- services.yaml
|
||||||
|
- ingress.yaml
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: minecraft-dynmap
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: minecraft
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 80
|
||||||
|
targetPort: 80
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: minecraft-webstatus-mod
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: minecraft
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 80
|
||||||
|
targetPort: 8080
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: minecraft-game
|
||||||
|
spec:
|
||||||
|
type: LoadBalancer
|
||||||
|
externalTrafficPolicy: Cluster
|
||||||
|
ports:
|
||||||
|
- port: 30565
|
||||||
|
targetPort: 25565
|
||||||
|
selector:
|
||||||
|
app: minecraft
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
# MTProxy
|
||||||
|
|
||||||
|
Argo CD deploys this directory through the `mtproxy` entry in
|
||||||
|
`core-state/values.yaml`. Two telemt DaemonSets run on every node labeled
|
||||||
|
`homelab.hexor.cy/exposure=external`: classic MTProxy on 30443/TCP and
|
||||||
|
fake-TLS on 30444/TCP. The classic listener replaces the old amd64-only
|
||||||
|
`telegrammessenger/proxy` image so the arm64 `spb` node is covered.
|
||||||
|
|
||||||
|
Vaultwarden item `k8s/mtproxy/secret` must contain a custom field named
|
||||||
|
`Secret` with the existing 32-character hexadecimal MTProxy secret. External
|
||||||
|
Secrets renders both configurations from that field. Reloader restarts the
|
||||||
|
DaemonSets when it changes. Changing this value invalidates existing links.
|
||||||
|
|
||||||
|
`mtproxy-link-reconciler` lists external nodes every five minutes and creates
|
||||||
|
`mtproxy-links` and `telemt-links` Secrets. A node's public DNS name must be
|
||||||
|
`<node>.hexor.cy` and must point to that node. The reader at `proxy.hexor.cy`
|
||||||
|
has read-only access to those two Secrets and is protected by Keycloak's
|
||||||
|
forward auth; its access policy is in `terraform/keycloak/terraform.tfvars`.
|
||||||
|
The proxy Pods have no Kubernetes API access.
|
||||||
|
|
||||||
|
Before traffic is switched over, allow inbound 30443/TCP and 30444/TCP on
|
||||||
|
every external node and verify both DNS and connectivity on each node.
|
||||||
|
Neither the cluster nor host firewall is changed by these manifests.
|
||||||
@@ -0,0 +1,149 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: DaemonSet
|
||||||
|
metadata:
|
||||||
|
name: mtproxy-classic
|
||||||
|
labels:
|
||||||
|
app: mtproxy-classic
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: mtproxy-classic
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: mtproxy-classic
|
||||||
|
annotations:
|
||||||
|
reloader.stakater.com/auto: "true"
|
||||||
|
spec:
|
||||||
|
nodeSelector:
|
||||||
|
homelab.hexor.cy/exposure: external
|
||||||
|
automountServiceAccountToken: false
|
||||||
|
securityContext:
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 65532
|
||||||
|
runAsGroup: 65532
|
||||||
|
fsGroup: 65532
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
containers:
|
||||||
|
- name: telemt
|
||||||
|
image: ghcr.io/telemt/telemt@sha256:b311c20596213a3941dcd11f499be982de74f554eecfffe57fab51c1bf80d50a
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
workingDir: /run/telemt
|
||||||
|
args: ["/app/config.toml"]
|
||||||
|
ports:
|
||||||
|
- name: proxy
|
||||||
|
containerPort: 30443
|
||||||
|
hostPort: 30443
|
||||||
|
protocol: TCP
|
||||||
|
- name: metrics
|
||||||
|
containerPort: 9090
|
||||||
|
protocol: TCP
|
||||||
|
readinessProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: proxy
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 50m
|
||||||
|
memory: 64Mi
|
||||||
|
limits:
|
||||||
|
memory: 256Mi
|
||||||
|
securityContext:
|
||||||
|
readOnlyRootFilesystem: true
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop: ["ALL"]
|
||||||
|
volumeMounts:
|
||||||
|
- name: config
|
||||||
|
mountPath: /app/config.toml
|
||||||
|
subPath: classic.toml
|
||||||
|
readOnly: true
|
||||||
|
- name: workdir
|
||||||
|
mountPath: /run/telemt
|
||||||
|
volumes:
|
||||||
|
- name: config
|
||||||
|
secret:
|
||||||
|
secretName: mtproxy-config
|
||||||
|
defaultMode: 0444
|
||||||
|
items:
|
||||||
|
- key: classic.toml
|
||||||
|
path: classic.toml
|
||||||
|
- name: workdir
|
||||||
|
emptyDir:
|
||||||
|
medium: Memory
|
||||||
|
sizeLimit: 4Mi
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: DaemonSet
|
||||||
|
metadata:
|
||||||
|
name: mtproxy-tls
|
||||||
|
labels:
|
||||||
|
app: mtproxy-tls
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: mtproxy-tls
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: mtproxy-tls
|
||||||
|
annotations:
|
||||||
|
reloader.stakater.com/auto: "true"
|
||||||
|
spec:
|
||||||
|
nodeSelector:
|
||||||
|
homelab.hexor.cy/exposure: external
|
||||||
|
automountServiceAccountToken: false
|
||||||
|
securityContext:
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 65532
|
||||||
|
runAsGroup: 65532
|
||||||
|
fsGroup: 65532
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
containers:
|
||||||
|
- name: telemt
|
||||||
|
image: ghcr.io/telemt/telemt@sha256:b311c20596213a3941dcd11f499be982de74f554eecfffe57fab51c1bf80d50a
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
workingDir: /run/telemt
|
||||||
|
args: ["/app/config.toml"]
|
||||||
|
ports:
|
||||||
|
- name: proxy
|
||||||
|
containerPort: 30444
|
||||||
|
hostPort: 30444
|
||||||
|
protocol: TCP
|
||||||
|
- name: metrics
|
||||||
|
containerPort: 9090
|
||||||
|
protocol: TCP
|
||||||
|
readinessProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: proxy
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 50m
|
||||||
|
memory: 64Mi
|
||||||
|
limits:
|
||||||
|
memory: 256Mi
|
||||||
|
securityContext:
|
||||||
|
readOnlyRootFilesystem: true
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop: ["ALL"]
|
||||||
|
volumeMounts:
|
||||||
|
- name: config
|
||||||
|
mountPath: /app/config.toml
|
||||||
|
subPath: tls.toml
|
||||||
|
readOnly: true
|
||||||
|
- name: workdir
|
||||||
|
mountPath: /run/telemt
|
||||||
|
volumes:
|
||||||
|
- name: config
|
||||||
|
secret:
|
||||||
|
secretName: mtproxy-config
|
||||||
|
defaultMode: 0444
|
||||||
|
items:
|
||||||
|
- key: tls.toml
|
||||||
|
path: tls.toml
|
||||||
|
- name: workdir
|
||||||
|
emptyDir:
|
||||||
|
medium: Memory
|
||||||
|
sizeLimit: 4Mi
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
apiVersion: external-secrets.io/v1
|
||||||
|
kind: ExternalSecret
|
||||||
|
metadata:
|
||||||
|
name: mtproxy-config
|
||||||
|
spec:
|
||||||
|
refreshInterval: 1h
|
||||||
|
secretStoreRef:
|
||||||
|
name: vaultwarden-fields
|
||||||
|
kind: ClusterSecretStore
|
||||||
|
target:
|
||||||
|
name: mtproxy-config
|
||||||
|
creationPolicy: Owner
|
||||||
|
deletionPolicy: Retain
|
||||||
|
template:
|
||||||
|
type: Opaque
|
||||||
|
data:
|
||||||
|
SECRET: "{{ .secret }}"
|
||||||
|
classic.toml: |
|
||||||
|
[general]
|
||||||
|
use_middle_proxy = true
|
||||||
|
log_level = "normal"
|
||||||
|
|
||||||
|
[general.modes]
|
||||||
|
classic = true
|
||||||
|
secure = false
|
||||||
|
tls = false
|
||||||
|
|
||||||
|
[server]
|
||||||
|
port = 30443
|
||||||
|
metrics_port = 9090
|
||||||
|
metrics_whitelist = ["0.0.0.0/0"]
|
||||||
|
|
||||||
|
[server.api]
|
||||||
|
enabled = false
|
||||||
|
|
||||||
|
[[server.listeners]]
|
||||||
|
ip = "0.0.0.0"
|
||||||
|
|
||||||
|
[access.users]
|
||||||
|
user = "{{ .secret }}"
|
||||||
|
tls.toml: |
|
||||||
|
[general]
|
||||||
|
use_middle_proxy = true
|
||||||
|
log_level = "normal"
|
||||||
|
|
||||||
|
[general.modes]
|
||||||
|
classic = false
|
||||||
|
secure = false
|
||||||
|
tls = true
|
||||||
|
|
||||||
|
[server]
|
||||||
|
port = 30444
|
||||||
|
metrics_port = 9090
|
||||||
|
metrics_whitelist = ["0.0.0.0/0"]
|
||||||
|
|
||||||
|
[server.api]
|
||||||
|
enabled = false
|
||||||
|
|
||||||
|
[[server.listeners]]
|
||||||
|
ip = "0.0.0.0"
|
||||||
|
|
||||||
|
[censorship]
|
||||||
|
tls_domain = "ya.ru"
|
||||||
|
mask = true
|
||||||
|
tls_emulation = true
|
||||||
|
tls_front_dir = "tlsfront"
|
||||||
|
|
||||||
|
[access.users]
|
||||||
|
user = "{{ .secret }}"
|
||||||
|
data:
|
||||||
|
- secretKey: secret
|
||||||
|
remoteRef:
|
||||||
|
key: k8s/mtproxy/secret
|
||||||
|
property: Secret
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
apiVersion: traefik.io/v1alpha1
|
||||||
|
kind: Middleware
|
||||||
|
metadata:
|
||||||
|
name: mtproxy-auth
|
||||||
|
spec:
|
||||||
|
forwardAuth:
|
||||||
|
address: http://auth-proxy.keycloak.svc:80/auth
|
||||||
|
trustForwardHeader: false
|
||||||
|
---
|
||||||
|
apiVersion: traefik.io/v1alpha1
|
||||||
|
kind: IngressRoute
|
||||||
|
metadata:
|
||||||
|
name: mtproxy-links
|
||||||
|
spec:
|
||||||
|
entryPoints:
|
||||||
|
- websecure
|
||||||
|
routes:
|
||||||
|
- match: Host(`proxy.hexor.cy`)
|
||||||
|
kind: Rule
|
||||||
|
middlewares:
|
||||||
|
- name: mtproxy-auth
|
||||||
|
services:
|
||||||
|
- name: mtproxy-link-reader
|
||||||
|
port: 80
|
||||||
|
tls:
|
||||||
|
secretName: mtproxy-links-tls
|
||||||
|
---
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: Certificate
|
||||||
|
metadata:
|
||||||
|
name: mtproxy-links-tls
|
||||||
|
spec:
|
||||||
|
secretName: mtproxy-links-tls
|
||||||
|
issuerRef:
|
||||||
|
name: letsencrypt
|
||||||
|
kind: ClusterIssuer
|
||||||
|
dnsNames:
|
||||||
|
- proxy.hexor.cy
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
namespace: mtproxy
|
||||||
|
resources:
|
||||||
|
- external-secrets.yaml
|
||||||
|
- daemonsets.yaml
|
||||||
|
- metrics.yaml
|
||||||
|
- links.yaml
|
||||||
|
- reader.yaml
|
||||||
|
- ingress.yaml
|
||||||
|
configMapGenerator:
|
||||||
|
- name: mtproxy-link-reconciler
|
||||||
|
files:
|
||||||
|
- reconcile.py=link-reconciler.py
|
||||||
|
generatorOptions:
|
||||||
|
disableNameSuffixHash: true
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
"""Publish client links for every external node, using its public DNS name."""
|
||||||
|
|
||||||
|
import base64
|
||||||
|
import json
|
||||||
|
import urllib.error
|
||||||
|
import urllib.parse
|
||||||
|
import urllib.request
|
||||||
|
|
||||||
|
|
||||||
|
API = "https://kubernetes.default.svc"
|
||||||
|
NAMESPACE = open("/var/run/secrets/kubernetes.io/serviceaccount/namespace", encoding="utf-8").read().strip()
|
||||||
|
TOKEN = open("/var/run/secrets/kubernetes.io/serviceaccount/token", encoding="utf-8").read().strip()
|
||||||
|
CA = "/var/run/secrets/kubernetes.io/serviceaccount/ca.crt"
|
||||||
|
|
||||||
|
|
||||||
|
def request(method, path, body=None):
|
||||||
|
import ssl
|
||||||
|
|
||||||
|
data = json.dumps(body).encode() if body is not None else None
|
||||||
|
req = urllib.request.Request(
|
||||||
|
API + path,
|
||||||
|
data=data,
|
||||||
|
method=method,
|
||||||
|
headers={
|
||||||
|
"Authorization": "Bearer " + TOKEN,
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
with urllib.request.urlopen(req, context=ssl.create_default_context(cafile=CA), timeout=15) as response:
|
||||||
|
return json.load(response)
|
||||||
|
|
||||||
|
|
||||||
|
def publish(name, links):
|
||||||
|
path = f"/api/v1/namespaces/{NAMESPACE}/secrets"
|
||||||
|
data = {node: base64.b64encode(link.encode()).decode() for node, link in links.items()}
|
||||||
|
try:
|
||||||
|
current = request("GET", f"{path}/{name}")
|
||||||
|
except urllib.error.HTTPError as error:
|
||||||
|
if error.code != 404:
|
||||||
|
raise
|
||||||
|
request("POST", path, {"apiVersion": "v1", "kind": "Secret", "metadata": {"name": name}, "type": "Opaque", "data": data})
|
||||||
|
return
|
||||||
|
if current.get("data", {}) == data:
|
||||||
|
return
|
||||||
|
# PUT replaces the data map, removing links for nodes that are no longer external.
|
||||||
|
request("PUT", f"{path}/{name}", {
|
||||||
|
"apiVersion": "v1",
|
||||||
|
"kind": "Secret",
|
||||||
|
"metadata": {"name": name, "resourceVersion": current["metadata"]["resourceVersion"]},
|
||||||
|
"type": "Opaque",
|
||||||
|
"data": data,
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
secret = open("/config/SECRET", encoding="utf-8").read().strip()
|
||||||
|
if len(secret) != 32 or any(char not in "0123456789abcdefABCDEF" for char in secret):
|
||||||
|
raise ValueError("Vaultwarden Secret must be 32 hexadecimal characters")
|
||||||
|
|
||||||
|
selector = urllib.parse.quote("homelab.hexor.cy/exposure=external", safe="")
|
||||||
|
nodes = request("GET", f"/api/v1/nodes?labelSelector={selector}")["items"]
|
||||||
|
if not nodes:
|
||||||
|
raise ValueError("No external nodes found")
|
||||||
|
|
||||||
|
classic = {}
|
||||||
|
tls = {}
|
||||||
|
for node in nodes:
|
||||||
|
name = node["metadata"]["name"]
|
||||||
|
# DNS is maintained outside the cluster; no public IP needs to be stored on a Node.
|
||||||
|
host = f"{name}.hexor.cy"
|
||||||
|
classic[name] = f"tg://proxy?server={host}&port=30443&secret={secret}"
|
||||||
|
tls[name] = f"tg://proxy?server={host}&port=30444&secret=ee{secret}79612e7275"
|
||||||
|
|
||||||
|
publish("mtproxy-links", classic)
|
||||||
|
publish("telemt-links", tls)
|
||||||
|
print(f"Published MTProxy links for {len(nodes)} external nodes")
|
||||||
@@ -0,0 +1,108 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: mtproxy-link-reconciler
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRole
|
||||||
|
metadata:
|
||||||
|
name: mtproxy-external-node-reader
|
||||||
|
rules:
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["nodes"]
|
||||||
|
verbs: ["list"]
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: ClusterRoleBinding
|
||||||
|
metadata:
|
||||||
|
name: mtproxy-external-node-reader
|
||||||
|
roleRef:
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
kind: ClusterRole
|
||||||
|
name: mtproxy-external-node-reader
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: mtproxy-link-reconciler
|
||||||
|
namespace: mtproxy
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: Role
|
||||||
|
metadata:
|
||||||
|
name: mtproxy-link-writer
|
||||||
|
rules:
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["secrets"]
|
||||||
|
verbs: ["create"]
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["secrets"]
|
||||||
|
resourceNames: ["mtproxy-links", "telemt-links"]
|
||||||
|
verbs: ["get", "update"]
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: RoleBinding
|
||||||
|
metadata:
|
||||||
|
name: mtproxy-link-writer
|
||||||
|
roleRef:
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
kind: Role
|
||||||
|
name: mtproxy-link-writer
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: mtproxy-link-reconciler
|
||||||
|
---
|
||||||
|
apiVersion: batch/v1
|
||||||
|
kind: CronJob
|
||||||
|
metadata:
|
||||||
|
name: mtproxy-link-reconciler
|
||||||
|
spec:
|
||||||
|
schedule: "*/5 * * * *"
|
||||||
|
concurrencyPolicy: Forbid
|
||||||
|
successfulJobsHistoryLimit: 1
|
||||||
|
failedJobsHistoryLimit: 2
|
||||||
|
jobTemplate:
|
||||||
|
spec:
|
||||||
|
backoffLimit: 2
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
serviceAccountName: mtproxy-link-reconciler
|
||||||
|
restartPolicy: OnFailure
|
||||||
|
nodeSelector:
|
||||||
|
homelab.hexor.cy/exposure: external
|
||||||
|
securityContext:
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 65534
|
||||||
|
runAsGroup: 65534
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
containers:
|
||||||
|
- name: reconcile
|
||||||
|
image: python:3.13-alpine3.22@sha256:e81548ac35b07a3bd4805f275107592ef458b1e893c0e04d45aedaa19416cca5
|
||||||
|
command: ["python", "/scripts/reconcile.py"]
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 10m
|
||||||
|
memory: 32Mi
|
||||||
|
limits:
|
||||||
|
memory: 128Mi
|
||||||
|
securityContext:
|
||||||
|
readOnlyRootFilesystem: true
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop: ["ALL"]
|
||||||
|
volumeMounts:
|
||||||
|
- name: scripts
|
||||||
|
mountPath: /scripts
|
||||||
|
readOnly: true
|
||||||
|
- name: config
|
||||||
|
mountPath: /config
|
||||||
|
readOnly: true
|
||||||
|
volumes:
|
||||||
|
- name: scripts
|
||||||
|
configMap:
|
||||||
|
name: mtproxy-link-reconciler
|
||||||
|
- name: config
|
||||||
|
secret:
|
||||||
|
secretName: mtproxy-config
|
||||||
|
items:
|
||||||
|
- key: SECRET
|
||||||
|
path: SECRET
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: mtproxy-classic-metrics
|
||||||
|
labels:
|
||||||
|
app: mtproxy-classic
|
||||||
|
spec:
|
||||||
|
clusterIP: None
|
||||||
|
selector:
|
||||||
|
app: mtproxy-classic
|
||||||
|
ports:
|
||||||
|
- name: metrics
|
||||||
|
port: 9090
|
||||||
|
targetPort: metrics
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: mtproxy-tls-metrics
|
||||||
|
labels:
|
||||||
|
app: mtproxy-tls
|
||||||
|
spec:
|
||||||
|
clusterIP: None
|
||||||
|
selector:
|
||||||
|
app: mtproxy-tls
|
||||||
|
ports:
|
||||||
|
- name: metrics
|
||||||
|
port: 9090
|
||||||
|
targetPort: metrics
|
||||||
|
---
|
||||||
|
apiVersion: monitoring.coreos.com/v1
|
||||||
|
kind: ServiceMonitor
|
||||||
|
metadata:
|
||||||
|
name: mtproxy-classic
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: mtproxy-classic
|
||||||
|
endpoints:
|
||||||
|
- port: metrics
|
||||||
|
path: /metrics
|
||||||
|
interval: 30s
|
||||||
|
scrapeTimeout: 10s
|
||||||
|
relabelings:
|
||||||
|
- action: replace
|
||||||
|
sourceLabels: [__meta_kubernetes_pod_node_name]
|
||||||
|
targetLabel: node
|
||||||
|
---
|
||||||
|
apiVersion: monitoring.coreos.com/v1
|
||||||
|
kind: ServiceMonitor
|
||||||
|
metadata:
|
||||||
|
name: mtproxy-tls
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: mtproxy-tls
|
||||||
|
endpoints:
|
||||||
|
- port: metrics
|
||||||
|
path: /metrics
|
||||||
|
interval: 30s
|
||||||
|
scrapeTimeout: 10s
|
||||||
|
relabelings:
|
||||||
|
- action: replace
|
||||||
|
sourceLabels: [__meta_kubernetes_pod_node_name]
|
||||||
|
targetLabel: node
|
||||||
@@ -0,0 +1,96 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: mtproxy-link-reader
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: Role
|
||||||
|
metadata:
|
||||||
|
name: mtproxy-link-reader
|
||||||
|
rules:
|
||||||
|
- apiGroups: [""]
|
||||||
|
resources: ["secrets"]
|
||||||
|
resourceNames: ["mtproxy-links", "telemt-links"]
|
||||||
|
verbs: ["get"]
|
||||||
|
---
|
||||||
|
apiVersion: rbac.authorization.k8s.io/v1
|
||||||
|
kind: RoleBinding
|
||||||
|
metadata:
|
||||||
|
name: mtproxy-link-reader
|
||||||
|
roleRef:
|
||||||
|
apiGroup: rbac.authorization.k8s.io
|
||||||
|
kind: Role
|
||||||
|
name: mtproxy-link-reader
|
||||||
|
subjects:
|
||||||
|
- kind: ServiceAccount
|
||||||
|
name: mtproxy-link-reader
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: mtproxy-link-reader
|
||||||
|
labels:
|
||||||
|
app: mtproxy-link-reader
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: mtproxy-link-reader
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: mtproxy-link-reader
|
||||||
|
spec:
|
||||||
|
serviceAccountName: mtproxy-link-reader
|
||||||
|
nodeSelector:
|
||||||
|
homelab.hexor.cy/exposure: external
|
||||||
|
securityContext:
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 1000
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
containers:
|
||||||
|
- name: reader
|
||||||
|
image: ultradesu/k8s-secrets:0.2.2@sha256:f206942d21ca9dcd131d6e19ba26cc17671815919217aef657b30a9f85854778
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
args:
|
||||||
|
- --secrets
|
||||||
|
- mtproxy-links,telemt-links
|
||||||
|
- --namespace
|
||||||
|
- mtproxy
|
||||||
|
- --port
|
||||||
|
- "3000"
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: 3000
|
||||||
|
readinessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: http
|
||||||
|
livenessProbe:
|
||||||
|
httpGet:
|
||||||
|
path: /health
|
||||||
|
port: http
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 50m
|
||||||
|
memory: 64Mi
|
||||||
|
limits:
|
||||||
|
memory: 128Mi
|
||||||
|
securityContext:
|
||||||
|
readOnlyRootFilesystem: true
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop: ["ALL"]
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: mtproxy-link-reader
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
app: mtproxy-link-reader
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 80
|
||||||
|
targetPort: http
|
||||||
@@ -0,0 +1,151 @@
|
|||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: rustdesk-hbbs
|
||||||
|
annotations:
|
||||||
|
reloader.stakater.com/auto: "true"
|
||||||
|
labels:
|
||||||
|
app: rustdesk-hbbs
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
strategy:
|
||||||
|
type: Recreate
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: rustdesk-hbbs
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: rustdesk-hbbs
|
||||||
|
spec:
|
||||||
|
nodeSelector:
|
||||||
|
kubernetes.io/hostname: music
|
||||||
|
containers:
|
||||||
|
- name: hbbs
|
||||||
|
image: rustdesk/rustdesk-server@sha256:8ecdab65deb7c84652a626380e31d11a8f1fbafd97916d57f95c20628f943c00
|
||||||
|
imagePullPolicy: Always
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
memory: "128Mi"
|
||||||
|
cpu: "100m"
|
||||||
|
limits:
|
||||||
|
memory: "512Mi"
|
||||||
|
cpu: "750m"
|
||||||
|
command: ["hbbs"]
|
||||||
|
args:
|
||||||
|
- "--relay-servers"
|
||||||
|
- "rd.hexor.cy:21117"
|
||||||
|
- "--port"
|
||||||
|
- "21116"
|
||||||
|
ports:
|
||||||
|
- name: registry
|
||||||
|
containerPort: 21116
|
||||||
|
protocol: TCP
|
||||||
|
- name: registry-udp
|
||||||
|
containerPort: 21116
|
||||||
|
protocol: UDP
|
||||||
|
- name: nat
|
||||||
|
containerPort: 21115
|
||||||
|
protocol: TCP
|
||||||
|
readinessProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: registry
|
||||||
|
volumeMounts:
|
||||||
|
- name: keys
|
||||||
|
mountPath: /data
|
||||||
|
readOnly: true
|
||||||
|
- name: data
|
||||||
|
mountPath: /data-persistent
|
||||||
|
env:
|
||||||
|
- name: RUST_LOG
|
||||||
|
value: "info"
|
||||||
|
- name: DB_URL
|
||||||
|
value: "/data-persistent/db_v2.sqlite3"
|
||||||
|
workingDir: /data
|
||||||
|
volumes:
|
||||||
|
- name: keys
|
||||||
|
secret:
|
||||||
|
secretName: rustdesk-keys
|
||||||
|
items:
|
||||||
|
- key: id_ed25519
|
||||||
|
path: id_ed25519
|
||||||
|
mode: 0600
|
||||||
|
- key: id_ed25519.pub
|
||||||
|
path: id_ed25519.pub
|
||||||
|
mode: 0644
|
||||||
|
- name: data
|
||||||
|
hostPath:
|
||||||
|
path: /data/k8s/rustdesk/hbbs
|
||||||
|
type: Directory
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: rustdesk-hbbr
|
||||||
|
annotations:
|
||||||
|
reloader.stakater.com/auto: "true"
|
||||||
|
labels:
|
||||||
|
app: rustdesk-hbbr
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
strategy:
|
||||||
|
type: Recreate
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: rustdesk-hbbr
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: rustdesk-hbbr
|
||||||
|
spec:
|
||||||
|
nodeSelector:
|
||||||
|
kubernetes.io/hostname: music
|
||||||
|
containers:
|
||||||
|
- name: hbbr
|
||||||
|
image: rustdesk/rustdesk-server@sha256:8ecdab65deb7c84652a626380e31d11a8f1fbafd97916d57f95c20628f943c00
|
||||||
|
imagePullPolicy: Always
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
memory: "128Mi"
|
||||||
|
cpu: "100m"
|
||||||
|
limits:
|
||||||
|
memory: "512Mi"
|
||||||
|
cpu: "750m"
|
||||||
|
command: ["hbbr"]
|
||||||
|
args:
|
||||||
|
- "--port"
|
||||||
|
- "21117"
|
||||||
|
ports:
|
||||||
|
- name: relay
|
||||||
|
containerPort: 21117
|
||||||
|
protocol: TCP
|
||||||
|
readinessProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: relay
|
||||||
|
volumeMounts:
|
||||||
|
- name: keys
|
||||||
|
mountPath: /data
|
||||||
|
readOnly: true
|
||||||
|
- name: data
|
||||||
|
mountPath: /data-persistent
|
||||||
|
env:
|
||||||
|
- name: RUST_LOG
|
||||||
|
value: "info"
|
||||||
|
workingDir: /data
|
||||||
|
volumes:
|
||||||
|
- name: keys
|
||||||
|
secret:
|
||||||
|
secretName: rustdesk-keys
|
||||||
|
items:
|
||||||
|
- key: id_ed25519
|
||||||
|
path: id_ed25519
|
||||||
|
mode: 0600
|
||||||
|
- key: id_ed25519.pub
|
||||||
|
path: id_ed25519.pub
|
||||||
|
mode: 0644
|
||||||
|
- name: data
|
||||||
|
hostPath:
|
||||||
|
path: /data/k8s/rustdesk/hbbr
|
||||||
|
type: Directory
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
apiVersion: external-secrets.io/v1
|
||||||
|
kind: ExternalSecret
|
||||||
|
metadata:
|
||||||
|
name: rustdesk-keys
|
||||||
|
spec:
|
||||||
|
refreshInterval: 1h
|
||||||
|
secretStoreRef:
|
||||||
|
name: vaultwarden-fields
|
||||||
|
kind: ClusterSecretStore
|
||||||
|
target:
|
||||||
|
name: rustdesk-keys
|
||||||
|
creationPolicy: Owner
|
||||||
|
deletionPolicy: Retain
|
||||||
|
template:
|
||||||
|
type: Opaque
|
||||||
|
data:
|
||||||
|
id_ed25519: "{{ .private_key }}"
|
||||||
|
id_ed25519.pub: "{{ .public_key }}"
|
||||||
|
data:
|
||||||
|
- secretKey: private_key
|
||||||
|
remoteRef:
|
||||||
|
key: k8s/rustdesk/secrets
|
||||||
|
property: Cert
|
||||||
|
- secretKey: public_key
|
||||||
|
remoteRef:
|
||||||
|
key: k8s/rustdesk/secrets
|
||||||
|
property: Key
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
namespace: rustdesk
|
||||||
|
resources:
|
||||||
|
- external-secrets.yaml
|
||||||
|
- deployment.yaml
|
||||||
|
- service.yaml
|
||||||
|
- network-policy.yaml
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
---
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: rustdesk-network-policy
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app: rustdesk-hbbs
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
- Egress
|
||||||
|
ingress:
|
||||||
|
# Allow all incoming connections to RustDesk ports
|
||||||
|
- from: []
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 21115
|
||||||
|
- protocol: TCP
|
||||||
|
port: 21116
|
||||||
|
- protocol: UDP
|
||||||
|
port: 21116
|
||||||
|
egress:
|
||||||
|
# Allow DNS
|
||||||
|
- to: []
|
||||||
|
ports:
|
||||||
|
- protocol: UDP
|
||||||
|
port: 53
|
||||||
|
- protocol: TCP
|
||||||
|
port: 53
|
||||||
|
# Allow communication between HBBS and HBBR
|
||||||
|
- to:
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app: rustdesk-hbbr
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 21117
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: NetworkPolicy
|
||||||
|
metadata:
|
||||||
|
name: rustdesk-hbbr-network-policy
|
||||||
|
spec:
|
||||||
|
podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app: rustdesk-hbbr
|
||||||
|
policyTypes:
|
||||||
|
- Ingress
|
||||||
|
- Egress
|
||||||
|
ingress:
|
||||||
|
# Allow all incoming connections to relay port
|
||||||
|
- from: []
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 21117
|
||||||
|
# Allow connections from HBBS
|
||||||
|
- from:
|
||||||
|
- podSelector:
|
||||||
|
matchLabels:
|
||||||
|
app: rustdesk-hbbs
|
||||||
|
ports:
|
||||||
|
- protocol: TCP
|
||||||
|
port: 21117
|
||||||
|
egress:
|
||||||
|
# Allow DNS
|
||||||
|
- to: []
|
||||||
|
ports:
|
||||||
|
- protocol: UDP
|
||||||
|
port: 53
|
||||||
|
- protocol: TCP
|
||||||
|
port: 53
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
# Preserve client source IPs for RustDesk NAT detection. Public DNS points to music,
|
||||||
|
# where both servers and their persistent data live.
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: rustdesk-hbbs
|
||||||
|
labels:
|
||||||
|
app: rustdesk-hbbs
|
||||||
|
spec:
|
||||||
|
type: LoadBalancer
|
||||||
|
externalTrafficPolicy: Local
|
||||||
|
selector:
|
||||||
|
app: rustdesk-hbbs
|
||||||
|
ports:
|
||||||
|
- name: registry-tcp
|
||||||
|
port: 21116
|
||||||
|
targetPort: 21116
|
||||||
|
protocol: TCP
|
||||||
|
- name: nat
|
||||||
|
port: 21115
|
||||||
|
targetPort: 21115
|
||||||
|
protocol: TCP
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: rustdesk-hbbs-udp
|
||||||
|
labels:
|
||||||
|
app: rustdesk-hbbs
|
||||||
|
spec:
|
||||||
|
type: LoadBalancer
|
||||||
|
externalTrafficPolicy: Local
|
||||||
|
selector:
|
||||||
|
app: rustdesk-hbbs
|
||||||
|
ports:
|
||||||
|
- name: registry-udp
|
||||||
|
port: 21116
|
||||||
|
targetPort: 21116
|
||||||
|
protocol: UDP
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: rustdesk-hbbr
|
||||||
|
labels:
|
||||||
|
app: rustdesk-hbbr
|
||||||
|
spec:
|
||||||
|
type: LoadBalancer
|
||||||
|
externalTrafficPolicy: Local
|
||||||
|
selector:
|
||||||
|
app: rustdesk-hbbr
|
||||||
|
ports:
|
||||||
|
- name: relay
|
||||||
|
port: 21117
|
||||||
|
targetPort: 21117
|
||||||
|
protocol: TCP
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
# Shadowsocks on spb
|
||||||
|
|
||||||
|
One shadowsocks-rust pod runs on `spb`, exposing `8388/TCP` and `8388/UDP`
|
||||||
|
through host ports. Client settings:
|
||||||
|
|
||||||
|
- Server: `spb.hexor.cy`
|
||||||
|
- Port: `8388`
|
||||||
|
- Method: `chacha20-ietf-poly1305`
|
||||||
|
- Password: the `Password` custom field of the Vaultwarden item named
|
||||||
|
`k8s/shadowsocks/secrets` (exact name, not an item UUID).
|
||||||
|
|
||||||
|
Create that item in the server secrets vault accessible to the External Secrets
|
||||||
|
bot. Use a long random password, for example generated with `openssl rand -base64 32`.
|
||||||
|
External Secrets creates `shadowsocks-config`; Reloader restarts the deployment
|
||||||
|
when the Secret changes. No persistent storage is required.
|
||||||
|
|
||||||
|
The spb NixOS configuration opens port 8388 for both protocols. Apply that
|
||||||
|
configuration when deploying this application for the first time.
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: shadowsocks
|
||||||
|
annotations:
|
||||||
|
reloader.stakater.com/auto: "true"
|
||||||
|
labels:
|
||||||
|
app: shadowsocks
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
strategy:
|
||||||
|
type: Recreate
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: shadowsocks
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: shadowsocks
|
||||||
|
spec:
|
||||||
|
nodeSelector:
|
||||||
|
kubernetes.io/hostname: spb
|
||||||
|
automountServiceAccountToken: false
|
||||||
|
securityContext:
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 65534
|
||||||
|
runAsGroup: 65534
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
containers:
|
||||||
|
- name: shadowsocks
|
||||||
|
# shadowsocks-rust v1.25.0; multi-arch image includes linux/arm64.
|
||||||
|
image: ghcr.io/shadowsocks/ssserver-rust:v1.25.0@sha256:22240c07d8ce3a36421ede770bd775dcc5fc56d5d829943196957b05452dc36f
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
command: ["/usr/bin/ssserver"]
|
||||||
|
args:
|
||||||
|
- --log-without-time
|
||||||
|
- -c
|
||||||
|
- /etc/shadowsocks-rust/config.json
|
||||||
|
ports:
|
||||||
|
- name: proxy-tcp
|
||||||
|
containerPort: 8388
|
||||||
|
hostPort: 8388
|
||||||
|
protocol: TCP
|
||||||
|
- name: proxy-udp
|
||||||
|
containerPort: 8388
|
||||||
|
hostPort: 8388
|
||||||
|
protocol: UDP
|
||||||
|
readinessProbe:
|
||||||
|
tcpSocket:
|
||||||
|
port: proxy-tcp
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: 50m
|
||||||
|
memory: 32Mi
|
||||||
|
limits:
|
||||||
|
memory: 256Mi
|
||||||
|
securityContext:
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
readOnlyRootFilesystem: true
|
||||||
|
capabilities:
|
||||||
|
drop: ["ALL"]
|
||||||
|
volumeMounts:
|
||||||
|
- name: config
|
||||||
|
mountPath: /etc/shadowsocks-rust
|
||||||
|
readOnly: true
|
||||||
|
volumes:
|
||||||
|
- name: config
|
||||||
|
secret:
|
||||||
|
secretName: shadowsocks-config
|
||||||
|
defaultMode: 0444
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
apiVersion: external-secrets.io/v1
|
||||||
|
kind: ExternalSecret
|
||||||
|
metadata:
|
||||||
|
name: shadowsocks-config
|
||||||
|
spec:
|
||||||
|
refreshInterval: 1h
|
||||||
|
secretStoreRef:
|
||||||
|
name: vaultwarden-fields
|
||||||
|
kind: ClusterSecretStore
|
||||||
|
target:
|
||||||
|
name: shadowsocks-config
|
||||||
|
creationPolicy: Owner
|
||||||
|
deletionPolicy: Retain
|
||||||
|
template:
|
||||||
|
type: Opaque
|
||||||
|
data:
|
||||||
|
config.json: |
|
||||||
|
{
|
||||||
|
"server": "0.0.0.0",
|
||||||
|
"server_port": 8388,
|
||||||
|
"method": "chacha20-ietf-poly1305",
|
||||||
|
"password": {{ .password | toJson }},
|
||||||
|
"mode": "tcp_and_udp"
|
||||||
|
}
|
||||||
|
data:
|
||||||
|
- secretKey: password
|
||||||
|
remoteRef:
|
||||||
|
key: k8s/shadowsocks/secrets
|
||||||
|
property: Password
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
namespace: shadowsocks
|
||||||
|
resources:
|
||||||
|
- external-secrets.yaml
|
||||||
|
- deployment.yaml
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: web-petting
|
||||||
|
labels:
|
||||||
|
app: web-petting
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: web-petting
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: web-petting
|
||||||
|
annotations:
|
||||||
|
reloader.stakater.com/auto: "true"
|
||||||
|
spec:
|
||||||
|
nodeSelector:
|
||||||
|
homelab.hexor.cy/pool: core
|
||||||
|
homelab.hexor.cy/exposure: external
|
||||||
|
containers:
|
||||||
|
- name: web-petting
|
||||||
|
image: ultradesu/web-petting:latest
|
||||||
|
imagePullPolicy: Always
|
||||||
|
args:
|
||||||
|
- web-petting
|
||||||
|
- -l
|
||||||
|
- 0.0.0.0:3000
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
containerPort: 3000
|
||||||
|
env:
|
||||||
|
- name: RUST_LOG
|
||||||
|
value: info
|
||||||
|
- name: WEB_PETTING_DEBUG
|
||||||
|
value: "false"
|
||||||
|
- name: WEB_PETTING_DATABASE_URL
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: web-petting-secrets
|
||||||
|
key: WEB_PETTING_DATABASE_URL
|
||||||
|
# Everything persistent is in PostgreSQL and R2; /data is scratch space only.
|
||||||
|
volumeMounts:
|
||||||
|
- name: data
|
||||||
|
mountPath: /data
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
memory: 256Mi
|
||||||
|
limits:
|
||||||
|
memory: 1Gi
|
||||||
|
volumes:
|
||||||
|
- name: data
|
||||||
|
emptyDir: {}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: web-petting
|
||||||
|
annotations:
|
||||||
|
cert-manager.io/cluster-issuer: letsencrypt
|
||||||
|
traefik.ingress.kubernetes.io/router.entrypoints: websecure
|
||||||
|
spec:
|
||||||
|
ingressClassName: traefik
|
||||||
|
rules:
|
||||||
|
- host: pet.hexor.cy
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: web-petting
|
||||||
|
port:
|
||||||
|
number: 80
|
||||||
|
- host: xn--l1acako8eb.xn--p1ai
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: web-petting
|
||||||
|
port:
|
||||||
|
number: 80
|
||||||
|
tls:
|
||||||
|
- secretName: web-petting-tls
|
||||||
|
hosts:
|
||||||
|
- pet.hexor.cy
|
||||||
|
- secretName: web-petting-murnyanya-tls
|
||||||
|
hosts:
|
||||||
|
- xn--l1acako8eb.xn--p1ai
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
|
||||||
|
resources:
|
||||||
|
- secrets.yaml
|
||||||
|
- deployment.yaml
|
||||||
|
- service.yaml
|
||||||
|
- ingress.yaml
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
# Read-only access to the web-petting-db Secret in the psql namespace
|
||||||
|
# (see postgresql/databases/web-petting.yaml for the other half).
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ServiceAccount
|
||||||
|
metadata:
|
||||||
|
name: db-credentials-reader
|
||||||
|
---
|
||||||
|
apiVersion: external-secrets.io/v1
|
||||||
|
kind: SecretStore
|
||||||
|
metadata:
|
||||||
|
name: psql-credentials
|
||||||
|
spec:
|
||||||
|
provider:
|
||||||
|
kubernetes:
|
||||||
|
remoteNamespace: psql
|
||||||
|
server:
|
||||||
|
caProvider:
|
||||||
|
type: ConfigMap
|
||||||
|
name: kube-root-ca.crt
|
||||||
|
key: ca.crt
|
||||||
|
auth:
|
||||||
|
serviceAccount:
|
||||||
|
name: db-credentials-reader
|
||||||
|
---
|
||||||
|
apiVersion: external-secrets.io/v1
|
||||||
|
kind: ExternalSecret
|
||||||
|
metadata:
|
||||||
|
name: web-petting-secrets
|
||||||
|
spec:
|
||||||
|
refreshInterval: 1h
|
||||||
|
secretStoreRef:
|
||||||
|
kind: SecretStore
|
||||||
|
name: psql-credentials
|
||||||
|
target:
|
||||||
|
name: web-petting-secrets
|
||||||
|
template:
|
||||||
|
data:
|
||||||
|
WEB_PETTING_DATABASE_URL: "postgresql://{{ .username }}:{{ .password }}@main-rw.psql.svc:5432/web_petting"
|
||||||
|
data:
|
||||||
|
- secretKey: username
|
||||||
|
remoteRef:
|
||||||
|
key: web-petting-db
|
||||||
|
property: username
|
||||||
|
- secretKey: password
|
||||||
|
remoteRef:
|
||||||
|
key: web-petting-db
|
||||||
|
property: password
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: web-petting
|
||||||
|
labels:
|
||||||
|
app: web-petting
|
||||||
|
spec:
|
||||||
|
type: ClusterIP
|
||||||
|
selector:
|
||||||
|
app: web-petting
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 80
|
||||||
|
targetPort: 3000
|
||||||
|
protocol: TCP
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
apiVersion: argoproj.io/v1alpha1
|
|
||||||
kind: Application
|
|
||||||
metadata:
|
|
||||||
name: argocd
|
|
||||||
namespace: argocd
|
|
||||||
spec:
|
|
||||||
project: core
|
|
||||||
destination:
|
|
||||||
namespace: argocd
|
|
||||||
server: https://kubernetes.default.svc
|
|
||||||
source:
|
|
||||||
repoURL: https://gt.hexor.cy/ab/homelab.git
|
|
||||||
targetRevision: k8s-ng
|
|
||||||
path: k8s-ng/argocd
|
|
||||||
syncPolicy:
|
|
||||||
automated:
|
|
||||||
selfHeal: true
|
|
||||||
prune: true
|
|
||||||
syncOptions:
|
|
||||||
- CreateNamespace=true
|
|
||||||
- ServerSideApply=true
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
/*.tgz
|
|
||||||
output
|
|
||||||
ci/
|
|
||||||
*.gotmpl
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
dependencies:
|
|
||||||
- name: redis-ha
|
|
||||||
repository: https://dandydeveloper.github.io/charts/
|
|
||||||
version: 4.38.0
|
|
||||||
digest: sha256:0d8b0161248c5ab2c77d62fc77d5ca28393f73f7b7a8abd5474b78bc969cab39
|
|
||||||
generated: "2026-06-15T10:27:45.019725+02:00"
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
annotations:
|
|
||||||
artifacthub.io/changes: |
|
|
||||||
- kind: added
|
|
||||||
description: Prevent high Redis' sentinel CPU usage after rolling update
|
|
||||||
artifacthub.io/signKey: |
|
|
||||||
fingerprint: 2B8F22F57260EFA67BE1C5824B11F800CD9D2252
|
|
||||||
url: https://argoproj.github.io/argo-helm/pgp_keys.asc
|
|
||||||
apiVersion: v2
|
|
||||||
appVersion: v3.5.2
|
|
||||||
dependencies:
|
|
||||||
- condition: redis-ha.enabled
|
|
||||||
name: redis-ha
|
|
||||||
repository: https://dandydeveloper.github.io/charts/
|
|
||||||
version: 4.38.0
|
|
||||||
description: A Helm chart for Argo CD, a declarative, GitOps continuous delivery tool
|
|
||||||
for Kubernetes.
|
|
||||||
home: https://github.com/argoproj/argo-helm
|
|
||||||
icon: https://argo-cd.readthedocs.io/en/stable/assets/logo.png
|
|
||||||
keywords:
|
|
||||||
- argoproj
|
|
||||||
- argocd
|
|
||||||
- gitops
|
|
||||||
kubeVersion: '>=1.25.0-0'
|
|
||||||
maintainers:
|
|
||||||
- name: argoproj
|
|
||||||
url: https://argoproj.github.io/
|
|
||||||
name: argo-cd
|
|
||||||
sources:
|
|
||||||
- https://github.com/argoproj/argo-cd
|
|
||||||
- https://github.com/argoproj/argo-helm/tree/main/charts/argo-cd
|
|
||||||
version: 10.6.0
|
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -1,25 +0,0 @@
|
|||||||
# 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/
|
|
||||||
ci/
|
|
||||||
*.gotmpl
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
apiVersion: v2
|
|
||||||
appVersion: 8.8.0
|
|
||||||
description: This Helm chart provides a highly available Redis implementation with
|
|
||||||
a master/slave configuration and uses Sentinel sidecars for failover management
|
|
||||||
home: https://redis.io/
|
|
||||||
icon: https://img.icons8.com/external-tal-revivo-shadow-tal-revivo/24/external-redis-an-in-memory-data-structure-project-implementing-a-distributed-logo-shadow-tal-revivo.png
|
|
||||||
keywords:
|
|
||||||
- redis
|
|
||||||
- keyvalue
|
|
||||||
- database
|
|
||||||
maintainers:
|
|
||||||
- email: aaron.layfield@gmail.com
|
|
||||||
name: dandydeveloper
|
|
||||||
name: redis-ha
|
|
||||||
sources:
|
|
||||||
- https://redis.io/download
|
|
||||||
- https://github.com/DandyDeveloper/charts/blob/master/charts/redis-ha
|
|
||||||
- https://github.com/oliver006/redis_exporter
|
|
||||||
version: 4.38.0
|
|
||||||
@@ -1,500 +0,0 @@
|
|||||||
# Redis
|
|
||||||
|
|
||||||
[Redis](http://redis.io/) is an advanced key-value cache and store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets, sorted sets, bitmaps and hyperloglogs.
|
|
||||||
|
|
||||||
## TL;DR
|
|
||||||
|
|
||||||
```bash
|
|
||||||
helm repo add dandydev https://dandydeveloper.github.io/charts
|
|
||||||
helm install dandydev/redis-ha
|
|
||||||
```
|
|
||||||
|
|
||||||
By default this chart install 3 pods total:
|
|
||||||
|
|
||||||
* one pod containing a redis master and sentinel container (optional prometheus metrics exporter sidecar available)
|
|
||||||
* two pods each containing a redis slave and sentinel containers (optional prometheus metrics exporter sidecars available)
|
|
||||||
|
|
||||||
## Introduction
|
|
||||||
|
|
||||||
This chart bootstraps a [Redis](https://redis.io) highly available master/slave statefulset in a [Kubernetes](http://kubernetes.io) cluster using the Helm package manager.
|
|
||||||
|
|
||||||
## Prerequisites
|
|
||||||
|
|
||||||
* Kubernetes 1.8+ with Beta APIs enabled
|
|
||||||
* PV provisioner support in the underlying infrastructure
|
|
||||||
* Helm v3+
|
|
||||||
|
|
||||||
## Upgrading the Chart
|
|
||||||
|
|
||||||
Please note that there have been a number of changes simplifying the redis management strategy (for better failover and elections) in the 3.x version of this chart. These changes allow the use of official [redis](https://hub.docker.com/_/redis/) images that do not require special RBAC or ServiceAccount roles. As a result when upgrading from version >=2.0.1 to >=3.0.0 of this chart, `Role`, `RoleBinding`, and `ServiceAccount` resources should be deleted manually.
|
|
||||||
|
|
||||||
### Upgrading the chart from 3.x to 4.x
|
|
||||||
|
|
||||||
Starting from version `4.x` HAProxy sidecar prometheus-exporter removed and replaced by the embedded [HAProxy metrics endpoint](https://github.com/haproxy/haproxy/tree/master/contrib/prometheus-exporter), as a result when upgrading from version 3.x to 4.x section `haproxy.exporter` should be removed and the `haproxy.metrics` need to be configured for fit your needs.
|
|
||||||
|
|
||||||
## Installing the Chart
|
|
||||||
|
|
||||||
To install the chart
|
|
||||||
|
|
||||||
```bash
|
|
||||||
helm repo add dandydev https://dandydeveloper.github.io/charts
|
|
||||||
helm install dandydev/redis-ha
|
|
||||||
```
|
|
||||||
|
|
||||||
The command deploys Redis on the Kubernetes cluster in the default configuration. By default this chart install one master pod containing redis master container and sentinel container along with 2 redis slave pods each containing their own sentinel sidecars. The [configuration](#configuration) section lists the parameters that can be configured during installation.
|
|
||||||
|
|
||||||
> **Tip**: List all releases using `helm list`
|
|
||||||
|
|
||||||
## Uninstalling the Chart
|
|
||||||
|
|
||||||
To uninstall/delete the deployment:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
helm delete <chart-name>
|
|
||||||
```
|
|
||||||
|
|
||||||
The command removes all the Kubernetes components associated with the chart and deletes the release.
|
|
||||||
|
|
||||||
## Configuration
|
|
||||||
|
|
||||||
The following table lists the configurable parameters of the Redis chart and their default values.
|
|
||||||
|
|
||||||
### General parameters
|
|
||||||
|
|
||||||
| Parameter | Description | Type | Default |
|
|
||||||
|-----|------|---------|-------------|
|
|
||||||
| `additionalAffinities` | Additional affinities to add to the Redis server pods. # Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity | object | `{}` |
|
|
||||||
| `affinity` | Override all other affinity settings for the Redis server pods with a string. | string | `""` |
|
|
||||||
| `auth` | Configures redis with AUTH (requirepass & masterauth conf params) | bool | `false` |
|
|
||||||
| `authKey` | Defines the key holding the redis password in existing secret. | string | `"auth"` |
|
|
||||||
| `authSecretAnnotations` | Annotations for auth secret | object | `{}` |
|
|
||||||
| `configmap.labels` | Custom labels for the redis configmap | object | `{}` |
|
|
||||||
| `configmapTest.image` | Image for redis-ha-configmap-test hook | object | `{"repository":"koalaman/shellcheck","tag":"v0.11.0"}` |
|
|
||||||
| `configmapTest.image.repository` | Repository of the configmap shellcheck test image. | string | `"koalaman/shellcheck"` |
|
|
||||||
| `configmapTest.image.tag` | Tag of the configmap shellcheck test image. | string | `"v0.11.0"` |
|
|
||||||
| `configmapTest.resources` | Resources for the ConfigMap test pod | object | `{}` |
|
|
||||||
| `containerSecurityContext` | Security context to be added to the Redis containers. | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"runAsNonRoot":true,"runAsUser":1000,"seccompProfile":{"type":"RuntimeDefault"}}` |
|
|
||||||
| `emptyDir` | Configuration of `emptyDir`, used only if persistentVolume is disabled and no hostPath specified | object | `{}` |
|
|
||||||
| `existingSecret` | An existing secret containing a key defined by `authKey` that configures `requirepass` and `masterauth` in the conf parameters (Requires `auth: enabled`, cannot be used in conjunction with `.Values.redisPassword`) | string | `nil` |
|
|
||||||
| `extraContainers` | Extra containers to include in StatefulSet | list | `[]` |
|
|
||||||
| `extraInitContainers` | Extra init containers to include in StatefulSet | list | `[]` |
|
|
||||||
| `extraLabels` | Labels added here are applied to all created resources | object | `{}` |
|
|
||||||
| `extraVolumes` | Extra volumes to include in StatefulSet | list | `[]` |
|
|
||||||
| `fullnameOverride` | Full name of the Redis HA Resources | string | `""` |
|
|
||||||
| `global.compatibility` | Openshift compatibility options | object | `{"openshift":{"adaptSecurityContext":"auto"}}` |
|
|
||||||
| `global.priorityClassName` | Default priority class for all components | string | `""` |
|
|
||||||
| `hardAntiAffinity` | Whether the Redis server pods should be forced to run on separate nodes. # This is accomplished by setting their AntiAffinity with requiredDuringSchedulingIgnoredDuringExecution as opposed to preferred. # Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#inter-pod-affinity-and-anti-affinity-beta-feature | bool | `true` |
|
|
||||||
| `hostPath.chown` | if chown is true, an init-container with root permissions is launched to change the owner of the hostPath folder to the user defined in the security context | bool | `true` |
|
|
||||||
| `hostPath.path` | Use this path on the host for data storage. path is evaluated as template so placeholders are replaced | string | `""` |
|
|
||||||
| `image.pullPolicy` | Redis image pull policy | string | `"IfNotPresent"` |
|
|
||||||
| `image.repository` | Redis image repository | string | `"public.ecr.aws/docker/library/redis"` |
|
|
||||||
| `image.tag` | Redis image tag | string | `"8.8.0-alpine"` |
|
|
||||||
| `imagePullSecrets` | Reference to one or more secrets to be used when pulling redis images | list | `[]` |
|
|
||||||
| `init.resources` | Extra init resources | object | `{}` |
|
|
||||||
| `labels` | Custom labels for the redis pod | object | `{}` |
|
|
||||||
| `nameOverride` | Name override for Redis HA resources | string | `""` |
|
|
||||||
| `networkPolicy.annotations` | Annotations for NetworkPolicy | object | `{}` |
|
|
||||||
| `networkPolicy.egressRules` | user can define egress rules too, uses the same structure as ingressRules | list | `[{"ports":[{"port":53,"protocol":"UDP"},{"port":53,"protocol":"TCP"}],"selectors":[{"namespaceSelector":{}},{"ipBlock":{"cidr":"169.254.0.0/16"}}]}]` |
|
|
||||||
| `networkPolicy.egressRules[0].selectors[0]` | Allow all destinations for DNS traffic | object | `{"namespaceSelector":{}}` |
|
|
||||||
| `networkPolicy.enabled` | whether NetworkPolicy for Redis StatefulSets should be created. when enabled, inter-Redis connectivity is created | bool | `false` |
|
|
||||||
| `networkPolicy.ingressRules` | User defined ingress rules that Redis should permit into. Uses the format defined in https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors | list | `[]` |
|
|
||||||
| `networkPolicy.labels` | Labels for NetworkPolicy | object | `{}` |
|
|
||||||
| `nodeSelector` | Node labels for pod assignment | object | `{}` |
|
|
||||||
| `persistentVolume.accessModes` | Persistent volume access modes | list | `["ReadWriteOnce"]` |
|
|
||||||
| `persistentVolume.annotations` | Annotations for the volume | object | `{}` |
|
|
||||||
| `persistentVolume.enabled` | Enable persistent volume | bool | `true` |
|
|
||||||
| `persistentVolume.labels` | Labels for the volume | object | `{}` |
|
|
||||||
| `persistentVolume.size` | Persistent volume size | string | `"10Gi"` |
|
|
||||||
| `persistentVolume.storageClass` | redis-ha data Persistent Volume Storage Class | string | `nil` |
|
|
||||||
| `podDisruptionBudget` | Pod Disruption Budget rules | object | `{}` |
|
|
||||||
| `podManagementPolicy` | The statefulset pod management policy | string | `"OrderedReady"` |
|
|
||||||
| `priorityClassName` | Kubernetes priorityClass name for the redis-ha-server pod | string | `""` |
|
|
||||||
| `rbac.create` | Create and use RBAC resources | bool | `true` |
|
|
||||||
| `redis.annotations` | Annotations for the redis statefulset | object | `{}` |
|
|
||||||
| `redis.authClients` | It is possible to disable client side certificates authentication when "authClients" is set to "no" | string | `""` |
|
|
||||||
| `redis.config` | Any valid redis config options in this section will be applied to each server, For multi-value configs use list instead of string (for example loadmodule) (see below) | object | see values.yaml |
|
|
||||||
| `redis.config.maxmemory` | Max memory to use for each redis instance. Default is unlimited. | string | `"0"` |
|
|
||||||
| `redis.config.maxmemory-policy` | Max memory policy to use for each redis instance. Default is volatile-lru. | string | `"volatile-lru"` |
|
|
||||||
| `redis.config.min-replicas-max-lag` | Value in seconds | int | `5` |
|
|
||||||
| `redis.config.repl-diskless-sync` | When enabled, directly sends the RDB over the wire to slaves, without using the disk as intermediate storage. Default is false. | string | `"yes"` |
|
|
||||||
| `redis.config.save` | Please note that local (on-disk) RDBs will still be created when re-syncing with a new slave. The only way to prevent this is to enable diskless replication. | string | `"900 1"` |
|
|
||||||
| `redis.customArgs` | Allows overriding the redis container arguments | list | `[]` |
|
|
||||||
| `redis.customCommand` | Allows overriding the redis container command | list | `[]` |
|
|
||||||
| `redis.customConfig` | Allows for custom redis.conf files to be applied. If this is used then `redis.config` is ignored | string | `nil` |
|
|
||||||
| `redis.disableCommands` | Array with commands to disable | list | `["FLUSHDB","FLUSHALL"]` |
|
|
||||||
| `redis.envFrom` | Load environment variables from ConfigMap/Secret | list | `[]` |
|
|
||||||
| `redis.extraVolumeMounts` | additional volumeMounts for Redis container | list | `[]` |
|
|
||||||
| `redis.lifecycle` | Container Lifecycle Hooks for redis container Ref: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/ | object | see values.yaml |
|
|
||||||
| `redis.livenessProbe` | Liveness probe parameters for redis container | object | `{"enabled":true,"failureThreshold":5,"initialDelaySeconds":30,"periodSeconds":15,"successThreshold":1,"timeoutSeconds":15}` |
|
|
||||||
| `redis.livenessProbe.enabled` | Enable the Liveness Probe | bool | `true` |
|
|
||||||
| `redis.livenessProbe.failureThreshold` | Failure threshold for liveness probe | int | `5` |
|
|
||||||
| `redis.livenessProbe.initialDelaySeconds` | Initial delay in seconds for liveness probe | int | `30` |
|
|
||||||
| `redis.livenessProbe.periodSeconds` | Period in seconds after which liveness probe will be repeated | int | `15` |
|
|
||||||
| `redis.livenessProbe.successThreshold` | Success threshold for liveness probe | int | `1` |
|
|
||||||
| `redis.livenessProbe.timeoutSeconds` | Timeout seconds for liveness probe | int | `15` |
|
|
||||||
| `redis.masterGroupName` | Redis convention for naming the cluster group: must match `^[\\w-\\.]+$` and can be templated | string | `"mymaster"` |
|
|
||||||
| `redis.minReadySeconds` | Configure the 'minReadySeconds' parameter to StatefulSet ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#minreadyseconds | int | `0` |
|
|
||||||
| `redis.podAnnotations` | Annotations to be added to the redis statefulset pods | object | `{}` |
|
|
||||||
| `redis.port` | Port to access the redis service | int | `6379` |
|
|
||||||
| `redis.readinessProbe` | Readiness probe parameters for redis container | object | `{"enabled":true,"failureThreshold":5,"initialDelaySeconds":30,"periodSeconds":15,"successThreshold":1,"timeoutSeconds":15}` |
|
|
||||||
| `redis.readinessProbe.enabled` | Enable the Readiness Probe | bool | `true` |
|
|
||||||
| `redis.readinessProbe.failureThreshold` | Failure threshold for readiness probe | int | `5` |
|
|
||||||
| `redis.readinessProbe.initialDelaySeconds` | Initial delay in seconds for readiness probe | int | `30` |
|
|
||||||
| `redis.readinessProbe.periodSeconds` | Period in seconds after which readiness probe will be repeated | int | `15` |
|
|
||||||
| `redis.readinessProbe.successThreshold` | Success threshold for readiness probe | int | `1` |
|
|
||||||
| `redis.readinessProbe.timeoutSeconds` | Timeout seconds for readiness probe | int | `15` |
|
|
||||||
| `redis.resources` | CPU/Memory for master/slave nodes resource requests/limits | object | `{}` |
|
|
||||||
| `redis.startupProbe` | Startup probe parameters for redis container | object | `{"enabled":true,"failureThreshold":5,"initialDelaySeconds":30,"periodSeconds":15,"successThreshold":1,"timeoutSeconds":15}` |
|
|
||||||
| `redis.startupProbe.enabled` | Enable Startup Probe | bool | `true` |
|
|
||||||
| `redis.startupProbe.failureThreshold` | Failure threshold for startup probe | int | `5` |
|
|
||||||
| `redis.startupProbe.initialDelaySeconds` | Initial delay in seconds for startup probe | int | `30` |
|
|
||||||
| `redis.startupProbe.periodSeconds` | Period in seconds after which startup probe will be repeated | int | `15` |
|
|
||||||
| `redis.startupProbe.successThreshold` | Success threshold for startup probe | int | `1` |
|
|
||||||
| `redis.startupProbe.timeoutSeconds` | Timeout seconds for startup probe | int | `15` |
|
|
||||||
| `redis.terminationGracePeriodSeconds` | Increase terminationGracePeriodSeconds to allow writing large RDB snapshots. (k8s default is 30s) ref: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-termination-forced | int | `60` |
|
|
||||||
| `redis.tlsPort` | TLS Port to access the redis service | int | `nil` |
|
|
||||||
| `redis.tlsReplication` | Configures redis with tls-replication parameter, if true sets "tls-replication yes" in redis.conf | bool | `nil` |
|
|
||||||
| `redis.updateStrategy` | Update strategy for Redis StatefulSet # ref: https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#update-strategies | object | `{"type":"RollingUpdate"}` |
|
|
||||||
| `redisPassword` | A password that configures a `requirepass` and `masterauth` in the conf parameters (Requires `auth: enabled`) | string | `nil` |
|
|
||||||
| `replicas` | Number of redis master/slave | int | `3` |
|
|
||||||
| `restore.existingSecret` | Set existingSecret to true to use secret specified in existingSecret above | bool | `false` |
|
|
||||||
| `restore.redis.source` | | string | `""` |
|
|
||||||
| `restore.s3.access_key` | Restore init container - AWS AWS_ACCESS_KEY_ID to access restore.s3.source | string | `""` |
|
|
||||||
| `restore.s3.region` | Restore init container - AWS AWS_REGION to access restore.s3.source | string | `""` |
|
|
||||||
| `restore.s3.secret_key` | Restore init container - AWS AWS_SECRET_ACCESS_KEY to access restore.s3.source | string | `""` |
|
|
||||||
| `restore.s3.source` | Restore init container - AWS S3 location of dump - i.e. s3://bucket/dump.rdb or false | string | `""` |
|
|
||||||
| `restore.ssh.key` | Restore init container - SSH private key to scp restore.ssh.source to init container. Key should be in one line separated with \n. i.e. `-----BEGIN RSA PRIVATE KEY-----\n...\n...\n-----END RSA PRIVATE KEY-----` | string | `""` |
|
|
||||||
| `restore.ssh.source` | Restore init container - SSH scp location of dump - i.e. user@server:/path/dump.rdb or false | string | `""` |
|
|
||||||
| `restore.timeout` | Timeout for the restore | int | `600` |
|
|
||||||
| `ro_replicas` | Comma separated list of slaves which never get promoted to be master. Count starts with 0. Allowed values 1-9. i.e. 3,4 - 3th and 4th redis slave never make it to be master, where master is index 0. | string | `""` |
|
|
||||||
| `schedulerName` | Use an alternate scheduler, e.g. "stork". ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/ | string | `""` |
|
|
||||||
| `securityContext` | Security context to be added to the Redis StatefulSet. | object | `{"fsGroup":1000,"runAsNonRoot":true,"runAsUser":1000}` |
|
|
||||||
| `serviceAccount.annotations` | Annotations to be added to the service account for the redis statefulset | object | `{}` |
|
|
||||||
| `serviceAccount.automountToken` | opt in/out of automounting API credentials into container. Ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ | bool | `false` |
|
|
||||||
| `serviceAccount.create` | Specifies whether a ServiceAccount should be created | bool | `true` |
|
|
||||||
| `serviceAccount.name` | The name of the ServiceAccount to use. If not set and create is true, a name is generated using the redis-ha.fullname template | string | `""` |
|
|
||||||
| `serviceLabels` | Custom labels for redis service | object | `{}` |
|
|
||||||
| `splitBrainDetection.interval` | Interval between redis sentinel and server split brain checks (in seconds) | int | `60` |
|
|
||||||
| `splitBrainDetection.resources` | splitBrainDetection resources | object | `{}` |
|
|
||||||
| `splitBrainDetection.retryInterval` | | int | `10` |
|
|
||||||
| `sysctlImage.command` | sysctlImage command to execute | list | `[]` |
|
|
||||||
| `sysctlImage.enabled` | Enable an init container to modify Kernel settings | bool | `false` |
|
|
||||||
| `sysctlImage.mountHostSys` | Mount the host `/sys` folder to `/host-sys` | bool | `false` |
|
|
||||||
| `sysctlImage.pullPolicy` | sysctlImage Init container pull policy | string | `"Always"` |
|
|
||||||
| `sysctlImage.registry` | sysctlImage Init container registry | string | `"public.ecr.aws/docker/library"` |
|
|
||||||
| `sysctlImage.repository` | sysctlImage Init container name | string | `"busybox"` |
|
|
||||||
| `sysctlImage.resources` | sysctlImage resources | object | `{}` |
|
|
||||||
| `sysctlImage.tag` | sysctlImage Init container tag | string | `"1.38.0"` |
|
|
||||||
| `tls.caCertFile` | Name of CA certificate file | string | `"ca.crt"` |
|
|
||||||
| `tls.certFile` | Name of certificate file | string | `"redis.crt"` |
|
|
||||||
| `tls.dhParamsFile` | Name of Diffie-Hellman (DH) key exchange parameters file (Example: redis.dh) | string | `nil` |
|
|
||||||
| `tls.keyFile` | Name of key file | string | `"redis.key"` |
|
|
||||||
| `tolerations` | | list | `[]` |
|
|
||||||
| `topologySpreadConstraints.enabled` | Enable topology spread constraints | bool | `false` |
|
|
||||||
| `topologySpreadConstraints.maxSkew` | Max skew of pods tolerated | string | `""` |
|
|
||||||
| `topologySpreadConstraints.topologyKey` | Topology key for spread constraints | string | `""` |
|
|
||||||
| `topologySpreadConstraints.whenUnsatisfiable` | Enforcement policy, hard or soft | string | `""` |
|
|
||||||
|
|
||||||
### Redis Sentinel parameters
|
|
||||||
|
|
||||||
| Parameter | Description | Type | Default |
|
|
||||||
|-----|------|---------|-------------|
|
|
||||||
| `sentinel.auth` | Enables or disables sentinel AUTH (Requires `sentinel.password` to be set) | bool | `false` |
|
|
||||||
| `sentinel.authClients` | It is possible to disable client side certificates authentication when "authClients" is set to "no" | string | `""` |
|
|
||||||
| `sentinel.authKey` | The key holding the sentinel password in an existing secret. | string | `"sentinel-password"` |
|
|
||||||
| `sentinel.config` | Valid sentinel config options in this section will be applied as config options to each sentinel (see below) | object | see values.yaml |
|
|
||||||
| `sentinel.customArgs` | | list | `[]` |
|
|
||||||
| `sentinel.customCommand` | | list | `[]` |
|
|
||||||
| `sentinel.customConfig` | Allows for custom sentinel.conf files to be applied. If this is used then `sentinel.config` is ignored | string | `""` |
|
|
||||||
| `sentinel.existingSecret` | An existing secret containing a key defined by `sentinel.authKey` that configures `requirepass` in the conf parameters (Requires `sentinel.auth: enabled`, cannot be used in conjunction with `.Values.sentinel.password`) | string | `""` |
|
|
||||||
| `sentinel.extraVolumeMounts` | additional volumeMounts for Sentinel container | list | `[]` |
|
|
||||||
| `sentinel.lifecycle` | Container Lifecycle Hooks for sentinel container. Ref: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/ | object | `{}` |
|
|
||||||
| `sentinel.livenessProbe.enabled` | | bool | `true` |
|
|
||||||
| `sentinel.livenessProbe.failureThreshold` | Failure threshold for liveness probe | int | `5` |
|
|
||||||
| `sentinel.livenessProbe.initialDelaySeconds` | Initial delay in seconds for liveness probe | int | `30` |
|
|
||||||
| `sentinel.livenessProbe.periodSeconds` | Period in seconds after which liveness probe will be repeated | int | `15` |
|
|
||||||
| `sentinel.livenessProbe.successThreshold` | Success threshold for liveness probe | int | `1` |
|
|
||||||
| `sentinel.livenessProbe.timeoutSeconds` | Timeout seconds for liveness probe | int | `15` |
|
|
||||||
| `sentinel.password` | A password that configures a `requirepass` in the conf parameters (Requires `sentinel.auth: enabled`) | string | `nil` |
|
|
||||||
| `sentinel.resolveHostnames` | Configures sentinel with resolve-hostnames parameter, if true sets "resolve-hostnames yes" in sentinel.conf | bool | `nil` |
|
|
||||||
| `sentinel.announceHostnames` | Configures sentinel with announce-hostnames parameter, if true sets "announce-hostnames yes" in sentinel.conf | bool | `nil` |
|
|
||||||
| `sentinel.port` | Port to access the sentinel service | int | `26379` |
|
|
||||||
| `sentinel.quorum` | Minimum number of nodes expected to be live. | int | `2` |
|
|
||||||
| `sentinel.readinessProbe.enabled` | | bool | `true` |
|
|
||||||
| `sentinel.readinessProbe.failureThreshold` | Failure threshold for readiness probe | int | `5` |
|
|
||||||
| `sentinel.readinessProbe.initialDelaySeconds` | Initial delay in seconds for readiness probe | int | `30` |
|
|
||||||
| `sentinel.readinessProbe.periodSeconds` | Period in seconds after which readiness probe will be repeated | int | `15` |
|
|
||||||
| `sentinel.readinessProbe.successThreshold` | Success threshold for readiness probe | int | `3` |
|
|
||||||
| `sentinel.readinessProbe.timeoutSeconds` | Timeout seconds for readiness probe | int | `15` |
|
|
||||||
| `sentinel.resources` | CPU/Memory for sentinel node resource requests/limits | object | `{}` |
|
|
||||||
| `sentinel.startupProbe` | Startup probe parameters for redis container | object | `{"enabled":true,"failureThreshold":3,"initialDelaySeconds":5,"periodSeconds":10,"successThreshold":1,"timeoutSeconds":15}` |
|
|
||||||
| `sentinel.startupProbe.enabled` | Enable Startup Probe | bool | `true` |
|
|
||||||
| `sentinel.startupProbe.failureThreshold` | Failure threshold for startup probe | int | `3` |
|
|
||||||
| `sentinel.startupProbe.initialDelaySeconds` | Initial delay in seconds for startup probe | int | `5` |
|
|
||||||
| `sentinel.startupProbe.periodSeconds` | Period in seconds after which startup probe will be repeated | int | `10` |
|
|
||||||
| `sentinel.startupProbe.successThreshold` | Success threshold for startup probe | int | `1` |
|
|
||||||
| `sentinel.startupProbe.timeoutSeconds` | Timeout seconds for startup probe | int | `15` |
|
|
||||||
| `sentinel.tlsPort` | TLS Port to access the sentinel service | int | `nil` |
|
|
||||||
| `sentinel.tlsReplication` | Configures sentinel with tls-replication parameter, if true sets "tls-replication yes" in sentinel.conf | bool | `nil` |
|
|
||||||
|
|
||||||
### HAProxy parameters
|
|
||||||
|
|
||||||
| Parameter | Description | Type | Default |
|
|
||||||
|-----|------|---------|-------------|
|
|
||||||
| `haproxy.IPv6.enabled` | Enable HAProxy parameters to bind and consume IPv6 addresses. Enabled by default. | bool | `true` |
|
|
||||||
| `haproxy.additionalAffinities` | Additional affinities to add to the haproxy pods. | object | `{}` |
|
|
||||||
| `haproxy.additionalPorts` | Additional ports to expose on HAProxy service and deployment. Each port should have a name, containerPort, and optionally servicePort (defaults to containerPort) | list | `[]` |
|
|
||||||
| `haproxy.affinity` | Override all other affinity settings for the haproxy pods with a string. | string | `""` |
|
|
||||||
| `haproxy.annotations` | HAProxy template annotations | object | `{}` |
|
|
||||||
| `haproxy.checkFall` | haproxy.cfg `check fall` setting | int | `1` |
|
|
||||||
| `haproxy.checkInterval` | haproxy.cfg `check inter` setting | string | `"1s"` |
|
|
||||||
| `haproxy.containerPort` | Modify HAProxy deployment container port | int | `6379` |
|
|
||||||
| `haproxy.containerSecurityContext` | Security context to be added to the HAProxy containers. | object | `{"allowPrivilegeEscalation":false,"capabilities":{"drop":["ALL"]},"runAsNonRoot":true,"seccompProfile":{"type":"RuntimeDefault"}}` |
|
|
||||||
| `haproxy.customConfig` | Allows for custom config-haproxy.cfg file to be applied. If this is used then default config will be overwriten | string | `nil` |
|
|
||||||
| `haproxy.deploymentAnnotations` | HAProxy deployment annotations | object | `{}` |
|
|
||||||
| `haproxy.deploymentStrategy` | Deployment strategy for the haproxy deployment | object | `{"type":"RollingUpdate"}` |
|
|
||||||
| `haproxy.emptyDir` | Configuration of `emptyDir` | object | `{}` |
|
|
||||||
| `haproxy.enabled` | Enabled HAProxy LoadBalancing/Proxy | bool | `false` |
|
|
||||||
| `haproxy.extraConfig` | Allows to place any additional configuration section to add to the default config-haproxy.cfg | string | `nil` |
|
|
||||||
| `haproxy.hardAntiAffinity` | Whether the haproxy pods should be forced to run on separate nodes. | bool | `true` |
|
|
||||||
| `haproxy.image.pullPolicy` | HAProxy Image PullPolicy | string | `"IfNotPresent"` |
|
|
||||||
| `haproxy.image.repository` | HAProxy Image Repository | string | `"public.ecr.aws/docker/library/haproxy"` |
|
|
||||||
| `haproxy.image.tag` | HAProxy Image Tag | string | `"3.0.8-alpine"` |
|
|
||||||
| `haproxy.imagePullSecrets` | Reference to one or more secrets to be used when pulling images ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ | list | `[]` |
|
|
||||||
| `haproxy.init.resources` | Extra init resources | object | `{}` |
|
|
||||||
| `haproxy.labels` | Custom labels for the haproxy pod | object | `{}` |
|
|
||||||
| `haproxy.lifecycle` | Container lifecycle hooks. Ref: https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/ | object | `{}` |
|
|
||||||
| `haproxy.metrics.enabled` | HAProxy enable prometheus metric scraping | bool | `false` |
|
|
||||||
| `haproxy.metrics.port` | HAProxy prometheus metrics scraping port | int | `9101` |
|
|
||||||
| `haproxy.metrics.portName` | HAProxy metrics scraping port name | string | `"http-exporter-port"` |
|
|
||||||
| `haproxy.metrics.scrapePath` | HAProxy prometheus metrics scraping path | string | `"/metrics"` |
|
|
||||||
| `haproxy.metrics.serviceMonitor.disableAPICheck` | Disable API Check on ServiceMonitor | bool | `false` |
|
|
||||||
| `haproxy.metrics.serviceMonitor.enabled` | When set true then use a ServiceMonitor to configure scraping | bool | `false` |
|
|
||||||
| `haproxy.metrics.serviceMonitor.endpointAdditionalProperties` | Set additional properties for the ServiceMonitor endpoints such as relabeling, scrapeTimeout, tlsConfig, and more. | object | `{}` |
|
|
||||||
| `haproxy.metrics.serviceMonitor.interval` | Set how frequently Prometheus should scrape (default is 30s) | string | `""` |
|
|
||||||
| `haproxy.metrics.serviceMonitor.labels` | Set labels for the ServiceMonitor, use this to define your scrape label for Prometheus Operator | object | `{}` |
|
|
||||||
| `haproxy.metrics.serviceMonitor.namespace` | Set the namespace the ServiceMonitor should be deployed | string | `.Release.Namespace` |
|
|
||||||
| `haproxy.metrics.serviceMonitor.telemetryPath` | Set path to redis-exporter telemtery-path (default is /metrics) | string | `""` |
|
|
||||||
| `haproxy.metrics.serviceMonitor.timeout` | Set timeout for scrape (default is 10s) | string | `""` |
|
|
||||||
| `haproxy.networkPolicy.annotations` | Annotations for Haproxy NetworkPolicy | object | `{}` |
|
|
||||||
| `haproxy.networkPolicy.egressRules` | user can define egress rules too, uses the same structure as ingressRules | list | `[]` |
|
|
||||||
| `haproxy.networkPolicy.enabled` | whether NetworkPolicy for Haproxy should be created | bool | `false` |
|
|
||||||
| `haproxy.networkPolicy.ingressRules` | user defined ingress rules that Haproxy should permit into. uses the format defined in https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors | list | `[]` |
|
|
||||||
| `haproxy.networkPolicy.labels` | Labels for Haproxy NetworkPolicy | object | `{}` |
|
|
||||||
| `haproxy.podAnnotations` | Annotations to be added to the HAProxy deployment pods | object | `{}` |
|
|
||||||
| `haproxy.podDisruptionBudget` | Pod Disruption Budget ref: https://kubernetes.io/docs/tasks/run-application/configure-pdb/ | object | `{}` |
|
|
||||||
| `haproxy.priorityClassName` | Kubernetes priorityClass name for the haproxy pod | string | `""` |
|
|
||||||
| `haproxy.readOnly` | Enable read-only redis-slaves | object | `{"enabled":false,"port":6380}` |
|
|
||||||
| `haproxy.readOnly.enabled` | Enable if you want a dedicated port in haproxy for redis-slaves | bool | `false` |
|
|
||||||
| `haproxy.readOnly.port` | Port for the read-only redis-slaves | int | `6380` |
|
|
||||||
| `haproxy.replicas` | Number of HAProxy instances | int | `3` |
|
|
||||||
| `haproxy.resources` | HAProxy resources | object | `{}` |
|
|
||||||
| `haproxy.securityContext` | Security context to be added to the HAProxy deployment. | object | `{"fsGroup":99,"runAsNonRoot":true,"runAsUser":99}` |
|
|
||||||
| `haproxy.service.annotations` | HAProxy service annotations | string | `nil` |
|
|
||||||
| `haproxy.service.externalIPs` | HAProxy external IPs | object | `{}` |
|
|
||||||
| `haproxy.service.externalTrafficPolicy` | HAProxy service externalTrafficPolicy value (haproxy.service.type must be LoadBalancer) | string | `nil` |
|
|
||||||
| `haproxy.service.labels` | HAProxy service labels | object | `{}` |
|
|
||||||
| `haproxy.service.loadBalancerIP` | HAProxy service loadbalancer IP | string | `nil` |
|
|
||||||
| `haproxy.service.loadBalancerSourceRanges` | List of CIDR's allowed to connect to LoadBalancer | list | `[]` |
|
|
||||||
| `haproxy.service.nodePort` | HAProxy service nodePort value (haproxy.service.type must be NodePort) | int | `nil` |
|
|
||||||
| `haproxy.service.type` | HAProxy service type "ClusterIP", "LoadBalancer" or "NodePort" | string | `"ClusterIP"` |
|
|
||||||
| `haproxy.serviceAccount.automountToken` | | bool | `true` |
|
|
||||||
| `haproxy.serviceAccount.create` | Specifies whether a ServiceAccount should be created | bool | `true` |
|
|
||||||
| `haproxy.serviceAccountName` | HAProxy serviceAccountName | string | `"redis-sa"` |
|
|
||||||
| `haproxy.servicePort` | Modify HAProxy service port | int | `6379` |
|
|
||||||
| `haproxy.stickyBalancing` | HAProxy sticky load balancing to Redis nodes. Helps with connections shutdown. | bool | `false` |
|
|
||||||
| `haproxy.tests.resources` | Pod resources for the tests against HAProxy. | object | `{}` |
|
|
||||||
| `haproxy.timeout.check` | haproxy.cfg `timeout check` setting | string | `"2s"` |
|
|
||||||
| `haproxy.timeout.client` | haproxy.cfg `timeout client` setting | string | `"330s"` |
|
|
||||||
| `haproxy.timeout.connect` | haproxy.cfg `timeout connect` setting | string | `"4s"` |
|
|
||||||
| `haproxy.timeout.server` | haproxy.cfg `timeout server` setting | string | `"330s"` |
|
|
||||||
| `haproxy.timeout.tunnel` | haproxy.cfg `timeout tunnel` setting | string | `"1h"` |
|
|
||||||
| `haproxy.tls` | Enable TLS termination on HAproxy, This will create a volume mount | object | `{"certMountPath":"/tmp/","enabled":false,"keyName":null,"secretName":""}` |
|
|
||||||
| `haproxy.tls.certMountPath` | Path to mount the secret that contains the certificates. haproxy | string | `"/tmp/"` |
|
|
||||||
| `haproxy.tls.enabled` | If "true" this will enable TLS termination on haproxy | bool | `false` |
|
|
||||||
| `haproxy.tls.keyName` | Key file name | string | `nil` |
|
|
||||||
| `haproxy.tls.secretName` | Secret containing the .pem file | string | `""` |
|
|
||||||
|
|
||||||
### Prometheus exporter parameters
|
|
||||||
|
|
||||||
| Parameter | Description | Type | Default |
|
|
||||||
|-----|------|---------|-------------|
|
|
||||||
| `exporter.address` | Address/Host for Redis instance. Exists to circumvent issues with IPv6 dns resolution that occurs on certain environments | string | `"localhost"` |
|
|
||||||
| `exporter.enabled` | If `true`, the prometheus exporter sidecar is enabled | bool | `false` |
|
|
||||||
| `exporter.extraArgs` | Additional args for redis exporter | object | `{}` |
|
|
||||||
| `exporter.image` | Exporter image | string | `"quay.io/oliver006/redis_exporter"` |
|
|
||||||
| `exporter.livenessProbe.httpGet.path` | Exporter liveness probe httpGet path | string | `"/metrics"` |
|
|
||||||
| `exporter.livenessProbe.httpGet.port` | Exporter liveness probe httpGet port | int | `9121` |
|
|
||||||
| `exporter.livenessProbe.initialDelaySeconds` | Initial delay in seconds for liveness probe of exporter | int | `15` |
|
|
||||||
| `exporter.livenessProbe.periodSeconds` | Period in seconds after which liveness probe will be repeated | int | `15` |
|
|
||||||
| `exporter.livenessProbe.timeoutSeconds` | Timeout seconds for liveness probe of exporter | int | `3` |
|
|
||||||
| `exporter.port` | Exporter port | int | `9121` |
|
|
||||||
| `exporter.portName` | Exporter port name | string | `"exporter-port"` |
|
|
||||||
| `exporter.pullPolicy` | Exporter image pullPolicy | string | `"IfNotPresent"` |
|
|
||||||
| `exporter.readinessProbe.httpGet.path` | Exporter readiness probe httpGet path | string | `"/metrics"` |
|
|
||||||
| `exporter.readinessProbe.httpGet.port` | Exporter readiness probe httpGet port | int | `9121` |
|
|
||||||
| `exporter.readinessProbe.initialDelaySeconds` | Initial delay in seconds for readiness probe of exporter | int | `15` |
|
|
||||||
| `exporter.readinessProbe.periodSeconds` | Period in seconds after which readiness probe will be repeated | int | `15` |
|
|
||||||
| `exporter.readinessProbe.successThreshold` | Success threshold for readiness probe of exporter | int | `2` |
|
|
||||||
| `exporter.readinessProbe.timeoutSeconds` | Timeout seconds for readiness probe of exporter | int | `3` |
|
|
||||||
| `exporter.resources` | cpu/memory resource limits/requests | object | `{}` |
|
|
||||||
| `exporter.scrapePath` | Exporter scrape path | string | `"/metrics"` |
|
|
||||||
| `exporter.script` | A custom custom Lua script that will be mounted to exporter for collection of custom metrics. Creates a ConfigMap and sets env var `REDIS_EXPORTER_SCRIPT`. | string | `""` |
|
|
||||||
| `exporter.serviceMonitor.disableAPICheck` | Disable API Check on ServiceMonitor | bool | `false` |
|
|
||||||
| `exporter.serviceMonitor.enabled` | When set true then use a ServiceMonitor to configure scraping | bool | `false` |
|
|
||||||
| `exporter.serviceMonitor.endpointAdditionalProperties` | Set additional properties for the ServiceMonitor endpoints such as relabeling, scrapeTimeout, tlsConfig, and more. | object | `{}` |
|
|
||||||
| `exporter.serviceMonitor.interval` | Set how frequently Prometheus should scrape (default is 30s) | string | `""` |
|
|
||||||
| `exporter.serviceMonitor.labels` | Set labels for the ServiceMonitor, use this to define your scrape label for Prometheus Operator | object | `{}` |
|
|
||||||
| `exporter.serviceMonitor.metricRelabelings` | | list | `[]` |
|
|
||||||
| `exporter.serviceMonitor.namespace` | Set the namespace the ServiceMonitor should be deployed | string | `.Release.Namespace` |
|
|
||||||
| `exporter.serviceMonitor.relabelings` | | list | `[]` |
|
|
||||||
| `exporter.serviceMonitor.telemetryPath` | Set path to redis-exporter telemtery-path (default is /metrics) | string | `""` |
|
|
||||||
| `exporter.serviceMonitor.timeout` | Set timeout for scrape (default is 10s) | string | `""` |
|
|
||||||
| `exporter.tag` | Exporter image tag | string | `"v1.86.0"` |
|
|
||||||
| `prometheusRule.additionalLabels` | Additional labels to be set in metadata. | object | `{}` |
|
|
||||||
| `prometheusRule.enabled` | If true, creates a Prometheus Operator PrometheusRule. | bool | `false` |
|
|
||||||
| `prometheusRule.interval` | How often rules in the group are evaluated (falls back to `global.evaluation_interval` if not set). | string | `"10s"` |
|
|
||||||
| `prometheusRule.namespace` | Namespace which Prometheus is running in. | string | `nil` |
|
|
||||||
| `prometheusRule.rules` | Rules spec template (see https://github.com/prometheus-operator/prometheus-operator/blob/master/Documentation/api.md#rule). | list | `[]` |
|
|
||||||
|
|
||||||
Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example,
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ helm repo add dandydev https://dandydeveloper.github.io/charts
|
|
||||||
$ helm install \
|
|
||||||
--set image=redis \
|
|
||||||
--set tag=5.0.5-alpine \
|
|
||||||
dandydev/redis-ha
|
|
||||||
```
|
|
||||||
|
|
||||||
The above command sets the Redis server within `default` namespace.
|
|
||||||
|
|
||||||
Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example,
|
|
||||||
|
|
||||||
```bash
|
|
||||||
helm install -f values.yaml dandydev/redis-ha
|
|
||||||
```
|
|
||||||
|
|
||||||
> **Tip**: You can use the default [values.yaml](values.yaml)
|
|
||||||
|
|
||||||
## Custom Redis and Sentinel config options
|
|
||||||
|
|
||||||
This chart allows for most redis or sentinel config options to be passed as a key value pair through the `values.yaml` under `redis.config` and `sentinel.config`. See links below for all available options.
|
|
||||||
|
|
||||||
[Example redis.conf](http://download.redis.io/redis-stable/redis.conf)
|
|
||||||
[Example sentinel.conf](http://download.redis.io/redis-stable/sentinel.conf)
|
|
||||||
|
|
||||||
For example `repl-timeout 60` would be added to the `redis.config` section of the `values.yaml` as:
|
|
||||||
|
|
||||||
```yml
|
|
||||||
repl-timeout: "60"
|
|
||||||
```
|
|
||||||
|
|
||||||
Note:
|
|
||||||
|
|
||||||
1. Some config options should be renamed by redis version,e.g.:
|
|
||||||
|
|
||||||
```yml
|
|
||||||
# In redis 5.x,see https://raw.githubusercontent.com/antirez/redis/5.0/redis.conf
|
|
||||||
min-replicas-to-write: 1
|
|
||||||
min-replicas-max-lag: 5
|
|
||||||
|
|
||||||
# In redis 4.x and redis 3.x,see https://raw.githubusercontent.com/antirez/redis/4.0/redis.conf and https://raw.githubusercontent.com/antirez/redis/3.0/redis.conf
|
|
||||||
min-slaves-to-write 1
|
|
||||||
min-slaves-max-lag 5
|
|
||||||
```
|
|
||||||
|
|
||||||
Sentinel options supported must be in the the `sentinel <option> <master-group-name> <value>` format. For example, `sentinel down-after-milliseconds 30000` would be added to the `sentinel.config` section of the `values.yaml` as:
|
|
||||||
|
|
||||||
```yml
|
|
||||||
down-after-milliseconds: 30000
|
|
||||||
```
|
|
||||||
|
|
||||||
If more control is needed from either the redis or sentinel config then an entire config can be defined under `redis.customConfig` or `sentinel.customConfig`. Please note that these values will override any configuration options under their respective section. For example, if you define `sentinel.customConfig` then the `sentinel.config` is ignored.
|
|
||||||
|
|
||||||
## Host Kernel Settings
|
|
||||||
|
|
||||||
Redis may require some changes in the kernel of the host machine to work as expected, in particular increasing the `somaxconn` value and disabling transparent huge pages.
|
|
||||||
To do so, you can set up a privileged initContainer with the `sysctlImage` config values, for example:
|
|
||||||
|
|
||||||
```yml
|
|
||||||
sysctlImage:
|
|
||||||
enabled: true
|
|
||||||
mountHostSys: true
|
|
||||||
command:
|
|
||||||
- /bin/sh
|
|
||||||
- -xc
|
|
||||||
- |-
|
|
||||||
sysctl -w net.core.somaxconn=10000
|
|
||||||
echo never > /host-sys/kernel/mm/transparent_hugepage/enabled
|
|
||||||
```
|
|
||||||
|
|
||||||
## HAProxy startup
|
|
||||||
|
|
||||||
When HAProxy is enabled, it will attempt to connect to each announce-service of each redis replica instance in its init container before starting.
|
|
||||||
It will fail if announce-service IP is not available fast enough (10 seconds max by announce-service).
|
|
||||||
A such case could happen if the orchestator is pending the nomination of redis pods.
|
|
||||||
Risk is limited because announce-service is using `publishNotReadyAddresses: true`, although, in such case, HAProxy pod will be rescheduled afterward by the orchestrator.
|
|
||||||
|
|
||||||
PodDisruptionBudgets are not configured by default, you may need to set the `haproxy.podDisruptionBudget` parameter in values.yaml to enable it.
|
|
||||||
|
|
||||||
## Network policies
|
|
||||||
|
|
||||||
If `networkPolicy.enabled` is set to `true`, then a `NetworkPolicy` resource is created with default rules to allow inter-Redis and Sentinel connectivity.
|
|
||||||
This is a requirement for Redis Pods to come up successfully.
|
|
||||||
|
|
||||||
You will need to define `ingressRules` to permit your application connectivity to Redis.
|
|
||||||
The `selectors` block should be in the format of a [label selector](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors).
|
|
||||||
Templating is also supported in the selectors.
|
|
||||||
See such a configuration below.
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
networkPolicy: true
|
|
||||||
ingressRules:
|
|
||||||
- selectors:
|
|
||||||
- namespaceSelector:
|
|
||||||
matchLabels:
|
|
||||||
name: my-redis-client-namespace
|
|
||||||
podSelector:
|
|
||||||
matchLabels:
|
|
||||||
# template example
|
|
||||||
app: |-
|
|
||||||
{{- .App.Name }}
|
|
||||||
## ports block is optional (defaults to below), define the block to override the defaults
|
|
||||||
# ports:
|
|
||||||
# - port: 6379
|
|
||||||
# protocol: TCP
|
|
||||||
# - port: 26379
|
|
||||||
# protocol: TCP
|
|
||||||
```
|
|
||||||
|
|
||||||
Should your Pod require additional egress rules, define them in a `egressRules` key which is structured identically to an `ingressRules` key.
|
|
||||||
|
|
||||||
## Sentinel and redis server split brain detection
|
|
||||||
|
|
||||||
Under not entirely known yet circumstances redis sentinel and its corresponding redis server reach a condition that this chart authors call "split brain" (for short). The observed behaviour is the following: the sentinel switches to the new re-elected master, but does not switch its redis server. Majority of original discussion on the problem has happened at the #121.
|
|
||||||
|
|
||||||
The proposed solution is currently implemented as a sidecar container that runs a bash script with the following logic:
|
|
||||||
|
|
||||||
1. At intervals defined by splitBrainDetection.interval, the sidecar checks which node is recognized as master by Sentinel.
|
|
||||||
2. If the current pod is the master according to Sentinel, it verifies that the local Redis server is also running as master.
|
|
||||||
3. If the current pod is not the master, it ensures the local Redis server is replicating from the correct master node.
|
|
||||||
4. If any of these checks fail, the sidecar will retry the check at intervals defined by splitBrainDetection.retryInterval.
|
|
||||||
5. If the checks continue to fail after the retry attempts, the sidecar triggers a reinitialization: it regenerates the Redis configuration and instructs the Redis server to shut down. Kubernetes will then automatically restart the container.
|
|
||||||
|
|
||||||
# Change Log
|
|
||||||
|
|
||||||
## 4.14.9 - ** POTENTIAL BREAKING CHANGE. **
|
|
||||||
Introduced the ability to change the Haproxy Deployment container pod
|
|
||||||
- Container port in redis-haproxy-deployment.yam has been changed. Was **redis.port** To **haproxy.containerPort**. Default value is 6379.
|
|
||||||
- Port in redis-haproxy-service.yaml has been changed. Was **redis.port** To **haproxy.servicePort**. Default value is 6379.
|
|
||||||
|
|
||||||
## 4.21.0 - BREAKING CHANGES (Kubernetes Deprecation)
|
|
||||||
This version introduced the deprecation of the PSP and subsequently added fields to the securityContexts that were introduced in Kubernetes v1.19:
|
|
||||||
|
|
||||||
https://kubernetes.io/docs/tutorials/security/seccomp/
|
|
||||||
|
|
||||||
As a result, from this version onwards Kubernetes versions older than 1.19 will fail to install without the removal of `.Values.containerSecurityContext.seccompProfile` and `.Values.haproxy.containerSecurityContext.seccompProfile` (If HAProxy is enabled)
|
|
||||||
|
|
||||||
----------------------------------------------
|
|
||||||
Autogenerated from chart metadata using [helm-docs](https://github.com/norwoodj/helm-docs)
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
Redis can be accessed via {{ if ne (int .Values.redis.port) 0 }}port {{ .Values.redis.port }}{{ end }} {{ if .Values.redis.tlsPort }} tls-port {{ .Values.redis.tlsPort }}{{ end }} and Sentinel can be accessed via {{ if ne (int .Values.sentinel.port) 0 }}port {{ .Values.sentinel.port }}{{ end }} {{ if .Values.sentinel.tlsPort }} tls-port {{ .Values.sentinel.tlsPort }}{{ end }} on the following DNS name from within your cluster:
|
|
||||||
{{ template "redis-ha.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local
|
|
||||||
|
|
||||||
To connect to your Redis server:
|
|
||||||
|
|
||||||
{{- if .Values.auth }}
|
|
||||||
1. To retrieve the redis password:
|
|
||||||
echo $(kubectl get secret {{ template "redis-ha.fullname" . }} -o "jsonpath={.data['auth']}" | base64 --decode)
|
|
||||||
|
|
||||||
2. Connect to the Redis master pod that you can use as a client. By default the {{ template "redis-ha.fullname" . }}-server-0 pod is configured as the master:
|
|
||||||
|
|
||||||
kubectl exec -it {{ template "redis-ha.fullname" . }}-server-0 -n {{ .Release.Namespace }} -c redis -- sh
|
|
||||||
|
|
||||||
3. Connect using the Redis CLI (inside container):
|
|
||||||
|
|
||||||
redis-cli -a <REDIS-PASS-FROM-SECRET>
|
|
||||||
{{- else }}
|
|
||||||
1. Run a Redis pod that you can use as a client:
|
|
||||||
|
|
||||||
kubectl exec -it {{ template "redis-ha.fullname" . }}-server-0 -n {{ .Release.Namespace }} -c redis -- sh
|
|
||||||
|
|
||||||
2. Connect using the Redis CLI:
|
|
||||||
|
|
||||||
redis-cli -h {{ template "redis-ha.fullname" . }}.{{ .Release.Namespace }}.svc.cluster.local
|
|
||||||
{{- end }}
|
|
||||||
@@ -1,822 +0,0 @@
|
|||||||
{{/* vim: set filetype=mustache: */}}
|
|
||||||
|
|
||||||
{{- define "config-redis.conf" }}
|
|
||||||
{{- if .Values.redis.customConfig }}
|
|
||||||
{{ tpl .Values.redis.customConfig . | indent 4 }}
|
|
||||||
{{- else }}
|
|
||||||
dir "/data"
|
|
||||||
port {{ .Values.redis.port }}
|
|
||||||
{{- if .Values.sentinel.tlsPort }}
|
|
||||||
tls-port {{ .Values.redis.tlsPort }}
|
|
||||||
tls-cert-file /tls-certs/{{ .Values.tls.certFile }}
|
|
||||||
tls-key-file /tls-certs/{{ .Values.tls.keyFile }}
|
|
||||||
{{- if .Values.tls.dhParamsFile }}
|
|
||||||
tls-dh-params-file /tls-certs/{{ .Values.tls.dhParamsFile }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.tls.caCertFile }}
|
|
||||||
tls-ca-cert-file /tls-certs/{{ .Values.tls.caCertFile }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if eq (default "yes" .Values.redis.authClients) "no"}}
|
|
||||||
tls-auth-clients no
|
|
||||||
{{- end }}
|
|
||||||
tls-replication {{ if .Values.redis.tlsReplication }}yes{{ else }}no{{ end }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.redis.disableCommands }}
|
|
||||||
{{- range .Values.redis.disableCommands }}
|
|
||||||
rename-command {{ . }} ""
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
{{- range $key, $value := .Values.redis.config }}
|
|
||||||
{{- if kindIs "slice" $value }}
|
|
||||||
{{- range $value }}
|
|
||||||
{{ $key }} {{ . }}
|
|
||||||
{{- end }}
|
|
||||||
{{- else }}
|
|
||||||
{{ $key }} {{ $value }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.auth }}
|
|
||||||
requirepass replace-default-auth
|
|
||||||
masterauth replace-default-auth
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{- define "config-sentinel.conf" }}
|
|
||||||
{{- if .Values.sentinel.customConfig }}
|
|
||||||
{{ tpl .Values.sentinel.customConfig . | indent 4 }}
|
|
||||||
{{- else }}
|
|
||||||
dir "/data"
|
|
||||||
port {{ .Values.sentinel.port }}
|
|
||||||
{{- if .Values.sentinel.bind }}
|
|
||||||
bind {{ .Values.sentinel.bind }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.sentinel.tlsPort }}
|
|
||||||
tls-port {{ .Values.sentinel.tlsPort }}
|
|
||||||
tls-cert-file /tls-certs/{{ .Values.tls.certFile }}
|
|
||||||
tls-key-file /tls-certs/{{ .Values.tls.keyFile }}
|
|
||||||
{{- if .Values.tls.dhParamsFile }}
|
|
||||||
tls-dh-params-file /tls-certs/{{ .Values.tls.dhParamsFile }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.tls.caCertFile }}
|
|
||||||
tls-ca-cert-file /tls-certs/{{ .Values.tls.caCertFile }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if eq (default "yes" .Values.sentinel.authClients) "no"}}
|
|
||||||
tls-auth-clients no
|
|
||||||
{{- end }}
|
|
||||||
tls-replication {{ if .Values.sentinel.tlsReplication }}yes{{ else }}no{{ end }}
|
|
||||||
{{- end }}
|
|
||||||
{{- range $key, $value := .Values.sentinel.config }}
|
|
||||||
{{- if eq "maxclients" $key }}
|
|
||||||
{{ $key }} {{ $value }}
|
|
||||||
{{- else }}
|
|
||||||
sentinel {{ $key }} {{ template "redis-ha.masterGroupName" $ }} {{ $value }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.auth }}
|
|
||||||
sentinel auth-pass {{ template "redis-ha.masterGroupName" . }} replace-default-auth
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.sentinel.auth }}
|
|
||||||
requirepass replace-default-sentinel-auth
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.sentinel.resolveHostnames }}
|
|
||||||
sentinel resolve-hostnames yes
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.sentinel.announceHostnames }}
|
|
||||||
sentinel announce-hostnames yes
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{- define "lib.sh" }}
|
|
||||||
sentinel_get_master() {
|
|
||||||
set +e
|
|
||||||
if [ "$SENTINEL_PORT" -eq 0 ]; then
|
|
||||||
if [ "$RESOLVE_HOSTNAMES" = true ]; then
|
|
||||||
redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" {{ if .Values.sentinel.auth }} -a "${SENTINELAUTH}" --no-auth-warning{{ end }} --tls --cacert /tls-certs/{{ .Values.tls.caCertFile }} {{ if ne (default "yes" .Values.sentinel.authClients) "no"}} --cert /tls-certs/{{ .Values.tls.certFile }} --key /tls-certs/{{ .Values.tls.keyFile }}{{ end }} sentinel get-master-addr-by-name "${MASTER_GROUP}" |\
|
|
||||||
head -n 1 | grep -E '^\s*[a-zA-Z0-9.-]+\s*$'
|
|
||||||
else
|
|
||||||
redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" {{ if .Values.sentinel.auth }} -a "${SENTINELAUTH}" --no-auth-warning{{ end }} --tls --cacert /tls-certs/{{ .Values.tls.caCertFile }} {{ if ne (default "yes" .Values.sentinel.authClients) "no"}} --cert /tls-certs/{{ .Values.tls.certFile }} --key /tls-certs/{{ .Values.tls.keyFile }}{{ end }} sentinel get-master-addr-by-name "${MASTER_GROUP}" |\
|
|
||||||
head -n 1 | grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))'
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
if [ "$RESOLVE_HOSTNAMES" = true ]; then
|
|
||||||
redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" {{ if .Values.sentinel.auth }} -a "${SENTINELAUTH}" --no-auth-warning{{ end }} sentinel get-master-addr-by-name "${MASTER_GROUP}" |\
|
|
||||||
head -n 1 | grep -E '^\s*[a-zA-Z0-9.-]+\s*$'
|
|
||||||
else
|
|
||||||
redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" {{ if .Values.sentinel.auth }} -a "${SENTINELAUTH}" --no-auth-warning{{ end }} sentinel get-master-addr-by-name "${MASTER_GROUP}" |\
|
|
||||||
head -n 1 | grep -E '((^\s*((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?s*$))'
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
set -e
|
|
||||||
}
|
|
||||||
|
|
||||||
sentinel_get_master_retry() {
|
|
||||||
master=''
|
|
||||||
retry=${1}
|
|
||||||
sleep=3
|
|
||||||
for i in $(seq 1 "${retry}"); do
|
|
||||||
master=$(sentinel_get_master)
|
|
||||||
if [ -n "${master}" ]; then
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
sleep $((sleep + i))
|
|
||||||
done
|
|
||||||
echo "${master}"
|
|
||||||
}
|
|
||||||
|
|
||||||
identify_master() {
|
|
||||||
echo "Identifying redis master (get-master-addr-by-name).."
|
|
||||||
echo " using sentinel ({{ template "redis-ha.fullname" . }}), sentinel group name ({{ template "redis-ha.masterGroupName" . }})"
|
|
||||||
MASTER="$(sentinel_get_master_retry 3)"
|
|
||||||
if [ -n "${MASTER}" ]; then
|
|
||||||
echo " $(date) Found redis master (${MASTER})"
|
|
||||||
else
|
|
||||||
echo " $(date) Did not find redis master (${MASTER})"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
sentinel_update() {
|
|
||||||
echo "Updating sentinel config.."
|
|
||||||
echo " evaluating sentinel id (\${SENTINEL_ID_${INDEX}})"
|
|
||||||
eval MY_SENTINEL_ID="\$SENTINEL_ID_${INDEX}"
|
|
||||||
echo " sentinel id (${MY_SENTINEL_ID}), sentinel grp (${MASTER_GROUP}), quorum (${QUORUM})"
|
|
||||||
sed -i "1s/^/sentinel myid ${MY_SENTINEL_ID}\\n/" "${SENTINEL_CONF}"
|
|
||||||
if [ "$SENTINEL_TLS_REPLICATION_ENABLED" = true ]; then
|
|
||||||
echo " redis master (${1}:${REDIS_TLS_PORT})"
|
|
||||||
sed -i "2s/^/sentinel monitor ${MASTER_GROUP} ${1} ${REDIS_TLS_PORT} ${QUORUM} \\n/" "${SENTINEL_CONF}"
|
|
||||||
else
|
|
||||||
echo " redis master (${1}:${REDIS_PORT})"
|
|
||||||
sed -i "2s/^/sentinel monitor ${MASTER_GROUP} ${1} ${REDIS_PORT} ${QUORUM} \\n/" "${SENTINEL_CONF}"
|
|
||||||
fi
|
|
||||||
echo "sentinel announce-ip ${ANNOUNCE_IP}" >> ${SENTINEL_CONF}
|
|
||||||
if [ "$SENTINEL_PORT" -eq 0 ]; then
|
|
||||||
echo " announce (${ANNOUNCE_IP}:${SENTINEL_TLS_PORT})"
|
|
||||||
echo "sentinel announce-port ${SENTINEL_TLS_PORT}" >> ${SENTINEL_CONF}
|
|
||||||
else
|
|
||||||
echo " announce (${ANNOUNCE_IP}:${SENTINEL_PORT})"
|
|
||||||
echo "sentinel announce-port ${SENTINEL_PORT}" >> ${SENTINEL_CONF}
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
redis_update() {
|
|
||||||
echo "Updating redis config.."
|
|
||||||
if [ "$REDIS_TLS_REPLICATION_ENABLED" = true ]; then
|
|
||||||
echo " we are slave of redis master (${1}:${REDIS_TLS_PORT})"
|
|
||||||
echo "slaveof ${1} ${REDIS_TLS_PORT}" >> "${REDIS_CONF}"
|
|
||||||
echo "slave-announce-port ${REDIS_TLS_PORT}" >> ${REDIS_CONF}
|
|
||||||
else
|
|
||||||
echo " we are slave of redis master (${1}:${REDIS_PORT})"
|
|
||||||
echo "slaveof ${1} ${REDIS_PORT}" >> "${REDIS_CONF}"
|
|
||||||
echo "slave-announce-port ${REDIS_PORT}" >> ${REDIS_CONF}
|
|
||||||
fi
|
|
||||||
echo "slave-announce-ip ${ANNOUNCE_IP}" >> ${REDIS_CONF}
|
|
||||||
}
|
|
||||||
|
|
||||||
copy_config() {
|
|
||||||
echo "Copying default redis config.."
|
|
||||||
echo " to '${REDIS_CONF}'"
|
|
||||||
cp /readonly-config/redis.conf "${REDIS_CONF}"
|
|
||||||
echo "Copying default sentinel config.."
|
|
||||||
echo " to '${SENTINEL_CONF}'"
|
|
||||||
cp /readonly-config/sentinel.conf "${SENTINEL_CONF}"
|
|
||||||
}
|
|
||||||
|
|
||||||
setup_defaults() {
|
|
||||||
echo "Setting up defaults.."
|
|
||||||
echo " using statefulset index (${INDEX})"
|
|
||||||
if [ "${INDEX}" = "0" ]; then
|
|
||||||
echo "Setting this pod as master for redis and sentinel.."
|
|
||||||
echo " using announce (${ANNOUNCE_IP})"
|
|
||||||
redis_update "${ANNOUNCE_IP}"
|
|
||||||
sentinel_update "${ANNOUNCE_IP}"
|
|
||||||
echo " make sure ${ANNOUNCE_IP} is not a slave (slaveof no one)"
|
|
||||||
sed -i "s/^.*slaveof.*//" "${REDIS_CONF}"
|
|
||||||
else
|
|
||||||
if [ "$RESOLVE_HOSTNAMES" = true ]; then
|
|
||||||
echo "Getting redis master hostname.."
|
|
||||||
echo " blindly assuming (${SERVICE}-announce-0.${NAMESPACE}.svc) is master"
|
|
||||||
DEFAULT_MASTER="${SERVICE}-announce-0.${NAMESPACE}.svc"
|
|
||||||
echo " identified redis (may be redis master) hostname (${DEFAULT_MASTER})"
|
|
||||||
else
|
|
||||||
echo "Getting redis master ip.."
|
|
||||||
echo " blindly assuming (${SERVICE}-announce-0) or (${SERVICE}-server-0) are master"
|
|
||||||
DEFAULT_MASTER="$(getent_hosts 0 | awk '{ print $1 }')"
|
|
||||||
if [ -z "${DEFAULT_MASTER}" ]; then
|
|
||||||
echo "Error: Unable to resolve redis master (getent hosts)."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo " identified redis (may be redis master) ip (${DEFAULT_MASTER})"
|
|
||||||
fi
|
|
||||||
echo "Setting default slave config for redis and sentinel.."
|
|
||||||
echo " using master address (${DEFAULT_MASTER})"
|
|
||||||
redis_update "${DEFAULT_MASTER}"
|
|
||||||
sentinel_update "${DEFAULT_MASTER}"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
redis_ping() {
|
|
||||||
set +e
|
|
||||||
if [ "$REDIS_PORT" -eq 0 ]; then
|
|
||||||
redis-cli -h "${MASTER}"{{ if .Values.auth }} -a "${AUTH}" --no-auth-warning{{ end }} -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/{{ .Values.tls.caCertFile }} {{ if ne (default "yes" .Values.sentinel.authClients) "no"}} --cert /tls-certs/{{ .Values.tls.certFile }} --key /tls-certs/{{ .Values.tls.keyFile }}{{ end }} ping
|
|
||||||
else
|
|
||||||
redis-cli -h "${MASTER}"{{ if .Values.auth }} -a "${AUTH}" --no-auth-warning{{ end }} -p "${REDIS_PORT}" ping
|
|
||||||
fi
|
|
||||||
set -e
|
|
||||||
}
|
|
||||||
|
|
||||||
redis_ping_retry() {
|
|
||||||
ping=''
|
|
||||||
retry=${1}
|
|
||||||
sleep=3
|
|
||||||
for i in $(seq 1 "${retry}"); do
|
|
||||||
if [ "$(redis_ping)" = "PONG" ]; then
|
|
||||||
ping='PONG'
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
sleep $((sleep + i))
|
|
||||||
MASTER=$(sentinel_get_master)
|
|
||||||
done
|
|
||||||
echo "${ping}"
|
|
||||||
}
|
|
||||||
|
|
||||||
find_master() {
|
|
||||||
echo "Verifying redis master.."
|
|
||||||
if [ "$REDIS_PORT" -eq 0 ]; then
|
|
||||||
echo " ping (${MASTER}:${REDIS_TLS_PORT})"
|
|
||||||
else
|
|
||||||
echo " ping (${MASTER}:${REDIS_PORT})"
|
|
||||||
fi
|
|
||||||
if [ "$(redis_ping_retry 3)" != "PONG" ]; then
|
|
||||||
echo " $(date) Can't ping redis master (${MASTER})"
|
|
||||||
echo "Attempting to force failover (sentinel failover).."
|
|
||||||
|
|
||||||
if [ "$SENTINEL_PORT" -eq 0 ]; then
|
|
||||||
echo " on sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})"
|
|
||||||
if redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" {{ if .Values.sentinel.auth }} -a "${SENTINELAUTH}" --no-auth-warning{{ end }} --tls --cacert /tls-certs/{{ .Values.tls.caCertFile }} {{ if ne (default "yes" .Values.sentinel.authClients) "no"}} --cert /tls-certs/{{ .Values.tls.certFile }} --key /tls-certs/{{ .Values.tls.keyFile }}{{ end }} sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then
|
|
||||||
echo " $(date) Failover returned with 'NOGOODSLAVE'"
|
|
||||||
echo "Setting defaults for this pod.."
|
|
||||||
setup_defaults
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo " on sentinel (${SERVICE}:${SENTINEL_PORT}), sentinel grp (${MASTER_GROUP})"
|
|
||||||
if redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" {{ if .Values.sentinel.auth }} -a "${SENTINELAUTH}" --no-auth-warning{{ end }} sentinel failover "${MASTER_GROUP}" | grep -q 'NOGOODSLAVE' ; then
|
|
||||||
echo " $(date) Failover returned with 'NOGOODSLAVE'"
|
|
||||||
echo "Setting defaults for this pod.."
|
|
||||||
setup_defaults
|
|
||||||
return 0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Hold on for 10sec"
|
|
||||||
sleep 10
|
|
||||||
echo "We should get redis master's ip now. Asking (get-master-addr-by-name).."
|
|
||||||
if [ "$SENTINEL_PORT" -eq 0 ]; then
|
|
||||||
echo " sentinel (${SERVICE}:${SENTINEL_TLS_PORT}), sentinel grp (${MASTER_GROUP})"
|
|
||||||
else
|
|
||||||
echo " sentinel (${SERVICE}:${SENTINEL_PORT}), sentinel grp (${MASTER_GROUP})"
|
|
||||||
fi
|
|
||||||
MASTER="$(sentinel_get_master)"
|
|
||||||
if [ "${MASTER}" ]; then
|
|
||||||
echo " $(date) Found redis master (${MASTER})"
|
|
||||||
echo "Updating redis and sentinel config.."
|
|
||||||
sentinel_update "${MASTER}"
|
|
||||||
redis_update "${MASTER}"
|
|
||||||
else
|
|
||||||
echo "$(date) Error: Could not failover, exiting..."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo " $(date) Found reachable redis master (${MASTER})"
|
|
||||||
echo "Updating redis and sentinel config.."
|
|
||||||
sentinel_update "${MASTER}"
|
|
||||||
redis_update "${MASTER}"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
redis_ro_update() {
|
|
||||||
echo "Updating read-only redis config.."
|
|
||||||
echo " redis.conf set 'replica-priority 0'"
|
|
||||||
echo "replica-priority 0" >> ${REDIS_CONF}
|
|
||||||
}
|
|
||||||
|
|
||||||
getent_hosts() {
|
|
||||||
index=${1:-${INDEX}}
|
|
||||||
service="${SERVICE}-announce-${index}"
|
|
||||||
if [ "$RESOLVE_HOSTNAMES" = true ]; then
|
|
||||||
echo "${service}.${NAMESPACE}.svc"
|
|
||||||
else
|
|
||||||
host=$(getent hosts "${service}")
|
|
||||||
echo "${host}"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
identify_announce_ip() {
|
|
||||||
if [ "$ANNOUNCE_HOSTNAMES" = true ]; then
|
|
||||||
echo "Identify announce hostname for this pod.."
|
|
||||||
echo " using (${SERVICE}-announce-${INDEX}.${NAMESPACE}.svc)"
|
|
||||||
ANNOUNCE_IP="${SERVICE}-announce-${INDEX}.${NAMESPACE}.svc"
|
|
||||||
else
|
|
||||||
echo "Identify announce ip for this pod.."
|
|
||||||
echo " using (${SERVICE}-announce-${INDEX}) or (${SERVICE}-server-${INDEX})"
|
|
||||||
ANNOUNCE_IP=$(getent_hosts | awk '{ print $1 }')
|
|
||||||
fi
|
|
||||||
echo " identified announce (${ANNOUNCE_IP})"
|
|
||||||
}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{- define "vars.sh" }}
|
|
||||||
HOSTNAME="$(cat /proc/sys/kernel/hostname)"
|
|
||||||
{{- if .Values.ro_replicas }}
|
|
||||||
RO_REPLICAS="{{ .Values.ro_replicas }}"
|
|
||||||
{{- end }}
|
|
||||||
INDEX="${HOSTNAME##*-}"
|
|
||||||
SENTINEL_PORT={{ .Values.sentinel.port }}
|
|
||||||
ANNOUNCE_IP=''
|
|
||||||
MASTER=''
|
|
||||||
MASTER_GROUP="{{ template "redis-ha.masterGroupName" . }}"
|
|
||||||
QUORUM="{{ .Values.sentinel.quorum }}"
|
|
||||||
REDIS_CONF=/data/conf/redis.conf
|
|
||||||
REDIS_PORT={{ .Values.redis.port }}
|
|
||||||
REDIS_TLS_PORT={{ .Values.redis.tlsPort }}
|
|
||||||
SENTINEL_CONF=/data/conf/sentinel.conf
|
|
||||||
SENTINEL_TLS_PORT={{ .Values.sentinel.tlsPort }}
|
|
||||||
SERVICE={{ template "redis-ha.fullname" . }}
|
|
||||||
NAMESPACE="{{ .Release.Namespace }}"
|
|
||||||
SENTINEL_TLS_REPLICATION_ENABLED={{ default false .Values.sentinel.tlsReplication }}
|
|
||||||
REDIS_TLS_REPLICATION_ENABLED={{ default false .Values.redis.tlsReplication }}
|
|
||||||
RESOLVE_HOSTNAMES={{ default false .Values.sentinel.resolveHostnames }}
|
|
||||||
ANNOUNCE_HOSTNAMES={{ default false .Values.sentinel.announceHostnames }}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{- define "config-init.sh" }}
|
|
||||||
echo "$(date) Start..."
|
|
||||||
{{- include "vars.sh" . }}
|
|
||||||
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
{{- include "lib.sh" . }}
|
|
||||||
|
|
||||||
mkdir -p /data/conf/
|
|
||||||
|
|
||||||
echo "Initializing config.."
|
|
||||||
copy_config
|
|
||||||
|
|
||||||
# where is redis master
|
|
||||||
identify_master
|
|
||||||
|
|
||||||
identify_announce_ip
|
|
||||||
|
|
||||||
if [ -z "${ANNOUNCE_IP}" ]; then
|
|
||||||
echo "Error: Could not resolve the announce address for this pod"
|
|
||||||
exit 1
|
|
||||||
elif [ "${MASTER}" ]; then
|
|
||||||
find_master
|
|
||||||
else
|
|
||||||
setup_defaults
|
|
||||||
fi
|
|
||||||
|
|
||||||
{{- if .Values.ro_replicas }}
|
|
||||||
# works only if index is less than 10
|
|
||||||
echo "Verifying redis read-only replica.."
|
|
||||||
echo " we have RO_REPLICAS='${RO_REPLICAS}' with INDEX='${INDEX}'"
|
|
||||||
if echo "${RO_REPLICAS}" | grep -q "${INDEX}" ; then
|
|
||||||
redis_ro_update
|
|
||||||
fi
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
if [ "${AUTH:-}" ]; then
|
|
||||||
echo "Setting redis auth values.."
|
|
||||||
ESCAPED_AUTH=$(echo "${AUTH}" | sed -e 's/[\/&]/\\&/g');
|
|
||||||
sed -i "s/replace-default-auth/${ESCAPED_AUTH}/" "${REDIS_CONF}" "${SENTINEL_CONF}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "${SENTINELAUTH:-}" ]; then
|
|
||||||
echo "Setting sentinel auth values"
|
|
||||||
ESCAPED_AUTH_SENTINEL=$(echo "$SENTINELAUTH" | sed -e 's/[\/&]/\\&/g');
|
|
||||||
sed -i "s/replace-default-sentinel-auth/${ESCAPED_AUTH_SENTINEL}/" "$SENTINEL_CONF"
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "$(date) Ready..."
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{- define "trigger-failover-if-master.sh" }}
|
|
||||||
{{- if or (eq (int .Values.redis.port) 0) (eq (int .Values.sentinel.port) 0) }}
|
|
||||||
TLS_CLIENT_OPTION="--tls --cacert /tls-certs/{{ .Values.tls.caCertFile }}{{ if ne (default "yes" .Values.sentinel.authClients) "no"}} --cert /tls-certs/{{ .Values.tls.certFile }} --key /tls-certs/{{ .Values.tls.keyFile }}{{end}}"
|
|
||||||
{{- end }}
|
|
||||||
get_redis_role() {
|
|
||||||
is_master=$(
|
|
||||||
redis-cli \
|
|
||||||
{{- if .Values.auth }}
|
|
||||||
-a "${AUTH}" --no-auth-warning \
|
|
||||||
{{- end }}
|
|
||||||
-h localhost \
|
|
||||||
{{- if (int .Values.redis.port) }}
|
|
||||||
-p {{ .Values.redis.port }} \
|
|
||||||
{{- else }}
|
|
||||||
-p {{ .Values.redis.tlsPort }} ${TLS_CLIENT_OPTION} \
|
|
||||||
{{- end}}
|
|
||||||
info | grep -c 'role:master' || true
|
|
||||||
)
|
|
||||||
}
|
|
||||||
get_redis_role
|
|
||||||
if [[ "$is_master" -eq 1 ]]; then
|
|
||||||
echo "This node is currently master, we trigger a failover."
|
|
||||||
{{- $masterGroupName := include "redis-ha.masterGroupName" . }}
|
|
||||||
response=$(
|
|
||||||
redis-cli \
|
|
||||||
{{- if .Values.sentinel.auth }}
|
|
||||||
-a "${SENTINELAUTH}" --no-auth-warning \
|
|
||||||
{{- end }}
|
|
||||||
-h localhost \
|
|
||||||
{{- if (int .Values.sentinel.port) }}
|
|
||||||
-p {{ .Values.sentinel.port }} \
|
|
||||||
{{- else }}
|
|
||||||
-p {{ .Values.sentinel.tlsPort }} ${TLS_CLIENT_OPTION} \
|
|
||||||
{{- end}}
|
|
||||||
SENTINEL failover {{ $masterGroupName }}
|
|
||||||
)
|
|
||||||
if [[ "$response" != "OK" ]] ; then
|
|
||||||
echo "$response"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
timeout=30
|
|
||||||
while [[ "$is_master" -eq 1 && $timeout -gt 0 ]]; do
|
|
||||||
sleep 1
|
|
||||||
get_redis_role
|
|
||||||
timeout=$((timeout - 1))
|
|
||||||
done
|
|
||||||
echo "Failover successful"
|
|
||||||
fi
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{- define "fix-split-brain.sh" }}
|
|
||||||
{{- include "vars.sh" . }}
|
|
||||||
|
|
||||||
ROLE=''
|
|
||||||
REDIS_MASTER=''
|
|
||||||
|
|
||||||
set -eu
|
|
||||||
|
|
||||||
{{- include "lib.sh" . }}
|
|
||||||
|
|
||||||
redis_role() {
|
|
||||||
set +e
|
|
||||||
if [ "$REDIS_PORT" -eq 0 ]; then
|
|
||||||
ROLE=$(redis-cli {{ if .Values.auth }} -a "${AUTH}" --no-auth-warning{{ end }} -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/{{ .Values.tls.caCertFile }} {{ if ne (default "yes" .Values.sentinel.authClients) "no"}} --cert /tls-certs/{{ .Values.tls.certFile }} --key /tls-certs/{{ .Values.tls.keyFile }}{{ end }} info | grep role | sed 's/role://' | sed 's/\r//')
|
|
||||||
else
|
|
||||||
ROLE=$(redis-cli {{ if .Values.auth }} -a "${AUTH}" --no-auth-warning{{ end }} -p "${REDIS_PORT}" info | grep role | sed 's/role://' | sed 's/\r//')
|
|
||||||
fi
|
|
||||||
set -e
|
|
||||||
}
|
|
||||||
|
|
||||||
identify_redis_master() {
|
|
||||||
set +e
|
|
||||||
if [ "$REDIS_PORT" -eq 0 ]; then
|
|
||||||
REDIS_MASTER=$(redis-cli {{ if .Values.auth }} -a "${AUTH}" --no-auth-warning{{ end }} -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/{{ .Values.tls.caCertFile }} {{ if ne (default "yes" .Values.sentinel.authClients) "no"}} --cert /tls-certs/{{ .Values.tls.certFile }} --key /tls-certs/{{ .Values.tls.keyFile }}{{ end }} info | grep master_host | sed 's/master_host://' | sed 's/\r//')
|
|
||||||
else
|
|
||||||
REDIS_MASTER=$(redis-cli {{ if .Values.auth }} -a "${AUTH}" --no-auth-warning{{ end }} -p "${REDIS_PORT}" info | grep master_host | sed 's/master_host://' | sed 's/\r//')
|
|
||||||
fi
|
|
||||||
set -e
|
|
||||||
}
|
|
||||||
|
|
||||||
reinit() {
|
|
||||||
set +e
|
|
||||||
sh /readonly-config/init.sh
|
|
||||||
|
|
||||||
if [ "$REDIS_PORT" -eq 0 ]; then
|
|
||||||
echo "shutdown" | redis-cli {{ if .Values.auth }} -a "${AUTH}" --no-auth-warning{{ end }} -p "${REDIS_TLS_PORT}" --tls --cacert /tls-certs/{{ .Values.tls.caCertFile }} {{ if ne (default "yes" .Values.sentinel.authClients) "no"}} --cert /tls-certs/{{ .Values.tls.certFile }} --key /tls-certs/{{ .Values.tls.keyFile }}{{ end }}
|
|
||||||
else
|
|
||||||
echo "shutdown" | redis-cli {{ if .Values.auth }} -a "${AUTH}" --no-auth-warning{{ end }} -p "${REDIS_PORT}"
|
|
||||||
fi
|
|
||||||
set -e
|
|
||||||
}
|
|
||||||
|
|
||||||
identify_announce_ip
|
|
||||||
|
|
||||||
while [ -z "${ANNOUNCE_IP}" ]; do
|
|
||||||
echo "Error: Could not resolve the announce address for this pod."
|
|
||||||
sleep 30
|
|
||||||
identify_announce_ip
|
|
||||||
done
|
|
||||||
|
|
||||||
QUORUM_FAIL_COUNT=0
|
|
||||||
MAX_QUORUM_FAILURES=${MAX_QUORUM_FAILURES:-5}
|
|
||||||
|
|
||||||
trap "exit 0" TERM
|
|
||||||
while true; do
|
|
||||||
sleep {{ .Values.splitBrainDetection.interval }}
|
|
||||||
|
|
||||||
# where is redis master
|
|
||||||
identify_master
|
|
||||||
|
|
||||||
if [ "$MASTER" = "$ANNOUNCE_IP" ]; then
|
|
||||||
QUORUM_FAIL_COUNT=0
|
|
||||||
redis_role
|
|
||||||
if [ "$ROLE" != "master" ]; then
|
|
||||||
echo "waiting for redis to become master"
|
|
||||||
sleep {{ .Values.splitBrainDetection.retryInterval }}
|
|
||||||
identify_master
|
|
||||||
redis_role
|
|
||||||
echo "Redis role is $ROLE, expected role is master. No need to reinitialize."
|
|
||||||
if [ "$ROLE" != "master" ]; then
|
|
||||||
echo "Redis role is $ROLE, expected role is master, reinitializing"
|
|
||||||
reinit
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
elif [ "${MASTER}" ]; then
|
|
||||||
QUORUM_FAIL_COUNT=0
|
|
||||||
identify_redis_master
|
|
||||||
if [ "$REDIS_MASTER" != "$MASTER" ]; then
|
|
||||||
echo "Redis master and local master are not the same. waiting."
|
|
||||||
sleep {{ .Values.splitBrainDetection.retryInterval }}
|
|
||||||
identify_master
|
|
||||||
if [ "$MASTER" = "$ANNOUNCE_IP" ]; then
|
|
||||||
echo "This pod became master during wait, skipping reinit"
|
|
||||||
else
|
|
||||||
identify_redis_master
|
|
||||||
echo "Redis master is ${MASTER}, expected master is ${REDIS_MASTER}. No need to reinitialize."
|
|
||||||
if [ "${REDIS_MASTER}" != "${MASTER}" ]; then
|
|
||||||
echo "Redis master is ${MASTER}, expected master is ${REDIS_MASTER}, reinitializing"
|
|
||||||
reinit
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
QUORUM_FAIL_COUNT=$((QUORUM_FAIL_COUNT + 1))
|
|
||||||
echo "WARNING: Sentinel returned no master (quorum may be broken). Failure count: $QUORUM_FAIL_COUNT/$MAX_QUORUM_FAILURES"
|
|
||||||
if [ "$QUORUM_FAIL_COUNT" -ge "$MAX_QUORUM_FAILURES" ]; then
|
|
||||||
echo "ERROR: Quorum broken for $MAX_QUORUM_FAILURES consecutive checks. Attempting sentinel reset..."
|
|
||||||
if [ "$SENTINEL_PORT" -eq 0 ]; then
|
|
||||||
redis-cli -h "${SERVICE}" -p "${SENTINEL_TLS_PORT}" {{ if .Values.sentinel.auth }} -a "${SENTINELAUTH}" --no-auth-warning{{ end }} --tls --cacert /tls-certs/{{ .Values.tls.caCertFile }} {{ if ne (default "yes" .Values.sentinel.authClients) "no"}} --cert /tls-certs/{{ .Values.tls.certFile }} --key /tls-certs/{{ .Values.tls.keyFile }}{{ end }} sentinel reset "${MASTER_GROUP}" || true
|
|
||||||
else
|
|
||||||
redis-cli -h "${SERVICE}" -p "${SENTINEL_PORT}" {{ if .Values.sentinel.auth }} -a "${SENTINELAUTH}" --no-auth-warning{{ end }} sentinel reset "${MASTER_GROUP}" || true
|
|
||||||
fi
|
|
||||||
QUORUM_FAIL_COUNT=0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{- define "config-haproxy.cfg" }}
|
|
||||||
{{- if .Values.haproxy.customConfig }}
|
|
||||||
{{ tpl .Values.haproxy.customConfig . | indent 4 }}
|
|
||||||
{{- else }}
|
|
||||||
defaults REDIS
|
|
||||||
mode tcp
|
|
||||||
timeout connect {{ .Values.haproxy.timeout.connect }}
|
|
||||||
timeout server {{ .Values.haproxy.timeout.server }}
|
|
||||||
timeout client {{ .Values.haproxy.timeout.client }}
|
|
||||||
timeout check {{ .Values.haproxy.timeout.check }}
|
|
||||||
timeout tunnel {{ .Values.haproxy.timeout.tunnel }}
|
|
||||||
|
|
||||||
listen health_check_http_url
|
|
||||||
bind {{ if .Values.haproxy.IPv6.enabled }}[::]{{ end }}:8888 {{ if .Values.haproxy.IPv6.enabled }}v4v6{{ end }}
|
|
||||||
mode http
|
|
||||||
monitor-uri /healthz
|
|
||||||
option dontlognull
|
|
||||||
|
|
||||||
{{- $root := . }}
|
|
||||||
{{- $fullName := include "redis-ha.fullname" . }}
|
|
||||||
{{- $replicas := int (toString .Values.replicas) }}
|
|
||||||
{{- $masterGroupName := include "redis-ha.masterGroupName" . }}
|
|
||||||
{{- range $i := until $replicas }}
|
|
||||||
# Check Sentinel and whether they are nominated master
|
|
||||||
backend check_if_redis_is_master_{{ $i }}
|
|
||||||
mode tcp
|
|
||||||
option tcp-check
|
|
||||||
tcp-check connect
|
|
||||||
{{- if $root.Values.sentinel.auth }}
|
|
||||||
tcp-check send "AUTH ${SENTINELAUTH}"\r\n
|
|
||||||
tcp-check expect string +OK
|
|
||||||
{{- end }}
|
|
||||||
tcp-check send PING\r\n
|
|
||||||
tcp-check expect string +PONG
|
|
||||||
tcp-check send SENTINEL\ get-master-addr-by-name\ {{ $masterGroupName }}\r\n
|
|
||||||
tcp-check expect string REPLACE_ANNOUNCE{{ $i }}
|
|
||||||
tcp-check send QUIT\r\n
|
|
||||||
{{- range $i := until $replicas }}
|
|
||||||
{{- if $.Values.sentinel.resolveHostnames }}
|
|
||||||
server R{{ $i }} {{ $fullName }}-announce-{{ $i }}.{{ $.Release.Namespace }}.svc:26379 check inter {{ $root.Values.haproxy.checkInterval }}
|
|
||||||
{{- else }}
|
|
||||||
server R{{ $i }} {{ $fullName }}-announce-{{ $i }}:26379 check inter {{ $root.Values.haproxy.checkInterval }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
# decide redis backend to use
|
|
||||||
#master
|
|
||||||
frontend ft_redis_master
|
|
||||||
{{- if .Values.haproxy.tls.enabled }}
|
|
||||||
bind {{ if .Values.haproxy.IPv6.enabled }}[::]{{ end }}:{{ $root.Values.haproxy.containerPort }} ssl crt {{ .Values.haproxy.tls.certMountPath }}{{ .Values.haproxy.tls.keyName }} {{ if .Values.haproxy.IPv6.enabled }}v4v6{{ end }}
|
|
||||||
{{ else }}
|
|
||||||
bind {{ if .Values.haproxy.IPv6.enabled }}[::]{{ end }}:{{ if ne (int $root.Values.redis.port) 0 }}{{ $root.Values.redis.port }}{{ else }}{{ $root.Values.redis.tlsPort }}{{ end }} {{ if .Values.haproxy.IPv6.enabled }}v4v6{{ end }}
|
|
||||||
{{- end }}
|
|
||||||
use_backend bk_redis_master
|
|
||||||
{{- if .Values.haproxy.readOnly.enabled }}
|
|
||||||
#slave
|
|
||||||
frontend ft_redis_slave
|
|
||||||
bind {{ if .Values.haproxy.IPv6.enabled }}[::]{{ end }}:{{ .Values.haproxy.readOnly.port }} {{ if .Values.haproxy.IPv6.enabled }}v4v6{{ end }}
|
|
||||||
use_backend bk_redis_slave
|
|
||||||
{{- end }}
|
|
||||||
# Check all redis servers to see if they think they are master
|
|
||||||
backend bk_redis_master
|
|
||||||
{{- if .Values.haproxy.stickyBalancing }}
|
|
||||||
balance source
|
|
||||||
hash-type consistent
|
|
||||||
{{- end }}
|
|
||||||
mode tcp
|
|
||||||
option tcp-check
|
|
||||||
tcp-check connect
|
|
||||||
{{- if .Values.auth }}
|
|
||||||
tcp-check send "AUTH ${AUTH}"\r\n
|
|
||||||
tcp-check expect string +OK
|
|
||||||
{{- end }}
|
|
||||||
tcp-check send PING\r\n
|
|
||||||
tcp-check expect string +PONG
|
|
||||||
tcp-check send info\ replication\r\n
|
|
||||||
tcp-check expect string role:master
|
|
||||||
tcp-check send QUIT\r\n
|
|
||||||
tcp-check expect string +OK
|
|
||||||
{{- range $i := until $replicas }}
|
|
||||||
use-server R{{ $i }} if { srv_is_up(R{{ $i }}) } { nbsrv(check_if_redis_is_master_{{ $i }}) ge 2 }
|
|
||||||
{{- if $.Values.sentinel.resolveHostnames }}
|
|
||||||
server R{{ $i }} {{ $fullName }}-announce-{{ $i }}.{{ $.Release.Namespace }}.svc:{{ $root.Values.redis.port }} check inter {{ $root.Values.haproxy.checkInterval }} fall {{ $root.Values.haproxy.checkFall }} rise 1
|
|
||||||
{{- else }}
|
|
||||||
server R{{ $i }} {{ $fullName }}-announce-{{ $i }}:{{ $root.Values.redis.port }} check inter {{ $root.Values.haproxy.checkInterval }} fall {{ $root.Values.haproxy.checkFall }} rise 1
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.haproxy.readOnly.enabled }}
|
|
||||||
backend bk_redis_slave
|
|
||||||
{{- if .Values.haproxy.stickyBalancing }}
|
|
||||||
balance source
|
|
||||||
hash-type consistent
|
|
||||||
{{- end }}
|
|
||||||
mode tcp
|
|
||||||
option tcp-check
|
|
||||||
tcp-check connect
|
|
||||||
{{- if .Values.auth }}
|
|
||||||
tcp-check send "AUTH ${AUTH}"\r\n
|
|
||||||
tcp-check expect string +OK
|
|
||||||
{{- end }}
|
|
||||||
tcp-check send PING\r\n
|
|
||||||
tcp-check expect string +PONG
|
|
||||||
tcp-check send info\ replication\r\n
|
|
||||||
tcp-check expect string role:slave
|
|
||||||
tcp-check send QUIT\r\n
|
|
||||||
tcp-check expect string +OK
|
|
||||||
{{- range $i := until $replicas }}
|
|
||||||
{{- if $.Values.sentinel.resolveHostnames }}
|
|
||||||
server R{{ $i }} {{ $fullName }}-announce-{{ $i }}.{{ $.Release.Namespace }}.svc:{{ $root.Values.redis.port }} check inter {{ $root.Values.haproxy.checkInterval }} fall {{ $root.Values.haproxy.checkFall }} rise 1
|
|
||||||
{{- else }}
|
|
||||||
server R{{ $i }} {{ $fullName }}-announce-{{ $i }}:{{ $root.Values.redis.port }} check inter {{ $root.Values.haproxy.checkInterval }} fall {{ $root.Values.haproxy.checkFall }} rise 1
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.haproxy.metrics.enabled }}
|
|
||||||
frontend stats
|
|
||||||
mode http
|
|
||||||
bind {{ if .Values.haproxy.IPv6.enabled }}[::]{{ end }}:{{ .Values.haproxy.metrics.port }} {{ if .Values.haproxy.IPv6.enabled }}v4v6{{ end }}
|
|
||||||
http-request use-service prometheus-exporter if { path {{ .Values.haproxy.metrics.scrapePath }} }
|
|
||||||
stats enable
|
|
||||||
stats uri /stats
|
|
||||||
stats refresh 10s
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.haproxy.extraConfig }}
|
|
||||||
# Additional configuration
|
|
||||||
{{ .Values.haproxy.extraConfig | indent 4 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
|
|
||||||
{{- define "config-haproxy_init.sh" }}
|
|
||||||
HAPROXY_CONF=/data/haproxy.cfg
|
|
||||||
cp /readonly/haproxy.cfg "$HAPROXY_CONF"
|
|
||||||
{{- $fullName := include "redis-ha.fullname" . }}
|
|
||||||
{{- $replicas := int (toString .Values.replicas) }}
|
|
||||||
{{- $resolveHostnames := .Values.sentinel.resolveHostnames }}
|
|
||||||
{{- $namespace := .Release.Namespace }}
|
|
||||||
{{- range $i := until $replicas }}
|
|
||||||
{{- if $resolveHostnames }}
|
|
||||||
ANNOUNCE_IP{{ $i }}="{{ $fullName }}-announce-{{ $i }}.{{ $namespace }}.svc"
|
|
||||||
echo "Using hostname for {{ $fullName }}-announce-{{ $i }}.{{ $namespace }}.svc: $ANNOUNCE_IP{{ $i }}"
|
|
||||||
{{- else }}
|
|
||||||
for loop in $(seq 1 10); do
|
|
||||||
getent hosts {{ $fullName }}-announce-{{ $i }} && break
|
|
||||||
echo "Waiting for service {{ $fullName }}-announce-{{ $i }} to be ready ($loop) ..." && sleep 1
|
|
||||||
done
|
|
||||||
ANNOUNCE_IP{{ $i }}=$(getent hosts "{{ $fullName }}-announce-{{ $i }}" | awk '{ print $1 }')
|
|
||||||
if [ -z "$ANNOUNCE_IP{{ $i }}" ]; then
|
|
||||||
echo "Could not resolve the announce address for {{ $fullName }}-announce-{{ $i }}"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
{{- end }}
|
|
||||||
sed -i "s/REPLACE_ANNOUNCE{{ $i }}/$ANNOUNCE_IP{{ $i }}/" "$HAPROXY_CONF"
|
|
||||||
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{- define "redis_liveness.sh" }}
|
|
||||||
{{- if not (ne (int .Values.sentinel.port) 0) }}
|
|
||||||
TLS_CLIENT_OPTION="--tls --cacert /tls-certs/{{ .Values.tls.caCertFile }}{{ if ne (default "yes" .Values.sentinel.authClients) "no"}} --cert /tls-certs/{{ .Values.tls.certFile }} --key /tls-certs/{{ .Values.tls.keyFile }}{{end}}"
|
|
||||||
{{- end }}
|
|
||||||
response=$(
|
|
||||||
redis-cli \
|
|
||||||
{{- if .Values.auth }}
|
|
||||||
-a "${AUTH}" --no-auth-warning \
|
|
||||||
{{- end }}
|
|
||||||
-h localhost \
|
|
||||||
{{- if ne (int .Values.redis.port) 0 }}
|
|
||||||
-p {{ .Values.redis.port }} \
|
|
||||||
{{- else }}
|
|
||||||
-p {{ .Values.redis.tlsPort }} ${TLS_CLIENT_OPTION} \
|
|
||||||
{{- end}}
|
|
||||||
ping
|
|
||||||
)
|
|
||||||
echo "response=$response"
|
|
||||||
case $response in
|
|
||||||
PONG|LOADING*) ;;
|
|
||||||
*) exit 1 ;;
|
|
||||||
esac
|
|
||||||
exit 0
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{- define "redis_readiness.sh" }}
|
|
||||||
{{- if not (ne (int .Values.sentinel.port) 0) }}
|
|
||||||
TLS_CLIENT_OPTION="--tls --cacert /tls-certs/{{ .Values.tls.caCertFile }}{{ if ne (default "yes" .Values.sentinel.authClients) "no"}} --cert /tls-certs/{{ .Values.tls.certFile }} --key /tls-certs/{{ .Values.tls.keyFile }}{{end}}"
|
|
||||||
{{- end }}
|
|
||||||
response=$(
|
|
||||||
redis-cli \
|
|
||||||
{{- if .Values.auth }}
|
|
||||||
-a "${AUTH}" --no-auth-warning \
|
|
||||||
{{- end }}
|
|
||||||
-h localhost \
|
|
||||||
{{- if ne (int .Values.redis.port) 0 }}
|
|
||||||
-p {{ .Values.redis.port }} \
|
|
||||||
{{- else }}
|
|
||||||
-p {{ .Values.redis.tlsPort }} ${TLS_CLIENT_OPTION} \
|
|
||||||
{{- end}}
|
|
||||||
ping
|
|
||||||
)
|
|
||||||
if [ "$response" != "PONG" ] ; then
|
|
||||||
echo "ping=$response"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
response=$(
|
|
||||||
redis-cli \
|
|
||||||
{{- if .Values.auth }}
|
|
||||||
-a "${AUTH}" --no-auth-warning \
|
|
||||||
{{- end }}
|
|
||||||
-h localhost \
|
|
||||||
{{- if ne (int .Values.redis.port) 0 }}
|
|
||||||
-p {{ .Values.redis.port }} \
|
|
||||||
{{- else }}
|
|
||||||
-p {{ .Values.redis.tlsPort }} ${TLS_CLIENT_OPTION} \
|
|
||||||
{{- end}}
|
|
||||||
role
|
|
||||||
)
|
|
||||||
role=$( echo "$response" | sed "1!d" )
|
|
||||||
if [ "$role" = "master" ]; then
|
|
||||||
echo "role=$role"
|
|
||||||
exit 0
|
|
||||||
elif [ "$role" = "slave" ]; then
|
|
||||||
repl=$( echo "$response" | sed "4!d" )
|
|
||||||
echo "role=$role; repl=$repl"
|
|
||||||
if [ "$repl" = "connected" ]; then
|
|
||||||
exit 0
|
|
||||||
else
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "role=$role"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{- define "sentinel_liveness.sh" }}
|
|
||||||
{{- if not (ne (int .Values.sentinel.port) 0) }}
|
|
||||||
TLS_CLIENT_OPTION="--tls --cacert /tls-certs/{{ .Values.tls.caCertFile }}{{ if ne (default "yes" .Values.sentinel.authClients) "no"}} --cert /tls-certs/{{ .Values.tls.certFile }} --key /tls-certs/{{ .Values.tls.keyFile }}{{end}}"
|
|
||||||
{{- end }}
|
|
||||||
response=$(
|
|
||||||
redis-cli \
|
|
||||||
{{- if .Values.sentinel.auth }}
|
|
||||||
-a "${SENTINELAUTH}" --no-auth-warning \
|
|
||||||
{{- end }}
|
|
||||||
-h localhost \
|
|
||||||
{{- if ne (int .Values.sentinel.port) 0 }}
|
|
||||||
-p {{ .Values.sentinel.port }} \
|
|
||||||
{{- else }}
|
|
||||||
-p {{ .Values.sentinel.tlsPort }} ${TLS_CLIENT_OPTION} \
|
|
||||||
{{- end}}
|
|
||||||
ping
|
|
||||||
)
|
|
||||||
if [ "$response" != "PONG" ]; then
|
|
||||||
echo "$response"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
echo "response=$response"
|
|
||||||
{{- end }}
|
|
||||||
@@ -1,154 +0,0 @@
|
|||||||
{{/* vim: set filetype=mustache: */}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Create a default fully qualified app name.
|
|
||||||
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
|
||||||
*/}}
|
|
||||||
{{- define "redis-ha.name" -}}
|
|
||||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Create a default fully qualified app name.
|
|
||||||
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
|
||||||
*/}}
|
|
||||||
{{- define "redis-ha.fullname" -}}
|
|
||||||
{{- if .Values.fullnameOverride -}}
|
|
||||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
|
|
||||||
{{- else -}}
|
|
||||||
{{- $name := default .Chart.Name .Values.nameOverride -}}
|
|
||||||
{{- if contains $name .Release.Name -}}
|
|
||||||
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
|
|
||||||
{{- else -}}
|
|
||||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Return sysctl image
|
|
||||||
*/}}
|
|
||||||
{{- define "redis.sysctl.image" -}}
|
|
||||||
{{- $registryName := default "docker.io" .Values.sysctlImage.registry -}}
|
|
||||||
{{- $tag := default "latest" .Values.sysctlImage.tag | toString -}}
|
|
||||||
{{- printf "%s/%s:%s" $registryName .Values.sysctlImage.repository $tag -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{- /*
|
|
||||||
Credit: @technosophos
|
|
||||||
https://github.com/technosophos/common-chart/
|
|
||||||
labels.standard prints the standard Helm labels.
|
|
||||||
The standard labels are frequently used in metadata.
|
|
||||||
*/ -}}
|
|
||||||
{{- define "labels.standard" -}}
|
|
||||||
app: {{ template "redis-ha.name" . }}
|
|
||||||
heritage: {{ .Release.Service | quote }}
|
|
||||||
release: {{ .Release.Name | quote }}
|
|
||||||
chart: {{ template "chartref" . }}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{- /*
|
|
||||||
Credit: @technosophos
|
|
||||||
https://github.com/technosophos/common-chart/
|
|
||||||
chartref prints a chart name and version.
|
|
||||||
It does minimal escaping for use in Kubernetes labels.
|
|
||||||
Example output:
|
|
||||||
zookeeper-1.2.3
|
|
||||||
wordpress-3.2.1_20170219
|
|
||||||
*/ -}}
|
|
||||||
{{- define "chartref" -}}
|
|
||||||
{{- replace "+" "_" .Chart.Version | printf "%s-%s" .Chart.Name -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Create the name of the service account to use
|
|
||||||
*/}}
|
|
||||||
{{- define "redis-ha.serviceAccountName" -}}
|
|
||||||
{{- if .Values.serviceAccount.create -}}
|
|
||||||
{{ default (include "redis-ha.fullname" .) .Values.serviceAccount.name }}
|
|
||||||
{{- else -}}
|
|
||||||
{{ default "default" .Values.serviceAccount.name }}
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{- define "redis-ha.masterGroupName" -}}
|
|
||||||
{{- $masterGroupName := tpl ( .Values.redis.masterGroupName | default "") . -}}
|
|
||||||
{{- $validMasterGroupName := regexMatch "^[\\w-\\.]+$" $masterGroupName -}}
|
|
||||||
{{- if $validMasterGroupName -}}
|
|
||||||
{{ $masterGroupName }}
|
|
||||||
{{- else -}}
|
|
||||||
{{ required "A valid .Values.redis.masterGroupName entry is required (matching ^[\\w-\\.]+$)" ""}}
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Return the appropriate apiVersion for poddisruptionbudget.
|
|
||||||
*/}}
|
|
||||||
{{- define "redis-ha.podDisruptionBudget.apiVersion" -}}
|
|
||||||
{{- if .Capabilities.APIVersions.Has "policy/v1" }}
|
|
||||||
{{- print "policy/v1" -}}
|
|
||||||
{{- else -}}
|
|
||||||
{{- print "policy/v1beta1" -}}
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Return true if the detected platform is Openshift
|
|
||||||
Usage:
|
|
||||||
{{- include "common.compatibility.isOpenshift" . -}}
|
|
||||||
*/}}
|
|
||||||
{{- define "compatibility.isOpenshift" -}}
|
|
||||||
{{- if .Capabilities.APIVersions.Has "security.openshift.io/v1" -}}
|
|
||||||
{{- true -}}
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Render a compatible securityContext depending on the platform. By default it is maintained as it is. In other platforms like Openshift we remove default user/group values that do not work out of the box with the restricted-v1 SCC
|
|
||||||
Usage:
|
|
||||||
{{- include "compatibility.renderSecurityContext" (dict "secContext" .Values.containerSecurityContext "context" $) -}}
|
|
||||||
*/}}
|
|
||||||
{{- define "compatibility.renderSecurityContext" -}}
|
|
||||||
{{- $adaptedContext := .secContext -}}
|
|
||||||
|
|
||||||
{{- if (((.context.Values.global).compatibility).openshift) -}}
|
|
||||||
{{- if or (eq .context.Values.global.compatibility.openshift.adaptSecurityContext "force") (and (eq .context.Values.global.compatibility.openshift.adaptSecurityContext "auto") (include "compatibility.isOpenshift" .context)) -}}
|
|
||||||
{{/* Remove incompatible user/group values that do not work in Openshift out of the box */}}
|
|
||||||
{{- $adaptedContext = omit $adaptedContext "fsGroup" "runAsUser" "runAsGroup" -}}
|
|
||||||
{{- if not .secContext.seLinuxOptions -}}
|
|
||||||
{{/* If it is an empty object, we remove it from the resulting context because it causes validation issues */}}
|
|
||||||
{{- $adaptedContext = omit $adaptedContext "seLinuxOptions" -}}
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
{{/* Remove fields that are disregarded when running the container in privileged mode */}}
|
|
||||||
{{- if $adaptedContext.privileged -}}
|
|
||||||
{{- $adaptedContext = omit $adaptedContext "capabilities" "seLinuxOptions" -}}
|
|
||||||
{{- end -}}
|
|
||||||
{{- omit $adaptedContext "enabled" | toYaml -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Defines the redis ports to be used inside network policies
|
|
||||||
Usage:
|
|
||||||
{{- include "redis-ports" . -}}
|
|
||||||
*/}}
|
|
||||||
{{- define "redis-ports" -}}
|
|
||||||
{{- if ne (int .Values.redis.port) 0 }}
|
|
||||||
- port: {{ .Values.redis.port }}
|
|
||||||
protocol: TCP
|
|
||||||
{{- end -}}
|
|
||||||
{{- if ne (int .Values.sentinel.port) 0 }}
|
|
||||||
- port: {{ .Values.sentinel.port }}
|
|
||||||
protocol: TCP
|
|
||||||
{{- end -}}
|
|
||||||
{{- if ne (int .Values.redis.tlsPort) 0 }}
|
|
||||||
- port: {{ .Values.redis.tlsPort }}
|
|
||||||
protocol: TCP
|
|
||||||
{{- end -}}
|
|
||||||
{{- if ne (int .Values.sentinel.tlsPort) 0 }}
|
|
||||||
- port: {{ .Values.sentinel.tlsPort }}
|
|
||||||
protocol: TCP
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
-19
@@ -1,19 +0,0 @@
|
|||||||
{{- if and .Values.auth (not (tpl (.Values.existingSecret | default "" ) . )) -}}
|
|
||||||
{{ $fullAnnotations := mustMerge .Values.redis.annotations .Values.authSecretAnnotations }}
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Secret
|
|
||||||
metadata:
|
|
||||||
name: {{ template "redis-ha.fullname" . }}
|
|
||||||
namespace: {{ .Release.Namespace | quote }}
|
|
||||||
{{- with $fullAnnotations }}
|
|
||||||
annotations: {{ . | toYaml | nindent 4 }}
|
|
||||||
{{- end }}
|
|
||||||
labels:
|
|
||||||
{{ include "labels.standard" . | indent 4 }}
|
|
||||||
{{- range $key, $value := .Values.extraLabels }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
type: Opaque
|
|
||||||
data:
|
|
||||||
{{ .Values.authKey }}: {{ .Values.redisPassword | b64enc | quote }}
|
|
||||||
{{- end -}}
|
|
||||||
-64
@@ -1,64 +0,0 @@
|
|||||||
{{- $fullName := include "redis-ha.fullname" . }}
|
|
||||||
{{- $namespace := .Release.Namespace -}}
|
|
||||||
{{- $replicas := int (toString .Values.replicas) }}
|
|
||||||
{{- $root := . }}
|
|
||||||
{{- range $i := until $replicas }}
|
|
||||||
---
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: {{ $fullName }}-announce-{{ $i }}
|
|
||||||
namespace: {{ $namespace | quote }}
|
|
||||||
labels:
|
|
||||||
{{ include "labels.standard" $root | indent 4 }}
|
|
||||||
{{- range $key, $value := $root.Values.extraLabels }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
annotations:
|
|
||||||
{{- if (semverCompare "<=1.10-0" $.Capabilities.KubeVersion.Version) }}
|
|
||||||
service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
|
|
||||||
{{- end }}
|
|
||||||
{{- if $root.Values.serviceAnnotations }}
|
|
||||||
{{ toYaml $root.Values.serviceAnnotations | indent 4 }}
|
|
||||||
{{- end }}
|
|
||||||
spec:
|
|
||||||
{{- if (semverCompare ">=1.11-0" $.Capabilities.KubeVersion.Version) }}
|
|
||||||
publishNotReadyAddresses: true
|
|
||||||
{{- end }}
|
|
||||||
type: ClusterIP
|
|
||||||
ports:
|
|
||||||
{{- if ne (int $root.Values.redis.port) 0 }}
|
|
||||||
- name: tcp-server
|
|
||||||
port: {{ $root.Values.redis.port }}
|
|
||||||
protocol: TCP
|
|
||||||
targetPort: redis
|
|
||||||
{{- end }}
|
|
||||||
{{- if $root.Values.redis.tlsPort }}
|
|
||||||
- name: server-tls
|
|
||||||
port: {{ $root.Values.redis.tlsPort }}
|
|
||||||
protocol: TCP
|
|
||||||
targetPort: redis-tls
|
|
||||||
{{- end }}
|
|
||||||
{{- if ne (int $root.Values.sentinel.port) 0 }}
|
|
||||||
- name: tcp-sentinel
|
|
||||||
port: {{ $root.Values.sentinel.port }}
|
|
||||||
protocol: TCP
|
|
||||||
targetPort: sentinel
|
|
||||||
{{- end }}
|
|
||||||
{{- if $root.Values.sentinel.tlsPort }}
|
|
||||||
- name: sentinel-tls
|
|
||||||
port: {{ $root.Values.sentinel.tlsPort }}
|
|
||||||
protocol: TCP
|
|
||||||
targetPort: sentinel-tls
|
|
||||||
{{- end }}
|
|
||||||
{{- if $root.Values.exporter.enabled }}
|
|
||||||
- name: http-exporter
|
|
||||||
port: {{ $root.Values.exporter.port }}
|
|
||||||
protocol: TCP
|
|
||||||
targetPort: {{ $root.Values.exporter.portName }}
|
|
||||||
{{- end }}
|
|
||||||
selector:
|
|
||||||
release: {{ $root.Release.Name }}
|
|
||||||
app: {{ include "redis-ha.name" $root }}
|
|
||||||
"statefulset.kubernetes.io/pod-name": {{ $fullName }}-server-{{ $i }}
|
|
||||||
{{- end }}
|
|
||||||
-37
@@ -1,37 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: ConfigMap
|
|
||||||
metadata:
|
|
||||||
name: {{ template "redis-ha.fullname" . }}-configmap
|
|
||||||
namespace: {{ .Release.Namespace | quote }}
|
|
||||||
labels:
|
|
||||||
heritage: {{ .Release.Service }}
|
|
||||||
release: {{ .Release.Name }}
|
|
||||||
chart: {{ .Chart.Name }}-{{ .Chart.Version }}
|
|
||||||
app: {{ template "redis-ha.fullname" . }}
|
|
||||||
{{- range $key, $value := .Values.configmap.labels }}
|
|
||||||
{{ $key }}: {{ $value | toString }}
|
|
||||||
{{- end }}
|
|
||||||
{{- range $key, $value := .Values.extraLabels }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
data:
|
|
||||||
redis.conf: |
|
|
||||||
{{- include "config-redis.conf" . }}
|
|
||||||
|
|
||||||
sentinel.conf: |
|
|
||||||
{{- include "config-sentinel.conf" . }}
|
|
||||||
|
|
||||||
init.sh: |
|
|
||||||
{{- include "config-init.sh" . }}
|
|
||||||
|
|
||||||
fix-split-brain.sh: |
|
|
||||||
{{- include "fix-split-brain.sh" . }}
|
|
||||||
|
|
||||||
{{ if .Values.haproxy.enabled }}
|
|
||||||
haproxy.cfg: |
|
|
||||||
{{- include "config-haproxy.cfg" . }}
|
|
||||||
{{- end }}
|
|
||||||
haproxy_init.sh: |
|
|
||||||
{{- include "config-haproxy_init.sh" . }}
|
|
||||||
trigger-failover-if-master.sh: |
|
|
||||||
{{- include "trigger-failover-if-master.sh" . }}
|
|
||||||
-14
@@ -1,14 +0,0 @@
|
|||||||
{{- if .Values.exporter.script }}
|
|
||||||
apiVersion: v1
|
|
||||||
kind: ConfigMap
|
|
||||||
metadata:
|
|
||||||
name: {{ template "redis-ha.fullname" . }}-exporter-script-configmap
|
|
||||||
namespace: {{ .Release.Namespace | quote }}
|
|
||||||
labels:
|
|
||||||
{{ include "labels.standard" . | indent 4 }}
|
|
||||||
{{- range $key, $value := .Values.extraLabels }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
data:
|
|
||||||
script: {{ toYaml .Values.exporter.script | indent 2 }}
|
|
||||||
{{- end }}
|
|
||||||
-20
@@ -1,20 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: ConfigMap
|
|
||||||
metadata:
|
|
||||||
name: {{ template "redis-ha.fullname" . }}-health-configmap
|
|
||||||
namespace: {{ .Release.Namespace | quote }}
|
|
||||||
labels:
|
|
||||||
heritage: {{ .Release.Service }}
|
|
||||||
release: {{ .Release.Name }}
|
|
||||||
chart: {{ .Chart.Name }}-{{ .Chart.Version }}
|
|
||||||
app: {{ template "redis-ha.fullname" . }}
|
|
||||||
{{- range $key, $value := .Values.extraLabels }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
data:
|
|
||||||
redis_liveness.sh: |
|
|
||||||
{{- include "redis_liveness.sh" . }}
|
|
||||||
redis_readiness.sh: |
|
|
||||||
{{- include "redis_readiness.sh" . }}
|
|
||||||
sentinel_liveness.sh: |
|
|
||||||
{{- include "sentinel_liveness.sh" . }}
|
|
||||||
-68
@@ -1,68 +0,0 @@
|
|||||||
{{- if .Values.networkPolicy.enabled }}
|
|
||||||
{{- $root := . }}
|
|
||||||
kind: NetworkPolicy
|
|
||||||
apiVersion: networking.k8s.io/v1
|
|
||||||
metadata:
|
|
||||||
name: {{ template "redis-ha.fullname" . }}-network-policy
|
|
||||||
namespace: {{ .Release.Namespace | quote }}
|
|
||||||
{{- if .Values.networkPolicy.annotations }}
|
|
||||||
annotations:
|
|
||||||
{{- range $key, $value := .Values.networkPolicy.annotations }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
labels:
|
|
||||||
{{ include "labels.standard" . | indent 4 }}
|
|
||||||
{{- range $key, $value := .Values.networkPolicy.labels }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
spec:
|
|
||||||
podSelector:
|
|
||||||
matchLabels:
|
|
||||||
release: {{ .Release.Name }}
|
|
||||||
app: {{ template "redis-ha.name" . }}
|
|
||||||
policyTypes:
|
|
||||||
- Ingress
|
|
||||||
- Egress
|
|
||||||
egress:
|
|
||||||
- to:
|
|
||||||
- podSelector:
|
|
||||||
matchLabels:
|
|
||||||
release: {{ .Release.Name }}
|
|
||||||
app: {{ template "redis-ha.name" . }}
|
|
||||||
ports:
|
|
||||||
{{- include "redis-ports" . | nindent 6 }}
|
|
||||||
{{- range $rule := .Values.networkPolicy.egressRules }}
|
|
||||||
- to:
|
|
||||||
{{ (tpl (toYaml $rule.selectors) $) | indent 7 }}
|
|
||||||
ports:
|
|
||||||
{{ toYaml $rule.ports | indent 7 }}
|
|
||||||
{{- end }}
|
|
||||||
ingress:
|
|
||||||
- from:
|
|
||||||
- podSelector:
|
|
||||||
matchLabels:
|
|
||||||
release: {{ .Release.Name }}
|
|
||||||
app: {{ template "redis-ha.name" . }}
|
|
||||||
ports:
|
|
||||||
{{- include "redis-ports" . | nindent 6 }}
|
|
||||||
{{- if .Values.haproxy.enabled }}
|
|
||||||
- from:
|
|
||||||
- podSelector:
|
|
||||||
matchLabels:
|
|
||||||
release: {{ .Release.Name }}
|
|
||||||
app: {{ template "redis-ha.name" . }}-haproxy
|
|
||||||
ports:
|
|
||||||
{{- include "redis-ports" . | nindent 6 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- range $rule := .Values.networkPolicy.ingressRules }}
|
|
||||||
- from:
|
|
||||||
{{ (tpl (toYaml $rule.selectors) $) | indent 7 }}
|
|
||||||
ports:
|
|
||||||
{{- if $rule.ports }}
|
|
||||||
{{ toYaml $rule.ports | indent 7 }}
|
|
||||||
{{- else }}
|
|
||||||
{{- include "redis-ports" $root | nindent 6 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
-18
@@ -1,18 +0,0 @@
|
|||||||
{{- if .Values.podDisruptionBudget -}}
|
|
||||||
apiVersion: {{ template "redis-ha.podDisruptionBudget.apiVersion" . }}
|
|
||||||
kind: PodDisruptionBudget
|
|
||||||
metadata:
|
|
||||||
name: {{ template "redis-ha.fullname" . }}-pdb
|
|
||||||
namespace: {{ .Release.Namespace | quote }}
|
|
||||||
labels:
|
|
||||||
{{ include "labels.standard" . | indent 4 }}
|
|
||||||
{{- range $key, $value := .Values.extraLabels }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
spec:
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
release: {{ .Release.Name }}
|
|
||||||
app: {{ template "redis-ha.name" . }}
|
|
||||||
{{ toYaml .Values.podDisruptionBudget | indent 2 }}
|
|
||||||
{{- end -}}
|
|
||||||
-19
@@ -1,19 +0,0 @@
|
|||||||
{{- if .Values.prometheusRule.enabled }}
|
|
||||||
apiVersion: monitoring.coreos.com/v1
|
|
||||||
kind: PrometheusRule
|
|
||||||
metadata:
|
|
||||||
name: {{ template "redis-ha.fullname" . }}
|
|
||||||
{{- if .Values.prometheusRule.namespace }}
|
|
||||||
namespace: {{ .Values.prometheusRule.namespace }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.prometheusRule.additionalLabels }}
|
|
||||||
labels: {{- toYaml .Values.prometheusRule.additionalLabels | nindent 4 }}
|
|
||||||
{{- end }}
|
|
||||||
spec:
|
|
||||||
groups:
|
|
||||||
- name: {{ template "redis-ha.fullname" . }}
|
|
||||||
{{- if .Values.prometheusRule.interval }}
|
|
||||||
interval: {{ .Values.prometheusRule.interval }}
|
|
||||||
{{- end }}
|
|
||||||
rules: {{- tpl (toYaml .Values.prometheusRule.rules) . | nindent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
-19
@@ -1,19 +0,0 @@
|
|||||||
{{- if and .Values.serviceAccount.create .Values.rbac.create }}
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: Role
|
|
||||||
metadata:
|
|
||||||
name: {{ template "redis-ha.fullname" . }}
|
|
||||||
namespace: {{ .Release.Namespace | quote }}
|
|
||||||
labels:
|
|
||||||
{{ include "labels.standard" . | indent 4 }}
|
|
||||||
{{- range $key, $value := .Values.extraLabels }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
rules:
|
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
resources:
|
|
||||||
- endpoints
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
{{- end }}
|
|
||||||
-19
@@ -1,19 +0,0 @@
|
|||||||
{{- if and .Values.serviceAccount.create .Values.rbac.create }}
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: RoleBinding
|
|
||||||
metadata:
|
|
||||||
name: {{ template "redis-ha.fullname" . }}
|
|
||||||
namespace: {{ .Release.Namespace | quote }}
|
|
||||||
labels:
|
|
||||||
{{ include "labels.standard" . | indent 4 }}
|
|
||||||
{{- range $key, $value := .Values.extraLabels }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
subjects:
|
|
||||||
- kind: ServiceAccount
|
|
||||||
name: {{ template "redis-ha.serviceAccountName" . }}
|
|
||||||
roleRef:
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
kind: Role
|
|
||||||
name: {{ template "redis-ha.fullname" . }}
|
|
||||||
{{- end }}
|
|
||||||
-32
@@ -1,32 +0,0 @@
|
|||||||
{{- if not .Values.restore.existingSecret }}
|
|
||||||
|
|
||||||
|
|
||||||
{{- $regexRestoreS3 := "^s3://.+|^S3://.+" -}}
|
|
||||||
{{- $regexRestoreSSH := "^.+@.+:.+" -}}
|
|
||||||
|
|
||||||
{{- if or (regexFind $regexRestoreSSH (toString .Values.restore.ssh.source)) (regexFind $regexRestoreS3 (toString .Values.restore.s3.source)) }}
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Secret
|
|
||||||
metadata:
|
|
||||||
name: {{ include "redis-ha.fullname" . }}-secret
|
|
||||||
namespace: {{ .Release.Namespace | quote }}
|
|
||||||
labels:
|
|
||||||
heritage: {{ .Release.Service }}
|
|
||||||
release: {{ .Release.Name }}
|
|
||||||
chart: {{ .Chart.Name }}-{{ .Chart.Version }}
|
|
||||||
app: {{ template "redis-ha.fullname" . }}
|
|
||||||
{{- range $key, $value := .Values.extraLabels }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
type: Opaque
|
|
||||||
data:
|
|
||||||
{{- if regexFind $regexRestoreSSH (toString .Values.restore.ssh.source) }}
|
|
||||||
SSH_KEY: "{{ .Values.restore.ssh.key | b64enc }}"
|
|
||||||
{{- end }}
|
|
||||||
{{- if regexFind $regexRestoreS3 (toString .Values.restore.s3.source) }}
|
|
||||||
AWS_SECRET_ACCESS_KEY: "{{ .Values.restore.s3.secret_key | b64enc }}"
|
|
||||||
AWS_ACCESS_KEY_ID: "{{ .Values.restore.s3.access_key | b64enc }}"
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{- end }}
|
|
||||||
-57
@@ -1,57 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: {{ template "redis-ha.fullname" . }}
|
|
||||||
namespace: {{ .Release.Namespace | quote }}
|
|
||||||
labels:
|
|
||||||
{{ include "labels.standard" . | indent 4 }}
|
|
||||||
{{- if .Values.exporter.enabled }}
|
|
||||||
exporter: enabled
|
|
||||||
{{- end }}
|
|
||||||
{{- range $key, $value := .Values.extraLabels }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
{{- range $key, $value := .Values.serviceLabels }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
annotations:
|
|
||||||
{{- if .Values.serviceAnnotations }}
|
|
||||||
{{ toYaml .Values.serviceAnnotations | indent 4 }}
|
|
||||||
{{- end }}
|
|
||||||
spec:
|
|
||||||
type: ClusterIP
|
|
||||||
clusterIP: None
|
|
||||||
ports:
|
|
||||||
{{- if ne (int .Values.redis.port) 0 }}
|
|
||||||
- name: tcp-server
|
|
||||||
port: {{ .Values.redis.port }}
|
|
||||||
protocol: TCP
|
|
||||||
targetPort: redis
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.redis.tlsPort }}
|
|
||||||
- name: server-tls
|
|
||||||
port: {{ .Values.redis.tlsPort }}
|
|
||||||
protocol: TCP
|
|
||||||
targetPort: redis-tls
|
|
||||||
{{- end }}
|
|
||||||
{{- if ne (int .Values.sentinel.port) 0 }}
|
|
||||||
- name: tcp-sentinel
|
|
||||||
port: {{ .Values.sentinel.port }}
|
|
||||||
protocol: TCP
|
|
||||||
targetPort: sentinel
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.sentinel.tlsPort }}
|
|
||||||
- name: sentinel-tls
|
|
||||||
port: {{ .Values.sentinel.tlsPort }}
|
|
||||||
protocol: TCP
|
|
||||||
targetPort: sentinel-tls
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.exporter.enabled }}
|
|
||||||
- name: http-exporter-port
|
|
||||||
port: {{ .Values.exporter.port }}
|
|
||||||
protocol: TCP
|
|
||||||
targetPort: {{ .Values.exporter.portName }}
|
|
||||||
{{- end }}
|
|
||||||
selector:
|
|
||||||
release: {{ .Release.Name }}
|
|
||||||
app: {{ template "redis-ha.name" . }}
|
|
||||||
-35
@@ -1,35 +0,0 @@
|
|||||||
{{- if .Values.serviceAccount.create }}
|
|
||||||
apiVersion: v1
|
|
||||||
kind: ServiceAccount
|
|
||||||
metadata:
|
|
||||||
name: {{ template "redis-ha.serviceAccountName" . }}
|
|
||||||
namespace: {{ .Release.Namespace | quote }}
|
|
||||||
labels:
|
|
||||||
heritage: {{ .Release.Service }}
|
|
||||||
release: {{ .Release.Name }}
|
|
||||||
chart: {{ .Chart.Name }}-{{ .Chart.Version }}
|
|
||||||
app: {{ template "redis-ha.fullname" . }}
|
|
||||||
{{- range $key, $value := .Values.extraLabels }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.serviceAccount.annotations }}
|
|
||||||
annotations:
|
|
||||||
{{ toYaml .Values.serviceAccount.annotations | indent 4 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if or .Values.auth .Values.sentinel.auth }}
|
|
||||||
secrets:
|
|
||||||
{{- end }}
|
|
||||||
{{- if and (and (.Values.auth) (.Values.sentinel.auth)) (eq (.Values.existingSecret) (.Values.sentinel.existingSecret)) }}
|
|
||||||
- name: {{ default (include "redis-ha.fullname" .) (tpl (.Values.existingSecret | default "" ) . ) }}
|
|
||||||
{{- else }}
|
|
||||||
{{- if .Values.auth }}
|
|
||||||
- name: {{ default (include "redis-ha.fullname" .) (tpl (.Values.existingSecret | default "" ) . ) }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.sentinel.auth }}
|
|
||||||
- name: {{ default (printf "%s-sentinel" (include "redis-ha.fullname" .)) (tpl (.Values.sentinel.existingSecret | default "" ) . ) }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.imagePullSecrets }}
|
|
||||||
imagePullSecrets: {{ toYaml .Values.imagePullSecrets | nindent 0 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
-47
@@ -1,47 +0,0 @@
|
|||||||
{{- if and ( or .Values.exporter.serviceMonitor.disableAPICheck ( .Capabilities.APIVersions.Has "monitoring.coreos.com/v1" ) ) ( .Values.exporter.serviceMonitor.enabled ) ( .Values.exporter.enabled ) }}
|
|
||||||
apiVersion: monitoring.coreos.com/v1
|
|
||||||
kind: ServiceMonitor
|
|
||||||
metadata:
|
|
||||||
name: {{ template "redis-ha.fullname" . }}
|
|
||||||
namespace: {{ .Values.exporter.serviceMonitor.namespace | default .Release.Namespace | quote }}
|
|
||||||
labels:
|
|
||||||
{{ include "labels.standard" . | indent 4 }}
|
|
||||||
{{- range $key, $value := .Values.extraLabels }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
{{- range $key, $value := .Values.exporter.serviceMonitor.labels }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
spec:
|
|
||||||
endpoints:
|
|
||||||
- targetPort: {{ .Values.exporter.port }}
|
|
||||||
{{- if .Values.exporter.serviceMonitor.interval }}
|
|
||||||
interval: {{ .Values.exporter.serviceMonitor.interval }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.exporter.serviceMonitor.telemetryPath }}
|
|
||||||
path: {{ .Values.exporter.serviceMonitor.telemetryPath }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.exporter.serviceMonitor.timeout }}
|
|
||||||
scrapeTimeout: {{ .Values.exporter.serviceMonitor.timeout }}
|
|
||||||
{{- end }}
|
|
||||||
{{- with .Values.exporter.serviceMonitor.endpointAdditionalProperties }}
|
|
||||||
{{- toYaml . | nindent 4 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.exporter.serviceMonitor.metricRelabelings }}
|
|
||||||
metricRelabelings:
|
|
||||||
{{- toYaml .Values.exporter.serviceMonitor.metricRelabelings | nindent 6 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.exporter.serviceMonitor.relabelings }}
|
|
||||||
relabelings:
|
|
||||||
{{- toYaml .Values.exporter.serviceMonitor.relabelings | nindent 6 }}
|
|
||||||
{{- end }}
|
|
||||||
jobLabel: {{ template "redis-ha.fullname" . }}
|
|
||||||
namespaceSelector:
|
|
||||||
matchNames:
|
|
||||||
- {{ .Release.Namespace | quote }}
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: {{ template "redis-ha.name" . }}
|
|
||||||
release: {{ .Release.Name }}
|
|
||||||
exporter: enabled
|
|
||||||
{{- end }}
|
|
||||||
-668
@@ -1,668 +0,0 @@
|
|||||||
{{- $regexRestoreS3 := "^s3://.+|^S3://.+" -}}
|
|
||||||
{{- $regexRestoreSSH := "^.+@.+:.+" -}}
|
|
||||||
{{- $regexRestoreRedis := "^redis://(?:[A-Za-z0-9_]+(?::[^@]+)?@)?[A-Za-z0-9.-]+(?::\\d{1,5})?(?:/\\d+)?$" -}}
|
|
||||||
|
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: StatefulSet
|
|
||||||
metadata:
|
|
||||||
name: {{ template "redis-ha.fullname" . }}-server
|
|
||||||
namespace: {{ .Release.Namespace | quote }}
|
|
||||||
labels:
|
|
||||||
{{ template "redis-ha.fullname" . }}: replica
|
|
||||||
{{- range $key, $value := .Values.extraLabels }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
{{ include "labels.standard" . | indent 4 }}
|
|
||||||
annotations:
|
|
||||||
{{ toYaml .Values.redis.annotations | indent 4 }}
|
|
||||||
spec:
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
release: {{ .Release.Name }}
|
|
||||||
app: {{ template "redis-ha.name" . }}
|
|
||||||
serviceName: {{ template "redis-ha.fullname" . }}
|
|
||||||
replicas: {{ .Values.replicas }}
|
|
||||||
podManagementPolicy: {{ .Values.podManagementPolicy }}
|
|
||||||
updateStrategy:
|
|
||||||
type: {{ .Values.redis.updateStrategy.type }}
|
|
||||||
{{- if .Values.redis.minReadySeconds }}
|
|
||||||
minReadySeconds: {{ .Values.redis.minReadySeconds }}
|
|
||||||
{{- end }}
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
annotations:
|
|
||||||
checksum/init-config: {{ print (include "config-redis.conf" .) (include "config-sentinel.conf" .) (include "config-init.sh" .) (include "fix-split-brain.sh" .) (include "redis_liveness.sh" .) (include "redis_readiness.sh" .) (include "sentinel_liveness.sh" .) (include "trigger-failover-if-master.sh" .)| sha256sum }}
|
|
||||||
{{- if .Values.redis.podAnnotations }}
|
|
||||||
{{ toYaml .Values.redis.podAnnotations | indent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if and (.Values.exporter.enabled) (not .Values.exporter.serviceMonitor.enabled) }}
|
|
||||||
prometheus.io/port: "{{ .Values.exporter.port }}"
|
|
||||||
prometheus.io/scrape: "true"
|
|
||||||
prometheus.io/path: {{ .Values.exporter.scrapePath }}
|
|
||||||
{{- end }}
|
|
||||||
labels:
|
|
||||||
release: {{ .Release.Name }}
|
|
||||||
app: {{ template "redis-ha.name" . }}
|
|
||||||
{{ template "redis-ha.fullname" . }}: replica
|
|
||||||
{{- range $key, $value := .Values.labels }}
|
|
||||||
{{ $key }}: {{ $value | toString }}
|
|
||||||
{{- end }}
|
|
||||||
{{- range $key, $value := .Values.extraLabels }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
spec:
|
|
||||||
{{- if .Values.redis.terminationGracePeriodSeconds }}
|
|
||||||
terminationGracePeriodSeconds: {{ .Values.redis.terminationGracePeriodSeconds }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.schedulerName }}
|
|
||||||
schedulerName: "{{ .Values.schedulerName }}"
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.nodeSelector }}
|
|
||||||
nodeSelector:
|
|
||||||
{{ toYaml .Values.nodeSelector | indent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.tolerations }}
|
|
||||||
tolerations:
|
|
||||||
{{ toYaml .Values.tolerations | indent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
affinity:
|
|
||||||
{{- if .Values.affinity }}
|
|
||||||
{{- with .Values.affinity }}
|
|
||||||
{{ tpl . $ | indent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- else }}
|
|
||||||
{{- if .Values.additionalAffinities }}
|
|
||||||
{{ toYaml .Values.additionalAffinities | indent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
podAntiAffinity:
|
|
||||||
{{- if .Values.hardAntiAffinity }}
|
|
||||||
requiredDuringSchedulingIgnoredDuringExecution:
|
|
||||||
- labelSelector:
|
|
||||||
matchLabels:
|
|
||||||
app: {{ template "redis-ha.name" . }}
|
|
||||||
release: {{ .Release.Name }}
|
|
||||||
{{ template "redis-ha.fullname" . }}: replica
|
|
||||||
topologyKey: kubernetes.io/hostname
|
|
||||||
{{- else }}
|
|
||||||
preferredDuringSchedulingIgnoredDuringExecution:
|
|
||||||
- weight: 100
|
|
||||||
podAffinityTerm:
|
|
||||||
labelSelector:
|
|
||||||
matchLabels:
|
|
||||||
app: {{ template "redis-ha.name" . }}
|
|
||||||
release: {{ .Release.Name }}
|
|
||||||
{{ template "redis-ha.fullname" . }}: replica
|
|
||||||
topologyKey: kubernetes.io/hostname
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.topologySpreadConstraints.enabled }}
|
|
||||||
topologySpreadConstraints:
|
|
||||||
- maxSkew: {{ .Values.topologySpreadConstraints.maxSkew | default 1 }}
|
|
||||||
topologyKey: {{ .Values.topologySpreadConstraints.topologyKey | default "topology.kubernetes.io/zone" }}
|
|
||||||
whenUnsatisfiable: {{ .Values.topologySpreadConstraints.whenUnsatisfiable | default "ScheduleAnyway" }}
|
|
||||||
labelSelector:
|
|
||||||
matchLabels:
|
|
||||||
app: {{ template "redis-ha.name" . }}
|
|
||||||
release: {{ .Release.Name }}
|
|
||||||
{{ template "redis-ha.fullname" . }}: replica
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.imagePullSecrets }}
|
|
||||||
imagePullSecrets: {{ toYaml .Values.imagePullSecrets | nindent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
securityContext: {{- include "compatibility.renderSecurityContext" (dict "secContext" .Values.securityContext "context" $) | nindent 8 }}
|
|
||||||
serviceAccountName: {{ template "redis-ha.serviceAccountName" . }}
|
|
||||||
automountServiceAccountToken: {{ .Values.serviceAccount.automountToken }}
|
|
||||||
initContainers:
|
|
||||||
{{- if .Values.sysctlImage.enabled }}
|
|
||||||
- name: init-sysctl
|
|
||||||
image: {{ template "redis.sysctl.image" . }}
|
|
||||||
imagePullPolicy: {{ .Values.sysctlImage.pullPolicy }}
|
|
||||||
resources: {{ toYaml .Values.sysctlImage.resources | nindent 10 }}
|
|
||||||
{{- if .Values.sysctlImage.mountHostSys }}
|
|
||||||
volumeMounts:
|
|
||||||
- name: host-sys
|
|
||||||
mountPath: /host-sys
|
|
||||||
{{- end }}
|
|
||||||
command: {{ toYaml .Values.sysctlImage.command | nindent 10 }}
|
|
||||||
securityContext: {{- include "compatibility.renderSecurityContext" (dict "secContext" .Values.containerSecurityContext "context" $) | nindent 10 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if and .Values.hostPath.path .Values.hostPath.chown }}
|
|
||||||
- name: hostpath-chown
|
|
||||||
image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
|
|
||||||
securityContext:
|
|
||||||
runAsUser: 0
|
|
||||||
runAsNonRoot: false
|
|
||||||
resources: {{ toYaml .Values.init.resources | nindent 10 }}
|
|
||||||
command:
|
|
||||||
- chown
|
|
||||||
- "{{ .Values.containerSecurityContext.runAsUser }}:{{ .Values.securityContext.fsGroup }}"
|
|
||||||
- /data
|
|
||||||
volumeMounts:
|
|
||||||
- name: data
|
|
||||||
mountPath: /data
|
|
||||||
{{- end }}
|
|
||||||
- name: config-init
|
|
||||||
image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
|
|
||||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
|
||||||
resources: {{ toYaml .Values.init.resources | nindent 10 }}
|
|
||||||
command:
|
|
||||||
- sh
|
|
||||||
args:
|
|
||||||
- /readonly-config/init.sh
|
|
||||||
securityContext: {{- include "compatibility.renderSecurityContext" (dict "secContext" .Values.containerSecurityContext "context" $) | nindent 10 }}
|
|
||||||
env:
|
|
||||||
{{- $replicas := int (toString .Values.replicas) -}}
|
|
||||||
{{- range $i := until $replicas }}
|
|
||||||
- name: SENTINEL_ID_{{ $i }}
|
|
||||||
value: {{ printf "%s\n%s\nindex: %d" (include "redis-ha.name" $) ($.Release.Name) $i | sha256sum | trunc 40 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.auth }}
|
|
||||||
- name: AUTH
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
{{- if tpl (.Values.existingSecret | default "" ) . }}
|
|
||||||
name: {{ tpl (.Values.existingSecret | default "" ) . }}
|
|
||||||
{{- else }}
|
|
||||||
name: {{ template "redis-ha.fullname" . }}
|
|
||||||
{{- end }}
|
|
||||||
key: {{ .Values.authKey }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.sentinel.auth }}
|
|
||||||
- name: SENTINELAUTH
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
{{- if tpl (.Values.sentinel.existingSecret | default "" ) . }}
|
|
||||||
name: {{ tpl (.Values.sentinel.existingSecret | default "" ) . }}
|
|
||||||
{{- else }}
|
|
||||||
name: {{ template "redis-ha.fullname" . }}-sentinel
|
|
||||||
{{- end }}
|
|
||||||
key: {{ .Values.sentinel.authKey }}
|
|
||||||
{{- end }}
|
|
||||||
volumeMounts:
|
|
||||||
- name: config
|
|
||||||
mountPath: /readonly-config
|
|
||||||
readOnly: true
|
|
||||||
- name: data
|
|
||||||
mountPath: /data
|
|
||||||
{{- if .Values.redis.tlsPort }}
|
|
||||||
- mountPath: /tls-certs
|
|
||||||
name: tls-certs
|
|
||||||
{{- end}}
|
|
||||||
{{ if regexFind $regexRestoreS3 (toString .Values.restore.s3.source) }}
|
|
||||||
- name: restore-s3
|
|
||||||
image: s3cmd/s3cmd:latest
|
|
||||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
|
||||||
resources: {{ toYaml .Values.init.resources | nindent 10 }}
|
|
||||||
command:
|
|
||||||
- sh
|
|
||||||
args:
|
|
||||||
- "-c"
|
|
||||||
- "timeout -t {{ .Values.restore.timeout }} \
|
|
||||||
s3cmd get {{ if .Values.restore.s3.region }}--region {{ .Values.restore.s3.region }} {{ end }}--force '{{ .Values.restore.s3.source }}' /data/dump.rdb_ \
|
|
||||||
&& test -s /data/dump.rdb_ \
|
|
||||||
&& if test -s /data/dump.rdb; \
|
|
||||||
then cp -v /data/dump.rdb /data/dump.rdb_orig; fi \
|
|
||||||
&& mv -v /data/dump.rdb_ /data/dump.rdb"
|
|
||||||
envFrom:
|
|
||||||
- secretRef:
|
|
||||||
{{- if .Values.restore.existingSecret }}
|
|
||||||
name: {{ tpl (.Values.existingSecret | default "" ) . }}
|
|
||||||
{{- else }}
|
|
||||||
name: {{ include "redis-ha.fullname" . }}-secret
|
|
||||||
{{- end }}
|
|
||||||
volumeMounts:
|
|
||||||
- name: data
|
|
||||||
mountPath: /data
|
|
||||||
{{- end }}
|
|
||||||
{{ if regexFind $regexRestoreSSH (toString .Values.restore.ssh.source) }}
|
|
||||||
- name: restore-ssh
|
|
||||||
image: lgatica/openssh-client:latest
|
|
||||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
|
||||||
resources: {{ toYaml .Values.init.resources | nindent 10 }}
|
|
||||||
command:
|
|
||||||
- sh
|
|
||||||
args:
|
|
||||||
- "-c"
|
|
||||||
- "rm -f key && echo -e \"${SSH_KEY}\" >key \
|
|
||||||
&& chmod 400 key \
|
|
||||||
&& timeout {{ .Values.restore.timeout }} \
|
|
||||||
scp -i key \
|
|
||||||
-o StrictHostKeyChecking=no \
|
|
||||||
-o UserKnownHostsFile=/dev/null \
|
|
||||||
'{{ .Values.restore.ssh.source }}' \
|
|
||||||
/data/dump.rdb_ \
|
|
||||||
&& test -s /data/dump.rdb_ \
|
|
||||||
&& if test -s /data/dump.rdb; \
|
|
||||||
then cp -v /data/dump.rdb /data/dump.rdb_orig; fi \
|
|
||||||
&& mv -v /data/dump.rdb_ /data/dump.rdb"
|
|
||||||
securityContext: {{- include "compatibility.renderSecurityContext" (dict "secContext" .Values.containerSecurityContext "context" $) | nindent 10 }}
|
|
||||||
envFrom:
|
|
||||||
- secretRef:
|
|
||||||
{{- if .Values.restore.existingSecret }}
|
|
||||||
name: {{ tpl (.Values.existingSecret | default "" ) . }}
|
|
||||||
{{- else }}
|
|
||||||
name: {{ include "redis-ha.fullname" . }}-secret
|
|
||||||
{{- end }}
|
|
||||||
volumeMounts:
|
|
||||||
- name: data
|
|
||||||
mountPath: /data
|
|
||||||
{{- end }}
|
|
||||||
{{ if regexFind $regexRestoreRedis (toString .Values.restore.redis.source) }}
|
|
||||||
- name: restore-redis
|
|
||||||
image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
|
|
||||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
|
||||||
resources: {{ toYaml .Values.init.resources | nindent 10 }}
|
|
||||||
command:
|
|
||||||
- sh
|
|
||||||
args:
|
|
||||||
- "-c"
|
|
||||||
- "echo $HOSTNAME | grep -q 'ha-server-0' \
|
|
||||||
&& nc -w 5 -vz {{ regexReplaceAll "^redis:\\/\\/(.*)" .Values.restore.redis.source "${1}" }} \
|
|
||||||
&& test ! -s /data/dump.rdb \
|
|
||||||
&& timeout {{ .Values.restore.timeout }} \
|
|
||||||
redis-cli -u {{ .Values.restore.redis.source }} --rdb /data/dump.rdb_ \
|
|
||||||
&& test -s /data/dump.rdb_ \
|
|
||||||
&& if test -s /data/dump.rdb; \
|
|
||||||
then cp -v /data/dump.rdb /data/dump.rdb_orig; fi \
|
|
||||||
&& mv -v /data/dump.rdb_ /data/dump.rdb || true"
|
|
||||||
{{- if .Values.restore.existingSecret }}
|
|
||||||
envFrom:
|
|
||||||
- secretRef:
|
|
||||||
name: {{ tpl (.Values.existingSecret | default "" ) . }}
|
|
||||||
{{- end }}
|
|
||||||
volumeMounts:
|
|
||||||
- name: data
|
|
||||||
mountPath: /data
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.extraInitContainers }}
|
|
||||||
{{- toYaml .Values.extraInitContainers | nindent 6 }}
|
|
||||||
{{- end }}
|
|
||||||
containers:
|
|
||||||
- name: redis
|
|
||||||
image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
|
|
||||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
|
||||||
command:
|
|
||||||
{{- if .Values.redis.customCommand }}
|
|
||||||
{{ toYaml .Values.redis.customCommand | indent 10 }}
|
|
||||||
{{- else }}
|
|
||||||
- redis-server
|
|
||||||
{{- end }}
|
|
||||||
args:
|
|
||||||
{{- if .Values.redis.customArgs }}
|
|
||||||
{{ toYaml .Values.redis.customArgs | indent 10 }}
|
|
||||||
{{- else }}
|
|
||||||
- /data/conf/redis.conf
|
|
||||||
{{- end }}
|
|
||||||
securityContext: {{- include "compatibility.renderSecurityContext" (dict "secContext" .Values.containerSecurityContext "context" $) | nindent 10 }}
|
|
||||||
{{- if .Values.auth }}
|
|
||||||
env:
|
|
||||||
- name: AUTH
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
{{- if tpl (.Values.existingSecret | default "" ) . }}
|
|
||||||
name: {{ tpl (.Values.existingSecret | default "" ) . }}
|
|
||||||
{{- else }}
|
|
||||||
name: {{ template "redis-ha.fullname" . }}
|
|
||||||
{{- end }}
|
|
||||||
key: {{ .Values.authKey }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.redis.envFrom }}
|
|
||||||
envFrom:
|
|
||||||
{{ toYaml .Values.redis.envFrom | indent 10 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.redis.livenessProbe.enabled }}
|
|
||||||
livenessProbe:
|
|
||||||
initialDelaySeconds: {{ .Values.redis.livenessProbe.initialDelaySeconds }}
|
|
||||||
periodSeconds: {{ .Values.redis.livenessProbe.periodSeconds }}
|
|
||||||
timeoutSeconds: {{ .Values.redis.livenessProbe.timeoutSeconds }}
|
|
||||||
successThreshold: {{ .Values.redis.livenessProbe.successThreshold }}
|
|
||||||
failureThreshold: {{ .Values.redis.livenessProbe.failureThreshold }}
|
|
||||||
exec:
|
|
||||||
command:
|
|
||||||
- sh
|
|
||||||
- -c
|
|
||||||
- /health/redis_liveness.sh
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.redis.readinessProbe.enabled }}
|
|
||||||
readinessProbe:
|
|
||||||
initialDelaySeconds: {{ .Values.redis.readinessProbe.initialDelaySeconds }}
|
|
||||||
periodSeconds: {{ .Values.redis.readinessProbe.periodSeconds }}
|
|
||||||
timeoutSeconds: {{ .Values.redis.readinessProbe.timeoutSeconds }}
|
|
||||||
successThreshold: {{ .Values.redis.readinessProbe.successThreshold }}
|
|
||||||
failureThreshold: {{ .Values.redis.readinessProbe.failureThreshold }}
|
|
||||||
exec:
|
|
||||||
command:
|
|
||||||
- sh
|
|
||||||
- -c
|
|
||||||
- /health/redis_readiness.sh
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.redis.startupProbe.enabled }}
|
|
||||||
startupProbe:
|
|
||||||
initialDelaySeconds: {{ .Values.redis.startupProbe.initialDelaySeconds }}
|
|
||||||
periodSeconds: {{ .Values.redis.startupProbe.periodSeconds }}
|
|
||||||
timeoutSeconds: {{ .Values.redis.startupProbe.timeoutSeconds }}
|
|
||||||
successThreshold: {{ .Values.redis.startupProbe.successThreshold }}
|
|
||||||
failureThreshold: {{ .Values.redis.startupProbe.failureThreshold }}
|
|
||||||
exec:
|
|
||||||
command:
|
|
||||||
- sh
|
|
||||||
- -c
|
|
||||||
- /health/redis_readiness.sh
|
|
||||||
{{- end }}
|
|
||||||
resources:
|
|
||||||
{{ toYaml .Values.redis.resources | indent 10 }}
|
|
||||||
ports:
|
|
||||||
{{- if ne (int .Values.redis.port) 0 }}
|
|
||||||
- name: redis
|
|
||||||
containerPort: {{ .Values.redis.port }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.redis.tlsPort }}
|
|
||||||
- name: redis-tls
|
|
||||||
containerPort: {{ .Values.redis.tlsPort }}
|
|
||||||
{{- end }}
|
|
||||||
volumeMounts:
|
|
||||||
- name: config
|
|
||||||
mountPath: /readonly-config
|
|
||||||
readOnly: true
|
|
||||||
- mountPath: /data
|
|
||||||
name: data
|
|
||||||
{{- if .Values.redis.tlsPort }}
|
|
||||||
- mountPath: /tls-certs
|
|
||||||
name: tls-certs
|
|
||||||
{{- end}}
|
|
||||||
- mountPath: /health
|
|
||||||
name: health
|
|
||||||
{{- if .Values.redis.extraVolumeMounts }}
|
|
||||||
{{- toYaml .Values.redis.extraVolumeMounts | nindent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
lifecycle:
|
|
||||||
{{ toYaml .Values.redis.lifecycle | indent 10 }}
|
|
||||||
- name: sentinel
|
|
||||||
image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
|
|
||||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
|
||||||
command:
|
|
||||||
{{- if .Values.sentinel.customCommand }}
|
|
||||||
{{ toYaml .Values.sentinel.customCommand | indent 10 }}
|
|
||||||
{{- else }}
|
|
||||||
- redis-sentinel
|
|
||||||
{{- end }}
|
|
||||||
args:
|
|
||||||
{{- if .Values.sentinel.customArgs }}
|
|
||||||
{{ toYaml .Values.sentinel.customArgs | indent 10 }}
|
|
||||||
{{- else }}
|
|
||||||
- /data/conf/sentinel.conf
|
|
||||||
{{- end }}
|
|
||||||
securityContext: {{- include "compatibility.renderSecurityContext" (dict "secContext" .Values.containerSecurityContext "context" $) | nindent 10 }}
|
|
||||||
{{- if or .Values.auth .Values.sentinel.auth}}
|
|
||||||
env:
|
|
||||||
{{- if .Values.auth }}
|
|
||||||
- name: AUTH
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
{{- if tpl (.Values.existingSecret | default "" ) . }}
|
|
||||||
name: {{ tpl (.Values.existingSecret | default "" ) . }}
|
|
||||||
{{- else }}
|
|
||||||
name: {{ template "redis-ha.fullname" . }}
|
|
||||||
{{- end }}
|
|
||||||
key: {{ .Values.authKey }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.sentinel.auth }}
|
|
||||||
- name: SENTINELAUTH
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
{{- if tpl (.Values.sentinel.existingSecret | default "" ) . }}
|
|
||||||
name: {{ tpl (.Values.sentinel.existingSecret | default "" ) . }}
|
|
||||||
{{- else }}
|
|
||||||
name: {{ template "redis-ha.fullname" . }}-sentinel
|
|
||||||
{{- end }}
|
|
||||||
key: {{ .Values.sentinel.authKey }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.sentinel.livenessProbe.enabled }}
|
|
||||||
livenessProbe:
|
|
||||||
initialDelaySeconds: {{ .Values.sentinel.livenessProbe.initialDelaySeconds }}
|
|
||||||
periodSeconds: {{ .Values.sentinel.livenessProbe.periodSeconds }}
|
|
||||||
timeoutSeconds: {{ .Values.sentinel.livenessProbe.timeoutSeconds }}
|
|
||||||
successThreshold: {{ .Values.sentinel.livenessProbe.successThreshold }}
|
|
||||||
failureThreshold: {{ .Values.sentinel.livenessProbe.failureThreshold }}
|
|
||||||
exec:
|
|
||||||
command:
|
|
||||||
- sh
|
|
||||||
- -c
|
|
||||||
- /health/sentinel_liveness.sh
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.sentinel.readinessProbe.enabled }}
|
|
||||||
readinessProbe:
|
|
||||||
initialDelaySeconds: {{ .Values.sentinel.readinessProbe.initialDelaySeconds }}
|
|
||||||
periodSeconds: {{ .Values.sentinel.readinessProbe.periodSeconds }}
|
|
||||||
timeoutSeconds: {{ .Values.sentinel.readinessProbe.timeoutSeconds }}
|
|
||||||
successThreshold: {{ .Values.sentinel.readinessProbe.successThreshold }}
|
|
||||||
failureThreshold: {{ .Values.sentinel.readinessProbe.failureThreshold }}
|
|
||||||
exec:
|
|
||||||
command:
|
|
||||||
- sh
|
|
||||||
- -c
|
|
||||||
- /health/sentinel_liveness.sh
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.sentinel.startupProbe.enabled }}
|
|
||||||
startupProbe:
|
|
||||||
initialDelaySeconds: {{ .Values.sentinel.startupProbe.initialDelaySeconds }}
|
|
||||||
periodSeconds: {{ .Values.sentinel.startupProbe.periodSeconds }}
|
|
||||||
timeoutSeconds: {{ .Values.sentinel.startupProbe.timeoutSeconds }}
|
|
||||||
successThreshold: {{ .Values.sentinel.startupProbe.successThreshold }}
|
|
||||||
failureThreshold: {{ .Values.sentinel.startupProbe.failureThreshold }}
|
|
||||||
exec:
|
|
||||||
command:
|
|
||||||
- sh
|
|
||||||
- -c
|
|
||||||
- /health/sentinel_liveness.sh
|
|
||||||
{{- end }}
|
|
||||||
resources:
|
|
||||||
{{ toYaml .Values.sentinel.resources | indent 10 }}
|
|
||||||
ports:
|
|
||||||
{{- if ne (int .Values.sentinel.port) 0 }}
|
|
||||||
- name: sentinel
|
|
||||||
containerPort: {{ .Values.sentinel.port }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.sentinel.tlsPort }}
|
|
||||||
- name: sentinel-tls
|
|
||||||
containerPort: {{ .Values.sentinel.tlsPort }}
|
|
||||||
{{- end }}
|
|
||||||
volumeMounts:
|
|
||||||
- mountPath: /data
|
|
||||||
name: data
|
|
||||||
{{- if .Values.redis.tlsPort }}
|
|
||||||
- mountPath: /tls-certs
|
|
||||||
name: tls-certs
|
|
||||||
{{- end }}
|
|
||||||
- mountPath: /health
|
|
||||||
name: health
|
|
||||||
{{- if .Values.sentinel.extraVolumeMounts }}
|
|
||||||
{{- toYaml .Values.sentinel.extraVolumeMounts | nindent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
lifecycle:
|
|
||||||
{{ toYaml .Values.sentinel.lifecycle | indent 10 }}
|
|
||||||
|
|
||||||
- name: split-brain-fix
|
|
||||||
image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
|
|
||||||
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
|
||||||
livenessProbe: {{ .Values.splitBrainDetection.livenessProbe | toYaml | nindent 10 }}
|
|
||||||
readinessProbe: {{ .Values.splitBrainDetection.readinessProbe | toYaml | nindent 10 }}
|
|
||||||
resources: {{ toYaml .Values.splitBrainDetection.resources | nindent 10 }}
|
|
||||||
command:
|
|
||||||
- sh
|
|
||||||
args:
|
|
||||||
- /readonly-config/fix-split-brain.sh
|
|
||||||
securityContext: {{- include "compatibility.renderSecurityContext" (dict "secContext" .Values.containerSecurityContext "context" $) | nindent 10 }}
|
|
||||||
env:
|
|
||||||
{{- $replicas := int (toString .Values.replicas) -}}
|
|
||||||
{{- range $i := until $replicas }}
|
|
||||||
- name: SENTINEL_ID_{{ $i }}
|
|
||||||
value: {{ printf "%s\n%s\nindex: %d" (include "redis-ha.name" $) ($.Release.Name) $i | sha256sum | trunc 40 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.auth }}
|
|
||||||
- name: AUTH
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
{{- if tpl (.Values.existingSecret | default "" ) . }}
|
|
||||||
name: {{ tpl (.Values.existingSecret | default "" ) . }}
|
|
||||||
{{- else }}
|
|
||||||
name: {{ template "redis-ha.fullname" . }}
|
|
||||||
{{- end }}
|
|
||||||
key: {{ .Values.authKey }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.sentinel.auth }}
|
|
||||||
- name: SENTINELAUTH
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
{{- if tpl (.Values.sentinel.existingSecret | default "" ) . }}
|
|
||||||
name: {{ tpl (.Values.sentinel.existingSecret | default "" ) . }}
|
|
||||||
{{- else }}
|
|
||||||
name: {{ template "redis-ha.fullname" . }}-sentinel
|
|
||||||
{{- end }}
|
|
||||||
key: {{ .Values.sentinel.authKey }}
|
|
||||||
{{- end }}
|
|
||||||
volumeMounts:
|
|
||||||
- name: config
|
|
||||||
mountPath: /readonly-config
|
|
||||||
readOnly: true
|
|
||||||
- mountPath: /data
|
|
||||||
name: data
|
|
||||||
{{- if .Values.redis.tlsPort }}
|
|
||||||
- mountPath: /tls-certs
|
|
||||||
name: tls-certs
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{- if .Values.exporter.enabled }}
|
|
||||||
- name: redis-exporter
|
|
||||||
image: "{{ .Values.exporter.image }}:{{ .Values.exporter.tag }}"
|
|
||||||
imagePullPolicy: {{ .Values.exporter.pullPolicy }}
|
|
||||||
args:
|
|
||||||
{{- range $key, $value := .Values.exporter.extraArgs }}
|
|
||||||
- --{{ $key }}={{ $value }}
|
|
||||||
{{- end }}
|
|
||||||
securityContext: {{- include "compatibility.renderSecurityContext" (dict "secContext" .Values.containerSecurityContext "context" $) | nindent 10 }}
|
|
||||||
env:
|
|
||||||
- name: REDIS_ADDR
|
|
||||||
{{- if .Values.exporter.sslEnabled }}
|
|
||||||
value: rediss://{{ default "localhost" .Values.exporter.address }}:{{ .Values.redis.tlsPort }}
|
|
||||||
{{- else }}
|
|
||||||
value: redis://{{ default "localhost" .Values.exporter.address }}:{{ .Values.redis.port }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.auth }}
|
|
||||||
- name: REDIS_PASSWORD
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
{{- if tpl (.Values.existingSecret | default "" ) . }}
|
|
||||||
name: {{ tpl (.Values.existingSecret | default "" ) . }}
|
|
||||||
{{- else }}
|
|
||||||
name: {{ template "redis-ha.fullname" . }}
|
|
||||||
{{- end }}
|
|
||||||
key: {{ .Values.authKey }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.exporter.script }}
|
|
||||||
- name: REDIS_EXPORTER_SCRIPT
|
|
||||||
value: /script/script.lua
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.exporter.sslEnabled }}
|
|
||||||
- name: REDIS_EXPORTER_TLS_CLIENT_KEY_FILE
|
|
||||||
value: /tls-certs/{{ .Values.tls.keyFile }}
|
|
||||||
- name: REDIS_EXPORTER_TLS_CLIENT_CERT_FILE
|
|
||||||
value: /tls-certs/{{ .Values.tls.certFile }}
|
|
||||||
- name: REDIS_EXPORTER_TLS_CA_CERT_FILE
|
|
||||||
value: /tls-certs/{{ .Values.tls.caCertFile }}
|
|
||||||
{{- end }}
|
|
||||||
livenessProbe:
|
|
||||||
{{ toYaml .Values.exporter.livenessProbe | indent 10 }}
|
|
||||||
readinessProbe:
|
|
||||||
{{ toYaml .Values.exporter.readinessProbe | indent 10 }}
|
|
||||||
resources:
|
|
||||||
{{ toYaml .Values.exporter.resources | indent 10 }}
|
|
||||||
ports:
|
|
||||||
- name: {{ .Values.exporter.portName }}
|
|
||||||
containerPort: {{ .Values.exporter.port }}
|
|
||||||
volumeMounts:
|
|
||||||
{{- if .Values.exporter.script }}
|
|
||||||
- mountPath: /script
|
|
||||||
name: script-mount
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.exporter.sslEnabled }}
|
|
||||||
- mountPath: /tls-certs
|
|
||||||
name: tls-certs
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.extraContainers }}
|
|
||||||
{{- toYaml .Values.extraContainers | nindent 6 }}
|
|
||||||
{{- end -}}
|
|
||||||
{{- with .Values.priorityClassName | default .Values.global.priorityClassName }}
|
|
||||||
priorityClassName: {{ . }}
|
|
||||||
{{- end }}
|
|
||||||
volumes:
|
|
||||||
- name: config
|
|
||||||
configMap:
|
|
||||||
name: {{ template "redis-ha.fullname" . }}-configmap
|
|
||||||
{{- if .Values.sysctlImage.mountHostSys }}
|
|
||||||
- name: host-sys
|
|
||||||
hostPath:
|
|
||||||
path: /sys
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.exporter.script }}
|
|
||||||
- name: script-mount
|
|
||||||
configMap:
|
|
||||||
name: {{ template "redis-ha.fullname" . }}-exporter-script-configmap
|
|
||||||
items:
|
|
||||||
- key: script
|
|
||||||
path: script.lua
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.redis.tlsPort }}
|
|
||||||
- name: tls-certs
|
|
||||||
secret:
|
|
||||||
{{- if tpl (.Values.tls.secretName | default "" ) . }}
|
|
||||||
secretName: {{ tpl (.Values.tls.secretName | default "" ) . }}
|
|
||||||
{{- else }}
|
|
||||||
secretName: {{ template "redis-ha.fullname" . }}-tls-secret
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
- name: health
|
|
||||||
configMap:
|
|
||||||
name: {{ template "redis-ha.fullname" . }}-health-configmap
|
|
||||||
defaultMode: 0755
|
|
||||||
{{- if .Values.extraVolumes }}
|
|
||||||
{{- toYaml .Values.extraVolumes | nindent 6 }}
|
|
||||||
{{- end -}}
|
|
||||||
{{- if .Values.persistentVolume.enabled }}
|
|
||||||
volumeClaimTemplates:
|
|
||||||
- apiVersion: v1
|
|
||||||
kind: PersistentVolumeClaim
|
|
||||||
metadata:
|
|
||||||
name: data
|
|
||||||
annotations:
|
|
||||||
{{- range $key, $value := .Values.persistentVolume.annotations }}
|
|
||||||
{{ $key }}: {{ $value }}
|
|
||||||
{{- end }}
|
|
||||||
labels: {{- toYaml .Values.persistentVolume.labels | nindent 8 }}
|
|
||||||
|
|
||||||
spec:
|
|
||||||
accessModes:
|
|
||||||
{{- range .Values.persistentVolume.accessModes }}
|
|
||||||
- {{ . | quote }}
|
|
||||||
{{- end }}
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
storage: {{ .Values.persistentVolume.size | quote }}
|
|
||||||
{{- if .Values.persistentVolume.storageClass }}
|
|
||||||
{{- if (eq "-" .Values.persistentVolume.storageClass) }}
|
|
||||||
storageClassName: ""
|
|
||||||
{{- else }}
|
|
||||||
storageClassName: "{{ .Values.persistentVolume.storageClass }}"
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
{{- else if .Values.hostPath.path }}
|
|
||||||
- name: data
|
|
||||||
hostPath:
|
|
||||||
path: {{ tpl .Values.hostPath.path .}}
|
|
||||||
{{- else }}
|
|
||||||
- name: data
|
|
||||||
emptyDir:
|
|
||||||
{{ toYaml .Values.emptyDir | indent 10 }}
|
|
||||||
{{- end }}
|
|
||||||
-218
@@ -1,218 +0,0 @@
|
|||||||
{{- if .Values.haproxy.enabled }}
|
|
||||||
kind: Deployment
|
|
||||||
apiVersion: apps/v1
|
|
||||||
metadata:
|
|
||||||
name: {{ template "redis-ha.fullname" . }}-haproxy
|
|
||||||
namespace: {{ .Release.Namespace | quote }}
|
|
||||||
labels:
|
|
||||||
{{ include "labels.standard" . | indent 4 }}
|
|
||||||
component: haproxy
|
|
||||||
{{- range $key, $value := .Values.extraLabels }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.haproxy.deploymentAnnotations }}
|
|
||||||
annotations:
|
|
||||||
{{- range $key, $value := .Values.haproxy.deploymentAnnotations }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
spec:
|
|
||||||
{{- with .Values.haproxy.deploymentStrategy }}
|
|
||||||
strategy:
|
|
||||||
{{- toYaml . | nindent 4 }}
|
|
||||||
{{- end }}
|
|
||||||
revisionHistoryLimit: 1
|
|
||||||
replicas: {{ .Values.haproxy.replicas }}
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: {{ template "redis-ha.name" . }}-haproxy
|
|
||||||
release: {{ .Release.Name }}
|
|
||||||
component: haproxy
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
name: {{ template "redis-ha.fullname" . }}-haproxy
|
|
||||||
labels:
|
|
||||||
app: {{ template "redis-ha.name" . }}-haproxy
|
|
||||||
release: {{ .Release.Name }}
|
|
||||||
component: haproxy
|
|
||||||
{{- range $key, $value := .Values.haproxy.labels }}
|
|
||||||
{{ $key }}: {{ $value | toString }}
|
|
||||||
{{- end }}
|
|
||||||
{{- range $key, $value := .Values.extraLabels }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
annotations:
|
|
||||||
{{- if and (.Values.haproxy.metrics.enabled) (not .Values.haproxy.metrics.serviceMonitor.enabled) }}
|
|
||||||
prometheus.io/port: "{{ .Values.haproxy.metrics.port }}"
|
|
||||||
prometheus.io/scrape: "true"
|
|
||||||
prometheus.io/path: "{{ .Values.haproxy.metrics.scrapePath }}"
|
|
||||||
{{- end }}
|
|
||||||
checksum/config: {{ print (include "config-haproxy.cfg" .) (include "config-haproxy_init.sh" .) | sha256sum }}
|
|
||||||
{{- if .Values.haproxy.podAnnotations }}
|
|
||||||
{{ toYaml .Values.haproxy.podAnnotations | indent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
spec:
|
|
||||||
# Needed when using unmodified rbac-setup.yml
|
|
||||||
{{ if .Values.haproxy.serviceAccount.create }}
|
|
||||||
serviceAccountName: {{ template "redis-ha.serviceAccountName" . }}-haproxy
|
|
||||||
{{- else }}
|
|
||||||
serviceAccountName: {{ .Values.haproxy.serviceAccountName }}
|
|
||||||
{{- end }}
|
|
||||||
securityContext: {{- include "compatibility.renderSecurityContext" (dict "secContext" .Values.haproxy.securityContext "context" $) | nindent 8 }}
|
|
||||||
automountServiceAccountToken: {{ .Values.haproxy.serviceAccount.automountToken }}
|
|
||||||
nodeSelector:
|
|
||||||
{{ toYaml .Values.nodeSelector | indent 8 }}
|
|
||||||
tolerations:
|
|
||||||
{{ toYaml .Values.tolerations | indent 8 }}
|
|
||||||
affinity:
|
|
||||||
{{- if .Values.haproxy.affinity }}
|
|
||||||
{{- with .Values.haproxy.affinity }}
|
|
||||||
{{ tpl . $ | indent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- else }}
|
|
||||||
{{- if .Values.haproxy.additionalAffinities }}
|
|
||||||
{{ toYaml .Values.haproxy.additionalAffinities | indent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
podAntiAffinity:
|
|
||||||
{{- if .Values.haproxy.hardAntiAffinity }}
|
|
||||||
requiredDuringSchedulingIgnoredDuringExecution:
|
|
||||||
- labelSelector:
|
|
||||||
matchLabels:
|
|
||||||
app: {{ template "redis-ha.name" . }}-haproxy
|
|
||||||
release: {{ .Release.Name }}
|
|
||||||
component: haproxy
|
|
||||||
topologyKey: kubernetes.io/hostname
|
|
||||||
{{- else }}
|
|
||||||
preferredDuringSchedulingIgnoredDuringExecution:
|
|
||||||
- weight: 100
|
|
||||||
podAffinityTerm:
|
|
||||||
labelSelector:
|
|
||||||
matchLabels:
|
|
||||||
app: {{ template "redis-ha.name" . }}-haproxy
|
|
||||||
release: {{ .Release.Name }}
|
|
||||||
component: haproxy
|
|
||||||
topologyKey: kubernetes.io/hostname
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.topologySpreadConstraints.enabled }}
|
|
||||||
topologySpreadConstraints:
|
|
||||||
- maxSkew: {{ .Values.topologySpreadConstraints.maxSkew | default 1 }}
|
|
||||||
topologyKey: {{ .Values.topologySpreadConstraints.topologyKey | default "topology.kubernetes.io/zone" }}
|
|
||||||
whenUnsatisfiable: {{ .Values.topologySpreadConstraints.whenUnsatisfiable | default "ScheduleAnyway" }}
|
|
||||||
labelSelector:
|
|
||||||
matchLabels:
|
|
||||||
app: {{ template "redis-ha.name" . }}-haproxy
|
|
||||||
release: {{ .Release.Name }}
|
|
||||||
component: haproxy
|
|
||||||
{{- end }}
|
|
||||||
initContainers:
|
|
||||||
- name: config-init
|
|
||||||
image: {{ .Values.haproxy.image.repository }}:{{ .Values.haproxy.image.tag }}
|
|
||||||
imagePullPolicy: {{ .Values.haproxy.image.pullPolicy }}
|
|
||||||
resources:
|
|
||||||
{{ toYaml .Values.haproxy.init.resources | indent 10 }}
|
|
||||||
command:
|
|
||||||
- sh
|
|
||||||
args:
|
|
||||||
- /readonly/haproxy_init.sh
|
|
||||||
securityContext: {{- include "compatibility.renderSecurityContext" (dict "secContext" .Values.haproxy.containerSecurityContext "context" $) | nindent 10 }}
|
|
||||||
volumeMounts:
|
|
||||||
- name: config-volume
|
|
||||||
mountPath: /readonly
|
|
||||||
readOnly: true
|
|
||||||
- name: data
|
|
||||||
mountPath: /data
|
|
||||||
{{- if .Values.haproxy.imagePullSecrets }}
|
|
||||||
imagePullSecrets: {{ toYaml .Values.haproxy.imagePullSecrets | nindent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
containers:
|
|
||||||
- name: haproxy
|
|
||||||
image: {{ .Values.haproxy.image.repository }}:{{ .Values.haproxy.image.tag }}
|
|
||||||
imagePullPolicy: {{ .Values.haproxy.image.pullPolicy }}
|
|
||||||
securityContext: {{- include "compatibility.renderSecurityContext" (dict "secContext" .Values.haproxy.containerSecurityContext "context" $) | nindent 10 }}
|
|
||||||
{{- if or .Values.auth .Values.sentinel.auth}}
|
|
||||||
env:
|
|
||||||
{{- if .Values.auth }}
|
|
||||||
- name: AUTH
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
{{- if tpl (.Values.existingSecret | default "" ) . }}
|
|
||||||
name: {{ tpl (.Values.existingSecret | default "" ) . }}
|
|
||||||
{{- else }}
|
|
||||||
name: {{ template "redis-ha.fullname" . }}
|
|
||||||
{{- end }}
|
|
||||||
key: {{ .Values.authKey }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.sentinel.auth }}
|
|
||||||
- name: SENTINELAUTH
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
{{- if tpl (.Values.sentinel.existingSecret | default "" ) . }}
|
|
||||||
name: {{ tpl (.Values.sentinel.existingSecret | default "" ) . }}
|
|
||||||
{{- else }}
|
|
||||||
name: {{ template "redis-ha.fullname" . }}-sentinel
|
|
||||||
{{- end }}
|
|
||||||
key: {{ .Values.sentinel.authKey }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
livenessProbe:
|
|
||||||
httpGet:
|
|
||||||
path: /healthz
|
|
||||||
port: probe
|
|
||||||
initialDelaySeconds: 5
|
|
||||||
periodSeconds: 3
|
|
||||||
readinessProbe:
|
|
||||||
httpGet:
|
|
||||||
path: /healthz
|
|
||||||
port: probe
|
|
||||||
initialDelaySeconds: 5
|
|
||||||
periodSeconds: 3
|
|
||||||
ports:
|
|
||||||
- name: probe
|
|
||||||
containerPort: 8888
|
|
||||||
- name: redis
|
|
||||||
containerPort: {{ default "6379" .Values.haproxy.containerPort }}
|
|
||||||
{{- if .Values.haproxy.readOnly.enabled }}
|
|
||||||
- name: readonlyport
|
|
||||||
containerPort: {{ default "6380" .Values.haproxy.readOnly.port }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.haproxy.metrics.enabled }}
|
|
||||||
- name: metrics-port
|
|
||||||
containerPort: {{ default "9101" .Values.haproxy.metrics.port }}
|
|
||||||
{{- end }}
|
|
||||||
{{- range .Values.haproxy.additionalPorts }}
|
|
||||||
- name: {{ .name }}
|
|
||||||
containerPort: {{ .containerPort }}
|
|
||||||
{{- end }}
|
|
||||||
resources:
|
|
||||||
{{ toYaml .Values.haproxy.resources | indent 10 }}
|
|
||||||
volumeMounts:
|
|
||||||
- name: data
|
|
||||||
mountPath: /usr/local/etc/haproxy
|
|
||||||
- name: shared-socket
|
|
||||||
mountPath: /run/haproxy
|
|
||||||
{{- if .Values.haproxy.tls.enabled }}
|
|
||||||
- name: pemfile
|
|
||||||
mountPath: {{ .Values.haproxy.tls.certMountPath }}
|
|
||||||
{{- end }}
|
|
||||||
lifecycle:
|
|
||||||
{{ toYaml .Values.haproxy.lifecycle | indent 10 }}
|
|
||||||
{{- with .Values.haproxy.priorityClassName | default .Values.global.priorityClassName }}
|
|
||||||
priorityClassName: {{ . }}
|
|
||||||
{{- end }}
|
|
||||||
volumes:
|
|
||||||
{{- if .Values.haproxy.tls.enabled }}
|
|
||||||
- name: pemfile
|
|
||||||
secret:
|
|
||||||
secretName: {{ tpl .Values.haproxy.tls.secretName . }}
|
|
||||||
{{- end }}
|
|
||||||
- name: config-volume
|
|
||||||
configMap:
|
|
||||||
name: {{ template "redis-ha.fullname" . }}-configmap
|
|
||||||
- name: shared-socket
|
|
||||||
emptyDir:
|
|
||||||
{{ toYaml .Values.haproxy.emptyDir | indent 10 }}
|
|
||||||
- name: data
|
|
||||||
emptyDir:
|
|
||||||
{{ toYaml .Values.haproxy.emptyDir | indent 10 }}
|
|
||||||
{{- end }}
|
|
||||||
-66
@@ -1,66 +0,0 @@
|
|||||||
{{- if and .Values.haproxy.enabled .Values.haproxy.networkPolicy.enabled }}
|
|
||||||
{{- $root := . }}
|
|
||||||
kind: NetworkPolicy
|
|
||||||
apiVersion: networking.k8s.io/v1
|
|
||||||
metadata:
|
|
||||||
name: {{ template "redis-ha.fullname" . }}-haproxy-network-policy
|
|
||||||
namespace: {{ .Release.Namespace | quote }}
|
|
||||||
{{- if .Values.haproxy.networkPolicy.annotations }}
|
|
||||||
annotations:
|
|
||||||
{{- range $key, $value := .Values.haproxy.networkPolicy.annotations }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
labels:
|
|
||||||
{{- include "labels.standard" . | nindent 4 }}
|
|
||||||
{{- range $key, $value := .Values.haproxy.networkPolicy.labels }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
spec:
|
|
||||||
podSelector:
|
|
||||||
matchLabels:
|
|
||||||
release: {{ .Release.Name }}
|
|
||||||
app: {{ template "redis-ha.name" . }}-haproxy
|
|
||||||
component: haproxy
|
|
||||||
policyTypes:
|
|
||||||
- Ingress
|
|
||||||
- Egress
|
|
||||||
egress:
|
|
||||||
- to:
|
|
||||||
- podSelector:
|
|
||||||
matchLabels:
|
|
||||||
release: {{ .Release.Name }}
|
|
||||||
app: {{ template "redis-ha.name" . }}
|
|
||||||
ports:
|
|
||||||
{{- include "redis-ports" . | nindent 6 }}
|
|
||||||
- to:
|
|
||||||
- namespaceSelector: {}
|
|
||||||
ports:
|
|
||||||
- port: 53
|
|
||||||
protocol: UDP
|
|
||||||
- port: 53
|
|
||||||
protocol: TCP
|
|
||||||
{{- range $rule := .Values.haproxy.networkPolicy.egressRules }}
|
|
||||||
- to:
|
|
||||||
{{- (tpl (toYaml $rule.selectors) $) | nindent 8 }}
|
|
||||||
ports:
|
|
||||||
{{- toYaml $rule.ports | nindent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
ingress:
|
|
||||||
- from:
|
|
||||||
- podSelector:
|
|
||||||
matchLabels:
|
|
||||||
release: {{ .Release.Name }}
|
|
||||||
app: {{ template "redis-ha.name" . }}
|
|
||||||
ports:
|
|
||||||
{{- include "redis-ports" . | nindent 8 }}
|
|
||||||
{{- range $rule := .Values.haproxy.networkPolicy.ingressRules }}
|
|
||||||
- from:
|
|
||||||
{{- (tpl (toYaml $rule.selectors) $) | nindent 8 }}
|
|
||||||
ports:
|
|
||||||
{{- if $rule.ports }}
|
|
||||||
{{- toYaml $rule.ports | nindent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- include "redis-ports" $root | nindent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
-19
@@ -1,19 +0,0 @@
|
|||||||
{{- if .Values.haproxy.podDisruptionBudget -}}
|
|
||||||
apiVersion: {{ template "redis-ha.podDisruptionBudget.apiVersion" . }}
|
|
||||||
kind: PodDisruptionBudget
|
|
||||||
metadata:
|
|
||||||
name: {{ template "redis-ha.fullname" . }}-haproxy-pdb
|
|
||||||
namespace: {{ .Release.Namespace | quote }}
|
|
||||||
labels:
|
|
||||||
{{ include "labels.standard" . | indent 4 }}
|
|
||||||
{{- range $key, $value := .Values.extraLabels }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
spec:
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
release: {{ .Release.Name }}
|
|
||||||
app: {{ template "redis-ha.name" . }}-haproxy
|
|
||||||
component: haproxy
|
|
||||||
{{ toYaml .Values.haproxy.podDisruptionBudget | indent 2 }}
|
|
||||||
{{- end -}}
|
|
||||||
-22
@@ -1,22 +0,0 @@
|
|||||||
{{- if .Values.haproxy.enabled }}
|
|
||||||
{{- if and .Values.haproxy.serviceAccount.create .Values.rbac.create }}
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: Role
|
|
||||||
metadata:
|
|
||||||
name: {{ template "redis-ha.fullname" . }}-haproxy
|
|
||||||
namespace: {{ .Release.Namespace | quote }}
|
|
||||||
labels:
|
|
||||||
{{ include "labels.standard" . | indent 4 }}
|
|
||||||
component: haproxy
|
|
||||||
{{- range $key, $value := .Values.extraLabels }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
rules:
|
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
resources:
|
|
||||||
- endpoints
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
-22
@@ -1,22 +0,0 @@
|
|||||||
{{- if .Values.haproxy.enabled }}
|
|
||||||
{{- if and .Values.haproxy.serviceAccount.create .Values.rbac.create }}
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: RoleBinding
|
|
||||||
metadata:
|
|
||||||
name: {{ template "redis-ha.fullname" . }}-haproxy
|
|
||||||
namespace: {{ .Release.Namespace | quote }}
|
|
||||||
labels:
|
|
||||||
{{ include "labels.standard" . | indent 4 }}
|
|
||||||
component: haproxy
|
|
||||||
{{- range $key, $value := .Values.extraLabels }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
subjects:
|
|
||||||
- kind: ServiceAccount
|
|
||||||
name: {{ template "redis-ha.serviceAccountName" . }}-haproxy
|
|
||||||
roleRef:
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
kind: Role
|
|
||||||
name: {{ template "redis-ha.fullname" . }}-haproxy
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
-75
@@ -1,75 +0,0 @@
|
|||||||
{{- if .Values.haproxy.enabled }}
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: {{ template "redis-ha.fullname" . }}-haproxy
|
|
||||||
namespace: {{ .Release.Namespace | quote }}
|
|
||||||
labels:
|
|
||||||
{{ include "labels.standard" . | indent 4 }}
|
|
||||||
component: haproxy
|
|
||||||
{{- range $key, $value := .Values.extraLabels }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
{{- range $key, $value := .Values.haproxy.service.labels }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
annotations:
|
|
||||||
{{- if .Values.haproxy.service.annotations }}
|
|
||||||
{{ toYaml .Values.haproxy.service.annotations | indent 4 }}
|
|
||||||
{{- end }}
|
|
||||||
spec:
|
|
||||||
type: {{ default "ClusterIP" .Values.haproxy.service.type }}
|
|
||||||
{{- if .Values.haproxy.service.clusterIP }}
|
|
||||||
clusterIP: {{ .Values.haproxy.service.clusterIP }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.haproxy.service.ipFamilyPolicy }}
|
|
||||||
ipFamilyPolicy: {{ .Values.haproxy.service.ipFamilyPolicy }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.haproxy.service.ipFamilies }}
|
|
||||||
ipFamilies: {{ toYaml .Values.haproxy.service.ipFamilies | nindent 2 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if and (eq .Values.haproxy.service.type "LoadBalancer") .Values.haproxy.service.loadBalancerIP }}
|
|
||||||
loadBalancerIP: {{ .Values.haproxy.service.loadBalancerIP }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if and (eq .Values.haproxy.service.type "LoadBalancer") .Values.haproxy.service.externalTrafficPolicy }}
|
|
||||||
externalTrafficPolicy: {{ .Values.haproxy.service.externalTrafficPolicy }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if and (eq .Values.haproxy.service.type "LoadBalancer") .Values.haproxy.service.loadBalancerSourceRanges }}
|
|
||||||
loadBalancerSourceRanges: {{ toYaml .Values.haproxy.service.loadBalancerSourceRanges | nindent 2 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.haproxy.service.externalIPs }}
|
|
||||||
externalIPs:
|
|
||||||
{{- range $key, $value := .Values.haproxy.service.externalIPs }}
|
|
||||||
- {{ $value }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
ports:
|
|
||||||
- name: tcp-haproxy
|
|
||||||
port: {{ .Values.haproxy.servicePort }}
|
|
||||||
protocol: TCP
|
|
||||||
targetPort: redis
|
|
||||||
{{- if and (eq .Values.haproxy.service.type "NodePort") .Values.haproxy.service.nodePort }}
|
|
||||||
nodePort: {{ .Values.haproxy.service.nodePort }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.haproxy.readOnly.enabled }}
|
|
||||||
- name: tcp-haproxyreadonly
|
|
||||||
port: {{ .Values.haproxy.readOnly.port }}
|
|
||||||
protocol: TCP
|
|
||||||
targetPort: {{ .Values.haproxy.readOnly.port }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.haproxy.metrics.enabled }}
|
|
||||||
- name: {{ .Values.haproxy.metrics.portName }}
|
|
||||||
port: {{ .Values.haproxy.metrics.port }}
|
|
||||||
protocol: TCP
|
|
||||||
targetPort: metrics-port
|
|
||||||
{{- end }}
|
|
||||||
{{- range .Values.haproxy.additionalPorts }}
|
|
||||||
- name: {{ .name }}
|
|
||||||
port: {{ .servicePort | default .containerPort }}
|
|
||||||
protocol: TCP
|
|
||||||
targetPort: {{ .name }}
|
|
||||||
{{- end }}
|
|
||||||
selector:
|
|
||||||
release: {{ .Release.Name }}
|
|
||||||
app: {{ template "redis-ha.name" . }}-haproxy
|
|
||||||
{{- end }}
|
|
||||||
-15
@@ -1,15 +0,0 @@
|
|||||||
{{- if and .Values.haproxy.serviceAccount.create .Values.haproxy.enabled }}
|
|
||||||
apiVersion: v1
|
|
||||||
kind: ServiceAccount
|
|
||||||
metadata:
|
|
||||||
name: {{ template "redis-ha.serviceAccountName" . }}-haproxy
|
|
||||||
namespace: {{ .Release.Namespace | quote }}
|
|
||||||
labels:
|
|
||||||
heritage: {{ .Release.Service }}
|
|
||||||
release: {{ .Release.Name }}
|
|
||||||
chart: {{ .Chart.Name }}-{{ .Chart.Version }}
|
|
||||||
app: {{ template "redis-ha.fullname" . }}
|
|
||||||
{{- range $key, $value := .Values.extraLabels }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
-39
@@ -1,39 +0,0 @@
|
|||||||
{{- if and ( or .Values.haproxy.metrics.serviceMonitor.disableAPICheck ( .Capabilities.APIVersions.Has "monitoring.coreos.com/v1" ) ) ( .Values.haproxy.metrics.serviceMonitor.enabled ) ( .Values.haproxy.metrics.enabled ) }}
|
|
||||||
apiVersion: monitoring.coreos.com/v1
|
|
||||||
kind: ServiceMonitor
|
|
||||||
metadata:
|
|
||||||
name: {{ template "redis-ha.fullname" . }}-haproxy
|
|
||||||
namespace: {{ .Values.haproxy.metrics.serviceMonitor.namespace | default .Release.Namespace | quote }}
|
|
||||||
labels:
|
|
||||||
{{ include "labels.standard" . | indent 4 }}
|
|
||||||
{{- range $key, $value := .Values.extraLabels }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
{{- range $key, $value := .Values.haproxy.metrics.serviceMonitor.labels }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
spec:
|
|
||||||
endpoints:
|
|
||||||
- targetPort: {{ .Values.haproxy.metrics.port }}
|
|
||||||
{{- if .Values.haproxy.metrics.serviceMonitor.interval }}
|
|
||||||
interval: {{ .Values.haproxy.metrics.serviceMonitor.interval }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.haproxy.metrics.serviceMonitor.telemetryPath }}
|
|
||||||
path: {{ .Values.haproxy.metrics.serviceMonitor.telemetryPath }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.haproxy.metrics.serviceMonitor.timeout }}
|
|
||||||
scrapeTimeout: {{ .Values.haproxy.metrics.serviceMonitor.timeout }}
|
|
||||||
{{- end }}
|
|
||||||
{{- with .Values.haproxy.metrics.serviceMonitor.endpointAdditionalProperties }}
|
|
||||||
{{- toYaml . | nindent 4 }}
|
|
||||||
{{- end }}
|
|
||||||
jobLabel: {{ template "redis-ha.fullname" . }}-haproxy
|
|
||||||
namespaceSelector:
|
|
||||||
matchNames:
|
|
||||||
- {{ .Release.Namespace | quote }}
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: {{ template "redis-ha.name" . }}
|
|
||||||
release: {{ .Release.Name }}
|
|
||||||
component: haproxy
|
|
||||||
{{- end }}
|
|
||||||
-27
@@ -1,27 +0,0 @@
|
|||||||
{{- if and .Values.redis.tlsPort (not (tpl (.Values.tls.secretName | default "" ) . )) -}}
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Secret
|
|
||||||
metadata:
|
|
||||||
metadata:
|
|
||||||
name: {{ template "redis-ha.fullname" . }}-tls-secret
|
|
||||||
namespace: {{ .Release.Namespace | quote }}
|
|
||||||
labels:
|
|
||||||
{{ include "labels.standard" . | indent 4 }}
|
|
||||||
{{- range $key, $value := .Values.extraLabels }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
type: Opaque
|
|
||||||
data:
|
|
||||||
{{- if .Values.tls.caCertFile }}
|
|
||||||
{{ .Values.tls.caCertFile }}: {{ .Files.Get "certs/ca.crt" | b64enc }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.tls.certFile }}
|
|
||||||
{{ .Values.tls.certFile }}: {{ .Files.Get "certs/redis.crt" | b64enc }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.tls.keyFile }}
|
|
||||||
{{ .Values.tls.keyFile }}: {{ .Files.Get "certs/redis.key" | b64enc }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.tls.dhParamsFile }}
|
|
||||||
{{ .Values.tls.dhParamsFile }}: {{ .Files.Get "certs/redis.dh" | b64enc }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
-15
@@ -1,15 +0,0 @@
|
|||||||
{{- if and .Values.sentinel.auth (not (tpl ( .Values.sentinel.existingSecret | default "" ) . )) -}}
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Secret
|
|
||||||
metadata:
|
|
||||||
name: {{ template "redis-ha.fullname" . }}-sentinel
|
|
||||||
namespace: {{ .Release.Namespace | quote }}
|
|
||||||
labels:
|
|
||||||
{{ include "labels.standard" . | indent 4 }}
|
|
||||||
{{- range $key, $value := .Values.extraLabels }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
type: Opaque
|
|
||||||
data:
|
|
||||||
{{ .Values.sentinel.authKey }}: {{ .Values.sentinel.password | b64enc | quote }}
|
|
||||||
{{- end -}}
|
|
||||||
-32
@@ -1,32 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: Pod
|
|
||||||
metadata:
|
|
||||||
name: {{ template "redis-ha.fullname" . }}-configmap-test
|
|
||||||
namespace: {{ .Release.Namespace | quote }}
|
|
||||||
labels:
|
|
||||||
{{ include "labels.standard" . | indent 4 }}
|
|
||||||
annotations:
|
|
||||||
"helm.sh/hook": test-success
|
|
||||||
spec:
|
|
||||||
nodeSelector: {{ toYaml .Values.nodeSelector | nindent 4 }}
|
|
||||||
tolerations: {{ toYaml .Values.tolerations | nindent 4 }}
|
|
||||||
containers:
|
|
||||||
- name: check-init
|
|
||||||
image: {{ .Values.configmapTest.image.repository }}:{{ .Values.configmapTest.image.tag }}
|
|
||||||
args:
|
|
||||||
- --shell=sh
|
|
||||||
- /readonly-config/init.sh
|
|
||||||
volumeMounts:
|
|
||||||
- name: config
|
|
||||||
mountPath: /readonly-config
|
|
||||||
readOnly: true
|
|
||||||
resources: {{ toYaml .Values.configmapTest.resources | nindent 6 }}
|
|
||||||
securityContext: {{- include "compatibility.renderSecurityContext" (dict "secContext" .Values.containerSecurityContext "context" $) | nindent 6 }}
|
|
||||||
{{- if .Values.imagePullSecrets }}
|
|
||||||
imagePullSecrets: {{ toYaml .Values.imagePullSecrets | nindent 4 }}
|
|
||||||
{{- end }}
|
|
||||||
restartPolicy: Never
|
|
||||||
volumes:
|
|
||||||
- name: config
|
|
||||||
configMap:
|
|
||||||
name: {{ template "redis-ha.fullname" . }}-configmap
|
|
||||||
-32
@@ -1,32 +0,0 @@
|
|||||||
{{- if .Values.haproxy.enabled }}
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Pod
|
|
||||||
metadata:
|
|
||||||
name: {{ template "redis-ha.fullname" . }}-service-test
|
|
||||||
namespace: {{ .Release.Namespace | quote }}
|
|
||||||
labels:
|
|
||||||
{{ include "labels.standard" . | indent 4 }}
|
|
||||||
annotations:
|
|
||||||
{{- if .Values.podAnnotations }}
|
|
||||||
{{ toYaml .Values.podAnnotations | indent 4 }}
|
|
||||||
{{- end }}
|
|
||||||
"helm.sh/hook": test-success
|
|
||||||
spec:
|
|
||||||
nodeSelector:
|
|
||||||
{{ toYaml .Values.nodeSelector | indent 4 }}
|
|
||||||
tolerations:
|
|
||||||
{{ toYaml .Values.tolerations | indent 4 }}
|
|
||||||
containers:
|
|
||||||
- name: "{{ .Release.Name }}-service-test"
|
|
||||||
image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
|
|
||||||
command:
|
|
||||||
- sh
|
|
||||||
- -c
|
|
||||||
- redis-cli -h {{ template "redis-ha.fullname" . }}-haproxy -p {{ .Values.redis.port }} info server
|
|
||||||
resources: {{ toYaml .Values.haproxy.tests.resources | nindent 6 }}
|
|
||||||
securityContext: {{- include "compatibility.renderSecurityContext" (dict "secContext" .Values.containerSecurityContext "context" $) | nindent 6 }}
|
|
||||||
{{- if .Values.imagePullSecrets }}
|
|
||||||
imagePullSecrets: {{ toYaml .Values.imagePullSecrets | nindent 4 }}
|
|
||||||
{{- end }}
|
|
||||||
restartPolicy: Never
|
|
||||||
{{- end }}
|
|
||||||
File diff suppressed because it is too large.
Load diff
@@ -1,37 +0,0 @@
|
|||||||
{{- if .Values.notifications.logLevel }}
|
|
||||||
DEPRECATED option notifications.logLevel - Use `configs.params."notificationscontroller.log.level"`
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.notifications.logFormat }}
|
|
||||||
DEPRECATED option notifications.logFormat - Use `configs.params."notificationscontroller.log.format"`
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.dex.logLevel }}
|
|
||||||
DEPRECATED option dex.logLevel - Use `configs.params."dexserver.log.level"`
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.dex.logFormat }}
|
|
||||||
DEPRECATED option dex.logFormat - Use `configs.params."dexserver.log.format"`
|
|
||||||
{{- end }}
|
|
||||||
In order to access the server UI you have the following options:
|
|
||||||
|
|
||||||
{{ $rootpath := default "" (index .Values "configs" "params" "server.rootpath") -}}
|
|
||||||
1. kubectl port-forward service/{{ include "argo-cd.fullname" . }}-server -n {{ include "argo-cd.namespace" . }} 8080:443
|
|
||||||
{{ if $rootpath }}
|
|
||||||
and then open the browser on http://localhost:8080/{{ $rootpath }} and accept the certificate
|
|
||||||
{{ else }}
|
|
||||||
and then open the browser on http://localhost:8080 and accept the certificate
|
|
||||||
{{ end }}
|
|
||||||
2. enable ingress in the values file `server.ingress.enabled` and either
|
|
||||||
- Add the annotation for ssl passthrough: https://argo-cd.readthedocs.io/en/stable/operator-manual/ingress/#option-1-ssl-passthrough
|
|
||||||
- Set the `configs.params."server.insecure"` in the values file and terminate SSL at your ingress: https://argo-cd.readthedocs.io/en/stable/operator-manual/ingress/#option-2-multiple-ingress-objects-and-hosts
|
|
||||||
|
|
||||||
|
|
||||||
{{ if eq (toString (index .Values.configs.cm "admin.enabled")) "true" -}}
|
|
||||||
After reaching the UI the first time you can login with username: admin and the random password generated during the installation. You can find the password by running:
|
|
||||||
|
|
||||||
kubectl -n {{ include "argo-cd.namespace" . }} get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d
|
|
||||||
|
|
||||||
(You should delete the initial secret afterwards as suggested by the Getting Started Guide: https://argo-cd.readthedocs.io/en/stable/getting_started/#4-login-using-the-cli)
|
|
||||||
{{ else if or (index .Values.configs.cm "dex.config") (index .Values.configs.cm "oidc.config") -}}
|
|
||||||
After reaching the UI the first time you can login using Dex or OIDC.
|
|
||||||
{{ else -}}
|
|
||||||
After reaching the UI the first time you cannot login with username and password since you've disabled it. You should enable admin back or configure Dex via `configs.cm.dex.config` or OIDC via `configs.cm.oidc.config`.
|
|
||||||
{{ end -}}
|
|
||||||
@@ -1,147 +0,0 @@
|
|||||||
{{/* vim: set filetype=mustache: */}}
|
|
||||||
{{/*
|
|
||||||
Expand the name of the chart.
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.name" -}}
|
|
||||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Create a default fully qualified app name.
|
|
||||||
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
|
||||||
If release name contains chart name it will be used as a full name.
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.fullname" -}}
|
|
||||||
{{- if .Values.fullnameOverride -}}
|
|
||||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}}
|
|
||||||
{{- else -}}
|
|
||||||
{{- $name := default .Chart.Name .Values.nameOverride -}}
|
|
||||||
{{- if contains $name .Release.Name -}}
|
|
||||||
{{- .Release.Name | trunc 63 | trimSuffix "-" -}}
|
|
||||||
{{- else -}}
|
|
||||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Create chart name and version as used by the chart label.
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.chart" -}}
|
|
||||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Create Argo CD app version
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.defaultTag" -}}
|
|
||||||
{{- default .Chart.AppVersion .Values.global.image.tag }}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Return valid version label
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.versionLabelValue" -}}
|
|
||||||
{{ regexReplaceAll "[^-A-Za-z0-9_.]" (include "argo-cd.defaultTag" .) "-" | trunc 63 | trimAll "-" | trimAll "_" | trimAll "." | quote }}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Common labels
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.labels" -}}
|
|
||||||
helm.sh/chart: {{ include "argo-cd.chart" .context }}
|
|
||||||
{{ include "argo-cd.selectorLabels" (dict "context" .context "component" .component "name" .name) }}
|
|
||||||
app.kubernetes.io/managed-by: {{ .context.Release.Service }}
|
|
||||||
app.kubernetes.io/part-of: argocd
|
|
||||||
app.kubernetes.io/version: {{ include "argo-cd.versionLabelValue" .context }}
|
|
||||||
{{- with .context.Values.global.additionalLabels }}
|
|
||||||
{{ toYaml . }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Selector labels
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.selectorLabels" -}}
|
|
||||||
{{- if .name -}}
|
|
||||||
app.kubernetes.io/name: {{ include "argo-cd.name" .context }}-{{ .name }}
|
|
||||||
{{ end -}}
|
|
||||||
app.kubernetes.io/instance: {{ .context.Release.Name }}
|
|
||||||
{{- if .component }}
|
|
||||||
app.kubernetes.io/component: {{ .component }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Common affinity definition
|
|
||||||
Pod affinity
|
|
||||||
- Soft prefers different nodes
|
|
||||||
- Hard requires different nodes and prefers different availibility zones
|
|
||||||
Node affinity
|
|
||||||
- Soft prefers given user expressions
|
|
||||||
- Hard requires given user expressions
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.affinity" -}}
|
|
||||||
{{- with .component.affinity -}}
|
|
||||||
{{- toYaml . -}}
|
|
||||||
{{- else -}}
|
|
||||||
{{- $preset := .context.Values.global.affinity -}}
|
|
||||||
{{- if (eq $preset.podAntiAffinity "soft") }}
|
|
||||||
podAntiAffinity:
|
|
||||||
preferredDuringSchedulingIgnoredDuringExecution:
|
|
||||||
- weight: 100
|
|
||||||
podAffinityTerm:
|
|
||||||
labelSelector:
|
|
||||||
matchLabels:
|
|
||||||
app.kubernetes.io/name: {{ include "argo-cd.name" .context }}-{{ .component.name }}
|
|
||||||
topologyKey: kubernetes.io/hostname
|
|
||||||
{{- else if (eq $preset.podAntiAffinity "hard") }}
|
|
||||||
podAntiAffinity:
|
|
||||||
preferredDuringSchedulingIgnoredDuringExecution:
|
|
||||||
- weight: 100
|
|
||||||
podAffinityTerm:
|
|
||||||
labelSelector:
|
|
||||||
matchLabels:
|
|
||||||
app.kubernetes.io/name: {{ include "argo-cd.name" .context }}-{{ .component.name }}
|
|
||||||
topologyKey: topology.kubernetes.io/zone
|
|
||||||
requiredDuringSchedulingIgnoredDuringExecution:
|
|
||||||
- labelSelector:
|
|
||||||
matchLabels:
|
|
||||||
app.kubernetes.io/name: {{ include "argo-cd.name" .context }}-{{ .component.name }}
|
|
||||||
topologyKey: kubernetes.io/hostname
|
|
||||||
{{- end }}
|
|
||||||
{{- with $preset.nodeAffinity.matchExpressions }}
|
|
||||||
{{- if (eq $preset.nodeAffinity.type "soft") }}
|
|
||||||
nodeAffinity:
|
|
||||||
preferredDuringSchedulingIgnoredDuringExecution:
|
|
||||||
- weight: 1
|
|
||||||
preference:
|
|
||||||
matchExpressions:
|
|
||||||
{{- toYaml . | nindent 6 }}
|
|
||||||
{{- else if (eq $preset.nodeAffinity.type "hard") }}
|
|
||||||
nodeAffinity:
|
|
||||||
requiredDuringSchedulingIgnoredDuringExecution:
|
|
||||||
nodeSelectorTerms:
|
|
||||||
- matchExpressions:
|
|
||||||
{{- toYaml . | nindent 6 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Common deployment strategy definition
|
|
||||||
- Recreate don't have additional fields, we need to remove them if added by the mergeOverwrite
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.strategy" -}}
|
|
||||||
{{- $preset := . -}}
|
|
||||||
{{- if (eq (toString $preset.type) "Recreate") }}
|
|
||||||
type: Recreate
|
|
||||||
{{- else if (eq (toString $preset.type) "RollingUpdate") }}
|
|
||||||
type: RollingUpdate
|
|
||||||
{{- with $preset.rollingUpdate }}
|
|
||||||
rollingUpdate:
|
|
||||||
{{- toYaml . | nindent 2 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end -}}
|
|
||||||
@@ -1,347 +0,0 @@
|
|||||||
{{/* vim: set filetype=mustache: */}}
|
|
||||||
{{/*
|
|
||||||
Create controller name and version as used by the chart label.
|
|
||||||
Truncated at 52 chars because StatefulSet label 'controller-revision-hash' is limited
|
|
||||||
to 63 chars and it includes 10 chars of hash and a separating '-'.
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.controller.fullname" -}}
|
|
||||||
{{- printf "%s-%s" (include "argo-cd.fullname" .) .Values.controller.name | trunc 52 | trimSuffix "-" -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Create the name of the controller service account to use
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.controller.serviceAccountName" -}}
|
|
||||||
{{- if .Values.controller.serviceAccount.create -}}
|
|
||||||
{{ default (include "argo-cd.controller.fullname" .) .Values.controller.serviceAccount.name }}
|
|
||||||
{{- else -}}
|
|
||||||
{{ default "default" .Values.controller.serviceAccount.name }}
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Create dex name and version as used by the chart label.
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.dex.fullname" -}}
|
|
||||||
{{- printf "%s-%s" (include "argo-cd.fullname" .) .Values.dex.name | trunc 63 | trimSuffix "-" -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Create Dex server endpoint
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.dex.server" -}}
|
|
||||||
{{- $insecure := index .Values.configs.params "dexserver.disable.tls" | toString -}}
|
|
||||||
{{- $scheme := (eq $insecure "true") | ternary "http" "https" -}}
|
|
||||||
{{- $host := include "argo-cd.dex.fullname" . -}}
|
|
||||||
{{- $port := int .Values.dex.servicePortHttp -}}
|
|
||||||
{{- printf "%s://%s:%d" $scheme $host $port }}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Create the name of the dex service account to use
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.dex.serviceAccountName" -}}
|
|
||||||
{{- if .Values.dex.serviceAccount.create -}}
|
|
||||||
{{ default (include "argo-cd.dex.fullname" .) .Values.dex.serviceAccount.name }}
|
|
||||||
{{- else -}}
|
|
||||||
{{ default "default" .Values.dex.serviceAccount.name }}
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Create redis name and version as used by the chart label.
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.redis.fullname" -}}
|
|
||||||
{{- $redisHa := (index .Values "redis-ha") -}}
|
|
||||||
{{- $redisHaContext := dict "Chart" (dict "Name" "redis-ha") "Release" .Release "Values" $redisHa -}}
|
|
||||||
{{- if $redisHa.enabled -}}
|
|
||||||
{{- if $redisHa.haproxy.enabled -}}
|
|
||||||
{{- printf "%s-haproxy" (include "redis-ha.fullname" $redisHaContext) | trunc 63 | trimSuffix "-" -}}
|
|
||||||
{{- else -}}
|
|
||||||
{{- include "redis-ha.fullname" $redisHaContext | trunc 63 | trimSuffix "-" -}}
|
|
||||||
{{- end -}}
|
|
||||||
{{- else -}}
|
|
||||||
{{- printf "%s-%s" (include "argo-cd.fullname" .) .Values.redis.name | trunc 63 | trimSuffix "-" -}}
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Return Redis server endpoint
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.redis.server" -}}
|
|
||||||
{{- $redisHa := (index .Values "redis-ha") -}}
|
|
||||||
{{- if or (and .Values.redis.enabled (not $redisHa.enabled)) (and $redisHa.enabled $redisHa.haproxy.enabled) }}
|
|
||||||
{{- printf "%s:%s" (include "argo-cd.redis.fullname" .) (toString .Values.redis.servicePort) }}
|
|
||||||
{{- else if and .Values.externalRedis.host .Values.externalRedis.port }}
|
|
||||||
{{- printf "%s:%s" .Values.externalRedis.host (toString .Values.externalRedis.port) }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Create the name of the redis service account to use
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.redis.serviceAccountName" -}}
|
|
||||||
{{- if .Values.redis.serviceAccount.create -}}
|
|
||||||
{{ default (include "argo-cd.redis.fullname" .) .Values.redis.serviceAccount.name }}
|
|
||||||
{{- else -}}
|
|
||||||
{{ default "default" .Values.redis.serviceAccount.name }}
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Create Redis secret-init name
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.redisSecretInit.fullname" -}}
|
|
||||||
{{- printf "%s-%s" (include "argo-cd.fullname" .) .Values.redisSecretInit.name | trunc 63 | trimSuffix "-" -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Create the name of the Redis secret-init service account to use
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.redisSecretInit.serviceAccountName" -}}
|
|
||||||
{{- if .Values.redisSecretInit.serviceAccount.create -}}
|
|
||||||
{{ default (include "argo-cd.redisSecretInit.fullname" .) .Values.redisSecretInit.serviceAccount.name }}
|
|
||||||
{{- else -}}
|
|
||||||
{{ default "default" .Values.redisSecretInit.serviceAccount.name }}
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Create argocd server name and version as used by the chart label.
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.server.fullname" -}}
|
|
||||||
{{- printf "%s-%s" (include "argo-cd.fullname" .) .Values.server.name | trunc 63 | trimSuffix "-" -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Create the name of the Argo CD server service account to use
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.server.serviceAccountName" -}}
|
|
||||||
{{- if .Values.server.serviceAccount.create -}}
|
|
||||||
{{ default (include "argo-cd.server.fullname" .) .Values.server.serviceAccount.name }}
|
|
||||||
{{- else -}}
|
|
||||||
{{ default "default" .Values.server.serviceAccount.name }}
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Create argocd repo-server name and version as used by the chart label.
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.repoServer.fullname" -}}
|
|
||||||
{{- printf "%s-%s" (include "argo-cd.fullname" .) .Values.repoServer.name | trunc 63 | trimSuffix "-" -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Create the name of the repo-server service account to use
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.repoServer.serviceAccountName" -}}
|
|
||||||
{{- if .Values.repoServer.serviceAccount.create -}}
|
|
||||||
{{ default (include "argo-cd.repoServer.fullname" .) .Values.repoServer.serviceAccount.name }}
|
|
||||||
{{- else -}}
|
|
||||||
{{ default "default" .Values.repoServer.serviceAccount.name }}
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Create argocd application set name and version as used by the chart label.
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.applicationSet.fullname" -}}
|
|
||||||
{{- printf "%s-%s" (include "argo-cd.fullname" .) .Values.applicationSet.name | trunc 63 | trimSuffix "-" -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Create the name of the application set service account to use
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.applicationSet.serviceAccountName" -}}
|
|
||||||
{{- if .Values.applicationSet.serviceAccount.create -}}
|
|
||||||
{{ default (include "argo-cd.applicationSet.fullname" .) .Values.applicationSet.serviceAccount.name }}
|
|
||||||
{{- else -}}
|
|
||||||
{{ default "default" .Values.applicationSet.serviceAccount.name }}
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Create argocd notifications name and version as used by the chart label.
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.notifications.fullname" -}}
|
|
||||||
{{- printf "%s-%s" (include "argo-cd.fullname" .) .Values.notifications.name | trunc 63 | trimSuffix "-" -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Create the name of the notifications service account to use
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.notifications.serviceAccountName" -}}
|
|
||||||
{{- if .Values.notifications.serviceAccount.create -}}
|
|
||||||
{{ default (include "argo-cd.notifications.fullname" .) .Values.notifications.serviceAccount.name }}
|
|
||||||
{{- else -}}
|
|
||||||
{{ default "default" .Values.notifications.serviceAccount.name }}
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Create argocd commit-server name and version as used by the chart label.
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.commitServer.fullname" -}}
|
|
||||||
{{- printf "%s-%s" (include "argo-cd.fullname" .) .Values.commitServer.name | trunc 63 | trimSuffix "-" -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Create the name of the commit-server service account to use
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.commitServer.serviceAccountName" -}}
|
|
||||||
{{- if .Values.commitServer.serviceAccount.create -}}
|
|
||||||
{{ default (include "argo-cd.commitServer.fullname" .) .Values.commitServer.serviceAccount.name }}
|
|
||||||
{{- else -}}
|
|
||||||
{{ default "default" .Values.commitServer.serviceAccount.name }}
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Argo Configuration Preset Values (Influenced by Values configuration)
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.config.cm.presets" -}}
|
|
||||||
{{- $presets := dict -}}
|
|
||||||
{{- $_ := set $presets "url" (printf "https://%s" .Values.global.domain) -}}
|
|
||||||
{{- if eq (toString (index .Values.configs.cm "statusbadge.enabled")) "true" -}}
|
|
||||||
{{- $_ := set $presets "statusbadge.url" (printf "https://%s/" .Values.global.domain) -}}
|
|
||||||
{{- end -}}
|
|
||||||
{{- if .Values.configs.styles -}}
|
|
||||||
{{- $_ := set $presets "ui.cssurl" "./custom/custom.styles.css" -}}
|
|
||||||
{{- end -}}
|
|
||||||
{{- toYaml $presets }}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Merge Argo Configuration with Preset Configuration
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.config.cm" -}}
|
|
||||||
{{- $config := omit .Values.configs.cm "create" "annotations" "resourceExclusionsAdditional" -}}
|
|
||||||
{{- $preset := include "argo-cd.config.cm.presets" . | fromYaml | default dict -}}
|
|
||||||
{{- $merged := mergeOverwrite $preset $config -}}
|
|
||||||
{{- if .Values.configs.cm.resourceExclusionsAdditional }}
|
|
||||||
{{- $existing := get $merged "resource.exclusions" | default "" | trimSuffix "\n" }}
|
|
||||||
{{- $additional := .Values.configs.cm.resourceExclusionsAdditional | toYaml }}
|
|
||||||
{{- $_ := set $merged "resource.exclusions" (list $existing $additional | compact | join "\n") -}}
|
|
||||||
{{- end }}
|
|
||||||
{{- range $key, $value := $merged }}
|
|
||||||
{{- $fmted := $value | toString }}
|
|
||||||
{{- if not (eq $fmted "") }}
|
|
||||||
{{ $key }}: {{ $fmted | toYaml }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Argo Params Default Configuration Presets
|
|
||||||
NOTE: Configuration keys must be stored as dict because YAML treats dot as separator
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.config.params.presets" -}}
|
|
||||||
{{- $presets := dict -}}
|
|
||||||
{{- $_ := set $presets "repo.server" (printf "%s:%s" (include "argo-cd.repoServer.fullname" .) (.Values.repoServer.service.port | toString)) -}}
|
|
||||||
{{- $_ := set $presets "server.repo.server.strict.tls" (.Values.repoServer.certificateSecret.enabled | toString ) -}}
|
|
||||||
{{- $_ := set $presets "redis.server" (include "argo-cd.redis.server" .) -}}
|
|
||||||
{{- $_ := set $presets "applicationsetcontroller.enable.leader.election" (gt ((.Values.applicationSet.replicas | default .Values.applicationSet.replicaCount) | int64) 1) -}}
|
|
||||||
{{- if .Values.dex.enabled -}}
|
|
||||||
{{- $_ := set $presets "server.dex.server" (include "argo-cd.dex.server" .) -}}
|
|
||||||
{{- $_ := set $presets "server.dex.server.strict.tls" .Values.dex.certificateSecret.enabled -}}
|
|
||||||
{{- end -}}
|
|
||||||
{{- if .Values.commitServer.enabled -}}
|
|
||||||
{{- $_ := set $presets "commit.server" (printf "%s:%s" (include "argo-cd.commitServer.fullname" .) (.Values.commitServer.service.port | toString)) -}}
|
|
||||||
{{- end -}}
|
|
||||||
{{- range $component := tuple "applicationsetcontroller" "controller" "server" "reposerver" "notificationscontroller" "dexserver" "commitserver" -}}
|
|
||||||
{{- $_ := set $presets (printf "%s.log.format" $component) $.Values.global.logging.format -}}
|
|
||||||
{{- $_ := set $presets (printf "%s.log.level" $component) $.Values.global.logging.level -}}
|
|
||||||
{{- end -}}
|
|
||||||
{{- toYaml $presets }}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Merge Argo Params Configuration with Preset Configuration
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.config.params" -}}
|
|
||||||
{{- $config := omit .Values.configs.params "create" "annotations" }}
|
|
||||||
{{- $preset := include "argo-cd.config.params.presets" . | fromYaml | default dict -}}
|
|
||||||
{{- range $key, $value := mergeOverwrite $preset $config }}
|
|
||||||
{{ $key }}: {{ toString $value | toYaml }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Expand the namespace of the release.
|
|
||||||
Allows overriding it for multi-namespace deployments in combined charts.
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.namespace" -}}
|
|
||||||
{{- default .Release.Namespace .Values.namespaceOverride | trunc 63 | trimSuffix "-" -}}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Dual stack definition
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.dualStack" -}}
|
|
||||||
{{- with .Values.global.dualStack.ipFamilyPolicy }}
|
|
||||||
ipFamilyPolicy: {{ . }}
|
|
||||||
{{- end }}
|
|
||||||
{{- with .Values.global.dualStack.ipFamilies }}
|
|
||||||
ipFamilies: {{ toYaml . | nindent 4 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
secretKeyRef of env variable REDIS_USERNAME
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.redisUsernameSecretRef" -}}
|
|
||||||
{{- if .Values.externalRedis.host -}}
|
|
||||||
name: {{ default "argocd-redis" .Values.externalRedis.existingSecret }}
|
|
||||||
key: redis-username
|
|
||||||
optional: {{ if .Values.externalRedis.username }}false{{ else }}true{{ end }}
|
|
||||||
|
|
||||||
{{- else -}}
|
|
||||||
name: "argocd-redis"
|
|
||||||
key: redis-username
|
|
||||||
optional: true
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
secretKeyRef of env variable REDIS_PASSWORD
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.redisPasswordSecretRef" -}}
|
|
||||||
{{- if .Values.externalRedis.host -}}
|
|
||||||
{{- /* External Redis use case */ -}}
|
|
||||||
{{- /* Secret is required when specifying existingSecret or a password, otherwise it is optional */ -}}
|
|
||||||
name: {{ default "argocd-redis" .Values.externalRedis.existingSecret }}
|
|
||||||
key: redis-password
|
|
||||||
optional: {{ if or .Values.externalRedis.existingSecret .Values.externalRedis.password }}false{{ else }}true{{ end }}
|
|
||||||
|
|
||||||
{{- else if and .Values.redisSecretInit.enabled -}}
|
|
||||||
{{- /* Default case where Secret is generated by the Job with Helm pre-install hooks */ -}}
|
|
||||||
name: "argocd-redis" # hard-coded in Job command and embedded Redis deployments (standalone and redis-ha)
|
|
||||||
key: auth
|
|
||||||
optional: false # Secret is not optional in this case !
|
|
||||||
|
|
||||||
{{- else -}}
|
|
||||||
{{- /* All other use cases (e.g. disabled pre-install Job) */ -}}
|
|
||||||
name: "argocd-redis"
|
|
||||||
key: auth
|
|
||||||
optional: true
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Return the target Kubernetes version
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.kubeVersion" -}}
|
|
||||||
{{- default .Capabilities.KubeVersion.Version .Values.kubeVersionOverride }}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
||||||
{{/*
|
|
||||||
Return the appropriate apiVersion for monitoring CRDs
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.apiVersions.monitoring" -}}
|
|
||||||
{{- if .Values.apiVersionOverrides.monitoring -}}
|
|
||||||
{{- print .Values.apiVersionOverrides.monitoring -}}
|
|
||||||
{{- else -}}
|
|
||||||
{{- print "monitoring.coreos.com/v1" -}}
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
{{/* vim: set filetype=mustache: */}}
|
|
||||||
{{/*
|
|
||||||
Return the target Kubernetes version
|
|
||||||
*/}}
|
|
||||||
{{- define "argo-cd.kubeVersion" -}}
|
|
||||||
{{- default .Capabilities.KubeVersion.Version .Values.kubeVersionOverride }}
|
|
||||||
{{- end }}
|
|
||||||
@@ -1,70 +0,0 @@
|
|||||||
{{- if .Values.createAggregateRoles }}
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: ClusterRole
|
|
||||||
metadata:
|
|
||||||
name: {{ include "argo-cd.fullname" . }}-aggregate-to-view
|
|
||||||
labels:
|
|
||||||
rbac.authorization.k8s.io/aggregate-to-view: "true"
|
|
||||||
{{- include "argo-cd.labels" (dict "context" .) | nindent 4 }}
|
|
||||||
rules:
|
|
||||||
- apiGroups:
|
|
||||||
- argoproj.io
|
|
||||||
resources:
|
|
||||||
- applications
|
|
||||||
- applicationsets
|
|
||||||
- appprojects
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
|
|
||||||
---
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: ClusterRole
|
|
||||||
metadata:
|
|
||||||
name: {{ include "argo-cd.fullname" . }}-aggregate-to-edit
|
|
||||||
labels:
|
|
||||||
rbac.authorization.k8s.io/aggregate-to-edit: "true"
|
|
||||||
{{- include "argo-cd.labels" (dict "context" .) | nindent 4 }}
|
|
||||||
rules:
|
|
||||||
- apiGroups:
|
|
||||||
- argoproj.io
|
|
||||||
resources:
|
|
||||||
- applications
|
|
||||||
- applicationsets
|
|
||||||
- appprojects
|
|
||||||
verbs:
|
|
||||||
- create
|
|
||||||
- delete
|
|
||||||
- deletecollection
|
|
||||||
- get
|
|
||||||
- list
|
|
||||||
- patch
|
|
||||||
- update
|
|
||||||
- watch
|
|
||||||
|
|
||||||
---
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: ClusterRole
|
|
||||||
metadata:
|
|
||||||
name: {{ include "argo-cd.fullname" . }}-aggregate-to-admin
|
|
||||||
labels:
|
|
||||||
rbac.authorization.k8s.io/aggregate-to-admin: "true"
|
|
||||||
{{- include "argo-cd.labels" (dict "context" .) | nindent 4 }}
|
|
||||||
rules:
|
|
||||||
- apiGroups:
|
|
||||||
- argoproj.io
|
|
||||||
resources:
|
|
||||||
- applications
|
|
||||||
- applicationsets
|
|
||||||
- appprojects
|
|
||||||
verbs:
|
|
||||||
- create
|
|
||||||
- delete
|
|
||||||
- deletecollection
|
|
||||||
- get
|
|
||||||
- list
|
|
||||||
- patch
|
|
||||||
- update
|
|
||||||
- watch
|
|
||||||
{{- end }}
|
|
||||||
-23
@@ -1,23 +0,0 @@
|
|||||||
{{- if .Values.createClusterRoles }}
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: ClusterRole
|
|
||||||
metadata:
|
|
||||||
name: {{ include "argo-cd.controller.fullname" . }}
|
|
||||||
labels:
|
|
||||||
{{- include "argo-cd.labels" (dict "context" . "component" .Values.controller.name "name" .Values.controller.name) | nindent 4 }}
|
|
||||||
rules:
|
|
||||||
{{- if .Values.controller.clusterRoleRules.enabled }}
|
|
||||||
{{- toYaml .Values.controller.clusterRoleRules.rules | nindent 2 }}
|
|
||||||
{{- else }}
|
|
||||||
- apiGroups:
|
|
||||||
- '*'
|
|
||||||
resources:
|
|
||||||
- '*'
|
|
||||||
verbs:
|
|
||||||
- '*'
|
|
||||||
- nonResourceURLs:
|
|
||||||
- '*'
|
|
||||||
verbs:
|
|
||||||
- '*'
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
-16
@@ -1,16 +0,0 @@
|
|||||||
{{- if .Values.createClusterRoles }}
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: ClusterRoleBinding
|
|
||||||
metadata:
|
|
||||||
name: {{ include "argo-cd.controller.fullname" . }}
|
|
||||||
labels:
|
|
||||||
{{- include "argo-cd.labels" (dict "context" . "component" .Values.controller.name "name" .Values.controller.name) | nindent 4 }}
|
|
||||||
roleRef:
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
kind: ClusterRole
|
|
||||||
name: {{ include "argo-cd.controller.fullname" . }}
|
|
||||||
subjects:
|
|
||||||
- kind: ServiceAccount
|
|
||||||
name: {{ include "argo-cd.controller.serviceAccountName" . }}
|
|
||||||
namespace: {{ include "argo-cd.namespace" . }}
|
|
||||||
{{- end }}
|
|
||||||
-459
@@ -1,459 +0,0 @@
|
|||||||
{{- if .Values.controller.dynamicClusterDistribution }}
|
|
||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
{{- with (mergeOverwrite (deepCopy .Values.global.deploymentAnnotations) .Values.controller.deploymentAnnotations) }}
|
|
||||||
annotations:
|
|
||||||
{{- range $key, $value := . }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
name: {{ template "argo-cd.controller.fullname" . }}
|
|
||||||
namespace: {{ include "argo-cd.namespace" . }}
|
|
||||||
labels:
|
|
||||||
{{- include "argo-cd.labels" (dict "context" . "component" .Values.controller.name "name" .Values.controller.name) | nindent 4 }}
|
|
||||||
{{- with (mergeOverwrite (deepCopy .Values.global.deploymentLabels) .Values.controller.deploymentLabels) }}
|
|
||||||
{{- toYaml . | nindent 4 }}
|
|
||||||
{{- end }}
|
|
||||||
spec:
|
|
||||||
replicas: {{ .Values.controller.replicas }}
|
|
||||||
revisionHistoryLimit: {{ .Values.controller.revisionHistoryLimit | default .Values.global.revisionHistoryLimit }}
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
{{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.controller.name) | nindent 6 }}
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
annotations:
|
|
||||||
checksum/cmd-params: {{ include (print $.Template.BasePath "/argocd-configs/argocd-cmd-params-cm.yaml") . | sha256sum }}
|
|
||||||
{{- if .Values.configs.cm.create }}
|
|
||||||
checksum/cm: {{ include (print $.Template.BasePath "/argocd-configs/argocd-cm.yaml") . | sha256sum }}
|
|
||||||
{{- end }}
|
|
||||||
{{- with (mergeOverwrite (deepCopy .Values.global.podAnnotations) .Values.controller.podAnnotations) }}
|
|
||||||
{{- range $key, $value := . }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
labels:
|
|
||||||
{{- include "argo-cd.labels" (dict "context" . "component" .Values.controller.name "name" .Values.controller.name) | nindent 8 }}
|
|
||||||
{{- with (mergeOverwrite (deepCopy .Values.global.podLabels) .Values.controller.podLabels) }}
|
|
||||||
{{- toYaml . | nindent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
spec:
|
|
||||||
{{- with .Values.controller.runtimeClassName | default .Values.global.runtimeClassName }}
|
|
||||||
runtimeClassName: {{ . }}
|
|
||||||
{{- end }}
|
|
||||||
{{- with .Values.controller.imagePullSecrets | default .Values.global.imagePullSecrets }}
|
|
||||||
imagePullSecrets:
|
|
||||||
{{- toYaml . | nindent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- with .Values.global.hostAliases }}
|
|
||||||
hostAliases:
|
|
||||||
{{- toYaml . | nindent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- with .Values.global.securityContext }}
|
|
||||||
securityContext:
|
|
||||||
{{- toYaml . | nindent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- with .Values.controller.priorityClassName | default .Values.global.priorityClassName }}
|
|
||||||
priorityClassName: {{ . }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.controller.terminationGracePeriodSeconds }}
|
|
||||||
terminationGracePeriodSeconds: {{ .Values.controller.terminationGracePeriodSeconds }}
|
|
||||||
{{- end }}
|
|
||||||
serviceAccountName: {{ include "argo-cd.controller.serviceAccountName" . }}
|
|
||||||
automountServiceAccountToken: {{ .Values.controller.automountServiceAccountToken }}
|
|
||||||
containers:
|
|
||||||
- args:
|
|
||||||
- /usr/local/bin/argocd-application-controller
|
|
||||||
- --metrics-port={{ .Values.controller.containerPorts.metrics }}
|
|
||||||
{{- if .Values.controller.metrics.applicationLabels.enabled }}
|
|
||||||
{{- range .Values.controller.metrics.applicationLabels.labels }}
|
|
||||||
- --metrics-application-labels
|
|
||||||
- {{ . }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
{{- with .Values.controller.extraArgs }}
|
|
||||||
{{- toYaml . | nindent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
image: {{ default .Values.global.image.repository .Values.controller.image.repository }}:{{ default (include "argo-cd.defaultTag" .) .Values.controller.image.tag }}
|
|
||||||
imagePullPolicy: {{ default .Values.global.image.imagePullPolicy .Values.controller.image.imagePullPolicy }}
|
|
||||||
name: {{ .Values.controller.name }}
|
|
||||||
env:
|
|
||||||
{{- with (concat .Values.global.env .Values.controller.env) }}
|
|
||||||
{{- tpl (toYaml .) $ | nindent 10 }}
|
|
||||||
{{- end }}
|
|
||||||
- name: ARGOCD_ENABLE_DYNAMIC_CLUSTER_DISTRIBUTION
|
|
||||||
value: "true"
|
|
||||||
- name: ARGOCD_CONTROLLER_HEARTBEAT_TIME
|
|
||||||
value: {{ .Values.controller.heartbeatTime | quote }}
|
|
||||||
- name: ARGOCD_APPLICATION_CONTROLLER_NAME
|
|
||||||
value: {{ template "argo-cd.controller.fullname" . }}
|
|
||||||
- name: ARGOCD_RECONCILIATION_TIMEOUT
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cm
|
|
||||||
key: timeout.reconciliation
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_HARD_RECONCILIATION_TIMEOUT
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cm
|
|
||||||
key: timeout.hard.reconciliation
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_RECONCILIATION_JITTER
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
key: timeout.reconciliation.jitter
|
|
||||||
name: argocd-cm
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_REPO_ERROR_GRACE_PERIOD_SECONDS
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: controller.repo.error.grace.period.seconds
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: repo.server
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_TIMEOUT_SECONDS
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: controller.repo.server.timeout.seconds
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_APPLICATION_CONTROLLER_STATUS_PROCESSORS
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: controller.status.processors
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_APPLICATION_CONTROLLER_OPERATION_PROCESSORS
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: controller.operation.processors
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_APPLICATION_CONTROLLER_LOGFORMAT
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: controller.log.format
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_APPLICATION_CONTROLLER_LOGLEVEL
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: controller.log.level
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_LOG_FORMAT_TIMESTAMP
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: log.format.timestamp
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_APPLICATION_CONTROLLER_METRICS_CACHE_EXPIRATION
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: controller.metrics.cache.expiration
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_TIMEOUT_SECONDS
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: controller.self.heal.timeout.seconds
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_TIMEOUT_SECONDS
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: controller.self.heal.backoff.timeout.seconds
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_FACTOR
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: controller.self.heal.backoff.factor
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_CAP_SECONDS
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: controller.self.heal.backoff.cap.seconds
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_APPLICATION_CONTROLLER_SELF_HEAL_BACKOFF_COOLDOWN_SECONDS
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: controller.self.heal.backoff.cooldown.seconds
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_SYNC_WAVE_DELAY
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: controller.sync.wave.delay.seconds
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_APPLICATION_CONTROLLER_SYNC_TIMEOUT
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: controller.sync.timeout.seconds
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_PLAINTEXT
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: controller.repo.server.plaintext
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_APPLICATION_CONTROLLER_REPO_SERVER_STRICT_TLS
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: controller.repo.server.strict.tls
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_APPLICATION_CONTROLLER_PERSIST_RESOURCE_HEALTH
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: controller.resource.health.persist
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_APP_STATE_CACHE_EXPIRATION
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: controller.app.state.cache.expiration
|
|
||||||
optional: true
|
|
||||||
- name: REDIS_SERVER
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: redis.server
|
|
||||||
optional: true
|
|
||||||
- name: REDIS_COMPRESSION
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: redis.compression
|
|
||||||
optional: true
|
|
||||||
- name: REDISDB
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: redis.db
|
|
||||||
optional: true
|
|
||||||
- name: REDIS_USERNAME
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
{{- include "argo-cd.redisUsernameSecretRef" . | nindent 16 }}
|
|
||||||
- name: REDIS_PASSWORD
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
{{- include "argo-cd.redisPasswordSecretRef" . | nindent 16 }}
|
|
||||||
- name: REDIS_SENTINEL_USERNAME
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: {{ default (include "argo-cd.redis.fullname" .) .Values.externalRedis.existingSecret }}
|
|
||||||
key: redis-sentinel-username
|
|
||||||
optional: true
|
|
||||||
- name: REDIS_SENTINEL_PASSWORD
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: {{ default (include "argo-cd.redis.fullname" .) .Values.externalRedis.existingSecret }}
|
|
||||||
key: redis-sentinel-password
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_DEFAULT_CACHE_EXPIRATION
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: controller.default.cache.expiration
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_APPLICATION_CONTROLLER_OTLP_ADDRESS
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: otlp.address
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_APPLICATION_CONTROLLER_OTLP_INSECURE
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: otlp.insecure
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_APPLICATION_CONTROLLER_OTLP_HEADERS
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: otlp.headers
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_APPLICATION_NAMESPACES
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: application.namespaces
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_CONTROLLER_SHARDING_ALGORITHM
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: controller.sharding.algorithm
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_APPLICATION_CONTROLLER_KUBECTL_PARALLELISM_LIMIT
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: controller.kubectl.parallelism.limit
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_K8SCLIENT_RETRY_MAX
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: controller.k8sclient.retry.max
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_K8SCLIENT_RETRY_BASE_BACKOFF
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: controller.k8sclient.retry.base.backoff
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_APPLICATION_CONTROLLER_SERVER_SIDE_DIFF
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: controller.diff.server.side
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_IGNORE_NORMALIZER_JQ_TIMEOUT
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: controller.ignore.normalizer.jq.timeout
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_HYDRATOR_ENABLED
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: hydrator.enabled
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_CLUSTER_CACHE_BATCH_EVENTS_PROCESSING
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: controller.cluster.cache.batch.events.processing
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_CLUSTER_CACHE_EVENTS_PROCESSING_INTERVAL
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: controller.cluster.cache.events.processing.interval
|
|
||||||
optional: true
|
|
||||||
- name: ARGOCD_APPLICATION_CONTROLLER_COMMIT_SERVER
|
|
||||||
valueFrom:
|
|
||||||
configMapKeyRef:
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
key: commit.server
|
|
||||||
optional: true
|
|
||||||
{{- with .Values.controller.envFrom }}
|
|
||||||
envFrom:
|
|
||||||
{{- toYaml . | nindent 10 }}
|
|
||||||
{{- end }}
|
|
||||||
ports:
|
|
||||||
- name: metrics
|
|
||||||
containerPort: {{ .Values.controller.containerPorts.metrics }}
|
|
||||||
protocol: TCP
|
|
||||||
readinessProbe:
|
|
||||||
httpGet:
|
|
||||||
path: /healthz
|
|
||||||
port: metrics
|
|
||||||
initialDelaySeconds: {{ .Values.controller.readinessProbe.initialDelaySeconds }}
|
|
||||||
periodSeconds: {{ .Values.controller.readinessProbe.periodSeconds }}
|
|
||||||
timeoutSeconds: {{ .Values.controller.readinessProbe.timeoutSeconds }}
|
|
||||||
successThreshold: {{ .Values.controller.readinessProbe.successThreshold }}
|
|
||||||
failureThreshold: {{ .Values.controller.readinessProbe.failureThreshold }}
|
|
||||||
resources:
|
|
||||||
{{- toYaml .Values.controller.resources | nindent 10 }}
|
|
||||||
{{- with .Values.controller.containerSecurityContext }}
|
|
||||||
securityContext:
|
|
||||||
{{- toYaml . | nindent 10 }}
|
|
||||||
{{- end }}
|
|
||||||
workingDir: /home/argocd
|
|
||||||
volumeMounts:
|
|
||||||
{{- with (concat .Values.global.extraVolumeMounts .Values.controller.volumeMounts) }}
|
|
||||||
{{- toYaml . | nindent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
- mountPath: /app/config/controller/tls
|
|
||||||
name: argocd-repo-server-tls
|
|
||||||
- mountPath: /home/argocd
|
|
||||||
name: argocd-home
|
|
||||||
- name: argocd-cmd-params-cm
|
|
||||||
mountPath: /home/argocd/params
|
|
||||||
{{- with .Values.controller.extraContainers }}
|
|
||||||
{{- tpl (toYaml .) $ | nindent 6 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- with .Values.controller.initContainers }}
|
|
||||||
initContainers:
|
|
||||||
{{- tpl (toYaml .) $ | nindent 6 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- with include "argo-cd.affinity" (dict "context" . "component" .Values.controller) }}
|
|
||||||
affinity:
|
|
||||||
{{- trim . | nindent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- with .Values.controller.nodeSelector | default .Values.global.nodeSelector }}
|
|
||||||
nodeSelector:
|
|
||||||
{{- toYaml . | nindent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- with .Values.controller.tolerations | default .Values.global.tolerations }}
|
|
||||||
tolerations:
|
|
||||||
{{- toYaml . | nindent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- with .Values.controller.topologySpreadConstraints | default .Values.global.topologySpreadConstraints }}
|
|
||||||
topologySpreadConstraints:
|
|
||||||
{{- range $constraint := . }}
|
|
||||||
- {{ toYaml $constraint | nindent 8 | trim }}
|
|
||||||
{{- if not $constraint.labelSelector }}
|
|
||||||
labelSelector:
|
|
||||||
matchLabels:
|
|
||||||
{{- include "argo-cd.selectorLabels" (dict "context" $ "name" $.Values.controller.name) | nindent 12 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
volumes:
|
|
||||||
{{- with (concat .Values.global.extraVolumes .Values.controller.volumes) }}
|
|
||||||
{{- toYaml . | nindent 6 }}
|
|
||||||
{{- end }}
|
|
||||||
- name: argocd-home
|
|
||||||
{{- if .Values.controller.emptyDir.sizeLimit }}
|
|
||||||
emptyDir:
|
|
||||||
sizeLimit: {{ .Values.controller.emptyDir.sizeLimit }}
|
|
||||||
{{- else }}
|
|
||||||
emptyDir: {}
|
|
||||||
{{- end }}
|
|
||||||
|
|
||||||
- name: argocd-repo-server-tls
|
|
||||||
secret:
|
|
||||||
secretName: argocd-repo-server-tls
|
|
||||||
optional: true
|
|
||||||
items:
|
|
||||||
- key: tls.crt
|
|
||||||
path: tls.crt
|
|
||||||
- key: tls.key
|
|
||||||
path: tls.key
|
|
||||||
- key: ca.crt
|
|
||||||
path: ca.crt
|
|
||||||
- name: argocd-cmd-params-cm
|
|
||||||
configMap:
|
|
||||||
optional: true
|
|
||||||
name: argocd-cmd-params-cm
|
|
||||||
items:
|
|
||||||
- key: controller.profile.enabled
|
|
||||||
path: profiler.enabled
|
|
||||||
{{- if .Values.controller.hostNetwork }}
|
|
||||||
hostNetwork: {{ .Values.controller.hostNetwork }}
|
|
||||||
{{- end }}
|
|
||||||
{{- with .Values.controller.dnsConfig }}
|
|
||||||
dnsConfig:
|
|
||||||
{{- toYaml . | nindent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
dnsPolicy: {{ .Values.controller.dnsPolicy }}
|
|
||||||
{{- end }}
|
|
||||||
-35
@@ -1,35 +0,0 @@
|
|||||||
{{- if .Values.controller.metrics.enabled }}
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: {{ include "argo-cd.controller.fullname" . }}-metrics
|
|
||||||
namespace: {{ include "argo-cd.namespace" . }}
|
|
||||||
labels:
|
|
||||||
{{- include "argo-cd.labels" (dict "context" . "component" .Values.controller.name "name" "metrics") | nindent 4 }}
|
|
||||||
{{- with .Values.controller.metrics.service.labels }}
|
|
||||||
{{- toYaml . | nindent 4 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if or .Values.controller.metrics.service.annotations .Values.global.addPrometheusAnnotations }}
|
|
||||||
annotations:
|
|
||||||
{{- if .Values.global.addPrometheusAnnotations }}
|
|
||||||
prometheus.io/port: {{ .Values.controller.metrics.service.servicePort | quote }}
|
|
||||||
prometheus.io/scrape: "true"
|
|
||||||
{{- end }}
|
|
||||||
{{- range $key, $value := .Values.controller.metrics.service.annotations }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
spec:
|
|
||||||
type: {{ .Values.controller.metrics.service.type }}
|
|
||||||
{{- if and .Values.controller.metrics.service.clusterIP (eq .Values.controller.metrics.service.type "ClusterIP") }}
|
|
||||||
clusterIP: {{ .Values.controller.metrics.service.clusterIP }}
|
|
||||||
{{- end }}
|
|
||||||
{{- include "argo-cd.dualStack" . | indent 2 }}
|
|
||||||
ports:
|
|
||||||
- name: {{ .Values.controller.metrics.service.portName }}
|
|
||||||
protocol: TCP
|
|
||||||
port: {{ .Values.controller.metrics.service.servicePort }}
|
|
||||||
targetPort: metrics
|
|
||||||
selector:
|
|
||||||
{{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.controller.name) | nindent 4 }}
|
|
||||||
{{- end }}
|
|
||||||
-20
@@ -1,20 +0,0 @@
|
|||||||
{{- if or .Values.controller.networkPolicy.create .Values.global.networkPolicy.create }}
|
|
||||||
apiVersion: networking.k8s.io/v1
|
|
||||||
kind: NetworkPolicy
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
{{- include "argo-cd.labels" (dict "context" . "component" .Values.controller.name "name" .Values.controller.name) | nindent 4 }}
|
|
||||||
name: {{ template "argo-cd.controller.fullname" . }}
|
|
||||||
namespace: {{ include "argo-cd.namespace" . }}
|
|
||||||
spec:
|
|
||||||
ingress:
|
|
||||||
- from:
|
|
||||||
- namespaceSelector: {}
|
|
||||||
ports:
|
|
||||||
- port: metrics
|
|
||||||
podSelector:
|
|
||||||
matchLabels:
|
|
||||||
{{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.controller.name) | nindent 6 }}
|
|
||||||
policyTypes:
|
|
||||||
- Ingress
|
|
||||||
{{- end }}
|
|
||||||
-27
@@ -1,27 +0,0 @@
|
|||||||
{{- if .Values.controller.pdb.enabled }}
|
|
||||||
apiVersion: policy/v1
|
|
||||||
kind: PodDisruptionBudget
|
|
||||||
metadata:
|
|
||||||
name: {{ include "argo-cd.controller.fullname" . }}
|
|
||||||
namespace: {{ include "argo-cd.namespace" . }}
|
|
||||||
labels:
|
|
||||||
{{- include "argo-cd.labels" (dict "context" . "component" .Values.controller.name "name" .Values.controller.name) | nindent 4 }}
|
|
||||||
{{- with .Values.controller.pdb.labels }}
|
|
||||||
{{- toYaml . | nindent 4 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- with .Values.controller.pdb.annotations }}
|
|
||||||
annotations:
|
|
||||||
{{- range $key, $value := . }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
spec:
|
|
||||||
{{- with .Values.controller.pdb.maxUnavailable }}
|
|
||||||
maxUnavailable: {{ . }}
|
|
||||||
{{- else }}
|
|
||||||
minAvailable: {{ .Values.controller.pdb.minAvailable | default 0 }}
|
|
||||||
{{- end }}
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
{{- include "argo-cd.selectorLabels" (dict "context" . "name" .Values.controller.name) | nindent 6 }}
|
|
||||||
{{- end }}
|
|
||||||
-25
@@ -1,25 +0,0 @@
|
|||||||
{{- $apiVersion := include "argo-cd.apiVersions.monitoring" . }}
|
|
||||||
{{- if and (.Capabilities.APIVersions.Has "monitoring.coreos.com/v1") .Values.controller.metrics.enabled .Values.controller.metrics.rules.enabled }}
|
|
||||||
apiVersion: {{ $apiVersion }}
|
|
||||||
kind: PrometheusRule
|
|
||||||
metadata:
|
|
||||||
name: {{ template "argo-cd.controller.fullname" . }}
|
|
||||||
namespace: {{ default (include "argo-cd.namespace" .) .Values.controller.metrics.rules.namespace | quote }}
|
|
||||||
labels:
|
|
||||||
{{- include "argo-cd.labels" (dict "context" . "component" .Values.controller.name "name" .Values.controller.name) | nindent 4 }}
|
|
||||||
{{- if .Values.controller.metrics.rules.selector }}
|
|
||||||
{{- toYaml .Values.controller.metrics.rules.selector | nindent 4 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- if .Values.controller.metrics.rules.additionalLabels }}
|
|
||||||
{{- toYaml .Values.controller.metrics.rules.additionalLabels | nindent 4 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- with .Values.controller.metrics.rules.annotations }}
|
|
||||||
annotations:
|
|
||||||
{{- toYaml . | nindent 4 }}
|
|
||||||
{{- end }}
|
|
||||||
spec:
|
|
||||||
groups:
|
|
||||||
- name: argocd
|
|
||||||
rules:
|
|
||||||
{{- toYaml .Values.controller.metrics.rules.spec | nindent 4 }}
|
|
||||||
{{- end }}
|
|
||||||
-64
@@ -1,64 +0,0 @@
|
|||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: Role
|
|
||||||
metadata:
|
|
||||||
name: {{ template "argo-cd.controller.fullname" . }}
|
|
||||||
namespace: {{ include "argo-cd.namespace" . }}
|
|
||||||
labels:
|
|
||||||
{{- include "argo-cd.labels" (dict "context" . "component" .Values.controller.name "name" .Values.controller.name) | nindent 4 }}
|
|
||||||
rules:
|
|
||||||
{{- with .Values.controller.roleRules }}
|
|
||||||
{{- toYaml . | nindent 2 }}
|
|
||||||
{{- else }}
|
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
resources:
|
|
||||||
- secrets
|
|
||||||
- configmaps
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
- apiGroups:
|
|
||||||
- argoproj.io
|
|
||||||
resources:
|
|
||||||
- applications
|
|
||||||
- applicationsets
|
|
||||||
- appprojects
|
|
||||||
verbs:
|
|
||||||
- create
|
|
||||||
- get
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
- update
|
|
||||||
- patch
|
|
||||||
- delete
|
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
resources:
|
|
||||||
- events
|
|
||||||
verbs:
|
|
||||||
- create
|
|
||||||
- list
|
|
||||||
- apiGroups:
|
|
||||||
- apps
|
|
||||||
resources:
|
|
||||||
- deployments
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
{{- if and (not .Values.createClusterRoles) .Values.controller.dynamicClusterDistribution }}
|
|
||||||
- apiGroups:
|
|
||||||
- ""
|
|
||||||
resources:
|
|
||||||
- configmaps
|
|
||||||
resourceNames:
|
|
||||||
- argocd-app-controller-shard-cm
|
|
||||||
verbs:
|
|
||||||
- get
|
|
||||||
- list
|
|
||||||
- watch
|
|
||||||
- create
|
|
||||||
- update
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
-15
@@ -1,15 +0,0 @@
|
|||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: RoleBinding
|
|
||||||
metadata:
|
|
||||||
name: {{ include "argo-cd.controller.fullname" . }}
|
|
||||||
namespace: {{ include "argo-cd.namespace" . }}
|
|
||||||
labels:
|
|
||||||
{{- include "argo-cd.labels" (dict "context" . "component" .Values.controller.name "name" .Values.controller.name) | nindent 4 }}
|
|
||||||
roleRef:
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
kind: Role
|
|
||||||
name: {{ include "argo-cd.controller.fullname" . }}
|
|
||||||
subjects:
|
|
||||||
- kind: ServiceAccount
|
|
||||||
name: {{ include "argo-cd.controller.serviceAccountName" . }}
|
|
||||||
namespace: {{ include "argo-cd.namespace" . }}
|
|
||||||
-19
@@ -1,19 +0,0 @@
|
|||||||
{{- if .Values.controller.serviceAccount.create }}
|
|
||||||
apiVersion: v1
|
|
||||||
kind: ServiceAccount
|
|
||||||
automountServiceAccountToken: {{ .Values.controller.serviceAccount.automountServiceAccountToken }}
|
|
||||||
metadata:
|
|
||||||
name: {{ include "argo-cd.controller.serviceAccountName" . }}
|
|
||||||
namespace: {{ include "argo-cd.namespace" . }}
|
|
||||||
{{- with .Values.controller.serviceAccount.annotations }}
|
|
||||||
annotations:
|
|
||||||
{{- range $key, $value := . }}
|
|
||||||
{{ $key }}: {{ $value | quote }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
labels:
|
|
||||||
{{- include "argo-cd.labels" (dict "context" . "component" .Values.controller.name "name" .Values.controller.name) | nindent 4 }}
|
|
||||||
{{- with .Values.controller.serviceAccount.labels }}
|
|
||||||
{{- toYaml . | nindent 4 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- end }}
|
|
||||||
-52
@@ -1,52 +0,0 @@
|
|||||||
{{- $apiVersion := include "argo-cd.apiVersions.monitoring" . }}
|
|
||||||
{{- if and (.Capabilities.APIVersions.Has $apiVersion) .Values.controller.metrics.enabled .Values.controller.metrics.serviceMonitor.enabled }}
|
|
||||||
apiVersion: {{ $apiVersion }}
|
|
||||||
kind: ServiceMonitor
|
|
||||||
metadata:
|
|
||||||
name: {{ template "argo-cd.controller.fullname" . }}
|
|
||||||
namespace: {{ default (include "argo-cd.namespace" .) .Values.controller.metrics.serviceMonitor.namespace | quote }}
|
|
||||||
labels:
|
|
||||||
{{- include "argo-cd.labels" (dict "context" . "component" .Values.controller.name "name" .Values.controller.name) | nindent 4 }}
|
|
||||||
{{- with .Values.controller.metrics.serviceMonitor.selector }}
|
|
||||||
{{- toYaml . | nindent 4 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- with .Values.controller.metrics.serviceMonitor.additionalLabels }}
|
|
||||||
{{- toYaml . | nindent 4 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- with .Values.controller.metrics.serviceMonitor.annotations }}
|
|
||||||
annotations:
|
|
||||||
{{- toYaml . | nindent 4 }}
|
|
||||||
{{- end }}
|
|
||||||
spec:
|
|
||||||
endpoints:
|
|
||||||
- port: {{ .Values.controller.metrics.service.portName }}
|
|
||||||
{{- with .Values.controller.metrics.serviceMonitor.interval }}
|
|
||||||
interval: {{ . }}
|
|
||||||
{{- end }}
|
|
||||||
{{- with .Values.controller.metrics.serviceMonitor.scrapeTimeout }}
|
|
||||||
scrapeTimeout: {{ . }}
|
|
||||||
{{- end }}
|
|
||||||
path: /metrics
|
|
||||||
{{- with .Values.controller.metrics.serviceMonitor.relabelings }}
|
|
||||||
relabelings:
|
|
||||||
{{- toYaml . | nindent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
{{- with .Values.controller.metrics.serviceMonitor.metricRelabelings }}
|
|
||||||
metricRelabelings:
|
|
||||||
{{- toYaml . | nindent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
honorLabels: {{ .Values.controller.metrics.serviceMonitor.honorLabels }}
|
|
||||||
{{- with .Values.controller.metrics.serviceMonitor.scheme }}
|
|
||||||
scheme: {{ . }}
|
|
||||||
{{- end }}
|
|
||||||
{{- with .Values.controller.metrics.serviceMonitor.tlsConfig }}
|
|
||||||
tlsConfig:
|
|
||||||
{{- toYaml . | nindent 8 }}
|
|
||||||
{{- end }}
|
|
||||||
namespaceSelector:
|
|
||||||
matchNames:
|
|
||||||
- {{ include "argo-cd.namespace" . }}
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
{{- include "argo-cd.selectorLabels" (dict "context" . "component" .Values.controller.name "name" "metrics") | nindent 6 }}
|
|
||||||
{{- end }}
|
|
||||||
Loaded 100 of 358 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user