misc: zot registry, k8s OIDC, server configs, sandbox experiments, and notes

- docker-30/zot: add Zot OCI registry with on-demand sync to docker.io,
  registry.k8s.io, ghcr.io, quay.io
- kubernetes-kvm-terraform: wire Kanidm OIDC via structured
  AuthenticationConfiguration; add reference apiserver manifest and
  join-node-02 helper
- servers: reorganize shadow/ under servers/, add saint vhost config and
  utility-101 VM definition, add shadow hrajfrisbee.cz vhost and
  storage-23 notes
- experiments: add notes and configs for e2b dev VM, kata + firecracker
  on kube, microsandbox, orb-stack k3s (terraform + cloud-init), rke2
- vms/docker: document tailscale + node-exporter setup
- blog: stub post on Gateway API
- chore: gitignore tmp/, smtp_password, and the two local-only
  credential caches; add per-project .claude/settings.json

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-01 18:12:38 +02:00
parent 5ca27a832b
commit 80d0cc1168
34 changed files with 2814 additions and 1 deletions

View File

@@ -0,0 +1,14 @@
apiVersion: apiserver.config.k8s.io/v1beta1
kind: AuthenticationConfiguration
jwt:
- issuer:
url: https://idm.home.hrajfrisbee.cz/oauth2/openid/k8s
audiences:
- k8s
claimMappings:
username:
claim: preferred_username
prefix: ""
groups:
claim: groups
prefix: ""

View File

@@ -0,0 +1,155 @@
#!/usr/bin/env bash
# Manual equivalent of the cloud-init user_data for kube-node-33 (node_02).
# Run as root on the target VM.
#
# Before running, generate a fresh join command on the control plane:
# kubeadm token create --print-join-command
# Then paste it below.
set -euo pipefail
JOIN_COMMAND="kubeadm join 192.168.0.31:6443 --token <token> --discovery-token-ca-cert-hash sha256:<hash>"
# ---------------------------------------------------------------------------
# Hostname
# ---------------------------------------------------------------------------
hostnamectl set-hostname kube-node-33
# ---------------------------------------------------------------------------
# Packages
# ---------------------------------------------------------------------------
apt-get update
apt-get install -y \
qemu-guest-agent \
openssh-server \
apt-transport-https \
ca-certificates \
curl \
gnupg \
nvme-cli
systemctl enable --now qemu-guest-agent
systemctl enable --now ssh
# ---------------------------------------------------------------------------
# nvme-tcp
# ---------------------------------------------------------------------------
apt-get install -y linux-modules-extra-$(uname -r)
modprobe nvme-tcp
echo "nvme-tcp" >> /etc/modules-load.d/nvme-tcp.conf
# ---------------------------------------------------------------------------
# Kernel modules for Kubernetes
# ---------------------------------------------------------------------------
cat > /etc/modules-load.d/k8s.conf <<'EOF'
overlay
br_netfilter
EOF
modprobe overlay
modprobe br_netfilter
cat > /etc/sysctl.d/k8s.conf <<'EOF'
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sysctl --system
# ---------------------------------------------------------------------------
# containerd
# ---------------------------------------------------------------------------
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" \
> /etc/apt/sources.list.d/docker.list
apt-get update && apt-get install -y containerd.io
cat > /etc/containerd/config.toml <<'EOF'
version = 2
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
runtime_type = "io.containerd.runc.v2"
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
SystemdCgroup = true
[plugins."io.containerd.grpc.v1.cri".registry]
config_path = "/etc/containerd/certs.d"
EOF
# Registry mirrors pointing to Zot at 192.168.0.30:5000
mkdir -p \
/etc/containerd/certs.d/docker.io \
/etc/containerd/certs.d/registry.k8s.io \
/etc/containerd/certs.d/ghcr.io \
/etc/containerd/certs.d/quay.io
cat > /etc/containerd/certs.d/docker.io/hosts.toml <<'EOF'
server = "https://registry-1.docker.io"
[host."http://192.168.0.30:5000/v2/docker.io"]
capabilities = ["pull", "resolve"]
skip_verify = true
override_path = true
EOF
cat > /etc/containerd/certs.d/registry.k8s.io/hosts.toml <<'EOF'
server = "https://registry.k8s.io"
[host."http://192.168.0.30:5000/v2/registry.k8s.io"]
capabilities = ["pull", "resolve"]
skip_verify = true
override_path = true
EOF
cat > /etc/containerd/certs.d/ghcr.io/hosts.toml <<'EOF'
server = "https://ghcr.io"
[host."http://192.168.0.30:5000/v2/ghcr.io"]
capabilities = ["pull", "resolve"]
skip_verify = true
override_path = true
EOF
cat > /etc/containerd/certs.d/quay.io/hosts.toml <<'EOF'
server = "https://quay.io"
[host."http://192.168.0.30:5000/v2/quay.io"]
capabilities = ["pull", "resolve"]
skip_verify = true
override_path = true
EOF
systemctl restart containerd
# ---------------------------------------------------------------------------
# kubelet systemd drop-in
# ---------------------------------------------------------------------------
mkdir -p /etc/systemd/system/kubelet.service.d
cat > /etc/systemd/system/kubelet.service.d/10-containerd.conf <<'EOF'
[Unit]
After=containerd.service
Requires=containerd.service
[Service]
ExecStartPre=/bin/bash -c 'until [ -S /var/run/containerd/containerd.sock ]; do sleep 1; done'
ExecStartPre=/usr/bin/crictl info
EOF
# ---------------------------------------------------------------------------
# kubeadm / kubelet / kubectl v1.32
# ---------------------------------------------------------------------------
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.32/deb/Release.key \
| gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.32/deb/ /" \
> /etc/apt/sources.list.d/kubernetes.list
apt-get update && apt-get install -y kubelet kubeadm kubectl
apt-mark hold kubelet kubeadm kubectl
# ---------------------------------------------------------------------------
# kubectl shell helpers (available after next login / source)
# ---------------------------------------------------------------------------
cat > /etc/profile.d/kubectl.sh <<'EOF'
alias k='kubectl'
source <(kubectl completion bash)
complete -o default -F __start_kubectl k
EOF
# ---------------------------------------------------------------------------
# Join the cluster
# ---------------------------------------------------------------------------
$JOIN_COMMAND

