관리 메뉴

피터의 개발이야기

[kubernets] skaffold란, Kubernetes 로컬 개발환경 본문

Kubernetes/kube 개발환경

[kubernets] skaffold란, Kubernetes 로컬 개발환경

기록하는 백앤드개발자 2022. 9. 21. 16:42
반응형

[kubernetes] 개발환경 목차

ㅁ kubernetes 로컬 개발 환경의 한계

 Kubernetes 는 컨테이너화된 애플리케이션의 배포, 확장 및 관리를 자동화하기 위한 탁월한 도구이다. 하지만 Kubernetes의 로컬 개발환경은 고통스러운 프로세스일 수 있다. 일반적인 워크플로를 설명하자면, 로컬에서 코드의 수정 및 기능 테스트를 확인하고, 도커 이미지를 빌드 및 태그 지정하고, 배포 구성을 만들고 Kubernetes에 배포한다. 버그가 있거나 업그레이드가 필요한 경우 개발자는 처음부터 동일한 절차를 따라야 한다. 

 

 

ㅁ Skaffold란?

 

  Skaffold는 Kubernetes 네이티브 애플리케이션을 위한 지속적인 개발을 용이하게 하는 CLI 도구이다. Skaffold는 애플리케이션을 빌드, 푸시 및 배포하기 위한 워크플로를 처리하고 CI/CD 파이프라인을 만들기 위한 빌딩 블록을 제공한다. 이를 통해 Skaffold가 로컬 또는 원격 Kubernetes 클러스터에 지속적으로 배포하는 동안 로컬에서 애플리케이션을 반복하는 데 집중할 수 있다.

 

 

ㅁ Skaffold Work Flow

https://skaffold.dev/docs/pipeline-stages/

  • Code change
    Skaffold는 Git을 모니터링하고 코드변경 시 자동으로 코드를 빌드한다.
  • Docker container build
    빌드된 코드에 따라 도커 컨테이너를 패키징한다. 도커 이미지 태깅 시, SHA256 해쉬를 생성하거나 날짜, 또는 Git commit ID를 태그로 사용하는데, Git commit ID를 사용할 경우에는 코드 변경에 따른 컨테이너 버전 추적이 가능하다.
  • Kubernetes resources deploy
    태깅이된 컨테이너 이미지를 지정되어 있는 컨테이너 리파지토리에 저장하고, 미리 정의되어 있는 쿠버네티스 YAML 파일을 이용하여 변경 내용을 대상 쿠버네티스 클러스터에 반영한다.
  • Debugging on k8s cluster
    반영된 파드에서 테스트를 진행한다.

 위의 과정은 파이프라인으로 자동화 되었기 때문에, 개발자가 코드 변경하면, 자동으로 코드 반영이 이루어지고, 더욱이 Skaffold를 종료하면, 개발 시 생성된 쿠버네티스 리소스를 자동으로 정리까지 하여, 개발자는 개발에 더욱 집중할 수 있다.

 

 

ㅁ Skaffold 특징

  • 빠른 로컬 Kubernetes 개발
    • 최적화된 소스의  쿠버네티스 적용
      - Skaffold는 소스 코드의 변경 사항을 감지 하고 정책 기반 이미지 태깅  최적화되고 빠른 로컬 워크플로 를 통해 애플리케이션을 자동으로 빌드 , 푸시 , 테스트  배포 하는 파이프라인을 처리한다.
    • 지속적인 피드백 
      - Skaffold는 배포 로깅 및 리소스 포트 전달을 자동으로 관리한다.
  • Skaffold 프로젝트는 모든 곳에서 작동한다.
    • 다른 개발자와 공유
      - Skaffold는 
      프로젝트를 전 세계와 공유하는 가장 쉬운 방법 이다. git clone and skaffold run
    • 컨텍스트 인식 
      - Skaffold profiles, local config 환경 변수 및 플래그를 사용하여 환경 간의 차이점을 쉽게 통합한다.
    • CI/CD 빌딩 블록 - skaffold build, skaffold test, skaffold deploy를 CI/CD 파이프라인의 일부로 사용하거나 단순하게 skaffold run으로 한번에 실행할 수 있다.
    • GitOps 통합 - skaffold renderGitOps 워크플로에서 사용할 이미지를 빌드하고 템플릿화된 Kubernetes 매니페스트를 렌더링하는 데 사용한다.
  • skaffold.yaml - 프로젝트에 대한 단일 플러그형 선언적 구성
    • skaffold init 
      - Skaffold는 빌드 및 배포 구성을 검색하고 Skaffold 구성을 생성할 수 있다.
    • 다중 구성 요소 앱 
      - Skaffold는 많은 구성 요소가 있는 응용 프로그램을 지원하므로 마이크로 서비스 기반 응용 프로그램에 적합하다.
    • 고유한 도구 가져오기 
      - Skaffold에는 플러그형 아키텍처가 있어 빌드 및 배포 단계의 다양한 구현이 가능하다.
  • 경량
    • 클라이언트 측 전용 
      - Skaffold에는 클러스터 측 구성 요소가 없으므로 클러스터에 대한 오버헤드나 유지 관리 부담이 없다.
    • 최소 파이프라인 
      - Skaffold는 작업을 단순하게 유지하기 위해 독단적이고 최소한의 파이프라인을 제공한다.

 

 

