Java in the Cloud: 지속적 통합 설정 자습서

게시 됨: 2022-03-11

매년 우리는 IT 산업의 점점 더 빠른 진화를 목격하고 있습니다. "Write Once, Run Anywhere"라는 획기적인 슬로건이 소프트웨어 개발 커뮤니티에 완전히 새로운 수준의 기대치를 설정한 지 20년이 넘었습니다. 그리고 오늘날 우리는 특히 Java 개발과 일반적으로 소프트웨어 개발을 완전히 새로운 가능성의 세계로 집합적으로 가져간 결과적으로 계속 확장되는 도구 세트와 함께 있습니다.

Agile, DevOps, 지속적 통합 및 배포와 같은 방법론은 마이크로서비스의 발전과 함께 소프트웨어 개발 프로세스 생산성을 그 어느 때보다 크게 향상시켰습니다. 자동화를 활용하고 올바른 도구 세트를 설정하면 소프트웨어 제품의 개발 및 제공을 놀라울 정도로 쉽게 만들 수 있습니다.

이 기사에서는 DevOps로 건너가 제품 개발 및 제공을 최대한으로 최적화하기 위해 검색하는 Java 개발자의 관점에서 이 새로운 세계를 살펴볼 것입니다.

오늘날 Spring Boot, Docker, Cloud, Amazon Web Services, Continuous Delivery와 같은 용어는 널리 사용되지만 널리 이해되지는 않습니다. 이 기사는 이러한 모든 기술을 제시하고 이러한 용어를 설명하는 가장 쉬운 방법을 택하고, 작은 소프트웨어를 개발하고 언급된 모든 도구를 사용하여 프로덕션 제공을 위해 준비하는 자습서 형식으로 마무리합니다.

Java, Spring Boot, Docker, 클라우드, Amazon Web Services, 지속적 통합

JVM 문제를 처리하는 것이 지겹습니까? Java 앱을 Dockerize합니다.
트위터

이 도구를 사용하는 이유는 무엇입니까?

Docker로 배포 간소화

"Write Once, Run Anywhere"는 코드를 어디에서나 실행할 수 있는 JVM(Java Virtual Machine)과 같은 기술을 탄생시킨 획기적인 개념이었습니다. 그리고 수십 년이 지난 지금 여기에서 Docker라는 것이 IT 커뮤니티에 제공되고 있습니다. Docker는 소프트웨어를 배치하고 원하는 거의 모든 곳에서 고통 없이 실행할 수 있는 포함 도구입니다.

그러나 Java 개발자는 Docker를 보고 "왜 필요한가요? 마스터 포터블 솔루션으로 잘 알려진 JVM이 이미 있습니다."라고 말할 수 있습니다. 하지만 그렇습니까?

"한 번 작성하고 어디에서나 실행"은 좋은 소리를 내고 잘 재생됩니다. 적어도 대부분의 경우. 여러 JVM 벤더, 여러 Java 버전, 여러 운영 체제, 위의 모든 것의 다양한 순열 및 조합을 만날 때까지. 그런 다음 우아한 "한 번 작성, 어디서나 실행" 패러다임에서 비생산적인 "한 번 작성, 모든 곳에서 디버그 "의 함정으로 전환하는 자신을 발견하게 됩니다.

그리고 바로 여기에서 Docker가 도움이 되어 하루를 절약할 수 있습니다.

Docker는 소프트웨어의 개발, 테스트 및 배송을 단순화합니다. 테스트할 소프트웨어가 있는 경우 Docker 컨테이너에 넣으면 실행되며 관련된 모든 당사자가 쉽게 설치할 수 있습니다.

관련: Docker 시작하기: Devops 단순화

Spring Boot로 개발 속도 향상

"어디서나 실행" 슬로건이 도입된 지 10년도 채 되지 않아 Spring 프레임워크가 등장했습니다. 오늘날 Spring 생태계는 계속해서 번성하고 있으며 Spring Boot와 같은 가치 있는 Spring 기반 프로젝트를 많이 생산했습니다. Spring Boot 웹사이트에 명시된 바와 같이:

Spring Boot를 사용하면 실행할 수 있는 독립 실행형 프로덕션 등급 Spring 기반 애플리케이션을 쉽게 만들 수 있습니다.

Spring Boot를 사용하면 몇 분 만에 애플리케이션을 시작하고 실행할 수 있습니다. 소프트웨어 개발자는 소프트웨어 개발에 집중할 수 있으며 모든 구성을 수행하는 도구의 이점을 누릴 수 있습니다.

