<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Jacob Baek's home</title>
    <link>https://mr100do.tistory.com/</link>
    <description>DevOps, Cloud, ...
if you have any question, please send mail to me
(dubaek@gmail.com)</description>
    <language>ko</language>
    <pubDate>Mon, 27 Jul 2026 00:35:09 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>Jacob_baek</managingEditor>
    <image>
      <title>Jacob Baek's home</title>
      <url>https://t1.daumcdn.net/cfile/tistory/1273BE4F4F7FA2930F</url>
      <link>https://mr100do.tistory.com</link>
    </image>
    <item>
      <title>Why Rootless Docker-in-Docker Fails on Ubuntu 24.04+</title>
      <link>https://mr100do.tistory.com/427958</link>
      <description>&lt;h1&gt;Issue&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;With the adoption of Ubuntu 24.04 (Noble) in modern Kubernetes environments, many users have started encountering failures when running rootless Docker-in-Docker (DinD) containers.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A typical error looks like this:&lt;/p&gt;
&lt;pre class=&quot;groovy&quot;&gt;&lt;code&gt;[rootlesskit:parent] error: failed to start the child:2fork/exec /proc/self/exe: operation not permitted&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;This post explains the root cause, why it only happens on newer Ubuntu versions, and what actually works in practice.&lt;/p&gt;
&lt;h1&gt;Background: How Rootless DinD Works&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;docker:dind-rootless is designed to run Docker without root privileges.&lt;br /&gt;Internally, it relies on:&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;dockerd-rootless.sh
  &amp;rarr; rootlesskit
    &amp;rarr; user namespace (userns)
    &amp;rarr; mount namespace
    &amp;rarr; network namespace
    &amp;rarr; re-exec via /proc/self/exe
    &amp;rarr; start dockerd&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Key requirement:&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RootlessKit must create an unprivileged user namespace.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Without this, the Docker daemon never starts.&lt;/p&gt;
&lt;h1&gt;What Changed in Ubuntu 24.04&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Starting from Ubuntu 23.10 and fully enforced in 24.04:&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Unprivileged user namespace creation is restricted by AppArmor by default.&lt;br /&gt;&lt;a href=&quot;https://discourse.ubuntu.com/t/understanding-apparmor-user-namespace-restriction/58007&quot;&gt;https://discourse.ubuntu.com/t/understanding-apparmor-user-namespace-restriction/58007&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;This behavior is controlled by:&lt;/p&gt;
&lt;pre class=&quot;awk&quot;&gt;&lt;code&gt;/proc/sys/kernel/apparmor_restrict_unprivileged_userns&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;When enabled:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Non-root processes cannot freely create user namespaces&lt;/li&gt;
&lt;li&gt;Only processes explicitly allowed by AppArmor profiles can do so&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Why this worked on Ubuntu 22.04&lt;br /&gt;Nothing in Kubernetes changed &amp;mdash; this is a host OS security change&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;Failure Mechanism&lt;/h1&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Rootless DinD starts&lt;/li&gt;
&lt;li&gt;RootlessKit tries to: &lt;code&gt;unshare(CLONE_NEWUSER)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Kernel checks AppArmor policy&lt;/li&gt;
&lt;li&gt;AppArmor denies &lt;code&gt;userns_create&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;RootlessKit fails when re-executing: &lt;code&gt;fork/exec /proc/self/exe &amp;rarr; EPERM&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;Why privileged: true Does NOT Fix It&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Even ifsecurityContext set &quot;privileged:true&quot;, it would be failed.&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;securityContext: 
  privileged: true&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Because&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;privileged: true &amp;rarr; grants capabilities&lt;/li&gt;
&lt;li&gt;RootlessKit &amp;rarr; runs as non-root user&lt;/li&gt;
&lt;li&gt;Ubuntu 24.04 restriction &amp;rarr; applies to unprivileged user namespace&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;How to fix it&lt;/h1&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;1. Use Rootful DinD&lt;/h2&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;apiVersion: v1
kind: Pod
metadata:
  name: dind-rootful
spec:
  containers:
    - name: dind
      image: docker:28.0.1-dind 
      securityContext:
        privileged: true&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;2. Use Ubuntu 22.04 Node&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;If you can use Ubuntu 22.04 node, it would be option that you can use DinD rootless.&lt;/p&gt;
&lt;pre class=&quot;groovy&quot;&gt;&lt;code&gt;nodeSelector:
  kubernetes.io/os-image: Ubuntu2204&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;3. Disable restriont (not recommended)&lt;/h2&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;$ sysctl -w kernel.apparmor_restrict_unprivileged_userns=0&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;4. Custom AppArmor Profile (Advanced / Not Recommended in Managed K8s)&lt;/h2&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;cat &amp;lt;&amp;lt;EOF &amp;gt; /etc/apparmor.d/rootlesskit
profile rootlesskit /usr/bin/rootlesskit flags=(unconfined) {
  userns,
}
EOF

