AWS에 Jenkins를 구축해보자 - (3) Jenkins 초기설정

Jongwon·2023년 10월 11일
1

에피메테우스

목록 보기
3/6
post-thumbnail

이전 단계

이전 게시글을 따라오셨다면 현재는 아래와 같은 상태일 것입니다.

  • VPC 설정이 완료되었고, Private Subnet 안에 Jenkins EC2, Public Subnet안에 Bastion EC2가 있다.
  • Jenkins가 EC2 내부에서 실행중이다.
  • private EC2의 Key가 Bastion EC2 내부에 있다.
  • 8080 포트가 Bastion Host에 대해 개방되어 있다.

SSH Tunneling

Bastion Host가 생성되어 있으니, SSH Tunneling을 통해 내 Port에서 Jenkins의 Port로 포트포워딩이 가능합니다.

로컬에서 8080으로 열게된다면 이후 Spring Boot와 충돌이 발생할 수 있으므로 9000:8080으로 포워딩을 해보도록 하겠습니다.

SSH Tunneling

  1. WSL에서 bastionKey.pem의 위치로 이동합니다.

  2. 아래 형식으로 명령어를 실행합니다.
    ssh -i [bastion 키 위치] -A - L localhost:[내가 열 포트, 9000]:[jenkins private ip]:8080 ec2-user@[bastion public ip]
    ex=> ssh -i "~/keys/bastionKey.pem" -A -L localhost:9000:10.100.0.132:8080 ec2-user@52.78.112.86

Bastion Host가 Amazon Linux가 아니라면, ec2-user 대신 다른 값(ubuntu)가 들어갈 수 있습니다. 인스턴스 상세 페이지에서 연결 버튼을 눌러 user@ip-address를 확인할 수 있습니다.

또한 jenkins를 custom으로 8080이외의 포트로 열었다면 해당 포트로 포워딩을 해야합니다. 만약 접속이 되지 않는다면 인바운드 설정이 되어있지 않을 확률이 높습니다. 해당 부분도 확인해주세요.

Flag 설명
-i : private key file을 이용하여 인증을 진행하겠다는 것을 알립니다.
-L : port forwarding 명령어입니다.
-A : 원격서버가 로컬의 ssh-agent에 연결하도록 하여 더이상의 인증이 불필요하게 합니다.


아래와 같이 Bastion으로 접속됩니다. 하지만 실제로는 내 로컬의 9000번 포트와 Jenkins의 8080포트가 연결되어 있습니다.

  1. 브라우저에서 localhost:9000으로 이동합니다.

이제 로컬에서 Jenkins Console로 접속할 수 있습니다.



EC2 가용 메모리 늘리기

비용 문제로 Jenkins를 t3.micro에서 돌리고 있지만, top 명령어를 확인해보면 메모리 공간이 부족한 것을 확인할 수 있습니다.

https://kth990303.tistory.com/361
위의 글에있는 명령어를 통해 Swap영역을 메모리 영역으로 사용하게 하면 조금 더 여유롭게 사용할 수 있습니다.



Jenkins 설정 전...

이제 AWS와 관련한 세팅은 거의 완료되었습니다. 깃헙과 연동하기 위한 설정들을 진행해보도록 하겠습니다.

AWS Lambda 설정

Lambda코드를 Python으로 작성할 예정이기 때문에 local에서 python이 설치되어 있어야 합니다.

Lambda 생성

람다부터 설정하겠습니다. 먼저 람다에게 역할을 부여해야 합니다.

1~3의 과정은 Root 계정으로 접속하여 Lambda 생성 시 IAM 계정 자동 생성을 선택하여 만든다면 생략 가능합니다.

  1. IAM -> 역할 -> 역할 만들기를 클릭합니다.

  2. AWS 서비스 -> 사용사례는 Lambda로 설정합니다.

  3. AWSLambdaVPCAccessExecutionRole권한을 추가합니다.

  4. Lambda 서비스로 이동합니다.

  5. 함수 생성을 클릭합니다.

  6. 아래와 같이 설정합니다. 이때 Root계정으로 진행중이라면 기본 Lambda 권한을 가진 새 역할 생성으로 선택해주세요.

