<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Operations on KubeClaw</title><link>https://projectious-work.github.io/kubeclaw/docs/operations/</link><description>Recent content in Operations on KubeClaw</description><generator>Hugo</generator><language>en</language><atom:link href="https://projectious-work.github.io/kubeclaw/docs/operations/index.xml" rel="self" type="application/rss+xml"/><item><title>Scale Up/Down</title><link>https://projectious-work.github.io/kubeclaw/docs/operations/scale-up-down/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://projectious-work.github.io/kubeclaw/docs/operations/scale-up-down/</guid><description>&lt;p&gt;This guide covers scaling your cluster at both the infrastructure and Kubernetes levels.&lt;/p&gt;
&lt;h2 id="scale-infrastructure"&gt;Scale Infrastructure&lt;/h2&gt;
&lt;h3 id="add-worker-nodes"&gt;Add worker nodes&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Edit &lt;code&gt;terraform.tfvars&lt;/code&gt; &amp;ndash; update &lt;code&gt;worker_node_types&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-hcl" data-lang="hcl"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;worker_node_types&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt; { type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt; &amp;#34;cx23&amp;#34;, count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt; }&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt; { type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt; &amp;#34;cx33&amp;#34;, count&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; }&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="c1"&gt; # 3 workers total, mixed types
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Apply changes:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;tofu apply
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Regenerate Ansible inventory:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;./scripts/generate-ansible-inventory.sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Run Ansible playbooks on the new nodes &amp;ndash; see &lt;a href="https://projectious-work.github.io/kubeclaw/docs/guide/ansible/"&gt;Server Management (Ansible)&lt;/a&gt; for the full workflow.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="add-replica-control-nodes"&gt;Add replica control nodes&lt;/h3&gt;
&lt;p&gt;Same pattern using &lt;code&gt;control_node_types&lt;/code&gt;:&lt;/p&gt;</description></item><item><title>SSH Key Rotation</title><link>https://projectious-work.github.io/kubeclaw/docs/operations/ssh-key-rotation/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://projectious-work.github.io/kubeclaw/docs/operations/ssh-key-rotation/</guid><description>&lt;h2 id="when-to-rotate"&gt;When to rotate&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Periodically (e.g. annually)&lt;/li&gt;
&lt;li&gt;If compromise is suspected&lt;/li&gt;
&lt;li&gt;When personnel changes occur&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="with-auto-generated-keys"&gt;With auto-generated keys&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1. Mark old key resources for recreation&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;tofu taint &lt;span class="s1"&gt;&amp;#39;tls_private_key.control_node[0]&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;tofu taint &lt;span class="s1"&gt;&amp;#39;tls_private_key.worker_node[0]&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2. Generate new keys and update servers&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;tofu apply
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 3. Export new keys&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;./scripts/setup-ssh.sh
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="alert alert-primary" role="alert"&gt;&lt;div class="h4 alert-heading" role="heading"&gt;Warning&lt;/div&gt;


During rotation SSH access may be briefly interrupted. Keep Hetzner web console root access available as a fallback.

&lt;/div&gt;

