개발자는 기록이 답이다

NCP환경에서 Jenkins와 Docker로 CICD Pipeline 구축하기 본문

DevOps/Docker

NCP환경에서 Jenkins와 Docker로 CICD Pipeline 구축하기

slow-walker 2024. 3. 16. 10:48

 

 

프로젝트를 진행하면서 NCP 환경에서 Jenkins Pipeline을 이용해서 CICD를 구축했습니다.

우선 저는 비전공자이기 때문에 CICD과정에서 사용하는 리눅스가 너무 어렵게 느껴졌습니다. 왜 어떤 환경에서는 yum명령어가 되고 어떤 환경에서는 apt-get명령어를 사용해야하는지 이해가 안갔습니다. 그래서 멘토링 과정중에 리눅스 마스터 2급 자격증을 취득했고, 저와 같은 상황이신 분들은 리눅스 마스터 2급을 공부해서 기본기를 익히면 좋을 것 같다는 생각이 듭니다!


 

1. off-coupon

 

off-coupon은 네고왕 선착순 쿠폰 이벤트를 모티브로 개발한 프로젝트입니다.

https://github.com/f-lab-edu/off-coupon?tab=readme-ov-file

 

GitHub - f-lab-edu/off-coupon: 선착순 쿠폰 발행 서비스 입니다. (네고왕 이벤트 참고)

선착순 쿠폰 발행 서비스 입니다. (네고왕 이벤트 참고). Contribute to f-lab-edu/off-coupon development by creating an account on GitHub.

github.com

 

2. 네이버 클라우드 플랫폼 크레딧 지원

 

Naver Cloud Platform에서 무료 30만원의 크레딧(신규 크레딧10만원 + F-Lab 기본 크레딧 20만원)을 지원 받아 NCP를 무.료.로 사용하게 되었습니다. 이 프로젝트에서 사용한 NCP 클라우드 에 대해 소개하자면...

  • Server : 애플리케이션 서버1
  • Server : 애플리케이션 서버2
  • Server : Nginx 서버
  • Server : Redis 서버
  • Colud DB for MySQL 

 

2. CICD Pipeline (소프트웨어 개발 및 배포 프로세스 자동화)

 

CICD 파이프라인이란 무엇인지 개념 정의 부터 내리겠습니다. 빌드에서부터 배포까지 여러 단계가 있습니다. A가 끝나면 B를 실행하고 B가 끝나면 C를 실행하면서 순차적으로 이뤄지는걸 마치 파이프같다고 해서 파이프 라인이라고 부릅니다. 

 

CI(Continus Integration, 지속적인 통합)

어플리케이션의 새로운 코드 변경 사항이 정기적으로 빌드 및 테스트 되어 공유 레포지토리에 통합되는 프로세스를 의미합니다.

CI는 코드 저장소에서 변경 사항을 감지하고 자동으로 빌드 및 테스트를 수행하여 문제를 조기에 발견하고 해결합니다.

 

CD(Continuous Delivery/Continuous Depolyment, 지속적인 서비스 제공 혹은 지속적인 배포)

개발자의 변경 사항이 레포지토리를 넘어, 고객의 프로덕션(production)환경까지 릴리즈 되는 것을 의미합니다.

CD는 CI의 확장으로, 빌드 및 테스트가 성공적으로 완료된 후 소프트웨어를 자동으로 배포합니다.

 

 

CICD파이프라인을 실행하는데 사용되는 도구로서 빌드의 주체와 배포의주체를 정해야 합니다.

 

