<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>개발계발 - 1</title>
    <link>https://myphiloprogramming.tistory.com/</link>
    <description></description>
    <language>ko</language>
    <pubDate>Fri, 19 Jun 2026 05:28:36 +0900</pubDate>
    <generator>TISTORY</generator>
    <ttl>100</ttl>
    <managingEditor>냥냥친구</managingEditor>
    <image>
      <title>개발계발 - 1</title>
      <url>https://tistory1.daumcdn.net/tistory/3074978/attach/e4f367a48ffe4b0a9b8e15efca2d7764</url>
      <link>https://myphiloprogramming.tistory.com</link>
    </image>
    <item>
      <title>numble 챌린지 중간 회고</title>
      <link>https://myphiloprogramming.tistory.com/39</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;나는 numble에서 &lt;a href=&quot;https://www.numble.it/deepdive/37&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;실전&lt;span&gt; &lt;/span&gt;가이드&lt;span&gt; &lt;/span&gt;프로젝트&lt;span&gt;_Kubernetes&lt;/span&gt;로&lt;span&gt; &lt;/span&gt;모니터링&lt;span&gt; &lt;/span&gt;시스템&lt;span&gt; &lt;/span&gt;구축하기&lt;/a&gt;를 진행하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;사이드프로젝트를 해야겠다는 생각과 쿠버네티스에 대한 공부를 하고 싶다는 생각을 하고 있던 참이었는데 우연히 이 두 가지를 충족시킬 수 있는 프로그램을 발견하게 돼서, 심지어 가격도 해볼 만해서 바로 결제했다. ㅋㅅㅋ&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특히 &lt;a href=&quot;https://www.numble.it/deepdive/37#164b5910237245788e2b6cff3e3ae401&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;여기&lt;/a&gt;에 혹했다. ㅎ&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1450&quot; data-origin-height=&quot;418&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/TYLvO/btscvYxjAfq/jj1rJPMw8yckraRJMGOFSK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/TYLvO/btscvYxjAfq/jj1rJPMw8yckraRJMGOFSK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/TYLvO/btscvYxjAfq/jj1rJPMw8yckraRJMGOFSK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FTYLvO%2FbtscvYxjAfq%2Fjj1rJPMw8yckraRJMGOFSK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1450&quot; height=&quot;418&quot; data-origin-width=&quot;1450&quot; data-origin-height=&quot;418&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;프로젝트는 팀을 이루어 진행하지만 결과물은 각자 제출해야 된다. 각자 제출이다 보니 팀원 스케줄에 너무 얽매이지도 않고 처음부터 끝까지 다 해볼 수 있다는 장점이 있다.! 우리팀은 카톡방을 하나 파서 모르는 것을 질문하며 진행 중이다. (아직까지는 순항중..!)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;나는 쿠버네티스 지식이 전무한 상태에서 시작했기 때문에 노드, 파드 등 개념부터&amp;nbsp; argoCD, kibana 툴 등 공부할게 매우매우 많다. ㅋㅋ 지식의 양 팍팍 늘어나는 중!! (바라던 부분인데 좀 힘들다..) 다행히도 호스트님이 예시 코드를 제공해 주어 모르는 부분을 참고하며 진행하고 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클라우드 서비스로는 네이버클라우드플랫폼(NCP)을 이용하고 있다. numble에서 크레딧을 최대 100만 원 제공해 주기 때문에 프로젝트 종료기간까지는 문제없이 무료로 이용할 수 있을 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;네이버 클라우드 플랫폼은 처음사용해보는데 깔끔하고 좋다. 특히 가이드 문서가 정말 잘 되어있어 편리하다.!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS를 사용해본 유저라면 NCP 역시 무난하게 사용할 수 있을 것 같다!&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;3442&quot; data-origin-height=&quot;1710&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/DfcdU/btscHcUCr1W/RKDehElzDTjwnzMklWJDl0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/DfcdU/btscHcUCr1W/RKDehElzDTjwnzMklWJDl0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/DfcdU/btscHcUCr1W/RKDehElzDTjwnzMklWJDl0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FDfcdU%2FbtscHcUCr1W%2FRKDehElzDTjwnzMklWJDl0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;3442&quot; height=&quot;1710&quot; data-origin-width=&quot;3442&quot; data-origin-height=&quot;1710&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;최초 가입 시에는 10만 원 크레딧도 준다고 하니 한 번 테스트해 봐도 좋을 것 같다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이제 2주 정도 남았는데 마지막까지 열심히해서 프로젝트 완수해야지!&lt;/p&gt;</description>
      <category>프로젝트/기타</category>
      <category>Kubenetes</category>
      <category>numble</category>
      <category>사이드프로젝트</category>
      <author>냥냥친구</author>
      <guid isPermaLink="true">https://myphiloprogramming.tistory.com/39</guid>
      <comments>https://myphiloprogramming.tistory.com/39#entry39comment</comments>
      <pubDate>Tue, 25 Apr 2023 14:36:03 +0900</pubDate>
    </item>
    <item>
      <title>[쿠버네티스 세팅하기] 1. 쿠버네티스 구성 살펴보기</title>
      <link>https://myphiloprogramming.tistory.com/38</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;쿠버네티스는 공식 문서가 매우 잘 되어있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만, 많은 내용을 담고 있어 쿠버네티스 구성에 대한 내용을 간략하게 정리해 보았다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;&lt;a href=&quot;https://kubernetes.io/ko/docs/concepts/overview/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;https://kubernetes.io/ko/docs/concepts/overview/&lt;/a&gt;&lt;/b&gt;&lt;/p&gt;