systemctl restart apparmor&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;Test Result&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I run the DinD rootless container on Ubuntu 22/24 OS.&lt;br /&gt;The result is different.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Ubuntu 22&lt;/h2&gt;
&lt;pre class=&quot;tcl&quot;&gt;&lt;code&gt;root@ubuntu22node:/# cat /proc/sys/kernel/unprivileged_userns_clone
1
### by apparmor
root@ubuntu22node:/# cat /proc/sys/kernel/apparmor_restrict_unprivileged_userns
cat: /proc/sys/kernel/apparmor_restrict_unprivileged_userns: No such file or directory&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Ubuntu 24&lt;/h2&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;root@ubuntu24node:/# cat /proc/sys/kernel/unprivileged_userns_clone
1
root@ubuntu24node:/# cat /proc/sys/kernel/apparmor_restrict_unprivileged_userns
1
root@ubuntu24node:/# sudo dmesg -T | grep -iE 'apparmor|userns|rootlesskit|DENIED' | tail -n 3
[Fri Jun 26 05:08:49 2026] audit: type=1400 audit(1782450529.255:124): apparmor=&quot;DENIED&quot; operation=&quot;capable&quot; class=&quot;cap&quot; profile=&quot;unprivileged_userns&quot; pid=8815 comm=&quot;rootlesskit&quot; capability=21  capname=&quot;sys_admin&quot;
[Fri Jun 26 05:09:04 2026] audit: type=1400 audit(1782450544.540:125): apparmor=&quot;AUDIT&quot; operation=&quot;userns_create&quot; class=&quot;namespace&quot; info=&quot;Userns create - transitioning profile&quot; profile=&quot;unconfined&quot; pid=8860 comm=&quot;rootlesskit&quot; requested=&quot;userns_create&quot; target=&quot;unprivileged_userns&quot;
[Fri Jun 26 05:09:29 2026] audit: type=1400 audit(1782450569.900:126): apparmor=&quot;AUDIT&quot; operation=&quot;userns_create&quot; class=&quot;namespace&quot; info=&quot;Userns create - transitioning profile&quot; profile=&quot;unconfined&quot; pid=9028 comm=&quot;rootlesskit&quot; requested=&quot;userns_create&quot; target=&quot;unprivileged_userns&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;Generating Apparmor custom profile&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;If you want to make custom profile and apply apparmor profile on your pod it would be good option.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/kubernetes/kubernetes/tree/v1.36.2/test/images/apparmor-loader&quot;&gt;https://github.com/kubernetes/kubernetes/tree/v1.36.2/test/images/apparmor-loader&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/tuxerrante/kapparmor&quot;&gt;https://github.com/tuxerrante/kapparmor&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;References&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://docs.docker.com/engine/security/rootless/troubleshoot/#errors-when-starting-the-docker-daemon&quot;&gt;https://docs.docker.com/engine/security/rootless/troubleshoot/#errors-when-starting-the-docker-daemon&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://devco.re/blog/2025/06/26/the-journey-of-bypassing-ubuntus-unprivileged-namespace-restriction-en/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://devco.re/blog/2025/06/26/the-journey-of-bypassing-ubuntus-unprivileged-namespace-restriction-en/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Cloud/Kubernetes</category>
      <category>AppArmor</category>
      <category>dind rootless</category>
      <category>ubuntu24</category>
      <author>Jacob_baek</author>
      <guid isPermaLink="true">https://mr100do.tistory.com/427958</guid>
      <comments>https://mr100do.tistory.com/427958#entry427958comment</comments>
      <pubDate>Wed, 1 Jul 2026 10:45:13 +0900</pubDate>
    </item>
    <item>
      <title>AKS Node Disk Usage Analysis</title>
      <link>https://mr100do.tistory.com/427956</link>
      <description>&lt;h1&gt;Understanding Disk Pressure and Root Causes&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Disk pressure on AKS nodes is a common issue in production environments.&lt;br /&gt;While Kubernetes provides basic mechanisms such as image garbage collection, these are often insufficient to resolve real-world disk usage problems.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;This post walks through how disk is actually consumed on AKS nodes, what frequently causes disk pressure, and how to systematically analyze it using a diagnostic script.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A helper script is available here:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/jacobbaek/k8s-troubleshoot/tree/main/node-disk-analyzer&quot;&gt;Node Disk Analyzer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Why Disk Pressure Happens on AKS Nodes&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;From a Kubernetes perspective, node disk usage is not limited to a single component.&lt;br /&gt;Instead, it is shared across multiple categories collectively known as &lt;b&gt;local ephemeral storage&lt;/b&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;In practice, disk pressure is usually caused by the following:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Container images (image cache)&lt;/li&gt;
