This commit is contained in:
12
deploy/k8s/configmap.yaml
Normal file
12
deploy/k8s/configmap.yaml
Normal file
@@ -0,0 +1,12 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: kubeviz-config
|
||||
namespace: kubeviz
|
||||
data:
|
||||
ADDR: ":8080"
|
||||
SESSION_TTL: "30m"
|
||||
MAX_UPLOAD_SIZE: "5242880"
|
||||
COOKIE_SECURE: "true"
|
||||
LOG_LEVEL: "info"
|
||||
GIT_ALLOWED_HOSTS: "github.com,gitlab.com,bitbucket.org"
|
||||
60
deploy/k8s/deployment.yaml
Normal file
60
deploy/k8s/deployment.yaml
Normal file
@@ -0,0 +1,60 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: kubeviz
|
||||
namespace: kubeviz
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: kubeviz
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: kubeviz
|
||||
spec:
|
||||
automountServiceAccountToken: false
|
||||
securityContext:
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
containers:
|
||||
- name: kubeviz
|
||||
image: kubeviz:latest
|
||||
imagePullPolicy: IfNotPresent
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
runAsNonRoot: true
|
||||
capabilities:
|
||||
drop: ["ALL"]
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
name: http
|
||||
envFrom:
|
||||
- configMapRef:
|
||||
name: kubeviz-config
|
||||
volumeMounts:
|
||||
- name: tmp
|
||||
mountPath: /tmp
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 512Mi
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
initialDelaySeconds: 3
|
||||
periodSeconds: 10
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 20
|
||||
volumes:
|
||||
- name: tmp
|
||||
emptyDir: {}
|
||||
24
deploy/k8s/ingress.yaml
Normal file
24
deploy/k8s/ingress.yaml
Normal file
@@ -0,0 +1,24 @@
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: kubeviz
|
||||
namespace: kubeviz
|
||||
annotations:
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: "10m"
|
||||
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||
spec:
|
||||
tls:
|
||||
- hosts:
|
||||
- kubeviz.local
|
||||
secretName: kubeviz-tls
|
||||
rules:
|
||||
- host: kubeviz.local
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: kubeviz
|
||||
port:
|
||||
number: 80
|
||||
4
deploy/k8s/namespace.yaml
Normal file
4
deploy/k8s/namespace.yaml
Normal file
@@ -0,0 +1,4 @@
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: kubeviz
|
||||
13
deploy/k8s/service.yaml
Normal file
13
deploy/k8s/service.yaml
Normal file
@@ -0,0 +1,13 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: kubeviz
|
||||
namespace: kubeviz
|
||||
spec:
|
||||
selector:
|
||||
app: kubeviz
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
102
deploy/quadlet/README.md
Normal file
102
deploy/quadlet/README.md
Normal file
@@ -0,0 +1,102 @@
|
||||
# Quadlet Templates (AlmaLinux + Podman)
|
||||
|
||||
Files:
|
||||
- `kubeviz.container`: system-level Quadlet unit template
|
||||
- `kubeviz-traefik.container`: direct Traefik-label variant (shared Podman network)
|
||||
- `traefik.network`: optional shared network Quadlet
|
||||
- `kubeviz.env.example`: optional external environment file
|
||||
|
||||
## 1. Install template
|
||||
|
||||
```bash
|
||||
sudo mkdir -p /etc/containers/systemd
|
||||
sudo cp deploy/quadlet/kubeviz.container /etc/containers/systemd/kubeviz.container
|
||||
```
|
||||
|
||||
Alternative (Traefik-label mode):
|
||||
|
||||
```bash
|
||||
sudo cp deploy/quadlet/traefik.network /etc/containers/systemd/traefik.network
|
||||
sudo cp deploy/quadlet/kubeviz-traefik.container /etc/containers/systemd/kubeviz.container
|
||||
```
|
||||
|
||||
Optional env file:
|
||||
|
||||
```bash
|
||||
sudo mkdir -p /etc/kubeviz
|
||||
sudo cp deploy/quadlet/kubeviz.env.example /etc/kubeviz/kubeviz.env
|
||||
# then uncomment EnvironmentFile in kubeviz.container
|
||||
```
|
||||
|
||||
## 2. Set real image
|
||||
|
||||
Edit `/etc/containers/systemd/kubeviz.container` and replace:
|
||||
- `ghcr.io/REPLACE_ME/kubeviz:v0.1.0`
|
||||
|
||||
For Gitea CI/CD without external registry, use a stable local tag:
|
||||
|
||||
```ini
|
||||
Image=localhost/kubeviz:prod
|
||||
Pull=never
|
||||
```
|
||||
|
||||
## 3. Start service
|
||||
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable --now kubeviz.service
|
||||
sudo systemctl status kubeviz.service
|
||||
sudo journalctl -u kubeviz.service -f
|
||||
```
|
||||
|
||||
## 4. Update rollout
|
||||
|
||||
```bash
|
||||
sudo systemctl restart kubeviz.service
|
||||
```
|
||||
|
||||
Because `Pull=always` is set, Podman will pull the latest image for the configured tag on restart.
|
||||
|
||||
## 5. Traefik integration
|
||||
|
||||
Route `kubeviz.valtrix.systems` to `http://127.0.0.1:18080`.
|
||||
Keep `COOKIE_SECURE=true` in production.
|
||||
|
||||
If you use `kubeviz-traefik.container`, Traefik discovers KubeViz via labels and the shared `traefik` network instead of localhost port mapping.
|
||||
|
||||
## 6. Gitea pipeline (direct deploy on server)
|
||||
|
||||
Workflow template is included at:
|
||||
- `.gitea/workflows/deploy-kubeviz.yml`
|
||||
- `scripts/deploy-with-podman.sh`
|
||||
|
||||
The deploy script builds with Podman, tags `localhost/kubeviz:prod`, and restarts `kubeviz.service`.
|
||||
|
||||
Required sudo permissions for the Gitea runner user (example):
|
||||
|
||||
```text
|
||||
gitea-runner ALL=(root) NOPASSWD:/usr/bin/podman build *,/usr/bin/podman tag *,/usr/bin/systemctl restart kubeviz.service,/usr/bin/systemctl is-active kubeviz.service
|
||||
```
|
||||
|
||||
The user must be the one that executes the Gitea Actions runner service (often `gitea-runner`).
|
||||
Check it with:
|
||||
|
||||
```bash
|
||||
systemctl cat gitea-runner | grep -E '^User='
|
||||
```
|
||||
|
||||
For BasicAuth labels, use htpasswd hashes (not plain passwords), for example:
|
||||
|
||||
```bash
|
||||
htpasswd -nB smb
|
||||
```
|
||||
|
||||
Then set the generated value in:
|
||||
- `traefik.http.middlewares.kubeviz-auth.basicauth.users=smb:<hash>`
|
||||
|
||||
After updating sudoers:
|
||||
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl restart gitea-runner
|
||||
```
|
||||
47
deploy/quadlet/kubeviz-traefik.container
Normal file
47
deploy/quadlet/kubeviz-traefik.container
Normal file
@@ -0,0 +1,47 @@
|
||||
[Unit]
|
||||
Description=KubeViz behind Traefik (Podman network)
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Container]
|
||||
ContainerName=kubeviz
|
||||
Image=localhost/kubeviz:prod
|
||||
Pull=always
|
||||
|
||||
# Attach to the same user-defined network as Traefik.
|
||||
Network=traefik.network
|
||||
|
||||
Environment=TZ=Europe/Berlin
|
||||
Environment=ADDR=:8080
|
||||
Environment=SESSION_TTL=30m
|
||||
Environment=MAX_UPLOAD_SIZE=5242880
|
||||
Environment=COOKIE_SECURE=true
|
||||
Environment=LOG_LEVEL=info
|
||||
Environment=GIT_ALLOWED_HOSTS=github.com,gitlab.com,gitea.smb-corp.de
|
||||
|
||||
NoNewPrivileges=true
|
||||
ReadOnly=true
|
||||
Tmpfs=/tmp:rw,size=128m,mode=1777
|
||||
User=65532
|
||||
Group=65532
|
||||
|
||||
# Traefik labels (Podman provider)
|
||||
Label=traefik.enable=true
|
||||
Label=traefik.http.routers.kubeviz.rule=Host(`kubeviz.valtrix.systems`)
|
||||
Label=traefik.http.routers.kubeviz.entrypoints=websecure
|
||||
Label=traefik.http.routers.kubeviz.tls=true
|
||||
Label=traefik.http.routers.kubeviz.tls.certresolver=letsencrypt
|
||||
Label=traefik.http.routers.kubeviz.middlewares=kubeviz-sec-headers,kubeviz-auth
|
||||
Label=traefik.http.services.kubeviz.loadbalancer.server.port=8080
|
||||
Label=traefik.docker.network=traefik
|
||||
Label=traefik.http.middlewares.kubeviz-sec-headers.headers.customResponseHeaders.Content-Security-Policy=default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'self'; img-src 'self' data:; style-src 'self' 'unsafe-inline'; script-src 'self'; script-src-elem 'self' 'unsafe-inline'; connect-src 'self' wss: https:; font-src 'self' data:; worker-src 'self' blob:;
|
||||
Label=traefik.http.middlewares.kubeviz-auth.basicauth.users=smb:REPLACE_WITH_HTPASSWD_HASH
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
RestartSec=3
|
||||
TimeoutStartSec=90
|
||||
TimeoutStopSec=20
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
45
deploy/quadlet/kubeviz.container
Normal file
45
deploy/quadlet/kubeviz.container
Normal file
@@ -0,0 +1,45 @@
|
||||
[Unit]
|
||||
Description=KubeViz (Go Kubernetes manifest visualizer)
|
||||
After=network-online.target
|
||||
Wants=network-online.target
|
||||
|
||||
[Container]
|
||||
ContainerName=kubeviz
|
||||
Image=localhost/kubeviz:prod
|
||||
Pull=always
|
||||
|
||||
# Bind only on localhost; Traefik handles public ingress.
|
||||
PublishPort=127.0.0.1:18080:8080
|
||||
|
||||
# Runtime config
|
||||
Environment=ADDR=:8080
|
||||
Environment=SESSION_TTL=30m
|
||||
Environment=MAX_UPLOAD_SIZE=5242880
|
||||
Environment=COOKIE_SECURE=true
|
||||
Environment=LOG_LEVEL=info
|
||||
Environment=GIT_ALLOWED_HOSTS=github.com,gitlab.com,bitbucket.org
|
||||
|
||||
# Optional: keep env values in a separate file
|
||||
# EnvironmentFile=/etc/kubeviz/kubeviz.env
|
||||
|
||||
# Security hardening
|
||||
NoNewPrivileges=true
|
||||
ReadOnly=true
|
||||
Tmpfs=/tmp:rw,size=128m,mode=1777
|
||||
User=65532
|
||||
Group=65532
|
||||
|
||||
# Process / service behavior
|
||||
HealthCmd=/app/kubeviz --help
|
||||
HealthInterval=30s
|
||||
HealthTimeout=5s
|
||||
HealthRetries=3
|
||||
|
||||
[Service]
|
||||
Restart=always
|
||||
RestartSec=3
|
||||
TimeoutStartSec=90
|
||||
TimeoutStopSec=20
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
7
deploy/quadlet/kubeviz.env.example
Normal file
7
deploy/quadlet/kubeviz.env.example
Normal file
@@ -0,0 +1,7 @@
|
||||
# Copy to /etc/kubeviz/kubeviz.env and reference via EnvironmentFile in kubeviz.container
|
||||
ADDR=:8080
|
||||
SESSION_TTL=30m
|
||||
MAX_UPLOAD_SIZE=5242880
|
||||
COOKIE_SECURE=true
|
||||
LOG_LEVEL=info
|
||||
GIT_ALLOWED_HOSTS=github.com,gitlab.com,bitbucket.org
|
||||
6
deploy/quadlet/traefik.network
Normal file
6
deploy/quadlet/traefik.network
Normal file
@@ -0,0 +1,6 @@
|
||||
[Unit]
|
||||
Description=Shared network for Traefik-routed containers
|
||||
|
||||
[Network]
|
||||
NetworkName=traefik
|
||||
Driver=bridge
|
||||
Reference in New Issue
Block a user