Docker PostgreSQL 볼륨 매핑 권한 문제 without root
상황
1. Docker 컨테이너 위에 PostgreSQL을 돌림
2. PostgreSQL Data 파일을 볼륨 매핑 함.
3. 권한 문제 발생
Docker 일반 사용자 사용
usermod -aG docker user_name
docker 계정 생성 후, 해당 계정을 docker 그룹에 포함 시킨다.
Docker with PostgreSQL
Docker-Hub에서 PostgreSQL 9.1 이미지를 받는다.
아래와 같이 docker-compose.yml에 docker postgres run 정보를 기입한다.
version: '2'
services:
postgres:
image: postgres:9.1
container_name: postgres
ports:
- '5432:5432'
volumes:
- ./pgdata:/var/lib/postgresql/data
...
Docker 데이터 파일은 사전에 만든 Data 파일이다.
Docker 데이터 파일을 볼륨 매핑을 한다.
나니?? 여기서 문제가 발생
문제 pgdata 유저 권한이 바뀜
파일 소유자가 변경이 되었음.
systemd-coredump는 뭐임??
더구나, 파일 권한은 700 접근 조차 하지 못함. 그러나 docker 컨테이너에서 postgresql은 잘 돌아감.
root에서는 볼 수 있으나, 개발 서버는 몰라도, 운영 서버에서 root 권한을 이런거에 함부로 쓸 수 없음
소유자를 강제로 바꿔보자...
user$ docker exec -it postgres chown -R user_name:user_name /var/lib/postgresql/data
root$ chown -R user_name:user_name pgdata
근데 이번에는 Tomcat에서 난리남
javax.naming.NamingException: Cannot create PoolableConnectionFactory (FATAL: could not open relation mapping file "global/pg_filenode.map": Permission denied)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:749)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:464)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1119)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1014)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:504)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:303)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:299)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1120)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1044)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:942)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:813)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)
... 109 more
아마도 소유자를 강제로 바꿔서 문제가 된 듯... 해당 예외를 구글링 해도 잘 모르겠음..
문제의 회피
user$ docker exec -it postgres chmod 770 -R /var/lib/postgresql/data
소유자만 바뀌고 그룹은 유저이름 그대로이기 때문에 그룹에만 권한을 줬음.
일단 됨. 뭔가 태는 안나오는데 가동은 됨
또 문제 발생
docker postgresql 컨테이너에서 생성한 파일, 예를 들어 로그 파일 같은 것은 사용자와 그룹 모두 권한이 바뀌어서 사용하지 못함. 사용하기 위해서는 문제의 회피와 같은 명령을 입력해야함, 그러니까 아래 그림과 같음
결국 본질을 보지 못하고 회피한 문제는 똥이 되어 돌아왔다 ㅋㅋㅋ
문제의 해결
하루 종일 삽질해도 모르겠음ㅋㅋㅋㅋ 그냥 다음 날로 미룸.
다음 날, 이것저것 Docker 관련 컬럼을 보고 있었는데, 웬걸 괜찮은 컬럼을 발견함.
Docker UID/GID의 이해
https://medium.com/@mccode/understanding-how-uid-and-gid-work-in-docker-containers-c37a01d01cf
근데 이걸 봤는데도 바로 아이디어가 떠오르지 않음.
또 다시 다음날 ㅋㅋㅋㅋㅋㅋㅋ 아침에 출근하는데 갑자기 어떤 아이디어가 대가리를 때림
메모 해놓고 와서 하니깐 됨 잘 됨 ㅋㅋㅋㅋㅋㅋㅋㅋㅋ
아래와 같음
일단 아래 스크립트는 docker 빌드를 쉘 스크립트로 만든 것임 그중 일부분을 발췌한 것임
install_user=$1
install_dir=$2
uid=$UID
gid=$(getent group docker | awk -F: '{printf $3}')
...
docker build -t dream-postgres:9.1 -<<EOF
FROM postgres:9.1
MAINTAINER ehdvudee
RUN groupmod -og $gid postgres
RUN usermod -u $uid postgres
EOF
위의 UID/GID의 이해 컬럼이 정말 큰 도움이 되었음, 해당 글을 보고 uid/gid의 개념을 파악함.
또한 docker hub의 postgres는 postgres 계정 권한으로 PostgreSQL 엔진을 돌림
docker postgres 컨테이너에서 passwd를 확인하면 아래와 같음
docker exec -it postgres bash
cat /etc/passwd
postgres:x:999:999::/home/postgres:/bin/sh
현재 파일에서 엉뚱하게 소유 권한이 바뀐 이유는 다음과 같음
1. Docker 컨테이너 내부의 postgres 계정 uid/gid는 999이다.
2. HostOS의 999 uid/gid를 가진 계정은 systemd-coredump이다.
3. 즉, 파일 권한의 매핑은 uid/gid를 통해 이루어지는 것이다.
결론
Docker Postgresql 볼륨 매핑한 디렉토리의 권한을 일반 사용자 권한으로 하고 싶으면
Dockerfile을 빌드할 때 usermod와 groupmod를 통해 postgres의 uid/gid를 일반 사용자의 uid/gid로 매핑을 한다.
'개발관련 > (과거)메모' 카테고리의 다른 글
Tomcat 튜닝 가이드 (0) | 2020.05.14 |
---|---|
Java에서 HTTPS 좀 알고 구성해보자.. (0) | 2020.04.06 |
JUnit과 함께하는 AssertJ (0) | 2019.11.12 |
Hashed Data RSA 서명할 때 주의사항 (0) | 2019.10.01 |
스프링 빈과 Thread-Safe (0) | 2019.10.01 |