&lt;li&gt;Container writable layers (overlayfs)&lt;/li&gt;
&lt;li&gt;Container logs&lt;/li&gt;
&lt;li&gt;Pod volumes (such as emptyDir)&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Understanding each of these categories is critical for accurate troubleshooting.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Key Disk Usage Categories&lt;/h2&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;1. Container Images&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Location: /var/lib/containerd/io.containerd.snapshotter.v1.overlayfs&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;This is where container images are stored after being pulled.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Typical causes of growth:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Frequent deployments with new image tags&lt;/li&gt;
&lt;li&gt;Large image sizes&lt;/li&gt;
&lt;li&gt;Stale images not cleaned up&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Kubelet manages this area through image garbage collection using:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;imageGcHighThreshold&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;imageGcLowThreshold&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;However, this only applies to unused images.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;2. Container Writable Layer (overlayfs)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Location: /var/lib/containerd/io.containerd.snapshotter.v1.overlayfs&lt;br /&gt;This is the writable layer for running containers.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Any file created inside a container (excluding mounted volumes) is stored here.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Typical causes:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Applications writing logs to files instead of stdout&lt;/li&gt;
&lt;li&gt;Temporary or cache data inside the container filesystem&lt;/li&gt;
&lt;li&gt;High container churn (frequent restarts)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Important characteristics:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Not managed by image garbage collection&lt;/li&gt;
&lt;li&gt;Often a major contributor to disk pressure&lt;/li&gt;
&lt;li&gt;Difficult to notice without explicit analysis&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;3. Container Logs&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Locations: /var/log/containers, /var/log/pods&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;These are stdout/stderr logs captured by Kubernetes.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Typical causes:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Verbose logging levels (debug/trace)&lt;/li&gt;
&lt;li&gt;Lack of log rotation configuration&lt;/li&gt;
&lt;li&gt;High request volume&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Mitigation options:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;containerLogMaxSizeMB&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;containerLogMaxFiles&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;4. Pod Volumes (emptyDir and others)&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Location: /var/lib/kubelet/pods&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;This includes all pod-level data such as:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;code&gt;emptyDir&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;mounted volume data stored on node disk&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Typical use cases:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;temporary files&lt;/li&gt;
&lt;li&gt;caching&lt;/li&gt;
&lt;li&gt;data sharing between containers&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Typical issues:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Applications continuously writing data without cleanup&lt;/li&gt;
&lt;li&gt;Batch jobs generating files&lt;/li&gt;
&lt;li&gt;Sidecars buffering data (e.g., log forwarders)&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Unlike overlayfs, this is intentional storage defined by workload configuration.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Why Image GC Alone Is Not Enough&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A common misconception is that increasing image GC thresholds will resolve disk pressure.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;This is not accurate.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Image garbage collection only affects: container images (content store)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;It does not address:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;logs&lt;/li&gt;
&lt;li&gt;overlayfs usage&lt;/li&gt;
&lt;li&gt;emptyDir or pod volume data&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;In many cases, disk pressure persists even after image cleanup because the majority of usage is outside the image layer.&lt;/p&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Approach to Disk Usage Analysis&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;To properly troubleshoot disk pressure, the goal is to answer:&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Which category is consuming the most disk space?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A structured approach includes:&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Measure usage per category&lt;/li&gt;
&lt;li&gt;Compare relative proportions&lt;/li&gt;
&lt;li&gt;Identify dominant contributor&lt;/li&gt;
&lt;li&gt;Apply targeted mitigation&lt;/li&gt;
&lt;/ol&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Diagnostic Script&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;To simplify this process, the following analyzer can be deployed to a specific node:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/jacobbaek/k8s-troubleshoot/tree/main/node-disk-analyzer&quot;&gt;AKS Node Disk Analyzer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;The script runs inside a privileged pod and inspects the host filesystem.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;It provides:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Per-category disk usage (images, overlay, logs, volumes)&lt;/li&gt;
&lt;li&gt;Percentage breakdown&lt;/li&gt;
&lt;li&gt;Top contributing directories&lt;/li&gt;
&lt;li&gt;Largest files on the node&lt;/li&gt;
&lt;li&gt;Classification hints&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Example Output Interpretation&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;A typical output may look like:&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;Usage Summary (KB)
Image   : 12,000,000
Overlay : 8,000,000
Log     : 2,000,000
Volume  : 500,000
TOTAL   : 22,500,000
Percentage (%)
Image   : 53%
Overlay : 35%
Log     : 8%
Volume  : 2%&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;How to interpret this&lt;/h3&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Image dominant (&amp;gt;50%):
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;large image cache&lt;/li&gt;
&lt;li&gt;stale images not cleaned&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Overlay dominant:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;application writing data inside container filesystem&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Log dominant:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;excessive stdout logging&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Volume dominant:
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;emptyDir or mounted workload data growing&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Troubleshooting Guidance by Category&lt;/h2&gt;
&lt;table data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Typical Root Cause&lt;/th&gt;
&lt;th&gt;Recommended Action&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Image&lt;/td&gt;
&lt;td&gt;Stale images, large images&lt;/td&gt;
&lt;td&gt;Adjust GC, prune images&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Overlay&lt;/td&gt;
&lt;td&gt;File writes inside container&lt;/td&gt;
&lt;td&gt;Change logging pattern, cleanup temp files&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Log&lt;/td&gt;
&lt;td&gt;Excessive stdout logging&lt;/td&gt;
&lt;td&gt;Tune log rotation, reduce verbosity&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Volume&lt;/td&gt;
&lt;td&gt;emptyDir or workload-generated files&lt;/td&gt;
&lt;td&gt;Add lifecycle cleanup, enforce limits&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Best Practices&lt;/h2&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Always identify the dominant disk consumer before taking action&lt;/li&gt;
&lt;li&gt;Do not rely solely on garbage collection&lt;/li&gt;
&lt;li&gt;Ensure application-level cleanup policies exist&lt;/li&gt;
&lt;li&gt;Configure log rotation proactively&lt;/li&gt;
&lt;li&gt;Monitor node disk usage continuously&lt;/li&gt;
&lt;/ul&gt;
&lt;hr data-ke-style=&quot;style1&quot; /&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;Conclusion&lt;/h2&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Disk pressure in AKS is rarely caused by a single factor.&lt;br /&gt;It is the result of how multiple layers in Kubernetes share the same node filesystem.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Accurate troubleshooting requires breaking down disk usage into:&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;images&lt;/li&gt;
&lt;li&gt;overlayfs&lt;/li&gt;
&lt;li&gt;logs&lt;/li&gt;
&lt;li&gt;volumes&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Using a structured approach and proper tooling allows you to identify the root cause quickly and apply the right mitigation strategy.&lt;/p&gt;</description>
      <category>Cloud/Kubernetes</category>
      <author>Jacob_baek</author>
      <guid isPermaLink="true">https://mr100do.tistory.com/427956</guid>
      <comments>https://mr100do.tistory.com/427956#entry427956comment</comments>
      <pubDate>Mon, 15 Jun 2026 10:46:24 +0900</pubDate>
    </item>
    <item>
      <title>InternalTrafficPolicy</title>
      <link>https://mr100do.tistory.com/427938</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://kubernetes.io/docs/concepts/services-networking/service-traffic-policy/&quot;&gt;https://kubernetes.io/docs/concepts/services-networking/service-traffic-policy/&lt;/a&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;연결하려는 pod가 동일 node에 없는 경우 연결자체가 안된다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;## internaltrafficpolicy = local and pods are not in same node.
