Initial commit

This commit is contained in:
2025-05-30 00:45:17 +02:00
commit 45c0cbaff5
31 changed files with 5847 additions and 0 deletions

3
.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
secrets.yaml
infra/tailscale.patch.yaml
.DS_Store

View File

@@ -0,0 +1,18 @@
apiVersion: batch/v1
kind: CronJob
metadata:
name: autoupdate-teable-figurines-currencies
spec:
schedule: "0 3 * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: autoupdate-teable-figurines-currencies
image: git.prettysunflower.moe/prettysunflower/autoupdate-teable-figurines-currencies:v1.0
imagePullPolicy: IfNotPresent
envFrom:
- secretRef:
name: autoupdate-teable-figurines-currencies-secret
restartPolicy: OnFailure

View File

@@ -0,0 +1,3 @@
resources:
- cronjob.yaml
- secrets.yaml

View File

@@ -0,0 +1,23 @@
apiVersion: v1
kind: Secret
metadata:
name: autoupdate-teable-figurines-currencies-secret
type: Opaque
data:
RATES_EXCHANGE_APIKEY: ENC[AES256_GCM,data:mQ7j0QNtmPRKEbs0/1Gyha1d4dQSVs2TwheGiQu0LPoAeYLe1gyzSGGS+/SF8lKl,iv:42LINaSLOptLq2/NrqR+c40t7wMWj90PaMVp74GbakY=,tag:7/WuSXVH9AZbveiaSjN1ig==,type:str]
TEABLE_APIKEY: ENC[AES256_GCM,data:iuHX8DJIgb7k4+e3AHjDDnyx1PRMa1IAKBzBBIln8nT6CzWgZHXCheb3Bz6rJUTUutvOEXgSWBRffkJZ3kjayifAmEXHLxMQtrKqfa3dm0ghJQCqCZaewL9vN2VAe3D2,iv:WojW3eQYAaKK6h5m9+7kUgJRcotYEqaDbfDva/Cwc08=,tag:HkzwC3d5Ndv5FoXVJZMmYw==,type:str]
sops:
age:
- recipient: age1r0tjhg6uexyj0p7fp0ftv5h7r7e3ptzkk2797pznfvrvsm576u0s37yyaw
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAramZZVEV3TEhyUmErZDNZ
RlR0Mm44WThoMEZqd2dYUWVXRS9qNjJKZ2swCjd0ZXhLUkVHUkNvcjlIU21Kd0h1
SUNyeSt1bWtVTkwwT054aTVXUzhzZHcKLS0tIFY4dGdUZ1VRWkZZSUNJOU1RbGx4
d09XVFVKY1dNcVdldCtSUUxYZUtXd0kKynbS+MZUw0fWcQ5HbiiOnf0NajSD4mQ0
QhcFWaadsR5LZjdxTfS1XFcbVGa2H8E3FtQvksz7lGwLsU0xqMRGzw==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-05-29T22:38:31Z"
mac: ENC[AES256_GCM,data:cVxy/FkFJnxjzygwf0KdBNvF13nKk8wOjiMSaAtkXcrYPQshu5dONx/2pkG0HjifVKIZvATu/3G7nhcb7pX5+t03QOPkqmoHSowxejMB7w5eX24MALhzAMze/5nlnRQMLA5ZQ+3lG1SNsUXAXlWrlNAS4FKYvIjsvFRA0OTH95s=,iv:NdE7v3ysPuyACIFgquSwZN4AXhFr9Pv9k0PkqAEsVxc=,tag:zM4ga1oK7OpW+ppiS0/HTg==,type:str]
encrypted_regex: ^(data|stringData)$
version: 3.10.2

View File

@@ -0,0 +1,14 @@
---
apiVersion: v1
kind: Pod
metadata:
name: alpine
labels:
app: alpine
spec:
containers:
- image: alpine:latest
name: alpine
command:
- sleep
- "3600"

View File

@@ -0,0 +1,21 @@
---
apiVersion: v1
kind: Pod
metadata:
name: busybox
labels:
app: busybox
spec:
containers:
- image: busybox
name: busybox
command:
- sleep
- "3600"
volumeMounts:
- name: data
mountPath: "/data"
volumes:
- name: data
persistentVolumeClaim:
claimName: technitium-data-pvc

