블로그

일프로

[kubernetes] 데브옵스 한방정리 #8

해당 블로그는 [쿠버네티스 어나더 클래스] 강의에 일부 내용입니다. 많은 관심 부탁 드려요!강의 링크 : https://inf.run/NzKy 이번 블로그에서는 아래 DevOps를 구성하는 오픈소스들이라는 주제로 데브옵스를 설명을 드립니다. 내용의 수준은 비전공자가 데브옵스에 대한 전반적인 내용을 이해하기 좋은 정도인 점 참고 바래요.데브옵스를 구성하는 오픈소스들DevOps가 개발에서 운영까지 원할한 흐름을 만드는 건데, 중간에 가장 중요한 역할을 하는게 CI/CD죠. CI는 통합된 소스를 가지고 빌드/테스트를 자동화 시키는 기능을 만드는 거고, CD는 배포를 자동화 시키는 기능을 만드는 거예요.그래서 결국 개발을 해서 커밋을 하는 순간, 운영 환경에 App이 자동으로 배포가 되는 파이프라인이 만들어 지는데, 세부적으로 나누면 위 그림처럼 8가지 단계가 있습니다.계획/개발, 빌드/테스트, 릴리즈/배포, 그리고 운영/모니터링 인데, 이걸 각 단계를 대표적으로 사용하는 오픈소스를 가지고 얘기를 해보겠습니다.[계획] 단계부터 시작 할께요.제가 개발할 당시에는 redmine을 많이 쓰긴 했는데, 지금은 Jira나 notion을 많이 써요. 기능은 비슷한데, UI가 요즘 스타일로 많이 세련되 졌고요. 개발 일정을 공유하거나 이슈 사항들을 기록해야 되기 때문에 이런 툴을 사용하죠. 협업은 서로 메신저를 통해서 개발에 관련된 대화를 하는 걸 말하는데, 사실 카톡이나 사내 메신저를 써도 되는 부분이긴 하지만  그래도 슬렉을 쓰는 가장 큰 이유가 하나 있습니다. 그 이유는 가장 마지막에 설명 드릴께요. 다음으로 [개발]인데인텔리제이나, OpenJDK, 그리고 Spring Boot는 이전에 말씀 드렸고, 밑에 JUnit은 테스트 코드를 작성할 때 필요해요.보통 개발할때 if문 3~4개에 for문도 여러개 섞어서 복잡한 로직을 만들어 내죠. 이게 처음 만들 때는 집중해서 만들기 때문에 로직이 이해 되는데, 하루만 지나도 이 로직이 이해가 안되기 시작해요. 아무래 내가 짠 코드라도 다시 이해하는게 힘들어 지는데, 이럴때는 차라리 입력값을 넣어서 돌려보고, 결과값을 보는 게 로직을 이해하는 데 쉽거든요.그래서 바로 이런 테스트 코드를 만들어 놓는 게 좋고, 혹시라도 다른 사람이 이 로직을 수정하더라도, 테스트 코드를 돌려봐서 기대했던 값이 잘 나오면 안심을 할 수가 있죠. 그래서 코드를 개발할 때 조금만 고생해서 이렇게 테스트 코드도 같이 만들어 놓습니다. 다음으로 코드 분석 이라고 해서 FindBug나 PMD는 내가 짠 코드 패턴에 혹시 모를 버그가 있는지를 체크해줘요. 그래서 잘못된 로직을 짜지 않도록 도와주는데, 이런거 뿐만아니라 개발자간에 미리 코딩 스타일을 정해 놓거나, 개발 편의를 위해서 사용하는 툴 들은 엄청 많습니다. 다음으로 [빌드]를 볼께요.빌드 대상은 소스와 컨테이너고 Gradle과 도커가 사용됩니다. 소스 빌드로 현재 Maven보단 Gradle을 많이 쓰지만 저장소 자체는 메이븐 저장소에서 라이브러리를 가져 오는 거고요. 도커도 이전 [컨테이너 한방정리]에서 많이 얘기를 해서 이번엔 넘어 갈께요.  이제 다음으로 [테스트] 예요.테스트를 해야되는 요소에는 크게 3가지가 있는데, 기능이랑 성능 그리고 커버리지예요.각각 Junit, Jmeter, JACOCO라는 툴 들이 쓰이고. 각자 개발단계에서 테스트 코드를 만들고 실행을 해봤더라도 코드들이 병합되고 나서 또 다른 결과가 나올 수 있기 때문에, 빌드 단계에서 이 JUnit을 실행시켜서 자동으로 테스트를 한번 더 돌려 보는 거예요.그래서 위치는 이렇게 빌드에 연결되서 테스트가 같이 실행되는 거고, 테스트 이후에 Jacoco라는 툴을 돌리면 이 테스트를 돌렸을 때 사용된 로직들이, App 전체에서 어느정도 범위를 테스트 해본 건지, 커버리지를 결과를 알려줍니다.그래서 내가 돌려본 테스트 케이스들이 전체 로직에서 많은 부분을 차지할 수록, 이 App에 대한 신뢰도가 높다고 판단을 해요. 그리고 JMeter는 성능 테스트를 하는 툴 인데, 이건 자동화 기능은 아니고, 여기 개발환경이나 검증환경을 대상으로 진행 합니다. 통상 별도의 성능 테스트 전문 인력이 날잡아서 수동으로 진행하고요. 이제 다음으로 [릴리즈]와 [배포] 입니다.릴리즈는 배포 가능한 패키지를 만드는 과정이에요.도커 빌드를 하기 위해서는 Dockerfile이라는 스크립트를 작성해야 되고, 또 쿠버네티스에 배포를 하기 위해서 yaml 파일들을 사전에 만들어 놔야 되는데 이렇게 배포를 하기 위한 별도의 패키지를 만드는 게 릴리즈고, 이 파일들도 변경관리가 되야 하기 때문에 작성한 내용들을 이렇게 Github에 올려 놓습니다.그리고 배포할 때 사용을 하는데, 이 릴리즈와 이 배포 부분이 이번 Sprint2에서 다루게 될 주요 범위예요. 배포를 하기 위한 툴로는 대표적으로 kustomize와 helm 그리고 argoCD가 있고, 다 Sprint2 강의에서 배우게 됩니다. Sprint1 강의에서는 kubectl로 배포를 했지만, 이제 이런 도구들을 써서 쿠버네티스에 배포를 하게 되는 거죠. 이제 다음 단계로 [운영]입니다. 이건 실제 운영환경을 구성하는 요소와 툴 들이라고 보시면 되요. 여기서 Nginx와 Istio는 네트워크 트래픽 관리에 대한 도구고, 나머지 들은 [쿠버네티스 무겁게 설치하기]에서 나왔던 익숙한 그림일 거예요. 이외에도 운영을 구성하는 환경들은 다 표현하기 힘들 정도 많지만, 이정도로만 하고 이렇게 인프라 환경 안에서 설치되고, 운영자는 이 툴들이 정상적으로 잘 돌아가고 있는지 확인해야 하는 역할을 하죠.그리고 마지막으로 [모니터링]인데,모니터링 요소는 주로 자원 사용량이나 App로그 그리고 트래픽 흐름을 많이 봐요. Grafana 나 Loki 그리고 Prometheus는 Sprint1에서 사용을 해봤고. 이게 자원 사용량이랑 App로그를 보기 위한 툴이였죠?그리고 Jaeger랑 Zipkin은 트래픽 흐름을 보기 위한 도구예요. 이제 마이크로서비스 환경이 많아졌기 때문에 서비스들 간에 트래픽이 어떻게 흘러가는지 추적을 하는게 중요해 졌습니다. 그래서 이런 오픈소스들을 설치해야 되고위치는 운영과 똑같이 인프라 환경 내에 설치가 되요. 이 App들은 다 쿠버네티스 클러스터 위에서 Pod로 띄어 진다고 보시면 됩니다. 그럼 여기까지가 모니터링까지 다 설명을 드린거고,  아까 [Slack을 쓰는 이유]를 마지막에 말씀드린다고 했는데, 딴게 아니라 이렇게 연결되는 그림들이 있어야 되서 그래요. 이렇게 슬렉은 데브옵스에 중요 포인트 차지하고 있는 툴들이랑 연동이 할 수가 있거든요. 통상 메신저에는 개발자나, 데브옵스 엔지니어 혹은 운영자들이 모여 있는 방이 각각 있을 텐데, 슬렉을 쓰면 이 파이프라인에서 발생하는 알람들을 필요한 방에 울리도록 설정할 수가 있는거죠. 그래서 이게 협업을 위한 여러 메신저들 중에서, 그래도 슬렉을 쓰면 좋은 점 이었습니다. 자 그럼 여기까지가 데브옵스를 구성하는 오픈소스들에 대한 설명이였는데, 어떻게 데브옵스가 좀 실질적으로 와닿으시나요? 현재는 이렇게 데브옵스가 복잡해 졌습니다. 그래서 기업에서는 데브옵스 엔지니어를 별도로 뽑을 수 밖에 없는 거고요. 뭔가 많아 보이지만, 그래도 차근차근 하나씩 구성하다 보면 생각보다 금방 파이프라인이 만들어 지기도하고 여기 있는걸 한번에 다 만들 필요는 없어요. 배포를 한다고 처음부터 helm이나 argoCD를 적용할 필요는 없는 거고 Kubectl 배포부터 일단 연결을 해 놓은 다음에 하나씩 장비를 업그레이드 하는 마음으로 바꿔 나가면 되거든요.이번 강의도 그런 스탭으로 구성을 했으니까, 끝까지 잘 따라오시길 바라고요!아래 내용들은 강의에서 자세히 설명 드릴 내용들입니다. 쿠버네티스 어나더클래스 DevOps 전체 구성도 DevOps에서 가장 중요한 것 (개발->빌드->실행파일) DevOps에 엮인 IT 직군들 DevOps 외 다른 Ops들 ps. ♡ make me want to be a better man :)

