PrivateNetwork: Configure cluster proxy backend
Change-Id: Ieeca2da6bd69ee3a440960ff3d4cdb9371f3a8c6
diff --git a/core/headscale/main.go b/core/headscale/main.go
index c2cfcf5..d4a129f 100644
--- a/core/headscale/main.go
+++ b/core/headscale/main.go
@@ -131,7 +131,7 @@
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
- if err := s.client.createUser(req.Name); err != nil {
+ if err := s.client.createUser(req.Name); err != nil && !errors.Is(err, ErrorAlreadyExists) {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
diff --git a/core/installer/values-tmpl/private-network.cue b/core/installer/values-tmpl/private-network.cue
index c22e5fc..b43ab1d 100644
--- a/core/installer/values-tmpl/private-network.cue
+++ b/core/installer/values-tmpl/private-network.cue
@@ -23,7 +23,13 @@
tag: "v1.8.0"
pullPolicy: "IfNotPresent"
}
- "tailscale-proxy": {
+ nginx: {
+ repository: "library"
+ name: "nginx"
+ tag: "1.27.1-alpine3.20-slim"
+ pullPolicy: "IfNotPresent"
+ }
+ tailscale: {
repository: "tailscale"
name: "tailscale"
tag: "v1.42.0"
@@ -44,6 +50,12 @@
branch: "main"
path: "charts/access-secrets"
}
+ service: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/service"
+ }
"ingress-nginx": {
kind: "GitRepository"
address: "https://code.v1.dodo.cloud/helm-charts"
@@ -62,6 +74,12 @@
branch: "main"
path: "charts/port-allocator"
}
+ headscaleUser: {
+ kind: "GitRepository"
+ address: "https://code.v1.dodo.cloud/helm-charts"
+ branch: "main"
+ path: "charts/headscale-user"
+ }
}
_ingressPrivate: "\(global.id)-ingress-private"
@@ -79,6 +97,18 @@
serviceAccountName: "\(global.id)-nginx-private"
}
}
+ "headscale-user": {
+ chart: charts.headscaleUser
+ values: {
+ resourceName: "private-network-proxy-backend"
+ username: "private-network-proxy"
+ headscaleApiAddress: "http://headscale-api.\(global.namespacePrefix)app-headscale.svc.cluster.local"
+ preAuthKey: {
+ enabled: true
+ secretName: _clusterProxySecretName
+ }
+ }
+ }
"ingress-nginx": {
chart: charts["ingress-nginx"]
values: {
@@ -108,6 +138,49 @@
extraArgs: {
"default-ssl-certificate": "\(_ingressPrivate)/cert-wildcard.\(global.privateDomain)"
}
+ extraVolumes: [{
+ name: _proxyBackendConfigName
+ configMap: {
+ name: _proxyBackendConfigName
+ }
+ }]
+ extraContainers: [{
+ name: "proxy"
+ image: images.tailscale.fullNameWithTag
+ securityContext: {
+ capabilities: {
+ add: ["NET_ADMIN"]
+ }
+ privileged: true
+ }
+ env: [{
+ name: "TS_KUBE_SECRET"
+ value: _clusterProxySecretName
+ }, {
+ name: "TS_HOSTNAME"
+ value: "cluster-proxy"
+ }, {
+ name: "TS_EXTRA_ARGS"
+ value: "--login-server=https://headscale.\(global.domain)"
+ }, {
+ name: "TS_USERSPACE"
+ value: "false"
+ }]
+ }, {
+ name: "proxy-backend"
+ image: images.nginx.fullNameWithTag
+ imagePullPolicy: images.nginx.pullPolicy
+ ports: [{
+ name: "proxy"
+ containerPort: 9090
+ protocol: "TCP"
+ }]
+ volumeMounts: [{
+ name: _proxyBackendConfigName
+ mountPath: "/etc/nginx"
+ readOnly: true
+ }]
+ }]
admissionWebhooks: {
enabled: false
}
@@ -130,9 +203,9 @@
username: input.privateNetwork.username // TODO(gio): maybe install headscale-user chart separately?
preAuthKeySecret: "headscale-preauth-key"
image: {
- repository: images["tailscale-proxy"].fullName
- tag: images["tailscale-proxy"].tag
- pullPolicy: images["tailscale-proxy"].pullPolicy
+ repository: images.tailscale.fullName
+ tag: images.tailscale.tag
+ pullPolicy: images.tailscale.pullPolicy
}
}
}
@@ -149,5 +222,57 @@
}
}
}
+ // TODO(gio): Generate proxy-backend-config as well
+ "proxy-backend-service": {
+ chart: charts.service
+ values: {
+ name: "proxy-backend-service"
+ type: "ClusterIP"
+ selector: {
+ "app.kubernetes.io/component": "controller"
+ "app.kubernetes.io/instance": "ingress-nginx"
+ "app.kubernetes.io/name": "ingress-nginx"
+ }
+ ports:[{
+ name: "http"
+ port: 80
+ targetPort: 9090
+ protocol: "TCP"
+ }]
+ }
+ }
}
}
+resources: {
+ "proxy-backend-config": {
+ apiVersion: "v1"
+ kind: "ConfigMap"
+ metadata: {
+ name: "proxy-backend-config"
+ namespace: release.namespace
+ }
+ data: {
+ "nginx.conf": """
+worker_processes 1;
+worker_rlimit_nofile 8192;
+events {
+ worker_connections 1024;
+}
+http {
+ map $http_host $backend {
+ }
+ server {
+ listen 9090;
+ location / {
+ resolver 135.181.48.180;
+ proxy_pass http://$backend;
+ }
+ }
+}
+"""
+ }
+ }
+}
+
+_clusterProxySecretName: "cluster-proxy-preauthkey"
+_proxyBackendConfigName: "proxy-backend-config"