<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>Cloud Engineer의 생존기</title>
    <link>https://floodnut.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Fri, 10 Apr 2026 06:02:52 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>Floodnut</managingEditor>
    <image>
      <title>Cloud Engineer의 생존기</title>
      <url>https://tistory1.daumcdn.net/tistory/4461647/attach/d002ac0321d548d5842675b1b7aee767</url>
      <link>https://floodnut.tistory.com</link>
    </image>
    <item>
      <title>[Kubernetes] Cluster API 맛만 보기</title>
      <link>https://floodnut.tistory.com/131</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;어쩌다가&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;진짜 이전에 스쳐 지나가면서 들었던 Cluster API가 갑자기 생각났다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그냥 그랬다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 그냥 진짜 개념만 맛만 보려고 공식 독스랑 훑어봤다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Cluster API는 무엇인가요?&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;image(1915).png&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;1211&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/mYqLp/btsK4tXfMcj/FSx4sjP1bgvk7ri2XcFXQK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/mYqLp/btsK4tXfMcj/FSx4sjP1bgvk7ri2XcFXQK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/mYqLp/btsK4tXfMcj/FSx4sjP1bgvk7ri2XcFXQK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FmYqLp%2FbtsK4tXfMcj%2FFSx4sjP1bgvk7ri2XcFXQK%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;1600&quot; height=&quot;1211&quot; data-filename=&quot;image(1915).png&quot; data-origin-width=&quot;1600&quot; data-origin-height=&quot;1211&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;오퍼레이터 패턴으로 Cluster를 설치하는 방식이라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;중앙에 관리 클러스터를 배치하고 해당 클러스터에 &lt;b&gt;Cluster API Controller&lt;/b&gt;를 배포한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 &lt;b&gt;Cluster API Controller&lt;/b&gt;는 추상 클래스와 유사한 역할을 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 왜? Cluster는 벤더 매니지드 클러스터 일 수도 있고, 직접 구축한 온프렘 클러스터일 수도 있고, 로컬 클러스터일 수도 있기 때문이다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt; 어떻게 쓰나요?&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;# EKS 예시
apiVersion: cluster.x-k8s.io/v1beta1
kind: Cluster
metadata:
 name: cluster-eks
spec:
 clusterNetwork:
 pods:
     cidrBlocks: [192.168.0.0/16]
 infrastructureRef:
     apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
     kind: AWSManagedCluster
     name: cluster-eks
 controlPlaneRef:
     apiVersion: controlplane.cluster.x-k8s.io/v1beta2
     kind: AWSManagedControlPlane
     name: cluster-eks&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;# Docker 클러스터 예시
kind: DockerCluster
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
metadata:
  name: my-cluster-docker
---
kind: Cluster
apiVersion: cluster.x-k8s.io/v1beta1
metadata:
  name: my-cluster
spec:
  infrastructureRef:
    kind: DockerCluster
    apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
    name: my-cluster-docker&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 EKS나 Docker 클러스터의 예시가 보인다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-10-23 오후 8.34.18.png&quot; data-origin-width=&quot;876&quot; data-origin-height=&quot;135&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/HI5IF/btsK4uPlFk0/AosfKpLT1ICXFuUzoQzaK1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/HI5IF/btsK4uPlFk0/AosfKpLT1ICXFuUzoQzaK1/img.png&quot; data-alt=&quot;지원하는 벤더들&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/HI5IF/btsK4uPlFk0/AosfKpLT1ICXFuUzoQzaK1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FHI5IF%2FbtsK4uPlFk0%2FAosfKpLT1ICXFuUzoQzaK1%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;876&quot; height=&quot;135&quot; data-filename=&quot;스크린샷 2024-10-23 오후 8.34.18.png&quot; data-origin-width=&quot;876&quot; data-origin-height=&quot;135&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;지원하는 벤더들&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 예시처럼, 여러 벤더를 대상으로 관리를 지원한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Docker 클러스터의 경우에는 Docker 프로바이더를 위한 환경변수를 주입하고, Management 클러스터와 Workload 클러스터를 세팅한다.&lt;/p&gt;
&lt;pre id=&quot;code_1733138950655&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;## Clustercli 설치
curl -L https://github.com/kubernetes-sigs/cluster-api/releases/download/v1.8.4/clusterctl-darwin-arm64 -o clusterctl
chmod +x ./clusterctl
sudo mv ./clusterctl /usr/local/bin/clusterctl
clusterctl version

## Management cluster 설치
export CLUSTER_TOPOLOGY=true
clusterctl init --infrastructure docker

## Workload cluster 설치
clusterctl generate cluster capi-quickstart --flavor development \
  --kubernetes-version v1.31.0 \
  --control-plane-machine-count=3 \
  --worker-machine-count=3 \
  &amp;gt; capi-quickstart.yaml
  
kubectl apply -f capi-quickstart.yaml

kubectl get cluster
# NAME              CLUSTERCLASS   PHASE     AGE   VERSION
# capi-quickstart   quick-start    Pending   15m   v1.31.0&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Cluster API가 관리하는 영역은 다음과 같은데, 흔히 우리가 서비스 레벨로 운영하던 쿠버네티스를 클러스터 단위로 라이프사이클을 관리하기 위한 선언적 API 다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;vm 정의를 위한 &lt;b&gt;Machine&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;컨트롤 플레인, 워커노드 구성-관리를 위한 &lt;b&gt;MachineSet&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;인프라 구성과 함께 MachineSet을 관리하기 위한 &lt;b&gt;MachineDeployment&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;Pod - ReplicaSet - Deployment 관계로 봐도 된다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구성요소를 살펴보면 아래와 같은 CRD들이 정의되어 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Bootstrap Provider
&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://cluster-api.sigs.k8s.io/developer/architecture/controllers/bootstrap&quot;&gt;Bootstrap&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ControlPlane Provider
&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://cluster-api.sigs.k8s.io/developer/architecture/controllers/control-plane&quot;&gt;ControlPlane&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Core
&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://cluster-api.sigs.k8s.io/developer/architecture/controllers/cluster&quot;&gt;Cluster&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cluster-api.sigs.k8s.io/developer/architecture/controllers/machine&quot;&gt;Machine&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cluster-api.sigs.k8s.io/developer/architecture/controllers/machine-set&quot;&gt;MachineSet&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cluster-api.sigs.k8s.io/developer/architecture/controllers/machine-deployment&quot;&gt;MachineDeployment&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cluster-api.sigs.k8s.io/developer/architecture/controllers/machine-health-check&quot;&gt;MachineHealthCheck&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://cluster-api.sigs.k8s.io/developer/architecture/controllers/machine-pool&quot;&gt;MachinePool&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;ClusterClass
&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://cluster-api.sigs.k8s.io/developer/architecture/controllers/cluster-topology&quot;&gt;Cluster Topology&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;AddOns
&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://cluster-api.sigs.k8s.io/developer/architecture/controllers/cluster-resource-set&quot;&gt;ClusterResourceSet&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1733138745403&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - crossplane-contrib/cross-capi-metal&quot; data-og-description=&quot;Contribute to crossplane-contrib/cross-capi-metal development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/crossplane-contrib/cross-capi-metal&quot; data-og-url=&quot;https://github.com/crossplane-contrib/cross-capi-metal&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/YCRpO/hyXGBOzgm6/TkhVk8XJF8Oc8scdX6bMD0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bMxeBT/hyXGLDHi9R/x7QqHJxl084jwSkpFhXI6K/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/crossplane-contrib/cross-capi-metal&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/crossplane-contrib/cross-capi-metal&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/YCRpO/hyXGBOzgm6/TkhVk8XJF8Oc8scdX6bMD0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/bMxeBT/hyXGLDHi9R/x7QqHJxl084jwSkpFhXI6K/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - crossplane-contrib/cross-capi-metal&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contribute to crossplane-contrib/cross-capi-metal development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또, 요렇게 크로스플레인이랑 통합되는 케이스가 있는 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Terraform 같은 IaC 대신 선언적으로 클러스터를 관리한다는 개념에서 유사하게 볼 수 있을 것 같은데, 여기까지는 아직 잘 모르겠다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;참고 자료&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;figure id=&quot;og_1733138997823&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Introduction - The Cluster API Book&quot; data-og-description=&quot;Cluster API is a Kubernetes sub-project focused on providing declarative APIs and tooling to simplify provisioning, upgrading, and operating multiple Kubernetes clusters. Started by the Kubernetes Special Interest Group (SIG) Cluster Lifecycle, the Cluster&quot; data-og-host=&quot;cluster-api.sigs.k8s.io&quot; data-og-source-url=&quot;https://cluster-api.sigs.k8s.io/&quot; data-og-url=&quot;https://cluster-api.sigs.k8s.io/&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://cluster-api.sigs.k8s.io/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://cluster-api.sigs.k8s.io/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Introduction - The Cluster API Book&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Cluster API is a Kubernetes sub-project focused on providing declarative APIs and tooling to simplify provisioning, upgrading, and operating multiple Kubernetes clusters. Started by the Kubernetes Special Interest Group (SIG) Cluster Lifecycle, the Cluster&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;cluster-api.sigs.k8s.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;figure id=&quot;og_1733138986384&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Controllers - The Cluster API Book&quot; data-og-description=&quot;Cluster API has a number of controllers, both in the core Cluster API and the reference providers, which move the state of the cluster toward some defined desired state through the process of controller reconciliation. Documentation for the CAPI controller&quot; data-og-host=&quot;cluster-api.sigs.k8s.io&quot; data-og-source-url=&quot;https://cluster-api.sigs.k8s.io/developer/architecture/controllers&quot; data-og-url=&quot;https://cluster-api.sigs.k8s.io/developer/architecture/controllers&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://cluster-api.sigs.k8s.io/developer/architecture/controllers&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://cluster-api.sigs.k8s.io/developer/architecture/controllers&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Controllers - The Cluster API Book&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Cluster API has a number of controllers, both in the core Cluster API and the reference providers, which move the state of the cluster toward some defined desired state through the process of controller reconciliation. Documentation for the CAPI controller&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;cluster-api.sigs.k8s.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DevOps, 클라우드/Container</category>
      <author>Floodnut</author>
      <guid isPermaLink="true">https://floodnut.tistory.com/131</guid>
      <comments>https://floodnut.tistory.com/131#entry131comment</comments>
      <pubDate>Mon, 2 Dec 2024 20:17:01 +0900</pubDate>
    </item>
    <item>
      <title>야, 너두 분산 추적 할 수 있어</title>
      <link>https://floodnut.tistory.com/130</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;개요&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내가 직접 구축하고 운영했던 모니터링 시스템이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;메트릭과 트레이스를 애플리케이션 단에서부터 직접 수집, 시각화하고 최적화나 대응까지 이어지는 하나의 라이프사이클이 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이 흐름을 정리한 적은 없었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 우선 분산 추적 시스템에 관해서만 가볍게 정리한다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;집계&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;OpenTelemetry&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-11-24 오후 8.50.23.png&quot; data-origin-width=&quot;1403&quot; data-origin-height=&quot;371&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/ckUIyK/btsKUyLa7DE/zLwscTrM0n6dSrKMLkMOu1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/ckUIyK/btsKUyLa7DE/zLwscTrM0n6dSrKMLkMOu1/img.png&quot; data-alt=&quot;OTel Collector의 집계 흐름&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/ckUIyK/btsKUyLa7DE/zLwscTrM0n6dSrKMLkMOu1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FckUIyK%2FbtsKUyLa7DE%2FzLwscTrM0n6dSrKMLkMOu1%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;1403&quot; height=&quot;371&quot; data-filename=&quot;스크린샷 2024-11-24 오후 8.50.23.png&quot; data-origin-width=&quot;1403&quot; data-origin-height=&quot;371&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;OTel Collector의 집계 흐름&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;OpenTelemetry(콜렉터)&lt;/b&gt;는 마이크로 서비스 환경에서 필요한 &lt;b&gt;분산 추적, 메트릭 및 로깅 정보 수집&lt;/b&gt;을 도와주는 &lt;b&gt;중계기 혹은 에이전트&lt;/b&gt;다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;수집된 애플리케이션 모니터링 데이터는 콜렉터를 통해서 Jaeger나 Prometheus와 같은 &lt;b&gt;저장소를 포함한 플랫폼&lt;/b&gt;으로 이동한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;OpenTelemetry(콜렉터)&lt;/b&gt;는 수집, 처리 및 전송 을 담당하고, 이에 대한 저장-쿼리는 &lt;b&gt;연결된 플랫폼&lt;/b&gt;에 위임한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;스팬 메트릭(Spanmetric)&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-11-24 오후 9.07.21.png&quot; data-origin-width=&quot;1408&quot; data-origin-height=&quot;230&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/9jTMU/btsKTUH2z9G/3U2PrGrmoIJtoyFpsn0QNk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/9jTMU/btsKTUH2z9G/3U2PrGrmoIJtoyFpsn0QNk/img.png&quot; data-alt=&quot;spanmetric 집계 파이프라인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/9jTMU/btsKTUH2z9G/3U2PrGrmoIJtoyFpsn0QNk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F9jTMU%2FbtsKTUH2z9G%2F3U2PrGrmoIJtoyFpsn0QNk%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;1408&quot; height=&quot;230&quot; data-filename=&quot;스크린샷 2024-11-24 오후 9.07.21.png&quot; data-origin-width=&quot;1408&quot; data-origin-height=&quot;230&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;spanmetric 집계 파이프라인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;추적 데이터의 경우, &lt;b&gt;트레이스와 스팬에 대한 처리 지연시간(Latency)&lt;/b&gt;이 함께 기록된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 지연시간은 시계열 데이터로 사용될 수 있는데, 이를 위한 파이프라인이 필요하다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;# example :: otel-collector config

connectors:
  spanmetrics:
    histogram:
      explicit:
        buckets: [5ms, 10ms, 15ms, 30ms, 50ms, 100ms, 300ms, 500ms, 1s]
    resource_metrics_cache_size: 1000 # default is 1000
    metrics_flush_interval : 10s # default is 15s
    namespace: default
    resource_metrics_key_attributes:
      - service.name
      - telemetry.sdk.language
      - telemetry.sdk.name
# ...