5187
apps/longhorn/longhorn.yaml Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,71 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: prettysunflower-website
namespace: prettysunflower-website
labels:
app.kubernetes.io/name: prettysunflower-website
spec:
replicas: 3
selector:
matchLabels:
app.kubernetes.io/name: prettysunflower-website
template:
metadata:
labels:
app.kubernetes.io/name: prettysunflower-website
spec:
containers:
- name: website
image: 'git.prettysunflower.moe/prettysunflower/prettysunflower-website:latest'
imagePullPolicy: Always
envFrom:
- secretRef:
name: prettysunflower-website-secret
ports:
- containerPort: 3334
- name: website-static
image: 'git.prettysunflower.moe/prettysunflower/prettysunflower-website-static:main'
imagePullPolicy: Always
ports:
- containerPort: 8001
- name: anubis
image: ghcr.io/techarohq/anubis:latest
imagePullPolicy: Always
env:
- name: "BIND"
value: ":8080"
- name: "DIFFICULTY"
value: "4"
- name: ED25519_PRIVATE_KEY_HEX
valueFrom:
secretKeyRef:
name: anubis-key
key: ED25519_PRIVATE_KEY_HEX
- name: "METRICS_BIND"
value: ":9090"
- name: "SERVE_ROBOTS_TXT"
value: "true"
- name: "TARGET"
value: "http://localhost:3334"
- name: "OG_PASSTHROUGH"
value: "true"
- name: "OG_EXPIRY_TIME"
value: "24h"
resources:
limits:
cpu: 750m
memory: 256Mi
requests:
cpu: 250m
memory: 256Mi
securityContext:
runAsUser: 1000
runAsGroup: 1000
runAsNonRoot: true
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
seccompProfile:
type: RuntimeDefault

View File

@@ -0,0 +1,5 @@
resources:
- deployment.yaml
- services.yaml
- secrets.yaml
- namespace.yaml

View File

@@ -0,0 +1,6 @@
kind: Namespace
apiVersion: v1
metadata:
name: prettysunflower-website
labels:
name: prettysunflower-website

View File

@@ -0,0 +1,47 @@
apiVersion: v1
kind: Secret
metadata:
name: prettysunflower-website-secret
namespace: prettysunflower-website
type: Opaque
data:
GOOGLE_API_KEY: ENC[AES256_GCM,data:Kff/H1QrNmyUoNCgG/DJmYTSluBfQkzATpNYcW+mpXA5igR1TW/8rxBI3pEavbiXq8s5dg==,iv:2w6gt7+r/bQTlWmObBeqkY/8osdAmvKaWUjIm+DjNyc=,tag:rLFP3GiJ+QMGFH81noKutQ==,type:str]
sops:
age:
- recipient: age1r0tjhg6uexyj0p7fp0ftv5h7r7e3ptzkk2797pznfvrvsm576u0s37yyaw
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzZXZUZklxb2UyRHA0OSt0
UXdad2FnQ2RVaVFKWkgvUFduUnVJVkpsZXhjCjF0dUlJTmVvUFVhZ2pueUdBS0t2
MHZKS29XRkUwTUUwSWNmb28relhxME0KLS0tIFZuT0JCZU9nMFltUk0yTU1zV2U0
YWdTRm5wdUdBN3BJelZhQUZhWllRTVUKxNufC3hgtybXvB+AL4rqeDCCGsbSTG3Z
f+04lkOLzcLr2sTBueGNG8UfnflSQI1JIrlHAzb7LlNi4vuH3KdFEg==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-05-29T22:40:27Z"
mac: ENC[AES256_GCM,data:JtiGrHVD+JJQ5ZwHLCT4rTOu/UoYCscn1Wv0F3E8Q1y9olFXLhq4b9L/vOGe+Wf4/8cl56zf9YnifWR73c71/qnTjsByN/0zqWJjtsDomaxFkGtjLwKbnvvJs3+NyUw1OJGSnL0c79rhEZTkzfFrN/td1hbr/Qho227UvoVOLsc=,iv:YHBAJqUJBz/kzcdNOUPDxaWqEVVmHvkgcjbP2FYwwDA=,tag:OIM5/vlgMCxRYocvy6xjRw==,type:str]
encrypted_regex: ^(data|stringData)$
version: 3.10.2
---
apiVersion: v1
kind: Secret
metadata:
name: anubis-key
namespace: prettysunflower-website
type: Opaque
data:
ED25519_PRIVATE_KEY_HEX: ENC[AES256_GCM,data:uVHaqVVCLb9j8y/zXo2ZutfYgi8tu1sLJ003yw0l7C+jy/s2hHKkgVwqXMTZRA+Hq0RIRNEwHyswfM8tQ2olmQVlPASEXnT0yW0lAidoZ/xf8fs1Am14vg==,iv:w/ag0nJ3MnP3UUGq6iMNu/qHLr+kt8G/Ntzd6APQCuY=,tag:mAHZM2PGAqHjnp4QVIkqPg==,type:str]
sops:
age:
- recipient: age1r0tjhg6uexyj0p7fp0ftv5h7r7e3ptzkk2797pznfvrvsm576u0s37yyaw
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSAzZXZUZklxb2UyRHA0OSt0
UXdad2FnQ2RVaVFKWkgvUFduUnVJVkpsZXhjCjF0dUlJTmVvUFVhZ2pueUdBS0t2
MHZKS29XRkUwTUUwSWNmb28relhxME0KLS0tIFZuT0JCZU9nMFltUk0yTU1zV2U0
YWdTRm5wdUdBN3BJelZhQUZhWllRTVUKxNufC3hgtybXvB+AL4rqeDCCGsbSTG3Z
f+04lkOLzcLr2sTBueGNG8UfnflSQI1JIrlHAzb7LlNi4vuH3KdFEg==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-05-29T22:40:27Z"
mac: ENC[AES256_GCM,data:JtiGrHVD+JJQ5ZwHLCT4rTOu/UoYCscn1Wv0F3E8Q1y9olFXLhq4b9L/vOGe+Wf4/8cl56zf9YnifWR73c71/qnTjsByN/0zqWJjtsDomaxFkGtjLwKbnvvJs3+NyUw1OJGSnL0c79rhEZTkzfFrN/td1hbr/Qho227UvoVOLsc=,iv:YHBAJqUJBz/kzcdNOUPDxaWqEVVmHvkgcjbP2FYwwDA=,tag:OIM5/vlgMCxRYocvy6xjRw==,type:str]
encrypted_regex: ^(data|stringData)$
version: 3.10.2

