<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>kubernetes &#8211; WONIZZ.LOG</title>
	<atom:link href="https://blog.wonizz.com/category/tech/kubernetes/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.wonizz.com</link>
	<description>DEVELOPMENT &#38; LIFE LOG</description>
	<lastBuildDate>Fri, 21 Aug 2026 15:44:31 +0000</lastBuildDate>
	<language>ko-KR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=7.0.2</generator>

<image>
	<url>https://i0.wp.com/blog.wonizz.com/wp-content/uploads/2026/08/wz-siteicon-512.png?fit=32%2C32&#038;ssl=1</url>
	<title>kubernetes &#8211; WONIZZ.LOG</title>
	<link>https://blog.wonizz.com</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">152411368</site>	<item>
		<title>[DevOps] Kubernetes HPA 실전 적용</title>
		<link>https://blog.wonizz.com/2024/07/24/devops-kubernetes-hpa/</link>
					<comments>https://blog.wonizz.com/2024/07/24/devops-kubernetes-hpa/#respond</comments>
		
		<dc:creator><![CDATA[워니]]></dc:creator>
		<pubDate>Wed, 24 Jul 2024 10:14:53 +0000</pubDate>
				<category><![CDATA[Tech]]></category>
		<category><![CDATA[kubernetes]]></category>
		<guid isPermaLink="false">https://blog.wonizz.com/?p=2278</guid>

					<description><![CDATA[<p>The standard Lorem Ipsum passage, used since the 1500s<br />
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."</p>
<p>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"</p>
<p>1914 translation by H. Rackham<br />
"But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?"</p>
<p>Section 1.10.33 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."</p>
<p>1914 translation by H. Rackham<br />
"On the other hand, we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment, so blinded by desire, that they cannot foresee the pain and trouble that are bound to ensue; and equal blame belongs to those who fail in their duty through weakness of will, which is the same as saying through shrinking from toil and pain. These cases are perfectly simple and easy to distinguish. In a free hour, when our power of choice is untrammelled and when nothing prevents our being able to do what we like best, every pleasure is to be welcomed and every pain avoided. But in certain circumstances and owing to the claims of duty or the obligations of business it will frequently occur that pleasures have to be repudiated and annoyances accepted. The wise man therefore always holds in these matters to this principle of selection: he rejects pleasures to secure other greater pleasures, or else he endures pains to avoid worse pains."</p>
<p>안녕하세요? 정리하는 개발자 워니즈입니다. 이번 포스팅은 kubernetes hpa 에 대해서 적용했던 사례에 대해서 정리를 해보려고합니다. 이 전에 작성된 포스팅이긴 하지만, HPA의 이론에 대해서는 아래의 포스팅을 참고해주시면 됩니다. [DevOps] k8s Horizontal POD autoscaling 위의 내용중에서도 HPA(Horizontal Pod Autoscaler)를 실제 적용하는 계획과 실행에 대해서 정리를 해보려고합니다. 1. HPA 적용 목적 및 정책 필자가 운영하는 k8s에는 100여개 이상의&#8230;&#160;</p>
<p>The post <a rel="nofollow" href="https://blog.wonizz.com/2024/07/24/devops-kubernetes-hpa/">[DevOps] Kubernetes HPA 실전 적용</a> appeared first on <a rel="nofollow" href="https://blog.wonizz.com">WONIZZ.LOG</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>The standard Lorem Ipsum passage, used since the 1500s<br />
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."</p>
<p>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"</p>
<p>1914 translation by H. Rackham<br />
"But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?"</p>
<p>Section 1.10.33 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."</p>
<p>1914 translation by H. Rackham<br />
"On the other hand, we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment, so blinded by desire, that they cannot foresee the pain and trouble that are bound to ensue; and equal blame belongs to those who fail in their duty through weakness of will, which is the same as saying through shrinking from toil and pain. These cases are perfectly simple and easy to distinguish. In a free hour, when our power of choice is untrammelled and when nothing prevents our being able to do what we like best, every pleasure is to be welcomed and every pain avoided. But in certain circumstances and owing to the claims of duty or the obligations of business it will frequently occur that pleasures have to be repudiated and annoyances accepted. The wise man therefore always holds in these matters to this principle of selection: he rejects pleasures to secure other greater pleasures, or else he endures pains to avoid worse pains."</p>
<p>안녕하세요? 정리하는 개발자 워니즈입니다. 이번 포스팅은 kubernetes hpa 에 대해서 적용했던 사례에 대해서 정리를 해보려고합니다.</p>
<p>이 전에 작성된 포스팅이긴 하지만, HPA의 이론에 대해서는 아래의 포스팅을 참고해주시면 됩니다.</p>
<ul>
<li><a class="wp-editor-md-post-content-link" href="https://blog.wonizz.com/2022/05/18/devops-k8s-hpa/" title="[DevOps] k8s Horizontal POD autoscaling">[DevOps] k8s Horizontal POD autoscaling</a></li>
</ul>
<p>위의 내용중에서도 <strong>HPA(Horizontal Pod Autoscaler)</strong>를 실제 적용하는 계획과 실행에 대해서 정리를 해보려고합니다.</p>
<p><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/blog.wonizz.com/wp-content/uploads/2024/07/k8s_hpa_1.png?w=1200&#038;ssl=1" alt="DevOps Kubernetes HPA 실전 적용 설명 이미지 1" /></p>
<h2>1. HPA 적용 목적 및 정책</h2>
<p>필자가 운영하는 k8s에는 100여개 이상의 MSA 어플리케이션들이 서비스를 하고 있습니다. 모든 서비스들이 최적으로 운영된다면 좋겠지만 보통은 보수적으로 pod를 산정하고 리소스를 산정합니다. 자연스럽게 k8s의 리소스가 부족한 현상이 발생하기 시작했고 조치가 필요했습니다.</p>
<p>HPA의 적용 목적은 다음과 같은 내용을 기반으로 하고 있습니다.</p>
<ul>
<li>성능 유지 : 트래픽이나 요청량이 증가할 떄 추가 POD를 자동으로 생성하여 처리 능력을 높입니다.</li>
<li>리소스 최적화 : 과도한 리소스 할당을 방지하고, 리소스 사용 효율성을 높입니다.</li>
<li>자동화 및 운영 효율성 증대 : 부하 발생시 수동으로 조절하던 부분을 메트릭 측정값을 기반으로 자동 조정합니다.</li>
</ul>
<p>위의 목적에 기재 되어있듯이 <strong>리소스 최적화</strong>에도 기반을 두고 작업을 예정하게 되었습니다.</p>
<ul>
<li>HPA 적용 정책
<pre><code class="language-yaml line-numbers">apiVersion: autoscaling/v2beta2

kind: HorizontalPodAutoscalermetadata:
  name: hpa-test
  namespace: dosi-store
spec:
  scaleTargetRef:
      apiVersion: apps/v1
      kind: Deployment
      name: {{ .Values.phase }}-test-api
  minReplicas: 6
  maxReplicas: 18 <- 기존대비 3배수로 설정
  behavior:
     scaleDown:
         stabilizationWindowSeconds: 300
         policies:
        - type: Pods
          value: 2
          periodSeconds: 10
     scaleUp:
        stabilizationWindowSeconds: 30
        policies:
        - type: Percent
          value: 50
          periodSeconds: 10
        - type: Pods
          value: 4
          periodSeconds: 10
       selectPolicy: Max
  metrics:
       - type: Resource
         resource:
            name: cpu
            target:
               type: Utilization
               averageUtilization: 70
</code></pre>
<ul>
<li><strong>minReplicas</strong> : 현재의 pod 갯수</li>
<li><strong>maxReplicas</strong> : 최대 증설의 pod 갯수 ( 6 * 3 = 18개로 기준을 잡음 )</li>
<li><strong>scaleDown</strong>
<ul>
<li>10초당 2개의 pod를 감소</li>
<li>정책 적용 결정이 수행되면 5분간의 유예기간으로 메트릭을 지속 탐지함.</li>
<li>스케일 다운이 바로 일어나면 서비스에 문제가 발생할 수 있을것이라 판단하여 <strong>5분간 유예설정.</strong></li>
</ul>
</li>
<li><strong>scaleUp</strong>
<ul>
<li>10초당 현재 갯수의 50% (ex, 현재가 6개면, 3개로 계산 ) / 15초당 4개의 pod를 증가 중 더 큰 범주 선택</li>
<li>정책 적용 결정이 수행되면 30초간의 유예기간으로 메트릭을 지속 탐지함.</li>
<li>스케일 다운이 바로 일어나면 서비스에 문제가 발생할 수 있을것이라 판단하여 <strong>30초간 유예설정.</strong></li>
</ul>
</li>
<li><strong>평균 CPU 사용률 70%를 임계점</strong>으로 설정.</li>
</ul>
</li>
</ul>
<h2>2. HPA 적용 계획</h2>
<p>HPA를 적용함에 있어서 기존의 수집된 <strong>Metric</strong>을 한달 기준으로 분석을 실시했습니다. 적용 대상이 되는 어플리케이션 선정은 다음을 기준으로 선정했습니다.</p>
<ul>
<li>HPA 적용 기준
<ul>
<li>트래픽이 제일 많은 어플리케이션</li>
<li>트래픽 대비 과도하게 스케일 아웃되어있는 어플리케이션</li>
<li>현재 CPU Usage가 스케일 대비 과도하게 낮은 어플리케이션</li>
</ul>
</li>
</ul>
<p>트래픽이 많으면서(변동량이 크면서), 서버 수량은 많고 리소스는 최소로 사용하는(오버 스펙)이 되어있는 어플리케이션들의 정보를 수집했습니다.</p>
<table>
<thead>
<tr>
<th>어플리케이션</th>
<th>평균 RPS / 최고 RPS</th>
<th>Current Replicas</th>
<th>Cpu Trend</th>
<th>Target Replicas</th>
<th>비고</th>
</tr>
</thead>
<tbody>
<tr>
<td>A application</td>
<td>22.4 / 69.5 (<strong>peak시 cpu 25%</strong>)</td>
<td>12</td>
<td>Grafana 기록</td>
<td>6</td>
<td></td>
</tr>
<tr>
<td>B application</td>
<td>8.9 / 47.8(<strong>peak시 cpu 10%</strong>)</td>
<td>8</td>
<td>Grafana 기록</td>
<td>4</td>
<td></td>
</tr>
<tr>
<td>C application</td>
<td>16.7 / 53.5(<strong>peak시 cpu 10%</strong>)</td>
<td>12</td>
<td>Grafana 기록</td>
<td>6</td>
<td></td>
</tr>
<tr>
<td>D application</td>
<td>32.1 / 230.2(<strong>peak시 cpu 40%</strong>)</td>
<td>12</td>
<td>Grafana 기록</td>
<td>6</td>
<td></td>
</tr>
<tr>
<td>E application</td>
<td>30.9 / 129.4 (<strong>peak시 cpu 16%</strong> )</td>
<td>12</td>
<td>Grafana 기록</td>
<td>6</td>
<td></td>
</tr>
</tbody>
</table>
<p>위의 표와 같이 기록을 수행하여 기존의 CPU 트렌드 기반으로 목표 지점은 CPU Usage를 20 ~ 30% 를 사용하는것을 목표료 하여 <strong>Target Replicas</strong>를 지정하고 축소 계획을 세웠습니다.</p>
<p>계획은 다음 순서로 진행을 하고자 했습니다.</p>
<ul>
<li>1) HPA 설정 배포 ( 설정은 현재의 서비스에 영향을 미치지 않음. )</p>
</li>
<li>2) pod수를 스케일 다운. ( 다운시 CPU Usage 기록 )
<ul>
<li>CPU Usage의 안정 범위 : 평시에 20-30% 정도 사용.</li>
</ul>
</li>
<li>3) 적용이후에는 위의 정책을 기준으로 필요한 어플리케이션에 확장.</p>
</li>
</ul>
<h2>3. HPA 적용 테스트</h2>
<p>사전에 HPA를 적용하기 이전에 테스트를 진행했습니다. API 1개에 부하를 쏟아서 CPU 임계점을 넘어가도록 설정했습니다.</p>
<pre><code class="language-bash line-numbers">NAME               REFERENCE                TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
alpha-test-app   Deployment/alpha-test-app   3%/70%     2         6         2          11m
alpha-test-app   Deployment/alpha-test-app   3%/70%     2         6         2          11m   ← 부하 테스트 시작
alpha-test-app   Deployment/alpha-test-app   111%/70%   2         6         2          12m   ← 임계치 상향 
alpha-test-app   Deployment/alpha-test-app   111%/70%   2         6         4          12m   ← Upscale (30초 유예)
alpha-test-app   Deployment/alpha-test-app   45%/70%    2         6         4          13m   ← 임계치 하향 
alpha-test-app   Deployment/alpha-test-app   2%/70%     2         6         4          14m 
alpha-test-app   Deployment/alpha-test-app   2%/70%     2         6         4          15m
alpha-test-app   Deployment/alpha-test-app   2%/70%     2         6         4          16m
alpha-test-app   Deployment/alpha-test-app   3%/70%     2         6         4          17m
alpha-test-app   Deployment/alpha-test-app   3%/70%     2         6         4          18m   ← DownScale (300초 유예)
alpha-test-app   Deployment/alpha-test-app   4%/70%     2         6         2          18m
alpha-test-app   Deployment/alpha-test-app   4%/70%     2         6         2          19m
alpha-test-app   Deployment/alpha-test-app   3%/70%     2         6         2          20m
</code></pre>
<ul>
<li>Upscale 적용 후
<p><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/blog.wonizz.com/wp-content/uploads/2024/07/k8s_hpa_2.png?w=1200&#038;ssl=1" alt="DevOps Kubernetes HPA 실전 적용 설명 이미지 2" /></p>
</li>
<li>
<p>Downscale 적용 후</p>
<p><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/blog.wonizz.com/wp-content/uploads/2024/07/k8s_hpa_3.png?w=1200&#038;ssl=1" alt="DevOps Kubernetes HPA 실전 적용 설명 이미지 3" /></p>
</li>
</ul>
<p>정확하게 HPA 동작에 의해 Upscale을 수행했다가 부하가 사라지면 정상화 됩니다.</p>
<ul>
<li>이슈 사항
<p>테스트를 진행하면서 이슈를 한가지 확인했는데요. 배포를 하게 되면 새로운 어플리케이션으로부터 Metric이 즉각 수집이 되지 않으면서 <strong>Degraded</strong>상태가 되는것을 확인했습니다. 따라서 Metric이 수집되지 않은 상태라면 <strong>Progressing</strong>상태로 마킹하는 내용이 필요했습니다.</p>
<p><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/blog.wonizz.com/wp-content/uploads/2024/07/k8s_hpa_4.png?w=1200&#038;ssl=1" alt="DevOps Kubernetes HPA 실전 적용 설명 이미지 4" /></p>
<ul>
<li>Resolve Ref : https://argo-cd.readthedocs.io/en/stable/operator-manual/health/#custom-health-checks</li>
</ul>
<pre><code class="language-yaml line-numbers">data:
  resource.customizations: |
    cert-manager.io/Certificate:
      health.lua: |
        hs = {}
        if obj.status ~= nil then
          if obj.status.conditions ~= nil then
            for i, condition in ipairs(obj.status.conditions) do
              if condition.type == "Ready" and condition.status == "False" then
                hs.status = "Degraded"
                hs.message = condition.message
                return hs
              end
              if condition.type == "Ready" and condition.status == "True" then
                hs.status = "Healthy"
                hs.message = condition.message
                return hs
              end
            end
          end
        end

        hs.status = "Progressing"
        hs.message = "Waiting for certificate"
        return hs
