Skip to content
isdnetworks
Go back

배포가 λ„λŠ”λ° 아무 일도 μ•ˆ 일어났닀

(μˆ˜μ •λ¨)

브랜치 이름을 μ •λ¦¬ν•˜λ©΄μ„œ dev λ₯Ό develop 으둜 λ°”κΏ¨λ‹€. λ©°μΉ  λ’€ 고친 게 μ•ˆ μ˜¬λΌκ°„λ‹€λŠ” 말이 λ‚˜μ™”λŠ”λ° 배포 이λ ₯은 μ „λΆ€ μ„±κ³΅μ΄μ—ˆλ‹€.

Table of contents

Open Table of contents

증상 β€” 성곡 이λ ₯κ³Ό μ•ˆ 바뀐 κ²°κ³Ό

배포 둜그λ₯Ό μ—΄μ—ˆλ‹€.

Started by user ...
Fetching changes from the remote Git repository
Checking out Revision 3c81f0a (origin/dev)
...
Finished: SUCCESS

origin/dev λ₯Ό λ°›κ³  μžˆμ—ˆλ‹€.

dev λŠ” 이제 μ•ˆ μ“°λŠ”λ° 원격에 μ°Έμ‘°κ°€ 남아 μžˆμ–΄μ„œ λ°›μ•„μ§€κΈ΄ ν–ˆλ‹€. λ°›μ•„μ§€λŠ”λ° μ˜› 것이 λ°›μ•„μ§€κ³  κ·Έ κ²°κ³Όκ°€ SUCCESS 둜 λ‚¨λŠ”λ‹€.

μ‹€νŒ¨ν–ˆμœΌλ©΄ κ·Έ μžλ¦¬μ—μ„œ μ•Œμ•˜μ„ 것이닀. μ„±κ³΅ν–ˆκΈ° λ•Œλ¬Έμ— λ©°μΉ  λ™μ•ˆ 아무도 λͺ» μ•Œμ•„μ±˜λ‹€.

원인 β€” 원격에 남은 μ˜› 이름

이름을 λ°”κΏ€ λ•Œ μƒˆ 것을 λ§Œλ“€κ³  μ˜› 것을 μ•ˆ μ§€μ› λ‹€.

$ git ls-remote --heads origin
3c81f0a  refs/heads/dev
8f2a1c3  refs/heads/develop

refs/heads/dev 와 refs/heads/develop 이 λ‘˜ λ‹€ μžˆμœΌλ‹ˆ μ˜› 것을 κ°€λ¦¬ν‚€λŠ” 섀정이 계속 λˆλ‹€.

$ git push origin --delete dev

--delete dev 둜 μ§€μš°κ³  λ‚˜λ‹ˆ κ·Έ 이름을 κ°€λ¦¬ν‚€λŠ” 것은 μ‹€νŒ¨ν•œλ‹€.

남겨 λ‘λŠ” 것이 μ•ˆμ „ν•΄ λ³΄μ˜€λŠ”λ° μ‹€μ œλ‘œλŠ” 잘λͺ»λœ μƒνƒœλ₯Ό 쑰용히 μœ μ§€ν•˜κ²Œ ν–ˆλ‹€. 남겨 λ‘λŠ” 것 λŒ€μ‹  μ§€μš°λŠ” μͺ½μ„ κ³¨λžλ‹€. μ΄μœ λŠ” μ—†μ–΄μ Έμ•Ό λ“œλŸ¬λ‚˜κ³  μ‹€νŒ¨λ‘œ λ“œλŸ¬λ‚˜λŠ” 편이 μ„±κ³΅ν•œ μ²™ μ§€λ‚˜κ°€λŠ” 것보닀 λ‚˜μ•„μ„œλ‹€.

이름을 λ°”κΎΈλŠ” μž‘μ—…μ€ μ˜› 이름을 μ§€μš°λŠ” κ²ƒκΉŒμ§€κ°€ ν•œ λ¬ΆμŒμ΄μ—ˆλ‹€.

쑰치 β€” κ°€λ¦¬ν‚€λŠ” 자리 μ „μˆ˜ 탐색

κ·Έ 이름이 어디에 λ°•ν˜€ μžˆλŠ”μ§€ νŒŒμΌμ—μ„œ μ°Ύμ•˜λ‹€.

$ grep -rn '\bdev\b' --include=*.xml --include=*.groovy /var/lib/jenkins/jobs/
/var/lib/jenkins/jobs/api-deploy/config.xml:  <name>*/dev</name>
/var/lib/jenkins/jobs/api-test/config.xml:    <name>*/dev</name>
/var/lib/jenkins/jobs/batch-deploy/config.xml:<name>*/dev</name>

config.xml 셋에 μžˆμ—ˆκ³  pull.sh 에도 μžˆμ—ˆλ‹€.