이 튜토리얼에서는 Spring Boot를 사용하여 마이크로 서비스를 개발할 것입니다.

Jenkins와 지속적 통합(CI)

DevOps는 개발자, 시스템 관리자, 테스터 및 궁극적으로 관련된 모든 당사자에게 소프트웨어 개발 및 제공 수명 주기를 최대한 고통스럽지 않고 원활하며 생산적으로 만드는 것을 목표로 소프트웨어 개발 및 시스템 관리 팀을 긴밀하게 통합하는 빠르게 성장하는 운동입니다. , 최종 사용자.

지속적 통합(CI)은 DevOps 혁명의 초석 중 하나입니다. 개발자가 코드 리포지토리에 코드를 커밋할 때마다 프로덕션에 전달(배포)하기 위해 자동으로 테스트되고 패키징된다는 아이디어입니다.

CI는 다음과 함께 진행됩니다.

  • 지속적인 전달 – 수동 트리거를 통해 프로덕션 배포에 대한 최종 사용자 비즈니스 테스트를 위해 준비된 패키지를 자동으로 전달합니다.
  • 지속적인 배포 – 패키지 제품을 프로덕션에 직접 자동 배포합니다.

CI 프로세스를 구현하는 데 사용할 수 있는 도구가 몇 개 이상 있습니다. 가장 인기 있는 것 중 하나는 오픈 소스 CI 도구인 Jenkins입니다. 천 개 이상의 플러그인과 그 뒤에 있는 거대한 커뮤니티가 있는 Jenkins는 지속적인 통합, 전달 또는 배포 구현에 대해 생각할 때 쉽게 선택할 수 있습니다.

자습서에서 Jenkins는 제품을 클라우드, 보다 구체적으로 Amazon(AWS) 클라우드에 제공하는 데 사용됩니다.

AWS를 사용한 클라우드 컴퓨팅

시스템 관리자 경험이 있는 경우 시스템 관리에 대한 걱정을 어깨에서 제거하는 것을 상상해 보십시오. 몇 가지 응용 프로그램이 있습니다. 얼마나 많은 리소스가 필요한지 알고 있지만 필요한 하드웨어 크기를 정확히 알지 못합니다. 당신이 추정을 하고, 자원을 구매하고, 시스템이 생산에 들어갑니다. 운이 좋다면 자신이 과대평가되고 필요한 것보다 더 많은 자원을 갖고 있다는 것을 알게 될 것입니다. 그러나 머피의 법칙이 주어지면 리소스 요구 사항을 과소 평가하고 엄청난 시간 압박 하에서 더 많은 메모리 또는 처리 능력을 얻기 위해 뒤죽박죽을 하게 될 가능성이 더 큽니다. 반대로 클라우드에 배포하는 경우 클라우드 공급자가 제공하는 유연성으로 시스템을 배치하고 필요에 따라 크기를 조정하기만 하면 됩니다. 클라우드를 사용하면 시스템 리소스 부족에 대해 걱정할 필요가 없으며 메모리 또는 CPU의 90%가 유휴 상태로 유지되는 것에 대해 걱정할 필요도 없습니다.

물론 어떤 공급자를 선택할지 결정하는 문제가 있습니다. 클라우드 전쟁은 여전히 ​​진행 중입니다. 컴퓨팅의 미래를 위한 Microsoft, Amazon 및 Google의 충돌은 최근 기술 세계 뉴스에서 찾을 수 있는 제목의 예입니다. 이 블로그에서는 현재 인기도와 시장 점유율을 기반으로 Amazon Web Services(AWS)를 선택했습니다.

AWS의 장점 중 하나는 가입 후 Amazon에서 많은 서비스를 제공한다는 것입니다.

AWS

이 자습서에서는 Elastic Compute Cloud EC2(더 구체적으로 Amazon EC2 Container Registry 또는 Amazon ECR) 및 Amazon S3(Simple Storage Services)의 두 가지 AWS 서비스를 사용합니다.

아마존 ECR

Docker 이미지를 어딘가에 저장해야 합니다. Amazon ECR은 관리형 AWS Docker 레지스트리 서비스입니다. Amazon ECR 웹 사이트에 명시된 대로:

… 개발자가 Docker 컨테이너 이미지를 쉽게 저장, 관리 및 배포할 수 있습니다. Amazon ECR은 Amazon EC2 Container Service(ECS)와 통합되어 개발에서 프로덕션으로의 워크플로를 단순화합니다. Amazon ECR을 사용하면 자체 컨테이너 리포지토리를 운영하거나 기본 인프라 확장에 대해 걱정할 필요가 없습니다.

