feat: run platform gateway through Tailscale sidecar
ci/woodpecker/push/woodpecker Pipeline was successful
ci/woodpecker/push/woodpecker Pipeline was successful
This commit is contained in:
+1
-1
@@ -11,7 +11,7 @@ AGENT_PORT=3100
|
||||
AGENT_GATEWAY_TOKEN=
|
||||
HEADSCALE_BASE_URL=https://atnmy-hs.duckdns.org
|
||||
HEADSCALE_API_KEY=
|
||||
HEADSCALE_GATEWAY_USERS=local-platform-gateway,platform-gateway
|
||||
HEADSCALE_GATEWAY_USERS=platform-gateway
|
||||
HEADSCALE_TEACHING_DEVICE_OWNER=tagged-devices
|
||||
LMS_GATEWAY_TOKEN=change-me
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ steps:
|
||||
volumes:
|
||||
- /home/future2/Studio_v2/woodpecker/kube/config:/tmp/kubeconfig:ro
|
||||
commands:
|
||||
- kubectl --kubeconfig=/tmp/kubeconfig apply -f k8s/platform-gateway.yaml
|
||||
- kubectl --kubeconfig=/tmp/kubeconfig -n studio-system rollout restart deployment/platform-gateway
|
||||
- kubectl --kubeconfig=/tmp/kubeconfig -n studio-system rollout status deployment/platform-gateway
|
||||
when:
|
||||
|
||||
@@ -30,3 +30,16 @@ Default URL: `http://localhost:4500`
|
||||
## Network Model
|
||||
|
||||
Students and instructors never connect directly to Headscale/Tailscale device endpoints. Clients call this gateway only. The gateway verifies auth, checks platform grants/session ownership, records audit context, and proxies allowed operations to the mobility agent running on each platform node.
|
||||
|
||||
## Kubernetes Tailscale Sidecar
|
||||
|
||||
The Kubernetes deployment runs a Tailscale sidecar in the same network namespace as
|
||||
the gateway. Create the one-time Headscale key secret before the first deployment:
|
||||
|
||||
```bash
|
||||
kubectl -n studio-system create secret generic platform-gateway-tailscale-auth \
|
||||
--from-literal=authkey='tskey-auth-...'
|
||||
```
|
||||
|
||||
The sidecar persists its machine state in `platform-gateway-tailscale-state`, so
|
||||
subsequent Gateway pod restarts do not consume another pre-auth key.
|
||||
|
||||
@@ -1,3 +1,33 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: platform-gateway
|
||||
namespace: studio-system
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: platform-gateway-tailscale-state
|
||||
namespace: studio-system
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["secrets"]
|
||||
verbs: ["get", "create", "update", "patch"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: platform-gateway-tailscale-state
|
||||
namespace: studio-system
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: platform-gateway
|
||||
namespace: studio-system
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: platform-gateway-tailscale-state
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
@@ -15,7 +45,30 @@ spec:
|
||||
labels:
|
||||
app: platform-gateway
|
||||
spec:
|
||||
serviceAccountName: platform-gateway
|
||||
containers:
|
||||
- name: tailscale
|
||||
image: tailscale/tailscale:stable
|
||||
env:
|
||||
- name: TS_KUBE_SECRET
|
||||
value: platform-gateway-tailscale-state
|
||||
- name: TS_AUTHKEY
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: platform-gateway-tailscale-auth
|
||||
key: authkey
|
||||
- name: TS_HOSTNAME
|
||||
value: platform-gateway
|
||||
- name: TS_USERSPACE
|
||||
value: "false"
|
||||
- name: TS_EXTRA_ARGS
|
||||
value: --login-server=https://atnmy-hs.duckdns.org --accept-routes
|
||||
securityContext:
|
||||
capabilities:
|
||||
add: ["NET_ADMIN"]
|
||||
volumeMounts:
|
||||
- name: dev-net-tun
|
||||
mountPath: /dev/net/tun
|
||||
- name: platform-gateway
|
||||
image: localhost:5000/platform-gateway:0.1.0
|
||||
imagePullPolicy: Always
|
||||
@@ -37,6 +90,11 @@ spec:
|
||||
port: 4500
|
||||
initialDelaySeconds: 15
|
||||
periodSeconds: 20
|
||||
volumes:
|
||||
- name: dev-net-tun
|
||||
hostPath:
|
||||
path: /dev/net/tun
|
||||
type: CharDevice
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
|
||||
+1
-1
@@ -21,7 +21,7 @@ export const config = {
|
||||
headscaleBaseUrl: required('HEADSCALE_BASE_URL', 'http://localhost:8080'),
|
||||
headscaleApiKey: process.env.HEADSCALE_API_KEY ?? '',
|
||||
headscaleTeachingDeviceOwner: (process.env.HEADSCALE_TEACHING_DEVICE_OWNER ?? 'tagged-devices').trim().replace(/@+$/, ''),
|
||||
headscaleGatewayUsers: (process.env.HEADSCALE_GATEWAY_USERS ?? process.env.HEADSCALE_GATEWAY_USER ?? 'local-platform-gateway')
|
||||
headscaleGatewayUsers: (process.env.HEADSCALE_GATEWAY_USERS ?? process.env.HEADSCALE_GATEWAY_USER ?? 'platform-gateway')
|
||||
.split(',')
|
||||
.map((user) => user.trim().replace(/@+$/, ''))
|
||||
.filter(Boolean),
|
||||
|
||||
Reference in New Issue
Block a user