diff --git a/explorer/k8s/helm/account-squid/.helmignore b/explorer/k8s/helm/account-squid/.helmignore new file mode 100644 index 00000000..0e8a0eb3 --- /dev/null +++ b/explorer/k8s/helm/account-squid/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/explorer/k8s/helm/account-squid/Chart.yaml b/explorer/k8s/helm/account-squid/Chart.yaml new file mode 100644 index 00000000..a22e3b45 --- /dev/null +++ b/explorer/k8s/helm/account-squid/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: account-squid +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "gemini-3h" diff --git a/explorer/k8s/helm/account-squid/config/explorer-env-file b/explorer/k8s/helm/account-squid/config/explorer-env-file new file mode 100644 index 00000000..d733c4f0 --- /dev/null +++ b/explorer/k8s/helm/account-squid/config/explorer-env-file @@ -0,0 +1,8 @@ +POSTGRES_HOST="" +POSTGRES_USER="" +POSTGRES_DB="account-squid" +POSTGRES_PASSWORD="" +POSTGRES_PORT=5432 +ARCHIVE_ENDPOINT="https://archive.gemini-3h.subspace.network/api" +RPC_ENDPOINT="wss://rpc-squids.gemini-3h.subspace.network/ws" +GQL_PORT=4350 diff --git a/explorer/k8s/helm/account-squid/misc/acme-certificate.yaml b/explorer/k8s/helm/account-squid/misc/acme-certificate.yaml new file mode 100644 index 00000000..91ede10a --- /dev/null +++ b/explorer/k8s/helm/account-squid/misc/acme-certificate.yaml @@ -0,0 +1,20 @@ +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: letsencrypt-production + namespace: explorer-network +spec: + acme: + # You must replace this email address with your own. + # Let's Encrypt will use this to contact you about expiring + # certificates, and issues related to your account. + email: alerts@subspace.network + server: https://acme-staging-v02.api.letsencrypt.org/directory + privateKeySecretRef: + # Secret resource that will be used to store the account's private key. + name: explorer-issuer-account-key + # Add a single challenge solver, HTTP01 using nginx + solvers: + - http01: + ingress: + class: nginx diff --git a/explorer/k8s/helm/account-squid/templates/NOTES.txt b/explorer/k8s/helm/account-squid/templates/NOTES.txt new file mode 100644 index 00000000..5a58c3f1 --- /dev/null +++ b/explorer/k8s/helm/account-squid/templates/NOTES.txt @@ -0,0 +1,22 @@ +1. Get the application URL by running these commands: +{{- if .Values.ingress.enabled }} +{{- range $host := .Values.ingress.hosts }} + {{- range .paths }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} + {{- end }} +{{- end }} +{{- else if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Values.namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "account-squid.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Values.namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get --namespace {{ .Values.namespace }} svc -w {{ include "account-squid.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Values.namespace }} {{ include "account-squid.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + echo http://$SERVICE_IP:{{ .Values.service.port }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Values.namespace }} -l "app.kubernetes.io/name={{ include "account-squid.name" . }},app.kubernetes.io/instance={{ .Values.namespace }}" -o jsonpath="{.items[0].metadata.name}") + export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Values.namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl --namespace {{ .Values.namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT +{{- end }} diff --git a/explorer/k8s/helm/account-squid/templates/_helpers.tpl b/explorer/k8s/helm/account-squid/templates/_helpers.tpl new file mode 100644 index 00000000..aca78366 --- /dev/null +++ b/explorer/k8s/helm/account-squid/templates/_helpers.tpl @@ -0,0 +1,60 @@ +{{/* + Expand the name of the chart. + */}} + {{- define "account-squid.name" -}} + {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} + {{- end }} + + {{/* + Create a default fully qualified app name. + */}} + {{- define "account-squid.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 "account-squid.chart" -}} + {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} + {{- end }} + + {{/* + Common labels + */}} + {{- define "account-squid.labels" -}} + helm.sh/chart: {{ include "account-squid.chart" . }} + {{ include "account-squid.selectorLabels" . }} + {{- if .Chart.AppVersion }} + app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} + {{- end }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{- end }} + + {{/* + Selector labels + */}} + {{- define "account-squid.selectorLabels" -}} + app.kubernetes.io/name: {{ include "account-squid.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + {{- end }} + + {{/* + Create the name of the service account to use + */}} + {{- define "account-squid.serviceAccountName" -}} + {{- if .Values.serviceAccount.create }} + {{- default (include "account-squid.fullname" .) .Values.serviceAccount.name }} + {{- else }} + {{- default "default" .Values.serviceAccount.name }} + {{- end }} + {{- end }} diff --git a/explorer/k8s/helm/account-squid/templates/clusterroles.yaml b/explorer/k8s/helm/account-squid/templates/clusterroles.yaml new file mode 100644 index 00000000..0ffdff97 --- /dev/null +++ b/explorer/k8s/helm/account-squid/templates/clusterroles.yaml @@ -0,0 +1,55 @@ +apiVersion: rbac.authorization.k8s.io/v1 +# This cluster role binding allows anyone in the "manager" group to +# read secrets in any namespace. +kind: ClusterRoleBinding +metadata: + name: secret-reader-cluster-binding + namespace: {{ .Values.namespace}} +subjects: + - kind: Group + name: manager # Name is case sensitive + apiGroup: rbac.authorization.k8s.io +roleRef: + kind: ClusterRole + name: secret-reader + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + # "namespace" omitted since ClusterRoles are not namespaced + name: secret-reader +rules: + - apiGroups: [""] + # at the HTTP level, the name of the resource for accessing Secret + # objects is "secrets" + resources: ["secrets"] + verbs: ["get", "watch", "list"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ include "account-squid.fullname" . }}-admin + namespace: {{ .Values.namespace}} +subjects: + - kind: Group + name: {{ include "account-squid.fullname" . }}-admin + apiGroup: rbac.authorization.k8s.io +roleRef: + kind: ClusterRole + name: admin + apiGroup: rbac.authorization.k8s.io +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: role-grantor +rules: +- apiGroups: ["rbac.authorization.k8s.io"] + resources: ["rolebindings"] + verbs: ["create"] +- apiGroups: ["rbac.authorization.k8s.io"] + resources: ["clusterroles"] + verbs: ["bind"] + # omit resourceNames to allow binding any ClusterRole + resourceNames: ["admin","edit","view"] diff --git a/explorer/k8s/helm/account-squid/templates/configmap.yaml b/explorer/k8s/helm/account-squid/templates/configmap.yaml new file mode 100644 index 00000000..405d0b96 --- /dev/null +++ b/explorer/k8s/helm/account-squid/templates/configmap.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Values.namespace }}-configmap + namespace: {{ .Values.namespace }} + labels: + app: {{ include "account-squid.fullname" . }} +data: + POSTGRES_PORT: {{ .Values.postgres.postgresPort }} + POSTGRES_DB: {{ .Values.postgres.postgresDatabase }} + POSTGRES_HOST : {{ .Values.postgres.postgresHost }} + files: + - ../config/explorer-env-file diff --git a/explorer/k8s/helm/account-squid/templates/hpa.yaml b/explorer/k8s/helm/account-squid/templates/hpa.yaml new file mode 100644 index 00000000..798b33f6 --- /dev/null +++ b/explorer/k8s/helm/account-squid/templates/hpa.yaml @@ -0,0 +1,46 @@ +{{- if .Values.autoscaling.enabled }} +apiVersion: autoscaling/v2beta1 +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "account-squid.fullname" . }} + labels: + {{- include "account-squid.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "account-squid.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} + - type: Pods + pods: + metric: + name: packets-per-second + target: + type: AverageValue + averageValue: 3k + - type: Object + object: + metric: + name: requests-per-second + describedObject: + apiVersion: networking.k8s.io/v1 + kind: Ingress + name: main-route + target: + type: Value + value: 10k +{{- end }} diff --git a/explorer/k8s/helm/account-squid/templates/ingress.yaml b/explorer/k8s/helm/account-squid/templates/ingress.yaml new file mode 100644 index 00000000..d814f5c3 --- /dev/null +++ b/explorer/k8s/helm/account-squid/templates/ingress.yaml @@ -0,0 +1,45 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "account-squid.fullname" . }}-ingress + namespace: {{ .Values.namespace }} + labels: + app.kubernetes.io/name: {{ include "account-squid.name" . }} + helm.sh/chart: {{ include "account-squid.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + {{- with .Values.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + ingressClassName: nginx + tls: + - hosts: + - {{ .Values.ingress.hosts | first | quote }} + secretName: {{ .Values.ingress.tls.secretName | quote }} + rules: + {{- range .Values.ingress.hosts }} + - host: {{ . | quote }} + http: + paths: + {{- range .paths }} + - path: {{ .path | quote }} + pathType: {{ .pathType | quote }} + backend: + service: + name: {{ .Values.lb_service.name | quote }} + port: + number: {{ .Values.lb_service.port }} + {{- end }} + {{- end }} + +--- +apiVersion: v1 +kind: Secret +type: kubernetes.io/tls +metadata: + name: acme-tls-secret +data: + tls.crt: {{ .Values.ingress.tls.crt | quote }} + tls.key: {{ .Values.ingress.tls.key | quote }} diff --git a/explorer/k8s/helm/account-squid/templates/loadbal-svc.yaml b/explorer/k8s/helm/account-squid/templates/loadbal-svc.yaml new file mode 100644 index 00000000..d0d770e4 --- /dev/null +++ b/explorer/k8s/helm/account-squid/templates/loadbal-svc.yaml @@ -0,0 +1,26 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "account-squid.fullname" . }}-loadbal-svc + namespace: {{ .Values.namespace}} + labels: + app: {{ include "account-squid.fullname" . }}-app + chart: {{ include "account-squid.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} +spec: + selector: + name: {{ include "account-squid.fullname" . }}-app + app: {{ include "account-squid.fullname" . }}-app + type: {{ .Values.lb_service.type }} + sessionAffinity: None + sessionAffinityConfig: + clientIP: + timeoutSeconds: 10800 + ports: + {{- range .Values.lb_service.lb_ports }} + - port: {{ .port }} + name: {{ .name }} + targetPort: {{ .targetPort }} + protocol: {{ .protocol }} + {{- end }} diff --git a/explorer/k8s/helm/account-squid/templates/namespace.yaml b/explorer/k8s/helm/account-squid/templates/namespace.yaml new file mode 100644 index 00000000..d7e8a848 --- /dev/null +++ b/explorer/k8s/helm/account-squid/templates/namespace.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: {{ .Values.namespace }} + labels: + name: {{ .Values.namespace }} diff --git a/explorer/k8s/helm/account-squid/templates/postgres-configmap.yaml b/explorer/k8s/helm/account-squid/templates/postgres-configmap.yaml new file mode 100644 index 00000000..1a7bd885 --- /dev/null +++ b/explorer/k8s/helm/account-squid/templates/postgres-configmap.yaml @@ -0,0 +1,27 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "account-squid.fullname" . }}-postgres-configmap + namespace: {{ .Values.namespace }} +data: + postgres.conf: |- + max_connections = 200 + shared_buffers = 8GB + effective_cache_size = 24GB + maintenance_work_mem = 2GB + checkpoint_completion_target = 0.9 + wal_buffers = 16MB + default_statistics_target = 100 + random_page_cost = 1.1 + effective_io_concurrency = 200 + work_mem = 10485kB + min_wal_size = 1GB + max_wal_size = 4GB + max_worker_processes = 16 + max_parallel_workers_per_gather = 4 + max_parallel_workers = 16 + max_parallel_maintenance_workers = 4 + shared_preload_libraries='pg_stat_statements' + pg_stat_statements.track=all + # Replace with particular IP addresses in production + listen_addresses = '0.0.0.0' diff --git a/explorer/k8s/helm/account-squid/templates/pv.yaml b/explorer/k8s/helm/account-squid/templates/pv.yaml new file mode 100644 index 00000000..a473b4e3 --- /dev/null +++ b/explorer/k8s/helm/account-squid/templates/pv.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: PersistentVolume +metadata: + name: account-squid-data-pv +spec: + capacity: + storage: {{ .Values.persistence.size }} + volumeMode: Filesystem + accessModes: +{{ toYaml .Values.persistence.accessModes | indent 4 }} + storageClassName: {{ default "efs-sc" .Values.persistence.storageClass | quote }} + persistentVolumeReclaimPolicy: Retain + csi: + driver: efs.csi.aws.com + volumeHandle: fs-073d77123471b2917 diff --git a/explorer/k8s/helm/account-squid/templates/pvc.yaml b/explorer/k8s/helm/account-squid/templates/pvc.yaml new file mode 100644 index 00000000..8ae150f0 --- /dev/null +++ b/explorer/k8s/helm/account-squid/templates/pvc.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "account-squid.fullname" . }}-pvc + namespace: {{ .Values.namespace | quote }} + labels: + app: {{ include "account-squid.name" . }} + chart: {{ include "account-squid.chart" . }} + release: {{ .Release.Name | quote }} + heritage: {{ .Release.Service | quote }} +spec: + accessModes: + - ReadWriteOnce + storageClassName: efs-sc + resources: + requests: + storage: {{ .Values.persistence.size | quote }} diff --git a/explorer/k8s/helm/account-squid/templates/quota.yaml b/explorer/k8s/helm/account-squid/templates/quota.yaml new file mode 100644 index 00000000..86901b72 --- /dev/null +++ b/explorer/k8s/helm/account-squid/templates/quota.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: ResourceQuota +metadata: + name: cpu-mem-resourcequota + namespace: {{ .Values.namespace | quote }} +spec: + hard: + requests.cpu: "2" + requests.memory: 4Gi + limits.cpu: "8" + limits.memory: 16Gi diff --git a/explorer/k8s/helm/account-squid/templates/roles.yaml b/explorer/k8s/helm/account-squid/templates/roles.yaml new file mode 100644 index 00000000..a1a3de32 --- /dev/null +++ b/explorer/k8s/helm/account-squid/templates/roles.yaml @@ -0,0 +1,141 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: pod-reader-role + namespace: {{ .Values.namespace | quote }} +rules: + - apiGroups: [""] + resources: ["pods"] + verbs: ["get", "watch", "list"] + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: pod-reader-binding + namespace: {{ .Values.namespace | quote }} +subjects: + - kind: ServiceAccount + name: {{ include "account-squid.serviceAccountName" . }}-pod-read + namespace: {{ .Values.namespace | quote }} + apiGroup: rbac.authorization.k8s.io +roleRef: + kind: Role + name: pod-reader-role + apiGroup: rbac.authorization.k8s.io + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: deployment-manager-role + namespace: {{ .Values.namespace | quote }} +rules: + - apiGroups: [""] + resources: ["deployments"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: deployment-manager-role-binding + namespace: {{ .Values.namespace | quote }} +subjects: + - kind: ServiceAccount + name: {{ include "account-squid.serviceAccountName" . }}-admin + namespace: {{ .Values.namespace | quote }} + apiGroup: rbac.authorization.k8s.io +roleRef: + kind: Role + name: deployment-manager-role + apiGroup: rbac.authorization.k8s.io + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: role-viewer + namespace: {{ .Values.namespace | quote }} +rules: + - apiGroups: [""] + resources: + - services + - ingress + - nodes + - pods + verbs: + - get + - list + - apiGroups: [apiextensions.k8s.io] + resources: + - customresourcedefinitions + verbs: + - list + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: rolebinding-viewer + namespace: {{ .Values.namespace | quote }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: role-viewer +subjects: + - kind: ServiceAccount + name: {{ include "account-squid.serviceAccountName" . }} + namespace: {{ .Values.namespace | quote }} + apiGroup: rbac.authorization.k8s.io + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ include "account-squid.fullname" . }}-admin-role-binding + namespace: {{ .Values.namespace | quote }} +subjects: + - kind: User + name: {{ .Values.administrator.email }} + apiGroup: rbac.authorization.k8s.io + - kind: Group + name: {{ include "account-squid.fullname" . }}-admin + apiGroup: rbac.authorization.k8s.io + - kind: ServiceAccount + name: {{ include "account-squid.serviceAccountName" . }}-admin + namespace: {{ .Values.namespace | quote }} + apiGroup: rbac.authorization.k8s.io +roleRef: + kind: ClusterRole + name: admin + apiGroup: rbac.authorization.k8s.io + +--- + +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: role-grantor-binding + namespace: {{ .Values.namespace | quote }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: role-grantor +subjects: + - kind: User + name: {{ .Values.administrator.email }} + apiGroup: rbac.authorization.k8s.io + - kind: Group + name: {{ include "account-squid.fullname" . }}-admin + apiGroup: rbac.authorization.k8s.io + - kind: ServiceAccount + name: {{ include "account-squid.serviceAccountName" . }}-admin + namespace: {{ .Values.namespace | quote }} + apiGroup: rbac.authorization.k8s.io diff --git a/explorer/k8s/helm/account-squid/templates/secrets.yaml b/explorer/k8s/helm/account-squid/templates/secrets.yaml new file mode 100644 index 00000000..c81d843a --- /dev/null +++ b/explorer/k8s/helm/account-squid/templates/secrets.yaml @@ -0,0 +1,9 @@ +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "account-squid.fullname" . }}-postgres-secret +type: Opaque +data: + POSTGRES_PASSWORD: {{ .Values.postgres.postgresPassword | b64enc}} + POSTGRES_USER: {{ .Values.postgres.postgresUser | b64enc}} diff --git a/explorer/k8s/helm/account-squid/templates/service.yaml b/explorer/k8s/helm/account-squid/templates/service.yaml new file mode 100644 index 00000000..31313cbc --- /dev/null +++ b/explorer/k8s/helm/account-squid/templates/service.yaml @@ -0,0 +1,23 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "account-squid.fullname" . }}-svc + namespace: {{ .Values.namespace}} + labels: + app: {{ include "account-squid.fullname" . }}-app + chart: {{ include "account-squid.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + +spec: + selector: + name: {{ include "account-squid.fullname" . }}-app + app: {{ include "account-squid.fullname" . }}-app + type: {{ .Values.service.type }} + ports: + {{- range .Values.service.ports }} + - port: {{ .port }} + name: {{ .name }} + targetPort: {{ .targetPort }} + protocol: {{ .protocol }} + {{- end }} diff --git a/explorer/k8s/helm/account-squid/templates/serviceaccount.yaml b/explorer/k8s/helm/account-squid/templates/serviceaccount.yaml new file mode 100644 index 00000000..96f05723 --- /dev/null +++ b/explorer/k8s/helm/account-squid/templates/serviceaccount.yaml @@ -0,0 +1,21 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "account-squid.serviceAccountName" . }}-pod-read + namespace: {{ .Values.namespace | quote }} + +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "account-squid.serviceAccountName" . }}-admin + namespace: {{ .Values.namespace | quote }} + +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "account-squid.serviceAccountName" . }} + namespace: {{ .Values.namespace | quote }} +{{ end }} diff --git a/explorer/k8s/helm/account-squid/templates/statefulset.yaml b/explorer/k8s/helm/account-squid/templates/statefulset.yaml new file mode 100644 index 00000000..1fc4bd68 --- /dev/null +++ b/explorer/k8s/helm/account-squid/templates/statefulset.yaml @@ -0,0 +1,168 @@ +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ include "account-squid.fullname" . }}-app + namespace: {{ .Values.namespace | quote }} +spec: + {{- if not .Values.autoscaling.enabled }} + replicas: {{ .Values.replicaCount }} + {{- end }} + minReadySeconds: 5 + serviceName: {{ include "account-squid.fullname" . }}-app + template: + metadata: + labels: + app: {{ include "account-squid.name" . }} + release: {{ .Release.Name }} + matchLabels: + app: {{ include "account-squid.name" . }} + release: {{ .Release.Name }} + spec: + serviceAccountName: {{ include "account-squid.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: postgres + image: postgres:16 + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + ports: + - name: db + containerPort: 5432 + protocol: TCP + env: + - name: POSTGRES_HOST + valueFrom: + configMapKeyRef: + name: {{ include "account-squid.fullname" . }}-configmap + key: POSTGRES_HOST + - name: POSTGRES_DB + valueFrom: + configMapKeyRef: + name: {{ include "account-squid.fullname" . }}-configmap + key: POSTGRES_DB + - name: POSTGRES_PORT + valueFrom: + configMapKeyRef: + name: {{ include "account-squid.fullname" . }}-configmap + key: POSTGRES_PORT + - name: POSTGRES_USER + valueFrom: + secretKeyRef: + name: {{ include "account-squid.fullname" . }}-postgres-secret + key: POSTGRES_USER + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "account-squid.fullname" . }}-postgres-secret + key: POSTGRES_PASSWORD + volumeMounts: + - mountPath: "/var/lib/postgresql/data" + name: {{ include "account-squid.fullname" . }}-data + - mountPath: "/var/lib/postgresql/postgres.conf" + name: config + subPath: postgres.conf + livenessProbe: + exec: + command: + - pg_isready + - -U + - postgres + - -h + - 127.0.0.1 + - -p + - "5432" + initialDelaySeconds: 30 + periodSeconds: 10 + readinessProbe: + exec: + command: + - pg_isready + - -U + - postgres + - -h + - 127.0.0.1 + - -p + - "5432" + initialDelaySeconds: 5 + periodSeconds: 10 + resources: + {{- toYaml .Values.resources | nindent 12 }} + - name: processor + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + ports: + - name: processor + containerPort: 3000 + protocol: TCP + resources: + {{- toYaml .Values.resources | nindent 12 }} + env: + - name: POSTGRES_HOST + valueFrom: + configMapKeyRef: + name: {{ include "account-squid.fullname" . }}-configmap + key: POSTGRES_HOST + - name: POSTGRES_DB + valueFrom: + configMapKeyRef: + name: {{ include "account-squid.fullname" . }}-configmap + key: POSTGRES_DB + - name: POSTGRES_PORT + valueFrom: + configMapKeyRef: + name: {{ include "account-squid.fullname" . }}-configmap + key: POSTGRES_PORT + - name: POSTGRES_USER + valueFrom: + secretKeyRef: + name: {{ include "account-squid.fullname" . }}-postgres-secret + key: POSTGRES_USER + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "account-squid.fullname" . }}-postgres-secret + key: POSTGRES_PASSWORD + livenessProbe: + tcpSocket: + port: 3000 + initialDelaySeconds: 5 + periodSeconds: 30 + readinessProbe: + tcpSocket: + port: 3000 + initialDelaySeconds: 6 + periodSeconds: 30 + volumeMounts: + - mountPath: "/var/processor" + name: {{ include "account-squid.fullname" . }}-data + - name: graphql + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image_api.repository }}:{{ .Values.image_api.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy | quote }} + ports: + - name: graphql + containerPort: 4350 + protocol: TCP + livenessProbe: + tcpSocket: + port: 4350 + initialDelaySeconds: 5 + periodSeconds: 30 + readinessProbe: + tcpSocket: + port: 4350 + initialDelaySeconds: 6 + periodSeconds: 30 + volumeMounts: + - mountPath: "/var/graphql" + name: {{ include "account-squid.fullname" . }}-data + volumes: + - name: config + configMap: + name: {{ include "account-squid.fullname" . }}-postgres-configmap + - name: {{ include "account-squid.fullname" . }}-data + persistentVolumeClaim: + claimName: {{ include "account-squid.fullname" . }}-data-pvc diff --git a/explorer/k8s/helm/account-squid/templates/storageclass.yaml b/explorer/k8s/helm/account-squid/templates/storageclass.yaml new file mode 100644 index 00000000..6eba2d45 --- /dev/null +++ b/explorer/k8s/helm/account-squid/templates/storageclass.yaml @@ -0,0 +1,5 @@ +apiVersion: storage.k8s.io/v1 +kind: StorageClass +metadata: + name: efs-sc +provisioner: efs.csi.aws.com diff --git a/explorer/k8s/helm/account-squid/values.yaml b/explorer/k8s/helm/account-squid/values.yaml new file mode 100644 index 00000000..a10f95b5 --- /dev/null +++ b/explorer/k8s/helm/account-squid/values.yaml @@ -0,0 +1,178 @@ +# Default values for account-squid. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +administrator: + email: "who@example.org" + +namespace: squid + +image: + repository: ghcr.io/subspace/blockexplorer-processor + pullPolicy: Always + # Overrides the image tag whose default is the chart appVersion. + tag: "latest" + +image_api: + repository: ghcr.io/subspace/blockexplorer-api-server + pullPolicy: Always + # Overrides the image tag whose default is the chart appVersion. + tag: "latest" + + +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: true + # Annotations to add to the service account + annotations: {} + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: "" + +podAnnotations: {} + +podSecurityContext: + runAsNonRoot: true + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + +securityContext: + allowPrivilegeEscalation: false + +service: + type: ClusterIP + ports: + - port: 5432 + name: db + targetPort: 5432 + protocol: TCP + - port: 3000 + name: processor + targetPort: 3000 + protocol: TCP + - port: 4350 + name: graphql + targetPort: 4350 + protocol: TCP + +lb_service: + type: LoadBalancer + lb_ports: + - port: 4350 + name: graphql + targetPort: 4350 + protocol: TCP + +annotations: + kubernetes.io/ingress.class: nginx + kubernetes.io/tls-acme: "true" + nginx.ingress.kubernetes.io/proxy-set-header: "Host $host" + nginx.ingress.kubernetes.io/proxy-connect-timeout: "120s" + nginx.ingress.kubernetes.io/proxy-read-timeout: "120s" + nginx.ingress.kubernetes.io/proxy-send-timeout: "120s" + nginx.ingress.kubernetes.io/proxy-next-upstream: "http_504" + nginx.ingress.kubernetes.io/proxy-next-upstream-timeout: "3s" + nginx.ingress.kubernetes.io/proxy-next-upstream-tries: "3" + nginx.ingress.kubernetes.io/proxy-request-buffering: "on" + nginx.ingress.kubernetes.io/auth-keepalive-timeout: "120s" + nginx.ingress.kubernetes.io/client-max-body-size: "8m" + nginx.ingress.kubernetes.io/proxy-buffering: "on" + nginx.ingress.kubernetes.io/proxy-buffers-number: "4" + nginx.ingress.kubernetes.io/proxy-buffer-size: "8k" + nginx.ingress.kubernetes.io/proxy-max-temp-file-size: "1024m" + nginx.ingress.kubernetes.io/proxy-http-version: "1.0" + nginx.ingress.kubernetes.io/ssl-ciphers: "ALL:!aNULL:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP" + nginx.ingress.kubernetes.io/ssl-prefer-server-ciphers: "true" + nginx.ingress.kubernetes.io/connection-proxy-header: "keep-alive" + nginx.ingress.kubernetes.io/enable-cors: "true" + nginx.ingress.kubernetes.io/cors-allow-methods: "PUT GET, POST, OPTIONS" + nginx.ingress.kubernetes.io/cors-allow-headers: "X-Forwarded-For, X-REAL-IP" + nginx.ingress.kubernetes.io/cors-allow-origin: "*" + nginx.ingress.kubernetes.io/cors-max-age: "3600" + +ingress: + enabled: false + className: "nginx" + + hosts: + - host: squid.gemini-3h.subspace.network + path: /graphql + pathType: ImplementationSpecific + port: 4444 + + tls: + secretName: acme-tls-secret + hosts: squid.gemini-3h.subspace.network + certificate: {} + key: {} + + proxySetHeaders: {} + # -- Will add custom headers before sending response traffic to the client according to: https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#add-headers + addHeaders: {} + # -- Optionally customize the pod dnsConfig. + dnsConfig: {} + # -- Optionally customize the pod hostname. + +resources: + requests: + cpu: 2 + memory: 200Mi + + +autoscaling: + enabled: false + minReplicas: 1 + maxReplicas: 3 + targetCPUUtilizationPercentage: 80 + targetMemoryUtilizationPercentage: 80 + +replicaCount: 1 + +nodeSelector: + squid.gemini-3h.subspace.network/role: account-squid-node + + +tolerations: + - key: "squid.gemini-3h.subspace.network/role" + operator: "Equal" + value: "account-squid-node" + effect: "NoSchedule" + + +affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: squid.gemini-3h.subspace.network/role + operator: In + values: + - account-squid-node + + +persistence: + enabled: true + enableKubeWorkerClaim: true + existingClaim: "" + accessModes: + - ReadWriteOnce + size: 150G + storageClass: "" + + +prometheus: + enabled: true + interval: 15s + +# make sure to change this to secure password in production +postgres: + postgresUser: postgres + postgresPassword: postgres + postgresDatabase: postgres + postgresPort: 5432 + postgresHost: localhost