View File

@@ -0,0 +1,29 @@
apiVersion: v1
kind: Service
metadata:
name: website
namespace: prettysunflower-website
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: prettysunflower-website
ports:
- protocol: TCP
port: 80
targetPort: 8080
name: anubis
---
apiVersion: v1
kind: Service
metadata:
name: static
namespace: prettysunflower-website
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: prettysunflower-website
ports:
- protocol: TCP
port: 80
targetPort: 8001
name: anubis-static

View File

@@ -0,0 +1,32 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: technitium-dns
labels:
app.kubernetes.io/name: technitium-dns
spec:
replicas: 3
selector:
matchLabels:
app.kubernetes.io/name: technitium-dns
template:
metadata:
labels:
app.kubernetes.io/name: technitium-dns
spec:
volumes:
- name: technitium-data
persistentVolumeClaim:
claimName: technitium-data-pvc
containers:
- image: technitium/dns-server:latest
name: technitium
ports:
- containerPort: 5380
- containerPort: 53
protocol: TCP
- containerPort: 53
protocol: UDP
volumeMounts:
- name: technitium-data
mountPath: "/etc/dns"

View File

@@ -0,0 +1,4 @@
resources:
- pvc.yaml
- deployment.yaml
- services.yaml

11
apps/technitium/pvc.yaml Normal file
View File

@@ -0,0 +1,11 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: technitium-data-pvc
spec:
accessModes:
- ReadWriteMany
storageClassName: longhorn
resources:
requests:
storage: 1Gi

View File

@@ -0,0 +1,24 @@
apiVersion: v1
kind: Service
metadata:
name: technitium
spec:
type: NodePort
selector:
app.kubernetes.io/name: technitium-dns
ports:
- protocol: TCP
port: 80
targetPort: 5380
nodePort: 30011
name: http
- protocol: TCP
port: 53
targetPort: 53
nodePort: 30012
name: dns-tcp
- protocol: UDP
port: 53
targetPort: 53
nodePort: 30012
name: dns-udp

11
apps/thelounge/pvc.yaml Normal file
View File

@@ -0,0 +1,11 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: thelounge-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 2Gi

View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: Service
metadata:
name: thelounge
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: thelounge
ports:
- protocol: TCP
port: 80
targetPort: 9000

View File

@@ -0,0 +1,30 @@
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: thelounge
labels:
app.kubernetes.io/name: thelounge
spec:
replicas: 1
serviceName: "thelounge"
selector:
matchLabels:
app.kubernetes.io/name: thelounge
template:
metadata:
labels:
app.kubernetes.io/name: thelounge
spec:
volumes:
- name: thelounge-data
persistentVolumeClaim:
claimName: thelounge-pvc
containers:
- name: thelounge
image: ghcr.io/thelounge/thelounge:latest
imagePullPolicy: Always
ports:
- containerPort: 9000
volumeMounts:
- name: thelounge-data
mountPath: "/var/opt/thelounge"