아마존 S3

언급했듯이 우리가 개발하는 애플리케이션은 Amazon S3에 파일을 업로드할 Spring Boot 마이크로서비스가 될 것입니다. Amazon S3 웹 사이트에 명시된 대로:

…개발자와 IT 팀에 안전하고 내구성이 뛰어나며 확장성이 뛰어난 클라우드 스토리지를 제공합니다. Amazon S3는 웹 어디에서나 원하는 양의 데이터를 저장하고 검색할 수 있는 간단한 웹 서비스 인터페이스를 통해 사용하기 쉬운 객체 스토리지입니다.

실용적인 "방법" 튜토리얼

목표는 Amazon S3에 파일을 업로드할 Spring Boot 마이크로서비스 배포를 준비하는 것입니다. 단계는 다음과 같습니다.

  • 마이크로서비스 개발
  • 서비스가 고정될 빌드 프로세스 정의
  • Git 코드 리포지토리 호스팅을 위해 Bitbucket 사용
  • Bitbucket을 Jenkins와 통합하여 Gradle을 사용하여 애플리케이션 패키징
  • 원격 Amazon ECR에 푸시

다음은 필요한 모든 구성 요소를 설정하기 위한 자습서입니다.

  • Spring Boot 예제 애플리케이션 – Gradle을 사용하여 패키징되고 도커화된 마이크로 서비스
  • 새로운 Ubuntu 서버에 Jenkins 설치
  • Webhook을 통한 Jenkins와의 Bitbucket 통합
  • Jenkins 작업 구성
  • 애플리케이션이 포함된 Docker 이미지를 저장하는 Amazon ECR

전제 조건

AWS 클라우드 리소스를 사용하려면 먼저 Amazon에 등록해야 합니다. 등록하면 등록 후 12개월 동안 실습 경험을 제공할 목적으로 즉각적인 프리 티어 사용 혜택이 있는 계정을 얻게 됩니다.

언급했듯이 이 자습서에서는 Amazon S3 및 Amazon ECR을 사용합니다. 둘 다 서비스에 연결하려면 액세스 키가 필요합니다.

AWS에 가입한 후 계정 보안 자격 증명 으로 이동하여 액세스 키 를 선택하고 "새 액세스 키 생성"을 클릭합니다. 클릭하면 ID와 함께 키가 생성됩니다. 나중에 AWS Jenkins 통합을 구성하고 S3 파일 업로드를 개발할 때 사용할 것이므로 안전한 곳에 저장해야 합니다.

AWS 보안 자격 증명

다음 전제 조건은 Amazon S3 버킷(스토리지 컨테이너)이 필요하다는 것입니다. Spring Boot Service는 Amazon S3 스토리지에서 파일을 업로드 및 다운로드할 것입니다. 버킷 생성은 충분히 간단하며 몇 번의 클릭만 필요합니다. 이를 수행하는 방법에 대한 전체 설명은 버킷 만들기 설명서에 나와 있습니다.

또한 Bitbucket을 사용하여 코드를 호스팅하고 Jenkins에 대한 요청을 트리거하므로 Bitbucket 계정도 필요합니다. Bitbucket은 개발자를 위한 훌륭한 옵션이며, 주요 이점 중 하나는 생성할 수 있는 비공개 리포지토리의 양에 제한이 없다는 것입니다.

응용 프로그램 개발

Spring 어노테이션의 모든 세부 사항과 작동 방식을 설명하기 보다는 순수한 개발자의 관점에서 전체 설정의 더 어려운 부분에 초점을 맞출 것입니다. 즉, CI에 필요한 Linux, Jenkins 및 기타 도구의 설치 및 구성입니다. Spring Boot 마이크로서비스 애플리케이션을 포함하여 이 튜토리얼에서 사용된 모든 코드 예제는 프로젝트의 Bickbucket 리포지토리에서 사용할 수 있습니다.

우리의 응용 프로그램 구성은 간단합니다. StorageWebserviceApplication.java 파일에 Spring Boot 애플리케이션 진입점이 있습니다. 파일 업로드 및 다운로드 논리는 StorageService.java 에 있습니다. StorageController.java 는 파일 업로드 및 다운로드에 사용되는 API 엔드포인트를 포함하는 Rest 컨트롤러입니다. 다음은 프로젝트 계층 구조입니다.

프로젝트 계층

우리는 Gradle을 빌드 도구로 선택했으며 애플리케이션을 패키징하고 Docker 이미지를 구성합니다. 그래서 다음으로 Gradle 빌드 파일, 서비스 구성 요소 및 Dockerfile에 대해 설명합니다.

