Compare commits
17
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e93d4ba86c | ||
|
|
7a1213d504 | ||
|
|
40aa23dfdf | ||
|
|
71fce30506 | ||
|
|
0666715a5e | ||
|
|
949ae5cb38 | ||
|
|
e150969070 | ||
|
|
abfdda5f57 | ||
|
|
2d9e3abee8 | ||
|
|
9fa8d9cf60 | ||
|
|
2e4fad3bf7 | ||
|
|
5d22691c3e | ||
|
|
4eee161e0f | ||
|
|
719fa77521 | ||
|
|
64cd1f2c4e | ||
|
|
f780e31f9c | ||
|
|
c93a24f786 |
@@ -4,7 +4,9 @@ metadata:
|
||||
name: comfyui
|
||||
namespace: comfyui
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||
# No cert-manager annotation and no tls: block. This host is covered by
|
||||
# the *.riotpiao.com wildcard, which nginx serves as its
|
||||
# default-ssl-certificate (ingress-nginx/riotpiao-com-tls).
|
||||
nginx.ingress.kubernetes.io/proxy-read-timeout: "600"
|
||||
nginx.ingress.kubernetes.io/proxy-send-timeout: "600"
|
||||
nginx.ingress.kubernetes.io/proxy-body-size: "0"
|
||||
@@ -16,10 +18,6 @@ metadata:
|
||||
proxy_set_header Connection "upgrade";
|
||||
spec:
|
||||
ingressClassName: nginx
|
||||
tls:
|
||||
- secretName: comfyui-tls
|
||||
hosts:
|
||||
- comfyui.riotpiao.com
|
||||
rules:
|
||||
- host: comfyui.riotpiao.com
|
||||
http:
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: azhi-riotpiao
|
||||
namespace: argocd
|
||||
annotations:
|
||||
argocd.argoproj.io/sync-wave: '8'
|
||||
spec:
|
||||
project: homelab
|
||||
source:
|
||||
# Private GitHub. The read-only credential is Secret azhi-infra-github in
|
||||
# namespace argocd, created out-of-band.
|
||||
repoURL: https://github.com/ToyoGlobal/azhi-infra.git
|
||||
# The repository's default branch. It is not `main`: this repo's work
|
||||
# happens on the staging slice branch, and `main` is behind it.
|
||||
targetRevision: feat/azi-riotpiao-cnpg
|
||||
# One directory, because ArgoCD reads a single path per source. That
|
||||
# directory is a root kustomization over foundation, postgres and
|
||||
# azhi-server.
|
||||
path: k8s/overlays/azi-riotpiao
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: azi-riotpiao
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
# The two Secrets this namespace needs are credentials, so they are created
|
||||
# by hand and NOT by this Application:
|
||||
# acr-pull — the private Alibaba ACR pull credential
|
||||
# azhi-riotpiao-app-env — DB credentials, JWT secrets, AES key
|
||||
# A missing imagePullSecret fails the pod outright and a missing app-env
|
||||
# Secret leaves it in CreateContainerConfigError, which is the intended
|
||||
# loud failure rather than a pod that runs against unknown values.
|
||||
@@ -0,0 +1,20 @@
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: oidc-bootstrap
|
||||
namespace: argocd
|
||||
annotations:
|
||||
argocd.argoproj.io/sync-wave: "5"
|
||||
spec:
|
||||
project: homelab
|
||||
source:
|
||||
repoURL: https://forgejo.riotpiao.com/riotpiao-poimen/homelab.git
|
||||
targetRevision: main
|
||||
path: k8s/infra/oidc-bootstrap
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: kube-system
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
@@ -16,6 +16,12 @@ spec:
|
||||
- https://github.com/Riotpiaole/Poimen-memory.git
|
||||
- https://github.com/Riotpiaole/Poimen-workflows.git
|
||||
- https://github.com/Riotpiaole/poimen*.git
|
||||
# ToyoGlobal (GitHub, private). The azhi-infra Application reads its
|
||||
# manifests from here, so the URL must be listed or ArgoCD rejects the
|
||||
# Application with "repository not permitted". A read-only credential for
|
||||
# this repo lives in Secret azhi-infra-github in namespace argocd; it is
|
||||
# created out-of-band and is not committed, because it is a credential.
|
||||
- https://github.com/ToyoGlobal/azhi-infra.git
|
||||
# In-cluster Forgejo repos — explicit allowlist (no wildcard)
|
||||
- https://forgejo.riotpiao.com/riotpiao-poimen/homelab.git
|
||||
- https://forgejo.riotpiao.com/riotpiao-poimen/homelab-frontend.git
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
type: Opaque
|
||||
metadata:
|
||||
name: forgejo-registry-token
|
||||
namespace: cicd
|
||||
data:
|
||||
username: ENC[AES256_GCM,data:oRNecs0a7rs=,iv:/5EFdNqpSjoxe7XDmAEDMd6lXd0SMsRiMmBM9SIwDHY=,tag:Wi+ggoP+9/vgz9rHrxB9nA==,type:str]
|
||||
password: ENC[AES256_GCM,data:HbmwnWk3ST5SDWXwIhu+M5f/FOfFbJHaG0Q/IWrO63HRXmJTmLMpbjtWIXC9IMFoHeDZ1MNAV8A=,iv:ztJZgpaS//yYCiyr6/ubs/UiXkbGMnokvy4Pe45jQMk=,tag:WMpawc/SVAV4mxsCd6XqAA==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBjQmhxN2E3ZnNTdkR6U2c1
|
||||
ZStsQktkeWUwMEdmdFIyMkRYRVk1ZGppWlZ3CmUzR2JubWw2VjdWUGt6S2lpNmQ3
|
||||
cDdSWjJiYzRIWS9UVERpVDFJenFnaDAKLS0tIGhDSmNMSjZwcDVPR3U0dUcwNk9Q
|
||||
WmdGS1lyS3dkSXIvOFhyRklGRll2UlUK8NGts6a6Fv10c6gxIIPqIIqfgzQ3EEyk
|
||||
SFrMThwbdaOqLY4AMeDrg+k0Y2t1Xj/XOvdNbRCRictDwZUsptvO7A==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
recipient: age1e5fq3hwxy78psus2nfvmtmua36g0u3suk78ephw6246l974d2utsvn0hla
|
||||
encrypted_regex: ^(data|stringData)$
|
||||
lastmodified: "2026-10-06T02:01:24Z"
|
||||
mac: ENC[AES256_GCM,data:imebczVzG9YWd42ER4a+w+Bi3dxbN0HFm/1igxzJt6Z0HG/q6i0s59swpGVruk9dQJWrlO8KKqX739ATp2KGC5szrEuRFvPemF594XFCg6ykW+ZeP5VtTvpJg2nHv7/Pu+71ljKKi4gqOJ4SJDn8owAbSN+su6PiT323wax930A=,iv:iG/G2+qQkvbBU95w/GG2PrbAHDOaamuvjqMDBxSW6zI=,tag:wy9Vn72HBDHqCyzTcV15/Q==,type:str]
|
||||
version: 3.13.2
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
type: Opaque
|
||||
metadata:
|
||||
name: memory-agent-oidc
|
||||
namespace: poimen
|
||||
data:
|
||||
CLIENT_ID: ENC[AES256_GCM,data:c/RvtV6anofX8h1BmlKu9w==,iv:3lQ1BR8kVvF1RHVfKstmb0Y7u/uX5OrvmGiCi/xTpjw=,tag:9JC2WkfQFWaiZroAEmPenw==,type:str]
|
||||
CLIENT_SECRET: ENC[AES256_GCM,data:I258/6O43PccyllYN/wfoKvTgNgZONTivM/KFIr8TGqSl+2XQkwBXvK2VQc5Xgc5cpwlrgnjk8pjQbqr,iv:MZyA+V5z9Po2VoxqvOSlWh1fZp1lrkcbYMx7VcSIaJs=,tag:gXH0BpA8KOZiVd+4RnhRzg==,type:str]
|
||||
ISSUER: ENC[AES256_GCM,data:GX/uQPDoeJWXXQZlzD6oOIvxo7H4LRAv4MrPAiCgmv6WxW59+KKkymuDT/T9MiDm4bNhxVPgB7nHbDcMHfPvU2zCNM2TWYUsNOgGwxNAqM8=,iv:5OEsdrUZvMLO2C8Ea2i5alsyFGtmEk3othTemk8fOk4=,tag:8CMlRY2JCe4z4fv4WuWjRQ==,type:str]
|
||||
TOKEN_URL: ENC[AES256_GCM,data:KeU1pQzvQ2/1lQhOqNtcR7t5TGVx1J7NY8ogxCXS6IuHhVe0zWYIbC4BYFc2H9PAjsMJwCCg75N1FrIiCYBvpfK8ln0=,iv:NbPiJC/B7W1Zm+JwnEGDikE2cb3L4l6TBeQTKEb2boM=,tag:FRmllFLZzQW03lsCu9mAUA==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBmK0dPSmhKT01FSitDdUNW
|
||||
Um1XQU9FVnBUeDdoWXpCcXRzVXh0VXkvNGxNClZaQ3R5U2NkYTJjaFdHRWhUVmFS
|
||||
K0tHZVRFRDZGREVRZzZqcWJ6dnRpUUEKLS0tIE15UUNtMStKbWwzb3dEVGEwN1VQ
|
||||
cktlVTM2SUhpOGJZMXJOOG84RnhCQzAKOdM0pThEaN37SJtRrKIivncMu8Z91Btq
|
||||
es6NOlJdBUhzIhnEJWfDzZ9aA6I/fYzugKbC+AfUwdGgThAgHx9crg==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
recipient: age1e5fq3hwxy78psus2nfvmtmua36g0u3suk78ephw6246l974d2utsvn0hla
|
||||
encrypted_regex: ^(data|stringData)$
|
||||
lastmodified: "2026-10-06T02:01:24Z"
|
||||
mac: ENC[AES256_GCM,data:/BTQ984D+hsk0LmnjD3hxopB65NAR54LhoAPNcATWA7MCTJXfdnYRu3gNxUzyiyCBd+rDaPp77TBnak4jVjMnOiYJsYLj1R7hrrhTZopz8pT+YNMupperwsirKZwK8it4Mu+fnpCyox2mtGED0hk+Nh/b6IteTRt5lS7noumo2M=,iv:RWIrVkNYj+8mqMSPiLueToexabzAtVbIR525m6bUrlg=,tag:5+wcNoNYsjGKpFlML+N70Q==,type:str]
|
||||
version: 3.13.2
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
type: Opaque
|
||||
metadata:
|
||||
name: oauth2-credentials
|
||||
namespace: iam
|
||||
data:
|
||||
api-gw-client-secret: ENC[AES256_GCM,data:YiUCk61cCsTJE8gTLZWhqVPsCSu3b4OnG+Oh456A+mnxip0FjLTTqV+kYBdfZivIkn9ua4RcVW+rYILu,iv:K08m1EaB7/SIVNWZ3FfeRP4tbCAo6KeiNC0NpE9VO1o=,tag:ZXV9YRWUOPJ/vdoqMtvQeA==,type:str]
|
||||
minio-client-secret: ENC[AES256_GCM,data:vcwLo1cJqbZr2MwkAKO09xPjb09ss7+s6HIvEfaLxt8ka5PUAlXQ37pTkynuktlKq/t0DvSk+x1+5G7QqVD1JJlwyDGM6yuOhBQ3MwucLNl+T4RDKtgGuA==,iv:sCdd+UNX2TfTAM6Zslrh8KrvBSzqpe67F3YMGrl4YDU=,tag:9Tpzm9NEXNuXyCd7l7GeHw==,type:str]
|
||||
poimen-client-secret: ENC[AES256_GCM,data:dYtCiMGZaOFokihfGD2SXJDfXrhfwEQcTOPNu7JNHDUnx0hqwAdYAPAJTEN21p0OpHYDINMs5lwUpMwY,iv:ll8USuzs0881ryHImVjHGO0iFxUzqg5XtI6Ekd+EFXE=,tag:I/4ZfB9Ss4zEP57sRtRTXQ==,type:str]
|
||||
paperless-client-secret: ENC[AES256_GCM,data:XMj9rHkI20lI37vChq9wS5lUq7l95SisRX0LChuj09O5w76Zt9NdG6OEUYQFf1z8vCfMJxBInIEEIq0e,iv:UpYy2ZEZ4AgBACEyrlxEcr13V+8Ksu4p8JHYApmyYHo=,tag:o9Z+/b6T9POgowIsks56kw==,type:str]
|
||||
grafana-client-secret: ENC[AES256_GCM,data:V/j0+P3HoDLqYjRalWK4v1hvJTuVmzxVra47HsF1/BZvWZjIyEIH3Pt8BekT3O1dUFynxjcaxdZMBVYg,iv:9pMp+vIsp/sA7GP9wqNDf5DdZVLDow46OURW0mMRXIc=,tag:i7VJFA5o0hToZEJ5JPWIvw==,type:str]
|
||||
sops:
|
||||
age:
|
||||
- enc: |
|
||||
-----BEGIN AGE ENCRYPTED FILE-----
|
||||
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2amZPendIOU9PeStOcmJG
|
||||
c1dzOFVvd3RoT3dXQlJUNkdCSytEZUVGVEJJCklMUkNjUytBMXh0OVUrNUlpMWw3
|
||||
aHRFT1hBZTZHNHVtaGJCTEFyT2ZWNWsKLS0tIENxR3FKMEplV0V5Y0dsZzBkODVG
|
||||
U0ZlT2R0VFdEQmpsakVvZ1FJRkRQYTAKESQcSlMAuCG0/tLWWZaeoPayf1EKxSaf
|
||||
e4o8TmjmSgPEhepQ/LmNXl6obyuqUxztkh4Mm6pocqDp+gfzt7X/1g==
|
||||
-----END AGE ENCRYPTED FILE-----
|
||||
recipient: age1e5fq3hwxy78psus2nfvmtmua36g0u3suk78ephw6246l974d2utsvn0hla
|
||||
encrypted_regex: ^(data|stringData)$
|
||||
lastmodified: "2026-10-06T02:01:24Z"
|
||||
mac: ENC[AES256_GCM,data:AI/znHiUa/Rwg0YRz65qUZ+b6V73oi3ZfAG/V5uZZvrGFrA0EISzD5LaP5Kl4GUU1svo4G5EI4aftPDgpdPptz21CCa8iYkXGe9pTDmtaE5ZICQAUbRcVhGMTfuWFhrgEhMfCJdOpfHaIQVEsQJQJgrnkXQVuUe9aT75LQz7pnY=,iv:KbIaYT0VeBT2WeSU5V5ZB4e+04JICYaY+egGN1Pv5bM=,tag:pPbhDxeLUx6V1XC/LPwxTg==,type:str]
|
||||
version: 3.13.2
|
||||
|
||||
@@ -7,31 +7,34 @@ metadata:
|
||||
exec:
|
||||
path: ksops
|
||||
files:
|
||||
- agent-pod-models.enc.yaml
|
||||
- agent-pod-ssh-key.enc.yaml
|
||||
- authentik-secrets.enc.yaml
|
||||
- cloudflare-secrets.enc.yaml
|
||||
- forgejo-registry-pat.enc.yaml
|
||||
- forgejo-registry-pat-api.enc.yaml
|
||||
- forgejo-registry-pull.enc.yaml
|
||||
- forgejo-runner-token.enc.yaml
|
||||
- forgejo-secrets.enc.yaml
|
||||
- grafana-oidc-secrets.enc.yaml
|
||||
- grafana-secrets.enc.yaml
|
||||
- homarr-auth-oidc.enc.yaml
|
||||
- homarr-db-encryption.enc.yaml
|
||||
- homarr-secrets.enc.yaml
|
||||
- homelab-ca-secrets.enc.yaml
|
||||
- loki-secrets.enc.yaml
|
||||
- minio-secrets.enc.yaml
|
||||
- paperless-secrets.enc.yaml
|
||||
- vault-secrets.enc.yaml
|
||||
- vault-unseal-keys.enc.yaml
|
||||
- portfolio-secrets.enc.yaml
|
||||
- gotify-admin-secrets.enc.yaml
|
||||
- gotify-tokens-secrets.enc.yaml
|
||||
- gotify-smtp-secrets.enc.yaml
|
||||
- forgejo-smtp-secrets.enc.yaml
|
||||
- paperless-ai-secrets.enc.yaml
|
||||
- agent-pod-models.enc.yaml
|
||||
- agent-pod-ssh-key.enc.yaml
|
||||
- authentik-secrets.enc.yaml
|
||||
- cloudflare-secrets.enc.yaml
|
||||
- forgejo-registry-pat.enc.yaml
|
||||
- forgejo-registry-pat-api.enc.yaml
|
||||
- forgejo-registry-pull.enc.yaml
|
||||
- forgejo-runner-token.enc.yaml
|
||||
- forgejo-secrets.enc.yaml
|
||||
- grafana-oidc-secrets.enc.yaml
|
||||
- grafana-secrets.enc.yaml
|
||||
- homarr-auth-oidc.enc.yaml
|
||||
- homarr-db-encryption.enc.yaml
|
||||
- homarr-secrets.enc.yaml
|
||||
- homelab-ca-secrets.enc.yaml
|
||||
- loki-secrets.enc.yaml
|
||||
- minio-secrets.enc.yaml
|
||||
- paperless-secrets.enc.yaml
|
||||
- vault-secrets.enc.yaml
|
||||
- vault-unseal-keys.enc.yaml
|
||||
- portfolio-secrets.enc.yaml
|
||||
- gotify-admin-secrets.enc.yaml
|
||||
- gotify-tokens-secrets.enc.yaml
|
||||
- gotify-smtp-secrets.enc.yaml
|
||||
- forgejo-smtp-secrets.enc.yaml
|
||||
- paperless-ai-secrets.enc.yaml
|
||||
- memory-agent-oidc.enc.yaml
|
||||
- oauth2-credentials.enc.yaml
|
||||
- forgejo-registry-token.enc.yaml
|
||||
- pi-sandbox-secrets.enc.yaml
|
||||
- etcd-defrag-creds.enc.yaml
|
||||
|
||||
@@ -8,6 +8,19 @@
|
||||
# depend on them existing first.
|
||||
installCRDs: true
|
||||
|
||||
# Point the ACME DNS-01 self-check at the public resolvers directly.
|
||||
#
|
||||
# Without these flags cert-manager resolves through the pod resolver
|
||||
# (CoreDNS at 10.96.0.10). The self-check then never saw the TXT record and
|
||||
# reported "Waiting for DNS-01 challenge propagation" forever. The wildcard
|
||||
# certificate renewal stalled on 2026-09-23 and the cert expired on
|
||||
# 2026-10-23, which broke every Cloudflare Tunnel origin with
|
||||
# "x509: certificate has expired".
|
||||
#
|
||||
extraArgs:
|
||||
- --dns01-recursive-nameservers=1.1.1.1:53,8.8.8.8:53
|
||||
- --dns01-recursive-nameservers-only
|
||||
|
||||
# Tolerate the control-plane taint (talos-cp-1 is the only schedulable node).
|
||||
tolerations:
|
||||
- key: node-role.kubernetes.io/control-plane
|
||||
|
||||
@@ -1,13 +1,21 @@
|
||||
# k8s/bootstrap/ingress/riotpiao-com-cert.yaml
|
||||
# Public wildcard cert for *.riotpiao.com, signed by Let's Encrypt (DNS-01 via
|
||||
# Cloudflare, see ../cert-manager/letsencrypt-issuer.yaml). Distinct from
|
||||
# homelab-tls (self-signed homelab-ca, internal *.riotpiao.com) —
|
||||
# reference riotpiao-com-tls explicitly on ingresses that expose riotpiao.com
|
||||
# hosts to the internet; it is not nginx's default-ssl-certificate.
|
||||
# Cloudflare, see ../cert-manager/letsencrypt-issuer.yaml).
|
||||
#
|
||||
# issuerRef starts on letsencrypt-staging. Switch to letsencrypt-prod once the
|
||||
# staging cert issues cleanly, then delete this Certificate's Secret to force
|
||||
# a re-issue against prod (staging certs aren't browser-trusted).
|
||||
# nginx serves this secret as its default-ssl-certificate
|
||||
# (../ingress/nginx-values.yaml), so every Ingress that omits a tls: block uses
|
||||
# it. Do not add per-host tls: blocks for *.riotpiao.com hosts: they create a
|
||||
# second, single-host certificate and split the wildcard coverage.
|
||||
#
|
||||
# Renewal is automatic and does not drop traffic:
|
||||
# - cert-manager starts a new order 30 days before expiry (renewBefore).
|
||||
# - cert-manager writes the renewed pair into the same secret.
|
||||
# - ingress-nginx watches the secret and hot-reloads. No pod restart.
|
||||
# - The old pair stays valid until the new one is written, so no gap exists.
|
||||
#
|
||||
# The DNS-01 self-check must reach the public resolvers directly. Without the
|
||||
# --dns01-recursive-nameservers flags in ../../cert-manager/cert-manager-values.yaml
|
||||
# the self-check never sees the TXT record and renewal stalls until expiry.
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Certificate
|
||||
metadata:
|
||||
|
||||
@@ -107,7 +107,9 @@ ingress:
|
||||
enabled: true
|
||||
className: nginx
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||
# No cert-manager annotation. forgejo.riotpiao.com is covered by the
|
||||
# *.riotpiao.com wildcard, served as nginx's default-ssl-certificate.
|
||||
#
|
||||
# This chart Ingress and the hand-written one in
|
||||
# k8s/bootstrap/ingress/ingress.yaml both claim forgejo.riotpiao.com.
|
||||
# ingress-nginx breaks the tie by oldest creationTimestamp, and the chart's
|
||||
@@ -125,10 +127,9 @@ ingress:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
tls:
|
||||
- secretName: forgejo-tls
|
||||
hosts:
|
||||
- forgejo.riotpiao.com
|
||||
# tls: intentionally omitted. The chart would create a second, single-host
|
||||
# certificate (forgejo-tls) that expired on 2026-10-23 and competed with the
|
||||
# wildcard. The wildcard covers this host.
|
||||
|
||||
# Resources
|
||||
resources:
|
||||
|
||||
@@ -0,0 +1,59 @@
|
||||
# One-shot bootstrap: restart the control-plane apiservers ONCE so they pick up the
|
||||
# OIDC authenticator (they last started before the Authentik provider existed, so OIDC
|
||||
# tokens were never accepted -> every login got 401). Delete this whole directory after.
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: oidc-bootstrap
|
||||
namespace: kube-system
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: oidc-bootstrap
|
||||
namespace: kube-system
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["pods"]
|
||||
verbs: ["get", "list", "delete"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: oidc-bootstrap
|
||||
namespace: kube-system
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: oidc-bootstrap
|
||||
namespace: kube-system
|
||||
roleRef:
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
kind: Role
|
||||
name: oidc-bootstrap
|
||||
---
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: oidc-bootstrap-restart-apiserver-v2
|
||||
namespace: kube-system
|
||||
spec:
|
||||
backoffLimit: 4
|
||||
ttlSecondsAfterFinished: 7200
|
||||
template:
|
||||
spec:
|
||||
serviceAccountName: oidc-bootstrap
|
||||
restartPolicy: Never
|
||||
containers:
|
||||
- name: restart
|
||||
image: docker.io/curlimages/curl:8.22.0
|
||||
command: ["/bin/sh", "-c"]
|
||||
args:
|
||||
- |
|
||||
set -u
|
||||
TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)
|
||||
CA=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt
|
||||
for pod in kube-apiserver-talos-cp-1 kube-apiserver-talos-cp-2 kube-apiserver-talos-cp-3; do
|
||||
curl -sS --max-time 15 --cacert "$CA" -H "Authorization: Bearer $TOKEN" -X DELETE "https://kubernetes.default.svc/api/v1/namespaces/kube-system/pods/$pod?gracePeriodSeconds=0" -o /dev/null -w "$pod -> HTTP %{http_code}\n" || echo "$pod -> request failed"
|
||||
done
|
||||
echo "deletes requested; kubelet recreates each static pod in ~20-40s"
|
||||
@@ -0,0 +1,141 @@
|
||||
# One-shot: restart the control-plane API servers so their OIDC authenticator initialises.
|
||||
#
|
||||
# Two earlier mechanisms failed and are documented so nobody repeats them:
|
||||
# 1. deleting the mirror pod does NOT restart a static pod (deletes returned 200, no restart);
|
||||
# 2. matching /proc/*/cmdline for 'kube-apiserver' also matched this script's own cmdline,
|
||||
# so every pod SIGTERMed itself (exit 143) before reaching the real process.
|
||||
# This version matches /proc/<pid>/comm (the process name) and skips \$\$, so self-kill is
|
||||
# impossible. hostPID + privileged are permitted in the 'cicd' namespace. Delays stagger the
|
||||
# three control planes by 2 minutes each, so only one API server is down at a time.
|
||||
---
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: oidc-restart-apiserver-cp1-v2
|
||||
namespace: cicd
|
||||
spec:
|
||||
backoffLimit: 0
|
||||
ttlSecondsAfterFinished: 3600
|
||||
template:
|
||||
spec:
|
||||
hostPID: true
|
||||
restartPolicy: Never
|
||||
nodeSelector:
|
||||
kubernetes.io/hostname: talos-cp-1
|
||||
tolerations:
|
||||
- key: node-role.kubernetes.io/control-plane
|
||||
operator: Exists
|
||||
effect: NoSchedule
|
||||
- key: node-role.kubernetes.io/master
|
||||
operator: Exists
|
||||
effect: NoSchedule
|
||||
containers:
|
||||
- name: kill
|
||||
image: docker.io/library/busybox:1.36
|
||||
securityContext:
|
||||
privileged: true
|
||||
command: ["/bin/sh", "-c"]
|
||||
args:
|
||||
- |
|
||||
echo "sleeping 10s before restarting the API server on talos-cp-1"
|
||||
sleep 10
|
||||
self=$$
|
||||
killed=0
|
||||
for d in /proc/[0-9]*; do
|
||||
pid=${d#/proc/}
|
||||
[ "$pid" = "$self" ] && continue
|
||||
comm=$(cat "$d/comm" 2>/dev/null)
|
||||
[ "$comm" = "kube-apiserver" ] || continue
|
||||
echo "SIGTERM -> pid $pid"
|
||||
kill -TERM "$pid" 2>/dev/null && killed=$((killed+1))
|
||||
done
|
||||
echo "signalled $killed API server process(es); kubelet recreates the static pod"
|
||||
|
||||
---
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: oidc-restart-apiserver-cp2-v2
|
||||
namespace: cicd
|
||||
spec:
|
||||
backoffLimit: 0
|
||||
ttlSecondsAfterFinished: 3600
|
||||
template:
|
||||
spec:
|
||||
hostPID: true
|
||||
restartPolicy: Never
|
||||
nodeSelector:
|
||||
kubernetes.io/hostname: talos-cp-2
|
||||
tolerations:
|
||||
- key: node-role.kubernetes.io/control-plane
|
||||
operator: Exists
|
||||
effect: NoSchedule
|
||||
- key: node-role.kubernetes.io/master
|
||||
operator: Exists
|
||||
effect: NoSchedule
|
||||
containers:
|
||||
- name: kill
|
||||
image: docker.io/library/busybox:1.36
|
||||
securityContext:
|
||||
privileged: true
|
||||
command: ["/bin/sh", "-c"]
|
||||
args:
|
||||
- |
|
||||
echo "sleeping 120s before restarting the API server on talos-cp-2"
|
||||
sleep 120
|
||||
self=$$
|
||||
killed=0
|
||||
for d in /proc/[0-9]*; do
|
||||
pid=${d#/proc/}
|
||||
[ "$pid" = "$self" ] && continue
|
||||
comm=$(cat "$d/comm" 2>/dev/null)
|
||||
[ "$comm" = "kube-apiserver" ] || continue
|
||||
echo "SIGTERM -> pid $pid"
|
||||
kill -TERM "$pid" 2>/dev/null && killed=$((killed+1))
|
||||
done
|
||||
echo "signalled $killed API server process(es); kubelet recreates the static pod"
|
||||
|
||||
---
|
||||
apiVersion: batch/v1
|
||||
kind: Job
|
||||
metadata:
|
||||
name: oidc-restart-apiserver-cp3-v2
|
||||
namespace: cicd
|
||||
spec:
|
||||
backoffLimit: 0
|
||||
ttlSecondsAfterFinished: 3600
|
||||
template:
|
||||
spec:
|
||||
hostPID: true
|
||||
restartPolicy: Never
|
||||
nodeSelector:
|
||||
kubernetes.io/hostname: talos-cp-3
|
||||
tolerations:
|
||||
- key: node-role.kubernetes.io/control-plane
|
||||
operator: Exists
|
||||
effect: NoSchedule
|
||||
- key: node-role.kubernetes.io/master
|
||||
operator: Exists
|
||||
effect: NoSchedule
|
||||
containers:
|
||||
- name: kill
|
||||
image: docker.io/library/busybox:1.36
|
||||
securityContext:
|
||||
privileged: true
|
||||
command: ["/bin/sh", "-c"]
|
||||
args:
|
||||
- |
|
||||
echo "sleeping 240s before restarting the API server on talos-cp-3"
|
||||
sleep 240
|
||||
self=$$
|
||||
killed=0
|
||||
for d in /proc/[0-9]*; do
|
||||
pid=${d#/proc/}
|
||||
[ "$pid" = "$self" ] && continue
|
||||
comm=$(cat "$d/comm" 2>/dev/null)
|
||||
[ "$comm" = "kube-apiserver" ] || continue
|
||||
echo "SIGTERM -> pid $pid"
|
||||
kill -TERM "$pid" 2>/dev/null && killed=$((killed+1))
|
||||
done
|
||||
echo "signalled $killed API server process(es); kubelet recreates the static pod"
|
||||
|
||||
Reference in New Issue
Block a user