DevOps, Infra

[skaffold] Skaffold , kustomize with Spring Boot

seulseul 2022. 12. 27. 02:48

Skaffold는 애플리케이션 구축, 푸시 및 배포를 위한 워크플로를 처리하고 CI/CD 파이프라인 생성을 위한 빌딩 블록을 제공한다.

Google 에서 개발했으며 아래와 같은 파이프라인으로 동작한다.

 



목차

 

     

    1. install

    1.1.skaffold 설치

    curl -Lo skaffold https://storage.googleapis.com/skaffold/releases/v2.0.0/skaffold-linux-amd64 
    sudo install skaffold /usr/local/bin/

    1.2. kustomize 설치

    kustomize CLI 미설치시 skaffold deploy 작업중 error 발생함

     

    curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh"| bash
    sudo install kustomize /usr/local/bin

    2. plugin 추가

     

    skaffold 에서 jib step 을 실행하기 때문에 build.gradle 또는 pom.xml 에 jib 플러그인을 추가해줘야한다.

     

    2.1. build.gradle 예시 (gradle)

    plugins {
    	
    
    	id 'com.google.cloud.tools.jib' version '3.3.1'
    	
    	
    }

    2.2. pom.xml 예시 (maven)

    <build>
    	<plugins>
    			
    			<!--  생략 -->
    			
                      <plugin>
                        <groupId>com.google.cloud.tools</groupId>
                        <artifactId>jib-maven-plugin</artifactId>
                        <version>3.0.0</version>
                      </plugin>
                  
    	</plugins>
    </build>

    3. 프로젝트 구조

     

    위 이미지는 skaffold 와 resource 가 프로젝트에 같이 있는 경우이다.
    1. skaffold.yaml 은 프로젝트 ROOT 위치에 있다. (필수)
    2. kustomization.yaml , 각종 resource yaml 은 k8s/base Directory 위치에 있다.
    (사용자의 커스텀일 뿐 정해진 규칙은 아님)

     

    4. skaffold.yml

    apiVersion: skaffold/v2beta18
    kind: Config
    profiles:
      - name: dev                 # skaffold 실행시 -p로 정의된 profile
        build:
          local:
            push: true # false는 로컬 테스트
          artifacts:
            - image: jei0486/demo-fe # on dev server (docker hub에 push하고 실행)
              # - image: demo-fe   # local(로컬/push없이 실행만)
              jib:
                args:
                  - -DskipTests
                  - "-Djib.container.environment=SPRING_PROFILES_ACTIVE=dev"  # jib 플러그인을 통해 dev profile에 대해 수행
                fromImage: docker.io/library/openjdk:11.0.11-jre         # 실행을 위한 runtime image
        deploy:
          kustomize:
            paths:
            - k8s/base
    
    #    deploy:
    #      kubectl:
    #        manifests:
    #          - k8s/demo-fe-cm.yaml
    #          - k8s/demo-fe.yaml
    #          - k8s/demo-fe-ingress.yaml

     

     

    deploy.kustomize.paths 에 kustomization.yaml 이 위치한 path 를 기입해준다.
    deploy 방식은 kustomize 뿐 아니라 kubectl , helm , google cloud run 등이 있다.

    만약 deploy 방법으로, kustomize 를 사용하지 않고 kubectl 을 사용할 경우 kustomize 를 설치하지 않아도 된다.
    주석처리된 deploy.kubectl 부분과 같이 작성하면된다.

     

    Deploy [UPDATED]

    Easy and Repeatable Container & Kubernetes Development

    skaffold.dev

     

     

    5. kustomization

    apiVersion: kustomize.config.k8s.io/v1beta1
    kind: Kustomization
    resources:
      - demo-fe.yaml
      - demo-fe-cm.yaml
      - demo-fe-ingress.yaml
    
    images:
      - name: jei0486/demo-fe
        newTag: v2

    Kustomize ? Declarative Management of Kubernetes Objects Using Kustomize
    Kustomizekustomization 파일 통해 쿠버네티스 오브젝트를 사용자가 원하는 대로 변경하는(customize) 독립형 도구이다.

     

    6. skaffold 명령어

    6.1. skaffold build

    # skaffold build
    skaffold build -p dev -t v0.2
    • build : build 후 docker 파일을 registry 에 업로드만 한다.

     

    6.2. skaffold dev

    # skaffold dev
    skaffold dev -p dev -t v0.2
    • dev : 실행함과 동시에 터미널에 로그가 뜨게된다.
      • Ctrl + C 를 누르면 deployment 및 service 와 같은 모든 resources 가 삭제된다.

    6.2.1. 실행 터미널

    04:28:17 ubuntu@DESKTOP demo-api ±|main ✗|→ TAG=v2 skaffold dev -p dev --cache-artifacts=false
    Listing files to watch...
     - docker.io/jei0486/demo-api
    Generating tags...
     - docker.io/jei0486/demo-api -> docker.io/jei0486/demo-api:v2
    Starting build...
    Found [k3d-k3s-default] context, using local docker daemon.
    Building [docker.io/jei0486/demo-api]...
    Target platforms: [linux/amd64]
    > Task :_skaffoldFailIfJibOutOfDate
    > Task :compileJava UP-TO-DATE
    > Task :processResources UP-TO-DATE
    > Task :classes UP-TO-DATE
    
    > Task :jib
    
    Containerizing application to jei0486/demo-api:v2...
    Base image 'openjdk:11.0.11-jre' does not use a specific image digest - build may not be reproducible
    Getting manifest for base image openjdk:11.0.11-jre...
    Building dependencies layer...
    Building resources layer...
    Building classes layer...
    Building jvm arg files layer...
    Using credentials from Docker config (/home/ubuntu/.docker/config.json) for jei0486/demo-api:v2
    The base image requires auth. Trying again for openjdk:11.0.11-jre...
    Using credentials from Docker config (/home/ubuntu/.docker/config.json) for openjdk:11.0.11-jre
    Using base image with digest: sha256:50c85f8bc95c66f3eb1d8fd79cbf34e9cd509fe4cc584253e7566a832877b840
    
    Container entrypoint set to [java, -cp, @/app/jib-classpath-file, com.demo.api.DemoApiApplication]
    
    Built and pushed image as jei0486/demo-api:v2
    
    BUILD SUCCESSFUL in 13s
    4 actionable tasks: 2 executed, 2 up-to-date
    Build [docker.io/jei0486/demo-api] succeeded
    Tags used in deployment:
     - docker.io/jei0486/demo-api -> docker.io/jei0486/demo-api:v2@sha256:c2a25e0da412d05de50c1966a5ede6d68743a727ea17465a50e93ac218cbe2a0
    Starting deploy...
    Loading images into k3d cluster nodes...
    Images loaded in 65ns
     - configmap/demo-api-configmap unchanged
     - service/demo-api-svc configured
     - deployment.apps/demo-api configured
    Waiting for deployments to stabilize...
     - api:deployment/demo-api: creating container demo-api
        - api:pod/demo-api-6dc4db69d-gs94f: creating container demo-api
     - api:deployment/demo-api is ready.
    Deployments stabilized in 5.063 seconds
    Press Ctrl+C to exit
    [demo-api] 07:28:48.541 [Thread-0] DEBUG org.springframework.boot.devtools.restart.classloader.RestartClassLoader - Created RestartClassLoader org.springframework.boot.devtools.restart.classloader.RestartClassLoader@708a3bc0
    [demo-api] 07:28:48.407 [INFO ] [SpringApplicationShutdownHook] o.s.o.j.LocalContainerEntityManagerFactoryBean - Closing JPA EntityManagerFactory for persistence unit 'default'
    [demo-api] 07:28:48.409 [INFO ] [SpringApplicationShutdownHook] com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown initiated...
    [demo-api] 07:28:48.413 [INFO ] [SpringApplicationShutdownHook] com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown completed.
    [demo-api]
    [demo-api]   .   ____          _            __ _ _
    [demo-api]  /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
    [demo-api] ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
    [demo-api]  \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
    [demo-api]   '  |____| .__|_| |_|_| |_\__, | / / / /
    [demo-api]  =========|_|==============|___/=/_/_/_/
    [demo-api]  :: Spring Boot ::               (v2.6.13)
    [demo-api]
    [demo-api] 07:28:48.829 [INFO ] [restartedMain] com.demo.api.DemoApiApplication - Starting DemoApiApplication using Java 11.0.11 on demo-api-6dc4db69d-gs94f with PID 1 (/app/classes started by root in /)
    [demo-api] 07:28:48.830 [INFO ] [restartedMain] com.demo.api.DemoApiApplication - The following 1 profile is active: "dev"
    [demo-api] 07:28:48.866 [INFO ] [restartedMain] o.s.b.d.e.DevToolsPropertyDefaultsPostProcessor - Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
    [demo-api] 07:28:48.866 [INFO ] [restartedMain] o.s.b.d.e.DevToolsPropertyDefaultsPostProcessor - For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
    Watching for changes...
    [demo-api] 07:28:49.201 [INFO ] [restartedMain] o.s.d.r.c.RepositoryConfigurationDelegate - Bootstrapping Spring Data JPA repositories in DEFAULT mode.
    [demo-api] 07:28:49.229 [INFO ] [restartedMain] o.s.d.r.c.RepositoryConfigurationDelegate - Finished Spring Data repository scanning in 22 ms. Found 1 JPA repository interfaces.
    [demo-api] rpc error: code = NotFound desc = an error occurred when try to find container "530a9ce496b8a0026b77bc0f29d24156e15065595e4b9481a8660e18edea3916": not found[demo-api] 07:28:49.759 [INFO ] [restartedMain] o.s.b.w.e.tomcat.TomcatWebServer - Tomcat initialized with port(s): 8088 (http)
    [demo-api] 07:28:49.767 [INFO ] [restartedMain] o.a.catalina.core.StandardService - Starting service [Tomcat]
    [demo-api] 07:28:49.767 [INFO ] [restartedMain] o.a.catalina.core.StandardEngine - Starting Servlet engine: [Apache Tomcat/9.0.68]
    [demo-api] 07:28:49.816 [INFO ] [restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/] - Initializing Spring embedded WebApplicationContext
    [demo-api] 07:28:49.816 [INFO ] [restartedMain] o.s.b.w.s.c.ServletWebServerApplicationContext - Root WebApplicationContext: initialization completed in 949 ms
    [demo-api] 07:28:50.093 [INFO ] [restartedMain] o.h.jpa.internal.util.LogHelper - HHH000204: Processing PersistenceUnitInfo [name: default]
    [demo-api] 07:28:50.118 [INFO ] [restartedMain] org.hibernate.Version - HHH000412: Hibernate ORM core version 5.6.12.Final
    [demo-api] 07:28:50.262 [INFO ] [restartedMain] o.h.annotations.common.Version - HCANN000001: Hibernate Commons Annotations {5.1.2.Final}
    [demo-api] 07:28:50.314 [INFO ] [restartedMain] com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
    [demo-api] 07:28:50.362 [INFO ] [restartedMain] com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed.
    [demo-api] 07:28:50.373 [INFO ] [restartedMain] org.hibernate.dialect.Dialect - HHH000400: Using dialect: org.hibernate.dialect.MySQL5InnoDBDialect
    [demo-api] 07:28:50.659 [INFO ] [restartedMain] o.h.e.t.j.p.i.JtaPlatformInitiator - HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]
    [demo-api] 07:28:50.664 [INFO ] [restartedMain] o.s.o.j.LocalContainerEntityManagerFactoryBean - Initialized JPA EntityManagerFactory for persistence unit 'default'
    [demo-api] 07:28:50.849 [WARN ] [restartedMain] o.s.b.a.o.j.JpaBaseConfiguration$JpaWebConfiguration - spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
    [demo-api] 07:28:51.088 [INFO ] [restartedMain] o.s.b.d.a.OptionalLiveReloadServer - LiveReload server is running on port 35729
    [demo-api] 07:28:51.092 [INFO ] [restartedMain] o.s.b.a.e.web.EndpointLinksResolver - Exposing 1 endpoint(s) beneath base path '/actuator'
    [demo-api] 07:28:51.119 [INFO ] [restartedMain] o.s.b.w.e.tomcat.TomcatWebServer - Tomcat started on port(s): 8088 (http) with context path ''
    [demo-api] 07:28:51.129 [INFO ] [restartedMain] com.demo.api.DemoApiApplication - Started DemoApiApplication in 2.576 seconds (JVM running for 2.88)

    6.3. skaffold run

    # skaffold run
    skaffold run -p dev -t v0.2

    한 번 빌드 및 배포한다.

    Skafflod CLI URL 에서 다양한 Skaffold CLI 와 Option 을 확인할 수 있다.

    'DevOps, Infra' 카테고리의 다른 글

    [Jenkins] 빌드 자동화 - polling  (0) 2022.12.27
    [Jenkins] 플러그인 설치 및 준비  (0) 2022.12.27
    Git 브랜치 전략 3가지  (0) 2022.12.27
    Jenkins Install for WSL  (0) 2022.12.27
    [DB]PostgreSQL 9.4 설치 (centos7)  (0) 2021.03.20