ㅁ Skaffold 설치

$ brew install skaffold
Running `brew update --auto-update`...
==> Auto-updated Homebrew!
Updated 2 taps (homebrew/core and homebrew/cask).
==> New Formulae
antidote           camlp-streams      fonts-encodings    ghc@8.10           kubesess           llvm@14            opencl-icd-loader  schemathesis       xctesthtmlreport
apophenia          cargo-zigbuild     fuego-firestore    got                liblbfgs           lmfit              pyyaml             taplo              xwin
bdftopcf           commitlint         gator              has                liburing           mailsy             quilt-installer    toml-test
c                  distrobox          gdrive-downloader  hof                licenseplist       objconv            scala@2.13         weasyprint
==> New Casks
apifox                bluebubbles           doll                  languagetool          lunacy                plugdata              sanesidebuttons       xprocheck
apipost               bridge                douyin                lectrote              macforge              postman-cli           spline
arduino-ide           dcp-o-matic-editor    keet                  lookingglassbridge    notesnook             reflect               typcn-bilibili
beast2                devcleaner            laconvolver           lookingglassstudio    orka-vm-tools         rnnoise               whist-browser

You have 42 outdated formulae installed.
You can upgrade them with brew upgrade
or list them with brew outdated.

==> Downloading https://ghcr.io/v2/homebrew/core/skaffold/manifests/1.39.2
######################################################################## 100.0%
==> Downloading https://ghcr.io/v2/homebrew/core/skaffold/blobs/sha256:ae52545e4ffe685e2f211aaebc8b34dd0095f99badfe0408b777da1604cc3eda
==> Downloading from https://pkg-containers.githubusercontent.com/ghcr1/blobs/sha256:ae52545e4ffe685e2f211aaebc8b34dd0095f99badfe0408b777da1604cc3eda?se=2022-09-23T05%3A50%3A
######################################################################## 100.0%
==> Pouring skaffold--1.39.2.arm64_big_sur.bottle.tar.gz
==> Caveats
zsh completions have been installed to:
  /opt/homebrew/share/zsh/site-functions
==> Summary
🍺  /opt/homebrew/Cellar/skaffold/1.39.2: 8 files, 81.4MB
==> Running `brew cleanup skaffold`...
Disable this behaviour by setting HOMEBREW_NO_INSTALL_CLEANUP.
Hide these hints with HOMEBREW_NO_ENV_HINTS (see `man brew`).

 ㅇ 설치 안내는 이곳에서 확인할 수 있다.

 ㅇ Homebrew를 이용해 Mac에 설치하였다.

 ㅇ 준비사항으로 minikube와 kubectl은 이미 설치되어 있는 상태이다.

 

 

ㅁ Skaffold 자동완성 기능

 ㅇ Skaffold의 자동완성기능을 설정하도록 한다. 

 ㅇ 개인적으로 CLI 도구 이용 시 자동완성기능을 사용하는데, 이 기능을 사용하면, 해당 도구에 대한 이해와 작업 속도가 향상된다.

 

 ㅇ OS X 기준으로 설치를 진행하여 자동완성 기능 세팅을 완료하였다.

 

 

ㅁ 예제코드 다운로드

$ git clone --depth 1 https://github.com/GoogleContainerTools/skaffold
'skaffold'에 복제합니다...
remote: Enumerating objects: 3013, done.
remote: Counting objects: 100% (3013/3013), done.
remote: Compressing objects: 100% (2434/2434), done.
remote: Total 3013 (delta 791), reused 1432 (delta 347), pack-reused 0
오브젝트를 받는 중: 100% (3013/3013), 19.50 MiB | 16.60 MiB/s, 완료.
델타를 알아내는 중: 100% (791/791), 완료.

cd skaffold/examples/getting-started

 ㅇ 샘플코드를 다운 받고 위의 경로로 이동하였다. 

 

 