AWS API를 사용하려면 Gradle 사용에 대한 AWS 설명서에 정의된 대로 빌드 파일에 종속성을 포함해야 합니다.

요약하면 Gradle 스크립트의 AWS 종속성 구성 부분은 다음과 같습니다.

 buildscript { ... repositories { mavenCentral() } dependencies { ... classpath("io.spring.gradle:dependency-management-plugin:0.5.4.RELEASE") } } .. apply plugin: "io.spring.dependency-management" dependencyManagement { imports { mavenBom ('com.amazonaws:aws-java-sdk-bom:1.10.47') } } dependencies { .. compile ('com.amazonaws:aws-java-sdk-s3') }

이전에 언급했듯이 Amazon S3에 파일을 업로드할 때 S3 버킷 에 파일을 업로드합니다.

버킷에 연결하려면 Amazon S3 클라이언트에 자격 증명이 제공되어야 합니다. 자격 증명은 이전에 만든 액세스 키입니다. application.properties 파일에서 액세스 키 ID와 값을 정의합니다. 버킷 이름을 toptal-s3-example 지정했습니다.

application.properties

이제 주요 서비스 구성 요소는 다음과 같습니다.

 @Service public class StorageService { @Value("${aws.accesKeyId}") private String awsAccessKeyId; @Value("${aws.secretKey}") private String awsSecretKey; @Value("${aws.bucketName}") private String awsBucketName; private AWSCredentials credentials; private AmazonS3 s3client;; @PostConstruct public void init(){ credentials = new BasicAWSCredentials(awsAccessKeyId, awsSecretKey); s3client = new AmazonS3Client(credentials); } public void uploadFile(MultipartFile file) throws IOException { File fileForUpload = transformMultipartToFile(file); s3client.putObject(new PutObjectRequest(awsBucketName, file.getOriginalFilename(), fileForUpload)); } public InputStream downloadFile(String amazonFileKey) throws IOException { S3Object fetchFile = s3client.getObject(new GetObjectRequest(awsBucketName, amazonFileKey)); InputStream objectData = fetchFile.getObjectContent(); return objectData; } …

StorageServiceapplication.properties 파일에서 자격 증명을 읽고 이를 사용하여 BasicAWSCredentials 객체를 인스턴스화한 후 AmazonS3Client 객체를 인스턴스화합니다. 다음은 Amazon S3 클라이언트 객체에서 파일 업로드를 위해 putObject 를 호출하고 파일 다운로드를 위해 getObject 를 호출하는 간단한 문제입니다.

Docker 컨테이너 내에서 서비스를 실행하고 Gradle 빌드 프로세스 중에 Docker 이미지를 빌드합니다. 다음과 같이 build.gradle 파일을 추가로 구성하여 이를 수행합니다.

 buildscript { ... dependencies { ... classpath('se.transmode.gradle:gradle-docker:1.2') } } ..... apply plugin: 'docker' ... task buildDocker(type: Docker, dependsOn: build) { push = false applicationName = "storageservice" dockerfile = file('src/main/docker/Dockerfile') doFirst { copy { from jar into stageDir } } }

Buildscript 부분과 apply plugin 은 꽤 표준적입니다. 또한 src/main/docker/Dockerfile 에 저장된 Docker 구성을 읽고 JAR 파일을 Docker 빌드에 복사하는 buildDocker 작업을 정의했습니다.

Dockerfile에는 이미지를 준비하는 데 사용할 순수 Docker 명령 목록이 포함되어 있습니다.

 FROM frolvlad/alpine-oraclejdk8 ADD storageWebService-0.0.1-SNAPSHOT.jar storageService.jar EXPOSE 8080 CMD ["java", "-Djava.security.egd=file:/dev/./urandom", "-jar", "/storageService.jar"]

애플리케이션을 실행하기 위한 전제 조건은 JVM(Java Virtual Machine)을 설치하는 것입니다. Docker는 Java가 설치된 이미지 목록을 제공하며 최소 5MB Alpine Linux를 기반으로 가장 작은 이미지 중 하나를 선택합니다. frolvlad/alpine-oraclejdk8 이미지는 우리가 필요로 하는 모든 것을 갖추고 있으며 매우 작습니다(단 170MB).

FROM 명령은 언급된 이미지를 빌드할 기반으로 설정합니다. 빌드된 JAR 파일을 ADD 이라는 이름으로 컨테이너 파일 시스템에 storageService.jar 합니다. 다음으로 EXPOSE 명령을 사용하여 런타임에 포트 8080 에서 수신 대기하도록 Docker 컨테이너를 정의합니다. 그러나 이것은 호스트에서 8080 으로의 통신을 활성화하지 않습니다. 이미지가 완료되고 이미지를 실행하려면 docker run -p 8080:8080 amazonRepository/storageservice 명령을 사용하여 컨테이너에 포트를 게시해야 합니다. 여기서 amazonRepository 는 나중에 구성할 리포지토리입니다. 지도 시간. CMD 를 사용하여 컨테이너를 실행할 때 실행할 명령을 정의합니다. CMD 명령의 괄호 안에 있는 값은 단순히 컨테이너를 실행할 때 다음이 실행됨을 의미합니다.

 java -Djava.security.egd=file:/dev/./urandom -jar /storageService.jar

-Djava.security.egd=file:/dev/./urandom 옵션은 시작 중 JVM 지연을 완화하는 데 필요합니다. 생략하면 부팅 프로세스 중에 필요한 난수 생성 프로세스로 인해 애플리케이션 부팅이 매우 느려집니다.

이것은 "응용 프로그램 개발" 부분을 요약합니다. 이렇게 하면 나중에 Docker 컨테이너를 실행할 때 여기에서 만든 서비스가 자동으로 시작됩니다. 그럼, 지속적 통합 프로세스를 설정하는 데 필요한 다른 도구의 설치 및 구성을 시작하겠습니다.

애플리케이션 및 시스템 운영

먼저 Jenkins CI 도구를 설정할 깨끗한 Linux 서버가 필요합니다. 다음 지침은 특히 Ubuntu 14.04용입니다. 다른 Linux 배포판에서는 지침이 약간 다를 수 있습니다. 사용된 Jenkins 버전은 2.7.1이며 사용하는 Jenkins 버전에 따라 화면 및 안내가 약간 다를 수 있습니다.

따라서 Linux 서버 콘솔로 이동하여 필수 구성 요소 설치를 시작합니다.

JDK 전제 조건

JDK가 설치되어 있어야 합니다. 다음은 JDK8 설치 지침입니다.

 sudo add-apt-repository ppa:webupd8team/java sudo apt-get install python-software-properties sudo apt-get update sudo apt-get install oracle-java8-installer java -version

도커 설치

Jenkins가 Docker 빌드를 트리거할 수 있으려면 다음과 같이 docker-engine 을 설치해야 합니다.

 sudo apt-get install apt-transport-https ca-certificates sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D #create a docker list file sudo vi /etc/apt/sources.list.d/docker.list #add the following entry in the docker.list file (change trusty to #the release you are running on if you are running on different, ie. #xenial, precise...): deb https://apt.dockerproject.org/repo ubuntu-trusty main #save and exit the file sudo apt-get update apt-cache policy docker-engine sudo apt-get install docker-engine

이제 Docker 엔진을 설치했으므로 다음 명령을 사용하여 hello-world Docker 이미지를 시작하여 Docker가 올바르게 작동하는지 확인합니다.

 sudo docker run hello-world

Hello-world 이미지 출력은 다음과 같으며, 이를 통해 엔진이 정상적으로 작동하는 것을 확인할 수 있습니다.

Hello-world Docker 엔진

AWS 명령줄 인터페이스(CLI) 설치

다음으로 AWS CLI를 설치합니다. 나중에 Jenkins 작업 구성에서 CLI를 사용하여 AWS 인증 및 Amazon EC2 컨테이너 레지스트리에 대한 Docker 이미지 푸시 명령을 실행합니다.

AWS CLI를 설치하려면 Amazon CLI 설명서에 자세히 설명된 지침을 따릅니다.

두 가지 설치 옵션 중에서 Python 프로그램을 설치하고 관리하는 데 사용되는 패키지 관리 시스템인 Pip을 사용한 설치를 선택합니다. 다음 세 가지 명령을 실행하여 간단히 Pip 및 AWS CLI를 설치합니다.

 #install Python version 2.7 if it was not already installed during the JDK #prerequisite installation sudo apt-get install python2.7 #install Pip package management for python sudo apt-get install python-pip #install AWS CLI sudo pip install awscli

AWS ECR

빌드 프로세스의 마지막 단계로 Docker 이미지를 Amazon 컨테이너 레지스트리로 푸시합니다. Amazon 웹 서비스 콘솔에서 AWS EC2 Container Service를 찾습니다.

AWS EC2 컨테이너 서비스

왼쪽에서 Repositories 하위 메뉴를 선택하고 시작하기 를 클릭합니다.

AWS EC2 컨테이너 서비스

그런 다음 저장소 이름을 입력하고 다음 단계 버튼을 클릭하는 저장소 구성을 위한 첫 번째 화면이 표시됩니다.

AWS EC2 컨테이너 서비스

다음 단계 를 클릭하면 이미지를 저장소로 푸시하는 방법에 대한 지침이 포함된 화면이 표시됩니다.

AWS EC2 컨테이너 서비스

Docker 이미지를 빌드하고 레지스트리에 푸시하는 방법에 대한 예가 제공되지만 지금은 이에 대해 걱정할 필요가 없습니다. 이를 통해 저장소를 만들었습니다.

Jenkins 설치 및 구성

Jenkins를 설치하려면 셸에 다음 명령을 입력합니다.

 #Download Jenkins key and pipe it to apt-key tool, apt-key command #add will read from input stream, as defined by „–„. When added #apt will be able to authenticate package to be installed. wget -q -O - https://jenkins-ci.org/debian/jenkins-ci.org.key | sudo apt-key add - #create a sources list for jenkins sudo sh -c 'echo deb http://pkg.jenkins-ci.org/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list' #update your local package list sudo apt-get update #install jenkins sudo apt-get install jenkins

설치가 완료되면 Jenkins가 자동으로 시작됩니다. 다음 명령으로 서비스 상태를 확인하십시오.

 sudo service jenkins status

Jenkins는 Bitbucket Git 저장소에 연결할 것이며 이를 위해서는 Git을 설치해야 합니다.

 #install Git sudo apt-get install git

Jenkins는 Docker 이미지가 생성되는 동안 Gradle 빌드 프로세스를 트리거합니다. 이렇게 하려면 Jenkins 사용자를 docker 사용자 그룹에 추가해야 합니다.

 #add Jenkins user to docker user group sudo usermod -aG docker jenkins

빌드 프로세스 중에 Jenkins는 Docker 이미지를 Amazon ECR로 푸시합니다. 이를 활성화하려면 Jenkins 사용자에 대해 AWS를 구성해야 합니다.

먼저 jenkins 사용자로 전환해야 합니다. 그렇게 하려면 비밀번호를 설정해야 합니다.

 #change Jenkins password sudo passwd jenkins #switch to Jenkins user su – jenkins #configure AWS aws configure

aws configure 명령을 입력한 후 생성된 보안 액세스 키와 키 ID를 입력하기 시작합니다(이들은 이전 프로세스에서 생성한 자격 증명임). 제 경우에는 계정의 지역이 us-west-2 이므로 입력합니다. 또한 AWS 명령의 기본 출력 형식을 JSON으로 설정합니다.

AWS JSON 기본 출력 형식

이제 포트 8080에서 액세스할 수 있는 웹 콘솔을 통해 Jenkins 구성으로 이동할 수 있습니다.

URL에 액세스하면 다음 시작하기 화면이 표시됩니다.

젠킨스 시작하기

화면에 표시된 대로 비밀번호를 입력해야 합니다. 이 작업을 완료하면 설정 마법사에서 다음을 수행하라는 메시지를 표시합니다.

  • 설치할 플러그인을 선택합니다. 제안된 플러그인 설치 를 선택합니다.
  • 사용자 자격 증명을 입력하여 첫 번째 관리자 사용자 만들기

완료되면 저장 및 마침 을 클릭합니다. 이것으로 Jenkins 설정 구성을 마쳤습니다.

빌드 작업 정의를 시작하기 전에 몇 가지 추가 플러그인을 추가해야 합니다. Jenkins 관리 로 이동하여 플러그인 관리 를 클릭합니다. 사용 가능 탭에서 먼저 Bitbucket 플러그인 을 찾고 확인란을 선택하고 다시 시작한 후 다운로드 및 설치를 클릭 합니다.

젠킨스

그러면 다음 화면과 같은 화면이 표시됩니다.

Jenkins 플러그인 설치

플러그인 설치 후 작업을 설정하는 데 필요한 다음 추가 플러그인에 대한 프로세스를 반복합니다.

  • Gradle 플러그인
  • Docker 빌드 단계 플러그인
  • Cloudbees Docker 사용자 정의 빌드 환경 플러그인
  • 아마존 ECR 플러그인

우리가 사용하는 Docker 빌드 단계 플러그인은 Docker 데몬에 요청을 보냅니다. 이를 위해 포트 2375에서 TCP 소켓을 활성화해야 합니다. 이를 위해 etc/default/docker 에 있는 Docker 구성 파일을 입력합니다.

 sudo vi /etc/default/docker

여기에 구성에 다음 줄을 추가합니다.

 DOCKER_OPTS='-H tcp://127.0.0.1:2375 -H unix:///var/run/docker.sock'

파일을 저장하고 종료하고 Docker 및 Jenkins 서비스를 모두 다시 시작합니다.

 sudo service docker restart sudo service jenkins restart

Jenkins가 재부팅되면 Jenkins 콘솔로 이동하고 Manage Jenkins 에서 Configure System 을 선택합니다.

Jenkins 시스템 구성

Docker 빌더 섹션을 찾고 REST API URL에 http://localhost:2375 를 입력하고 적용 을 클릭하여 변경 사항을 확인합니다. 그런 다음 테스트 연결 을 클릭하여 모든 것이 정상인지 확인합니다.

도커 빌더

구성을 저장하고 Jenkins 작업 구성을 진행합니다.

작업 구성

Jenkins 홈 페이지로 이동하여 새 항목 을 만듭니다.

Jenkins 작업 구성

Freestyle 프로젝트 를 선택하고 다음 화면과 같이 프로젝트 이름을 입력합니다.

젠킨스 프리스타일 프로젝트

확인 을 클릭하면 작업 구성 페이지가 표시됩니다. Bitbucket Git 리포지토리로 푸시할 때마다 프로젝트가 빌드되기를 원합니다. 이를 달성하려면 먼저 연결할 저장소를 정의해야 합니다.

1단계: 소스 코드 관리

소스 코드 관리에서 Git을 선택하고 Bitbucket 리포지토리의 URL을 입력합니다. URL의 형식은 https://bitbucket.org/bitbucketUsername/repositoryName 입니다.

URL을 입력하면 Jenkins가 자동으로 연결 테스트를 시도합니다. 아직 자격 증명을 입력하지 않았기 때문에 연결할 수 없다는 오류가 표시됩니다.

젠킨스 오류

추가 드롭다운 목록을 열고 자격 증명 Jenkins 공급자를 클릭합니다.

자격 증명 Jenkins

Bitbucket 계정의 사용자 이름과 비밀번호를 입력하는 다음 화면이 표시됩니다.

Bitbucket과 Jenkins

새 자격 증명 레코드를 추가한 후 자격 증명 드롭다운에서 선택했는지 확인하면 소스 코드 관리 설정이 완료됩니다.

2단계: 트리거 빌드

트리거 빌드를 원격으로 확인하고 인증 토큰을 정의합니다. 임의의 보안 토큰을 정의해야 합니다.

빌드 트리거

3단계: Bitbucket 웹훅

Jenkins는 Bitbucket에서 사용할 URL을 이미 제공했습니다. Bitbucket 리포지토리 페이지로 이동하여 설정 메뉴에서 Web hooks 를 클릭합니다. 이후에 Add webhook 을 클릭하면 다음 화면이 표시되며 다음과 같이 입력됩니다.

Bitbucket 웹훅

URL의 구조는 http://JENKINS_URL _HOST:PORT/job/JOB_NAME/build?token=TOKEN 입니다.

Jenkins URL, 실행 중인 포트, 생성한 작업 이름 및 이전에 정의한 토큰과 함께 위의 값을 각각 입력합니다.

Webhook을 저장한 후 필요한 경우 편집하거나 새 코드를 푸시할 때마다 생성된 요청을 볼 수 있는 다음 화면이 제공됩니다.

Bitbucket 웹훅

이 구성을 사용하면 분기에 관계없이 각 리포지토리 푸시에서 웹훅이 트리거됩니다. Jenkins 측에서는 빌드를 트리거할 분기 푸시를 정의할 수 있습니다.

Bitbucket이 Jenkins에 코드를 푸시하려면 익명 읽기 액세스를 허용하도록 Jenkins 글로벌 보안을 재구성해야 합니다. 또한 설정을 위해 사이트 간 요청 위조를 방지하는 기본 Jenkins 옵션을 비활성화해야 합니다. 이렇게 하려면 Jenkins 관리 로 이동하여 글로벌 보안 구성 을 선택합니다. 익명 읽기 액세스 허용 을 선택하고 사이트 간 위조 악용 방지를 선택합니다 . 그런 다음 구성을 저장합니다.

글로벌 보안 구성

이것은 단순함을 위해 수행된다는 점에 유의하십시오. 전체 설정은 이 자습서의 범위를 능가하며 TLS 연결에서 역방향 프록시 뒤에서 Jenkins를 추가로 보호하고 CSRF 방지를 활성화하는 작업을 포함합니다.

4단계: Gradle 빌드

이제 Jenkins 작업으로 돌아가 계속 구성할 수 있습니다. 빌드 섹션에서 빌드 단계를 추가합니다. Invoke gradle script .

Gradle 스크립트 호출

이 양식에 다음을 입력합니다.

Gradle 스크립트 호출

화면에 표시된 대로 호스트에 Gradle을 설치할 필요가 없는 편리한 Gradle 기능인 Gradle 래퍼를 사용합니다. Make gradlew 실행 가능 상자를 선택했는지 확인하십시오.

작업에서 buildbuildDocker 를 지정합니다.

5단계: Docker 태그 이미지

빌드의 이 부분은 Gradle의 dockerBuild 작업에서 이전에 준비한 Docker 이미지에 태그를 지정합니다. 이를 위해 작업에 새 빌드 단계를 추가합니다. Docker 명령 실행 . 태그 이미지 명령을 선택하고 이미지 이름, 이미지를 푸시할 대상 리포지토리 및 태그를 설정합니다.

도커 태그 이미지

6단계: Amazon ECR에 Docker 푸시

마지막으로 이미지를 Amazon ECR에 푸시하는 방법을 정의해야 합니다. 이를 위해 새로운 Execute 셸 빌드 단계를 추가하고 AWS에 인증하고 Amazon ECR에 이미지를 푸시하도록 명령을 설정합니다.

 #region for our account is us-west-2 aws ecr get-login --region us-west-2 | bash #push the previously tagged image docker push 058432294874.dkr.ecr.us-west-2.amazonaws.com/springbootdocker:${BUILD_NUMBER} 

Amazon ECR에 Docker 푸시

이것으로 우리는 빌드 프로세스를 마쳤습니다. 새 코드를 리포지토리에 푸시하면 이 작업이 활성화되고 새 Docker 이미지가 Docker 레지스트리에 "자동으로" 업로드됩니다.

그런 다음 이미지를 docker-engine 이 설치된 곳으로 가져올 수 있으며 다음 명령으로 실행할 수 있습니다.

 docker run -p 8080:8080 amazonRepository/springbootdocker

이 명령은 S3 버킷에 파일을 업로드 및 다운로드하기 위한 다음 엔드포인트와 함께 Spring Boot 마이크로서비스를 시작합니다.

  • http://hostnameURL:8080/api/storage/upload
  • http://hostnameURL:8080/api/storage/download?fileName=xyz

Java 및 지속적 통합을 통한 추가 단계

항상 해야 할 일이 더 많습니다. 이 튜토리얼에서는 많은 내용을 다루었지만, 저는 이것을 더 배우기 위한 시작점으로만 생각합니다. Nginx와 같은 웹 프록시 서버 뒤에 Jenkins를 배치하고 TLS 연결을 설정하는 것은 더 많은 일을 할 수 있고 틀림없이 해야 하는 두 가지 예일 뿐입니다.

Docker 이미지는 Amazon ECR에서 사용할 수 있으며 배포할 준비가 되었습니다. 이제 수동으로 가져와 배포할 수 있습니다. 그러나 더 정밀한 솔루션은 이를 더 자동화하는 것입니다. CI는 첫 번째 단계일 뿐이며 다음 단계는 지속적 전달입니다. 고가용성은 어떻습니까? Amazon AWS EC2는 프로덕션 기반 서비스에 필수인 클러스터 환경에서 클라우드에 컨테이너를 등록하는 기능을 제공합니다. 지속적 배포 프로세스를 개발하는 좋은 예시는 다음 AWS 블로그 게시물에서 찾을 수 있습니다.

결론

전반적으로 우리는 매끄럽고 깨끗한 소프트웨어 개발 프로세스를 마련했습니다. 사용 가능한 도구를 활용하여 생산성을 극대화하는 데 도움이 되는 인프라를 만들었습니다. 이제 REST 엔드포인트가 있는 간단한 웹 서비스인 Java 서비스의 구성에 대해 걱정할 필요가 없습니다. Spring Boot 컨벤션이 모든 것을 처리하고 서비스 로직에만 집중하도록 합니다. 우리는 코드를 Bitbucket Git 리포지토리에 푸시할 때마다 Jenkins를 활용하여 새로운 Docker 이미지를 빌드하고 결국 클라우드가 Docker 이미지와 파일을 저장하도록 설정했습니다. Docker 이미지에 포함된 서비스를 배포할 때 운영 체제의 제한 사항이 없습니다(운영 체제에 docker-engine 이 설치되어 있는 한).