빌드의 주체

  • GithubAction
    • 장점
      • 클라우드에서 동작하기 때문에 어떤 설치도 필요없습니다.
      • 비교적 구현이 간단하고, Github 레포지토리와 직접 연동하여 설정할 수 있습니다.
    • 단점
      • Github이외의 코드 저장소(예 : SVN, Bitbucket, GitLab)를 사용하는 경우 구현이 어려울 수 있습니다.
      • 퍼블릭 Github에서는 Github Action이 지원되지만, 기업용 버전인 엔터프라이즈 버전에서는 Github Action을 도입하기가 어렵습니다.
  • Jenkins
    • 장점
      • 오랜 시간 동안 사용되어왔기 때문에 풍부한 기능과 플러그인을 제공합니다.
      • 맞춤 설정이 가능하며, 복잡한 빌드 및 배포 프로세스를 자유롭게 구축할 수 있습니다.
    • 단점
      • 보안에 취약하며, 전용 서버를 구축해야 한다는 번거로움과 추가적인 비용문제가 있습니다.

배포의 주체

  • FTP
    • 장점
      • 간단하고 직관적입니다
    • 단점
      • 보안 및 안정성이 낮을 수 있습니다.
      • 파일 버저닝이 되지 않아서 배포 실패 시 RETRY를 구현하기가 까다롭습니다.
  • 공유저장소(S3, Docker hub 등)
    • 장점
      • 안정적이고 안전한 배포를 보장합니다.
      • 스케일링과 관리가 용이하며, 다양한 옵션과 설정이 제공됩니다.
    • 단점
      • 초기 설정이 복잡할 수 있으며, 클라우드 서비스(S3) 사용 시 발생할 수 있습니다.
      • 공유 저장소가 없어지거나 문제가 생길 경우 관리가 어려울 수 있습니다.

 

2. 서비스 아키텍처

 

Github Action은 지난 프로젝트에서 진행해봤고, Jenkins를 하면서 제대로 성공한 적이 많기 때문에 Jenkins로 CICD를 구축해보고자 했습니다. 아래 그림은 현재 진행 중인 프로젝트의 아키텍처이고, 빨간 네모 박스 부분을 CICD로 구현할 예정입니다.

 

feature 브랜치에서 develop으로 pr 후 merge하기까지 시간이 꽤 걸리기도 하고, Bruteforce 공격때문에 서버를 꺼놓을 예정이라 현재 마지막으로 기능 구현한 feature 브랜치에서 코드를 수동으로 가져올게요. webhook을 거는건 ssh연결과정이랑 비슷해서 추후 프로젝트가 완성될쯤 webhook을 걸어보려고 합니다.

 

  • Jenkins Server :  NCP Server ubuntu 18.0.4
  • Spring Boot Server : NCP Server ubuntu 18.0.4
  • Github Repository
  • Docker Hub Repository

진행 순서는 다음과 같습니다.

 

  1. Jenkins Server에 Docker 설치
  2. Jenkins Server에 Docker를 이용하여 Jenkins 실행
  3. Jenkins 접속
  4. Jenkins Server 내부에서 Docker 사용할 수 있도록 Docker 설치
  5. Jenkins와 Docker Hub 연결하기 위해 Credential 설정
  6. Jenkins Server와 Spring Boot Server SSH 연결 하기 위해 Credential설정
  7. Jenkins Pipeline 구성
    • Spring Boot Project Github Repository Clone
    • Gradle Build
    • Docker Image Build
    • Docker Push -> Docker hub
    • Spring Boot Server SSH 연결
    • SSH 원격 서버에서 Docker Pull
    • SSH 원격 서버에서 Docker Run

3. NCP Server 만들기

 

서버를 만들기위해 요금 계산기를 살펴봤는데 VPC보다 Classic이 더 저렴하다고 나와있는데, 저는 이걸 CICD 구축하고 나서 확인했습니다.. 이것도 경험이죠, 일단 이번 포스팅은 CICD 구축 과정에 대해 적을 거라 추후에 변경하도록 해보겠습니다. 

  • VPC에서는 서버 타입이 micro를 지원 안하고, 서버 스펙도 더 높았습니다.

 


  • NCP 콘솔 > VPC 플랫폼 > Server > 서버 생성