함수 이름런타임아키텍처권한
자유, ex) webhook-jenkins최신 버전 Python, ex) Python 3.11x86_64기존 역할 사용

  1. 코드를 입력합니다.
import json
import requests

def lambda_handler(event, context):
    payload = json.loads(event['body'])

    relevant_changes = any(
        file.startswith("backend/epimetheus") 
        for commit in payload['commits'] 
        for file in commit['modified'] + commit['added'] + commit['removed']
    )
    
    body_content = event['body']


    if relevant_changes:
        jenkins_url = "http://10.100.0.132:8080/generic-webhook-trigger/invoke?token=***********"
        headers = {
            "Content-Type": "application/json"
        }
        response = requests.post(jenkins_url, data=body_content, headers=headers)
        return {
            'statusCode': 200,
            'body': response.text
        }
    else:
        return {
            'statusCode': 200,
            'body': 'No relevant changes detected'
        }

jenkins url은 http://[Jenkins EC2 IP주소:8080]/generic-webhook-trigger/invoke?token=[이후 Jenkins에서 지정할 토큰값]형식 입니다.
다음 글에서 Generic Webhook Trigger로 빌드 Trigger를 하게 되는데, 이 URL 형식을 지켜야 합니다.

Repository에서 /backend/epimetheus 아래에 Spring Boot Project가 존재하기 때문에 위와 같이 해당 위치의 파일에 커밋이 발생했을 때만 Lambda가 발생하도록 하였습니다.

  1. Lambda -> 계층으로 이동합니다.

  2. 계층 생성을 클릭합니다.

  3. 파이썬의 requests라이브러리를 받아 압축파일을 생성해야 합니다.
    pip3 install requests
    pip3 show requests
    아래 위치에 있는 폴더를 압축하여 계층 생성 페이지에서 zip 파일 업로드로 올립니다.

  4. 생성했던 Lambda에서 계층 추가를 클릭합니다.

  5. 사용자 지정 계층 -> 방금 추가한 계층 클릭 -> 추가를 클릭합니다.


VPC 관련 설정

  1. EC2 서비스로 이동합니다.

  2. 보안 그룹 -> 보안 그룹 생성을 클릭합니다.

  3. 아래와 같이 설정합니다.

보안 그룹 이름VPC아웃바운드 규칙
jenkinsLambdaGroup이전에 만든 VPC사용자 지정 TCP, 8080, 대상은 jenkins의 Security Group
  1. 다시 생성했던 Lambda에서 구성 -> VPC 편집을 클릭합니다.

  2. 생성했던 VPC를 선택합니다.

  3. 서브넷은 Jenkins가 존재하는 서브넷으로 선택합니다. 고가용성을 위해 여기에서는 private-subnet 2개를 모두 하겠습니다.

  4. 보안 그룹은 3에서 만든 보안그룹인 jenkinsLambdaGroup로 선택합니다.

  5. EC2 콘솔에서 Jenkins의 보안그룹으로 이동합니다.

  6. 인바운드 규칙 편집으로 8080포트를 jenkinsLambdaGroup에 대하여 개방합니다.


API Gateway 설정

  1. API Gateway 서비스로 이동합니다.

  2. Rest API를 구축합니다.

  3. 리소스 탭에서 작업 -> 리소스 생성을 클릭합니다.

리소스 이름리소스 경로CORS 활성화
trigger-jenkinstrigger-jenkinso
  1. 해당 리소스에서 메서드 생성 -> POST를 추가합니다.
통합 유형Lambda 프록시 통합 사용Lambda 리전Lambda 함수
Lambda 함수oap-northeast-2webhook-jenkins

  1. 작업 -> API 배포를 클릭합니다.

  2. 새 스테이지를 클릭하여 스테이지를 생성합니다. 이름은 자유롭게 하셔도 됩니다.

  3. 상단에 적혀있는 URL은 추후 Webhook에서 사용할 예정이니 기억해두시기 바랍니다.


Github Webhook 설정

