[Docker] Appendix A. Docker Problems (feat. 재부팅)

김희정·2023년 2월 6일
2

Docker

목록 보기
3/3
post-thumbnail

💎 들어가며

docker를 사용하면서 재부팅(reboot)후 발생할 수 있는 상황해결책에 대해 모색해보았고, 이를 포스팅으로 정리해보았습니다.


1. Docker Command 권한 문제

💬 문제 발생

도커를 처음 설치하고 도커 명령어를 사용하려고 하면 아래와 같은 에러가 발생하는데요. 이 때 조치해주었던 방안이 재부팅 후에는 리셋이 되어 다시 발생합니다.

$ docker ps
Got permission denied while trying to connect to the Docker daemon socket
at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.24/containers/json":
dial unix /var/run/docker.sock: connect: permission denied

🔨 조치 방안

💡 .bashrc에 해당 명령어 쓰기

.bashrc 로그인한 사용자의 Home 디렉터리의 파일을 열어 아래와 같이 명령을 넣어줍니다.

$ vi ~/.bashrc

이 때, 아래와 같이 파일 권한을 변경하거나 파일 소유자를 변경하는 두가지 방법이 있습니다.

# 파일 권한 변경
sudo chmod 666 /var/run/docker.sock
# 파일 소유자 변경
sudo chown root:khj /var/run/docker.sock

이제 쉘에 로그인할 때마다 번번히 명령어를 치지않아도 되지만 chmodchown의 경우에는 root 사용자에게만 명령을 사용할 권한을 주기 때문에 sudo 명령이 무조건 들어가야 합니다.
(+ docker는 보안문제 때문에 관리자 권한으로 막아둔 거라고 하네요. 개발 환경에서만 사용하도록 합시다.)

때문에, 첫 쉘 로그인시 root 비밀번호를 쳐줘야 되는 단점은 있습니다.

💡 .bashrc란 무엇인가?

~/.bashrc란 무엇인가?

~/.bashrc는 개인 사용자에 대한 환경설정 파일입니다. 쉘(bash)이 실행될 때 마다 읽어들이는 파일입니다.

[출저] /etc/profile, ~/.bash_profile, ~/.bashrc, /etc/bashrc 파일 비교

쉘(bash)는 사용자로부터 명령을 받아 그것을 해석하고 실행하는 역할을 수행하는 프로그램입니다. 우리가 흔히 Windows의 명령프롬프트(cmd), Linux의 터미널(Terminal)이 이에 해당합니다.

bashrc 파일은 쉘에 접근하기 전에 수행할 명령을 모아놓은 스크립트 파일입니다. 보통은 쉘에 로그인한 뒤 수행되지만, source 명령어를 사용하면 스크립트 변경사항을 바로 적용할 수 있습니다.


2. Docker Container 자동 실행

💬 문제 발생

재부팅 후, 아무런 의심 없이 컨테이너에 접속하려 아래 명령을 내려보았습니다.

$ docker exec -it web bash
> Error response from daemon: Container
> 3f4c242bde74b34e096422bffeff9344437971f59c8e0268ed7232cba6769e23 is not running

What? Is not Running? 실행 중이지 않다구요..?

docker ps 명령을 통해 알아보니, 실행중인 컨테이너가 없네요.

$ docker ps
CONTAINER ID   IMAGE         COMMAND       CREATED      STATUS       PORTS     NAMES

예, 그렇다네요.. 컨테이너를 생성한 뒤에 재부팅을 한것이 처음이라 몰랐습니다.

혹시나 망상 속 도커는 인메모리가 아닐까 컨테이너가 없어진 것은 아닐까, 조심스레 전체 컨테이너를 검색해보았습니다.

$ docker ps -a
CONTAINER ID	IMAGE	COMMAND				CREATED		STATUS                   PORTS     NAMES
3f4c242bde74	httpd	"httpd-foreground"	5 days ago	Exited (0) 3 hours ago             web

컨테이너는 죽은건 아니네요.😣 근데 가장 큰 문제가 있습니다... 재시작 시에는 port 바인딩이 안돼요!!😥


