<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Kubernetes on JJGadgets</title><link>https://6f8f7e98.jjgadgets-tech.pages.dev/categories/kubernetes/</link><description>Recent content in Kubernetes on JJGadgets</description><generator>Hugo -- gohugo.io</generator><language>en</language><copyright>JJGadgets</copyright><lastBuildDate>Sun, 11 May 2025 13:23:18 +0800</lastBuildDate><atom:link href="https://6f8f7e98.jjgadgets-tech.pages.dev/categories/kubernetes/index.xml" rel="self" type="application/rss+xml"/><item><title>Tidbits: Ceph RGW - List All S3 Buckets Disk Usage</title><link>https://6f8f7e98.jjgadgets-tech.pages.dev/2025/ceph-rgw-list-all-s3-buckets-disk-usage/</link><pubDate>Sun, 11 May 2025 13:23:18 +0800</pubDate><guid>https://6f8f7e98.jjgadgets-tech.pages.dev/2025/ceph-rgw-list-all-s3-buckets-disk-usage/</guid><description>&lt;p>Quick one liner command to list all Ceph RGW buckets usage, using &lt;code>jq&lt;/code> to extract only the bucket name and size KV pairs and converting from bytes to gigabytes (GB):&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">radosgw-admin bucket stats &lt;span class="p">|&lt;/span> jq &lt;span class="s1">&amp;#39;def calc(val): if val!=null then val|tonumber/1000000000|tostring + &amp;#34;GB&amp;#34; else . end; .[] | {bucket} + (.usage.&amp;#34;rgw.main&amp;#34; | {size: (calc(.size)), size_actual: (calc(.size_actual)), size_utilized: (calc(.size_utilized))})&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>For me, I use Rook-Ceph on Kubernetes for my homelab, and like to view the output in Neovim, so the full command line for me looks like this:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-sh" data-lang="sh">&lt;span class="line">&lt;span class="cl">kubectl &lt;span class="nb">exec&lt;/span> -it -n rook-ceph deploy/rook-ceph-tools -- radosgw-admin bucket stats &lt;span class="p">|&lt;/span> jq &lt;span class="s1">&amp;#39;def calc(val): if val!=null then val|tonumber/1000000000|tostring + &amp;#34;GB&amp;#34; else . end; .[] | {bucket} + (.usage.&amp;#34;rgw.main&amp;#34; | {size: (calc(.size)), size_actual: (calc(.size_actual)), size_utilized: (calc(.size_utilized))})&amp;#39;&lt;/span> &lt;span class="p">|&lt;/span> nvim
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Or only the &lt;code>jq&lt;/code> query if you prefer:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="err">def&lt;/span> &lt;span class="err">calc(val):&lt;/span> &lt;span class="err">if&lt;/span> &lt;span class="err">val!=&lt;/span>&lt;span class="kc">null&lt;/span> &lt;span class="err">then&lt;/span> &lt;span class="err">val|tonumber/&lt;/span>&lt;span class="mi">1000000000&lt;/span>&lt;span class="err">|tostring&lt;/span> &lt;span class="err">+&lt;/span> &lt;span class="s2">&amp;#34;GB&amp;#34;&lt;/span> &lt;span class="err">else&lt;/span> &lt;span class="err">.&lt;/span> &lt;span class="err">end;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="err">.&lt;/span>&lt;span class="p">[]&lt;/span> &lt;span class="err">|&lt;/span> &lt;span class="p">{&lt;/span>&lt;span class="err">bucket&lt;/span>&lt;span class="p">}&lt;/span> &lt;span class="err">+&lt;/span> &lt;span class="err">(.usage.&lt;/span>&lt;span class="s2">&amp;#34;rgw.main&amp;#34;&lt;/span> &lt;span class="err">|&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="err">size:&lt;/span> &lt;span class="err">(calc(.size)),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="err">size_actual:&lt;/span> &lt;span class="err">(calc(.size_actual)),&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="err">size_utilized:&lt;/span> &lt;span class="err">(calc(.size_utilized))&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>&lt;span class="err">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Here&amp;rsquo;s an example output:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;span class="lnt">35
&lt;/span>&lt;span class="lnt">36
&lt;/span>&lt;span class="lnt">37
&lt;/span>&lt;span class="lnt">38
&lt;/span>&lt;span class="lnt">39
&lt;/span>&lt;span class="lnt">40
&lt;/span>&lt;span class="lnt">41
&lt;/span>&lt;span class="lnt">42
&lt;/span>&lt;span class="lnt">43
&lt;/span>&lt;span class="lnt">44
&lt;/span>&lt;span class="lnt">45
&lt;/span>&lt;span class="lnt">46
&lt;/span>&lt;span class="lnt">47
&lt;/span>&lt;span class="lnt">48
&lt;/span>&lt;span class="lnt">49
&lt;/span>&lt;span class="lnt">50
&lt;/span>&lt;span class="lnt">51
&lt;/span>&lt;span class="lnt">52
&lt;/span>&lt;span class="lnt">53
&lt;/span>&lt;span class="lnt">54
&lt;/span>&lt;span class="lnt">55
&lt;/span>&lt;span class="lnt">56
&lt;/span>&lt;span class="lnt">57
&lt;/span>&lt;span class="lnt">58
&lt;/span>&lt;span class="lnt">59
&lt;/span>&lt;span class="lnt">60
&lt;/span>&lt;span class="lnt">61
&lt;/span>&lt;span class="lnt">62
&lt;/span>&lt;span class="lnt">63
&lt;/span>&lt;span class="lnt">64
&lt;/span>&lt;span class="lnt">65
&lt;/span>&lt;span class="lnt">66
&lt;/span>&lt;span class="lnt">67
&lt;/span>&lt;span class="lnt">68
&lt;/span>&lt;span class="lnt">69
&lt;/span>&lt;span class="lnt">70
&lt;/span>&lt;span class="lnt">71
&lt;/span>&lt;span class="lnt">72
&lt;/span>&lt;span class="lnt">73
&lt;/span>&lt;span class="lnt">74
&lt;/span>&lt;span class="lnt">75
&lt;/span>&lt;span class="lnt">76
&lt;/span>&lt;span class="lnt">77
&lt;/span>&lt;span class="lnt">78
&lt;/span>&lt;span class="lnt">79
&lt;/span>&lt;span class="lnt">80
&lt;/span>&lt;span class="lnt">81
&lt;/span>&lt;span class="lnt">82
&lt;/span>&lt;span class="lnt">83
&lt;/span>&lt;span class="lnt">84
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;bucket&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;pg-authentik&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;1.688277968GB&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size_actual&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;1.725648896GB&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size_utilized&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;1.688277968GB&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;bucket&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;pg-gts-robo&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;0.003353182GB&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size_actual&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;0.003444736GB&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size_utilized&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;0.003353182GB&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;bucket&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;joplin&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">null&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size_actual&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">null&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size_utilized&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">null&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;bucket&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;pg-atuin&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;0.468781088GB&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size_actual&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;0.48617472GB&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size_utilized&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;0.468781088GB&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;bucket&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;gotosocial-media&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;7.746584026GB&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size_actual&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;7.825215488GB&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size_utilized&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;7.746584026GB&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;bucket&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;gts-robo-media&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">null&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size_actual&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">null&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size_utilized&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">null&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;bucket&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;zipline-data&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;0.00079149GB&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size_actual&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;0.000794624GB&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size_utilized&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;0.00079149GB&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;bucket&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;pg-home&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;2.763082224GB&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size_actual&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;2.787741696GB&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size_utilized&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;2.763082224GB&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;bucket&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;reactive-resume-media&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">null&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size_actual&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">null&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size_utilized&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">null&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;bucket&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;pg-gotosocial-valetudo&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">null&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size_actual&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">null&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size_utilized&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">null&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;bucket&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;volsync&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;373.431380366GB&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size_actual&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;373.502193664GB&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size_utilized&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;373.431380366GB&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;bucket&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;pg-default&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;2.899299768GB&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size_actual&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;2.965950464GB&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size_utilized&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;2.899299768GB&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;bucket&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;k8s-schemas-rgw&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;0.0391532GB&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size_actual&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;0.040087552GB&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size_utilized&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;0.0391532GB&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;bucket&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;pg-gotosocial&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;6.635240072GB&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size_actual&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;6.69478912GB&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;size_utilized&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;6.635240072GB&amp;#34;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div></description></item><item><title>Flux Repo Structure</title><link>https://6f8f7e98.jjgadgets-tech.pages.dev/2024/flux-repo-structure/</link><pubDate>Wed, 03 May 2023 00:00:00 +0000</pubDate><guid>https://6f8f7e98.jjgadgets-tech.pages.dev/2024/flux-repo-structure/</guid><description>&lt;h1 id="introduction">Introduction&lt;/h1>
&lt;p>In this post, I go over the repository structure that I use for my Kubernetes homelab, powered with GitOps by FluxCD.&lt;/p>
&lt;p>Remember that &lt;em>there is no &amp;ldquo;right way&amp;rdquo; or &amp;ldquo;one size fits all&amp;rdquo; to repo structuring&lt;/em>, define and be clear on your goals before you structure your repo.&lt;/p>
&lt;p>&lt;strong>NOTE:&lt;/strong> From here on out, all &lt;em>files&lt;/em> will be in bold and is prefixed by &lt;strong>./&lt;/strong> while all &lt;em>folders&lt;/em> will be in bold and suffixed by &lt;strong>/&lt;/strong> e.g. &lt;strong>folder/&lt;/strong> and &lt;strong>./file.yaml&lt;/strong>&lt;/p>
&lt;h1 id="goals">Goals&lt;/h1>
&lt;ul>
&lt;li>
&lt;p>Define desired configuration of apps and services deployed in Kubernetes cluster.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Version control all configuration changes with Git.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Automate all the things! (as much as possible)&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Establish high security baseline of both Kubernetes cluster&amp;rsquo;s components, and GitOps components.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Allow for basic multi-cluster environments (production and non-production) while using monorepo&lt;/p>
&lt;ul>
&lt;li>Cluster-specific configurations using variable substitution in deploy manifests, and cluster-specific secrets.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>Allow for opting-in which apps/services/components to deploy per cluster, to optimize resource allocation (CPU, memory, storage, network etc).&lt;/p>
&lt;ul>
&lt;li>I &lt;em>don&amp;rsquo;t really need&lt;/em> a Minecraft Java server on both prod and staging if I don&amp;rsquo;t change any of its configuration, do I?&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>Minimize human errors or forgetfulness by keeping duplicated code to an absolute minimum.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;h1 id="repo-structure-kube">Repo Structure (&lt;strong>kube/&lt;/strong>)&lt;/h1>
&lt;ul>
&lt;li>
&lt;h2 id="bootstrap">&lt;strong>bootstrap/&lt;/strong>&lt;/h2>
&lt;ul>
&lt;li>
&lt;p>&lt;strong>flux/&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>
&lt;p>&lt;strong>./kustomization.yaml&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Installs Flux from the kustomization.yaml located in ./manifests/install of fluxcd/flux2 remote GitHub repo.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;h2 id="clusters">&lt;strong>clusters/&lt;/strong>&lt;/h2>
&lt;ul>
&lt;li>
&lt;p>&lt;strong>cluster-name/&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Cluster specific folder&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Any name is fine, e.g. &lt;strong>prod/&lt;/strong> and &lt;strong>dev/&lt;/strong>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>distro/&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Cluster distribution&amp;rsquo;s configuration&lt;/p>
&lt;/li>
&lt;li>
&lt;p>e.g. Talos via talhelper (&lt;strong>talos/&lt;/strong>)&lt;/p>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>config/&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>
&lt;p>All Flux manifests for cluster-specific configuration state goes here&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>./flux-install.yaml&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Flux SourceRepository pointed to Flux&amp;rsquo;s manifests OCI repo, scoped to version branch&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Fluxtomization to deploy and control Flux&amp;rsquo;s components (takes over control of Flux components from Flux bootstrap)&lt;/p>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>./flux-repo.yaml&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Flux SourceRepository pointed to user&amp;rsquo;s repo (e.g. JJGadgets/Biohazard, onedr0p/home-ops, 0dragosh/homelab etc), use SSH key to clone (and optionally push if configured)&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&amp;ldquo;Master&amp;rdquo; Fluxtomization to deploy and control cluster-specific configuration (path points to cluster folder) and all other deployments (via cluster folder&amp;rsquo;s ./kustomization.yaml)&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Includes configuration and patches for variable substitution ( &lt;code>${VARIABLE}&lt;/code> ) and SOPS secret decryption of all other deployments&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Includes patches for DRYing configs&lt;/p>
&lt;ul>
&lt;li>For the truly lazy, patching a Fluxtomization with patches for other resources controlled by said Fluxtomization (e.g. HelmRelease) is possible&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>./kustomization.yaml&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Native Kubernetes Kustomization to control what resources are deployed, either by Fluxtomization or &lt;code>kubectl apply -k&lt;/code>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Used here for opt-in deployment of all cluster-specific configuration manifests in cluster folder.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Used here for opt-in deployment of which apps folders to deploy to cluster (from &lt;strong>kube/deploy/&lt;/strong>).&lt;/p>
&lt;ul>
&lt;li>
&lt;p>References the apps folders to deploy like so: &lt;code>../../../deploy/apps/jellyfin&lt;/code>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Each app folder will then have its own &lt;strong>kustomization.yaml&lt;/strong>, which opts-in deployment of the namespaces needed as well as the app&amp;rsquo;s Fluxtomization (&lt;strong>ks.yaml&lt;/strong>).&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Indirectly the &amp;ldquo;master&amp;rdquo; Fluxtomization &lt;em>also controls the namespaces deployed&lt;/em> (since there&amp;rsquo;s no Fluxtomizations in between the chain of &lt;strong>kustomization.yaml&lt;/strong>s).&lt;/p>
&lt;/li>
&lt;li>
&lt;p>This allows the app&amp;rsquo;s Fluxtomization to add &amp;ldquo;master&amp;rdquo; Fluxtomization as dependency (via dependsOn).&lt;/p>
&lt;ul>
&lt;li>Ensures that namespaces are always deployed before the resources are deployed within the namespaces.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;em>NOTE:&lt;/em> (about namespacing)&lt;/p>
&lt;ul>
&lt;li>
&lt;p>I choose to group apps in their own namespace, unless an app requires either multiple containers (e.g. server and web client, or microservices architecture), or 2 different apps must be in the same namespace to share Kubernetes resources or other reasons.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>My structure is a janky ghetto way to implement &amp;ldquo;multi-cluster&amp;rdquo; with a very specific purpose of having production and non-production (dev/test/staging/UAT, whichever is appropriate) clusters, where the differences in the clusters mostly come down to cluster-specific variables/secrets and control of which apps are deployed, allowing the non-prod cluster(s) to be scaled smaller than the prod cluster (e.g. I &lt;em>don&amp;rsquo;t really need&lt;/em> Jellyfin on both prod and staging if I don&amp;rsquo;t change any of its configuration)&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Other folks like onedr0p, bjw-s, 0dragosh etc will have the &amp;ldquo;master&amp;rdquo; Fluxtomization deploy a separate &amp;ldquo;apps&amp;rdquo; Fluxtomization that points to &lt;strong>kubernetes/apps&lt;/strong> which has &lt;strong>kubernetes/apps/namespace/kustomization.yaml&lt;/strong> control both namespace and app Fluxtomizations (&lt;strong>kubernetes/apps/namespace/app/ks.yaml&lt;/strong>) to deploy, &lt;em>which isn&amp;rsquo;t a wrong way to structure for their needs&lt;/em>, however this means that there is no easy way to control which cluster should deploy which apps which I desire&lt;/p>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>./secrets.yaml&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Cluster-specific native Kubernetes secrets, encrypted-at-rest by SOPS (Flux supports decrypting SOPS-encrypted files).&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Can be used via variable substitution at deploy-time.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>external-secrets is preferred over storing secrets in here to easily sync and/or consume namespace-specific secrets.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>One hacky way to have cluster-specific yet namespace-specific native Kubernetes secrets (you can&amp;rsquo;t reference a secret stored in &lt;code>flux-system&lt;/code> namespace from e.g. &lt;code>minecraft&lt;/code> namespace) is to variable substitute the secret data into a &lt;code>kind: Secret&lt;/code> manifest in &lt;strong>kube/deploy/&lt;/strong>.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>./vars.yaml&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Cluster-specific variables.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Can be used via variable substitution at deploy-time.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;h2 id="deploy">&lt;strong>deploy/&lt;/strong>&lt;/h2>
&lt;ul>
&lt;li>
&lt;p>Apps, services and components to be deployed to clusters.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Contains baseline common manifests that are written to work across all clusters.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Cluster-specific configuration is achieved via variable substitution and optionally patches.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>core/&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Backend(-related) components that are &amp;ldquo;core&amp;rdquo; to Kubernetes clusters for them to operate, such as CNI, storage solution, Ingress Controller, and more.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>apps/&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>
&lt;p>User-facing apps and services.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>app-name/&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Replace &lt;strong>app-name/&lt;/strong> with app name, such as &lt;strong>minecraft/&lt;/strong>, &lt;strong>authentik/&lt;/strong>, or &lt;strong>immich/&lt;/strong>.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>./ns.yaml&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Namespace definition for app, or group of apps.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>./ks.yaml&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>
&lt;p>All app-specific Fluxtomizations that deploy and control the app&amp;rsquo;s resources.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Points to either &lt;strong>app/&lt;/strong> and/or &lt;strong>component-name/&lt;/strong> folders which are explained below.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Use dependsOn to ensure that dependencies (such as storage solution and Ingress Controller) are deployed and configured before app&amp;rsquo;s resources are deployed and configured.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>./repo.yaml&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>Only needed if deployment method relies on Flux SourceRepository, such as HelmRepository or OCIRepository.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>./kustomization.yaml&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Native Kubernetes Kustomization to control what resources are deployed, either by Fluxtomization or &lt;code>kubectl apply -k&lt;/code>&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Used here for opting-in all YAML files but not folders, since folders are controlled by app-specific Fluxtomization which itself is controlled by &amp;ldquo;master&amp;rdquo; Fluxtomization via this and cluster&amp;rsquo;s &lt;strong>kustomization.yaml&lt;/strong>.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>app/&lt;/strong> OR &lt;strong>component-name/&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>
&lt;p>All manifests used to deploy Kubernetes resources needed for app are placed here.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Usually if both &lt;strong>app/&lt;/strong> and another folder such as &lt;strong>config/&lt;/strong> or &lt;strong>certs/&lt;/strong> are present, &lt;strong>app/&lt;/strong> is used to deploy components which are a dependency for the other folders&amp;rsquo; resources to be deployed.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>./netpol.yaml&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>
&lt;p>CiliumNetworkPolicy or Kubernetes native Network Policy&lt;/p>
&lt;/li>
&lt;li>
&lt;p>&amp;ldquo;&lt;em>Principle of Least Privilege&lt;/em>&amp;rdquo; and &amp;ldquo;&lt;em>Default Deny&lt;/em>&amp;rdquo; practices are followed, only allow necessary connections&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Commonly allowed include Ingress Controller, intra-namespace traffic, communication with other apps&amp;rsquo; Kubernetes services &lt;em>as needed&lt;/em>.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Not all Kubernetes components need to be network accessible by every application, such as APIServer, storage solution pods/services, or Flux. Assign only if such traffic is necessary for app to function.&lt;/p>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>
&lt;p>&lt;strong>./hr.yaml&lt;/strong>&lt;/p>
&lt;ul>
&lt;li>HelmRelease deployment method.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul>
&lt;/li>
&lt;/ul></description></item></channel></rss>