Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions hack/k8s/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
auth-secret.yaml
84 changes: 84 additions & 0 deletions hack/k8s/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
This directory contains a generic starter deployment for running Scion in Kubernetes.

The base deploys a single Scion combo pod in the `scion` namespace with:

- Hub API
- Runtime Broker
- Web dashboard
- SQLite and local template storage on a PVC
- a `ClusterIP` service intended for `kubectl port-forward`
- development auth enabled by default for evaluation and local testing

The base intentionally does not assume any cluster-specific ingress, TLS, telemetry,
network policy, private registry, or node scheduling setup.

## Prerequisites

Scion does not currently publish pre-built images. Build and push the images you
want the cluster to use first.

For a quick start:

```bash
image-build/scripts/build-images.sh \
--registry ghcr.io/<your-org> \
--target all \
--platform linux/amd64 \
--push
```

If your cluster is multi-arch, use `--platform all` instead.

## Configure the base

1. Set the Scion server image:

```bash
cd hack/k8s
kustomize edit set image scion-server=ghcr.io/<your-org>/scion-server:latest
```

2. Edit `settings.yaml`:
- set `image_registry` to the registry where your Scion harness images were pushed
- keep `server.hub.public_url` as `http://127.0.0.1:8080` if you plan to access Scion through `kubectl port-forward`
- change `server.hub.public_url` and `server.auth.dev_mode` before exposing Scion outside the cluster

3. If you want stable web sessions or OAuth, copy `auth-secret.example.yaml` to
`auth-secret.yaml`, fill in the values, and apply it before the deployment:

```bash
cp auth-secret.example.yaml auth-secret.yaml
kubectl apply -f auth-secret.yaml
```

The deployment loads `scion-auth` as an optional secret, so the base still works
without it.

## Deploy

```bash
kubectl apply -k hack/k8s
kubectl -n scion rollout status deploy/scion
kubectl -n scion port-forward svc/scion 8080:80
```

Open <http://127.0.0.1:8080>.

With the default `dev_mode: true` setting, the web UI can be used without OAuth.
For CLI access, export the Hub endpoint and the generated dev token:

```bash
export SCION_HUB_ENDPOINT=http://127.0.0.1:8080
export SCION_DEV_TOKEN="$(kubectl -n scion exec deploy/scion -- cat /home/scion/.scion/dev-token)"
```

## Productionizing

Before using this outside a trusted environment:

- set `server.auth.dev_mode: false` in `settings.yaml`
- create `scion-auth` from `auth-secret.example.yaml`
- change `server.hub.public_url` to the external URL that users will visit
- add ingress or Gateway API resources for your cluster
- add image pull secrets if your server or harness images live in a private registry
- add network policies that match your cluster's API server, DNS, and egress rules
19 changes: 19 additions & 0 deletions hack/k8s/auth-secret.example.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
apiVersion: v1
kind: Secret
metadata:
name: scion-auth
namespace: scion
type: Opaque
stringData:
# Optional but recommended if you want login sessions to survive pod restarts.
SCION_SERVER_SESSION_SECRET: "<openssl rand -base64 32>"

# Example GitHub OAuth credentials. Remove these keys if you are not using GitHub.
SCION_SERVER_OAUTH_WEB_GITHUB_CLIENTID: "<github-web-client-id>"
SCION_SERVER_OAUTH_WEB_GITHUB_CLIENTSECRET: "<github-web-client-secret>"
SCION_SERVER_OAUTH_CLI_GITHUB_CLIENTID: "<github-cli-client-id>"
SCION_SERVER_OAUTH_CLI_GITHUB_CLIENTSECRET: "<github-cli-client-secret>"

