diff --git a/deploy/charts/nebulous/Chart.yaml b/deploy/charts/nebulous/Chart.yaml index 7620500..d4efc13 100644 --- a/deploy/charts/nebulous/Chart.yaml +++ b/deploy/charts/nebulous/Chart.yaml @@ -7,10 +7,10 @@ home: https://github.com/agentsea/nebulous # 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.2.0 +version: 0.2.1 # 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: "0.1.61" +appVersion: "0.1.75" diff --git a/deploy/charts/nebulous/README.md b/deploy/charts/nebulous/README.md index 0b68418..57ba550 100644 --- a/deploy/charts/nebulous/README.md +++ b/deploy/charts/nebulous/README.md @@ -1,6 +1,6 @@ # nebulous -![Version: 0.2.0](https://img.shields.io/badge/Version-0.2.0-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.1.61](https://img.shields.io/badge/AppVersion-0.1.61-informational?style=flat-square) +![Version: 0.2.1](https://img.shields.io/badge/Version-0.2.1-informational?style=flat-square) ![Type: application](https://img.shields.io/badge/Type-application-informational?style=flat-square) ![AppVersion: 0.1.75](https://img.shields.io/badge/AppVersion-0.1.75-informational?style=flat-square) A cross-cloud container orchestrator for AI workloads @@ -39,12 +39,14 @@ helm install nebulous nebulous/nebulous -f values.yaml \ | headscale.derp.configMap.key | string | `"servers.yaml"` | The key in the ConfigMap containing the DERP server configuration YAML file. | | headscale.derp.configMap.name | string | `""` | The name of the ConfigMap containing the DERP server configuration. | | headscale.derp.externalMaps | list | `[]` | URLs of externally available DERP maps encoded in JSON. | -| headscale.dns.base_domain | string | `""` | The base domain for MagicDNS hostnames. Cannot be the same as the Headscale server's domain. Refer to https://github.com/juanfont/headscale/blob/main/config-example.yaml for details. | -| headscale.domain | string | `""` | The domain under which the Headscale server is exposed. | +| headscale.dns.baseDomain | string | `""` | The base domain for MagicDNS hostnames. Cannot be the same as the Headscale server's domain. Refer to https://github.com/juanfont/headscale/blob/main/config-example.yaml for details. | +| headscale.domain | string | `""` | The domain under which the Headscale server is exposed. Required if create is true. The headscale server must be reachable at https://${domain}:443. | | headscale.imageTag | string | `"latest"` | The Headscale image tag. | | headscale.ingress.annotations | object | `{}` | Annotations to add to the Ingress resource. | | headscale.ingress.enabled | bool | `false` | If enabled, create an Ingress resource. Ignored unless 'enabled' is true. | | headscale.ingress.ingressClassName | string | `""` | The ingress class. | +| headscale.log.format | string | `"text"` | The log format of the Headscale server. Options are "text" or "json". | +| headscale.log.level | string | `"info"` | The log level of the Headscale server. Options are "off", "trace", "debug", "info", "warn", "error". | | headscale.namespaceOverride | string | `""` | Namespace override for the Headscale deployment. | | headscale.prefixes | object | `{"v4":"100.64.0.0/10","v6":"fd7a:115c:a1e0::/48"}` | Prefixes to allocate tailaddresses from. Must be within the IP ranges supported by the Tailscale client. Refer to https://github.com/juanfont/headscale/blob/main/config-example.yaml for details. | | headscale.privateKeys.claimName | string | `"headscale-keys-pvc"` | The name of the PersistentVolumeClaim for the Headscale private keys. | @@ -54,10 +56,17 @@ helm install nebulous nebulous/nebulous -f values.yaml \ | headscale.service.annotations | object | `{}` | The annotations to add to the Kubernetes service. | | headscale.service.nameOverride | string | `""` | Override the name of the Kubernetes service. | | headscale.service.port | int | `80` | The port of the Kubernetes service. | +| headscale.service.type | string | `"ClusterIP"` | The type of the Kubernetes service. Options are "ClusterIP", "NodePort", and "LoadBalancer". | | headscale.sqlite.claimName | string | `"headscale-sqlite-pvc"` | The name of the PersistentVolumeClaim for the Headscale sqlite database. | | headscale.sqlite.createPersistentVolumeClaim | bool | `true` | If true, create a PersistentVolumeClaim for the Headscale sqlite database. | | headscale.sqlite.size | string | `"10Gi"` | The size of the PersistentVolumeClaim created for the Headscale sqlite database. | | headscale.sqlite.storageClassName | string | `""` | The storage class of the PersistentVolumeClaim created for the Headscale sqlite database. | +| headscale.tls.letsencrypt.claimName | string | `"headscale-tls-pvc"` | The name of the PersistentVolumeClaim for the Headscale Let's Encrypt cache. | +| headscale.tls.letsencrypt.createPersistentVolumeClaim | bool | `true` | If true, create a PersistentVolumeClaim for the Headscale Let's Encrypt cache. | +| headscale.tls.letsencrypt.email | string | `""` | The email address for the Let's Encrypt certificate. | +| headscale.tls.letsencrypt.hostname | string | `""` | The hostname for the Let's Encrypt certificate. Has to match the domain of the Headscale server. | +| headscale.tls.letsencrypt.size | string | `"16Mi"` | The size of the PersistentVolumeClaim created for the Headscale Let's Encrypt cache. | +| headscale.tls.letsencrypt.storageClassName | string | `""` | The storage class of the PersistentVolumeClaim created for the Headscale Let's Encrypt cache. | | image.pullPolicy | string | `"IfNotPresent"` | | | image.repository | string | `"us-docker.pkg.dev/agentsea-dev/nebulous/server"` | The repository to pull the server image from. | | image.tag | string | `""` | The nebulous image tag. Defaults to the Helm chart's appVersion. | @@ -77,7 +86,7 @@ helm install nebulous nebulous/nebulous -f values.yaml \ | postgres.persistence.enabled | bool | `false` | If enabled, use a PersistentVolumeClaim for the Postgres data. Ignored unless 'create' is true. | | postgres.persistence.size | string | `"100Gi"` | The size of the PersistentVolumeClaim for the Postgres data. | | postgres.persistence.storageClassName | string | `""` | The storage class of the PersistentVolumeClaim for the Postgres data. | -| postgres.secret.keys.connection_string | string | `"CONNECTION_STRING"` | The key in the secret containing the Postgres connection string. | +| postgres.secret.keys.connectionString | string | `"CONNECTION_STRING"` | The key in the secret containing the Postgres connection string. | | postgres.secret.name | string | `"postgres-secret"` | Name of the secret with the Postgres connection string. | | providers.aws.auth | object | `{"accessKeyId":"","secretAccessKey":""}` | Manual configuration of the AWS credentials. Not recommended for production. | | providers.aws.enabled | bool | `false` | Enable access to AWS. | @@ -91,11 +100,7 @@ helm install nebulous nebulous/nebulous -f values.yaml \ | redis.auth | object | `{"database":0,"host":"","password":"nebulous","port":6379}` | Manual configuration of the Redis connection. Except for 'host', this information is also used if 'create' is true. | | redis.create | bool | `false` | If enabled, create a Redis deployment and service. Not recommended for production. | | redis.imageTag | string | `"latest"` | The redis image tag. Ignored unless 'create' is true. | -| redis.ingress.annotations | object | `{}` | Annotations to add to the Ingress resource. | -| redis.ingress.enabled | bool | `false` | If enabled, create an Ingress resource. Ignored unless 'create' is true. | -| redis.ingress.host | string | `""` | The host field of the Ingress rule. | -| redis.ingress.ingressClassName | string | `""` | The ingress class. | -| redis.secret.keys.connection_string | string | `"CONNECTION_STRING"` | The key in the secret containing the Redis connection string. | +| redis.secret.keys.connectionString | string | `"CONNECTION_STRING"` | The key in the secret containing the Redis connection string. | | redis.secret.keys.password | string | `"PASSWORD"` | The key in the secret containing the Redis password. | | redis.secret.name | string | `"redis-secret"` | Name of the secret with the Redis connection string and password. | | redis.service.annotations | object | `{}` | The annotations to add to the Kubernetes service. | @@ -125,6 +130,5 @@ helm install nebulous nebulous/nebulous -f values.yaml \ | tailscale.loginServer | string | `"https://login.tailscale.com"` | The Tailscale host to connect to. If headscale.enabled is true, this is ignored. | | tailscale.secret.keys.apiKey | string | `"API_KEY"` | The key in the secret containing the Tailscale API key | | tailscale.secret.keys.authKey | string | `"AUTH_KEY"` | The key in the secret containing the Tailscale auth key | -| tailscale.secret.keys.loginServer | string | `"LOGIN_SERVER"` | The key in the secret containing the Tailscale host. | | tailscale.secret.name | string | `"tailscale-secret"` | Name of the secret with the Redis connection string and password. | diff --git a/deploy/charts/nebulous/templates/_helpers.tpl b/deploy/charts/nebulous/templates/_helpers.tpl index 3deb881..1b4eeeb 100644 --- a/deploy/charts/nebulous/templates/_helpers.tpl +++ b/deploy/charts/nebulous/templates/_helpers.tpl @@ -46,7 +46,15 @@ headscale {{- end }} {{- define "headscale.host" -}} -{{- include "headscale.serviceName" . }}.{{- include "headscale.namespace" . }}.svc.cluster.local +https://{{- required ".Values.headscale.domain is required" .Values.headscale.domain }} +{{- end }} + +{{- define "tailscale.loginServer" }} +{{- if .Values.headscale.create }} +{{- include "headscale.host" . }} +{{- else }} +{{- required ".Values.tailscale.loginServer is required" .Values.tailscale.loginServer }} +{{- end }} {{- end }} {{- define "postgres.name" -}} diff --git a/deploy/charts/nebulous/templates/deployment.yaml b/deploy/charts/nebulous/templates/deployment.yaml index f21a147..a5ffff6 100644 --- a/deploy/charts/nebulous/templates/deployment.yaml +++ b/deploy/charts/nebulous/templates/deployment.yaml @@ -7,6 +7,8 @@ metadata: {{- include "common.labels" . | nindent 4 }} spec: replicas: 1 + strategy: + type: Recreate selector: matchLabels: app: {{ include "nebulous.appSelector" . }} @@ -19,6 +21,8 @@ spec: "helm.sh/restart-timestamp": "{{ now | date "20250101010203" }}" {{- end }} spec: + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet serviceAccountName: {{ include "nebulous.serviceAccountName" . }} containers: - name: nebulous-server @@ -26,6 +30,12 @@ spec: {{- with .Values.image.pullPolicy }} imagePullPolicy: {{.}} {{- end }} + securityContext: + capabilities: + add: + - NET_ADMIN + - NET_RAW + privileged: true ports: - containerPort: 3000 env: @@ -38,7 +48,7 @@ spec: valueFrom: secretKeyRef: name: {{ .Values.postgres.secret.name }} - key: {{ .Values.postgres.secret.keys.connection_string }} + key: {{ .Values.postgres.secret.keys.connectionString }} - name: MESSAGE_QUEUE_TYPE value: {{ .Values.messageQueue.type }} {{- if eq .Values.messageQueue.type "redis" }} @@ -46,7 +56,7 @@ spec: valueFrom: secretKeyRef: name: {{ .Values.redis.secret.name }} - key: {{ .Values.redis.secret.keys.connection_string }} + key: {{ .Values.redis.secret.keys.connectionString }} - name: REDIS_PASSWORD valueFrom: secretKeyRef: @@ -62,14 +72,14 @@ spec: - name: AWS_SECRET_ACCESS_KEY valueFrom: secretKeyRef: - name: {{ .Values.providers.aws.secret.name }} + name: {{ .Values.providers.aws.secret.name }} key: {{ .Values.providers.aws.secret.keys.secretAccessKey }} {{- end }} {{- if .Values.providers.runpod.enabled }} - name: RUNPOD_API_KEY valueFrom: secretKeyRef: - name: {{ .Values.providers.runpod.secret.name }} + name: {{ .Values.providers.runpod.secret.name }} key: {{ .Values.providers.runpod.secret.keys.apiKey }} {{- end }} - name: TS_AUTHKEY @@ -79,9 +89,9 @@ spec: key: {{ .Values.tailscale.secret.keys.authKey }} - name: TS_LOGINSERVER valueFrom: - secretKeyRef: - name: {{ .Values.tailscale.secret.name }} - key: {{ .Values.tailscale.secret.keys.loginServer }} + secretKeyRef: + name: {{ .Values.tailscale.secret.name }} + key: {{ .Values.tailscale.secret.keys.loginServer }} - name: RUST_LOG value: {{ .Values.logLevel | lower }} envFrom: @@ -96,6 +106,8 @@ spec: mountPath: /datasets - name: model-pvc mountPath: /models + - name: dev-net-tun + mountPath: /dev/net/tun volumes: - name: huggingface-pvc persistentVolumeClaim: @@ -109,3 +121,7 @@ spec: - name: model-pvc persistentVolumeClaim: claimName: {{ .Values.storage.model.claimName }} + - name: dev-net-tun + hostPath: + path: /dev/net/tun + type: CharDevice diff --git a/deploy/charts/nebulous/templates/headscale.yaml b/deploy/charts/nebulous/templates/headscale.yaml index 43382ec..e4f7249 100644 --- a/deploy/charts/nebulous/templates/headscale.yaml +++ b/deploy/charts/nebulous/templates/headscale.yaml @@ -11,15 +11,20 @@ data: server_url: {{ printf "https://%s:443" .Values.headscale.domain }} listen_addr: 0.0.0.0:8080 metrics_listen_addr: 0.0.0.0:9090 - # TLS termination happens at the Ingress level - # (see https://headscale.net/stable/ref/integration/reverse-proxy/#tls) - tls_cert_path: "" - tls_key_path: "" noise: private_key_path: /mnt/keys/noise_private.key prefixes: v4: 100.64.0.0/10 v6: fd7a:115c:a1e0::/48 + {{- if .Values.headscale.tls.letsencrypt.hostname }} + tls_letsencrypt_hostname: {{ .Values.headscale.tls.letsencrypt.hostname }} + acme_email: {{ .Values.headscale.tls.letsencrypt.email }} + tls_letsencrypt_listen: ":http" + tls_letsencrypt_cache_dir: /mnt/letsencrypt + tls_letsencrypt_challenge_type: HTTP-01 + {{- end }} + tls_cert_path: "" + tls_key_path: "" database: type: sqlite derp: @@ -33,7 +38,10 @@ data: - /mnt/derp/{{ .Values.headscale.derp.configMap.key }} {{- end }} dns: - base_domain: {{ .Values.headscale.dns.base_domain }} + base_domain: {{ .Values.headscale.dns.baseDomain }} + log: + format: {{ .Values.headscale.log.format }} + level: {{ .Values.headscale.log.level }} --- {{- if .Values.headscale.sqlite.createPersistentVolumeClaim }} apiVersion: v1 @@ -73,6 +81,25 @@ spec: storage: {{ .Values.headscale.privateKeys.size }} --- {{- end }} +{{- if and .Values.headscale.tls.letsencrypt.hostname .Values.headscale.tls.letsencrypt.createPersistentVolumeClaim }} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ .Values.headscale.tls.letsencrypt.claimName }} + namespace: {{ include "headscale.namespace" . }} + labels: + {{- include "common.labels" . | nindent 4 }} +spec: + {{- with .Values.headscale.tls.letsencrypt.storageClassName }} + storageClassName: {{.}} + {{- end }} + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.headscale.tls.letsencrypt.size }} +--- +{{- end }} apiVersion: apps/v1 kind: Deployment metadata: @@ -106,6 +133,10 @@ spec: name: sqlite - mountPath: /mnt/keys name: private-keys + {{- if .Values.headscale.tls.letsencrypt.hostname }} + - mountPath: /mnt/letsencrypt + name: tls-letsencrypt + {{- end }} {{- if .Values.headscale.derp.configMap.name }} - mountPath: /mnt/derp name: derp-config @@ -120,20 +151,17 @@ spec: - name: private-keys persistentVolumeClaim: claimName: {{ .Values.headscale.privateKeys.claimName }} + {{- if .Values.headscale.tls.letsencrypt.hostname }} + - name: tls-letsencrypt + persistentVolumeClaim: + claimName: {{ .Values.headscale.tls.letsencrypt.claimName }} + {{- end }} {{- if .Values.headscale.derp.configMap.name }} - name: derp-config configMap: name: {{ .Values.headscale.derp.configMap.name }} {{- end }} --- -apiVersion: v1 -kind: ServiceAccount -metadata: - name: headscale-api-key-generator - namespace: {{ include "nebulous.namespace" . }} - labels: - {{- include "common.labels" . | nindent 4 }} ---- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: @@ -155,7 +183,7 @@ metadata: {{- include "common.labels" . | nindent 4 }} subjects: - kind: ServiceAccount - name: headscale-api-key-generator + name: {{ include "nebulous.serviceAccountName" . }} namespace: {{ include "nebulous.namespace" . }} roleRef: kind: Role @@ -165,87 +193,31 @@ roleRef: apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: - name: secret-writer + name: secret-management namespace: {{ include "nebulous.namespace" . }} labels: {{- include "common.labels" . | nindent 4 }} rules: - apiGroups: [ "" ] resources: [ "secrets" ] - verbs: [ "create", "delete", "get", "list" ] + verbs: [ "create", "delete", "get", "list", "patch", "update" ] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: - name: allow-secret-creation + name: secret-management namespace: {{ include "nebulous.namespace" . }} labels: {{- include "common.labels" . | nindent 4 }} subjects: - kind: ServiceAccount - name: headscale-api-key-generator + name: {{ include "nebulous.serviceAccountName" . }} namespace: {{ include "nebulous.namespace" . }} roleRef: kind: Role - name: secret-writer + name: secret-management apiGroup: rbac.authorization.k8s.io --- -apiVersion: batch/v1 -kind: Job -metadata: - name: delete-old-tailscale-secret - annotations: - "helm.sh/hook": pre-upgrade - "helm.sh/hook-weight": "-10" -spec: - template: - spec: - restartPolicy: Never - serviceAccountName: headscale-api-key-generator - containers: - - name: delete-secret - image: bitnami/kubectl - command: - - "/bin/sh" - - "-c" - - "kubectl delete secret {{ .Values.tailscale.secret.name }} -n {{ include "nebulous.namespace" . }} --ignore-not-found" ---- -apiVersion: batch/v1 -kind: Job -metadata: - name: generate-tailscale-secret-for-headscale - namespace: {{ include "nebulous.namespace" . }} - labels: - {{- include "common.labels" . | nindent 4 }} - annotations: - "helm.sh/hook": "post-install,post-upgrade" - "helm.sh/hook-weight": "5" -spec: - template: - spec: - serviceAccountName: headscale-api-key-generator - restartPolicy: OnFailure - containers: - - name: api-key-generator - image: bitnami/kubectl - command: [ "/bin/sh", "-c", " - echo 'Waiting for Headscale Pod to be ready...'; - until kubectl get pod -l app={{ include "headscale.name" . }} -n {{ include "headscale.namespace" . }} -o jsonpath='{.items[0].status.phase}' | grep -q Running; do - sleep 1; - done; - POD_NAME=$(kubectl get pod -l app={{ include "headscale.name" . }} -n {{ include "headscale.namespace" . }} -o jsonpath='{.items[0].metadata.name}') - - kubectl exec $POD_NAME -- headscale users create nebu || echo 'User nebu already exists. That is OK.'; - - API_KEY=$(kubectl exec $POD_NAME -- headscale apikeys create --expiration 99y); - AUTH_KEY=$(kubectl exec $POD_NAME -- headscale preauthkeys create --user nebu --reusable); - - kubectl create secret generic {{ .Values.tailscale.secret.name }} -n {{ include "nebulous.namespace" . }} \ - --from-literal={{ .Values.tailscale.secret.keys.apiKey }}=$API_KEY \ - --from-literal={{ .Values.tailscale.secret.keys.authKey }}=$AUTH_KEY \ - --from-literal={{ .Values.tailscale.secret.keys.loginServer }}={{ include "headscale.host" . }}; - " ] ---- apiVersion: v1 kind: Service metadata: @@ -254,9 +226,9 @@ metadata: labels: {{- include "common.labels" . | nindent 4 }} {{- with .Values.headscale.service.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} spec: selector: app: {{ include "headscale.name" . }} @@ -264,7 +236,7 @@ spec: - protocol: TCP port: {{ .Values.headscale.service.port }} targetPort: 8080 - type: ClusterIP + type: {{ .Values.headscale.service.type }} --- apiVersion: v1 kind: Service @@ -298,18 +270,10 @@ spec: {{- with .Values.headscale.ingress.ingressClassName }} ingressClassName: {{.}} {{- end }} - rules: - - http: - paths: - - backend: - service: - name: {{ include "headscale.name" . }} - port: - number: {{ .Values.headscale.service.port }} - path: / - pathType: Prefix - {{- with .Values.headscale.domain }} - host: {{.}} - {{- end }} + defaultBackend: + service: + name: {{ include "headscale.serviceName" . }} + port: + number: {{ .Values.headscale.service.port }} {{- end }} {{- end }} diff --git a/deploy/charts/nebulous/templates/ingress.yaml b/deploy/charts/nebulous/templates/ingress.yaml index 31edfb6..bdd3de1 100644 --- a/deploy/charts/nebulous/templates/ingress.yaml +++ b/deploy/charts/nebulous/templates/ingress.yaml @@ -11,20 +11,12 @@ metadata: {{- toYaml . | nindent 4 }} {{- end }} spec: - {{- with .Values.ingress.className }} + {{- with .Values.ingress.ingressClassName }} ingressClassName: {{.}} {{- end }} - rules: - - http: - paths: - - backend: - service: - name: {{ include "nebulous.serviceName" . }} - port: - number: {{ .Values.service.port }} - path: / - pathType: Prefix - {{- with .Values.ingress.host }} - host: {{.}} - {{- end }} + defaultBackend: + service: + name: {{ include "nebulous.serviceName" . }} + port: + number: {{ .Values.service.port }} {{- end }} diff --git a/deploy/charts/nebulous/templates/postgres.yaml b/deploy/charts/nebulous/templates/postgres.yaml index fc5dfa1..59f309d 100644 --- a/deploy/charts/nebulous/templates/postgres.yaml +++ b/deploy/charts/nebulous/templates/postgres.yaml @@ -8,7 +8,7 @@ metadata: {{- include "common.labels" . | nindent 4 }} type: Opaque data: - {{ .Values.postgres.secret.keys.connection_string }}: {{ printf "postgresql://%s:%s@%s:%d/%s" .Values.postgres.auth.user .Values.postgres.auth.password (include "postgres.host") (int .Values.postgres.auth.port) .Values.postgres.auth.database | b64enc }} + {{ .Values.postgres.secret.keys.connectionString }}: {{ printf "postgresql://%s:%s@%s:%d/%s" .Values.postgres.auth.user .Values.postgres.auth.password (include "postgres.host") (int .Values.postgres.auth.port) .Values.postgres.auth.database | b64enc }} --- {{- end }} {{- if .Values.postgres.create }} diff --git a/deploy/charts/nebulous/templates/redis.yaml b/deploy/charts/nebulous/templates/redis.yaml index 557e8c7..1e8f8b0 100644 --- a/deploy/charts/nebulous/templates/redis.yaml +++ b/deploy/charts/nebulous/templates/redis.yaml @@ -8,7 +8,7 @@ metadata: {{- include "common.labels" . | nindent 4 }} type: Opaque data: - {{ .Values.redis.secret.keys.connection_string }}: {{ printf "redis://%s:%d/%d" (include "redis.host" .) (int .Values.redis.auth.port) (int .Values.redis.auth.database) | b64enc }} + {{ .Values.redis.secret.keys.connectionString }}: {{ printf "redis://%s:%d/%d" (include "redis.host" .) (int .Values.redis.auth.port) (int .Values.redis.auth.database) | b64enc }} {{ .Values.redis.secret.keys.password}}: {{ .Values.redis.auth.password | b64enc }} --- {{- end }} @@ -30,7 +30,31 @@ spec: labels: app: {{ include "redis.name" . }} spec: + hostNetwork: true + dnsPolicy: ClusterFirstWithHostNet containers: + - name: tailscale + image: tailscale/tailscale:latest + env: + - name: TS_STATE_DIR + value: /var/lib/tailscale + - name: TS_USERSPACE + value: "true" + - name: TS_AUTH_KEY + valueFrom: + secretKeyRef: + name: {{ .Values.tailscale.secret.name }} + key: {{ .Values.tailscale.secret.keys.authKey }} + - name: TS_EXTRA_ARGS + value: --login-server {{ include "tailscale.loginServer" . }} + volumeMounts: + - name: dev-net-tun + mountPath: /dev/net/tun + securityContext: + capabilities: + add: + - NET_ADMIN + - NET_RAW - name: redis image: "redis:{{ .Values.redis.imageTag }}" command: @@ -47,6 +71,11 @@ spec: key: {{ .Values.redis.secret.keys.password }} ports: - containerPort: 6379 + volumes: + - name: dev-net-tun + hostPath: + path: /dev/net/tun + type: CharDevice --- apiVersion: v1 kind: Service @@ -67,35 +96,4 @@ spec: port: {{ .Values.redis.auth.port }} targetPort: 6379 type: ClusterIP ---- -{{- if .Values.redis.ingress.enabled }} -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: {{ include "redis.serviceName" . }} - namespace: {{ include "nebulous.namespace" . }} - labels: - {{- include "common.labels" . | nindent 4 }} - {{- with .Values.redis.ingress.annotations }} - annotations: - {{- toYaml . | nindent 4 }} - {{- end }} -spec: - {{- with .Values.redis.ingress.ingressClassName }} - ingressClassName: {{.}} - {{- end }} - rules: - - http: - paths: - - backend: - service: - name: {{ include "redis.name" . }} - port: - number: {{ .Values.redis.auth.port }} - path: / - pathType: Prefix - {{- with .Values.redis.ingress.host }} - host: {{.}} - {{- end }} -{{- end }} {{- end }} diff --git a/deploy/charts/nebulous/values.yaml b/deploy/charts/nebulous/values.yaml index 55c04b0..43cfc6b 100644 --- a/deploy/charts/nebulous/values.yaml +++ b/deploy/charts/nebulous/values.yaml @@ -56,8 +56,6 @@ tailscale: # -- Name of the secret with the Redis connection string and password. name: "tailscale-secret" keys: - # -- The key in the secret containing the Tailscale host. - loginServer: "LOGIN_SERVER" # -- The key in the secret containing the Tailscale API key apiKey: "API_KEY" # -- The key in the secret containing the Tailscale auth key @@ -111,7 +109,7 @@ postgres: name: "postgres-secret" keys: # -- The key in the secret containing the Postgres connection string. - connection_string: "CONNECTION_STRING" + connectionString: "CONNECTION_STRING" # -- Manual configuration of the Postgres connection. Except for 'host', this information is also used if 'create' is true. auth: @@ -145,7 +143,7 @@ redis: name: "redis-secret" keys: # -- The key in the secret containing the Redis connection string. - connection_string: "CONNECTION_STRING" + connectionString: "CONNECTION_STRING" # -- The key in the secret containing the Redis password. password: "PASSWORD" @@ -167,17 +165,6 @@ redis: # -- Override the name of the Kubernetes service. nameOverride: "" - ingress: - # -- If enabled, create an Ingress resource. Ignored unless 'create' is true. - enabled: false - - # -- Annotations to add to the Ingress resource. - annotations: { } - # -- The ingress class. - ingressClassName: "" - # -- The host field of the Ingress rule. - host: "" - ## Headscale configuration headscale: # -- If true, create a Headscale deployment and service. Overrides tailscale configuration. Not recommended for production. @@ -186,7 +173,8 @@ headscale: namespaceOverride: "" # -- The Headscale image tag. imageTag: "latest" - # -- The domain under which the Headscale server is exposed. + # -- The domain under which the Headscale server is exposed. Required if create is true. + # The headscale server must be reachable at https://${domain}:443. domain: "" # -- Prefixes to allocate tailaddresses from. Must be within the IP ranges supported by the Tailscale client. @@ -198,7 +186,13 @@ headscale: dns: # -- The base domain for MagicDNS hostnames. Cannot be the same as the Headscale server's domain. # Refer to https://github.com/juanfont/headscale/blob/main/config-example.yaml for details. - base_domain: "" + baseDomain: "" + + log: + # -- The log level of the Headscale server. Options are "off", "trace", "debug", "info", "warn", "error". + level: "info" + # -- The log format of the Headscale server. Options are "text" or "json". + format: "text" # -- The Headscale DERP configuration. Either 'externalMapUrls' or 'configMap' must be set. derp: @@ -232,9 +226,28 @@ headscale: # -- The storage class of the PersistentVolumeClaim created for the Headscale private keys. storageClassName: "" + tls: + letsencrypt: + # -- The hostname for the Let's Encrypt certificate. Has to match the domain of the Headscale server. + hostname: "" + # -- The email address for the Let's Encrypt certificate. + email: "" + + # -- The name of the PersistentVolumeClaim for the Headscale Let's Encrypt cache. + claimName: "headscale-tls-pvc" + + # -- If true, create a PersistentVolumeClaim for the Headscale Let's Encrypt cache. + createPersistentVolumeClaim: true + # -- The size of the PersistentVolumeClaim created for the Headscale Let's Encrypt cache. + size: "16Mi" + # -- The storage class of the PersistentVolumeClaim created for the Headscale Let's Encrypt cache. + storageClassName: "" + service: # -- The port of the Kubernetes service. port: 80 + # -- The type of the Kubernetes service. Options are "ClusterIP", "NodePort", and "LoadBalancer". + type: "ClusterIP" # -- The annotations to add to the Kubernetes service. annotations: { } # -- Override the name of the Kubernetes service.