&lt;h2 id="with-custom-keys"&gt;With custom keys&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1. Create new keys&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh-keygen -t ed25519 -f ~/.ssh/k8s-control-new -C &lt;span class="s2"&gt;&amp;#34;control-node-new&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2. Add the new public key to the server (before removing the old one)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh control-node
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;ssh-ed25519 AAAA... control-node-new&amp;#34;&lt;/span&gt; &amp;gt;&amp;gt; ~/.ssh/authorized_keys
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 3. Test the new key&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -i ~/.ssh/k8s-control-new kubernetes-admin@&amp;lt;node-ip&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 4. Remove the old key from authorized_keys&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;ssh -i ~/.ssh/k8s-control-new control-node
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Edit ~/.ssh/authorized_keys and remove the old key line&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 5. Update terraform.tfvars with the new public key&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# control_node_public_key = &amp;#34;ssh-ed25519 AAAA... (new key)&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 6. Sync OpenTofu state&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;tofu apply
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Repeat for worker node keys if applicable.&lt;/p&gt;</description></item><item><title>Kubernetes Maintenance</title><link>https://projectious-work.github.io/kubeclaw/docs/operations/kubernetes-maintenance/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://projectious-work.github.io/kubeclaw/docs/operations/kubernetes-maintenance/</guid><description>&lt;p&gt;Operational procedures for upgrading and managing the Kubernetes cluster. For initial cluster setup, see the &lt;a href="https://projectious-work.github.io/kubeclaw/docs/guide/kubernetes/"&gt;Kubernetes (kubeadm)&lt;/a&gt; guide.&lt;/p&gt;
&lt;h2 id="upgrade-kubernetes"&gt;Upgrade Kubernetes&lt;/h2&gt;
&lt;p&gt;Kubernetes upgrades follow a strict order: &lt;strong&gt;control plane first, then workers&lt;/strong&gt;. This is the standard CKA upgrade workflow.&lt;/p&gt;
&lt;h3 id="upgrade-control-plane"&gt;Upgrade control plane&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1. Unhold packages&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-mark unhold kubeadm
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 2. Upgrade kubeadm&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; sudo apt-get install -y &lt;span class="nv"&gt;kubeadm&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1.33.*-*
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 3. Check available upgrade&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo kubeadm upgrade plan
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 4. Apply the upgrade&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo kubeadm upgrade apply v1.33.0
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 5. Drain the control node (if running workloads)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl drain &lt;span class="k"&gt;$(&lt;/span&gt;hostname&lt;span class="k"&gt;)&lt;/span&gt; --ignore-daemonsets --delete-emptydir-data
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 6. Upgrade kubelet and kubectl&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-mark unhold kubelet kubectl
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-get install -y &lt;span class="nv"&gt;kubelet&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1.33.*-* &lt;span class="nv"&gt;kubectl&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1.33.*-*
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt-mark hold kubelet kubeadm kubectl
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl daemon-reload
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo systemctl restart kubelet
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 7. Uncordon the node&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;kubectl uncordon &lt;span class="k"&gt;$(&lt;/span&gt;hostname&lt;span class="k"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="upgrade-worker-nodes"&gt;Upgrade worker nodes&lt;/h3&gt;
&lt;p&gt;On each worker node:&lt;/p&gt;</description></item><item><title>Security</title><link>https://projectious-work.github.io/kubeclaw/docs/operations/security/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://projectious-work.github.io/kubeclaw/docs/operations/security/</guid><description>&lt;div class="alert alert-warning" role="alert"&gt;&lt;div class="h4 alert-heading" role="heading"&gt;Design intent, not a security guarantee&lt;/div&gt;


This page describes what the design *intends* to protect against. KubeClaw is
a [prototype](/kubeclaw/docs/project-status/) and has not been
adversarially tested or audited -- assume gaps exist. Treat the table below as
a statement of intent, not of assurance.
&lt;/div&gt;

&lt;h2 id="security-summary"&gt;Security Summary&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Layer&lt;/th&gt;
					&lt;th&gt;Protection&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Network (Hetzner)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Firewall blocks all inbound; IPv6-only, no public IPv4&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Network (K8s)&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Cilium egress whitelist per namespace/app (FQDN-based)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Access&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Cloudflare Tunnel (outbound-only connection, no open ports)&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Authentication&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Cloudflare Access policies + SSH key-only auth&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Container&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Non-root user, dropped capabilities, resource limits&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;SSH&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Key-only auth, fail2ban, no TCP forwarding on workers&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;&lt;strong&gt;Storage&lt;/strong&gt;&lt;/td&gt;
					&lt;td&gt;Isolated PVCs per workload&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="what-this-setup-protects-against"&gt;What this setup protects against&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Direct server attacks&lt;/strong&gt; &amp;ndash; no public IPs, no open inbound ports&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Unauthorized access&lt;/strong&gt; &amp;ndash; Cloudflare Access + SSH key-only auth&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Data exfiltration&lt;/strong&gt; &amp;ndash; FQDN-based egress whitelist per application&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Lateral movement&lt;/strong&gt; &amp;ndash; namespace isolation, per-pod network policies&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Resource abuse&lt;/strong&gt; &amp;ndash; container resource limits&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="what-to-monitor"&gt;What to monitor&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;API key and token compromise&lt;/strong&gt; &amp;ndash; rotate regularly&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cloudflare Tunnel health&lt;/strong&gt; &amp;ndash; monitor via Zero Trust dashboard&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Node resource utilization&lt;/strong&gt; &amp;ndash; watch for memory pressure on small instances&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="security-notes"&gt;Security notes&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Passwords in cloud-init&lt;/strong&gt; are visible in cloud-init logs. Change them after first login.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SSH keys&lt;/strong&gt; should be different for each server role.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Root password&lt;/strong&gt; is only intended for emergency access via Hetzner Web Console.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Terraform state&lt;/strong&gt; contains sensitive data (private keys when auto-generated). Protect state files.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;UFW rules&lt;/strong&gt; for HTTP/HTTPS on worker nodes can be removed after initial setup:
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw delete allow out to any port &lt;span class="m"&gt;80&lt;/span&gt; proto tcp
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo ufw delete allow out to any port &lt;span class="m"&gt;443&lt;/span&gt; proto tcp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="openclaw-specific-security"&gt;OpenClaw-specific security&lt;/h2&gt;
&lt;p&gt;When running OpenClaw:&lt;/p&gt;</description></item><item><title>Password Management</title><link>https://projectious-work.github.io/kubeclaw/docs/operations/password-management/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://projectious-work.github.io/kubeclaw/docs/operations/password-management/</guid><description>&lt;h2 id="which-credentials-exist"&gt;Which credentials exist?&lt;/h2&gt;
&lt;table&gt;
	&lt;thead&gt;
			&lt;tr&gt;
					&lt;th&gt;Credential&lt;/th&gt;
					&lt;th&gt;Purpose&lt;/th&gt;
					&lt;th&gt;Storage&lt;/th&gt;
			&lt;/tr&gt;
	&lt;/thead&gt;
	&lt;tbody&gt;
			&lt;tr&gt;
					&lt;td&gt;Hetzner API Token&lt;/td&gt;
					&lt;td&gt;Create infrastructure&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;terraform.tfvars&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Root password&lt;/td&gt;
					&lt;td&gt;Emergency web console&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;terraform.tfvars&lt;/code&gt;&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;SSH private keys&lt;/td&gt;
					&lt;td&gt;Server access&lt;/td&gt;
					&lt;td&gt;&lt;code&gt;~/.ssh/&lt;/code&gt; or password manager&lt;/td&gt;
			&lt;/tr&gt;
			&lt;tr&gt;
					&lt;td&gt;Cloudflare Tunnel token&lt;/td&gt;
					&lt;td&gt;Tunnel auth&lt;/td&gt;
					&lt;td&gt;Cloudflare Dashboard&lt;/td&gt;
			&lt;/tr&gt;
	&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="recommended-dashlane-structure"&gt;Recommended Dashlane structure&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;📁 K8s Cluster
├── 🔐 Hetzner API Token
│ └── Token: xxx
├── 🔐 Root Password
│ └── Password: xxx
├── 📝 SSH Keys (Secure Note)
│ ├── Control Node Private Key: ...
│ ├── Control Node Public Key: ...
│ ├── Worker Node Private Key: ...
│ └── Worker Node Public Key: ...
└── 🔐 Cloudflare Tunnel Token
 └── Token: xxx
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="securing-terraformtfvars"&gt;Securing terraform.tfvars&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;terraform.tfvars&lt;/code&gt; contains sensitive data. Options:&lt;/p&gt;</description></item><item><title>Troubleshooting</title><link>https://projectious-work.github.io/kubeclaw/docs/operations/troubleshooting/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://projectious-work.github.io/kubeclaw/docs/operations/troubleshooting/</guid><description>&lt;h2 id="infrastructure-issues"&gt;Infrastructure Issues&lt;/h2&gt;
&lt;h3 id="cloudflared-wont-start-ipv6-only"&gt;cloudflared won&amp;rsquo;t start (IPv6-only)&lt;/h3&gt;
&lt;p&gt;Check &lt;code&gt;/etc/cloudflared/config.yml&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;edge-ip-version&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;6&amp;#34;&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="alert alert-primary" role="alert"&gt;&lt;div class="h4 alert-heading" role="heading"&gt;Important&lt;/div&gt;


The value must be a string in quotes (`"6"`, not `6`). Cloudflared defaults to IPv4 connections to Cloudflare's edge servers.

&lt;/div&gt;

&lt;h3 id="ssh-key-rotation-failed"&gt;SSH key rotation failed&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Connect via Hetzner web console (root password)&lt;/li&gt;
&lt;li&gt;Add the new key manually:
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;ssh-ed25519 AAAA...&amp;#34;&lt;/span&gt; &amp;gt;&amp;gt; /home/kubernetes-admin/.ssh/authorized_keys
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="ansible-cannot-connect"&gt;Ansible cannot connect&lt;/h3&gt;
&lt;p&gt;Check:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Is &lt;code&gt;cloudflared&lt;/code&gt; installed locally?&lt;/li&gt;
&lt;li&gt;Is the tunnel running? (&lt;code&gt;cloudflared tunnel list&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Is the inventory correct? (&lt;code&gt;./scripts/generate-ansible-inventory.sh&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Is the ssh-agent running with keys loaded? (&lt;code&gt;ssh-add -l&lt;/code&gt;)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="state-lost--keys-gone"&gt;State lost / keys gone&lt;/h3&gt;
&lt;p&gt;With auto-generated keys:&lt;/p&gt;</description></item></channel></rss>