root@aks-nodepool1-23236778-vmss000002:/# iptables-save | grep -i nginx
-A KUBE-SERVICES -d 10.0.130.191/32 -p tcp -m comment --comment &quot;default/nginx-sample-svc has no local endpoints&quot; -j DROP
## internaltrafficpolicy = cluster
root@aks-nodepool1-23236778-vmss000002:/# iptables-save | grep -i nginx
-A KUBE-SEP-VKFWAD6C5GW7XJNY -s 10.240.0.50/32 -m comment --comment &quot;default/nginx-sample-svc&quot; -j KUBE-MARK-MASQ
-A KUBE-SEP-VKFWAD6C5GW7XJNY -p tcp -m comment --comment &quot;default/nginx-sample-svc&quot; -m tcp -j DNAT --to-destination 10.240.0.50:8080
-A KUBE-SERVICES -d 10.0.130.191/32 -p tcp -m comment --comment &quot;default/nginx-sample-svc cluster IP&quot; -j KUBE-SVC-JT67RD6F3OETQGP2
-A KUBE-SVC-JT67RD6F3OETQGP2 -d 10.0.130.191/32 ! -i azv+ -p tcp -m comment --comment &quot;default/nginx-sample-svc cluster IP&quot; -j KUBE-MARK-MASQ
-A KUBE-SVC-JT67RD6F3OETQGP2 -m comment --comment &quot;default/nginx-sample-svc -&amp;gt; 10.240.0.50:8080&quot; -j KUBE-SEP-VKFWAD6C5GW7XJNY&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약 동일 node에 통신을 하려는 두 pod가 있는 경우는&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;## internaltrafficpolicy = local and pods are in same node. 
root@aks-nodepool1-23236778-vmss000002:/# iptables-save |grep nginx
-A KUBE-SEP-HLUNARSNCDYYPHUV -s 10.240.0.68/32 -m comment --comment &quot;default/nginx-sample-svc&quot; -j KUBE-MARK-MASQ
-A KUBE-SEP-HLUNARSNCDYYPHUV -p tcp -m comment --comment &quot;default/nginx-sample-svc&quot; -m tcp -j DNAT --to-destination 10.240.0.68:8080
-A KUBE-SERVICES -d 10.0.130.191/32 -p tcp -m comment --comment &quot;default/nginx-sample-svc cluster IP&quot; -j KUBE-SVL-JT67RD6F3OETQGP2
-A KUBE-SVL-JT67RD6F3OETQGP2 -d 10.0.130.191/32 ! -i azv+ -p tcp -m comment --comment &quot;default/nginx-sample-svc cluster IP&quot; -j KUBE-MARK-MASQ
-A KUBE-SVL-JT67RD6F3OETQGP2 -m comment --comment &quot;default/nginx-sample-svc -&amp;gt; 10.240.0.68:8080&quot; -j KUBE-SEP-HLUNARSNCDYYPHUV&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;보통 아래와 같은 service endpoint 에 매칭되는 rule이 존재하며 nodeIP:port로 지정되어 있다.&lt;br /&gt;(여기서 10.240.0.41 는 nginx-sample pod가 동작되고 있는 node이다.)&lt;/p&gt;
&lt;pre class=&quot;mipsasm&quot;&gt;&lt;code&gt;-A KUBE-SVC-JT67RD6F3OETQGP2 -m comment --comment &quot;default/nginx-sample-svc -&amp;gt; 10.240.0.41:8080&quot; -j KUBE-SEP-I4JGEQAI6S5SYXV7&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 pod를 4개로 늘린 경우 아래와 같이 가중치가 붙는 형태로 rule이 생성된다.&lt;br /&gt;(여기서 10.240.0.73 이 실제 확인중인 node의 ip이다. 즉, 동일 node는 가중치가 없고 바로 연결을 지향한다.)&lt;/p&gt;
&lt;pre class=&quot;mipsasm&quot;&gt;&lt;code&gt;-A KUBE-SVC-JT67RD6F3OETQGP2 -m comment --comment &quot;default/nginx-sample-svc -&amp;gt; 10.240.0.148:8080&quot; -m statistic --mode random --probability 0.25000000000 -j KUBE-SEP-44HLQTUCEZ7VEBKD
-A KUBE-SVC-JT67RD6F3OETQGP2 -m comment --comment &quot;default/nginx-sample-svc -&amp;gt; 10.240.0.29:8080&quot; -m statistic --mode random --probability 0.33333333349 -j KUBE-SEP-7CLJKZYKU4YYJTUQ
-A KUBE-SVC-JT67RD6F3OETQGP2 -m comment --comment &quot;default/nginx-sample-svc -&amp;gt; 10.240.0.41:8080&quot; -m statistic --mode random --probability 0.50000000000 -j KUBE-SEP-I4JGEQAI6S5SYXV7
-A KUBE-SVC-JT67RD6F3OETQGP2 -m comment --comment &quot;default/nginx-sample-svc -&amp;gt; 10.240.0.73:8080&quot; -j KUBE-SEP-PD4DNTIBFNIHTOXJ&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Cloud/Kubernetes</category>
      <author>Jacob_baek</author>
      <guid isPermaLink="true">https://mr100do.tistory.com/427938</guid>
      <comments>https://mr100do.tistory.com/427938#entry427938comment</comments>
      <pubDate>Tue, 25 Nov 2025 17:54:26 +0900</pubDate>
    </item>
    <item>
      <title>envoy gateway api controller</title>
      <link>https://mr100do.tistory.com/427937</link>
      <description>&lt;h1&gt;Background&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://www.kubernetes.dev/blog/2025/11/12/ingress-nginx-retirement/&quot;&gt;https://www.kubernetes.dev/blog/2025/11/12/ingress-nginx-retirement/&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;Envoy controller&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://gateway.envoyproxy.io/docs/tasks/quickstart/&quot;&gt;https://gateway.envoyproxy.io/docs/tasks/quickstart/&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;Installation&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://gateway.envoyproxy.io/docs/tasks/quickstart/&quot;&gt;https://gateway.envoyproxy.io/docs/tasks/quickstart/&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;jboss-cli&quot;&gt;&lt;code&gt;helm install eg oci://docker.io/envoyproxy/gateway-helm --version v1.6.0 -n envoy-gateway-system --create-namespace&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://gateway.envoyproxy.io/latest/install/install-yaml/&quot;&gt;https://gateway.envoyproxy.io/latest/install/install-yaml/&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;quick start and learn how it works&lt;/h1&gt;