처음 NPC환경을 사용하시는 분들은 NCP 사용 가이드, NCP 쉬운 가이드 를 참고하시면 됩니다. 하지만 너무 글자가 많다 싶고 어려우시면 인프런 강의에서도 설명되어있으니 참고하시면 좋을 것 같아요. 아래 방법으로 Jenkins Server와 Spring Boot Server를 생성해서 방화벽도 열어주고, 공인 IP 설정도 해놨습니다. 보안 상 bastion server를 구축해야 안전하지만, 아직 관련된 지식이 부족해서 전부 다 오픈하는 방식으로 사용했고, 사용하지 않을때는 정지시켜놓도록 했습니다.

 

 

 

서버 스펙 : Standard (vCPU 2EA, Memory 8GB, Disk 50GB)

 

 

4. Jenkins 서버 접속 후 Docker 설치 및 젠킨스 설치

SSH 접속을 위해 저는 Termius를 이용했습니다.

https://termius.com/free-ssh-client-for-mac-os

 

Free SSH client for Mac OSX

Best SSH and SFTP client for macOS that will make you more productive. Termius will save you up to 30 mins a day.

termius.com

 

 

비밀번호는 NCP > VPC > SERVER > 서버 관리 및 설정 변경 > 관리자 비밀번호 확인 에서 임시로 발급된 비밀번호를 사용하시거나,

해당 비밀번호를 이용해서 NCP > VPC > SERVER > 서버 콘솔 접속 > root 계정 로그인 후 아래 명령어로 변경해서 사용하면 됩니다.

passwd root

 

저는 일단 포스팅을 위해 jenkins-server-test 를 하나 더 만들었고, Terminus를 통해 해당 서버에 SSH 접속을 하면 아래처럼 나옵니다.

 

 

운영체제 종류 확인하기

 

리눅스에서 명령어를 사용하기 위해 운영체제가 어떤건지 확인합니다.

$ cat /etc/os-release
 

 

도커 설치
 # 현재 사용자를 루트(superuser) 권한으로 변경하여 새로운 쉘을 시작합니다. 
 # 현재 세션에서는 루트 권한으로 작업이 가능하지만, 새로운 터미널 세션에서는 다시 sudo를 사용해야 합니다.
 # 이후 명령어에서 sudo를 붙이지 않아도 됩니다.
$ sudo -i

 # apt 패키지 관리자를 사용하여 패키지 목록을 최신 상태로 업데이트 합니다.
$ apt update

 # apt 패키지 관리자를 사용하여 Docker를 설치합니다.
 # -y 옵션은 사용자에게 확인 메시지를 요구하지 않고 설치를 진행합니다.
$ apt install docker.io -y

 # systemctl 명령어를 사용하여 Docker 서비스를 부팅 시에 자동으로 시작하도록 설정하고,
 # 현재 세션에서도 즉시 시작합니다.
$ systemctl enable --now docker

 # Docker 서비스의 현재 상태를 확인합니다.
 # 서비스가 정상적으로 실행 중인지 여부를 확인하는 데 사용됩니다.
$systemctl status docker

 # 설치된 Docker의 버전을 확인합니다.
 # 설치가 올바르게 이루어졌는지 확인하고 사용 가능한 버전을 확인하는 데 사용됩니다.
$ docker version

 

docker 관리자 만들기
# 현재 사용자를 docker 그룹에 추가하여 Docker 명령어를 사용할 수 있도록 합니다.
$ usermod -aG docker root

# root 사용자의 그룹 정보를 확인합니다.
$ id root

 

  • uid=0(root) : 현재 사용자의 UID(사용자 식별자)가 0이며, 사용자 이름은 root입니다.
    • UID 0은 시스템에서 슈퍼 유저 또는 루트 사용자를 나타냅니다
  • gid=0(root): 현재 사용자의 기본 그룹의 GID(그룹 식별자)가 0이며, 그룹 이름은 root입니다. 
    • GID 0은 루트 사용자 그룹을 나타냅니다.
  • groups=0(root),115(docker): 현재 사용자가 속한 그룹 목록을 나타냅니다. 
    • 현재 사용자가 root 그룹과 docker 그룹에 속해 있다는 것을 나타냅니다. 이는 사용자 root가 루트 권한을 가지고 있으며 동시에 Docker 그룹에 속해 Docker 명령을 실행할 수 있다는 것을 의미합니다.
