@llm-translate/cli 1.0.0-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.dockerignore +51 -0
- package/.env.example +33 -0
- package/.github/workflows/docs-pages.yml +57 -0
- package/.github/workflows/release.yml +49 -0
- package/.translaterc.json +44 -0
- package/CLAUDE.md +243 -0
- package/Dockerfile +55 -0
- package/README.md +371 -0
- package/RFC.md +1595 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +4494 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/index.d.ts +1152 -0
- package/dist/index.js +3841 -0
- package/dist/index.js.map +1 -0
- package/docker-compose.yml +56 -0
- package/docs/.vitepress/config.ts +161 -0
- package/docs/api/agent.md +262 -0
- package/docs/api/engine.md +274 -0
- package/docs/api/index.md +171 -0
- package/docs/api/providers.md +304 -0
- package/docs/changelog.md +64 -0
- package/docs/cli/dir.md +243 -0
- package/docs/cli/file.md +213 -0
- package/docs/cli/glossary.md +273 -0
- package/docs/cli/index.md +129 -0
- package/docs/cli/init.md +158 -0
- package/docs/cli/serve.md +211 -0
- package/docs/glossary.json +235 -0
- package/docs/guide/chunking.md +272 -0
- package/docs/guide/configuration.md +139 -0
- package/docs/guide/cost-optimization.md +237 -0
- package/docs/guide/docker.md +371 -0
- package/docs/guide/getting-started.md +150 -0
- package/docs/guide/glossary.md +241 -0
- package/docs/guide/index.md +86 -0
- package/docs/guide/ollama.md +515 -0
- package/docs/guide/prompt-caching.md +221 -0
- package/docs/guide/providers.md +232 -0
- package/docs/guide/quality-control.md +206 -0
- package/docs/guide/vitepress-integration.md +265 -0
- package/docs/index.md +63 -0
- package/docs/ja/api/agent.md +262 -0
- package/docs/ja/api/engine.md +274 -0
- package/docs/ja/api/index.md +171 -0
- package/docs/ja/api/providers.md +304 -0
- package/docs/ja/changelog.md +64 -0
- package/docs/ja/cli/dir.md +243 -0
- package/docs/ja/cli/file.md +213 -0
- package/docs/ja/cli/glossary.md +273 -0
- package/docs/ja/cli/index.md +111 -0
- package/docs/ja/cli/init.md +158 -0
- package/docs/ja/guide/chunking.md +271 -0
- package/docs/ja/guide/configuration.md +139 -0
- package/docs/ja/guide/cost-optimization.md +30 -0
- package/docs/ja/guide/getting-started.md +150 -0
- package/docs/ja/guide/glossary.md +214 -0
- package/docs/ja/guide/index.md +32 -0
- package/docs/ja/guide/ollama.md +410 -0
- package/docs/ja/guide/prompt-caching.md +221 -0
- package/docs/ja/guide/providers.md +232 -0
- package/docs/ja/guide/quality-control.md +137 -0
- package/docs/ja/guide/vitepress-integration.md +265 -0
- package/docs/ja/index.md +58 -0
- package/docs/ko/api/agent.md +262 -0
- package/docs/ko/api/engine.md +274 -0
- package/docs/ko/api/index.md +171 -0
- package/docs/ko/api/providers.md +304 -0
- package/docs/ko/changelog.md +64 -0
- package/docs/ko/cli/dir.md +243 -0
- package/docs/ko/cli/file.md +213 -0
- package/docs/ko/cli/glossary.md +273 -0
- package/docs/ko/cli/index.md +111 -0
- package/docs/ko/cli/init.md +158 -0
- package/docs/ko/guide/chunking.md +271 -0
- package/docs/ko/guide/configuration.md +139 -0
- package/docs/ko/guide/cost-optimization.md +30 -0
- package/docs/ko/guide/getting-started.md +150 -0
- package/docs/ko/guide/glossary.md +214 -0
- package/docs/ko/guide/index.md +32 -0
- package/docs/ko/guide/ollama.md +410 -0
- package/docs/ko/guide/prompt-caching.md +221 -0
- package/docs/ko/guide/providers.md +232 -0
- package/docs/ko/guide/quality-control.md +137 -0
- package/docs/ko/guide/vitepress-integration.md +265 -0
- package/docs/ko/index.md +58 -0
- package/docs/zh/api/agent.md +262 -0
- package/docs/zh/api/engine.md +274 -0
- package/docs/zh/api/index.md +171 -0
- package/docs/zh/api/providers.md +304 -0
- package/docs/zh/changelog.md +64 -0
- package/docs/zh/cli/dir.md +243 -0
- package/docs/zh/cli/file.md +213 -0
- package/docs/zh/cli/glossary.md +273 -0
- package/docs/zh/cli/index.md +111 -0
- package/docs/zh/cli/init.md +158 -0
- package/docs/zh/guide/chunking.md +271 -0
- package/docs/zh/guide/configuration.md +139 -0
- package/docs/zh/guide/cost-optimization.md +30 -0
- package/docs/zh/guide/getting-started.md +150 -0
- package/docs/zh/guide/glossary.md +214 -0
- package/docs/zh/guide/index.md +32 -0
- package/docs/zh/guide/ollama.md +410 -0
- package/docs/zh/guide/prompt-caching.md +221 -0
- package/docs/zh/guide/providers.md +232 -0
- package/docs/zh/guide/quality-control.md +137 -0
- package/docs/zh/guide/vitepress-integration.md +265 -0
- package/docs/zh/index.md +58 -0
- package/package.json +91 -0
- package/release.config.mjs +15 -0
- package/schemas/glossary.schema.json +110 -0
- package/src/cli/commands/dir.ts +469 -0
- package/src/cli/commands/file.ts +291 -0
- package/src/cli/commands/glossary.ts +221 -0
- package/src/cli/commands/init.ts +68 -0
- package/src/cli/commands/serve.ts +60 -0
- package/src/cli/index.ts +64 -0
- package/src/cli/options.ts +59 -0
- package/src/core/agent.ts +1119 -0
- package/src/core/chunker.ts +391 -0
- package/src/core/engine.ts +634 -0
- package/src/errors.ts +188 -0
- package/src/index.ts +147 -0
- package/src/integrations/vitepress.ts +549 -0
- package/src/parsers/markdown.ts +383 -0
- package/src/providers/claude.ts +259 -0
- package/src/providers/interface.ts +109 -0
- package/src/providers/ollama.ts +379 -0
- package/src/providers/openai.ts +308 -0
- package/src/providers/registry.ts +153 -0
- package/src/server/index.ts +152 -0
- package/src/server/middleware/auth.ts +93 -0
- package/src/server/middleware/logger.ts +90 -0
- package/src/server/routes/health.ts +84 -0
- package/src/server/routes/translate.ts +210 -0
- package/src/server/types.ts +138 -0
- package/src/services/cache.ts +899 -0
- package/src/services/config.ts +217 -0
- package/src/services/glossary.ts +247 -0
- package/src/types/analysis.ts +164 -0
- package/src/types/index.ts +265 -0
- package/src/types/modes.ts +121 -0
- package/src/types/mqm.ts +157 -0
- package/src/utils/logger.ts +141 -0
- package/src/utils/tokens.ts +116 -0
- package/tests/fixtures/glossaries/ml-glossary.json +53 -0
- package/tests/fixtures/input/lynq-installation.ko.md +350 -0
- package/tests/fixtures/input/lynq-installation.md +350 -0
- package/tests/fixtures/input/simple.ko.md +27 -0
- package/tests/fixtures/input/simple.md +27 -0
- package/tests/unit/chunker.test.ts +229 -0
- package/tests/unit/glossary.test.ts +146 -0
- package/tests/unit/markdown.test.ts +205 -0
- package/tests/unit/tokens.test.ts +81 -0
- package/tsconfig.json +28 -0
- package/tsup.config.ts +34 -0
- package/vitest.config.ts +16 -0
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
// ============================================================================
|
|
2
|
+
// Token Counting Utilities
|
|
3
|
+
// ============================================================================
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Approximate token count for a given text.
|
|
7
|
+
* This is a rough estimate - actual token counts may vary by model.
|
|
8
|
+
*
|
|
9
|
+
* Rules of thumb:
|
|
10
|
+
* - English: ~4 characters per token
|
|
11
|
+
* - CJK (Korean, Japanese, Chinese): ~1.5 characters per token
|
|
12
|
+
* - Code: ~3.5 characters per token
|
|
13
|
+
*/
|
|
14
|
+
export function estimateTokens(text: string): number {
|
|
15
|
+
if (!text) return 0;
|
|
16
|
+
|
|
17
|
+
// Count different character types
|
|
18
|
+
let latinChars = 0;
|
|
19
|
+
let cjkChars = 0;
|
|
20
|
+
let otherChars = 0;
|
|
21
|
+
|
|
22
|
+
for (const char of text) {
|
|
23
|
+
const code = char.charCodeAt(0);
|
|
24
|
+
|
|
25
|
+
// CJK Unified Ideographs and related ranges
|
|
26
|
+
if (
|
|
27
|
+
(code >= 0x4e00 && code <= 0x9fff) || // CJK Unified Ideographs
|
|
28
|
+
(code >= 0x3400 && code <= 0x4dbf) || // CJK Extension A
|
|
29
|
+
(code >= 0xac00 && code <= 0xd7af) || // Hangul Syllables
|
|
30
|
+
(code >= 0x3040 && code <= 0x309f) || // Hiragana
|
|
31
|
+
(code >= 0x30a0 && code <= 0x30ff) // Katakana
|
|
32
|
+
) {
|
|
33
|
+
cjkChars++;
|
|
34
|
+
} else if (
|
|
35
|
+
(code >= 0x0041 && code <= 0x005a) || // A-Z
|
|
36
|
+
(code >= 0x0061 && code <= 0x007a) || // a-z
|
|
37
|
+
(code >= 0x0030 && code <= 0x0039) // 0-9
|
|
38
|
+
) {
|
|
39
|
+
latinChars++;
|
|
40
|
+
} else {
|
|
41
|
+
otherChars++;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Calculate tokens based on character types
|
|
46
|
+
const latinTokens = latinChars / 4;
|
|
47
|
+
const cjkTokens = cjkChars / 1.5;
|
|
48
|
+
const otherTokens = otherChars / 3;
|
|
49
|
+
|
|
50
|
+
return Math.ceil(latinTokens + cjkTokens + otherTokens);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Check if text exceeds a token limit
|
|
55
|
+
*/
|
|
56
|
+
export function exceedsTokenLimit(text: string, limit: number): boolean {
|
|
57
|
+
return estimateTokens(text) > limit;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Truncate text to approximately fit within a token limit
|
|
62
|
+
*/
|
|
63
|
+
export function truncateToTokenLimit(text: string, limit: number): string {
|
|
64
|
+
const estimated = estimateTokens(text);
|
|
65
|
+
|
|
66
|
+
if (estimated <= limit) {
|
|
67
|
+
return text;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Estimate character limit based on average token ratio
|
|
71
|
+
const avgCharsPerToken = text.length / estimated;
|
|
72
|
+
const targetChars = Math.floor(limit * avgCharsPerToken * 0.95); // 5% safety margin
|
|
73
|
+
|
|
74
|
+
return text.slice(0, targetChars) + '...';
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// ============================================================================
|
|
78
|
+
// Token Budget Calculator
|
|
79
|
+
// ============================================================================
|
|
80
|
+
|
|
81
|
+
export interface TokenBudget {
|
|
82
|
+
total: number;
|
|
83
|
+
system: number;
|
|
84
|
+
glossary: number;
|
|
85
|
+
context: number;
|
|
86
|
+
content: number;
|
|
87
|
+
reserved: number;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export function calculateTokenBudget(
|
|
91
|
+
maxTokens: number,
|
|
92
|
+
glossarySize: number,
|
|
93
|
+
contextSize: number
|
|
94
|
+
): TokenBudget {
|
|
95
|
+
// Reserve tokens for system prompt, formatting, etc.
|
|
96
|
+
const reserved = 500;
|
|
97
|
+
|
|
98
|
+
// Glossary and context have fixed sizes
|
|
99
|
+
const glossary = glossarySize;
|
|
100
|
+
const context = contextSize;
|
|
101
|
+
|
|
102
|
+
// System prompt estimate
|
|
103
|
+
const system = 300;
|
|
104
|
+
|
|
105
|
+
// Content gets the remainder
|
|
106
|
+
const content = maxTokens - reserved - glossary - context - system;
|
|
107
|
+
|
|
108
|
+
return {
|
|
109
|
+
total: maxTokens,
|
|
110
|
+
system,
|
|
111
|
+
glossary,
|
|
112
|
+
context,
|
|
113
|
+
content: Math.max(content, 100), // Ensure minimum content budget
|
|
114
|
+
reserved,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
{
|
|
2
|
+
"metadata": {
|
|
3
|
+
"name": "ML/AI Glossary",
|
|
4
|
+
"sourceLang": "en",
|
|
5
|
+
"targetLangs": ["ko", "ja", "zh-CN"],
|
|
6
|
+
"version": "1.0.0",
|
|
7
|
+
"domain": "machine-learning"
|
|
8
|
+
},
|
|
9
|
+
"terms": [
|
|
10
|
+
{
|
|
11
|
+
"source": "machine learning",
|
|
12
|
+
"targets": {
|
|
13
|
+
"ko": "머신러닝",
|
|
14
|
+
"ja": "機械学習",
|
|
15
|
+
"zh-CN": "机器学习"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"source": "artificial intelligence",
|
|
20
|
+
"targets": {
|
|
21
|
+
"ko": "인공지능",
|
|
22
|
+
"ja": "人工知能",
|
|
23
|
+
"zh-CN": "人工智能"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"source": "neural network",
|
|
28
|
+
"targets": {
|
|
29
|
+
"ko": "신경망",
|
|
30
|
+
"ja": "ニューラルネットワーク",
|
|
31
|
+
"zh-CN": "神经网络"
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"source": "deep learning",
|
|
36
|
+
"targets": {
|
|
37
|
+
"ko": "딥러닝",
|
|
38
|
+
"ja": "ディープラーニング",
|
|
39
|
+
"zh-CN": "深度学习"
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
"source": "API",
|
|
44
|
+
"targets": {},
|
|
45
|
+
"doNotTranslate": true
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
"source": "SDK",
|
|
49
|
+
"targets": {},
|
|
50
|
+
"doNotTranslate": true
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
}
|
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
# 설치 가이드
|
|
2
|
+
|
|
3
|
+
이 가이드는 Lynq의 다양한 설치 방법을 다룹니다.
|
|
4
|
+
|
|
5
|
+
[[toc]]
|
|
6
|
+
|
|
7
|
+
::: tip 로컬에서 시도하고 싶으신가요?
|
|
8
|
+
처음 사용자를 위해 자동화된 설정이 포함된 [Minikube를 사용한 빠른 시작](quickstart.md) 가이드를 사용하세요.
|
|
9
|
+
:::
|
|
10
|
+
|
|
11
|
+
## 전제 조건
|
|
12
|
+
|
|
13
|
+
### 필수
|
|
14
|
+
|
|
15
|
+
| 구성 요소 | 최소 버전 | 참고 |
|
|
16
|
+
| --- | --- | --- |
|
|
17
|
+
| Kubernetes 클러스터 | v1.11.3+ | API 호환성은 최신 릴리스로 테스트됨 |
|
|
18
|
+
| `kubectl` | 클러스터와 일치 | 배포할 클러스터를 대상으로 해야 함 |
|
|
19
|
+
| **cert-manager** | **v1.13.0+** | **모든 설치에 필수** (프로덕션, 개발, 로컬) |
|
|
20
|
+
|
|
21
|
+
::: danger cert-manager는 필수입니다
|
|
22
|
+
**cert-manager v1.13.0+**는 **모든 설치에 필수**입니다 (프로덕션, 개발 및 로컬 환경). 이는 webhook TLS 인증서를 프로비저닝하고, 자동 갱신을 처리하며, CA 번들을 webhook 구성에 주입합니다.
|
|
23
|
+
|
|
24
|
+
**Webhook은 더 이상 선택 사항이 아닙니다.** 이들은 승인 시간에 필수적인 검증 및 기본값 설정을 제공합니다.
|
|
25
|
+
|
|
26
|
+
Lynq를 배포하기 전에 설치하세요:
|
|
27
|
+
```bash
|
|
28
|
+
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml
|
|
29
|
+
```
|
|
30
|
+
:::
|
|
31
|
+
|
|
32
|
+
### 선택 사항
|
|
33
|
+
|
|
34
|
+
- **MySQL 데이터베이스** (노드 데이터 소스용, PostgreSQL 지원은 v1.2에서 계획됨)
|
|
35
|
+
|
|
36
|
+
## Kubernetes 호환성
|
|
37
|
+
|
|
38
|
+
### 지원되는 버전
|
|
39
|
+
|
|
40
|
+
이 오퍼레이터는 GA/안정적인 Kubernetes API 및 controller-runtime 패턴만 사용하므로 지원되는 업스트림 버전 스큐 전체에서 호환됩니다.
|
|
41
|
+
|
|
42
|
+
**검증된 버전** (엔드-투-엔드 테스트 및 프로덕션 검증됨):
|
|
43
|
+
|
|
44
|
+
| Kubernetes 버전 | 상태 |
|
|
45
|
+
|--------------------|--------|
|
|
46
|
+
| v1.28 | ✅ 검증됨 |
|
|
47
|
+
| v1.29 | ✅ 검증됨 |
|
|
48
|
+
| v1.30 | ✅ 검증됨 |
|
|
49
|
+
| v1.31 | ✅ 검증됨 |
|
|
50
|
+
| v1.32 | ✅ 검증됨 |
|
|
51
|
+
| v1.33 | ✅ 검증됨 |
|
|
52
|
+
| 기타 GA 릴리스 | ⚠️ 작동할 것으로 예상됨 |
|
|
53
|
+
|
|
54
|
+
::: tip 호환성 철학
|
|
55
|
+
이 오퍼레이터는 Kubernetes 버전 스큐 전체에서 작동하도록 설계되었습니다. 이전 또는 최신 버전도 작동할 것으로 예상되지만, 광범위하게 배포하기 전에 스테이징 환경에서 검증하세요.
|
|
56
|
+
:::
|
|
57
|
+
|
|
58
|
+
## 설치 방법
|
|
59
|
+
|
|
60
|
+
### 방법 1: Helm으로 설치 (권장)
|
|
61
|
+
|
|
62
|
+
**cert-manager는 모든 설치에 필수**입니다.
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
# Step 1: Install cert-manager (REQUIRED)
|
|
66
|
+
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml
|
|
67
|
+
|
|
68
|
+
# Step 2: Wait for cert-manager to be ready
|
|
69
|
+
kubectl wait --for=condition=Available --timeout=300s -n cert-manager \
|
|
70
|
+
deployment/cert-manager \
|
|
71
|
+
deployment/cert-manager-webhook \
|
|
72
|
+
deployment/cert-manager-cainjector
|
|
73
|
+
|
|
74
|
+
# Step 3: Add Helm repository
|
|
75
|
+
helm repo add lynq https://k8s-lynq.github.io/lynq
|
|
76
|
+
helm repo update
|
|
77
|
+
|
|
78
|
+
# Step 4: Install Lynq
|
|
79
|
+
helm install lynq lynq/lynq \
|
|
80
|
+
--namespace lynq-system \
|
|
81
|
+
--create-namespace
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
자세한 구성 옵션은 [Helm 차트 README](https://github.com/k8s-lynq/lynq/blob/main/chart/README.md)를 참조하세요.
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
### 방법 2: Kustomize로 설치
|
|
89
|
+
|
|
90
|
+
**cert-manager는 webhook TLS 인증서 관리에 필수**입니다.
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
# Step 1: Install cert-manager (if not already installed)
|
|
94
|
+
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml
|
|
95
|
+
|
|
96
|
+
# Step 2: Wait for cert-manager to be ready
|
|
97
|
+
kubectl wait --for=condition=Available --timeout=300s -n cert-manager deployment/cert-manager
|
|
98
|
+
kubectl wait --for=condition=Available --timeout=300s -n cert-manager deployment/cert-manager-webhook
|
|
99
|
+
|
|
100
|
+
# Step 3: Install Lynq
|
|
101
|
+
# cert-manager will automatically issue and manage webhook TLS certificates
|
|
102
|
+
kubectl apply -k https://github.com/k8s-lynq/lynq/config/default
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
::: info cert-manager가 처리하는 것
|
|
106
|
+
- webhook 서버용 TLS 인증서 발급
|
|
107
|
+
- 만료 전에 인증서 갱신
|
|
108
|
+
- webhook 구성에 CA 번들 주입
|
|
109
|
+
- Kubernetes 클러스터를 위한 검증된 인증서 자동화 제공
|
|
110
|
+
:::
|
|
111
|
+
|
|
112
|
+
### 방법 3: 소스에서 설치
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
# Clone repository
|
|
116
|
+
git clone https://github.com/k8s-lynq/lynq.git
|
|
117
|
+
cd lynq
|
|
118
|
+
|
|
119
|
+
# Install CRDs
|
|
120
|
+
make install
|
|
121
|
+
|
|
122
|
+
# Install cert-manager first if not already installed
|
|
123
|
+
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml
|
|
124
|
+
|
|
125
|
+
# Deploy operator
|
|
126
|
+
make deploy IMG=ghcr.io/k8s-lynq/lynq:latest
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
::: warning TLS 기억하기
|
|
130
|
+
소스에서 배포할 때도 오퍼레이터 매니페스트를 적용하기 전에 cert-manager를 설치하세요. 그렇지 않으면 webhook이 시작되지 않습니다.
|
|
131
|
+
:::
|
|
132
|
+
|
|
133
|
+
### 방법 4: Minikube를 사용한 로컬 개발
|
|
134
|
+
|
|
135
|
+
로컬 개발의 경우 자동화된 설정 스크립트와 함께 Minikube를 사용하세요. **cert-manager는 설정 스크립트에 의해 자동으로 설치**됩니다.
|
|
136
|
+
|
|
137
|
+
자세한 지침은 [Minikube를 사용한 로컬 개발](local-development-minikube.md)을 참조하세요.
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
# Quick setup (cert-manager included)
|
|
141
|
+
./scripts/setup-minikube.sh # Create cluster with cert-manager
|
|
142
|
+
./scripts/deploy-to-minikube.sh # Build and deploy operator
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
::: tip 로컬 개발에서의 cert-manager
|
|
146
|
+
설정 스크립트가 cert-manager를 자동으로 설치합니다. 제공된 스크립트를 사용할 때 로컬 개발을 위해 수동으로 설치할 필요가 없습니다.
|
|
147
|
+
:::
|
|
148
|
+
|
|
149
|
+
## 검증
|
|
150
|
+
|
|
151
|
+
오퍼레이터가 실행 중인지 확인하세요:
|
|
152
|
+
|
|
153
|
+
```bash
|
|
154
|
+
# Check operator deployment
|
|
155
|
+
kubectl get deployment -n lynq-system lynq-controller-manager
|
|
156
|
+
|
|
157
|
+
# Check operator logs
|
|
158
|
+
kubectl logs -n lynq-system deployment/lynq-controller-manager -f
|
|
159
|
+
|
|
160
|
+
# Verify CRDs are installed
|
|
161
|
+
kubectl get crd | grep operator.lynq.sh
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
예상 출력:
|
|
165
|
+
```
|
|
166
|
+
lynqhubs.operator.lynq.sh 2025-01-15T10:00:00Z
|
|
167
|
+
lynqnodes.operator.lynq.sh 2025-01-15T10:00:00Z
|
|
168
|
+
lynqforms.operator.lynq.sh 2025-01-15T10:00:00Z
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
::: tip 문제 해결
|
|
172
|
+
배포가 준비되지 않은 경우 `kubectl describe deployment/lynq-controller-manager`을(를) 검사하여 webhook, RBAC 또는 이미지 문제를 확인하세요.
|
|
173
|
+
:::
|
|
174
|
+
|
|
175
|
+
## 구성 옵션
|
|
176
|
+
|
|
177
|
+
### Webhook TLS 구성
|
|
178
|
+
|
|
179
|
+
Webhook TLS는 cert-manager에 의해 자동으로 관리됩니다. 기본 구성에는 다음이 포함됩니다:
|
|
180
|
+
|
|
181
|
+
```yaml
|
|
182
|
+
# config/default/kustomization.yaml
|
|
183
|
+
# Webhook patches are enabled by default
|
|
184
|
+
patches:
|
|
185
|
+
- path: manager_webhook_patch.yaml
|
|
186
|
+
- path: webhookcainjection_patch.yaml
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
::: info cert-manager의 역할
|
|
190
|
+
- 웹훅 서버용 TLS 인증서 발급
|
|
191
|
+
- 웹훅 구성에 CA 번들 삽입
|
|
192
|
+
- 만료 전 인증서 갱신
|
|
193
|
+
:::
|
|
194
|
+
|
|
195
|
+
### 리소스 제한
|
|
196
|
+
|
|
197
|
+
클러스터 크기에 따라 오퍼레이터 리소스 제한을 조정합니다:
|
|
198
|
+
|
|
199
|
+
```yaml
|
|
200
|
+
# config/manager/manager.yaml
|
|
201
|
+
resources:
|
|
202
|
+
limits:
|
|
203
|
+
cpu: 500m # Increase for large clusters
|
|
204
|
+
memory: 512Mi # Increase for many nodes
|
|
205
|
+
requests:
|
|
206
|
+
cpu: 100m
|
|
207
|
+
memory: 128Mi
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
### 동시성 설정
|
|
211
|
+
|
|
212
|
+
동시 재조정 워커를 구성합니다:
|
|
213
|
+
|
|
214
|
+
```yaml
|
|
215
|
+
spec:
|
|
216
|
+
template:
|
|
217
|
+
spec:
|
|
218
|
+
containers:
|
|
219
|
+
- name: manager
|
|
220
|
+
args:
|
|
221
|
+
- --node-concurrency=10 # Concurrent LynqNode reconciliations (default: 10)
|
|
222
|
+
- --form-concurrency=5 # Concurrent Template reconciliations (default: 5)
|
|
223
|
+
- --hub-concurrency=3 # Concurrent Hub syncs (default: 3)
|
|
224
|
+
- --leader-elect # Enable leader election
|
|
225
|
+
```
|
|
226
|
+
|
|
227
|
+
## 다중 플랫폼 지원
|
|
228
|
+
|
|
229
|
+
오퍼레이터는 여러 아키텍처를 지원합니다:
|
|
230
|
+
|
|
231
|
+
- `linux/amd64` (Intel/AMD 64비트)
|
|
232
|
+
- `linux/arm64` (ARM 64비트, Apple Silicon)
|
|
233
|
+
|
|
234
|
+
컨테이너 이미지는 플랫폼에 맞게 자동으로 선택되어 가져옵니다.
|
|
235
|
+
|
|
236
|
+
## 네임스페이스 격리
|
|
237
|
+
|
|
238
|
+
기본적으로 오퍼레이터는 `lynq-system` 네임스페이스에 설치됩니다:
|
|
239
|
+
|
|
240
|
+
```bash
|
|
241
|
+
# Check operator namespace
|
|
242
|
+
kubectl get all -n lynq-system
|
|
243
|
+
|
|
244
|
+
# View RBAC
|
|
245
|
+
kubectl get clusterrole | grep lynq
|
|
246
|
+
kubectl get clusterrolebinding | grep lynq
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## 업그레이드
|
|
250
|
+
|
|
251
|
+
### CRD 먼저 업그레이드
|
|
252
|
+
|
|
253
|
+
```bash
|
|
254
|
+
# Upgrade CRDs (safe, preserves existing data)
|
|
255
|
+
make install
|
|
256
|
+
|
|
257
|
+
# Or with kubectl
|
|
258
|
+
kubectl apply -f config/crd/bases/
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### 오퍼레이터 업그레이드
|
|
262
|
+
|
|
263
|
+
```bash
|
|
264
|
+
# Update operator deployment
|
|
265
|
+
kubectl set image -n lynq-system \
|
|
266
|
+
deployment/lynq-controller-manager \
|
|
267
|
+
manager=ghcr.io/k8s-lynq/lynq:v1.1.0
|
|
268
|
+
|
|
269
|
+
# Or use make
|
|
270
|
+
make deploy IMG=ghcr.io/k8s-lynq/lynq:v1.1.0
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
### 롤백
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
# Rollback to previous version
|
|
277
|
+
kubectl rollout undo -n lynq-system \
|
|
278
|
+
deployment/lynq-controller-manager
|
|
279
|
+
|
|
280
|
+
# Check rollout status
|
|
281
|
+
kubectl rollout status -n lynq-system \
|
|
282
|
+
deployment/lynq-controller-manager
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
## 제거
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
# Delete operator deployment
|
|
289
|
+
kubectl delete -k config/default
|
|
290
|
+
|
|
291
|
+
# Or with make
|
|
292
|
+
make undeploy
|
|
293
|
+
|
|
294
|
+
# Delete CRDs (WARNING: This deletes all LynqNode data!)
|
|
295
|
+
make uninstall
|
|
296
|
+
|
|
297
|
+
# Or with kubectl
|
|
298
|
+
kubectl delete crd lynqhubs.operator.lynq.sh
|
|
299
|
+
kubectl delete crd lynqforms.operator.lynq.sh
|
|
300
|
+
kubectl delete crd lynqnodes.operator.lynq.sh
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
**경고:** CRD를 삭제하면 모든 LynqHub, LynqForm 및 LynqNode 리소스가 삭제됩니다. 필요한 경우 백업을 준비하세요.
|
|
304
|
+
|
|
305
|
+
## 설치 문제 해결
|
|
306
|
+
|
|
307
|
+
### 웹훅 TLS 오류
|
|
308
|
+
|
|
309
|
+
**오류:** `open /tmp/k8s-webhook-server/serving-certs/tls.crt: no such file or directory`
|
|
310
|
+
|
|
311
|
+
**해결책:** cert-manager를 설치하여 웹훅 TLS 인증서를 자동으로 관리합니다.
|
|
312
|
+
|
|
313
|
+
```bash
|
|
314
|
+
# Install cert-manager
|
|
315
|
+
kubectl apply -f https://github.com/cert-manager/cert-manager/releases/download/v1.13.0/cert-manager.yaml
|
|
316
|
+
|
|
317
|
+
# Wait for cert-manager to be ready
|
|
318
|
+
kubectl wait --for=condition=Available --timeout=300s -n cert-manager deployment/cert-manager
|
|
319
|
+
|
|
320
|
+
# Restart operator to pick up certificates
|
|
321
|
+
kubectl rollout restart -n lynq-system deployment/lynq-controller-manager
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
### CRD가 이미 존재함
|
|
325
|
+
|
|
326
|
+
**오류:** `Error from server (AlreadyExists): customresourcedefinitions.apiextensions.k8s.io "lynqnodes.operator.lynq.sh" already exists`
|
|
327
|
+
|
|
328
|
+
**해결책:** 이는 업그레이드 중에 정상적인 현상입니다. CRD 업데이트가 자동으로 적용됩니다.
|
|
329
|
+
|
|
330
|
+
### 이미지 풀 오류
|
|
331
|
+
|
|
332
|
+
**오류:** `Failed to pull image "ghcr.io/k8s-lynq/lynq:latest"`
|
|
333
|
+
|
|
334
|
+
**해결책:** 클러스터가 GitHub Container Registry(ghcr.io)에 접근할 수 있는지 확인합니다. 필요한 경우 네트워크 정책 및 이미지 풀 시크릿을 확인하세요.
|
|
335
|
+
|
|
336
|
+
### 권한 거부 오류
|
|
337
|
+
|
|
338
|
+
**오류:** `Error from server (Forbidden): User "system:serviceaccount:lynq-system:lynq-controller-manager" cannot create resource`
|
|
339
|
+
|
|
340
|
+
**해결책:** RBAC 리소스가 설치되었는지 확인합니다:
|
|
341
|
+
```bash
|
|
342
|
+
kubectl apply -f config/rbac/
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
## 다음 단계
|
|
346
|
+
|
|
347
|
+
- [첫 번째 LynqHub 생성](quickstart.md#step-4-deploy-lynqhub)
|
|
348
|
+
- [템플릿에 대해 알아보기](templates.md)
|
|
349
|
+
- [모니터링 구성](monitoring.md)
|
|
350
|
+
- [보안 설정](security.md)
|