View File

@@ -0,0 +1,33 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: uptime-kuma
namespace: uptime-kuma
labels:
app.kubernetes.io/name: uptime-kuma
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: uptime-kuma
template:
metadata:
labels:
app.kubernetes.io/name: uptime-kuma
spec:
hostAliases:
- ip: "100.113.193.5"
hostnames:
- "mail.prettysunflower.moe"
volumes:
- name: uptime-kuma-data
persistentVolumeClaim:
claimName: uptime-kuma-pvc
containers:
- image: louislam/uptime-kuma:1
name: uptime-kuma
ports:
- containerPort: 3001
volumeMounts:
- name: uptime-kuma-data
mountPath: "/app/data"

View File

@@ -0,0 +1,5 @@
resources:
- deployment.yaml
- services.yaml
- pvc.yaml
- namespace.yaml

View File

@@ -0,0 +1,6 @@
kind: Namespace
apiVersion: v1
metadata:
name: uptime-kuma
labels:
name: uptime-kuma

12
apps/uptime-kuma/pvc.yaml Normal file
View File

@@ -0,0 +1,12 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: uptime-kuma-pvc
namespace: uptime-kuma
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 3Gi

View File

@@ -0,0 +1,14 @@
apiVersion: v1
kind: Service
metadata:
name: uptime-kuma
namespace: uptime-kuma
spec:
type: ClusterIP
selector:
app.kubernetes.io/name: uptime-kuma
ports:
- protocol: TCP
port: 80
targetPort: 3001
name: http

11
apps/znc/pvc.yaml Normal file
View File

@@ -0,0 +1,11 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: znc-pvc
spec:
accessModes:
- ReadWriteOnce
storageClassName: longhorn
resources:
requests:
storage: 2Gi

19
apps/znc/services.yaml Normal file
View File

@@ -0,0 +1,19 @@
apiVersion: v1
kind: Service
metadata:
name: znc-service
spec:
type: NodePort
selector:
app.kubernetes.io/name: znc
ports:
- protocol: TCP
port: 4921
targetPort: 4921
nodePort: 30004
name: https
- protocol: TCP
port: 4922
targetPort: 4922
nodePort: 30008
name: http

30
apps/znc/statefulset.yaml Normal file
View File

@@ -0,0 +1,30 @@
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: znc
labels:
app.kubernetes.io/name: znc
spec:
replicas: 1
serviceName: "znc"
selector:
matchLabels:
app.kubernetes.io/name: znc
template:
metadata:
labels:
app.kubernetes.io/name: znc
spec:
volumes:
- name: znc-config
persistentVolumeClaim:
claimName: znc-pvc
containers:
- name: znc
image: znc:latest
imagePullPolicy: Always
ports:
- containerPort: 4921
volumeMounts:
- name: znc-config
mountPath: "/znc-data"

7
infra/clusterconfig/.gitignore vendored Normal file
View File

@@ -0,0 +1,7 @@
yakumo-yukari.yaml
yakumo-byakuren.yaml
yakumo-tojiko.yaml
yakumo-chen.yaml
yakumo-ran.yaml
yakumo-fujiwara-no-moukou.yaml
talosconfig

View File

