deployment-strategy
1
总安装量
1
周安装量
#42123
全站排名
安装命令
npx skills add https://github.com/shaul1991/shaul-agents-plugin --skill deployment-strategy
Skill 文档
Deployment Strategy Agent
ìí
ìì íê³ ì 뢰í ì ìë ë°°í¬ ì ëµì ì립íê³ ì¤íí©ëë¤.
ë°°í¬ ì ëµ ì í
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â ë°°í¬ ì ëµ ë¹êµ â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ¤
â â
â Big Bang (ê¶ì¥íì§ ìì) â
â ââââââââââââ ââââââââââââ â
â â v1.0 â ââ⺠â v2.0 â í ë²ì 100% ì í â
â ââââââââââââ ââââââââââââ 리ì¤í¬: ëì â
â â
â Blue-Green â
â ââââââââââââ ââââââââââââ â
â â Blue â â Green â ë íê²½ ì ì§ â
â â (v1.0) â ââ⺠â (v2.0) â í¸ëí½ ì¦ì ì í â
â ââââââââââââ ââââââââââââ 롤백: ì¦ì ê°ë¥ â
â â
â Canary â
â ââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â
â â v1.0: 100% ââ⺠90% ââ⺠50% ââ⺠0% â â
â â v2.0: 0% ââ⺠10% ââ⺠50% ââ⺠100% â â
â ââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â
â ì ì§ì 롤ìì, 리ì¤í¬ ìµìí â
â â
â Feature Flag â
â ââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â
â â ì½ëë ë°°í¬ë¨, 기ë¥ì ë¹íì± â â
â â Flag ON: í¹ì ì¬ì©ì/ê·¸ë£¹ë§ íì±í â â
â â 문ì ì Flag OFFë¡ ì¦ì ë¹íì±í â â
â ââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â
â â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
Feature Flag ì¤ì
LaunchDarkly ì¤ì
// src/lib/feature-flags.ts
import * as LaunchDarkly from 'launchdarkly-js-client-sdk';
const client = LaunchDarkly.initialize(
process.env.LAUNCHDARKLY_CLIENT_ID!,
{
key: 'user-id',
email: 'user@example.com',
custom: {
plan: 'premium',
beta: true,
},
}
);
export const isFeatureEnabled = async (flagKey: string): Promise<boolean> => {
await client.waitForInitialization();
return client.variation(flagKey, false);
};
// ì¬ì© ìì
if (await isFeatureEnabled('new-checkout-flow')) {
// ì ì²´í¬ìì íë¡ì°
} else {
// 기존 ì²´í¬ìì íë¡ì°
}
ìì²´ 구í Feature Flag
// src/lib/feature-flags.ts
interface FeatureFlag {
key: string;
enabled: boolean;
percentage: number;
allowedUsers: string[];
allowedGroups: string[];
killSwitch: boolean;
}
const flags: Record<string, FeatureFlag> = {
'new-feature': {
key: 'new-feature',
enabled: true,
percentage: 10, // 10% ì¬ì©ììê² ë
¸ì¶
allowedUsers: ['admin'], // í¹ì ì¬ì©ìë íì íì±í
allowedGroups: ['beta'], // ë² í 그룹ì íì íì±í
killSwitch: false, // ê¸´ê¸ ë¹íì±í ì¤ìì¹
},
};
export const isEnabled = (
flagKey: string,
userId: string,
userGroups: string[] = []
): boolean => {
const flag = flags[flagKey];
if (!flag || !flag.enabled || flag.killSwitch) {
return false;
}
// í¹ì ì¬ì©ì ì²´í¬
if (flag.allowedUsers.includes(userId)) {
return true;
}
// í¹ì 그룹 ì²´í¬
if (userGroups.some(g => flag.allowedGroups.includes(g))) {
return true;
}
// í¼ì¼í°ì§ ê¸°ë° ë¡¤ìì
const hash = hashUserId(userId);
return hash < flag.percentage;
};
const hashUserId = (userId: string): number => {
let hash = 0;
for (let i = 0; i < userId.length; i++) {
hash = ((hash << 5) - hash) + userId.charCodeAt(i);
hash |= 0;
}
return Math.abs(hash) % 100;
};
React Hook
// src/hooks/useFeatureFlag.ts
import { useEffect, useState } from 'react';
import { isEnabled } from '@/lib/feature-flags';
import { useUser } from '@/hooks/useUser';
export const useFeatureFlag = (flagKey: string): boolean => {
const [enabled, setEnabled] = useState(false);
const { user } = useUser();
useEffect(() => {
if (user) {
setEnabled(isEnabled(flagKey, user.id, user.groups));
}
}, [flagKey, user]);
return enabled;
};
// ì¬ì© ìì
const MyComponent = () => {
const showNewFeature = useFeatureFlag('new-feature');
return showNewFeature ? <NewFeature /> : <OldFeature />;
};
Canary ë°°í¬
Kubernetes Canary
# canary-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-canary
spec:
replicas: 1 # ì ì²´ì 10%
selector:
matchLabels:
app: myapp
version: canary
template:
metadata:
labels:
app: myapp
version: canary
spec:
containers:
- name: app
image: myapp:v2.0
ports:
- containerPort: 3000
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-stable
spec:
replicas: 9 # ì ì²´ì 90%
selector:
matchLabels:
app: myapp
version: stable
template:
metadata:
labels:
app: myapp
version: stable
spec:
containers:
- name: app
image: myapp:v1.0
ports:
- containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
name: app-service
spec:
selector:
app: myapp # ë ë²ì 모ë ì í
ports:
- port: 80
targetPort: 3000
Canary 롤ìì ì¤í¬ë¦½í¸
#!/bin/bash
# canary-rollout.sh
CANARY_PERCENTAGE=$1
TOTAL_REPLICAS=10
CANARY_REPLICAS=$((TOTAL_REPLICAS * CANARY_PERCENTAGE / 100))
STABLE_REPLICAS=$((TOTAL_REPLICAS - CANARY_REPLICAS))
echo "Rolling out canary: $CANARY_PERCENTAGE%"
echo "Canary replicas: $CANARY_REPLICAS"
echo "Stable replicas: $STABLE_REPLICAS"
# Canary ì¤ì¼ì¼
kubectl scale deployment app-canary --replicas=$CANARY_REPLICAS
# Stable ì¤ì¼ì¼
kubectl scale deployment app-stable --replicas=$STABLE_REPLICAS
# ìí íì¸
kubectl rollout status deployment/app-canary
kubectl rollout status deployment/app-stable
Canary 롤ìì ë¨ê³
## Canary ë°°í¬ ì²´í¬ë¦¬ì¤í¸
### Stage 1: 10% (1ìê°)
- [ ] Canary ë°°í¬ ìë£
- [ ] ìë¬ì¨ < 1%
- [ ] ìëµ ìê° ì ì
- [ ] ë¡ê·¸ íì¸
### Stage 2: 25% (2ìê°)
- [ ] í¸ëí½ ì¦ê°
- [ ] ë©í¸ë¦ ì ì
- [ ] ì¬ì©ì í¼ëë°± ìì
### Stage 3: 50% (4ìê°)
- [ ] ì ë° í¸ëí½
- [ ] ì±ë¥ ì í ìì
- [ ] DB ë¶í ì ì
### Stage 4: 100% (ì ì²´ 롤ìì)
- [ ] 모ë í¸ëí½ ì í
- [ ] ì´ì ë²ì ì ê±°
- [ ] 문ì ì
ë°ì´í¸
Blue-Green ë°°í¬
# blue-green.yaml
# Blue (íì¬ íë¡ëì
)
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-blue
spec:
replicas: 3
selector:
matchLabels:
app: myapp
color: blue
template:
metadata:
labels:
app: myapp
color: blue
spec:
containers:
- name: app
image: myapp:v1.0
---
# Green (ì ë²ì )
apiVersion: apps/v1
kind: Deployment
metadata:
name: app-green
spec:
replicas: 3
selector:
matchLabels:
app: myapp
color: green
template:
metadata:
labels:
app: myapp
color: green
spec:
containers:
- name: app
image: myapp:v2.0
---
# Service (í¸ëí½ ì íì©)
apiVersion: v1
kind: Service
metadata:
name: app-service
spec:
selector:
app: myapp
color: blue # greenì¼ë¡ ë³ê²½íì¬ ì í
ports:
- port: 80
targetPort: 3000
ì í ì¤í¬ë¦½í¸
#!/bin/bash
# switch-traffic.sh
CURRENT_COLOR=$(kubectl get svc app-service -o jsonpath='{.spec.selector.color}')
if [ "$CURRENT_COLOR" == "blue" ]; then
NEW_COLOR="green"
else
NEW_COLOR="blue"
fi
echo "Switching from $CURRENT_COLOR to $NEW_COLOR"
# í¸ëí½ ì í
kubectl patch svc app-service -p '{"spec":{"selector":{"color":"'$NEW_COLOR'"}}}'
# íì¸
kubectl get svc app-service -o jsonpath='{.spec.selector.color}'
롤백 ì ëµ
ìë 롤백 ì¡°ê±´
# rollback-conditions.yaml
rollback:
automatic: true
conditions:
- metric: error_rate
threshold: 5%
duration: 5m
- metric: latency_p99
threshold: 2000ms
duration: 5m
- metric: cpu_usage
threshold: 90%
duration: 10m
actions:
- type: alert
channels: [slack, pagerduty]
- type: rollback
target: previous_stable
- type: scale_down
target: canary
replicas: 0
롤백 ì¤í¬ë¦½í¸
#!/bin/bash
# rollback.sh
echo "Starting rollback..."
# Kubernetes 롤백
kubectl rollout undo deployment/app
# ëë í¹ì ë²ì ì¼ë¡
kubectl rollout undo deployment/app --to-revision=2
# Feature Flag ë¹íì±í
curl -X PATCH https://api.launchdarkly.com/api/v2/flags/project/flag-key \
-H "Authorization: api-key" \
-H "Content-Type: application/json" \
-d '{"patch":[{"op":"replace","path":"/environments/production/on","value":false}]}'
# ìí íì¸
kubectl rollout status deployment/app
echo "Rollback completed"
ë°°í¬ ì²´í¬ë¦¬ì¤í¸
## ë°°í¬ ì ì²´í¬ë¦¬ì¤í¸
### ì½ë ì¤ë¹
- [ ] 모ë í
ì¤í¸ íµê³¼
- [ ] ì½ë 리뷰 ìë£
- [ ] ë³´ì ì¤ìº íµê³¼
- [ ] 문ì ì
ë°ì´í¸
### íê²½ ì¤ë¹
- [ ] íê²½ ë³ì ì¤ì
- [ ] Secret ì
ë°ì´í¸
- [ ] DB ë§ì´ê·¸ë ì´ì
ì¤ë¹
- [ ] Feature Flag ì¤ì
### ë°°í¬ ì¤ë¹
- [ ] 롤백 ê³í ì립
- [ ] 모ëí°ë§ ëìë³´ë ì¤ë¹
- [ ] ì림 ì±ë íì¸
- [ ] ì¨ì½ ë´ë¹ì íì¸
### ë°°í¬ í ì²´í¬ë¦¬ì¤í¸
- [ ] í¬ì¤ì²´í¬ íµê³¼
- [ ] ìë¬ì¨ ì ì
- [ ] ì±ë¥ ì ì
- [ ] ë¡ê·¸ íì¸
모ëí°ë§ ëìë³´ë
## ë°°í¬ ëª¨ëí°ë§ ì§í
### íµì¬ ì§í
| ì§í | ìê³ê° | íì¬ | ìí |
|------|--------|------|------|
| Error Rate | < 1% | 0.2% | â
|
| P99 Latency | < 500ms | 320ms | â
|
| CPU Usage | < 80% | 45% | â
|
| Memory Usage | < 80% | 62% | â
|
### ë¹ì¦ëì¤ ì§í
| ì§í | ê¸°ì¤ | íì¬ | ë³í |
|------|------|------|------|
| ì íì¨ | 3.2% | 3.1% | -0.1% |
| ì´íë¥ | 45% | 46% | +1% |
| íì´ì§ë·° | 10K/h | 9.8K/h | -2% |
ì°ì¶ë¬¼ ìì¹
- ë°°í¬ ê³í:
docs/features/<기ë¥ëª >/implementation/deployment-plan.md - 롤백 ê³í:
docs/features/<기ë¥ëª >/implementation/rollback-plan.md - ë°°í¬ ì²´í¬ë¦¬ì¤í¸:
docs/features/<기ë¥ëª >/gates/gate-6-checklist.md