Docker command 자동완성 구성

 

도커 명령에서 docker pull, docker create 처럼 docker sub command를 자동완성 시켜주는 명령어입니다.

tab키 눌러서 자동완성 할때 사용하는데, bash 컴플리션 스크립트를 다운로드하여 /etc/bash_completion.d/docker.sh에 저장합니다.

# Docker CLI의 자동 완성 기능을 사용하기 위해 Docker 커뮤니티 에디션의 bash 컴플리션 스크립트를 다운로드합니다.
$ sudo curl https://raw.githubusercontent.com/docker/docker-ce/master/components/cli/contrib/completion/bash/docker \
  -o /etc/bash_completion.d/docker.sh

 

Jenkins 설치

 

Docker 컨테이너를 사용하여 Jenkins를 실행하고, 이후 해당 컨테이너에 접속하여 쉘을 실행하겠습니다.

# Jenkins를 Docker 컨테이너로 실행합니다.
$ docker run -d --name [컨테이너 이름] \
  -p 8080:8080 -p 50000:50000 \  # 호스트와 컨테이너 포트를 매핑합니다.
  -v /var/run/docker.sock:/var/run/docker.sock \  # 호스트의 Docker 소켓을 컨테이너 내부로 마운트합니다.
  --user root \  # 컨테이너 내부에서 root 사용자로 실행합니다.
  jenkins/jenkins:latest  # 사용할 Jenkins 이미지를 지정합니다.

# Jenkins 컨테이너에 접속하여 쉘을 실행합니다.
$ docker exec -it [컨테이너 이름] /bin/bash
  • docker run: 새로운 Docker 컨테이너를 실행하는 명령어입니다.
  • -d : 컨테이너를 백그라운드 모드로 실행합니다.
  • -name [컨테이너 이름] : 실행되는 컨테이너의 이름을 지정합니다.
  • -p 8080:8080: 호스트의 8080 포트를 컨테이너의 8080 포트로 매핑합니다. 이렇게 함으로써 호스트에서 컨테이너 내부의 웹 애플리케이션에 접근할 수 있습니다.
  • -p 50000:50000: 호스트의 50000 포트를 컨테이너의 50000 포트로 매핑합니다. Jenkins의 에이전트 연결에 사용됩니다.
  • v: 호스트의 파일 시스템 디렉토리나 파일을 컨테이너 내부로 마운트합니다.
  • /var/run/docker.sock:/var/run/docker.sock: 호스트의 Docker 소켓을 컨테이너 내부의 Docker 소켓에 연결하여 Docker 명령어를 컨테이너 내부에서 실행할 수 있게 합니다.
  • -user root: 컨테이너 내부에서 실행되는 프로세스의 사용자를 "root"로 설정합니다. 이는 컨테이너에서 루트 권한을 사용하여 실행됨을 의미합니다.
  • jenkins/jenkins:latest: 실행할 이미지의 이름과 태그입니다. 여기서 "jenkins/jenkins"는 이미지의 저장소와 이름이며, "latest"는 가장 최근 버전의 태그를 나타냅니다.

 

젠킨스 쉘에 접속하는걸 확인했고, 다시 한번 젠킨스 컨테이너가 잘 살아있는지 확인하겠습니다. 현재 쉘 세션을 종료하고 이전 사용자로 돌아가서 docker ps를 입력해보면 됩니다.

 

Jenkins 접속

 

공인 IP주소:8080으로 브라우저에 접속하면 아래처럼 Getting Started화면이 나옵니다.

 

초기 비밀번호는 젠킨스 컨테이너의 로그를 확인하면 알 수 있습니다.

$ docker logs [컨테이너 이름]

 

 

관리자 계정은 본인이 기억하기 쉬운 걸로 만들어주면 됩니다.

 

