-
AWS 망 구성하고 서비스 배포하기네트워크 & 인프라 2022. 3. 28. 14:33
이번에는 AWS를 통해 망을 구성하고 서비스를 배포하는 미션을 진행했다.
배포부분은 heroku 배포를 제외하고는 진행해본 적이 없기에 이번 미션을 통해서 배포에 대해 많은 부분을 배울 수 있어 뿌듯했다! 👏
미션을 진행하던 도중 주의를 기울이지 않은 부분에서 문제가 발생한 부분도 있었지만
해당 부분을 해결하면서 더 많이 배울 수 있었다!😀
망 구성하기
망 생성
- VPC 생성
- Subnet 생성
- 외부망 : 64개씩 2개 (AZ 다르게 구성) (a, b)
- 내부망 : 32개씩 1개 (c)
- 관리용(bastion server) : 32개씩 1개 (d)
- 인터넷 게이트웨이 연결
- 라우팅 테이블 생성 (외부망용 1개, 내부망용 1개)
- 시큐어리티 그룹 설정
- 외부망
- 전체대역 : 8080 포트 오픈
- 관리망 : 22번 포트 오픈
- 내부망
- 외부망 : 3306포트 오픈
- 관리망 : 22번 포트오픈
- 관리망
- 자신의 공인 IP : 22번 포트 오픈
- 외부망
- 서버 생성
- 외부망에 웹 서비스 용도 EC2
- 내부망에 데이터베이스용 EC2
- 관리망에 베스천 서버 용도 EC2
- 베스천 서버에 Session Timeout 600s 설정
- 베스천 서버에 Command 감사로그 설정
- ubuntu 64 bit (Ubuntu Server 18.04 LTS)
- Instance Type : t3.medium
- 서브넷 : 서브넷 선택, 퍼블릭 IP 자동 할당 (활성화)
- 내부망은 퍼블릭 IP 자동 할당 비활성화 후 탄력적 아이피 생성
- Nat gateway 생성 (같은 리전 안에있는 a 서브넷에 생성)
- 연결 ip 할당
- 내부망 라우팅에서 nat gateway 0.0.0.0/0으로 추가 생성
- 스토리지
- 보안그룹 : 위의 포트에 맞춰서 선택
Bastion 서버
먼저 생성한 서버에 접속해보자.
발급받은 pem 키 위치에 가서 pem키에 권한 설정 후 접속을 실행한다.
$ chmod 400 [pem파일명] $ ssh -i [pem파일명] ubuntu@[SERVER_IP]
이제 Bastion 서버를 구성해보자.
Bastion이란 성 외곽을 보호하기 위한 돌출 부분이라는 뜻으로 Bastion 서버 란 서버가 악성 루트킷, 랜섬웨어 등으로 피해를 보더라도 Bastion 서버 재구성을 통해 서비스에 영향을 최소화 하기 위한 서버를 뜻한다. 예를 들어 22번 포트의 보안이 뚫리면 심각한 문제가 되지만 모든 서버에 동일 수준의 보안을 설정하면 Auto-Scaling 등 확정성을 고려한 구성과 배치되어 보안 설정의 일정 부분을 포기하게 된다. 이 경우 Bastion Server를 통해 문제를 해결할 수 있다. 추가로 Bastion 서버 구성시 서비스 정상 트래픽과 관리자용 트래픽을 구분할 수 있다는 이점이 있다. 서비스가 DDos 공격을 받는 것에 대비하여 Bastion 서버에 22번 포트를 오픈하고 그 서버에 보안을 집중할 수 있다.
## 우선 pem 키를 복사한다 $ cat [pem 파일명] $ ssh -i [pem 파일명] ubuntu@[베스천 서버 public ip] ## bastion 서버에 pem 키를 복사한다 bastion $ vi [pem 키] bastion $ chmod 400 [pem파일명] ## bastion 서버에서 pem 키를 이용해서 서비스용 서버를 실행한다. ## 같은 vpc 안에 위치하기 때문에 서비스 서버의 private ip로 진행한다. ## 먼저 telnet으로 22번포트 연결 가능 여부 확인 bastion $ telnet [서비스용 서버 private ip] 22 Connected ... ## 연결이 안되면 ufw 방화벽 확인 bastion $ sudo ufw enable bastion $ sudo ufw allow ssh bastion $ sudo ufw allow 22 ## 연결 되었으면 서버 접속 ## 우선 pem 키로 실행을 해야 ssh 키를 이용한 접속을 설정할 수 있다. bastion $ ssh -i [pem 파일명] ubuntu@[서비스용 서버 private ip] service $ exit ## ssh 키 설정 bastion $ ssh-keygen -t rsa ## 생성된 id_rsa.pub 복사 (~ubuntu@ 부분만 제거하고 앞까지 복사) bastion $ cat ~/.ssh/id_rsa.pub ## 권한이 없다고 하면 설정해준다. bastion $ sudo chmod 600 ~/.ssh/id_rsa bastion $ sudo chmod 644 ~/.ssh/id_rsa.pub bastion $ sudo nano ~/.ssh/authorized_keys ## 서비스용 서버 접속 bastion $ ssh -i [pem 파일명] ubuntu@[서비스용 서버 private ip] ## PasswordAuthentication yes 설정 service $ sudo nano /etc/ssh/sshd_config ## 아까 복사한 id_rsa.pub 키 복사 service $ vi ~/.ssh/authorized_keys service $ exit ## 베스천 서버에서 ssh 키를 이용해서 서버 실행 정상적으로 실행 되는 것을 확인 bastion $ ssh ubuntu@[서비스용 서버 private ip] service $ exit ## 베스천 서버에서 별칭 등록해준다. ## [서비스용 private ip] [별칭] bastion $ vi /etc/hosts ## 베스천 서버에서 별칭으로 접속 확인 bastion $ ssh [별칭]
홤경변수 설정
서버 환경변수를 설정하여(session Timeout 설정) 일정시간 작업을 하지 않을 경우 터미널 연결을 해제하도록 하자.
bastion $ sudo vi ~/.profile HISTTIMEFORMAT="%F %T -- " ## history 명령 결과에 시간값 추가 export HISTTIMEFORMAT export TMOUT=600 ## 세션 타임아웃 설정 bastion $ source ~/.profile bastion $ env
shell prompt 변경하여 bastion 등 구분해야 하는 서버의 shell prompt 를 설정하여 관리자의 인적 장애를 방지하자.
bastion $ sudo vi ~/.bashrc USERNAME=BASTION PS1='[\e[1;31m$USER\e[0m][\e[1;32m\t\e[0m][\e[1;33m\u\e[0m@\e[1;36m\h\e[0m \w] \n\$ \[\033[00m\]' bastion $ source ~/.bashrc
logger를 이용하여 감사로그를 작성하도록 남기도록 하자. 작업 이력 히스토리를 기록해두어야 장애 발생시 원인을 분석할 수 있다.
bastion $ sudo vi ~/.bashrc tty=`tty | awk -F"/dev/" '{print $2}'` IP=`w | grep "$tty" | awk '{print $3}'` export PROMPT_COMMAND='logger -p local0.debug "[USER]$(whoami) [IP]$IP [PID]$$ [PWD]`pwd` [COMMAND] $(history 1 | sed "s/^[ ]*[0-9]\+[ ]*//" )"' bastion $ source ~/.bashrc bastion $ sudo vi /etc/rsyslog.d/50-default.conf local0.* /var/log/command.log # 원격지에 로그를 남길 경우 local0.* @원격지서버IP bastion $ sudo service rsyslog restart bastion $ tail -f /var/log/command.log
환경 세팅 확인
환경 세팅 확인하자.
# 현재 위치를 확인합니다. $ pwd # 파일시스템별 가용공간을 확인합니다. $ df -h # 각 디렉토리별로 디스크 사용량을 확인합니다. $ sudo du -shc /* # 현재 경로의 파일들(숨김파일 포함)의 정보를 확인합니다. $ ls -al # 소스코드를 관리할 디렉토리를 생성하고 이동합니다. $ mkdir nextstep && cd nextstep # git 명령어의 위치를 확인해봅니다. $ which git && which java
프로그램 실행
자바 설치하고 작성한 프로젝트를 실행시켜 보도록 하자.
service $ sudo apt update service $ sudo apt install default-jre service $ sudo apt install default-jdk service $ java --version openjdk 11.0.14 2022-01-18 OpenJDK Runtime Environment (build 11.0.14+9-Ubuntu-0ubuntu2.18.04) OpenJDK 64-Bit Server VM (build 11.0.14+9-Ubuntu-0ubuntu2.18.04, mixed mode, sharing)
git 레파지토리 복사하자.
service $ git clone [git 레파지토리 url] ## 빌드 service $ cd [해당 폴더] service $ ./gradlew clean build # jar파일을 찾아본다. service $ find ./* -name "*jar" ## 어플리케이션 실행 후 정상 작동 확인 service $ java -jar [jar파일명] & service $ curl http://localhost:8080
- -Dserver.port=8000 옵션을 활용하여 port를 변경할 수 있다.
- 서버를 시작 시간이 너무 오래 걸리는 경우 -Djava.security.egd 옵션을 적용하자.
$ java -Djava.security.egd=file:/dev/./urandom -jar [jar파일명] &
터미널 세션이 끊어질 경우 background로 돌던 프로세스에 hang-up signal이 발생해 죽는 경우가 있는데 nohup 명령어를 활용하여 이를 방지할 수 있다.
$ nohup java -jar [jar파일명] 1> [로그파일명] 2>&1 &
로그를 확인하자.
# java applicaion이 남기는 로그를 확인합니다. $ tail -f [로그파일명] # 파일을 압축하고 파일 소유자와 모드를 변경해봅니다. $ tar -cvf [파일명] [압축할파일 또는 디렉터리] $ sudo chown [소유자계정명]:[소유그룹명] [file이름] $ chmod [옵션] [파일명] > https://ko.wikipedia.org/wiki/Chmod
브라우저에서 http://[서버 ip]:[port]로 접근
프로그램을 종료하자.
## 프로세스 pid를 찾는 명령어 $ ps -ef | grep java $ pgrep -f java ( losf -i : [포트번호]) ## 프로세스 종료 명령어 $ kill -2 [PID] (kill -9 [PID]) ## 명령 이력 확인 $ history
배포하기
개요
외부망에 웹 어플리케이션 배포 및 DNS 설정
- 운영환경
- 웹 어플리케이션 앞단에 Reverse Proxy 구성
- 외부망에 Nginx로 Reverse Proxy 구성
- Reverse Proxy에 TLS 설정
- 운영 데이터베이스 구성
- 웹 어플리케이션 앞단에 Reverse Proxy 구성
- 개발환경
- 설정파일 나누기
- JUnit : h2
- Local : docker(mysql)
- Prod : 운영 DB를 사용하도록 설정
- 데이터 베이스 테이블 스키마 버전 관리
- 설정파일 나누기
Reverse Proxy
우선 도커를 설치하자.
## 서비스용 서버 접속 bastion $ ssh [서비스용 서버 별칭] ## 도커 설치 service $ sudo apt-get update && \ sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common && \ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - && \ sudo apt-key fingerprint 0EBFCD88 && \ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" && \ sudo apt-get update && \ sudo apt-get install -y docker-ce && \ sudo usermod -aG docker ubuntu && \ sudo curl -L "https://github.com/docker/compose/releases/download/1.23.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose && \ sudo chmod +x /usr/local/bin/docker-compose && \ sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
Reverse proxy를 설정하자. 클라이언트로부터 요청을 받아 웹 서버로 요청을 전송하면 웹서버는 응답을 클라이언트가 아닌 Reverse proxy로 반환하고 리버스 프록시는 다시 이 응답을 클라이언트로 반환한다. 이를 통해 WAS는 비지니스 로직만 담당하여 TLS와 같은 부수적인 기능에 영향받지 않게 된다.
- 통상 Proxy Server
- LAN -> WAN의 요청을 대리 수행
- Reverse Proxy
- WAN -> LAN의 요청을 대리 수행
- 보안성 향상, 향상성 향상, 웹 가속 (압축/SSL 처리로 백엔드 리소스 확보/캐싱)
- Load Balancer
- 부하 분산, 서버상태 체크, 세션 관리
- Nginx
- Reverse Proxy 역할 + Load Balancer 역할 모두 수행
이용할 무료도메인 생성하자.
https://xn--220b31d95hq8o.xn--3e0b707e/
내도메인.한국 - 한글 무료 도메인 등록센터
한글 무료 도메인 내도메인.한국, 웹포워딩, DNS 등 무료 도메인 기능 제공
xn--220b31d95hq8o.xn--3e0b707e
로그인 하고 도메인을 등록한다
패킷 스니핑을 방지하기 위해 서버의 보안과 별개로 서버와 클라이언트간 통신상의 암호화(TLS)를 이용해 통신하도록 설정하자.
letsencrypt를 이용하여 무료로 TLS 인증서를 사용하자.
service $ docker run -it --rm --name certbot \ -v '/etc/letsencrypt:/etc/letsencrypt' \ -v '/var/lib/letsencrypt:/var/lib/letsencrypt' \ certbot/certbot certonly -d 'yourdomain.com' --manual --preferred-challenges dns --server https://acme-v02.api.letsencrypt.org/directory ## 오류발생 시 다음과 같이 권한 부여 후 다시 실행 docker: Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/create?name=certbot": dial unix /var/run/docker.sock: connect: permission service $ sudo chmod 666 /var/run/docker.sock
이메일 입력 후 약관동의 (Y), 메일 수신 (N)
인증서가 생성된것을 확인하면 바로 엔터를 누르지 말고 내 도메인에 생성된 인증서를 DNS TXT 레코드로 추가한다. 그 이후 터미널에서 엔터를 눌러준다.
## 잘 생성되었는지 확인 service $ sudo ls /etc/letsencrypt/live/[내 도메인] README cert.pem chain.pem fullchain.pem privkey.pem
생성한 인증서를 활용하여 Reverse Proxy에 TLS 설정을 해봅시다. 우선 인증서를 현재 경로로 옮깁니다.
service $ sudo cp /etc/letsencrypt/live/[내 도메인]/fullchain.pem ./ service $ sudo cp /etc/letsencrypt/live/[내 도메인]/privkey.pem ./
현재 폴더에 Dockerfile, nginx.conf 파일을 생성한다.
service $ vi Dockerfile FROM nginx COPY nginx.conf /etc/nginx/nginx.conf COPY fullchain.pem /etc/letsencrypt/live/[도메인주소]/fullchain.pem COPY privkey.pem /etc/letsencrypt/live/[도메인주소]/privkey.pem service $ vi nginx.conf events {} http { upstream app { server 172.17.0.1:8080; } # Redirect all traffic to HTTPS server { listen 80; return 301 https://$host$request_uri; } server { listen 443 ssl; ssl_certificate /etc/letsencrypt/live/[도메인주소]/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/[도메인주소]/privkey.pem; # Disable SSL ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # 통신과정에서 사용할 암호화 알고리즘 ssl_prefer_server_ciphers on; ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:DH+3DES:!ADH:!AECDH:!MD5; # Enable HSTS # client의 browser에게 http로 어떠한 것도 load 하지 말라고 규제합니다. # 이를 통해 http에서 https로 redirect 되는 request를 minimize 할 수 있습니다. add_header Strict-Transport-Security "max-age=31536000" always; # SSL sessions ssl_session_cache shared:SSL:10m; ssl_session_timeout 10m; location / { proxy_pass http://app; } } }
docker컨테이너 생성하고 Reverse Proxy를 실행시켜보자. (-it 옵션을 주어야 exit 해도 종료되지 않는다)
service $ sudo docker build -t nextstep/reverse-proxy:0.0.2 . service $ sudo docker run -d -it -p 80:80 -p 443:443 --name proxy nextstep/reverse-proxy:0.0.2
reverse proxy의 포트를 443으로 설정하였으므로, 서비스 서버(public)의 443 포트를 보안규칙에 0.0.0.0/0으로 열어주어야 한다.
git 폴더로 이동 해서 우리의 프로그램 실행시키자.
service $ ./gradlew clean build service $ find ./* -name "*jar" service $ java -jar [jar 파일 위치]
https://[내도매인]에서 올바르게 실행되는 것을 확인할 수 있다.
여기서 만약 서버 exit 해도 계속 살아있도록 하기위해서는 nohup을 사용한다.
service $ nohup java -jar [jar 파일 위치] &
운영 데이터베이스 연결
이제 운영 데이터베이스를 연결하자.
이번 미션에서는 컨테이너로 운영 DB 사용했다. (하지만 실무에서는 컨테이너를 DB로 사용해서는 안된다)
과연 도커(Docker) 컨테이너를 통해 데이터베이스를 운영하는 게 좋은 방법일까?
과연 도커(Docker) 컨테이너를 통해 데이터베이스를 운영하는 게 좋은 방법일까? 개인적으로 만들어보고 싶은 웹 어플리케이션이 있어서 도커를 활용해보려고 했는데 데이터베이스와 관련한 부
this-programmer.tistory.com
베스천 서버에서 내부망으로 들어가서 도커 실행해준다.
여기서도 -it 옵션을 해주어야 exit 해도 서버가 살아있는다.
bastion $ ssh -i [pem 파일명] ubuntu@[내부망 private ip] internal $ $ docker run -d -it -p 3306:3306 [운영DB 컨테이너]
Flyway
이제 프로젝트 설정파일을 나누어 실행 옵션에 따라서 데이터베이스 운용이 다르게 설정되도록 적용하자.
//application.properties spring.profiles.active=local handlebars.suffix=.html handlebars.enabled=true logging.level.org.hibernate.type.descriptor.sql=trace spring.jpa.properties.hibernate.show_sql=true spring.jpa.properties.hibernate.format_sql=true security.jwt.token.secret-key= eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIiLCJuYW1lIjoiSm9obiBEb2UiLCJpYXQiOjE1MTYyMzkwMjJ9.ih1aovtQShabQ7l0cINw4k1fagApg3qLWiB8Kt59Lno security.jwt.token.expire-length= 3600000
//application-test.propertes spring.h2.console.enabled=true spring.h2.console.path=/h2-console spring.datasource.url=jdbc:h2:mem:test spring.datasource.driverClassName=org.h2.Driver spring.datasource.username=sa spring.datasource.password=
//application-local.properties spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/test?useSSL=false&useUnicode=true&serverTimezone=Asia/Seoul&allowPublicKeyRetrieval=true spring.datasource.username=root spring.datasource.password=00000 spring.jpa.show-sql=true spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect spring.jpa.hibernate.ddl-auto=validate
//application-prod.properties spring.datasource.url=jdbc:mysql://[내부망 private ip]:3306/subway?serverTimezone=Asia/Seoul&characterEncoding=UTF-8&enabledTLSProtocols=TLSv1.2 spring.datasource.username=[사용자이름] spring.datasource.password=[패스워드] spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.jpa.hibernate.ddl-auto=validate spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
설정파일에 따라 프로그램을 실행할 때에는 다음과 같이 실행해준다.
$ java -jar -Dspring.profiles.active=prod [jar파일명]
여기서 Flyway 를 적용하여 데이터베이스 테이블 스키마를 관리하도록 하자. 운영중인 서비스의 경우 JPA등 ORM을 사용하여 기존의 테이블을 변경하는 것은 데이터 유실 , 참조 무결성 제약 등으로 인해 어려움이 존재하는데 이럴때 로컬에서 개발중일 때는 h2 등 in-memory 형태의 데이터베이스를 사용하여 빠르게 개발하고 운영 DB는 점진적으로 migration 하는 것이 유용한데 이때 사용하는 것이 Flyway이다.
gradle에 다음과 같이 flyway dependency를 추가해준다.
// mysql implementation 'mysql:mysql-connector-java' // flyway implementation('org.flywaydb:flyway-core:6.4.2')
src/main/resources/db/migration 폴더에 V1__init.sql파일을 생성해준다. (데이터베이스 초기 생성 테이블)
create table favorite ( id bigint auto_increment, created_date timestamp, modified_date timestamp, member_id bigint, source_station_id bigint, target_station_id bigint, primary key (id) ); create table line ( id bigint auto_increment, created_date timestamp, modified_date timestamp, color varchar(255), name varchar(255), primary key (id) ); create table member ( id bigint auto_increment, created_date timestamp, modified_date timestamp, age integer, email varchar(255), password varchar(255), primary key (id) ); create table section ( id bigint auto_increment, distance integer not null, down_station_id bigint, line_id bigint, up_station_id bigint, primary key (id) ); create table station ( id bigint auto_increment, created_date timestamp, modified_date timestamp, name varchar(255), primary key (id) ); alter table line add constraint line_name_unique unique (name); alter table station add constraint station_name_unique unique (name); alter table section add constraint fk_section_down_station_id foreign key (down_station_id) references station (id); alter table section add constraint fk_section_line_id foreign key (line_id) references line (id); alter table section add constraint fk_section_up_station_id foreign key (up_station_id) references station (id);
application-local.properties와 application-prod.properties에 다음과 같이 flyway옵션을 추가해준다. 기존 테이블이 존재하는 경우 다음과 같이 버전을 만들어 생성할 것이다.
spring.flyway.enabled=true spring.flyway.baseline-on-migrate=true spring.flyway.baseline-version=2
데이터테이블을 보면 다음과 같이 버전으로 스크립트가 관리되는 것을 확인할 수 있다.
이번엔 키, 계정 정보, 접속 URL등을 포함한 설정파일이 private 저장소에서 별도로 관리되도록 하자.우선 private 저장소를 생성 후 설정파일들을 모두 옮겨 놓는다.git 서브모듈 기능을 사용하여 특정경로의 private repository를 참조하도록 한다.$ git submodule add [자신의 private 저장소] ./src/main/resources/config
소스코드를 받을 때에는 submodule을 포함하여 clone 하도록 한다.
$ git clone --recurse-submodules [자신의 프로젝트 저장소]
설정파일이 변경된 경우 다음과 같이 반영해준다.git submodule foreach git pull origin main git submodule foreach git add . git submodule foreach git commit -m "commit message" git submodule foreach git push origin main
SonarLint
Sonarqube / ESLint 등 정적테스트, Maven / Gradle 등을 활용한 Build, JUnit 등을 활용한 동적 테스트를 통해 Code로 조기에 문제를 발견할 수 있다.plugin에서 SonarLint를 다운받아 적용해준다.Multirun
로컬에서 서버를 띄울 때, Multirun 플러그인을 활용하면 쉽게 서버를 띄울 수 있다.배포 스크립트 작성하기
#!/bin/bash ## 변수 설정 txtrst='\033[1;37m' # White txtred='\033[1;31m' # Red txtylw='\033[1;33m' # Yellow txtpur='\033[1;35m' # Purple txtgrn='\033[1;32m' # Green txtgra='\033[1;30m' # Gray PROJECT_NAME=infra-subway-deploy BRANCH="$1" CASE="$2" SLACK_MESSAGE="Deployed New App Successfully!" SLACK_URL=[slack web hook url] echo -e "${txtylw}=======================================${txtrst}" echo -e "${txtgrn} << 스크립트 🧐 >>${txtrst}" echo -e "${txtylw}=======================================${txtrst}" function check_df() { git fetch master=$(git rev-parse $BRANCH > /dev/null 2>&1) remote=$(git rev-parse origin $BRANCH > /dev/null 2>&1) if [[ $master == $remote ]]; then echo -e "[$(date)] Nothing to do!!! 😫" exit 0 fi } ## 저장소 pull function pull() { echo -e "" echo -e ">> Pull Request 🏃♂️ " git pull origin yunhalee05 } ## 프로세스 pid를 찾는 명령어 function findProcess() { CURRENT_PID=$(pgrep -f java.*.jar) echo -e "" echo -e ">> Current pid 📡 : $CURRENT_PID" } ## 프로세스를 종료하는 명령어 function killProcess() { if [ -z "$CURRENT_PID" ]; then echo -e ">> There's no running app." else echo -e ">> Kill Process 🪓" kill -15 $CURRENT_PID sleep 5 fi } ## gradle build function gradleBuild() { echo -e ">> Build Gradle... ⌛️" ./gradlew clean build } ## 새 어플리케이션 배포 function deployNewApp() { JAR_FILE=$(./build/libs/subway-0.0.1-SNAPSHOT.jar) echo -e ">>" nohup java -jar -Dspring.profiles.active=prod & } function send_slack() { curl -X POST --data "payload={\"text\": \"${SLACK_MESSAGE}\"}" ${SLACK_URL} } function deploy(){ cd $PROJECT_NAME pull; findProcess; killProcess; gradleBuild; deployNewApp; send_slack; } check_df; case $CASE in -f) deploy; exit 0;; esac echo -e ">> ${txtred} Are you sure to deploy new APP 🤔? ${txtrst} [Y/N] " read react case $react in [Yy]* ) deploy; exit 0;; esac
추가로 메일로 결과를 받기 위해서는 다음과 같이 설정할 수 있다.
$ sudo apt update $ sudo apt upgrade $ sudo apt install mailutils $ vi mail.sh #!/bin/bash TO=$1 function send_mail() { echo "Hello, this is $(hostname). --- $(date)" | mail -s "Mail Test $(date)" $TO } send_mail $ ./mail.sh [받을 메일 주소]
이번에 crontab을 이용해서 정해진 시간마다 배포스크립트가 작동하도록 설정하자.
$crontab -e ## *(분 0-59) *(시간 0-23) *(일 1-31) *(월 1-12) *(요일 1-7) ## 매주 금요일 5시 45분마다 배포스크립트 동작 45 5 * * 5 /home/ubuntu/deploy.sh
( 참고한 사이트 )
프로젝트 공방
NEXTSTEP
edu.nextstep.camp
공개키 인증으로 SSH Password 없이 접속하기
공개키 인증으로 SSH Password 없이 접속하기 SSH Key 만들기 SSH Key를 통해서 서버에 접속시 Unix 계열에서는 ssh-keygen 명령어를 이용하면 된다. Window OS에서는 SSH Client 프로그램이 자체적으로 생성 제공
blog.secuof.net
SSH 접속 시 공개키를 사용하여 접속하기
이미지도 함께 보려면 : http://blog.naver.com/choibit/140054432679 리눅스의 OpenSSH는 신뢰성있는 원격 접속을 지원해 준다. SFTP를 사용할 수 있도록 해주며, 암호화 통신을 할 수 있다. 이런 SSH는 더욱 강..
blog.pages.kr
https://aws.amazon.com/ko/premiumsupport/knowledge-center/ec2-linux-resolve-ssh-connection-errors/
EC2 인스턴스와 SSH를 연결할 때 "Connection Refused" 또는 "Connection Timed Out" 오류 해결
오류 메시지: "ssh: connect to host ec2-X-X-X-X.compute-1.amazonaws.com port 22: Connection timed out". 이 오류 메시지는 SSH 클라이언트에서 발생합니다. 이 오류는 서버가 클라이언트에 응답하지 않고 클라이언트
aws.amazon.com
https://happy-coding-day.tistory.com/178?category=807028
[우아한테크코스Pro] 그럴듯한 서비스 만들기(network) - 1 [4/9]
이번 4주차에서는 그럴듯한 서비스 만들기 라는 주제를 가지고 미션에 참여했습니다. AWS 를 활용해 네트워크를 구성하며, 네트워크 기본 개념을 학습했습니다. 위와 같은 네트워크 망을 구축하
happy-coding-day.tistory.com
https://deeplify.dev/back-end/spring/port-is-already-in-use
[스프링/Spring] Port 8080 is already in use 에러 해결 방법
스프링에서 가끔 발생하는 8080 포트는 이미 사용중이라는 에러에 대해서 알아보고 해결하는 방법까지 알아보도록 하겠습니다.
deeplify.dev
[ssh] Permission denied (publickey). 접속 오류 해결하기 - 재테크 인공지능
ssh 접속 시 Permission denied (publickey). 라는 오류가 계속 노출될 경우 해결방안입니다.
investechnews.com
https://steady-coding.tistory.com/439
[우아한 테크코스 3기] LEVEL 2 회고 - 배포 미션 (108일차)
안녕하세요? 제이온입니다. 사실 오늘 109일차인데 어제 밀려가지고 어제 회고부터 올리려고 합니다. 협업 미션 소개 이번 미션은 특별합니다. 그 전까지는 2명 내지 3명이서 페어 프로그래밍을
steady-coding.tistory.com
https://jerry92k.tistory.com/49?category=981718
[서비스배포] AWS에 서비스 배포하기 -<2> 서버 구성 및 서비스 배포
목표 시스템 구성도 서버 구성 외부망 1대 reverse proxy용 nginx 웹서비스용 자바어플리케이션 서버 내부망 1대 웹서비스에서 사용할 데이터베이스 저장소 실행 흐름 1) 사용자가 https://jerry92k-subway.n-
jerry92k.tistory.com
https://github.com/occidere/TIL/issues/116
docker 설치 후 /var/run/docker.sock의 permission denied 발생하는 경우 · Issue #116 · occidere/TIL
docker 설치 후 /var/run/docker.sock의 permission denied 발생하는 경우 상황 docker 설치 후 usermod로 사용자를 docker 그룹에 추가까지 완료 후 터미널 재접속까지 했으나 permission denied 발생 (설치 참고: https://b
github.com
https://velog.io/@max9106/AWS-EC2-Reverse-Proxy-WAS-MySQL
[실습] AWS EC2를 사용해 배포해보기(Reverse Proxy - WAS - MySQL)
AWS EC2를 이용해서 아래의 구조로 배포를 해보려고 한다. Reverse Proxy - WAS - DB
velog.io
[Docker] Docker로 DB 사용하기
노트북에 DB Server 안깔고 도커로 MySQL 이미지 받아서 Container 사용하기 Docker docker engine (server) 시스템 상의 서비스 client (docker command) 내부 또는 외부의 docker engine으로 명령을 전달 docker..
seokr.tistory.com
https://hyeon9mak.github.io/reverse-proxy-was-db-infrastructure/
ReverseProxy-WAS-DB 서버 구성하기
hyeon9mak.github.io
NEXTSTEP 인프라공방 - (미션 2) 서비스 배포하기 실습 - fistkim101
0. 들어가며 이번 미션은 일단 개념부터가 모르는 게 너무 많이 나와서 미션 수행 이전에 개념들을 공부하느라고 시간이 많이 소요되었다. 아래는 이번 미션을 수행하기 위해 이해해야할 개념들
fistkim101.github.io
https://wlsvud84.tistory.com/32
리눅스 크론탭(crontab)설정
안녕하세요 롯사입니다. unix 기반의 리눅스 시스템에는 예약된 작업을 주기적으로 실행시킬 수 있는 잡 스케쥴러 cron 있습니다. 보통 cron을 사용하는 목적은 고정된 시간과 날짜 그리고 간격에
wlsvud84.tistory.com
https://velog.io/@nefertiri/AWS-EC2-%EC%84%9C%EB%B2%84%EC%97%90-%EB%B0%B0%ED%8F%AC%ED%95%98%EA%B8%B0
AWS EC2 서버에 배포하기
AWS EC2 서버에 스프링 웹 애플리케이션 배포하기
velog.io
https://velog.io/@honux/Git-submodule-%EA%B0%84%EB%8B%A8-%EC%82%AC%EC%9A%A9%EB%B2%95-1
Git submodule 간단 사용법 1
깃 저장소 안에 또 다른 깃 저장소가 필요한 경우가 종종 생긴다. 이 때 사용하는 방법은 1) submodule 2) subtree 가 있다. 서브 모듈은 엄밀하게 말하면 내 저장소의 특정 커밋이 자식 저장소의 특정
velog.io
https://ecsimsw.tistory.com/entry/Flyway%EB%A1%9C-DB-Migration
Flyway와 DB Migration / 우리 팀에서 Flyway를 사용하는 이유
Flyway 소개하기 DB Migration DB Migration의 필요를 모를 수 있다. 솔직히 나는 몰랐다. 배포 후 데이터를 관리해본 경험이 없었고, 유지 보수 중 스키마 구조가 바뀌는 상황에 어떻게 대처하는지 생각
www.ecsimsw.com
https://hyeon9mak.github.io/reverse-proxy-was-db-infrastructure/
ReverseProxy-WAS-DB 서버 구성하기
hyeon9mak.github.io
https://dev-coco.tistory.com/85
[Spring Boot] MySQL & JPA 연동 및 테스트 (Gradle 프로젝트)
SpringBoot에서 MySQL 그리고 Spring Data JPA를 연동하는 방법에 대해 알아보도록 하겠습니다. 1. 프로젝트에 의존성 추가하기 build.gradle에 의존성을 아래와 같이 추가해줍니다. dependencies { implementatio..
dev-coco.tistory.com
https://velog.io/@max9106/AWS-EC2-Reverse-Proxy-WAS-MySQL
[실습] AWS EC2를 사용해 배포해보기(Reverse Proxy - WAS - MySQL)
AWS EC2를 이용해서 아래의 구조로 배포를 해보려고 한다. Reverse Proxy - WAS - DB
velog.io
https://stackoverflow.com/questions/64069312/ssh-connection-timed-out-on-ec2-ubuntu
SSH Connection timed out on EC2 Ubuntu
I am trying to secure my apache with Let's Encrypt on Ubuntu 18.04, I ran these commands: $ sudo add-apt-repository ppa:certbot/certbot $ sudo apt install python-certbot-apache $ sudo ufw enable...
stackoverflow.com
https://happy-coding-day.tistory.com/178?category=807028
[우아한테크코스Pro] 그럴듯한 서비스 만들기(network) - 1 [4/9]
이번 4주차에서는 그럴듯한 서비스 만들기 라는 주제를 가지고 미션에 참여했습니다. AWS 를 활용해 네트워크를 구성하며, 네트워크 기본 개념을 학습했습니다. 위와 같은 네트워크 망을 구축하
happy-coding-day.tistory.com
'네트워크 & 인프라' 카테고리의 다른 글
부하 테스트 ( + k6, grafana + influxdb, ngrinder) (0) 2022.04.14 웹 성능 진단하기 (0) 2022.04.14 Mac에서 docker, docker machine, virtualbox설치하기 (0) 2022.03.28 통신 확인하기 (0) 2022.03.23 통신망 ( + AWS 에서 망 분리하기) (0) 2022.03.23