View File

@@ -0,0 +1,132 @@
apiVersion: v1
kind: Pod
metadata:
annotations:
kubeadm.kubernetes.io/kube-apiserver.advertise-address.endpoint: 192.168.0.31:6443
creationTimestamp: null
labels:
component: kube-apiserver
tier: control-plane
name: kube-apiserver
namespace: kube-system
spec:
containers:
- command:
- kube-apiserver
- --advertise-address=192.168.0.31
- --allow-privileged=true
- --authorization-mode=Node,RBAC
- --client-ca-file=/etc/kubernetes/pki/ca.crt
- --enable-admission-plugins=NodeRestriction
- --enable-bootstrap-token-auth=true
- --etcd-cafile=/etc/kubernetes/pki/etcd/ca.crt
- --etcd-certfile=/etc/kubernetes/pki/apiserver-etcd-client.crt
- --etcd-keyfile=/etc/kubernetes/pki/apiserver-etcd-client.key
- --etcd-servers=https://127.0.0.1:2379
- --kubelet-client-certificate=/etc/kubernetes/pki/apiserver-kubelet-client.crt
- --kubelet-client-key=/etc/kubernetes/pki/apiserver-kubelet-client.key
- --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname
#- --oidc-issuer-url=https://idm.home.hrajfrisbee.cz/oauth2/openid/k8s
#- --oidc-client-id=k8s
#- --oidc-signing-algs=ES256
- --authentication-config=/etc/kubernetes/auth-config.yaml
- --proxy-client-cert-file=/etc/kubernetes/pki/front-proxy-client.crt
- --proxy-client-key-file=/etc/kubernetes/pki/front-proxy-client.key
- --requestheader-allowed-names=front-proxy-client
- --requestheader-client-ca-file=/etc/kubernetes/pki/front-proxy-ca.crt
- --requestheader-extra-headers-prefix=X-Remote-Extra-
- --requestheader-group-headers=X-Remote-Group
- --requestheader-username-headers=X-Remote-User
- --secure-port=6443
- --service-account-issuer=https://kubernetes.default.svc.cluster.local
- --service-account-key-file=/etc/kubernetes/pki/sa.pub
- --service-account-signing-key-file=/etc/kubernetes/pki/sa.key
- --service-cluster-ip-range=10.96.0.0/12
- --tls-cert-file=/etc/kubernetes/pki/apiserver.crt
- --tls-private-key-file=/etc/kubernetes/pki/apiserver.key
image: registry.k8s.io/kube-apiserver:v1.32.11
imagePullPolicy: IfNotPresent
livenessProbe:
failureThreshold: 8
httpGet:
host: 192.168.0.31
path: /livez
port: 6443
scheme: HTTPS
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 15
name: kube-apiserver
readinessProbe:
failureThreshold: 3
httpGet:
host: 192.168.0.31
path: /readyz
port: 6443
scheme: HTTPS
periodSeconds: 1
timeoutSeconds: 15
resources:
requests:
cpu: 250m
startupProbe:
failureThreshold: 24
httpGet:
host: 192.168.0.31
path: /livez
port: 6443
scheme: HTTPS
initialDelaySeconds: 10
periodSeconds: 10
timeoutSeconds: 15
volumeMounts:
- mountPath: /etc/ssl/certs
name: ca-certs
readOnly: true
- mountPath: /etc/ca-certificates
name: etc-ca-certificates
readOnly: true
- mountPath: /etc/kubernetes/pki
name: k8s-certs
readOnly: true
- mountPath: /usr/local/share/ca-certificates
name: usr-local-share-ca-certificates
readOnly: true
- mountPath: /usr/share/ca-certificates
name: usr-share-ca-certificates
readOnly: true
- mountPath: /etc/kubernetes
name: k8s-config
readOnly: true
hostNetwork: true
priority: 2000001000
priorityClassName: system-node-critical
securityContext:
seccompProfile:
type: RuntimeDefault
volumes:
- hostPath:
path: /etc/ssl/certs
type: DirectoryOrCreate
name: ca-certs
- hostPath:
path: /etc/ca-certificates
type: DirectoryOrCreate
name: etc-ca-certificates
- hostPath:
path: /etc/kubernetes/pki
type: DirectoryOrCreate
name: k8s-certs
- hostPath:
path: /usr/local/share/ca-certificates
type: DirectoryOrCreate
name: usr-local-share-ca-certificates
- hostPath:
path: /usr/share/ca-certificates
type: DirectoryOrCreate
name: usr-share-ca-certificates
- hostPath:
path: /etc/kubernetes
type: DirectoryOrCreate
name: k8s-config
status: {}