# Optional if you want device-flow login.
SCION_SERVER_OAUTH_DEVICE_GITHUB_CLIENTID: "<github-device-client-id>"
SCION_SERVER_OAUTH_DEVICE_GITHUB_CLIENTSECRET: "<github-device-client-secret>"
95 changes: 95 additions & 0 deletions hack/k8s/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: scion
labels:
app.kubernetes.io/name: scion
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: scion
template:
metadata:
labels:
app.kubernetes.io/name: scion
spec:
serviceAccountName: scion
securityContext:
fsGroup: 1000
runAsNonRoot: true
runAsUser: 1000
runAsGroup: 1000
seccompProfile:
type: RuntimeDefault
containers:
- name: scion
image: scion-server:latest
imagePullPolicy: Always
command:
- /usr/local/bin/scion
args:
- server
- start
- --foreground
- --production
- --enable-hub
- --enable-runtime-broker
- --enable-web
- --web-port=8080
- --runtime-broker-port=9800
- --auto-provide
env:
- name: HOME
value: /home/scion
- name: SCION_LOG_LEVEL
value: info
envFrom:
- secretRef:
name: scion-auth
optional: true
ports:
- name: http
containerPort: 8080
- name: broker
containerPort: 9800
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: "2"
memory: 2Gi
readinessProbe:
httpGet:
path: /healthz
port: http
initialDelaySeconds: 10
periodSeconds: 5
timeoutSeconds: 5
livenessProbe:
httpGet:
path: /healthz
port: http
initialDelaySeconds: 20
periodSeconds: 10
timeoutSeconds: 5
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
volumeMounts:
- name: state
mountPath: /home/scion/.scion
- name: settings
mountPath: /home/scion/.scion/settings.yaml
subPath: settings.yaml
readOnly: true
volumes:
- name: state
persistentVolumeClaim:
claimName: scion-state
- name: settings
configMap:
name: scion-settings
17 changes: 17 additions & 0 deletions hack/k8s/kustomization.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization

namespace: scion

configMapGenerator:
- name: scion-settings
files:
- settings.yaml

resources:
- namespace.yaml
- serviceaccount.yaml
- rbac.yaml
- state-pvc.yaml
- deployment.yaml
- service.yaml
12 changes: 12 additions & 0 deletions hack/k8s/namespace.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
apiVersion: v1
kind: Namespace
metadata:
name: scion
labels:
app.kubernetes.io/name: scion
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/audit-version: latest
pod-security.kubernetes.io/enforce: restricted
pod-security.kubernetes.io/enforce-version: latest
pod-security.kubernetes.io/warn: restricted
pod-security.kubernetes.io/warn-version: latest
50 changes: 50 additions & 0 deletions hack/k8s/rbac.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: scion-runtime-manager
rules:
- apiGroups:
- ""
resources:
- pods
verbs:
- create
- get
- list
- patch
- update
- delete
- apiGroups:
- ""
resources:
- pods/exec
verbs:
- create
- get
- apiGroups:
- ""
resources:
- pods/log
verbs:
- get
- apiGroups:
- ""
resources:
- secrets
verbs:
- create
- get
- list
- delete
---
Comment on lines +37 to +39

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The secrets resource is missing the get verb. If the runtime manager needs to check for the existence of a secret before creating it, or if it needs to read secret metadata, the get permission is required. Without it, operations that rely on checking state before acting (like idempotency checks) will fail.

      - create
      - get
      - list
      - delete

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: scion-runtime-manager
subjects:
- kind: ServiceAccount
name: scion
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: scion-runtime-manager
16 changes: 16 additions & 0 deletions hack/k8s/service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
apiVersion: v1
kind: Service
metadata:
name: scion
spec:
selector:
app.kubernetes.io/name: scion
ports:
- name: http
port: 80
targetPort: http
protocol: TCP
Comment on lines +9 to +12

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The service only exposes the HTTP port (80). Since the deployment also runs a runtime broker on port 9800, this port should be included in the service definition to allow agents or other cluster components to reach the broker via the service DNS name.

    - name: http
      port: 80
      targetPort: http
      protocol: TCP
    - name: broker
      port: 9800
      targetPort: broker
      protocol: TCP

- name: broker
port: 9800
targetPort: broker
protocol: TCP
4 changes: 4 additions & 0 deletions hack/k8s/serviceaccount.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: scion
40 changes: 40 additions & 0 deletions hack/k8s/settings.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
schema_version: "1"

active_profile: remote

# Replace this with the registry where you pushed the Scion harness images.
image_registry: ghcr.io/example

runtimes:
kubernetes:
type: kubernetes
namespace: scion
list_all_namespaces: false

profiles:
remote:
runtime: kubernetes

server:
hub:
host: 0.0.0.0
# This default matches `kubectl port-forward svc/scion 8080:80`.
public_url: http://127.0.0.1:8080
broker:
enabled: true
hub_endpoint: http://127.0.0.1:8080
# Agent pods need a cluster-reachable endpoint, not the port-forward URL.
container_hub_endpoint: http://scion.scion.svc.cluster.local
broker_name: scion-k8s
broker_nickname: scion
database:
driver: sqlite
url: /home/scion/.scion/hub.db
storage:
provider: local
local_path: /home/scion/.scion/storage
auth:
# Convenient for evaluation. Disable this before exposing Scion publicly.
dev_mode: true
secrets:
backend: local
10 changes: 10 additions & 0 deletions hack/k8s/state-pvc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: scion-state
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 20Gi