service:
  extensions: [pprof, zpages, health_check, sigv4auth]
  pipelines:
    metrics:
      receivers: [otlp, spanmetrics]
      processors: [batch]
      exporters: [otlphttp/prometheus]
    traces:
      receivers: [otlp]
      processors: [batch]
      exporters: [otlp, spanmetrics]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 OTel-collector 구성 예시를 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;service&lt;/b&gt; 필드에는 &lt;b&gt;metrics와 traces&lt;/b&gt; 파이프라인이 정의되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;traces 파이프라인&lt;/b&gt;을 통해 집계된 추적 데이터은 다시 &lt;b&gt;metrics 파이프라인의 receiver&lt;/b&gt;로 전달된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 스팬메트릭이 집계되는데, 이때 connectors가 동작을 하게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나 같은 경우는 실시간 레이턴시와 레이턴시 분포(중위값, P95 지표 등)를 보고자 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 위해서는 connectors에 스팬메트릭을 히스토그램으로 집계하고자 버킷을 정의했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기 정의된 버킷은 &lt;b&gt;LE(Lower or Equal than).&lt;/b&gt; 즉, 기준보다 작거나 같은 값을 모두 기록한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예를 들어, &lt;b&gt;4ms의 레이턴시를 가지는 트레이스는 5ms보다 큰 버킷에 모두&lt;/b&gt; 들어간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1s의 레이턴시를 가지는 트레이스는 +inf라는 디폴트 버킷&lt;/b&gt;에만 들어가게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 스팬메트릭을 처리-집계해서 분포를 볼 수 있게 된다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;추적 (Trace)&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Jaeger&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷_2024-11-18_오전_11.51.16.png&quot; data-origin-width=&quot;1552&quot; data-origin-height=&quot;1511&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bZuRq4/btsKTrlIRH8/3UtunnzLZOFFDadQ5qJqk1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bZuRq4/btsKTrlIRH8/3UtunnzLZOFFDadQ5qJqk1/img.png&quot; data-alt=&quot;Jaeger-ui&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bZuRq4/btsKTrlIRH8/3UtunnzLZOFFDadQ5qJqk1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbZuRq4%2FbtsKTrlIRH8%2F3UtunnzLZOFFDadQ5qJqk1%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;1552&quot; height=&quot;1511&quot; data-filename=&quot;스크린샷_2024-11-18_오전_11.51.16.png&quot; data-origin-width=&quot;1552&quot; data-origin-height=&quot;1511&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Jaeger-ui&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Jaeger는 오픈소스 분산 추적 도구로, 초기 구축에 사용했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실시간으로 집계되는 데이터를 저장하고 Jaeger-ui를 사용한다면 시각화된 트레이스-스팬과 서비스 현황을 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위에 &lt;b&gt;하늘색 큰 박스&lt;/b&gt;로 가린 것이 모두 &lt;b&gt;개별적인 트레이스&lt;/b&gt;다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1732454020147&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;documentation&quot; data-og-title=&quot;Deployment&quot; data-og-description=&quot;DeploymentSee also: The main Jaeger backend components are released as Docker images on Docker Hub: There are orchestration templates for running Jaeger with: Configuration Options Jaeger binaries can be configured in a number of ways (in the order of decr&quot; data-og-host=&quot;www.jaegertracing.io&quot; data-og-source-url=&quot;https://www.jaegertracing.io/docs/1.19/deployment/#storage-backends&quot; data-og-url=&quot;https://www.jaegertracing.io/docs/1.19/deployment/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bDg6rI/hyXDmqa91q/0djvTV38JxBaPIBga6UMg1/img.png?width=1801&amp;amp;height=587&amp;amp;face=0_0_1801_587&quot;&gt;&lt;a href=&quot;https://www.jaegertracing.io/docs/1.19/deployment/#storage-backends&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.jaegertracing.io/docs/1.19/deployment/#storage-backends&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bDg6rI/hyXDmqa91q/0djvTV38JxBaPIBga6UMg1/img.png?width=1801&amp;amp;height=587&amp;amp;face=0_0_1801_587');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Deployment&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;DeploymentSee also: The main Jaeger backend components are released as Docker images on Docker Hub: There are orchestration templates for running Jaeger with: Configuration Options Jaeger binaries can be configured in a number of ways (in the order of decr&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.jaegertracing.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Jaeger 같은 경우에는 스팬 스토리지로 메모리, badger와 같은 내장 저장소나 카산드라, 엘라스틱서치를 쓸 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또는, 카프라로 트레이스를 전파시켜서 저장시킬 수도 있다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Tempo와 로깅 통합&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;tempo_elasticsearch2 (1).png&quot; data-origin-width=&quot;1606&quot; data-origin-height=&quot;889&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/qUthK/btsKUH2bVJZ/rwjjOd3WrUylH844kBbMv1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/qUthK/btsKUH2bVJZ/rwjjOd3WrUylH844kBbMv1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/qUthK/btsKUH2bVJZ/rwjjOd3WrUylH844kBbMv1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FqUthK%2FbtsKUH2bVJZ%2FrwjjOd3WrUylH844kBbMv1%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;1606&quot; height=&quot;889&quot; data-filename=&quot;tempo_elasticsearch2 (1).png&quot; data-origin-width=&quot;1606&quot; data-origin-height=&quot;889&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;p data-ke-size=&quot;size16&quot;&gt;템포(Tempo) 역시는 Jaeger와 같은 &lt;b&gt;분산 트레이싱 도구&lt;/b&gt; 다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Grafana를 만든 Grafana-Labs에서 개발했으며, LGTM 스택이라고 불리는 모니터링 스택에서 &lt;b&gt;T&lt;/b&gt;에 해당한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Loki(로깅), Grafana(시각화), Tempo(분산추적), Mimir(메트릭)&lt;/b&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Jaeger와의 차이점을 살펴보면 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Tempo의 경우, &lt;b&gt;자체 UI가 존재하지 않고 Grafana와 통합&lt;/b&gt;되어 시각화를 제공한다.&lt;/li&gt;
&lt;li&gt;Jaeger는 KV 스토리지(Badger, 카산드라 ...) 나 ElasticSearch 등을 저장소로 사용하지만, Tempo는 버킷을 저장소로 사용한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Tempo는 &lt;b&gt;로깅 도구&lt;/b&gt;(ElasticSearch, OpenSearch, Loki 등)와 &lt;b&gt;분산 트레이싱 데이터를 연결&lt;/b&gt;할 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;&amp;ldquo;이 로그는 A 트레이싱 에서 생성된 로그야&amp;rdquo;&lt;/b&gt; 라는 것을 바로 인지할 수 있게 돕는 다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;이벤트 및 오류기록&lt;/b&gt;&lt;/h3&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;edited_스크린샷 2024-11-18 오후 12.04.27.png&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;387&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eqeLEo/btsKVSaDaUm/lPjEnrGnDC6lgNvW1yhwY1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eqeLEo/btsKVSaDaUm/lPjEnrGnDC6lgNvW1yhwY1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eqeLEo/btsKVSaDaUm/lPjEnrGnDC6lgNvW1yhwY1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeqeLEo%2FbtsKVSaDaUm%2FlPjEnrGnDC6lgNvW1yhwY1%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;787&quot; height=&quot;579&quot; data-filename=&quot;edited_스크린샷 2024-11-18 오후 12.04.27.png&quot; data-origin-width=&quot;1024&quot; data-origin-height=&quot;387&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;p data-ke-size=&quot;size16&quot;&gt;모든 데이터를 스팬으로 기록하면 좋겠지만, 스팬을 생성하고 추적 데이터에 연결하는 것 또한 비용이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 모니터링 수단에 애플리케이션이나 시스템에 과한 부하를 주는 것을 원치 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇기에, 스팬 자체를 기록하는 것보다 특정 상황에서 이를 &lt;b&gt;이벤트 로그로 기록&lt;/b&gt;하는 것을 고려해볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이에 대한 명확한 기준이 없다면, 스스로 기준을 잡아서 &lt;b&gt;이벤트 로그로 기록할지&lt;/b&gt; 혹은 &lt;b&gt;스팬으로 기록할지&lt;/b&gt;를 결정해 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래의 예시들은 스팬으로 기록할지, 이벤트 로그로 기록할지를 결정한 &lt;b&gt;완전 주관적인 기준&lt;/b&gt;이다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;비동기 혹은 메인 루프 밖에서 동작하는가? (별도 프로세스 혹은 스레드 등등)
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;멀티 스레딩&lt;/b&gt;의 경우, 분리된 스레드가 무거운 작업을 한다면 &lt;b&gt;스팬을 기록&lt;/b&gt;해 볼 수 있음.&lt;/li&gt;
&lt;li&gt;이외에 &lt;b&gt;가벼운 작업&lt;/b&gt;의 경우, &lt;b&gt;이벤트 로깅&lt;/b&gt;이 타당할 수 있음.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;이벤트 루프&lt;/b&gt;의 경우, 분리된 비동기 루프가 무거운 작업을 한다면 &lt;b&gt;스팬을 기록&lt;/b&gt;해 볼 수 있음.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;멀티 프로세싱&lt;/b&gt;의 경우, &lt;b&gt;스팬을 기록&lt;/b&gt;하는 것이 타당할 수 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;서비스가 분리되어 있는가?
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;분리된 서비스는 필연적으로 스팬을 전파하고 &lt;b&gt;새로운 자식 스팬을 기록-연결&lt;/b&gt;해야 추적 데이터에서 확인 가능함.&lt;/li&gt;
&lt;li&gt;여러 곳으로 &lt;b&gt;요청을 전파&lt;/b&gt;하는 시점인 경우, &lt;b&gt;스팬을 기록&lt;/b&gt;하는 것이 타당할 수 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-11-24 오후 9.43.07.png&quot; data-origin-width=&quot;988&quot; data-origin-height=&quot;468&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wrQKQ/btsKUItiRn4/yGGYmy0xwM0keckAACVuHK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wrQKQ/btsKUItiRn4/yGGYmy0xwM0keckAACVuHK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wrQKQ/btsKUItiRn4/yGGYmy0xwM0keckAACVuHK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwrQKQ%2FbtsKUItiRn4%2FyGGYmy0xwM0keckAACVuHK%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;988&quot; height=&quot;468&quot; data-filename=&quot;스크린샷 2024-11-24 오후 9.43.07.png&quot; data-origin-width=&quot;988&quot; data-origin-height=&quot;468&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;pre class=&quot;cs&quot;&gt;&lt;code&gt;async execute(
  params: any
  span?: Span,
) {

  // ...

  try {
    // ...
  } catch (e) {
    if (span) {
      span.recordException(e);
    }

    return [];
  }
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;단순한 Info 레벨의 이벤트 로그 외에도, 예외 처리 역시 스팬에 기록할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예외 처리를 스팬에 기록한다면, &lt;b&gt;오류가 발생한 요청 흐름을 트레이스 하나로 디버깅 할 수 있게 된다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Sentry와 같은 SaaS가 오류를 기록하고 알림을 발생시키는 흐름도 유사하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;트레이스 전파&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;Trace: API 요청 (Trace ID: ABCD)
└── Span 1: 프론트엔드 요청 전송 (Span ID: 1)
    └── Span 2: 백엔드 서비스 A 처리 (Span ID: 2)
        └── Span 3: 서비스 B 호출 (Span ID: 3)
            └── Span 4: 데이터베이스 쿼리 실행 (Span ID: 4)&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;시스템은 하나의 함수나 애플리케이션으로 동작하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여러 애플리케이션이 유기적으로 연결되고 각자의 역할을 수행하면서 하나의 시스템이자 서비스를 구축한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 이 시스템 내의 흐름을 확인하고 싶다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;단순하게 애플리케이션 하나에서 발생하는 이벤트가 아니라, 이 이벤트로부터 어떤 흐름이 발생하고 전파되는지 보고싶다.&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTTP나 gRPC와 같은 HTTP 기반의 프로토콜은 헤더를 가지고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 헤더에는 KV 형식으로 값을 넣을 수 있다. 우리는 이 곳에 부모의 스팬 ID 값을 기록한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;HTTP 헤더 / gRPC 메타데이터&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class=&quot;javascript&quot;&gt;&lt;code&gt;setTraceParent(span: Span, metadata: Metadata) {
  const traceContext = span.spanContext();
  const traceFlagsHex = traceContext.traceFlags.toString(16).padStart(2, '0');
  const traceparent = `00-${traceContext.traceId}-${traceContext.spanId}-${traceFlagsHex}`;
  metadata.set('traceparent', traceparent);
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;KV 형식에 담겨야 하는 것은 W3C Trace Context 표준의 &lt;b&gt;traceparent&lt;/b&gt; 헤더이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각 자리가 의미하는 것을 알아보면 다음 표와 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;{version}-{trace-id}-{span-id}-{trace-flags}&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;table data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style14&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;이름&lt;/td&gt;
&lt;td&gt;설명&lt;/td&gt;
&lt;td&gt;예시&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;version&lt;/td&gt;
&lt;td&gt;W3C Trace Context 표준의 버전&lt;/td&gt;
&lt;td&gt;00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;trace-id&lt;/td&gt;
&lt;td&gt;해당 트레이스 자체 ID&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;span-id&lt;/td&gt;
&lt;td&gt;해당 트레이스 내 현재 부모 Span의 ID (기록 당시의 Span id)&lt;/td&gt;
&lt;td&gt;&amp;nbsp;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;trace-flags&lt;/td&gt;
&lt;td&gt;해당 트레이스를 샘플링 할지 결정하는 플래그&lt;/td&gt;
&lt;td&gt;00(x), 01 (o)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 이렇게 &lt;b&gt;traceparent&lt;/b&gt;의 값을 구성하고, 헤더에 담아서 다음 서비스로 전파한다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Baggage&lt;/b&gt;&lt;/h3&gt;
&lt;figure id=&quot;og_1732453868177&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Baggage&quot; data-og-description=&quot;Contextual information that is passed between signals.&quot; data-og-host=&quot;opentelemetry.io&quot; data-og-source-url=&quot;https://opentelemetry.io/docs/concepts/signals/baggage/&quot; data-og-url=&quot;https://opentelemetry.io/docs/concepts/signals/baggage/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/dob9cR/hyXDfq26US/6tfUwSPK3u9a38DNduzsZ0/img.png?width=1910&amp;amp;height=1000&amp;amp;face=0_0_1910_1000,https://scrap.kakaocdn.net/dn/cFHAsx/hyXC8ladmj/3dGid8KFJ94oRMXdmtrAmk/img.png?width=1910&amp;amp;height=1000&amp;amp;face=0_0_1910_1000&quot;&gt;&lt;a href=&quot;https://opentelemetry.io/docs/concepts/signals/baggage/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://opentelemetry.io/docs/concepts/signals/baggage/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/dob9cR/hyXDfq26US/6tfUwSPK3u9a38DNduzsZ0/img.png?width=1910&amp;amp;height=1000&amp;amp;face=0_0_1910_1000,https://scrap.kakaocdn.net/dn/cFHAsx/hyXC8ladmj/3dGid8KFJ94oRMXdmtrAmk/img.png?width=1910&amp;amp;height=1000&amp;amp;face=0_0_1910_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Baggage&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contextual information that is passed between signals.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;opentelemetry.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;OpenTelemetry에서 Baggage는 컨텍스트 상에 함께 존재하는 정보이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Baggage는 KV 저장소이고 컨텍스트와 함께 원하는 데이터를 전파하도록 돕는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Baggage를 사용하면 데이터를 서비스와 프로세스 간에 전달할 수 있으며, 이 데이터는 해당 서비스에서 트레이스, 메트릭 또는 로그에 추가하여 사용할 수 있다.&lt;/p&gt;
&lt;table data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style14&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;특징&lt;/td&gt;
&lt;td&gt;Baggage&lt;/td&gt;
&lt;td&gt;Attributes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;목적&lt;/td&gt;
&lt;td&gt;요청의 &lt;b&gt;전역적인 컨텍스트&lt;/b&gt;를 공유 및 전파&lt;/td&gt;
&lt;td&gt;특정 스팬(Span)과 연관된 &lt;b&gt;추적 정보&lt;/b&gt;를 기록&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;전파 범위&lt;/td&gt;
&lt;td&gt;&lt;b&gt;서비스 간 전파&lt;/b&gt; (분산 컨텍스트와 함께 전달)&lt;/td&gt;
&lt;td&gt;&lt;b&gt;현재 스팬 내&lt;/b&gt;에서만 유효, 다른 스팬으로 전파되지 않음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;저장 위치&lt;/td&gt;
&lt;td&gt;분산 컨텍스트의 일부로 전역에 저장됨&lt;/td&gt;
&lt;td&gt;개별 스팬에 로컬로 저장됨&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;데이터 크기 제한&lt;/td&gt;
&lt;td&gt;네트워크 전파 시 제한 (예: 헤더 크기)&lt;/td&gt;
&lt;td&gt;제한 없음 (추적 데이터에 포함되므로 수집에만 영향을 줌)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;유즈케이스&lt;/td&gt;
&lt;td&gt;요청 전체의 흐름에서 &lt;b&gt;공유해야 하는 정보&lt;/b&gt;를 저장&lt;/td&gt;
&lt;td&gt;특정 스팬의 &lt;b&gt;속성&lt;/b&gt;이나 상세 정보를 기록&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;cs&quot;&gt;&lt;code&gt;const baggage = api.propagation.createBaggage({
  'tenant-id': { value: '12345' },
  'region': { value: 'ap-northeast-2' }
});
api.context.setBaggage(baggage);&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Baggage의 경우, 요청 흐름에서 계속 전파되는 KV 정보를 가진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;reasonml&quot;&gt;&lt;code&gt;span.setAttribute('http.method', 'POST');
span.setAttribute('db.statement', 'SELECT * FROM users');&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이와 반대로, Attribute는 단일 스팬에서만 기록되는 KV 정보를 가진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Sampling&lt;/b&gt;&lt;/h3&gt;
&lt;figure id=&quot;og_1732453904897&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;Sampling&quot; data-og-description=&quot;Learn about sampling and the different sampling options available in OpenTelemetry.&quot; data-og-host=&quot;opentelemetry.io&quot; data-og-source-url=&quot;https://opentelemetry.io/docs/concepts/sampling/&quot; data-og-url=&quot;https://opentelemetry.io/docs/concepts/sampling/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/UxX83/hyXzO9qap2/1urp9vOsf5kYkkdcFcyehK/img.png?width=1910&amp;amp;height=1000&amp;amp;face=0_0_1910_1000,https://scrap.kakaocdn.net/dn/DouDc/hyXDawuW2a/Q1ZRjtVMmmTFTrx7kBT5o1/img.png?width=1910&amp;amp;height=1000&amp;amp;face=0_0_1910_1000&quot;&gt;&lt;a href=&quot;https://opentelemetry.io/docs/concepts/sampling/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://opentelemetry.io/docs/concepts/sampling/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/UxX83/hyXzO9qap2/1urp9vOsf5kYkkdcFcyehK/img.png?width=1910&amp;amp;height=1000&amp;amp;face=0_0_1910_1000,https://scrap.kakaocdn.net/dn/DouDc/hyXDawuW2a/Q1ZRjtVMmmTFTrx7kBT5o1/img.png?width=1910&amp;amp;height=1000&amp;amp;face=0_0_1910_1000');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Sampling&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Learn about sampling and the different sampling options available in OpenTelemetry.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;opentelemetry.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;트레이싱은 분산 시스템 상에서 서비스 간의 요청 흐름을 관찰할 수 있도록 돕는 도구다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇지만, 대부분의 요청 흐름이 정상이라면 모든 트레이싱 데이터를 기록할 필요는 없고, &lt;b&gt;유효한 트레이싱만 기록하는 샘플링&lt;/b&gt;이 필요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;공식 문서에서는 샘플링을 고려하는 기준을 다음과 같이 잡고 있다.&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;blockquote data-ke-style=&quot;style3&quot;&gt;⚠️ 데이터 양이 적거나 사전에 집계할 수 있다면 샘플링하지 않는 것이 적합하다.&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc; color: #333333; text-align: start;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;초당 1000개 이상&lt;/b&gt;의 트레이스를 생성하는 경우
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;트레이스 데이터 양이 많아 처리 비용이 크게 증가할 때 샘플링이 유용하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;대부분의 트레이스 데이터가 정상적인 트래픽&lt;/b&gt;을 나타내며, 데이터에 큰 변화가 없는 경우
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;정상 트래픽에서 얻는 정보가 제한적일 때, 데이터 일부만 저장해도 충분할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;오류나 높은 지연 시간과 같은 문제가 있는 데이터를 기준으로 판단할 수 있는 경우
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;특정 조건(예: 오류, 높은 지연 시간)&lt;/b&gt;이 발생한 데이터를 우선적으로 수집할 때 샘플링을 적용할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;오류나 지연 시간 이외에도 특정 데이터를 판단할 수 있는 도메인별 기준이 있는 경우
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;도메인에 특화된 규칙(예: 비정상적인 사용자 행동)을 기반으로 샘플링 여부를 결정할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;데이터를 샘플링할지 버릴지 결정하는 공통적인 규칙을 설명할 수 있는 경우
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;예측 가능한 방식으로 데이터를 선별할 수 있다면 샘플링을 효율적으로 활용할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;b&gt;서비스별로 샘플링 비율&lt;/b&gt;을 다르게 적용할 수 있는 경우
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;트래픽이 많은 서비스와 적은 서비스에 서로 다른 샘플링 전략을 적용할 수 있다면 더욱 효과적이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;샘플링되지 않은 데이터를 저비용 스토리지 시스템으로 라우팅할 수 있는 경우
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;선택적으로 저장하지 않은 데이터를 저렴한 저장소로 전송해 나중에 필요할 때 사용할 수 있는 방법이 있다면 샘플링이 유용하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&amp;nbsp;&lt;/h4&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;Head Sampling vs Tail Sampling&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리는 &lt;b&gt;샘플링 여부&lt;/b&gt;를 &lt;b&gt;트레이스 생성-시작 시점&lt;/b&gt; 혹은 &lt;b&gt;종료 시점&lt;/b&gt;에 결정할 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;Head Sampling의 경우&lt;/b&gt;, 명확한 판단 이전에 샘플링이 적용되므로, &lt;b&gt;정확도가 떨어질 수 있으나 빠르고 가볍게 처리&lt;/b&gt;할 수 있다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Tail Sampling의 경우&lt;/b&gt;, 데이터를 일시적으로 저장하고 처리 완료 후 샘플링이 적용되므로, &lt;b&gt;추가 처리 시간이 필요하나 정확한 처리&lt;/b&gt;가 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이러한 샘플링 기준은 아래와 같이 적용할 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;OTel 콜렉터의 processor에서 tail-sampling을 적용하는 예시는 다음과 같다.&lt;/li&gt;
&lt;/ul&gt;
&lt;figure id=&quot;og_1732453988240&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;opentelemetry-collector-contrib/processor/tailsamplingprocessor at main &amp;middot; open-telemetry/opentelemetry-collector-contrib&quot; data-og-description=&quot;Contrib repository for the OpenTelemetry Collector - open-telemetry/opentelemetry-collector-contrib&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/tailsamplingprocessor&quot; data-og-url=&quot;https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/tailsamplingprocessor&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bfrlLl/hyXDcVqjxR/Oke3ZqMAkqFbDzFV5qlq5K/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/eIIeVg/hyXC8Mf5uC/ikakmc5o8GNkPRbXhwcsh0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/tailsamplingprocessor&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/open-telemetry/opentelemetry-collector-contrib/tree/main/processor/tailsamplingprocessor&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bfrlLl/hyXDcVqjxR/Oke3ZqMAkqFbDzFV5qlq5K/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/eIIeVg/hyXC8Mf5uC/ikakmc5o8GNkPRbXhwcsh0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;opentelemetry-collector-contrib/processor/tailsamplingprocessor at main &amp;middot; open-telemetry/opentelemetry-collector-contrib&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Contrib repository for the OpenTelemetry Collector - open-telemetry/opentelemetry-collector-contrib&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;processors:
  tail_sampling:
    policies:
      - name: error-policy # 특정 오류 상태를 가진 트레이스만 샘플링
        latency:
          threshold_ms: 500
      - name: endpoint-policy # 특정 endpoint의 트레이스만 샘플링
        attributes:
          include:
            - key: http.target
              value: &quot;/endpoint&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;traceparent&lt;/b&gt; 헤더에 존재하는 trace-flags 역시 샘플링에 영향을 미친다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이 값이 01인 경우, 샘플링을 수행한다.&lt;/li&gt;
&lt;li&gt;샘플링되지 않는 경우(00), 추적데이터에 기록되지 않는다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;끝으로&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Observability 스택과 분산 추적 시스템을 구축하고 운용하면서 생각했던 트레이스에 대한 기본적인 내용 만을 다뤘다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 실제 상용 환경에서는 더 고려할 것이 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요기서는 메트릭에 대한 것을 세부적으로 다루진 않았는데, 나중에 기회가 되면 다뤄보겠다.&lt;/p&gt;</description>
      <category>DevOps, 클라우드/Observability &amp;amp; Monitoring</category>
      <category>Jaeger</category>
      <category>Observability</category>
      <category>opentelemetry</category>
      <category>Prometheus</category>
      <category>모니터링</category>
      <category>오블완</category>
      <category>티스토리챌린지</category>
      <author>Floodnut</author>
      <guid isPermaLink="true">https://floodnut.tistory.com/130</guid>
      <comments>https://floodnut.tistory.com/130#entry130comment</comments>
      <pubDate>Sun, 24 Nov 2024 21:59:48 +0900</pubDate>
    </item>
    <item>
      <title>[컨테이너] 파드 네트워킹 살짝 열어보기</title>
      <link>https://floodnut.tistory.com/129</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;CNI에 이어서&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;figure id=&quot;og_1731741419860&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[컨테이너] 처음 열어보는 CNI 스펙&quot; data-og-description=&quot;CNI 유지성으로 사용하기지금까지 여러 도구를 사용하면서 공식 문서를 수 차례 참고하고 열어보았지만, CNI는 그렇게 진지하게 대했던 적은 없었던 것 같다.&amp;nbsp;Cilium에서 eBPF가 어쨌고, Calico에서 BG&quot; data-og-host=&quot;www.floodnut.com&quot; data-og-source-url=&quot;https://www.floodnut.com/127&quot; data-og-url=&quot;https://www.floodnut.com/127&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bAPTOE/hyXwkOazf9/qVhK0nkyhzpUMAkoK5Jzok/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512,https://scrap.kakaocdn.net/dn/CznaS/hyXzRDymxu/VKFGkVelBSCokBvTlijTd0/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512&quot;&gt;&lt;a href=&quot;https://www.floodnut.com/127&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.floodnut.com/127&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bAPTOE/hyXwkOazf9/qVhK0nkyhzpUMAkoK5Jzok/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512,https://scrap.kakaocdn.net/dn/CznaS/hyXzRDymxu/VKFGkVelBSCokBvTlijTd0/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[컨테이너] 처음 열어보는 CNI 스펙&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;CNI 유지성으로 사용하기지금까지 여러 도구를 사용하면서 공식 문서를 수 차례 참고하고 열어보았지만, CNI는 그렇게 진지하게 대했던 적은 없었던 것 같다.&amp;nbsp;Cilium에서 eBPF가 어쨌고, Calico에서 BG&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.floodnut.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지난 포스팅에서는 처음으로 CNI 스펙에 관련된 내용을 보면서, 어떤 인터페이스를 구현해야 하는지 확인했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에도 파드 네트워킹이나 네트워크 인터페이스 흐름이 어떻게 되는지 얕고 난잡하게 알아보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;파드 네트워크 구성&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;edited_스크린샷 2024-11-16 오후 4.24.12.png&quot; data-origin-width=&quot;1149&quot; data-origin-height=&quot;686&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dwk5Ru/btsKL44ooB4/cGoqPqcrsLl5iQ39KmA7gK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dwk5Ru/btsKL44ooB4/cGoqPqcrsLl5iQ39KmA7gK/img.png&quot; data-alt=&quot;파드 네트워크 생성 흐름&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dwk5Ru/btsKL44ooB4/cGoqPqcrsLl5iQ39KmA7gK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fdwk5Ru%2FbtsKL44ooB4%2FcGoqPqcrsLl5iQ39KmA7gK%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;1149&quot; height=&quot;686&quot; data-filename=&quot;edited_스크린샷 2024-11-16 오후 4.24.12.png&quot; data-origin-width=&quot;1149&quot; data-origin-height=&quot;686&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;파드 네트워크 생성 흐름&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파드 네트워크 생성 흐름을 살짝 확인해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Kubelet이 파드를 노드에 스케줄링하면, 파드에서 네트워크 설정을 요청한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면, Kubelet이 CNI를 통해서 파드의 네트워크를 설정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CNI는 내부에서 네임스페이스를 생성해 네트워크를 격리하고, IP와 네트워크 인터페이스를 할당한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 과정을 통해서 파드가 Kubelet-CNI를 통해 클러스터에 등록되고 통신한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 과정을 CRI 구현체에서 확인할 수 있는데, 이는 다음과 같다.&lt;/p&gt;
&lt;pre id=&quot;code_1731843357676&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;// containerd/internal/cri/server/sandbox_run.go

// setupPodNetwork setups up the network for a pod
func (c *criService) setupPodNetwork(ctx context.Context, sandbox *sandboxstore.Sandbox) error {
	var (
		id        = sandbox.ID
		config    = sandbox.Config
		path      = sandbox.NetNSPath
		netPlugin = c.getNetworkPlugin(sandbox.RuntimeHandler)
		err       error
		result    *cni.Result
	)
	if netPlugin == nil {
		return errors.New(&quot;cni config not initialized&quot;)
	}
	if c.config.UseInternalLoopback {
		err := c.bringUpLoopback(path)
		if err != nil {
			return fmt.Errorf(&quot;unable to set lo to up: %w&quot;, err)
		}
	}
	opts, err := cniNamespaceOpts(id, config) // &amp;lt;---------- 여기서 네트워크 네임스페이스 설정
	if err != nil {
		return fmt.Errorf(&quot;get cni namespace options: %w&quot;, err)
	}
	log.G(ctx).WithField(&quot;podsandboxid&quot;, id).Debugf(&quot;begin cni setup&quot;)
	netStart := time.Now()
	
	// 여기서 네트워크 플러그인에 셋업 요청
	if c.config.CniConfig.NetworkPluginSetupSerially {
		result, err = netPlugin.SetupSerially(ctx, id, path, opts...)
	} else {
		result, err = netPlugin.Setup(ctx, id, path, opts...)
	}
	networkPluginOperations.WithValues(networkSetUpOp).Inc()
	networkPluginOperationsLatency.WithValues(networkSetUpOp).UpdateSince(netStart)
	if err != nil {
		networkPluginOperationsErrors.WithValues(networkSetUpOp).Inc()
		return err
	}
	logDebugCNIResult(ctx, id, result)
	// Check if the default interface has IP config
	if configs, ok := result.Interfaces[defaultIfName]; ok &amp;amp;&amp;amp; len(configs.IPConfigs) &amp;gt; 0 {
		sandbox.IP, sandbox.AdditionalIPs = selectPodIPs(ctx, configs.IPConfigs, c.config.IPPreference)
		sandbox.CNIResult = result
		return nil
	}
	return fmt.Errorf(&quot;failed to find network info for sandbox %q&quot;, id)
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨테이너 런타임 중 하나인 containerd 내부 로직을 열어보면, &lt;b&gt;setupPodNetwork&lt;/b&gt;라는 함수가 존재하는 것을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 함수에서는 컨테이너 ID, 네트워크 네임스페이스와 네트워크 플러그인을 설정하는 로직을 확인할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre id=&quot;code_1731843538033&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;sudo crictl pods

# WARN[0000] runtime connect using default endpoints: [unix:///run/containerd/containerd.sock unix:///run/crio/crio.sock unix:///var/run/cri-dockerd.sock]. As the default settings are now deprecated, you should set the endpoint instead. 
POD ID              CREATED             STATE               NAME                                               NAMESPACE           ATTEMPT             RUNTIME
8ca5a045204a8       10 minutes ago      Ready               prometheus-grafana-5c7b44cc98-8685f                default             0                   (default)

# ...&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;edited_스크린샷 2024-09-25 오전 1.17.26.png&quot; data-origin-width=&quot;909&quot; data-origin-height=&quot;100&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bpKsyh/btsKMHnlWBh/aeeGhopHL1O7ALk8HuSdh0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bpKsyh/btsKMHnlWBh/aeeGhopHL1O7ALk8HuSdh0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bpKsyh/btsKMHnlWBh/aeeGhopHL1O7ALk8HuSdh0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbpKsyh%2FbtsKMHnlWBh%2FaeeGhopHL1O7ALk8HuSdh0%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;909&quot; height=&quot;100&quot; data-filename=&quot;edited_스크린샷 2024-09-25 오전 1.17.26.png&quot; data-origin-width=&quot;909&quot; data-origin-height=&quot;100&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;p data-ke-size=&quot;size16&quot;&gt;간단하게 확인해보면, &lt;b&gt;sandbox.ID&lt;/b&gt;는 POD ID로 설정된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 값은 CNI (calico)가 설정하는 &lt;b&gt;cni.projectcalico.org/containerID&lt;/b&gt; 와 동일한 것을 확인할 수 있다.&lt;/p&gt;
&lt;pre id=&quot;code_1731843710795&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;apiVersion: v1
kind: Pod
metadata:
  annotations:
    checksum/config: 0e9cbd0ea8e24e32f7dfca5bab17a2ba05652642f0a09a4882833ae88e4cc4a3
    checksum/sc-dashboard-provider-config: e70bf6a851099d385178a76de9757bb0bef8299da6d8443602590e44f05fdf24
    checksum/secret: 032056e9c62bbe9d1daa41ee49cd3d9524c076f51ca4c65adadf4ef08ef28712
    cni.projectcalico.org/containerID: 8ca5a045204a86919863f7f310cc80c9faca8b40249c806c01e25548585e7586
	// ...&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후 동작에서, 아래 함수의 결과로 네임스페이스를 설정 값을 가져오는 것을 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;opts,&amp;nbsp;err&amp;nbsp;:=&amp;nbsp;cniNamespaceOpts(id,&amp;nbsp;config)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이렇게 가져온 컨테이너 정보와 네트워크 설정값을 네트워크 플러그인에 전달하고, 파드에 네트워크를 할당한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CNI는 많은 것을 하지만, 파드 네트워크 설정만 확인하면 대략 이런 흐름으로 동작한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://tetrate.io/blog/kubernetes-networking/&quot; target=&quot;_blank&quot; rel=&quot;noopener&amp;nbsp;noreferrer&quot;&gt;https://tetrate.io/blog/kubernetes-networking/&lt;/a&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1731741704383&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;CNI Essentials: Kubernetes Networking under the Hood&quot; data-og-description=&quot;Effective management of networking is crucial in containerized environments. The Container Network Interface (CNI) is a standard that defines how containers should be networked. This article delves into the fundamentals of CNI and explores its relationship&quot; data-og-host=&quot;tetrate.io&quot; data-og-source-url=&quot;https://tetrate.io/blog/kubernetes-networking/&quot; data-og-url=&quot;https://tetrate.io/blog/kubernetes-networking/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bM3jSK/hyXzI7G66g/sszh7pa3jfkCKPg1N1t9g1/img.jpg?width=1024&amp;amp;height=576&amp;amp;face=0_0_1024_576,https://scrap.kakaocdn.net/dn/dn8IfU/hyXzVsp5T4/gyEPZkOw6DQUcARBnXpnd1/img.png?width=1024&amp;amp;height=683&amp;amp;face=0_0_1024_683,https://scrap.kakaocdn.net/dn/qxSKX/hyXwt5pfLF/cVfI4aLhbRyTklijY101i1/img.png?width=1024&amp;amp;height=604&amp;amp;face=0_0_1024_604&quot;&gt;&lt;a href=&quot;https://tetrate.io/blog/kubernetes-networking/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://tetrate.io/blog/kubernetes-networking/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bM3jSK/hyXzI7G66g/sszh7pa3jfkCKPg1N1t9g1/img.jpg?width=1024&amp;amp;height=576&amp;amp;face=0_0_1024_576,https://scrap.kakaocdn.net/dn/dn8IfU/hyXzVsp5T4/gyEPZkOw6DQUcARBnXpnd1/img.png?width=1024&amp;amp;height=683&amp;amp;face=0_0_1024_683,https://scrap.kakaocdn.net/dn/qxSKX/hyXwt5pfLF/cVfI4aLhbRyTklijY101i1/img.png?width=1024&amp;amp;height=604&amp;amp;face=0_0_1024_604');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;CNI Essentials: Kubernetes Networking under the Hood&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Effective management of networking is crucial in containerized environments. The Container Network Interface (CNI) is a standard that defines how containers should be networked. This article delves into the fundamentals of CNI and explores its relationship&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;tetrate.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>DevOps, 클라우드/Container</category>
      <category>iptable</category>
      <category>네트워크</category>
      <category>오블완</category>
      <category>쿠버네티스</category>
      <category>티스토리챌린지</category>
      <author>Floodnut</author>
      <guid isPermaLink="true">https://floodnut.tistory.com/129</guid>
      <comments>https://floodnut.tistory.com/129#entry129comment</comments>
      <pubDate>Sun, 17 Nov 2024 20:47:01 +0900</pubDate>
    </item>
    <item>
      <title>[컨테이너] 처음 열어보는 CNI 스펙</title>
      <link>https://floodnut.tistory.com/127</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;CNI 유지성으로 사용하기&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;지금까지 여러 도구를 사용하면서 공식 문서를 수 차례 참고하고 열어보았지만, CNI는 그렇게 진지하게 대했던 적은 없었던 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Cilium에서 eBPF가 어쨌고, Calico에서 BGP, Bird, Felix 어쨌고, 또 AWS VPC CNI는 또 어떻고...&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 제반사항들을 그저 이론으로만 접하고 있었다고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 이런 이론조차도 작은 트러블 슈팅에는 도움이 되었지만, 그래도 앞으로는 CNI를 좀 더 유지성하게 써보기 위해서 '조금만 더' 다이브 해보려고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;CNI 스펙&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CNI를 준수하는 컨테이너 오케스트레이션은 꼭 쿠버네티스만 있는 것은 아니다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS ECS, Apache Mesos도 역시 CNI를 준수하고, Containerd나 CRI-O와 같은 런타임 역시 CNI와 함께 동작할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 컨테이너 관리를 위한 CNI 구현체들은 많다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Calico, Cilium이나 AWS VPC CNI도 있을 것이고 AWS ECS CNI와 Azure Container Networking 등 수 많은 구현체가 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;각각이 추구하는 방향이나 구현 방식은 다르더라고 &lt;b&gt;CNI&lt;/b&gt; 라는 인터페이스를 준수할 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니 이 스펙을 먼저 확인해 볼 필요가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CNI Docs를 읽어보면서 어떤 요구사항들이 있는지 확인해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1731135115049&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;cni/SPEC.md at main &amp;middot; containernetworking/cni&quot; data-og-description=&quot;Container Network Interface - networking for Linux containers - containernetworking/cni&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/containernetworking/CNI/blob/main/SPEC.md&quot; data-og-url=&quot;https://github.com/containernetworking/cni/blob/main/SPEC.md&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/catKBI/hyXwldB34k/tgCGAFGkk7mE5GuARIhJ1k/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/but2sJ/hyXs0Cbk0h/6OuTBlzKqKB88kmkNY2sJK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/containernetworking/CNI/blob/main/SPEC.md&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/containernetworking/CNI/blob/main/SPEC.md&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/catKBI/hyXwldB34k/tgCGAFGkk7mE5GuARIhJ1k/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/but2sJ/hyXs0Cbk0h/6OuTBlzKqKB88kmkNY2sJK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;cni/SPEC.md at main &amp;middot; containernetworking/cni&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Container Network Interface - networking for Linux containers - containernetworking/cni&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CNI 스펙이 결정하는 요소는 다음과 같다.&lt;/b&gt;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;관리자가 &lt;b&gt;네트워크 구성을 정의&lt;/b&gt;하기 위한 포맷.&lt;/li&gt;
&lt;li&gt;컨테이너 런타임이 &lt;b&gt;네트워크 플러그인에 요청&lt;/b&gt;을 보내기 위한 프로토콜.&lt;/li&gt;
&lt;li&gt;제공된 구성을 기반으로 &lt;b&gt;플러그인을 실행&lt;/b&gt;하는 절차.&lt;/li&gt;
&lt;li&gt;플러그인이 다른 플러그인에 &lt;b&gt;기능을 위임&lt;/b&gt;하는 절차.&lt;/li&gt;
&lt;li&gt;플러그인이 런타임에 &lt;b&gt;결과를 반환&lt;/b&gt;하기 위한 데이터 포맷.&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이걸 요약하면 결국 다음과 같다.&lt;/p&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;div data-message-model-slug=&quot;gpt-4o&quot; data-message-id=&quot;b06e4e53-15d5-4929-b5a8-c2bbbd7eb4c9&quot; data-message-author-role=&quot;assistant&quot;&gt;
&lt;div&gt;
&lt;div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&quot;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;관리자가 정의한 &lt;b&gt;네트워크 구성&lt;/b&gt;을 통해서 컨테이너 런타임이 네트워크 플러그인과 통신하는 &lt;b&gt;프로토콜과 응답 규격&lt;/b&gt;을 결정한다.&lt;/span&gt;&lt;b&gt;&lt;span style=&quot;font-family: AppleSDGothicNeo-Regular, 'Malgun Gothic', '맑은 고딕', dotum, 돋움, sans-serif;&quot;&gt;&quot;&lt;/span&gt;&lt;/b&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;네트워크 구성&lt;/b&gt;&lt;/h4&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1731134957320&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;{
  &quot;cniVersion&quot;: &quot;1.1.0&quot;,
  &quot;cniVersions&quot;: [&quot;0.3.1&quot;, &quot;0.4.0&quot;, &quot;1.0.0&quot;, &quot;1.1.0&quot;],
  &quot;name&quot;: &quot;dbnet&quot;,
  &quot;plugins&quot;: [
    {
      &quot;type&quot;: &quot;bridge&quot;,
      // plugin specific parameters
      &quot;bridge&quot;: &quot;cni0&quot;,
      &quot;keyA&quot;: [&quot;some more&quot;, &quot;plugin specific&quot;, &quot;configuration&quot;],

      &quot;ipam&quot;: {
        &quot;type&quot;: &quot;host-local&quot;,
        // ipam specific
        &quot;subnet&quot;: &quot;10.1.0.0/16&quot;,
        &quot;gateway&quot;: &quot;10.1.0.1&quot;,
        &quot;routes&quot;: [
            {&quot;dst&quot;: &quot;0.0.0.0/0&quot;}
        ]
      },
      &quot;dns&quot;: {
        &quot;nameservers&quot;: [ &quot;10.1.0.1&quot; ]
      }
    },
    {
      &quot;type&quot;: &quot;tuning&quot;,
      &quot;capabilities&quot;: {
        &quot;mac&quot;: true
      },
      &quot;sysctl&quot;: {
        &quot;net.core.somaxconn&quot;: &quot;500&quot;
      }
    },
    {
        &quot;type&quot;: &quot;portmap&quot;,
        &quot;capabilities&quot;: {&quot;portMappings&quot;: true}
    }
  ]
}&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 134px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style14&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 14px;&quot;&gt;
&lt;td style=&quot;width: 21.938%; height: 14px;&quot;&gt;속성 명&lt;/td&gt;
&lt;td style=&quot;width: 10.1937%; height: 14px;&quot;&gt;속성 타입&lt;/td&gt;
&lt;td style=&quot;width: 67.8682%; height: 14px;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 12px;&quot;&gt;
&lt;td style=&quot;width: 21.938%; height: 12px;&quot;&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;cniVersion&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10.1937%; height: 12px;&quot;&gt;string&lt;/td&gt;
&lt;td style=&quot;width: 67.8682%; height: 12px;&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이 구성 목록과 모든 개별 구성이 준수하는 CNI 스펙의&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #0070d1;&quot; href=&quot;https://semver.org/&quot;&gt;Semantic Version 2.0&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;현재 버전은 1.1.0&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 21.938%; height: 18px;&quot;&gt;&lt;span style=&quot;color: #333333; text-align: left;&quot;&gt;cniVersions&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;/td&gt;
&lt;td style=&quot;width: 10.1937%; height: 18px;&quot;&gt;string list&lt;/td&gt;
&lt;td style=&quot;width: 67.8682%; height: 18px;&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;이 구성이 지원하는 모든 CNI 버전의 목록.&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 21.938%; height: 18px;&quot;&gt;name&lt;/td&gt;
&lt;td style=&quot;width: 10.1937%; height: 18px;&quot;&gt;string&lt;/td&gt;
&lt;td style=&quot;width: 67.8682%; height: 18px;&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;네트워크 이름.&lt;/li&gt;
&lt;li&gt;호스트(또는 다른 관리 도메인)의 모든 네트워크 구성에서 고유해야 함.&lt;/li&gt;
&lt;li&gt;영문-숫자로 시작해야 하며, 특수문자는 언더바(), 마침표(.), 하이픈(-)을 쓸 수 있다.&lt;/li&gt;
&lt;li&gt;파일 경로에서 허용되지 않는 문자를 포함해서는 안 됨.&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 21.938%; height: 18px;&quot;&gt;disableCheck&lt;/td&gt;
&lt;td style=&quot;width: 10.1937%; height: 18px;&quot;&gt;boolean&lt;/td&gt;
&lt;td style=&quot;width: 67.8682%; height: 18px;&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;disableCheck가 true이면, 런타임은 이 네트워크 구성 목록에 대해 CHECK를 호출해서는 안 됨.&lt;/li&gt;
&lt;li&gt;이를 통해 관리자는 플러그인 조합이 잘못된 오류를 반환하는 것으로 알려진 경우 CHECK를 방지할 수 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 21.938%; height: 18px;&quot;&gt;disableGC&lt;/td&gt;
&lt;td style=&quot;width: 10.1937%; height: 18px;&quot;&gt;boolean&lt;/td&gt;
&lt;td style=&quot;width: 67.8682%; height: 18px;&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;disableGC가 true이면, 런타임은 이 네트워크 구성 목록에 대해 GC를 호출해서는 안 됨.&lt;/li&gt;
&lt;li&gt;이를 통해 관리자는 가비지 컬렉션이 원치 않는 영향을 미칠 수 있다고 알려진 경우
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;(예: 여러 런타임 간 공유 구성) GC를 방지할 수 있음.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 21.938%; height: 18px;&quot;&gt;loadOnlyInlinedPlugins&lt;/td&gt;
&lt;td style=&quot;width: 10.1937%; height: 18px;&quot;&gt;boolean&lt;/td&gt;
&lt;td style=&quot;width: 67.8682%; height: 18px;&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: none;&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;false(기본값)인 경우,&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;a style=&quot;color: #0070d1;&quot; href=&quot;https://github.com/containernetworking/cni/blob/main/SPEC.md#plugin-configuration-objects&quot;&gt;플러그인 구성 객체&lt;/a&gt;를 여러 소스에서 집계할 수 있음을 나타냄.&lt;/li&gt;
&lt;li&gt;다른 소스에서 집계된 유효한 플러그인 구성 객체는 해당 네트워크 이름의 최종 plugins 목록에 추가되어야 함.&lt;/li&gt;
&lt;li&gt;true로 설정된 경우, 주 네트워크 구성 이외의 소스에서 집계된 유효한 플러그인 구성 객체는 무시됨을 나타냄.&lt;/li&gt;
&lt;li&gt;네트워크 구성에 plugins가 없는 경우, loadOnlyInlinedPlugins를 true로 설정할 수 없음.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 18px;&quot;&gt;
&lt;td style=&quot;width: 21.938%; height: 18px;&quot;&gt;plugins&lt;/td&gt;
&lt;td style=&quot;width: 10.1937%; height: 18px;&quot;&gt;list&lt;/td&gt;
&lt;td style=&quot;width: 67.8682%; height: 18px;&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;a style=&quot;background-color: #e6f5ff; color: #0070d1;&quot; href=&quot;https://github.com/containernetworking/cni/blob/main/SPEC.md#plugin-configuration-objects&quot;&gt;플러그인 구성 객체&lt;/a&gt;의 목록.&lt;/li&gt;
&lt;li&gt;이 키가 인라인 플러그인 객체로 채워지고 loadOnlyInlinedPlugins가 true인 경우, 네트워크의 최종 플러그인 세트는 이 목록의 모든 플러그인 객체와 네트워크와 같은 이름의 형제 폴더에서 로드된 모든 플러그인을 병합한 것으로 구성되어야 함.&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 예시처럼 CNI 스펙은 표와 같은 속성을 네트워크 구성에서 정의한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 구현에 영향을 주는 만큼, 어떤 버전을 사용하는지나 어떤 동작이나 케이스를 지원해야 하는지 명시되어 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히, GC와 플러그인이 눈에 띈다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가비지 컬렉터가 CNI 상에서 사용된다고 생각하지 못했는데, 이 스펙을 보면서 알게 되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또, 플러그인을 지원하는 것을 볼 수 있는데, 이는 결국 CNI 구현체 단독으로 모든 동작을 하는게 아니라 플러그인에 별도의 동작을 위임하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;프로토콜&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CNI 프로토콜은 컨테이너 런타임이 바이너리를 실행하는 방식으로 동작한다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;CNI는 플러그인 바이너리와 런타임 사이의 프로토콜을 정의하며, 컨테이너의 네트워크 인터페이스를 구성하는 책임을 수행한다.&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;플러그인은 크게 두 가지 범주로 나뉘는데, 다음과 같은 플러그인이 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;인터페이스 플러그인&lt;/b&gt;: 컨테이너 내부에 네트워크 인터페이스를 생성하고 이를 통해 네트워크 연결이 가능하도록 보장한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;체인 플러그인&lt;/b&gt;: 이미 생성된 인터페이스의 구성을 조정하며, 필요한 경우 더 많은 인터페이스를 추가로 생성할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;런타임은 플러그인에 파라미터와 구성을 전달하는데, 파라미터는 환경 변수로, 구성은 표준 입력(stdin)을 통해 전달된다. 플러그인은 성공 시 표준 출력(stdout)으로 결과를 반환하고, 실패 시 표준 오류(stderr)로 에러를 반환한다. 그 구성 값과 결과는 JSON 형식으로 인코딩된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파라미터는 호출에 따라 달라지는 설정을 정의하며, 구성은 특별한 경우를 제외하고는 네트워크에 대해 일정하게 유지된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;런타임은 런타임의 네트워킹 도메인에서 플러그인을 실행해야 한다. (대부분의 경우, 이는 루트 네임스페이스 또는 dom0를 의미한다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로토콜의 파라미터는 OS의 환경 변수를 통해 플러그인에 전달되는데, 그 요소들을 살펴보면 다음과 같은 것들이 있다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%; height: 847px;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style14&quot;&gt;
&lt;tbody&gt;
&lt;tr style=&quot;height: 20px;&quot;&gt;
&lt;td style=&quot;width: 20.5814%; height: 20px;&quot;&gt;환경 변수&lt;/td&gt;
&lt;td style=&quot;width: 79.4186%; height: 20px;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 120px;&quot;&gt;
&lt;td style=&quot;width: 20.5814%; height: 120px;&quot;&gt;CNI_COMMAND&lt;/td&gt;
&lt;td style=&quot;width: 79.4186%; height: 120px;&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CNI 동작 명령어&lt;/li&gt;
&lt;li&gt;1.0.0를 기준으로, 다음 5개의 동작을 구현한다.&lt;/li&gt;
&lt;li&gt;ADD, DEL, CHECK, GC, VERSION&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 171px;&quot;&gt;
&lt;td style=&quot;width: 20.5814%; height: 171px;&quot;&gt;CNI_CONTAINERID&lt;/td&gt;
&lt;td style=&quot;width: 79.4186%; height: 171px;&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;컨테이너 ID.&lt;/li&gt;
&lt;li&gt;런타임에 의해 할당된 컨테이너의 고유한 일반 텍스트 식별자이며 비어 있어서는 안 된다.&lt;/li&gt;
&lt;li&gt;영문-숫자로 시작해야 하며, 특수문자는 언더바(), 마침표(.), 하이픈(-)을 쓸 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 157px;&quot;&gt;
&lt;td style=&quot;width: 20.5814%; height: 157px;&quot;&gt;CNI_NETNS&lt;/td&gt;
&lt;td style=&quot;width: 79.4186%; height: 157px;&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;컨테이너의 &quot;격리 도메인&quot;에 대한 레퍼런스.&lt;/li&gt;
&lt;li&gt;네트워크 네임스페이스를 사용하는 경우, 네트워크 네임스페이스에 대한 경로로 사용
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;e.g. /run/netns/[nsname]&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 117px;&quot;&gt;
&lt;td style=&quot;width: 20.5814%; height: 117px;&quot;&gt;CNI_IFNAME&lt;/td&gt;
&lt;td style=&quot;width: 79.4186%; height: 117px;&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;컨테이너 내부에 생성할 인터페이스의 이름.&lt;/li&gt;
&lt;li&gt;플러그인이 이 인터페이스 이름을 사용할 수 없는 경우 오류를 반환해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 131px;&quot;&gt;
&lt;td style=&quot;width: 20.5814%; height: 131px;&quot;&gt;CNI_ARGS&lt;/td&gt;
&lt;td style=&quot;width: 79.4186%; height: 131px;&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;호출 시 사용자가 전달한 추가 인자.&lt;/li&gt;
&lt;li&gt;세미콜론으로 구분된 영숫자 key-value 쌍
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;e.g. &quot;FOO=BAR;ABC=123&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style=&quot;height: 131px;&quot;&gt;
&lt;td style=&quot;width: 20.5814%; height: 131px;&quot;&gt;CNI_PATH&lt;/td&gt;
&lt;td style=&quot;width: 79.4186%; height: 131px;&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;CNI 플러그인 실행 파일을 검색할 경로 목록&lt;/li&gt;
&lt;li&gt;경로는 OS별 목록 구분자로 구분
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;e.g. Linux는 :, Windows는 ;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 두 가지를 조금 더 확인해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선, &lt;b&gt;CNI_COMMAND&lt;/b&gt; 라는 파라미터가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요것은 말 그대로 CNI 상에 정의된 동작을 의미한다. ADD, DEL, CHECK, GC, VERSION와 같은 동작이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;b&gt;CNI_NETNS, &lt;/b&gt;CNI_CONTAINERID,&amp;nbsp; CNI_IFNAME&lt;/b&gt;는 함께 사용되며 컨테이너 별로 고유한 네트워크 정보를 부여하기 위해 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;CNI 동작을 보면서 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;ADD&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;네트워크 네임스페이스(CNI_NETNS)에 존재하는 컨테이너 내부에 네트워크 인터페이스(CNI_IFNAME)를 생성 혹은 수정&lt;/li&gt;
&lt;li&gt;플러그인을 위한 입력이 이전 결과(prevResult)을 포함하는 경우, 이에 대한 핸들링을 해야 한다.&lt;/li&gt;
&lt;li&gt;컨테이너에 이미 존재하는 name을 전달받은 경우, 에러 처리&lt;/li&gt;
&lt;li&gt;동일한 (CNI_CONTAINERID, CNI_IFNAME) 쌍에 대해서 &lt;b&gt;DEL(삭제)&lt;/b&gt; 없이 ADD를 2번 호출하면 안된다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;다른 인터페이스에 대해서만 컨테이너 id를 2번 이상 추가할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;DEL&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;네트워크 네임스페이스(CNI_NETNS)에 존재하는 컨테이너 내부에 네트워크 인터페이스(CNI_IFNAME)를 삭제 혹은 ADD 동작을 취소&lt;/li&gt;
&lt;li&gt;특정 리소스가 누락되어도 &lt;b&gt;DEL&lt;/b&gt; 작업을 완료할 수 있어야 한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;IPAM 플러그인 &amp;rarr; 컨테이너의 네트워크 네임스페이스가 누락되어도 IP 할당을 해제하고 성공 상태를 반환해야 한다. (IPAM이 필수가 아니라면)&lt;/li&gt;
&lt;li&gt;DHCP &amp;rarr; 컨테이너 네트워크 인터페이스에서 일반적으로 'release' 메시지를 전송하며, 작업 실패 시 에러를 반환하지 않아야 한다.&lt;/li&gt;
&lt;li&gt;브리지 플러그인 &amp;rarr; &lt;b&gt;DEL&lt;/b&gt; 작업을 IPAM 플러그인에 위임하고, 컨테이너 네트워크 네임스페이스나 네트워크 인터페이스가 누락되어도 리소스를 정리해야 한다.&lt;/li&gt;
&lt;li&gt;인터페이스나 수정 사항이 없어도 성공 상태를 반환해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CHECK&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;존재하는 컨테이너의 상태를 런타임에 확인한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;Version&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;json으로 직렬화된 버전&lt;/b&gt; 결과 객체를 표준 출력으로 반환한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;GC&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;런타임에 Network에 추가될 것이라 예상 집합을 구체화한다.&lt;/li&gt;
&lt;li&gt;네트워크 플러그인이 예상 집합에 존재하지 않는 리소스를 삭제한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;DEL&lt;/b&gt;의 대안으로 &lt;b&gt;GC&lt;/b&gt;를 사용하면 안된다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;DEL로 삭제하지 못한 리소스를 GC가 삭제해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;STATUS&lt;/b&gt;&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;런타임에 네트워크 플러그인의 readiness를 파악한다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;ADD 처리 준비가 된 경우 0을 반환하며 종료한다.&lt;/li&gt;
&lt;li&gt;ADD 요청을 처리할 수 없는 경우, 0이 아닌 반환 코드 함께 종료하고, 표준 출력에 에러를 출력한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;플러그인이 &lt;b&gt;STATUS&lt;/b&gt;에 의존하면 안된다.
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;순수하게 상태 확인 용으로만 사용해야 한다.&lt;/li&gt;
&lt;li&gt;&lt;b&gt;STATUS&lt;/b&gt;가 에러를 반환해도 다른 작업 **(ADD, DEL 등)**은 그대로 역할을 수행해야 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 동작들 중에서 &lt;b&gt;ADD&lt;/b&gt;나 &lt;b&gt;DEL&lt;/b&gt;을 보면 결국 컨테이너를 CNI가 관리하는 네트워크 대역에 참여시키고 해제시키는 동작을 정의하는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히, &lt;b&gt;CNI_CONTAINERID, CNI_IFNAME&lt;/b&gt;는 한 쌍으로 튜플처럼 고유하게 관리되는 것을 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;리눅스 상에서는 네트워크 네임스페이스를 사용해서 컨테이너 격리와 유사하게 네트워크를 격리할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨테이너 역시 격리된 하나의 네임스페이스 상에서는 하나의 컨테이너가 중복된 네트워크 인터페이스를 가질 수 없도록 정의하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;플러그인&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;마지막으로, 플러그인에 대해 살펴보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 플러그인이라는 것 자체가 CNI에서 관리하는 부수적인 바이너리지만 CNI라는 것에서 중요한 요소라고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1731137895985&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - aws/amazon-ecs-cni-plugins: Networking Plugins repository for ECS Task Networking&quot; data-og-description=&quot;Networking Plugins repository for ECS Task Networking - aws/amazon-ecs-cni-plugins&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/aws/amazon-ecs-cni-plugins&quot; data-og-url=&quot;https://github.com/aws/amazon-ecs-cni-plugins&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/FlhNC/hyXwrkzsh0/9lNQWjhQcAxWkm9gscsUVK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/9GVWT/hyXsSEcg3H/lWMwhdBgBT9E8HtgvOKAhk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/aws/amazon-ecs-cni-plugins&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/aws/amazon-ecs-cni-plugins&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/FlhNC/hyXwrkzsh0/9lNQWjhQcAxWkm9gscsUVK/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/9GVWT/hyXsSEcg3H/lWMwhdBgBT9E8HtgvOKAhk/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - aws/amazon-ecs-cni-plugins: Networking Plugins repository for ECS Task Networking&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Networking Plugins repository for ECS Task Networking - aws/amazon-ecs-cni-plugins&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-09-18 오후 6.08.50.png&quot; data-origin-width=&quot;148&quot; data-origin-height=&quot;85&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dCjKxx/btsKDVFF3eb/9aEML6MId1qkLiBjhDE03K/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dCjKxx/btsKDVFF3eb/9aEML6MId1qkLiBjhDE03K/img.png&quot; data-alt=&quot;ECS CNI의 플러그인&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dCjKxx/btsKDVFF3eb/9aEML6MId1qkLiBjhDE03K/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdCjKxx%2FbtsKDVFF3eb%2F9aEML6MId1qkLiBjhDE03K%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;211&quot; height=&quot;121&quot; data-filename=&quot;스크린샷 2024-09-18 오후 6.08.50.png&quot; data-origin-width=&quot;148&quot; data-origin-height=&quot;85&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;ECS CNI의 플러그인&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ECS CNI에 존재하는 플러그인을 보면 ecs-bridge, eni, ipam이 있는 것을 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ECS는 AWS 매니지드 서비스이기 때문에 AWS 네트워크와 관련된 서비스에 연결된 플러그인들이 함께 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ecs-bridge의 경우에는 veth 페어를 만들고 네트워크 네임스페이스를 브릿지에 연결한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 도커를 사용할 때 보면 docker0-veth 인터페이스 쌍을 통해서 호스트와 호스트 외부의 연결을 수행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ecs 역시 오케스트레이션이기에 kubelet과 같은 에이전트가 존재한다. (ecs-agent)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ecs-agent는 파게이트 혹은 ec2로 동작하는 태스크를 주시하면서 ecs와 통신한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 위해서 존재하는게 ecs-bridge 플러그이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 밖에도, eni나 ipam 플러그인을 보면 eni 역시 태스크(혹은 파드)에 부착되면서 ip 대역을 할당받도록 도와준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1731138216144&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;GitHub - projectcalico/calico: Cloud native networking and network security&quot; data-og-description=&quot;Cloud native networking and network security. Contribute to projectcalico/calico development by creating an account on GitHub.&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/projectcalico/calico&quot; data-og-url=&quot;https://github.com/projectcalico/calico&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/EhmU9/hyXwgchH73/OwY3nAA8wCkiLB1rGQMiH1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/Iabdy/hyXsSc4Eqq/qQEF7bjSkCZ5wB1rKhW15K/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/projectcalico/calico&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/projectcalico/calico&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/EhmU9/hyXwgchH73/OwY3nAA8wCkiLB1rGQMiH1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/Iabdy/hyXsSc4Eqq/qQEF7bjSkCZ5wB1rKhW15K/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;GitHub - projectcalico/calico: Cloud native networking and network security&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Cloud native networking and network security. Contribute to projectcalico/calico development by creating an account on GitHub.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Calico 역시 앞서 언급했던 구현체들을 포함하고 있고, 다음의 경로에서 쿠버네티스의 파드 네트워크 동작이나 ipam과 같은 플러그인을 확인할 수 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;/calico/cni-plugin/pkg/k8s/k8s.go&lt;br /&gt;/calico/cni-plugin/pkg/plugin/plugin.go&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div data-ke-type=&quot;moreLess&quot; data-text-more=&quot;더보기&quot; data-text-less=&quot;닫기&quot;&gt;&lt;a class=&quot;btn-toggle-moreless&quot;&gt;더보기&lt;/a&gt;
&lt;div class=&quot;moreless-content&quot;&gt;
&lt;pre id=&quot;code_1731138459122&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;grep 'github.com/containernetworking/cni' -r ./                                                                                                                                   

.//app-policy/config/cluster/node-config.yaml:        ExecStartPre=/usr/bin/wget -N -P /opt/cni/bin https://github.com/containernetworking/cni/releases/download/v0.5.1/cni-v0.5.1.tgz
.//go.mod:      github.com/containernetworking/cni v1.2.0
.//felix/fv/test-workload/test-workload.go:     cniv1 &quot;github.com/containernetworking/cni/pkg/types/100&quot;
.//go.sum:github.com/containernetworking/cni v1.2.0 h1:fEjhlfWwWAXEvlcMQu/i6z8DA0Kbu7EcmR5+zb6cm5I=
.//go.sum:github.com/containernetworking/cni v1.2.0/go.mod h1:/r+vA/7vrynNfbvSP9g8tIKEoy6win7sALJAw4ZiJks=
.//cni-plugin/win_tests/calico_cni_k8s_windows_test.go: cniv1 &quot;github.com/containernetworking/cni/pkg/types/100&quot;
.//cni-plugin/tests/calico_cni_test.go: cniv1 &quot;github.com/containernetworking/cni/pkg/types/100&quot;
.//cni-plugin/tests/calico_cni_ipam_test.go:    &quot;github.com/containernetworking/cni/pkg/types&quot;
.//cni-plugin/tests/calico_cni_k8s_test.go:     cniv1 &quot;github.com/containernetworking/cni/pkg/types/100&quot;
.//cni-plugin/internal/pkg/azure/azure.go:      &quot;github.com/containernetworking/cni/pkg/skel&quot;
.//cni-plugin/internal/pkg/azure/azure_test.go: &quot;github.com/containernetworking/cni/pkg/skel&quot;
.//cni-plugin/internal/pkg/utils/network_windows.go:    &quot;github.com/containernetworking/cni/pkg/skel&quot;
.//cni-plugin/internal/pkg/utils/network_windows.go:    cniv1 &quot;github.com/containernetworking/cni/pkg/types/100&quot;
.//cni-plugin/internal/pkg/utils/network_linux.go:      cniv1 &quot;github.com/containernetworking/cni/pkg/types/100&quot;
.//cni-plugin/internal/pkg/utils/network_linux.go:      &quot;github.com/containernetworking/cni/pkg/skel&quot;
.//cni-plugin/internal/pkg/utils/utils.go:      &quot;github.com/containernetworking/cni/pkg/skel&quot;
.//cni-plugin/internal/pkg/utils/utils.go:      cnitypes &quot;github.com/containernetworking/cni/pkg/types&quot;
.//cni-plugin/internal/pkg/utils/utils.go:      cniv1 &quot;github.com/containernetworking/cni/pkg/types/100&quot;
.//cni-plugin/internal/pkg/testutils/utils_windows.go:  &quot;github.com/containernetworking/cni/pkg/invoke&quot;
.//cni-plugin/internal/pkg/testutils/utils_windows.go:  &quot;github.com/containernetworking/cni/pkg/skel&quot;
.//cni-plugin/internal/pkg/testutils/utils_windows.go:  &quot;github.com/containernetworking/cni/pkg/types&quot;
.//cni-plugin/internal/pkg/testutils/utils_windows.go:  types020 &quot;github.com/containernetworking/cni/pkg/types/020&quot;
.//cni-plugin/internal/pkg/testutils/utils_windows.go:  cniv1 &quot;github.com/containernetworking/cni/pkg/types/100&quot;
.//cni-plugin/internal/pkg/testutils/utils_linux.go:    &quot;github.com/containernetworking/cni/pkg/invoke&quot;
.//cni-plugin/internal/pkg/testutils/utils_linux.go:    &quot;github.com/containernetworking/cni/pkg/types&quot;
.//cni-plugin/internal/pkg/testutils/utils_linux.go:    types020 &quot;github.com/containernetworking/cni/pkg/types/020&quot;
.//cni-plugin/internal/pkg/testutils/utils_linux.go:    cniv1 &quot;github.com/containernetworking/cni/pkg/types/100&quot;
.//cni-plugin/README.md:[cni]: https://github.com/containernetworking/cni
.//cni-plugin/README.md:[cni specification]: https://github.com/containernetworking/cni/blob/master/SPEC.md
.//cni-plugin/pkg/types/types.go:       &quot;github.com/containernetworking/cni/pkg/types&quot;
.//cni-plugin/pkg/k8s/k8s.go:   &quot;github.com/containernetworking/cni/pkg/skel&quot;
.//cni-plugin/pkg/k8s/k8s.go:   cnitypes &quot;github.com/containernetworking/cni/pkg/types&quot;
.//cni-plugin/pkg/k8s/k8s.go:   cniv1 &quot;github.com/containernetworking/cni/pkg/types/100&quot;
.//cni-plugin/pkg/k8s/k8s.go:   // See: https://github.com/containernetworking/cni/blob/master/CONVENTIONS.md#cni_args for more info.
.//cni-plugin/pkg/plugin/plugin.go:     &quot;github.com/containernetworking/cni/pkg/skel&quot;
.//cni-plugin/pkg/plugin/plugin.go:     cnitypes &quot;github.com/containernetworking/cni/pkg/types&quot;
.//cni-plugin/pkg/plugin/plugin.go:     cniv1 &quot;github.com/containernetworking/cni/pkg/types/100&quot;
.//cni-plugin/pkg/plugin/plugin.go:     cniSpecVersion &quot;github.com/containernetworking/cni/pkg/version&quot;
.//cni-plugin/pkg/dataplane/dataplane.go:       &quot;github.com/containernetworking/cni/pkg/skel&quot;
.//cni-plugin/pkg/dataplane/dataplane.go:       cniv1 &quot;github.com/containernetworking/cni/pkg/types/100&quot;
.//cni-plugin/pkg/dataplane/grpc/grpc_dataplane.go:     &quot;github.com/containernetworking/cni/pkg/skel&quot;
.//cni-plugin/pkg/dataplane/grpc/grpc_dataplane.go:     cniv1 &quot;github.com/containernetworking/cni/pkg/types/100&quot;
.//cni-plugin/pkg/dataplane/linux/dataplane_linux.go:   &quot;github.com/containernetworking/cni/pkg/skel&quot;
.//cni-plugin/pkg/dataplane/linux/dataplane_linux.go:   cniv1 &quot;github.com/containernetworking/cni/pkg/types/100&quot;
.//cni-plugin/pkg/dataplane/windows/dataplane_windows.go:       &quot;github.com/containernetworking/cni/pkg/skel&quot;
.//cni-plugin/pkg/dataplane/windows/dataplane_windows.go:       cniv1 &quot;github.com/containernetworking/cni/pkg/types/100&quot;
.//cni-plugin/pkg/ipamplugin/ipam_plugin.go:    &quot;github.com/containernetworking/cni/pkg/skel&quot;
.//cni-plugin/pkg/ipamplugin/ipam_plugin.go:    cnitypes &quot;github.com/containernetworking/cni/pkg/types&quot;
.//cni-plugin/pkg/ipamplugin/ipam_plugin.go:    cniv1 &quot;github.com/containernetworking/cni/pkg/types/100&quot;
.//cni-plugin/pkg/ipamplugin/ipam_plugin.go:    cniSpecVersion &quot;github.com/containernetworking/cni/pkg/version&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: none;&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: none;&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: none;&quot;&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li style=&quot;list-style-type: none;&quot;&gt;&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;길어서 접어두긴 했는데, calico의 경우에는 k8s, ipam과 데이터 플레인 구현체 외에는 특이한 플러그인을 당장 확인하지는 못했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;이어서는&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;처음에 말한 것 처럼, 조금만 더 다이브 해본 것을 정리한 것이라 내용이 엄청 깊진 않다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 패킷도 직접 잡아보면서 테스트해볼까 했는데 요건 좀 더 고민해볼까 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음에는 파드 네트워크까지 확장해서 한번 짧게만 정리해보자.&lt;/p&gt;</description>
      <category>DevOps, 클라우드/Container</category>
      <category>CNI</category>
      <category>ECS</category>
      <category>쿠버네티스</category>
      <author>Floodnut</author>
      <guid isPermaLink="true">https://floodnut.tistory.com/127</guid>
      <comments>https://floodnut.tistory.com/127#entry127comment</comments>
      <pubDate>Sat, 9 Nov 2024 16:52:34 +0900</pubDate>
    </item>
    <item>
      <title>[서비스메시] Istio로 트래픽 관리하기</title>
      <link>https://floodnut.tistory.com/126</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;서비스메시&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서비스메시를 가볍게 훑어보면서 느낀 점이 하나 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿠버네티스와 같은 기존의 오케스트레이션에 포함된 기능과 유사한 역할을 하는 것이 많다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론, 내가 아직 명확한 유즈케이스를 직접 접해보지 못해서 그런 것이라 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;분명히 쿠버네티스 단독으로 해결하지 못하는 페인포인트가 있을 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래도 서비스메시, 특히 Istio가 제공하는 트래픽 제어에 관한 내용을 살짝 정리해 보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;세부적인 디테일은 따로.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;서비스의 추상화&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서비스가 파드에 대한 라우팅을 결정하는 것처럼, 버추얼서비스(VirtualService)도 서비스에 대한 라우팅을 결정한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래의 예시처럼, VirtualService 리소스가 라우팅 정책을 적용해서 특정 서비스로 트래픽을 &lt;b&gt;라우팅&lt;/b&gt;한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 이렇게 라우팅된 트래픽에 대한 &lt;b&gt;세부적인 정책을 적용&lt;/b&gt;하는 리소스가 DestinationRule이다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: virtual-service-name
  namespace: default
spec:
  hosts:
    - service.default.svc.cluster.local # 쿠버네티스에 등록된 서비스 DNS 호스트
  http:
    - route:
        - destination:
            host: service.default.svc.cluster.local # 라우팅할 대상 서비스 DNS 1
            subset: dr-1 # 사용할 DR 서브셋 명
          weight: 90
        - destination:
            host: service-2.default.svc.cluster.local # 라우팅할 대상 서비스 DNS 2
            subset: dr-2 # 사용할 DR 서브셋 명
          weight: 10
      # 요렇게 uri 매칭도 할 수 있다.
      # match:
      #  - uri:
      #      prefix: &quot;/v1&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위의 예시를 보면 다음과 같은 규칙들을 적용하고 있는 것을 볼 수 있다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 19.3024%;&quot;&gt;규칙 또는 정책&lt;/td&gt;
&lt;td style=&quot;width: 80.6976%;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 19.3024%;&quot;&gt;라우팅 규칙&lt;/td&gt;
&lt;td style=&quot;width: 80.6976%;&quot;&gt;&lt;span&gt;요청의 URI, 헤더, 쿼리 파라미터 등 기반으로 라우팅 규칙을 설정&lt;/span&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 19.3024%;&quot;&gt;트래픽 분산&lt;/td&gt;
&lt;td style=&quot;width: 80.6976%;&quot;&gt;버전 관리된 서비스 별로 트래픽을 분산하여 카나리 배포를 지원&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 19.3024%;&quot;&gt;Retry, Timeout 정책&lt;/td&gt;
&lt;td style=&quot;width: 80.6976%;&quot;&gt;실패한 요청을 자동 재시도, Timeout 설정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 19.3024%;&quot;&gt;헤더 변조&lt;/td&gt;
&lt;td style=&quot;width: 80.6976%;&quot;&gt;요청-응답 헤더 변조&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 보여주는 쿠버네티스 서비스와의 차이는 다음과 같다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;쿠버네티스 서비스는 포드의 IP 주소를 발견하는 방법을 제공한다.&lt;/li&gt;
&lt;li&gt;버추얼서비스는 프록시를 동적으로 재구성할 수 있게 해주며, 시스템을 재시작하지 않고도 트래픽을 조절한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #444447; text-align: start;&quot;&gt;그니까... 우리가 개발하고 운영하는 애플리케이션을&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;서비스 형태로&lt;span style=&quot;background-color: #ffffff; color: #444447; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;배포할 때에는 필연적으로 그 파드와 서비스에 대한 정의가 필요하다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #444447; text-align: start;&quot;&gt;이렇게 구성된 서비스들을 재배포하거나 할 필요 없이 동적으로 라우팅할 수 있도록&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;추상화해 주는&lt;span style=&quot;background-color: #ffffff; color: #444447; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: dr-name
  namespace: default
spec:
  host: service # Service
  subsets:
      # Label selector로 동작
    - labels:
        version: a
      name: dr-1
    - labels:
        version: b
      name: dr-2
  # 요런 식으로 요청에 대한 정책을 지정할 수 있다.
  trafficPolicy:
    loadBalancer:
      simple: ROUND_ROBIN
    connectionPool:
      http:
        maxRequestsPerConnection: 1
    outlierDetection:
      consecutiveErrors: 5
      interval: 1m # 연속 오류 탐지 interval
      baseEjectionTime: 30s # 인스턴스를 트래픽에서 제외시키는 시간
      maxEjectionPercent: 50 # 트래픽 분배를 제외하는 인스턴스 비율&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DestinationRule 역시 더 많은 정책을 설정할 수 있지만, 기본적으로 위의 예시에서 적용하는 것들은 다음과 같다.&lt;/p&gt;
&lt;table style=&quot;border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style13&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 18.8372%;&quot;&gt;규칙 또는 정책&lt;/td&gt;
&lt;td style=&quot;width: 81.1628%;&quot;&gt;설명&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 18.8372%;&quot;&gt;서킷 브레이커&lt;/td&gt;
&lt;td style=&quot;width: 81.1628%;&quot;&gt;특정 서비스로 인입되는 트래픽을 차단해 장애 전파 방지&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 18.8372%;&quot;&gt;로드 밸런싱&lt;/td&gt;
&lt;td style=&quot;width: 81.1628%;&quot;&gt;RR, 가중치 등 로드 밸런싱 지원&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;width: 18.8372%;&quot;&gt;비정상 상태 감지&lt;/td&gt;
&lt;td style=&quot;width: 81.1628%;&quot;&gt;연속적으로 발생한 오류나 인스턴스 상태를 감지하고 트래픽 차단 등의 정책을 지정&lt;br /&gt;시스템 복구를 감지하고, 복구 된 시스템으로 트래픽 라우팅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 조금 더 찾아보다가 궁금해진 점이 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VirtualService - Service - Pod 순으로 라우팅을 할 때, 노드 지역성에 기반한 라우팅은 없을까 하는 생각이 들었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;또, 이런 지역성 라우팅이 Consul이나 Linkerd와 같은 다른 서비스메시에는 어떻게 되어있을까 하는 궁금증이 살짝 들었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;근데 찾아보니 아래와 같은게 있더라.&lt;/p&gt;
&lt;figure id=&quot;og_1728118011255&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Locality Load Balancing&quot; data-og-description=&quot;This series of tasks demonstrate how to configure locality load balancing in Istio.&quot; data-og-host=&quot;istio.io&quot; data-og-source-url=&quot;https://istio.io/latest/docs/tasks/traffic-management/locality-load-balancing/&quot; data-og-url=&quot;https://istio.io/latest/docs/tasks/traffic-management/locality-load-balancing/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/0sSmi/hyXazkv9O0/fSIo40oVsStQC2YIF2LU81/img.png?width=4096&amp;amp;height=2048&amp;amp;face=0_0_4096_2048&quot;&gt;&lt;a href=&quot;https://istio.io/latest/docs/tasks/traffic-management/locality-load-balancing/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://istio.io/latest/docs/tasks/traffic-management/locality-load-balancing/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/0sSmi/hyXazkv9O0/fSIo40oVsStQC2YIF2LU81/img.png?width=4096&amp;amp;height=2048&amp;amp;face=0_0_4096_2048');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Locality Load Balancing&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;This series of tasks demonstrate how to configure locality load balancing in Istio.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;istio.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;자세한 것은 다음에 기회를 봐서 알아보도록 하자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;로드 밸런싱&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리가 분산 시스템, 분산 스토리지, 마이크로 서비스 등 네트워크 상에 분산되어 있는 시스템을 운용할 때 항상 나오는 개념이 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;바로 해시다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해시의 주요 목적 중 하나는 결국 입력 값을 항상 일관된 출력 값으로 내보내는게 주 목적이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실제 구현 방식은 잘 모르더라도 우리가&amp;nbsp; 흔히 SHA와 같은 해시를 많이 접하고 사용한다고 생각한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해시 자체가 빠르게 값을 변환할 수 있지만, SHA와 같은 해시는 보안-암호학적 설계가 우선이었고 좀 더 성능-효율에 중심이 된 해시도 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;murmur 같은 해시들은 보안적 목적이 아니라, 분산 환경에서 빠르고 효율적으로 데이터를 분배하기 위한 목적으로 설계되었다고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어찌되었건, 클라이언트로부터의 요청에서는 IP, 헤더 등등의 데이터를 추출할 수 있고 이 데이터를 해싱해 사용하면 일관되게 트래픽을 나눌 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-09-01 오후 2.32.50.png&quot; data-origin-width=&quot;917&quot; data-origin-height=&quot;502&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5jVNF/btsJV4qt6Hp/Fk1KxEJNdKH4w6RWTUUha0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5jVNF/btsJV4qt6Hp/Fk1KxEJNdKH4w6RWTUUha0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5jVNF/btsJV4qt6Hp/Fk1KxEJNdKH4w6RWTUUha0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5jVNF%2FbtsJV4qt6Hp%2FFk1KxEJNdKH4w6RWTUUha0%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;674&quot; height=&quot;369&quot; data-filename=&quot;스크린샷 2024-09-01 오후 2.32.50.png&quot; data-origin-width=&quot;917&quot; data-origin-height=&quot;502&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;p data-ke-size=&quot;size16&quot;&gt;Envoy 같은 경우는 Ring-Hash, Cookie-hashing, Maglev를 사용하고 있었는데, Ring-hash를 가중치 기반 라우팅과 함께 사용될 때 세션 어피니티가 정상적으로 동작하지 않는 문제가 있었다.&lt;/p&gt;
&lt;figure id=&quot;og_1728118687707&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;explore load balancing with istio vs standard kubernetes &amp;amp; Load Balancing Implementation &amp;middot; Issue #89 &amp;middot; airavata-courses/deveng&quot; data-og-description=&quot;&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/airavata-courses/devengers/issues/89&quot; data-og-url=&quot;https://github.com/airavata-courses/devengers/issues/89&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/kcGiu/hyXavvGUH0/SMW1SaWzRdrxk7rPJ9rF10/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/ePmS3/hyXeb3mtAI/0Gf6C2GPgYCFbX5eusqQB0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/airavata-courses/devengers/issues/89&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/airavata-courses/devengers/issues/89&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/kcGiu/hyXavvGUH0/SMW1SaWzRdrxk7rPJ9rF10/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/ePmS3/hyXeb3mtAI/0Gf6C2GPgYCFbX5eusqQB0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;explore load balancing with istio vs standard kubernetes &amp;amp; Load Balancing Implementation &amp;middot; Issue #89 &amp;middot; airavata-courses/deveng&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;figure id=&quot;og_1728118605622&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;traffic splitting with session affinity &amp;middot; Issue #8167 &amp;middot; envoyproxy/envoy&quot; data-og-description=&quot;Can Envoy perform traffic splitting while preserving session affinity? For example, use Ring Hash or Maglev to select the weighted cluster according to its weight? This way, when route.RouteAction....&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/envoyproxy/envoy/issues/8167&quot; data-og-url=&quot;https://github.com/envoyproxy/envoy/issues/8167&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/lPLOq/hyXeb3mtuM/7I3z1GqUPImqf8bPTqH1EK/img.png?width=1200&amp;amp;height=600&amp;amp;face=978_121_1060_211,https://scrap.kakaocdn.net/dn/5TvDT/hyXd2STz1f/9rk3tkqR40cdSsco8eRtdk/img.png?width=1200&amp;amp;height=600&amp;amp;face=978_121_1060_211&quot;&gt;&lt;a href=&quot;https://github.com/envoyproxy/envoy/issues/8167&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/envoyproxy/envoy/issues/8167&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/lPLOq/hyXeb3mtuM/7I3z1GqUPImqf8bPTqH1EK/img.png?width=1200&amp;amp;height=600&amp;amp;face=978_121_1060_211,https://scrap.kakaocdn.net/dn/5TvDT/hyXd2STz1f/9rk3tkqR40cdSsco8eRtdk/img.png?width=1200&amp;amp;height=600&amp;amp;face=978_121_1060_211');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;traffic splitting with session affinity &amp;middot; Issue #8167 &amp;middot; envoyproxy/envoy&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Can Envoy perform traffic splitting while preserving session affinity? For example, use Ring Hash or Maglev to select the weighted cluster according to its weight? This way, when route.RouteAction....&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;figure id=&quot;og_1728118666720&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;Ring Hash consistent traffic splitting between multiple upstreams &amp;middot; Issue #7276 &amp;middot; envoyproxy/envoy&quot; data-og-description=&quot;Hello, I'm trying to consistently split traffic between multiple upstreams to do some canary release. However, I can't get ring hash based on header working with weighted_cluster: for a given heade...&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/envoyproxy/envoy/issues/7276&quot; data-og-url=&quot;https://github.com/envoyproxy/envoy/issues/7276&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bHCaFs/hyXd3qITj8/qG4uebic5ITmkDBHPT0Esk/img.png?width=1200&amp;amp;height=600&amp;amp;face=995_103_1036_148,https://scrap.kakaocdn.net/dn/bAcz3K/hyXavblGP1/LWm8PURLYFwQSa0WECwXWk/img.png?width=1200&amp;amp;height=600&amp;amp;face=995_103_1036_148&quot;&gt;&lt;a href=&quot;https://github.com/envoyproxy/envoy/issues/7276&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/envoyproxy/envoy/issues/7276&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bHCaFs/hyXd3qITj8/qG4uebic5ITmkDBHPT0Esk/img.png?width=1200&amp;amp;height=600&amp;amp;face=995_103_1036_148,https://scrap.kakaocdn.net/dn/bAcz3K/hyXavblGP1/LWm8PURLYFwQSa0WECwXWk/img.png?width=1200&amp;amp;height=600&amp;amp;face=995_103_1036_148');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Ring Hash consistent traffic splitting between multiple upstreams &amp;middot; Issue #7276 &amp;middot; envoyproxy/envoy&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Hello, I'm trying to consistently split traffic between multiple upstreams to do some canary release. However, I can't get ring hash based on header working with weighted_cluster: for a given heade...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;가중치 라우팅을 사용하면 가중치 규칙이 먼저 적용된 후에 세션 어피니티가 로드 밸런서가 적용되었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Envoy와 같은 프록시는 프록시에 인입되기 전과 인출된 후가 나뉜다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라이언트-서버의 관점으로 보면 프록시 이전 구간이 다운스트림이고, 프록시가 관리하면서 라우팅해주는 구간이 업스트림이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-10-05 오후 7.21.04.png&quot; data-origin-width=&quot;1360&quot; data-origin-height=&quot;192&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bILueS/btsJWTVZfU0/mK89i4pLg5fTzjJbJVC6gk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bILueS/btsJWTVZfU0/mK89i4pLg5fTzjJbJVC6gk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bILueS/btsJWTVZfU0/mK89i4pLg5fTzjJbJVC6gk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbILueS%2FbtsJWTVZfU0%2FmK89i4pLg5fTzjJbJVC6gk%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;1360&quot; height=&quot;192&quot; data-filename=&quot;스크린샷 2024-10-05 오후 7.21.04.png&quot; data-origin-width=&quot;1360&quot; data-origin-height=&quot;192&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프록시에 묶여있는 서비스들이 이미 가중치 규칙이 적용된 트래픽만 수신하기에, Sticky-Session 과 같은 처리 이전에 전체 트래픽을 대상으로 이미 라우팅이 이루어진다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해싱은 라우팅 정책(다운스트림)의 일부이고, 클러스터 자체의 고유 값이 아니기에 업스트림 로드밸런싱에서 관리하지 않는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이후에는 서로 격리된 프록시(LB)로 트래픽이 전달되고, 여기서 아무리 세션 분할을 걸어도 트래픽을 나눌 수 없게 되는 것이다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-10-05 오후 7.12.14.png&quot; data-origin-width=&quot;612&quot; data-origin-height=&quot;173&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bO6i28/btsJWyq1E7M/fCfDxtILQyrttYWFaxSopk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bO6i28/btsJWyq1E7M/fCfDxtILQyrttYWFaxSopk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bO6i28/btsJWyq1E7M/fCfDxtILQyrttYWFaxSopk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbO6i28%2FbtsJWyq1E7M%2FfCfDxtILQyrttYWFaxSopk%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;612&quot; height=&quot;173&quot; data-filename=&quot;스크린샷 2024-10-05 오후 7.12.14.png&quot; data-origin-width=&quot;612&quot; data-origin-height=&quot;173&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;p data-ke-size=&quot;size16&quot;&gt;이를 해결하기 위해서는 쿠키 기반 라우팅과 가중치 라우팅을 함께 사용할 때, 쿠키 기반 라우팅 정책을 선행해서 적용하면 된다고 한다.&lt;/p&gt;
&lt;figure id=&quot;og_1728124299261&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;Session affinity doesn't seem to apply to weighted subsets - Envoy support required &amp;middot; Issue #9764 &amp;middot; istio/istio&quot; data-og-description=&quot;Describe the bug When attempting to apply session affinity to weighted subsets, the session affinity doesn't seem to apply and the subsets will randomly get served based on their weights as normal....&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/istio/istio/issues/9764#issuecomment-631994703&quot; data-og-url=&quot;https://github.com/istio/istio/issues/9764&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/yP2O4/hyXd70ZLlH/5kXgt1fjLrkSMpKJ3UlWc0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/HsFWE/hyXaHiADRK/uP0uYUdZ8g9EeFfj08iGn1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600&quot;&gt;&lt;a href=&quot;https://github.com/istio/istio/issues/9764#issuecomment-631994703&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/istio/istio/issues/9764#issuecomment-631994703&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/yP2O4/hyXd70ZLlH/5kXgt1fjLrkSMpKJ3UlWc0/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600,https://scrap.kakaocdn.net/dn/HsFWE/hyXaHiADRK/uP0uYUdZ8g9EeFfj08iGn1/img.png?width=1200&amp;amp;height=600&amp;amp;face=0_0_1200_600');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Session affinity doesn't seem to apply to weighted subsets - Envoy support required &amp;middot; Issue #9764 &amp;middot; istio/istio&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Describe the bug When attempting to apply session affinity to weighted subsets, the session affinity doesn't seem to apply and the subsets will randomly get served based on their weights as normal....&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이와 관련된 Envoy 공식 문서도 아래에 같이 첨부해놓는다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1728118825337&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Consistent hashing matcher (proto) &amp;mdash; envoy 1.32.0-dev-9244dc documentation&quot; data-og-description=&quot;&amp;copy; Copyright 2016-2024, Envoy Project Authors.&quot; data-og-host=&quot;www.envoyproxy.io&quot; data-og-source-url=&quot;https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/matching/input_matchers/consistent_hashing/v3/consistent_hashing.proto&quot; data-og-url=&quot;https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/matching/input_matchers/consistent_hashing/v3/consistent_hashing.proto&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/matching/input_matchers/consistent_hashing/v3/consistent_hashing.proto&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.envoyproxy.io/docs/envoy/latest/api-v3/extensions/matching/input_matchers/consistent_hashing/v3/consistent_hashing.proto&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Consistent hashing matcher (proto) &amp;mdash; envoy 1.32.0-dev-9244dc documentation&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;&amp;copy; Copyright 2016-2024, Envoy Project Authors.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.envoyproxy.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1728118822568&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Stateful session &amp;mdash; envoy 1.32.0-dev-9244dc documentation&quot; data-og-description=&quot;Stateful session is an HTTP filter which overrides the upstream host based on extensible session state and updates the session state based on the final selected upstream host. The override host will eventually overwrites the load balancing result. This fil&quot; data-og-host=&quot;www.envoyproxy.io&quot; data-og-source-url=&quot;https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/stateful_session_filter#config-http-filters-stateful-session&quot; data-og-url=&quot;https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/stateful_session_filter#config-http-filters-stateful-session&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/stateful_session_filter#config-http-filters-stateful-session&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_filters/stateful_session_filter#config-http-filters-stateful-session&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Stateful session &amp;mdash; envoy 1.32.0-dev-9244dc documentation&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Stateful session is an HTTP filter which overrides the upstream host based on extensible session state and updates the session state based on the final selected upstream host. The override host will eventually overwrites the load balancing result. This fil&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.envoyproxy.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;figure id=&quot;og_1728118822152&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;HTTP route components (proto) &amp;mdash; envoy 1.32.0-dev-9244dc documentation&quot; data-og-description=&quot;The top level element in the routing configuration is a virtual host. Each virtual host has a logical name as well as a set of domains that get routed to it based on the incoming request&amp;rsquo;s host header. This allows a single listener to service multiple to&quot; data-og-host=&quot;www.envoyproxy.io&quot; data-og-source-url=&quot;https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto.html#config-route-v3-routeaction-hashpolicy-cookie&quot; data-og-url=&quot;https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto.html#config-route-v3-routeaction-hashpolicy-cookie&quot; data-og-image=&quot;&quot;&gt;&lt;a href=&quot;https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto.html#config-route-v3-routeaction-hashpolicy-cookie&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto.html#config-route-v3-routeaction-hashpolicy-cookie&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url();&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;HTTP route components (proto) &amp;mdash; envoy 1.32.0-dev-9244dc documentation&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;The top level element in the routing configuration is a virtual host. Each virtual host has a logical name as well as a set of domains that get routed to it based on the incoming request&amp;rsquo;s host header. This allows a single listener to service multiple to&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.envoyproxy.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;그래서?&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 우리가 Ingress, Service 와 같은 쿠버네티스 리소스를 접하다보면 어느 정도는 기능이 겹친다고는 볼 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만, 좀 더 세부적인 조정이 가능하고 서비스 영역이 아니라 서비서보다 앞서서 프록시 단에서 정책을 주입하고 서비스의 변경을 최소화 하는게 서비스메시의 주안점이 아닐까 싶다.&lt;/p&gt;</description>
      <category>DevOps, 클라우드/Service Mesh</category>
      <author>Floodnut</author>
      <guid isPermaLink="true">https://floodnut.tistory.com/126</guid>
      <comments>https://floodnut.tistory.com/126#entry126comment</comments>
      <pubDate>Sat, 5 Oct 2024 18:04:14 +0900</pubDate>
    </item>
    <item>
      <title>[서비스메시] Ambient Mesh에 대해서</title>
      <link>https://floodnut.tistory.com/123</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;궁금증&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서비스 메시를 공부하다가 문득 이런 궁금증이 생겼다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;i&gt;&quot;Kube-proxy도 노드 상에 데몬셋의 형태로 존재하며 파드로 요청을 라우팅하는데, Envoy와 같이 Istio가 사용하는 프록시는 데몬셋의 형태로 관리할 수 없을까?&quot;&lt;/i&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프록시를 노드 별로 데몬셋(혹은 유사한 형태)로 서빙하려면 다음과 조건들이 붙지 않을까 생각했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;Istio를 사용하지 않는 네임스페이스의 리소스에 대한 라우팅은 무시할 것&lt;/li&gt;
&lt;li&gt;프록시를 통과하는 요청을 네임스페이스 별로 격리할 것&lt;/li&gt;
&lt;li&gt;동일 네임스페이스 내 파드 간 요청이 발생해도 노드의 프록시를 경유할 것&lt;/li&gt;
&lt;li&gt;...&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 이런 조건들을 생각해보기는 했지만 이게 꼭 지켜져야 하는 필수 조건인가도 고민이 좀 됐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러다 문득 Istio 블로그에서 요런 글을 보게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;div&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;Introducing Ambient Mesh&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: 'Noto Serif KR';&quot;&gt;A new dataplane mode for Istio without sidecars.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;figure id=&quot;og_1722958817918&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;Introducing Ambient Mesh&quot; data-og-description=&quot;A new dataplane mode for Istio without sidecars.&quot; data-og-host=&quot;istio.io&quot; data-og-source-url=&quot;https://istio.io/latest/blog/2022/introducing-ambient-mesh/&quot; data-og-url=&quot;https://istio.io/latest/blog/2022/introducing-ambient-mesh/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/cJBbbX/hyWKJmEBfW/gawrkovyZFgcaSIadrKVO0/img.png?width=4096&amp;amp;height=2048&amp;amp;face=0_0_4096_2048,https://scrap.kakaocdn.net/dn/ix1Bf/hyWKB3fzrN/gFekJIv4S9I1aV2OT4f1N0/img.png?width=4267&amp;amp;height=1868&amp;amp;face=0_0_4267_1868,https://scrap.kakaocdn.net/dn/BmXvD/hyWKyMdF4T/vkcykV8UBcfj3YHtpbMaA1/img.png?width=4267&amp;amp;height=1868&amp;amp;face=0_0_4267_1868&quot;&gt;&lt;a href=&quot;https://istio.io/latest/blog/2022/introducing-ambient-mesh/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://istio.io/latest/blog/2022/introducing-ambient-mesh/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/cJBbbX/hyWKJmEBfW/gawrkovyZFgcaSIadrKVO0/img.png?width=4096&amp;amp;height=2048&amp;amp;face=0_0_4096_2048,https://scrap.kakaocdn.net/dn/ix1Bf/hyWKB3fzrN/gFekJIv4S9I1aV2OT4f1N0/img.png?width=4267&amp;amp;height=1868&amp;amp;face=0_0_4267_1868,https://scrap.kakaocdn.net/dn/BmXvD/hyWKyMdF4T/vkcykV8UBcfj3YHtpbMaA1/img.png?width=4267&amp;amp;height=1868&amp;amp;face=0_0_4267_1868');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Introducing Ambient Mesh&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;A new dataplane mode for Istio without sidecars.&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;istio.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;사이드카 프록시&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;traditional-istio.png&quot; data-origin-width=&quot;4267&quot; data-origin-height=&quot;1868&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/daLFQA/btsIVbEZ48A/zY2NCn4RDhTruB23oMvfW1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/daLFQA/btsIVbEZ48A/zY2NCn4RDhTruB23oMvfW1/img.png&quot; data-alt=&quot;사이드카를 활용하는 기존의 방식&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/daLFQA/btsIVbEZ48A/zY2NCn4RDhTruB23oMvfW1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdaLFQA%2FbtsIVbEZ48A%2FzY2NCn4RDhTruB23oMvfW1%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;4267&quot; height=&quot;1868&quot; data-filename=&quot;traditional-istio.png&quot; data-origin-width=&quot;4267&quot; data-origin-height=&quot;1868&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;사이드카를 활용하는 기존의 방식&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존의 Istio는 사이드카 프록시를 활용해서 앱 컨테이너의 앞단에서 요청을 먼저 처리하고 포워딩을 결정해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앱 컨테이너는 기존의 로직을 최대한 유지한 채로 프록시로부터 수신한 요청을 처리하고 그대로 반환하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사이드카는 하나의 애플리케이션이 온전한 wrapper 형태로 존재하게 해주고, 주요 비즈니스 로직 외의 부수적인 로직을 처리할 수 있게 해주었다. (K8S Pods, ECS Tasks, ...)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 요런 패턴으로 서비스를 관리하다보면서 느끼는 문제점이 있다. 사이드카 컨테이너의 변경은 곧 해당 서비스 전체를 재배포로 이어진다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;요런 문제를 위 블로그에서 짚고 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;&lt;b&gt;사이드카는 애플리케이션에 주입된 형태로 존재해야 한다.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;애플리케이션의 리소스를 공유한다.&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Istio 정책에 영향을 받는 프록시는 애플리케이션의 의도와 상관없이 특정 파드로의 요청을 부정확하게 처리할 가능성이 있다.&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 중에서 1, 2번의 경우가 사이드카의 대표적인 문제점이라고 생각된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1번은 파드의 로컬 네트워크 내에서 요청을 처리할 수 있는 장점이 있다는 반면에 앞서 말한 주입과 업그레이드에 문제가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;2번의 경우는, 한 노드에 불필요하게 여러 리소스를 소비하는 컨테이너가 존재할 수 있다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;애플리케이션에서 리소스 제한을 걸어두면 그 안에서 공유하겠지만, 이것 자체가 애플리케이션의 리소스 고갈을 유발할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그렇다고 사이드카를 위해서 리소스 여유분을 더 확보하자니, 노드 자체의 리소스가 더 소모된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;Ambient Mesh&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아키텍처는 늘 트레이드 오프라고 하듯이, 정말 편리한 형태로 서빙을 도와주는 사이드카 패턴이지만 위와 같은 단점도 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존의 Istio 데이터 플레인에 존재하는 문제는 더 있었는데, 추상화된 하나의 레이어가 모든 기능을 담당한다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;흔히들 보는 mTLS 같은 보안 레이어부터 L7 레이어까지 모든 기능이 하나의 데이터 플레인 레이어에 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러니까 작은 기능이나 정책 하나만 적용하려고 해도 모든 데이터 플레인 레이어가 사용된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Ambient Mesh는 이런 문제을 해결하기 위해서 Secure Overlay Layer와 L7 Processing Layer를 구분해서 구현하게 했다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ambient-layers.png&quot; data-origin-width=&quot;3130&quot; data-origin-height=&quot;1612&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bFw7YT/btsIVFy6GY4/UbzdnzUEcpROqUojcnumZ1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bFw7YT/btsIVFy6GY4/UbzdnzUEcpROqUojcnumZ1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bFw7YT/btsIVFy6GY4/UbzdnzUEcpROqUojcnumZ1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbFw7YT%2FbtsIVFy6GY4%2FUbzdnzUEcpROqUojcnumZ1%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;3130&quot; height=&quot;1612&quot; data-filename=&quot;ambient-layers.png&quot; data-origin-width=&quot;3130&quot; data-origin-height=&quot;1612&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;p data-ke-size=&quot;size16&quot;&gt;요런 레이어링은 Istio로의 전환에도 도움을 준다고 한다. (네임스페이스에 Istio 전체를 일괄 적용하지 않고 부분 적용 할 수 있으니 점진적으로 전환할 수 있다.)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기존의 L7 수준에서 이루어지던 HTTP 기반 요청 라우팅, 애플리케이션 레벨의 로드밸런싱 등등의 기능을 L7 Processing Layer에서 처리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고, L4 (+L7) 수준에서 이루지던 TCP 기반의 정책과 기능들이나 mTLS와 같은 보안 요소들을 Secure Overlay Layer에서 처리한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;ambient-secure-overlay.png&quot; data-origin-width=&quot;4267&quot; data-origin-height=&quot;1868&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/4VEVa/btsIWUPxNTP/gXOMa6LiiAs5Su2K54F430/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/4VEVa/btsIWUPxNTP/gXOMa6LiiAs5Su2K54F430/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/4VEVa/btsIWUPxNTP/gXOMa6LiiAs5Su2K54F430/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F4VEVa%2FbtsIWUPxNTP%2FgXOMa6LiiAs5Su2K54F430%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;4267&quot; height=&quot;1868&quot; data-filename=&quot;ambient-secure-overlay.png&quot; data-origin-width=&quot;4267&quot; data-origin-height=&quot;1868&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그리고 주요 포인트인&lt;b&gt; &lt;/b&gt;&lt;u&gt;&lt;b&gt;데몬셋 형태의 배포&lt;/b&gt;&lt;/u&gt;를 통해서 에이전트 형태로 노드마다 동작하는 특징을 가지고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;ztunnel 이라는 것으로 Ambient-Mesh 내 구성요소들을 연결한다고 한다. 요것은 Secure-Overlay를 생성해서 L4 수준의 정책을 적용시켜준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;L7 기능이 필요하다면 Ambient Mesh를 활성화하고 L7 정책을 적용할 네임스페이스를 구성하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;웨이포인트 프록시가 그 역할을 수행하는데, 이건 별도 Deployment 리소스로 동적으로 배포되게 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 웨이포인트는 &lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #293655; text-align: start;&quot;&gt;HTTP CONNECT over mTLS&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;를 통해서 HTTP 연결된 터널 위에 존재한다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;그러니까 정리하면, L4 기능은 노드의 공유 에이전트가 ztunnel로써 수행하고, L7 기능은 웨이포인트 프록시를 통해서 수행된다는 것이다.&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;u&gt;&lt;b&gt;데몬셋 형태의 배포&lt;/b&gt;&lt;/u&gt;는 L4 ztunnel에만 해당되는 이야기고 L7은 별도의 파드(웨이포인트)에서 처리된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 이유를 말해주고 있는데 Envoy 자체가 멀티 테넌트를 고려해서 만든 것이 아니여서 라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;L7의 복잡한 정책이 공유 에이전트에서 처리되는 순간 보안 문제가 발생할 수 있으니, ztunnel이 커버하는 영역을 L4 처리로만 한정짓는 것으로 완화한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 style=&quot;color: #000000; text-align: start;&quot; data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;그래서 Ambient-Mesh 쓰냐?&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;뭔가 블로그 글을 보다보면 Ambient-Mesh는 최고야! 라고 말하는 것 같지만... 늘 공유 자원을 사용하는 곳에서는 문제가 발생하기 마련이다. 그런 점에서 사이드카를 통해서 단순한 기술적 문제 뿐만 아니라 컴플라이언스 같은 요소들도 같이 고려해볼 수 있다는 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;늘 그렇지만, 대체되는 기술이 아니라 공존하는 기술로써 쓰인다고 말하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;어찌되었건 Ambient Mesh를 이용하면 L4 처리는 노드에서 데몬셋 형태로 처리되는 것이 가능하지만, L7 처리는 별도의 파드에서 수행되니 원래의 궁금증이 완전히 해결되지는 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이 기술이 L7 처리를 분리한 이유를 기술하고 있으니, 이 문제를 효과적으로 해결할 방법이 고안되지 않는 한 이것이 또 다른 대안이 아니겠나 싶다.&amp;nbsp;&lt;/p&gt;</description>
      <category>DevOps, 클라우드/Service Mesh</category>
      <category>ambient</category>
      <category>istio</category>
      <category>서비스메시</category>
      <author>Floodnut</author>
      <guid isPermaLink="true">https://floodnut.tistory.com/123</guid>
      <comments>https://floodnut.tistory.com/123#entry123comment</comments>
      <pubDate>Mon, 5 Aug 2024 00:08:09 +0900</pubDate>
    </item>
    <item>
      <title>[서비스메시] 변수명은 중요하다.</title>
      <link>https://floodnut.tistory.com/122</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;서론&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서비스 메시를 공부하다가 핸즈온 과정에서 Jaeger를 배포했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;업무 중에 Jaeger로 추적 스팬들을 뽑아낼 일이 있어서 익숙하다고 생각했는데, 지금 돌이켜보니 신규 구축이라 최신 버전을 끌어다 썼던 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;핸즈온 과정에서는 v1.20을 사용하고 있었고, arm 환경에서 테스트하려면 아래 포스팅에서 언급한 바와 같이 v1.24 이상의 버전을 사용해야 했다.&lt;/p&gt;
&lt;figure id=&quot;og_1722094170231&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[서비스메시] Istio, Envoy&quot; data-og-description=&quot;서비스 메시, Istio와 Envoy서비스 메시는 주로 분산 아키텍처에서 각 소프트웨어 컴포넌트 간의 네트워킹을 관리한다.특히 쿠버네티스 환경에서 마이크로서비스 간의 상호 연결을 관리하고, 그에&quot; data-og-host=&quot;www.floodnut.com&quot; data-og-source-url=&quot;https://floodnut.tistory.com/120&quot; data-og-url=&quot;https://www.floodnut.com/120&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/8FqvN/hyWCEUovy0/sdtft0Pa540h4KeBl8tank/img.jpg?width=320&amp;amp;height=320&amp;amp;face=0_0_320_320,https://scrap.kakaocdn.net/dn/UcwKq/hyWCDHVFCU/avVmcHkQp2WKtKssYvtucK/img.jpg?width=320&amp;amp;height=320&amp;amp;face=0_0_320_320,https://scrap.kakaocdn.net/dn/WcEgS/hyWG09imYE/Okc3TYZcMNyfaa8eTyX0wK/img.png?width=2032&amp;amp;height=1167&amp;amp;face=0_0_2032_1167&quot;&gt;&lt;a href=&quot;https://floodnut.tistory.com/120&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://floodnut.tistory.com/120&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/8FqvN/hyWCEUovy0/sdtft0Pa540h4KeBl8tank/img.jpg?width=320&amp;amp;height=320&amp;amp;face=0_0_320_320,https://scrap.kakaocdn.net/dn/UcwKq/hyWCDHVFCU/avVmcHkQp2WKtKssYvtucK/img.jpg?width=320&amp;amp;height=320&amp;amp;face=0_0_320_320,https://scrap.kakaocdn.net/dn/WcEgS/hyWG09imYE/Okc3TYZcMNyfaa8eTyX0wK/img.png?width=2032&amp;amp;height=1167&amp;amp;face=0_0_2032_1167');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[서비스메시] Istio, Envoy&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;서비스 메시, Istio와 Envoy서비스 메시는 주로 분산 아키텍처에서 각 소프트웨어 컴포넌트 간의 네트워킹을 관리한다.특히 쿠버네티스 환경에서 마이크로서비스 간의 상호 연결을 관리하고, 그에&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.floodnut.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #444447; text-align: start;&quot;&gt;minikube에서 처음 테스트를 한 후, 내 개인 클러스터에서 다시 배포하려는데 아키텍처 문제를&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;신경 쓰고 싶지&lt;span style=&quot;background-color: #ffffff; color: #444447; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;않아서 v1.24를 사용했다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #444447; text-align: start;&quot;&gt;그런데, Jaeger로 스팬들이 안 모이더라 ㅜㅜ&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #444447; text-align: start;&quot;&gt;무슨 문제가 있나 싶어서 v1.20부터 v1.24 간의 패치 노트를 찾아봤다.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;background-color: #ffffff; color: #444447; text-align: start;&quot;&gt;그리고&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;v1.22에서&lt;span style=&quot;background-color: #ffffff; color: #444447; text-align: start;&quot;&gt;&lt;span&gt;&amp;nbsp;&lt;/span&gt;문제점을 찾아냈다.&lt;/span&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1722094350288&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;object&quot; data-og-title=&quot;Release Release 1.22.0 &amp;middot; jaegertracing/jaeger&quot; data-og-description=&quot;Backend Changes Breaking Changes Remove deprecated TLS flags (#2790, @albertteoh): --cassandra.tls is replaced by --cassandra.tls.enabled --cassandra-archive.tls is replaced by --cassandra-archi...&quot; data-og-host=&quot;github.com&quot; data-og-source-url=&quot;https://github.com/jaegertracing/jaeger/releases/tag/v1.22.0&quot; data-og-url=&quot;https://github.com/jaegertracing/jaeger/releases/tag/v1.22.0&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/b86SS2/hyWCJVFkSW/kRoZphhV6SJZkuO6uCT7lk/img.png?width=1200&amp;amp;height=600&amp;amp;face=95_463_138_509&quot;&gt;&lt;a href=&quot;https://github.com/jaegertracing/jaeger/releases/tag/v1.22.0&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://github.com/jaegertracing/jaeger/releases/tag/v1.22.0&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/b86SS2/hyWCJVFkSW/kRoZphhV6SJZkuO6uCT7lk/img.png?width=1200&amp;amp;height=600&amp;amp;face=95_463_138_509');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;Release Release 1.22.0 &amp;middot; jaegertracing/jaeger&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;Backend Changes Breaking Changes Remove deprecated TLS flags (#2790, @albertteoh): --cassandra.tls is replaced by --cassandra.tls.enabled --cassandra-archive.tls is replaced by --cassandra-archi...&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;github.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;--collector.zipkin.http-port is replaced by --collector.zipkin.host-port&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;zipkin-collector의 http port를 지칭하던 flag가 &lt;b&gt;collector.zipkin.http-port&lt;/b&gt;에서 &lt;b&gt;collector.zipkin.host-port&lt;/b&gt;로 변경되었고, 여기에 해당하는 환경변수 역시 &lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;COLLECTOR_ZIPKIN_HTTP_PORT &lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;에서 &lt;/span&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; text-align: start;&quot;&gt;COLLECTOR_ZIPKIN_HOST_PORT&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; text-align: start;&quot;&gt;로 변경됐다.&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사실 이건 서비스 메시보다는 분산 추적에 대한 내용이라고 봐야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래도 서비스 메시 공부하면서 느낀 거니까 서비스 메시라고 할게요&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;변수명&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 문득 느낀 점이 하나 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;envoy 역시 v2 http 필터에서 v3 http 필터로 오면서 &lt;b&gt;host_rewrite&lt;/b&gt;를 deprecate 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;대신, v3에서는 &lt;b&gt;host_rewrite_literal&lt;/b&gt;과 &lt;b&gt;&lt;b&gt;host_rewrite_regex&lt;/b&gt;&lt;/b&gt;가 추가됐다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;literal은 라우팅할 호스트 필드 전체를 입력하는 것이고, regex는 정규표현식을 입력한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;해당 필드에 들어가는 값의 성격은 다르더라도, 결국 문자열 형태로 입력될 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런 부분에서, 값의 성격이 달라지면서 오는 혼동을 줄이고자 명시적으로 필드를 구분한 것이라 생각했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Zipkin-Collector의 flag과 env 명이 달라진 것도 유사한 이유일 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Jaeger v1.20과 v1.24 둘 다 Http-Collector로 thrift, proto와 같은 rpc와 http를 지원한다.&lt;/p&gt;
&lt;table style=&quot;background-color: #ffffff; color: #4a4a4a; text-align: start; border-collapse: collapse; width: 100%;&quot; border=&quot;1&quot; data-ke-align=&quot;alignLeft&quot; data-ke-style=&quot;style6&quot;&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;&lt;b&gt;14268&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;&lt;b&gt;HTTP&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;&lt;b&gt;collector&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;&lt;b&gt;accept&lt;span&gt;&amp;nbsp;&lt;/span&gt;jaeger.thrift&lt;span&gt;&amp;nbsp;&lt;/span&gt;directly from clients&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;&lt;b&gt;14250&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;&lt;b&gt;HTTP&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;&lt;b&gt;collector&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;&lt;b&gt;accept&lt;span&gt;&amp;nbsp;&lt;/span&gt;model.proto&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;&lt;b&gt;9411&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;&lt;b&gt;HTTP&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;&lt;b&gt;collector&lt;/b&gt;&lt;/td&gt;
&lt;td style=&quot;text-align: left;&quot;&gt;&lt;b&gt;Zipkin compatible endpoint (optional)&lt;/b&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만, grpc 역시 http/2 위에서 도는 프로토콜임에도 http와 명시적으로 구분하고 있는데 zipkin-collector는 이걸 http로 퉁쳐버린 것이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;구분할 것이라면 확실하게 구분하던지, 아니면 통일하고 호환성을 제공하는지를 결정하려한 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 &lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; text-align: start;&quot;&gt;HOST &lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; text-align: start;&quot;&gt;라는 단어를 사용하지 않았을까?&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;&lt;span style=&quot;background-color: #ffffff; color: #000000; text-align: start;&quot;&gt;&lt;span style=&quot;background-color: #ffffff; text-align: start;&quot;&gt;익숙함은 무섭다.&lt;/span&gt;&lt;/span&gt;&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 당연하게 &quot;&lt;i&gt;http-collector 면 http call만 가능한거 아니야? ㅋㅋ&lt;/i&gt;&quot; 라고 생각하고 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;왜냐면 Jaeger는 http와 http 상에서 도는 다른 프로토콜을 구분해 주었으니까.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그러면 우리가 rpc를 사용할 수 있는 환경임에도, http를 유지한다면 자연스럽게 순수 http로만 call하지 않았을까 싶다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이래서 변수 명이 중요하다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;패치 노트와 공식 문서를 보지 않았다면 몰랐을 테니...&lt;/p&gt;</description>
      <category>DevOps, 클라우드/Service Mesh</category>
      <category>Jaeger</category>
      <category>zipkin</category>
      <author>Floodnut</author>
      <guid isPermaLink="true">https://floodnut.tistory.com/122</guid>
      <comments>https://floodnut.tistory.com/122#entry122comment</comments>
      <pubDate>Sun, 28 Jul 2024 00:49:47 +0900</pubDate>
    </item>
    <item>
      <title>[HomeLab] K8S 노드에 Label 추가하기</title>
      <link>https://floodnut.tistory.com/121</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;파드가 죽어요&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재 가지고 있는 쿠버네티스 클러스터에는 4개의 워커 노드가 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;3대의 arm64 노드와 1대의 x86 노드를 사용하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이전에 Envoy를 테스트하면서 v1.11 이미지를 사용했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재는 1.31 버전이 최신 버전임을 확인할 수 있다.&lt;/p&gt;
&lt;figure id=&quot;og_1721499711949&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;article&quot; data-og-title=&quot;[서비스메시] Istio, Envoy&quot; data-og-description=&quot;서비스 메시, Istio와 Envoy서비스 메시는 주로 분산 아키텍처에서 각 소프트웨어 컴포넌트 간의 네트워킹을 관리한다.특히 쿠버네티스 환경에서 마이크로서비스 간의 상호 연결을 관리하고, 그에&quot; data-og-host=&quot;www.floodnut.com&quot; data-og-source-url=&quot;https://floodnut.tistory.com/120&quot; data-og-url=&quot;https://www.floodnut.com/120&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/bQPwYB/hyWCDGx5lZ/lG9TVEhYpdaZnbTBxiAzc1/img.jpg?width=320&amp;amp;height=320&amp;amp;face=0_0_320_320,https://scrap.kakaocdn.net/dn/VCgrE/hyWCNvBWzS/KAPm4BeWgTkNGn7ckNvnKK/img.jpg?width=320&amp;amp;height=320&amp;amp;face=0_0_320_320,https://scrap.kakaocdn.net/dn/daACBY/hyWCOafamM/CQb5kYZ0FZY4R1HkKNyf60/img.png?width=2032&amp;amp;height=1167&amp;amp;face=0_0_2032_1167&quot;&gt;&lt;a href=&quot;https://floodnut.tistory.com/120&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://floodnut.tistory.com/120&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/bQPwYB/hyWCDGx5lZ/lG9TVEhYpdaZnbTBxiAzc1/img.jpg?width=320&amp;amp;height=320&amp;amp;face=0_0_320_320,https://scrap.kakaocdn.net/dn/VCgrE/hyWCNvBWzS/KAPm4BeWgTkNGn7ckNvnKK/img.jpg?width=320&amp;amp;height=320&amp;amp;face=0_0_320_320,https://scrap.kakaocdn.net/dn/daACBY/hyWCOafamM/CQb5kYZ0FZY4R1HkKNyf60/img.png?width=2032&amp;amp;height=1167&amp;amp;face=0_0_2032_1167');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;[서비스메시] Istio, Envoy&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;서비스 메시, Istio와 Envoy서비스 메시는 주로 분산 아키텍처에서 각 소프트웨어 컴포넌트 간의 네트워킹을 관리한다.특히 쿠버네티스 환경에서 마이크로서비스 간의 상호 연결을 관리하고, 그에&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;www.floodnut.com&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 생겼던 문제가 4대의 노드 중 arm64 노드에 파드가 생성되면 아키텍처 차이로 파드가 계속 죽는다.&lt;/p&gt;
&lt;pre class=&quot;gauss&quot;&gt;&lt;code&gt;exec format error&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;컨테이너 이미지&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최근에야 멀티 아키텍처를 지원하는 컨테이너 이미지가 많아지면서 큰 문제는 안보이지만 지금 테스트 하는 이미지는 그렇지 않았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래에서 Jaeger로 예시를 들지만 요렇게 버전에 따른 차이를 볼 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-07-21 오전 3.05.40.png&quot; data-origin-width=&quot;1136&quot; data-origin-height=&quot;180&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/UYPD6/btsIHbEyKEO/5JJeaHC0bhoP2IsLgxcZhK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/UYPD6/btsIHbEyKEO/5JJeaHC0bhoP2IsLgxcZhK/img.png&quot; data-alt=&quot;amd64(x86)만 지원하는 jaeger 1.14&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/UYPD6/btsIHbEyKEO/5JJeaHC0bhoP2IsLgxcZhK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FUYPD6%2FbtsIHbEyKEO%2F5JJeaHC0bhoP2IsLgxcZhK%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;1136&quot; height=&quot;180&quot; data-filename=&quot;스크린샷 2024-07-21 오전 3.05.40.png&quot; data-origin-width=&quot;1136&quot; data-origin-height=&quot;180&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;amd64(x86)만 지원하는 jaeger 1.14&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-07-21 오전 3.05.18.png&quot; data-origin-width=&quot;1130&quot; data-origin-height=&quot;282&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MX3Qr/btsIGuEZ5dl/uaKh98idR5vnHlWtajPdZ0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MX3Qr/btsIGuEZ5dl/uaKh98idR5vnHlWtajPdZ0/img.png&quot; data-alt=&quot;여러 아키텍처를 지원하는 jaeger 1.59&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MX3Qr/btsIGuEZ5dl/uaKh98idR5vnHlWtajPdZ0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMX3Qr%2FbtsIGuEZ5dl%2FuaKh98idR5vnHlWtajPdZ0%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;1130&quot; height=&quot;282&quot; data-filename=&quot;스크린샷 2024-07-21 오전 3.05.18.png&quot; data-origin-width=&quot;1130&quot; data-origin-height=&quot;282&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;여러 아키텍처를 지원하는 jaeger 1.59&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Envoy 같은 경우도 확인해보면 v1.11는 amd64만 지원한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;v1.16 부터 arm64도 함께 지원하면서 해당 이미지를 사용했다.&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;엥? 그러면 그냥 최신 이미지 사용하면 거의 문제 없는거 아냐?&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라고 생각했었는데 이번에 Envoy 하면서 조금 바뀌었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;정확한 차이는 모르지만 Prometheus도 v1과 v2의 config 설정이 다르다고 들었고, Envoy도 버전이 올라가면서 http filter가 v2가 아닌 v3를 사용하게 하는 경우가 생긴다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이런식으로 내가 테스트하려는 버전과 최신 버전이 항상 동일한 기능을 제공한다고 볼 수가 없었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하위호환을 지원하는 경우라면 좋겠지만 그냥 바로 deprecate 시켜버렸다면...&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&amp;nbsp;&lt;/h3&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;노드에 Label 추가&lt;/b&gt;&lt;/h3&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 사실 큰 작업을 한 것은 아니고 앞으로 배포할 파드에 nodeSelector를 좀 더 잘 명시해보기로 했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이를 위해서 다음과 같이 전체 노드에 대해서 label을 추가했다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;k label nodes arm64-****** arch=arm64 gpu=false 
k label nodes x8664-****** arch=x8664 gpu=false 
# ...&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;전체 노드를 컨벤션에 맞춰서 &lt;b&gt;{architecture}-{resources}-{unique-string}&lt;/b&gt; 요렇게 관리하고 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 노드 식별 자체는 쉬웠고, 파드가 앞으로 노드를 잘 선택해서 배포되면 편하겠다 싶었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Envoy로 예시를 들었지만, Jaeger나 Kiali도 마찬가지였다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그래서 요렇게 앞으로 &lt;b&gt;nodeSelector&lt;/b&gt;를 잘 이용해보고자 한다.&lt;/p&gt;
&lt;pre class=&quot;dts&quot;&gt;&lt;code&gt;spec:
  nodeSelector:
    arch: &quot;x8664&quot;
# ...&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;k get pods -n istio-system

# ...
jaeger-68f8fb4676-n9qgt                1/1     Running   0          156m
kiali-7b54d865d-7vqwr                  1/1     Running   0          156m&lt;/code&gt;&lt;/pre&gt;</description>
      <category>DevOps, 클라우드/Container</category>
      <author>Floodnut</author>
      <guid isPermaLink="true">https://floodnut.tistory.com/121</guid>
      <comments>https://floodnut.tistory.com/121#entry121comment</comments>
      <pubDate>Sun, 21 Jul 2024 03:22:45 +0900</pubDate>
    </item>
    <item>
      <title>[서비스메시] Istio, Envoy</title>
      <link>https://floodnut.tistory.com/120</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;서비스 메시, Istio와 Envoy&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서비스 메시는 주로 분산 아키텍처에서 각 &lt;b&gt;소프트웨어 컴포넌트 간의 네트워킹을 관리&lt;/b&gt;한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특히 쿠버네티스 환경에서 마이크로서비스 간의 상호 연결을 관리하고, 그에 대한 가시성을 제공한다.&lt;/li&gt;
&lt;li&gt;기본 쿠버네티스 기능만으로는 어렵다.&lt;/li&gt;
&lt;li&gt;서비스 메시를 사용하면 네트워크 트래픽을 경유하는 다양한 로직을 구성할 수 있다.&lt;/li&gt;
&lt;li&gt;이를 통해 원격 측정, 보안, 트래픽 관리 등 여러 기능을 구현 가능하다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Istio는 각 파드에 프록시 컨테이너를 주입하여 네트워크 요청을 관리한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;프록시는 네트워크 호출을 가로채어 서비스 메시의 로직을 적용하고, 이를 대상 컨테이너로 전달한다.&lt;/li&gt;
&lt;li&gt;이 과정에서 Istio는 원격 측정 데이터를 수집하고, 호출 체인을 추적한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Istio의 구성 요소는 크게 &lt;b&gt;데이터 플레인&lt;/b&gt;과 &lt;b&gt;컨트롤 플레인&lt;/b&gt;으로 나뉜다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데이터 플레인은 각 파드에 주입되는 프록시를 포함하며, 컨트롤 플레인은 Istio 시스템 자체를 실행하는 파드들로 구성된다.&lt;/li&gt;
&lt;li&gt;최신 버전의 Istio에서는 Istio Daemon 파드가 대부분의 기능 담당한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-07-13 오후 6.14.57.png&quot; data-origin-width=&quot;557&quot; data-origin-height=&quot;174&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/MNjzt/btsIy2f7T4n/kCDNUqQmuayRFO9yHj8gE1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/MNjzt/btsIy2f7T4n/kCDNUqQmuayRFO9yHj8gE1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/MNjzt/btsIy2f7T4n/kCDNUqQmuayRFO9yHj8gE1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FMNjzt%2FbtsIy2f7T4n%2FkCDNUqQmuayRFO9yHj8gE1%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;557&quot; height=&quot;174&quot; data-filename=&quot;스크린샷 2024-07-13 오후 6.14.57.png&quot; data-origin-width=&quot;557&quot; data-origin-height=&quot;174&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;p data-ke-size=&quot;size16&quot;&gt;Istio는 여러 서비스 메시 구현 중 하나로, 프록시를 이용하여 &lt;b&gt;서비스 간 통신을 관리&lt;/b&gt;하는 역할을 한다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Istio는 Envoy 프록시를 기본 사이드카 컨테이너로서 구현하여, 특정 컨테이너가 클러스터 내 다른 컨테이너를 호출할 때 이를 프록시를 통해 라우팅한다.&lt;/li&gt;
&lt;li&gt;Istio는 Kubernetes의 커스텀 리소스 정의를 통해 Envoy를 설정하고 관리하며, 사용자는 일반적인 Kubernetes YAML을 사용하여 Istio를 구성할 수 있다.&lt;/li&gt;
&lt;li&gt;Istio를 사용하는 주된 이유는, Envoy를 직접 다루는 것보다 훨씬 편리하고 추상화된 서비스 메시 기능을 제공하기 때문이다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Envoy Demo 구성 파일&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;admin:
  access_log_path: /tmp/admin_access.log
  address:
    socket_address:
      protocol: TCP
      address: 0.0.0.0
      port_value: 9901 # Admin Endpoint Port
static_resources:
  listeners:
  - name: listener_0
    address:
      socket_address:
        protocol: TCP
        address: 0.0.0.0
        port_value: 10000 # 임의의 Envoy Listener Port(http)
    filter_chains:
    - filters:
      - name: envoy.http_connection_manager
        typed_config:
          &quot;@type&quot;: type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager
          stat_prefix: ingress_http
          route_config:
            name: api_and_internal_split_routing
            virtual_hosts:
            - name: backend
              domains: [&quot;*&quot;]
              routes:
              - match:
                  prefix: &quot;/api&quot;
                route:
                  cluster: service_api
                  prefix_rewrite: &quot;/&quot;
                  host_rewrite: &quot;www.google.com&quot;
          http_filters:
          - name: envoy.router
  clusters: # grouping 된 타겟, K8s Cluster가 아님
  - name: service_api
    connect_timeout: 10s
    type: STRICT_DNS
    # Comment out the following line to test on v6 networks
    dns_lookup_family: V4_ONLY
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: service_api
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: www.google.com
                port_value: 443
    tls_context:
      sni: www.google.com&lt;/code&gt;&lt;/pre&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;envoy 내장 필터 체인으로 envoy.http_connection_manager 를 사용한다.&lt;/li&gt;
&lt;li&gt;이 필터 체인의 proto 스키마는 다음과 같다.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;해당 필터는 envoy 내장 TCP 필터이며 http에 대한 스펙을 정의하고 있다.&lt;/li&gt;
&lt;li&gt;가상 호스트로 prefix-matching을 사용하고 있으며 reverse-proxy로 들어온 요청을 rewrite 하고 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-07-13 오후 4.54.54.png&quot; data-origin-width=&quot;2032&quot; data-origin-height=&quot;1167&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bk8FK5/btsIybrAJQZ/iTfLqOuTHZU8FPbHp3EbD1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bk8FK5/btsIybrAJQZ/iTfLqOuTHZU8FPbHp3EbD1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bk8FK5/btsIybrAJQZ/iTfLqOuTHZU8FPbHp3EbD1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2Fbk8FK5%2FbtsIybrAJQZ%2FiTfLqOuTHZU8FPbHp3EbD1%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;2032&quot; height=&quot;1167&quot; data-filename=&quot;스크린샷 2024-07-13 오후 4.54.54.png&quot; data-origin-width=&quot;2032&quot; data-origin-height=&quot;1167&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;그래서 위 리버스 프록시에서 /api 로 접근하는 http 요청에 대해서 호스트를 &lt;a href=&quot;http://www.google.com%EC%9C%BC%EB%A1%9C&quot;&gt;www.google.com으로&lt;/a&gt; 라우팅해준다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-07-13 오후 4.58.50.png&quot; data-origin-width=&quot;2032&quot; data-origin-height=&quot;1167&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/RNnr2/btsIyzr1SAU/o5v13UQiF3beeVoMkamupk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/RNnr2/btsIyzr1SAU/o5v13UQiF3beeVoMkamupk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/RNnr2/btsIyzr1SAU/o5v13UQiF3beeVoMkamupk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FRNnr2%2FbtsIyzr1SAU%2Fo5v13UQiF3beeVoMkamupk%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;2032&quot; height=&quot;1167&quot; data-filename=&quot;스크린샷 2024-07-13 오후 4.58.50.png&quot; data-origin-width=&quot;2032&quot; data-origin-height=&quot;1167&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;어드민 페이지는 요렇게 정의한 9901 포트로 접근해 확인할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Envoy v2와 v3 스펙 차이&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;1.16.x 버전까지의 envoy는 필터 체인에서 v2의 내장 tcp(http) 스키마를 사용할 수 있다.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;데모에서 제공하는 http_connection_manager 가 v2의 구현체다.&lt;/li&gt;
&lt;li&gt;근데, 1.17 부터는 v3를 extension 형태로 지원한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;v2 정적 리소스 스펙&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;json&quot;&gt;&lt;code&gt;{
  &quot;codec_type&quot;: &quot;...&quot;,
  &quot;stat_prefix&quot;: &quot;...&quot;,
  &quot;rds&quot;: &quot;{...}&quot;,
  &quot;route_config&quot;: &quot;{...}&quot;,
  &quot;scoped_routes&quot;: &quot;{...}&quot;,
  &quot;http_filters&quot;: [],
  &quot;add_user_agent&quot;: &quot;{...}&quot;,
  &quot;tracing&quot;: &quot;{...}&quot;,
  &quot;common_http_protocol_options&quot;: &quot;{...}&quot;,
  &quot;http_protocol_options&quot;: &quot;{...}&quot;,
  &quot;http2_protocol_options&quot;: &quot;{...}&quot;,
  &quot;server_name&quot;: &quot;...&quot;,
  &quot;server_header_transformation&quot;: &quot;...&quot;,
  &quot;max_request_headers_kb&quot;: &quot;{...}&quot;,
  &quot;idle_timeout&quot;: &quot;{...}&quot;,
  &quot;stream_idle_timeout&quot;: &quot;{...}&quot;,
  &quot;request_timeout&quot;: &quot;{...}&quot;,
  &quot;drain_timeout&quot;: &quot;{...}&quot;,
  &quot;delayed_close_timeout&quot;: &quot;{...}&quot;,
  &quot;access_log&quot;: [],
  &quot;use_remote_address&quot;: &quot;{...}&quot;,
  &quot;xff_num_trusted_hops&quot;: &quot;...&quot;,
  &quot;internal_address_config&quot;: &quot;{...}&quot;,
  &quot;skip_xff_append&quot;: &quot;...&quot;,
  &quot;via&quot;: &quot;...&quot;,
  &quot;generate_request_id&quot;: &quot;{...}&quot;,
  &quot;preserve_external_request_id&quot;: &quot;...&quot;,
  &quot;forward_client_cert_details&quot;: &quot;...&quot;,
  &quot;set_current_client_cert_details&quot;: &quot;{...}&quot;,
  &quot;proxy_100_continue&quot;: &quot;...&quot;,
  &quot;upgrade_configs&quot;: [],
  &quot;normalize_path&quot;: &quot;{...}&quot;,
  &quot;merge_slashes&quot;: &quot;...&quot;,
  &quot;request_id_extension&quot;: &quot;{...}&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;b&gt;v3 정적 리소스 스펙&lt;/b&gt;&lt;/h3&gt;
&lt;pre class=&quot;nimrod&quot;&gt;&lt;code&gt;{
  &quot;codec_type&quot;: ...,
  &quot;stat_prefix&quot;: ...,
  &quot;rds&quot;: {...},
  &quot;route_config&quot;: {...},
  &quot;scoped_routes&quot;: {...},
  &quot;http_filters&quot;: [],
  &quot;add_user_agent&quot;: {...},
  &quot;tracing&quot;: {...},
  &quot;common_http_protocol_options&quot;: {...},
  &quot;http_protocol_options&quot;: {...},
  &quot;http2_protocol_options&quot;: {...},
  &quot;server_name&quot;: ...,
  &quot;server_header_transformation&quot;: ...,
  &quot;scheme_header_transformation&quot;: {...},
  &quot;max_request_headers_kb&quot;: {...},
  &quot;stream_idle_timeout&quot;: {...},
  &quot;request_timeout&quot;: {...},
  &quot;request_headers_timeout&quot;: {...},
  &quot;drain_timeout&quot;: {...},
  &quot;delayed_close_timeout&quot;: {...},
  &quot;access_log&quot;: [],
  &quot;access_log_flush_interval&quot;: {...},
  &quot;flush_access_log_on_new_request&quot;: ...,
  &quot;access_log_options&quot;: {...},
  &quot;use_remote_address&quot;: {...},
  &quot;xff_num_trusted_hops&quot;: ...,
  &quot;original_ip_detection_extensions&quot;: [],
  &quot;early_header_mutation_extensions&quot;: [],
  &quot;internal_address_config&quot;: {...},
  &quot;skip_xff_append&quot;: ...,
  &quot;via&quot;: ...,
  &quot;generate_request_id&quot;: {...},
  &quot;preserve_external_request_id&quot;: ...,
  &quot;always_set_request_id_in_response&quot;: ...,
  &quot;forward_client_cert_details&quot;: ...,
  &quot;set_current_client_cert_details&quot;: {...},
  &quot;proxy_100_continue&quot;: ...,
  &quot;upgrade_configs&quot;: [],
  &quot;normalize_path&quot;: {...},
  &quot;merge_slashes&quot;: ...,
  &quot;path_with_escaped_slashes_action&quot;: ...,
  &quot;request_id_extension&quot;: {...},
  &quot;local_reply_config&quot;: {...},
  &quot;strip_matching_host_port&quot;: ...,
  &quot;strip_any_host_port&quot;: ...,
  &quot;stream_error_on_invalid_http_message&quot;: {...},
  &quot;strip_trailing_host_dot&quot;: ...,
  &quot;proxy_status_config&quot;: {...},
  &quot;append_x_forwarded_port&quot;: ...,
  &quot;append_local_overload&quot;: ...,
  &quot;add_proxy_protocol_connection_state&quot;: {...}
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;v2 http 라우터와 v3 http 라우터에는 차이가 존재한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 공식 docs에서 제공하는 v2 라우팅 스펙과 v3 라우팅 스펙를 보면 필터 설정에 대한 차이를 볼 수 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style2&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;v2: envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager&lt;br /&gt;v3: envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;typed_config:
  &quot;@type&quot;: type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager
  stat_prefix: ingress_http
  route_config:
    name: api_and_internal_split_routing
    virtual_hosts:
    - name: backend
      domains: [&quot;*&quot;]
      routes:
      - match:
          prefix: &quot;/api&quot;
        route:
          cluster: service_api
          prefix_rewrite: &quot;/&quot;
          host_rewrite: &quot;www.google.com&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞서 작성한 demo config에서의 차이를 보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;v2 route-config에서는 host_rewite 를 통해서 라우팅할 호스트를 지정하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이에 대한 공식 docs를 보면 다음과 같은 설명이 있다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;host_rewrite&lt;/b&gt;&lt;br /&gt;&lt;i&gt;(string) Indicates that during forwarding, the host header will be swapped with this value. Only one of host_rewrite, auto_host_rewrite, auto_host_rewrite_header may be set.&lt;/i&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그니까&amp;hellip; &lt;b&gt;host_rewrite,&lt;/b&gt; &lt;b&gt;auto_host_rewrite&lt;/b&gt;, &lt;b&gt;auto_host_rewrite_header&lt;/b&gt; 중 하나의 필드를 통해서 호스트를 필수적으로 지정해야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;그런데 v3 route-config에서는 host_rewrite 를 지원하지 않는다.&lt;br /&gt;host_rewrite를 대체 할 수 있는 필드는 &lt;a href=&quot;https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-host-rewrite-literal&quot;&gt;host_rewrite_literal&lt;/a&gt;, &lt;a href=&quot;https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-auto-host-rewrite&quot;&gt;auto_host_rewrite&lt;/a&gt;, &lt;a href=&quot;https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-host-rewrite-header&quot;&gt;host_rewrite_header&lt;/a&gt;, &lt;a href=&quot;https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-host-rewrite-path-regex&quot;&gt;host_rewrite_path_regex&lt;/a&gt; 뿐이다.&lt;/p&gt;
&lt;blockquote data-ke-style=&quot;style1&quot;&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;host_rewrite_literal&lt;/b&gt;&lt;br /&gt;&lt;i&gt;(&lt;a href=&quot;https://developers.google.com/protocol-buffers/docs/proto#scalar&quot;&gt;string&lt;/a&gt;) Indicates that during forwarding, the host header will be swapped with this value. Using this option will append the &lt;a href=&quot;https://www.envoyproxy.io/docs/envoy/latest/configuration/http/http_conn_man/headers#config-http-conn-man-headers-x-forwarded-host&quot;&gt;x-forwarded-host&lt;/a&gt; header if &lt;a href=&quot;https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-append-x-forwarded-host&quot;&gt;append_x_forwarded_host&lt;/a&gt; is set. Only one of &lt;a href=&quot;https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-host-rewrite-literal&quot;&gt;host_rewrite_literal&lt;/a&gt;, &lt;a href=&quot;https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-auto-host-rewrite&quot;&gt;auto_host_rewrite&lt;/a&gt;, &lt;a href=&quot;https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-host-rewrite-header&quot;&gt;host_rewrite_header&lt;/a&gt;, &lt;a href=&quot;https://www.envoyproxy.io/docs/envoy/latest/api-v3/config/route/v3/route_components.proto#envoy-v3-api-field-config-route-v3-routeaction-host-rewrite-path-regex&quot;&gt;host_rewrite_path_regex&lt;/a&gt; may be set.&lt;/i&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라우팅 스펙이 변경되면서 내장된 필터 스펙도 변경된다.&lt;br /&gt;우리는 아래의 처럼 envoy의 내장 router를 바로 사용했었다.&lt;br /&gt;그렇지만, v3에서는 filter에 내장된 tcp 라우터 중 http 라우터를 선택하고 그 구현체를 직접 정의해야 한다.&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;# v2
http_filters:
- name: envoy.router&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;vim&quot;&gt;&lt;code&gt;# v3
http_filters:
- name: envoy.filters.http.router
  typed_config:
   &quot;@type&quot;: type.googleapis.com/envoy.extensions.filters.http.router.v3.Router&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클러스터 스펙도 함께 확인해보자.&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;마찬가지로 tls_contex 에서 단순하게 Server Name Indication만 정의했던 v2다.&lt;/li&gt;
&lt;li&gt;그렇지만, v3에서는 transport_socket 레벨에서 그 구현체를 정의하도록 변경되었다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;# v2
  clusters: # grouping 된 타겟, K8s Cluster가 아님
  - name: service_api
    connect_timeout: 10s
    type: STRICT_DNS
    # Comment out the following line to test on v6 networks
    dns_lookup_family: V4_ONLY
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: service_api
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: www.google.com
                port_value: 443
    tls_context:
      sni: www.google.com&lt;/code&gt;&lt;/pre&gt;
&lt;pre class=&quot;vim&quot;&gt;&lt;code&gt;# v3
    transport_socket:
      name: envoy.transport_sockets.tls
      typed_config:
        &quot;@type&quot;: type.googleapis.com/envoy.extensions.transport_sockets.tls.v3.UpstreamTlsContext
        sni: www.google.com&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;결론&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨테이너 오케스트레이션을 접하다보면 늘 서비스 디스커버리, 서비스 메시, 프록시가 함께 따라다니더라.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이번에 서비스 메시가 좀 궁금해져서 제일 많이 노출되는 Istio를 공부해보기 시작했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;간단한 개념과 프록시 설정법만 확인해봤는데 버전 별 스펙이 다른데 설정할 값도 많아서 좀 신경써서 구축해야겠다 싶다.&lt;/p&gt;</description>
      <category>DevOps, 클라우드/Service Mesh</category>
      <category>envoy</category>
      <category>istio</category>
      <author>Floodnut</author>
      <guid isPermaLink="true">https://floodnut.tistory.com/120</guid>
      <comments>https://floodnut.tistory.com/120#entry120comment</comments>
      <pubDate>Sat, 13 Jul 2024 18:24:22 +0900</pubDate>
    </item>
    <item>
      <title>[HomeLab] Tailscale 을 쿠버네티스에 배포하기</title>
      <link>https://floodnut.tistory.com/119</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;서론&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인터넷에서 내 클러스터로 들어오는 인바운드는 모두 허용할 수 없었다.&lt;br /&gt;외부에 노출시킬 서비스를 제외하고는 VPN 등을 통해서 접근하게 해야했다.&lt;br /&gt;기존에는 Tailscale을 통해 각 노드에 직접 접근했으나 Calico와의 충돌 문제가 있었다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Tailscale은 쿠버네티스에 배포할 수 있다.&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이게 무슨 소리냐면 VPN 대역에서만 접근할 수 있는 Tailscale 서비스를 클러스터에 배포할 수 있다는 뜻이다.&lt;br /&gt;내 사설망에 일종의 VPN Ingress-Controller가 생기는 셈이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;배포 유형은 3가지를 지원한다고 한다.&lt;/p&gt;
&lt;ol style=&quot;list-style-type: decimal;&quot; data-ke-list-type=&quot;decimal&quot;&gt;
&lt;li&gt;프록시
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;Tailscale 프록시를 통해서 쿠버네티스 서비스와 통신할 수 있도록 해준다.&lt;/li&gt;
&lt;li&gt;다만, 통신하려는 '서비스' 외에 다른 쿠버네티스 리소스에 접근하거나 제어할 수 없다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;사이드카
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;특정 파드에 사이드카 형태로 배포한다.&lt;/li&gt;
&lt;li&gt;VPN 대역에서 파드를 토출할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;서브넷 라우터
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;쿠버네티스 클러스터 네트워크 전체를 VPN 대역에 노출한다.&lt;/li&gt;
&lt;li&gt;쿠버네티스 네트워크 정책이나 Tailscale의 접근 제어가 허용한다면 클러스터의 모든 포드 또는 서비스에 연결할 수 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같은 배포 유형 중 어떤 배포 방식을 선택할지 고민했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 (2.) 사이드카 방식의 경우, 작은 규모의 클러스터에 불필요한 부하를 더 줄 것이라 판단했다.&lt;br /&gt;(1.) 프록시 방식은 내가 가진 규모의 클러스터에서 좀 더 모범 사례에 가까울 것 같았다.&lt;br /&gt;다만, 아직 설정할 것이 많고 이미 구축된 서비스 외에 외부에서 접근할 일이 있다면 (3.) 서브넷 라우터가 좀 더 적합한 방식일 것이라 판단했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Tailscale를 쿠버네티스 클러스터에 배포하기&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-07-05 오전 12.14.54.png&quot; data-origin-width=&quot;909&quot; data-origin-height=&quot;128&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/wdBQl/btsIo7iVvNL/T4a4eYsXi5vJEeDtOzoLDK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/wdBQl/btsIo7iVvNL/T4a4eYsXi5vJEeDtOzoLDK/img.png&quot; data-alt=&quot;Tailscale 관리자 콘솔&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/wdBQl/btsIo7iVvNL/T4a4eYsXi5vJEeDtOzoLDK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwdBQl%2FbtsIo7iVvNL%2FT4a4eYsXi5vJEeDtOzoLDK%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;909&quot; height=&quot;128&quot; data-filename=&quot;스크린샷 2024-07-05 오전 12.14.54.png&quot; data-origin-width=&quot;909&quot; data-origin-height=&quot;128&quot;/&gt;&lt;/span&gt;&lt;figcaption&gt;Tailscale 관리자 콘솔&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우선 Tailscale에서 인증키를 발급받자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;관리자 콘솔에서 &lt;code&gt;Settings&lt;/code&gt; 탭을 누르면 좌측의 &lt;code&gt;Key&lt;/code&gt; 메뉴에서 인증키를 발급 받을 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;우리의 클러스터에는 외부에 노출되지 않은 서비스가 있다고 가정한다.&lt;/p&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:latest
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginxapp
spec:
  selector:
    app: nginx
  ports:
    - port: 80
      targetPort: 80&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성한 키를 쿠버네티스의 시크릿 리소스로 생성한다.&lt;/p&gt;
&lt;pre class=&quot;routeros&quot;&gt;&lt;code&gt;apiVersion: v1
kind: Secret
metadata:
  name: ts_key
type: Opaque
data:
  TAILSCALE_KEY: &amp;lt;YOUR_BASE64_ENCODED_TAILSCALE_KEY&amp;gt;
# 평문 키를 사용할 경우
# stringData: 
#   TAILSCALE_KEY: &amp;lt;YOUR_PLAIN_TAILSCALE_KEY&amp;gt;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;앞서 등록한 시크릿 키를 활용하는 서비스 어카운트를 생성한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;br /&gt;Tailscale 파드는 서비스 어카운트에 접근해 인증할 때 시크릿 키를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 서비스 어카운트로 Tailscale 파드를 동작시키며 RBAC에서 허용된 권한으로 클러스터에 접근할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;현재의 Role을 살펴보면...&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;ts_key&lt;/code&gt; 시크릿 리소스에 대한 일부 read/write 권한을 허용한다.&lt;/li&gt;
&lt;li&gt;이 Role은 &lt;code&gt;tailscale&lt;/code&gt; 서비스 어카운트에 붙어있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class=&quot;yaml&quot;&gt;&lt;code&gt;apiVersion: v1
kind: ServiceAccount
metadata:
  name: tailscale
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: tailscale
rules:
  - apiGroups: [&quot;&quot;]
    resourceNames: [&quot;ts_key&quot;]
    resources: [&quot;secrets&quot;]
    verbs: [&quot;get&quot;, &quot;update&quot;, &quot;patch&quot;]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: tailscale
subjects:
  - kind: ServiceAccount
    name: tailscale
roleRef:
  kind: Role
  name: tailscale
  apiGroup: rbac.authorization.k8s.io&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제는 Tailscale 파드를 배포하자.&lt;br /&gt;앞서 말한 것처럼 서브넷 라우터 방식으로 배포할 것이다.&lt;/p&gt;
&lt;pre class=&quot;less&quot;&gt;&lt;code&gt;apiVersion: v1
kind: Pod
metadata:
  name: tailscale-subnet
spec:
  serviceAccountName: tailscale
  containers:
    - name: tailscale
      image: ghcr.io/tailscale/tailscale:v1.68.1
      env:
        - name: TS_KUBE_SECRET
          value: ts_key
        - name: TAILSCALE_KEY
          valueFrom:
            secretKeyRef:
              name: ts_key
              key: TAILSCALE_KEY
        - name: TS_ROUTES
          value: &quot;&amp;lt;POD_CIDR&amp;gt;,&amp;lt;SERVICE_CIDR&amp;gt;&quot;
        - name: TS_USERSPACE
          value: &quot;true&quot;
      securityContext:
        runAsUser: 1000
        runAsGroup: 1000
      resources:
        limits:
          memory: 512Mi
          cpu: &quot;1&quot;
        requests:
          memory: 256Mi
          cpu: &quot;0.2&quot;&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;여기서 각 env를 살펴보면 다음과 같다.&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;TAILSCALE_KEY&lt;/code&gt;: 먼저 등록한 tailscale 시크릿이다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;TS_ROUTES&lt;/code&gt;: CNI가 지원하는 Pod 대역, 서비스 대역을 콤마로 구분한 문자열이다.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;TS_USERSPACE&lt;/code&gt;: tailscale이 유저공간 네트워킹을 사용하도록 한다.&lt;/li&gt;
&lt;/ul&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;위와 같이 파드를 배포하고 확인해보면 다음과 같이 &lt;code&gt;tailscale-subnet&lt;/code&gt; 파드가 생성된 것을 확인할 수 있다.&lt;br /&gt;지금은 namespace를 설정하지 않아서 default ns에 생성되었다.&lt;/p&gt;
&lt;pre class=&quot;angelscript&quot;&gt;&lt;code&gt;kubectl  apply -f tailscale.deployment.yaml
pod/tailscale-subnet created

kubectl get pods 
NAME               READY   STATUS   RESTARTS      AGE
tailscale-subnet   1/1     Running  1 (68s ago)   2m21s&lt;/code&gt;&lt;/pre&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Tailscale 콘솔에서 라우팅 설정하기&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 Tailscale 관리자 콘솔에서 Machine 목록을 확인하면 서브넷 라우터로 배포한 `tailscale-subnet` 파드가 등록된 것을 확인할 수 있다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-07-06 오후 1.24.42.png&quot; data-origin-width=&quot;223&quot; data-origin-height=&quot;130&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/dHW5UQ/btsIpVB3skE/OKPueIvWL5I8o6yG13byq0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/dHW5UQ/btsIpVB3skE/OKPueIvWL5I8o6yG13byq0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/dHW5UQ/btsIpVB3skE/OKPueIvWL5I8o6yG13byq0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FdHW5UQ%2FbtsIpVB3skE%2FOKPueIvWL5I8o6yG13byq0%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;223&quot; height=&quot;130&quot; data-filename=&quot;스크린샷 2024-07-06 오후 1.24.42.png&quot; data-origin-width=&quot;223&quot; data-origin-height=&quot;130&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 라우팅 설정을 하기 위해 해당 머신(파드)의 라우팅 설정에 들어간다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라우팅 설정에는 앞서 `TSROUTE` 로 설정한 파드 CIDR 대역과 서비스 CIDR 대역이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 대역으로 라우팅을 허용하자.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-07-06 오후 1.27.02.png&quot; data-origin-width=&quot;234&quot; data-origin-height=&quot;408&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/cECEfh/btsIpXfvI09/KIQc6NHKY6MPvFKBNoLkm1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/cECEfh/btsIpXfvI09/KIQc6NHKY6MPvFKBNoLkm1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/cECEfh/btsIpXfvI09/KIQc6NHKY6MPvFKBNoLkm1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FcECEfh%2FbtsIpXfvI09%2FKIQc6NHKY6MPvFKBNoLkm1%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;234&quot; height=&quot;408&quot; data-filename=&quot;스크린샷 2024-07-06 오후 1.27.02.png&quot; data-origin-width=&quot;234&quot; data-origin-height=&quot;408&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-07-06 오후 1.27.12.png&quot; data-origin-width=&quot;495&quot; data-origin-height=&quot;500&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5lNjO/btsIqA5ccFi/wcp6QT8p3AqAujQyeMYGw0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5lNjO/btsIqA5ccFi/wcp6QT8p3AqAujQyeMYGw0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5lNjO/btsIqA5ccFi/wcp6QT8p3AqAujQyeMYGw0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5lNjO%2FbtsIqA5ccFi%2Fwcp6QT8p3AqAujQyeMYGw0%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;495&quot; height=&quot;500&quot; data-filename=&quot;스크린샷 2024-07-06 오후 1.27.12.png&quot; data-origin-width=&quot;495&quot; data-origin-height=&quot;500&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;Cluster-IP로 배포된 Internal 서비스 접근하기&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;라우팅 설정까지 완료하면 우린 서비스의 Cluster-IP로 접근할 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;물론 Tailscale VPN을 켜야한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-07-06 오후 1.51.51.png&quot; data-origin-width=&quot;2032&quot; data-origin-height=&quot;1167&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bXmujl/btsIpHD3sUr/hbKC8Us7C9zmZLw4tXVRBk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bXmujl/btsIpHD3sUr/hbKC8Us7C9zmZLw4tXVRBk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bXmujl/btsIpHD3sUr/hbKC8Us7C9zmZLw4tXVRBk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbXmujl%2FbtsIpHD3sUr%2FhbKC8Us7C9zmZLw4tXVRBk%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;2032&quot; height=&quot;1167&quot; data-filename=&quot;스크린샷 2024-07-06 오후 1.51.51.png&quot; data-origin-width=&quot;2032&quot; data-origin-height=&quot;1167&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-filename=&quot;스크린샷 2024-07-06 오후 1.37.58.png&quot; data-origin-width=&quot;1161&quot; data-origin-height=&quot;267&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/whCpb/btsIoRUVAVL/AP8flxxfbLUQ7fdlNk6sR0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/whCpb/btsIoRUVAVL/AP8flxxfbLUQ7fdlNk6sR0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/whCpb/btsIoRUVAVL/AP8flxxfbLUQ7fdlNk6sR0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FwhCpb%2FbtsIoRUVAVL%2FAP8flxxfbLUQ7fdlNk6sR0%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;1161&quot; height=&quot;267&quot; data-filename=&quot;스크린샷 2024-07-06 오후 1.37.58.png&quot; data-origin-width=&quot;1161&quot; data-origin-height=&quot;267&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;내부에서만 접근할 ArgoCD 서비스를 VPN를 통해서만 접근할 수 있도록 설정했다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;VPN 자체도 구축해보고 싶었는데 우선 편의성과 내 시간을 지키기 위해서 이 방법을 선택했다.&lt;/p&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&amp;nbsp;&lt;/h2&gt;
&lt;h2 data-ke-size=&quot;size26&quot;&gt;&lt;b&gt;참고&lt;/b&gt;&lt;/h2&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://tailscale.com/learn/managing-access-to-kubernetes-with-tailscale&quot;&gt;https://tailscale.com/learn/managing-access-to-kubernetes-with-tailscale&lt;/a&gt;&lt;/p&gt;</description>
      <category>DevOps, 클라우드/Container</category>
      <author>Floodnut</author>
      <guid isPermaLink="true">https://floodnut.tistory.com/119</guid>
      <comments>https://floodnut.tistory.com/119#entry119comment</comments>
      <pubDate>Fri, 5 Jul 2024 00:52:19 +0900</pubDate>
    </item>
  </channel>
</rss>