이 글에서는 구글 클라우드의 기본 VM인 debian 계열 리눅스에 docker를 설치하는 방법 대해서 설명합니다.
구글 클라우드 서버에 docker 설치
다음 명령을 순차적으로 수행하면 설치가 완료됩니다.
"이전 Docker 인스턴스 제거"와 "비 root 사용자로 Docker 실행"는 필요 시 수행하시면 됩니다.
# 이전 Docker 인스턴스 제거
sudo apt-get remove docker docker-engine docker.io containerd runc
# Docker CE를 위한 초기 패키지 설치
sudo apt-get update
sudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-release
# Docker CE GPG 키 추가
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# Docker CE APT 리포지토리에 추가
echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/debian $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Docker CE 설치
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io
# Docker CE 설치 확인
sudo docker run hello-world
# 비 root 사용자로 Docker 실행
sudo groupadd docker
sudo usermod -aG docker $USER
newgrp docker
web 서버 docker 이미지 실행하기
docker 설치 완료 후에 docker hub로 부터 이미지를 받아서 실행하기 위해서는 docker hub에 로그인을 해야 합니다.
1. Docker에 로그인 하기
sudo docker login을 통해 로그인을 합니다. sudo를 앞에 넣어주지 않으면 /var/run/docker.sock 파일에 대한 권한 문제로 로그인이 실패하는 것을 확인했습니다. 다.
처음에 사용자 이름과 비밀번호를 물어보고 다음부터는 바로 로그인이 됩니다.
2. Docker 이미지를 가져오기
sudo docker pull 이미지이름:태그
eeddyit0@instance-1:~$ sudo docker pull lswhh/myflask:v3.0
v3.0: Pulling from lswhh/myflask
7007490126ef: Pull complete
1d60bfe7d569: Pull complete
89b66eb40820: Pull complete
4f4fb700ef54: Pull complete
f5403cdde9e1: Pull complete
4678f683a89b: Downloading [=> ] 339MB/8.734GB
7b5d670363e1: Downloading [======> ] 362.6MB/2.964GB
b2a839aaa970: Download complete
b01fda8b2cf3: Download complete
491c4101ced8: Downloading [====================> ] 58.41MB/139.5MB
이미지 용량에 따라서 시간이 오래 걸릴 수 있습니다.
eeddyit0@instance-1:~$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
lswhh/myflask v3.0 ea4321c72a78 4 weeks ago 16.4GB
다운이 완료되면 웹 서비스 포트를 개방하여 이미지를 실행합니다.
3. Docker 이미지 실행
Docker 이미지를 실행하고, 호스트의 8000, 5000, 443, 80 포트를 컨테이너의 동일한 포트에 바인딩합니다. 그리고 /bin/bash를 실행하여 bash 셸에 진입합니다. <이미지 이름> 부분은 실행하려는 Docker 이미지의 이름으로 대체해야 합니다.
이미지마다 차이가 있는데 저의 경우 start.sh로 무한루프 도는 쉘을 만들어 놓았습니다.
docker는 시작하면서 entrypoint에 해당하는 쉘을 수행하는데, 이 쉘이 종료되면 docker가 종료되기 때문에 웹 서비스의 경우 무한루프 도는 쉘을 넣어놓습니다.
sudo docker run -d -p 8000:8000 -p 5000:5000 -p 443:443 -p 80:80 lswhh/myflask:v3.0 start.sh
위의 명령 수행 후 docker ps를 해보면 아래와 같습니다. docker ps를 수행 후 container id를 알아내서 docker exec -it [container id] bash 를 수행하면, 실행 중인 docker 이미지의 bash 쉘에 로그인 할 수 있습니다. eeddyit0@instance-1:~$ sudo docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2c898b2349b7 lswhh/myflask:v3.0 "start.sh" 8 seconds ago Up 7 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp, 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp, 0.0.0.0:8000->8000/tcp, :::8000->8000/tcp, 8090/tcp silly_solomon
eeddyit0@instance-1:~$ sudo docker exec -it 2c898b2349b7 bash
root@2c898b2349b7:/home/eddy_lee#
제 이미지의 경우 웹 서버를 자동으로 띄워주지 않도록 해 놓았으므로 bash로 로그인 해서 띄워 줘야 합니다.
4. 웹 서비스 실행 및 방화벽 설정
docker 이미지에서 웹 서버를 시작하고 정상적으로 외부에서 접속되는지 확인합니다.
기본적으로 구글 클라우드는 방화벽이 설정되어있어서 외부 접속이 되지 않습니다. 구글 클라우드 서버에서 방화벽 규칙을 추가하여 https:443 포트와 http:80 포트 등 사용하는 포트들을 열어줍니다.
nginx의 설정 파일을 열어서 내용을 확인 후 ip부분으로 호스팅하는 것이 있으면 신규 구글 클라우드 서버의 ip로 변경해 줍니다.
vi /etc/nginx/sites-available/myflaskapp
root@2c898b2349b7:/home/eddy_lee#
server {
listen 80;
server_name it.2story.org 34.64.235.86; #<-- ip 변경
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_pass http://localhost:8000;
}
proxy_connect_timeout 1200;
proxy_send_timeout 1200;
proxy_read_timeout 1200;
send_timeout 1200;
}
IP를 변경 후에는 웹 서비스를 실행합니다. 이 부분은 제가 설정해 놓은 웹 서비스 실행 방식입니다.
root@2c898b2349b7:/home/eddy_lee# . venv/bin/activate
(venv) root@2c898b2349b7:/home/eddy_lee# cat restart
cat: restart: No such file or directory
(venv) root@2c898b2349b7:/home/eddy_lee# cat restart.sh
cat: restart.sh: No such file or directory
(venv) root@2c898b2349b7:/home/eddy_lee# ls
flask imgFilterApp start.sh venv
(venv) root@2c898b2349b7:/home/eddy_lee# cd flask/
(venv) root@2c898b2349b7:/home/eddy_lee/flask# cat restart.sh
bin/killport 8000
bin/gunicorn.start
sudo /etc/init.d/nginx restart
(venv) root@2c898b2349b7:/home/eddy_lee/flask# ps -ef |grep gunicorn
root 277 46 0 06:25 pts/0 00:00:00 grep --color=auto gunicorn
(venv) root@2c898b2349b7:/home/eddy_lee/flask# bin/gunicorn.start
(venv) root@2c898b2349b7:/home/eddy_lee/flask# tail -f error.log
[2023-10-12 11:19:16 +0000] [4685] [INFO] Using worker: sync
[2023-10-12 11:19:16 +0000] [4687] [INFO] Booting worker with pid: 4687
[2023-10-12 11:19:16 +0000] [4688] [INFO] Booting worker with pid: 4688
SELECT qid, topic, situation, lquestion, rquestion, lvote_count, rvote_count FROM questions WHERE qid >= '1'
fetch
[2023-11-15 06:25:37 +0000] [283] [INFO] Starting gunicorn 20.1.0
[2023-11-15 06:25:37 +0000] [283] [INFO] Listening at: http://0.0.0.0:8000 (283)
[2023-11-15 06:25:37 +0000] [283] [INFO] Using worker: sync
[2023-11-15 06:25:37 +0000] [285] [INFO] Booting worker with pid: 285
[2023-11-15 06:25:37 +0000] [286] [INFO] Booting worker with pid: 286
^C
(venv) root@2c898b2349b7:/home/eddy_lee/flask# ps -ef |grep guni
root 283 1 0 06:25 ? 00:00:00 gunicorn: master [app:app]
root 285 283 8 06:25 ? 00:00:01 gunicorn: worker [app:app]
root 286 283 8 06:25 ? 00:00:01 gunicorn: worker [app:app]
root 293 46 0 06:25 pts/0 00:00:00 grep --color=auto guni
(venv) root@2c898b2349b7:/home/eddy_lee/flask# /etc/init.d/nginx restart
* Restarting nginx nginx
외부 웹 서버에서 nginx가 실행되어있는 구글 클라우드 서버의 IP로 접속해 보았을 때 접속이 되면 완료하면 됩니다.
하지만, 접속이 안되는 경우 방화벽 문제인지 확인하기 위해서 local 에서 curl 명령으로 확인해 봅니다.
venv) root@2c898b2349b7:/home/eddy_lee/flask# curl -X GET localhost
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
curl이 위와 같이 정상적으로 수행되는데 외부 접속이 안되는 경우가 있는데, 이 경우 새로 추가한 규칙의 우선순위를 확인해 보셔야 합니다.
기본 우선순위보다 높은 우선순위로 설정해야 합니다. 기본 우선순위는 65535이며, 그 이하의 숫자값이 더 높은 우선순위가 됩니다. 즉, 낮은 값이 우선순위가 높은 것이 됩니다.
기타 오류가 발생하는 부분 수정: 현재 라이브러리 에러가 발생하여 일부 flask앱 실행이 안되었는데, 아래와 같이 라이브러리를 설치해 주니 문제없이 수행됩니다. 참고삼아 기록합니다.
apt-get update
apt-get install libglib2.0-0
4. 인증서 갱신
docker 이미지에서 웹 서버를 시작하기 전에 https의 보안 인증서를 갱신해 줘야 합니다.
보안 인증서는 3개월 마다 갱신해 줘야 합니다.
certbot --nginx 명령을 수행하면 몇 가지 질문과 동의사항에 동의한 후 자동으로 nginx의 설정에서 인증서를 발급받을 수 있습니다.
Which names would you like to activate HTTPS for?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: ai.2story.org
2: it.2story.org
3: vs.2story.org
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel):
Obtaining a new certificate
Performing the following challenges:
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 1
Future versions of Certbot will automatically configure the webserver so that all requests redirect to secure HTTPS access. You can control this behavior and disable this warning with the --redirect and --no-redirect flags.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations! You have successfully enabled https://ai.2story.org,
https://it.2story.org, and https://vs.2story.org
You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=ai.2story.org
https://www.ssllabs.com/ssltest/analyze.html?d=it.2story.org
https://www.ssllabs.com/ssltest/analyze.html?d=vs.2story.org
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/ai.2story.org/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/ai.2story.org/privkey.pem
Your cert will expire on 2024-02-13. To obtain a new or tweaked
version of this certificate in the future, simply run certbot again
with the "certonly" option. To non-interactively renew *all* of
your certificates, run "certbot renew"
- Your account credentials have been saved in your Certbot
configuration directory at /etc/letsencrypt. You should make a
secure backup of this folder now. This configuration directory will
also contain certificates and private keys obtained by Certbot so
making regular backups of this folder is ideal.
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
'리눅스&OS' 카테고리의 다른 글
tcp 네트워크 timer를 통해 리눅스 커널에서 소켓 끊는 현상 확인하기 (0) | 2024.01.05 |
---|---|
nginx용 docker 이미지 무식하게 만들기 (0) | 2023.12.05 |
Ubuntu(우분투 20.04)에서 Docker를 사용하기 (from Docker hub) (0) | 2023.12.05 |
리눅스 커널(linux kernel) 버전 정보 확인 uname | version | hostnamectl (0) | 2023.11.23 |
https 보안 인증서 let's encrypt에서 certbot으로 재발급 받기 (0) | 2023.11.22 |