배포하고 확인했을 때는 정상이었는데 한 시간 뒤에 오류가 났다. 나는 그 사이에 아무것도 안 건드렸다.
Table of contents
Open Table of contents
다른 사람이 설정을 바꿨다
stat 으로 설정 파일 수정 시각을 보니 내 배포보다 한 시간 뒤였다. 물어보니 다른 사람이 DB 주소를 바꾼 것이었고 서버를 옮기는 작업 중이었다.
같은 서버를 여러 사람이 만지면 내가 아는 상태가 지금 상태가 아닐 수 있다. 배포하고 확인한 것은 그 시점의 상태였다.
설정 파일을 svn 에 넣는 것부터 했다. 비밀번호가 든 부분은 빼고 구조만 관리하고 값은 별도 파일에 두어 svn:ignore 로 뺐다. 이렇게 하니 svn log 에 누가 언제 무엇을 바꿨는지가 남았다.
바뀌면 알게 했다
기록만으로는 부족했다. 바뀌었다는 것을 그때 알아야 했다.
NEW=$(md5sum /etc/app/*.conf | sort)
if [ -f "$STATE" ]; then
DIFF=$(diff "$STATE" <(echo "$NEW"))
if [ -n "$DIFF" ]; then
notify "설정 변경 감지:\n$DIFF"
fi
fi
echo "$NEW" > "$STATE"
crontab 으로 5분마다 돌면서 md5sum 이 달라지면 알린다. 누가 바꿨는지는 안 나오지만 바뀌었다는 것은 안다.
이 스크립트를 crontab 에 걸 때 한 번 깨졌다. diff "$STATE" <(echo "$NEW") 의 <(...) 는 bash 문법이라 sh 로 돌면 그 줄에서 문법 오류가 난다. 첫 줄에 #!/bin/bash 를 두고 crontab 에도 SHELL=/bin/bash 를 적어 뒀다.
작업 중임을 표시하게 했다
동시에 만지는 것 자체를 줄이려고 작업 중 표시를 뒀다. deploy.sh 가 그것을 확인하고 다른 작업이 진행 중이면 알려 준다.
if /opt/tools/lock-server.sh --check | grep -q "작업 중"; then
echo "다른 작업이 진행 중입니다:"
/opt/tools/lock-server.sh --check
printf "그래도 진행하시겠습니까? (yes): "
read a
[ "$a" = "yes" ] || exit 1
fi
강제로 막지는 않았다. 급한 경우가 있어서 모르고 진행하는 것만 막고 알고 진행하는 것은 열어 뒀다.
잠그고 안 푸는 경우도 있어서 시각을 넣고 오래되면 무시하게 했다. 무시하되 알린다. 조용히 넘어가면 잠금 자체가 의미가 없어진다.
내가 아는 상태의 기록
작업을 시작할 때 현재 상태를 먼저 찍게 했다.
[설정] db.conf 8f3a... (2015-05-16 09:12)
[설정] app.conf b21c... (2015-05-10 14:03)
[프로세스] app 3821 (14시간 가동)
[버전] 1.4.2
작업 뒤에 다시 찍어 diff 하면 내가 바꾼 것과 남이 바꾼 것이 갈린다. 내가 안 건드린 파일의 md5sum 이 바뀌어 있으면 그 사이에 다른 작업이 있었던 것이다.
deploy.sh 도 시작과 끝에 md5sum 을 로그에 남기게 했다. 배포 중에 설정이 바뀌었으면 두 값이 다르다. 문제가 났을 때 그 로그를 보면 배포와 설정 변경 중 무엇이 먼저였는지 알 수 있다.
정리
- 같은 서버를 여러 사람이 만지면 내가 아는 상태가 아닐 수 있다
- 설정 파일을
svn에 넣되 비밀 값은svn:ignore로 뺀다 crontab으로md5sum을 주기적으로 확인해 바뀌면 알린다<(...)는 bash 문법이라sh로 돌면 문법 오류가 난다- 누가인지는 몰라도 바뀌었다는 것만 알아도 추적이 빨라진다
- 작업 중임을 표시하고
deploy.sh가 확인하게 한다 - 강제로 막지 말고 알고 진행하게 한다
- 배포 전후
md5sum을 남기면 그 사이 변경이 드러난다