$ grep -rn 'dev' /srv/deploy/*.sh
/srv/deploy/pull.sh:12:  git pull origin dev

관리 ν™”λ©΄λ§Œ 봀으면 pull.sh μͺ½μ„ 놓쳀을 것이닀.

ν™”λ©΄μœΌλ‘œ 찾으면 화면에 λ‚˜μ˜€λŠ” κ²ƒλ§Œ 찾게 λœλ‹€. 같은 값이 어디에 λ°•ν˜€ μžˆλŠ”μ§€λŠ” νŒŒμΌμ—μ„œ λ’€μ Έμ•Ό μ „λΆ€ λ‚˜μ˜¨λ‹€.

μ„€μ • β€” 이름을 ν•œ μžλ¦¬μ—

각 섀정에 λ¬Έμžμ—΄λ‘œ λ°•ν˜€ 있으면 λ‹€μŒμ— 또 λ°”κΏ€ λ•Œ 또 흩어진닀. μžλ¦¬λ§ˆλ‹€ κ³ μΉ˜λŠ” 것과 ν•œ 자리둜 λͺ¨μœΌλŠ” 것 두 κ°€μ§€ 방법 쀑 λ’€μͺ½μ΄μ—ˆλ‹€.

// Jenkinsfile
environment {
    DEPLOY_BRANCH = 'develop'
}
# /etc/deploy.env
DEPLOY_BRANCH=develop

μŠ€ν¬λ¦½νŠΈλŠ” DEPLOY_BRANCH λ₯Ό 읽어 κ°„λ‹€.

. /etc/deploy.env
git pull origin "$DEPLOY_BRANCH"

이제 이름이 λ°”λ€Œλ©΄ deploy.env ν•œ 곳만 κ³ μΉœλ‹€.

μ΄λ²ˆμ—λ„ config.xml μ…‹ 쀑 ν•˜λ‚˜λ§Œ 고쳀으면 같은 증상이 λ‹€μ‹œ 났을 것이닀. 값을 ν•œ 자리둜 λͺ¨μœΌλŠ” 것이 이 μ’…λ₯˜μ˜ 사고λ₯Ό μ—†μ• λŠ” λ°©λ²•μ΄μ—ˆλ‹€.

검증 β€” 무엇을 λ°°ν¬ν–ˆλŠ”μ§€ 남긴닀

성곡인데 μ•ˆ λ°”λ€ŒλŠ” 상황을 λ‹€μ‹œ λ§Œλ‚˜κ³  μ‹Άμ§€ μ•Šμ•˜λ‹€.

REV=$(git rev-parse --short HEAD)
BR=$(git rev-parse --abbrev-ref HEAD)
echo "$BR@$REV  $(date -Is)  by ${BUILD_USER:-jenkins}" > /srv/app/REVISION
$ curl -s http://web01/health
{"rev":"develop@8f2a1c3","at":"2018-06-24T12:10:33+09:00"}

REVISION κ³Ό health μ‘λ‹΅μœΌλ‘œ λ„λŠ” κ²ƒμ—μ„œ λ³Έλ‹€.

κΈ°λŒ€ν•œ 것과 λ‹€λ₯΄λ©΄ λ©ˆμΆ”κ²Œλ„ ν–ˆλ‹€.

EXPECT=$(git rev-parse "origin/$DEPLOY_BRANCH")
ACTUAL=$(git rev-parse HEAD)
if [ "$EXPECT" != "$ACTUAL" ]; then
    echo "받은 것이 κΈ°λŒ€μ™€ λ‹€λ¦…λ‹ˆλ‹€: expect=$EXPECT actual=$ACTUAL"; exit 1
fi

μΌλΆ€λŸ¬ λ‹€λ₯Έ μ»€λ°‹μœΌλ‘œ 체크아웃해 놓고 expect 와 actual 비ꡐ가 λ©ˆμΆ”λŠ”μ§€ λ΄€κ³  λ©ˆμ·„λ‹€.

κ΅ν›ˆ β€” μ’…λ£Œ μ½”λ“œλŠ” κ²°κ³Όλ₯Ό λ§ν•˜μ§€ μ•ŠλŠ”λ‹€

이 κ±΄μ—μ„œ 남은 것은 μ’…λ£Œ μ½”λ“œμ˜ λœ»μ΄μ—ˆλ‹€.

λ°›λŠ” 것에 μ„±κ³΅ν–ˆλ‹€   β†’  무엇을 λ°›μ•˜λŠ”μ§€λŠ” μ•ˆ λ§ν•œλ‹€
μŠ€ν¬λ¦½νŠΈκ°€ 끝났닀    β†’  λŒ€μƒμ΄ λ°”λ€Œμ—ˆλŠ”μ§€λŠ” μ•ˆ λ§ν•œλ‹€

성곡은 λͺ…령이 λλ‚¬λ‹€λŠ” λœ»μ΄μ§€ μ˜λ„ν•œ μƒνƒœκ°€ λλ‹€λŠ” 뜻이 μ•„λ‹ˆλ‹€.

BEFORE=$(curl -s http://web01/health | ...)
# 배포
AFTER=$(curl -s http://web01/health | ...)
[ "$BEFORE" = "$AFTER" ] && { echo "λ°°ν¬λλŠ”λ° ν‘œμ‹œκ°€ κ·ΈλŒ€λ‘œμž…λ‹ˆλ‹€"; exit 1; }

배포 μ „ν›„μ˜ rev λ₯Ό λΉ„κ΅ν•˜λŠ” 확인을 λ”°λ‘œ λΆ™μ˜€λ‹€.

바뀐 것을 λ³΄λŠ” 확인이 μ—†μœΌλ©΄ μ„±κ³΅λ§Œ μŒ“μΈλ‹€. μ΄λ²ˆμ—λ„ 며칠치 성곡 이λ ₯이 μžˆμ—ˆμ§€λ§Œ 그쀑 무엇도 μ‹€μ œλ‘œλŠ” 아무 일을 ν•˜μ§€ μ•Šμ•˜λ‹€.

정리


Share this post on:

Previous Post
인과관계λ₯Ό λ°°μ œν•˜λŠ” μ„Έ 단계
Next Post
μ „μ—­ κ·œμΉ™μ΄ ν•˜μœ„μ—λ„ λ‘œλ“œλœλ‹€