데브옵스 · 인프라쿠버네티스어나더클래스지상편Sprint2일프로kubernetes데브옵스devops오픈소스

일프로

[쿠어클#15] 가상화 한방 정리

 [쿠버네티스 어나더 클래스] Sprint3의 첫 번째 강의 주제는 가상화 한방정리 입니다. 그동안 컨테이너 한방정리와 데브옵스 한방정리가 있었고, 이번이 3번째네요. 😀 먼저, 해당 강의 내용에 대한 소개를 드리면, 가상화가 나온지는 오래되긴 했는데, 컨테이너나 데브옵스 처럼, IT를 하는 사람들이라면 누구나 알아야되는 분야가 아니긴 해요. 게다가 로우레벨의 기술이라 재미도 없고, 또 어렵고요. 이걸 안다고 해도 이 분야에서 전문적으로 일을 하는 사람이 아니고서야 크게 메리트가 없습니다. 그냥 VirtualBox나 다른 가상화 도구들을 잘 쓰기만 해도 충분한데, 그만큼 가상화가 많이 발전하고 추상화 되버린 거죠.그래서 이 세션에서는 가상화 한방정리이지만 가상화 기술만을 중점적으로 다루지는 않습니다. 가상화보다 더 큰 개념들을 보면서 가상화에 대한 포지션을 알려드리고, 이후 본격적으로 가상화에 대한 설명을 드릴텐데, 쿠버네티스와 관련된 가상화에 대한 얘기를 할 거에요. 그리고 이번 블로그에서는 누구나 알고 있는 가상화 기술 비교와 쿠버네티에서 가장 어려운 리소스에 대한 얘기를 해보겠습니다.누구나 알고 있는 가상화 기술 비교VM 가상화 부터 설명드리면, 이렇게 호스트 가상화와 하이버파이저 가상화가 있고. 호스트 가상화가 물리 서버에 Host OS로 운영체제가 있고, 그 위에 여러 종류에 하이퍼바이저가 있어서VM을 만드는 방식입니다. 그리고 사용자가 원하는 Guest OS를 설치하게 되는데, 이 호스트 가상화는 자신이 주로 쓰는 운영체제가 있고, 그 외에 보조 적인 운영체제가 일시적으로 필요할 때 많이 쓰는 방식이고요.하이퍼바이저 가상화는 물리 서버위에 바로 하이퍼바이저가 있어서 Host OS 없이 VM이 만들어 지는 구조 에요. 마찬가지로 사용자가 원하는 Guest OS를 설치하지만, Host OS가 없기 때문에 이 호스트 가상화보다 성능이 더 좋다고 볼 수가 있습니다. 하지만 VM을 생성하고 관리하는데 어려울 수는 있는데, 이 Guest OS가 특정 App이나 사용자에 대한 메인 운영체제로 쓰이는 통상 데이터 센터에서 주로 사용을 해요.데이터 센터에는 보안상 외부와 차단된 네트워크 망이 구성되고, 내부 서버들 끼리만 통신이 되는데, 그렇다고 개발 업무도 이 데이터 센터에서 할 수는 없고요. 외부에서 접근을 하려면 VDI라고 해서 외부 사용자에 대한 인증을 거쳐서, 이 사용자 세션에 대해서만 VM에 접속해서 작업을 할 수 있게 해줍니다. 그리고 단순 원격 접속이기 때문에 이 VM으로 부터 내 PC로 데이터를 가져오지도 못하고요.그래서 이렇게 데이터센터가 있는 기업들은 자사의 데이터를 보호하기 위한 솔루션을 적용하는데, 그런 솔루션이 알아서 하이퍼바이저 가상화로 VM들도 관리를 해주기 때문에 어려울 부분은 없습니다.그래서 VM 가상화에는 대표적으로 이 두 가지가 있지만, 현재 대중적으로 크게 관심을 끌 만한 기술이 아니고요. 요즘은 쿠버네티스가 대두 되면서 VM과 컨테이너 가상화에 대한 비교를 많이 하죠.구성을 보면,  호스트 가상화랑 마찬가지로 Host OS 위에 하이퍼바이저와 같은 역할을 하는 컨테이너 런타임이 있고요.그래서 컨테이너를 만들어 주는 구조까지는 똑같은데, 그 내용을 보면 이 VM에는 GuestOS도 있고, 패키지들(Bins/Libs)도 App 뿐만아니라 OS에 관련된 모든 패키지들이 있는 데 반해, 컨테이너에는 GuestOS도 없고 이 App에 필요한 패키지들이 포함이 되는 구조예요. 그래서 결국 VM은 사이즈도 크고 GuestOS를 위한 추가 리소스가 더 필요합니다. 컨테이너의 경우 이 컨테이너가 HostOS의 커널을 공유하기 때문에 이렇게 App이랑 최소한의 추가 패키지들만 가지고 동작 시킬 수 있는 거고요. 이에 따른 장점은 명확합니다. 사이즈가 작아지기 때문에 다운받기도 빨라지는 등 이동적인 면에서 편리하고요. VM에는 GuestOS 기동시간이 있는데 비해서, 컨테이너는 App만 기동하면 되기 때문에 상대적으로 시작과 종료가 빨라집니다.  그래서 결국 자연스럽게 자원 사용에 대한 효율도 높아지게 되는 거죠.그리고 이런 컨테이너를 만들어주는 컨테이너 런타임에 대해서 말씀드리면, 이전 컨테이너 한방정리때 설명드렸던 내용인데, 컨테이너 런타임에는 High 레벨로는 도커나 컨테어너디 그리고 cir-o가 있고, 모두 Low Level인 runC를 사용하는 구조예요. 그리고 이 runC가 OCI라고해서 표준 규격의 컨테이너를 만들어 주기 때문에, 다른 런타임에서도 이런 표준 규격으로 컨테이너를 만든다면 서로 컨테이너를 공유해서 사용할 수가 있어요. 그 방법으로 리눅스 커널에는 이런 기술들이 있고요. 간략하게 이 기술들에 대해서 설명드리면, chroot는 각 프로세스 별로 루트 디렉토리를 할당해 줘서 서로 파일을 분리시키는 거고요. namespace는 HostOS의 시스템들을 프로세스 별로 각각 분리해서 만들어 주는데, 시스템 종류에는 마운팅이라던지 프로세스 id나 유저 등 여러가지가 있습니다. 이런걸 프로세스 별로 각각 할당해 주는거예요.마지막으로 cgroup은 프로세스 별로 HostOS에 리소스를 분리해서 할당해주는 기술이고요. 이 리소스에는 우리가 흔히 아는 메모리나 cpu, 네트워크 들이 있는거죠.그래서 한 프로세스에는 이렇게 디렉토리나 시스템, 그리고 리소스가 할당이 되서 독립적으로 관리가 되는데 이걸 우리는 컨테이너라고 부르는 겁니다.다음으로 쿠버네티스에서 가장 어려운 리소스에 대해서 말씀을 드려 볼게요. 쿠버네티스에서 가장 어려운 리소스바로 아래 세 가지 리소스 입니다.다른 리소스들도 많지만, 이 세 가지 리소스만 제대로 알면, 다른 리소스들은 결국 이 리소스스들 위한 보조 기능이라고 말할 수 있고요. 만약 처음 쿠버네티스 리소스를 만든다면 이 세가지를 확실히 한 다음에 다음 리소스들에 대한 세팅을 마춰 나가시면 됩니다.그만큼 중요한 리소스고요. 앞으로 Sprint3 전체 강의에서 이 리소스들을 상세하게 배워나갈 꺼지만, 여기서는 이 세 가지가 정말 중요할 수 밖에 없는 이유와 또 복잡할 수 밖에 없는 이유 대해서 말씀을 드릴께요.물리 서버들이 있고, 이 서버들은 게이트웨이에 연결이 되서 사내 네트워크 망이 만들어져요. 그리고 이 게이트웨이에 라우터를 붙이면, 기업 외부 인터넷으로 나가거나 외부 사용자들이 내 서비스에 들어 올 수 있게 되요. 그리고 그 서비스에 대한 데이터를 안전하게 보관하기 위해서 이 서버에 스토리지도 붙여 놔야 됩니다.그래서 이렇게 이전부터 이 서버와 네트워크 그리고 스토리지는 App을 서비스 하기 위한 기본 구성이었던 거죠. 이 부분을 편하게 갈려면 클라우드 서비스를 쓰는 거고요.이 물리적인 구성들이 쿠버네티스에서는  Pod와 Service 그리고 PV로 대신 사용하는 거기 때문에 이 세가지 리소스가 가장 중요하다고 말씀을 드리는 거예요.그리고 이제 이 세가지가 또 복잡할 수 밖에 없는 이유에 대해서 말씀을 드리면,물리 서버의 경우, 서버실에 서버가 많아 질 수록 서버실 공간도 커져야 되고, 그럼 전기세도 많이 들어요. 그래서 고 사양의 서버 한 대를 설치하고 위와 같이 가상화를 시켜서 쓰는 게 비용적으로 더 효율적입니다. 그렇기 때문에 쿠버네티스도 결국 이 가상화된 VM위에 올라가지게 되요. 그리고 이제 내부로 들어가서 Pod를 보면, 먼저 CRI라고 해서 컨테이너 런타임 인터페이스로 이런 제품들을 설치할 수가 있고요. 그럼 이 런타임들이 컨테이너를 만들어 주고, 이 컨테이너가 바로 하나의 App이 되는 셈인데, 쿠버네티스는 Pod라는 개념안에 이 컨테이너가 들어 있기 때문에 결국 App을 대표하는게 Pod가 되는거죠.그래서 이전에 VM위에 App을 띄었던 게 Pod라는 엄청 추상화된 리소스에 들어가게 되고요.App으로 사용자의 트래픽이 들어와야 되고요. App에서 만들어지는 데이터도 어딘가에 저장을 해야되야 되는데, 쿠버네티스에서는 그걸 하기 위한 리소스로 Service와 PV가 있는 겁니다.다음으로 Service를 보면, 쿠버네티스에서는 CNI라고해서 컨테이너 네트워크 인터페이스로 여러가지 제품들이 있어요. 저희는 여기서 칼리코를 설치했던 거고요. 이게 오버레이 네트워크라고해서 컨테이너들 간에 통신을 할 수 있게 해줘요.그리고 이 네트워크가 내 운영체제 위에 있는 IPTables랑 연결이 되서 실제 물리적인 서버로 가야 되는데, 그 사이 구간에 또 가상화된 네트워크가 있습니다. 저희는 쿠버네티스를 설치할 때 가상화 도구로 Virtualbox를 썼고요. 여기서 제공해주는 네트워크를 사용했었어요.그래서 이렇게 이 가상화 구간에 대한 네트워크 방식이 있고. 또 이 실제 물리 구성단에 네트워크 방식도 다양하기 때문에 네트워크는 알면 알 수록 어려운 분야지만 그래도 이 그림 정도는 알아야 Service에서 제공하는 타입들에 대해서 이해를 할 수 있게 됩니다.ClusterIP는 컨테이너 간의 네트워크고요. NodePort는 이 VM의 네트워크를 말해요. 그리고 LoadBlancer는 클라우드 서비스 상에서의 네트워크고요. 그리고 이 ExternalName는 DNS 서버와 관련이 있거든요.쿠버네티스를 설치하면 CoreDNS라는 서버도 같이 구성이 되는데, 이 CoreDNS가 서비스가 새로 만들어지면 이름이랑 IP 주소를 자동으로 등록해 놓기 때문에 우리는 특정 Pod에서 Service에 이름으로만 호출을 해도 CoreDNS로 부터 실제 IP를 받아서 원하는 Service로 트래픽을 전달 할 수 있게 됩니다.그리고 회사 내에도 쿠버네티스가 아닌 기존에 VM들을 도메인으로 호출하기 위한 사내 DNS서버가 있을 수 있거든요. 만약 컨테이너 안에서 도메인 명으로 VM에 있는 서비스를 호출하고 싶으면, 이렇게 CoreDNS서버에 이 사내 DNS서버를 업스트림 서버로 설정해 놓으면 됩니다. 결론적으로 Service는 이 네트워크 구성들을 알아야, 더 잘 쓸 수가 있다는 거죠.글고 이제 마지막으로 PV를 보면,PV를 잘 다루려면 이 스토리지에는 여러 종류의 스토리지들이 있다는 걸 알아야 되요. 쿠버네티스에서는 PV로 제공되는 옵션을 보면 ReadWriteMany는 파일 스토리지를 가리키고, ReadWriteOnce는 블록 스토리지를 주로 의미하거든요.그리고 쿠버네티스에서는 CSI라고 해서 Pod 에서 실제 스토리지로 까지 연결 해주기 위한 여러 솔루션들이 있고요. 그래서 이걸 내용들을 잘 알아야. 내가 저장하려는 데이터가 어떤 종류인지에 따라 그에 맞는 스토리지를 결정하고, 또 그걸 지원해주는 솔루션을 절 선택할 수가 있는 거죠. 그래서 여기까지 쿠버네티스에서 가장 어려운 리소스에 대해서 말씀을 드렸는데, 이제 좀 이 세가지 리소스가 Sprint1에서 배웠던 리소스 들중에서 무게감이 좀 다를 거 같다는 느낌이 드시나요?그럼 이번 블로그는  여기까지고요, 해당 강의에서는 아래 내용들에 대해서 더 다룹니다 😀[쿠버네티스 어나더 클래스] : https://inf.run/unreTIT에는 어떤 직군들이 있을까? 한번쯤 알고 넘어가면 좋을 서비스 모델 아무나 모르는 컨테이너 기술의 장점쿠버네티스에 대한 단점ps. 블로그 내용이 도움이 되셨다면 좋아요♡ 부탁 드립니다 :)

데브옵스 · 인프라쿠버네티스어나더클래스지상편Sprint3일프로데브옵스가상화한방정리

일프로

[쿠어클#13] Helm과 Kustomize 비교하며 사용하기 (2/2)

Sprint2 추가 강의가 업로드 됐어요!  Helm과 Kustomize 비교하며 사용하기 두 번째 시간입니다. 이번 시간에는 Kustomize 패키지 구조를 설명을 드릴 거예요.먼저 최초 패키지를 만드는 방법을 보면, Helm 패키지는 이렇게 helm create 명령을 날리면 이런 구조의 패키지가 자동으로 만들어졌는데, Kustomize는 직접 폴더를 만들어야 되고요. 그리고 이 폴더 밑에  이렇게 하위 폴더 구성도 직접 만들어야 되요.어려운 구조는 아니지만 그래도 사전에 Kustomize의 구성이 이렇다라는 건 미리 알고 있어야 되는 거죠. (물론 Kustomize 가이드에 잘 나와 있어요) 그리고 아래와 같이 각 폴더 밑에 내가 배포할 yaml 파일들도 만들어 줍니다.좀 수동으로 만들어야 할 부분이 많긴 한데, Helm은 알고 있어야 되는 파일들이 많았던 거 에 비해서 Kustomize는 파일 구조가 간단해 보이죠? 이 폴더 구조랑 이 kustomization 파일에 기능만 알면 다 예요.그래서 하나씩 보면, 메인 폴더가 있고 밑에 base는 Default 포맷이 될 yaml 파일들을 넣는 폴더입니다. 기존부터 kubectl로 배포하던 deployment yaml 파일을 그대로 여기에 넣으면, 이게 베이스 yaml 파일이 되는 거예요. 이런 식으로 밑에 배포할 파일들을 다 넣으면 되요.그리고 Kustomization.yaml이 제일 중요한 파일 입니다. 리소스 yaml 파일들 중에서 어떤 파일을 배포할 건지 선택하는 내용이 있고, 또 그 yaml 파일들에서 반복적으로 사용하는 속성들을 공통값을 설정할 수 있어요. 먼저 어떤 파일을 배포할 건지 선택하는 방법은helm의 경우, hpa.yaml 파일 내부에 이렇게 if문이 있고, values.yaml 파일에서 이렇게 false를 하면 이 hpa가 배포가 안됐고요. kustomize는 이 Kustomization 파일에 [resouce] 키가 있어서 내가 배포할 파일들만 명시적으로 정할 수 있어요.이게 배포할 파일을 선택하는데 있어서 두 패키지 매니저에 대한 차이 입니다.그리고 공통값 설정에 대한 차이는Helm은 Deployment 템플릿 내에 변수를 넣는 부분이 있고, 여러 파일들(_helpers.tpl, Chart.yaml, values.yaml)에서 변수를 주입하는 방식이 다양했었죠?반면 kustomize는 Deployment에는 특별한 내용이 없고, Kustomization.yaml 파일에 명시적으로 coommonLabels라는 키가 있어서 여기에 내용을 넣으면, 배포될 모든 yaml 파일에 label로 그 내용이 들어가 집니다.마지막으로 환경별로 배포할 때 기본값 들을 어떻게 주는지 말씀 드릴게요.kustomize는 overlays 폴더 밑에 환경별로 폴더를 만들고, 해당 폴더마다 그 환경에 맞는 yaml 파일들을 넣어 놓습니다.그리고 여기에도 마찬가지로  Kustomization.yaml 파일이 있는데, 하는 역할은 같아요.각 환경별 파일에 있는 yaml 파일들에 대해서 배포할 파일을 지정하고 공통값을 설정할 수가 있습니다. 그래서 개발 환경을 배포 하려면 [kubectl apply -k ./app/overlays/dev] 처럼, 배포 명령에 해당 환경별 폴더 경로를 주면 되고요. 반면 Helm의 경우, values.yaml 파일을 각각의 환경별로 추가하고, 배포할 때 -f 옵션으로 이 원하는 환경의 values-dev.yaml 파일을 선택하면 됩니다. 헬름은 변수를 가져다 쓰는 방법이 다양했는데, 또 한 가지가 더 늘었죠? 그래도 다 사용해야 되는 상황이 있고, 실습을 하면서 자세하게 설명을 드릴게요. 그럼 이번 블로그는  여기까지고요, 해당 강의에서는 실습과 더불어 추가적으로 아래 내용들에 대해서 더 다룹니다 😀[쿠버네티스 어나더 클래스] : https://inf.run/unreT  배포 파이프라인 구축 후 마주하게 되는 고민들ps. 매너가 좋아요♡를 만든다 :) 

데브옵스 · 인프라쿠버네티스어나더클래스지상편Sprint2일프로데브옵스HelmKustomizeJenkins

일프로

[쿠버네티스 어나더클래스] 배포를 시작하기 전에 반드시 알아야 할 것들 #10

Sprint2 추가 강의가 업로드 됐어요! (https://inf.run/NzKy)이번 강의에서는 배포를 하기전에 반드시 알아야 될 것들 이라는 주제로 설명을 드릴 건데, 배포에 관련된 툴 공부를 바로 시작하는 것보단, 어떤 걸 써야 되는지, 왜 써야 되는지를 아는 게 더 중요하다고 생각해서 준비한 강의 입니다.저는 예전에 최신 솔루션을 많이 알고, 신규 업데이트 된 기능을 빨리 쓰는 사람이 능력 있어 보였고, 저도 그렇게 되고 싶었는데 여러 프로젝트를 해보니 프로젝트 상황에 따라 적합한 기술을 쓰는 게 더 중요하더라고요. 신규 기술이라고 빨리 도입했다가 레퍼런스가 별로 없어서 프로젝트 내내 구글링하고 이슈 수정 요청을 하느라 고생했던 적도 있고, 원대한 포부를 가지고 한번에 많은 툴 들을 적용 하려고 했다가, 운영이 시작되면서 예상하지 못한 문제 때문에 장애처리에 시달리는 경험도 해보면서 진취적인 성향에서 일을 단계적으로 하려는 성향으로 바꼈는데, 결국 이렇게 일을 하는 게 월급을 높이는데도 효과가 더 좋았다고 말씀드릴 수 있습니다.부디 적재적소에 맞는 도구를 사용할 줄 아는 사람이 되길 바라면서 이번 블로그도 시작해 볼께요. CI/CD 파이프라인을 구성할 때 고려해야 하는 요소첫번째로, 파이프라인을 구성 할 때 [관리 담당]에 대한 부분을 고려해야 합니다.이 그림상으로만 보면 굳이 작업을 분리할 필요가 없이 젠킨스 파이프라인을 쓰는게 깔끔해 보이죠? 수정할 일이 생겼을 때, 세 군데 들어가서 보는 것보다 한 곳에서 보는 게 편하기도 하고요. 그래서 일반적으로는 젠킨스 파이프 라인을 선택하는 게 기능적으로는 좋다고 볼 수 있습니다.근데, 실무에서 일하다 보면 기능적인 구분 보다 보다 담당하는 사람에 따라 구성을 분리를 하는 게 좋을 때도 많아요. 각각 역할을 구성하는 관리 담당자가 다를 수가 있거든요. 실제 프로젝트에서는 기능이 만들어져 있고, 그에 따라 담당자를 정하는 게 아니고, 담당자가 먼저 정해지고, 함께 기능을 만들어가기 때문에 그래요.그리고 내가 이런 큰 그림을 그리는 위치라면, 기능보다 이렇게 관리 담당자 별로 구성을 나누는 게 업무 분장 측면이나 관리 책임적으로 더 효율적입니다.그래서 배포 파이프라인을 구성할 때, 기능적인 측면과 관리적인 측면을 고려해서 현재 뭘 중시하는 게 효율적인 지를 고민해 볼 필요가 있는 요소에요. 다음으로 [운영정책]인데, 젠킨스에서는 소스 빌드랑 컨테이너 빌드만 하고요.  ArgoCD라는 쿠버네티스 전용 배포툴을 이용하면 각각에 쿠버네티스 환경에 배포를 할 수 가 있어요. 그럼 이때 이 배포 툴들은 이제 젠킨스가 아닌 argoCD를 통해서 사용 되는 겁니다. 그리고 밑에 아래 그림 처럼 배포 영역을 빌드와 구분해서도 많이 쓰기도 해요. 근데 여기서 제가 얘기 하려는 부분은 배포와 인프라 환경의 관계를 이렇게 1대 다로 구성할 수도 있고, 이렇게 각 환경마다 ArgoCD를 둬서 1대 1로 구축 할 수도 있다는 거죠. (후자 방식을 더 많이 쓰긴 하지만)이런 구성에 장단점은 명확 합니다. 위 구성은 ArgoCD를 이중 관리 해야되는 부담감은 있지만, 개발환경에서 뭘 하던 장애가 나도 운영환경에는 영향이 없죠. 반대로 아래 구성은 하나만 관리해서 편의성은 좋은데, 개발 환경 때문에 장애가 나면, 운영환경도 배포를 못하는 거고요. 지금은 배포와 argoCD를 가지고 말씀 드리는 거지만, 이런 구조적인 상황에 따른 장단점은 IT 전반에서 시스템을 설계를 할 때 흔히 볼 수 있는 상황이예요.그럼 이때, 그래도 실무에서는 운영환경에 영향도가 중요할 텐데, 관리가 불편하더라도 당연히 이 방식을 선택해야 하지 않을까?라고 생각 할 수 있을 것 같아요. 근데 이건 정말 회사마다 운영 방침에 따라 관리 편의를 중시할 꺼냐, 장애 영향도를 중시할 꺼냐에 따라 다릅니다. 하지만 관리 편의를 중시한다는 게 장애가 나도 된다는 말은 아니고, 이 배포 부분이나 CI/CD 전체 서버가 죽더라도, 새로운 배포를 못할 뿐이지, 현재 돌아가고 있는 서비스에 문제가 되는거 아니잖아요? 그래서 좀 유연한 운영 정책을 가지고 있는 곳에서는 이렇게 서비스에 지장이 없는 경우라면, 이렇게 중앙 구성을 하고, 심지어 이 구성에 이중화를 안 시키기도 해요. 왜냐면 그만큼 안전을 중시하기 위해 들어가는 비용도 만만치가 않거든요.그래서 배포를 단일 구성으로 갈지, 분리 구성으로 갈지에 대한 고민도 필요하다는 말씀을 드립니다. 다음으로 [제품 선정]이에요.온라인 용 CI/CD 툴로는 GitHub Actions가 있고, 오프라인 용으로는 Jenkins랑, jenkinsX, 그리고 TEKTON이란 게 있어요. 온라인은 인터넷 환경에 연결해서 쓰기 때문에,  당연히  CI/CD 서버를 별도로 만들 필요가 없다는 장점이 있죠.그리고 오프라인으로 JenkinsX는 젠킨스에서 컨테이너 환경에 맞춰서 새롭게 만든거고, Tekton 역시 컨테이너 환경에 최적화된 CI/CD를 목적으로 만들어진 도구이에요. 그럼 이제 여기서 CI/CD 제품을 선정할 때, 큰 기준이 되는 게 온라인이랑 오프라인인데 대체로 Github와 같은 글로벌한 제품들은 보안이 잘 되기 때문에, 기업에서 인터넷 환경에 접속해서 쓴다고 문제 될 건 없어요. 기업이라고 해서 무조건 내부에 서버실을 만들어서 내 서비스를 운영할 필요는 없다는 거죠. 지금은 클라우드 서비스에 내 시스템을 다 올려서 많이들 쓰고 있으니까 잘 공감이 되리라 생각 됩니다.근데 그럼에도 불구하고 자사에 시스템이 인터넷 상에 있으면 안되는 기업도 많아요.  금융권 내지는 의료기관이나 공공기관들이 대표적이고, 그 밖에도 많은데 정확히는 시스템에 대한 제한이 아니라, 그 시스템이 다루는 데이터가 중요하기 때문에 인터넷 영역으로 올리면 안되는 거죠.이 CI/CD 서버 역시 개발 소스나 릴리즈 파일들에서 중요한 정보들이 많거든요. 그래서 이럴 때는 오프라인 툴을 쓸 수 밖에 없는거고 추가적으로 CI 전용 Tool에는 이런게 있고, CD 전용 툴로 이렇게 ArgoCD랑 Spinnaker라는 툴도 있어요. 다 컨테이너 환경에 최적화 된 툴 들인데 이렇게 오프라인을 써야 한다고 하더라도  비슷한 기능에 툴 들이 참 많죠.이전 에도 말씀드렸지만, 이럴 땐 레퍼런스가  많이 쓰는 걸 선택하는 게 가장 후회가 적습니다. 이렇게 제품 선정에 있어서, 데이터 보안 상황에 따른 온라인과 오프라인 제품의 선택 그리고 레퍼런스가 많은 제품 인지를 보는 게 좋은데 한 가지 더 추가를 하면,제품을 도입하고, 계속 유지보수로 계약할 수 있는 업체가 있냐 없냐의 유무도 중요합니다. 이건 레퍼런스를 떠나서, 어차피 회사 내부에 해당 제품을 직접 다루는 사람이 없거나, 아니면 유지보수 인원에 비해서 엄청 많은 제품들을 사용하고 있는 상태인 회사에서 한번 설치한 이후에 잦은 관리가 필요 없는 제품일 경우, 최소한에 유지보수 비용만 들여서 필요할 때 해당 제품에 전문가를 부르는 게 나으니까요.그리고 다음으로 도커 대체가 있습니다. 이게 뭐냐면, 컨테이너 빌드를 할 때, 도커말고 다른 제품을 쓰려고 하는 이유가 있어요. 처음 도커가 나오고 대중적인 인기를 끌다 보니, 안 좋은 점도 많이 부각됐죠. 물론 단점은 꾸준히 보완 돼 왔고, 여전히 편하게 쓰고 있긴 하지만 그래도 개선되기 힘든 두 가지를 말씀드리면 "Docker가 무겁다는거"랑, "Daemon이 필요하다는 거"예요. 도커가 기능이 많기 때문에 새로 만들지 않는 이상 가벼워지기 힘든 부분이고, 그러다보니 자원을 많이 사용하긴 해요.  근데 다행이도 빌드 속도가 느리다는 건 아닙니다. 오해하시면 안되고 또 하나가, 도커 Daemon이 항상 띄어져 있어야지, 컨테이너가 돌아간다는 거예요.이 Daemon이라는 게 리눅스에 백그라운드로 항상 돌아가고 있어야지, 실행 가능한 제품이라는 거예요. 우리가 kubectl을 쓸 때는, 별도로 kubectl을 띄어 놓지 놓지 않아도 그냥 명령어를 칠 때만 실행하고 쓰고 끝나잖아요? 이런건 daemon-less app 이라고 말하고, 반면에 도커는 daemon이 필요한 app 이라는 거죠.그래서 도커로 컨테이너를 여러게 띄었는데, 도커 데몬이 죽으면 모든 컨테이너가 같이 다운됩니다. 좀 치명적인 단점이긴 한데, 근데 이건 도커를 CI/CD 빌드용으로 고민할 땐 그리 문제 되진 않아요. 빌드할 때 도커가 내려가져 있으면, 올리고 빌드하면 되는거고, ci/cd 서버에 컨테이너를 띄어 놓을 일은 없기 때문에 도커가 갑자기 죽는 상황에 대한 문제는 없습니다. 그래서 저는 그래도 도커를 아직 까진 선호하는 입장이지만, 자원 활용에 중시 한다면, 혹은 상황에 따라 다른 솔루션 들을 쓰게 될 수도 있는 거고요. 그럼 이 상태에서, 컨테이너 빌드로 빌다라는게 있습니다. 근데 이걸 쓸 경우, 함께 써야하는 친구들이 있어요. 각각에 역할을 보면, 먼저 podman을 이용해서 도커 로그인을 하고, 이미지를 가져오는 기능이 있어서 openjdk 같은 베이스이미지를 가져 옵니다. 그리고 buildah로 컨테이너 빌드하고, 이미지가 만들어지면, skepo가 이미지 푸시 기능이 있어서, 도커 허브로 이미지를 업로드 해요. 그리고 앞에서 처럼 argoCD를 통해서 쿠버네티스 배포가 되는 구성 되고요.좀 복잡해 보이긴 하지만,  도커보다 자원 사용률은 낮고요.  또 이 자원 사용률을 무시할 순 없는 게, 젠킨스에서 소스빌드랑 컨테이너 빌드가 갑자기 많아 졌을 때 가끔씩 도커빌드를 하다가 메모리가 부족하다는 에러를 낼 때도 있거든요. 그리고 buildah는 백그라운드 실행이 필요 없는, Daemon-less App 입니다. 그래서 이젠 컨테이너 빌드에 대한 선택의 폭이 생겼고, 추가적으로 하나 더 말씀드리면, 쿠버네티스 위에서만 돌아가는 제품도 있어요. Kaniko라고 해서 컨테이너 환경에서 돌아가도록 만들어 졌는데, 이건 다행이 하나만 있으면 되니까 도커 대체로 시도해 볼 만 하겠죠? 이 후 내용은 해당 강의에서 추가적으로 다루는 내용들입니다. 배포 전략을 세울 때 고려해야 하는 요소단계별로 구축해보는 배포 파이프라인 ps. 뒤로가기 함부로 누르지마라. 너는 누구에게 한 번이라도 좋아요♡를 준 사람이었느냐 :)

데브옵스 · 인프라쿠버네티스어나더클래스지상편Sprint2일프로데브옵스인프런kubeops

일프로

[쿠어클#14] ArgoCD 빠르게 레벨업 하기

Sprint2 추가 강의가 업로드 됐어요! 이번 수업에서는 ArgoCD의 아키텍처에 대해서 설명을 드리겠습니다.먼저 Argo 제품들에 대한 설명부터 드릴게요.ArgoCD는 쿠버네티스 전용 배포 툴이고, 릴리즈 파일 저장소로 Git을 반드시 필요로 해요. 그래서 ArgoCD를 쓰려면 쿠버네티스는 당연한 거고, 변경관리 저장소가 꼭 Git이어야 합니다.이전에 제가 했던 프로젝트에서는 형상관리를 SVN으로 썼거든요. SI 프로젝트에서는 개발량이 많기 때문에, 그 많은 기능들이 오픈 때까지 일단 다 돌아가는 게 하는 게 중요하지. 상대방의 코드를 리뷰 할 시간이 별로 없어요. 그래서 Git을 사용하는 문화를 정착 시키기 보다 최소한의 기능으로 누구나 빨리 익히고 쓸 수 있는 SVN을 더 선호하게 됩니다. 근데 그러면 ArgoCD는 사용할 수가 없는 거죠.다음으로 ImageUpdater는 ArgoCD의 추가 기능이에요. 이걸 사용하면 도커 허브에서 컨테이너 이미지에 대한 변경을 감지해서 배포를 할 수 있는 파이프라인을 만들 수 있습니다.그리고 BlueGreen과 Canary와 같은 고급 배포를 지원해주는 Rollouts가 있고요.다음으로 Events는 카프카와 같은 역할을 하는 솔루션이라고 보시면 되요. 통상 카프카를 이용해서 이벤트 버스 구조의 아키텍쳐를 만드는데, 이벤트 버스에 대해서는 여기서 설명을 드리기엔 큰 주제라 한번 검색을 해보시길 바라고요.  아시는 분들은 argo에서도 그런 역할을 해주는 제품이 있다고 보면 됩니다. 그리고 Workflow는 airflow나 kubeflow와 같은 역할을 하는 워크플로우 매니지먼트 도구고요. 역시 잘 모르시는 분은 추가적인 검색을 해보시면 좋은데, 결국 Argo 제품만을 가지고 아래와 같은 아키텍처가 만들어 질 수 있어요.Argo Events는 시스템들간에 이벤트를 주고 받는 메인 통로 역할을 해주고요. 이 중에 Workflow로 보내지는 이벤트가 있을 수 있고, workflow 안에는 받은 이벤트에 내부 값에 따라서 어떤 작업을 실행하라는 순서도가 있는거죠.  그래서 그 워크 플로우에 결과에 따라서 작업이 실행 되는데, 그 중에 배포를 하라는 작업이 있을 수 있고, 그럼 CD가 실행이 되요. 그리고 Rollous를 통해서 특정 배포 전략으로 쿠버네티스에 자원을 생성 시켜 주는거죠.그럼 이 제품들의 쓰임에 대해서 대략적인 맥락이 보이나요? 이제 ArgoCD가 쿠버네티스에 설치됐을 때 아키텍쳐에 대해서 설명을 드릴게요.먼저 쿠버네티스 컴포넌트들은 아래와 같이 구성돼 있고요.우리는 30000번 포트를 통해서 UI에 접근하거나, Kubectl로 CLI를 날렸었죠? 그럼 kube-apiserver가 API를 받아서 관련된 컴포넌트들 한테 트래픽을 전달을 해주는 구조였는데, 이런 구조는 다른 솔루션들도 비슷합니다. 먼저 이 Server는 API Server 와 Dashboard 역할을 동시에 합니다. 그래서 nodeport로 ArgoCD UI에 접속을 할 수 있고 kubectl처럼 argocd 라는 툴을 설치해서 CLI를 날릴 수도 있어요. 다음으로 Github가 있고, 여기에 내 App에 대해서 배포할 yaml 파일이 있다고 해볼게요. 그럼 Repo Server는 Git에 연결해서 yaml 파일을 가져오고 그걸로 ArgoCD에 배포할 yaml 매니패스트를 만들어 놓는 역할을 해요.그리고 Applicaiton Controller는 쿠버네티스에 리소스를 모니터링 하면서 이 Git에서 받은 내용과 다른 게 있는지 비교를 해주고요. 그래서 내용이 다르면, Git에 있는 내용으로 배포가 진행됩니다. 그리고 Kube API가 쿠버네티스로 리소스 생성 명령을 날려주는 역할을 하고요. 그리고 Notification은 ArgoCD에서 발생하는 이벤트를 외부로 트리거 해주는 역할을 담당해요. 그리고 Dex는 외부 인증관리를 하는 역할인데, 쿠버네티스를 하다보면 Grafana 나 이외에도 다양한 Dashobard들을 많이 쓰게 되거든요. 근데 관리자 입장에서 그 UI마다 ID/Password를 만들고 관리하기가 참 번거롭죠. 그래서 흔히 IAM 솔루션을 사용하는데, 그럼 사용자가 여기에다가만 로그인을 하면 이 IAM솔루션이랑 연결된 시스템에는 별도로 로그인을 안해도 자동 로그인이 되는 거죠. 흔히 SSO라고 하고요. 쿠버네티스에서는 대표적으로 KeyCloak이 있어요.Redis는 아시는 분은 잘 아시겠지만, 메모리 DB에요. 통상 시스템에서 캐시역할을 많이 하는 데, ArgoCD에서는 여기 Github와 연동되는 구간이랑 kube-apiserver랑 연동되는 구간에 캐시로 쓰여서. 불필요한 통신을 줄여주는 기능을 합니다. 그리고 마지막으로는 ApplicationSet Controller는 멀티 클러스터를 위한 App 패키징 관리 역할인데, 이게 뭐냐면  ArgoCD는 이렇게 클러스터마다 설치를 할 수도 있지만 이렇게 하나만 설치해서 여러 클러스터로 App을 배포할 수도 있다고 했잖아요? 그럼 배포 환경마다 ArgoCD에서 배포 구성을 만들어 줘야 하는데, 그럼 또 중복되는 구성들이 생기기 때문에, ApplicationSet Controller가 환경별로 다른 부분만 세팅해서 사용할 수 있는 템플릿을 제공해 줘요. 마치 Helm이랑 Kustomize에서 했던 것 처럼요.그래서 여기까지가 ArgoCD 아키텍쳐에 대한 설명을 드린거고, 처음 한번 정도는 이런 전체적인 구성들을 이해하면 좋은 게내가 ArgoCD에 기능에 일부만 쓰고 있더라도, 내가 알지만 안 쓰는 거지 기능을 몰라서 안 쓰는 건 아니라는 안심이 생겨요!이제 Argo App들을 어떻게 설치하는 보면,이 강의에서는 3개를 설치해 볼 거고. 이 제품들은 모두 Artifact Hub에서 Helm 패키지로 설치를 할 수가 있거든요. 그래서 이 패키지들에 특정 버전을 다운 받아서 제 강의 레파지토리에 그대로 복사를 해 놨고, 이 강의 실습 환경에 맞는 values 파일을 추가 했어요.그리고 이제 강의를 실습 하시는 분들께서는 본인에 클러스터에 설치를 하려면, CI/CD Server에 Jenkins로 Argo App들을 설치하는 잡을 하나 만들고요. 실행을 하면, 제 Github에서 패키지를 다운받은 다음에 본인에 쿠버네티스 클러스터로 설치가 됩니다. 이제 ArgoCD에서 Application을 만들어 보겠습니다. 우리는 배포를 하기 위해서 Application 이라는 걸 만들어야 되요. 이건 젠킨스에서 배포 단위 별로 프로젝트를 만들었던 거랑 똑같은 개념이고요. 하나의 app을 배포하는 단위가 Application인거고. 그럼 Application은 App별로 여러 개 만들어 지겠죠?그리고 Default라는 Project에 소속 되는데, 이 Project는 Application을 그룹핑 하는 용도고, 쿠버네티스에 네임스페이스 같이 Default라는 프로젝트가 기본적으로 만들어져 있어요.이제 이 Application을 만들 때 어떤 내용들을 넣어야 되는지 볼게요.먼저 Source라고해서 연동할 Git에 대한 정보를 입력해야 되요.  그리고 Destination이라고 해서 배포할 쿠버네티스 클러스터 정보도 줘야 됩니다. 너무 당연한 항목이죠?근데 생소할 수 있는 용어가 있는데, Refresh랑 Synchronize고요. ArgoCD UI에도 이 버튼들이 있는데,, Git에 연결을 해 놓으면 자동으로 변경 사항을 감지하지만, 3분 정도에 체크 인터벌이 있는데, 이때 Refresh 버튼을 누르면 바로 변경 사항을 체크 해줍니다. 그리고 Sync버튼을 누르면 쿠버네티스에 배포하는 실행하는 거고요.이제 또 다른 항목으로 General이 있고, 기본 정보나 배포시에 줄 옵션들이 들어가요. 여기서 주목할 옵션으로 Sync Policy가 있고요. 리소스에 대한 변경사항이 감지 됐다면, 이제 수동으로 배포할 지, 자동으로 배포할 지를 선택하는 옵션이고, 자동으로 할 경우에는 3분 이내에 배포가 됩니다.그리고 Sync Option은 배포 상세 옵션으로, 여러가지가 있는데, 예를 들어 배포할 때 네임스페이스를 자동생성 할 건지? 같은 배포시에 줄 수 있을 법한 기능들이 있고요.Prune Policy는 리소스 삭제 정책에 대한 부분이고. 그외에도 몇 가지 더 있긴 한데 대략 이정도 느낌에 설정들이 있다는 것만 알고 넘어갈게요. 마지막으로 이렇게 ArgoCD에서는 3가지 배포 방식에 배포 툴을 지원합니다. 그래서 내 릴리즈 파일이 어떤 방식 인지에 따라서 선택을 해주면 되는데, ArgoCD가 릴리즈 파일을 다운 받으면서 자동으로 인식을 해요.그럼 이번 블로그는  여기까지고요, 해당 강의에서는 실습과 더불어 추가적으로 아래 내용들에 대해서 더 다룹니다 😀[쿠버네티스 어나더 클래스] : https://inf.run/unreT ArgoCD Image Updater를 이용한 이미지 자동 배포 Argo Rollouts를 이용한 배포 - BlueGreenArgo Rollouts를 이용한 배포 - Canaryps. 매너가 좋아요♡를 만든다 :)

데브옵스 · 인프라쿠버네티스어나더클래스지상편Sprint2일프로데브옵스ArgoCDBlueGreenCanary

일프로

[쿠어클#11] Jenkins Pipeline 기초부터 Blue-Green까지

Sprint2 추가 강의가 업로드 됐어요!이번 강의에서는 Jenkins Pipeline 기초부터 Blue/Green까지라는 주제 입니다. Step 1. Jenkins Pipeline 기본 구성 만들기Step1으로 Jenkins Pipeline에 대한 기본 구성을 만들어 볼거고, Github에서 릴리즈 파일들을 가져와서 빌드/배포하는 구성을 이번에는 젠킨스 파이프라인으로 만들어 보겠습니다. Step 2. Github 연결 및 파이프라인 세분화두 번째 Step은 Github 연결과 파이프라인 세분화인데, Jenknis Pipeline을 쓰는 이유인 파이프라인 스크립트를 Github에서 가져오고, 파이프라인을 좀더 세분화 시켜볼꺼예요. 이렇게 세분화 하면 좋은 점이 각 구간별로 시간이 얼마나 걸리는지 바로 보이기 때문에 이전 배포보다 왜 느려졌는지 눈에 잘 뛰기도 하고, 생각보다 오래 걸리는 구간이 있으면 개선 포인트로 잡기도 좋아요. Step 3, 4. Blue/Green 배포 만들기 및 특징 실습다음으로 Blue/Green 배포를 만듭니다. 처음 Blue가 배포된 상태에서, Green 배포를 하고, V2 버전에 Deployment가 생성이 되면, 트래픽을 V2로 전환 합니다. Service의 Selector를 변경할 거고요. 그런 다음 v1 Deployment를 삭제하면, 이 Blue 배포가 없어지는 거죠. 근데 이 과정 중에서 유즈케이스로 말씀드렸던 운영에서만 테스트 가능한 경우를 하나 해볼 거고, 다음으로 수동 배포시 롤백이 빠르다는 것도 해볼 거예요. 그래서 여기까지가 수동으로 Blue/Green 배포를 할 때 해볼 수 있는 실습들입니다. 다음으로 Step4로는 버튼 한번으로 자동 배포가 되는 Script를 만들고, V2에 과도한 트래픽을 유입 시켰을 때 V2 Pod에 문제가 발생할 수 있는 부분은 실습 환경을 구성하기가 쉽지 않게 때문에 별도로 실습을 해보진 않지만 꼭 주의하시길 바랍니다. 실습 내용은 강의에서 다루고 있어요. (https://inf.run/NzKy)   Blue/Green 시 고려해야 하는 요소다음으로, Blue/Green시 필요한 요소라고 해서 yaml을 만들 때 어떤 걸 고려해야 되는지를 설명 드리겠습니다. 먼저 왼쪽은 Blue 배포에 대한 yaml 파일이고, 이건 이전 부터 계속 봤왔 던 내용이에요. 그리고 오른쪽은 Green 배포를 위한 Deployment yaml 파일 내용 입니다. 뭐가 다른지 보이시나요? deployment 이름 뒤에 추가적으로 시퀀스가 붙어 있죠? 바로 Blue/Green 배포를 고려한 Deployment에 네이밍이 필요한건데, Blue/Green은 기존배포와 나중배포에 대한 상징적인 표현이고, 배포 할 때마다 계속 새 Deployment를 만들 줘어야 되기 때문에 이렇게 네이밍에 신경을 써줘야 합니다. 다음으로 블루/그린 배포를 위한 추가 레이블 및 셀렉터가 필요해요. 현재 이 레이블 상태라면 Green을 만들자마자 Service가 Green Pod에도 연결을 하겠죠. 그래서 블루/그린 배포를 위한 Selector와 Label을 추가적으로 만들어야 되요. 그리고 Green에는 이렇게 값을 다르게 만들어야 되는 거고요.  그래서 여기까지가 Blue/Green 배포를 한다고 했을 때, 미리 고민해서 구성 해놔야 되는 yaml 파일에 내용 입니다. 이번 강의는 실습이 많은 강의라 블로그에는 이정도까지만 정리하겠습니다 ^^그럼 강의에서 만나요!ps. 뒤로가기 함부로 누르지마라. 너는 누구에게 한 번이라도 좋아요♡를 준 사람이었느냐 :)

데브옵스 · 인프라쿠버네티스어나더클래스지상편Sprint2일프로데브옵스인프런젠킨스blue/green

일프로

[kubernetes] 손쉽게 데브옵스 환경을 구축하는 방법 #9

해당 블로그는 [쿠버네티스 어나더 클래스] 강의에 일부 내용입니다. 많은 관심 부탁 드려요!강의 링크 : https://inf.run/NzKy 이번 강의에서 손쉽게 데브옵스 환경을 구축하는 방법으로 CI/CD 서버를 만들어 볼 건데, 먼저 간략하게 Sprint 2 범위에 실습 환경에 대해서 설명을 드릴께요.[지상편] 실습 환경 (전체범위)[지상편] 최종 실습환경 구성은 여기 보이는 환경들을 모두 설치하는 건데, 각 Sprint 마다 하나씩 환경을 구성해요. 이런 흐름이 내 PC에서 모두 이뤄지는 거고 Sprint1 때는 CI/CD환경이 없기 때문에 인프라 환경만 구성해서, 아래와 같이 실습을 해봤었죠?이제 Sprint2에서 CI/CD 환경을 구성 할 건데, Sprint2 환경 구성 범위먼저 인프라 환경때와 마찬가지로, Virtualbox랑 Vagrant를 이용하면, Guest OS가 만들어 지고, 스크립트를 통해서 이런 프로그램들이 모두 설치 됩니다. 뒤에서 설치 내용은 자세히 설명 드릴 거고요.설치가 다 완료 됐으면, 이제 내 PC에 브라우저에서 Jenkins dashboard를 접속을 할 수가 있게 되요. 그래서 빌드를 실행하면, 저에 Github에서 소스를 다운받아서 빌드가 실행 됩니다. 이 소스는 Sprint1에서 제가 실습을 위해서 만들었던 App에 소스고요.다음으로 컨테이너 빌드를 하면, 소스빌드를 해서 만들어진 Jar 파일이 사용되서 컨테이너 이미지가 만들어지고 Dockerhub로 업로드를 하게 되는데, 직접 도커허브에 가입해서, 내 도커 저장소에 이미지를 올릴 거예요. 그래서 지금까지 이렇게 제 도커 허브 username이 들어간 이미지를 사용했다면, 이제부터 자신이 가입한 username 으로 이미지 이름이 변경됩니다.그리고 도커빌드를 할때 필요한 도커파일이랑 배포를 할때 필요한 yaml 파일들을 저장할 용도로 Github가 필요한데, 기존에 있으신 분들은 그대로 쓰시면 되고요. 없으신 분들은 여기도 가입을 하셔야 되요. 그래서 컨테이너 빌드나 배포를 하면, 제 Github가 아닌, 본인에 Github에서 릴리즈 파일들을 다운 받아서 배포를 하게 되는데여기서 중요한건, 이 배포되는 yaml 파일에 들어가는 image 명에 내 도커허브 username이 있어야 여기서 이미지를 가져 올수 있어요. 이게 이번 Sprint2에 실습 구성과 진행 흐름인데 만약에 좀 헷갈려도 걱정하지 마세요. 한번 더 설명 드릴 꺼에요.단계별 설치 시작먼저 Sprint1에서 했던 것 처럼, 제가 올려놓은 Vagrant 설치 스크립트를 실행하면, 이렇게 CI/CD  서버가 한번에 구성되는데, 이 설치 스크립트에서 일어나는 일을 설명 드릴께요.Vagrantfile로 설치되는 내용먼저, 자원 할당을 보면, CPU 2 core에 Memory 2Gi, Disk 30기가를 줬어요. 그리고 Sprint2 부터는 실습할 때 이 두 환경이 모두 띄어져 있어야 되니까. 내 pc에 자원이 충분한지 확인을 해보시고요.그리고 네트워크 설정을 보시면, IP는 인프라 환경이 30번이었고, CI/CD 서버는 20번 이예요. Host-Only Network는  VM간에 통신을 하거나 내 호스트 PC에서 VM을 접속하기 위한 네트워크라서 IP가 같으면 안되고 근데 이 네트워크는 외부 인터넷에 접속은 안되거든요.그래서 NAT를 추가로 쓰는거고, IP는 자동할당  되는데, 이 IP가 인프라 환경이랑 같지만 인터넷만 쓰기 위한 용도라 문제는 안됩니다.다음으로 여기서 부터가 본격적으로 설치 스크립트에 해당하는 부분인데, 첫번째로 리눅스 기본 설정에 대한 내용들이고 이건 인프라 환경에 쿠버네티스를 설치할 때도 했던 내용이예요.그리고 kubectl을 설치 합니다. 이건 젠킨스에서 배포할때 쓸 용도고여 NAT를 설정해놨기 때문에 이렇게 외부 저장소에서 이 kubectl 패키지를 다운 받아서 설치할 수 있는 거죠. 그리고 마찬가지로 Docker 설치가 있어요. 이걸로 젠킨스에서 컨테이너 빌드를 하고, dockerhub로 이미지를 올리게 되고 다음으로 소스 빌드를 해야되니까 OpenJdk랑 Gradle 설치가 있습니다.그리고 Git도 설치를 해서, 빌드에 쓸 소스 코드랑  릴리즈 파일들을 가져와요.마지막으로 Jenkins를 설치하는데, 이때 OpenJDK를 11 버전으로 하나더 설치해요. 그 이유는 젠킨스가 11버전에 돌아가기 때문에 Jenkins 설치용으로 필요한거고 이건 제가 만든 소스코드가 17버전으로 만들었기 때문에 소스코드 빌드용으로 필요한 거에요. 다시 여길로 돌아와서, 이렇게 Vagrant로 CI/CD 서버가 만들어 졌으면 원격접속 툴로 접속을 해놓고요.그리고 이제 Jenkins 대시보드에도 접속해볼 수 있는데, 여기에 접속하면 최초 젠킨스 초기 세팅을 한번 하게되요. 사용자 생성하고 권장 플러그인들을 다운받는 그런 과정들이 있고 다음으로 전역 설정이라는 걸 하는데, 이게 뭐냐면 이 직접 설치한 버전에 Gradle이랑 OpenJdk를 젠킨스에서 빌드를 할 때 사용하겠다고 등록 하는거예요. 그리고 다음으로 이제 자신에 dockerhub를 써야 되니까 도커허브에 가입하는 단계가 있고요.다음으로 dockerhub 사용 설정이라고 해서, 두 가지가 있는데 첫 번째는 내 CI/CD 서버에서 내 도커허브로 이미지를 올릴 수 있도록 로그인을 해 놓는 거랑 두 번째로 젠킨스에서 docker를 사용할 수 있도록 권한을 부여 해야 합니다.그리고 다음으로 인프라 환경에 있는 인증서를 이 CI/CD 환경에 복사 해줘야 돼요. 그래야 젠킨스에서 kubectl로 배포를 할 때 쿠버네티스에 API를 날릴 수 있습니다.그리고 다음으로 내 Github에 가입을 하고, 설정이 있는데, 설정이 뭐냐면, 제 Github에 Dockerfile이랑 yaml파일들이 있거든요. 이걸 본인이 가입한 Github로 복사해 가는거예요. 그리고 복사하면, Deployment 파일 image 부분에 제 Dockerhub username이 있을 텐데, 이 부분을 수정하는 내용이 있고.마지막으로 젠킨스에서 빌드/배포를 하기위한 프로젝트 설정이 있습니다. 실행버튼을 누르게 되면 쿠버네티스에서 리소스가 생성되고요. 그중에서 Pod를 만들 때 이미지는 이젠 내 도커허브에서 가져가는 거죠.그래서 이렇게가 전체적인 설치 순서고, 이제 두번 정도 설명드릴 셈인데, 어떻게 이해가 잘 되셔나요?뭔가 많아 보일 수는 있는데, 제가 까페에 올려놓는 설치 가이드를 따라하다보면 정말 금방이고 근데 이것도 CI/CD가 흘러가기 위한 최소한에 기능만 쓴거에요. 이 흐름을 시작으로 배포강의가 진행되면서 점점 더 고도화가 됩니다.아래 자세한 설치 가이드가 있는 링크를 걸어 놓을께요.https://cafe.naver.com/kubeops/84만약, 해당 내용으로 설치가 힘드시다면 제 강의에서 설치 실습 영상을 추천 드립니다 :) ps. ♡ make me want to be a better man :)

데브옵스 · 인프라쿠버네티스어나더클래스지상편Sprint2일프로kubernetes데브옵스인프런devopsjenkins

일프로

[쿠어클#17] Application 개발자가 꼭 알아야 하는 Pod 기능들

이번 섹션에서는 Application 개발자가 꼭 알아야 하는 Pod 기능들이라는 주제로 여러 얘기 들을 해볼 건데요. 왜 개발자가 꼭 알아야 되냐면, 이번에 배우는 Pod의 기능들은 개발 로직이 받쳐주지 못하면, 써먹을 수 없는 기능들 이라서 그래요. 그래서 내 App이 쿠버네티스 환경 배포된다고 했을 때, 개발자 입장에서는 그 로직들을 잘 구현해 줘야 하고, 데브옵스 엔지니어 입장에서는 개발자에게 이런 로직들이 꼭 필요하다고 잘 얘기할 수 있어야 됩니다. 그럼 블로그를 시작해 볼께요.Application 개발자가 꼭 알아야 하는 Pod 기능들아래 그림을 보면, 워커노드 위에 [Pod가 생성]되는 과정에서 특정 노드(nodeSelector)를 지정 할 수가 있었고요.  이 워커노드에 리소스(resource)는 내 Pod에서 지정된 리소스보다 많이 있어야 겠죠. 그럼 DockerHub에서 이미지(image)를 가져와서 컨테이너와 App이 만들어 집니다. 이제 다음으로 [Pod가 기동하고 운영]되는 과정이 있는데, 여기서부터 컨테이너 안에 Application 개발이랑 관련된 내용들이 시작 됩니다.이제 여기서 이전에 배웠던 내용을 얘기해 볼게요.Probe를 설정하면 kubelet이, App에 헬스 체크 API를 날려주기 때문에 App에는 이 API들에 마춰서 Health를 체크를 해주는 로직이 필요 했고요. Comfigmap을 통해서 환경 변수를 줄 수 있었고, Application에서는 파라미터를 받아서 처리를 해주는 설정이 있어야 됐어요.그리고 또 민감하게 다뤄야 하는 설정 파일의 경우, Secret을 통해 컨테이너로 마운팅 할 수 있었고, App에서 이 파일에 접근하는 로직을 통해서 데이터를 읽을 수가 있어요.그리고 파일을 저장하고, 영구적으로 보관해야 되는 경우,  PV를 통해서 워커노드에 넣을 수 있는데 이것도 개발 로직과 관련된 부분이라고 볼 수 있겠고요. 여기까지는 Sprint1에서 배웠던 내용 이였고. 워밍업 이였습니다. 😀이제부터가 이번 섹션에서 배울 내용들을 설명드릴 건데, 잘 들어 주시길 바랄께요.위 그림을 보시면, 수집 서버 입장에서 모든 Pod의 정보를 조회해 볼 목적으로 API를 날리는 상황이라고 해볼게요. 근데 Service에서는 pod로 트래픽을 랜덤하게 보내주기 때문에, 트래픽을 여러번 시도해야지 모든 Pod를 식별 할 수 있고. 이런 구조는 많은 네트워크 트래픽을 유발 시키기 때문에 좋지 않은 구조입니다.기존 VM 환경에서는 내가 배포할 App에 대해서 고정 IP가 정해져 있었고, 이 IP들을 모두 수집서버에 Config로 등록해서 딱 필요한 만큼의 조회 트래픽을 날렸었거든요. 근데 Pod는 IP가 자동 생성 되기도 하지만, Pod가 재생성 됐을 때 이 IP가 변경되기 때문에 쿠버네티스 환경에서 수집서버는 내가 정보를 조회 해야할 Pod들 한테 트래픽을 보내기가 힘들어 졌습니다.그럼 쿠버네티스 환경에서는 이런 상황을 어떤 구조로 바꿔서 해결해야 되냐면, Pod 스스로가 자신의 Pod 정보를 수집 서버에 전송해 주는  구성으로 만들어야 되요. 그리고 이러기 위해서  App에서 내 Pod 정보를 조회하는 로직이 필요한 거고요. 그 로직에는 이렇게 3가지 방식이 있는데, 이 방법들에 대한 차이와 사용법을 강의 수업에서 설명 드려요.이렇게 마이크로 서비스 아키텍쳐에서 전체 네트워크 트래픽을 줄이기 위해서 수집서버가 주기적으로 Pod 상태를 조회 하는게 아닌 각 Application들이 자신의 상태가 변경이 될 때마다 수집 서버로 API를 전송하는 방법을 쓰고요. 이외에도 Service를 통해서 특정 Pod에 호출이 된 다음에, 이후에는 이 두 Pod 끼리만 서로 양방향 통신을 해야 되는 경우 있습니다. 대표적으로 P2P 통신이고요. 우리가 메세지 관련된 어플리케이션을 만들 때, 그 통신 로직에 내 IP 주소를 넣어야 되요. 시스템 성능적인 면이나, 마찬가지로 전체 네트워크 트래픽을 줄이는 데 유리해요.  그래서 이렇게 개발 입장에서도 내 Pod의 IP 정보가 필요한 상황은 많다라는 말씀을 드리고 싶습니다. 이제 다음으로 Pod가 종료되는 상황에 대해서 얘기를 해볼께요.이건 정말 이전에 배웠던 probe 만큼이나 꼭 필요하고 중요한 내용이에요.통상 Applicaiton이 중단되는 경우는 장애가 발생하거나, 업그레이드, 혹은 시스템 점검이 있어서, 공지를 하고 내리기도 해요. 그리고 주로 새벽에 작업을 하기 때문에 이때 App을 종료시키다가 에러가 좀 나도 딱히 문제라고 생각하지 않습니다. 시스템을 내린 이후에 로그를 볼 생각 자체도 잘 안하고요. 그래서 지금까지 시스템 종료에 대해서 덜 중요하게 생각을 했을 수 있는데, 쿠버네티스 환경에서는 업그레이드나 스케일링들이 운영중도 빈번하게 일어나기 때문에 이런 상황에도 App 종료에 대한 로그를 계속 지켜볼게 아니라면, 이젠 App이 안전하게 종료되도록 만드는 부분이 매우 중요해 졌습니다.그리고 쿠버네티스 또한 App 종료에 대해서 지원해 주는 기능들이 있는데, 이 기능들에 대해서 간략하게 설명 드릴께요. Pod 삭제 명령을 받으면 kubelet은 App한테 종료 신호를 보내고요.  App이 스스로 종료될 때까지 기다려요. 근데 어느 정도 시간이 지나도 App이 종료되지 않으면 강제로 Pod를 삭제 시켜 버리고요. 그래서 App에서는종료신호를 받았을 때, 현재 실행중인 App들을 잘 정리하는 로직을 만들어 놔야 합니다. App이 어떤 정리를 해야 되는 지에 대한 부분은 강의에서 자세히 말씀을 드릴 거고요.그리고 또 App은 종료 신호와는 별개로 내부적으로 메모리 릭이 나거나 해서 장애가 발생하고, 종료 될 수도 있거든요.  이럴 때 쿠버네티스가 알아서 컨테이너를 리스타트 시켜주기 때문에 걱정할 필요는 없지만, 그래도 한번씩 이전 컨테이너가 왜 재시작 됐는지에 대한 사유는 조회를 해봐야 되요.그래서 kubectl로 이전 컨테이너의 상태를 확인하는 방법들을 알려드릴 거고요. 또 App이 종료될 때 특정 파일에 에러에 대한 사유를 저장해 놓으면, Pod에는 이걸 kubectl로 볼 수 있게 해주는 기능도 있습니다.그리고 마지막으로 이렇게 Pod의 생성과 운영, 그리고 종료에 따라  Pod와 컨테이너 상태에 대해서 얘기를 해볼께요.Pod의 상태는 Phase라는 속성에 있고요. 이렇게 각각의 진행에 따라 그 값들이 달라져요.그리고 Pod 종료시에 Succeded와 failed이 있는 걸 보면, 쿠버네티스는 종료에 대해서 성공적인 종료와, 실패적인 종료를 구분해 놨다는 게 느껴지시죠? 그리고 Pod에 상태가 있지만, 컨테이너에도 별도로 상태가 또 존재합니다.containerStatuses라는 속성이고요. 이건 좀 단순해 보일 수 있는데, 여기에 이렇게 세부적인 Reason이 또 있어요.여기 CrashLoopBackOff는 Pod가 재대로 기동이 안될 때 대시보드에서 자주 볼 수 있는데, 실제 Pod는 Pending이고, 컨테이너는 waiting상태에서 이 reason 속성을 화면에 보여줬던 거죠. 그리고 종료에 있어서는 두 가지 Completed와 Error가 있습니다. 일반적으로 컨테이너가 정상 종료되면 Completed고, Pod도 Succeeded로 끝나는데, 한 Pod에는 컨테이너는 두 개 이상 있을 수 있기 때문에, 이때는 컨테이너 하나라도 Error가 있으면 Pod는 Failed 상태가 끝나게 되요. 그래서 다시 Pod 종료에 대한 상태를 정리하면,SIGTERM을 받은 App이 정상적으로 자원을 정리하고 스스로 종료가 되면 컨테이너의 상태가 Completed고 Pod도 Succeeded로 끝나지만, 스스로 정리를 다 못하고, 강제 삭제가 됐을 때는 컨테이너 상태는 Error고 Pod의 상태는 Failed로 끝나는 거에요.그럼 이번 블로그는  여기까지고요, 해당 강의에서는 아래 내용들에 대해서 더 다룹니다 😀[쿠버네티스 어나더 클래스] : https://inf.run/3oKqK내 Pod 정보를 API로 노출시키기 내 Application을 안정적으로 종료하기ps. 한번도 좋아요♡를 안 준 사람은 있어도, 한번만 좋아요♡를 준 사람은 없다. 당신은 어떤 사람인가요? :)

데브옵스 · 인프라쿠버네티스어나더클래스지상편Sprint3일프로데브옵스ApplicationPod

데브옵스, OOO와 OOOO를 잡아야 한다는데?

안정적이고 효율적인 서비스 운영을 위한 방법을 찾고 적용하는 데브옵스는 오늘날 많은 팀에서 도입하고 있는 개발 방법론입니다. 데브옵스 엔지니어링에 대한 수요는 늘고 있지만, 서비스 규모는 점점 더 크고 복잡해지는데다 새로운 기술 역시 꾸준히 등장하는 만큼 진입 장벽이 높게 느껴지기 마련인데요.데브옵스의 핵심 요소는 크게 (1) 인프라 관리 (2) 딜리버리 (3) 모니터링 세 가지로 나뉩니다. 이 중에서도 인프라와 딜리버리 파이프라인 구축은 코드 생성 - 테스트 - 배포 - 운영에 이르는 흐름을 하나의 관리 프로세스로 관리하고 효율을 높이는 과정에서 중심축 역할을 합니다.복잡한 비즈니스의 민첩성과 확장성을 높이고, 개발과 운영을 유기적으로 만들 수 있게 ‘일하는 방식’을 달리하는 데브옵스. 성공적인 데브옵스 도입을 위해서는 이러한 핵심 역량을 중심으로 팀에 맞는 전략을 찾아가는 것이 중요합니다.•••주니어 데브옵스 엔지니어가 되기 위한 핵심 역량을 빠르게 완성하고 싶으신가요?지금 인프런 프리즘 [DevOps 기본 입문 로드맵]을 통해 학습해보세요. https://www.inflearn.com/roadmaps/658•••인프런 프리즘 브랜드 스토리 읽어보기 >>

데브옵스 · 인프라DevOps데브옵스인프런프리즘InflearnPrism신입개발자취업AWS인프라딜리버리CICD

채널톡 아이콘