앞서 언급했듯이 Private Subnet에 있는 Jenkins는 Github과 직접적으로 연동할 수는 없습니다. 대신, Github Webhook을 통해 Http 요청을 보내고, Lambda가 이를 받아서 처리하도록 하겠습니다.

  1. 깃헙 레포지토리의 Settings -> Webhooks로 이동합니다.

  2. Add webhook을 클릭합니다.

  3. Payload URL에 API Gateway에서 나왔던 URL을 입력합니다.

  4. Content type : application/json

  5. Secret : Github Enterprise Server에서만 요청을 받을 때 사용됩니다. 사용될 임의의 String값을 입력하시면 됩니다.




중간점검

현재까지 정말 많은 일을 완료했습니다.

  • SSH Tunneling으로 localhost 9000에서 Jenkins EC2의 8080포트로 포워딩됩니다.
  • Swap Memory 사용으로 EC2의 가용 메모리 크기가 증가했습니다.
  • Lambda 함수를 생성하였고, Jenkins EC2의 8080포트로 아웃바운드 하도록 설정했습니다.
  • API Gateway를 통해 URL을 생성하고, Lambda에 연결하였습니다.
  • Github Webhook을 설정하여 push시 Jenkins로 request를 보내도록 하였습니다.




Jenkins 설정

본격적으로 Jenkins 설정으로 넘어가보도록 하겠습니다.

초기설정

처음에는 위와같이 Admin Password를 입력하라는 창이 뜹니다. 하지만 이는 모르기 때문에 직접 들어가서 설정파일을 확인해야 합니다.

  1. ssh 명령으로 jenkins에 접속합니다.
    => 이때 bastion host에서 접속해야 합니다.

  2. 아래 명령어를 통해 데이터만 확인하겠습니다.
    sudo cat /var/lib/jenkins/secrets/initialAdminPassword

  3. 출력된 글자를 브라우저 창에 붙여넣습니다.

여기서부터 Jenkins 인스턴스가 인터넷에 접속할 수 있어야 합니다. 따라서 NAT 게이트웨이를 연결해 주겠습니다.

  1. 왼쪽의 Install suggested plugins로 설치하겠습니다.

  1. 설치가 완료되면 계정을 생성합니다. 이후 이 ID와 패스워드를 통해 콘솔에 접속할 수 있습니다

  2. Jenkins에 접근할 때 입력할 URL입니다. Private 영역에 있기 때문에 외부에선 접속이 안되고, Lambda등을 통해 VPC 내부에서 연결요청이 오기 때문에 [Jenkins IP]:8080으로 설정합니다.
    => http://10.100.0.132:8080

  3. 완료되면 콘솔창으로 이동하게 됩니다.


플러그인 추가

기본으로 제공되지 않았던 플러그인들을 설치합니다.

  1. Jenkins 관리 -> Plugins -> Available Plugins로 이동합니다.

  2. 아래의 플러그인들을 추가합니다.

  • AWS Credentials
  • Pipeline: AWS Steps
  • Amazon EC2
  • AWS CodeDeploy
  • Generic Webhook Trigger
  1. Jenkins를 재시작합니다.

  2. Jenkins 관리 -> Tools -> Add JDK로 본인의 프로젝트에 맞는 JDK를 추가합니다. tar.gz파일이 있는 링크를 올리면 됩니다.
    => 다음 링크 글을 참조해주세요

  3. Gradle도 추가해줍니다.

  4. Apply & Save를 진행합니다.



결과

  • SSH Tunneling으로 localhost 9000에서 Jenkins EC2의 8080포트로 포워딩됩니다.
  • Swap Memory 사용으로 EC2의 가용 메모리 크기가 증가했습니다.
  • Lambda 함수를 생성하였고, Jenkins EC2의 8080포트로 아웃바운드 하도록 설정했습니다.
  • API Gateway를 통해 URL을 생성하고, Lambda에 연결하였습니다.
  • Github Webhook을 설정하여 push시 Jenkins로 request를 보내도록 하였습니다.
  • Jenkins 초기 Plugin 설정을 진행했습니다.

다음 글에서는 Pipeline과 CodeDeploy 설정을 하며 마무리를 하도록 하겠습니다.

profile
Backend Engineer

0개의 댓글