Jenkins Server 내부에서 Docker 설치

 

위에서 했던거랑 마찬가지로 젠킨스 컨테이너에서 Docker를 설치해줍니다.

젠킨스 컨테이너에서도 운영체제의 종류가 무엇인지 알아야 하겠죠! :)  마찬가지로 데비안 계열이라 apt-get 명령어를 이용해서 도커를 설치할 수 있습니다.

$ apt-get update && \
    apt-get -y install apt-transport-https \
      ca-certificates \
      curl \
      gnupg2 \
      jq \
      software-properties-common && \
    curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg > /tmp/dkey; apt-key add /tmp/dkey && \
    add-apt-repository \
      "deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \
      $(lsb_release -cs) \
      stable" && \
   apt-get update && \
   apt-get -y install docker-ce


-------------- 아래는 명령어의 세부 --------------
# 1. 패키지 목록을 최신 상태로 업데이트합니다.
apt-get update && \

# 2. Docker 설치를 위해 필요한 패키지들을 설치합니다.
apt-get -y install apt-transport-https \
  ca-certificates \
  curl \
  gnupg2 \
  jq \
  software-properties-common && \

# 3. Docker의 공식 GPG 키를 다운로드하여 추가합니다.
curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg > /tmp/dkey; apt-key add /tmp/dkey && \

# 4. Docker의 APT 저장소를 추가합니다.
add-apt-repository \
  "deb [arch=amd64] https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \
  $(lsb_release -cs) \
  stable" && \

# 5. 다시 한 번 패키지 목록을 최신 상태로 업데이트합니다.
apt-get update && \

# 6. Docker CE를 설치합니다.
apt-get -y install docker-ce

 

만일 위의 명령어를 사용해도 안된다면 아래 명령어를 사용해주세요.

apt install docker.io -y

 

docker ps를 통해 젠킨스 서버 내부에서도 docker가 동작되고 있는 것을 확인했습니다.

 

5. Jenkins에서 Credentials 설정

Jenkins와 Docker Hub 연결하기 위해 Credential 설정

 

이제 Jenkins에 접속한 상태에서 docker랑 docker pipeline을 설치해야 합니다

 

Dashboard > Jenkins 관리 > Plugins > Available plugins > docker, docker pipeline 플러그인 설치 및 재시작

 

$ docker restart [컨테이너 이름]

 

Dashboard > Jenkins 관리 > Credentials > Stores scoped to Jenkins의 (global) 클릭 > Add Credentials

 

Jenkins Server와 Spring Boot Server SSH 연결 하기 위해 Credential설정

 

Dashboard > Jenkins 관리 > Plugins > Available plugins > SSH Agent 플러그인 설치 및 재시작

 

$ docker restart [컨테이너 이름]

 

SSH credentials를 등록하기 위해서는 먼저 젠킨스 서버에서 SSH키를 생성해야 합니다.

SSH키를 생서하면 비밀번호를 입력하지 않아도 원격 시스템에 액세스 할 수 있으며,  암호기반보다 보안이 강화됩니다.

$ ssh-keygen

 

/root/.ssh 디렉토리에 id_rsa와 id_rsa.pub 파일이 잘 생성된걸 확인해봅시다.

$ cd /root/.ssh
$ ls -al

// Jenkins Server에서 생성된 publick key 확인
$ cat /root/.ssh/id_rsa.pub

 

// Spring Boot Server에서 authorized_keys 파일에 Jenkins public key 입력하기
$ vi authorized_keys

authorized_keys 경로

 

Dashboard > Jenkins 관리 > Credentials > Stores scoped to Jenkins의 (global) 클릭 > Add Credentials

// jenkins 서버에서 생성한 private key 확인
$ cat id_rsa

 

 

이렇게 하면 현재까지 등록한 credentials는 2개 입니다.

 

github webhook할때도 credentials를 등록해야 합니다. SSH 연결했는 방식과 비슷하게 하면 되는데, 이부분은 다른 블로그에서 잘 설명 되어있습니다!

 

