Skip to content

Commit 32fc633

Browse files
committed
content: cicd, network, linux 카테고리 문제 추가
1 parent 69350bf commit 32fc633

51 files changed

Lines changed: 4520 additions & 0 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
---
2+
id: "cicd-002"
3+
title: "GitHub Actions 작업 무한 대기로 인한 러너 점유"
4+
category: "cicd"
5+
difficulty: 1
6+
tags: ["github-actions", "timeout", "runner", "cost"]
7+
hints:
8+
- "GitHub Actions 작업의 기본 타임아웃 시간이 얼마인지 확인해 보세요."
9+
- "job 레벨에서 실행 시간을 제한할 수 있는 설정이 있는지 확인해 보세요."
10+
---
11+
12+
## 상황
13+
14+
GitHub Actions를 사용하여 배포 파이프라인을 운영 중입니다. 최근 deploy 작업이 간헐적으로 멈추면서 러너가 6시간 동안 점유되고, 다른 작업이 큐에 밀려 팀 전체 CI/CD가 지연되고 있습니다. 워크플로우 설정을 확인하여 원인을 분석하고 해결하세요.
15+
16+
## 데이터
17+
18+
### .github/workflows/deploy.yml
19+
20+
```yaml
21+
name: Deploy
22+
23+
on:
24+
push:
25+
branches: [main]
26+
27+
jobs:
28+
deploy:
29+
runs-on: ubuntu-latest
30+
steps:
31+
- uses: actions/checkout@v4
32+
33+
- name: Deploy to production
34+
run: ./scripts/long-running-task.sh
35+
36+
- name: Notify Slack
37+
run: |
38+
curl -X POST "$SLACK_WEBHOOK" \
39+
-d '{"text": "Deployment completed"}'
40+
```
41+
42+
### GitHub Actions 실행 로그
43+
44+
```log
45+
2024-03-01T09:00:12Z Run ./scripts/long-running-task.sh
46+
2024-03-01T09:00:13Z Connecting to deployment server...
47+
2024-03-01T09:00:14Z Uploading artifacts...
48+
2024-03-01T09:00:15Z Waiting for deployment to complete...
49+
...
50+
(이후 6시간 동안 출력 없음)
51+
...
52+
2024-03-01T15:00:15Z Error: The operation was canceled.
53+
2024-03-01T15:00:15Z ##[error]The runner has received a shutdown signal.
54+
```
55+
56+
## 해설
57+
58+
### 원인 분석
59+
60+
워크플로우에 `timeout-minutes`가 설정되어 있지 않습니다. GitHub Actions의 기본 타임아웃은 **6시간(360분)**으로, 배포 스크립트가 네트워크 문제나 외부 서비스 무응답으로 멈추면 최대 6시간 동안 러너를 점유하게 됩니다.
61+
62+
이는 다음과 같은 문제를 야기합니다:
63+
- 러너 동시 실행 수 제한에 걸려 다른 작업이 대기 상태에 빠짐
64+
- GitHub Actions 사용 시간 기반 과금 시 불필요한 비용 발생
65+
66+
### 해결 방법
67+
68+
```yaml
69+
jobs:
70+
deploy:
71+
runs-on: ubuntu-latest
72+
timeout-minutes: 10
73+
steps:
74+
- uses: actions/checkout@v4
75+
76+
- name: Deploy to production
77+
timeout-minutes: 5
78+
run: ./scripts/long-running-task.sh
79+
80+
- name: Notify Slack
81+
run: |
82+
curl -X POST "$SLACK_WEBHOOK" \
83+
-d '{"text": "Deployment completed"}'
84+
```
85+
86+
```bash
87+
# job 레벨: 전체 작업에 대한 타임아웃
88+
timeout-minutes: 10
89+
90+
# step 레벨: 개별 단계에 대한 더 세밀한 타임아웃
91+
timeout-minutes: 5
92+
```
93+
94+
### 실무 팁
95+
96+
모든 GitHub Actions 작업에는 반드시 `timeout-minutes`를 설정하세요. 일반적으로 배포 작업은 5~15분, 빌드 작업은 10~30분이 적절합니다. job 레벨과 step 레벨 모두 설정하면 외부 서비스 무응답에 의한 러너 낭비를 효과적으로 방지할 수 있습니다.
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
---
2+
id: "cicd-003"
3+
title: "Docker 이미지 latest 태그로 인한 롤백 불가"
4+
category: "cicd"
5+
difficulty: 1
6+
tags: ["docker", "image-tag", "commit-sha", "rollback"]
7+
hints:
8+
- "Docker 이미지 목록에서 태그가 어떻게 되어 있는지 확인해 보세요."
9+
- "특정 커밋 시점의 이미지를 식별할 수 있는 태깅 전략을 생각해 보세요."
10+
- "`GITHUB_SHA` 환경 변수를 활용할 수 있는지 확인해 보세요."
11+
---
12+
13+
## 상황
14+
15+
운영 환경 배포 후 애플리케이션에 심각한 버그가 발견되어 이전 버전으로 롤백해야 합니다. 그러나 Docker 이미지 레지스트리를 확인한 결과 모든 이미지가 동일한 태그로 되어 있어 어떤 커밋 버전의 이미지인지 추적할 수 없습니다. 빌드 워크플로우를 분석하여 원인을 찾으세요.
16+
17+
## 데이터
18+
19+
### .github/workflows/build.yml
20+
21+
```yaml
22+
name: Build and Push
23+
24+
on:
25+
push:
26+
branches: [main]
27+
28+
jobs:
29+
build:
30+
runs-on: ubuntu-latest
31+
steps:
32+
- uses: actions/checkout@v4
33+
34+
- name: Build Docker image
35+
run: docker build -t myapp:latest .
36+
37+
- name: Push Docker image
38+
run: docker push myapp:latest
39+
```
40+
41+
### docker images 출력
42+
43+
```log
44+
REPOSITORY TAG IMAGE ID CREATED SIZE
45+
myapp latest a1b2c3d4e5f6 2 minutes ago 245MB
46+
```
47+
48+
### 배포 히스토리
49+
50+
```log
51+
2024-03-01 09:00 배포 v1 (정상) - myapp:latest
52+
2024-03-02 10:00 배포 v2 (정상) - myapp:latest
53+
2024-03-03 11:00 배포 v3 (장애) - myapp:latest ← 현재
54+
# v2로 롤백하고 싶지만 해당 이미지를 식별할 수 없음
55+
```
56+
57+
## 해설
58+
59+
### 원인 분석
60+
61+
워크플로우에서 Docker 이미지를 항상 `latest` 태그로만 빌드하고 있습니다. `latest`는 가장 최근 빌드를 가리키는 가변 태그(mutable tag)이므로 새 이미지가 push되면 이전 이미지에 대한 참조가 사라집니다.
62+
63+
이로 인해:
64+
- 특정 커밋에 해당하는 이미지를 식별할 수 없음
65+
- 롤백 시 이전 버전의 이미지를 찾을 수 없음
66+
- 운영 환경에서 실행 중인 이미지가 어떤 코드 버전인지 추적 불가
67+
68+
### 해결 방법
69+
70+
```yaml
71+
name: Build and Push
72+
73+
on:
74+
push:
75+
branches: [main]
76+
77+
jobs:
78+
build:
79+
runs-on: ubuntu-latest
80+
steps:
81+
- uses: actions/checkout@v4
82+
83+
- name: Set short SHA
84+
run: echo "SHORT_SHA=${GITHUB_SHA::7}" >> $GITHUB_ENV
85+
86+
- name: Build Docker image
87+
run: |
88+
docker build \
89+
-t myapp:${{ env.SHORT_SHA }} \
90+
-t myapp:latest \
91+
.
92+
93+
- name: Push Docker image
94+
run: |
95+
docker push myapp:${{ env.SHORT_SHA }}
96+
docker push myapp:latest
97+
```
98+
99+
```bash
100+
# 롤백 시 특정 커밋의 이미지로 즉시 복구 가능
101+
kubectl set image deployment/myapp myapp=myapp:abc1234
102+
```
103+
104+
### 실무 팁
105+
106+
Docker 이미지 태깅에는 Git commit SHA(short)를 기본으로 사용하고, `latest`는 보조 태그로 함께 붙이는 것이 좋습니다. 추가로 Git 태그 기반 시맨틱 버전(v1.2.3)도 병행하면 릴리스 추적이 용이합니다. 이미지 레이블(`org.opencontainers.image.revision`)에 전체 SHA를 기록하면 감사(audit) 추적에도 도움이 됩니다.
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
---
2+
id: "cicd-004"
3+
title: "일시적 오류로 인한 배포 파이프라인 반복 실패"
4+
category: "cicd"
5+
difficulty: 1
6+
tags: ["github-actions", "retry", "transient-error", "deployment"]
7+
hints:
8+
- "에러 로그에서 실패 원인이 영구적인 문제인지 일시적인 문제인지 구분해 보세요."
9+
- "GitHub Actions에서 실패한 단계를 자동으로 재시도할 수 있는 방법이 있는지 찾아보세요."
10+
---
11+
12+
## 상황
13+
14+
GitHub Actions 배포 파이프라인이 최근 자주 실패합니다. 실패 후 수동으로 "Re-run jobs"를 클릭하면 대부분 성공합니다. 팀원들이 매번 수동 재실행을 해야 하는 상황이 반복되고 있습니다. 워크플로우와 에러 로그를 분석하여 원인을 파악하고 해결하세요.
15+
16+
## 데이터
17+
18+
### .github/workflows/deploy.yml
19+
20+
```yaml
21+
name: Deploy
22+
23+
on:
24+
push:
25+
branches: [main]
26+
27+
jobs:
28+
deploy:
29+
runs-on: ubuntu-latest
30+
steps:
31+
- uses: actions/checkout@v4
32+
33+
- name: Deploy to production
34+
run: ./scripts/deploy.sh
35+
```
36+
37+
### GitHub Actions 실행 로그 (실패)
38+
39+
```log
40+
Run ./scripts/deploy.sh
41+
Authenticating with deployment server...
42+
Uploading build artifacts...
43+
Error: ETIMEDOUT - Connection timed out after 30000ms
44+
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1141:16)
45+
Error: Process completed with exit code 1.
46+
```
47+
48+
### GitHub Actions 실행 로그 (수동 재실행 - 성공)
49+
50+
```log
51+
Run ./scripts/deploy.sh
52+
Authenticating with deployment server...
53+
Uploading build artifacts...
54+
Deploying version abc1234...
55+
Deployment successful!
56+
```
57+
58+
## 해설
59+
60+
### 원인 분석
61+
62+
에러 로그에서 `ETIMEDOUT - Connection timed out`이 확인됩니다. 이는 배포 서버와의 네트워크 연결이 일시적으로 실패한 것으로, 수동 재실행 시 성공하는 전형적인 일시적 오류(transient error) 패턴입니다.
63+
64+
현재 워크플로우에는 재시도 로직이 없어 일시적 네트워크 문제가 발생할 때마다 파이프라인이 실패하고, 팀원이 수동으로 재실행해야 합니다.
65+
66+
### 해결 방법
67+
68+
```yaml
69+
name: Deploy
70+
71+
on:
72+
push:
73+
branches: [main]
74+
75+
jobs:
76+
deploy:
77+
runs-on: ubuntu-latest
78+
steps:
79+
- uses: actions/checkout@v4
80+
81+
- name: Deploy to production
82+
uses: nick-fields/retry@v3
83+
with:
84+
timeout_minutes: 2
85+
max_attempts: 3
86+
command: ./scripts/deploy.sh
87+
```
88+
89+
```bash
90+
# nick-fields/retry 액션의 주요 옵션
91+
# timeout_minutes: 각 시도당 최대 실행 시간
92+
# max_attempts: 최대 재시도 횟수
93+
# retry_wait_seconds: 재시도 간 대기 시간 (기본 10초)
94+
# retry_on: error | timeout | any (재시도 트리거 조건)
95+
```
96+
97+
### 실무 팁
98+
99+
외부 서비스 호출이 포함된 CI/CD 단계에는 재시도 로직을 기본으로 추가하세요. 단, 재시도 대상은 일시적 오류(네트워크 타임아웃, 429 Too Many Requests)에 한정해야 하며, 인증 실패(401)나 리소스 부족(500) 같은 영구적 오류는 재시도해도 해결되지 않으므로 구분이 중요합니다.

0 commit comments

Comments
 (0)