&lt;figure id=&quot;og_1681559180368&quot; contenteditable=&quot;false&quot; data-ke-type=&quot;opengraph&quot; data-ke-align=&quot;alignCenter&quot; data-og-type=&quot;website&quot; data-og-title=&quot;쿠버네티스란 무엇인가?&quot; data-og-description=&quot;쿠버네티스는 컨테이너화된 워크로드와 서비스를 관리하기 위한 이식할 수 있고, 확장 가능한 오픈소스 플랫폼으로, 선언적 구성과 자동화를 모두 지원한다. 쿠버네티스는 크고 빠르게 성장하&quot; data-og-host=&quot;kubernetes.io&quot; data-og-source-url=&quot;https://kubernetes.io/ko/docs/concepts/overview/&quot; data-og-url=&quot;https://kubernetes.io/ko/docs/concepts/overview/&quot; data-og-image=&quot;https://scrap.kakaocdn.net/dn/jwMXd/hyShPkYSgN/iVm0fVCpATP3JhppFCi1Xk/img.png?width=1727&amp;amp;height=373&amp;amp;face=0_0_1727_373,https://scrap.kakaocdn.net/dn/cyumQt/hySi6elIa1/u9yKJu52tPY6obwT0uaLuk/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512&quot;&gt;&lt;a href=&quot;https://kubernetes.io/ko/docs/concepts/overview/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot; data-source-url=&quot;https://kubernetes.io/ko/docs/concepts/overview/&quot;&gt;
&lt;div class=&quot;og-image&quot; style=&quot;background-image: url('https://scrap.kakaocdn.net/dn/jwMXd/hyShPkYSgN/iVm0fVCpATP3JhppFCi1Xk/img.png?width=1727&amp;amp;height=373&amp;amp;face=0_0_1727_373,https://scrap.kakaocdn.net/dn/cyumQt/hySi6elIa1/u9yKJu52tPY6obwT0uaLuk/img.png?width=512&amp;amp;height=512&amp;amp;face=0_0_512_512');&quot;&gt;&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;og-text&quot;&gt;
&lt;p class=&quot;og-title&quot; data-ke-size=&quot;size16&quot;&gt;쿠버네티스란 무엇인가?&lt;/p&gt;
&lt;p class=&quot;og-desc&quot; data-ke-size=&quot;size16&quot;&gt;쿠버네티스는 컨테이너화된 워크로드와 서비스를 관리하기 위한 이식할 수 있고, 확장 가능한 오픈소스 플랫폼으로, 선언적 구성과 자동화를 모두 지원한다. 쿠버네티스는 크고 빠르게 성장하&lt;/p&gt;
&lt;p class=&quot;og-host&quot; data-ke-size=&quot;size16&quot;&gt;kubernetes.io&lt;/p&gt;
&lt;/div&gt;
&lt;/a&gt;&lt;/figure&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style1&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;쿠버네티스란&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨테이너화된 애플리케이션을 배포, 확장 및 관리해주는 시스템이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;규모가 큰 서비스들은 여러개의 서버에 여러개의 애플리케이션을 띄워놓고 운영하는데, 서버 하나하나씩 독립적으로 관리한다면 같은 일을 여러번 관리하는 등의 번거로운 점이 발생한다. 이런 불편함을 해결해주는 것이 쿠버네티스다. yml 파일에 구성하려는 서버 리소스를 명세하고 배포하면 여러 서버에 걸쳐 항상 그 상태를 유지 및 관리해준다. 스케일 아웃된 여러 개의 컨테이너를 하나로 묶어 트래픽을 로드밸런싱해주거나 명세를 통한 자동 롤아웃과 롤백 등을 제공한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;쿠버네티스 클러스터&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿠버네티스 클러스터의 구성은 아래와 같다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;2352&quot; data-origin-height=&quot;1126&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/5T1jm/btsaqOPnlZo/UK9tWLiTqP4kZKxw6DQEek/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/5T1jm/btsaqOPnlZo/UK9tWLiTqP4kZKxw6DQEek/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/5T1jm/btsaqOPnlZo/UK9tWLiTqP4kZKxw6DQEek/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2F5T1jm%2FbtsaqOPnlZo%2FUK9tWLiTqP4kZKxw6DQEek%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;2352&quot; height=&quot;1126&quot; data-origin-width=&quot;2352&quot; data-origin-height=&quot;1126&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;컨트롤 플레인 컴포넌트&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클러스터에 관한 전반적인 결정을 수행하고 클러스터 이벤트를 핸들링한다.&lt;/p&gt;
&lt;h3 id=&quot;kube-apiserver&quot; style=&quot;background-color: #ffffff; color: #222222; text-align: left;&quot; data-ke-size=&quot;size23&quot;&gt;kube-apiserver&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿠버네티스 api를 노출하는, 컨트롤 플레인의 프론트엔드이다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;etcd&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #222222; text-align: left;&quot;&gt;클러스터 데이터를 담는 쿠버네티스 뒷단의 저장소로 사용되는 key-value 스토리지이다.&lt;/span&gt;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;span style=&quot;background-color: #ffffff; color: #222222; text-align: left;&quot;&gt;kube-scheduler&lt;/span&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;생성된 파드를 노드에 할당하는 등의 스케줄링 작업을 진행한다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;kube-controller-manager&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;컨트롤러 프로세스를 실행한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;노드 컴포넌트&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;동작 중인 파드를 유지, 쿠버네티스 런타임 환경 제공한다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;kubelet&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파드의 스펙 등 컨테이너를 관리한다.&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;kube-proxy&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클러스터의 각 노드에서 실행되는 네트워크 프록시로 노드의 네트워크 규칙을 관리한다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음으로는 주요 개념들을 살펴보자.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;노드&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;노드는 컨트롤플레인에 의해 관리되며 파드를 실행하는데 필요한 서비스를 포함한다. 하나의 노드는 하나의 서버라고 이해하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하나의 클러스터 안에는 여러 개의 노드가 있을 수 있고, 하나의 노드 안에는 여러 개의 파드가 있을 수 있다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;파드&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿠버네티스에서 생성하고 관리할 수 있는 배포 가능한 가장 작은 컴퓨터 단위이다. 하나 이상의 컨테이너를 포함하며 컨테이너에 대한 스토리지 및 네트워크를 공유한다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1606&quot; data-origin-height=&quot;1224&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/bhxcMf/btsal4Zhc9I/ExOnUketaqdRnctW9IUmx1/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/bhxcMf/btsal4Zhc9I/ExOnUketaqdRnctW9IUmx1/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/bhxcMf/btsal4Zhc9I/ExOnUketaqdRnctW9IUmx1/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FbhxcMf%2Fbtsal4Zhc9I%2FExOnUketaqdRnctW9IUmx1%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;656&quot; height=&quot;500&quot; data-origin-width=&quot;1606&quot; data-origin-height=&quot;1224&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;파드 템플릿&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파드템플릿은 파드를 생성하기 위한 명세이다. 파드 템플릿이 변경되면 기존의 파드를 갱신하지않고 새로운 파드를 생성한 후 교체한다.&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래는 예시이다.&lt;/p&gt;
&lt;pre id=&quot;code_1681562329237&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;apiVersion: batch/v1
kind: Job
metadata:
  name: hello