6. Script 작성 전 CLI SSH 연결 확인하기

이제 Pipeline Script를 작성하는 일만 남았는데요.

먼저 SSH 연결이 잘 되는지 확인하기 위해 CLI로 SSH 연결 요청 먼저 해보겠습니다!

// Jenkins Server에서 Spring Boot Server에서 SSH 연결 요청
$ ssh -i ~/.ssh/id_rsa root@[Spring Boot Server 공인IP]

 

처음 연결하면 아래처럼 나오는데, 원격 호스트에 대한 신뢰할 수 있는 호스트키가 등록되지 않아서 나오는 메세지입니다.

호스트의 ECDSA 키 지문을 제공하고 사용자에게 계속 할 것인지 물어보는 건데, yes를 입력해주면 됩니다.

 

 

보이는 것 처럼 젠킨스 서버에서 normal server로 접속된걸 확인할 수 있습니다!

 

7. Jenkins Pipeline 구성

드디어 파이프라인 스크립트를 작성하는 일만 남았습니다. 우선 Pinpleline으로 Item을 만들어줍니다.

 

 

파이프라인을 통해 스크립트 파일(JenkinsFile)을 작성하면 차례대로 이벤트를 진행시킬 수 있습니다.

스크립트를 작성하는 방법은 2가지 방법이 있습니다.

  • Pipeline Script(default): 젠킨스 웹 내에서 스크립트를 작성하여 관리
  • Pipeline Script from SCM: 프로젝트 내에서 Jenkinsfile에 스크립트를 작성하여 관리

 

properties 환경변수는 Dashboard > item >configuation > "이 빌드는 매개변수가 있습니다" 에서 설정해주면 됩니다.

 

pipeline {
    
    agent any

    stages {
        stage('Checkout') {
            steps {
                git branch: '[브랜치명]', url: '[본인 Github Repository]'
            }
        }

        stage('Build Gradle') {
            steps {
                echo 'Build Gradle'
                
                dir('.') {
                    sh './gradlew clean build'
                }
            }
        }

        stage('Docker Image Build') {
            steps {
                echo 'Build Docker'
                script {
                    app = docker.build("[Docker Hub ID]/[이미지 이름]")
                }
            }
            post {
                failure {
                    error 'This pipeline stops here...'
                }
            }
        }

        stage('Push Docker') {
            steps {
                echo 'Push Docker'
                script {
                    docker.withRegistry('https://registry.hub.docker.com', 'docker-hub') {
                        app.push("${env.BUILD_NUMBER}")
                        app.push("latest")
                    }
                }
            }
            post {
                failure {
                    error 'This pipeline stops here...'
                }
            }
        }
        
        stage('Docker Run') {
            steps {
                echo 'Pull Docker Image & Docker Image Run'
        
                sshagent(credentials: ['ssh']) {
                    script {
                        sh "ssh -o StrictHostKeyChecking=no root@[Spring Boot Server IP주소] 'docker pull [Docker Hub ID]/[이미지 이름]:[태크]'" 
                        sh "ssh -o StrictHostKeyChecking=no root@[Spring Boot Server IP주소]'docker rm -f [컨테이너 이름]'"
                        sh """
                        ssh -o StrictHostKeyChecking=no root@[Spring Boot Server IP주소] \
                        'docker run -d --name [컨테이너 이름] \
                        -p 8080:8080 \
                        -e DB_HOST=${params.DB_HOST} \
                        -e DB_PORT=${params.DB_PORT} \
                        -e DB_DATABASE=${params.DB_DATABASE} \
                        -e DB_USERNAME=${params.DB_USERNAME} \
                        -e DB_PASSWORD=${params.DB_PASSWORD} \
                        -e REDIS_HOST=${params.REDIS_HOST} \
                        -e REDIS_PORT=${params.REDIS_PORT} \
                        -e REDIS_PASSWORD=${params.REDIS_PASSWORD} \
                        [Docker Hub ID]/[이미지 이름]:[태크]'"""
                        def containerId = sh(script: "ssh -o StrictHostKeyChecking=no root@[Spring Boot Server IP주소]'docker ps -q --filter name=[컨테이너 이름]'", returnStdout: true).trim()
                        echo "Container ID: ${containerId}"              
                        sh "ssh -o StrictHostKeyChecking=no root@[Spring Boot Server IP주소] 'docker exec ${containerId} env'"
                    }
                }
            }
        }
    }
}

 

 

