Compare commits
10 Commits
831a14f1a3
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 013140f02c | |||
| 49083910c6 | |||
| d3dd1da442 | |||
| 0e9940f0a3 | |||
| 8719e1723c | |||
| 742d24ab55 | |||
| fa75dcc2ca | |||
| 171cf347f4 | |||
| 075ce3f35c | |||
| a50720e84d |
@@ -1,190 +0,0 @@
|
|||||||
name: Build Docker Image
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches: [main]
|
|
||||||
tags:
|
|
||||||
- 'v*'
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
env:
|
|
||||||
REGISTRY: gitea0213.kro.kr
|
|
||||||
IMAGE_NAME: ${{ github.repository }}
|
|
||||||
DOCKER_HOST: tcp://172.17.0.1:2375
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
build-and-push:
|
|
||||||
runs-on: ubuntu-24.04-arm
|
|
||||||
permissions:
|
|
||||||
contents: write
|
|
||||||
packages: write
|
|
||||||
|
|
||||||
outputs:
|
|
||||||
image-tag: ${{ steps.meta.outputs.tags }}
|
|
||||||
image-digest: ${{ steps.build.outputs.digest }}
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- name: Checkout code
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Log in to Gitea Container Registry
|
|
||||||
run: |
|
|
||||||
echo "${{ secrets.GITEAREGISTRY }}" | docker login ${{ env.REGISTRY }} --username bluemayne --password-stdin
|
|
||||||
|
|
||||||
- name: Lowercase repository name
|
|
||||||
id: lowercase
|
|
||||||
run: |
|
|
||||||
echo "repo=$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- name: Extract metadata (tags, labels)
|
|
||||||
id: meta
|
|
||||||
uses: docker/metadata-action@v5
|
|
||||||
with:
|
|
||||||
images: ${{ env.REGISTRY }}/${{ steps.lowercase.outputs.repo }}
|
|
||||||
tags: |
|
|
||||||
type=ref,event=branch
|
|
||||||
type=ref,event=pr
|
|
||||||
type=semver,pattern={{version}}
|
|
||||||
type=semver,pattern={{major}}.{{minor}}
|
|
||||||
type=sha,prefix={{branch}}-sha-,format=long
|
|
||||||
type=raw,value=latest,enable={{is_default_branch}}
|
|
||||||
|
|
||||||
- name: Build and push Docker image
|
|
||||||
id: build
|
|
||||||
run: |
|
|
||||||
TAGS="${{ steps.meta.outputs.tags }}"
|
|
||||||
|
|
||||||
# Build the image
|
|
||||||
docker build \
|
|
||||||
-t $(echo "$TAGS" | head -n 1) \
|
|
||||||
-f ./deploy/docker/Dockerfile \
|
|
||||||
./services/backend
|
|
||||||
|
|
||||||
# Tag all versions
|
|
||||||
FIRST_TAG=$(echo "$TAGS" | head -n 1)
|
|
||||||
echo "$TAGS" | while read tag; do
|
|
||||||
if [ "$tag" != "$FIRST_TAG" ]; then
|
|
||||||
docker tag "$FIRST_TAG" "$tag"
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
|
|
||||||
# Push all tags
|
|
||||||
echo "$TAGS" | while read tag; do
|
|
||||||
docker push "$tag"
|
|
||||||
done
|
|
||||||
|
|
||||||
# Get digest
|
|
||||||
DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' "$FIRST_TAG" | cut -d'@' -f2)
|
|
||||||
echo "digest=$DIGEST" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- name: Extract SHA tag
|
|
||||||
id: extract-tag
|
|
||||||
run: |
|
|
||||||
# Extract the SHA-based tag from the tags list
|
|
||||||
TAGS="${{ steps.meta.outputs.tags }}"
|
|
||||||
echo "All tags:"
|
|
||||||
echo "$TAGS"
|
|
||||||
echo "---"
|
|
||||||
|
|
||||||
# Get commit SHA (full 40 characters)
|
|
||||||
COMMIT_SHA="${{ github.sha }}"
|
|
||||||
|
|
||||||
# Get current branch name
|
|
||||||
BRANCH_NAME="${{ github.ref_name }}"
|
|
||||||
echo "Branch: $BRANCH_NAME"
|
|
||||||
|
|
||||||
# Method 1: Extract the full SHA tag from docker/metadata-action output
|
|
||||||
# docker/metadata-action creates: <branch>-sha-<full-40-char-sha>
|
|
||||||
SHA_TAG=$(echo "$TAGS" | grep -oE "${BRANCH_NAME}-sha-[a-f0-9]{40}" | head -n 1)
|
|
||||||
|
|
||||||
# Method 2: If not found, try to extract any branch-sha- tag (fallback)
|
|
||||||
if [ -z "$SHA_TAG" ]; then
|
|
||||||
SHA_TAG=$(echo "$TAGS" | grep -oE "${BRANCH_NAME}-sha-[a-f0-9]+" | head -n 1)
|
|
||||||
if [ -n "$SHA_TAG" ]; then
|
|
||||||
echo "⚠️ Found SHA tag (may not be full 40 chars): $SHA_TAG"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Method 3: Fallback to commit SHA directly (construct the tag)
|
|
||||||
if [ -z "$SHA_TAG" ]; then
|
|
||||||
SHA_TAG="${BRANCH_NAME}-sha-$COMMIT_SHA"
|
|
||||||
echo "⚠️ Could not extract from tags, using commit SHA: $SHA_TAG"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ -z "$SHA_TAG" ]; then
|
|
||||||
echo "❌ ERROR: Failed to extract SHA tag"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "sha-tag=$SHA_TAG" >> $GITHUB_OUTPUT
|
|
||||||
echo "✅ Extracted SHA tag: $SHA_TAG"
|
|
||||||
|
|
||||||
- name: Update kustomization with new image tag
|
|
||||||
env:
|
|
||||||
GITEA_TOKEN: ${{ secrets.GITEAREGISTRYTOKEN }}
|
|
||||||
run: |
|
|
||||||
git config --global user.name "gitea-actions[bot]"
|
|
||||||
git config --global user.email "gitea-actions[bot]@users.noreply.gitea.com"
|
|
||||||
|
|
||||||
# Validate that SHA_TAG is not empty
|
|
||||||
SHA_TAG="${{ steps.extract-tag.outputs.sha-tag }}"
|
|
||||||
if [ -z "$SHA_TAG" ]; then
|
|
||||||
echo "❌ ERROR: SHA_TAG is empty, cannot update kustomization"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# For mas, we only have prod overlay (main branch)
|
|
||||||
BRANCH_NAME="${{ github.ref_name }}"
|
|
||||||
if [ "$BRANCH_NAME" = "main" ]; then
|
|
||||||
OVERLAY="prod"
|
|
||||||
else
|
|
||||||
echo "⚠️ Unknown branch: $BRANCH_NAME, skipping kustomization update"
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
KUSTOMIZATION_FILE="deploy/k8s/overlays/$OVERLAY/kustomization.yaml"
|
|
||||||
|
|
||||||
# Check if kustomization file has images section
|
|
||||||
if grep -q "images:" "$KUSTOMIZATION_FILE"; then
|
|
||||||
echo "📝 Updating $KUSTOMIZATION_FILE with tag: $SHA_TAG"
|
|
||||||
|
|
||||||
# Update kustomization.yaml with new image tag
|
|
||||||
# Handle both cases: newTag: (with value) and newTag: (empty)
|
|
||||||
sed -i.bak "s|newTag:.*|newTag: $SHA_TAG|" "$KUSTOMIZATION_FILE"
|
|
||||||
|
|
||||||
# Verify the update was successful
|
|
||||||
if grep -q "newTag: $SHA_TAG" "$KUSTOMIZATION_FILE"; then
|
|
||||||
echo "✅ Successfully updated kustomization.yaml"
|
|
||||||
rm -f "$KUSTOMIZATION_FILE.bak"
|
|
||||||
else
|
|
||||||
echo "❌ ERROR: Failed to update kustomization.yaml"
|
|
||||||
cat "$KUSTOMIZATION_FILE"
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Commit and push if there are changes
|
|
||||||
if git diff --quiet; then
|
|
||||||
echo "No changes to commit"
|
|
||||||
else
|
|
||||||
git add "$KUSTOMIZATION_FILE"
|
|
||||||
git commit -m "Update $OVERLAY image to $SHA_TAG"
|
|
||||||
git push
|
|
||||||
echo "✅ Kustomization updated with new image tag: $SHA_TAG"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "ℹ️ $OVERLAY overlay uses base image (latest tag), skipping kustomization update"
|
|
||||||
echo " Image built with tag: $SHA_TAG"
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: Display image information
|
|
||||||
run: |
|
|
||||||
echo "✅ Image built and pushed successfully!"
|
|
||||||
echo "📦 Image tags:"
|
|
||||||
echo "${{ steps.meta.outputs.tags }}"
|
|
||||||
echo "🔖 SHA tag: ${{ steps.extract-tag.outputs.sha-tag }}"
|
|
||||||
echo "🔖 Digest: ${{ steps.build.outputs.digest }}"
|
|
||||||
echo ""
|
|
||||||
echo "🚀 Kustomization updated with new image tag"
|
|
||||||
echo " ArgoCD will automatically detect and deploy this new image"
|
|
||||||
echo " Monitor deployment at your ArgoCD dashboard"
|
|
||||||
|
|
||||||
67
.github/workflows/build.yml
vendored
Normal file
67
.github/workflows/build.yml
vendored
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
name: Build Docker Image
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [main]
|
||||||
|
tags:
|
||||||
|
- 'v*'
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
REGISTRY: ghcr.io
|
||||||
|
IMAGE_NAME: ${{ github.repository }}
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build-and-push:
|
||||||
|
runs-on: ubuntu-24.04-arm
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Log in to GitHub Container Registry
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ${{ env.REGISTRY }}
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Lowercase repository name
|
||||||
|
id: lowercase
|
||||||
|
run: |
|
||||||
|
echo "repo=$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]')" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
|
- name: Extract metadata (tags, labels)
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
|
with:
|
||||||
|
images: ${{ env.REGISTRY }}/${{ steps.lowercase.outputs.repo }}
|
||||||
|
tags: |
|
||||||
|
type=ref,event=branch
|
||||||
|
type=semver,pattern={{version}}
|
||||||
|
type=raw,value=latest,enable={{is_default_branch}}
|
||||||
|
|
||||||
|
- name: Build and push Docker image
|
||||||
|
id: build
|
||||||
|
uses: docker/build-push-action@v5
|
||||||
|
with:
|
||||||
|
context: ./langgraph
|
||||||
|
file: ./Dockerfile
|
||||||
|
push: true
|
||||||
|
platforms: linux/arm64
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
cache-from: type=gha
|
||||||
|
cache-to: type=gha,mode=max
|
||||||
|
|
||||||
|
- name: Display image information
|
||||||
|
run: |
|
||||||
|
echo "Image built and pushed successfully!"
|
||||||
|
echo "Image tags:"
|
||||||
|
echo "${{ steps.meta.outputs.tags }}"
|
||||||
337
README.md
337
README.md
@@ -1,337 +0,0 @@
|
|||||||
# MAS (Multi-Agent System)
|
|
||||||
|
|
||||||
**K8s 인프라 분석 & 의사결정 시스템** - 클러스터를 분석하고 도구 도입 여부를 결정해주는 AI 시스템
|
|
||||||
|
|
||||||
## 🎯 What is this?
|
|
||||||
|
|
||||||
MAS는 Kubernetes 클러스터 상태를 분석하고, **도구 도입 추천/비추천을 결정**해주는 AI 에이전트 시스템입니다.
|
|
||||||
|
|
||||||
**사용 시나리오:**
|
|
||||||
1. "Tekton 도입 여부를 결정해줘" → 클러스터 분석 → **도입 추천/비추천 결정**
|
|
||||||
2. 한국어로 이유, 대안, 구현 가이드 제공
|
|
||||||
3. 기술적 세부사항 없이 **명확한 결론** 제시
|
|
||||||
|
|
||||||
## 🤖 Agents
|
|
||||||
|
|
||||||
### Planning Agent (Claude 4.5)
|
|
||||||
- 도구 요구사항 분석
|
|
||||||
- 필요한 K8s 리소스 파악
|
|
||||||
- 확인이 필요한 클러스터 정보 정의
|
|
||||||
|
|
||||||
### Research Agent (Groq Llama 3.3)
|
|
||||||
- kubectl 명령어로 클러스터 상태 분석
|
|
||||||
- 기존 도구 확인 (ArgoCD, Gitea, Prometheus 등)
|
|
||||||
- 리소스 사용률 및 버전 확인
|
|
||||||
|
|
||||||
### Decision Agent (Claude 4.5)
|
|
||||||
- **도입 추천/비추천 결정** (한국어)
|
|
||||||
- 명확한 이유 제시
|
|
||||||
- 대안 제시 (비추천인 경우)
|
|
||||||
- 간단한 구현 가이드 (추천인 경우)
|
|
||||||
|
|
||||||
### Tech stack
|
|
||||||
- **Backend**: LangGraph + LangChain + FastAPI
|
|
||||||
- **UI**: Chainlit (chat-style UI)
|
|
||||||
- **Database**: PostgreSQL (CNPG)
|
|
||||||
- **Cache**: Redis
|
|
||||||
- **LLMs**: Claude API (Orchestrator, Planning, Prompt Gen) + Groq Llama 3.3 (Research)
|
|
||||||
- **Deploy**: Kubernetes + ArgoCD
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🚀 Local development
|
|
||||||
|
|
||||||
### 1. Run with Docker Compose
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd deploy/docker
|
|
||||||
|
|
||||||
# Copy or create .env and fill in your API keys
|
|
||||||
# (ANTHROPIC_API_KEY, GROQ_API_KEY, etc.)
|
|
||||||
|
|
||||||
# Start the full stack
|
|
||||||
docker compose up -d
|
|
||||||
|
|
||||||
# Tail logs
|
|
||||||
docker compose logs -f mas
|
|
||||||
```
|
|
||||||
|
|
||||||
Open: `http://localhost:8000`
|
|
||||||
|
|
||||||
### 2. Run backend directly (Python)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
cd services/backend
|
|
||||||
|
|
||||||
# Create venv
|
|
||||||
python -m venv venv
|
|
||||||
source venv/bin/activate # Windows: venv\Scripts\activate
|
|
||||||
|
|
||||||
# Install dependencies
|
|
||||||
pip install -r requirements.txt
|
|
||||||
|
|
||||||
# Environment variables
|
|
||||||
cp .env.example .env
|
|
||||||
# Edit .env and set your API keys
|
|
||||||
|
|
||||||
# Run Chainlit app
|
|
||||||
chainlit run chainlit_app.py
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## ☸️ Kubernetes deployment
|
|
||||||
|
|
||||||
### 1. Create namespace and secrets
|
|
||||||
|
|
||||||
```bash
|
|
||||||
kubectl create namespace mas
|
|
||||||
|
|
||||||
kubectl create secret generic mas-api-keys \
|
|
||||||
--from-literal=anthropic-api-key=YOUR_CLAUDE_KEY \
|
|
||||||
--from-literal=openai-api-key=YOUR_OPENAI_KEY \
|
|
||||||
--from-literal=google-api-key=YOUR_GEMINI_KEY \
|
|
||||||
-n mas
|
|
||||||
```
|
|
||||||
|
|
||||||
### 2. Deploy via ArgoCD
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Create ArgoCD Application
|
|
||||||
kubectl apply -f deploy/argocd/mas.yaml
|
|
||||||
|
|
||||||
# Sync and check status
|
|
||||||
argocd app sync mas
|
|
||||||
argocd app get mas
|
|
||||||
```
|
|
||||||
|
|
||||||
### 3. Deploy from your server (example)
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# SSH into your k3s master
|
|
||||||
ssh oracle-master
|
|
||||||
|
|
||||||
# Apply ArgoCD Application
|
|
||||||
sudo kubectl apply -f /path/to/deploy/argocd/mas.yaml
|
|
||||||
|
|
||||||
# Check status
|
|
||||||
sudo kubectl get pods -n mas
|
|
||||||
sudo kubectl logs -f deployment/mas -n mas
|
|
||||||
```
|
|
||||||
|
|
||||||
Ingress example (if configured): `https://mas.mayne.vcn`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🎨 UI customization
|
|
||||||
|
|
||||||
### Chainlit theme & behavior
|
|
||||||
|
|
||||||
You can customize the UI via `services/backend/.chainlit`:
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[UI]
|
|
||||||
name = "MAS"
|
|
||||||
show_readme_as_default = true
|
|
||||||
default_collapse_content = true
|
|
||||||
```
|
|
||||||
|
|
||||||
### Agent prompts
|
|
||||||
|
|
||||||
System prompts for each agent live in `services/backend/agents.py`.
|
|
||||||
You can tune:
|
|
||||||
- how the **Orchestrator** routes tasks
|
|
||||||
- coding style of backend/frontend agents
|
|
||||||
- SRE troubleshooting behavior
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📊 Observability
|
|
||||||
|
|
||||||
### Prometheus ServiceMonitor (example)
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
apiVersion: monitoring.coreos.com/v1
|
|
||||||
kind: ServiceMonitor
|
|
||||||
metadata:
|
|
||||||
name: mas
|
|
||||||
namespace: mas
|
|
||||||
spec:
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: mas
|
|
||||||
endpoints:
|
|
||||||
- port: http
|
|
||||||
path: /metrics
|
|
||||||
```
|
|
||||||
|
|
||||||
### Grafana dashboards
|
|
||||||
|
|
||||||
Recommended panels:
|
|
||||||
- LangGraph workflow metrics
|
|
||||||
- Per-agent latency & error rate
|
|
||||||
- Token usage and cost estimates
|
|
||||||
- Backend API latency & 5xx rate
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔧 Advanced features
|
|
||||||
|
|
||||||
### 1. MCP (Model Context Protocol) with Claude
|
|
||||||
|
|
||||||
Using Claude Code as Orchestrator, MAS can access:
|
|
||||||
- Filesystem (read/write project files)
|
|
||||||
- Git (status, commit, push, PR)
|
|
||||||
- SSH (run remote commands on your servers)
|
|
||||||
- PostgreSQL (schema inspection, migrations, queries)
|
|
||||||
- Kubernetes (kubectl via MCP tool)
|
|
||||||
|
|
||||||
This allows fully automated workflows like:
|
|
||||||
- “Create a new service, add deployment manifests, and deploy to k3s.”
|
|
||||||
- “Debug failing pods and propose a fix, then open a PR.”
|
|
||||||
|
|
||||||
### 2. Multi-agent collaboration (LangGraph)
|
|
||||||
|
|
||||||
Typical workflow:
|
|
||||||
|
|
||||||
```text
|
|
||||||
User request
|
|
||||||
↓
|
|
||||||
Claude Orchestrator
|
|
||||||
↓ decides which agent(s) to call
|
|
||||||
Backend Dev → Frontend Dev → SRE
|
|
||||||
↓
|
|
||||||
Claude Orchestrator (review & summary)
|
|
||||||
↓
|
|
||||||
Final answer to user
|
|
||||||
```
|
|
||||||
|
|
||||||
Examples:
|
|
||||||
- Full‑stack feature (API + UI + monitoring)
|
|
||||||
- Infra rollout (Harbor, Tekton, CNPG, MetalLB) with validation
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📝 Usage examples
|
|
||||||
|
|
||||||
### Example 1: Tekton 도입 여부 결정
|
|
||||||
|
|
||||||
```text
|
|
||||||
User: "Tekton 도입 여부를 결정해줘"
|
|
||||||
|
|
||||||
🎼 Orchestrator → 조율
|
|
||||||
|
|
||||||
📋 Planning Agent:
|
|
||||||
→ Tekton 요구사항: Namespace, CRDs, Controllers
|
|
||||||
→ 필요 리소스: 2 CPU, 4GB RAM
|
|
||||||
→ 확인 필요: 기존 CI/CD 도구, K8s 버전
|
|
||||||
|
|
||||||
🔍 Research Agent:
|
|
||||||
→ kubectl get nodes: v1.33.6, 3 nodes ✓
|
|
||||||
→ kubectl get pods -A: ArgoCD 운영 중 발견
|
|
||||||
→ Gitea Actions 사용 가능 확인
|
|
||||||
|
|
||||||
💡 Decision Agent:
|
|
||||||
❌ Tekton 도입 비추천
|
|
||||||
|
|
||||||
이유:
|
|
||||||
- ArgoCD + Gitea Actions로 충분
|
|
||||||
- 추가 리소스 소비 불필요
|
|
||||||
- 학습 곡선 및 유지보수 부담
|
|
||||||
|
|
||||||
대안:
|
|
||||||
- Gitea Actions 활용 (이미 설치됨)
|
|
||||||
- ArgoCD로 배포 자동화 유지
|
|
||||||
|
|
||||||
✨ Output: 명확한 한국어 보고서
|
|
||||||
```
|
|
||||||
|
|
||||||
### Example 2: Harbor 필요성 분석
|
|
||||||
|
|
||||||
```text
|
|
||||||
User: "Harbor가 필요한지 분석해줘"
|
|
||||||
|
|
||||||
→ Planning: Harbor 요구사항 분석
|
|
||||||
→ Research: 기존 registry 확인 (Gitea Container Registry 발견)
|
|
||||||
→ Decision:
|
|
||||||
❌ Harbor 도입 비추천
|
|
||||||
이유: Gitea Container Registry로 충분
|
|
||||||
|
|
||||||
✨ 사용자 친화적 한국어 결론
|
|
||||||
```
|
|
||||||
|
|
||||||
### Example 3: Prometheus 설치 여부
|
|
||||||
|
|
||||||
```text
|
|
||||||
User: "Prometheus를 설치해야 할까?"
|
|
||||||
|
|
||||||
→ Planning: Monitoring stack 요구사항
|
|
||||||
→ Research: 이미 Prometheus 운영 중 발견!
|
|
||||||
→ Decision:
|
|
||||||
✅ 이미 설치되어 있음
|
|
||||||
현재 상태: monitoring namespace에서 정상 작동 중
|
|
||||||
|
|
||||||
✨ 중복 설치 방지
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 🔧 Workflow
|
|
||||||
|
|
||||||
```
|
|
||||||
User Input: "X 도입 여부를 결정해줘"
|
|
||||||
↓
|
|
||||||
Orchestrator (조율)
|
|
||||||
↓
|
|
||||||
Planning Agent (도구 요구사항 분석)
|
|
||||||
↓
|
|
||||||
Research Agent (클러스터 상태 분석)
|
|
||||||
↓
|
|
||||||
Decision Agent (한국어 의사결정 보고서)
|
|
||||||
↓
|
|
||||||
Output: ✅ 추천 또는 ❌ 비추천 (이유 포함)
|
|
||||||
```
|
|
||||||
|
|
||||||
## 📊 출력 예시
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
# Tekton 도입 분석 결과
|
|
||||||
|
|
||||||
## 📊 현재 클러스터 상태
|
|
||||||
- Kubernetes 버전: v1.33.6
|
|
||||||
- 노드: 3개 (1 control-plane, 2 workers)
|
|
||||||
- 기존 CI/CD: ArgoCD, Gitea Actions
|
|
||||||
- 운영 애플리케이션: 15개
|
|
||||||
|
|
||||||
## 💡 권장사항: Tekton 도입 비추천
|
|
||||||
|
|
||||||
### ❌ 비추천 이유
|
|
||||||
1. ArgoCD + Gitea Actions 조합으로 충분
|
|
||||||
2. 추가 리소스 소비 (2 CPU, 4GB RAM)
|
|
||||||
3. 학습 곡선 및 운영 부담 증가
|
|
||||||
|
|
||||||
### 🔄 권장 대안
|
|
||||||
- Gitea Actions로 빌드 파이프라인 구성
|
|
||||||
- ArgoCD로 GitOps 배포 유지
|
|
||||||
- 필요시 GitHub Actions 연동
|
|
||||||
|
|
||||||
## 🎯 결론
|
|
||||||
현재 인프라로 충분하며, Tekton 도입은 불필요합니다.
|
|
||||||
```
|
|
||||||
|
|
||||||
## 🤝 Contributing
|
|
||||||
|
|
||||||
Contributions are welcome:
|
|
||||||
- Improve Planning Agent prompts for better folder structures
|
|
||||||
- Enhance Research Agent kubectl commands
|
|
||||||
- Add more infrastructure tools (Harbor, Tekton, CNPG, MetalLB, etc.)
|
|
||||||
- Better Markdown template for Prompt Generator
|
|
||||||
|
|
||||||
Feel free to open issues or PRs in your Git repository.
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 📄 License
|
|
||||||
|
|
||||||
MIT
|
|
||||||
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
apiVersion: argoproj.io/v1alpha1
|
|
||||||
kind: Application
|
|
||||||
metadata:
|
|
||||||
name: mas-prod
|
|
||||||
namespace: argocd
|
|
||||||
finalizers:
|
|
||||||
- resources-finalizer.argocd.argoproj.io
|
|
||||||
spec:
|
|
||||||
project: default
|
|
||||||
source:
|
|
||||||
repoURL: https://github.com/Mayne0213/mas.git
|
|
||||||
targetRevision: main
|
|
||||||
path: deploy/k8s/overlays/prod
|
|
||||||
destination:
|
|
||||||
server: https://kubernetes.default.svc
|
|
||||||
namespace: mas
|
|
||||||
syncPolicy:
|
|
||||||
automated:
|
|
||||||
prune: true
|
|
||||||
selfHeal: true
|
|
||||||
allowEmpty: false
|
|
||||||
syncOptions:
|
|
||||||
- CreateNamespace=true
|
|
||||||
retry:
|
|
||||||
limit: 5
|
|
||||||
backoff:
|
|
||||||
duration: 5s
|
|
||||||
factor: 2
|
|
||||||
maxDuration: 3m
|
|
||||||
revisionHistoryLimit: 10
|
|
||||||
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
apiVersion: argoproj.io/v1alpha1
|
|
||||||
kind: Application
|
|
||||||
metadata:
|
|
||||||
name: mas
|
|
||||||
namespace: argocd
|
|
||||||
finalizers:
|
|
||||||
- resources-finalizer.argocd.argoproj.io
|
|
||||||
spec:
|
|
||||||
project: default
|
|
||||||
|
|
||||||
source:
|
|
||||||
repoURL: https://github.com/Mayne0213/mas.git
|
|
||||||
targetRevision: main
|
|
||||||
path: deploy/argocd
|
|
||||||
|
|
||||||
destination:
|
|
||||||
server: https://kubernetes.default.svc
|
|
||||||
namespace: argocd
|
|
||||||
|
|
||||||
syncPolicy:
|
|
||||||
automated:
|
|
||||||
prune: true
|
|
||||||
selfHeal: true
|
|
||||||
allowEmpty: false
|
|
||||||
|
|
||||||
syncOptions:
|
|
||||||
- CreateNamespace=true
|
|
||||||
|
|
||||||
retry:
|
|
||||||
limit: 5
|
|
||||||
backoff:
|
|
||||||
duration: 5s
|
|
||||||
factor: 2
|
|
||||||
maxDuration: 3m
|
|
||||||
|
|
||||||
revisionHistoryLimit: 10
|
|
||||||
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
|
||||||
kind: Kustomization
|
|
||||||
|
|
||||||
resources:
|
|
||||||
# App of Apps Application (self-managing)
|
|
||||||
- application.yaml
|
|
||||||
|
|
||||||
# Application deployments
|
|
||||||
- application-prod.yaml
|
|
||||||
|
|
||||||
@@ -1,84 +0,0 @@
|
|||||||
apiVersion: apps/v1
|
|
||||||
kind: Deployment
|
|
||||||
metadata:
|
|
||||||
name: mas
|
|
||||||
namespace: mas
|
|
||||||
labels:
|
|
||||||
app: mas
|
|
||||||
spec:
|
|
||||||
replicas: 1
|
|
||||||
selector:
|
|
||||||
matchLabels:
|
|
||||||
app: mas
|
|
||||||
template:
|
|
||||||
metadata:
|
|
||||||
labels:
|
|
||||||
app: mas
|
|
||||||
spec:
|
|
||||||
hostPID: true # 호스트 프로세스 네임스페이스 접근
|
|
||||||
serviceAccountName: mas
|
|
||||||
containers:
|
|
||||||
- name: mas
|
|
||||||
image: github.com/Mayne0213/mas:latest
|
|
||||||
imagePullPolicy: Always
|
|
||||||
securityContext:
|
|
||||||
privileged: true # nsenter 사용을 위한 권한
|
|
||||||
ports:
|
|
||||||
- containerPort: 8000
|
|
||||||
name: http
|
|
||||||
env:
|
|
||||||
- name: ANTHROPIC_API_KEY
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: mas-api-keys
|
|
||||||
key: anthropic-api-key
|
|
||||||
- name: GROQ_API_KEY
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: mas-api-keys
|
|
||||||
key: groq-api-key
|
|
||||||
- name: GROQ_API_BASE
|
|
||||||
value: "https://api.groq.com/openai/v1"
|
|
||||||
# Chainlit uses asyncpg directly (not SQLAlchemy)
|
|
||||||
- name: CHAINLIT_DATABASE_URL
|
|
||||||
value: "postgresql://bluemayne:$(POSTGRES_PASSWORD)@postgresql-cnpg-rw.postgresql-cnpg.svc.cluster.local:5432/mas"
|
|
||||||
# SQLAlchemy format (if needed)
|
|
||||||
- name: DATABASE_URL
|
|
||||||
value: "postgresql://bluemayne:$(POSTGRES_PASSWORD)@postgresql-cnpg-rw.postgresql-cnpg.svc.cluster.local:5432/mas"
|
|
||||||
- name: POSTGRES_HOST
|
|
||||||
value: "postgresql-cnpg-rw.postgresql-cnpg.svc.cluster.local"
|
|
||||||
- name: POSTGRES_PORT
|
|
||||||
value: "5432"
|
|
||||||
- name: POSTGRES_USER
|
|
||||||
value: "bluemayne"
|
|
||||||
- name: POSTGRES_PASSWORD
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: postgresql-password
|
|
||||||
key: password
|
|
||||||
- name: GITEA_TOKEN
|
|
||||||
valueFrom:
|
|
||||||
secretKeyRef:
|
|
||||||
name: mas-api-keys
|
|
||||||
key: gitea-token
|
|
||||||
optional: true
|
|
||||||
- name: REDIS_URL
|
|
||||||
value: "redis://redis:6379/0"
|
|
||||||
resources:
|
|
||||||
requests:
|
|
||||||
memory: "256Mi"
|
|
||||||
cpu: "100m"
|
|
||||||
limits:
|
|
||||||
memory: "1Gi"
|
|
||||||
# cpu: removed to prevent throttling
|
|
||||||
volumeMounts:
|
|
||||||
- name: projects
|
|
||||||
mountPath: /mnt/projects
|
|
||||||
nodeSelector:
|
|
||||||
kubernetes.io/hostname: mayne-vcn # Only run on master node where Projects directory exists
|
|
||||||
volumes:
|
|
||||||
- name: projects
|
|
||||||
hostPath:
|
|
||||||
path: /home/ubuntu/Projects
|
|
||||||
type: Directory
|
|
||||||
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
|
||||||
kind: Kustomization
|
|
||||||
|
|
||||||
resources:
|
|
||||||
- deployment.yaml
|
|
||||||
- service.yaml
|
|
||||||
- serviceaccount.yaml
|
|
||||||
|
|
||||||
commonLabels:
|
|
||||||
app.kubernetes.io/name: mas
|
|
||||||
app.kubernetes.io/component: platform
|
|
||||||
|
|
||||||
images:
|
|
||||||
- name: github.com/Mayne0213/mas
|
|
||||||
newTag: latest
|
|
||||||
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: Service
|
|
||||||
metadata:
|
|
||||||
name: mas
|
|
||||||
namespace: mas
|
|
||||||
labels:
|
|
||||||
app: mas
|
|
||||||
spec:
|
|
||||||
type: ClusterIP
|
|
||||||
ports:
|
|
||||||
- port: 8000
|
|
||||||
targetPort: 8000
|
|
||||||
protocol: TCP
|
|
||||||
name: http
|
|
||||||
selector:
|
|
||||||
app: mas
|
|
||||||
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: ServiceAccount
|
|
||||||
metadata:
|
|
||||||
name: mas
|
|
||||||
namespace: mas
|
|
||||||
---
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: ClusterRole
|
|
||||||
metadata:
|
|
||||||
name: mas-viewer
|
|
||||||
rules:
|
|
||||||
- apiGroups: ["", "apps", "batch", "networking.k8s.io"]
|
|
||||||
resources: ["*"]
|
|
||||||
verbs: ["get", "list", "watch"]
|
|
||||||
---
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: ClusterRole
|
|
||||||
metadata:
|
|
||||||
name: mas-writer
|
|
||||||
rules:
|
|
||||||
- apiGroups: ["", "apps", "batch", "networking.k8s.io"]
|
|
||||||
resources: ["*"]
|
|
||||||
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
|
|
||||||
---
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: ClusterRoleBinding
|
|
||||||
metadata:
|
|
||||||
name: mas-viewer-binding
|
|
||||||
roleRef:
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
kind: ClusterRole
|
|
||||||
name: mas-viewer
|
|
||||||
subjects:
|
|
||||||
- kind: ServiceAccount
|
|
||||||
name: mas
|
|
||||||
namespace: mas
|
|
||||||
---
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: ClusterRoleBinding
|
|
||||||
metadata:
|
|
||||||
name: mas-writer-binding
|
|
||||||
roleRef:
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
kind: ClusterRole
|
|
||||||
name: mas-writer
|
|
||||||
subjects:
|
|
||||||
- kind: ServiceAccount
|
|
||||||
name: mas
|
|
||||||
namespace: mas
|
|
||||||
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
apiVersion: external-secrets.io/v1beta1
|
|
||||||
kind: ExternalSecret
|
|
||||||
metadata:
|
|
||||||
name: mas-api-keys
|
|
||||||
spec:
|
|
||||||
refreshInterval: 1h
|
|
||||||
secretStoreRef:
|
|
||||||
kind: ClusterSecretStore
|
|
||||||
name: vault-backend
|
|
||||||
target:
|
|
||||||
name: mas-api-keys
|
|
||||||
creationPolicy: Owner
|
|
||||||
data:
|
|
||||||
- secretKey: anthropic-api-key
|
|
||||||
remoteRef:
|
|
||||||
key: mas/api-keys
|
|
||||||
property: ANTHROPIC_API_KEY
|
|
||||||
- secretKey: groq-api-key
|
|
||||||
remoteRef:
|
|
||||||
key: mas/api-keys
|
|
||||||
property: GROQ_API_KEY
|
|
||||||
---
|
|
||||||
apiVersion: external-secrets.io/v1beta1
|
|
||||||
kind: ExternalSecret
|
|
||||||
metadata:
|
|
||||||
name: postgresql-password
|
|
||||||
spec:
|
|
||||||
refreshInterval: 1h
|
|
||||||
secretStoreRef:
|
|
||||||
kind: ClusterSecretStore
|
|
||||||
name: vault-backend
|
|
||||||
target:
|
|
||||||
name: postgresql-password
|
|
||||||
creationPolicy: Owner
|
|
||||||
data:
|
|
||||||
- secretKey: password
|
|
||||||
remoteRef:
|
|
||||||
key: databases/postgresql-cnpg
|
|
||||||
property: PASSWORD
|
|
||||||
- secretKey: postgres-password
|
|
||||||
remoteRef:
|
|
||||||
key: databases/postgresql-cnpg
|
|
||||||
property: POSTGRES_PASSWORD
|
|
||||||
---
|
|
||||||
apiVersion: external-secrets.io/v1beta1
|
|
||||||
kind: ExternalSecret
|
|
||||||
metadata:
|
|
||||||
name: postgresql-root-password
|
|
||||||
spec:
|
|
||||||
refreshInterval: 1h
|
|
||||||
secretStoreRef:
|
|
||||||
kind: ClusterSecretStore
|
|
||||||
name: vault-backend
|
|
||||||
target:
|
|
||||||
name: postgresql-root-password
|
|
||||||
creationPolicy: Owner
|
|
||||||
data:
|
|
||||||
- secretKey: password
|
|
||||||
remoteRef:
|
|
||||||
key: databases/postgresql-cnpg
|
|
||||||
property: POSTGRES_PASSWORD
|
|
||||||
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
apiVersion: networking.k8s.io/v1
|
|
||||||
kind: Ingress
|
|
||||||
metadata:
|
|
||||||
name: mas-ingress
|
|
||||||
annotations:
|
|
||||||
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
|
||||||
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
|
||||||
# WebSocket 지원 (Chainlit UI에 필요)
|
|
||||||
nginx.ingress.kubernetes.io/websocket-services: "mas"
|
|
||||||
# 프록시 타임아웃 설정 (장시간 스트리밍 응답)
|
|
||||||
nginx.ingress.kubernetes.io/proxy-connect-timeout: "3600"
|
|
||||||
nginx.ingress.kubernetes.io/proxy-send-timeout: "3600"
|
|
||||||
nginx.ingress.kubernetes.io/proxy-read-timeout: "3600"
|
|
||||||
# 프록시 버퍼링 비활성화 (스트리밍 응답)
|
|
||||||
nginx.ingress.kubernetes.io/proxy-buffering: "off"
|
|
||||||
spec:
|
|
||||||
ingressClassName: haproxy
|
|
||||||
tls:
|
|
||||||
- hosts:
|
|
||||||
- mas0213.kro.kr
|
|
||||||
- www.mas0213.kro.kr
|
|
||||||
secretName: mas-tls
|
|
||||||
rules:
|
|
||||||
- host: mas0213.kro.kr
|
|
||||||
http:
|
|
||||||
paths:
|
|
||||||
- path: /
|
|
||||||
pathType: Prefix
|
|
||||||
backend:
|
|
||||||
service:
|
|
||||||
name: mas
|
|
||||||
port:
|
|
||||||
number: 8000
|
|
||||||
- host: www.mas0213.kro.kr
|
|
||||||
http:
|
|
||||||
paths:
|
|
||||||
- path: /
|
|
||||||
pathType: Prefix
|
|
||||||
backend:
|
|
||||||
service:
|
|
||||||
name: mas
|
|
||||||
port:
|
|
||||||
number: 8000
|
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
|
||||||
kind: Kustomization
|
|
||||||
|
|
||||||
namespace: mas
|
|
||||||
|
|
||||||
resources:
|
|
||||||
- ../../base
|
|
||||||
- resourcequota.yaml
|
|
||||||
- externalsecret.yaml
|
|
||||||
- ingress.yaml
|
|
||||||
|
|
||||||
commonLabels:
|
|
||||||
environment: production
|
|
||||||
|
|
||||||
# 이미지 태그 설정 (ArgoCD Image Updater가 자동으로 업데이트)
|
|
||||||
images:
|
|
||||||
- name: github.com/Mayne0213/mas
|
|
||||||
newTag: main-sha-004c30bfa872c37dd3da5ad8501589c415807da8
|
|
||||||
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: Namespace
|
|
||||||
metadata:
|
|
||||||
name: mas
|
|
||||||
labels:
|
|
||||||
name: mas
|
|
||||||
environment: production
|
|
||||||
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: ResourceQuota
|
|
||||||
metadata:
|
|
||||||
name: mas-quota
|
|
||||||
spec:
|
|
||||||
hard:
|
|
||||||
requests.cpu: "4"
|
|
||||||
requests.memory: 8Gi
|
|
||||||
# limits.cpu: "8" # Removed to prevent quota enforcement (we removed CPU limits cluster-wide)
|
|
||||||
limits.memory: 16Gi
|
|
||||||
persistentvolumeclaims: "5"
|
|
||||||
|
|
||||||
@@ -1,127 +0,0 @@
|
|||||||
apiVersion: v1
|
|
||||||
kind: ServiceAccount
|
|
||||||
metadata:
|
|
||||||
name: mas
|
|
||||||
namespace: mas
|
|
||||||
---
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: ClusterRole
|
|
||||||
metadata:
|
|
||||||
name: mas-viewer
|
|
||||||
rules:
|
|
||||||
# Read-only access to most resources
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources:
|
|
||||||
- pods
|
|
||||||
- pods/log
|
|
||||||
- services
|
|
||||||
- endpoints
|
|
||||||
- namespaces
|
|
||||||
- nodes
|
|
||||||
- persistentvolumeclaims
|
|
||||||
- configmaps
|
|
||||||
verbs: ["get", "list", "watch"]
|
|
||||||
|
|
||||||
- apiGroups: ["apps"]
|
|
||||||
resources:
|
|
||||||
- deployments
|
|
||||||
- statefulsets
|
|
||||||
- daemonsets
|
|
||||||
- replicasets
|
|
||||||
verbs: ["get", "list", "watch"]
|
|
||||||
|
|
||||||
- apiGroups: ["batch"]
|
|
||||||
resources:
|
|
||||||
- jobs
|
|
||||||
- cronjobs
|
|
||||||
verbs: ["get", "list", "watch"]
|
|
||||||
|
|
||||||
- apiGroups: ["networking.k8s.io"]
|
|
||||||
resources:
|
|
||||||
- ingresses
|
|
||||||
verbs: ["get", "list", "watch"]
|
|
||||||
|
|
||||||
- apiGroups: ["argoproj.io"]
|
|
||||||
resources:
|
|
||||||
- applications
|
|
||||||
verbs: ["get", "list", "watch"]
|
|
||||||
|
|
||||||
# Describe resources
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources:
|
|
||||||
- pods/status
|
|
||||||
- services/status
|
|
||||||
verbs: ["get"]
|
|
||||||
---
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: ClusterRoleBinding
|
|
||||||
metadata:
|
|
||||||
name: mas-viewer-binding
|
|
||||||
roleRef:
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
kind: ClusterRole
|
|
||||||
name: mas-viewer
|
|
||||||
subjects:
|
|
||||||
- kind: ServiceAccount
|
|
||||||
name: mas
|
|
||||||
namespace: mas
|
|
||||||
---
|
|
||||||
# YAML Manager용 write 권한 (Groq 에이전트)
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: ClusterRole
|
|
||||||
metadata:
|
|
||||||
name: mas-writer
|
|
||||||
rules:
|
|
||||||
# Write access for YAML Manager
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources:
|
|
||||||
- pods
|
|
||||||
- services
|
|
||||||
- configmaps
|
|
||||||
- secrets
|
|
||||||
verbs: ["create", "update", "patch", "delete"]
|
|
||||||
|
|
||||||
- apiGroups: ["apps"]
|
|
||||||
resources:
|
|
||||||
- deployments
|
|
||||||
- statefulsets
|
|
||||||
- daemonsets
|
|
||||||
- replicasets
|
|
||||||
verbs: ["create", "update", "patch", "delete"]
|
|
||||||
|
|
||||||
- apiGroups: ["networking.k8s.io"]
|
|
||||||
resources:
|
|
||||||
- ingresses
|
|
||||||
verbs: ["create", "update", "patch", "delete"]
|
|
||||||
|
|
||||||
- apiGroups: ["batch"]
|
|
||||||
resources:
|
|
||||||
- jobs
|
|
||||||
- cronjobs
|
|
||||||
verbs: ["create", "update", "patch", "delete"]
|
|
||||||
|
|
||||||
# Namespace management
|
|
||||||
- apiGroups: [""]
|
|
||||||
resources:
|
|
||||||
- namespaces
|
|
||||||
verbs: ["create", "update", "patch"]
|
|
||||||
|
|
||||||
# ArgoCD Application management
|
|
||||||
- apiGroups: ["argoproj.io"]
|
|
||||||
resources:
|
|
||||||
- applications
|
|
||||||
verbs: ["create", "update", "patch", "delete"]
|
|
||||||
---
|
|
||||||
apiVersion: rbac.authorization.k8s.io/v1
|
|
||||||
kind: ClusterRoleBinding
|
|
||||||
metadata:
|
|
||||||
name: mas-writer-binding
|
|
||||||
roleRef:
|
|
||||||
apiGroup: rbac.authorization.k8s.io
|
|
||||||
kind: ClusterRole
|
|
||||||
name: mas-writer
|
|
||||||
subjects:
|
|
||||||
- kind: ServiceAccount
|
|
||||||
name: mas
|
|
||||||
namespace: mas
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user