chore: remove zot stack

This commit is contained in:
Brad Stein 2025-12-16 14:10:04 -03:00
parent 3066db793d
commit 8b9fc8ff1c
14 changed files with 0 additions and 468 deletions

View File

@ -9,4 +9,3 @@ resources:
- ../../services/monitoring
- ../../services/pegasus
- ../../services/vault
- ../../services/zot

View File

@ -2,7 +2,6 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- zot/kustomization.yaml
- gitea/kustomization.yaml
- vault/kustomization.yaml
- jitsi/kustomization.yaml

View File

@ -1,18 +0,0 @@
# clusters/atlas/flux-system/applications/zot/kustomization.yaml
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: zot
namespace: flux-system
spec:
interval: 10m
path: ./services/zot
targetNamespace: zot
prune: false
sourceRef:
kind: GitRepository
name: flux-system
namespace: flux-system
wait: true
dependsOn:
- name: core

View File

@ -1,76 +0,0 @@
#!/usr/bin/env bash
# Sync Keycloak users into Zot htpasswd.
# Intended to be rendered into a ConfigMap/Job; keep real secrets out of git.
set -euo pipefail
require() { command -v "$1" >/dev/null 2>&1 || { echo "missing required binary: $1" >&2; exit 1; }; }
require curl; require jq; require kubectl; require htpasswd
: "${KEYCLOAK_URL:=https://sso.bstein.dev}"
: "${KEYCLOAK_REALM:=atlas}"
: "${KEYCLOAK_CLIENT_ID:?set KEYCLOAK_CLIENT_ID or export via secret}"
: "${KEYCLOAK_CLIENT_SECRET:?set KEYCLOAK_CLIENT_SECRET or export via secret}"
: "${ZOT_NAMESPACE:=zot}"
: "${HTPASSWD_SECRET_NAME:=zot-htpasswd}"
: "${DEFAULT_PASSWORD:=TempSsoPass!2025}"
: "${UI_PROXY_USER:=zot-ui-proxy}"
: "${UI_PROXY_PASSWORD:=TempSsoUiPass!2025}"
fetch_token() {
curl -fsS -X POST \
-d "grant_type=client_credentials" \
-d "client_id=${KEYCLOAK_CLIENT_ID}" \
-d "client_secret=${KEYCLOAK_CLIENT_SECRET}" \
"${KEYCLOAK_URL}/realms/${KEYCLOAK_REALM}/protocol/openid-connect/token" \
| jq -r '.access_token'
}
pull_users() {
local token="$1"
curl -fsS -H "Authorization: Bearer ${token}" \
"${KEYCLOAK_URL}/admin/realms/${KEYCLOAK_REALM}/users?max=500" \
| jq -r '.[] | select(.enabled == true) | select(.username | startswith("service-account-") | not) | .username'
}
decode_secret_file() {
local ns="$1" name="$2" key="$3" out="$4"
if kubectl -n "${ns}" get secret "${name}" >/dev/null 2>&1; then
kubectl -n "${ns}" get secret "${name}" -o "jsonpath={.data.${key}}" | base64 -d > "${out}" || true
else
: > "${out}"
fi
}
ensure_htpasswd_line() {
local user="$1" password="$2" file="$3"
if ! grep -q "^${user}:" "${file}" 2>/dev/null; then
htpasswd -nbB "${user}" "${password}" >> "${file}"
echo "added user ${user} to htpasswd"
fi
}
main() {
local token tmp existing
tmp="$(mktemp)"
existing="$(mktemp)"
trap 'rm -f "${tmp}" "${existing}"' EXIT
decode_secret_file "${ZOT_NAMESPACE}" "${HTPASSWD_SECRET_NAME}" htpasswd "${existing}"
cp "${existing}" "${tmp}"
ensure_htpasswd_line "${UI_PROXY_USER}" "${UI_PROXY_PASSWORD}" "${tmp}"
token="$(fetch_token)"
readarray -t users < <(pull_users "${token}")
for user in "${users[@]}"; do
ensure_htpasswd_line "${user}" "${DEFAULT_PASSWORD}" "${tmp}"
done
kubectl create secret generic "${HTPASSWD_SECRET_NAME}" \
--namespace "${ZOT_NAMESPACE}" \
--from-file=htpasswd="${tmp}" \
--dry-run=client -o yaml | kubectl apply -f -
}
main "$@"

View File

