기존에 Dockerfile에 직접 ENV를 작성해 배포할 이미지에 환경변수를 적용시켰는데, 이 방식은 보안과 유연성 측면에서 문제가 있습니다.
보안
Dockerfile은 AWS EC2에 보관되고 보통 애플리케이션 코드와 함께 평문 형태로 관리됩니다. 만약 해당 AWS EC2에 접근이 가능하다면 Dockerfile 열람을 통해 환경변수가 모두 외부로 노출될 수 있습니다.
유연성
Dockerfile에 환경 변수를 하드코딩하면, 배포 환경이 변경되거나 다른 설정을 사용해야 할 때 Dockerfile을 수정해야 합니다. 이는 유연성을 제한하고 유지 보수를 어렵게 만듭니다. 만약 환경 변수를 외부에서 주입할 수 있다면, Docker 이미지를 더 유연하게 관리할 수 있습니다.
하지만 Docker Secret 은 보안이 필요한 환경변수같은 정보를 평문 형태가 아닌 오브젝트로서 사용되고, Spring Boot와 같은 웹 애플리케이션 코드를 봐도 환경변수를 알 수 없습니다.
이제 Docker Secret 의 장점과 사용 목적은 확실하게 알았으니까, 이제 실제 AWS EC2와 이전까지 리팩토링하던 Spring Boot에 적용시켜 봅시다.
Ubuntu 22.04 t2.micro 프리티어 인스턴스를 하나 만든 후, 접속합니다.
Spring Boot도 올려야하고, MySQL도 필요하고, Docker Secret 도 해야하니까, 거기에 사용할 Docker를 설치합니다.
일단 apt를 사용해 Docker를 설치할 것이므로, apt를 업데이트합니다.
sudo apt update
https관련 패키지를 설치합니다.
sudo apt install apt-transport-https ca-certificates curl software-properties-common
docker repository 접근을 위한 gpg 키를 설정합니다.
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
docker repository를 등록합니다.
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
다시 apt를 업데이트합니다.
sudo apt update
apt를 사용해 docker-ce를 설치합니다.
sudo apt install docker-ce
설치된 docker 버전을 확인합니다.
docker --version
MySQL 설치 명령어를 입력합니다.
sudo docker pull mysql
설치된 docker 이미지를 확인합니다.
sudo docker images
mysql docker contatiner를 생성하고 실행합니다.
sudo docker run --name mysql-container -e MYSQL_ROOT_PASSWORD=1234 -d -p 3306:3306 mysql
이제 실행되고 있는 docker contatiner를 확인합니다.
sudo docker ps -a
bash를 이용해 MySQL docker contatiner 에 접속합니다.
sudo docker exec -it mysql-container bash
bash-4.4# mysql -u root -p
Enter password:1234
전 DBeaver를 사용해 DB에 접근할 것이므로 EC2의 보안 그룹 인바운드 규칙을 수정하고, SQL 쿼리문을 날려 외부접속을 위한 유저를 추가합니다. (저는 이번만 사용할 인스턴스이기 때문에 인바운드 규칙 IP를 모두 열어줬습니다.)
// 유저 추가
mysql > create user 'testUser'@'%' identified by '1234';
// 모든 IP 접속 허용
mysql > GRANT ALL PRIVILEGES ON *.* to testUser@'%';
mysql > GRANT ALL PRIVILEGES ON *.* to testUser@'localhost';
// 변경사항 적용
mysql > FLUSH PRIVILEGES;
// Spring Boot와 연동할 DB 생성
mysql > create database common;
Connect by : URL
URL : jdbc:mysql://본인IP:DB포트/DB이름?useSSL=false&allowPublicKeyRetrieval=true
Authentication
이후 Test Connection을 하면
연결이 됩니다.
이제 로컬에 있는 Spring Boot에서 DB 연결을 해봅시다.
Spring Boot의 application.properties를 수정합니다.
spring.profiles.active=local
spring.datasource.url=jdbc:mysql://본인IP:DB포트/DB이름?useSSL=false&allowPublicKeyRetrieval=true
spring.datasource.username=testUser
spring.datasource.password=1234
그리고 기존에 만들어놓은 Controller 에 Postman 을 사용해 요청을 보냅니다.
잘 동작합니다.