spec:
  template:
    # 여기서부터 파드 템플릿이다
    spec:
      containers:
      - name: hello
        image: busybox:1.28
        command: ['sh', '-c', 'echo &quot;Hello, Kubernetes!&quot; &amp;amp;&amp;amp; sleep 3600']
      restartPolicy: OnFailure
    # 여기까지 파드 템플릿이다&lt;/code&gt;&lt;/pre&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;워크로드 리소스&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;워크로드 리소스로는 디플로이먼트, 레플리카 셋, 스테이트풀셋 등이 있다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;레플리카 셋&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;레플리카셋은 명세된 내용을 달성하기 위해 파드를 띄우거나 삭제한다. 명세 내용으로는 파드를 식별하는 방법이 명시된 셀렉터, 유지해야 하는 파드 개수를 명시하는 레플리카 개수, 레플리카 수 유지를 위해 생성하는 신규 파드에 대한 데이터를 명시하는 파드 템플릿을 포함한다.&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;디플로이먼트&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파드와 레플리카셋에 대한 선언적 업데이트 제공하며 레플리카 셋의 상위 수준의 리소스이다. 블로그를 좀 찾아보니 레플리카셋 대신 디플로이먼트를 주로 사용하는 것 같다.&lt;/p&gt;
&lt;hr contenteditable=&quot;false&quot; data-ke-type=&quot;horizontalRule&quot; data-ke-style=&quot;style6&quot; /&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;서비스&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파드에서 실행중인 애플리케이션을 네트워크 서비스로 노출하는 추상화 방법이다. 아래 그림이 직관적인 이해를 돕는다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;954&quot; data-origin-height=&quot;746&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/eblqGJ/btsakhSeBQZ/2cFWr9gWeTTWmUFWTnA4bK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/eblqGJ/btsakhSeBQZ/2cFWr9gWeTTWmUFWTnA4bK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/eblqGJ/btsakhSeBQZ/2cFWr9gWeTTWmUFWTnA4bK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FeblqGJ%2FbtsakhSeBQZ%2F2cFWr9gWeTTWmUFWTnA4bK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;681&quot; height=&quot;533&quot; data-origin-width=&quot;954&quot; data-origin-height=&quot;746&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서비스에 고유한 ip주소와 파드 집합에 대한 단일 dns명을 부여하고 로드밸런싱을 수행한다. 파드가 영구적이지 않고 새로 뜨고 교체되기 때문에 논리적으로 파드에 접근할 수 있도록 해주는 역할을 한다.&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;인그레스&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;클러스터 내의 서비스에 대한 외부 접근을 관리하는 api 오브젝트이며, 일반적으로 http를 관리한다. 외부 접근을 허용하게 하는 또 다른 방법으로는 노드 포트가 있는데 이는 L4레벨까지만 다룰 수 있어서 L7레벨까지의 접근을 허용하려면 인그레스를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쿠버네티스 세팅을 진행하며 추가로 필요한 개념들은 계속 추가해 나갈 예정!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다음 포스팅에서는 쿠버네티스 세팅을 진행해보겠다.&lt;/p&gt;</description>
      <category>개발계발/인프라</category>
      <category>Kubernetes</category>
      <category>쿠버네티스</category>
      <author>냥냥친구</author>
      <guid isPermaLink="true">https://myphiloprogramming.tistory.com/38</guid>
      <comments>https://myphiloprogramming.tistory.com/38#entry38comment</comments>
      <pubDate>Sat, 15 Apr 2023 21:48:47 +0900</pubDate>
    </item>
    <item>
      <title>Django ALLOWED_HOST, CORS_ORIGIN_WHITELIST</title>
      <link>https://myphiloprogramming.tistory.com/37</link>
      <description>&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;ALLOWED_HOST&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;서버로 요청하는 Host에 대한 Allowed 리스트.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;DEBUG=True라면 기본값으로 &lt;b&gt;['.localhost',&amp;nbsp;'127.0.0.1',&amp;nbsp;'[::1]']&lt;/b&gt; 로 설정된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;  참고 : &lt;b&gt;[::1] 는&lt;/b&gt; 로컬의 &lt;b&gt;IPV6&lt;/b&gt;을 의미한다. IPV4에서 localhost와 같은 역할.!&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;&lt;span style=&quot;color: #000000;&quot;&gt;&lt;b&gt;CORS_ORIGIN_WHITELIST&lt;/b&gt;&lt;/span&gt;&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;Origin 헤더에 대한 Allowed 리스트. Origin 헤더는 fetch가 시작되는 위치로, GET 요청을 제외하고 포함된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;a href=&quot;https://github.com/adamchainz/django-cors-headers&quot;&gt;django-cors-headers&lt;/a&gt; 라이브러리에서 제공하는 기능이다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;아래와 같이 INSTALLED_APP과 MIDDLEWARE에서 추가 후, CORS_ORIGIN_WHITELIST를 정의할 수 있다.&lt;/p&gt;
