diff --git a/.mise/mise.lock b/.mise/mise.lock index f00e523..25d4661 100644 --- a/.mise/mise.lock +++ b/.mise/mise.lock @@ -481,6 +481,7 @@ url = "https://github.com/tamasfe/taplo/releases/download/0.10.0/taplo-linux-aar url_api = "https://api.github.com/repos/tamasfe/taplo/releases/assets/257322597" [tools.taplo."platforms.linux-x64"] +checksum = "blake3:4871fab0e60275a1eb46e7190726e144f56c9a9527f59b0d1da5a042baead8e2" url = "https://github.com/tamasfe/taplo/releases/download/0.10.0/taplo-linux-x86_64.gz" url_api = "https://api.github.com/repos/tamasfe/taplo/releases/assets/257322600" diff --git a/.sops.yaml b/.sops.yaml new file mode 100644 index 0000000..2413073 --- /dev/null +++ b/.sops.yaml @@ -0,0 +1,12 @@ +--- +creation_rules: + - path_regex: talos/.*\.sops\.ya?ml + mac_only_encrypted: true + age: "age1pq1kujt4l0f4ef0f2duw2txmcf87js23qxxq376erctqq6l8kc25duvszyk0kphpf4rfw54v9flae2zz86s3agchwux83ae8y5g38kgpehpv468gfdyqvks2hqd3s9r2zt6jd40vrjh5gzlhaex2v4hfya5wx7fykt89ty3ve9lsh2kemwytfuskruytq9kxwvys5w9uwa99a3ts2x68pex52j87qtkgjs4wnsmzeta0qsekz4jtrfqnhthge52nppe57fndaxzqsr3y64z5yyczh89mw97lur68uauk83z0c7c5j0ejj0azxmtt9fmm94rje9zefkf2dep0pgl84rcq64vk50neg5dye0rk3wxfeehvrqv5gnav6wmg5665kdmgxsvwje32kerj8zppvla6v92ul7gn4htw698yl5nqzx8lga4lxtj2kw5sdp9vamvsfmjwuqer5s9tpa2skhj3r4n0jjspy39uat4yk5fre6cr0xg6rqrdp3w0ktgzq4gx89r8252xklxxc4scxf4eaqphqgrcz8kcemjz0zlsq6knud6enq3z3spqjrdr3uagrk93j0rshc2zvy7tqqudzajqmre7l29qae6800pzpt6tf5emqj50lqp2xdey3df5uj06232ntfu2djzk6c8juh6h9tchk4vapn4g4jf8chlv5fqlfx4jnrsy8jv6szvwq6nx0nr0fn48ajae8fspnep8e9q5c9eukku86zejcq907292wypzcj4uurqs7ffranj73qsqsx3jtug75zkzyrf39ztqhkhxlcehddhav0vl4gpuexrs0qytdwfk9asc95kls7dx7g8xk96nwxphxd4za06ne4pmpcq9l88qc5wnjsdtxhtvdv0hmat24khs4dfw8ejpnyftqgkkjk80r23e03c08vs7vcj4d28qcmxg6g59sjz0zgkfj3g42nq7re4ysrz55qqhqxsrgxnmczw5wd8ufw3qcc8gsj87qm6h54h8tzj6e4jfcxwjhwmx2g0yanrczvrgw62yna9hy0wytrxjjcawejhfnj6jdsz588yu6epgs3uuuvnhdscxthpnduy2a8k7egzm7r8yyjp3ev29dve6ksr5rrk0v5xce55s3h9wn8dld0edj6ha9yfyvzgqhghv55fxfvmpn9vxyvs0w96hrzmngzjw9dv9k7wqmtcwh8qyzqrkfmm0xxw942wnlatfqssw9c8qpesgajh8v2aa6jpv2x4se3ck55y2apelskfs26yt5r5kjw5su5qptrnsentvy6exy92q5jzny4dvmx3y5s2uhfehnjcvtwrxhwldfjen7w9x43vdm96p7dv3fzvwhzmjvzr05nvjugrvky04fqehzhhmsfkw09v50uyht8yst5sd8ze6aahrlaymkhmzlaux5hh9p23qk9j44ck7pnurlz5z3ahfvhmkv4x5mgz0aundmhchg9zazdw9v7y0ue2pvhgqfnkj4vxs9s7dem8w69pzzqngt47y2a8qvkkgctq33jxmff8y2ag3pqyc5d2lqak7m2slas50h73vtk42q9j65jt634n9e5f8w7l0qy00xg9l3pg80qtfsctf06lx3p3p20kczwdvy6edf5yp0t2rtffwfgld7zun2my9ys9w0wh9glaxqwf85ay4fm2sjyhjkt4r2ruyl80ke4rrlpyue5f8zm4z4p8xy6447rggmpnfnem5kdar2lpapu9dua40r4rd7dzn0zprpqmc239q4jeg6e5uag59zdzysjzc89r5xt9m8fufjmtsau64fx2ef8gpas58ccn57esrxavcg6x596zdnv963d94a65ft6vkjpdky45tn9ulcf6xdms9c06m4dm4fgzw3rxtzezz2770wva4avw654r24d9hdh7are0rn69c9sdwd5mx45fruaze6l6" + - path_regex: (bootstrap|kubernetes)/.*\.sops\.ya?ml + encrypted_regex: "^(data|stringData)$" + mac_only_encrypted: true + age: "age1pq1kujt4l0f4ef0f2duw2txmcf87js23qxxq376erctqq6l8kc25duvszyk0kphpf4rfw54v9flae2zz86s3agchwux83ae8y5g38kgpehpv468gfdyqvks2hqd3s9r2zt6jd40vrjh5gzlhaex2v4hfya5wx7fykt89ty3ve9lsh2kemwytfuskruytq9kxwvys5w9uwa99a3ts2x68pex52j87qtkgjs4wnsmzeta0qsekz4jtrfqnhthge52nppe57fndaxzqsr3y64z5yyczh89mw97lur68uauk83z0c7c5j0ejj0azxmtt9fmm94rje9zefkf2dep0pgl84rcq64vk50neg5dye0rk3wxfeehvrqv5gnav6wmg5665kdmgxsvwje32kerj8zppvla6v92ul7gn4htw698yl5nqzx8lga4lxtj2kw5sdp9vamvsfmjwuqer5s9tpa2skhj3r4n0jjspy39uat4yk5fre6cr0xg6rqrdp3w0ktgzq4gx89r8252xklxxc4scxf4eaqphqgrcz8kcemjz0zlsq6knud6enq3z3spqjrdr3uagrk93j0rshc2zvy7tqqudzajqmre7l29qae6800pzpt6tf5emqj50lqp2xdey3df5uj06232ntfu2djzk6c8juh6h9tchk4vapn4g4jf8chlv5fqlfx4jnrsy8jv6szvwq6nx0nr0fn48ajae8fspnep8e9q5c9eukku86zejcq907292wypzcj4uurqs7ffranj73qsqsx3jtug75zkzyrf39ztqhkhxlcehddhav0vl4gpuexrs0qytdwfk9asc95kls7dx7g8xk96nwxphxd4za06ne4pmpcq9l88qc5wnjsdtxhtvdv0hmat24khs4dfw8ejpnyftqgkkjk80r23e03c08vs7vcj4d28qcmxg6g59sjz0zgkfj3g42nq7re4ysrz55qqhqxsrgxnmczw5wd8ufw3qcc8gsj87qm6h54h8tzj6e4jfcxwjhwmx2g0yanrczvrgw62yna9hy0wytrxjjcawejhfnj6jdsz588yu6epgs3uuuvnhdscxthpnduy2a8k7egzm7r8yyjp3ev29dve6ksr5rrk0v5xce55s3h9wn8dld0edj6ha9yfyvzgqhghv55fxfvmpn9vxyvs0w96hrzmngzjw9dv9k7wqmtcwh8qyzqrkfmm0xxw942wnlatfqssw9c8qpesgajh8v2aa6jpv2x4se3ck55y2apelskfs26yt5r5kjw5su5qptrnsentvy6exy92q5jzny4dvmx3y5s2uhfehnjcvtwrxhwldfjen7w9x43vdm96p7dv3fzvwhzmjvzr05nvjugrvky04fqehzhhmsfkw09v50uyht8yst5sd8ze6aahrlaymkhmzlaux5hh9p23qk9j44ck7pnurlz5z3ahfvhmkv4x5mgz0aundmhchg9zazdw9v7y0ue2pvhgqfnkj4vxs9s7dem8w69pzzqngt47y2a8qvkkgctq33jxmff8y2ag3pqyc5d2lqak7m2slas50h73vtk42q9j65jt634n9e5f8w7l0qy00xg9l3pg80qtfsctf06lx3p3p20kczwdvy6edf5yp0t2rtffwfgld7zun2my9ys9w0wh9glaxqwf85ay4fm2sjyhjkt4r2ruyl80ke4rrlpyue5f8zm4z4p8xy6447rggmpnfnem5kdar2lpapu9dua40r4rd7dzn0zprpqmc239q4jeg6e5uag59zdzysjzc89r5xt9m8fufjmtsau64fx2ef8gpas58ccn57esrxavcg6x596zdnv963d94a65ft6vkjpdky45tn9ulcf6xdms9c06m4dm4fgzw3rxtzezz2770wva4avw654r24d9hdh7are0rn69c9sdwd5mx45fruaze6l6" +stores: + yaml: + indent: 2 diff --git a/bootstrap/deploy-key.sops.yaml b/bootstrap/deploy-key.sops.yaml new file mode 100644 index 0000000..b310d61 --- /dev/null +++ b/bootstrap/deploy-key.sops.yaml @@ -0,0 +1,55 @@ +apiVersion: v1 +kind: Secret +metadata: + name: deploy-key + namespace: flux-system +stringData: + identity: ENC[AES256_GCM,data:8w3RUSbeP0Pnu0YrQXcAkoe49MsEk2kWyHAJ03j9n5MCFAP7BvHeFmAzrqit5dWO3GTdl8lTpkVfANhq4yXn/zVa8XMUf1k/8fBJSyN41ZvyQ/Kop0pnJpb9VJsUMHuA8fDhqDRp/cNtc10iLEoTa3I13mMsAnImibTWGX8OCskHCvSLvhkEmakt1A28DT9NpEYSrf0OfKqbRio29azjsxdfDKRyRUwhRUoYNgic4FGIKYDGKyoMmRGIfLTCV3kntD9Sy/Jc7DV+hpYFVvvsfYuMkcCDFSOfltAnCi93VjBYniY5NqRN00aAgYZmAHeORdIH251Ck6S+krfxQ3lQVnd38Esy/7nzKtLYXY6z5xB/pVTWzQNOz2rYwpkfZLxQzRhIo8SOUpBNCleA6VnA1q30IVogKZU1czDT2tbSL16c35409XjsqfUGPn5h7vGdYCJSqClftqp5RTzd2tdjfoYybLDhQo6PvOPY8ADHBTpfa3kGMOXxiSRcgdQiQIXQtPoRBvxKnJskeEqdfmKd,iv:+BRQJbSoHOt6Wysjv2nW2Me38uAdG66nu0Ov+xTSSTg=,tag:EN4U8gAdqXg0GzrEPUITYA==,type:str] + known_hosts: ENC[AES256_GCM,data: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,iv:EaIrKf6XalfWt6LLhGWetmVuV0zDQaLvFdia0Wm4AG4=,tag:0riZDzFfQZBQoWPQhfIHJQ==,type:str] +sops: + age: + - enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IG1sa2VtNzY4eDI1NTE5IGwrN1ZFQVow + YXZMcnlaRUY5azk3RG1rRFpmTHhicjlKWG9RMGRRd216aHU5d0NLSy9MUnNLdDZk + M0dkUHJnc3lYb0xHbTZIL1RKRE1zYkI4Y0JxVnBGdUlmdkJnR0gxWlVXWTV3Uitj + dkREbW95bi9mNEpyY0RRRjN0N0o0bGgxVnNKaU9Ca3VYV1lVUytjZTRLc0c4RWg1 + T1hNdmtZa0xaN3JqaE1KRHZYRkNEYWdIdHdYYWp4Z3JGeFZNMVRzQUtHZXE2NTYv + WjhaQzdpY0FndGpVQmlUN2haQ3dJOGlnRjZWc1gxQThKUGNkMjk0UmMrTElZbTY0 + akZ6V0FETm1WdWFmSW9EYmNyZG5qZTZqRnhxMjh4ZjY0YjZzeHRPZGhPQ2RneGlZ + SDRVblR2R2tjemM2UGl0SW4xWmt1bm9nOURiSHFRZXRxMjdDK0JqT29pNm5vMzNi + VFZKMGJ3WStIWHVuazR3aG4vaU14dFZWZzB1cG1oQXRYZysrS1dQWTRid1pRdjRJ + SWpBaVFLL3VkZ0dzcVo0TFJJMkpvM3VUaUZZU3RFcXVteDk4eGF4UysxUmZHU3dr + TEhlRUxYNi9WWmtDdnI5QytIcDZiZk4vTVY0djA3T2lhUXpJSnFtY0FQMFQ4cjZV + ajZjM1dsT1FISjBhSjlaSW5SN09GQU9IUUpWTVJKbmtsUXdwNUwvM3luNmRDcW9m + dUdvSS9jcmoyWE13dGlYVXhiTmhpSm82Y1hJVFVaL0lRVTcyYzNKMWR3ZGZscWls + OWJxNitkN2Iza1dXVUdaSVZXaWxFRDY3a1ZsV0VCUFJieVRvODN2V29WeGwxUWpK + cERWNDhLODdBYU5pTFNidGQwSmpEcTNyczdzWEJhdngvZUlFdFRBeWFUVzNKMzEr + QlpxVDNjcmUwaUFMbFlhTEpUQ05HVnBJc1ExNXNCbmxvNW1zdHJ6dGNXSWdoaDlI + TDhabUZlMndPZ3RlWUpXSENLbG5tMmFKekhtUkNKeUtUTnVkeFR2SjRsSzRDMlhi + Q1IyNzRZTU9zNXdBQjQwcEcrTE5hbGVuZHF2elFrRWo5ZGpicXF5eDc3RHN1Vjdt + Y3I0UHFOSnRDNXZ5ZVpSZXJqeTlaWHdVbjVBaXAzaXVBckN4OUp1MldsSWViNEk1 + Z3dIOVRhRW1zb1BTNGo1czYxdThXYjlYTkdqOE43cmdXSWFGeTMxbi9hOWpTOEo4 + N0FIb3hCd3laV2t5RVpGQ3FqRUF0Mk0wUlZIcEVQcGN1YSsvUGdLdkQvQXVTV09h + TEhyZHNzRjJkU3RqZTJGR1h6RkM5dmVuL2pPOGxGRzhDc2h3bXhLd2wrS0NEZXNm + NU1NeTZuQmYrUFpJQ3ZIZmxVMG52NHY2bHJhNnQvTklHQXFRaGt6S1g3TGpiajU0 + ZUxiTGhMc1Q2dUlmVkFYZTNzU0xRV3JnQ2grOFhLeDFiaXZ6UUlubzRsNk8zNXl6 + RjQwa295aUxLR0JyRDRTR3BiY3BNdDZ3eHZYRTNscnFRaXpkSW4zajRXSmlUaXBL + SW5FdnFKc3J1K0hDYmxTMnJGN3V6UVl3NGhGMmNidldDSUMxZThsL2QwNmFpd1VK + Q3pFRlpOKytrYlZFRThZRHBrZHVBT3Q0bkZuYmQ4S1lXU3JENUZTeDZiZ2l5UmlE + VlpMTW14OVlDT1VWWU1rbHoxSGw5ZTZaR0xFM2dkS3JubnRPMys1N3hiem9menpp + eU1CaUxhWTVjYU0xVXZRdXBFN3NrTklQSFJzcXZwRmV4Qm5ORWNPTldoZ1FhUFZr + MXZJVG8xeWVhRzBtdXRRREU2WktUM1lsNmJKT2tEblZKZVBLb2prVXJiZHBhamtN + VTZ1ck9hS1c3Zkx1ajQyYTVsOGt4dGIzekk0bkhabTBjcy94dWQ3ZERpTTkyTWZ6 + SlZuUUlLVEh0c2NtNWpYZEZzMGZSaUVZdDlJSHkwYllmaHFkQ2NjOXJTV1RCUQpI + SmVxc3pZYjFheTBOdnhsZHFHNTlsenZjTnowZUFFQklVQ2FUN1p3WStJCi0tLSBE + N0cvem1zY051dG05WldSeXNpTExWQnFVMXpUd0s0ZGRFRjNYSGJacVlVCqVCVxE2 + Id8s8etDCJ0J+jVJfjjCaBNyqXq6dzej+cak3+0x6wbQomqbF9+J2X9RiF/RlBw/ + WTLJ3rqEHh07Tf8= + -----END AGE ENCRYPTED FILE----- + recipient: age1pq1kujt4l0f4ef0f2duw2txmcf87js23qxxq376erctqq6l8kc25duvszyk0kphpf4rfw54v9flae2zz86s3agchwux83ae8y5g38kgpehpv468gfdyqvks2hqd3s9r2zt6jd40vrjh5gzlhaex2v4hfya5wx7fykt89ty3ve9lsh2kemwytfuskruytq9kxwvys5w9uwa99a3ts2x68pex52j87qtkgjs4wnsmzeta0qsekz4jtrfqnhthge52nppe57fndaxzqsr3y64z5yyczh89mw97lur68uauk83z0c7c5j0ejj0azxmtt9fmm94rje9zefkf2dep0pgl84rcq64vk50neg5dye0rk3wxfeehvrqv5gnav6wmg5665kdmgxsvwje32kerj8zppvla6v92ul7gn4htw698yl5nqzx8lga4lxtj2kw5sdp9vamvsfmjwuqer5s9tpa2skhj3r4n0jjspy39uat4yk5fre6cr0xg6rqrdp3w0ktgzq4gx89r8252xklxxc4scxf4eaqphqgrcz8kcemjz0zlsq6knud6enq3z3spqjrdr3uagrk93j0rshc2zvy7tqqudzajqmre7l29qae6800pzpt6tf5emqj50lqp2xdey3df5uj06232ntfu2djzk6c8juh6h9tchk4vapn4g4jf8chlv5fqlfx4jnrsy8jv6szvwq6nx0nr0fn48ajae8fspnep8e9q5c9eukku86zejcq907292wypzcj4uurqs7ffranj73qsqsx3jtug75zkzyrf39ztqhkhxlcehddhav0vl4gpuexrs0qytdwfk9asc95kls7dx7g8xk96nwxphxd4za06ne4pmpcq9l88qc5wnjsdtxhtvdv0hmat24khs4dfw8ejpnyftqgkkjk80r23e03c08vs7vcj4d28qcmxg6g59sjz0zgkfj3g42nq7re4ysrz55qqhqxsrgxnmczw5wd8ufw3qcc8gsj87qm6h54h8tzj6e4jfcxwjhwmx2g0yanrczvrgw62yna9hy0wytrxjjcawejhfnj6jdsz588yu6epgs3uuuvnhdscxthpnduy2a8k7egzm7r8yyjp3ev29dve6ksr5rrk0v5xce55s3h9wn8dld0edj6ha9yfyvzgqhghv55fxfvmpn9vxyvs0w96hrzmngzjw9dv9k7wqmtcwh8qyzqrkfmm0xxw942wnlatfqssw9c8qpesgajh8v2aa6jpv2x4se3ck55y2apelskfs26yt5r5kjw5su5qptrnsentvy6exy92q5jzny4dvmx3y5s2uhfehnjcvtwrxhwldfjen7w9x43vdm96p7dv3fzvwhzmjvzr05nvjugrvky04fqehzhhmsfkw09v50uyht8yst5sd8ze6aahrlaymkhmzlaux5hh9p23qk9j44ck7pnurlz5z3ahfvhmkv4x5mgz0aundmhchg9zazdw9v7y0ue2pvhgqfnkj4vxs9s7dem8w69pzzqngt47y2a8qvkkgctq33jxmff8y2ag3pqyc5d2lqak7m2slas50h73vtk42q9j65jt634n9e5f8w7l0qy00xg9l3pg80qtfsctf06lx3p3p20kczwdvy6edf5yp0t2rtffwfgld7zun2my9ys9w0wh9glaxqwf85ay4fm2sjyhjkt4r2ruyl80ke4rrlpyue5f8zm4z4p8xy6447rggmpnfnem5kdar2lpapu9dua40r4rd7dzn0zprpqmc239q4jeg6e5uag59zdzysjzc89r5xt9m8fufjmtsau64fx2ef8gpas58ccn57esrxavcg6x596zdnv963d94a65ft6vkjpdky45tn9ulcf6xdms9c06m4dm4fgzw3rxtzezz2770wva4avw654r24d9hdh7are0rn69c9sdwd5mx45fruaze6l6 + encrypted_regex: ^(data|stringData)$ + lastmodified: "2026-09-16T19:18:39Z" + mac: ENC[AES256_GCM,data:1vITCxz9DIk/0wV+cfjqJa2SQjBsxIGXEBGiR7dP/9oXQaklSqJHAX876HvVJh+YxAUDRAIMZCP7p8e3y03IYIOuarNOqlwtS5YytB6MImC4gGomF4yfBHIDw3fT9fbMk1zvI8gyFn9tbO72K4mHLpTgsU8En21okdjuiaBAQ/Q=,iv:uQdxqkLtiwQfvfsSFFXK3scz9D1lVeTT4/qw3wpvP44=,tag:wOM+lUJI+epdIypMneVgNw==,type:str] + mac_only_encrypted: true + version: 3.13.3 diff --git a/bootstrap/helmfile/apps.yaml b/bootstrap/helmfile/apps.yaml new file mode 100644 index 0000000..2da1833 --- /dev/null +++ b/bootstrap/helmfile/apps.yaml @@ -0,0 +1,54 @@ +--- +# yaml-language-server: $schema=https://json.schemastore.org/helmfile + +# Bootstraps core applications that provide a minimal runtime base for the +# cluster. These releases are installed first so the cluster has the resources +# Flux needs before its own reconciliation begins. +# +# After this bootstrap phase, Flux is ready to take over management of the +# application stack and continue reconciling downstream state. + +helmDefaults: + cleanupOnFail: true + forceConflicts: true + wait: true + waitForJobs: true + +bases: + - default.yaml + +releases: + - name: cilium + namespace: kube-system + inherit: + - template: default + + - name: coredns + namespace: kube-system + inherit: + - template: default + needs: ["kube-system/cilium"] + + - name: spegel + namespace: kube-system + inherit: + - template: default + needs: ["kube-system/coredns"] + + - name: cert-manager + namespace: cert-manager + inherit: + - template: default + needs: ["kube-system/spegel"] + + - name: flux-operator + namespace: flux-system + inherit: + - template: default + needs: ["cert-manager/cert-manager"] + + - name: flux-instance + namespace: flux-system + inherit: + - template: default + needs: ["flux-system/flux-operator"] diff --git a/bootstrap/helmfile/crds.yaml b/bootstrap/helmfile/crds.yaml new file mode 100644 index 0000000..5e57287 --- /dev/null +++ b/bootstrap/helmfile/crds.yaml @@ -0,0 +1,30 @@ +--- +# yaml-language-server: $schema=https://json.schemastore.org/helmfile + +# Bootstraps cluster-wide Custom Resource Definitions (CRDs) by extracting them +# from upstream Helm charts and applying them directly with kubectl. The releases +# below are never reconciled with helmfile apply or helmfile sync — only their +# CRDs are rendered (via --include-crds) and piped to the cluster. +# +# Installing CRDs out-of-band ensures they exist before Flux begins reconciling +# workloads that reference them, avoiding the need for dependsOn chains on nearly +# every Kustomization that consumes a CRD-backed resource. + +helmDefaults: + args: + - --include-crds + - --no-hooks + +bases: + - default.yaml + +releases: + - name: envoy-gateway + namespace: network + inherit: + - template: default + + - name: prometheus-operator-crds + namespace: observability + chart: oci://ghcr.io/prometheus-community/charts/prometheus-operator-crds + version: 29.0.0 diff --git a/bootstrap/helmfile/default.yaml b/bootstrap/helmfile/default.yaml new file mode 100644 index 0000000..575ff5d --- /dev/null +++ b/bootstrap/helmfile/default.yaml @@ -0,0 +1,8 @@ +--- +# yaml-language-server: $schema=https://json.schemastore.org/helmfile +templates: + default: + chart: '{{ (fromYaml (tpl (readFile "./templates/release.yaml.gotmpl") .)).chart }}' + version: '{{ (fromYaml (tpl (readFile "./templates/release.yaml.gotmpl") .)).version }}' + values: + - ./templates/values.yaml.gotmpl diff --git a/bootstrap/helmfile/templates/release.yaml.gotmpl b/bootstrap/helmfile/templates/release.yaml.gotmpl new file mode 100644 index 0000000..00cb5eb --- /dev/null +++ b/bootstrap/helmfile/templates/release.yaml.gotmpl @@ -0,0 +1,3 @@ +{{- $oci := fromYaml (readFile (printf "../../kubernetes/apps/%s/%s/app/ocirepository.yaml" .Release.Namespace .Release.Name)) -}} +chart: {{ $oci.spec.url }} +version: {{ $oci.spec.ref.tag }} diff --git a/bootstrap/helmfile/templates/values.yaml.gotmpl b/bootstrap/helmfile/templates/values.yaml.gotmpl new file mode 100644 index 0000000..2a046fa --- /dev/null +++ b/bootstrap/helmfile/templates/values.yaml.gotmpl @@ -0,0 +1 @@ +{{ (fromYaml (readFile (printf "../../../kubernetes/apps/%s/%s/app/helmrelease.yaml" .Release.Namespace .Release.Name))).spec.values | toYaml }} diff --git a/bootstrap/mod.just b/bootstrap/mod.just new file mode 100644 index 0000000..81d4106 --- /dev/null +++ b/bootstrap/mod.just @@ -0,0 +1,105 @@ +set no-exit-message +set quiet +set shell := ['bash', '-euo', 'pipefail', '-c'] +set script-interpreter := ['bash', '-euo', 'pipefail'] +set default-list +set default-script + +kubernetes_dir := justfile_dir() + '/kubernetes' + +[doc('Bootstrap the Talos cluster')] +[group('bootstrap')] +talos: talos-secret talos-apply talos-talosconfig talos-kubeconfig + +[doc('Bootstrap apps into the Talos cluster')] +[group('bootstrap')] +apps: apps-ready apps-namespaces apps-secrets apps-crds apps-helm + just log info "Cluster is bootstrapped — Flux will start syncing the Git repository" + +# No sops call or existence guard is needed: the bundle is stored already +# encrypted with the repo's age recipient, and existing bundles are left +# untouched. +[private] +[working-directory('../talos')] +talos-secret: + just log info "Generating secrets" stage "{{ recipe_name() }}" + topf secrets --confirm=false > /dev/null + +[private] +[working-directory('../talos')] +talos-apply: + just log info "Applying talos config and bootstrapping" stage "{{ recipe_name() }}" + topf apply --auto-bootstrap --confirm=false + +[private] +[working-directory('../talos')] +talos-talosconfig: + just log info "Generating talosconfig" stage "{{ recipe_name() }}" + topf talosconfig > talosconfig + +# topf issues short-lived admin certs by default; 8760h keeps the +# kubeconfig usable long-term. +[private] +[working-directory('../talos')] +talos-kubeconfig: + just log info "Fetching kubeconfig" stage "{{ recipe_name() }}" + topf kubeconfig --validity 8760h > "{{ justfile_dir() }}/kubeconfig" + +[private] +apps-crds: + just log info "Applying CRDs" stage "{{ recipe_name() }}" + if ! helmfile --file "{{ source_directory() }}/helmfile/crds.yaml" template --quiet | yq eval-all --exit-status 'select(.kind == "CustomResourceDefinition")' | kubectl apply --server-side --force-conflicts --filename -; then + just log fatal "Failed to apply crds" + fi + +[private] +apps-helm: + just log info "Syncing helmfile" stage "{{ recipe_name() }}" + if ! helmfile --file "{{ source_directory() }}/helmfile/apps.yaml" sync --hide-notes; then + just log fatal "Failed to sync helmfile" + fi + +[private] +apps-namespaces: + just log info "Applying namespaces for apps" stage "{{ recipe_name() }}" + for app in "{{ kubernetes_dir }}/apps"/*/; do + ns="$(basename "$app")" + if kubectl create namespace "$ns" --dry-run=client -o yaml \ + | kubectl apply --server-side --filename - &>/dev/null; then + just log info "Namespace applied" namespace "$ns" + else + just log fatal "Failed to apply namespace" namespace "$ns" + fi + done + +[private] +apps-secrets: + just log info "Applying secrets for apps" stage "{{ recipe_name() }}" + for secret in \ + "{{ source_directory() }}/deploy-key.sops.yaml" \ + "{{ source_directory() }}/sops-age.sops.yaml" \ + "{{ kubernetes_dir }}/components/sops/cluster-secrets.sops.yaml" + do + name="$(basename "$secret" .sops.yaml)" + if sops decrypt "$secret" \ + | kubectl --namespace flux-system apply --server-side --filename - &>/dev/null; then + just log info "Secret applied" resource "$name" + else + just log fatal "Failed to apply secret" resource "$name" + fi + done + +# Wait until nodes register as Ready=False. They only become Ready=True once the CNI is healthy. +[private] +apps-ready: + just log info "Waiting for nodes to register as Ready=False" stage "{{ recipe_name() }}" + if ! kubectl wait nodes --for=condition=Ready=True --all --timeout=10s &>/dev/null; then + deadline=$((SECONDS + 600)) + until kubectl wait nodes --for=condition=Ready=False --all --timeout=10s &>/dev/null; do + if (( SECONDS >= deadline )); then + just log fatal "Timed out waiting for nodes to register" + fi + just log info "Nodes not available, waiting for nodes to be available. Retrying in 5 seconds..." + sleep 5 + done + fi diff --git a/bootstrap/sops-age.sops.yaml b/bootstrap/sops-age.sops.yaml new file mode 100644 index 0000000..43a9f9f --- /dev/null +++ b/bootstrap/sops-age.sops.yaml @@ -0,0 +1,54 @@ +apiVersion: v1 +kind: Secret +metadata: + name: sops-age + namespace: flux-system +stringData: + age.agekey: ENC[AES256_GCM,data:YRjc3lHz4Y1vwUVqVeqjwIygXc0ifZdj73cv/paYsFndC4/dEToRY3oZk92ZquUACIa5k85iOPCBTeR9V632QCcjhwDsbXxE36IKFKs=,iv:h7Y2WIyG2zkvIIwC1WOPbGfCWN324qExyszqdePwS4A=,tag:U50t2W5lTt/ebt2GIgJWNw==,type:str] +sops: + age: + - enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IG1sa2VtNzY4eDI1NTE5IFVwZlZaeFc1 + M0plcDcvMmVPd3VSbkZVMWgya1ZwUXlZck9qMDBybWorYWVwVFBTVjhiaHVOWkho + SVpuN1UwUVRqeXZyY0JXMEFjRG13bmRPYXF3ZGM2d1BOQ2xvcTBma1dDTk9udjkv + MVNIZ2VHWnVzamo0UnE0MXdkRXRBOHppb3JhMHhWNXR0d3lvaTRlUzNxaHBhSWw1 + N2tCVUNPRkFSODRlaWd2TEdDbCt4em1QMm5iSTFwUUNldllZcGJ5K0tRNXUvdHFt + Wld5MnVGeUx2eFBRZ3Q0R25CZEpEQVB3dFpZNWZKL3FNZW5kMFV6VzU5SldyaWVv + elIvRklMVEFtNFF4elZxclc5ZHd0cVZFQVp2Q3cvYWptSjIrOHNNRDFMUHNmQmtz + Tzk5Q1FKelo1MEpqcUE2Sy9ucjZFeWNwQnIzcDNvWC9hcW9RSXVvT3ljWWJGVFVG + SXk0Sncva1hjYVFQOVVtRlpOK2EzU1Y1OGJJdmQ3NWEzbjF5UmNJYm41cUxvb0xm + dXRFU0Jqd3FxM25HcDQxM0ZKWUUreS9SVmsyVHpJS3JLeDhXdWU0K3NYTytUcjJa + eWNaYXRURVFpb3BleGMxMWl1NGJJZ3U0OTV0dklENFA0YUVGYWRSQ0NWTmVGT0xh + ak13SmxNTEk2ZCtwajh1WjFDeG52RklRWkJ4S1Vza2hMQ0JpRG5aYm9ra3pZZExR + dXEyUDBHL1kwOVVPbkw3Nk0wV2xiU2IwVU8rdmR5dTZSUmYwenc4ZEFYTEFEK0ZZ + bnhaNGl6REpFZmhuejluMVNFTDlPbkJSUUM1WWpJUXUvSFRNOUFiUzlMVG9ZUUhU + Vi9CVVdxbktRYjA0M2pPZllNVHZuMFo0TVlzU2dHcHZObnFYZXJyODBDUm5KZXFi + Y21KN2x0RmJFTEEzeVBDbDFkZHhFSm1YaWNQcjlOQ0N1OFZOQ2ZvOWRZdnFEbDIz + dmlQOVc3cnhiM2RBSDV4emh0dk43R0s0MUlUVDUvYTRsQ3VuVXJLYUF2ZGUzUjBP + YnlzSVB6dHBnQm1SSVpYdnNRWlJQMzErMG9mcFdBMWdEcnZXM0RmV2t0SEoxcS9Q + bnpoMUtpczU2V2g0SUxueWlVYmtONWdsdlNyMTNvNDNhd0YvSzllYW5MV3J4WVhW + bktPT2xrQTJKTWFFWEZGQUowSkU5SzNMd2FaZ3RjQjU1STlOaUdWTTB0Z2xJQkVx + a3BTT2R5bm95amd1Sjd5RkZwSVJmeVBsemtVdStRck81K2pRSzFkaFUxN1gwSGlX + Ky9ydjI5QWs4akRFUkY1SG5QNUtYT0pOVFBWNHE1ZUpFdThqT1pzdFFZMVBmOWJB + ZnBaQU1UNHU5MWs1V2J2VmlCZlo3bTErMXNQbUwyczU1YTZtWDA0dU9oemU1alcv + a3JyYjZwWUEwM1Y4Y1RyelVjd2RDemZmRXFibzltSlhuNFdqYjNya3dxSFMvajJt + bkdjZDIwdGpmTTIrbG0ySFBob2hoZnUyRmVUbG1CUTNxR2V0a1h6VHF3Unk1Umc1 + algyVEczT3J0WGhQeTBzYk1QT0hwbHg4MDR4WkRsY0ZubUxjWFpCcHdxWEtxb2tp + Si9IYzBSQU1EUkl5YXJzU0VCKzVaRks0dzBMWVNtZW1mYWVTdmVMb1QzSFB1bGor + aitIU2dRYXQybG5DaDZwdHJhNnJtNkNtM3NSV2hqaUU5WE52ald6b0dmZFU4WFJp + aThqeGx5OWMvQ0N3SHhYR3EzRnlTWHdTT1FtQTZDUnVyNEg3VVl6Wml0dlpVYVl5 + Vk5kNm1zZU5CR2s1dDRpSTYrdDVBV2pHcTEvamNwQjFXeHl1NGMvYVBmT3lDRTRt + NVE3M3hWa1VTRGNSczNxWnBUcCtPNGVPYi92UGZxc0dyMzFFYUVaVWVBOExlTDcv + eDZ4YUt1Mk5pN2c0Wm9RZk9TK1RkUWh0VVg3MmpJYW1MODhBUUk1Tm1KNDJDUQpS + alJlRWw2Z0Rrcy9tRVhKRVF5eWNJMlBwKytsNnRwNG4yL2RBSjlhTkw0Ci0tLSAx + KzhwMXF5bWowbS9TTEh1bzZCOFFZMFNQQ0lJV2RTT0l6azFEcW1waitrCtC57Bhf + GZ0O6k6RkMeIX7smJFeAPpFUSlVEnOOIXdth3ylzbYlaAUP/br3oTWILxc+NOY+x + bKhVMF4VxCBsdN4= + -----END AGE ENCRYPTED FILE----- + recipient: age1pq1kujt4l0f4ef0f2duw2txmcf87js23qxxq376erctqq6l8kc25duvszyk0kphpf4rfw54v9flae2zz86s3agchwux83ae8y5g38kgpehpv468gfdyqvks2hqd3s9r2zt6jd40vrjh5gzlhaex2v4hfya5wx7fykt89ty3ve9lsh2kemwytfuskruytq9kxwvys5w9uwa99a3ts2x68pex52j87qtkgjs4wnsmzeta0qsekz4jtrfqnhthge52nppe57fndaxzqsr3y64z5yyczh89mw97lur68uauk83z0c7c5j0ejj0azxmtt9fmm94rje9zefkf2dep0pgl84rcq64vk50neg5dye0rk3wxfeehvrqv5gnav6wmg5665kdmgxsvwje32kerj8zppvla6v92ul7gn4htw698yl5nqzx8lga4lxtj2kw5sdp9vamvsfmjwuqer5s9tpa2skhj3r4n0jjspy39uat4yk5fre6cr0xg6rqrdp3w0ktgzq4gx89r8252xklxxc4scxf4eaqphqgrcz8kcemjz0zlsq6knud6enq3z3spqjrdr3uagrk93j0rshc2zvy7tqqudzajqmre7l29qae6800pzpt6tf5emqj50lqp2xdey3df5uj06232ntfu2djzk6c8juh6h9tchk4vapn4g4jf8chlv5fqlfx4jnrsy8jv6szvwq6nx0nr0fn48ajae8fspnep8e9q5c9eukku86zejcq907292wypzcj4uurqs7ffranj73qsqsx3jtug75zkzyrf39ztqhkhxlcehddhav0vl4gpuexrs0qytdwfk9asc95kls7dx7g8xk96nwxphxd4za06ne4pmpcq9l88qc5wnjsdtxhtvdv0hmat24khs4dfw8ejpnyftqgkkjk80r23e03c08vs7vcj4d28qcmxg6g59sjz0zgkfj3g42nq7re4ysrz55qqhqxsrgxnmczw5wd8ufw3qcc8gsj87qm6h54h8tzj6e4jfcxwjhwmx2g0yanrczvrgw62yna9hy0wytrxjjcawejhfnj6jdsz588yu6epgs3uuuvnhdscxthpnduy2a8k7egzm7r8yyjp3ev29dve6ksr5rrk0v5xce55s3h9wn8dld0edj6ha9yfyvzgqhghv55fxfvmpn9vxyvs0w96hrzmngzjw9dv9k7wqmtcwh8qyzqrkfmm0xxw942wnlatfqssw9c8qpesgajh8v2aa6jpv2x4se3ck55y2apelskfs26yt5r5kjw5su5qptrnsentvy6exy92q5jzny4dvmx3y5s2uhfehnjcvtwrxhwldfjen7w9x43vdm96p7dv3fzvwhzmjvzr05nvjugrvky04fqehzhhmsfkw09v50uyht8yst5sd8ze6aahrlaymkhmzlaux5hh9p23qk9j44ck7pnurlz5z3ahfvhmkv4x5mgz0aundmhchg9zazdw9v7y0ue2pvhgqfnkj4vxs9s7dem8w69pzzqngt47y2a8qvkkgctq33jxmff8y2ag3pqyc5d2lqak7m2slas50h73vtk42q9j65jt634n9e5f8w7l0qy00xg9l3pg80qtfsctf06lx3p3p20kczwdvy6edf5yp0t2rtffwfgld7zun2my9ys9w0wh9glaxqwf85ay4fm2sjyhjkt4r2ruyl80ke4rrlpyue5f8zm4z4p8xy6447rggmpnfnem5kdar2lpapu9dua40r4rd7dzn0zprpqmc239q4jeg6e5uag59zdzysjzc89r5xt9m8fufjmtsau64fx2ef8gpas58ccn57esrxavcg6x596zdnv963d94a65ft6vkjpdky45tn9ulcf6xdms9c06m4dm4fgzw3rxtzezz2770wva4avw654r24d9hdh7are0rn69c9sdwd5mx45fruaze6l6 + encrypted_regex: ^(data|stringData)$ + lastmodified: "2026-09-16T19:18:39Z" + mac: ENC[AES256_GCM,data:ghV8V2IExENuntQlcnirocvhdaJabhPxDzk4x4EmVSbAIYw6PdSckGzy/KF0vhNxOpBMJhF3lqAwkqZQEVLXP0P9Reh4gWi7tp9Vsk8OUbAChoGykbHhthKKcOeysiSl8jZwL/wBVkbLG/9n6ItIIPb5qOiwgVXOObS477vUufY=,iv:Lb/qCGxrdbLs00HKjQUIiRGPRsVMzThYuZ6zX6dvdNs=,tag:jDMo8sd/F6d0zrss6hBAxA==,type:str] + mac_only_encrypted: true + version: 3.13.3 diff --git a/kubernetes/apps/cert-manager/cert-manager/app/clusterissuer.yaml b/kubernetes/apps/cert-manager/cert-manager/app/clusterissuer.yaml new file mode 100644 index 0000000..9a606c4 --- /dev/null +++ b/kubernetes/apps/cert-manager/cert-manager/app/clusterissuer.yaml @@ -0,0 +1,30 @@ +--- +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: selfsigned +spec: + selfSigned: {} +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: internal-ca +spec: + isCA: true + commonName: internal-ca + secretName: internal-ca + privateKey: + algorithm: ECDSA + size: 256 + issuerRef: + name: selfsigned + kind: ClusterIssuer +--- +apiVersion: cert-manager.io/v1 +kind: ClusterIssuer +metadata: + name: internal-ca +spec: + ca: + secretName: internal-ca diff --git a/kubernetes/apps/cert-manager/cert-manager/app/helmrelease.yaml b/kubernetes/apps/cert-manager/cert-manager/app/helmrelease.yaml new file mode 100644 index 0000000..ba524b1 --- /dev/null +++ b/kubernetes/apps/cert-manager/cert-manager/app/helmrelease.yaml @@ -0,0 +1,20 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: cert-manager +spec: + chartRef: + kind: OCIRepository + name: cert-manager + interval: 1h + values: + crds: + enabled: true + replicaCount: 2 + dns01RecursiveNameservers: https://1.1.1.1:443/dns-query,https://1.0.0.1:443/dns-query + dns01RecursiveNameserversOnly: true + prometheus: + enabled: true + servicemonitor: + enabled: true diff --git a/kubernetes/apps/cert-manager/cert-manager/app/kustomization.yaml b/kubernetes/apps/cert-manager/cert-manager/app/kustomization.yaml new file mode 100644 index 0000000..60788ee --- /dev/null +++ b/kubernetes/apps/cert-manager/cert-manager/app/kustomization.yaml @@ -0,0 +1,7 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ./clusterissuer.yaml + - ./helmrelease.yaml + - ./ocirepository.yaml diff --git a/kubernetes/apps/cert-manager/cert-manager/app/ocirepository.yaml b/kubernetes/apps/cert-manager/cert-manager/app/ocirepository.yaml new file mode 100644 index 0000000..55a808f --- /dev/null +++ b/kubernetes/apps/cert-manager/cert-manager/app/ocirepository.yaml @@ -0,0 +1,13 @@ +--- +apiVersion: source.toolkit.fluxcd.io/v1 +kind: OCIRepository +metadata: + name: cert-manager +spec: + interval: 15m + layerSelector: + mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip + operation: copy + ref: + tag: v1.21.2 + url: oci://quay.io/jetstack/charts/cert-manager diff --git a/kubernetes/apps/cert-manager/cert-manager/ks.yaml b/kubernetes/apps/cert-manager/cert-manager/ks.yaml new file mode 100644 index 0000000..f92d628 --- /dev/null +++ b/kubernetes/apps/cert-manager/cert-manager/ks.yaml @@ -0,0 +1,30 @@ +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: cert-manager +spec: + healthChecks: + - apiVersion: helm.toolkit.fluxcd.io/v2 + kind: HelmRelease + name: cert-manager + namespace: cert-manager + - apiVersion: cert-manager.io/v1 + kind: ClusterIssuer + name: internal-ca + healthCheckExprs: + - apiVersion: cert-manager.io/v1 + kind: ClusterIssuer + current: status.conditions.exists(e, e.type == 'Ready' && e.status == 'True') + interval: 1h + path: ./kubernetes/apps/cert-manager/cert-manager/app + postBuild: + substituteFrom: + - name: cluster-secrets + kind: Secret + prune: true + sourceRef: + kind: GitRepository + name: flux-system + namespace: flux-system + targetNamespace: cert-manager diff --git a/kubernetes/apps/cert-manager/kustomization.yaml b/kubernetes/apps/cert-manager/kustomization.yaml new file mode 100644 index 0000000..e24fb0b --- /dev/null +++ b/kubernetes/apps/cert-manager/kustomization.yaml @@ -0,0 +1,11 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: cert-manager + +components: + - ../../components/sops + +resources: + - ./namespace.yaml + - ./cert-manager/ks.yaml diff --git a/kubernetes/apps/cert-manager/namespace.yaml b/kubernetes/apps/cert-manager/namespace.yaml new file mode 100644 index 0000000..6e34540 --- /dev/null +++ b/kubernetes/apps/cert-manager/namespace.yaml @@ -0,0 +1,7 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: cert-manager + annotations: + kustomize.toolkit.fluxcd.io/prune: disabled diff --git a/kubernetes/apps/default/echo/app/helmrelease.yaml b/kubernetes/apps/default/echo/app/helmrelease.yaml new file mode 100644 index 0000000..30907a5 --- /dev/null +++ b/kubernetes/apps/default/echo/app/helmrelease.yaml @@ -0,0 +1,31 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: echo +spec: + chartRef: + kind: OCIRepository + name: echo + interval: 1h + values: + replicaCount: 2 + config: + kubernetes: true + trustedProxies: + - "10.42.0.0/16" + httpRoute: + enabled: true + hostnames: + - "{{ .Release.Name }}.${SECRET_DOMAIN}" + parentRefs: + - name: envoy-internal + namespace: network + monitoring: + serviceMonitor: + enabled: true + resources: + requests: + cpu: 10m + limits: + memory: 64Mi diff --git a/kubernetes/apps/default/echo/app/kustomization.yaml b/kubernetes/apps/default/echo/app/kustomization.yaml new file mode 100644 index 0000000..2ccd5a8 --- /dev/null +++ b/kubernetes/apps/default/echo/app/kustomization.yaml @@ -0,0 +1,6 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ./helmrelease.yaml + - ./ocirepository.yaml diff --git a/kubernetes/apps/default/echo/app/ocirepository.yaml b/kubernetes/apps/default/echo/app/ocirepository.yaml new file mode 100644 index 0000000..22e6205 --- /dev/null +++ b/kubernetes/apps/default/echo/app/ocirepository.yaml @@ -0,0 +1,13 @@ +--- +apiVersion: source.toolkit.fluxcd.io/v1 +kind: OCIRepository +metadata: + name: echo +spec: + interval: 15m + layerSelector: + mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip + operation: copy + ref: + tag: 0.2.5 + url: oci://ghcr.io/home-operations/charts/echo diff --git a/kubernetes/apps/default/echo/ks.yaml b/kubernetes/apps/default/echo/ks.yaml new file mode 100644 index 0000000..f942a81 --- /dev/null +++ b/kubernetes/apps/default/echo/ks.yaml @@ -0,0 +1,19 @@ +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: echo +spec: + interval: 1h + path: ./kubernetes/apps/default/echo/app + postBuild: + substituteFrom: + - name: cluster-secrets + kind: Secret + prune: true + sourceRef: + kind: GitRepository + name: flux-system + namespace: flux-system + targetNamespace: default + wait: false diff --git a/kubernetes/apps/default/kustomization.yaml b/kubernetes/apps/default/kustomization.yaml new file mode 100644 index 0000000..d7271b1 --- /dev/null +++ b/kubernetes/apps/default/kustomization.yaml @@ -0,0 +1,11 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: default + +components: + - ../../components/sops + +resources: + - ./namespace.yaml + - ./echo/ks.yaml diff --git a/kubernetes/apps/default/namespace.yaml b/kubernetes/apps/default/namespace.yaml new file mode 100644 index 0000000..e3f8a49 --- /dev/null +++ b/kubernetes/apps/default/namespace.yaml @@ -0,0 +1,7 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: default + annotations: + kustomize.toolkit.fluxcd.io/prune: disabled diff --git a/kubernetes/apps/flux-system/flux-instance/app/helmrelease.yaml b/kubernetes/apps/flux-system/flux-instance/app/helmrelease.yaml new file mode 100644 index 0000000..ce046f3 --- /dev/null +++ b/kubernetes/apps/flux-system/flux-instance/app/helmrelease.yaml @@ -0,0 +1,133 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: flux-instance +spec: + chartRef: + kind: OCIRepository + name: flux-instance + interval: 1h + values: + commonAnnotations: + fluxcd.controlplane.io/reconcileArtifactEvery: 1h + instance: + cluster: + networkPolicy: false + components: + - source-controller + - kustomize-controller + - helm-controller + - notification-controller + sync: + kind: GitRepository + url: "https://git.grachevko.ru/grachevko/home-ops.git" + ref: "refs/heads/main" + path: kubernetes/flux/cluster + commonMetadata: + labels: + app.kubernetes.io/name: flux + kustomize: + patches: + - # Increase the number of workers + patch: | + - op: add + path: /spec/template/spec/containers/0/args/- + value: --concurrent=10 + - op: add + path: /spec/template/spec/containers/0/args/- + value: --requeue-dependency=5s + target: + kind: Deployment + name: (kustomize-controller|helm-controller|source-controller) + - # Increase the memory limits + patch: | + apiVersion: apps/v1 + kind: Deployment + metadata: + name: all + spec: + template: + spec: + containers: + - name: manager + resources: + limits: + memory: 1Gi + target: + kind: Deployment + name: (kustomize-controller|helm-controller|source-controller) + - # Enable in-memory kustomize builds + patch: | + - op: add + path: /spec/template/spec/containers/0/args/- + value: --concurrent=20 + - op: replace + path: /spec/template/spec/volumes/0 + value: + name: temp + emptyDir: + medium: Memory + target: + kind: Deployment + name: kustomize-controller + - # Enable Helm repositories caching + patch: | + - op: add + path: /spec/template/spec/containers/0/args/- + value: --helm-cache-max-size=10 + - op: add + path: /spec/template/spec/containers/0/args/- + value: --helm-cache-ttl=60m + - op: add + path: /spec/template/spec/containers/0/args/- + value: --helm-cache-purge-interval=5m + target: + kind: Deployment + name: source-controller + - # Flux near OOM detection for Helm + patch: | + - op: add + path: /spec/template/spec/containers/0/args/- + value: --feature-gates=OOMWatch=true + - op: add + path: /spec/template/spec/containers/0/args/- + value: --oom-watch-memory-threshold=95 + - op: add + path: /spec/template/spec/containers/0/args/- + value: --oom-watch-interval=500ms + target: + kind: Deployment + name: helm-controller + - # Disable chart digest tracking + patch: | + - op: add + path: /spec/template/spec/containers/0/args/- + value: --feature-gates=DisableChartDigestTracking=true + target: + kind: Deployment + name: helm-controller + - # Controller-level SOPS decryption + patch: | + - op: add + path: /spec/template/spec/containers/0/args/- + value: --sops-age-secret=sops-age + target: + kind: Deployment + name: kustomize-controller + - # Watch configmaps and secrets attached to HelmReleases and Kustomizations + patch: |- + - op: add + path: /spec/template/spec/containers/0/args/- + value: --watch-configs-label-selector=owner!=helm + target: + kind: Deployment + name: (helm-controller|kustomize-controller) + - # Cancel health checks on new Kustomizations revisions + patch: |- + - op: add + path: /spec/template/spec/containers/0/args/- + value: --feature-gates=CancelHealthCheckOnNewRevision=true + target: + kind: Deployment + name: kustomize-controller diff --git a/kubernetes/apps/flux-system/flux-instance/app/kustomization.yaml b/kubernetes/apps/flux-system/flux-instance/app/kustomization.yaml new file mode 100644 index 0000000..2ccd5a8 --- /dev/null +++ b/kubernetes/apps/flux-system/flux-instance/app/kustomization.yaml @@ -0,0 +1,6 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ./helmrelease.yaml + - ./ocirepository.yaml diff --git a/kubernetes/apps/flux-system/flux-instance/app/ocirepository.yaml b/kubernetes/apps/flux-system/flux-instance/app/ocirepository.yaml new file mode 100644 index 0000000..8aa1733 --- /dev/null +++ b/kubernetes/apps/flux-system/flux-instance/app/ocirepository.yaml @@ -0,0 +1,13 @@ +--- +apiVersion: source.toolkit.fluxcd.io/v1 +kind: OCIRepository +metadata: + name: flux-instance +spec: + interval: 15m + layerSelector: + mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip + operation: copy + ref: + tag: 0.60.0 + url: oci://ghcr.io/controlplaneio-fluxcd/charts/flux-instance diff --git a/kubernetes/apps/flux-system/flux-instance/ks.yaml b/kubernetes/apps/flux-system/flux-instance/ks.yaml new file mode 100644 index 0000000..1a35461 --- /dev/null +++ b/kubernetes/apps/flux-system/flux-instance/ks.yaml @@ -0,0 +1,21 @@ +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: flux-instance +spec: + dependsOn: + - name: flux-operator + interval: 1h + path: ./kubernetes/apps/flux-system/flux-instance/app + postBuild: + substituteFrom: + - name: cluster-secrets + kind: Secret + prune: true + sourceRef: + kind: GitRepository + name: flux-system + namespace: flux-system + targetNamespace: flux-system + wait: false diff --git a/kubernetes/apps/flux-system/flux-operator/app/helmrelease.yaml b/kubernetes/apps/flux-system/flux-operator/app/helmrelease.yaml new file mode 100644 index 0000000..08fba38 --- /dev/null +++ b/kubernetes/apps/flux-system/flux-operator/app/helmrelease.yaml @@ -0,0 +1,13 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: flux-operator +spec: + chartRef: + kind: OCIRepository + name: flux-operator + interval: 1h + values: + serviceMonitor: + create: true diff --git a/kubernetes/apps/flux-system/flux-operator/app/kustomization.yaml b/kubernetes/apps/flux-system/flux-operator/app/kustomization.yaml new file mode 100644 index 0000000..2ccd5a8 --- /dev/null +++ b/kubernetes/apps/flux-system/flux-operator/app/kustomization.yaml @@ -0,0 +1,6 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ./helmrelease.yaml + - ./ocirepository.yaml diff --git a/kubernetes/apps/flux-system/flux-operator/app/ocirepository.yaml b/kubernetes/apps/flux-system/flux-operator/app/ocirepository.yaml new file mode 100644 index 0000000..dc939db --- /dev/null +++ b/kubernetes/apps/flux-system/flux-operator/app/ocirepository.yaml @@ -0,0 +1,13 @@ +--- +apiVersion: source.toolkit.fluxcd.io/v1 +kind: OCIRepository +metadata: + name: flux-operator +spec: + interval: 15m + layerSelector: + mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip + operation: copy + ref: + tag: 0.60.0 + url: oci://ghcr.io/controlplaneio-fluxcd/charts/flux-operator diff --git a/kubernetes/apps/flux-system/flux-operator/ks.yaml b/kubernetes/apps/flux-system/flux-operator/ks.yaml new file mode 100644 index 0000000..2e39824 --- /dev/null +++ b/kubernetes/apps/flux-system/flux-operator/ks.yaml @@ -0,0 +1,19 @@ +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: flux-operator +spec: + interval: 1h + path: ./kubernetes/apps/flux-system/flux-operator/app + postBuild: + substituteFrom: + - name: cluster-secrets + kind: Secret + prune: true + sourceRef: + kind: GitRepository + name: flux-system + namespace: flux-system + targetNamespace: flux-system + wait: true diff --git a/kubernetes/apps/flux-system/kustomization.yaml b/kubernetes/apps/flux-system/kustomization.yaml new file mode 100644 index 0000000..4b0dd43 --- /dev/null +++ b/kubernetes/apps/flux-system/kustomization.yaml @@ -0,0 +1,12 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: flux-system + +components: + - ../../components/sops + +resources: + - ./namespace.yaml + - ./flux-instance/ks.yaml + - ./flux-operator/ks.yaml diff --git a/kubernetes/apps/flux-system/namespace.yaml b/kubernetes/apps/flux-system/namespace.yaml new file mode 100644 index 0000000..120760a --- /dev/null +++ b/kubernetes/apps/flux-system/namespace.yaml @@ -0,0 +1,7 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: flux-system + annotations: + kustomize.toolkit.fluxcd.io/prune: disabled diff --git a/kubernetes/apps/kube-system/cilium/app/helmrelease.yaml b/kubernetes/apps/kube-system/cilium/app/helmrelease.yaml new file mode 100644 index 0000000..1ebf4df --- /dev/null +++ b/kubernetes/apps/kube-system/cilium/app/helmrelease.yaml @@ -0,0 +1,87 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: cilium +spec: + chartRef: + kind: OCIRepository + name: cilium + interval: 1h + values: + autoDirectNodeRoutes: true + bpf: + masquerade: true + # Ref: https://github.com/siderolabs/talos/issues/10002 + hostLegacyRouting: true + cni: + # Required for pairing with Multus CNI + exclusive: false + cgroup: + automount: + enabled: false + hostRoot: /sys/fs/cgroup + # The stable bond name is defined in talos/all/20-network-links.yaml.tpl + devices: bond0+ + dashboards: + enabled: true + endpointRoutes: + enabled: true + envoy: + enabled: false + gatewayAPI: + enabled: false + hubble: + enabled: false + ipam: + mode: kubernetes + ipv4NativeRoutingCIDR: "10.42.0.0/16" + k8sServiceHost: 127.0.0.1 + k8sServicePort: 7445 + kubeProxyReplacement: true + kubeProxyReplacementHealthzBindAddr: 0.0.0.0:10256 + l2announcements: + enabled: true + loadBalancer: + algorithm: maglev + mode: "snat" + localRedirectPolicies: + enabled: true + operator: + dashboards: + enabled: true + prometheus: + enabled: true + serviceMonitor: + enabled: true + replicas: 2 + rollOutPods: true + prometheus: + enabled: true + serviceMonitor: + enabled: true + trustCRDsExist: true + rollOutCiliumPods: true + routingMode: native + securityContext: + capabilities: + ciliumAgent: + - CHOWN + - KILL + - NET_ADMIN + - NET_RAW + - IPC_LOCK + - SYS_ADMIN + - SYS_RESOURCE + - PERFMON + - BPF + - DAC_OVERRIDE + - FOWNER + - SETGID + - SETUID + cleanCiliumState: + - NET_ADMIN + - SYS_ADMIN + - SYS_RESOURCE + socketLB: + enabled: true diff --git a/kubernetes/apps/kube-system/cilium/app/kustomization.yaml b/kubernetes/apps/kube-system/cilium/app/kustomization.yaml new file mode 100644 index 0000000..791e352 --- /dev/null +++ b/kubernetes/apps/kube-system/cilium/app/kustomization.yaml @@ -0,0 +1,7 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ./helmrelease.yaml + - ./ocirepository.yaml + - ./networks.yaml diff --git a/kubernetes/apps/kube-system/cilium/app/networks.yaml b/kubernetes/apps/kube-system/cilium/app/networks.yaml new file mode 100644 index 0000000..cdbd20e --- /dev/null +++ b/kubernetes/apps/kube-system/cilium/app/networks.yaml @@ -0,0 +1,23 @@ +--- +apiVersion: cilium.io/v2alpha1 +kind: CiliumLoadBalancerIPPool +metadata: + name: pool +spec: + allowFirstLastIPs: "No" + blocks: + - cidr: "192.168.40.0/24" +--- +apiVersion: cilium.io/v2alpha1 +kind: CiliumL2AnnouncementPolicy +metadata: + name: l2-policy +spec: + loadBalancerIPs: true + # NOTE: interfaces might need to be set if you have more than one active NIC on your hosts + # interfaces: + # - ^eno[0-9]+ + # - ^eth[0-9]+ + nodeSelector: + matchLabels: + kubernetes.io/os: linux diff --git a/kubernetes/apps/kube-system/cilium/app/ocirepository.yaml b/kubernetes/apps/kube-system/cilium/app/ocirepository.yaml new file mode 100644 index 0000000..b95952e --- /dev/null +++ b/kubernetes/apps/kube-system/cilium/app/ocirepository.yaml @@ -0,0 +1,13 @@ +--- +apiVersion: source.toolkit.fluxcd.io/v1 +kind: OCIRepository +metadata: + name: cilium +spec: + interval: 15m + layerSelector: + mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip + operation: copy + ref: + tag: 1.20.1 + url: oci://quay.io/cilium/charts/cilium diff --git a/kubernetes/apps/kube-system/cilium/ks.yaml b/kubernetes/apps/kube-system/cilium/ks.yaml new file mode 100644 index 0000000..ea0a835 --- /dev/null +++ b/kubernetes/apps/kube-system/cilium/ks.yaml @@ -0,0 +1,19 @@ +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: cilium +spec: + interval: 1h + path: ./kubernetes/apps/kube-system/cilium/app + postBuild: + substituteFrom: + - name: cluster-secrets + kind: Secret + prune: true + sourceRef: + kind: GitRepository + name: flux-system + namespace: flux-system + targetNamespace: kube-system + wait: false diff --git a/kubernetes/apps/kube-system/coredns/app/helmrelease.yaml b/kubernetes/apps/kube-system/coredns/app/helmrelease.yaml new file mode 100644 index 0000000..672dc4d --- /dev/null +++ b/kubernetes/apps/kube-system/coredns/app/helmrelease.yaml @@ -0,0 +1,69 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: coredns +spec: + chartRef: + kind: OCIRepository + name: coredns + interval: 1h + values: + fullnameOverride: coredns + image: + repository: mirror.gcr.io/coredns/coredns + k8sAppLabelOverride: kube-dns + serviceAccount: + create: true + service: + name: kube-dns + clusterIP: "10.43.0.10" + replicaCount: 2 + priorityClassName: system-cluster-critical + servers: + - zones: + - zone: . + scheme: dns:// + use_tcp: true + port: 53 + plugins: + - name: errors + - name: health + configBlock: |- + lameduck 5s + - name: ready + - name: kubernetes + parameters: cluster.local in-addr.arpa ip6.arpa + configBlock: |- + pods verified + fallthrough in-addr.arpa ip6.arpa + - name: autopath + parameters: "@kubernetes" + - name: forward + parameters: . /etc/resolv.conf + - name: cache + configBlock: |- + prefetch 20 + serve_stale + servfail 0 + - name: loop + - name: reload + - name: loadbalance + - name: prometheus + parameters: 0.0.0.0:9153 + - name: log + configBlock: |- + class error + affinity: + nodeAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + nodeSelectorTerms: + - matchExpressions: + - key: node-role.kubernetes.io/control-plane + operator: Exists + tolerations: + - key: CriticalAddonsOnly + operator: Exists + - key: node-role.kubernetes.io/control-plane + operator: Exists + effect: NoSchedule diff --git a/kubernetes/apps/kube-system/coredns/app/kustomization.yaml b/kubernetes/apps/kube-system/coredns/app/kustomization.yaml new file mode 100644 index 0000000..2ccd5a8 --- /dev/null +++ b/kubernetes/apps/kube-system/coredns/app/kustomization.yaml @@ -0,0 +1,6 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ./helmrelease.yaml + - ./ocirepository.yaml diff --git a/kubernetes/apps/kube-system/coredns/app/ocirepository.yaml b/kubernetes/apps/kube-system/coredns/app/ocirepository.yaml new file mode 100644 index 0000000..21e7231 --- /dev/null +++ b/kubernetes/apps/kube-system/coredns/app/ocirepository.yaml @@ -0,0 +1,13 @@ +--- +apiVersion: source.toolkit.fluxcd.io/v1 +kind: OCIRepository +metadata: + name: coredns +spec: + interval: 15m + layerSelector: + mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip + operation: copy + url: oci://ghcr.io/coredns/charts/coredns + ref: + tag: 1.47.1 diff --git a/kubernetes/apps/kube-system/coredns/ks.yaml b/kubernetes/apps/kube-system/coredns/ks.yaml new file mode 100644 index 0000000..5ac2a87 --- /dev/null +++ b/kubernetes/apps/kube-system/coredns/ks.yaml @@ -0,0 +1,19 @@ +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: coredns +spec: + interval: 1h + path: ./kubernetes/apps/kube-system/coredns/app + postBuild: + substituteFrom: + - name: cluster-secrets + kind: Secret + prune: true + sourceRef: + kind: GitRepository + name: flux-system + namespace: flux-system + targetNamespace: kube-system + wait: false diff --git a/kubernetes/apps/kube-system/kustomization.yaml b/kubernetes/apps/kube-system/kustomization.yaml new file mode 100644 index 0000000..c52fff4 --- /dev/null +++ b/kubernetes/apps/kube-system/kustomization.yaml @@ -0,0 +1,15 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: kube-system + +components: + - ../../components/sops + +resources: + - ./namespace.yaml + - ./cilium/ks.yaml + - ./coredns/ks.yaml + - ./metrics-server/ks.yaml + - ./reloader/ks.yaml + - ./spegel/ks.yaml diff --git a/kubernetes/apps/kube-system/metrics-server/app/helmrelease.yaml b/kubernetes/apps/kube-system/metrics-server/app/helmrelease.yaml new file mode 100644 index 0000000..befc886 --- /dev/null +++ b/kubernetes/apps/kube-system/metrics-server/app/helmrelease.yaml @@ -0,0 +1,21 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: metrics-server +spec: + chartRef: + kind: OCIRepository + name: metrics-server + interval: 1h + values: + args: + - --kubelet-insecure-tls + - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname + - --kubelet-use-node-status-port + - --metric-resolution=10s + - --kubelet-request-timeout=2s + metrics: + enabled: true + serviceMonitor: + enabled: true diff --git a/kubernetes/apps/kube-system/metrics-server/app/kustomization.yaml b/kubernetes/apps/kube-system/metrics-server/app/kustomization.yaml new file mode 100644 index 0000000..2ccd5a8 --- /dev/null +++ b/kubernetes/apps/kube-system/metrics-server/app/kustomization.yaml @@ -0,0 +1,6 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ./helmrelease.yaml + - ./ocirepository.yaml diff --git a/kubernetes/apps/kube-system/metrics-server/app/ocirepository.yaml b/kubernetes/apps/kube-system/metrics-server/app/ocirepository.yaml new file mode 100644 index 0000000..cf8351d --- /dev/null +++ b/kubernetes/apps/kube-system/metrics-server/app/ocirepository.yaml @@ -0,0 +1,13 @@ +--- +apiVersion: source.toolkit.fluxcd.io/v1 +kind: OCIRepository +metadata: + name: metrics-server +spec: + interval: 15m + layerSelector: + mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip + operation: copy + ref: + tag: 3.14.0 + url: oci://ghcr.io/home-operations/charts-mirror/metrics-server diff --git a/kubernetes/apps/kube-system/metrics-server/ks.yaml b/kubernetes/apps/kube-system/metrics-server/ks.yaml new file mode 100644 index 0000000..60042b7 --- /dev/null +++ b/kubernetes/apps/kube-system/metrics-server/ks.yaml @@ -0,0 +1,19 @@ +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: metrics-server +spec: + interval: 1h + path: ./kubernetes/apps/kube-system/metrics-server/app + postBuild: + substituteFrom: + - name: cluster-secrets + kind: Secret + prune: true + sourceRef: + kind: GitRepository + name: flux-system + namespace: flux-system + targetNamespace: kube-system + wait: false diff --git a/kubernetes/apps/kube-system/namespace.yaml b/kubernetes/apps/kube-system/namespace.yaml new file mode 100644 index 0000000..7f6e64f --- /dev/null +++ b/kubernetes/apps/kube-system/namespace.yaml @@ -0,0 +1,7 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: kube-system + annotations: + kustomize.toolkit.fluxcd.io/prune: disabled diff --git a/kubernetes/apps/kube-system/reloader/app/helmrelease.yaml b/kubernetes/apps/kube-system/reloader/app/helmrelease.yaml new file mode 100644 index 0000000..100b095 --- /dev/null +++ b/kubernetes/apps/kube-system/reloader/app/helmrelease.yaml @@ -0,0 +1,17 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: reloader +spec: + chartRef: + kind: OCIRepository + name: reloader + interval: 1h + values: + fullnameOverride: reloader + reloader: + readOnlyRootFileSystem: true + podMonitor: + enabled: true + namespace: "{{ .Release.Namespace }}" diff --git a/kubernetes/apps/kube-system/reloader/app/kustomization.yaml b/kubernetes/apps/kube-system/reloader/app/kustomization.yaml new file mode 100644 index 0000000..2ccd5a8 --- /dev/null +++ b/kubernetes/apps/kube-system/reloader/app/kustomization.yaml @@ -0,0 +1,6 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ./helmrelease.yaml + - ./ocirepository.yaml diff --git a/kubernetes/apps/kube-system/reloader/app/ocirepository.yaml b/kubernetes/apps/kube-system/reloader/app/ocirepository.yaml new file mode 100644 index 0000000..98a2f4d --- /dev/null +++ b/kubernetes/apps/kube-system/reloader/app/ocirepository.yaml @@ -0,0 +1,13 @@ +--- +apiVersion: source.toolkit.fluxcd.io/v1 +kind: OCIRepository +metadata: + name: reloader +spec: + interval: 15m + layerSelector: + mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip + operation: copy + ref: + tag: 2.2.17 + url: oci://ghcr.io/stakater/charts/reloader diff --git a/kubernetes/apps/kube-system/reloader/ks.yaml b/kubernetes/apps/kube-system/reloader/ks.yaml new file mode 100644 index 0000000..5f5c65a --- /dev/null +++ b/kubernetes/apps/kube-system/reloader/ks.yaml @@ -0,0 +1,19 @@ +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: reloader +spec: + interval: 1h + path: ./kubernetes/apps/kube-system/reloader/app + postBuild: + substituteFrom: + - name: cluster-secrets + kind: Secret + prune: true + sourceRef: + kind: GitRepository + name: flux-system + namespace: flux-system + targetNamespace: kube-system + wait: false diff --git a/kubernetes/apps/kube-system/spegel/app/helmrelease.yaml b/kubernetes/apps/kube-system/spegel/app/helmrelease.yaml new file mode 100644 index 0000000..9a150b5 --- /dev/null +++ b/kubernetes/apps/kube-system/spegel/app/helmrelease.yaml @@ -0,0 +1,19 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: spegel +spec: + chartRef: + kind: OCIRepository + name: spegel + interval: 1h + values: + spegel: + containerdSock: /run/containerd/containerd.sock + containerdRegistryConfigPath: /etc/cri/conf.d/hosts + service: + registry: + hostPort: 29999 + serviceMonitor: + enabled: true diff --git a/kubernetes/apps/kube-system/spegel/app/kustomization.yaml b/kubernetes/apps/kube-system/spegel/app/kustomization.yaml new file mode 100644 index 0000000..2ccd5a8 --- /dev/null +++ b/kubernetes/apps/kube-system/spegel/app/kustomization.yaml @@ -0,0 +1,6 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ./helmrelease.yaml + - ./ocirepository.yaml diff --git a/kubernetes/apps/kube-system/spegel/app/ocirepository.yaml b/kubernetes/apps/kube-system/spegel/app/ocirepository.yaml new file mode 100644 index 0000000..3fd3ace --- /dev/null +++ b/kubernetes/apps/kube-system/spegel/app/ocirepository.yaml @@ -0,0 +1,13 @@ +--- +apiVersion: source.toolkit.fluxcd.io/v1 +kind: OCIRepository +metadata: + name: spegel +spec: + interval: 15m + layerSelector: + mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip + operation: copy + ref: + tag: 0.7.4 + url: oci://ghcr.io/spegel-org/helm-charts/spegel diff --git a/kubernetes/apps/kube-system/spegel/ks.yaml b/kubernetes/apps/kube-system/spegel/ks.yaml new file mode 100644 index 0000000..f6a6a48 --- /dev/null +++ b/kubernetes/apps/kube-system/spegel/ks.yaml @@ -0,0 +1,19 @@ +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: spegel +spec: + interval: 1h + path: ./kubernetes/apps/kube-system/spegel/app + postBuild: + substituteFrom: + - name: cluster-secrets + kind: Secret + prune: true + sourceRef: + kind: GitRepository + name: flux-system + namespace: flux-system + targetNamespace: kube-system + wait: false diff --git a/kubernetes/apps/network/envoy-gateway/app/certificate.yaml b/kubernetes/apps/network/envoy-gateway/app/certificate.yaml new file mode 100644 index 0000000..eaf109d --- /dev/null +++ b/kubernetes/apps/network/envoy-gateway/app/certificate.yaml @@ -0,0 +1,18 @@ +--- +apiVersion: cert-manager.io/v1 +kind: Certificate +metadata: + name: "${SECRET_DOMAIN/./-}-production" +spec: + dnsNames: + - "${SECRET_DOMAIN}" + - "*.${SECRET_DOMAIN}" + duration: 160h + issuerRef: + name: internal-ca + kind: ClusterIssuer + privateKey: + algorithm: ECDSA + secretName: "${SECRET_DOMAIN/./-}-production-tls" + usages: + - digital signature diff --git a/kubernetes/apps/network/envoy-gateway/app/envoy.yaml b/kubernetes/apps/network/envoy-gateway/app/envoy.yaml new file mode 100644 index 0000000..d7dd52a --- /dev/null +++ b/kubernetes/apps/network/envoy-gateway/app/envoy.yaml @@ -0,0 +1,137 @@ +--- +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: EnvoyProxy +metadata: + name: envoy +spec: + logging: + level: + default: info + provider: + type: Kubernetes + kubernetes: + envoyDeployment: + replicas: 2 + container: + imageRepository: mirror.gcr.io/envoyproxy/envoy + resources: + requests: + cpu: 100m + limits: + memory: 1Gi + envoyService: + externalTrafficPolicy: Cluster + shutdown: + drainTimeout: 180s + telemetry: + metrics: + prometheus: + compression: + type: Zstd +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: GatewayClass +metadata: + name: envoy +spec: + controllerName: gateway.envoyproxy.io/gatewayclass-controller + parametersRef: + group: gateway.envoyproxy.io + kind: EnvoyProxy + name: envoy + namespace: network +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + name: envoy-internal + annotations: + external-dns.kubernetes.io/target: internal.${SECRET_DOMAIN} +spec: + gatewayClassName: envoy + infrastructure: + annotations: + external-dns.kubernetes.io/hostname: internal.${SECRET_DOMAIN} + lbipam.cilium.io/ips: "192.168.40.11" + listeners: + - name: http + protocol: HTTP + port: 80 + allowedRoutes: + namespaces: + from: Same + - name: https + protocol: HTTPS + port: 443 + allowedRoutes: + namespaces: + from: All + tls: + certificateRefs: + - kind: Secret + name: ${SECRET_DOMAIN/./-}-production-tls +--- +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: BackendTrafficPolicy +metadata: + name: envoy +spec: + compressor: + - type: Zstd + zstd: {} + - type: Brotli + brotli: {} + - type: Gzip + gzip: {} + retry: + numRetries: 2 + retryOn: + triggers: + - reset + targetSelectors: + - group: gateway.networking.k8s.io + kind: Gateway + tcpKeepalive: {} + timeout: + http: + requestTimeout: 0s +--- +apiVersion: gateway.envoyproxy.io/v1alpha1 +kind: ClientTrafficPolicy +metadata: + name: envoy +spec: + clientIPDetection: + xForwardedFor: + trustedCIDRs: + - "10.42.0.0/16" + http2: + onInvalidMessage: TerminateStream + http3: {} + targetSelectors: + - group: gateway.networking.k8s.io + kind: Gateway + tcpKeepalive: {} + tls: + minVersion: "1.2" + alpnProtocols: + - h2 + - http/1.1 +--- +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: https-redirect + annotations: + external-dns.kubernetes.io/controller: none +spec: + parentRefs: + - name: envoy-internal + namespace: network + sectionName: http + rules: + - filters: + - type: RequestRedirect + requestRedirect: + scheme: https + statusCode: 301 diff --git a/kubernetes/apps/network/envoy-gateway/app/helmrelease.yaml b/kubernetes/apps/network/envoy-gateway/app/helmrelease.yaml new file mode 100644 index 0000000..55f3dea --- /dev/null +++ b/kubernetes/apps/network/envoy-gateway/app/helmrelease.yaml @@ -0,0 +1,20 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: envoy-gateway +spec: + chartRef: + kind: OCIRepository + name: envoy-gateway + interval: 1h + values: + global: + imageRegistry: mirror.gcr.io + config: + envoyGateway: + provider: + type: Kubernetes + kubernetes: + deploy: + type: GatewayNamespace diff --git a/kubernetes/apps/network/envoy-gateway/app/kustomization.yaml b/kubernetes/apps/network/envoy-gateway/app/kustomization.yaml new file mode 100644 index 0000000..545ef59 --- /dev/null +++ b/kubernetes/apps/network/envoy-gateway/app/kustomization.yaml @@ -0,0 +1,9 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ./certificate.yaml + - ./envoy.yaml + - ./helmrelease.yaml + - ./ocirepository.yaml + - ./podmonitor.yaml diff --git a/kubernetes/apps/network/envoy-gateway/app/ocirepository.yaml b/kubernetes/apps/network/envoy-gateway/app/ocirepository.yaml new file mode 100644 index 0000000..de028ab --- /dev/null +++ b/kubernetes/apps/network/envoy-gateway/app/ocirepository.yaml @@ -0,0 +1,13 @@ +--- +apiVersion: source.toolkit.fluxcd.io/v1 +kind: OCIRepository +metadata: + name: envoy-gateway +spec: + interval: 15m + layerSelector: + mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip + operation: copy + ref: + tag: 1.9.1 + url: oci://mirror.gcr.io/envoyproxy/gateway-helm diff --git a/kubernetes/apps/network/envoy-gateway/app/podmonitor.yaml b/kubernetes/apps/network/envoy-gateway/app/podmonitor.yaml new file mode 100644 index 0000000..b199aa8 --- /dev/null +++ b/kubernetes/apps/network/envoy-gateway/app/podmonitor.yaml @@ -0,0 +1,18 @@ +--- +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: envoy-proxy +spec: + jobLabel: envoy-proxy + namespaceSelector: + matchNames: + - network + podMetricsEndpoints: + - port: metrics + path: /stats/prometheus + honorLabels: true + selector: + matchLabels: + app.kubernetes.io/component: proxy + app.kubernetes.io/name: envoy diff --git a/kubernetes/apps/network/envoy-gateway/ks.yaml b/kubernetes/apps/network/envoy-gateway/ks.yaml new file mode 100644 index 0000000..78a3ce9 --- /dev/null +++ b/kubernetes/apps/network/envoy-gateway/ks.yaml @@ -0,0 +1,19 @@ +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: envoy-gateway +spec: + interval: 1h + path: ./kubernetes/apps/network/envoy-gateway/app + postBuild: + substituteFrom: + - name: cluster-secrets + kind: Secret + prune: true + sourceRef: + kind: GitRepository + name: flux-system + namespace: flux-system + targetNamespace: network + wait: false diff --git a/kubernetes/apps/network/k8s-gateway/app/helmrelease.yaml b/kubernetes/apps/network/k8s-gateway/app/helmrelease.yaml new file mode 100644 index 0000000..69fb2f7 --- /dev/null +++ b/kubernetes/apps/network/k8s-gateway/app/helmrelease.yaml @@ -0,0 +1,21 @@ +--- +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: k8s-gateway +spec: + chartRef: + kind: OCIRepository + name: k8s-gateway + interval: 1h + values: + fullnameOverride: k8s-gateway + domain: "${SECRET_DOMAIN}" + ttl: 1 + service: + type: LoadBalancer + port: 53 + annotations: + lbipam.cilium.io/ips: "192.168.40.12" + externalTrafficPolicy: Cluster + watchedResources: ["HTTPRoute", "Service"] diff --git a/kubernetes/apps/network/k8s-gateway/app/kustomization.yaml b/kubernetes/apps/network/k8s-gateway/app/kustomization.yaml new file mode 100644 index 0000000..2ccd5a8 --- /dev/null +++ b/kubernetes/apps/network/k8s-gateway/app/kustomization.yaml @@ -0,0 +1,6 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +resources: + - ./helmrelease.yaml + - ./ocirepository.yaml diff --git a/kubernetes/apps/network/k8s-gateway/app/ocirepository.yaml b/kubernetes/apps/network/k8s-gateway/app/ocirepository.yaml new file mode 100644 index 0000000..29e381d --- /dev/null +++ b/kubernetes/apps/network/k8s-gateway/app/ocirepository.yaml @@ -0,0 +1,13 @@ +--- +apiVersion: source.toolkit.fluxcd.io/v1 +kind: OCIRepository +metadata: + name: k8s-gateway +spec: + interval: 1h + layerSelector: + mediaType: application/vnd.cncf.helm.chart.content.v1.tar+gzip + operation: copy + ref: + tag: 3.7.3 + url: oci://codeberg.org/k8s-gateway/charts/k8s-gateway diff --git a/kubernetes/apps/network/k8s-gateway/ks.yaml b/kubernetes/apps/network/k8s-gateway/ks.yaml new file mode 100644 index 0000000..844476f --- /dev/null +++ b/kubernetes/apps/network/k8s-gateway/ks.yaml @@ -0,0 +1,19 @@ +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: k8s-gateway +spec: + interval: 1h + path: ./kubernetes/apps/network/k8s-gateway/app + postBuild: + substituteFrom: + - name: cluster-secrets + kind: Secret + prune: true + sourceRef: + kind: GitRepository + name: flux-system + namespace: flux-system + targetNamespace: network + wait: false diff --git a/kubernetes/apps/network/kustomization.yaml b/kubernetes/apps/network/kustomization.yaml new file mode 100644 index 0000000..eb0fd3e --- /dev/null +++ b/kubernetes/apps/network/kustomization.yaml @@ -0,0 +1,12 @@ +--- +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: network + +components: + - ../../components/sops + +resources: + - ./namespace.yaml + - ./envoy-gateway/ks.yaml + - ./k8s-gateway/ks.yaml diff --git a/kubernetes/apps/network/namespace.yaml b/kubernetes/apps/network/namespace.yaml new file mode 100644 index 0000000..17866ba --- /dev/null +++ b/kubernetes/apps/network/namespace.yaml @@ -0,0 +1,7 @@ +--- +apiVersion: v1 +kind: Namespace +metadata: + name: network + annotations: + kustomize.toolkit.fluxcd.io/prune: disabled diff --git a/kubernetes/components/sops/cluster-secrets.sops.yaml b/kubernetes/components/sops/cluster-secrets.sops.yaml new file mode 100644 index 0000000..46a867c --- /dev/null +++ b/kubernetes/components/sops/cluster-secrets.sops.yaml @@ -0,0 +1,53 @@ +apiVersion: v1 +kind: Secret +metadata: + name: cluster-secrets +stringData: + SECRET_DOMAIN: ENC[AES256_GCM,data:c8E/5LHk3cCusf72,iv:R+rD3r0fMm9nipi5/GTYpUuEatjskr3sz9VMQS7cfgA=,tag:jrVmNafhpsj6P0wLbhzyKA==,type:str] +sops: + age: + - enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IG1sa2VtNzY4eDI1NTE5IE5hYko2NW11 + T2VVRlJlQ2RJdk5ZaWtlRk1NdUR5TGQ0YStlVmNRcHRTL21xL2FNNm5yVkZDT2d0 + OUZnc29Jd0x6ZnduN1l3NUlIR3oyc1RIM0UzalQraHkySnVLdE9YbVAwVWZNOE5B + blE3VXUxL2JqTlo2M2hCK01kdFFaODdiTHQzdnNhUnRrck5obTIwNktZSENieDZk + ZERwSzVyY0x4YmpSeXhOdU5WdUx1VTFvQnpjekd1N3R2TURjamNZdXpsUVcyS1gr + MVFPcWdkT1Y0ZTNHMDd2d1d6YVR3Y1V2dEx2THhWbVdOZVlqZjBQVlFnZVR6a1lQ + ZVhBVkpabW9GZ0tsM2hWMVBkZVpOU29CQit6cnV4Z29KVzBkU3Rsa0huTC9BN2tY + NXF2MFlmZTMvZnQxRlZ4aVVtUXlGLytrZDBaR016VlpaTS9tek5DVU1tVWcvU0xV + KzJ4cGpZS01OMDdIVjQvSFkyUFNFMURFc0FLZENRWGpuOXVMRkFDekxuTjBMY3pD + dkRmMWViVzAxUWRuSUtFWG9vL2J6c2gvbG5PMFZNWjYrZHczYlA1ajBvQ3Vubk5r + YldmR1c2NXNsdVkvVUpTMTFlMisyaHd5eTZ6UWxhZXFZZ2hxOExMTmlZRDl2VjJX + bE9ORWRLV0hyL1g2Z00rblBYaHlyU2JIZG94THB5R2hEeENMbEo5c2ZRTkJJUEFi + WjdiNXFBNjh5Vkc1K3JBaThVK25iSFBJQmNCNURSc0x5bHR5S0V1UEljRUlyUlZt + dS9GNlNUWURnclFGZFhSc0JVRStscjMwYUJSVG9VSWdUYzhmTElwR3NhQyszQ2U3 + KzZkTHRLcHAyazY5QTIrTXFpMkF0Vit0Sm1lMjUwVVJPVC9wV2RXdVdXcTJFY1hU + enMrL3JEa3Zsakl6MEkvc2srcEZmeHQrOWpRbTV3ZWlnMk1Qb0VUU0dZV3lxVC9a + QkFFbFU1WHNHRXRORFdtaGRqT3RkalBkQ3EzdkVvWE51c2ZCcHMyR0dOc0FBY2pP + czkxSkRJck96NzlkbVViRzNkVDhZaldkU2hmZkpjTUFLVGJhbHBHM29xQVpLTnEw + aXdsMHVpYjZTR09kbkNQU0pqajhWZ1R4bUkrUVZKdlBJeWFWMUE5MkdScFlWTWhj + dThIb2NKMFJMWG05N0FrTTRxMUJURU81eTNsWmU1OGtTMGM4NCs3RFlMTHhlUTdH + NzJiN2sxditzZ29pdVp1NlE5OXhnanF1ME1XcTVEMTJtUHhuaFY2enUwcGRURFhq + NTdVK0RWRlVvanF4Tk1zbnRHSzB3SVF4KzRQbFUybFJxZGtuenp0R0E2M2NacElT + QXNmZFYxOTRQbXdxUkRzKzFZMnNQTjlhQ2xNYlVOcVhxVm1WVUNpV0Uyajh6a2l2 + QXpuVk1XZWVCTnhNWFlZRHdRaU5ENWp6bHZuZzFLTHNvWmg4K0xKckhUUlQ4UGR3 + WTM2QWJqcXRXRlc2Y2R6RDQ2dkpVaXpZL09mRU1Rck44SjNMM2p3T1ZNd09pZmhN + UnNYdHRMR052bDU4dmNsay9NVWxabm1qMTBJbFYwcXc5WEgwc3pDSnFPVGxaMjhB + ejRrWUNzdGJXVnRiNWdYUTBrditVRlErUEMrbk96QjlJZTd0dzlVcEVuakVZQ295 + WHNHVzhQb1ZiemZqWkJXcjlaMVJVK0pWZFhpdVhjSk5sajBDc3VOV3I0Y0tpOGkv + ZU0wUVRtQ1VRM0E5ZEN4UFk0RDE5NzBNQ0pUcUtrbkF4YlpMWlRqUWRTK2dzems4 + cW5oTzNnUnFGb3YyRUFkY2lDOUdacG9ma2JtSC9MNnFhYUJBcGkyMmEyNUpJSi91 + aVpyb0tMeTNTNkhsZUdmK2M4dXYvVkNvRjFxNGhhMG9mM2ZmcXRZbGNSeGdEOENN + VVdrYjRkTzhHcW1Ic3RNdHkyb0RkdWoveU5CVzdGQzVka2hrYVR0YmNrQlhRQQpj + a0FRNDRKbmZ3WTg2NXZDVU80b0p5TDM5Q3RBckk0R09WdER0L1VpNE44Ci0tLSBp + TnhPdFVObkVBVmtUSm5UNkQzdlhjaERtNEM3QVQyREw2V21CUklrV2ZnCnldYCm6 + TPfysxZiJdVeDHctGGegEdbfruYd6XwN6vAg2CdtNQ10Ib8xqiCJd4ZRLe2PIa0B + 08FxUeFAWX5IELU= + -----END AGE ENCRYPTED FILE----- + recipient: age1pq1kujt4l0f4ef0f2duw2txmcf87js23qxxq376erctqq6l8kc25duvszyk0kphpf4rfw54v9flae2zz86s3agchwux83ae8y5g38kgpehpv468gfdyqvks2hqd3s9r2zt6jd40vrjh5gzlhaex2v4hfya5wx7fykt89ty3ve9lsh2kemwytfuskruytq9kxwvys5w9uwa99a3ts2x68pex52j87qtkgjs4wnsmzeta0qsekz4jtrfqnhthge52nppe57fndaxzqsr3y64z5yyczh89mw97lur68uauk83z0c7c5j0ejj0azxmtt9fmm94rje9zefkf2dep0pgl84rcq64vk50neg5dye0rk3wxfeehvrqv5gnav6wmg5665kdmgxsvwje32kerj8zppvla6v92ul7gn4htw698yl5nqzx8lga4lxtj2kw5sdp9vamvsfmjwuqer5s9tpa2skhj3r4n0jjspy39uat4yk5fre6cr0xg6rqrdp3w0ktgzq4gx89r8252xklxxc4scxf4eaqphqgrcz8kcemjz0zlsq6knud6enq3z3spqjrdr3uagrk93j0rshc2zvy7tqqudzajqmre7l29qae6800pzpt6tf5emqj50lqp2xdey3df5uj06232ntfu2djzk6c8juh6h9tchk4vapn4g4jf8chlv5fqlfx4jnrsy8jv6szvwq6nx0nr0fn48ajae8fspnep8e9q5c9eukku86zejcq907292wypzcj4uurqs7ffranj73qsqsx3jtug75zkzyrf39ztqhkhxlcehddhav0vl4gpuexrs0qytdwfk9asc95kls7dx7g8xk96nwxphxd4za06ne4pmpcq9l88qc5wnjsdtxhtvdv0hmat24khs4dfw8ejpnyftqgkkjk80r23e03c08vs7vcj4d28qcmxg6g59sjz0zgkfj3g42nq7re4ysrz55qqhqxsrgxnmczw5wd8ufw3qcc8gsj87qm6h54h8tzj6e4jfcxwjhwmx2g0yanrczvrgw62yna9hy0wytrxjjcawejhfnj6jdsz588yu6epgs3uuuvnhdscxthpnduy2a8k7egzm7r8yyjp3ev29dve6ksr5rrk0v5xce55s3h9wn8dld0edj6ha9yfyvzgqhghv55fxfvmpn9vxyvs0w96hrzmngzjw9dv9k7wqmtcwh8qyzqrkfmm0xxw942wnlatfqssw9c8qpesgajh8v2aa6jpv2x4se3ck55y2apelskfs26yt5r5kjw5su5qptrnsentvy6exy92q5jzny4dvmx3y5s2uhfehnjcvtwrxhwldfjen7w9x43vdm96p7dv3fzvwhzmjvzr05nvjugrvky04fqehzhhmsfkw09v50uyht8yst5sd8ze6aahrlaymkhmzlaux5hh9p23qk9j44ck7pnurlz5z3ahfvhmkv4x5mgz0aundmhchg9zazdw9v7y0ue2pvhgqfnkj4vxs9s7dem8w69pzzqngt47y2a8qvkkgctq33jxmff8y2ag3pqyc5d2lqak7m2slas50h73vtk42q9j65jt634n9e5f8w7l0qy00xg9l3pg80qtfsctf06lx3p3p20kczwdvy6edf5yp0t2rtffwfgld7zun2my9ys9w0wh9glaxqwf85ay4fm2sjyhjkt4r2ruyl80ke4rrlpyue5f8zm4z4p8xy6447rggmpnfnem5kdar2lpapu9dua40r4rd7dzn0zprpqmc239q4jeg6e5uag59zdzysjzc89r5xt9m8fufjmtsau64fx2ef8gpas58ccn57esrxavcg6x596zdnv963d94a65ft6vkjpdky45tn9ulcf6xdms9c06m4dm4fgzw3rxtzezz2770wva4avw654r24d9hdh7are0rn69c9sdwd5mx45fruaze6l6 + encrypted_regex: ^(data|stringData)$ + lastmodified: "2026-09-16T19:18:39Z" + mac: ENC[AES256_GCM,data:39l4LWDBWzX4nHhGKbijAl+77eFEu72bplq6AWc9F6dR8aD3huNyZL5ZMsY/ABnGJD95Ef1s7b1m4+UTUb6ae40uXSyjr/qM5UeYW3LIlm9X9W4ln+d2+BZi5r3zmhN7Fg37S6d7Fg5dsBEkJ2e3MDs48nhF1IBGQJu08EijRWA=,iv:Bwdwgw4xjXAzn0zFjkSbYvYJbNCfMPhPlm3DhqGlqIg=,tag:Ye9FepwpYnsp1t4NPZlL+Q==,type:str] + mac_only_encrypted: true + version: 3.13.3 diff --git a/kubernetes/components/sops/kustomization.yaml b/kubernetes/components/sops/kustomization.yaml new file mode 100644 index 0000000..1948b44 --- /dev/null +++ b/kubernetes/components/sops/kustomization.yaml @@ -0,0 +1,5 @@ +--- +apiVersion: kustomize.config.k8s.io/v1alpha1 +kind: Component +resources: + - ./cluster-secrets.sops.yaml diff --git a/kubernetes/flux/cluster/ks.yaml b/kubernetes/flux/cluster/ks.yaml new file mode 100644 index 0000000..77d76e8 --- /dev/null +++ b/kubernetes/flux/cluster/ks.yaml @@ -0,0 +1,57 @@ +--- +apiVersion: kustomize.toolkit.fluxcd.io/v1 +kind: Kustomization +metadata: + name: cluster-apps + namespace: flux-system +spec: + decryption: + provider: sops + deletionPolicy: WaitForTermination + interval: 1h + path: ./kubernetes/apps + prune: true + sourceRef: + kind: GitRepository + name: flux-system + namespace: flux-system + wait: false + patches: + - # Add Kustomization defaults for all child Kustomizations + patch: |- + apiVersion: kustomize.toolkit.fluxcd.io/v1 + kind: Kustomization + metadata: + name: _ + spec: + decryption: + provider: sops + deletionPolicy: WaitForTermination + patches: + - patch: |- + apiVersion: helm.toolkit.fluxcd.io/v2 + kind: HelmRelease + metadata: + name: _ + spec: + install: + crds: CreateReplace + strategy: + name: RetryOnFailure + rollback: + cleanupOnFail: true + recreate: true + upgrade: + cleanupOnFail: true + crds: CreateReplace + strategy: + name: RemediateOnFailure + remediation: + remediateLastFailure: true + retries: 2 + target: + group: helm.toolkit.fluxcd.io + kind: HelmRelease + target: + group: kustomize.toolkit.fluxcd.io + kind: Kustomization diff --git a/kubernetes/mod.just b/kubernetes/mod.just new file mode 100644 index 0000000..b1de2b1 --- /dev/null +++ b/kubernetes/mod.just @@ -0,0 +1,10 @@ +set quiet +set shell := ['bash', '-euo', 'pipefail', '-c'] +set script-interpreter := ['bash', '-euo', 'pipefail'] +set default-list +set default-script + +[doc('Force Flux to pull in changes from your Git repository')] +[group('kube')] +reconcile: + flux --namespace flux-system reconcile kustomization flux-system --with-source diff --git a/talos/README.md b/talos/README.md new file mode 100644 index 0000000..b0359f7 --- /dev/null +++ b/talos/README.md @@ -0,0 +1,20 @@ +# Talos Patching + +Machine configs are assembled by [topf](https://postfinance.github.io/topf/) from +`topf.yaml` plus the strategic merge patches in this directory. + + + +## Patch Directories + +Patches merge in this order, alphabetically within each directory, with later +patches taking precedence: + +- `all/`: applied to every node +- `control-plane/`: applied to control-plane nodes +- `worker/`: applied to worker nodes +- `node/${hostname}/`: applied to the node with the specified name + +Files ending in `.yaml.tpl` are Go-templated per node; see the +[topf configuration model](https://postfinance.github.io/topf/main/configuration-model/) +for the available template variables. diff --git a/talos/all/00-install.yaml.tpl b/talos/all/00-install.yaml.tpl new file mode 100644 index 0000000..1a38a86 --- /dev/null +++ b/talos/all/00-install.yaml.tpl @@ -0,0 +1,9 @@ +apiVersion: v1alpha1 +kind: UnattendedInstallConfig +provisioning: + diskSelector: + {{- if .Node.Data.installDisk }} + match: disk.dev_path == "{{ .Node.Data.installDisk }}" || "{{ .Node.Data.installDisk }}" in disk.symlinks + {{- else }} + match: disk.serial == "{{ .Node.Data.installDiskSerial }}" + {{- end }} diff --git a/talos/all/01-hostname.yaml.tpl b/talos/all/01-hostname.yaml.tpl new file mode 100644 index 0000000..a6ac043 --- /dev/null +++ b/talos/all/01-hostname.yaml.tpl @@ -0,0 +1,4 @@ +apiVersion: v1alpha1 +kind: HostnameConfig +auto: "off" +hostname: "{{ .Node.Host }}" diff --git a/talos/all/10-cluster.yaml b/talos/all/10-cluster.yaml new file mode 100644 index 0000000..a400aed --- /dev/null +++ b/talos/all/10-cluster.yaml @@ -0,0 +1,9 @@ +machine: + certSANs: + - "127.0.0.1" + - "192.168.40.10" +--- +apiVersion: v1alpha1 +kind: KubeNetworkConfig +podSubnets: ["10.42.0.0/16"] +serviceSubnets: ["10.43.0.0/16"] diff --git a/talos/all/20-network-links.yaml.tpl b/talos/all/20-network-links.yaml.tpl new file mode 100644 index 0000000..67413b2 --- /dev/null +++ b/talos/all/20-network-links.yaml.tpl @@ -0,0 +1,25 @@ +--- +apiVersion: v1alpha1 +kind: LinkAliasConfig +name: ethSel0 +selector: + match: glob("{{ .Node.Data.macAddr }}", mac(link.hardware_addr)) +--- +apiVersion: v1alpha1 +kind: BondConfig +name: bond0 +links: + - ethSel0 +bondMode: active-backup +mtu: {{ .Node.Data.mtu }} +addresses: + - address: "{{ .Node.IP }}/24" +routes: + - gateway: "192.168.40.1" +{{- if eq .Node.Role "control-plane" }} +--- +apiVersion: v1alpha1 +kind: Layer2VIPConfig +link: bond0 +name: "192.168.40.10" +{{- end }} diff --git a/talos/all/21-network.yaml b/talos/all/21-network.yaml new file mode 100644 index 0000000..9737cc5 --- /dev/null +++ b/talos/all/21-network.yaml @@ -0,0 +1,7 @@ +apiVersion: v1alpha1 +kind: ResolverConfig +nameservers: + - address: 192.168.40.1 + - address: 1.1.1.1 +searchDomains: + disableDefault: true diff --git a/talos/all/22-time.yaml b/talos/all/22-time.yaml new file mode 100644 index 0000000..e236a00 --- /dev/null +++ b/talos/all/22-time.yaml @@ -0,0 +1,6 @@ +apiVersion: v1alpha1 +kind: TimeSyncConfig +ntp: + servers: + - 192.168.40.1 + - 162.159.200.1 diff --git a/talos/all/30-kubelet.yaml b/talos/all/30-kubelet.yaml new file mode 100644 index 0000000..6a42c0e --- /dev/null +++ b/talos/all/30-kubelet.yaml @@ -0,0 +1,16 @@ +apiVersion: v1alpha1 +kind: KubeletConfig +config: + crashLoopBackOff: + maxContainerRestartPeriod: 60s + imageMaximumGCAge: 168h + maxParallelImagePulls: 3 + serializeImagePulls: false + shutdownGracePeriod: 90s + shutdownGracePeriodCriticalPods: 60s +--- +apiVersion: v1alpha1 +kind: KubeNodeConfig +nodeIP: + validSubnets: + - 192.168.40.0/24 diff --git a/talos/all/40-sysctls.yaml b/talos/all/40-sysctls.yaml new file mode 100644 index 0000000..4bda500 --- /dev/null +++ b/talos/all/40-sysctls.yaml @@ -0,0 +1,12 @@ +apiVersion: v1alpha1 +kind: SysctlConfig +params: + fs.inotify.max_user_watches: "1048576" # Watchdog + fs.inotify.max_user_instances: "8192" # Watchdog + net.core.rmem_max: "7500000" # Cloudflared | QUIC + net.core.wmem_max: "7500000" # Cloudflared | QUIC + net.ipv4.neigh.default.gc_thresh1: "4096" # Prevent ARP cache overflows + net.ipv4.neigh.default.gc_thresh2: "8192" # Prevent ARP cache overflows + net.ipv4.neigh.default.gc_thresh3: "16384" # Prevent ARP cache overflows + net.ipv4.tcp_slow_start_after_idle: "0" # Preserve congestion window after idle + user.max_user_namespaces: "11255" # User Namespaces diff --git a/talos/all/50-files.yaml b/talos/all/50-files.yaml new file mode 100644 index 0000000..7208111 --- /dev/null +++ b/talos/all/50-files.yaml @@ -0,0 +1,8 @@ +apiVersion: v1alpha1 +kind: CRICustomizationConfig +name: containerd +content: | + [plugins."io.containerd.cri.v1.images"] + discard_unpacked_layers = false + [plugins."io.containerd.cri.v1.runtime"] + device_ownership_from_security_context = true diff --git a/talos/all/60-encryption.yaml.tpl b/talos/all/60-encryption.yaml.tpl new file mode 100644 index 0000000..c478f5b --- /dev/null +++ b/talos/all/60-encryption.yaml.tpl @@ -0,0 +1,20 @@ +{{- if .Node.Data.encryptDisk }} +# Encrypt system disk with TPM +apiVersion: v1alpha1 +kind: VolumeConfig +name: STATE +encryption: + provider: luks2 + keys: + - slot: 0 + tpm: {} +--- +apiVersion: v1alpha1 +kind: VolumeConfig +name: EPHEMERAL +encryption: + provider: luks2 + keys: + - slot: 0 + tpm: {} +{{- end }} diff --git a/talos/all/61-kernel-modules.yaml.tpl b/talos/all/61-kernel-modules.yaml.tpl new file mode 100644 index 0000000..5e39729 --- /dev/null +++ b/talos/all/61-kernel-modules.yaml.tpl @@ -0,0 +1,6 @@ +{{- range .Node.Data.kernelModules }} +--- +apiVersion: v1alpha1 +kind: KernelModuleConfig +name: {{ . }} +{{- end }} diff --git a/talos/all/70-security.yaml b/talos/all/70-security.yaml new file mode 100644 index 0000000..bc5dfb2 --- /dev/null +++ b/talos/all/70-security.yaml @@ -0,0 +1,7 @@ +# Talos 1.14 defaults to running kubelet and pods in a sandboxed PID/mount +# namespace, which breaks workloads that rely on hostPID or host mounts +# (node-exporter, GPU plugins, in-tree iSCSI). Set to true to opt in; on +# encrypted disks expect a second reboot the first time it is enabled. +apiVersion: v1alpha1 +kind: SecurityProfileConfig +workloadIsolation: false diff --git a/talos/all/71-filesystem.yaml b/talos/all/71-filesystem.yaml new file mode 100644 index 0000000..e55ba22 --- /dev/null +++ b/talos/all/71-filesystem.yaml @@ -0,0 +1,9 @@ +# Weekly online maintenance for XFS volumes: trim discards unused blocks +# (SSDs, thin provisioning) and scrub checks filesystem metadata. +apiVersion: v1alpha1 +kind: FilesystemTrimConfig +interval: 168h0m0s +--- +apiVersion: v1alpha1 +kind: FilesystemScrubConfig +interval: 168h0m0s diff --git a/talos/control-plane/00-cluster.yaml b/talos/control-plane/00-cluster.yaml new file mode 100644 index 0000000..be2b670 --- /dev/null +++ b/talos/control-plane/00-cluster.yaml @@ -0,0 +1,61 @@ +cluster: + etcd: + extraArgs: + listen-metrics-urls: http://0.0.0.0:2381 + advertisedSubnets: + - 192.168.40.0/24 +--- +# Allow scheduling on control-plane nodes +apiVersion: v1alpha1 +kind: KubeNodeConfig +taints: + node-role.kubernetes.io/control-plane: + $patch: delete +--- +apiVersion: v1alpha1 +kind: KubeAdmissionControlConfig +name: PodSecurity +$patch: delete +--- +apiVersion: v1alpha1 +kind: KubeAPIServerConfig +certExtraSANs: + - "127.0.0.1" + - "192.168.40.10" +extraArgs: + # https://kubernetes.io/docs/tasks/extend-kubernetes/configure-aggregation-layer/ + enable-aggregator-routing: "true" +--- +apiVersion: v1alpha1 +kind: KubeControllerManagerConfig +extraArgs: + bind-address: 0.0.0.0 +--- +apiVersion: v1alpha1 +kind: KubeCoreDNSConfig +enabled: false +--- +# Disable built-in CNI and kube-proxy to use Cilium +apiVersion: v1alpha1 +kind: KubeFlannelCNIConfig +$patch: delete +--- +apiVersion: v1alpha1 +kind: KubeProxyConfig +enabled: false +--- +apiVersion: v1alpha1 +kind: KubeSchedulerConfig +extraArgs: + bind-address: 0.0.0.0 +config: + profiles: + - schedulerName: default-scheduler + pluginConfig: + - name: PodTopologySpread + args: + defaultingType: List + defaultConstraints: + - maxSkew: 1 + topologyKey: kubernetes.io/hostname + whenUnsatisfiable: ScheduleAnyway diff --git a/talos/mod.just b/talos/mod.just new file mode 100644 index 0000000..64b6b5a --- /dev/null +++ b/talos/mod.just @@ -0,0 +1,64 @@ +set quiet +set shell := ['bash', '-euo', 'pipefail', '-c'] +set script-interpreter := ['bash', '-euo', 'pipefail'] +set default-list +set default-script + +# Day-2 apply/upgrade recipes rely on topf's built-in diff-and-confirm +# prompt; only the destructive reset recipes disable it in favour of just's +# own confirmation. + +[doc('Apply Talos config to all nodes (shows a diff and asks first)')] +[group('talos')] +apply: + topf apply + +[arg('mode', pattern='auto|reboot|no-reboot|staged|try')] +[doc('Apply Talos config to a node (shows a diff and asks first)')] +[group('talos')] +apply-node node mode='auto': + topf apply --nodes-filter "^{{ node }}$" --mode "{{ mode }}" + +[doc('Show pending config changes without applying them')] +[group('talos')] +diff: + topf apply --dry-run + +[doc('List all nodes and their current state')] +[group('talos')] +nodes: + topf nodes + +[doc('Render Talos machine configs to ./rendered')] +[group('talos')] +render: + topf render --output ./rendered + +[confirm("This will destroy your cluster and reset all nodes to maintenance mode — continue? [y/N]")] +[doc('Reset all nodes back to maintenance mode (DESTRUCTIVE)')] +[group('talos')] +reset: + topf reset --confirm=false + +[confirm("This will reset node " + node + " to maintenance mode — continue? [y/N]")] +[doc('Reset a single node back to maintenance mode (DESTRUCTIVE)')] +[group('talos')] +reset-node node: + topf reset --nodes-filter "^{{ node }}$" --confirm=false + +# topf intentionally does not manage Kubernetes upgrades +[doc('Upgrade Kubernetes')] +[group('talos')] +upgrade-k8s: + talosctl --nodes "$(yq '[.nodes[] | select(.role == "control-plane")][0].ip' topf.yaml)" \ + upgrade-k8s --to "$(yq '.kubernetesVersion' topf.yaml)" + +[doc('Upgrade Talos on all nodes, one at a time (asks first)')] +[group('talos')] +upgrade: + topf upgrade + +[doc('Upgrade Talos on a single node (asks first)')] +[group('talos')] +upgrade-node node: + topf upgrade --nodes-filter "^{{ node }}$" diff --git a/talos/secrets.sops.yaml b/talos/secrets.sops.yaml new file mode 100644 index 0000000..489c15f --- /dev/null +++ b/talos/secrets.sops.yaml @@ -0,0 +1,70 @@ +cluster: + id: ENC[AES256_GCM,data:IvsEBUm3P5HqFfq9KCCsIXTnulv9uDVTk8c4LqkviEbznoH8MUXmpt3EZ9s=,iv:qnLyJ5nrPDJAZg4e3fvEyIkyIhlGRtenUqhD/3iUGik=,tag:eF/C6hn7Qs8NJKQ4OxGnng==,type:str] + secret: ENC[AES256_GCM,data:me/0qKybROIB+OulEllvBy+w2jZRBw/TDYzn9qRI7YQZvgWAltCETrp+6CQ=,iv:PZddpAF0T+pl8KrfEWltCwY2nGb+VQSN64E5WzP3zTY=,tag:ZQ8hghmZmvAy4eMXlH/XyA==,type:str] +secrets: + bootstraptoken: ENC[AES256_GCM,data:eO+j35gOlYv8YCNROFliO3VwfPAib0E=,iv:U8nI6VAw8aJ4W+f5Ne+YyQuZHLPJXiIBnBzinqVoHFQ=,tag:UY26cjlYUGnq1N0HHWQteQ==,type:str] + secretboxencryptionsecret: ENC[AES256_GCM,data:4i0meQvtuuvt03ZVewsKFFrF9yvBgpYcNaLYZkNgK4DkgSQSmsrTgBSp+uM=,iv:OfTllsc9LNgPP+IcT5oH7njcjU/1o6vCM/6lxhBjt20=,tag:WYpzM/FMdA3YKoGygQowHw==,type:str] +trustdinfo: + token: ENC[AES256_GCM,data:TtGm6d/OA0jtsJ6B2+5gJKqGWvGEL/8=,iv:TqoM7ZdAaS49WgblpHmkv5S2zzff21Fpv5zxbzJGm9o=,tag:RTNzxe7me3W3GF2ty9F7Jw==,type:str] +certs: + etcd: + crt: ENC[AES256_GCM,data:ZgAGyJ0kcWxV1OnQVQv2/+wwTEMDFtu1ybZk5N+HQvcDauwYIsunenxFZeceAr7fhO3gNUaS4OFUQEMR1DUOaELz1GhYwZ/buU0HSJvyyWyI3wopEOjgIT6ejKUSOSBEKiZZddvEMgho5a87aZE0qnacQmFR6yxR/EFaAj04oA3eL0cbMJV8pZNOR/Cej3iZB0k0RsrkY22YbTYUdJczou+gMiTxP/LQnJFDRA8S4XnmPDse3eJZ9fCGo9AkJa6yp//wQsBajNK0ICnAFcJz0WwG3ggqzvfv7i2i8tDcUMJ+Crw312rWHblSjIG1xMnuQWk1Io7zs/Y/9SAiBr2ILOGoR4O4y4e3nEN57kRN25aQOcxLbT6o2a0P7243w4Ty0rEEbU9tb5HzH8ACUwDCavNFUxL9MPy/oru9CEC8rRpp7OKwpOyr3OzAVjX3+ElrkunXJyXw0YYWBhvZy4KCvaw9IhTfc37WJoM+sjMZS23/LEs/KgZWPDx6tNBxkRskqLKXOOI6/Y1IvFIjC1v1DV9HAsCQlwpHxTjuZ6NXfA8BX5A4+aoLB5/UWZmK8XcgZ+6T6NHIedAztF33JUSc/Tw2AiF7B+x1+UievGHUQ8pHBWkuDf3lUdapeF4+eXQFZ3u6cjZdnUi5Sd31esjWEI9tnw/aCSk336MVykXl1zyf9gXt+BCnNFUmMlh8akE/8ntRSAJIeLqD/0nM6amGiLLXhugInR7xcumnR6wqKlmwq2wTZq+coHVA0LwZWk5TRe/VjU+Mo3VZvlu19AF8+kuykIMuWqUhYa/VudxF9PfjOUEVadFsaR67u9PDf9WbG/2Jq9y3CIkDPGiO8CxvXzXxCJR+ruswCZbvRcAFjSZwlgRqKU13x0R1+bwOCVKFU9GuqJbRwvQaiSTad19zqFpmY7fHif62fGE2baYqcmnODPa9dZ7NfbibJNMhHJ3R9x7zjrdb+gX7IrsDKjRzPCyS/1q8I3sz2NH9H4dKlEcQirvZ5mCyFnvkgxr/COy8wdNgfg==,iv:qmQyF2zAtsMhaIdt8Qpxddb7OoXRAIOGuXazeLqVTjA=,tag:CeQFgNVMUqMwFGrbwpCyCA==,type:str] + key: ENC[AES256_GCM,data:YcBRxCs6mwj1fjiUgcahHJbI+soPf3qRUrTvMf17AT8WKqXMgqcyEdFUg+4xi7KJKPSWaQm9SQA4N5te1UcEK0LWgwtG8bwry6FCzBlIDb378x+XJsSXcGHyJfS5h3kPlrX1xYS/TFupRJYG0qbJ+2+rBo1gCGO8nXy/nolfQd8lyH/5R+bfsYF3loGxoNZ2LvHhTuyIQ171cO35bXy1nLxCN1D2TZCztD0DzOMyK4bFO9Qo/EPoOgz4JSlP44rU8wy0p1QUtRR+Ay0Qu57q6oZX5VmPaulqMAJmxLNkfXbII7E5QjJSHUFg5cDWiBaZwfTWLSMy7IBwdyO3K5FO91Wp8F5SifYFaS57AuAgOdWT4b648Y6WoH62d9YB084lLuOG1OJv/A2TO0tBlsLjSA==,iv:jSB3Ycp4x3kKPh34AGI6zG9j3c0mgV0l/fIgZegTKhs=,tag:Hc8SBirQFSCkBnpfNrcvGA==,type:str] + k8s: + crt: ENC[AES256_GCM,data:pTn0tDGIZNS+G5iRiAML1kFRuA3MMA4iACPjhJAFwdTUZIRDiLODaWDPGVzE9OKyRWymAumDN6QfinYol5EqOPPLG1E7YA6ibeHr37YBO5nZGkzcIQKmU/awcbrHBvDkYIL1k5wTdnGygFSYXt3VyAqu+sCS1nN+/lwlBGKFKl64xPkcvlqmJlNRsim+3sZgD52AbrotalPghEcFYfbObSU2Ja7W9Hj29REImE70/VWHjGLA8jvXSGTpsObZjTfgCBnYp0rwFE5+M+6/fPPcVGGfDFAn2D17pp2e+FdGwGJJoPgyzk2B9L1JxdVz2pDI4t4mbfphCjB/acdmnIU21REdkzdhDaevi2syjlm7X2O62OBe4ckfw9rqZjV2WI0oBQwY+lhGjF3IJeMn+6b95E+ASOgagVLoT7TeVCAn6axmiXKmiDvpfvGN/TV3sRFcI4z0tNzTE+0sOE5TG5BHDd7iyB/1sIn2vOR0LhQ3oysgTqR9UNYM0rPabyT79/jkR7FMbpL6JAYDPJLIuaijt71J7JK0q9BpLN+BHzLURG2BBtk9RjYII7ZmAqRSGeaDvGZkQY8IDC5S/RQcxaD8dIZKhHSkY4BKjRkAosZcBqbL9OBruC/nJLDYwpY3bIpSyUNkyhFDJC1byMSqaLRjAt3WVkxYP8ZTrnb/4y4lrmJ2xbYkY893MriLnmQf0XLojIbG5elT/H3t72SVFI0xFgHpN6Xo/bTXxMRhcolwsPNST40+4NMvlUqZera9l4OaKPxmD79F+MsNFnyanXYqh6sDJZjxZHD3ZZRgukYpazn/A0IKBu0hzbXV2IxPT43mpuI3I275WzdwHF1c/m+ivaXbuWUwedq607Te09F4Y26SjWap2kfik/n1ETdFK8od5fNAreesukJcgV8CQ4fQrD2ebBysV7aKW5FXN082G50ad/sgJFcNN1Ic6KU5RWnmLV5EW5PquIGNmKLhAePKZ+oE6lw4NOuJTZPcFGX7F4jeCnqa3i9yc6fwVP5hwA9U2c8ZheIVbCuKJCo+X/tqUaWxC/y/ZZzTRk0y9Q==,iv:sGBHFXDlkBbj7LuF/6mlq/i1Wbq5WeMIQXlDU7s0biI=,tag:2Qj9oFIbcXHUni78LucPZQ==,type:str] + key: ENC[AES256_GCM,data:lQeRqHdZNI6JSkfQvt9xV3qUeDkzrQ+ZEhA0Snnjrt20DidyojYLmTWZ2xnOkX5i0kl6jMhcrs/gR2RIv3H8AjdPLpxf+F3SFh7exEqGZRG/iDkhlKxZ99fNwZM9IRN0E/7pCetFNpmsC0kdvE9KhSov2bhyVQaZUki70ZN/Hr0wglyz+jtB6Rol178+5Uti7Xem9B8lDqEzWVxC39hjr8ZFW6NKDJCMHdh0DwYDhhVkrC2/S6nQ+nmM/IgEUrGDPxRl2cBWml0xtXUAIg7yJa3DcSiZdoeVuicy3/n4X0zTTGSSwlnvhC7baEfgPbrFe2jDTIaK38RIcp3QfaFyf7fwHgoeURWhppIqsc0i+acmoY8StPd8fRB7WD6xxcmpNyIeCjFkN/FLs9fdilXeLw==,iv:j7c2pNtTVKtowP/t072lDS+jnFnkyv/l83Vg66Kz3bA=,tag:EanJQxPV7yokoJgM851m1w==,type:str] + k8saggregator: + crt: ENC[AES256_GCM,data:W34wnAgUpYPwb5fMuP28QJ4Zuw4xqoiFg0HfhRnMgVk4caTs8JP65JEqxZnJy4WbQZXUERHZMbTN94Tv6oQ57HEJGwTY2yUfr+X2SJvSo3bPdfmPEnniGGq+lAVIGkM0yim9BqeyLnPXGrbJvCZth4wNFj5fUDhA3DCcfAgzexT6tXGXLaGcWsA4EdEP1G8PsQwmIc4MgShNWZI3MvLSLUY/LCDE/arg7nvPMrsEJGpQrYtKgP85EFU43lQ5UN2lRso6BXeoauQml0w1bNI8UZf/tGYxnPtZ2m8WeA0x5ERlWi111BnsAFXi7b9FvscWs/naXIPMskT2joRS1fj5/0euiHWvuLuHj3KbMuJg3IVFXWcchAY3vXWdJy6mW6d5tc5oh/ZuB3B+Dt130PzFMQd2NNJjUthkPf3gWnWmhe9cKJijlH6Mn1LeSkntS8X8jwmc4kNZr61x1PUx3CtkJEu+0nvXD1qe3YdtZPTiwCy2afirUS5wQUa2fPKKJjEsVfnzPsMMRt4eEDiH8m/AeJ/8B5V2ciw9zgJWbtuJefNOGiZNmbjs8maS+yAsxWxznNK9WUysrJFgrxu7v1mboiEsf3JakybTLdQZ5ywAjvMJhIX/fAMuZFVbXm+hd0jS6I4C02T3riHb8dB+kBsxpJlA9qW0NfD53yc8kLaFKDJ/NR5dq1WJstn/8Xie5Oadnyl/Wb8Lzbm5dvuSgzuJvxBDuYlmXK8XmJQLD1XuSBKsHtXA8hy77QQX+K+QZgclq8eUXYcuqV/XiDJ5DIieOhwnAk11Ms1yEg5g/Pc1K0DY2T0Wf9kipsk5QAWdQuAvzi0hHgZ+U2QIjFmp1tjcTnGWiiuf+jvhjSToAOnfb1XwaCgZ5J0/v+OR1lZmQ7S2wQbn7xtVmQyH7HpIiY+jKXztd0tTjMiVPoqZ+gMGRNQ6rUItfXnBpBfoZnzhE4F2,iv:TdS4r1tyWtm0TrNgeJPft4ab9wPCXyaMJe7OkdJ8kS0=,tag:jYzUOWpYd7pS/obWalqGOw==,type:str] + key: ENC[AES256_GCM,data:Lmv4aPgFZrDw3jZSC8RF+lI61qnhJ4UMnVYIlXCgWhjEGZo1UwzfyVR5SJ7P0u7ZwEzA9hONiKzNSSQ0OQCaFp2Z0QbvmlxmTlbxtgLNZgNjuFBmblU3UzkfXVwpNr/uP39iXHEMVjMf/tDIJiqWwV9ZWn78CgDwffgbzpGur8F3vKa20AhVbTuFJzHbPoSMs3PlF5LSxOLY7RPOealaHUhuu4LXGtDw1vLWnLYFpBhXQE4yUw32otlOu1oKnQcX2tHsI6VxhFuT6VU6hbTnGL6i2FQzN0EleV+bHYPgBG/cnqcWP3f/WcT8foeTPdO53guv+YFNXJDMtRMC8/mRLXqsBkYx6x2zTfTEJja1tf5vCvoYDl9b927B7kPa3rfbV/0f0xeKhn+h5r5Plyi61w==,iv:4hdM4LJSDo+gIDSRXabFJ9uiy41YNtDqGRfWj+Qip7w=,tag:VRDOzcdoOfoQ9aoVqSyFPQ==,type:str] + k8sserviceaccount: + key: ENC[AES256_GCM,data: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,iv:nhcw3n3Q0kphtn5O3fyZzU3ETXF7vrcPFJdyjrkTVdg=,tag:09dk8qVaavkpP/Bd5QMm4Q==,type:str] + os: + crt: ENC[AES256_GCM,data:3lUqbPswymPv28gSAekLg/YSkxpFFjK2cX5q1HRc8Xirt/Q++pUHGvakKnOdzXjYkFu3QIDA24801zrumDQaqL+c9L/PRsQddmVNTDCwDSfugDW8t6CUsSTevJpT4YkZRfus9GASGZWarvCqpr9ALfastQ8nmuNWQ8AdgSrSIiPNo5VC3oCGWVHRGD91E9YGh8YnfS8wTARo6KwwKpmgj1AGxLD5Ch94OmpQd4QdYKP1hupULVPXPnDR55FQ+ys9VErYJcAnrkl4BnlFMjbfD3kD/j15N5Oi9b6QijgaG2hKYcCESUFtAjKVdyU7VxO5uUiUYhddTI+kyz+aZumZzgCNu5W2yZIIeGhPtev/IqWMvFsai1ErCJSZ9AQXd5N+XDPuLlKe3nkQS5/WWyK/IwmNwsy5CJKfMrG35x3lPa9yBIvk9kQ9Hx0+4sapTO7IHxyePUD0BfH8qxECl+/SBjRR3zXRuA0rKqVrSFHObH/RbgyL3U2lfStgt36g4tacmXGvF9DcPgw22hW7mI2w/DNIuniMN8EJ2DdWXszcI1hggJnpTvcwH/SfxJPR+8DUeGfc53FjSNNkMrXVeIafjTs5AMf7C9XORny2sYkvIj8IR0BhECfCOu6f2DI9nzlaFI0p8q2FfuE7rbYF32FMU9b9tzpwOsu5rT0rXTMQa3zIaZqoTSPtfhuAyAmqPW4dWAFixLorUBtbOsoUN6MKoCQlei4NLytWkF1VALC7L6lEIhMliNWtLXetxOOQYbYCovxh6QtBTcnI+nbOMgvLEMGuNWj6A5vgSB6e3Q4OUQB7PX0PS3tfwIXQDwWCV7dnZFUNGl27c6oRsLlhNN8CFENHgIO1N5IfVJBftIZAA7DDIlja,iv:bSnXwzOO7GrmtwftZjU66WNryQ8T7G0KfIUTlKPT9H8=,tag:7WT4k1nRO95RR0DRJCROFw==,type:str] + key: ENC[AES256_GCM,data:I7T89MWAsGVXUbpbZwRQiA0Vs1fAVGACorwa1azfvpHP61WjXtquJXnZl2CkUi635oMhK78D9obJ0T6IBPA594bT6CstQ7kX98vo35LFOFtedrI3ALBwO2zb7zsohrGRYuCfHJ56H/wjNJnZxjoYEOrGYJgDQjD5B9C47ga3/wFM9j4ff7QFmW7EJeuFnBUoHZ5NuO1pUqkniXyQajcg3NaiWIMdxPRQKjE/igOK5U1ubkNj,iv:lIKkMth76N1BUx6YuWaP6Jk5ARmgcr0hOP7EKzs8hE0=,tag:vFGxmMxkUKdowVI8g9Pe3Q==,type:str] +sops: + age: + - enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IG1sa2VtNzY4eDI1NTE5IGI5anNHUGRl + bE43THNZaHdPSTRkL3BoS0dMTzhRZ0cySktkYlBnMlplb2ZVVHpmakY5Qjlkb2Vu + eDlLL3RPdndJRDBHSHpwZ1BvUEd2bWxXN3h2NjByUUhKOGxsZUZzUlo3bkVYYnFp + UkJjVHlWcnIxQTNpRE15ODUyamxOYVhndnRBeXg5Mzlwck52dmE1RmxyNlJycjFE + Vkg5Z01MYXdzSVBoTWVyVUxQSERVOUh3dGZQVW1oYU9XUmpaNE55N3dwS1lmSWpO + RjZDNkYxSTh5d05Pczh1b1hNemxTL2pRemFrNlgxL21qOHhMcjIxOFlQM3J1SGd2 + WUJKWEFiSlgrNWprWnRwQnpBMTB3Wm1DS1hEQkgyNUdkT1dKYnpmZnRXbGlNQmth + cE9XSnk2cXFhQzVQSmltMDJQWUI4QjdFRzRERnY3K0RCcUlVZEdVUEk4alFtWTYr + MmFmanp3NkxqU3REcmdIZDYvbThaWU5tTEJsYm10U2owQmF1bUJEU2N3cXd0VXlm + Y3czRXpwQ204L1NheEdVYmErUEwyTjBoenVIdjVFcEE0R0JhL1VoNkVOMUJiVCs5 + ajZLZnMrZm1VUTZtcFR5V1V3R0pybllSU1BIdDJqdVRRL0lmQTFXcHVMYXJvbzdi + YVNjcTAxRDN0TFlUTllaOXNQZW52M09SaENhaVB0VENWQThYWEF5UW5JWVZrMVlI + d3lvdTBDMXBBSUVDRlhRRDJHY1RGRmlYaG9WamlyZVlZNnJVcjFrMHVqc3V6bUlD + KzU4b2hrV2txZVpmNGZaMWJVQmpRTkVhYTFtc05NVGcyYmNiYXJ0TytEc0NabVZs + SVlYcEgwZXZyYW5ncmQyT1pZbzFVQTJOSXdONlcxWVVyYkNrNG5nS3ZpU1JlaDla + MkxBODBnaEFJL0d1WmZETTY1U1U1Mnd2SGpEdEFxTm5ENTF1Qlh2ZTJHQWZYTTc4 + Y1NuTWVidlZYY3Zpby9iRjUyQXREbXRBNGhPRVdUTHlrVDRLMkxJaldzeFpkUVFD + Q1dLRWpZLy9Mei9QRjJpN2xPUzZGaWNUWSt1ZXUyNFMya2x5Umc3NzhMeG9vYWJC + MFRXb0ZQVTBTUGgyRHNSNTg5eU9Ia1ZlbUFHTitjdnpEMlZNTU5tUHFoQXdRdWpC + YUVnaElSUXpLcFJEcXpQSSt6bHVKZDBUL2s5ak0vQXpKVnZybm1nNEg3YmdPR2kx + RzI1bjZMZEQrR0dRK21wRmhnK1pyL09CTGg1dmJEbU5QQnkraTRqeU1uTnQzYytY + Z1B3S1FReHpBcUtsU21nTDEyWE9PME5EellEVjJhZ2ZGZzJGbUVaNWprMGVVdVd3 + VUY4bTVIV25BcThKUVZFRnlkQVoxZ0JZTGJyMUVwamF0SC84d2RyV1hMb0FqVVdI + bndmclN0SlVxMFM0QmEvMWQwTXFlVlg2Sm9PVjAxN3k4VWxOS2lucHh6R0c3NHVK + bkl6eWRlelJDdDU1ZTJxVXl0QTE5eldoa1NjeVFMSHVXWGg5WDY0QTVlUkhYQ1Z0 + MG1ORzdpSVUyM0xhNm1XRlVuMk1iZVNrL09QTzBuRTVjNG1qV21YL2I2TjFwczAz + aTJGcXRwL3dadldkSzBMdkRydjlsUkxHb3FBYmVRNUwwZlQxcTZYK0NJeXlNOEtU + dzVuTWdKbFFsTXdnYjR5NkNqSm9NaWFkdERDN0U1NWV4Lzh2dDkrNG8vS0lCUE9j + Vnh3QTRlcGp6QkZCQWZNSDI3SVB5MGozS2huM0I5WGduS0k1Y1dwQTVGY0ppRnJl + WmQyWmtKbU9ZVXZqMEFGa2ZWREMzdlUxYVRwY3R1WGNEM3pkSSsxUnllbGwvN1h5 + ODBkYm9BYUhnbS95eHNqQ21lbWs3WFhvenl0NkpJYjJQU1Z0T2haN21mVmxIOW56 + dWFHR3F1bmp6WkdtY2haaHlBeWJlR3FFMFYxVU53VC85eGkvS2RleGI0cmlTdwpt + ZjZkOURwajZ0SHZ4Q3MwL0hsWStnbUFUbHovYlA3aUhpUmVteUFUN0pBCi0tLSBM + K0tmZDdoZnpHK09Xc2NmSUt1ZTJBdUZwcnBudUdWNCtDSkdLVWdKNS93Cgx5HwwP + aWztjjfththyMzIFoxR/nCpWCm/F9zeGi8+VXmGKPFEqKQnF9K/8xJWzhVRrg2EC + FfqlpkLH/zrrFnI= + -----END AGE ENCRYPTED FILE----- + recipient: age1pq1kujt4l0f4ef0f2duw2txmcf87js23qxxq376erctqq6l8kc25duvszyk0kphpf4rfw54v9flae2zz86s3agchwux83ae8y5g38kgpehpv468gfdyqvks2hqd3s9r2zt6jd40vrjh5gzlhaex2v4hfya5wx7fykt89ty3ve9lsh2kemwytfuskruytq9kxwvys5w9uwa99a3ts2x68pex52j87qtkgjs4wnsmzeta0qsekz4jtrfqnhthge52nppe57fndaxzqsr3y64z5yyczh89mw97lur68uauk83z0c7c5j0ejj0azxmtt9fmm94rje9zefkf2dep0pgl84rcq64vk50neg5dye0rk3wxfeehvrqv5gnav6wmg5665kdmgxsvwje32kerj8zppvla6v92ul7gn4htw698yl5nqzx8lga4lxtj2kw5sdp9vamvsfmjwuqer5s9tpa2skhj3r4n0jjspy39uat4yk5fre6cr0xg6rqrdp3w0ktgzq4gx89r8252xklxxc4scxf4eaqphqgrcz8kcemjz0zlsq6knud6enq3z3spqjrdr3uagrk93j0rshc2zvy7tqqudzajqmre7l29qae6800pzpt6tf5emqj50lqp2xdey3df5uj06232ntfu2djzk6c8juh6h9tchk4vapn4g4jf8chlv5fqlfx4jnrsy8jv6szvwq6nx0nr0fn48ajae8fspnep8e9q5c9eukku86zejcq907292wypzcj4uurqs7ffranj73qsqsx3jtug75zkzyrf39ztqhkhxlcehddhav0vl4gpuexrs0qytdwfk9asc95kls7dx7g8xk96nwxphxd4za06ne4pmpcq9l88qc5wnjsdtxhtvdv0hmat24khs4dfw8ejpnyftqgkkjk80r23e03c08vs7vcj4d28qcmxg6g59sjz0zgkfj3g42nq7re4ysrz55qqhqxsrgxnmczw5wd8ufw3qcc8gsj87qm6h54h8tzj6e4jfcxwjhwmx2g0yanrczvrgw62yna9hy0wytrxjjcawejhfnj6jdsz588yu6epgs3uuuvnhdscxthpnduy2a8k7egzm7r8yyjp3ev29dve6ksr5rrk0v5xce55s3h9wn8dld0edj6ha9yfyvzgqhghv55fxfvmpn9vxyvs0w96hrzmngzjw9dv9k7wqmtcwh8qyzqrkfmm0xxw942wnlatfqssw9c8qpesgajh8v2aa6jpv2x4se3ck55y2apelskfs26yt5r5kjw5su5qptrnsentvy6exy92q5jzny4dvmx3y5s2uhfehnjcvtwrxhwldfjen7w9x43vdm96p7dv3fzvwhzmjvzr05nvjugrvky04fqehzhhmsfkw09v50uyht8yst5sd8ze6aahrlaymkhmzlaux5hh9p23qk9j44ck7pnurlz5z3ahfvhmkv4x5mgz0aundmhchg9zazdw9v7y0ue2pvhgqfnkj4vxs9s7dem8w69pzzqngt47y2a8qvkkgctq33jxmff8y2ag3pqyc5d2lqak7m2slas50h73vtk42q9j65jt634n9e5f8w7l0qy00xg9l3pg80qtfsctf06lx3p3p20kczwdvy6edf5yp0t2rtffwfgld7zun2my9ys9w0wh9glaxqwf85ay4fm2sjyhjkt4r2ruyl80ke4rrlpyue5f8zm4z4p8xy6447rggmpnfnem5kdar2lpapu9dua40r4rd7dzn0zprpqmc239q4jeg6e5uag59zdzysjzc89r5xt9m8fufjmtsau64fx2ef8gpas58ccn57esrxavcg6x596zdnv963d94a65ft6vkjpdky45tn9ulcf6xdms9c06m4dm4fgzw3rxtzezz2770wva4avw654r24d9hdh7are0rn69c9sdwd5mx45fruaze6l6 + lastmodified: "2026-09-16T19:18:48Z" + mac: ENC[AES256_GCM,data:X4DqQF8Gj51CUW5slRQOvex1JmHF1eedJiRybkKhXlcFo122jdJF/hj80dOUBH0nOb1XOoFMJYQS2prc2kUqqkPpql5WrtabHbQ4YarKiZBvT0kPkw+UQWwFPeWkmhRc01zqg0Ox5AREgHX4dOVTVz5cRW+RhV7HcG0oC4WqvIg=,iv:iN+wfWLpBxym41bXp0Su9W6d7CB8wgLW0wzoH6WmcaU=,tag:t+U3MR1GPnRQKMWcg22eQQ==,type:str] + mac_only_encrypted: true + unencrypted_suffix: _unencrypted + version: 3.13.3 diff --git a/talos/topf.yaml b/talos/topf.yaml new file mode 100644 index 0000000..0ab4da7 --- /dev/null +++ b/talos/topf.yaml @@ -0,0 +1,45 @@ +--- +clusterName: kubernetes +clusterEndpoint: https://192.168.40.10:6443 + +# renovate: datasource=github-releases depName=siderolabs/talos +talosVersion: v1.14.0 +# renovate: datasource=docker depName=ghcr.io/siderolabs/kubelet +kubernetesVersion: v1.37.0 + +secretsPath: secrets.sops.yaml + +nodes: + - host: "k8s-0" + ip: "192.168.40.20" + role: control-plane + schematicId: "e3fab82b561b5e559cdf1c0b1e5950c0e52700b9208a2cfaa5b18454796f3a7e" + data: + installDisk: "/dev/sda" + installDiskSerial: "" + macAddr: "bc:24:11:00:00:20" + mtu: 1500 + encryptDisk: false + kernelModules: [] + - host: "k8s-1" + ip: "192.168.40.21" + role: control-plane + schematicId: "e3fab82b561b5e559cdf1c0b1e5950c0e52700b9208a2cfaa5b18454796f3a7e" + data: + installDisk: "/dev/sda" + installDiskSerial: "" + macAddr: "bc:24:11:00:00:21" + mtu: 1500 + encryptDisk: false + kernelModules: [] + - host: "k8s-2" + ip: "192.168.40.22" + role: control-plane + schematicId: "e3fab82b561b5e559cdf1c0b1e5950c0e52700b9208a2cfaa5b18454796f3a7e" + data: + installDisk: "/dev/sda" + installDiskSerial: "" + macAddr: "bc:24:11:00:00:22" + mtu: 1500 + encryptDisk: false + kernelModules: []