@@ -0,0 +1,21 @@
apiVersion: ENC[AES256_GCM,data:oJNPhgWHrlk=,iv:N63w0eTGkE5CqOYzYU67PzgZwLqudVNGHKlh8IQ0owo=,tag:c7LGt8OaUvk2Nkw2TJ1x0A==,type:str]
kind: ENC[AES256_GCM,data:jdK9MYmBwfyj2URPK2AQMgrYezeXPw==,iv:2znWPT5kP9szEOCxq0GYg+BFCxqVwq9WX8ZeH0BqMFs=,tag:PgkMbyrIZ30jSDgNVj7joA==,type:str]
name: ENC[AES256_GCM,data:6gIyFBDRjkSn,iv:ilUtpwYtBp0UPZ92xifRqi1F+1YCvwF+W1VZDaUSCIA=,tag:n6xkJBOlIvmQP2M3TOVOmQ==,type:str]
environment:
- ENC[AES256_GCM,data:LxwtKRLHfdbmp/J3ajW/24Msrv1x3R8ytTzruFEuhp7gZYgiRvgZHpNssamh9slb+ALNWMosoow+xH8T/Bq5kJak4L9takd0,iv:cxYmo/y7wEJ/lm/8rM72ZoTAaRrr2uHcbgAdDUANiy0=,tag:ntzuhv9tiIb4Ta4JDGQ1AA==,type:str]
- ENC[AES256_GCM,data:cOAOFYpr2Nlwjesd2L1ZMZa4FAOWKeuVa+V5xnZVeh6reblh,iv:foawyP5/c7fFTMA+t+wCEdbYAKBgxXvy/6ETN9KE9yo=,tag:GC2I1PNc4CiMj8SFTDurjw==,type:str]
sops:
age:
- recipient: age1r0tjhg6uexyj0p7fp0ftv5h7r7e3ptzkk2797pznfvrvsm576u0s37yyaw
enc: |
-----BEGIN AGE ENCRYPTED FILE-----
YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSBRTFJnQUZuOXJua0Z6YmZt
YklGVE9TY1lPM3Z3OERGeGlFZzcxaUhQWlV3CnVoenl0cXBaQnJMT1lPYTBsRUJ5
dHVaWWViWmx6ZWNubDVhSERKalFFYXMKLS0tIEUyaDZ6R0VJTnRHMHRSYU5DSWpp
cW91L05QcFFkK1NwdG9GSEVVYlVNUXcKvgOu6LmN87ZDK4QbayvTY85v+II1eKDt
hWYQyZphg9QuedD7V7bHcd3lzTSSXITIt1/D3lAWXOe+mbYsOS1Q1A==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-05-29T22:49:39Z"
mac: ENC[AES256_GCM,data:efiVYu5nOzqewrkzlt46i2RE5rYHoSI3x4mux83nWlMcbw1k5dFcMnHOkjnNeMC5z2Jy1RJLw4nXi1l6LvC7kCsjHdUId58gXbqgJmADQmF9KFJDQ3tulQZhKNvU4J+Cm+EZIRtCCISnIpoc/CqprcUELHbp/86cFhqIZRjuTGg=,iv:X7sNIjTuiYx5qDX6rdUjEX6PT0d8tvILPLAn3H+5d5k=,tag:WhsiN8u8Itv6LKTDqTZKsw==,type:str]
unencrypted_suffix: _unencrypted
version: 3.10.2

100
infra/talconfig.yaml Normal file
View File

@@ -0,0 +1,100 @@
---
clusterName: yakumo
talosVersion: v1.10.3
kubernetesVersion: v1.33.1
endpoint: https://10.0.0.240:6443
domain: yakumo.prettysunflower.moe
allowSchedulingOnControlPlanes: false
clusterPodNets:
- 10.244.0.0/16
clusterSvcNets:
- 10.96.0.0/12
patches:
- |-
- op: add
path: /machine/network/kubespan
value:
enabled: true
- op: add
path: /machine/features/hostDNS
value:
forwardKubeDNSToHost: false
nodes:
- hostname: yukari
ipAddress: 10.0.0.240
controlPlane: true
arch: amd64
installDisk: /dev/sda
nodeLabels:
location: yul
- hostname: byakuren
ipAddress: 10.0.15.33
controlPlane: true
arch: amd64
installDisk: /dev/sda
nodeLabels:
location: fsn
- hostname: tojiko
ipAddress: 10.0.15.35
controlPlane: true
arch: amd64
installDisk: /dev/sda
nodeLabels:
location: fsn
- hostname: chen
ipAddress: 10.0.15.32
controlPlane: false
arch: amd64
installDisk: /dev/sda
nodeLabels:
location: fsn
- hostname: ran
ipAddress: 10.0.0.241
controlPlane: false
arch: amd64
installDisk: /dev/sda
nodeLabels:
location: yul
- hostname: fujiwara-no-moukou
ipAddress: 10.0.0.245
controlPlane: false
arch: amd64
installDisk: /dev/sda
nodeLabels:
location: yul
controlPlane:
extraManifests:
- tailscale.patch.yaml
schematic:
customization:
systemExtensions:
officialExtensions:
- siderolabs/iscsi-tools
- siderolabs/qemu-guest-agent
- siderolabs/tailscale
- siderolabs/util-linux-tools
worker:
extraManifests:
- tailscale.patch.yaml
schematic:
customization:
systemExtensions:
officialExtensions:
- siderolabs/iscsi-tools
- siderolabs/qemu-guest-agent
- siderolabs/tailscale
- siderolabs/util-linux-tools
patches:
- |-
- op: add
path: /machine/kubelet/extraMounts
value:
- destination: /var/lib/longhorn
type: bind
source: /var/lib/longhorn
options:
- bind
- rshared
- rw

38
infra/talsecret.sops.yaml Normal file

File diff suppressed because one or more lines are too long