&lt;pre class=&quot;stylus&quot;&gt;&lt;code&gt;$ kubectl apply -f https://github.com/envoyproxy/gateway/releases/download/v1.6.0/quickstart.yaml -n default
gatewayclass.gateway.networking.k8s.io/eg created
gateway.gateway.networking.k8s.io/eg created
serviceaccount/backend created
service/backend created
deployment.apps/backend created
httproute.gateway.networking.k8s.io/backend created&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;following the below service, you can access URL using external-ip&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;$ kubectl get svc -n envoy-gateway-system -l app.kubernetes.io/instance=eg
NAME            TYPE        CLUSTER-IP    EXTERNAL-IP   PORT(S)                                            AGE
envoy-gateway   ClusterIP   10.0.173.35   &amp;lt;none&amp;gt;        18000/TCP,18001/TCP,18002/TCP,19001/TCP,9443/TCP   76m
$ kubectl get svc -n envoy-gateway-system -l app.kubernetes.io/name=envoy
NAME                        TYPE           CLUSTER-IP    EXTERNAL-IP    PORT(S)        AGE
envoy-default-eg-e41e7b31   LoadBalancer   10.0.42.162   x.x.x.x        80:30436/TCP   72m
$ kubectl get gateway
NAME   CLASS   ADDRESS        PROGRAMMED   AGE
eg     eg      x.x.x.x        True         74m&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;ingress와의 차이점&lt;/h1&gt;
&lt;table data-ke-align=&quot;alignLeft&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&amp;nbsp;&lt;/th&gt;
&lt;th&gt;ingress&lt;/th&gt;
&lt;th&gt;gateway api&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;component&lt;/td&gt;
&lt;td&gt;ingress&lt;/td&gt;
&lt;td&gt;gateway / httproute&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;additional features&lt;/td&gt;
&lt;td&gt;annotation&lt;/td&gt;
&lt;td&gt;CRD로 추가 제공&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본 생성시에는 ingress와 비교해보았을때에는 gateway 와 httproute만 제공되면 서비스가 가능하다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;gateway : listener 역할 수행&lt;/li&gt;
&lt;li&gt;httproute : ingress에서 path 로 ingress내에 선언하였던 부분을 분리하여 설정할수 있다.&lt;/li&gt;
&lt;li&gt;그외에도 다양한 crd를 활용할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;$ kubectl get crd | grep gateway
backends.gateway.envoyproxy.io                        2025-11-21T04:43:10Z
backendtlspolicies.gateway.networking.k8s.io          2025-11-21T04:43:08Z
backendtrafficpolicies.gateway.envoyproxy.io          2025-11-21T04:43:11Z
clienttrafficpolicies.gateway.envoyproxy.io           2025-11-21T04:43:12Z
envoyextensionpolicies.gateway.envoyproxy.io          2025-11-21T04:43:12Z
envoypatchpolicies.gateway.envoyproxy.io              2025-11-21T04:43:13Z
envoyproxies.gateway.envoyproxy.io                    2025-11-21T04:43:14Z
gatewayclasses.gateway.networking.k8s.io              2025-11-21T04:43:08Z
gateways.gateway.networking.k8s.io                    2025-11-21T04:43:08Z
grpcroutes.gateway.networking.k8s.io                  2025-11-21T04:43:08Z
httproutefilters.gateway.envoyproxy.io                2025-11-21T04:43:15Z
httproutes.gateway.networking.k8s.io                  2025-11-21T04:43:09Z
referencegrants.gateway.networking.k8s.io             2025-11-21T04:43:08Z
securitypolicies.gateway.envoyproxy.io                2025-11-21T04:43:16Z
tcproutes.gateway.networking.k8s.io                   2025-11-21T04:43:08Z
tlsroutes.gateway.networking.k8s.io                   2025-11-21T04:43:08Z
udproutes.gateway.networking.k8s.io                   2025-11-21T04:43:08Z
xbackendtrafficpolicies.gateway.networking.x-k8s.io   2025-11-21T04:43:08Z
xlistenersets.gateway.networking.x-k8s.io             2025-11-21T04:43:08Z
xmeshes.gateway.networking.x-k8s.io                   2025-11-21T04:43:07Z&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;configuration&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;envoy-gateway.yaml&lt;/p&gt;
&lt;h1&gt;Usages&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://gateway.envoyproxy.io/docs/tasks/security/restrict-ip-access/&quot;&gt;whitelist&lt;/a&gt;&lt;/p&gt;
&lt;pre class=&quot;stylus&quot;&gt;&lt;code&gt;$ curl -H &quot;Host: www.example.com&quot; xxx.xxx.xxx.xxx
RBAC: access denied&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;spec:
  authorization:
    defaultAction: Deny
    rules:
    - action: Allow
      principal:
        clientCIDRs:
        - 218.238.135.0/24
        - 4.194.122.0/24&lt;/code&gt;&lt;/pre&gt;</description>
      <category>Cloud/Kubernetes</category>
      <author>Jacob_baek</author>
      <guid isPermaLink="true">https://mr100do.tistory.com/427937</guid>
      <comments>https://mr100do.tistory.com/427937#entry427937comment</comments>
      <pubDate>Mon, 17 Nov 2025 14:36:18 +0900</pubDate>
    </item>
    <item>
      <title>AKS-MCP</title>
      <link>https://mr100do.tistory.com/427921</link>
      <description>&lt;h1&gt;What is AKS MCP&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;You can operate your AKS cluster using AI.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;There are 15 functions&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;583&quot; data-origin-height=&quot;306&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/xQjfv/btsPUdJDeg3/SF077BZlqEh0uKgltw4RTK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/xQjfv/btsPUdJDeg3/SF077BZlqEh0uKgltw4RTK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/xQjfv/btsPUdJDeg3/SF077BZlqEh0uKgltw4RTK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FxQjfv%2FbtsPUdJDeg3%2FSF077BZlqEh0uKgltw4RTK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;583&quot; height=&quot;306&quot; data-origin-width=&quot;583&quot; data-origin-height=&quot;306&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h1&gt;Prerequiste&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;VSCode&lt;/li&gt;