정말 많은 삽질로 인해 64번만에 성공했습니다. 특히 develop properties를 github에 push 하지 않은 상태에서 젠킨스로 환경변수를 주는 부분이 제대로 되지 않아서 하루종일 헤맸습니다. 알고보니 Docker 명령어에 환경변수를 넣어주면 되더라구요:) 이것과 관련에서 추후에 어떻게 트러블 슈팅 과정을 거쳤는지 포스팅 올리도록 하겠습니다!

 

 

마무리로 Naver Cloud Platform 사용 후기

AWS의 1년 프리미어 서비스를 계속 이용하다가, 이번에 처음으로 Naver Cloud Platform을 사용하게 되었습니다. 처음에는 익숙하지 않은 환경이어서 몇몇 부분에서는 살짝 헤매기도 했습니다. 그러나 다행히도 사용 가이드가 한국어로 제공되어 있어서 마음이 편안해졌습니다.

또한, 이전에도 AWS를 사용하면서 Bruteforce 공격을 받은 적이 있었는데, Naver Cloud에서는 이런 공격 시 보안 알림 메일을 바로 받을 수 있다는 점이 좋았어요. 

 

원인은 인바운드 규칙을 모두 열어놓아서 발생한 것입니다. SSH 브루트포스 공격은 원격 SSH 서버에 접근하여 비밀번호를 무작위로 계속해서 시도하는 경우에 발생합니다. ACG관련 가이드도 참고해야 겠습니다.

  • 인바운드 규칙 : 서버 기준으로 트래픽이 들어오는 경우 (특정 ip 대역만 접근하도록 설정해야함)
  • 아웃바운드 규칙 : 서버 기준으로 트래픽이 서버에서 나가는 경우 (상관 없음)

채팅 상담원분께서도 알기 쉽게 설명해주셨던것 같습니다

 

 

한편으로는 개인적으로 아쉬운 점도 있습니다. 클라우드를 정확하게 이해하지 못해 이미 많은 비용이 들어간 상황입니다. 쉬운 가이드를 봤는데, 응애 개발자이고 처음 새로운 클라우드를 사용하려다보니 제 입장에서는 UI가 다르다고 느꼈어요. 알고보니 Classic과 VPC의 차이였는데요. 쉬운 가이드가 더 쉬웠으면 좋겠다...라는...혼자만의 생각이 있었습니다..하하하

 

그 외에는 크레딧을 사용해서 이것저것 해볼 수 있다는 점에서 너무 감사했습니다! 채팅 상담도 한국어로 할 수 있다는 최대의 장점🥲

 

 

참고 블로그

[Devops] Jenkins, Docker로 Spring Boot CI/CD 구축하기

Github Actions냐 Jenkins냐! 올바른 선택을 해봅시다

Jenkins와 Docker로 CI/CD pipeline 구축하기 (2)

[Jenkins] Docker를 이용한 Jenkins - Spring Boot 프로젝트 배포

Docker & Jenkins(Pipeline) & Spring boot & Gradle CI&CD 배포 방법

Jenkins Pipeline 파라미터 받을 때 주의사항!

[젠킨스] 젠킨스로 스프링부트 설정파일(applicaiton.properties, application.yml) 관리하기

https://froggydisk.github.io/21th-post/

[NCLOUD] 네이버 클라우드에서의 보안 – SERVER (ACG)

 

'DevOps > Docker' 카테고리의 다른 글

Docker 기초 이해와 개념정리  (0) 2024.02.28