Files
fips/examples/k8s-sidecar/pod.yaml
Johnathan Corgan 8d51dbd268 Move K8s sidecar from testing/ to examples/
The K8s sidecar is a standalone example, not a test harness — it has
no CI integration unlike testing/sidecar/. Move it to examples/
alongside sidecar-nostr-relay/ where it belongs. Update internal path
references in Dockerfile, build.sh, and README.
2026-03-19 19:36:39 +00:00

208 lines
6.8 KiB
YAML

# FIPS Kubernetes sidecar — example Pod manifest
#
# WARNING: The Secret below contains a placeholder nsec. Replace it with your
# real key before applying. Do NOT commit real keys to version control.
# Generate a fresh key with: openssl rand -hex 32
#
# Apply:
# kubectl apply -f pod.yaml
#
# Requirements on the node:
# - /dev/net/tun must exist (standard on all modern Linux kernels)
# - The container runtime must honour NET_ADMIN (true for containerd/CRI-O
# with default settings; may require a RuntimeClass tweak for gVisor)
#
# Kubernetes version: 1.28+
# -----------------------------------------------------------------------------
# Secret — node identity
# Replace the nsec value with your real key (hex or nsec1 bech32).
# In production, manage this with a secrets operator (External Secrets,
# Sealed Secrets, Vault Agent, etc.) rather than a plaintext manifest.
# -----------------------------------------------------------------------------
apiVersion: v1
kind: Secret
metadata:
name: fips-identity
type: Opaque
stringData:
nsec: "replace-this-with-your-hex-or-nsec1-secret-key"
---
apiVersion: v1
kind: Pod
metadata:
name: fips-sidecar-example
labels:
app: fips-sidecar-example
spec:
# Containers in the same Pod share the same network namespace automatically.
# The fips sidecar creates fips0; the app container sees it immediately.
#
# Start order: initContainers run first, then all containers start
# concurrently. If your app needs the TUN interface to be ready before it
# starts, use a readiness probe on the sidecar and a dependency in the app
# (or use a startup init container that waits for fips0 to appear).
# net.ipv6.* sysctls are namespaced per-pod in Linux. Declaring them here
# allows the fips sidecar entrypoint to set them at runtime via sysctl(8).
# bindv6only=0 means apps listening on 0.0.0.0 will also receive IPv6
# connections arriving via fips0, without needing to be rewritten.
# These are "unsafe" sysctls and require the kubelet --allowed-unsafe-sysctls
# flag or a corresponding RuntimeClass / PodSecurityPolicy exception.
securityContext:
sysctls:
- name: net.ipv6.conf.all.disable_ipv6
value: "0"
- name: net.ipv6.conf.default.disable_ipv6
value: "0"
- name: net.ipv6.bindv6only
value: "0"
volumes:
- name: tun-device
hostPath:
path: /dev/net/tun
type: CharDevice
# Optional: mount a pre-built fips.yaml instead of generating from env.
# - name: fips-config
# configMap:
# name: fips-config
containers:
# -----------------------------------------------------------------------
# FIPS sidecar — owns the network namespace setup
# -----------------------------------------------------------------------
- name: fips
image: your-registry.example.com/fips-sidecar:latest
imagePullPolicy: Always
securityContext:
capabilities:
add:
- NET_ADMIN # required: TUN creation and iptables
runAsNonRoot: false # fips needs root for iptables/TUN
runAsUser: 0
volumeMounts:
- name: tun-device
mountPath: /dev/net/tun
env:
# --- Identity (required) ---
- name: FIPS_NSEC
valueFrom:
secretKeyRef:
name: fips-identity
key: nsec
# --- Single peer shorthand ---
# Remove these and use FIPS_PEERS_JSON below for multiple peers.
- name: FIPS_PEER_NPUB
value: "" # e.g. npub1abc...
- name: FIPS_PEER_ADDR
value: "" # e.g. 203.0.113.10:2121
- name: FIPS_PEER_ALIAS
value: "gateway"
- name: FIPS_PEER_TRANSPORT
value: "udp"
# --- Multiple peers via JSON (overrides single-peer vars when non-empty) ---
# - name: FIPS_PEERS_JSON
# value: |
# [
# {"npub":"npub1abc...","alias":"gw1","addr":"203.0.113.10:2121","transport":"udp"},
# {"npub":"npub1def...","alias":"gw2","addr":"198.51.100.5:2121","transport":"udp"}
# ]
# --- Transport tuning ---
- name: FIPS_UDP_BIND
value: "0.0.0.0:2121"
# Uncomment to enable TCP transport (useful on networks that block UDP):
# - name: FIPS_TCP_BIND
# value: "0.0.0.0:8443"
# --- TUN interface ---
- name: FIPS_TUN_NAME
value: "fips0"
- name: FIPS_TUN_MTU
value: "1280"
# --- Network isolation ---
# "false" — fips0 is added alongside normal cluster networking. eth0
# continues to work as usual (services, DNS, other pods all reachable).
# "true" — eth0 is locked to FIPS transport only; app can only talk
# via fips0. Use for high-security mesh-only deployments.
- name: FIPS_ISOLATE
value: "false"
# Adjust if your CNI names the pod interface differently (e.g. ens3, net1).
- name: FIPS_POD_IFACE
value: "eth0"
# --- DNS ---
# Set to "false" if you manage pod DNS externally.
- name: FIPS_REWRITE_DNS
value: "true"
# --- Logging ---
- name: RUST_LOG
value: "info"
ports:
- name: fips-udp
containerPort: 2121
protocol: UDP
# - name: fips-tcp
# containerPort: 8443
# protocol: TCP
readinessProbe:
exec:
command: ["fipsctl", "show", "status"]
initialDelaySeconds: 5
periodSeconds: 10
failureThreshold: 3
livenessProbe:
exec:
command: ["fipsctl", "show", "status"]
initialDelaySeconds: 15
periodSeconds: 30
failureThreshold: 3
resources:
requests:
cpu: "50m"
memory: "32Mi"
limits:
cpu: "500m"
memory: "128Mi"
# -----------------------------------------------------------------------
# App container — shares the network namespace created by the fips sidecar
# -----------------------------------------------------------------------
- name: app
image: your-app:latest
imagePullPolicy: IfNotPresent
# No special capabilities needed — app uses fips0 like a normal interface.
securityContext:
runAsNonRoot: true
# The app sees: lo, eth0 (isolated by iptables), fips0 (mesh).
# All outbound traffic from the app flows through fips0.
# DNS resolution for <npub>.fips names works via dnsmasq on 127.0.0.1.
command: ["sleep", "infinity"] # replace with your actual workload command
resources:
requests:
cpu: "100m"
memory: "64Mi"
limits:
cpu: "1000m"
memory: "512Mi"
# Restart policy for the Pod. Use "Always" for long-running workloads.
restartPolicy: Always