ㅁ skaffold dev: continuous build & deploy on code changes

$ skaffold dev
Listing files to watch...
 - skaffold-example
Generating tags...
 - skaffold-example -> skaffold-example:b45769a
Checking cache...
 - skaffold-example: Not found. Building
Starting build...
Found [minikube] context, using local docker daemon.
Building [skaffold-example]...
Target platforms: [linux/amd64]
[+] Building 57.4s (13/13) FINISHED
 => [internal] load build definition from Dockerfile                                                                                                  0.1s
 => => transferring dockerfile: 515B                                                                                                                  0.0s
 => [internal] load .dockerignore                                                                                                                     0.0s
 => => transferring context: 2B                                                                                                                       0.0s
 => [internal] load metadata for docker.io/library/alpine:3                                                                                           4.2s
 => [internal] load metadata for docker.io/library/golang:1.18                                                                                        3.8s
 => [internal] load build context                                                                                                                     0.0s
 => => transferring context: 281B                                                                                                                     0.0s
 => [stage-1 1/2] FROM docker.io/library/alpine:3@sha256:bc41182d7ef5ffc53a40b044e725193bc10142a1243f395ee852a8d9730fc2ad                             1.1s
 => => resolve docker.io/library/alpine:3@sha256:bc41182d7ef5ffc53a40b044e725193bc10142a1243f395ee852a8d9730fc2ad                                     0.0s
 => => sha256:bc41182d7ef5ffc53a40b044e725193bc10142a1243f395ee852a8d9730fc2ad 1.64kB / 1.64kB                                                        0.0s
 => => sha256:1304f174557314a7ed9eddb4eab12fed12cb0cd9809e4c28f29af86979a3c870 528B / 528B                                                            0.0s
 => => sha256:9c6f0724472873bb50a2ae67a9e7adcb57673a183cea8b06eb778dca859181b5 1.47kB / 1.47kB                                                        0.0s
 => => sha256:213ec9aee27d8be045c6a92b7eac22c9a64b44558193775a1a7f626352392b49 2.81MB / 2.81MB                                                        0.5s
 => => extracting sha256:213ec9aee27d8be045c6a92b7eac22c9a64b44558193775a1a7f626352392b49                                                             0.5s
 => [builder 1/5] FROM docker.io/library/golang:1.18@sha256:040bc0980888e2df09499c73156f3f869d843b7033d11b465fee7f1a358a494a                         42.8s
 => => resolve docker.io/library/golang:1.18@sha256:040bc0980888e2df09499c73156f3f869d843b7033d11b465fee7f1a358a494a                                  0.0s
 => => sha256:040bc0980888e2df09499c73156f3f869d843b7033d11b465fee7f1a358a494a 2.36kB / 2.36kB                                                        0.0s
 => => sha256:ebd59a91af0c61cf28a22a9651ffd45612848bdcc1a43c2c3063825ba2e613fc 1.80kB / 1.80kB                                                        0.0s
 => => sha256:23858da423a6737f0467fab0014e5b53009ea7405d575636af0c3f100bbb2f10 55.03MB / 55.03MB                                                     19.9s
 => => sha256:326f452ade5c33097eba4ba88a24bd77a93a3d994d4dc39b936482655e664857 5.16MB / 5.16MB                                                        1.4s
 => => sha256:f81bafb819d5b520ab919b42e5925c4b32b62241fc1d036036d9bb5aa2f522d1 7.10kB / 7.10kB                                                        0.0s
 => => sha256:a42821cd14fb31c4aa253203e7f8e34fc3b15d69ce370f1223fbbe4252a64202 10.88MB / 10.88MB                                                      2.4s
 => => sha256:8471b75885efc7790a16be5328e3b368567b76a60fc3feabd6869c15e175ee05 54.58MB / 54.58MB                                                     21.2s
 => => sha256:b7aa120dd02d9fa75bb50861103f7837514028ea6f06e3e821b8c47c2c10d386 85.96MB / 85.96MB                                                      8.7s
 => => sha256:5cc67fe6144b8a2d33963edb62297bdaa3f968746061866b48db3f3125e68734 141.88MB / 141.88MB                                                   19.8s
 => => sha256:cd3416ecab879296d41843948ae859cadb4bd4300a60b23abef443645845ab4a 156B / 156B                                                           20.7s
 => => extracting sha256:23858da423a6737f0467fab0014e5b53009ea7405d575636af0c3f100bbb2f10                                                             3.7s
 => => extracting sha256:326f452ade5c33097eba4ba88a24bd77a93a3d994d4dc39b936482655e664857                                                             0.3s
 => => extracting sha256:a42821cd14fb31c4aa253203e7f8e34fc3b15d69ce370f1223fbbe4252a64202                                                             0.4s
 => => extracting sha256:8471b75885efc7790a16be5328e3b368567b76a60fc3feabd6869c15e175ee05                                                             3.6s
 => => extracting sha256:b7aa120dd02d9fa75bb50861103f7837514028ea6f06e3e821b8c47c2c10d386                                                             4.4s
 => => extracting sha256:5cc67fe6144b8a2d33963edb62297bdaa3f968746061866b48db3f3125e68734                                                             9.0s
 => => extracting sha256:cd3416ecab879296d41843948ae859cadb4bd4300a60b23abef443645845ab4a                                                             0.0s
 => [builder 2/5] WORKDIR /code                                                                                                                       0.7s
 => [builder 3/5] COPY main.go .                                                                                                                      0.0s
 => [builder 4/5] COPY go.mod .                                                                                                                       0.0s
 => [builder 5/5] RUN go build -gcflags="${SKAFFOLD_GO_GCFLAGS}" -trimpath -o /app main.go                                                            8.7s
 => [stage-1 2/2] COPY --from=builder /app .                                                                                                          0.1s
 => exporting to image                                                                                                                                0.0s
 => => exporting layers                                                                                                                               0.0s
 => => writing image sha256:65cf5e9a6ad18fd760e24a41367d404179e7ba20fadd9fd3ccc43ece1e145818                                                          0.0s
 => => naming to docker.io/library/skaffold-example:b45769a                                                                                           0.0s

Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
Build [skaffold-example] succeeded
Tags used in deployment:
 - skaffold-example -> skaffold-example:65cf5e9a6ad18fd760e24a41367d404179e7ba20fadd9fd3ccc43ece1e145818