&lt;li&gt;MCP binary (&lt;a href=&quot;https://github.com/Azure/aks-mcp/releases&quot;&gt;https://github.com/Azure/aks-mcp/releases&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;I used aks-mcp binary on WSL.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;How to use&lt;/h1&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;vscode and github copilot&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;github copilot&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;336&quot; data-origin-height=&quot;175&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/LtZjm/btsPWd2QwDA/RHqadUJY6vAkn1NcLCLQHk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/LtZjm/btsPWd2QwDA/RHqadUJY6vAkn1NcLCLQHk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/LtZjm/btsPWd2QwDA/RHqadUJY6vAkn1NcLCLQHk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLtZjm%2FbtsPWd2QwDA%2FRHqadUJY6vAkn1NcLCLQHk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;336&quot; height=&quot;175&quot; data-origin-width=&quot;336&quot; data-origin-height=&quot;175&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;configure tools on github copilot&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;411&quot; data-origin-height=&quot;98&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JSTZi/btsPWoXqkah/sNCIfoQ44mlCM3dqOHaNbk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JSTZi/btsPWoXqkah/sNCIfoQ44mlCM3dqOHaNbk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JSTZi/btsPWoXqkah/sNCIfoQ44mlCM3dqOHaNbk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJSTZi%2FbtsPWoXqkah%2FsNCIfoQ44mlCM3dqOHaNbk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;411&quot; height=&quot;98&quot; data-origin-width=&quot;411&quot; data-origin-height=&quot;98&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;mcp.json file&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;798&quot; data-origin-height=&quot;344&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bxIptH/btsPUglOKbk/EkhXcPqTOuXTNJ9zN5xvz1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bxIptH/btsPUglOKbk/EkhXcPqTOuXTNJ9zN5xvz1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bxIptH/btsPUglOKbk/EkhXcPqTOuXTNJ9zN5xvz1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbxIptH%2FbtsPUglOKbk%2FEkhXcPqTOuXTNJ9zN5xvz1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;798&quot; height=&quot;344&quot; data-origin-width=&quot;798&quot; data-origin-height=&quot;344&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Test result&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;246&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bQmHOy/btsPXJfO0ds/qKYIK4SMOekGomcCPmCiY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bQmHOy/btsPXJfO0ds/qKYIK4SMOekGomcCPmCiY1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bQmHOy/btsPXJfO0ds/qKYIK4SMOekGomcCPmCiY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbQmHOy%2FbtsPXJfO0ds%2FqKYIK4SMOekGomcCPmCiY1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;603&quot; height=&quot;246&quot; data-origin-width=&quot;603&quot; data-origin-height=&quot;246&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;you should input your subscription.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;claude desktop&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;claude_desktop_config.json file.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;706&quot; data-origin-height=&quot;350&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/BZAxp/btsPXUuAfal/VdXfJxNpeAhk65bduyuHqk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/BZAxp/btsPXUuAfal/VdXfJxNpeAhk65bduyuHqk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/BZAxp/btsPXUuAfal/VdXfJxNpeAhk65bduyuHqk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FBZAxp%2FbtsPXUuAfal%2FVdXfJxNpeAhk65bduyuHqk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;706&quot; height=&quot;350&quot; data-origin-width=&quot;706&quot; data-origin-height=&quot;350&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;restart claude desktop and you can see below Local MCP servers&lt;br /&gt;(I recommend to Exit button on the menu)&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;784&quot; data-origin-height=&quot;717&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Hf14D/btsPXB9S4qP/SRfnxkidsk3uvV6xRtkouK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Hf14D/btsPXB9S4qP/SRfnxkidsk3uvV6xRtkouK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Hf14D/btsPXB9S4qP/SRfnxkidsk3uvV6xRtkouK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHf14D%2FbtsPXB9S4qP%2FSRfnxkidsk3uvV6xRtkouK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;784&quot; height=&quot;717&quot; data-origin-width=&quot;784&quot; data-origin-height=&quot;717&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Test result&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;527&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bmdsZ9/btsPXCAZKAR/Jsm5Q6dihZb7VkT26STKwK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bmdsZ9/btsPXCAZKAR/Jsm5Q6dihZb7VkT26STKwK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bmdsZ9/btsPXCAZKAR/Jsm5Q6dihZb7VkT26STKwK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbmdsZ9%2FbtsPXCAZKAR%2FJsm5Q6dihZb7VkT26STKwK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;755&quot; height=&quot;527&quot; data-origin-width=&quot;755&quot; data-origin-height=&quot;527&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;doesn't need subscription id.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h1&gt;References&lt;/h1&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/ko-kr/azure/developer/azure-mcp-server/tools/azure-aks&quot;&gt;https://learn.microsoft.com/ko-kr/azure/developer/azure-mcp-server/tools/azure-aks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://blog.aks.azure.com/2025/08/06/aks-mcp-server&quot;&gt;https://blog.aks.azure.com/2025/08/06/aks-mcp-server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://modelcontextprotocol.io/quickstart/user&quot;&gt;https://modelcontextprotocol.io/quickstart/user&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Cloud/Public Cloud</category>
      <category>aks-mcp</category>
      <author>Jacob_baek</author>
      <guid isPermaLink="true">https://mr100do.tistory.com/427921</guid>
      <comments>https://mr100do.tistory.com/427921#entry427921comment</comments>
      <pubDate>Mon, 18 Aug 2025 11:26:55 +0900</pubDate>
    </item>
    <item>
      <title>how to check ACR login user</title>
      <link>https://mr100do.tistory.com/427918</link>
      <description>&lt;p&gt;Refresh token을 사용하여 아래와 같은 JWT 형태의 token을 decode 해볼수 있다.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;JWT=$(az acr login -n &amp;lt;ACRName&amp;gt; -t --query refreshToken -o tsv)
jq -R &amp;#39;split(&amp;quot;.&amp;quot;) | .[0],.[1] | @base64d | fromjson&amp;#39; &amp;lt;&amp;lt;&amp;lt; $(echo &amp;quot;$JWT&amp;quot;)&lt;/code&gt;&lt;/pre&gt;&lt;h1&gt;References&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://prefetch.net/blog/2020/07/14/decoding-json-web-tokens-jwts-from-the-linux-command-line/&quot;&gt;https://prefetch.net/blog/2020/07/14/decoding-json-web-tokens-jwts-from-the-linux-command-line/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Cloud/Public Cloud</category>
      <category>ACR Login</category>
      <category>token decode</category>
      <author>Jacob_baek</author>
      <guid isPermaLink="true">https://mr100do.tistory.com/427918</guid>
      <comments>https://mr100do.tistory.com/427918#entry427918comment</comments>
      <pubDate>Mon, 4 Aug 2025 14:24:28 +0900</pubDate>
    </item>
    <item>
      <title>ingress-nginx</title>
      <link>https://mr100do.tistory.com/427917</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같은 에러가 발생되는 경우&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;Error from server (BadRequest): error when creating &quot;nginx-with-svc-ingress.yaml&quot;: admission webhook &quot;validate.nginx.ingress.kubernetes.io&quot; denied the request: annotation group ConfigurationSnippet contains risky annotation based on ingress configuration&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음과 같은 방식으로 ingress-nginx를 업데이트 해줘야 한다.&amp;nbsp;&lt;br /&gt;helm 으로 ingress-nginx 를 배포하는 경우 아래와 같은 annotations-risk-level 과 allowSnippetAnnotations 설정추가가 필요하다.&lt;/p&gt;
&lt;pre class=&quot;jboss-cli&quot;&gt;&lt;code&gt;helm upgrade --install ingress-nginx ingress-nginx \
 --repo [https://kubernetes.github.io/ingress-nginx](https://kubernetes.github.io/ingress-nginx) \
 --namespace ingress-nginx --create-namespace \
 --set controller.allowSnippetAnnotations=true \
 --set controller.config.annotations-risk-level=Critical \
 --set controller.image.tag=v1.10.1 \
 --set controller.service.annotations.&quot;service\\.beta\\.kubernetes\\.io/azure-load-balancer-health-probe-request-path&quot;=/healthz&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://ellie.wtf/notes/ingress-nginx-risky-annotations&quot;&gt;https://ellie.wtf/notes/ingress-nginx-risky-annotations&lt;/a&gt;&lt;/p&gt;</description>
      <category>Cloud/Kubernetes</category>
      <author>Jacob_baek</author>
      <guid isPermaLink="true">https://mr100do.tistory.com/427917</guid>
      <comments>https://mr100do.tistory.com/427917#entry427917comment</comments>
      <pubDate>Mon, 14 Jul 2025 11:09:52 +0900</pubDate>
    </item>
    <item>
      <title>Entra ID token</title>
      <link>https://mr100do.tistory.com/427907</link>
      <description>&lt;p&gt;Azure infra 상에서 동작되는 app에서 azure infra의 resource를 사용하거나 접근해야할 경우 token 기반으로 접근이 이루어지는 경우들이 있다. 해당 token은 Entra ID에서 발급받고 관리되어진다. 이와 같은 경우 token에 대한 이해가 없다면 동작방식을 이해하는데 어려움이 따를수 있다.&lt;/p&gt;
&lt;h1&gt;Tokens&lt;/h1&gt;
&lt;p&gt;제공되는 token의 종류는 총 3가지로 아래와 같다. &lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Access Token : Oauth2 용(즉, 허가용)&lt;/li&gt;
&lt;li&gt;Refresh Token : Access Token 재발급을 위한 token&lt;/li&gt;
&lt;li&gt;ID token : OIDC 용 (즉, 인증용)  &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/entra/identity-platform/security-tokens&quot;&gt;https://learn.microsoft.com/en-us/entra/identity-platform/security-tokens&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;Token configuration&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Access token lifecycle : 기본으로 60 ~ 90 min (&lt;a href=&quot;https://learn.microsoft.com/en-us/entra/identity-platform/access-tokens#token-lifetime&quot;&gt;https://learn.microsoft.com/en-us/entra/identity-platform/access-tokens#token-lifetime&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Refresh token lifecycle :&lt;ul&gt;
&lt;li&gt;사용할때마다 갱신 되며 최대는 90 days (&lt;a href=&quot;https://learn.microsoft.com/en-us/entra/identity-platform/configurable-token-lifetimes#refresh-and-session-token-lifetime-policy-properties&quot;&gt;https://learn.microsoft.com/en-us/entra/identity-platform/configurable-token-lifetimes#refresh-and-session-token-lifetime-policy-properties&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;access token을 1시간마다 재발급 받는 과정에서 refresh token도 새로 발급됨 : &lt;a href=&quot;https://learn.microsoft.com/en-us/entra/identity-platform/refresh-tokens#token-lifetime&quot;&gt;https://learn.microsoft.com/en-us/entra/identity-platform/refresh-tokens#token-lifetime&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;Refresh token expire time은 지정불가&lt;br&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/entra/identity-platform/refresh-tokens#token-timeouts&quot;&gt;https://learn.microsoft.com/en-us/entra/identity-platform/refresh-tokens#token-timeouts&lt;/a&gt;&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;default token revocation 기간&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/entra/identity-platform/refresh-tokens#token-revocation&quot;&gt;https://learn.microsoft.com/en-us/entra/identity-platform/refresh-tokens#token-revocation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;2021-01-30 이후로 default로만 제공되며 이전에는 refresh token 설정이 가능했다.&lt;br&gt;현재는 conditional access 정책으로 관리하도록 한다.&lt;br&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/entra/identity-platform/configurable-token-lifetimes#refresh-and-session-token-lifetime-policy-properties&quot;&gt;https://learn.microsoft.com/en-us/entra/identity-platform/configurable-token-lifetimes#refresh-and-session-token-lifetime-policy-properties&lt;/a&gt;&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;다음과 같은 conditional access 정책에 따라 인증을 해제할수 있다.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/entra/identity/conditional-access/howto-conditional-access-session-lifetime&quot;&gt;https://learn.microsoft.com/en-us/entra/identity/conditional-access/howto-conditional-access-session-lifetime&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;Refresh Token Expire&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;최대 수명 : 90일&lt;br&gt;(Refresh Token이 rotation을 계속 하더라도 90일 이후에는 재로그인이 필요)&lt;/li&gt;
&lt;li&gt;idle Timeout : 14일&lt;br&gt;(Refresh Token 사용 안하고 14일 지나면 expire)&lt;ul&gt;
&lt;li&gt;여기서 사용을 안한다는 의미는 cli나 sdk 등을 통한 인증과정이 한번이라도 포함된 명령 수행이 없는 경우를 의미해.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;&lt;p&gt;Refresh token이 만료되지 않은 경우 cli/sdk 등을 통한 인증과정을 같이 수행하는 명령이 수행되어지는 경우&lt;br&gt;Access Token이 만료되어 있다면 재발급이 이루어진다. 즉, CLI / SDK / Application 이 idle 상태로 인증을 수행하는 과정이 없는 경우라면 재발급이 발생되지 않는다.&lt;/p&gt;
&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;code&gt;Refresh tokens replace themselves with a fresh token upon every use&lt;/code&gt;&lt;br&gt;&lt;a href=&quot;https://learn.microsoft.com/en-us/entra/identity-platform/refresh-tokens#token-lifetime&quot;&gt;https://learn.microsoft.com/en-us/entra/identity-platform/refresh-tokens#token-lifetime&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;References&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.cswrld.com/2024/06/microsoft-entra-id-token-lifetime-and-revocation/&quot;&gt;https://www.cswrld.com/2024/06/microsoft-entra-id-token-lifetime-and-revocation/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <category>Cloud/Public Cloud</category>
      <category>Entra ID token</category>
      <author>Jacob_baek</author>
      <guid isPermaLink="true">https://mr100do.tistory.com/427907</guid>
      <comments>https://mr100do.tistory.com/427907#entry427907comment</comments>
      <pubDate>Wed, 26 Feb 2025 10:20:06 +0900</pubDate>
    </item>
    <item>
      <title>fluentbit with azure blob storage</title>
      <link>https://mr100do.tistory.com/427869</link>
      <description>&lt;h1&gt;installation&lt;/h1&gt;
&lt;p&gt;fluentbit install using helm chart&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ helm repo add fluent https://fluent.github.io/helm-charts
$ kubectl create ns logging
$ helm upgrade --install fluent-bit fluent/fluent-bit -n logging&lt;/code&gt;&lt;/pre&gt;&lt;h1&gt;create storage account and blob container&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;$ az storage account create -n fluentbitteststor -g fluentbittest-rg -l koreacentral --sku Standard_LRS&lt;/code&gt;&lt;/pre&gt;&lt;h1&gt;config for azure blob&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt;$ kubectl edit configmap fluent-bit -n logging
...
    [OUTPUT]
        name                  azure_blob
        match                 *
        account_name          fluentbitteststor
        shared_key            xxxxxxxxxxxxxxxxxxxxxxxxxxxxx==
        path                  k8slogs
        container_name        fluentbittest
        auto_create_container on
        tls                   on&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href=&quot;https://docs.fluentbit.io/manual/pipeline/outputs/azure_blob&quot;&gt;https://docs.fluentbit.io/manual/pipeline/outputs/azure_blob&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;full configmap&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;  custom_parsers.conf: |
    [PARSER]
        Name docker_no_time
        Format json
        Time_Keep Off
        Time_Key time
        Time_Format %Y-%m-%dT%H:%M:%S.%L
  fluent-bit.conf: |
    [SERVICE]
        Daemon Off
        Flush 1
        Log_Level info
        Parsers_File /fluent-bit/etc/parsers.conf
        Parsers_File /fluent-bit/etc/conf/custom_parsers.conf
        HTTP_Server On
        HTTP_Listen 0.0.0.0
        HTTP_Port 2020
        Health_Check On

    [INPUT]
        Name tail
        Path /var/log/containers/*.log
        multiline.parser docker, cri
        Tag kube.*
        Mem_Buf_Limit 5MB
        Skip_Long_Lines On

    [INPUT]
        Name systemd
        Tag host.*
        Systemd_Filter _SYSTEMD_UNIT=kubelet.service
        Read_From_Tail On

    [INPUT]
        Name tail
        Path /var/log/*.log
        Tag system.*

    [FILTER]
        Name kubernetes
        Match kube.*
        Merge_Log On
        Keep_Log Off
        K8S-Logging.Parser On
        K8S-Logging.Exclude On

    [OUTPUT]
        name                  azure_blob
        match                 *
        account_name          fluentbitteststor
        shared_key            xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx==
        path                  k8slogs
        container_name        fluentbittest
        auto_create_container on
        tls                   on&lt;/code&gt;&lt;/pre&gt;&lt;h1&gt;restart daemonset&lt;/h1&gt;
&lt;p&gt;After modifying the fluent-bit configmap, run rollout like below. &lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ kubectl rollout restart ds fluent-bit -n logging
daemonset.apps/fluent-bit restarted&lt;/code&gt;&lt;/pre&gt;&lt;h1&gt;storage browser&lt;/h1&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;680&quot; data-origin-height=&quot;676&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/SdlVl/btsJifd74UZ/GlNLqtorTWn0S8CQsYkK5k/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/SdlVl/btsJifd74UZ/GlNLqtorTWn0S8CQsYkK5k/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/SdlVl/btsJifd74UZ/GlNLqtorTWn0S8CQsYkK5k/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FSdlVl%2FbtsJifd74UZ%2FGlNLqtorTWn0S8CQsYkK5k%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;680&quot; height=&quot;676&quot; data-origin-width=&quot;680&quot; data-origin-height=&quot;676&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>Cloud/Kubernetes</category>
      <author>Jacob_baek</author>
      <guid isPermaLink="true">https://mr100do.tistory.com/427869</guid>
      <comments>https://mr100do.tistory.com/427869#entry427869comment</comments>
      <pubDate>Tue, 27 Aug 2024 13:32:00 +0900</pubDate>
    </item>
    <item>
      <title>kubernetes authentication with cURL using service account</title>
      <link>https://mr100do.tistory.com/1601</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;kubernetes service account를 사용하여 cURL로 kubernetes에 접근하는 방법을 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같은 yaml을 통해 SA(service account) role, rolebinding 그리고 secret을 생성한다.&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  namespace: default
  name: onlypods
rules:
- apiGroups: [&quot;&quot;]
  resources: [&quot;pods&quot;]
  verbs: [&quot;get&quot;, &quot;watch&quot;, &quot;list&quot;]
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: curltest
  namespace: default
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: onlyreadpods
  namespace: default
subjects:
- kind: ServiceAccount
  name:  curltest
roleRef:
  kind: Role
  name: onlypods
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: Secret
type: kubernetes.io/service-account-token
metadata:
  name: curltest-secret
  annotations:
    kubernetes.io/service-account.name: curltest&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;참고로 1.24 이후부터 service account를 생성하더라도 secret을 자동으로 만들지 않기에 직접 생성을 해주어야 한다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 kubectl 명령 수행이 가능한 환경이라면 가능하다면 아래와 같은 TOKEN과 ca.crt를 가져와 cURL을 통핸 pod 정보를 가져올수 있다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;#!/bin/bash

APISERVER=$(kubectl config view -o jsonpath='{.clusters[].cluster.server}')

TOKEN=$(kubectl get secret curltest-secret -o jsonpath='{.data.token}' | base64 -d)

kubectl get secret curltest-secret -o jsonpath='{.data.ca\.crt}' | base64 -d &amp;gt; test-ca.crt

curl -H &quot;Authorization: Bearer $TOKEN&quot; --cacert kube-ca.crt &quot;$APISERVER/api/v1/namespaces/default/pods&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 아래와 같은 결과가 출력된다.&lt;/p&gt;
&lt;pre class=&quot;jboss-cli&quot;&gt;&lt;code&gt;{
  &quot;kind&quot;: &quot;PodList&quot;,
  &quot;apiVersion&quot;: &quot;v1&quot;,
  &quot;metadata&quot;: {
  ...&lt;/code&gt;&lt;/pre&gt;
&lt;h1&gt;Reference&lt;/h1&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://stackoverflow.com/questions/55415867/curl-kubernetes-with-serivceaccount-token-it-always-returns-unauthorized&quot;&gt;https://stackoverflow.com/questions/55415867/curl-kubernetes-with-serivceaccount-token-it-always-returns-unauthorized&lt;/a&gt;&lt;/p&gt;</description>
      <category>Cloud/Cloud Native</category>
      <author>Jacob_baek</author>
      <guid isPermaLink="true">https://mr100do.tistory.com/1601</guid>
      <comments>https://mr100do.tistory.com/1601#entry1601comment</comments>
      <pubDate>Tue, 2 Apr 2024 16:44:55 +0900</pubDate>
    </item>
  </channel>
</rss>