docker가 있으니 gerrit 업그레이드 스트레스는 잊으시오

3 minute read

코드 리뷰 툴로 gerrit을 쓰고 있다. 자연스럽게 작업자들이 pull, push하는 중앙 저장소가 gerrit이 된다. 잘 쓰고 있는데, 업그레이드하려니 걱정이 된다. 한 번에 문제없이 업그레이드되면 좋은데, 이걸 보장할 수가 없다. 만약 업그레이드가 실패해서 엉망이 되면 고통은 프로그래머 몫.

업그레이드 시도해보고 안 되면 재빨리 이전 버전으로 돌려서 제대로 돌아가게 한 다음 원인을 찾는다. 바쁘면 몰라. 다른 사람이 하겠지. 이렇게 쉽게 발을 뺄 수 있는 환경에서 업그레이드를 해보고 싶다. 깔끔하게 업그레이드를 하던가 깔끔하게 발을 빼던가.

그래서 docker를 보게 됐다. docker 소개는 도커(Docker) 튜토리얼 : 깐 김에 배포까지 - nacyot 참고.

docker hub에 필요한 것들을 다 세팅해 놓은 게 있다. openfrontier/gerrit.

$ docker run --name gerrit -d -p 8080:8080 -p 29418:29418 openfrontier/gerrit:2.11.x

2.12.x가 나왔지만, 버그 픽스가 된 안정적인 이전 버전을 받는다. 얼~ 바로 뜨네. 이렇게 한방에 되다니 편하면서도 뭔가 허탈하다.

현재 mysql을 gerrit db로 사용한다. 바꿀 생각 없음. 그대로 간다. 이것도 gerrit 버전을 선택한 것과 같은 기준으로 5.6.30을 선택한다.

$ docker run --name gerrit-mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.6.30

얼~ 바로 뜸.

이렇게 쓰면 gerrit, gerrit-mysql 컨테이너에 리뷰 데이터도 같이 저장된다. 이건 원하는 바가 아니다. 둘 다 업그레이드를 해야 할 상황이 올 텐데, 이때 컨테이너 데이터를 다른 곳에 옮기는 걸 해줘야 한다. 데이터만 분리해서 docker 철학에 맞게 사용하고 싶다. 이럴 때 사용하는 게 data volume container이다.

data volume container를 만들어 놓으면 업그레이드가 필요할 때, 한벌 복사해서 업그레이드한 gerrit 컨테이너에 붙여서 테스트해보면 된다. 제대로 db를 마이그레이션(migration) 하는지. 따로 폴더 단위로 백업받아서 업그레이드 테스트를 안 하고 격리된 환경에서 쉽게 테스트를 할 수 있다.

$ cd gerrit-data
$ cat Dockerfile

FROM debian:jessie
MAINTAINER ohyecloudy@gmail.com

RUN useradd -ms /bin/bash mysql
RUN mkdir -p /var/lib/mysql
RUN chown -R mysql:mysql /var/lib/mysql

RUN useradd -ms /bin/bash gerrit2
RUN mkdir -p /var/gerrit/review_site
RUN chown -R gerrit2:gerrit2 /var/gerrit/review_site

VOLUME ["/var/lib/mysql", "/var/gerrit/review_site"]

CMD ["echo", "Data container for mysql and gerrit"]

이건 직접 만들어야 한다. 사용하는 환경이 다 다르니 다른 사람도 쓰라고 공유한 이미지도 없음. gerrit, gerrit-mysql이 데이터를 저장하는 디렉터리를 볼륨으로 만들었다. 사용하는 계정을 만들고 해당 디렉터리에 권한을 추가한다.

$ docker build -t gerrit-data-img gerrit-data/.
$ docker run --name=gerrit-data gerrit-data-img

빌드해서 이미지를 만든다. 그리고 컨테이터도 생성.

$ docker run \
--name gerrit-mysql \
--volumes-from=gerrit-data \
-e MYSQL_ROOT_PASSWORD=123456 \
-e MYSQL_DATABASE=reviewdb \
-e MYSQL_USER=gerrit2 \
-e MYSQL_PASSWORD=gerrit \
-d \
mysql:5.6.30
$ docker run \
--name gerrit \
--volumes-from gerrit-data \
--link gerrit-mysql:db \
-p 8080:8080 -p 29418:29418 \
-e DATABASE_TYPE=mysql \
-e DB_ENV_MYSQL_DB=reviewdb \
-e DB_ENV_MYSQL_USER=gerrit2 \
-e DB_ENV_MYSQL_PASSWORD=gerrit \
-e AUTH_TYPE=DEVELOPMENT_BECOME_ANY_ACCOUNT \
-d \
openfrontier/gerrit:2.11.x

mysql, gerrit을 데이터 저장을 위해 만들어 놓은 data volume container에 연결해서 실행하면 끝~ LDAP 인증 타입을 사용하고 있어서 이건 회사에서 테스트해야 한다.

참고 - docker & jenkins: data that persists - riot games engineering

삽질 1

$ docker exec -it gerrit-mysql mysql --user=root --password=123456 -e "show databases;"
+--------------------+
| Database           |
+--------------------+
| information_schema |
| hello_docker       |
| mysql              |
| performance_schema |
+--------------------+
4 rows in set (0.01 sec)

gerrit database가 안 생긴다. data volume container에 mysql:mysql 계정이 없어서 생성이 안 됐다.

RUN useradd -ms /bin/bash mysql
RUN mkdir -p /var/lib/mysql
RUN chown -R mysql:mysql /var/lib/mysql

Dockerfile에 추가해서 해결.

삽질 2

gerrit을 실행하니 500 internal error 발생. docker 로그를 보니 all projects를 못 찾겠다고 한다.

$ docker exec -it gerrit-mysql mysql --user=gerrit2 --password=gerrit -e "show grants;"
+----------------------------------------------------------------+
| Grants for gerrit2@%                                           |
+----------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'gerrit2'@'%' IDENTIFIED BY PAS...       |
| GRANT ALL PRIVILEGES ON `reviewdb`.* TO 'gerrit2'@'%'          |
+----------------------------------------------------------------+
2 rows in set (0.00 sec)

권한을 의심했는데, 문제없다.

gerrit에서 mysql을 사용할 때, default 패스워드가 gerrit인 줄 알았는데, 아니다. 문서를 보지도 않고 밑도 끝도 없이 생각한 내 잘못이요.

-e DATABASE_PASSWORD=gerrit

gerrit 컨테이너 실행 인자에 추가해서 해결.

삽질 3

gerrit 기본 인증이 OPENID. 테스트하는데 이걸 언제 만들고 있어.

-e AUTH_TYPE=DEVELOPMENT_BECOME_ANY_ACCOUNT

그래서 DEVELOPMENT_BECOME_ANY_ACCOUNT 인증 방식을 사용하려고 옵션에 붙였는데, 여전히 OPENID 방식 인증을 요구한다.

$ docker exec -it gerrit bash
# cat $GERRIT_SITE/etc/gerrit.config | grep -A 1 auth
[auth]
    type = OPENID

어라. 옵션이 안 먹네. 왜 안 먹는 걸까?

openfrontier/docker-gerrit/gerrit-entrypoint.sh 스크립트를 보니 알겠다. data volume container를 붙여서 실행하니 gerrit.config가 생성된 상태. 여기서 옵션을 추가해서 다시 실행하니 반영이 안 됐던 것이었다.