@ -1,47 +0,0 @@
# services/zot/config.map
apiVersion: v1
kind: ConfigMap
metadata:
name: zot-config
namespace: zot
data:
config.json: |
{
"storage": {
"rootDirectory": "/var/lib/registry",
"dedupe": true,
"gc": true,
"gcDelay": "1h",
"gcInterval": "1h"
},
"http": {
"address": "0.0.0.0",
"port": "5000",
"realm": "zot-registry",
"compat": ["docker2s2"],
"auth": {
"htpasswd": { "path": "/etc/zot/htpasswd" }
},
"accessControl": {
"repositories": {
"**": {
"policies": [
{ "users": ["bstein", "zot-ui-proxy"], "actions": ["read", "create", "update", "delete"] }
],
"defaultPolicy": [],
"anonymousPolicy": []
}
},
"adminPolicy": {
"users": ["bstein", "zot-ui-proxy"],
"actions": ["read", "create", "update", "delete"]
}
}
},
"log": { "level": "info" },
"extensions": {
"ui": { "enable": true },
"search": { "enable": true },
"metrics": { "enable": true }
}
}

View File

@ -1,102 +0,0 @@
# services/zot/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: zot
namespace: zot
labels: { app: zot }
spec:
replicas: 1
selector:
matchLabels: { app: zot }
template:
metadata:
labels: { app: zot }
spec:
nodeSelector:
node-role.kubernetes.io/worker: "true"
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: hardware
operator: In
values: ["rpi4","rpi5"]
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 50
preference:
matchExpressions:
- key: hardware
operator: In
values: ["rpi4"]
containers:
- name: zot
image: ghcr.io/project-zot/zot-linux-arm64:v2.1.8
imagePullPolicy: IfNotPresent
args: ["serve", "/etc/zot/config.json"]
env:
- name: UI_PROXY_HTPASSWD
value: "zot-ui-proxy:$2y$05$ctfbLo5KBoNA6pluLGGWde6TK8eOPnIH9u8x/IivAhcE/k0qCCR3y"
ports:
- { name: http, containerPort: 5000 }
volumeMounts:
- name: cfg
mountPath: /etc/zot/config.json
subPath: config.json
readOnly: true
- name: htpasswd-merged
mountPath: /etc/zot/htpasswd
subPath: htpasswd
- name: zot-data
mountPath: /var/lib/registry
readinessProbe:
tcpSocket:
port: 5000
initialDelaySeconds: 2
periodSeconds: 5
livenessProbe:
tcpSocket:
port: 5000
initialDelaySeconds: 5
periodSeconds: 10
resources:
requests: { cpu: "50m", memory: "64Mi" }
initContainers:
- name: merge-htpasswd
image: busybox:1.36
command:
- sh
- -c
- |
set -e
if [ -f /src/htpasswd ]; then
cp /src/htpasswd /merged/htpasswd
else
touch /merged/htpasswd
fi
if [ -n "${UI_PROXY_HTPASSWD}" ]; then
echo "${UI_PROXY_HTPASSWD}" >> /merged/htpasswd
fi
env:
- name: UI_PROXY_HTPASSWD
value: "zot-ui-proxy:$2y$05$ctfbLo5KBoNA6pluLGGWde6TK8eOPnIH9u8x/IivAhcE/k0qCCR3y"
volumeMounts:
- name: htpasswd-source
mountPath: /src
readOnly: true
- name: htpasswd-merged
mountPath: /merged
volumes:
- name: cfg
configMap:
name: zot-config
- name: htpasswd-source
secret:
secretName: zot-htpasswd
optional: true
- name: htpasswd-merged
emptyDir: {}
- name: zot-data
persistentVolumeClaim:
claimName: zot-data

View File

@ -1,54 +0,0 @@
# services/zot/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: zot-cli
namespace: zot
annotations:
cert-manager.io/cluster-issuer: letsencrypt
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
traefik.ingress.kubernetes.io/router.middlewares: zot-zot-resp-headers@kubernetescrd
spec:
ingressClassName: traefik
tls:
- hosts: [ "cli.registry.bstein.dev" ]
secretName: cli-registry-bstein-dev-tls
rules:
- host: cli.registry.bstein.dev
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: zot
port:
number: 5000
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: zot-ui
namespace: zot
annotations:
cert-manager.io/cluster-issuer: letsencrypt
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.tls: "true"
traefik.ingress.kubernetes.io/router.middlewares: zot-zot-resp-headers@kubernetescrd
spec:
ingressClassName: traefik
tls:
- hosts: [ "web.registry.bstein.dev" ]
secretName: web-registry-bstein-dev-tls
rules:
- host: web.registry.bstein.dev
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: zot-oauth2-proxy
port:
number: 80