🔨 조치 방안

구글링해보니, 원래 컨테이너는 컴퓨터가 종료되면 같이 종료된다네요.

💡 Docker Run Option

가장 좋은 방법은 아래와 같이 Docker Container를 생성할 때, 재시작 옵션(--restart)always로 넣어주는 것입니다!!!

하지만, 언제나 문제는 뒤늦게 발생하는 법..

$ docker run -d --name web --restart always -p 80:80 httpd

Docker Run Restart Option

--restart
1. no : 재시작하지 않는다. (기본값)
2. on-failure : 에러로 인해 종료될 시 재시작한다.
3. always : 항상 재시작한다. 수동으로 종료한 경우, Docker가 재시작되면 같이 재시작된다.
4. unless-stopped : 컨테이너가 종료되지 않는다면, 항상 재시작한다. 종료되었다면, 직접 시작하기 전까지는 Docker가 재시작되도 컨테이너는 재시작되지 않는다.

[참조] Start containers automatically


💡 Docker Container 재실행

컨테이너를 옵션을 추가해 재실행하는 것은 구글링 결과 없습니다

단, docker commit을 이용해 이미지로 만들어 재실행하는 방법은 있습니다.


💡 service 파일로 자동 재실행 설정

그게 이미지를 저장하고 새 컨테이너를 생성하기 귀찮으면 systemd 서비스 등록으로 docker container를 자동 실행합니다.

1) service 파일 생성

systemd의 서비스가 있는 /etc/systemd/system 폴더로 이동한 뒤, vi 편집기를 열어 설정할 service 파일을 생성합니다.

$ cd /etc/systemd/system
$ vi [설정한 서비스].service

서비스 내용에는 아래와 같이 기술합니다.

[Unit]
Wants=docker.service
After=docker.service
 
[Service]
RemainAfterExit=yes
ExecStart=/usr/bin/docker start [실행할 docker container 이름]
ExecStop=/usr/bin/docker stop [실행할 docker container 이름]
 
[Install]
WantedBy=multi-user.target

2) service 시작

systemctl start 명령어를 통해 해당 서비스를 시작하거나 systemctl enable 명령어를 통해 부팅시 실행할 수 있도록 해당 서비스를 활성화합니다.

systemctl start [설정한 서비스]
systemctl enable [설정한 서비스]


📁 ETC

💻 쉘에 환경 변수 저장하기

위에서 환경설정 파일인 .bashrc에 대해 간략하게 설명했는데, 환경설정 파일에 대해 잘 와닿지 않을 것 같아 준비했습니다!🥰

Windows에서 시스템에서 환경 변수를 편집하듯이 리눅스에서도 환경설정 파일을 통해 환경 변수를 편집할 수 있습니다. 아래 예시는 대표적인 예로, JAVA_HOME을 설정하는 예시 입니다.

💡 Windows

Windows의 환경변수 편집

CMD에서 환경변수 설정/읽기

$ setx JAVA_HOME "C:\Program Files\Java\jdk-11.0.12"

$ echo %JAVA_HOME%
C:\Program Files\Java\jdk-11.0.12

💡 Linux

/etc/profile 수정

vi 편집기로 /etc/profile 파일을 엽니다.

$ sudo vi /etc/profile

맨 밑에 아래 내용 붙여 넣습니다.

export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64

source 명령을 통해 해당 변경사항을 저장합니다.

$ source /etc/profile

마지막 순서로 터미널에서 echo명령을 통해 JAVA_HOME을 확인합니다.

$ echo $JAVA_HOME

> /usr/lib/jvm/java-11-openjdk-amd64

💎 Reference


💎 마치며

이번 포스팅에서는 재부팅 시 발생할 수 있는 Docker 문제들에 대해 다뤄보았고, 특히 당혹스러웠던 Container의 죽음(death)에 방지할 방법에 대해 살펴보았습니다.

도움이 되셨다면 💘 하트 부탁드립니다.😁

profile
Java, Spring 기반 풀스택 개발자의 개발 블로그입니다.

0개의 댓글