</code></pre>
</li>
</ul>
<h2>4. HPA 적용 효과 및 사례</h2>
<p>실제로 적용을 하고 나서는 다음의 수준으로 <strong>리소스 최적화</strong>를 할 수 있었습니다.</p>
<ul>
<li>Previous Resources<br />
<img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/blog.wonizz.com/wp-content/uploads/2024/07/k8s_hpa_5.png?w=1200&#038;ssl=1" alt="DevOps Kubernetes HPA 실전 적용 설명 이미지 5" /></p>
</li>
<li>
<p>Current Resources</p>
<p><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/blog.wonizz.com/wp-content/uploads/2024/07/k8s_hpa_6.png?w=1200&#038;ssl=1" alt="DevOps Kubernetes HPA 실전 적용 설명 이미지 6" /></p>
</li>
</ul>
<p>CPU는 약 2%, Memory는 6.1% 가량을 최적화 했습니다. 물론 100개중에 약 5개 정도만 선제적으로 적용을 한것이라 큰 효과는 없다고 생각할 수 있습니다. 하지만 이를 통해서 HPA의 장점을 취득하고 리소스를 최적화를 할 수 있다는 것을 배울 수 있었습니다.</p>
<h2>5. 마치며..</h2>
<p>HPA를 통해서 좀더 유연한 인프라를 제공할 수 있다는 것을 알게 됐습니다. 실제로 운영하면서 여러 차례 트래픽 스파이크시에 동작하는 것을 보고서 그 효과를 체험할 수 있었습니다. k8s를 통해서 셀프 힐링, 배포 자동화 등등의 큰 장점도 있지만 트래픽에 유연하게 대응할 수 있는 인프라를 제공하는 측면도 굉장히 효과적이라고 생각합니다.</p>
<p>포스팅을 마치도록 하겠습니다. 감사합니다.</p>
<p>The post <a rel="nofollow" href="https://blog.wonizz.com/2024/07/24/devops-kubernetes-hpa/">[DevOps] Kubernetes HPA 실전 적용</a> appeared first on <a rel="nofollow" href="https://blog.wonizz.com">WONIZZ.LOG</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.wonizz.com/2024/07/24/devops-kubernetes-hpa/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2278</post-id>	</item>
		<item>
		<title>[Kubernetes] NetworkPolicy 적용</title>
		<link>https://blog.wonizz.com/2024/03/06/kubernetes-networkpolicy/</link>
					<comments>https://blog.wonizz.com/2024/03/06/kubernetes-networkpolicy/#respond</comments>
		
		<dc:creator><![CDATA[워니]]></dc:creator>
		<pubDate>Wed, 06 Mar 2024 10:11:43 +0000</pubDate>
				<category><![CDATA[kubernetes]]></category>
		<category><![CDATA[Tech]]></category>
		<guid isPermaLink="false">https://blog.wonizz.com/?p=2201</guid>

					<description><![CDATA[<p>The standard Lorem Ipsum passage, used since the 1500s<br />
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."</p>
<p>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"</p>
<p>1914 translation by H. Rackham<br />
"But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?"</p>
<p>Section 1.10.33 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."</p>
<p>1914 translation by H. Rackham<br />
"On the other hand, we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment, so blinded by desire, that they cannot foresee the pain and trouble that are bound to ensue; and equal blame belongs to those who fail in their duty through weakness of will, which is the same as saying through shrinking from toil and pain. These cases are perfectly simple and easy to distinguish. In a free hour, when our power of choice is untrammelled and when nothing prevents our being able to do what we like best, every pleasure is to be welcomed and every pain avoided. But in certain circumstances and owing to the claims of duty or the obligations of business it will frequently occur that pleasures have to be repudiated and annoyances accepted. The wise man therefore always holds in these matters to this principle of selection: he rejects pleasures to secure other greater pleasures, or else he endures pains to avoid worse pains."</p>
<p>안녕하세요? 정리하는 개발자 워니즈입니다. 오랜만에 블로그 포스팅을 합니다. 최근에 Blog Domain이 변경되면서 여러가지 고초를 겪었습니다. 이부분은 다른 포스팅에서 기록하도록 하겠습니다. 이번 포스팅은 Kubernets Networkpolicy에 대해서 정리를 해보려고합니다. 필자가 속한 프로젝트에서는 보안 네트워크(독립망)을 사용하고있어서 이러한 부분에 대해서 고려를 해본적은 없습니다. 하지만 이번에 개발팀으로부터 특정 어플리케이션에 대해서 직접 접근을 통해서 부정한 요청을 할 수 있으니 요청을 차단해달라는&#8230;&#160;</p>
<p>The post <a rel="nofollow" href="https://blog.wonizz.com/2024/03/06/kubernetes-networkpolicy/">[Kubernetes] NetworkPolicy 적용</a> appeared first on <a rel="nofollow" href="https://blog.wonizz.com">WONIZZ.LOG</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>The standard Lorem Ipsum passage, used since the 1500s<br />
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."</p>
<p>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"</p>
<p>1914 translation by H. Rackham<br />
"But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?"</p>
<p>Section 1.10.33 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."</p>
<p>1914 translation by H. Rackham<br />
"On the other hand, we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment, so blinded by desire, that they cannot foresee the pain and trouble that are bound to ensue; and equal blame belongs to those who fail in their duty through weakness of will, which is the same as saying through shrinking from toil and pain. These cases are perfectly simple and easy to distinguish. In a free hour, when our power of choice is untrammelled and when nothing prevents our being able to do what we like best, every pleasure is to be welcomed and every pain avoided. But in certain circumstances and owing to the claims of duty or the obligations of business it will frequently occur that pleasures have to be repudiated and annoyances accepted. The wise man therefore always holds in these matters to this principle of selection: he rejects pleasures to secure other greater pleasures, or else he endures pains to avoid worse pains."</p>
안녕하세요? 정리하는 개발자 워니즈입니다. 오랜만에 블로그 포스팅을 합니다. 최근에 Blog Domain이 변경되면서 여러가지 고초를 겪었습니다. 이부분은 다른 포스팅에서 기록하도록 하겠습니다.

<img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/blog.wonizz.com/wp-content/uploads/2024/03/networkpolicy_1.png?w=1200&#038;ssl=1" alt="Kubernetes NetworkPolicy 적용 설명 이미지 1" />

이번 포스팅은 <strong>Kubernets Networkpolicy</strong>에 대해서 정리를 해보려고합니다. 필자가 속한 프로젝트에서는 보안 네트워크(독립망)을 사용하고있어서 이러한 부분에 대해서 고려를 해본적은 없습니다. 하지만 이번에 개발팀으로부터 특정 어플리케이션에 대해서 직접 접근을 통해서 부정한 요청을 할 수 있으니 요청을 차단해달라는 요구사항을 접수하여 해당 내용을 진행하게 됐습니다.

<h2>1. Kubernetes NetworkPolicy란 무엇인가요?</h2>

Kubernetes NetworkPolicy는 Kubernetes 클러스터 내에서 파드 간 트래픽을 제어하기 위해 사용되는 정책 기능입니다. 이를 통해 특정 파트 또는 파드 그룹 간의 통신을 제한하거나 허용할 수 있습니다.

NetworkPolicy는 파드의 라벨을 기반으로 정책을 적용하며, 트래픽의 소스 및 대상 IP주소, 포트 및 프로토콜 등을 기준으로 통신을 제어할 수 있습니다.

<h2>2. Kubernetes 어플리케이션 요구사항</h2>

요구사항은 다음과 같습니다.

<ul>
<li>외부의 사용자는 API-GW로부터만 접근이 가능하고 직접 API혹은 INTERAL-API를 호출할수는 없다.</li>
<li>Kubernetes Cluster내에서 다른 팀의 다른 어플리케이션이 직접적으로 API혹은 INTERAL-API를 호출할수는 없다.</li>
<li>어플리케이션에 Inbound 트래픽 허용 설정이 필요하다.</li>
</ul>

다이어그램은 다음과 같습니다.

<img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/blog.wonizz.com/wp-content/uploads/2024/03/networkpolicy_2.png?w=1200&#038;ssl=1" alt="Kubernetes NetworkPolicy 적용 설명 이미지 2" />

<ul>
<li>API Server는 API Gatewa에서 들어오는 inbound 트래픽을 허용합니다.</li>
<li>Internal API Server는 API Server &#038; Internal API Gateway에서 들어오는 inbound 트래픽을 허용합니다.</li>
</ul>

따라서, inbound정책만 허용하고 이외에는 deny시키는 것으로 정책을 정하고 구성을 진행하기로했습니다.

<h2>3. Network Policy 설정</h2>

Network Policy는 OSI 3 또는 4 계층 수준에서 트래픽 흐름을 제어합니다. 제어할 수 있는 규칙은 다음과 같습니다 .

<h3>Ingress</h3>

<ul>
<li>Pod Selector : 특정 레이블 셀렉터를 사용하여 트래픽의 송신자 또는 수신자 파드를 선택합니다.</li>
<li>Namespace Selector : 특정 네임스페이스에서 트래픽을 허용 또는 거부할 수 있습니다.</li>
<li>IP Block : CIDR IP 대역으로, 특정 IP 대역에서만 트래픽이 들어오도록 지정할 수 있습니다.</li>
<li>Port : 포트 기반으로 트래픽을 제어합니다.</li>
<li>Protocol : TCP, UDP 등의 트래픽 프로토콜을 지정합니다.</li>
</ul>

<h3>Egress</h3>

<ul>
<li>IP Block : CIDR IP 대역으로, 특정 IP 대역에서만 트래픽이 나가도록 지정할 수 있습니다.</li>
<li>Port : 포트 기반으로 트래픽을 제어합니다.</li>
<li>Protocol : TCP, UDP 등의 트래픽 프로토콜을 지정합니다.</li>
</ul>

위의 요구사항중 inbound(ingress)만 허용하면서 특정 어플리케이션을 whitelist하는 방식으로 구성을 하기로했습니다.

<h3>Helm Chart 구성</h3>

<ul>
<li>api-server helm chart</li>
</ul>

<pre><code class="line-numbers">├── alpha-values.yaml
├── beta-values.yaml
├── Chart.yaml
├── prod-values.yaml
└── templates
    ├── deployment.yaml
    ├── networkpolicy.yaml   --> 신규 추가
    └── service.yaml
</code></pre>

helm chart 구성에서 networkpolicy.yaml 파일을 추가했습니다. 해당 내용을 통해서 values 파일에 지정된 app을 whitelist로 적용하도록 설정하겠습니다.

<ul>
<li>alpha-values.yaml</li>
</ul>

<pre><code class="language-yaml line-numbers">....
networkPolicies:
  - allowlist:
      - api-gateway
</code></pre>

<ul>
<li>networkpolicy.yaml</li>
</ul>

<pre><code class="language-yaml line-numbers">apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: {{ .Values.phase }}-{{ .Values.projectName }}
  namespace: {{ .Values.namespace }}
  labels:
    link.service.phase: {{ .Values.phase }}
    link.service.name: {{ .Values.namespace }}
    link.project.name: {{ .Values.projectName }}
spec:
  podSelector:
    matchLabels:
      link.service.phase: {{ .Values.phase }}
      link.service.name: {{ .Values.namespace }}
      link.project.name: {{ .Values.projectName }}
  policyTypes:
  - Ingress
{{- range .Values.networkPolicies }}
  {{- $allowlist := .allowlist }}
  {{- if $allowlist }}
  ingress:
    {{- range $allowlist }}
    - from:
        - podSelector:
            matchLabels:
              link.project.name: {{ . }}
    {{- end }}
    - from:
        - namespaceSelector:
            matchLabels:
              app.kubernetes.io/name: ingress-nginx
  {{- else }}
  ingress:
  - {}
  {{- end }}
{{- end }}
</code></pre>

위의 내용을 적용하면, api-server에서는 api-gateway만 inbound(ingress)로 허용하기로했습니다. 따라서 values파일에 지정된 <strong>api-gateway</strong>만 허용되도록 설정이 됩니다.

<pre><code class="language-yaml line-numbers">        - podSelector:
            matchLabels:
              link.project.name: {{ . }}
</code></pre>

설정 부분은 pod의 label을 통해서 지정하게 되어있습니다. <strong>link.project.name: api-gateway</strong> 가 되는 application의 트래픽만을 허용하겠다는 설정입니다.

<h2>4. 요청 테스트</h2>

<ul>
<li>API Gateway Server에서 API Server호출시 <strong>정상 호출</strong></li>
</ul>

<pre><code class="line-numbers">{"responseCode":"NOT_FOUND","responseData":"type: API or static resource is not found"}
</code></pre>

<ul>
<li>API Gateway Sever에서 Internal API 호출시 <strong>접근 불가</strong></li>
</ul>

<pre><code class="line-numbers">upstream connect error or disconnect/reset before headers. retried and the latest reset reason: connection failure, transport failure reason: delayed connect error: 110
</code></pre>

<h2>5. 마치며&#8230;</h2>

이번 시간에는 <strong>Kubernetes Networkpolicy</strong>에 대해서 정리를 해보았습니다. Kubernetes를 사용하면서 보안에 대해서 크게 생각을 해본적이 없었습니다. 이번 기회에 특정 inbound 혹은 outbound 트래픽 까지 제어를 할 수 있는 부분에 대해서 알 수 있었고, 이러한 설정을 통해서 내부 시스템들을 좀 더 안정적으로 운영할 수 있다는 것을 깨달았습니다.

다음시간에는 istio에서 설정하는 부분도 정리를 해보도록 하겠습니다. 감사합니다.

<h2>6. 참고</h2>

<a class="wp-editor-md-post-content-link" href="https://kmaster.tistory.com/70" target="_blank" rel="noopener">Network Policy</a>
<a class="wp-editor-md-post-content-link" href="https://waspro.tistory.com/609" target="_blank" rel="noopener">K8S 네트워크 Policy Management</a>
<a class="wp-editor-md-post-content-link" href="https://velog.io/@salgu1998/Kubernetes-%EC%BF%A0%EB%B2%84%EB%84%A4%ED%8B%B0%EC%8A%A4-Minikube-%ED%99%98%EA%B2%BD%EC%97%90%EC%84%9C-NetworkPolicy-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0%EC%9E%91%EC%84%B1-%EC%A4%91" target="_blank" rel="noopener">Kubernetes 쿠버네티스 &#8211; Minikube 환경에서 NetworkPolicy 적용하기</a>
<h2 class="wp-block-heading">함께 보면 좋은 글</h2>
<ul class="wp-block-list"><li><a href="https://blog.wonizz.com/2020/08/24/kubernetes-autoscaling-hpa/">[Kubernetes] Autoscaling 사용하기</a></li><li><a href="https://blog.wonizz.com/2020/06/03/kubernetes-helm-chartmuseum/">[Kubernetes] Helm Chartmuseum 사용법</a></li><li><a href="https://blog.wonizz.com/2024/07/24/devops-kubernetes-hpa/">[DevOps] Kubernetes HPA 실전 적용</a></li><li><a href="https://blog.wonizz.com/2022/10/05/kubernetes-k8s-cronjob-monitoring/">[Kubernetes] K8S Cronjob Monitoring</a></li></ul>
<p>The post <a rel="nofollow" href="https://blog.wonizz.com/2024/03/06/kubernetes-networkpolicy/">[Kubernetes] NetworkPolicy 적용</a> appeared first on <a rel="nofollow" href="https://blog.wonizz.com">WONIZZ.LOG</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.wonizz.com/2024/03/06/kubernetes-networkpolicy/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2201</post-id>	</item>
		<item>
		<title>[DevOps] Nginx Rate Limit</title>
		<link>https://blog.wonizz.com/2023/11/03/devops-nginx-rate-limit/</link>
					<comments>https://blog.wonizz.com/2023/11/03/devops-nginx-rate-limit/#respond</comments>
		
		<dc:creator><![CDATA[워니]]></dc:creator>
		<pubDate>Fri, 03 Nov 2023 08:29:21 +0000</pubDate>
				<category><![CDATA[kubernetes]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[Tech]]></category>
		<guid isPermaLink="false">https://blog.wonizz.tk/?p=2093</guid>

					<description><![CDATA[<p>The standard Lorem Ipsum passage, used since the 1500s<br />
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."</p>
<p>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"</p>
<p>1914 translation by H. Rackham<br />
"But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?"</p>
<p>Section 1.10.33 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."</p>
<p>1914 translation by H. Rackham<br />
"On the other hand, we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment, so blinded by desire, that they cannot foresee the pain and trouble that are bound to ensue; and equal blame belongs to those who fail in their duty through weakness of will, which is the same as saying through shrinking from toil and pain. These cases are perfectly simple and easy to distinguish. In a free hour, when our power of choice is untrammelled and when nothing prevents our being able to do what we like best, every pleasure is to be welcomed and every pain avoided. But in certain circumstances and owing to the claims of duty or the obligations of business it will frequently occur that pleasures have to be repudiated and annoyances accepted. The wise man therefore always holds in these matters to this principle of selection: he rejects pleasures to secure other greater pleasures, or else he endures pains to avoid worse pains."</p>
<p>안녕하세요? 정리하는 개발자 워니즈입니다. 이번 시간에는 Nginx를 통해 트래픽을 제어하기 위한 기능은 Rate Limit에 대해서 정리해보도록 하겠습니다. 필자가 Rate Limit 적용을 하면서 겪었던 사례도 함께 정리합니다. Nginx에 관한 시리즈 포스팅은 아래에서 확인이 가능합니다. [DevOps] Nginx 컴파일 설치 [DevOps] ansible nginx config 배포 구성 [DevOps] Nginx Logrotation 설정 [DevOps] Nginx GeoIP 모듈 적용 [DevOps] Nginx Log&#8230;&#160;</p>
<p>The post <a rel="nofollow" href="https://blog.wonizz.com/2023/11/03/devops-nginx-rate-limit/">[DevOps] Nginx Rate Limit</a> appeared first on <a rel="nofollow" href="https://blog.wonizz.com">WONIZZ.LOG</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>The standard Lorem Ipsum passage, used since the 1500s<br />
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."</p>
<p>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"</p>
<p>1914 translation by H. Rackham<br />
"But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?"</p>
<p>Section 1.10.33 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."</p>
<p>1914 translation by H. Rackham<br />
"On the other hand, we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment, so blinded by desire, that they cannot foresee the pain and trouble that are bound to ensue; and equal blame belongs to those who fail in their duty through weakness of will, which is the same as saying through shrinking from toil and pain. These cases are perfectly simple and easy to distinguish. In a free hour, when our power of choice is untrammelled and when nothing prevents our being able to do what we like best, every pleasure is to be welcomed and every pain avoided. But in certain circumstances and owing to the claims of duty or the obligations of business it will frequently occur that pleasures have to be repudiated and annoyances accepted. The wise man therefore always holds in these matters to this principle of selection: he rejects pleasures to secure other greater pleasures, or else he endures pains to avoid worse pains."</p>
<p>안녕하세요? 정리하는 개발자 워니즈입니다. 이번 시간에는 Nginx를 통해 트래픽을 제어하기 위한 기능은 <code>Rate Limit</code>에 대해서 정리해보도록 하겠습니다. 필자가 Rate Limit 적용을 하면서 겪었던 사례도 함께 정리합니다.</p>
<p>Nginx에 관한 시리즈 포스팅은 아래에서 확인이 가능합니다.</p>
<ul>
<li><input style="margin-right:5px" type="checkbox" class="task-list-item-checkbox" checked disabled /><a class="wp-editor-md-post-content-link" href="https://blog.wonizz.com/2022/02/09/devops-nginx-compile-installation/">[DevOps] Nginx 컴파일 설치</a>
  </li>
<li><input style="margin-right:5px" type="checkbox" class="task-list-item-checkbox" checked disabled /><a class="wp-editor-md-post-content-link" href="https://blog.wonizz.com/2022/07/11/devops-ansible-nginx-config-deploy/">[DevOps] ansible nginx config 배포 구성</a>
  </li>
<li><input style="margin-right:5px" type="checkbox" class="task-list-item-checkbox" checked disabled /><a class="wp-editor-md-post-content-link" href="https://blog.wonizz.com/2023/08/10/linux-logrotate/">[DevOps] Nginx Logrotation 설정</a>
  </li>
<li><input style="margin-right:5px" type="checkbox" class="task-list-item-checkbox" checked disabled /><a class="wp-editor-md-post-content-link" href="https://blog.wonizz.com/2023/08/17/devops-nginx-geoip-module/">[DevOps] Nginx GeoIP 모듈 적용</a>
  </li>
<li><input style="margin-right:5px" type="checkbox" class="task-list-item-checkbox" checked disabled /><a class="wp-editor-md-post-content-link" href="https://blog.wonizz.com/2023/10/19/devops-nginx-log-aggregation-dashboard/">[DevOps] Nginx Log Aggregation &#038; Dashboard</a>
  </li>
<li><input style="margin-right:5px" type="checkbox" class="task-list-item-checkbox" checked disabled /><a class="wp-editor-md-post-content-link" href="https://blog.wonizz.com/2023/11/03/devops-nginx-rate-limit/">[DevOps] Nginx Rate Limit</a>
  </li>
<li><input style="margin-right:5px" type="checkbox" class="task-list-item-checkbox" checked disabled /><a class="wp-editor-md-post-content-link" href="https://blog.wonizz.com/2024/07/18/devops-nginx-lua-module/">[DevOps] Nginx Lua module 사용법</a>
  </li>
</ul>
<h2>1. Rate Limit 이란?</h2>
<blockquote><p>
  Incomming connection 혹은 requests 에 대한 rate을 제한하는 기능입니다.
</p></blockquote>
<p>예를들어 너무 많은 connection이 동시에 발생해 server에 부담을 가하는 경우, rate limit을 초과한 connection은 reject할 수 있습니다.</p>
<h3>Rate Limit을 사용하는 이유</h3>
<p>Rate Limit을 사용하는 이유는 다음과 같습니다.</p>
<ul>
<li>DDos공격에 의한 자원 고갈을 방지</li>
<li>서버 과부하 방지
<ul>
<li>Bot에서 오는 트래픽이나 사용자의 잘못된 이용 패턴으로 유발된 트래픽을 걸러내는데 활용</li>
<li>서버가 처리할 수 있는 요청의 임계 값을 넘어선 요청을 방지함으로써 서버의 안정성을 높이는 역할</li>
</ul>
</li>
</ul>
<h3>Rate Limit 알고리즘</h3>
<p><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/blog.wonizz.tk/wp-content/uploads/2023/11/rate_limit_1.png?w=1200" alt="DevOps Nginx Rate Limit 설명 이미지 1" /></p>
<ul>
<li>토큰 버킷은 지정된 용량(버킷 크기)을 갖는 컨테이너로, 사전 설정된 양의 토큰(토큰 공급률)이 주기적으로 채워집니다.
<ul>
<li>각 요청은 처리될 떄 마다 하나의 토큰을 사용합니다.</li>
<li>요청이 들어오면 먼저 충분한 토큰이 있는지 검사한 후, 있는 경우 버킷에서 토큰 하나를 꺼낸 후 요청을 전달합니다.</li>
<li>만약 충분한 토큰이 없는 경우, 해당 요청은 버려집니다.</li>
</ul>
</li>
<li>장점
<ul>
<li>큐의 크기가 제한되어 있어, 메모리 사용 측며네서 효율적</li>
<li>고정된 처리율을 갖고 있어 안정적 출력이 필요한 경우 적합</li>
</ul>
</li>
<li>단점
<ul>
<li>단 시간에 트래픽이 몰려서 요청이 들어오면 쌓이게 되고 제때 처리하지 못하면 최신 요청들은 버려지게 됩니다.</li>
<li>버킷 크기의와 처리율을 튜닝하기 까다롭습니다.</li>
</ul>
</li>
</ul>
<h2>2. Nginx Rate Limit 설정</h2>
<p>Nginxdㅔ서는 Rate Limit을 2가지 방식으로 제공하고 있습니다.</p>
<ul>
<li>limit_req &#8211; 요청 제한
<pre><code class="line-numbers">#동일 아이피 당 Rate을 10r/s로 제한하겠다는 의미
limit_req_zone $binary_remote_addr zone=request_limit_per_ip:10m rate=10r/s;

server {
  location /login/ {
      limit_req zone=request_limit_per_ip burst=10 nodelay;

      proxy_pass http://my_upstream;
  }
}
</code></pre>
</li>
<li>limit_conn &#8211; 커녁션 제한
<pre><code class="line-numbers">#동시에 서버에 연결되는 커넥션 수로 10개로 제한하겠다는 의미
limit_req_zone $server_name zone=request_limit_per_server:10m;

server {
  location /login/ {
      limit_req zone=request_limit_per_server 10;

      proxy_pass http://my_upstream;
  }
}
</code></pre>
</li>
</ul>
<blockquote><p>
  Zone</p>
<ul>
<li>rate limit을 적용할 zone을 정의합니다.
<ul>
<li>$server_name(per serer)</li>
<li>$binary_remote_addr(per user)</li>
<li>$request_uri(per uri)</li>
</ul>
</li>
</ul>
<p>  zone size</p>
<ul>
<li>zone의 이름과 메모리에 저장할 zone의 사이즈 결정
<ul>
<li>zone=MYZONE:10m</li>
</ul>
</li>
</ul>
<p>  limit_req 정의</p>
<ul>
<li>rate=1r/s, rate=60r/m과 같이 frequency를 정의합니다.
<ul>
<li>예를들어 10r/s가 1초당 10개의 요청이 처리된다는 것이 아닙니다. <strong>0.1초에 1개의 요청을 처리할 수 있다는 의미</strong>입니다.</li>
</ul>
</li>
</ul>
</blockquote>
<h3>Burst Mode</h3>
<p>burst를 적용하면, rate limiting을 초과하는 connection을 즉시 reject하지 않고 wait하게 만들 수 있습니다. 일부 rate limit을 넘어 들어온 요청을 queue에 적재하고, rate limit 속도에 맞춰 pop 되어 실행합니다.</p>
<ul>
<li>속도가 제한된 엔드포인트에 10개의 병렬 요청 보내기
<ul>
<li>10개 요청 중 9개가 거부됩니다. 이는 <code>30r/m</code> 즉, 2초마다 새 요청이 허용된다는 의미입니다. 여기서는 10개의 요청이 동시에 도착했고, 그 중 하나는 허용되고 나머지 9개는 nginx에서 거부가 됩니다.</li>
</ul>
<p><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/cdn-media-1.freecodecamp.org/images/1%2AbqER3OkNtH4MNWZTCjF4Zg.gif?w=1200&#038;ssl=1" alt="DevOps Nginx Rate Limit 설명 이미지 2" /></p>
</li>
<li>Burtmode를 통해 허용치 늘리기
<ul>
<li><code>burst=5</code> 를 통해서 버스트를 처리할 수 있도록 합니다. 기존에는 1/10에서 6/10개가 성공이 되도록 허용치를 늘렸습니다. ( 나머지는 거부 ) 그러나 여기서 주목해야될 것은 나머지 5개가 허용이 되었더라도 <code>30r/m</code> 즉, 2초마다 1개의 요청에 대해서 처리하도록 제한합니다.</li>
</ul>
<p><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/cdn-media-1.freecodecamp.org/images/1%2AR9D2q4zmUdDQO2k0AvrOWA.gif?w=1200&#038;ssl=1" alt="DevOps Nginx Rate Limit 설명 이미지 3" /></p>
</li>
<li>Nodelay를 통해 burst mode된 나머지 요청도 지연없이 처리 하기
<ul>
<li><code>burst=5</code> 인경우와 처리되는 갯수는 동일합니다. 그러나 이제 처리 속도는 2초당 1개의 요청속도로 엄격하게 제한되지 않습니다.</li>
</ul>
<p><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/cdn-media-1.freecodecamp.org/images/1%2AwVpU5zy5Yfg6c_lx2VIrAw.gif?w=1200&#038;ssl=1" alt="DevOps Nginx Rate Limit 설명 이미지 4" /></p>
</li>
</ul>
<h2>4. Nginx Rate Limit 사용 사례</h2>
<p>필자가 운여하는 서비스에서 공격성 트래픽이 다수 들어오는 케이스가 있었습니다. 서두에서도 설명했듯이 Rate Limit을 설정하는 이유는 외부의 비이상적 트래픽으로부터 서비스를 보호하고 안정성을 유지하기 위함입니다.</p>
<h3>Requested URI 분석</h3>
<ul>
<li>공격성 트래픽에 의한 Request 패턴을 분석하기로 했습니다.
<ul>
<li>다양하게 호출을 하면서 내부의 취약점을 찾으려는 내용들이 식별됐습니다.</li>
</ul>
<pre><code class="line-numbers">{request_uri="/_next/static/LdA0nq_uXCJOjaYEOuZcS/.\\..\\.\\..\\.\\..\\.\\..\\.\\..\\.\\..\\.\\..\\.\\..\\etc/passwd"}
{request_uri="/_next/static/LdA0nq_uXCJOjaYEOuZcS/./WEB-INF/web.xml?"}

GET /api/v1/games/������������������������������������������������������������etc��passwd
GET /api/v1/games/(nslookup-q=cnamehitufxhlvamalcfebb.bxss.me||curlhitufxhlvamalcfebb.bxss.me))
GET /api/v1/games/../../../../../../../../boot.ini
</code></pre>
<p><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/blog.wonizz.tk/wp-content/uploads/2023/11/rate_limit_2.png?w=1200" alt="DevOps Nginx Rate Limit 설명 이미지 5" /></p>
</li>
<li>
<p>Rate Limit을 설정하기 위한 RPS 확인 (회고를 위한 기록)</p>
<ul>
<li>사실 해당 영역의 분석은 <code>잘못된</code> 내용입니다.</li>
<li>rate limit을 속도의 개념으로 생각해서 rps 분석을 통해서 적절한 값을 찾으려고했습니다. <- 이부분 부터가 잘못된 생각이였습니다.</li>
<li>아래의 그림을 통해서 rate limit 설정치 : 2 <= 제한값 <= 17 의 설정치를 계산했지만, 잘못된 내용이였습니다.</li>
<li>rate limit은 한개의 요청 이후 다음 요청이 들어올 떄까지의 속도이고 예를들어 `30r/m&#8220;은 2초안에 1개의 요청만 허용한다는 개념입니다.</li>
</ul>
<p><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/blog.wonizz.tk/wp-content/uploads/2023/11/rate_limit_3.png?w=1200" alt="DevOps Nginx Rate Limit 설명 이미지 6" /></p>
<p><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/blog.wonizz.tk/wp-content/uploads/2023/11/rate_limit_4.png?w=1200" alt="DevOps Nginx Rate Limit 설명 이미지 7" /></p>
</li>
</ul>
<h3>다시 처음부터 분석</h3>
<ul>
<li>Rate Limit 산정을 위한 Request 분석
<ul>
<li>한개의 IP에 대해서 요청을 상세히 분석합니다. 하나의 요청으로부터 다음 요청까지의 시간 차이를 계산하여 대략적인 rate limit의 값을 계산했습니다. 여기서는 약 0.2초의 1개의 요청을 허용하도록 산정하여 <code>5r/s</code> 로 산정을 하게 됐습니다.</li>
</ul>
<pre><code class="line-numbers">- 2023-07-21 14:53:32.105 "GET / HTTP/2.0”
- 2023-07-21 14:53:32.361 "GET /robots.txt?1689918812080 HTTP/2.0”
- 2023-07-21 14:53:32.857 "GET /_next/image?url=https%3A%2F% HTTP/2.0"
- 2023-07-21 14:53:33.358 "GET /_next/image?url=https%3A%2F% HTTP/2.0"
- 2023-07-21 14:53:34.109 "GET /api/v1/drops/banners?size=10 HTTP/2.0”
- 2023-07-21 14:53:34.359 "GET /api/v1/games/title HTTP/2.0”
- 2023-07-21 14:53:34.359 "GET /_next/image?url=https%3A%2F% HTTP/2.0"
- 2023-07-21 14:53:34.359 "GET /_next/image?url=https%3A%2F%5 HTTP/2.0"
</code></pre>
</li>
</ul>
<h3>설정 예시</h3>
<ul>
<li>실제로 설정한 예시
<pre><code class="line-numbers">#Back-end의 API에 대한 rate limit
limit_req_zone $whitelist zone=be_access_limit_per_ip:10m rate=10r/s;
...
location ~ ^/(api|pg-api)/ {
  limit_req zone=be_access_limit_per_ip burst=5 nodelay;
  limit_req_status 429;
  # limit_req_dry_run on;


#Front-end에 대한 rate limit
limit_req_zone $whitelist zone=fe_access_limit_per_ip:10m rate=10r/s;
...
location /  {
  limit_req zone=fe_access_limit_per_ip burst=5 nodelay;
  limit_req_status 429;
  # limit_req_dry_run on;

</code></pre>
</li>
</ul>
<h2>5. 마치며&#8230;</h2>
<p>이번 시간에는 nginx의 rate limit 기능을 알아보고, 실제로 적용해던 사례에 대해서 정리를 해보았습니다. 처음에는 단순하게 속도의 개념으로 알았는데 1개의 요청으로부터 다음 요청이 들어오는 사이의 시간을 조정하는것을 알게 됐습니다. 또한 burst mode를 통해서 동시다발적으로 요청이 들어올때도 제어해서 요청을 처리 할 수 있게 됐습니다. Nginx의 기능을 통해서 트래픽을 제어할 수 있게 되어 서비스에 많은 공헌을 하게 된것 같습니다.</p>
<h2>6. 참고</h2>
<p><a class="wp-editor-md-post-content-link" href="https://www.freecodecamp.org/news/nginx-rate-limiting-in-a-nutshell-128fe9e0126c/" target="_blank" rel="noopener">NGINX rate-limiting in a nutshell</a></p>
<p><a class="wp-editor-md-post-content-link" href="https://minholee93.tistory.com/entry/Nginx-Rate-Limiting" target="_blank" rel="noopener">[Nginx] Rate Limiting</a></p>
<p><a class="wp-editor-md-post-content-link" href="https://willseungh0.tistory.com/191" target="_blank" rel="noopener">[Nginx RateLimit] Nginx에 RateLimit 적용해보기</a></p>
<p>The post <a rel="nofollow" href="https://blog.wonizz.com/2023/11/03/devops-nginx-rate-limit/">[DevOps] Nginx Rate Limit</a> appeared first on <a rel="nofollow" href="https://blog.wonizz.com">WONIZZ.LOG</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.wonizz.com/2023/11/03/devops-nginx-rate-limit/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2093</post-id>	</item>
		<item>
		<title>[DevOps] Nginx Log Aggregation &#038; Dashboard</title>
		<link>https://blog.wonizz.com/2023/10/19/devops-nginx-log-aggregation-dashboard/</link>
					<comments>https://blog.wonizz.com/2023/10/19/devops-nginx-log-aggregation-dashboard/#respond</comments>
		
		<dc:creator><![CDATA[워니]]></dc:creator>
		<pubDate>Thu, 19 Oct 2023 11:14:40 +0000</pubDate>
				<category><![CDATA[kubernetes]]></category>
		<category><![CDATA[Tech]]></category>
		<guid isPermaLink="false">https://blog.wonizz.tk/?p=2074</guid>

					<description><![CDATA[<p>The standard Lorem Ipsum passage, used since the 1500s<br />
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."</p>
<p>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"</p>
<p>1914 translation by H. Rackham<br />
"But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?"</p>
<p>Section 1.10.33 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."</p>
<p>1914 translation by H. Rackham<br />
"On the other hand, we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment, so blinded by desire, that they cannot foresee the pain and trouble that are bound to ensue; and equal blame belongs to those who fail in their duty through weakness of will, which is the same as saying through shrinking from toil and pain. These cases are perfectly simple and easy to distinguish. In a free hour, when our power of choice is untrammelled and when nothing prevents our being able to do what we like best, every pleasure is to be welcomed and every pain avoided. But in certain circumstances and owing to the claims of duty or the obligations of business it will frequently occur that pleasures have to be repudiated and annoyances accepted. The wise man therefore always holds in these matters to this principle of selection: he rejects pleasures to secure other greater pleasures, or else he endures pains to avoid worse pains."</p>
<p>안녕하세요? 정리하는 개발자 워니즈 입니다. 이번시간에는 loki와 promtail에 대해서 정리를 해보도록 하겠습니다. 필자는 프로메테우스와 그라파나를 사용하다보니, 자연스럽게 Loki라는 제품에 대해서 접할 수 있었습니다. 그리고 로그를 좀 더 쉽게 수집하고 표현할 수 있다는 점에서 바로 적용을 해보기로 했습니다. 본 포스팅은 Loki를 처음 접하거나 간단하게 사용해 볼 수 있는 내용으로 구성했습니다. Nginx에 관한 시리즈 포스팅은 아래에서 확인이&#8230;&#160;</p>
<p>The post <a rel="nofollow" href="https://blog.wonizz.com/2023/10/19/devops-nginx-log-aggregation-dashboard/">[DevOps] Nginx Log Aggregation &#038; Dashboard</a> appeared first on <a rel="nofollow" href="https://blog.wonizz.com">WONIZZ.LOG</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>The standard Lorem Ipsum passage, used since the 1500s<br />
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."</p>
<p>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"</p>
<p>1914 translation by H. Rackham<br />
"But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?"</p>
<p>Section 1.10.33 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."</p>
<p>1914 translation by H. Rackham<br />
"On the other hand, we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment, so blinded by desire, that they cannot foresee the pain and trouble that are bound to ensue; and equal blame belongs to those who fail in their duty through weakness of will, which is the same as saying through shrinking from toil and pain. These cases are perfectly simple and easy to distinguish. In a free hour, when our power of choice is untrammelled and when nothing prevents our being able to do what we like best, every pleasure is to be welcomed and every pain avoided. But in certain circumstances and owing to the claims of duty or the obligations of business it will frequently occur that pleasures have to be repudiated and annoyances accepted. The wise man therefore always holds in these matters to this principle of selection: he rejects pleasures to secure other greater pleasures, or else he endures pains to avoid worse pains."</p>
<p>안녕하세요? 정리하는 개발자 워니즈 입니다. 이번시간에는 <strong>loki</strong>와 <strong>promtail</strong>에 대해서 정리를 해보도록 하겠습니다. 필자는 프로메테우스와 그라파나를 사용하다보니, 자연스럽게 Loki라는 제품에 대해서 접할 수 있었습니다. 그리고 로그를 좀 더 쉽게 수집하고 표현할 수 있다는 점에서 바로 적용을 해보기로 했습니다.</p>
<p>본 포스팅은 Loki를 처음 접하거나 간단하게 사용해 볼 수 있는 내용으로 구성했습니다.</p>
<p>Nginx에 관한 시리즈 포스팅은 아래에서 확인이 가능합니다.</p>
<ul>
<li><input style="margin-right:5px" type="checkbox" class="task-list-item-checkbox" checked disabled /><a class="wp-editor-md-post-content-link" href="https://blog.wonizz.com/2022/02/09/devops-nginx-compile-installation/">[DevOps] Nginx 컴파일 설치</a>
  </li>
<li><input style="margin-right:5px" type="checkbox" class="task-list-item-checkbox" checked disabled /><a class="wp-editor-md-post-content-link" href="https://blog.wonizz.com/2022/07/11/devops-ansible-nginx-config-deploy/">[DevOps] ansible nginx config 배포 구성</a>
  </li>
<li><input style="margin-right:5px" type="checkbox" class="task-list-item-checkbox" checked disabled /><a class="wp-editor-md-post-content-link" href="https://blog.wonizz.com/2023/08/10/linux-logrotate/">[DevOps] Nginx Logrotation 설정</a>
  </li>
<li><input style="margin-right:5px" type="checkbox" class="task-list-item-checkbox" checked disabled /><a class="wp-editor-md-post-content-link" href="https://blog.wonizz.com/2023/08/17/devops-nginx-geoip-module/">[DevOps] Nginx GeoIP 모듈 적용</a>
  </li>
<li><input style="margin-right:5px" type="checkbox" class="task-list-item-checkbox" checked disabled /><a class="wp-editor-md-post-content-link" href="https://blog.wonizz.com/2023/10/19/devops-nginx-log-aggregation-dashboard/">[DevOps] Nginx Log Aggregation &#038; Dashboard</a>
  </li>
<li><input style="margin-right:5px" type="checkbox" class="task-list-item-checkbox" checked disabled /><a class="wp-editor-md-post-content-link" href="https://blog.wonizz.com/2023/11/03/devops-nginx-rate-limit/">[DevOps] Nginx Rate Limit</a>
  </li>
<li><input style="margin-right:5px" type="checkbox" class="task-list-item-checkbox" checked disabled /><a class="wp-editor-md-post-content-link" href="https://blog.wonizz.com/2024/07/18/devops-nginx-lua-module/">[DevOps] Nginx Lua module 사용법</a>
  </li>
</ul>
<h2>1. Loki란 무엇인가요?</h2>
<p><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/blog.wonizz.tk/wp-content/uploads/2023/10//loki_1.png?w=1200" alt="DevOps Nginx Log Aggregation &#038; Dashboard 설명 이미지 1" /></p>
<p><strong>Loki</strong>는 Prometheus에 영감을 받아서 탄생한 클라우드 <strong>네이티브 인프라를 위한 로깅 서비스</strong> 입니다.</p>
<p><strong>KubeCon Seattle 2018에서 Grafana Labs에서 오픈소스로 공개</strong>된 Loki는 Kubernetes에서 Prometheus에 대한 경험이 있는 사용자에게 최적화된 로깅 백엔드입니다. Loki는 뛰어난 로그 검색 및 시각화 기능을 Grafana 6.0에서 제공합니다.</p>
<p><strong>Loki는 단일 로그 라인을 그대로 처리한다는 아이디어를 기반</strong>으로 만들어졌습니다. 이는 전체 텍스트 인덱싱을 하는 것이 아니라 Prometheus와 마찬가지로 동일한 label을 사용하여 관련 로그들을 그룹화한다는 것을 의미합니다. 이 방식은 훨씬 효율적이며 확장성이 좋습니다.</p>
<h3>구성 요소</h3>
<ul>
<li>Loki
<ul>
<li>메인 서버 구성 요소를 Loki라고 부르며 전달되는 로그들을 영구 저장하고 클라이언트의 <code>LogQL</code> 쿼리를 실행합니다.</li>
</ul>
</li>
</ul>
<p><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/blog.wonizz.tk/wp-content/uploads/2023/10//loki_2.png?w=1200" alt="DevOps Nginx Log Aggregation &#038; Dashboard 설명 이미지 2" /></p>
<p>Loki는 Components(querier, ingester, query-frontend, or distribute)로 구성이 됩니다.</p>
<ul>
<li>Distributor</li>
</ul>
<p>Distributor는 클라이언트(fluentd, fluent-bit, promtail)에서 들어오는 로그를 받아서 로그의 정확성을 검증하고 하나 이상의 Ingester에게 전달합니다.</p>
<ul>
<li>Ingester</li>
</ul>
<p>Ingester는 Distributors 로부터 로그를 수신하고 들어오는 데이터를 장기 저장소(DynamoDB, S3, Cassandra, etc.)에 저장을 합니다</p>
<ul>
<li>Querier</li>
</ul>
<p>Querier는 Ingester(내장 메모리) 및 장기 저장소(DynamoDB, S3, Cassandra, etc.) 에서 로그 쿼리 한 데이터를 가져온 후 중복을 제거 후 Grafana 또는 Query-Frontend 에게 데이터를 반환합니다.</p>
<ul>
<li>Query-Frontend</li>
</ul>
<p>쿼리 프론트엔드는 2020년 여름에 도입되었으며 분산 설정의 선택적 구성 요소입니다. 일종의 프록시 서비스라고 생각할 수 있습니다. Grafana에서 요청을 수신하고 일부 유효성 검사 및 캐싱을 수행한 다음 쿼리를 쿼리자에게 전달합니다.</p>
<h2>2. Loki 설치</h2>
<p>필자는 kubernetes를 운영하고 있기 때문에 helm을 통해서 설치하기로 했습니다.</p>
<p><a class="wp-editor-md-post-content-link" href="https://github.com/grafana/helm-charts/blob/main/charts/loki-stack/README.md" target="_blank" rel="noopener">loki stack helm cahrt</a></p>
<p>grafana/loki와 관련된 Helm Chart들을 살펴보면 5가지 방식으로 설치가 가능합니다.</p>
<ul>
<li><strong>grafana/loki : 현재 Grafana Loki에서 중점적으로 관리 및 업데이트하고 있는 Helm chart</strong></p>
</li>
<li><strong>grafana/loki-distributed : Microservice 형태로 Loki를 관리할 수 있도록 해주는 Helm chart</strong><br />
-> Ingester, Querier, Index Gateway, Distributor, Query-Frontend, Ruler 등으로 구분되어 있음</p>
</li>
<li><strong>grafana/loki-simple-scalable : 현재 Deprecated 되었지만 Loki를 아주 간단하게 관리할 수 있도록 도와주는 Helm chart</strong><br />
-> Write와 Read, Nginx gateway로만 구분되어 있다.</p>
</li>
<li><strong>grafana/loki-stack : 올인원 모놀리식 형태로 사용할 수 있는 Loki Helm chart</strong></p>
</li>
</ul>
<p>필자는 간단하면서도 내부용도로 사용하는 Loki를 구성하기 위해 올인원 방식으로 결정하였습니다.</p>
<ul>
<li>설치 버전 : v2.6.1
</li>
<li>
<p>Loki의 Chart 레포지토리를 helm에 추가</p>
</li>
</ul>
<pre><code class="language-bash line-numbers">$ helm repo add grafana https://grafana.github.io/helm-charts
$ helm repo update
</code></pre>
<blockquote><p>
  Loki의 Helm Chart에서 다음 사항을 false 처리함으로써 미사용으로 처리합니다.</p>
<ul>
<li>grafana.enabled=false</li>
<li>loki.persistence.enabled=false</li>
<li>promtail.enabled=false</li>
<li>Loki의 볼륨은 File System으로 관리 : 운영계일 경우 Loki : S3와 DynamoDB 혹은 Minio 등을 고려할 수 있겠지만 개발계에 로그와 모니터링 시스템을 구성할 예정이기 때문에 큰 상관이 없을 것이라 생각되어 파일 시스템으로 구성하되 최소한의 안전 장치로 PVC를 사용</li>
</ul>
</blockquote>
<p>필자의 구성은 Remote 서버의 Nginx 로그들을 Promtail을 통해서 Loki로 수집을 하고자 합니다. 따라서, 별도로 Cluster에는 Promtail이 필요 없기 때문에 미사용으로 표기를 합니다.</p>
<ul>
<li>values 파일 변경</li>
</ul>
<pre><code class="language-bash line-numbers">    $ helm upgrade --install loki grafana/loki-stack --create-namespace --namespace=monitoring --set grafana.enabled=false,promtail.enabled=false,loki.config.table_manager.retention_deletes_enabled=true,loki.config.table_manager.retention_period=336h,loki.persistence.enabled=false,loki.config.limits_config.max_query_series=100000,loki.config.frontend.max_outstanding_per_tenant: 4096,loki.config.query_range.parallelise_shardable_queries: true,loki.config.query_scheduler.max_outstanding_requests_per_tenant: 4096,loki.config.split_queries_by_interval: 15m,loki.config.max_query_parallelism: 32
</code></pre>
<ul>
<li>loki 설정 옵션</li>
</ul>
<pre><code class="language-bash line-numbers">grafana.enabled=false,
promtail.enabled=false,

loki.config.table_manager.retention_deletes_enabled=true,
loki.config.table_manager.retention_period=336h,
loki.persistence.enabled=false,

loki.config.limits_config.max_query_series=100000,
loki.config.frontend.max_outstanding_per_tenant: 4096,
loki.config.query_range.parallelise_shardable_queries: true,
loki.config.query_scheduler.max_outstanding_requests_per_tenant: 4096,

loki.config.split_queries_by_interval: 15m,
loki.config.max_query_parallelism: 32
</code></pre>
<ul>
<li>Nodeport 타입으로 변경</li>
</ul>
<pre><code class="language-bash line-numbers">$ kubectl edit svc loki -n monitoring
type : NodePort
</code></pre>
<ul>
<li>설치 검증</li>
</ul>
<pre><code class="language-bash line-numbers">$ kubectl --namespace=monitoring get services
$ kubectl --namespace=monitoring get pods
</code></pre>
<h2>3. Promtail 설치</h2>
<p>Loki를 설치 했으면, Nginx가 설치되어있는 서버에 <strong>Promtail</strong>을 설치하여, 로그를 Loki로 전송할 수 있도록 해보겠습니다.</p>
<p><a class="wp-editor-md-post-content-link" href="https://grafana.com/docs/loki/latest/clients/promtail/" target="_blank" rel="noopener">promtail official document</a></p>
<ul>
<li>설치 버전 : v2.7.3</li>
<li>binary download</li>
</ul>
<pre><code class="language-bash line-numbers">$ mkdir /etc/loki
$ cd /etc/loki
$ wget https://github.com/grafana/loki/releases/download/v2.7.3/promtail-linux-amd64.zip
$ unzip promtail-linux-amd64.zip
$ chmod a+x promtail-linux-amd64
$ rm -rf promtail-linux-amd64.zip
$ mv promtail-linux-amd64 promtail
</code></pre>
<ul>
<li>설정 파일 download &#038; 설정</li>
</ul>
<pre><code class="language-bash line-numbers">$ wget https://raw.githubusercontent.com/grafana/loki/main/clients/cmd/promtail/promtail-local-config.yaml

server:
  http_listen_port: 9080
  grpc_listen_port: 0

positions:
  filename: /tmp/positions.yaml

clients:
  - url: http://xx.xxx.xx.xxx:32617/loki/api/v1/push

scrape_configs:
- job_name: nginx
  static_configs:
  - targets:
      - localhost
    labels:
      job: nginxlogs
      __path__:  /home1/irteam/apps/nginx-1.20.1/logs/access_log
</code></pre>
<ul>
<li>service 등록</li>
</ul>
<pre><code class="language-bash line-numbers">$ sudo vi /etc/systemd/system/promtail.service

[Unit]
Description=Grafana Loki Promtail
Documentation=https://github.com/grafana/loki
After=network-online.target

[Service]
User=root
Restart=always
ExecStart=/etc/loki/promtail --config.file=/etc/loki/promtail-local-config.yaml

[Install]
WantedBy=multi-user.target
</code></pre>
<ul>
<li>service 시작</li>
</ul>
<pre><code class="language-bash line-numbers">$ systemctl restart promtail
$ systemctl status promtail 
</code></pre>
<h2>4. 그라파나 설정 및 대시 보드 구성</h2>
<p>이제 Loki, Promtail이 모두 구성이 됐으니, 로그는 정상적으로 수집이 될 것입니다. 그러면 Grafana에서 해당 Datasource 연결을 통해서 데이터가 정상적으로 수집이 되는지 확인을 해보도록 하겠습니다.</p>
<p><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/blog.wonizz.tk/wp-content/uploads/2023/10//loki_3.png?w=1200" alt="DevOps Nginx Log Aggregation &#038; Dashboard 설명 이미지 3" /></p>
<p>grafana의 Datasource를 추가해주는 화면에서 Target URL에 Loki의 IP:Nodeport를 입력을 해줍니다. 그렇게 되면, 정상적으로 연동이 됩니다.</p>
<ul>
<li>Grafana의 Explorer에서 LokiQL을 통해서 조회</li>
</ul>
<p><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/blog.wonizz.tk/wp-content/uploads/2023/10//loki_4.png?w=1200" alt="DevOps Nginx Log Aggregation &#038; Dashboard 설명 이미지 4" /></p>
<p>Nginx에서 쌓이는 Access log가 동일하게 Loki에서 정상 수집됨을 확인 할 수 있습니다.</p>
<ul>
<li>Grafana의 Dashboard 연동을 통해서 시각화</li>
</ul>
<p><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/blog.wonizz.tk/wp-content/uploads/2023/10//loki_5.png?w=1200" alt="DevOps Nginx Log Aggregation &#038; Dashboard 설명 이미지 5" /></p>
<h2> </h2>
<h2>5. 마치며&#8230;</h2>
<p>Nginx의 Access 로그는 서비스의 유입점이기 떄문에 굉장히 유용한 정보로 활용 될 수 있습니다. 이에 대한 로그를 빠르게 수집하고 시각화 하여 활용하게 되면 서비스의 안정화 혹은 사업적으로도 가치가 높습니다.</p>
<p>Loki와 Promtail에 대해서 간단하게 적용해 볼 수 있도록 포스팅을 정리해봤습니다. 추후에는 Loki의 쿼리 속도 개선에 대해서 정리를 해보도록 하겠습니다.</p>
<h2>6. 참고</h2>
<ul>
<li><strong><a class="wp-editor-md-post-content-link" href="https://devocean.sk.com/blog/techBoardDetail.do?ID=163964" target="_blank" rel="noopener">Grafana Loki에 대해 알아보자</a></strong></li>
<li><strong><a class="wp-editor-md-post-content-link" href="https://medium.com/@dudwls96/logging-grafana-loki-아키텍처-구성-6c1f0d83a5f3" target="_blank" rel="noopener">Logging/Grafana Loki 아키텍처 구성</a></strong></li>
<li><strong><a class="wp-editor-md-post-content-link" href="https://jerryljh.medium.com/loki-실-적용-내역-공유-db32169b7f43" target="_blank" rel="noopener">Loki 실 적용 내역 공유</a></strong></li>
<li><strong><a class="wp-editor-md-post-content-link" href="https://lapee79.github.io/article/loki-kubernetes-logging/" target="_blank" rel="noopener">Loki &#8211; Kubernetes 로깅</a></strong></li>
<li><strong><a class="wp-editor-md-post-content-link" href="https://dev.to/airoasis/lokireul-iyonghan-sonswiun-kubernetes-logging-1iho" target="_blank" rel="noopener">Loki를 이용한 손쉬운 Kubernetes Logging</a></strong></li>
<li><strong><a class="wp-editor-md-post-content-link" href="https://nyyang.tistory.com/159" target="_blank" rel="noopener">[EKS] 아주 가벼운 Loki + Grafana + Promtail 로그 시스템 구성</a></strong></li>
<li><strong><a class="wp-editor-md-post-content-link" href="https://volkovlabs.io/blog/nginx-loki-grafana-20230129/" target="_blank" rel="noopener">Website Analytics based on Nginx, Loki, Promtail, and Grafana</a></strong></li>
<li>Native 설치
<ul>
<li><strong><a class="wp-editor-md-post-content-link" href="https://wiki.linecorp.com/pages/viewpage.action?pageId=2997171053" target="_blank" rel="noopener">Grafana 외부 서버의 데이터를 가져오기 &#8211; NGINX &#8211; access.log</a></strong></li>
<li><strong><a class="wp-editor-md-post-content-link" href="https://mycup.tistory.com/319" target="_blank" rel="noopener">Grafana loki, promtail</a></strong></li>
</ul>
</li>
<li>Promtail 참고
<ul>
<li><strong><a class="wp-editor-md-post-content-link" href="https://gist.github.com/clayman083/4df41d1ee9fc3dd0598c90830a9c4740" target="_blank" rel="noopener">Promtail config for syslog and extract labels from nginx logs</a></strong></li>
<li><strong><a class="wp-editor-md-post-content-link" href="https://gist.github.com/ruanbekker/b863902b3c9d7194e28fa68d0860cf6d" target="_blank" rel="noopener">Tinkering with Loki, Promtail, Grafana, Prometheus, Nginx and Dnsmasq</a></strong></li>
</ul>
</li>
</ul>
<p>The post <a rel="nofollow" href="https://blog.wonizz.com/2023/10/19/devops-nginx-log-aggregation-dashboard/">[DevOps] Nginx Log Aggregation &#038; Dashboard</a> appeared first on <a rel="nofollow" href="https://blog.wonizz.com">WONIZZ.LOG</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.wonizz.com/2023/10/19/devops-nginx-log-aggregation-dashboard/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2074</post-id>	</item>
		<item>
		<title>[DevOps] Hubot 적용기</title>
		<link>https://blog.wonizz.com/2023/05/11/devops-hubot-automation-1/</link>
					<comments>https://blog.wonizz.com/2023/05/11/devops-hubot-automation-1/#comments</comments>
		
		<dc:creator><![CDATA[워니]]></dc:creator>
		<pubDate>Thu, 11 May 2023 12:53:16 +0000</pubDate>
				<category><![CDATA[kubernetes]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[Tech]]></category>
		<guid isPermaLink="false">https://blog.wonizz.tk/?p=2037</guid>

					<description><![CDATA[<p>The standard Lorem Ipsum passage, used since the 1500s<br />
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."</p>
<p>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"</p>
<p>1914 translation by H. Rackham<br />
"But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?"</p>
<p>Section 1.10.33 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."</p>
<p>1914 translation by H. Rackham<br />
"On the other hand, we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment, so blinded by desire, that they cannot foresee the pain and trouble that are bound to ensue; and equal blame belongs to those who fail in their duty through weakness of will, which is the same as saying through shrinking from toil and pain. These cases are perfectly simple and easy to distinguish. In a free hour, when our power of choice is untrammelled and when nothing prevents our being able to do what we like best, every pleasure is to be welcomed and every pain avoided. But in certain circumstances and owing to the claims of duty or the obligations of business it will frequently occur that pleasures have to be repudiated and annoyances accepted. The wise man therefore always holds in these matters to this principle of selection: he rejects pleasures to secure other greater pleasures, or else he endures pains to avoid worse pains."</p>
<p>안녕하세요? 정리하는 개발자 워니즈입니다. 이번시간에는 hubot 적용기에 대해서 정리를 해보도록 하겠습니다. 필자는 DevOps업무를 하다보니, 주로 여러개의 개발팀으로부터의 요청들 (CI/CD설정, 네트워크, 인프라, 모니터링 등)에 대해서 처리를 해주는 업무를 합니다. 요청양도 최근들어 꽤나 늘어났고, 요청의 범주도 굉장히 다양하기 때문에 Slack W/F를 통해서 모든것으르 제어하기는 어려운 시점이 왔습니다. JIRA의 티켓을 수동으로 등록하여 관리를 하고있었는데, 이부분을 자동화 시키고 슬랙&#8230;&#160;</p>
<p>The post <a rel="nofollow" href="https://blog.wonizz.com/2023/05/11/devops-hubot-automation-1/">[DevOps] Hubot 적용기</a> appeared first on <a rel="nofollow" href="https://blog.wonizz.com">WONIZZ.LOG</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>The standard Lorem Ipsum passage, used since the 1500s<br />
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."</p>
<p>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"</p>
<p>1914 translation by H. Rackham<br />
"But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?"</p>
<p>Section 1.10.33 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."</p>
<p>1914 translation by H. Rackham<br />
"On the other hand, we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment, so blinded by desire, that they cannot foresee the pain and trouble that are bound to ensue; and equal blame belongs to those who fail in their duty through weakness of will, which is the same as saying through shrinking from toil and pain. These cases are perfectly simple and easy to distinguish. In a free hour, when our power of choice is untrammelled and when nothing prevents our being able to do what we like best, every pleasure is to be welcomed and every pain avoided. But in certain circumstances and owing to the claims of duty or the obligations of business it will frequently occur that pleasures have to be repudiated and annoyances accepted. The wise man therefore always holds in these matters to this principle of selection: he rejects pleasures to secure other greater pleasures, or else he endures pains to avoid worse pains."</p>
안녕하세요? 정리하는 개발자 워니즈입니다. 이번시간에는 hubot 적용기에 대해서 정리를 해보도록 하겠습니다. 필자는 <strong>DevOps</strong>업무를 하다보니, 주로 여러개의 개발팀으로부터의 요청들 (CI/CD설정, 네트워크, 인프라, 모니터링 등)에 대해서 처리를 해주는 업무를 합니다.

요청양도 최근들어 꽤나 늘어났고, 요청의 범주도 굉장히 다양하기 때문에 <strong>Slack W/F</strong>를 통해서 모든것으르 제어하기는 어려운 시점이 왔습니다.

<strong>JIRA</strong>의 티켓을 수동으로 등록하여 관리를 하고있었는데, 이부분을 자동화 시키고 슬랙 Thread상에서 일감을 처리하면 자동 종료까지 되는 부분으로 업무의 프로세스를 개선하고 싶었습니다.

<h2>1. hubot 소개</h2>

<ul>
<li>Hubot 은 깃헙의 사내용으로 제작된 챗봇이지만, 많은 발전을 거듭하여 현재 오픈소스로 공개되어있습니다. Node 기반이며, Slack과 친화적입니다.</li>
<li>휴봇의 가장 큰 장점은 간단한 스크립트(CoffeeScript, JavaScript) 작성을 통해 강력한 기능을 추가할 수 있다는 점입니다.</li>
<li>특정 단어 혹은 문장에 따라 <strong>프로세스</strong>를 정의할 수 있습니다. 이미 구축된 스크립트들도 많이 공개 되어있어 손쉽게 스크립트를 추가하여 구현할 수 있습니다.</li>
</ul>

<pre><code class="language-coffeescript line-numbers">enterReplies = ['Hi', 'Target Acquired', 'Firing', 'Hello friend.', 'Gotcha', 'I see you']
leaveReplies = ['Are you still there?', 'Target lost', 'Searching']

module.exports = (robot) ->
  robot.enter (res) ->
    res.send res.random enterReplies
  robot.leave (res) ->
    res.send res.random leaveReplies

[출처] https://blog.hax0r.info/2017-05-14/slack-developer-kit-for-hubot/  [Hax0r blog]
</code></pre>

스크립트를 통해 Local 혹은 Heroku를 통해 배포하여 슬랙과 연동할 수 있습니다.

<ul>
<li><a class="wp-editor-md-post-content-link" href="https://github.com/hubot-scripts/hubot-diagnostics" target="_blank" rel="noopener">hubot-diagnostics</a>: 간단한 기본기능들이 들어있다. 위에서 사용했던 <code>ping</code>을 이 모듈이 응답한 것이다. 그 외 <code>time</code>과 <code>echo</code>도 있다.</li>
<li><a class="wp-editor-md-post-content-link" href="https://github.com/hubot-scripts/hubot-help" target="_blank" rel="noopener">hubot-help</a>: 현재 hubot의 명령어들을 표시해준다. script들의 # Commands 들을 가져와서 뿌려주는 역할을 한다.</li>
<li><a class="wp-editor-md-post-content-link" href="https://github.com/hubot-scripts/hubot-pugme" target="_blank" rel="noopener">hubot-pugme</a>: 설명을 보면은 가장 중요한 휴봇 스크립트라고 적혀있다. 기능은 퍼그 이미지 url을 랜덤으로 가져오는 것이다. 하지만 2년이 지나서 그런지 url이 유효하지 않다.</li>
<li><a class="wp-editor-md-post-content-link" href="https://github.com/hubot-scripts/hubot-rules" target="_blank" rel="noopener">hubot-rules</a>: hubot의 룰을 설명한다. <code>> hubot rules</code>으로 볼 수 있다.</li>
<li><a class="wp-editor-md-post-content-link" href="https://github.com/hubot-scripts/hubot-shipit" target="_blank" rel="noopener">hubot-shipit</a>: 가지고 있는 이미지URL중 랜덤으로 하나를 보내준다. <code>hubot-pugme</code>와 마찬가지로 유효한 URL이 별로 없다.</li>
<li><a class="wp-editor-md-post-content-link" href="https://github.com/hubot-scripts/hubot-heroku-keepalive" target="_blank" rel="noopener">hubot-heroku-keepalive</a>: 무료 heroku를 사용할 경우 하루 사용시간 제한이 있기 때문에 필요한 것 같다.</li>
<li><a class="wp-editor-md-post-content-link" href="https://github.com/hubot-scripts/hubot-redis-brain" target="_blank" rel="noopener">hubot-redis-brain</a>: hubot의 brain기능을 redis로 이용하는 것이다.
<a class="wp-editor-md-post-content-link" href="https://github.com/hubot-scripts/hubot-google-images" target="_blank" rel="noopener">hubot-google-images</a>와 <a class="wp-editor-md-post-content-link" href="https://github.com/hubot-scripts/hubot-google-translate" target="_blank" rel="noopener">hubot-google-translate</a>는 이름에서도 알 수 있듯이 구글의 API키를 받아서 구글 서비스를 사용할 때 필요하다.
<a class="wp-editor-md-post-content-link" href="https://github.com/gkoo/hubot-maps" target="_blank" rel="noopener">hubot-maps</a>도 구글의 맵서비스를 이용하는 것이다.</li>
</ul>

<h2>2. hubot 설치 및 설정</h2>

hubot은 기본적으로 node기반으로 수행되는 어플리케이션입니다. 따라서 npm과 node가 설치되어있어야 설치가 가능합니다.

<ul>
<li>node version : v16.17.0</li>
<li>npm version : 8.15.0</li>
</ul>

<h3>2-1. hubot 설치</h3>

<pre><code class="language-bash line-numbers">$ npm install -g yo generator-hubot
</code></pre>

여기서 <a class="wp-editor-md-post-content-link" href="http://yeoman.io/" target="_blank" rel="noopener">yoman</a> 이라는것을 같이 설치하게 되는데, 간단하게 말하면 구조를 어플리케이션의 구조를 잡아주는 도구라고 보시면 됩니다.

<pre><code class="language-bash line-numbers">$ mkdir -p ~/apps/devops
$ cd ~/apps/devops
$ yo hubot --adapter=slack
</code></pre>

여기서 몇가지 Interactive Question을 받게 되는데, 간단하게 입력을 하면됩니다.

<h3>2-2. hubot 설정</h3>

이제 간단하게 hubot 설치는 마쳤습니다. Hubot 기능중에 데이터 유지를 위해서 Redis module이 자동적으로 들어가있는데 이부분을 제거해야 합니다.

<pre><code class="language-bash line-numbers"># external-script.json
[]
</code></pre>

external-script.json에는 hubot에 필요한 모듈들을 탑재할 수 있는데, 별도의 서버에서 구성을 진행하기 때문에 모든 내용들을 삭제해줘도 무방합니다. 밑의 내용은 필수적으로 삭제를 진행합니다.

<ul>
<li>hubot-heroku-keepalive</li>
<li>hubot-redis-brain</li>
</ul>

<pre><code class="language-bash line-numbers"># ~/apps/devops/node_modules/hubot/src/hubot.js
...
const port = process.env.EXPRESS_PORT || process.env.PORT || 8083
...
</code></pre>

port도 겹치지 않게 custom port로 변경을 해줍니다.

<h3>2-3. Slack 설정</h3>

Hubot 사용의 가장 큰 목적은 Slack을 통해서 <strong>ChatOps</strong>를 구현하기 위함입니다. 따라서 Slack에 앱을 추가하고 연동을 하는 작업이 필요합니다.

<img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/blog.wonizz.com/wp-content/uploads/2023/05/hubot_1.png?w=1200&#038;ssl=1" alt="DevOps Hubot 적용기 설명 이미지 1" />

Slack 앱을 추가하면 Hubot 설정 페이지가 나오게 되고, 그곳에서 Hubot의 <strong>Token</strong>값을 얻을 수 있습니다.

<h3>2-4. Hubot 실행</h3>

<pre><code class="language-bash line-numbers">$ HUBOT_SLACK_TOKEN=xoxb-... ./bin/hubot --adapter slack
</code></pre>

hubot을 실행하게 되면, Slack상에 Hubot이 연결이 되면서 연결중으로 접속이 표시가 됩니다. 이렇게 되면 설치 &amp; 설정이 마무리 된것이고, Hubot에 대한 Script를 작성해서 기능을 추가하면 됩니다.

<h2>3. hubot script 가이드</h2>

hubot은 script를 통해서 기능 확장이 가능하고, 현재 open source로 나와있는 여러가지 Script들을 참고 할 수도 있습니다.

<ul>
<li><a class="wp-editor-md-post-content-link" href="https://hubot.github.com/docs/scripting/" target="_blank" rel="noopener">Hubot Script Guide</a>

<ul>
<li>.coffee 혹은 .js 파일로 작성이 가능합니다.</li>
</ul></li>
</ul>

<h3>3-1. send/ reply / emote</h3>

<pre><code class="language-bash line-numbers"># 경로에 script 작성 /apps/devops/scripts
# send : room으로 왔으면 room으로 전달, DM으로 오면 DM으로 전달
# reply : thread에 댓글 형식으로 메시지 전달
# emote : room으로 메시지 전달 
module.exports = (robot) -> 
  robot.hear /badger/i, (res) ->
    res.send "Badgers? BADGERS? WE DON'T NEED NO STINKIN BADGERS"

  robot.respond /open the pod bay doors/i, (res) ->
    res.reply "I'm afraid I can't let you do that."

  robot.hear /I like pie/i, (res) ->
    res.emote "makes a freshly baked pie"


</code></pre>

<h3>3-2. messageRoom</h3>

<pre><code class="language-bash line-numbers"># messageRoom 기능을 이용하여 지정된 방이나 사용자에게 메시지를 보낼 수 있습니다.
module.exports = (robot) ->
  robot.hear /green eggs/i, (res) ->
    room = "mytestroom"
    robot.messageRoom room, "I do not like green eggs and ham.  I do not like them sam-I-am."

  robot.respond /I don't like Sam-I-am/i, (res) ->
    room =  'joemanager'
    robot.messageRoom room, "Someone does not like Dr. Seus"
    res.reply  "That Sam-I-am\nThat Sam-I-am\nI do not like\nthat Sam-I-am"

  robot.hear /Sam-I-am/i, (res) ->
    room =  res.envelope.user.name
    robot.messageRoom room, "That Sam-I-am\nThat Sam-I-am\nI do not like\nthat Sam-I-am"
</code></pre>

<h3>3-3. Capturing</h3>

<pre><code class="language-bash line-numbers"># 정규식에 대해 들어오는 메시지를 처리할 수 있습니다. 
  robot.respond /open the (.*) doors/i, (res) ->
    doorType = res.match[1]
    if doorType is "pod bay"
      res.reply "I'm afraid I can't let you do that."
    else
      res.reply "Opening #{doorType} doors"
</code></pre>

<h3>3-4. HTTP 호출하기</h3>

<pre><code class="language-bash line-numbers"># Hubot은 3rd API들과 연계하기 위해서 HTTP 호출을 할 수 있습니다.
  data = JSON.stringify({
    foo: 'bar'
  })
  robot.http("https://midnight-train")
    .header('Content-Type', 'application/json')
    .post(data) (err, res, body) ->
      # your code here
      if err
        res.send "Encountered an error : ( #{err}"
        return
      # your code here, knowing it was successful   

      if res.statusCode isnt 200
        res.send "Request didn't come back HTTP 200 : ("
        return

      # RateLimit을 이용하여 호출량을 조절
      rateLimitRemaining = parseInt res.getHeader('X-RateLimit-Limit') if res.getHeader('X-RateLimit-Limit')
      if rateLimitRemaining and rateLimitRemaining < 1
        res.send "Rate Limit hit, stop believing for awhile"      

</code></pre>

<h3>3-5.  HTTP 수신기</h3>

<pre><code class="language-bash line-numbers"># Hubot은 HTTP 요청을 처리하기 위한 익스프레스 웹 프레임워크에 대한 지원을 포함합니다. 
# 해당 포트로 정적파일 제공도 가능합니다.

module.exports = (robot) ->
  # the expected value of :room is going to vary by adapter, it might be a numeric id, name, token, or some other value
  robot.router.post '/hubot/chatsecrets/:room', (req, res) ->
    room   = req.params.room
    data   = if req.body.payload? then JSON.parse req.body.payload else req.body
    secret = data.secret

    robot.messageRoom room, "I have a secret: #{secret}"

    res.send 'OK'

# Curl을 이용하여 테스트
// raw json, must specify Content-Type: application/json
curl -X POST -H "Content-Type: application/json" -d '{"secret":"C-TECH Astronomy"}' http://127.0.0.1:8080/hubot/chatsecrets/general

// defaults Content-Type: application/x-www-form-urlencoded, must st payload=...
curl -d 'payload=%7B%22secret%22%3A%22C-TECH+Astronomy%22%7D' http://127.0.0.1:8080/hubot/chatsecrets/general
</code></pre>

<h3>3-6. 기타 기능</h3>

<pre><code class="language-bash line-numbers"># Randomize
lulz = ['lol', 'rofl', 'lmao']

res.send res.random lulz

# Detect Enter & Exit
enterReplies = ['Hi', 'Target Acquired', 'Firing', 'Hello friend.', 'Gotcha', 'I see you']
leaveReplies = ['Are you still there?', 'Target lost', 'Searching']

module.exports = (robot) ->
  robot.enter (res) ->
    res.send res.random enterReplies
  robot.leave (res) ->
    res.send res.random leaveReplies

# Brain 
robot.respond /have a soda/i, (res) ->
  # Get number of sodas had (coerced to a number).
  sodasHad = robot.brain.get('totalSodas') * 1 or 0

  if sodasHad > 4
    res.reply "I'm too fizzy.."

  else
    res.reply 'Sure!'

    robot.brain.set 'totalSodas', sodasHad+1
robot.respond /sleep it off/i, (res) ->
  robot.brain.set 'totalSodas', 0
  msg.reply 'zzzzz'

</code></pre>

<h2>4. hubot 기능 구현</h2>

필자가 최초 생각했던 것처럼, Slack W/F와 연계하여 각 개발팀에서 DevOps를 통한 문의 및 요청들이 접수되면, 해당 내용을 기반으로 Hubot이 JIRA에 Ticket을 생성하고 해당 Ticket을 링크로 응답 합니다.

또한, 작업이 모두 완료된 이후로는 emoji를 설정하였을때, 작업을 종료하도록 구성하고자 합니다.

<h3>4-1. JIRA 자동 등록</h3>

JIRA에 자동 등록을 하기 위해서는 JIRA의 API를 활용해야 합니다.

<a class="wp-editor-md-post-content-link" href="https://developer.atlassian.com/server/jira/platform/jira-rest-api-examples/" target="_blank" rel="noopener">Jira Rest API 문서</a>

간단하게 JSON 구조를 만들어서 http request를 한 뒤, 결과를 parsing하여 massage로 다시 return해주는 구조입니다. 그렇게 되면, Slack의 Thread 상에서 티켓의 링크를 확인할 수 있습니다.

<pre><code class="language-coffeescript line-numbers">module.exports = (robot) ->
  robot.respond /create TICKET(.*)/i, (msg) ->

    threadId = getThreadId(msg);
    title = ''
    for line in msg.message.text.split(/\r?\n/)
      console.log (line)
      if line.indexOf("*Summary : *") != -1
        title = line.replace /\*Summary \:\*/, ""
    if title == ''
      msg.send 'Faild to get the subject'
      return
    json =
      fields:
        project:
          key: "LNDO"
        summary: title,
        description: msg.message.text,
        issuetype:
          name: "_Task"
        labels: ["help_devops_thread"]
    json = JSON.stringify(json)    

    create_query = btsBaseUrl + "/rest/api/2/issue"
    auth = btoa("#{user}:#{password}")

    msg.http(create_query)
      .headers(Authorization: "Basic #{auth}", 'Content-Type': 'application/json')
      .post(json) (err, res, body) ->
        issueName = undefined
        if body
          returnJson = JSON.parse(body)
          if returnJson.hasOwnProperty('key')
            issueName = returnJson.key
        if err
          console.log 'Error!'
          console.log err
        if issueName == undefined
          console.log res
          msg.send 'Error on creation issue on BTS'
        else
          link = '<https://jira.test.com/browse/' + issueName + '|' + issueName + '>'
          msg.send 'Create TICKET at ' + link
          threadCache[threadId] = {'lastUpdate': Date.now(), 'fsUpdate': Date.now(), 'BTS': issueName}
          fs.writeFileSync(threadDir + threadId, JSON.stringify(threadCache[threadId]))
</code></pre>

<h3>4-2. JIRA 상태 업데이트</h3>

Slack을 통해서 일감 처리가 완료되면, 이모지(DONE)를 통해서 해당 요청이 종료되었다는 것을 표기하였습니다. 그러다보니 명확하게 티켓과 동기화가 되지 않았었습니다. 이러한 부분을 이모지를 인식해서 티켓의 상태를 업데이트(Resolve)처리를 하도록 구성했습니다.

<pre><code class="language-coffeescript line-numbers">robot.respond /(.*)resolve TICKET(.*)/i, (msg) ->
    threadId = getThreadId(msg);
    getThreadCache(threadId);

    json =
      transition:
        id: "21"
      fields:
        resolution:
          name: "Done"
    json = JSON.stringify(json)

    BTS = threadCache[threadId]['BTS']
    resolve_query = btsBaseUrl + '/rest/api/2/issue/' + BTS + '/transitions?expand=transitions.fields&transitionId=21'
    auth = btoa("#{user}:#{password}")

    msg.http(resolve_query)
      .headers(Authorization: "Basic #{auth}", 'Content-Type': 'application/json')
      .post(json) (err, res, body) ->
        if body
          returnJson = JSON.parse(body)
          console.log(returnJson)
        if err
          console.log err
          msg.send 'There is an error reolsve ticket!'
        else
          link = '<https://jira.test.com/browse/' + BTS + '|' + BTS + '>'
          msg.send 'Cloase BTS  at ' + link
          threadCache[threadId] = {'lastUpdate': Date.now(), 'fsUpdate': Date.now(), 'BTS': BTS}
          fs.writeFileSync(threadDir + threadId, JSON.stringify(threadCache[threadId]))
</code></pre>

<h2>5. hubot 구성도</h2>

<img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/blog.wonizz.com/wp-content/uploads/2023/05/hubot_2.png?w=1200&#038;ssl=1" alt="DevOps Hubot 적용기 설명 이미지 2" />

전체적인 구성도는 위와 같습니다.

<ul>
<li>Request Layer : Slack W/F를 통해서 요청하는 영역</li>
<li>Slack - Hubot Layer : Slack의 W/F를 분석하여 Hubot 스크립트를 수행하는 영역</li>
<li>InfraStructure Layer : Hubot과 연계되는 Tools가 위치하는 영역</li>
</ul>

이번에 정리된 기준으로는 Jira의 Ticket을 생성하고 종료하는 내용이였습니다. 추후에는 기능을 좀더 강화 할 예정입니다.

<h2>6. 마치며..</h2>

이번시간에는 Slack W/F와 Hubot을 연계하여 업무를 자동화했던 내용을 정리해보았습니다. DevOps업무를 하면서 자동화 처리를 통하여 좀더 효율적으로 일하는 문화를 배울 수 있었고, 특히나 업무 자체를 코드화 시키고, 프로세스화 시키니까 처리하기가 좀더 수월했던 것 같습니다.

다음시간에는 Hubot의 좀더 강화된 기능을 사용하는 내용으로 찾아뵙겠습니다.
<h2 class="wp-block-heading">함께 보면 좋은 글</h2>
<ul class="wp-block-list"><li><a href="https://blog.wonizz.com/2021/09/01/kubeadm-pod-cidr-change/">[DevOps] kubeadm upgrade를 통한 pod cidr 변경</a></li><li><a href="https://blog.wonizz.com/2023/11/03/devops-nginx-rate-limit/">[DevOps] Nginx Rate Limit</a></li><li><a href="https://blog.wonizz.com/2023/05/09/devops-k8s-monitoring-with-datadog/">[DevOps] k8s monitoring with Datadog</a></li><li><a href="https://blog.wonizz.com/2023/05/08/devops-istio-virtualhost/">[DevOps] Istio virtualhost 사용법</a></li></ul>
<p>The post <a rel="nofollow" href="https://blog.wonizz.com/2023/05/11/devops-hubot-automation-1/">[DevOps] Hubot 적용기</a> appeared first on <a rel="nofollow" href="https://blog.wonizz.com">WONIZZ.LOG</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.wonizz.com/2023/05/11/devops-hubot-automation-1/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2037</post-id>	</item>
		<item>
		<title>[DevOps] k8s monitoring with Datadog</title>
		<link>https://blog.wonizz.com/2023/05/09/devops-k8s-monitoring-with-datadog/</link>
					<comments>https://blog.wonizz.com/2023/05/09/devops-k8s-monitoring-with-datadog/#respond</comments>
		
		<dc:creator><![CDATA[워니]]></dc:creator>
		<pubDate>Tue, 09 May 2023 01:51:38 +0000</pubDate>
				<category><![CDATA[kubernetes]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[Tech]]></category>
		<guid isPermaLink="false">https://blog.wonizz.tk/?p=2034</guid>

					<description><![CDATA[<p>The standard Lorem Ipsum passage, used since the 1500s<br />
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."</p>
<p>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"</p>
<p>1914 translation by H. Rackham<br />
"But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?"</p>
<p>Section 1.10.33 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."</p>
<p>1914 translation by H. Rackham<br />
"On the other hand, we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment, so blinded by desire, that they cannot foresee the pain and trouble that are bound to ensue; and equal blame belongs to those who fail in their duty through weakness of will, which is the same as saying through shrinking from toil and pain. These cases are perfectly simple and easy to distinguish. In a free hour, when our power of choice is untrammelled and when nothing prevents our being able to do what we like best, every pleasure is to be welcomed and every pain avoided. But in certain circumstances and owing to the claims of duty or the obligations of business it will frequently occur that pleasures have to be repudiated and annoyances accepted. The wise man therefore always holds in these matters to this principle of selection: he rejects pleasures to secure other greater pleasures, or else he endures pains to avoid worse pains."</p>
<p>안녕하세요? 정리하는 개발자 워니즈 입니다. 이번시간에는 올해 가장 뿌듯하면서도 성취감 있었던 일중 하나인 datadog모니터링 도입기에 대해서 정리를 하고자 합니다. 현재 진행중인 프로젝트는 Java기반의 Spring Boot로 된 서비스를 개발/운영중입니다. APM(Application Performance Monitoring)을 위해서 기존에는 pinpoint를 사용하고있었지만, 다소 부족한 기능과 전체적인 서비스 가시성을 확보하지 못하여, 상용 솔루션인 Datadog를 도입하기로 하였습니다. 1. Datadog Agent 소개 데이터독을 통해서 그러면&#8230;&#160;</p>
<p>The post <a rel="nofollow" href="https://blog.wonizz.com/2023/05/09/devops-k8s-monitoring-with-datadog/">[DevOps] k8s monitoring with Datadog</a> appeared first on <a rel="nofollow" href="https://blog.wonizz.com">WONIZZ.LOG</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>The standard Lorem Ipsum passage, used since the 1500s<br />
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."</p>
<p>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"</p>
<p>1914 translation by H. Rackham<br />
"But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?"</p>
<p>Section 1.10.33 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."</p>
<p>1914 translation by H. Rackham<br />
"On the other hand, we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment, so blinded by desire, that they cannot foresee the pain and trouble that are bound to ensue; and equal blame belongs to those who fail in their duty through weakness of will, which is the same as saying through shrinking from toil and pain. These cases are perfectly simple and easy to distinguish. In a free hour, when our power of choice is untrammelled and when nothing prevents our being able to do what we like best, every pleasure is to be welcomed and every pain avoided. But in certain circumstances and owing to the claims of duty or the obligations of business it will frequently occur that pleasures have to be repudiated and annoyances accepted. The wise man therefore always holds in these matters to this principle of selection: he rejects pleasures to secure other greater pleasures, or else he endures pains to avoid worse pains."</p>
안녕하세요? 정리하는 개발자 워니즈 입니다. 이번시간에는 올해 가장 뿌듯하면서도 성취감 있었던 일중 하나인 <strong>datadog</strong>모니터링 도입기에 대해서 정리를 하고자 합니다.

현재 진행중인 프로젝트는 Java기반의 Spring Boot로 된 서비스를 개발/운영중입니다. <strong>APM(Application Performance Monitoring)</strong>을 위해서 기존에는 pinpoint를 사용하고있었지만, 다소 부족한 기능과 전체적인 서비스 가시성을 확보하지 못하여, 상용 솔루션인 <strong>Datadog</strong>를 도입하기로 하였습니다.

<h2>1. Datadog Agent 소개</h2>

데이터독을 통해서 그러면 어떠한 내용들을 확인 할 수 있을까요? k8s Cluster와 관련된 모든 정보를 확인할 수 있습니다.

<ul>
<li>Cluster Node의 가시성 확보</li>
<li>POD / Container 레벨의 가시성 확보</li>
<li>Kubernetes Event 수집</li>
<li>Application의 Trace 정보 수집</li>
</ul>

그러면 각 Layer 별로 수집을 하기 위해서 어떤 내용이 필요한지 정리해보도록 하겠습니다.
Datadog의 내용들은 공식 Blog에서도 확인할 수 있습니다.

<a class="wp-editor-md-post-content-link" href="https://www.datadoghq.com/blog/" target="_blank" rel="noopener">Datadog Blog</a>

<img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/imgix.datadoghq.com/img/blog/datadog-cluster-agent/kubernetes_diagrams_before_updated.png?w=1200&#038;ssl=1" alt="datadog_1" />

<h3>Kubelet에서 노드 수준 데이터 수집</h3>

Datadog 에이전트는 각 worker node에서 kubelet을 모니터링하여 컨테이너가 어떻게 동작하는지에 대한 모든 메트릭들을 수집합니다.

<h3>API 서버에서 클러스터 수준 데이터 수집</h3>

Datadog 에이전트는 Kubernetes API 서버에 개별적으로 쿼맇아ㅕ 특정 구성 요소의 동작에 대한 데이터를 수집하고 클러스터 전체에 대한 주요 메타데이터를 수집합니다. 이 설정은 클러스터의 규모가 커지면 커질수록 API 서버 및 etcd에 대한 로드를 증가 시켰습니다.

<h3>Datadog 클러스터 에이전트를 통한 분산</h3>

<img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/imgix.datadoghq.com/img/blog/datadog-cluster-agent/kubernetes_diagrams_after_updated.png?w=1200&#038;ssl=1" alt="datadog_2" />

클러스터 에이전트는 API 서버와 노드 기반 에이전트 간의 프록시 역할을 합니다. 이는 API 서버의 직접 부하를 완화할 뿐만 아니라 노드 기반 에이전트가 노드 수준 데이터 수집에 집중할 수 있도록 하는 반면 클러스터 에이전트는 Control Plane에서 클러스터 수준 데이터를 수집합니다.

정리를 하면 다음과 같습니다.

<ul>
<li>datadog-agent : 데이터독 에이전트는 각 노드의 메트릭, 분산 추적 및 로그를 수집하고 서버 리소스(CPU, Memory등) 메트릭을 자동으로 수집</li>
<li>datadog-kube-state-metrics-agent : Kubernetes API를 감시하여 객체의 상태에 대한 메트릭을 수집.</li>
<li>datadog-cluster-agent : node agent에서 Master노드의 API 서버에 직접 쿼리를 하게되면 클러스터 증가시 Master노드의 API서버 및 etcd에 대한 로그가 증가하기 때문에 Master 노드의 서버 부하를 줄이기 위해 API서버와 node agent간의 프록시 역할을 한다.</li>
</ul>

<h2>2. Datadog Agent 설치</h2>

사용자 지정 릴리스 이름으로 차트를 설치하려면 <code>RELEASE_NAME</code>(예: <code>datadog-agent</code>):

<ol>
<li><a class="wp-editor-md-post-content-link" href="https://v3.helm.sh/docs/intro/install/" target="_blank" rel="noopener">Helm</a> 를 설치합니다 .</li>
<li>Datadog Helm 저장소를 추가합니다.<code>helm repo add datadog https://helm.datadoghq.com</code></li>
<li>새로 추가된 차트의 최신 버전 가져오기: <code>helm repo update</code>.</li>
<li>빈 values.yaml 파일을 만들고 원하는 경우 <a class="wp-editor-md-post-content-link" href="https://github.com/DataDog/helm-charts/blob/main/charts/datadog/values.yaml" target="_blank" rel="noopener">기본값</a> 을 재정의합니다 . <a class="wp-editor-md-post-content-link" href="https://github.com/DataDog/helm-charts/tree/main/examples/datadog" target="_blank" rel="noopener">여기</a> 에서 몇 가지 예를 찾을 수 있습니다 .</li>
<li>Datadog 에이전트를 배포합니다.</li>
</ol>

<pre><code class="language-bash line-numbers">helm install RELEASE_NAME -f datadog-values.yaml --set datadog.site='datadoghq.com' --set datadog.apiKey= datadog/datadog 
</code></pre>

<pre><code class="language-yaml line-numbers">targetSystem: "linux"
datadog:
  apiKey: 'sample'
  appKey: 'sample'
  clusterName: 'test-k8s'
  tags: []
  kubelet:
    tlsVerify: "false"
  logs:
    enabled: false
    containerCollectAll: false
    containerCollectUsingFiles: false
  apm:
    portEnabled: true
    socketPath: /var/run/datadog/apm.socket
    hostSocketPath: /var/run/datadog/
  processAgent:
    enabled: false
    processCollection: false
  systemProbe:
    enableTCPQueueLength: false
    enableOOMKill: false
    collectDNSStats: false
</code></pre>

<h3>설치 현황</h3>

<pre><code class="language-bash line-numbers">datadog-agent-2dvkn                                3/3     Running   0          95d
datadog-agent-2jkdh                                3/3     Running   0          95d
datadog-agent-5q595                                3/3     Running   0          95d
datadog-agent-6gnnd                                3/3     Running   0          95d
datadog-agent-6pxn7                                3/3     Running   0          39d
datadog-agent-7kwpl                                3/3     Running   0          95d
datadog-agent-875rt                                3/3     Running   0          95d
datadog-agent-8sbjr                                3/3     Running   0          95d
datadog-agent-9c6d6                                3/3     Running   0          39d
datadog-agent-cluster-agent-84bd789556-cff7d       1/1     Running   0          95d
datadog-agent-kube-state-metrics-fb456b9bf-hqn2p   1/1     Running   0          95d
....
</code></pre>

위와 같이 dd-agent들은 각 노드별로, cluster-agent, kube-state-metric은 하나의 특정 node에 설치가 됩니다.

<h2>3. Helm Chart 수정(APM 설정)</h2>

상위 설정까지 마치게 되면, 아래의 정보까지는 자동으로 수집이 되게 됩니다.

<ul>
<li>Cluster Node의 가시성 확보</li>
<li>POD / Container 레벨의 가시성 확보</li>
<li>Kubernetes Event 수집</li>
</ul>

그럼 이제 APM에 대한 설정을 정리해보겠습니다.

<ul>
<li>Application의 Trace 정보 수집</li>
</ul>

APM을 설정하기 위해서는 Application이 기동할 때, 사용되어야 할 내용들이 있습니다.

<pre><code class="language-yaml line-numbers">apiVersion: apps/v1
kind: Deployment
metadata:
....
## volume을 정의 합니다. 
## 1) dd-apm-agent mount를 위한 container volume 
## 2) apmsocket을 위한 hostpath volume
    spec:
      {{- if (ne .Values.phase "test") }}
      volumes:
      - name: datadog-apm-agent
        emptyDir: {}
      - hostPath:
          path: /var/run/datadog/
        name: apmsocketpath
      {{- end }}    
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: networkType
                operator: DoesNotExist
      containers:
      - name: {{ .Values.phase }}-{{ .Values.projectName }}
        image: {{ .Values.dockerImgName }}:{{ .Values.deployImgVersion }}
                ## volume을 mount 합니다. 
                ## 1) dd-apm-agent mount를 위한 container volume 
                ## 2) apmsocket을 위한 hostpath volume        
        {{- if (ne .Values.phase "test") }}
        volumeMounts:
        - name: datadog-apm-agent
          mountPath: /datadog/apm/agent
        - name: apmsocketpath
          mountPath: /var/run/datadog
        {{- end }}        
       .....      
                ## apm에 대한 셋팅을 합니다.
                ## 1) DD_ENV, DD_SERVICE, DD_VERSION 은 배포된 환경, 서비스 및 버전에 대한 정보 
                ## 2) DD_TRACE_ENABLED는 APM TRACE 사용 유무
        {{- if (ne .Values.phase "alpha") }}
        - name: DD_SERVICE
          valueFrom:
            fieldRef:
              fieldPath: metadata.labels['app']
        - name: DD_VERSION
          valueFrom:
            fieldRef:
              fieldPath: metadata.labels['version']
        - name: DD_ENV
          value: {{ .Values.phase }}
        - name: DD_TAGS
          value : {{ .Values.namespace }}
        - name: DD_TRACE_ENABLED
          value: "true"
        - name: DD_TRACE_SAMPLE_RATE
          value: "1"
        - name: DD_PROFILING_ENABLED
          value: "true"
        - name: DD_JMXFETCH_ENABLED
          value: "true"
                ## 어플리케이션 기동시 APM jar 파일을 삽입합니다. 
        command: ["/bin/sh"]
        args: ["-c", "/sbin/tini java -javaagent:/datadog/apm/agent/dd-java-agent.jar $JAVA_OPTS -jar  api-gateway.jar"]
        {{- end }}                  
      ......
      {{- if (ne .Values.phase "alpha") }}
            ## initcontainer를 이용하여 초기 dd-agent-jar파일을 다운받아 container volue을 mount 합니다.
      initContainers:
      - name: datadog-apm-agent
        image: busybox
        command:
        - wget
        - -O
        - /datadog/apm/agent/dd-java-agent.jar
        - https://dtdg.co/latest-java-tracer
        volumeMounts:
        - name: datadog-apm-agent
          mountPath: /datadog/apm/agent
      {{- end }}      

</code></pre>

위의 과정을 통해서 APM TRACE가 가능해지고, 삽입된 jar파일에서 수집된 정보들은 모두 dd-agent에게 <strong>socket</strong>을 통하여 전달하게 되고, 모든 내용은 SaaS형태의 Datadog 수집 서버로 전송을 하게 됩니다.

<h2>4. Dashboard 작성</h2>

필자는 Dashboard를 보고 한 눈에 어플리케이션들의 상황을 알 수 있게끔 구성을 하고 싶었습니다. 그래서 가장 중점적으로 보는 지표를 정해보기로 했습니다.

<ul>
<li>Kubernetes 현황</li>
<li>Kubernetes Contaeinr CPU, Memory</li>
<li>Kubernetes Events</li>
<li>Application Error(50*)</li>
<li>Application Latency(3s 이상)</li>
<li>Application Request Volume</li>
</ul>

위의 현황으로도 얼추 어느정도의 어플리케이션 상황들은 볼 수 있다라고 생각이 되었습니다.

<img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/blog.wonizz.com/wp-content/uploads/2023/05/datadog_1.png?w=1200&#038;ssl=1" alt="DevOps k8s monitoring with Datadog 설명 이미지 1" />

붉은색 박스로 표기해놓은 순서대로 위에서 지정한 지표들을 볼 수 있도록 구성했습니다. 실제로 배포시 혹은 특정 이벤트시에 해당 지표들을 매우 잘 활용하고 있으며, 서비스를 안정적으로 운영하는데 많은 기여를 하고 있다고 생각합ㄴ니다.

<h2>5. 마치며..</h2>

Datadog중에서 Cluster, Pod, Container 레벨까지는 Prometheus, Grafana로 충분히 모니터링이 가능합니다. 하지만, Datadog을 도입한 가장큰 이유중 하나는 APM 기능을 이용하기 위함이였습니다.

무수히 많은 어플리케이션들이 MSA 형태로 배포되어있고 호출을 통해서 서로가 서로에게 연결이 되어있습니다. 이상황에서 연결상에 문제라던지 장애를 맞이하면 어디부분에서 문제가 발생을 했는지 찾기가 굉장히 힘듭니다.

그러한 부분에 있어서 APM 도입을 통해 가장 크게 해소 할 수 있던 것 같고, 특히 성능 개선부분에 있어서도 여러가지 시야를 얻을 수 있었습니다.

<h2>6. 참조</h2>

https://dev.to/airoasis/kubernetes-datadog-spring-boot-3g34
<h2 class="wp-block-heading">함께 보면 좋은 글</h2>
<ul class="wp-block-list"><li><a href="https://blog.wonizz.com/2022/05/18/devops-k8s-hpa/">[DevOps] k8s Horizontal POD autoscaling</a></li><li><a href="https://blog.wonizz.com/2021/12/20/devops-k8s-log-aggregation/">[DevOps] k8s Log 수집 시스템 구성</a></li><li><a href="https://blog.wonizz.com/2023/11/03/devops-nginx-rate-limit/">[DevOps] Nginx Rate Limit</a></li><li><a href="https://blog.wonizz.com/2023/05/11/devops-hubot-automation-1/">[DevOps] Hubot 적용기</a></li></ul>
<p>The post <a rel="nofollow" href="https://blog.wonizz.com/2023/05/09/devops-k8s-monitoring-with-datadog/">[DevOps] k8s monitoring with Datadog</a> appeared first on <a rel="nofollow" href="https://blog.wonizz.com">WONIZZ.LOG</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.wonizz.com/2023/05/09/devops-k8s-monitoring-with-datadog/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2034</post-id>	</item>
		<item>
		<title>[DevOps] Istio virtualhost 사용법</title>
		<link>https://blog.wonizz.com/2023/05/08/devops-istio-virtualhost/</link>
					<comments>https://blog.wonizz.com/2023/05/08/devops-istio-virtualhost/#respond</comments>
		
		<dc:creator><![CDATA[워니]]></dc:creator>
		<pubDate>Mon, 08 May 2023 08:00:31 +0000</pubDate>
				<category><![CDATA[kubernetes]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[Tech]]></category>
		<guid isPermaLink="false">https://blog.wonizz.tk/?p=2028</guid>

					<description><![CDATA[<p>The standard Lorem Ipsum passage, used since the 1500s<br />
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."</p>
<p>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"</p>
<p>1914 translation by H. Rackham<br />
"But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?"</p>
<p>Section 1.10.33 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."</p>
<p>1914 translation by H. Rackham<br />
"On the other hand, we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment, so blinded by desire, that they cannot foresee the pain and trouble that are bound to ensue; and equal blame belongs to those who fail in their duty through weakness of will, which is the same as saying through shrinking from toil and pain. These cases are perfectly simple and easy to distinguish. In a free hour, when our power of choice is untrammelled and when nothing prevents our being able to do what we like best, every pleasure is to be welcomed and every pain avoided. But in certain circumstances and owing to the claims of duty or the obligations of business it will frequently occur that pleasures have to be repudiated and annoyances accepted. The wise man therefore always holds in these matters to this principle of selection: he rejects pleasures to secure other greater pleasures, or else he endures pains to avoid worse pains."</p>
<p>안녕하세요? 정리하는 개발자 워니즈입니다. 이번시간에는 Istio virtualhost를 통한 트래픽 관리에 대해서 정리를 해보려고 합니다. 필자가 속한 프로젝트에서는 Istio를 grpc 분산용으로 사용하고 있습니다. 그러나 따로 트래픽 관리라던지, 인증가 인가에 대한 내용을 적용하고 있지는 않습니다. Istio의 L7 Envoy proxy를 사용은 하고있으나, 적절하게 기능들을 활용하고 있지는 않기에 이번 포스팅을 통해서 어떠한 내용들을 다룰 수 있는지를 기록하고자 합니다. istio관련된&#8230;&#160;</p>
<p>The post <a rel="nofollow" href="https://blog.wonizz.com/2023/05/08/devops-istio-virtualhost/">[DevOps] Istio virtualhost 사용법</a> appeared first on <a rel="nofollow" href="https://blog.wonizz.com">WONIZZ.LOG</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>The standard Lorem Ipsum passage, used since the 1500s<br />
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."</p>
<p>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"</p>
<p>1914 translation by H. Rackham<br />
"But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?"</p>
<p>Section 1.10.33 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."</p>
<p>1914 translation by H. Rackham<br />
"On the other hand, we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment, so blinded by desire, that they cannot foresee the pain and trouble that are bound to ensue; and equal blame belongs to those who fail in their duty through weakness of will, which is the same as saying through shrinking from toil and pain. These cases are perfectly simple and easy to distinguish. In a free hour, when our power of choice is untrammelled and when nothing prevents our being able to do what we like best, every pleasure is to be welcomed and every pain avoided. But in certain circumstances and owing to the claims of duty or the obligations of business it will frequently occur that pleasures have to be repudiated and annoyances accepted. The wise man therefore always holds in these matters to this principle of selection: he rejects pleasures to secure other greater pleasures, or else he endures pains to avoid worse pains."</p>
<p>안녕하세요? 정리하는 개발자 워니즈입니다. 이번시간에는 Istio virtualhost를 통한 트래픽 관리에 대해서 정리를 해보려고 합니다. 필자가 속한 프로젝트에서는 Istio를 grpc 분산용으로 사용하고 있습니다. 그러나 따로 트래픽 관리라던지, 인증가 인가에 대한 내용을 적용하고 있지는 않습니다.</p>
<p>Istio의 L7 Envoy proxy를 사용은 하고있으나, 적절하게 기능들을 활용하고 있지는 않기에 이번 포스팅을 통해서 어떠한 내용들을 다룰 수 있는지를 기록하고자 합니다.</p>
<p>istio관련된 시리즈는 아래에서 확인이 가능합니다.</p>
<ul>
<li><input style="margin-right:5px" type="checkbox" class="task-list-item-checkbox" checked disabled /><a class="wp-editor-md-post-content-link" href="https://blog.wonizz.com/2022/06/28/devops-istio-1/">istio 1편 : Istio란 무엇인가요?</a></li>
<li><input style="margin-right:5px" type="checkbox" class="task-list-item-checkbox" checked disabled /><a class="wp-editor-md-post-content-link" href="https://blog.wonizz.com/2023/03/06/devops-istio-traffic-tracing-kiali/">istio 2편 : Istio Traffic Tracing : Kiali</a></li>
<li><input style="margin-right:5px" type="checkbox" class="task-list-item-checkbox" checked disabled /><a class="wp-editor-md-post-content-link" href="https://blog.wonizz.com/2023/05/08/devops-istio-virtualhost/">istio 3편 : Istio virtualhost 사용법</a></li>
</ul>
<h2>1. Bookinfo Sample app</h2>
<p>istio는 친절하게도 설치를 하게 되면 샘플 앱을 제공하고 있습니다. 이부분이 서비스 메시를 이해하는데 많은 도움이 되었습니다.</p>
<p>먼저 설치는 다음의 포스팅을 확인해주시기 바랍니다.</p>
<p>설치를 하고 다음의 경로를 이동을 하게 되면, example이 존재합니다.</p>
<pre><code class="language-bash line-numbers"># bookinfo sample 예제
/istio-1.10.0/samples/bookinfo

# bookinfo application 설치
$kubectl apply -f /platform/kube/book/bookinfo.yaml
</code></pre>
<p>해당 파일을 설치하게 되면, 다음과 같이 여러개의 어플리케이션이 설치가 됩니다.</p>
<pre><code class="language-bash line-numbers">service/details created
serviceaccount/bookinfo-details created
deployment.apps/details-v1 created

service/ratings created
serviceaccount/bookinfo-ratings created
deployment.apps/ratings-v1 created

service/reviews created
serviceaccount/bookinfo-reviews created
deployment.apps/reviews-v1 created
deployment.apps/reviews-v2 created
deployment.apps/reviews-v3 created

service/productpage created
serviceaccount/bookinfo-productpage created
deployment.apps/productpage-v1 created
</code></pre>
<p>productpage, details, reviews, ratings로 구성이 되어있고, 전체적인 아키텍처는 다음과 같습니다 .</p>
<p><img decoding="async" src="https://istio.io/latest/docs/examples/bookinfo/withistio.svg" alt="bookinfo_1" /></p>
<p>사전에 클러스터에 Istio-1.10.0 버전을 설치하였고, default namespace에 injection 까지 마친상태였습니다. 이후에 각 서비스와 함께 Envoy 사이트카를 주입하여 Istio 환경에서 서비스를 구성하고 실행하기만 하면됩니다.</p>
<p>예제에서는 Ingress를 사용하게끔 되어있지만, 별도의 Ingress Layer를 사용하지 않고, Product Page자체를 Node port로 외부로 노출시켰습니다.</p>
<pre><code class="language-bash line-numbers"># product page 외부로 노출 시키기

kubectl patch svc productpage -p '{"spec": {"type": "NodePort"}}'
service/productpage patched

# service port 
$ kubectl get svc
NAME          TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
details       ClusterIP   192.168.59.179   <none>        9080/TCP         94s
kubernetes    ClusterIP   192.168.0.1      <none>        443/TCP          22h
productpage   NodePort    192.168.32.89    <none>        9080:32383/TCP   94s
ratings       ClusterIP   192.168.50.87    <none>        9080/TCP         94s
reviews       ClusterIP   192.168.56.81    <none>        9080/TCP         94s
</code></pre>
<p>최종적으로 {host ip} : 32383/productpage 로 접속을 하면 다음과 같은 화면이 노출됩니다.</p>
<p><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/miro.medium.com/max/4800/1%2AJ5ydMnlPQN2N5sRfkQZeHQ.png?w=1200&#038;ssl=1" alt="bookinfo_2" /></p>
<h2>2. Destination rule과 Virtual host</h2>
<h3>1) Destinatino Rule</h3>
<p><code>DestinationRule</code>라우팅이 발생한 후 서비스를 위한 트래픽에 적용되는 정책을 정의합니다. 이러한 규칙은 로드 밸런싱에 대한 구성, 사이드카의 연결 풀 크기, 로드 밸런싱 풀에서 비정상 호스트를 감지하고 제거하기 위한 이상값 감지 설정을 지정합니다.</p>
<p>자세한 설정은 다음의 공식 Document에서 볼 수 있습니다.</p>
<p><a class="wp-editor-md-post-content-link" href="https://istio.io/latest/docs/reference/config/networking/destination-rule/" target="_blank" rel="noopener">Destination Rule</a></p>
<p>bookinfo 예제에서 다음의 경로 파일을 열어봅니다.</p>
<pre><code class="language-bash line-numbers"># destionation rule all 
$ vi bookinfo/networking/destination-rule-all.yaml
</code></pre>
<p>내용이 길지만, 하나의 부분에 대해서 말씀을 드리겠습니다.</p>
<pre><code class="language-yaml line-numbers">#  destination-rule-all.yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews
spec:
  host: reviews
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
  - name: v3
    labels:
      version: v3
</code></pre>
<p><code>host: reviews</code> 는 서비스의 이름을 말합니다.</p>
<p><code>subsets</code> 는 서비스의 개별 버전을 나타내는 하나 이상의 명명된 집합입니다. 트래픽 정책은 하위 집합 수준에서 재정의할 수 있습니다.</p>
<p>위에서는 각 labeling의 version기준으로  v1, v2, v3로 나누었습니다. 처음 아키텍처 그림에서 reviews가 3개의 버전을 서비스가 되는 것을 볼 수 있었습니다.</p>
<pre><code class="language-yaml line-numbers"># destination-rule-reviews.yaml
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: reviews
spec:
  host: reviews
  trafficPolicy:
    loadBalancer:
      simple: RANDOM
  subsets:
  - name: v1
    labels:
      version: v1
  - name: v2
    labels:
      version: v2
  - name: v3
    labels:
      version: v3
</code></pre>
<p><code>trafficPolicy</code> : loadBalancer, connectionPool, outlierDetection, tls을 통해 특정 목적지와 특정 포트에 적용할 수 있는 트래픽 정책입니다.</p>
<p>위의 예에서는 random traffic으로 로드밸런싱을 하도록 구성을 했습니다.</p>
<h3>2) Virtual Service</h3>
<p>위의 정해진 Destination Rule을 기준으로 가상 서비스를 만들 수 있습니다. 트래픽을 어떤식으로 라우팅을 할지 설정이 가능합니다.</p>
<pre><code class="language-yaml line-numbers"># virtual-service-all-v1.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: productpage
spec:
  hosts:
  - productpage
  http:
  - route:
    - destination:
        host: productpage
        subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
  - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - route:
    - destination:
        host: ratings
        subset: v1
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: details
spec:
  hosts:
  - details
  http:
  - route:
    - destination:
        host: details
        subset: v1
</code></pre>
<p>위의 예제에서는 모든 서비스를 v1으로 보내겠다는 설정을 적용하였습니다.</p>
<p><code>host</code> 트래픽이 보내질 목적지 host(Service name) 입니다.</p>
<p><code>http > route > destination</code> Destination Rule에서 정의한 곳으로 트래픽을 보내기 위해 설정을 합니다.</p>
<p>아래 2개의 파일을 배포하게 되면, ratings 서비스가 v1으로만 트래픽이 전달이 되므로, 별점 정보는 노출이 되지 않는(v1) 으로 서비스를 하게 됩니다.</p>
<p>destination-rule-all.yaml<br />
virtual-service-all-v1.yaml</p>
<p><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/blog.wonizz.com/wp-content/uploads/2023/05/istio_bookinfo_1.png?w=1200&#038;ssl=1" alt="DevOps Istio virtualhost 사용법 설명 이미지 1" /></p>
<h2>3. Intellegent Routing</h2>
<p>위의 예제와 더불어 Routing에 대해서 bookinfo 예제 파일로 설명을 드리겠습니다.</p>
<h3>특정 User에게 특정 버전만 서비스 하기</h3>
<pre><code class="language-yaml line-numbers"># virtual-service-reviews-test-v2.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
    - reviews
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    route:
    - destination:
        host: reviews
        subset: v2
  - route:
    - destination:
        host: reviews
        subset: v1
</code></pre>
<p>headers에 jason이라고 있으면, reviews를 v2로 서비스 하고 그외에는 v1으로 서비스를 합니다.</p>
<h3>점진적 마이그레이션</h3>
<p>다음 구성에서 보시듯이, reviews의 8:2 비율로 v1과 v2로 라우팅을 시키는 내용입니다.</p>
<pre><code class="language-yaml line-numbers"># virtual-service-reviews-80-20.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: reviews
spec:
  hosts:
    - reviews
  http:
  - route:
    - destination:
        host: reviews
        subset: v1
      weight: 80
    - destination:
        host: reviews
        subset: v2
      weight: 20
</code></pre>
<h2>4.  Fault Injection</h2>
<p>어플리케이션의 복원력에 대해서 확인하기 위해서 오류를 강제로 삽입할 수 있는 기능입니다.</p>
<p>다음 예제는 jason으로 로그인시 rating 서비스가 100%의 확률로 7초의 딜레이를 강제적으로 발생시키는 내용입니다.</p>
<pre><code class="language-yaml line-numbers"># virtual-service-ratings-test-delay.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    fault:
      delay:
        percentage:
          value: 100.0
        fixedDelay: 7s
    route:
    - destination:
        host: ratings
        subset: v1
  - route:
    - destination:
        host: ratings
        subset: v1
</code></pre>
<p>다음은 jason으로 로그인시 100%의 확률로 500에러를 발생하는 내용입니다.</p>
<pre><code class="language-yaml line-numbers"># virtual-service-ratings-test-abort.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: ratings
spec:
  hosts:
  - ratings
  http:
  - match:
    - headers:
        end-user:
          exact: jason
    fault:
      abort:
        percentage:
          value: 100.0
        httpStatus: 500
    route:
    - destination:
        host: ratings
        subset: v1
  - route:
    - destination:
        host: ratings
        subset: v1  
</code></pre>
<h2>5. Circuit Breaker</h2>
<p>Circuit Breaker는 탄력적인 마이크로 서비스 애플리케이션을 만드는 데 중요한 패턴입니다. Circuit breaking을 사용하면 장애의 영향, 지연 시간 급증 및 기타 네트워크 특성의 바람직하지 않은 영향을 제한하는 애플리케이션을 작성 할 수 있습니다.</p>
<ul>
<li>서비스 A -> B -> C의 구조에서 C가 장애가 발생을 하게 되면, B는 대기를 하게 되고 덩달아 A도 대기상태에 빠져 서비스 불능상태에 빠지게 됩니다. 하나의 장애가 다른 서비스들도 적체를 유발하여 장애가 전파됩니다.</li>
<li>Circuit Breaker는 기능 자체가 동작하지 않는 경우에 Breaking을 통해 해당 서비스로 트래픽이 가지 않도록 차단을 하여 장애가 전파되지 않도록 하는데 목적이 있습니다.</li>
</ul>
<h2>6. 마치며..</h2>
<p>이번시간에는 istio의 virtual host를 통해서 트래픽제어를 정리해봤습니다. istio를 잘만 활용하면, 수많은 MSA구조의 어플리케이션들 사이에서 적절하게 트래픽을 분배하고 라우팅을 할 수 있습니다. 이를 통해서 장애도 제어를 할 수 있을것 같다는 생각이 들었습니다.<br />
다음시간에는 istio의 실제 적용 사례를 정리해보도록 하겠습니다.</p>
<p>The post <a rel="nofollow" href="https://blog.wonizz.com/2023/05/08/devops-istio-virtualhost/">[DevOps] Istio virtualhost 사용법</a> appeared first on <a rel="nofollow" href="https://blog.wonizz.com">WONIZZ.LOG</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.wonizz.com/2023/05/08/devops-istio-virtualhost/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2028</post-id>	</item>
		<item>
		<title>[DevOps] Istio Traffic Tracing : Kiali</title>
		<link>https://blog.wonizz.com/2023/03/06/devops-istio-traffic-tracing-kiali/</link>
					<comments>https://blog.wonizz.com/2023/03/06/devops-istio-traffic-tracing-kiali/#respond</comments>
		
		<dc:creator><![CDATA[워니]]></dc:creator>
		<pubDate>Mon, 06 Mar 2023 12:01:12 +0000</pubDate>
				<category><![CDATA[kubernetes]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[Tech]]></category>
		<guid isPermaLink="false">https://blog.wonizz.tk/?p=2021</guid>

					<description><![CDATA[<p>The standard Lorem Ipsum passage, used since the 1500s<br />
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."</p>
<p>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"</p>
<p>1914 translation by H. Rackham<br />
"But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?"</p>
<p>Section 1.10.33 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."</p>
<p>1914 translation by H. Rackham<br />
"On the other hand, we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment, so blinded by desire, that they cannot foresee the pain and trouble that are bound to ensue; and equal blame belongs to those who fail in their duty through weakness of will, which is the same as saying through shrinking from toil and pain. These cases are perfectly simple and easy to distinguish. In a free hour, when our power of choice is untrammelled and when nothing prevents our being able to do what we like best, every pleasure is to be welcomed and every pain avoided. But in certain circumstances and owing to the claims of duty or the obligations of business it will frequently occur that pleasures have to be repudiated and annoyances accepted. The wise man therefore always holds in these matters to this principle of selection: he rejects pleasures to secure other greater pleasures, or else he endures pains to avoid worse pains."</p>
<p>안녕하세요? 정리하는 개발자 워니즈입니다. 이번시간에는 Kiali라는 툴에 대해서 정리를 해보려고 합니다. DevOps 엔지니어로서 가장 중점을 두는 부분은 모니터링영역입니다. (물론 개인적인 생각입니다.) 모니터링을 잘 구성해두고 철저히 관찰하고 이상유무를 체크하게 된다면, 사이트의 신뢰도 자연스럽게 유지가 될 것입니다. 필자가 운영하는 프로젝트에서는 80-90 여개의 MSA 구조 어플리케이션들이 얽히고 섥혀서 연결이 되어있습니다. 마치 사슬 구조처럼 연결이 외어있는데 Istio는 이러한 서비스&#8230;&#160;</p>
<p>The post <a rel="nofollow" href="https://blog.wonizz.com/2023/03/06/devops-istio-traffic-tracing-kiali/">[DevOps] Istio Traffic Tracing : Kiali</a> appeared first on <a rel="nofollow" href="https://blog.wonizz.com">WONIZZ.LOG</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>The standard Lorem Ipsum passage, used since the 1500s<br />
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."</p>
<p>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"</p>
<p>1914 translation by H. Rackham<br />
"But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?"</p>
<p>Section 1.10.33 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."</p>
<p>1914 translation by H. Rackham<br />
"On the other hand, we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment, so blinded by desire, that they cannot foresee the pain and trouble that are bound to ensue; and equal blame belongs to those who fail in their duty through weakness of will, which is the same as saying through shrinking from toil and pain. These cases are perfectly simple and easy to distinguish. In a free hour, when our power of choice is untrammelled and when nothing prevents our being able to do what we like best, every pleasure is to be welcomed and every pain avoided. But in certain circumstances and owing to the claims of duty or the obligations of business it will frequently occur that pleasures have to be repudiated and annoyances accepted. The wise man therefore always holds in these matters to this principle of selection: he rejects pleasures to secure other greater pleasures, or else he endures pains to avoid worse pains."</p>
<p>안녕하세요? 정리하는 개발자 워니즈입니다. 이번시간에는 <strong>Kiali</strong>라는 툴에 대해서 정리를 해보려고 합니다. DevOps 엔지니어로서 가장 중점을 두는 부분은 모니터링영역입니다. (물론 개인적인 생각입니다.) 모니터링을 잘 구성해두고 철저히 관찰하고 이상유무를 체크하게 된다면, 사이트의 신뢰도 자연스럽게 유지가 될 것입니다.</p>
<p>필자가 운영하는 프로젝트에서는 80-90 여개의 MSA 구조 어플리케이션들이 얽히고 섥혀서 연결이 되어있습니다. 마치 사슬 구조처럼 연결이 외어있는데 <strong>Istio</strong>는 이러한 서비스 메시 구조에서 네트웤영역을 담당해주는 오픈소스 입니다.</p>
<p>istio관련된 시리즈는 아래에서 확인이 가능합니다.</p>
<ul>
<li><input style="margin-right:5px" type="checkbox" class="task-list-item-checkbox" checked disabled /><a class="wp-editor-md-post-content-link" href="https://blog.wonizz.com/2022/06/28/devops-istio-1/">istio 1편 : Istio란 무엇인가요?</a></li>
<li><input style="margin-right:5px" type="checkbox" class="task-list-item-checkbox" checked disabled /><a class="wp-editor-md-post-content-link" href="https://blog.wonizz.com/2023/03/06/devops-istio-traffic-tracing-kiali/">istio 2편 : Istio Traffic Tracing : Kiali</a></li>
<li><input style="margin-right:5px" type="checkbox" class="task-list-item-checkbox" checked disabled /><a class="wp-editor-md-post-content-link" href="https://blog.wonizz.com/2023/05/08/devops-istio-virtualhost/">istio 3편 : Istio virtualhost 사용법</a></li>
</ul>
<p>Istio는 어플리케이션 pod에 side-car 형태로 붙어서 모든 네트워크의 입/출을 통제하고 관리하고 모니터링합니다. 여기서 수집된 정보들을 기반으로 Tracing을 해줄 수 있는것이 오늘 소개드리고자 하는 <strong>Kiali</strong>입니다.</p>
<h2>1. Kiali 설치 과정</h2>
<p>Kiali를 설치하기 이전에 Traffic정보를 수집할 수 있는 Prometheus가 필요합니다. 또한, Traffic Trace를 위해서는 Jaeger가 필요합니다.</p>
<h3>Istio Addon을 통해서 설치</h3>
<pre><code class="language-bash line-numbers">#istio를 다운로드 후, 설치
kubectl apply -f ${ISTIO_HOME}/samples/addons/kiali.yaml
</code></pre>
<h3>Helm을 통해서 설치</h3>
<pre><code class="language-bash line-numbers">helm install \
  --namespace istio-system \
  --set auth.strategy="anonymous" \
  --repo https://kiali.org/helm-charts \
  kiali-server \
  kiali-server
</code></pre>
<h3>Nodeport로 서비스 변경</h3>
<pre><code class="language-yaml line-numbers">spec:
  ports:
    - name: http
      nodePort: 32763
      port: 20001
      protocol: TCP
      targetPort: 20001
    - name: http-metrics
      nodePort: 32762
      port: 9090
      protocol: TCP
      targetPort: 9090
  selector:
    app.kubernetes.io/instance: kiali-server
    app.kubernetes.io/name: kiali
  sessionAffinity: None
  type: NodePort
</code></pre>
<p>필자는 위의 내용을 간단하게 helm chart로 커스텀 구성을 완료 했습니다.</p>
<pre><code class="language-bash line-numbers">.
├── Chart.yaml
├── values.yaml
└── templates
    ├── crds
    │   └── crds.yaml
    └── templates
        ├── configmap.yaml
        ├── dashboards
        │   ├── envoy.yaml
        │   ├── go.yaml
        │   ├── kiali.yaml
        │   ├── micrometer-1.1-jvm.yaml
        │   ├── micrometer-jvm-pool.yaml
        │   ├── micrometer-jvm.yaml
        │   ├── microprofile-1.1.yaml
        │   ├── microprofile-x.y.yaml
        │   ├── nodejs.yaml
        │   ├── quarkus.yaml
        │   ├── springboot-jvm-pool.yaml
        │   ├── springboot-jvm.yaml
        │   ├── springboot-tomcat.yaml
        │   ├── thorntail.yaml
        │   ├── tomcat.yaml
        │   ├── vertx-client.yaml
        │   ├── vertx-eventbus.yaml
        │   ├── vertx-jvm.yaml
        │   ├── vertx-pool.yaml
        │   └── vertx-server.yaml
        ├── deployment.yaml
        ├── rolebinding-controlplane.yaml
        ├── rolebinding.yaml
        ├── role-controlplane.yaml
        ├── role-viewer.yaml
        ├── role.yaml
        ├── serviceaccount.yaml
        └── service.yaml
</code></pre>
<h3>1) 기본 구성 파일</h3>
<ul>
<li>configmap.yaml : kiali의 설정 파일</li>
<li>deployment.yaml : kiali의 배포 파일</li>
<li>service.yaml : kiali 서비스 구성 파일</li>
</ul>
<h3>2) 권한 제어</h3>
<ul>
<li>Rolebinding-controlplane.yaml :</li>
<li>rolebinding.yaml</li>
<li>role-controlplane.yaml</li>
<li>role.yaml</li>
<li>role-viewer.yaml</li>
<li>serviceaccount.yaml : k8s 클러스터내에 모든 영역에 대해서 조회가 가능한 계정</li>
</ul>
<h3>3) 대시보드 파일</h3>
<ul>
<li>대시보드에 대한 내용들을 yaml 파일로 관리합니다.</li>
<li>기본적으로 제공되는 대시보드들에 대해서 helmchart로 구성</li>
</ul>
<h2>2. Kiali 기본</h2>
<h3>인증 전략</h3>
<p>Kiali의 인증전략은 여러가지가 존재합니다. 아래에서 참고 가능하지만, 아쉽게도 ID/PW를 적용하기 위해서는 오픈아이디커넥트(ex. Keycloak)를 적용해야 가능합니다. 따라서 필자는 <strong>token</strong>방식으로 설정을 해두었고, 토큰값으로 접근제어가 되도록 설정을 하였습니다.</p>
<p><a class="wp-editor-md-post-content-link" href="https://kiali.io/docs/configuration/authentication/" target="_blank" rel="noopener">인증 전략</a></p>
<pre><code class="language-yaml line-numbers">spec:
  auth:
    strategy: token
</code></pre>
<p>설정을 하게 되면 최초 로그인시에 Token을 요구하게 됩니다. 이 token의 상단의 serviceaccount에서 생성된 secret 값으로 그대로 복사하여 사용을 하면 됩니다.</p>
<h3>기본 네임스페이스 선택</h3>
<p>기본적으로 Kiali에 처음 액세스할 떄 대부분의 Kiali 페이지에서 사용자는 네임스페이스 드롭다운을 사용하여 데이터를 보려는 NS를 선택해야 합니다. 이러한 부분을 미리 정의된 네임스페이스 선택을 구성할 수 있습니다.</p>
<pre><code class="language-yaml line-numbers">spec:
  kiali_feature_flags:
    ui_defaults:
      namespaces:
      - istio-system
</code></pre>
<h3>프로메테우스 구성</h3>
<p>Kiali에서는 Prometheus가 토폴로지 그래프를 생성하고, 메트릭을 표시하고, 상태를 계산하고, 기타 기능들을 수행하기 위해 필요합니다.</p>
<p>기본적으로 Kiali는 Prometheus가 istio 추가 기능을 <strong>http://prometheus.<istio_namespace_name>:9090</strong>을 사용하고 있습니다. 만약 Prometheus가 다른 서비스 이름이 있거나 다른 네임스페이스에 있다면 아래와 같이 설정을 변경해야 합니다.</p>
<pre><code class="language-yaml line-numbers">spec:
  external_services:
    prometheus:
      # Prometheus service name is "metrics" and is in the "telemetry" namespace
      url: "http://metrics.telemetry:9090/"
</code></pre>
<h3>예거 구성</h3>
<p>Kiali는 여러 기능에 대해 분산 추적 데이터를 사용하여 향상된 경험을 제공하기 떄문에 Jaeger는 적극 권장 되는 서비스 입니다.</p>
<p>기본적으로 Kiali는 Jaeger Istio 추가 기능을 <strong>http://tracing.<istio_namespace_name>:16685/jaeger</strong>를 사용합니다. 만약 다른 서비스 이름이 있거나 다른 네임스페이스에 설치된 경우 다음 예와 같이 변경을 해야 합니다.</p>
<pre><code class="language-yaml line-numbers">spec:
  external_services:
    tracing:
      # Enabled by default. Kiali will anyway fallback to disabled if
      # Jaeger is unreachable.
      enabled: true
      # Jaeger service name is "tracing" and is in the "telemetry" namespace.
      # Make sure the URL you provide corresponds to the non-GRPC enabled endpoint
      # if you set "use_grpc" to false.
      in_cluster_url: 'http://tracing.telemetry:16685/jaeger'
      use_grpc: true
      # Public facing URL of Jaeger
      url: 'http://my-jaeger-host/jaeger'
</code></pre>
<h3>Traffic Health</h3>
<p><a class="wp-editor-md-post-content-link" href="https://kiali.io/docs/configuration/health/" target="_blank" rel="noopener">Health</a></p>
<p>아래 예시처럼, 예를들어 에러 율이 0.1% 이상이면 <strong>Degraded</strong>상태를 10%이상이면 <strong>Failure</strong>상태를 표기합니다.</p>
<pre><code class="language-yaml line-numbers"># ...
  health_config:
    rate:
      - namespace: ".*"
        kind: ".*"
        name: ".*"
        tolerance:
          - code: "^5\\d\\d$"
            direction: ".*"
            protocol: "http"
            degraded: 0
            failure: 10
          - code: "^4\\d\\d$"
            direction: ".*"
            protocol: "http"
            degraded: 10
            failure: 20
          - code: "^[1-9]$|^1[0-6]$"
            direction: ".*"
            protocol: "grpc"
            degraded: 0
            failure: 10
# ...
</code></pre>
<table>
<thead>
<tr>
<th>Priority</th>
<th>Rule (value=% matching requests)</th>
<th>Status</th>
</tr>
</thead>
<tbody>
<tr>
<td>1</td>
<td>value >= FAILURE threshold</td>
<td><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/kiali.io/images/documentation/health-configuration/failure.png?w=1200&#038;ssl=1" alt="img" />FAILURE</td>
</tr>
<tr>
<td>2</td>
<td>value >= DEGRADED threshold AND value < FAILURE threshold</td>
<td><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/kiali.io/images/documentation/health-configuration/degraded.png?w=1200&#038;ssl=1" alt="img" />DEGRADED</td>
</tr>
<tr>
<td>3</td>
<td>value > 0 AND value < DEGRADED threshold</td>
<td><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/kiali.io/images/documentation/health-configuration/healthy.png?w=1200&#038;ssl=1" alt="img" />HEALTHY</td>
</tr>
<tr>
<td>4</td>
<td>value = 0</td>
<td><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/kiali.io/images/documentation/health-configuration/healthy.png?w=1200&#038;ssl=1" alt="img" />HEALTHY</td>
</tr>
<tr>
<td>5</td>
<td>No traffic</td>
<td><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/kiali.io/images/documentation/health-configuration/no_health.png?w=1200&#038;ssl=1" alt="img" />No Health Information</td>
</tr>
</tbody>
</table>
<h2>3. Kiali 기능 정리</h2>
<h3>서비스 작업</h3>
<h4>Traffic management : 라우팅 요청</h4>
<ul>
<li>모든 규칙은 요청에 대해서 일치하는 경우와 라우팅 대상으로 구성이 됩니다.</li>
<li>요청 일치 부분은 Header, Uri, Scheme, Method를 사용하여 여러 필터를 추가 할 수 있습니다.</li>
<li>요청 일치 부분은 비어있을 수 있습니다. 이 경우 모든 HTTP 요청이 규칙에 적용됩니다.</li>
<li>라우팅 대상은 라우팅 되는 트래픽의 비율을 지정할 수 있습니다.</li>
</ul>
<p><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/kiali.io/images/documentation/features/actions-service-request-routing.png?w=1200&#038;ssl=1" alt="DevOps Istio Traffic Tracing : Kiali 설명 이미지 1" /></p>
<h4>Traffic management : 오류 주입</h4>
<p>고의적으로 결함을 주입하여, 서비스의 탄력성을 테스트할 수 있습니다.</p>
<ul>
<li>HTTP 지연 사양은 요청 전달 경로에 대기 시간을 주입한은데 사용됩니다.</li>
<li>HTTP 중단 사양은 요청을 즉시 중단하고 미리 지정된 상태 코드를 반환하는 데 사용합니다.</li>
</ul>
<p><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/kiali.io/images/documentation/features/actions-service-fault-injection.png?w=1200&#038;ssl=1" alt="DevOps Istio Traffic Tracing : Kiali 설명 이미지 2" /></p>
<h4>Traffic management : 트래픽 이동</h4>
<p>추후 canary 배포 혹은 blue/green 이용시 활용할 수 있는 부분으로 트래픽을 설정을 통해서 Weight를 줄 수 있습니다.</p>
<p><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/kiali.io/images/documentation/features/actions-service-traffic-shifting.png?w=1200&#038;ssl=1" alt="DevOps Istio Traffic Tracing : Kiali 설명 이미지 3" /></p>
<h4>Traffic management : 요청 시간 초과</h4>
<p>Istio를 사용하여 Timeout 설정을 지정할 수 있습니다.</p>
<ul>
<li>HTTP 시간 초과는 요청에 대한 시간 초과를 정의합니다.</li>
<li>HTTP 재시도는 HTTP 요청이 실패할 때 사용할 재시도 정책을 설명합니다.</li>
</ul>
<p><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/kiali.io/images/documentation/features/actions-service-request-timeout.png?w=1200&#038;ssl=1" alt="DevOps Istio Traffic Tracing : Kiali 설명 이미지 4" /></p>
<h2> </h2>
<h4>Traffic management : 회로 차단기</h4>
<ul>
<li>연결 풀은 업스트림 호스트에 대한 연결 제한을 정의합니다.</li>
<li>이상값 감지는 보고된 연속 오류를 기반으로 회로 차단기를 구현합니다.</li>
</ul>
<p><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/kiali.io/images/documentation/features/actions-service-advanced-circuit-breaker.png?w=1200&#038;ssl=1" alt="DevOps Istio Traffic Tracing : Kiali 설명 이미지 5" /></p>
<h2>4. Tracing 이란</h2>
<p>Kiali는 Jaeger for Distributed Tracing과의 기본 통합을 제공합니다. 따라서 사용자는 Jaeger의 추적 시각화에 액세스 할 수 있습니다.</p>
<h3>워크로드 세부 정보</h3>
<p>워크로드를 조사할 때 추적 탭을 클릭하여 차트에서 추적을 시각화 합니다. 추적을 선택하면 Kiali는 추적 세부 정보에 대한 탭과 범위 세부 정보데 대한 탭을 제공합니다. Kiali는 히트맵 접근 방식을 사용하여 사용자가 문제 추적 또는 범위를 식별하는데 도움을 줍니다.</p>
<p><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/kiali.io/images/documentation/features/trace-detail.png?w=1200&#038;ssl=1" alt="DevOps Istio Traffic Tracing : Kiali 설명 이미지 6" /></p>
<p><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/kiali.io/images/documentation/features/trace-span-detail.png?w=1200&#038;ssl=1" alt="DevOps Istio Traffic Tracing : Kiali 설명 이미지 7" /></p>
<h3>히트맵</h3>
<p>워크로드의 추적 탭에 표시되는 히트맵은 특정 추적의 요청 시간을 시간에 따라 집계된 기간 메트릭과 비교하는 메트릭입니다.</p>
<p><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/kiali.io/images/documentation/features/tracing-heatmap.png?w=1200&#038;ssl=1" alt="DevOps Istio Traffic Tracing : Kiali 설명 이미지 8" /></p>
<p>위의 히트맵의 오른쪽 상단 셀은 추적이 나타내는 요청 기간(5.96ms)이 지난 10분 이내에 워크로드에 대한 모든 인바운드 요청의 99번째 백분위수보다 17.5ms 더 빨랐음을 보여줍니다.</p>
<p>셀의 색상 범위는 빨간색과 녹색 사이입니다. 셀이 더 녹색이면 추적 기간이 집계 메트릭 데이터와 비교하여 더 빠릅니다. 빨간색 셀은 연결된 추적이 집계 메트릭 데이터에 비해 훨씬 느리므로 해당 추적을 검사하면 잠재적인 병목 현상이나 문제를 감지하는 데 도움이 될 수 있음을 나타냅니다.</p>
<h3>메트릭 상관 관계</h3>
<p>Kiali는 메트릭 차트에서 스팬 오버레이를 제공합니다. 사용자는 오버레이 생성 옵션을 활성화하여 <strong>spans</strong> 을 클릭한 뒤, 추적에 초첨을 맞춘 추적 탭으로 자동으로 이동 됩니다.</p>
<p><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/kiali.io/images/documentation/features/trace-metric-overlay.png?w=1200&#038;ssl=1" alt="DevOps Istio Traffic Tracing : Kiali 설명 이미지 9" /></p>
<h3>그래프 상관 관계</h3>
<p>그래프에서 노드를 선택하면 측면에 패널이 나타납니다. 트레이스를 선택하면 그래프는 트레이스 범위에 대한 오버레이를 표시합니다. 그리고 측면 패널은 스팬 세부 정ㅈ보를 표시하고 추적 세부 정보 보기에 대한 링크를 제공합니다.</p>
<p><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/kiali.io/images/documentation/features/trace-graph-overlay.png?w=1200&#038;ssl=1" alt="DevOps Istio Traffic Tracing : Kiali 설명 이미지 10" /></p>
<h3>로그 상관 관계</h3>
<p>Kiali는 로그 및 추적 정보에 대한 통합 보기를 제공할 수 있어 사용자가 관심 있는 추적을 식별하기 위해 로그를 사용할 수 있습니다. 옵션을 활성화하면 <code>spans</code>Kiali는 워크로드 로그 보기에 추적 항목을 추가합니다. 아래에서 시간 정렬된 순서로 사용자에게 애플리케이션 로그(흰색), Envoy 프록시 로그(금색) 및 추적 공간(파란색)의 통합 보기가 표시됩니다. 관심 범위를 클릭하면 관심 추적에 대한 세부 정보 보기로 이동합니다.</p>
<p><img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/kiali.io/images/documentation/features/trace-logs.png?w=1200&#038;ssl=1" alt="DevOps Istio Traffic Tracing : Kiali 설명 이미지 11" /></p>
<h2>5. 마치며..</h2>
<p>kiali를 통해서 네트워크 트래픽에 대한 흐름을 한 눈에 확인 할 수 있었습니다. istio의 기능을 이용하여 트래픽 제어를 손쉽게 할 수 있을뿐 더러, MSA 구조의 복잡한 구조에서 트래픽이 어디서 어디로 흘러가는 지 바로 확인 할 수 있는 점이 너무 좋았습니다.</p>
<p>다음시간에는 istio의 기능들에 대해서 하나씩 정리를 해보도록 하겠습니다.</p>
<p>The post <a rel="nofollow" href="https://blog.wonizz.com/2023/03/06/devops-istio-traffic-tracing-kiali/">[DevOps] Istio Traffic Tracing : Kiali</a> appeared first on <a rel="nofollow" href="https://blog.wonizz.com">WONIZZ.LOG</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.wonizz.com/2023/03/06/devops-istio-traffic-tracing-kiali/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2021</post-id>	</item>
		<item>
		<title>[Kubernetes] K8S Cronjob Monitoring</title>
		<link>https://blog.wonizz.com/2022/10/05/kubernetes-k8s-cronjob-monitoring/</link>
					<comments>https://blog.wonizz.com/2022/10/05/kubernetes-k8s-cronjob-monitoring/#respond</comments>
		
		<dc:creator><![CDATA[워니]]></dc:creator>
		<pubDate>Wed, 05 Oct 2022 00:29:27 +0000</pubDate>
				<category><![CDATA[kubernetes]]></category>
		<category><![CDATA[Tech]]></category>
		<guid isPermaLink="false">https://blog.wonizz.tk/?p=1971</guid>

					<description><![CDATA[<p>The standard Lorem Ipsum passage, used since the 1500s<br />
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."</p>
<p>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"</p>
<p>1914 translation by H. Rackham<br />
"But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?"</p>
<p>Section 1.10.33 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."</p>
<p>1914 translation by H. Rackham<br />
"On the other hand, we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment, so blinded by desire, that they cannot foresee the pain and trouble that are bound to ensue; and equal blame belongs to those who fail in their duty through weakness of will, which is the same as saying through shrinking from toil and pain. These cases are perfectly simple and easy to distinguish. In a free hour, when our power of choice is untrammelled and when nothing prevents our being able to do what we like best, every pleasure is to be welcomed and every pain avoided. But in certain circumstances and owing to the claims of duty or the obligations of business it will frequently occur that pleasures have to be repudiated and annoyances accepted. The wise man therefore always holds in these matters to this principle of selection: he rejects pleasures to secure other greater pleasures, or else he endures pains to avoid worse pains."</p>
<p>안녕하세요? 정리하는 개발자 워니즈입니다. 이번 시간에는 Cronjob을 어떻게 모니터링하고 notification을 발송할지에 대해서 정리해보는 시간을 갖도록 하겠습니다. 개발팀에서는 주기적으로 수행하는 어플리케이션들에 대해서 Cronjob으로 구성해달라는 요청이 왔었고, 요구사항에 맞추어 하나의 Helmchart내에서 편리하게 구성할 수 있도록 구조를 잡았습니다. [Kubernetes] Cronjob 구성하기 1. Cronjob metric Cronjob에 대한 메트릭을 먼저 확인하기로 했습니다. kube_job_complete : 실행 결과가 completed인 상태의 job 갯수&#8230;&#160;</p>
<p>The post <a rel="nofollow" href="https://blog.wonizz.com/2022/10/05/kubernetes-k8s-cronjob-monitoring/">[Kubernetes] K8S Cronjob Monitoring</a> appeared first on <a rel="nofollow" href="https://blog.wonizz.com">WONIZZ.LOG</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>The standard Lorem Ipsum passage, used since the 1500s<br />
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."</p>
<p>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"</p>
<p>1914 translation by H. Rackham<br />
"But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?"</p>
<p>Section 1.10.33 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."</p>
<p>1914 translation by H. Rackham<br />
"On the other hand, we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment, so blinded by desire, that they cannot foresee the pain and trouble that are bound to ensue; and equal blame belongs to those who fail in their duty through weakness of will, which is the same as saying through shrinking from toil and pain. These cases are perfectly simple and easy to distinguish. In a free hour, when our power of choice is untrammelled and when nothing prevents our being able to do what we like best, every pleasure is to be welcomed and every pain avoided. But in certain circumstances and owing to the claims of duty or the obligations of business it will frequently occur that pleasures have to be repudiated and annoyances accepted. The wise man therefore always holds in these matters to this principle of selection: he rejects pleasures to secure other greater pleasures, or else he endures pains to avoid worse pains."</p>
안녕하세요? 정리하는 개발자 워니즈입니다. 이번 시간에는 <strong>Cronjob</strong>을 어떻게 모니터링하고 <strong>notification</strong>을 발송할지에 대해서 정리해보는 시간을 갖도록 하겠습니다.

개발팀에서는 주기적으로 수행하는 어플리케이션들에 대해서 Cronjob으로 구성해달라는 요청이 왔었고, 요구사항에 맞추어 하나의 Helmchart내에서 편리하게 구성할 수 있도록 구조를 잡았습니다.

<ul>
<li><input style="margin-right:5px" type="checkbox" class="task-list-item-checkbox" checked disabled /><a class="wp-editor-md-post-content-link" href="https://blog.wonizz.ml/2022/06/29/kubernetes-cronjob/" target="_blank" rel="noopener">[Kubernetes] Cronjob 구성하기</a></li>
</ul>

<h2>1. Cronjob metric</h2>

Cronjob에 대한 메트릭을 먼저 확인하기로 했습니다.

<ul>
<li>kube_job_complete : 실행 결과가 completed인 상태의 job 갯수</li>
<li>kube_job_created : 실행 시간에 대한 Unix timestamp</li>
<li>kube_job_failed : 실행 결과가 failed인 상태의 job 갯수</li>
<li>kube_job_info : Job에 대한 정보</li>
<li>kube_job_labels : k8s에서 prometheus로 변환된 label 정보</li>
</ul>

<pre><code class="line-numbers">kube_job_complete{condition="false", job="test-kube-metric", job_name="test-1663646400", namespace="test", project="test-kube-metric", service="test-monitoring"}
0
kube_job_complete{condition="true", job="test-kube-metric", job_name="test-1663646400", namespace="test", project="test-kube-metric", service="test-monitoring"}
1
kube_job_complete{condition="unknown", job="test-kube-metric", job_name="test-1663646400", namespace="test", project="test-kube-metric", service="test-monitoring"}
0

kube_job_failed{condition="false", instance="lnlnklbd1502:31000", job="test-kube-metric", job_name="test-1663729200", namespace="test", project="test-kube-metric", service="test-monitoring"}
0
kube_job_failed{condition="true", instance="lnlnklbd1502:31000", job="test-kube-metric", job_name="test-1663729200", namespace="test", project="test-kube-metric", service="test-monitoring"}
1
kube_job_failed{condition="unknown", instance="lnlnklbd1502:31000", job="test-kube-metric", job_name="test-1663729200", namespace="test", project="test-kube-metric", service="test-monitoring"}
0
</code></pre>

아래는 <strong>status</strong>에 대한 metric인데, 위에는 <strong>excution</strong>에 대해서 초점을 맞추었다면 아래는 <strong>phase(result)</strong>에 대해서 초점을 맞춘것입니다.

<ul>
<li>kube_job_status_active : 구동중인 job에 대한 pod의 갯수</li>
<li>kube_job_status_completion_time : job이 completed된 시간을 출력.</li>
<li>kube_job_status_failed : 실패에 대한 이유와 Failed된 pod의 갯수</li>
<li>kube_job_status_start_time : Job manager에 의해 job이 시작된 시간을 출력</li>
<li>kube_job_status_succeeded : Completed된 pod의 갯수</li>
</ul>

<pre><code class="line-numbers">kube_job_status_succeeded{job="test-kube-metric", job_name="test-1663642800", namespace="test", project="test-kube-metric", service="test-monitoring"}
1

kube_job_status_failed{job="test-kube-metric", job_name="test-1663729200", namespace="test", project="test-kube-metric", reason="BackoffLimitExceeded", service="test-monitoring"}
1
</code></pre>

<h2>2. Cronjob dashboard</h2>

위에서 metric 확인을 한 이후에, 대시보드를 구성하기로 했습니다. Grafana에서 제공해주는 Dashboard를 찾아보았지만 너무 심플하기도했고 모니터링 하는데 활용하기는 어려운 부분이 있었습니다.

<img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/blog.wonizz.com/wp-content/uploads/2022/10/k8s_cronjob_1.png?w=1200&#038;ssl=1" alt="Kubernetes K8S Cronjob Monitoring 설명 이미지 1" />

단순히 현재 수행되는 내용들에 대해서 가시성 있게 볼 수는 있었지만, 성공에 대한 이력, 실패에 대한 이력, 그리고 현재 수행중인 상태를 한눈에 확인하고 싶었습니다.

<ul>
<li>전체 수행중인 Overview 화면</li>
<li>현재 실행중인 Job의 갯수</li>
<li>현재 완료된 Job의 갯수</li>
<li>현재 실패한 Job의 갯수</li>
</ul>

위와 같이 구성을 하기로 하였고, 가급적 한눈에 봤을 때 실패한 이력만 보고도 현재 어디서 어느 Job에 문제가 생겼는지를 판별 할 수 있게 하고 싶었습니다.

<h3>전체 Job 정보</h3>

전체는 job_info 정보를 갖고 있는 모든 job들을 합하여 계산하였습니다.

<pre><code class="line-numbers">sum(kube_job_info{farm="test-farm"})
</code></pre>

<h3>완료된 Job 정보</h3>

job_complete를 통해서 complete이 true인것만 추출하여 계산하였습니다.

<pre><code class="line-numbers">count(kube_job_complete{farm="test-farm"}==1)
</code></pre>

<h3>수행중인 Job 정보</h3>

상태가 active 인것의 Job들을 합하여 계산하였습니다.

<pre><code class="line-numbers">sum(kube_job_status_active{farm="test-farm"})
</code></pre>

<h3>실패한 Job 정보</h3>

job_failed를 통해서 failed가 true인것만 추출하여 계산하였습니다.

<pre><code class="line-numbers">count(kube_job_failed{farm="link-beta-kube-metric-farm"}==1)
</code></pre>

구성간에 한가지 확인하는데 오래걸렸던 사항은 Job의 정보는 <strong>현재</strong>에 초점을 맞춰야 하다보니 과거의 기록들은 볼필요가 없습니다. 
예를들어 A라는 Cronjob의 현재 수행상태를 보고싶은것이지 과거의 모든 정보들을 가져와서 표현을 하게 되면 정보가 많아져서 Dashboard의 역할을 할 수 없습니다.

<img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/blog.wonizz.com/wp-content/uploads/2022/10/k8s_cronjob_2.png?w=1200&#038;ssl=1" alt="Kubernetes K8S Cronjob Monitoring 설명 이미지 2" />

<strong>Type</strong>을 <strong>Instant</strong>로 선택해 줌으로써, 현재 상태만을 가져올 수 있었습니다.

최종적으로 다음과 같은 화면에 대해서 구성을 하였습니다

<ul>
<li>Overview</li>
<li>A Service 에대한 Cronjob</li>
<li>B Service 에 대한 Cronjob</li>
</ul>

<img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/blog.wonizz.com/wp-content/uploads/2022/10/k8s_cronjob_3.png?w=1200&#038;ssl=1" alt="Kubernetes K8S Cronjob Monitoring 설명 이미지 3" />

<h2>3. Cronjob Alert 구성</h2>

구성은 모두 됐으니, 이제 <strong>Alert</strong>를 구성하여, 개발팀에 알림 발송을 하기로 했습니다. Alert는 굉장히 심플하게 <strong>Failed</strong>인 상태가 1건이라도 발생시에 알림을 발송하기로했습니다.

<h3>실패한 Job 정보</h3>

<pre><code class="line-numbers">kube_job_failed{farm="beta-farm", job_name=~".*-payment-.*"}==1
</code></pre>

구성시 적용했던 job_failed와 한가지 달느것은 Metric Type을 <strong>Instant</strong>로 변경하여 최근에 발생한 건수가 존재한다면 바로 발송하는 방식으로 구성을 했습니다.

<img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/blog.wonizz.com/wp-content/uploads/2022/10/k8s_cronjob_4.png?w=1200&#038;ssl=1" alt="Kubernetes K8S Cronjob Monitoring 설명 이미지 4" />

<h2>4. Cronjob 개선 내용</h2>

알림 발송까지는 모두 정상적으로 되었으나, 한가지 문제점을 확인했습니다. 만약 실패했던 Cronjob에서 수행된 Job이 성공을 했다면, 현재 구성에서는 실패한 History를 3개 유지하도록 설정했기 때문에, 실패 알람이 계속 발생을 하는 문제가 있었습니다.

아래처럼 <strong>A Cronjob</strong>의 최신이 성공을 했다고 하더라도, 실패 이력이 계속 남아있어 알람은 계속 발생하였습니다.
그래서 수동으로 실패한 이력들을 모두 제거하는 방식으로 했었습니다.

<ul>
<li>A Cronjob

<ul>
<li>실패</li>
<li>실패</li>
<li>&#8230;.</li>
<li>성공</li>
</ul></li>
</ul>

이러한 방식을 개선하고자, 최신이 성공이라면 과거의 실패 History를 모두 제거하는 방식으로 코드를 개발하기로 했습니다.

결국, 하나의 Cronjob에서 최신의 수행이 <strong>성공(Completed)</strong>라면 과거의 <strong>실패(Failed)</strong>를 모두 제거하는 방식으로 개발을 수행했고, 정상적으로 동작을 하였습니다.

<pre><code class="language-bash line-numbers">#0. assign variable
LAST_JOB_NAME=""
LAST_CRON_NAME=""
LAST_STATUS=""
NEXT_JOB_NAME=""
NEXT_CRON_NAME=""
NEXT_STATUS=""
LOOPCOUNT=1
DEL_JOB_ARR=()
ARR=()

checkLastStatus() {
  if [[ "$LAST_STATUS" == "Complete" && ${#DEL_JOB_ARR[@]} -gt 0 ]]; then
  ### Failed -> pass && celar DEL_JOB_ARR
    CMD=`kubectl delete job "${DEL_JOB_ARR[@]}"`
    echo $CMD
  fi
  ### Complete -> delete all value from array
  DEL_JOB_ARR=()
}

#1. read line
#IFS=$'\n' read -ra ARR -d $'\0' <<< "$TEXT"

ARR=`kubectl get job -o json | jq -r '.items[] | .metadata.name + ":" + (select ( .status | has("conditions")) | .status.conditions[] | select(.status == "True") .type )'`
LASTCOUNT=${#ARR[@]}

for line in ${ARR[@]}
do
    #1. start loop
    if [[ $LOOPCOUNT -eq 1 ]]; then
        LAST_JOB_NAME=`echo $line | awk -F: '{print $NR}'`
        LAST_STATUS=`echo $line | awk -F: '{print $NF}'`
        LAST_CRON_NAME=`echo ${LAST_JOB_NAME::-11}`
        LOOPCOUNT=2
        continue
    fi

    #2. assign variable -> last, next
    NEXT_JOB_NAME=`echo $line | awk -F: '{print $NR}'`
    NEXT_STATUS=`echo $line | awk -F: '{print $NF}'`
    NEXT_CRON_NAME=${NEXT_JOB_NAME::-11}

    #3. compare
    if [[ "$LAST_CRON_NAME" == "$NEXT_CRON_NAME" ]]; then
    ### next == last then check last status
      ### last -> array
      DEL_JOB_ARR=("${DEL_JOB_ARR[@]}" "$LAST_JOB_NAME")
    else
    ### next != last then check last status
      checkLastStatus
    fi

    #4. update laste value for next
    LAST_JOB_NAME=$NEXT_JOB_NAME
    LAST_STATUS=$NEXT_STATUS
    LAST_CRON_NAME=$NEXT_CRON_NAME

    #5. increase loop count
    ((LOOPCOUNT=LOOPCOUNT+1))

    #6. last loop
    if [[ $LOOPCOUNT -eq $LASTCOUNT+1 ]]; then
      checkLastStatus
    fi
done
</code></pre>

<h2>5. 마치며&#8230;</h2>

Cronjob에 대한 Reference가 상당히 없는 상황에서 하나씩 구성해나가면서 현재 작성하는 것들이 다른사람의 Reference가 될 수도 있겠구나라는 생각을 했습니다.

Grafana에서도 제공하는 Dashboard만으로는 뭔가 완성도가 떨어진다고 생각이 들었는데 이러한 부분들도 오픈소스로 기여할 수 있는 방법이 있을지도 한번 찾아보려고 합니다. 제가 작성한 Dashboard를 다른사람들도 가져다가 Customizing하면서 발전시켜주면 너무 좋을 것 같습니다.
<h2 class="wp-block-heading">함께 보면 좋은 글</h2>
<ul class="wp-block-list"><li><a href="https://blog.wonizz.com/2020/08/24/kubernetes-autoscaling-hpa/">[Kubernetes] Autoscaling 사용하기</a></li><li><a href="https://blog.wonizz.com/2020/07/14/monitoring-grafana-alert-setting/">[Monitoring] Grafana Alert 셋팅</a></li><li><a href="https://blog.wonizz.com/2022/06/29/kubernetes-cronjob/">[Kubernetes] Cronjob 구성하기</a></li><li><a href="https://blog.wonizz.com/2024/07/24/devops-kubernetes-hpa/">[DevOps] Kubernetes HPA 실전 적용</a></li></ul>
<p>The post <a rel="nofollow" href="https://blog.wonizz.com/2022/10/05/kubernetes-k8s-cronjob-monitoring/">[Kubernetes] K8S Cronjob Monitoring</a> appeared first on <a rel="nofollow" href="https://blog.wonizz.com">WONIZZ.LOG</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.wonizz.com/2022/10/05/kubernetes-k8s-cronjob-monitoring/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1971</post-id>	</item>
		<item>
		<title>[DevOps] K8S Resource 최적화 사례</title>
		<link>https://blog.wonizz.com/2022/09/19/devops-k8s-resource-optimization/</link>
					<comments>https://blog.wonizz.com/2022/09/19/devops-k8s-resource-optimization/#respond</comments>
		
		<dc:creator><![CDATA[워니]]></dc:creator>
		<pubDate>Mon, 19 Sep 2022 03:22:25 +0000</pubDate>
				<category><![CDATA[kubernetes]]></category>
		<category><![CDATA[Docker]]></category>
		<category><![CDATA[Tech]]></category>
		<guid isPermaLink="false">https://blog.wonizz.tk/?p=1963</guid>

					<description><![CDATA[<p>The standard Lorem Ipsum passage, used since the 1500s<br />
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."</p>
<p>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"</p>
<p>1914 translation by H. Rackham<br />
"But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?"</p>
<p>Section 1.10.33 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."</p>
<p>1914 translation by H. Rackham<br />
"On the other hand, we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment, so blinded by desire, that they cannot foresee the pain and trouble that are bound to ensue; and equal blame belongs to those who fail in their duty through weakness of will, which is the same as saying through shrinking from toil and pain. These cases are perfectly simple and easy to distinguish. In a free hour, when our power of choice is untrammelled and when nothing prevents our being able to do what we like best, every pleasure is to be welcomed and every pain avoided. But in certain circumstances and owing to the claims of duty or the obligations of business it will frequently occur that pleasures have to be repudiated and annoyances accepted. The wise man therefore always holds in these matters to this principle of selection: he rejects pleasures to secure other greater pleasures, or else he endures pains to avoid worse pains."</p>
<p>안녕하세요? 정리하는 개발자 워니즈입니다. 이번시간에는 k8s의 리소스 최적화 사례에 대해서 정리를 해보려고 하빈다. 필자가 근무하는 프로젝트에서는 k8s를 직접 구축하여 사용하고 있습니다. 그런데, Worker Node에서 CPU Request가 초과했다는 메트릭을 식별했고, 배포간에는 pod가 pending이 되는 현상까지 식별했습니다. 무엇인가 문제가 생긴것임에는 틀림이 없어, 확인하여 조치하기로 했습니다. 1. k8s에서의 Request와 Limit이란? 필자가 운영하는 k8s에서는 수십개의 pod들이 MSA의 형태로 운영되고&#8230;&#160;</p>
<p>The post <a rel="nofollow" href="https://blog.wonizz.com/2022/09/19/devops-k8s-resource-optimization/">[DevOps] K8S Resource 최적화 사례</a> appeared first on <a rel="nofollow" href="https://blog.wonizz.com">WONIZZ.LOG</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p>The standard Lorem Ipsum passage, used since the 1500s<br />
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."</p>
<p>Section 1.10.32 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam, nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur?"</p>
<p>1914 translation by H. Rackham<br />
"But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again is there anyone who loves or pursues or desires to obtain pain of itself, because it is pain, but because occasionally circumstances occur in which toil and pain can procure him some great pleasure. To take a trivial example, which of us ever undertakes laborious physical exercise, except to obtain some advantage from it? But who has any right to find fault with a man who chooses to enjoy a pleasure that has no annoying consequences, or one who avoids a pain that produces no resultant pleasure?"</p>
<p>Section 1.10.33 of "de Finibus Bonorum et Malorum", written by Cicero in 45 BC<br />
"At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus, omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae. Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat."</p>
<p>1914 translation by H. Rackham<br />
"On the other hand, we denounce with righteous indignation and dislike men who are so beguiled and demoralized by the charms of pleasure of the moment, so blinded by desire, that they cannot foresee the pain and trouble that are bound to ensue; and equal blame belongs to those who fail in their duty through weakness of will, which is the same as saying through shrinking from toil and pain. These cases are perfectly simple and easy to distinguish. In a free hour, when our power of choice is untrammelled and when nothing prevents our being able to do what we like best, every pleasure is to be welcomed and every pain avoided. But in certain circumstances and owing to the claims of duty or the obligations of business it will frequently occur that pleasures have to be repudiated and annoyances accepted. The wise man therefore always holds in these matters to this principle of selection: he rejects pleasures to secure other greater pleasures, or else he endures pains to avoid worse pains."</p>
안녕하세요? 정리하는 개발자 워니즈입니다. 이번시간에는 k8s의 리소스 최적화 사례에 대해서 정리를 해보려고 하빈다. 필자가 근무하는 프로젝트에서는 k8s를 직접 구축하여 사용하고 있습니다.

그런데, Worker Node에서 CPU Request가 초과했다는 메트릭을 식별했고, 배포간에는 pod가 <strong>pending</strong>이 되는 현상까지 식별했습니다.

<img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/bobcares.com/wp-content/uploads/2022/07/podstates.png?w=1200&#038;ssl=1" alt="pod pending" />

무엇인가 문제가 생긴것임에는 틀림이 없어, 확인하여 조치하기로 했습니다.

<h2>1. k8s에서의 Request와 Limit이란?</h2>

필자가 운영하는 k8s에서는 수십개의 pod들이 MSA의 형태로 운영되고 있습니다. 1개의 pod에는 설정할수 있는 CPU와 Memory의 값이 있는데요. 이부분이 최적의 조건으로 설정이 된것이 아니라 최대한 크게 지정되었고, 지속적으로 어플리케이션이 생겨남에 따라 복제가 되어 관리가 되질 않았습니다.

<ul>
<li>Request : 컨테이너에 필요한 최소 리소스양을 정의 -> pod가 스케쥴링 되는 방식에 영향</li>
<li>Limit : 컨테이너가 사용할 수 있는 최대 리소스 양을 정의</li>
<li>CPU: Unless your app is specifically designed to take advantage of multiple cores (scientific computing and some databases come to mind), it is usually a best practice to keep <strong>the CPU request at ‘1’ or below, and run more replicas to scale it out.</strong> This gives the system more flexibility and reliability.</li>
<li>Memory : Mbyte 단위</li>
</ul>

그동안 Request와 Limit의 기준이 모호하게 설정되어있습니다.

<pre><code class="language-yaml line-numbers">resources:  
    requests:    
        cpu: 5
        memory: 10Gi
    limits:    
        cpu: 5
        memory: 10Gi
</code></pre>

실제 예시로 위와 같이 CPU를 <strong>5 core</strong>를 사용하도록 설정이 된 부분도 있었습니다. 여기서 replica가 4개만 설정되어도 <strong>20 core</strong> Resource를 사용하도록 강제하는 것입니다.

<h3>Qos Classes of k8s PODs</h3>

<ul>
<li>서비스 품질(Qos)는 스케쥴러가 pod의 스케쥴링 및 제거 우선순위를 결정하는데 사용하는 kubernetes 개념입니다.</li>
</ul>

<img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/miro.medium.com/max/1400/1%2AiGRP2cF86wMUWwztqQKi3A.png?w=1200&#038;ssl=1" alt="kubernetes QoS" />

<ul>
<li>종료 우선순위 : Base Effort > Burstable > Guaranteed

<ul>
<li>예를들어, Node에 메모리가 부족하게 되면, 종료를 하여 메모리를 확보</li>
</ul></li>
</ul>

<h2>2. k8s 리소스 최적화 방안</h2>

<strong>최적화</strong>가 어려운것은 <strong>정답</strong>이 없다는 것입니다. 필자가 운영하는 어플리케이션 마다의 비지니스도 다르고, 각자가 사용하는 리소스 소모량도 분명히 차이가 있었습니다.

우선 지난 1년간 수집된 <strong>Metric</strong>기반으로 데이터를 분석하기로 했습니다. 평균적으로 사용하는 양을 구했고 아래와 같이 CPU에 대한 사용률은 거의 없고, Memory 위주로 사용하는 것을 식별했습니다.

<table>
<thead>
<tr>
  <th>Namespace</th>
  <th>POD Name</th>
  <th>CPU</th>
  <th>Memory</th>
  <th>CPU optimization</th>
  <th>Memory Optimization</th>
</tr>
</thead>
<tbody>
<tr>
  <td>test-biz</td>
  <td>test-biz-custody-7b757d6664-8nl5q</td>
  <td>9m</td>
  <td>927Mi</td>
  <td>500m</td>
  <td>2Gi</td>
</tr>
<tr>
  <td>test-biz</td>
  <td>test-biz-custody-d77bffb45-nh929</td>
  <td>4m</td>
  <td>68Mi</td>
  <td>500m</td>
  <td>2Gi</td>
</tr>
<tr>
  <td>test-biz</td>
  <td>test-biz-gateway-5b8cc784b-bl58p</td>
  <td>16m</td>
  <td>695Mi</td>
  <td>500m</td>
  <td>2Gi</td>
</tr>
<tr>
  <td>test-biz</td>
  <td>test-biz-internal-gateway-65f489f884-t58br</td>
  <td>16m</td>
  <td>681Mi</td>
  <td>500m</td>
  <td>2Gi</td>
</tr>
<tr>
  <td>test-biz</td>
  <td>test-biz-member-6799f5c5d5-7k42h</td>
  <td>7m</td>
  <td>869Mi</td>
  <td>500m</td>
  <td>2Gi</td>
</tr>
<tr>
  <td>test-game</td>
  <td>test-game-5d4f9c64ff-twc6f</td>
  <td>5m</td>
  <td>67Mi</td>
  <td>500m</td>
  <td>2Gi</td>
</tr>
<tr>
  <td>test-market</td>
  <td>test-market-bff-54559c789-mn8ql</td>
  <td>4m</td>
  <td>68Mi</td>
  <td>500m</td>
  <td>2Gi</td>
</tr>
</tbody>
</table>

다음과 같은 기준에 의거하여 공통적인 Spec을 산정했습니다.

<ul>
<li>CPU 기준

<ul>
<li>.5 core 공통 적용</li>
<li>구글에서 <a class="wp-editor-md-post-content-link" href="https://cloud.google.com/blog/products/containers-kubernetes/kubernetes-best-practices-resource-requests-and-limits" target="_blank" rel="noopener">가이드</a>하는 문서를 따름.</li>
</ul></li>
<li>Memory 기준

<ul>
<li>1Gi 미만 : 2Gi</li>
<li>1Gi 이상 2Gi 미만 : 3Gi</li>
<li>2Gi 이상 3Gi 미만 : 4Gi</li>
<li>3Gi 이상 : 5Gi</li>
</ul></li>
</ul>

<h2>3. 최적화 진행한 맞이한 문제들</h2>

위에서 정한 Spec을 기준으로 수십개의 어플리케이션들을 전체적으로 재정의했고, 개발환경에 배포를 수행했습니다. 그런데 쉽게 될줄만 알았던 것이 문제에 봉착했었습니다.

<h3>어플리케이션 기동을 위한 최소한의 CPU</h3>

<img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/blog.wonizz.com/wp-content/uploads/2022/09/resource_optimzation_1.png?w=1200&#038;ssl=1" alt="DevOps K8S Resource 최적화 사례 설명 이미지 1" />

어플리케이션이 최초 기동 시 여러가지 자원들을 생성하고 연결(DB, Kafka, Redis 등)과정을 수립하는데 있어 CPU 소모가 이전보다 더 발생을 하게 됩니다. 즉, 위와 같은 그래프 패턴을 보이게 되는데 평상시에 대한 체크만 수행을 했고, Start할때 최소한의 필요한 양을 산정하지 못했습니다.

확인을 해본결과 <strong>1 Core</strong>를 넘지 않는 것을 확인하고, 공통 Spec으로 1 Core로 수정하기로 했습니다.

<h3>JVM사용을 위한 최소한의 Memory</h3>

위에서 선정한 Memory의 최적화는 <a class="wp-editor-md-post-content-link" href="https://medium.com/@marketing_864/best-practices-java-memory-arguments-for-containers-1d704a65f7db" target="_blank" rel="noopener">컨테이너에 대한 Java 메모리 할당</a>을 참고했습니다. 이 곳에서 설명하길 아래와 같이 되어있습니다.

<blockquote>
  항상 컨테이너에 최소 25% 더 많은 메모리를 할당해야 합니다(예: &#8216;-m&#8217;). 힙 크기 값보다. -Xmx 값을 2GB로 구성한 다음 컨테이너의 메모리 크기를 2.5GB 이상으로 구성했다고 가정합니다.
  
  힙 공간 외에도 애플리케이션에는 Java 스레드, 가비지 컬렉션, 메타 공간, 기본 메모리, 소켓 버퍼를 위한 공간이 필요합니다. 이러한 모든 구성 요소에는 할당된 힙 크기를 초과하는 추가 메모리가 필요합니다
</blockquote>

예를들어 pod가 2.5Gi가 할당되고 JVM에 2Gi가 할당 됐을 때 최적의 모범사례라고 할 수 있습니다.

그래서 다음과 같이 JVM 스펙을 산청했습니다.

<ul>
<li>pod 2.5Gi -> jvm 2Gi</li>
<li>pod 3.5Gi -> jvm 3Gi</li>
<li>pod 4.5Gi -> jvm 3Gi</li>
<li>pod 5.5Gi -> jvm 4Gi</li>
</ul>

위의 기준으로 설정하여 특별히 Java Process에 문제가 발생을 하지 않도록 구성했습니다.

<h2>4. 결과</h2>

<h3>AS-IS</h3>

<img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/blog.wonizz.com/wp-content/uploads/2022/09/resource_optimzation_2.png?w=1200&#038;ssl=1" alt="DevOps K8S Resource 최적화 사례 설명 이미지 2" />

master를 제외한 나머지 worker node들의 사용률이 아래와 같았고, 평균을 내면 위처럼 CPU가 대략 75%정도를 사용하고있었습니다.

<table>
<thead>
<tr>
  <th>Host Name</th>
  <th>Allocatable CPU</th>
  <th>CPU Requested</th>
  <th>Memory Requested</th>
</tr>
</thead>
<tbody>
<tr>
  <td>worker001</td>
  <td>7900m</td>
  <td>7455m (94%)</td>
  <td>11552310Ki (35%)</td>
</tr>
<tr>
  <td>worker002</td>
  <td>7900m</td>
  <td>7445m (94%)</td>
  <td>12559926Ki (38%)</td>
</tr>
<tr>
  <td>worker003</td>
  <td>7900m</td>
  <td>7445m (94%)</td>
  <td>13084214Ki (40%)</td>
</tr>
<tr>
  <td>Worker004</td>
  <td>7900m</td>
  <td>7445m (94%)</td>
  <td>8566396928 (25%)</td>
</tr>
</tbody>
</table>

<h3>TO-BE</h3>

<img data-recalc-dims="1" decoding="async" src="https://i0.wp.com/blog.wonizz.com/wp-content/uploads/2022/09/resource_optimization_3.png?w=1200&#038;ssl=1" alt="DevOps K8S Resource 최적화 사례 설명 이미지 3" />

절반정도로 CPU 요청량이 감소했으며, 어플리케이션 성능상에도 특별한 문제가 발생을 하지도 않았습니다.

<h2>5. 마치며&#8230;</h2>

<strong>최적화</strong>라는 것은 정답이 없기에 더더욱 어려운 것 같습니다. 이번의 최적화 작업을 진행하면서, 상황마다의 최적화 할 수 있는 요소들이 다양하다는 것을 느끼게 되었고, 확실히 <strong>데이터(Metric)</strong>기반으로 최적화를 진행하다보니 개발팀을 설득하기도 수월했다고 생각이 됩니다.

무수히 많은 어플리케이션들이 Cluster를 공유하면서 사용하다보니 자원이 많이 부족해질 수 있었던 상황인데 최적화를 통해서 쾌적환 환경을 제공할 수 있게 되어 굉장히 뿌듯했던 것 같습니다.

<h2>6. 참조</h2>

<a class="m-story" href="https://medium.com/inside-sumup/are-kubernetes-cpu-limits-bad-a04430bf54e1" target="_blank" data-width="1200" data-border="1" data-collapsed="" rel="noopener">Medium.com에서 보기</a>

https://blog.kubecost.com/blog/requests-and-limits/

<blockquote class="wp-embedded-content" data-secret="y1yPMn8xG9"><a href="https://itchain.wordpress.com/2018/05/16/kubernetes-resource-request-limit/" target="_blank" rel="noopener">Kubernetes Resource Request와 Limit의&nbsp;이해</a></blockquote><iframe class="wp-embedded-content" sandbox="allow-scripts" security="restricted"  title="&#8220;Kubernetes Resource Request와 Limit의&nbsp;이해&#8221; &#8212; Peter&#039;s Story" src="https://itchain.wordpress.com/2018/05/16/kubernetes-resource-request-limit/embed/#?secret=biDWqPnJ5G#?secret=y1yPMn8xG9" data-secret="y1yPMn8xG9" width="600" height="338" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>

<a class="m-story" href="https://medium.com/blutv/qos-classes-of-k8s-pods-722238a61c93" target="_blank" data-width="1200" data-border="1" data-collapsed="" rel="noopener">Medium.com에서 보기</a>

https://kubesphere.io/blogs/understand-requests-and-limits-in-kubernetes/
<h2 class="wp-block-heading">함께 보면 좋은 글</h2>
<ul class="wp-block-list"><li><a href="https://blog.wonizz.com/2021/09/01/kubeadm-pod-cidr-change/">[DevOps] kubeadm upgrade를 통한 pod cidr 변경</a></li><li><a href="https://blog.wonizz.com/2023/11/03/devops-nginx-rate-limit/">[DevOps] Nginx Rate Limit</a></li><li><a href="https://blog.wonizz.com/2023/05/11/devops-hubot-automation-1/">[DevOps] Hubot 적용기</a></li><li><a href="https://blog.wonizz.com/2023/05/09/devops-k8s-monitoring-with-datadog/">[DevOps] k8s monitoring with Datadog</a></li></ul>
<p>The post <a rel="nofollow" href="https://blog.wonizz.com/2022/09/19/devops-k8s-resource-optimization/">[DevOps] K8S Resource 최적화 사례</a> appeared first on <a rel="nofollow" href="https://blog.wonizz.com">WONIZZ.LOG</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.wonizz.com/2022/09/19/devops-k8s-resource-optimization/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">1963</post-id>	</item>
	</channel>
</rss>