Starting deploy...
 - pod/getting-started created
Waiting for deployments to stabilize...
 - pods is ready.
Deployments stabilized in 4.142 seconds
Press Ctrl+C to exit
Watching for changes...
[getting-started] Hello world!
[getting-started] Hello world!
[getting-started] Hello world!

 

 

ㅁ 소스 수정

 ㅇ main.go에서 Hello world! 문구를 Hello peterica!로 수정하였다.

 

 ㅇ 수정하는 순간 자동으로 반영작업이 이루어졌으며, 해당 문구가 바뀐 것을 확인할 수 있다.

 

 

 ㅇ 프로세스를 중지하였다.
 ㅇ 구성되었던 쿠버네티스 리소스도 함께 정리되었다.

 

 

ㅁ Skaffold run: 한번 빌드 및 배포

$ skaffold run
Generating tags...
 - skaffold-example -> skaffold-example:b45769a-dirty
Checking cache...
 - skaffold-example: Found Locally
Starting test...
Tags used in deployment:
 - skaffold-example -> skaffold-example:538ca76ea444f0f2ed95ce3e04cdfd1aefa58b1e454b17c42fc73cc758d5a93b
Starting deploy...
 - pod/getting-started created
Waiting for deployments to stabilize...
 - pods is ready.
Deployments stabilized in 4.148 seconds
You can also run [skaffold run --tail] to get the logs

 ㅇ 한 번에 한 번 빌드하고 배포를 원하는 경우 한 번만 실행되는 것을 확인할 수 있었다.

 

 

ㅁ skaffold delete

 ㅇ 위에서 run 했던 작업들을 정지하였다.

 ㅇ 리소스도 함께 정리되었다.

 

 

ㅁ 함께 보면 좋은 사이트

 

Skaffold

Easy and Repeatable Kubernetes Development

skaffold.dev

 ㅇ skaffold 공식 홈페이지

 

 

쿠버네티스 #27 - 쿠버네티스 애플리케이션을 위한 IDE 설정하기 - IntelliJ

쿠버네티스 애플리케이션을 위한 개발환경 #1 IntelliJ 조대협 (http://bcho.tistory.com) 일반적인 경우에는 로컬 환경에서 개발하고, 로컬에서 톰캣등을 띄워서 테스트하면 되지만, 만약 부가적으로 레

bcho.tistory.com

 ㅇ 쿠버네티스 애플리케이션을 위한 IDE 설정하기

 

 

 

Kubernetes Local Development: The Correct Way

The infinite loop of pain and suffering when developing on Kubernetes is a thing of the past.

towardsdatascience.com

 ㅇ 쿠버네티스 로컬 개발환경

 

 

 ㅇ Kubernetes Development made easy  

 

 

  ㅇ Remote Debugging in Kubernetes | IntelliJ using Cloud Code

 

 

반응형
Comments