학기 중에는 프로젝트 때문에 바빠서 글을 쓸 시간이 별로 없었다.
갑자기 글을 쓰게 된 것은 실수로 Docker + MYSQL 을 잘 굴리던 인스턴스를 날려버렸기 때문이다.
학과 프로젝트에서 사용할 테스트 서버로 친한 형의 서버를 사용하고 있었기에 별로 문제는 없었다.
하지만 오늘 한동안 연결이 불가능해지는 상황이 발생해서 그냥 다시 MYSQL을 올리기로 마음먹었다.
낮에 오라클 VPS에 도커 올리는 것 쯤이야 식은 죽 먹기지 하고 시작을 했는데...
한 4~5시간 이상 붙잡고 있어도 해결이 안되었다.
포기하고 저녁을 먹고 다시 붙잡으니 MYSQL에 접속하는 데 성공했다.
아예 인스턴스를 날리고 새로 만들어서 성공을 했고,
아마 Docker 내에 있는 MYSQL의 포트 설정이 문제였던 것 같다.
미래의 나에게, 혹은 다른 누군가에게 도움이 되었으면 좋겠다는 마음에, 기록을 남기고자 벨로그에 글을 남긴다.
오라클 클라우드에 이미 가입되어있다는 전제 하에 시작한다.
오라클 클라우드에 대한 대략적인 설명은 이 글에서 참고하길 바란다.
VM 인스턴스 생성을 클릭 한다.
이름을 적어주고 , 이미지는 Canonical Ubuntu 20.04로 한다.
Minimal로 하면 기본적으로 설치되는 패키지가 적어서 세팅에 더 오랜 시간이 걸린다.
미니멀하게 OS를 구성하고 싶다면 Minimal로 해도 무관하다.
중요한건 공용 IP 주소를 지정해주는 것.
공용 IP를 지정해주면 IP가 변경되지 않아
외부에서 접속할 때 고정된 IP로 인스턴스에 접속할 수 있다.
오라클에서 만들어주는 SSH 키 쌍을 저장한다.
전용 키(Private Key)와 공용 키(Public Key) 모두 로컬에 따로 보관해두는게 좋다.
직접 SSH키를 생성해서 사용한다면, 공용 키 파일 선택 or 공용 키 붙여넣기로 진행하면 된다.
전용 키 저장 버튼과 공용 키 저장 버튼으로 키 쌍을 받아 보관하자.
필자는 다른 인스턴스에 50GB를 할당해서, 이번 인스턴스에는 남은 50GB를 모두 할당하였다.
이제 생성 버튼을 누르면 인스턴스 생성이 진행된다.
생성이 완료된 모습이다.
빨간줄이 그어진 위치에 있는 공공 IP를 기록해둬야 한다.
서버(인스턴스)의 공공 IP이며, 가급적 외부에 노출되지 않는 편이 좋다.
SSH로 원격 접속을 할 때에도 사용된다.
개인키를 바탕화면에 꺼내둔다.
경로에 한글이 있으면 안된다. 계정명이 한글이면 주의. 다른 경로로 옮겨야 한다.
cmd, powershell이 아니라 putty로 접속해도 된다.
putty로 접속하는 방법은 구글에 많이 있으므로 참고하면 된다.
CMD를 켜서 다음과 같이 명령어를 입력한다.
ssh -i 개인키 ubuntu@아이피
yes를 입력하여 진행하면 ssh로 인스턴스에 접속이 된다.
만약 한번 같은 공공 IP로 ssh를 접속한 적이 있는 경우
이미지와 같이 이미 알려진 호스트키가 있다고 하는경우 다음 명령어를 입력한다.
ssh-keygen -R 호스트명
그리고 나서 다시 ssh 접속 시도를 하면 된다.
이렇게 접속된 모습을 볼 수 있다.
먼저 root의 비밀번호 설정을 한다.
sudo passwd root
그리고 ubuntu 계정의 비밀번호 설정도 해준다.
sudo passwd ubuntu
ssh 접속을 할 때 마다 개인키를 챙겨야 하니 피곤하다.
아이디와 비밀번호로 접속할 수 있게 하면 편하다.
ssh 디렉토리로 이동한다.
cd /etc/ssh
sshd 설정 파일을 건드리기 전에 백업본을 만들어둔다.
sudo cp sshd_config sshd_config.bak
sshd 설정 파일을 수정한다.
sudo nano sshd_config
원한다면 ssh 접속 포트도 바꿀 수 있다.
(포트를 변경한 경우 우분투 iptables 방화벽 설정을 따로 하여 허용해주지 않으면 접속 불가함)
만약 바꾼다면 오라클 클라우드에서 방화벽 설정을 바꾸고, 우분투 방화벽도 건드려줘야한다.
방화벽 관련 내용은 아래에서 다루겠다.
여기서 PasswordAuthentication을 yes로 바꾸고 저장한다.
기본은 no로 되어있다.
저장하고 나서는 ssh를 재실행해준다.
sudo service sshd reload
그리고 나서 cmd를 새로 하나 더 열어서 개인 키 없이 접속되는지 확인한다.
ssh ubuntu@공공 IP
접속에 성공했다면 개인키 없이 접속 설정은 끝난 것이다.
만약 root 계정을 원격 접속 허용하고자 한다면
sshd_config에서
PermitRootLogin을 yes로 바꾸고
ChallengeResponseAuthentication을 no로 설정해준다.
출처 : https://blog.lael.be/post/7678
제대로 사용하기 전에 업데이트를 해준다.
sudo apt update # 패키지 레포지토리 인덱스 갱신
sudo apt upgrade # 업그레이드 가능한 모든 패키지 업그레이드
업데이트가 오래 걸릴 수 있으니 아래에서 방화벽 설정을 진행하도록 한다.
오라클 인스턴스 페이지에서 서브넷을 클릭한다.
보안 목록에 항목을 클릭한다.
수신 규칙 추가 버튼을 누른다.
수신 규칙을 추가한다.
대상 포트를 MYSQL을 사용할 포트로 해두면 된다.
기본적으로 MYSQL은 TCP를 사용한다.
우분투는 기본적으로 iptables를 사용한다.
그런데 오라클 VPS는 오라클에서 별도의 방화벽을 제공하므로 리눅스 자체의 방화벽을 사용할 일이 없다.
기본적으로 iptables는 서버가 재시작되는 경우 설정이 되돌아가버리는데 설정을 따로 하는데 시간이 많이 소요된다.
방화벽을 사용할 것이라면 iptables를 날리고 ufw를 활성화 하여 사용하라고 한다.
그래서 iptables를 사용 중지하기로 했다.
# 방화벽 사용 중지
sudo iptables -F
# 방화벽 작동 목록 확인
sudo iptables -L
# 방화벽 정책 영속화 패키지 설치
sudo apt install -y iptables-persistent netfilter-persistent net-tools
# 영속화
sudo netfilter-persistent save
이제 도커 설치를 진행한다.
# 도커 다운로드 및 설치
curl -fsSL https://get.docker.com/ | sudo sh
위 명령어를 입력하면 자동으로 도커가 설치된다. 아주 간편하다!
docker는 기본적으로 sudo 권한이 필요한데, 사용할 때 마다 sudo를 입력하기 귀찮으니
현재(ubuntu) 계정에 권한을 추가해준다.
# 현재 계정에 docker 권한 추가하기
sudo usermod -aG docker $USER
$USER 대신 사용자명을 넣으면 해당 계정에 권한을 부여한다.
로그아웃 하고 다시 들어오면 권한이 적용된다.
이제 도커에 MySQL을 이미지를 올려보자.
# 최신 mysql 다운
docker pull mysql
# mysql 8.0.17 버전 이미지 다운
docker pull mysql:8.0.17
# 새로 추가된 프리티어 arm 아키텍쳐에서는 mariadb 사용
docker pull mariadb
버전을 명시하면 해당 버전으로 다운을 할 수 있다.
다운하는데 시간이 좀 걸릴 수 있다.
docker에 이미지를 올릴 때 명령어를 사용해서 올리는데
docker-compose 를 사용하면 yml 파일로 관리를 할 수 있다.
컨테이너를 살릴 때 마다 긴 명령어를 치기 귀찮으니 compose를 사용한다.
sudo apt install -y docker-compose
원하는 경로에 docker-compose.yml을 생성해준다.
nano docker-compose.yml
그리고 다음과 같이 내용을 채워준다.
version: "3" # 파일 규격 버전
services: # 이 항목 밑에 실행하려는 컨테이너 들을 정의
mysql: # 서비스 명
image: mysql:latest # 사용할 이미지
container_name: mysql # 컨테이너 이름 설정
ports:
- "3306:3306" # 접근 포트 설정 (컨테이너 외부:컨테이너 내부)
restart: always
environment: # -e 옵션
MYSQL_ROOT_PASSWORD: "MYSQL_ROOT계정용_패스워드를_넣으세요" # MYSQL 패스워드 설정 옵션
TZ: "Asia/Seoul"
command: # 명령어 실행
- --character-set-server=utf8mb4
- --collation-server=utf8mb4_unicode_ci
volumes:
- /home/ubuntu/docker/data/mysql:/var/lib/mysql # -v 옵션 (다렉토리 마운트 설정)
mysql 이미지를 버전에 맞게 해줘야 한다.
포트는 만약 다른 포트를 사용한다면 외부 포트를 바꾸자
컨테이너 이름은 원하는 것으로 바꿔도 무관하다.
MYSQL_ROOT_PASSWORD는 root의 초기 비밀번호이므로 설정해두고 기억해둔다.
volumes의 앞부분 경로는 mysql 컨테이너가 설치되므로 원하는 경로로 만들어준다.
작성을 완료했으면 docker-compose.yml이 존재하는 경로에서
docker-compose up -d
를 입력해준다.
docker-compose를 백그라운드로 돌리겠다는 의미이다.
mysql 컨테이너가 만들어지고, 바로 실행이 된다.
docker로 프로세스를 확인해보려면
docker ps -a
를 입력하면 된다.
포트 번호가 설정해둔 포트가 맞는지 확인한다.
????->3306이라면
외부 ???? 포트에서 도커 컨테이너 3006포트로 리다이렉팅 된다는 의미이다.
오라클, iptables 방화벽에서 ???? 포트만 설정이 되어있으면 된다.
이제 MySQL 컨테이너로 접속해서 설정을 시작한다.
# 컨테이너 접속
docker exec -it 컨테이너이름 bash
docker-compose.yml 파일에 입력한 컨테이너 이름으로 접속해야 한다.
이제 MySQL 서버에 접속한다.
mysql -u root -p
패스워드를 묻는데, docker-compose.yml에 설정해둔 MYSQL_ROOT_PASSWORD를 입력한다.
MySQL 서버에 접속이 되었다.
먼저 계정 목록을 확인해본다.
#계정 목록 확인
SELECT Host,User,plugin,authentication_string FROM mysql.user;
자동 생성되어있는 계정들이다.
Host는 어디에서 접속이 가능한지 나타내는 것이다.
%는 IP가 어떠하든 접속이 가능하다는 의미이고
localhost는 내부적으로만 접속이 가능하다는 의미이다.
이제 root 대신 외부에서 원격으로 접속할 계정을 만든다.
보안상 root 대신 사용할 계정을 하나 만들어 두고 쓰는게 좋다고 하기에
따로 계정을 생성하고 권한을 부여한다.
만약 특정 IP에서만 외부 접속을 허용하려면
아래 명령어에서 % 대신 IP 주소를 넣으면 된다.
# 계정 생성
CREATE USER '사용할_계정이름'@'%' IDENTIFIED BY '계정_비밀번호';
# 만든 계정에 모든 권한 부여
GRANT ALL PRIVILEGES ON *.* TO '사용할_계정이름'@'%';
# 권한을 flush
flush privileges;
정상적으로 만들어졌는지 확인해본다.
SELECT Host,User,plugin,authentication_string FROM mysql.user;
정상적으로 생성이 되었으면 MySQL 서버에서 나온다.
quit
을 입력해서 MySQL 서버에서 빠져나온다.
exit
를 사용하여 컨테이너에서도 빠져나온다.
sudo service docker restart
도커 재시작을 한번 해줘야 외부에서 접속이 잘 되는 듯 하다.
재시작을 해주고 컨테이너도 살려주자
docker-compose의 restart policy를 always로 설정했다면, 알아서 살아난다.
docker restart 컨테이너명
이제 정상적으로 잘 접속 되는지 확인해본다.
접속 테스트는 윈도우 MySQL Workbench로 하였다.
접속에 성공한 모습이다.
원래 Docker에 대해 좀 더 공부해보고 그에 대한 글을 따로 쓰려고 했는데, 학기 중에는 상황이 여의치 않을 것 같다.
아마 방학 때 따로 다루던가 해야할 것 같다.
글 감사합니다! 사용하던 중 vi가 없어서 설치하려고 apt-get을 해도 yum을 해도 둘 다 command not found가 나오는데 사용하시면서 이런 문제점은 없으셨는지 궁금합니다.. 답변 해주시면 감사하겠습니다!