2024. 1. 20. 20:02ㆍTechnology[DevOps]
[ 이번 게시글에서 구현할 사항 ]
- GitHub Actions 를 이용해 CI/CD 환경을 구축합니다.
- Reusable Template 을 만들어 여러 Repo 간 Actions 코드를 공유하여 새로운 Repo 생성 시 CI/CD 환경 구축을 단순화합니다.
1. GitHub > Actions > New workflow를 선택합니다. ( 처음 설정하는 경우 Actions 탭만 누르면 됩니다. )
2. 검색바에 gradle 검색 후 Java with Gradle 을 선택합니다.
3. 생성된 gradle.yml 파일을 수정합니다.
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle
name: Java CI with Gradle
on:
push:
branches: [ "master" ]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: Make gradlew executable
run: chmod +x ./gradlew
- name: Build with Gradle
run: ./gradlew bootJar
- name: Download Dockerfile
run: |
# jq 명령어를 사용하여 Dockerfile 부분 추출
dockerfile_content=$(curl -s [Dockerfile 저장위치] | jq -r '.content' | tr -d '"' | base64 -d)
# 추출한 Dockerfile 내용 출력
echo "$dockerfile_content" > Dockerfile
- name: Login to Docker registry
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
- name: docker build and push
run: |
docker build -t ${{ secrets.DOCKER_USERNAME }}/${{ secrets.repo }} .
docker push ${{ secrets.DOCKER_USERNAME }}/${{ secrets.repo }}
- name: executing remote ssh commands using password
uses: appleboy/ssh-action@master
with:
host: ${{ secrets.HOST }}
username: ${{ secrets.SERVER_USERNAME }}
key: ${{ secrets.KEY }}
script: |
[실행할 script 작성]
- on.push.branches 옵션은 해당 브랜치에 push 이벤트가 발생했을 때 해당 gradle.yml 파일을 실행합니다.
- permissions.contents 옵션은 해당 컨텐츠에 대한 권한을 부여합니다.
- jobs.build.runs-on 옵션은 아래 steps를 실행할 환경을 설정합니다.
- jobs.build.steps에는 순차적으로 실행할 job을 설정하는데, 형식은 name(선택사항)으로 이름을 적어주고 uses나 run으로 어떤일을 할지 적어줍니다. 여기서 uses는 이미 만들어져있는 것을 가져다쓰는 것이고 run은 직접 명령어를 적어준다는 의미입니다. with로 특정 파라미터를 지정할 수 있습니다.
아래는 제가 사용한 gradle.yml 파일의 steps에 대한 설명입니다.
1. checkout : GitHub의 코드를 Ubuntu-latest 환경에 복사합니다.
2. Set up JDK 17 : JDK 17버전을 설치합니다.
3. Make gradlew executable : gradlew의 실행권한을 부여합니다.
4. Build with Gradle : SpringBoot 코드를 gradlew bootJar 작업을 이용해 실행가능한 JAR파일을 생성합니다.
5. Download Dockerfile : 저의 경우 동일한 Dockerfile을 사용하므로 다른 Repo에서 Dockerfile을 Download 합니다.
6. Login to Docker registry : Docker Hub에 로그인 합니다.
7. docker build and push : 해당 JAR파일을 도커 이미지로 빌드 후 Docker Hub에 배포합니다.
8. executing remote ssh commands using password : ssh로 클라우드 서버에 접근 후 지정한 script를 실행합니다.
* 이 때 민감한 정보(ssh 접속정보 등)는 GitHub Secret을 이용해 암호화하여 사용합니다.
- Secret 등록
- Secret 사용
위 작성한 gradle.yml 파일에서 ${{ secrets.[설정한 변수명] }} 으로 Secret 변수를 사용합니다.
4. ssh 연결을 위해 rsa key를 생성합니다.
ssh-keygen -t rsa -b 4096 -C [이메일 입력]
위 명령어를 Ubuntu 환경에서 입력하게 되면,
public key는 /root/.ssh/id_rsa.pub 파일로 저장되고
private key는 /root/.ssh/id_rsa 파일로 저장됨을 확인할 수 있습니다.
/root/.ssh 폴더는 root 계정으로만 접근 가능하므로 root 계정으로 변경 후
cd /root/.ssh
# show public key
cat id_rsa.pub
# show private key
cat id_rsa
public key와 private key를 확인할 수 있습니다.
5. GCP를 이용하여 클라우드 환경을 구축한 경우 GCP 메타데이터에 등록합니다.
GCP 콘솔의 Compute engine > 설정 > 메타데이터 항목에서 SSH키에 추가를 해줍니다.
정상적으로 키가 입력이 되었으면 사용자 이름은 자동으로 입력이 됩니다.
6. public key를 authorized_keys로 복사를 합니다.
# public key를 authorized_keys 파일로 저장
cat id_rsa.pub >> authorized_keys
7. ssh 연결정보를 입력합니다.
위 작성한 gradle.yml 파일에서 ssh 연결을 하려면 파라미터 값으로 필요한 정보를 세팅해야합니다.
HOST : Compute engine의 IP 주소
USERNAME : Compute engine의 사용자 이름(터미널에서 맨 왼쪽에 뜨는 이름)
SSH_KEY : 위에서 생성한 rsa private key
위 값들은 GitHub Secret에 등록 후 gradle.yml 파일에서 Secret 변수를 사용하면 정상적으로 ssh 연결이 됩니다.
8. Actions 코드 재사용을 위해 Reusable Template을 만듭니다.
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle
name: Template for Java CI with Gradle
on:
workflow_call:
inputs:
repo:
required: true
type: string
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
[step 내용]
기존의 Actions 코드와 거의 동일하지만 on 부분이 Branch push 트리거에서 workflow_call로 바뀌어 외부에서 call했을 때 트리거가 되어 실행됨을 알 수 있습니다.
이 때 파라미터로 inputs 값을 받을 수 있고 각 input별 required 필수속성을 지정할 수 있고 type을 지정할 수 있습니다.
이렇게 받은 input값은 아래 jobs.build.steps 영역에서 ${{ inputs.repo }} 처럼 변수로 사용할 수 있습니다.
9. 기존에 push 이벤트로 트리거되던 부분을 Reusable Template 호출로 변경합니다.
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle
name: Java CI with Gradle
on:
push:
branches: [ "master" ]
permissions:
contents: read
jobs:
call-workflow-passing-data:
uses: [Reusable Template Repo 위치]/template.yml@[Branch명]
with:
repo: [전달할 파라미터 값]
secrets: inherit
master branch로 push 되었을 때,
기존엔 jobs.build.steps 영역에 실행할 로직을 작성했다면
이제는 jobs.call-workflow-passing-data를 사용하여 기존에 작성해둔 Reusable Template를 호출하고 전달할 파라미터값만 입력하는 방식으로 구현합니다.
이 때, secrets: inherit 로 작성해서 secret 변수를 일일이 전달하지 않고 가지고 있는 전체 secret 변수를 전달할 수 있습니다.
10. Repo 간 Secret 변수 공유를 위해 Organization Secret으로 설정합니다.
기본적으로 Repo 간 Secret 변수 공유가 되지 않으므로 매번 Repo를 새로 만들 때마다 Secret 변수를 설정해줘야하는 불편함이 있습니다.
이를 해결하기 위해 새로운 Organization을 만들고 해당 조직 내에 Secret 변수를 만들게 되면 조직 내의 Repo는 Organization Secret을 공유하여 사용할 수 있습니다.
11. Organization 을 만들게 되면 Intellij 같은 외부 앱들이 해당 조직 내의 Repo를 사용할 수 있도록 변경합니다.
기본적으로 Organization 은 Third Party의 접근을 제한하므로 Intellij 등에서 Push 등을 제한하고 있습니다.
이를 사용하려면,
위 화면에서 Third Party의 access를 허용할 수 있습니다.
'Technology[DevOps]' 카테고리의 다른 글
Kubernetes 환경 구축 ( Ubuntu ) - 6 (1) | 2024.09.04 |
---|---|
Kubernetes 환경 구축 ( Ubuntu ) - 4 (1) | 2024.01.17 |
K6를 이용한 트래픽 성능 테스트 (1) | 2024.01.09 |
Kubernetes 환경 구축 ( Ubuntu ) - 3 (1) | 2024.01.09 |
Kubernetes 환경 구축 ( Ubuntu ) - 2 (1) | 2024.01.06 |