Compare commits
25
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
07dd6097ec | ||
|
|
60361d4c8a | ||
|
|
a8cef5de1b | ||
|
|
505802dad5 | ||
|
|
ba66b604d4 | ||
|
|
4fbc49fc8c | ||
|
|
f493c9fe52 | ||
|
|
8a3c66eb2e | ||
|
|
9928999da4 | ||
|
|
b3def28f7c | ||
|
|
93dbcdb2fb | ||
|
|
47bf16cfac | ||
|
|
4664de8f97 | ||
|
|
fb52e4be88 | ||
|
|
f11a71c33f | ||
|
|
29326eead3 | ||
|
|
eb09b1b2a3 | ||
|
|
dd3a1f1e90 | ||
|
|
98a0462137 | ||
|
|
9aef2e0669 | ||
|
|
fd7597ddc2 | ||
|
|
10b0c1b853 | ||
|
|
674169cb08 | ||
|
|
0c6174b7a6 | ||
|
|
76888c3771 |
@@ -350,17 +350,17 @@ steps:
|
||||
--destination gitea.renner.uno/gitea_admin/heating-can:$TAG \
|
||||
--destination gitea.renner.uno/gitea_admin/heating-can:latest
|
||||
|
||||
# netbird-proxy-services: the controller that reconciles NetBird reverse-proxy
|
||||
# netbird-service-sync: the controller that reconciles NetBird reverse-proxy
|
||||
# services (public Ingress hosts -> TLS passthrough -> Traefik ClusterIP).
|
||||
# Runtime artifact like heating-can; same registry so the audit tracks it.
|
||||
- name: build-netbird-proxy-services
|
||||
- name: build-netbird-service-sync
|
||||
image: registry.gitlab.com/gitlab-ci-utils/container-images/kaniko:v1.25.18-debug
|
||||
directory: ci/images/netbird-proxy-services
|
||||
directory: ci/images/netbird-service-sync
|
||||
depends_on: []
|
||||
when:
|
||||
- event: deployment
|
||||
- event: push
|
||||
path: ["ci/images/netbird-proxy-services/**", ".woodpecker/build-ci-images.yml"]
|
||||
path: ["ci/images/netbird-service-sync/**", ".woodpecker/build-ci-images.yml"]
|
||||
environment:
|
||||
GITEA_USER: gitea_admin
|
||||
GITEA_TOKEN:
|
||||
@@ -374,11 +374,11 @@ steps:
|
||||
/kaniko/executor \
|
||||
--context . \
|
||||
--dockerfile Containerfile \
|
||||
--destination gitea.renner.uno/gitea_admin/netbird-proxy-services:$TAG \
|
||||
--destination gitea.renner.uno/gitea_admin/netbird-proxy-services:latest
|
||||
--destination gitea.renner.uno/gitea_admin/netbird-service-sync:$TAG \
|
||||
--destination gitea.renner.uno/gitea_admin/netbird-service-sync:latest
|
||||
|
||||
# wiki-index: embedding index over the Notes repo's wiki/, fed from Gitea and
|
||||
# queried by ~/Notes/bin/wiki_rank.py. Runtime artifact like netbird-proxy-services.
|
||||
# queried by ~/Notes/bin/wiki_rank.py. Runtime artifact like netbird-service-sync.
|
||||
- name: build-wiki-index
|
||||
image: registry.gitlab.com/gitlab-ci-utils/container-images/kaniko:v1.25.18-debug
|
||||
directory: ci/images/wiki-index
|
||||
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
# netbird-proxy-services: reconciles NetBird reverse-proxy services (public
|
||||
# netbird-service-sync: reconciles NetBird reverse-proxy services (public
|
||||
# domains -> TLS passthrough -> Traefik ClusterIP) from Ingresses carrying the
|
||||
# public label. Standard library only, so the image is the interpreter plus one
|
||||
# file; runs unprivileged as its own user.
|
||||
+5
-5
@@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
"""netbird-proxy-services: reconcile NetBird reverse-proxy services from Ingresses.
|
||||
"""netbird-service-sync: reconcile NetBird reverse-proxy services from Ingresses.
|
||||
|
||||
Source of truth: every Ingress carrying the public label (dns.renner.uno/public).
|
||||
For each host on such an Ingress the NetBird management gets one reverse-proxy
|
||||
@@ -30,11 +30,11 @@ import urllib.error
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
|
||||
LOG = logging.getLogger("netbird-proxy-services")
|
||||
LOG = logging.getLogger("netbird-service-sync")
|
||||
|
||||
NB = os.environ.get("NB_MANAGEMENT_URL", "https://netbird.renner.uno").rstrip("/")
|
||||
BAO_ADDR = os.environ.get("BAO_ADDR", "http://openbao.openbao.svc.cluster.local:8200").rstrip("/")
|
||||
BAO_ROLE = os.environ.get("BAO_ROLE", "netbird-proxy-services")
|
||||
BAO_ROLE = os.environ.get("BAO_ROLE", "netbird-service-sync")
|
||||
BAO_PAT_PATH = os.environ.get("BAO_PAT_PATH", "homelab/data/infrastructure/secret-rotators-bootstrap/netbird")
|
||||
BAO_PAT_KEY = os.environ.get("BAO_PAT_KEY", "pat")
|
||||
SERVICE_CIDR = os.environ.get("SERVICE_CIDR", "10.96.0.0/12")
|
||||
@@ -156,7 +156,7 @@ def ensure_network(nb):
|
||||
if n["name"] == NETWORK_NAME:
|
||||
return n["id"]
|
||||
n = nb.post("networks", {"name": NETWORK_NAME,
|
||||
"description": "managed by netbird-proxy-services; public ingress via TLS passthrough"})
|
||||
"description": "managed by netbird-service-sync; public ingress via TLS passthrough"})
|
||||
LOG.info("created network %s (%s)", NETWORK_NAME, n["id"])
|
||||
return n["id"]
|
||||
|
||||
@@ -166,7 +166,7 @@ def ensure_resource(nb, net):
|
||||
if r.get("address") == SERVICE_CIDR:
|
||||
return r["id"]
|
||||
r = nb.post(f"networks/{net}/resources", {"name": "cluster service CIDR", "address": SERVICE_CIDR,
|
||||
"description": "managed by netbird-proxy-services",
|
||||
"description": "managed by netbird-service-sync",
|
||||
"enabled": True, "groups": []})
|
||||
LOG.info("created subnet resource %s (%s)", SERVICE_CIDR, r["id"])
|
||||
return r["id"]
|
||||
@@ -118,14 +118,21 @@ spec:
|
||||
# traffic out to the VIP and back (which fails with L2 announcements).
|
||||
lbExternalClusterIP: true
|
||||
cni:
|
||||
# Multus (kubernetes/infrastructure/multus) runs alongside Cilium and
|
||||
# writes 00-multus.conf to /etc/cni/net.d so kubelet picks multus
|
||||
# first; multus then delegates to Cilium's 05-cilium.conflist via
|
||||
# clusterNetwork. The default `exclusive: true` makes cilium-cni's
|
||||
# install step rename anything alphabetically before its own config
|
||||
# to *.cilium_bak on every reconcile, which kept nuking multus.
|
||||
# Setting it false lets multus's config coexist.
|
||||
# Multus is the only writer of /etc/cni/net.d (#832): Cilium's conflist
|
||||
# goes to /etc/cni/net.d/multus/, which the container runtime does not
|
||||
# read, and Multus delegates to it via clusterNetwork. Without this a
|
||||
# pod created after a reboot, before Multus rewrote 00-multus.conf, came
|
||||
# up with Cilium alone. See kubernetes/infrastructure/multus.
|
||||
confPath: /etc/cni/net.d/multus
|
||||
# The default `exclusive: true` renames other configs in the conf dir to
|
||||
# *.cilium_bak on every reconcile, which kept nuking multus.
|
||||
exclusive: false
|
||||
# One agent at a time: the chart default of 2 restarts two of three
|
||||
# nodes' datapath at once.
|
||||
updateStrategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxUnavailable: 1
|
||||
# Talos-specific settings
|
||||
securityContext:
|
||||
capabilities:
|
||||
|
||||
@@ -19,7 +19,7 @@ resources:
|
||||
- cloudnative-pg/
|
||||
- mariadb-operator/
|
||||
- netbird-ingress/
|
||||
- netbird-proxy-services/
|
||||
- netbird-service-sync/
|
||||
- coredns-config/
|
||||
- k8s-gateway/
|
||||
- external-dns-unifi/
|
||||
|
||||
@@ -111,10 +111,18 @@ metadata:
|
||||
name: multus
|
||||
namespace: kube-system
|
||||
---
|
||||
# Multus is the only writer of /etc/cni/net.d (#832). Cilium writes its conflist
|
||||
# to /etc/cni/net.d/multus/, a subdirectory the container runtime does not read
|
||||
# (libcni skips directories); Multus picks it up there via multusAutoconfigDir
|
||||
# and writes 00-multus.conf. Until that file exists the runtime has no network
|
||||
# config at all, so no pod can be created with Cilium alone after a reboot.
|
||||
#
|
||||
# The "-subdir" names date from the node-by-node rollout; renaming would roll
|
||||
# Multus again for nothing.
|
||||
kind: ConfigMap
|
||||
apiVersion: v1
|
||||
metadata:
|
||||
name: multus-daemon-config
|
||||
name: multus-daemon-config-subdir
|
||||
namespace: kube-system
|
||||
labels:
|
||||
tier: node
|
||||
@@ -127,7 +135,7 @@ data:
|
||||
"logLevel": "verbose",
|
||||
"logToStderr": true,
|
||||
"cniConfigDir": "/host/etc/cni/net.d",
|
||||
"multusAutoconfigDir": "/host/etc/cni/net.d",
|
||||
"multusAutoconfigDir": "/host/etc/cni/net.d/multus",
|
||||
"multusConfigFile": "auto",
|
||||
"socketDir": "/host/run/multus/"
|
||||
}
|
||||
@@ -135,16 +143,16 @@ data:
|
||||
apiVersion: apps/v1
|
||||
kind: DaemonSet
|
||||
metadata:
|
||||
name: kube-multus-ds
|
||||
name: kube-multus-ds-subdir
|
||||
namespace: kube-system
|
||||
labels:
|
||||
tier: node
|
||||
app: multus
|
||||
name: multus
|
||||
name: multus-subdir
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
name: multus
|
||||
name: multus-subdir
|
||||
updateStrategy:
|
||||
type: RollingUpdate
|
||||
template:
|
||||
@@ -152,7 +160,7 @@ spec:
|
||||
labels:
|
||||
tier: node
|
||||
app: multus
|
||||
name: multus
|
||||
name: multus-subdir
|
||||
spec:
|
||||
# Upstream ships this DaemonSet with no priority class, so it runs at 0
|
||||
# and can preempt nothing. Any event that makes the pod need a fresh
|
||||
@@ -224,6 +232,10 @@ spec:
|
||||
volumeMounts:
|
||||
- name: cni
|
||||
mountPath: /host/etc/cni/net.d
|
||||
# Exists before Multus starts, so it waits for Cilium's conflist
|
||||
# instead of exiting on a missing directory.
|
||||
- name: cni-cilium-conf
|
||||
mountPath: /host/etc/cni/net.d/multus
|
||||
# multus-daemon expects that cnibin path must be identical between pod and container host.
|
||||
# e.g. if the cni bin is in '/opt/cni/bin' on the container host side, then it should be mount to '/opt/cni/bin' in multus-daemon,
|
||||
# not to any other directory, like '/opt/bin' or '/usr/bin'.
|
||||
@@ -279,6 +291,10 @@ spec:
|
||||
- name: cni
|
||||
hostPath:
|
||||
path: /etc/cni/net.d
|
||||
- name: cni-cilium-conf
|
||||
hostPath:
|
||||
path: /etc/cni/net.d/multus
|
||||
type: DirectoryOrCreate
|
||||
- name: cnibin
|
||||
hostPath:
|
||||
path: /opt/cni/bin
|
||||
@@ -287,7 +303,7 @@ spec:
|
||||
path: /
|
||||
- name: multus-daemon-config
|
||||
configMap:
|
||||
name: multus-daemon-config
|
||||
name: multus-daemon-config-subdir
|
||||
items:
|
||||
- key: daemon-config.json
|
||||
path: daemon-config.json
|
||||
|
||||
@@ -39,9 +39,11 @@ spec:
|
||||
name: whereabouts-reconciler
|
||||
spec:
|
||||
serviceAccountName: whereabouts
|
||||
# Every node here is a control plane node.
|
||||
# Every node here is a control plane node. Keyed: a keyless Exists would
|
||||
# also tolerate node.kubernetes.io/unschedulable and ignore cordons.
|
||||
tolerations:
|
||||
- operator: Exists
|
||||
- key: node-role.kubernetes.io/control-plane
|
||||
operator: Exists
|
||||
effect: NoSchedule
|
||||
containers:
|
||||
- name: whereabouts-reconciler
|
||||
|
||||
@@ -187,6 +187,14 @@ kind: Namespace
|
||||
metadata:
|
||||
name: gitea
|
||||
---
|
||||
# netbird-service-sync, moving out of `openbao` (issue #876). Declared here like
|
||||
# `woodpecker` above, so it exists before infrastructure-crds applies its
|
||||
# CiliumNetworkPolicies. No pod-security labels: the cluster default applies.
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: netbird-service-sync
|
||||
---
|
||||
# Local LLM inference (kubernetes/apps/llama-server). Declared here, like
|
||||
# `woodpecker` above, so the `infrastructure` KS creates it before
|
||||
# `infrastructure-crds` applies the namespace's CiliumNetworkPolicies.
|
||||
|
||||
+23
-23
@@ -1,28 +1,28 @@
|
||||
# Reconciles NetBird reverse-proxy services from Ingresses that carry
|
||||
# dns.renner.uno/public: one TLS-passthrough service per host on :443,
|
||||
# targeting Traefik's ClusterIP through a subnet resource over the service
|
||||
# CIDR (ci/images/netbird-proxy-services/controller.py).
|
||||
# CIDR (ci/images/netbird-service-sync/controller.py).
|
||||
#
|
||||
# openbao namespace, like the rotators: its default-deny already allows egress
|
||||
# to OpenBao, DNS, the apiserver and `world` (netbird.renner.uno), and the
|
||||
# NetBird PAT is read from OpenBao on every pass through the
|
||||
# netbird-proxy-services role — policies/netbird-proxy-services.hcl, applied
|
||||
# once by hand like the rotator roles. Until that role exists the pod logs an
|
||||
# auth error each minute and does nothing.
|
||||
# Own namespace; its egress (DNS, apiserver, OpenBao, NetBird API) is in
|
||||
# network-policies/netbird-service-sync-ns.yaml. The NetBird PAT is read from
|
||||
# OpenBao on every pass through the netbird-service-sync role —
|
||||
# policies/netbird-service-sync.hcl, applied once by hand like the rotator
|
||||
# roles. Until that role exists the pod logs an auth error each minute and does
|
||||
# nothing.
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: netbird-proxy-services
|
||||
namespace: openbao
|
||||
name: netbird-service-sync
|
||||
namespace: netbird-service-sync
|
||||
labels:
|
||||
app.kubernetes.io/name: netbird-proxy-services
|
||||
app.kubernetes.io/name: netbird-service-sync
|
||||
---
|
||||
# Read-only, cluster-wide: public Ingresses live in many namespaces, the
|
||||
# Traefik Service in ingress/.
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
name: netbird-proxy-services-read
|
||||
name: netbird-service-sync-read
|
||||
rules:
|
||||
- apiGroups: ["networking.k8s.io"]
|
||||
resources: ["ingresses"]
|
||||
@@ -34,23 +34,23 @@ rules:
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRoleBinding
|
||||
metadata:
|
||||
name: netbird-proxy-services-read
|
||||
name: netbird-service-sync-read
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: ClusterRole
|
||||
name: netbird-proxy-services-read
|
||||
name: netbird-service-sync-read
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: netbird-proxy-services
|
||||
namespace: openbao
|
||||
name: netbird-service-sync
|
||||
namespace: netbird-service-sync
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: netbird-proxy-services
|
||||
namespace: openbao
|
||||
name: netbird-service-sync
|
||||
namespace: netbird-service-sync
|
||||
labels:
|
||||
app.kubernetes.io/name: netbird-proxy-services
|
||||
app.kubernetes.io/name: netbird-service-sync
|
||||
spec:
|
||||
replicas: 1
|
||||
# One writer against the management API at a time.
|
||||
@@ -58,13 +58,13 @@ spec:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/name: netbird-proxy-services
|
||||
app.kubernetes.io/name: netbird-service-sync
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app.kubernetes.io/name: netbird-proxy-services
|
||||
app.kubernetes.io/name: netbird-service-sync
|
||||
spec:
|
||||
serviceAccountName: netbird-proxy-services
|
||||
serviceAccountName: netbird-service-sync
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
# Numeric, or the kubelet refuses the image's named user with
|
||||
@@ -80,7 +80,7 @@ spec:
|
||||
# image directory (branch and master alike) and the registry keeps
|
||||
# only the newest manifest per tag, so the digest must come from
|
||||
# the MASTER build of the code change.
|
||||
image: gitea.renner.uno/gitea_admin/netbird-proxy-services:2026-09-07@sha256:caffa308d802c6fcc6aea919ac94657c08b993651baa6b8d18de395bcc40523e
|
||||
image: gitea.renner.uno/gitea_admin/netbird-service-sync:2026-09-23@sha256:64f6057c508640e1dbc50457dc26e9b2de058a111fd46ca096021d7444b5bbff
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
@@ -92,7 +92,7 @@ spec:
|
||||
- name: BAO_ADDR
|
||||
value: http://openbao.openbao.svc.cluster.local:8200
|
||||
- name: BAO_ROLE
|
||||
value: netbird-proxy-services
|
||||
value: netbird-service-sync
|
||||
# Must match cluster.network.serviceSubnets in talos/patches/cluster.yaml.
|
||||
- name: SERVICE_CIDR
|
||||
value: "10.96.0.0/12"
|
||||
@@ -166,9 +166,6 @@ spec:
|
||||
- matchLabels:
|
||||
"k8s:io.kubernetes.pod.namespace": ingress
|
||||
app.kubernetes.io/name: traefik
|
||||
- matchLabels:
|
||||
"k8s:io.kubernetes.pod.namespace": apps
|
||||
app.kubernetes.io/name: gitea
|
||||
- matchLabels:
|
||||
"k8s:io.kubernetes.pod.namespace": gitea
|
||||
app.kubernetes.io/name: gitea
|
||||
|
||||
@@ -45,16 +45,6 @@ spec:
|
||||
- ports:
|
||||
- port: "1883"
|
||||
protocol: TCP
|
||||
# gitea delivers the notes repo's push webhook to wiki-index (ai ns) on :8080.
|
||||
# wiki-index's own ingress policy scopes this to the gitea pod.
|
||||
- toEndpoints:
|
||||
- matchLabels:
|
||||
"k8s:io.kubernetes.pod.namespace": ai
|
||||
app.kubernetes.io/name: wiki-index
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "8080"
|
||||
protocol: TCP
|
||||
- toEntities:
|
||||
- host
|
||||
- remote-node
|
||||
|
||||
@@ -23,6 +23,7 @@ resources:
|
||||
- woodpecker-ci-ns.yaml
|
||||
- woodpecker-ns.yaml
|
||||
- gitea-ns.yaml
|
||||
- netbird-service-sync-ns.yaml
|
||||
- trmnl-ns.yaml
|
||||
- wordpress-ns.yaml
|
||||
- ai-ns.yaml
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
---
|
||||
# Baseline policy for the `netbird-service-sync` namespace (issue #876).
|
||||
# The controller serves nothing; it only calls out: the Kubernetes API
|
||||
# (Ingress/Service reads), OpenBao (NetBird PAT) and the NetBird management API.
|
||||
apiVersion: cilium.io/v2
|
||||
kind: CiliumNetworkPolicy
|
||||
metadata:
|
||||
name: default-deny
|
||||
namespace: netbird-service-sync
|
||||
spec:
|
||||
endpointSelector: {}
|
||||
ingress:
|
||||
- fromEntities:
|
||||
- host
|
||||
- remote-node
|
||||
egress:
|
||||
- toEndpoints:
|
||||
- matchLabels:
|
||||
"k8s:io.kubernetes.pod.namespace": kube-system
|
||||
k8s-app: kube-dns
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "53"
|
||||
protocol: UDP
|
||||
- port: "53"
|
||||
protocol: TCP
|
||||
- toEntities:
|
||||
- kube-apiserver
|
||||
- toEndpoints:
|
||||
- matchLabels:
|
||||
"k8s:io.kubernetes.pod.namespace": openbao
|
||||
app.kubernetes.io/name: openbao
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "8200"
|
||||
protocol: TCP
|
||||
# NetBird management API (netbird.renner.uno).
|
||||
- toEntities:
|
||||
- world
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "443"
|
||||
protocol: TCP
|
||||
@@ -41,6 +41,16 @@ spec:
|
||||
- ports:
|
||||
- port: "8200"
|
||||
protocol: TCP
|
||||
# netbird-service-sync logs in via auth/kubernetes/role/netbird-service-sync
|
||||
# and reads the NetBird PAT on every pass.
|
||||
- fromEndpoints:
|
||||
- matchLabels:
|
||||
"k8s:io.kubernetes.pod.namespace": netbird-service-sync
|
||||
app.kubernetes.io/name: netbird-service-sync
|
||||
toPorts:
|
||||
- ports:
|
||||
- port: "8200"
|
||||
protocol: TCP
|
||||
# (Secret-rotation CronJobs run in THIS namespace since 2026-07-18, so their
|
||||
# OpenBao access is covered by the intra-namespace ingress rule above — no
|
||||
# per-app rule needed.)
|
||||
@@ -127,7 +137,7 @@ spec:
|
||||
# Egress complement to gitea-allow-flux-rotator (apps/gitea/networkpolicy.yaml).
|
||||
# The flux-git rotator mints a PAT against the in-cluster gitea Service; the
|
||||
# openbao default-deny only permits TCP egress to openbao/kube-dns/apiserver/
|
||||
# world, and gitea (apps ns) is in-cluster, so it needs an explicit allow.
|
||||
# world, and gitea (gitea ns) is in-cluster, so it needs an explicit allow.
|
||||
# Scoped to the flux-git rotator label and gitea :3000.
|
||||
apiVersion: cilium.io/v2
|
||||
kind: CiliumNetworkPolicy
|
||||
@@ -141,9 +151,6 @@ spec:
|
||||
app.kubernetes.io/name: flux-git
|
||||
egress:
|
||||
- toEndpoints:
|
||||
- matchLabels:
|
||||
"k8s:io.kubernetes.pod.namespace": apps
|
||||
app.kubernetes.io/name: gitea
|
||||
- matchLabels:
|
||||
"k8s:io.kubernetes.pod.namespace": gitea
|
||||
app.kubernetes.io/name: gitea
|
||||
@@ -153,10 +160,10 @@ spec:
|
||||
protocol: TCP
|
||||
---
|
||||
# Egress for the review-bot rotator. Its CronJob has two steps: the init step
|
||||
# mints review-bot's PAT against gitea (apps :3000), the main step upserts the
|
||||
# mints review-bot's PAT against gitea (gitea :3000), the main step upserts the
|
||||
# Woodpecker org secret against the woodpecker server (woodpecker :8000). Both run
|
||||
# under the same pod labels, so one egress policy covers both hops. Complements
|
||||
# gitea-allow-review-bot-rotator (apps) + woodpecker-allow-rotators (woodpecker).
|
||||
# gitea-allow-review-bot-rotator (gitea) + woodpecker-allow-rotators (woodpecker).
|
||||
apiVersion: cilium.io/v2
|
||||
kind: CiliumNetworkPolicy
|
||||
metadata:
|
||||
@@ -169,9 +176,6 @@ spec:
|
||||
app.kubernetes.io/name: review-bot
|
||||
egress:
|
||||
- toEndpoints:
|
||||
- matchLabels:
|
||||
"k8s:io.kubernetes.pod.namespace": apps
|
||||
app.kubernetes.io/name: gitea
|
||||
- matchLabels:
|
||||
"k8s:io.kubernetes.pod.namespace": gitea
|
||||
app.kubernetes.io/name: gitea
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
# OpenBao policy: netbird-proxy-services
|
||||
#
|
||||
# The reverse-proxy-services controller (Deployment netbird-proxy-services in
|
||||
# the openbao namespace) reads the NetBird PAT on every reconcile pass and
|
||||
# calls the management API with it. Read-only on that one path; it shares the
|
||||
# bootstrap credential with rotator-netbird but not that role's PATCH rights.
|
||||
#
|
||||
# NOT applied by Flux. Apply ONCE with an admin token:
|
||||
#
|
||||
# bao policy write netbird-proxy-services kubernetes/infrastructure/openbao/policies/netbird-proxy-services.hcl
|
||||
# bao write auth/kubernetes/role/netbird-proxy-services \
|
||||
# bound_service_account_names=netbird-proxy-services \
|
||||
# bound_service_account_namespaces=openbao \
|
||||
# policies=netbird-proxy-services ttl=15m
|
||||
#
|
||||
# The PAT itself is the one rotator-netbird already uses
|
||||
# (homelab/infrastructure/secret-rotators-bootstrap/netbird, key `pat`).
|
||||
#
|
||||
# Do NOT set token_no_default_policy=true (kv-v2 preflight needs the default policy).
|
||||
|
||||
path "homelab/data/infrastructure/secret-rotators-bootstrap/netbird" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
# OpenBao policy: netbird-service-sync
|
||||
#
|
||||
# The controller that syncs public Ingresses into NetBird reverse-proxy services
|
||||
# (Deployment netbird-service-sync in the netbird-service-sync namespace) reads
|
||||
# the NetBird PAT on every reconcile pass and calls the management API with it.
|
||||
# Read-only on that one path; it shares the bootstrap credential with
|
||||
# rotator-netbird but not that role's PATCH rights.
|
||||
#
|
||||
# NOT applied by Flux. Apply ONCE with an admin token:
|
||||
#
|
||||
# bao policy write netbird-service-sync kubernetes/infrastructure/openbao/policies/netbird-service-sync.hcl
|
||||
# bao write auth/kubernetes/role/netbird-service-sync \
|
||||
# bound_service_account_names=netbird-service-sync \
|
||||
# bound_service_account_namespaces=netbird-service-sync \
|
||||
# policies=netbird-service-sync ttl=15m
|
||||
#
|
||||
# The PAT itself is the one rotator-netbird already uses
|
||||
# (homelab/infrastructure/secret-rotators-bootstrap/netbird, key `pat`).
|
||||
#
|
||||
# Do NOT set token_no_default_policy=true (kv-v2 preflight needs the default policy).
|
||||
|
||||
path "homelab/data/infrastructure/secret-rotators-bootstrap/netbird" {
|
||||
capabilities = ["read"]
|
||||
}
|
||||
@@ -225,8 +225,7 @@ metadata:
|
||||
labels:
|
||||
app.kubernetes.io/part-of: homelab-backup
|
||||
spec:
|
||||
# Daily at 07:15 local. Every PVC in the shared `apps` namespace: Gitea's
|
||||
# data-gitea-0 until it moves to the `gitea` namespace (#878), gatus-data.
|
||||
# Daily at 07:15 local. Every PVC in the shared `apps` namespace (gatus-data).
|
||||
# No CNPG cluster runs here, so no labelSelector exclusion is needed.
|
||||
schedule: "15 7 * * *"
|
||||
useOwnerReferencesInBackup: false
|
||||
@@ -247,8 +246,7 @@ metadata:
|
||||
labels:
|
||||
app.kubernetes.io/part-of: homelab-backup
|
||||
spec:
|
||||
# Daily at 07:45 local. data-gitea-0 (SQLite, repos, LFS, packages) once
|
||||
# Gitea runs in the `gitea` namespace (#878).
|
||||
# Daily at 07:45 local. data-gitea-0 (SQLite, repos, LFS, packages).
|
||||
schedule: "45 7 * * *"
|
||||
useOwnerReferencesInBackup: false
|
||||
template:
|
||||
|
||||
@@ -96,7 +96,7 @@ spec:
|
||||
# that traffic is always a pod IP — collapsing all external clients
|
||||
# to one source. The NetBird reverse-proxy services are TLS
|
||||
# passthrough and carry the WAN client address in a PROXY protocol
|
||||
# v2 header (options.proxy_protocol, set by netbird-proxy-services);
|
||||
# v2 header (options.proxy_protocol, set by netbird-service-sync);
|
||||
# X-Forwarded-For stays trusted for HTTP-mode services. Both are
|
||||
# accepted from the pod CIDRs only; connections without a header
|
||||
# (direct LAN/mesh) keep their RemoteAddr.
|
||||
|
||||
@@ -58,6 +58,12 @@ machine:
|
||||
imageGCHighThresholdPercent: 70
|
||||
imageGCLowThresholdPercent: 60
|
||||
cluster:
|
||||
# etcd advertises on the management VLAN until the node↔node move (#576
|
||||
# step 3). Pinned so the node0 addresses cannot be picked on a reboot: Talos
|
||||
# never updates an existing member's peer URLs.
|
||||
etcd:
|
||||
advertisedSubnets:
|
||||
- 10.2.40.0/24
|
||||
# controlPlane.endpoint is NOT here: `talosctl gen config` takes it as its
|
||||
# second argument, and bootstrap.sh already passes https://k8s.renner.uno:6443
|
||||
# there. Setting it again in this patch restated the same value in a second
|
||||
|
||||
@@ -17,6 +17,8 @@ machine:
|
||||
# pod0 is a closed L2 fabric between the three nodes: statically
|
||||
# addressed, no gateway, nothing to learn from an RA.
|
||||
net.ipv6.conf.pod0.accept_ra: "0"
|
||||
# node0 is closed the same way.
|
||||
net.ipv6.conf.node0.accept_ra: "0"
|
||||
# ingress0 keeps RAs, at the default accept_ra of 2: an IPv6 default
|
||||
# router is a link-local address learned only from the RA, and with
|
||||
# net.ipv6.conf.all.forwarding=1 — which Cilium sets — Linux ignores RAs
|
||||
@@ -177,6 +179,19 @@ addresses:
|
||||
- address: 10.2.48.11/24
|
||||
- address: fd02:48::11/64
|
||||
---
|
||||
# Node network, VLAN 46: traffic among the three nodes themselves (#576) — the
|
||||
# node IP, etcd, apiserver↔kubelet. Closed like pod0: statically addressed, no
|
||||
# gateway, never routed via the UDM. Unused until the node IP moves here.
|
||||
apiVersion: v1alpha1
|
||||
kind: VLANConfig
|
||||
name: node0
|
||||
vlanID: 46
|
||||
parent: uplink
|
||||
up: true
|
||||
addresses:
|
||||
- address: fd02:46::11/64
|
||||
- address: 10.2.46.11/24
|
||||
---
|
||||
# Ingress network, VLAN 47. World-to-pod: the BGP session, the next hop for
|
||||
# every advertised LoadBalancer VIP, and the masquerade source for pod egress.
|
||||
# Publicly routed, which is what separates it from pod0.
|
||||
|
||||
@@ -16,6 +16,7 @@ machine:
|
||||
# ingress0 keeps RAs: it learns its IPv6 router and its address from them,
|
||||
# and only the default route is held back — see k8s-1.yaml.
|
||||
net.ipv6.conf.pod0.accept_ra: "0"
|
||||
net.ipv6.conf.node0.accept_ra: "0"
|
||||
net.ipv6.conf.ingress0.accept_ra_defrtr: "0"
|
||||
# Answer ARP only on the link that owns the address — see k8s-1.yaml (#793).
|
||||
net.ipv4.conf.all.arp_ignore: "1"
|
||||
@@ -122,6 +123,17 @@ addresses:
|
||||
- address: 10.2.48.12/24
|
||||
- address: fd02:48::12/64
|
||||
---
|
||||
# Node network, VLAN 46 — see k8s-1.yaml.
|
||||
apiVersion: v1alpha1
|
||||
kind: VLANConfig
|
||||
name: node0
|
||||
vlanID: 46
|
||||
parent: uplink
|
||||
up: true
|
||||
addresses:
|
||||
- address: fd02:46::12/64
|
||||
- address: 10.2.46.12/24
|
||||
---
|
||||
# Ingress network, VLAN 47. World-to-pod, publicly routed, statically
|
||||
# addressed — see k8s-1.yaml for why it is not leased.
|
||||
apiVersion: v1alpha1
|
||||
|
||||
@@ -12,6 +12,7 @@ machine:
|
||||
# ingress0 keeps RAs: it learns its IPv6 router and its address from them,
|
||||
# and only the default route is held back — see k8s-1.yaml.
|
||||
net.ipv6.conf.pod0.accept_ra: "0"
|
||||
net.ipv6.conf.node0.accept_ra: "0"
|
||||
net.ipv6.conf.ingress0.accept_ra_defrtr: "0"
|
||||
# Answer ARP only on the link that owns the address — see k8s-1.yaml (#793).
|
||||
net.ipv4.conf.all.arp_ignore: "1"
|
||||
@@ -109,6 +110,17 @@ addresses:
|
||||
- address: 10.2.48.13/24
|
||||
- address: fd02:48::13/64
|
||||
---
|
||||
# Node network, VLAN 46 — see k8s-1.yaml.
|
||||
apiVersion: v1alpha1
|
||||
kind: VLANConfig
|
||||
name: node0
|
||||
vlanID: 46
|
||||
parent: uplink
|
||||
up: true
|
||||
addresses:
|
||||
- address: fd02:46::13/64
|
||||
- address: 10.2.46.13/24
|
||||
---
|
||||
# Ingress network, VLAN 47. World-to-pod, publicly routed, statically
|
||||
# addressed — see k8s-1.yaml for why it is not leased.
|
||||
apiVersion: v1alpha1
|
||||
|
||||
Reference in New Issue
Block a user