View File

@ -1,13 +0,0 @@
# services/zot/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- namespace.yaml
- pvc.yaml
- deployment.yaml
- configmap.yaml
- service.yaml
- oauth2-proxy-deployment.yaml
- oauth2-proxy-service.yaml
- ingress.yaml
- middleware.yaml

View File

@ -1,26 +0,0 @@
# services/zot/middleware.yaml
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
name: zot-resp-headers
namespace: zot
spec:
headers:
customResponseHeaders:
Docker-Distribution-Api-Version: "registry/2.0"
accessControlAllowOriginList:
- "*"
accessControlAllowCredentials: true
accessControlAllowHeaders:
- Authorization
- Content-Type
- Docker-Distribution-Api-Version
- X-Registry-Auth
accessControlAllowMethods:
- GET
- HEAD
- OPTIONS
- POST
- PUT
- PATCH
- DELETE

View File

@ -1,5 +0,0 @@
# services/zot/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: zot

View File

@ -1,84 +0,0 @@
# services/zot/oauth2-proxy-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: zot-oauth2-proxy
namespace: zot
labels: { app: zot-oauth2-proxy }
spec:
replicas: 1
selector:
matchLabels: { app: zot-oauth2-proxy }
template:
metadata:
labels: { app: zot-oauth2-proxy }
spec:
nodeSelector:
node-role.kubernetes.io/worker: "true"
affinity:
nodeAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 50
preference:
matchExpressions:
- key: hardware
operator: In
values: ["rpi4","rpi5"]
containers:
- name: oauth2-proxy
image: quay.io/oauth2-proxy/oauth2-proxy:v7.6.0
imagePullPolicy: IfNotPresent
args:
- --provider=oidc
- --redirect-url=https://web.registry.bstein.dev/oauth2/callback
- --oidc-issuer-url=https://sso.bstein.dev/realms/atlas
- --scope=openid profile email
- --email-domain=*
- --cookie-domain=web.registry.bstein.dev
- --cookie-name=_zot_ui_oauth
- --set-xauthrequest=true
- --set-authorization-header=false
- --pass-authorization-header=false
- --pass-access-token=false
- --pass-basic-auth=true
- --cookie-secure=true
- --cookie-samesite=lax
- --cookie-refresh=20m
- --cookie-expire=168h
- --upstream=http://zot-ui-proxy:TempSsoUiPass%212025@zot:5000
- --http-address=0.0.0.0:4180
- --skip-provider-button=true
- --skip-jwt-bearer-tokens=true
env:
- name: OAUTH2_PROXY_CLIENT_ID
valueFrom:
secretKeyRef:
name: zot-oidc
key: client_id
- name: OAUTH2_PROXY_CLIENT_SECRET
valueFrom:
secretKeyRef:
name: zot-oidc
key: client_secret
- name: OAUTH2_PROXY_COOKIE_SECRET
valueFrom:
secretKeyRef:
name: zot-oidc
key: client_secret
ports:
- containerPort: 4180
name: http
readinessProbe:
httpGet:
path: /ping
port: 4180
initialDelaySeconds: 5
periodSeconds: 10
livenessProbe:
httpGet:
path: /ping
port: 4180
initialDelaySeconds: 20
periodSeconds: 20
resources:
requests: { cpu: "25m", memory: "64Mi" }

View File

@ -1,14 +0,0 @@
# services/zot/oauth2-proxy-service.yaml
apiVersion: v1
kind: Service
metadata:
name: zot-oauth2-proxy
namespace: zot
labels: { app: zot-oauth2-proxy }
spec:
type: ClusterIP
selector: { app: zot-oauth2-proxy }
ports:
- name: http
port: 80
targetPort: 4180

View File

@ -1,13 +0,0 @@
# services/zot/pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: zot-data
namespace: zot
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 25Gi
storageClassName: asteria

View File

@ -1,14 +0,0 @@
# services/zot/service.yaml
apiVersion: v1
kind: Service
metadata:
name: zot
namespace: zot
labels: { app: zot }
spec:
type: ClusterIP
selector: { app: zot }
ports:
- name: http
port: 5000
targetPort: 5000