&lt;pre class=&quot;jboss-cli&quot;&gt;&lt;code&gt;INSTALLED_APPS = [
    ...,
    &quot;corsheaders&quot;,
    ...,
]

MIDDLEWARE = [
    ...,
    &quot;corsheaders.middleware.CorsMiddleware&quot;,
    &quot;django.middleware.common.CommonMiddleware&quot;,
    ...,
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;443, 80 포트를 제외하고는 URI scheme + hostname + port로 정의해야 한다.&lt;/p&gt;
&lt;pre class=&quot;bash&quot; data-ke-language=&quot;bash&quot;&gt;&lt;code&gt;CORS_ORIGIN_WHITELIST = [
	'https://example.com',
	'http://127.0.0.1:9000',
]&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약, 정규표현식으로 Allowed 리스트를 정의하고 싶다면, &lt;b&gt;CORS_ALLOWED_ORIGIN_REGEXES&lt;/b&gt; 사용하면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;(CORS_ORIGIN_WHITELIST 와 함께 사용 가능.)&lt;/p&gt;
&lt;pre class=&quot;awk&quot;&gt;&lt;code&gt;CORS_ALLOWED_ORIGIN_REGEXES = [
    r&quot;^https://\\w+\\.example\\.com$&quot;,
]
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;CORS_ALLOW_ALL_ORIGINS&lt;/b&gt; 가 True이면 모든 Origin에 대해 출처가 허용됨을 의미한다. (제한이 없다.!)&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;예전에는 CORS_ORIGIN_ALLOW_ALL 이었다. 둘 다 사용할 경우 지금 이름이 먼저.!&lt;/p&gt;
&lt;pre class=&quot;ini&quot;&gt;&lt;code&gt;CORS_ALLOW_ALL_ORIGINS = True
&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;특정 path 만을 허용 할 수도 있다. CORS_URLS_REGEX 를 사용하며, 기본 값은 r'^.*$&amp;rsquo; 로, 모든 path에 대해 허용한다는 의미이다.&lt;/p&gt;
&lt;pre class=&quot;awk&quot;&gt;&lt;code&gt;CORS_URLS_REGEX = r&quot;^/api/.*$&quot;
&lt;/code&gt;&lt;/pre&gt;</description>
      <category>개발계발/Python</category>
      <category>Django</category>
      <author>냥냥친구</author>
      <guid isPermaLink="true">https://myphiloprogramming.tistory.com/37</guid>
      <comments>https://myphiloprogramming.tistory.com/37#entry37comment</comments>
      <pubDate>Fri, 9 Dec 2022 09:25:41 +0900</pubDate>
    </item>
    <item>
      <title>DynamoDB 톺아보기</title>
      <link>https://myphiloprogramming.tistory.com/36</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;Dynamo(다이나모) DB가 NoSQL이라 key-value 구조로 데이터를 저장한다는 것만 알고 있었는데, 이번에 처음 도입해 보니 생각보다 알아야 할 게 많았다. 여기저기 문서를 참고하며 배운 내용을 기록해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;DynamoDB란?&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;AWS 에서 제공하는 NoSQL 기반 데이터베이스 서비스로, 데이터 읽고 쓰기, 인덱싱, 샤딩과 백업 등을 지원한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;&lt;span style=&quot;color: #000000;&quot;&gt;필드가 고정이 아니다.&lt;/span&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;RDB와 달리 필드가 고정이 아니다. 아래의 People 테이블에서 보듯이 &lt;span style=&quot;color: #1b711d;&quot;&gt;&lt;b&gt;Address&lt;/b&gt;&lt;/span&gt;와 &lt;span style=&quot;color: #1b711d;&quot;&gt;&lt;b&gt;FavoriteColor&lt;/b&gt;&lt;/span&gt;가 없는 row도 가능하다. 여기서 없다는 것은 null이 아닌 키조차도 없음을 의미한다.&lt;/p&gt;
&lt;pre id=&quot;code_1667023659192&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;People

{
    &quot;PersonID&quot;: 101,
    &quot;LastName&quot;: &quot;Smith&quot;,
    &quot;FirstName&quot;: &quot;Fred&quot;,
    &quot;Phone&quot;: &quot;555-4321&quot;
},
{
    &quot;PersonID&quot;: 102,
    &quot;LastName&quot;: &quot;Jones&quot;,
    &quot;FirstName&quot;: &quot;Mary&quot;,
    &quot;Address&quot;: {
                &quot;Street&quot;: &quot;123 Main&quot;,
                &quot;City&quot;: &quot;Anytown&quot;,
                &quot;State&quot;: &quot;OH&quot;,
                &quot;ZIPCode&quot;: 12345
    }
},
{
    &quot;PersonID&quot;: 103,
    &quot;LastName&quot;: &quot;Stephens&quot;,
    &quot;FirstName&quot;: &quot;Howard&quot;,
    &quot;Address&quot;: {
                &quot;Street&quot;: &quot;123 Main&quot;,
                &quot;City&quot;: &quot;London&quot;,                                    
                &quot;PostalCode&quot;: &quot;ER3 5K8&quot;
    },
    &quot;FavoriteColor&quot;: &quot;Blue&quot;
}&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;기본키는 필요하다.&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다만, 다이나모도 RDB와 같이 기본키(Primary Key)가 필요하다. 다이나모에는 Partition Key와 Sort Key가 있는데, Parition Key를 단독으로 기본키로 사용하거나 Partition Key와 Sort Key를 복합키로하여 기본키로 사용할 수 있다. Key에 해당 하는 필드는 row에 값이 있어야 하며, 기본키는 고유한 값이어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 파티션 키(Partition Key)&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다이나모는 데이터를 파티션(Partition)으로 저장하는데 이 Key를 사용해 어떤 파티션에 저장할지 결정한다. 아래의 이미지와 같이 파티션 키를 해시함수 인자로 사용해서 출력되는 결과로 어떤 파티션에 저장할지 결정한다고 하는데, 이는 dynamoDB의 역할이므로 우리가 관리하지는 않는다.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1688&quot; data-origin-height=&quot;1168&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Iv9qi/btrPQg7iX3M/RPXYQQ68Px2piUaahtZmj0/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Iv9qi/btrPQg7iX3M/RPXYQQ68Px2piUaahtZmj0/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Iv9qi/btrPQg7iX3M/RPXYQQ68Px2piUaahtZmj0/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FIv9qi%2FbtrPQg7iX3M%2FRPXYQQ68Px2piUaahtZmj0%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1688&quot; height=&quot;1168&quot; data-origin-width=&quot;1688&quot; data-origin-height=&quot;1168&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;span&gt;Partition Key만으로 기본키로 사용하면 해당 필드는 고유해야 한다.&amp;nbsp; People 테이블에서는&lt;span&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;color: #1b711d;&quot;&gt;&lt;b&gt;PersonId&lt;/b&gt;&lt;/span&gt;가 해당한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 정렬 키(Sort Key)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파티션이 고유하지 않다면 정렬 키를 사용해 복합키로써 고유키를 지정할 수 있다. 파티션에서는 이 정렬 키를 사용해 row를 정렬한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;쿼리 VS 스캔&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테이블의 데이터를 조회할 때 조회 방식으로 쿼리와 스캔이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;쿼리&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;기본키나 인덱스를 기준으로 데이터를 조회한다. 인덱스를 기준으로 데이터를 탐색하기 때문에 빠른 결과를 기대할 수 있다. 한 번의 쿼리를 기준으로 최대 1MB의 데이터를 반환한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;스캔&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;인덱스로 지정되지 않은 필드로 데이터을 조회한다. 풀스캔하기 때문에 쿼리보다 질의 속도가 느리다.&lt;b&gt;&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;인덱스&lt;/b&gt;&lt;b&gt;&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;1. 로컬 보조 인덱스 (Local Secondary Index)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;테이블에 파티션 키와 정렬 키를 설정하면, 해당 키들로 인덱싱도 가능하다. 이 기본키들로 생성된 인덱스를 로컬 보조 인덱스(LSI)라고 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;2. 글로벌 보조 인덱스 (Global Secondary Index)&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파티션 키, 정렬 키 외에도 다른 필드로 필터를 해야 한다면, 글로벌 보조 인덱스(GSI)로 지정할 수 있다. &lt;b&gt;People &lt;/b&gt;테이블에서 FirstName이 같은 사람들을 쿼리하고 싶다면 FirstName로 인덱스를 추가할 수 있다. GSI는 테이블 등록 시점에 생성할 수도 있고 이미 생성된 테이블에 추가할 수도 있다. 다만, 데이터 양에 영향을 받기 때문에 인덱스 생성 속도가 느려질 수 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4 data-ke-size=&quot;size20&quot;&gt;&lt;b&gt;읽기 단위, 쓰기 단위&lt;/b&gt;&lt;/h4&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;읽기 단위&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;읽기 단위가 1이면 4KB 용량에 대해 초당 1회의 강력한 일관성 읽기 또는 초당 2회의 최종 읽관성 읽기를 나타낸다. 만약 읽기 단위가 10인 테이블을 생성한다면, 이 테이블은 4KB 항목에 대해 초당 10개의 row를 읽을 수 있다. 만약 4KB보다 큰 용량의 row를 읽으면 읽기 단위 2를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;쓰기 단위&lt;/b&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;쓰기 단위가 1이면 1KB 용량에 초당 1회 쓰기를 나타낸다. 만약 쓰기 단위가 10인 테이블을 생성한다면, 이 테이블은 초당 10 회 row를 쓸 수 있다. row 하나씩 쓰기 때문에, row 별 용량에 따라 쓰기 단위를 사용한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;</description>
      <category>개발계발/인프라</category>
      <category>AWS</category>
      <category>DB</category>
      <category>dynamdb</category>
      <category>Dynamo</category>
      <category>nosql</category>
      <author>냥냥친구</author>
      <guid isPermaLink="true">https://myphiloprogramming.tistory.com/36</guid>
      <comments>https://myphiloprogramming.tistory.com/36#entry36comment</comments>
      <pubDate>Sat, 29 Oct 2022 15:28:03 +0900</pubDate>
    </item>
    <item>
      <title>python Lint툴 적용하기(flake8, black)</title>
      <link>https://myphiloprogramming.tistory.com/35</link>
      <description>&lt;p data-ke-size=&quot;size16&quot;&gt;파이썬은 &lt;a href=&quot;https://peps.python.org/pep-0008/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;PEP8&lt;/a&gt;이라고 하는 파이썬 코드 작성 규칙이 있다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;이 작성 규칙을 지키지 않아도 스크립트를 실행하는데 문제가 없지만 코드의 일관성과 용이한 유지보수를 위해, 그리고 당신의 코드를 읽을 또 다른 동료를 위해 규칙을 지켜주어야 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;하지만 이 규칙을 모두 기억하기란 어려운 일이다. 이 때 린트툴을 사용하면 내가 작성한 코드를 읽고 코드 규칙에 어긋나는 부분을 알려준다. 심지어 직접 고쳐주기도 한다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;파이썬의 기본 린트툴로는 &lt;a href=&quot;https://pylint.pycqa.org/en/latest/&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;pylint&lt;/a&gt;가 있으며 유명한 flake8이나 black 패키지로 대체할 수 있다. 하나씩 사용해보자.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;flake8&lt;/h3&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;설치&lt;/p&gt;
&lt;pre id=&quot;code_1664082927510&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pip install flake8&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;실행&lt;/p&gt;
&lt;pre id=&quot;code_1664083001493&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;# 패키지 전체 검사
flake8
# 특정 경로 및 파일 검사
flake8 your_script.py&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;결과&lt;/p&gt;
&lt;pre id=&quot;code_1664083085044&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;./lib/youtube/youtube.py:3:1: F401 'json' imported but unused
./lib/youtube/youtube.py:6:1: F401 'apiclient.discovery.build' imported but unused
./lib/youtube/youtube.py:8:1: E265 block comment should start with '# '
./lib/youtube/youtube.py:13:1: E302 expected 2 blank lines, found 1
./lib/youtube/youtube.py:19:1: W293 blank line contains whitespace
./lib/youtube/youtube.py:35:1: W293 blank line contains whitespace
./lib/youtube/youtube.py:51:1: W293 blank line contains whitespace
./lib/youtube/youtube.py:67:1: W293 blank line contains whitespace&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;명령어를 실행하고 나면, 코드 내 규칙 오류를 잡아준다. F401, E302 등이 PEP8에 명시된 코드 규칙이며 어긴 내용을 간략하게 적어준다. 실행 내용을 참고하여 코드 규칙을 적용해주면 된다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;만약, lint를 적용하고 싶지 않은 파일이나 코드 규칙이 있다면, &lt;b&gt;.flake&lt;/b&gt; 파일 생성 후 아래와 같이 제외하고 싶은 내용을 작성해주고 실행하면 된다.&lt;/p&gt;
&lt;pre id=&quot;code_1664083381202&quot; class=&quot;crystal&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;[flake8]

exclude = 
    .git,
    .gitignore,
    venv,
    ./lib/

ignore =
    F401,
    E501&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;h3 data-ke-size=&quot;size23&quot;&gt;black&lt;/h3&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;black은 잘못된 코드 규칙을 직접 수정해준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&amp;nbsp;&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;설치&lt;/p&gt;
&lt;pre id=&quot;code_1664083442735&quot; class=&quot;bash&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;pip install black&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;실행&lt;/p&gt;
&lt;pre id=&quot;code_1664083590435&quot; class=&quot;armasm&quot; data-ke-language=&quot;bash&quot; data-ke-type=&quot;codeblock&quot;&gt;&lt;code&gt;black your_script.py&lt;/code&gt;&lt;/pre&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;b&gt;--check&amp;nbsp;&lt;/b&gt;옵션을 실행하면 포맷팅이 필요하다고 귀엽게 알려준다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;1054&quot; data-origin-height=&quot;182&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/Lkj9h/btrMVbOrvAL/KVEP7pTwSBgBiZbPFsK8oK/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/Lkj9h/btrMVbOrvAL/KVEP7pTwSBgBiZbPFsK8oK/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/Lkj9h/btrMVbOrvAL/KVEP7pTwSBgBiZbPFsK8oK/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FLkj9h%2FbtrMVbOrvAL%2FKVEP7pTwSBgBiZbPFsK8oK%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;1054&quot; height=&quot;182&quot; data-origin-width=&quot;1054&quot; data-origin-height=&quot;182&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;
&lt;p data-ke-size=&quot;size18&quot;&gt;결과&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;&lt;s&gt;(귀여운 반짝반짝 케이크)&lt;/s&gt;&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;실행 후 코드를 보면 모양새가 바뀐 것을 확인할 수 있다. 직접 해보시길..&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;다시 --check 옵션을 추가하면 All done! 이라며 케이크를 또 준다.&lt;/p&gt;
&lt;p data-ke-size=&quot;size16&quot;&gt;black은 &lt;a href=&quot;https://github.com/psf/black&quot; target=&quot;_blank&quot; rel=&quot;noopener&quot;&gt;공식 커뮤니티&lt;/a&gt;에서 개발한 것인데도 이렇게 귀엽다.&lt;/p&gt;
&lt;p&gt;&lt;figure class=&quot;imageblock alignCenter&quot; data-ke-mobileStyle=&quot;widthOrigin&quot; data-origin-width=&quot;914&quot; data-origin-height=&quot;182&quot;&gt;&lt;span data-url=&quot;https://blog.kakaocdn.net/dn/JwmWZ/btrMU5t4y1f/T83zASCbicIK0rcO2RoOXk/img.png&quot; data-phocus=&quot;https://blog.kakaocdn.net/dn/JwmWZ/btrMU5t4y1f/T83zASCbicIK0rcO2RoOXk/img.png&quot;&gt;&lt;img src=&quot;https://blog.kakaocdn.net/dn/JwmWZ/btrMU5t4y1f/T83zASCbicIK0rcO2RoOXk/img.png&quot; srcset=&quot;https://img1.daumcdn.net/thumb/R1280x0/?scode=mtistory2&amp;fname=https%3A%2F%2Fblog.kakaocdn.net%2Fdn%2FJwmWZ%2FbtrMU5t4y1f%2FT83zASCbicIK0rcO2RoOXk%2Fimg.png&quot; onerror=&quot;this.onerror=null; this.src='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png'; this.srcset='//t1.daumcdn.net/tistory_admin/static/images/no-image-v1.png';&quot; loading=&quot;lazy&quot; width=&quot;914&quot; height=&quot;182&quot; data-origin-width=&quot;914&quot; data-origin-height=&quot;182&quot;/&gt;&lt;/span&gt;&lt;/figure&gt;
&lt;/p&gt;</description>
      <category>개발계발/Python</category>
      <category>black</category>
      <category>flake8</category>
      <category>lint</category>
      <category>pylint</category>
      <category>python</category>
      <author>냥냥친구</author>
      <guid isPermaLink="true">https://myphiloprogramming.tistory.com/35</guid>
      <comments>https://myphiloprogramming.tistory.com/35#entry35comment</comments>
      <pubDate>Sun, 25 Sep 2022 14:32:39 +0900</pubDate>
    </item>
    <item>
      <title>[2293] 동전1</title>
      <link>https://myphiloprogramming.tistory.com/34</link>
      <description>&lt;h2&gt;백준 2293번 동전1&lt;/h2&gt;
&lt;pre class=&quot;vim&quot;&gt;&lt;code&gt;n, k = map(int, input().split())
c = []
dp = [0 for i in range(k + 1)]
dp[0] = 1
for i in range(n):
    c.append(int(input()))
for i in c:
    for j in range(1, k + 1):
        if j - i &amp;gt;= 0:
            dp[j] += dp[j - i]
print(dp[k])&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;핵심 아이디어&lt;/p&gt;
&lt;p&gt;k길이의 배열을 만들고, 각 원소 별 경우의 수를 계산하여 k가 되는 경우의 수를 구한다.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;설명&lt;/p&gt;
&lt;p&gt;dp 배열에서 원소를 &lt;code&gt;dp[key] = value&lt;/code&gt; 라고 한다면,&lt;/p&gt;
&lt;ul style=&quot;list-style-type: disc;&quot; data-ke-list-type=&quot;disc&quot;&gt;
&lt;li&gt;key : 1, 2, 3, ... k&lt;/li&gt;
&lt;li&gt;value : key를 만들 수 있는 경우의 수&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;예를 들어 [1, 2, 5] coin을 가지고 k = 4라면, 우리는 약간의 계산으로 경우의 수가 3개인 걸 알 수 있는데, 코드로 보면&lt;/p&gt;
&lt;ul style=&quot;list-style-type: circle;&quot; data-ke-list-type=&quot;circle&quot;&gt;
&lt;li data-ke-size=&quot;size16&quot;&gt;i = 1, j = 1 일 때, $j - i &amp;ge; 0$이므로 $dp[1] += dp[0]$ 이 된다. 이 때 dp[0]은 1이므로 dp[1]도 1이다.&amp;nbsp;&amp;nbsp;&lt;/li&gt;
&lt;li data-ke-size=&quot;size16&quot;&gt;i = 1, j =2,3,4일 때도 모두 j - i &amp;ge; 0이므로 dp[2], dp[3], dp[4] 역시 모두 1이다.&lt;/li&gt;
&lt;li data-ke-size=&quot;size16&quot;&gt;i =2, j = 2 일 때, j - i &amp;ge; 0이므로 dp[2] += dp[0] 이 된다. dp[2]는 2이다. 왜냐하면 누적값이기 때문에&lt;/li&gt;
&lt;li data-ke-size=&quot;size16&quot;&gt;i = 2, j =3 일 때, j -i &amp;ge; 0이므로, dp[3] += dp[1]에서 dp[1]은 1이므로, dp[3]도 1이다.&lt;/li&gt;
&lt;li data-ke-size=&quot;size16&quot;&gt;i = 2, j = 4일 때, j - i &amp;ge;0이므로, dp[4] += dp[2]에서 dp[2]는 2이므로 dp[4]도 3이다. 왜냐하면 dp[4]가 앞서 1이었기 때문에&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;이로써 dp[4] = 3이므로, 경우의 수가 3개가 나온다.&lt;/p&gt;</description>
      <category>개발계발/알고리즘</category>
      <author>냥냥친구</author>
      <guid isPermaLink="true">https://myphiloprogramming.tistory.com/34</guid>
      <comments>https://myphiloprogramming.tistory.com/34#entry34comment</comments>
      <pubDate>Tue, 22 Sep 2020 08:53:38 +0900</pubDate>
    </item>
    <item>
      <title>[17413] 단어뒤집기2 #python</title>
      <link>https://myphiloprogramming.tistory.com/33</link>
      <description>&lt;h2 data-ke-size=&quot;size26&quot;&gt;백준 17413번 단어뒤집기2&lt;/h2&gt;
&lt;pre class=&quot;sqf&quot;&gt;&lt;code&gt;text = list(input())
flag = False

result = []
temp = []
for i, t in enumerate(text):
    if t == &quot;&amp;lt;&quot;:
        if len(temp) &amp;gt; 0:
            temp.reverse()
            result.extend(temp)
            temp = []
        flag = True
        temp.append(t)
    elif t == &quot;&amp;gt;&quot;:
        flag = False
        temp.append(t)
        result.extend(temp)
        temp = []
    elif t == &quot; &quot;:
        if flag == False:
            temp.reverse()
            temp.append(t)
            result.extend(temp)
            temp = []
        else:
            temp.append(t)
    else:
        temp.append(t)
        if len(text) == i+1:
            temp.reverse()
            result.extend(temp)

print(''.join(result))&lt;/code&gt;&lt;/pre&gt;</description>
      <category>개발계발/알고리즘</category>
      <author>냥냥친구</author>
      <guid isPermaLink="true">https://myphiloprogramming.tistory.com/33</guid>
      <comments>https://myphiloprogramming.tistory.com/33#entry33comment</comments>
      <pubDate>Tue, 22 Sep 2020 08:52:04 +0900</pubDate>
    </item>
    <item>
      <title>[17729] 오등큰수 #python</title>
      <link>https://myphiloprogramming.tistory.com/32</link>
      <description>&lt;h2&gt;백준 17299번 오등큰수&lt;/h2&gt;
&lt;pre class=&quot;vim&quot;&gt;&lt;code&gt;import sys

num = int(input())
a = list(map(int, input().split(&quot; &quot;)))
result = [&quot;-1&quot; for _ in range(num)]
stack = [0]
count = dict()
for i in a:
    try:
        count[i] += 1
    except:
        count[i] = 1

for i in range(num):
    while stack and count[a[stack[-1]]] &amp;lt; count[a[i]]:
        result[stack[-1]] = str(a[i])
        stack.pop()
    stack.append(i)
    i+=1

print(&quot; &quot;.join(result))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;[17298]오큰수와 같은 유형의 문제이다. 다만, 오등큰수는 각 원소 별 합에 대한 크기를 비교한다.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;count&lt;/code&gt;에 원소를 키로 해서 키 별 원소 개수를 저장한다.&lt;/p&gt;
&lt;p&gt;stack에는 a의 인덱스 값을 저장할 건데, for문을 돌면서 count[a] 값이 작은 a의 인덱스를 stack에 push하다가 stack[-1]보다 큰 count[a]를 만나면 stack에서 인덱스를 pop한다.&lt;/p&gt;</description>
      <category>개발계발/알고리즘</category>
      <category>python</category>
      <category>백준</category>
      <category>알고리즘</category>
      <author>냥냥친구</author>
      <guid isPermaLink="true">https://myphiloprogramming.tistory.com/32</guid>
      <comments>https://myphiloprogramming.tistory.com/32#entry32comment</comments>
      <pubDate>Tue, 22 Sep 2020 08:49:39 +0900</pubDate>
    </item>
    <item>
      <title>[Tip] 백준 시간 초과 에러</title>
      <link>https://myphiloprogramming.tistory.com/31</link>
      <description>&lt;p&gt;로직의 이슈가 없는데도 시간 초과가 난다면, &lt;code&gt;input()&lt;/code&gt; 대신 아래와 같이 &lt;code&gt;sys&lt;/code&gt; 모듈을 사용하자.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;python 이외의 언어는 &lt;a href=&quot;https://www.acmicpc.net/problem/15552&quot;&gt;빠른 A+B&lt;/a&gt;를 참고하세요.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;pre class=&quot;dart&quot;&gt;&lt;code&gt;import sys

#num = int(input()) 대신 아래의 코드를 쓰자.
num = int(sys.stdin.readline())&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;하지만 우리는 코딩할 때, &lt;code&gt;input()&lt;/code&gt;으로 코드를 짜기 때문에 이를 일일히 &lt;code&gt;sys.stdin.readline()&lt;/code&gt; 바꾸기가 번거롭다. 그럴 때는 &lt;code&gt;sys.stdin.readline&lt;/code&gt; 를 &lt;code&gt;input&lt;/code&gt; 으로 덮어쓰면 조금 더 간편해진다.&lt;/p&gt;
&lt;pre class=&quot;makefile&quot;&gt;&lt;code&gt;import sys

input = sys.stdin.readline
#기존의 코드를 수정할 필요가 없어진다.
num = int(input())&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;참고로, &lt;code&gt;sys.stdin.readline()&lt;/code&gt; 은 마지막에 엔터 개행문자가 들어가므로 &lt;code&gt;rstirp()&lt;/code&gt;을 사용하여 제거해야 한다.&lt;/p&gt;
&lt;pre class=&quot;pgsql&quot;&gt;&lt;code&gt;import sys
input = sys.stdin.readline

text = input().strip(&quot; &quot;).rstrip()

#rstrip() : 문자열의 오른쪽 공백제거&lt;/code&gt;&lt;/pre&gt;</description>
      <category>개발계발/알고리즘</category>
      <category>tip</category>
      <category>백준</category>
      <category>알고리즘</category>
      <author>냥냥친구</author>
      <guid isPermaLink="true">https://myphiloprogramming.tistory.com/31</guid>
      <comments>https://myphiloprogramming.tistory.com/31#entry31comment</comments>
      <pubDate>Mon, 21 Sep 2020 23:44:15 +0900</pubDate>
    </item>
    <item>
      <title>[17298] 오큰수 #python</title>
      <link>https://myphiloprogramming.tistory.com/30</link>
      <description>&lt;h2&gt;백준 17298번 오큰수&lt;/h2&gt;
&lt;p&gt;내가 푼 코드 &amp;rArr; 시간초과&lt;/p&gt;
&lt;pre class=&quot;python&quot; data-ke-language=&quot;python&quot;&gt;&lt;code&gt;num = int(input())
a = list(map(int, input().split(&quot; &quot;)))
result = []
for i in range(num):
    if i+1 == num:
        result.append(&quot;-1&quot;)
        break
    max_num = max(a[i+1:])
    if a[i] &amp;lt; max_num:
        for j in range(i+1, num):
            if a[j] &amp;gt; a[i]:
                result.append(str(a[j]))
                break
    else:
        result.append(&quot;-1&quot;)
print(&quot; &quot;.join(result))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;정답&lt;/p&gt;
&lt;pre class=&quot;stata&quot;&gt;&lt;code&gt;num = int(input())
a = list(map(int, input().split(&quot; &quot;)))
result = [&quot;-1&quot; for _ in range(num)]
stack = []
stack.append(0)
i = 1
for i in range(num):
    while stack and a[stack[-1]] &amp;lt; a[i]:
        result[stack[-1]] = str(a[i])
        stack.pop()

    stack.append(i)
    i += 1

print(&quot; &quot;.join(result))&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;num의 최댓값이 백만이므로, 이중포문을 돌면 시간초과가 발생한다.&lt;/p&gt;
&lt;p&gt;stack을 사용해서 해결하는데, 작은 수의 인덱스를 stack에 push 하다가 큰 수를 만나면 큰 수보다 작은 stack의작은 수를 모두 pop한다. 이런 식으로 push와 pop을 반복하며 바로 다음 큰 수를 찾는다.&lt;/p&gt;</description>
      <category>개발계발/알고리즘</category>
      <category>python</category>
      <category>백준</category>
      <category>알고리즘</category>
      <author>냥냥친구</author>
      <guid isPermaLink="true">https://myphiloprogramming.tistory.com/30</guid>
      <comments>https://myphiloprogramming.tistory.com/30#entry30comment</comments>
      <pubDate>Mon, 21 Sep 2020 23:42:36 +0900</pubDate>
    </item>
  </channel>
</rss>