43 KiB
ðïž æ¶æææ¡£
ç®åœ
2.1.1 éæ±æè¿°
项ç®èæ¯
é®é¢éè¿°
åšäºåçæ¶ä»£ïŒKubernetes å·²æäžºå®¹åšçŒæçäºå®æ åïŒHelm æ¯ Kubernetes çå 管çå·¥å ·ãç¶èïŒåœåäŒäžåšäœ¿çš Helm è¿è¡åºçšéšçœ²æ¶é¢äžŽä»¥äžææïŒ
- å€é矀管ç倿 - äŒäžéåžžæå€äžª Kubernetes é矀ïŒåŒåãæµè¯ãç产ïŒïŒéèŠç»äžç管ççé¢
- å¶åä»åºåæ£ - Helm Chart å¯èœååžåšå€äžª OCI RegistryïŒHarborãDocker HubãGHCRïŒäžïŒéŸä»¥ç»äžæµè§
- éšçœ²æµçšç¹ç - éèŠæåšçŒå
helm installåœä»€ïŒé çœ®å€æç values.yaml - 猺ä¹å¯è§å - åœä»€è¡æäœå¯¹éææ¯äººåäžå奜ïŒçŒºå°çŽè§ç UI
- çæ¬ç®¡çå°éŸ - åºçšå级éèŠè®°äœåå²çæ¬ïŒå®¹æåºé
- çæ§ä¿¡æ¯åæ£ - éèŠåç¬è®¿é® Kubernetes Dashboard æ¥çåºçšç¶æ
è§£å³æ¹æ¡
OCDP Backend æäŸç»äžçå端 API æå¡ïŒå®ç°ïŒ
- â ç»äžç®¡ç - éäžç®¡çå€äžª Kubernetes é矀å OCI Registry
- â å¯è§åéšçœ² - éè¿ API ç®å Helm Chart çæµè§åéšçœ²æµçš
- â çæ¬æ§å¶ - 宿Žçåºçšçåœåšæç®¡çïŒå®è£ ãå级ãåžèœœïŒ
- â 宿¶çæ§ - éæ Kubernetes APIïŒå®æ¶è·ååºçšç¶æåèµæºäœ¿çšæ åµ
- â å®å šè®€è¯ - æ¯æçšæ·è®€è¯åæææ°æ®å å¯ååš
æ žå¿éæ±
äžå¡éæ±
| éæ± ID | éæ±æè¿° | äŒå 级 |
|---|---|---|
| BR-001 | æ¯æç®¡çå€äžª Kubernetes é矀 | P0 |
| BR-002 | æ¯æç®¡çå€äžª OCI Registry | P0 |
| BR-003 | æµè§åæçŽ¢ Helm Chart å¶å | P0 |
| BR-004 | éšçœ² Helm Chart å° Kubernetes é矀 | P0 |
| BR-005 | å级已éšçœ²çåºçš | P0 |
| BR-006 | æ¥çåºçšå®æ¶ç¶æåèµæºäœ¿çš | P1 |
| BR-007 | çšæ·è®€è¯åæé管ç | P1 |
| BR-008 | 审计æ¥å¿è®°åœ | P2 |
çšæ·è§è²
- å¹³å°ç®¡çå - 管çé矀ãRegistryãçšæ·
- åŒåè - éšçœ²å管çèªå·±çåºçš
- è¿ç»Žäººå - çæ§å绎æ€åºçšç¶æ
- 访客 - åªè¯»æ¥çåºçšå衚åç¶æ
åèœéæ±
F1. é矀管ç
æè¿°: 管çå€äžª Kubernetes é矀çè¿æ¥é 眮
åèœç¹:
- æ·»å é矀ïŒé 眮 API Server å°åãè¯ä¹ŠïŒ
- æ¥çé矀å衚å诊æ
- æµè¯éçŸ€è¿æ¥å¥åº·ç¶æ
- æŽæ°åå é€é矀é 眮
- æ¥çéçŸ€èµæºäœ¿çšæ åµïŒCPUãå åãèç¹æ°ïŒ
éªæ¶æ å:
- â æ¯æè¯ä¹Šè®€è¯å Token 讀è¯
- â ææä¿¡æ¯ïŒè¯ä¹Šãå¯é¥ïŒå å¯ååš
- â è¿æ¥å€±èŽ¥æ¶ç»åºæž æ°çé误æç€º
- â æ¯ææµè¯è¿æ¥åèœ
F2. Registry 管ç
æè¿°: 管çå€äžª OCI Registry çè¿æ¥é 眮
åèœç¹:
- æ·»å RegistryïŒHarborãDocker HubãGHCR çïŒ
- é 眮讀è¯ä¿¡æ¯ïŒçšæ·å/å¯ç ïŒ
- æ¥ç Registry å衚å诊æ
- æµè¯ Registry è¿æ¥å¥åº·ç¶æ
- æŽæ°åå é€ Registry é 眮
éªæ¶æ å:
- â æ¯æ Basic Auth å Bearer Token
- â å¯ç å å¯ååš
- â æ¯æ HTTP/HTTPS åèªçŸåè¯ä¹Š
- â è¿æ¥æµè¯è¿åååºæ¶éŽ
F3. Artifact æµè§
æè¿°: æµè§åæçŽ¢ OCI Registry äžç Helm Chart
åèœç¹:
- ååº Registry äžçææä»åº
- ååºä»åºäžçææå¶åïŒtagsïŒ
- æ¥çå¶å诊æ ïŒå€§å°ãå建æ¶éŽãannotationsïŒ
- èªåšè¯å«å¶åç±»åïŒHelm ChartãDocker ImageïŒ
- è·å Helm Chart ç values schema
éªæ¶æ å:
- â 笊å OCI Distribution Specification
- â
æ¯æ URL çŒç çä»åºåç§°ïŒåŠ
charts/appïŒ - â æ£ç¡®è§£æ manifest å config
- â 计ç®å¶åæ»å€§å°ïŒå 嫿æ layersïŒ
F4. åºçšéšçœ²
æè¿°: éšçœ² Helm Chart å° Kubernetes é矀
åèœç¹:
- éæ©é矀ãRegistryãChart åçæ¬
- é 眮 valuesïŒJSON æ YAMLïŒ
- å®è£ åºçšå°æå® namespace
- æ¥çå®è£ è¿åºŠåç¶æ
- è·ååºçšè®¿é®ç«¯ç¹
éªæ¶æ å:
- â æ¯æèªå®ä¹ Release åç§°
- â æ¯æ JSON å YAML æ ŒåŒç values
- â è®°åœéšçœ²åå²
F5. åºçšçåœåšæç®¡ç
æè¿°: 管çå·²éšçœ²åºçšç宿Žçåœåšæ
åèœç¹:
- æ¥çåºçšå衚å诊æ
- å级åºçšå°æ°çæ¬
- æ¥çéšçœ²åå²
- åžèœœåºçš
éªæ¶æ å:
- â å级æ¶ä¿çé 眮
- â åžèœœæ¶å¯éä¿çåå²
- â æŸç€ºæ¯æ¬¡éšçœ²çæè¿°ä¿¡æ¯
F6. çæ§åç¶æ
æè¿°: 宿¶çæ§åºçšåéçŸ€ç¶æ
åèœç¹:
- æ¥çåºçšå®æ¶ç¶æïŒRunningãFailed çïŒ
- æ¥çåºçšèµæºäœ¿çšïŒCPUãå åïŒ
- æ¥çé矀æŽäœçæ§
- æ¥çèç¹èµæºäœ¿çš
- çæ§æèŠç»è®¡
éªæ¶æ å:
- â 宿¶è·å Kubernetes èµæºç¶æ
- â æ¯æ Prometheus ææ éæ
- â æŸç€º Pod ç¶æåäºä»¶
- â èµæºäœ¿çšçŸåæ¯æŸç€º
F7. 讀è¯åææ
æè¿°: çšæ·èº«ä»œè®€è¯åè®¿é®æ§å¶
åèœç¹:
- çšæ·æ³šååç»åœ
- JWT Token 讀è¯
- Token å·æ°æºå¶
- å¯ç å å¯ååš
éªæ¶æ å:
- â äœ¿çš bcrypt ååžå¯ç
- â JWT Token æææé 眮
- â Refresh Token æ¯æ
- â å¯ç 区床éªè¯
éåèœéæ±
NFR1. æ§èœèŠæ±
| ææ | èŠæ± |
|---|---|
| API ååºæ¶éŽ | P95 < 500ms |
| å¹¶åçšæ·æ° | æ¯æ 100+ å¹¶å |
| æ°æ®åºè¿æ¥æ± | 25 äžªè¿æ¥ |
| Helm æäœè¶ æ¶ | 5 åé |
NFR2. å¯çšæ§
- ç³»ç»å¯çšæ§: 99.5%
- æ 鿢倿¶éŽ: < 5 åé
- æ°æ®å€ä»œ: æ¯æ¥å€ä»œ
- å¥åº·æ£æ¥: æäŸ
/health端ç¹
NFR3. å®å šæ§
- æ°æ®å å¯: AES-256 å å¯æææ°æ®
- äŒ èŸå®å š: æ¯æ HTTPS
- è®€è¯æ¹åŒ: JWT Token
- å¯ç çç¥: æå°é¿åºŠ 8 äœ
- 审计æ¥å¿: è®°åœæææäœïŒæªæ¥ïŒ
NFR4. 坿©å±æ§
- æ°Žå¹³æ©å±: æ¯æå€å®äŸéšçœ²
- æ°æ®åº: PostgreSQL æ¯æäž»ä»å€å¶
- æ ç¶æè®Ÿè®¡: API æå¡æ ç¶æ
- çŒåçç¥: æ¯æ RedisïŒæªæ¥ïŒ
NFR5. å¯ç»Žæ€æ§
- 代ç 莚é: éµåŸª Go æäœ³å®è·µ
- æµè¯èŠç: > 70%
- ææ¡£å®æŽ: API ææ¡£ãæ¶æææ¡£ãéšçœ²ææ¡£
- æ¥å¿è®°åœ: ç»æåæ¥å¿
- çæ§ææ : Prometheus ææ ïŒæªæ¥ïŒ
NFR6. å Œå®¹æ§
- Kubernetes çæ¬: 1.24+
- Helm çæ¬: 3.x
- OCI Registry: 笊å OCI Distribution Spec
- æ°æ®åº: PostgreSQL 15+
- Go çæ¬: 1.21+
2.1.2 äžå¡å»ºæš¡
äžå¡é¢å
OCDP Backend å±äºäºåçåºçšç®¡çé¢åïŒäž»èŠæ¶å以äžååïŒ
- å¶å管çå - OCI RegistryãHelm ChartãDocker Image
- é矀管çå - Kubernetes ClusterãNodeãNamespace
- åºçšéšçœ²å - Helm ReleaseãApplication Instance
- çæ§è¿ç»Žå - MetricsãLogsãEvents
æ žå¿å®äœ
é¢åæš¡ååŸ
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â Core Domain Entities â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
ââââââââââââ ââââââââââââ ââââââââââââ
â User âââââââââââ Cluster âââââââââââ Instance â
ââââââââââââ ââââââââââââ ââââââââââââ
â â â
â â â
⌠⌠âŒ
ââââââââââââ ââââââââââââ ââââââââââââ
â Auth â â Health â â Status â
â Token â â Check â â Resource â
ââââââââââââ ââââââââââââ ââââââââââââ
ââââââââââââ ââââââââââââ ââââââââââââ
â Registry âââââââââââArtifact âââââââââââ Chart â
ââââââââââââ ââââââââââââ ââââââââââââ
â â â
â â â
⌠⌠âŒ
ââââââââââââ ââââââââââââ ââââââââââââ
â Health â âRepositoryâ â Values â
â Check â â â â Schema â
ââââââââââââ ââââââââââââ ââââââââââââ
å®äœè¯Šè§£
1. UserïŒçšæ·ïŒ
è莣: 衚瀺系ç»çšæ·ïŒèŽèŽ£èº«ä»œè®€è¯
屿§:
ID: å¯äžæ è¯ç¬ŠUsername: çšæ·åïŒå¯äžïŒEmail: é®ç®±PasswordHash: å¯ç ååžïŒbcryptïŒCreatedAt: å建æ¶éŽUpdatedAt: æŽæ°æ¶éŽ
äžå¡è§å:
- çšæ·åå¯äž
- é®ç®±æ ŒåŒéªè¯
- å¯ç æå°é¿åºŠ 8 äœ
2. ClusterïŒé矀ïŒ
è莣: 衚瀺 Kubernetes éçŸ€è¿æ¥é 眮
屿§:
ID: å¯äžæ è¯ç¬ŠName: é矀åç§°Host: API Server å°åDescription: æè¿°CAData: CA è¯ä¹ŠïŒå å¯ååšïŒCertData: 客æ·ç«¯è¯ä¹ŠïŒå å¯ååšïŒKeyData: 客æ·ç«¯å¯é¥ïŒå å¯ååšïŒToken: Bearer TokenïŒå¯éïŒCreatedAt: å建æ¶éŽUpdatedAt: æŽæ°æ¶éŽ
äžå¡è§å:
- é矀åç§°å¯äž
- å¿ é¡»æäŸè¯ä¹Šæ Token
- Host å¿ é¡»æ¯ææç HTTPS URL
3. RegistryïŒéåä»åºïŒ
è莣: 衚瀺 OCI Registry è¿æ¥é 眮
屿§:
ID: å¯äžæ è¯ç¬ŠName: Registry åç§°URL: Registry URLDescription: æè¿°Username: çšæ·åPassword: å¯ç ïŒå å¯ååšïŒInsecure: æ¯åŠè·³è¿ SSL éªè¯CreatedAt: å建æ¶éŽUpdatedAt: æŽæ°æ¶éŽ
äžå¡è§å:
- Registry åç§°å¯äž
- URL å¿ é¡»æ¯ææç HTTP/HTTPS URL
- å¯ç å å¯ååš
4. InstanceïŒåºçšå®äŸïŒ
è莣: 衚瀺éšçœ²åš Kubernetes äžç Helm Release
屿§:
ID: å¯äžæ è¯ç¬ŠName: Release åç§°Namespace: Kubernetes namespaceClusterID: æå±é矀RegistryID: Chart æ¥æº RegistryRepository: Chart ä»åºåChart: Chart åç§°Version: Chart çæ¬Status: éšçœ²ç¶æRevision: åœåçæ¬å·Values: é 眮åŒïŒJSONïŒDescription: æè¿°CreatedAt: å建æ¶éŽUpdatedAt: æŽæ°æ¶éŽ
äžå¡è§å:
- åäžé矀å namespace äž Release åç§°å¯äž
- å¿ é¡»å ³èææç Cluster å Registry
- Values å¿ é¡»æ¯ææç JSON æ YAML
5. ArtifactïŒå¶åïŒ
è莣: 衚瀺 OCI Registry äžçå¶åïŒHelm ChartãDocker Image çïŒ
屿§:
RepositoryName: ä»åºåç§°Tag: æ çŸDigest: SHA256 æèŠType: å¶åç±»åïŒhelmãdockerãociïŒSize: æ»å€§å°MediaType: åªäœç±»åAnnotations: å æ°æ®CreatedAt: å建æ¶éŽ
äžå¡è§å:
- Tag æ Digest è³å°æäŸäžäžª
- èªåšè¯å«å¶åç±»å
- è®¡ç®ææ layers çæ»å€§å°
äžå¡æµçš
æµçš 1: çšæ·æ³šååç»åœ
ââââââââ ââââââââââââ ââââââââââââ ââââââââââââ
â User â â Handler â â Service â â Repo â
ââââ¬ââââ ââââââ¬ââââââ ââââââ¬ââââââ ââââââ¬ââââââ
â â â â
â Register â â â
âââââââââââââ>â â â
â â Create User â â
â âââââââââââââââ>â â
â â â Hash Password â
â â ââââââââ â
â â â<ââââââ â
â â â Save User â
â â âââââââââââââââ>â
â â â<âââââââââââââââ€
â â<ââââââââââââââ†â
â<ââââââââââââ†â â
â â â â
â Login â â â
âââââââââââââ>â â â
â â Authenticate â â
â âââââââââââââââ>â â
â â â Verify Pwd â
â â ââââââââ â
â â â<ââââââ â
â â â Gen JWT â
â â ââââââââ â
â â â<ââââââ â
â â<ââââââââââââââ†â
â<ââââââââââââ†Return Token â â
â â â â
æµçš 2: éšçœ²åºçš
ââââââââ ââââââââââââ ââââââââââââ ââââââââââââ ââââââââââââ
â User â â Handler â â Service â âHelmClientâ âKubernetesâ
ââââ¬ââââ ââââââ¬ââââââ ââââââ¬ââââââ ââââââ¬ââââââ ââââââ¬ââââââ
â â â â â
â Deploy App â â â â
âââââââââââââ>â â â â
â â Create Inst â â â
â âââââââââââââââ>â â â
â â â Validate â â
â â ââââââââ â â
â â â<ââââââ â â
â â â Pull Chart â â
â â âââââââââââââââ>â â
â â â<ââââââââââââââ†â
â â â Install Chart â â
â â âââââââââââââââ>â â
â â â â Apply K8s â
â â â âââââââââââââââ>â
â â â â<âââââââââââââââ€
â â â<ââââââââââââââ†â
â â â Save Instance â â
â â ââââââââ â â
â â â<ââââââ â â
â â<ââââââââââââââ†â â
â<ââââââââââââ†Return Status â â â
â â â â â
æµçš 3: æµè§å¶å
ââââââââ ââââââââââââ ââââââââââââ ââââââââââââ ââââââââââââ
â User â â Handler â â Service â âOCIClient â â Registry â
ââââ¬ââââ ââââââ¬ââââââ ââââââ¬ââââââ ââââââ¬ââââââ ââââââ¬ââââââ
â â â â â
âList Repos â â â â
âââââââââââââ>â â â â
â â Get Repos â â â
â âââââââââââââââ>â â â
â â â List Catalog â â
â â âââââââââââââââ>â â
â â â â GET _catalog â
â â â âââââââââââââââ>â
â â â â<âââââââââââââââ€
â â â<ââââââââââââââ†â
â â<ââââââââââââââ†â â
â<ââââââââââââ†â â â
â â â â â
âList Tags â â â â
âââââââââââââ>â â â â
â â Get Artifacts â â â
â âââââââââââââââ>â â â
â â â List Tags â â
â â âââââââââââââââ>â â
â â â â GET tags/list â
â â â âââââââââââââââ>â
â â â â<âââââââââââââââ€
â â â Get Manifest â â
â â âââââââââââââââ>â â
â â â â GET manifest â
â â â âââââââââââââââ>â
â â â â<âââââââââââââââ€
â â â<ââââââââââââââ†â
â â<ââââââââââââââ†â â
â<ââââââââââââ†â â â
â â â â â
çšäŸåºæ¯
UC1: åŒåè éšçœ²æµè¯åºçš
äž»è§: åŒåè Alice
å眮æ¡ä»¶:
- Alice å·²ç»åœç³»ç»
- ç³»ç»äžå·²é 眮åŒåç¯å¢é矀
- ç³»ç»äžå·²é 眮 Harbor Registry
åºæ¬æµçš:
- Alice éæ©"åŒåé矀"
- Alice æµè§ Harbor äžç"charts/nginx"ä»åº
- Alice éæ© nginx 1.0.0 çæ¬
- Alice é
眮 values:
{"replicaCount": 2} - Alice ç¹å»"éšçœ²"
- ç³»ç»æŸç€ºéšçœ²è¿åºŠ
- éšçœ²æåïŒæŸç€ºåºçšè®¿é®å°å
å眮æ¡ä»¶:
- nginx åºçšæåéšçœ²å°åŒåé矀
- åºçšç¶æäžº "deployed"
- Alice å¯ä»¥è®¿é®åºçš
åŒåžžæµçš:
- 3a. Chart çæ¬äžååš â æŸç€ºé误æç€º
- 5a. éšçœ²å€±èŽ¥ â æŸç€ºé误æ¥å¿
UC2: è¿ç»Žäººåå级ç产åºçš
äž»è§: è¿ç»Ž Bob
å眮æ¡ä»¶:
- Bob å·²ç»åœç³»ç»
- ç产ç¯å¢æè¿è¡äžç nginx åºçšïŒçæ¬ 1.0.0ïŒ
åºæ¬æµçš:
- Bob è¿å ¥"ç产é矀"åºçšå衚
- Bob éæ© nginx åºçš
- Bob æ¥çåœåçæ¬åé 眮
- Bob ç¹å»"å级"
- Bob éæ©æ°çæ¬ 1.1.0
- Bob æŽæ°é
眮:
{"replicaCount": 3} - Bob æ·»å å级诎æ
- Bob 确讀å级
- ç³»ç»æ§è¡æ»åšå级
- å级æåïŒRevision å¢å å° 2
å眮æ¡ä»¶:
- nginx åºçšåçº§å° 1.1.0
- 坿¬æ°å¢å å° 3
- åå²è®°åœäžä¿çäº Revision 1
åŒåžžæµçš:
- 9a. å级倱莥 â æŸç€ºé误信æ¯ïŒä¿æåç¶æ
- 9b. è¶ æ¶ â åæ¶å级ïŒä¿æåç¶æ
UC3: 管çåæ·»å æ°é矀
äž»è§: 管çå Charlie
å眮æ¡ä»¶:
- Charlie å·²ç»åœç³»ç»
- Charlie æé矀ç kubeconfig æä»¶
åºæ¬æµçš:
- Charlie è¿å ¥"é矀管ç"页é¢
- Charlie ç¹å»"æ·»å é矀"
- Charlie å¡«åé矀信æ¯:
- åç§°: "Production Cluster"
- API Server: "https://k8s.prod.com:6443"
- æè¿°: "ç产ç¯å¢é矀"
- Charlie ä» kubeconfig æåè¯ä¹Šæ°æ®
- Charlie ç²èŽŽ CAãCertãKey æ°æ®
- Charlie ç¹å»"æµè¯è¿æ¥"
- ç³»ç»æŸç€º"è¿æ¥æå"
- Charlie ä¿åé 眮
å眮æ¡ä»¶:
- æ°é矀添å å°ç³»ç»
- é矀è¯ä¹Šå å¯ååš
- å ¶ä»çšæ·å¯ä»¥äœ¿çšæ€é矀
åŒåžžæµçš:
- 6a. è¿æ¥å€±èŽ¥ â æŸç€ºå ·äœé误信æ¯
- 6b. è¯ä¹Šæ ŒåŒé误 â æç€ºæ£ç¡®çæ ŒåŒ
2.1.3 ææ¯å»ºæš¡
2.1.3.1 å èŸ¹åœ¢æ¶æ
æ¶ææŠè¿°
OCDP Backend éçšå èŸ¹åœ¢æ¶æïŒHexagonal ArchitectureïŒä¹ç§°äžºç«¯å£åéé åšæ¶æïŒïŒè¿æ¯äžç§å屿¶ææš¡åŒïŒåŒºè°äžå¡é»èŸäžå€éšäŸèµçå犻ã
æ žå¿åå
- äŸèµå眮 - ææå±äŸèµ DomainïŒDomain æ å€éšäŸèµ
- 端å£åéé åš - éè¿æ¥å£ïŒPortïŒå®ä¹äº€äºåè®®ïŒéè¿éé åšïŒAdapterïŒå®ç°å ·äœææ¯
- 坿µè¯æ§ - äžå¡é»èŸå¯ç¬ç«æµè¯ïŒæ éå€éšäŸèµ
- 坿¿æ¢æ§ - éé åšå¯èœ»æŸæ¿æ¢ïŒMock â ProductionïŒ
æ¶æåå±åŸ
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â Input Adapters â
â (HTTP REST API) â
â â
â ââââââââââââââââ ââââââââââââââââ ââââââââââââââââ â
â â Auth Handler â âCluster Handl â âInstance Handlâ â
â ââââââââââââââââ ââââââââââââââââ ââââââââââââââââ â
â â
ââââââââââââââââââââââââ¬âââââââââââââââââââââââââââââââââââââââ
â DTO / Request
â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â Domain Layer â
â (Business Logic) â
â â
â ââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â
â â Entities â â
â â User | Cluster | Registry | Instance | Artifact â â
â ââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â
â â
â ââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â
â â Services â â
â â AuthService | ClusterService | InstanceService â â
â ââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â
â â
â ââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â
â â Repository Interfaces (Ports) â â
â â UserRepo | ClusterRepo | OCIClient | HelmClient â â
â ââââââââââââââââââââââââââââââââââââââââââââââââââââââââ â
â â
ââââââââââââââââââââââââ¬âââââââââââââââââââââââââââââââââââââââ
â Interface Contract
â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â Output Adapters â
â (Infrastructure Implementations) â
â â
â ââââââââââââââââ ââââââââââââââââ ââââââââââââââââ â
â â Database â â OCI Client â â Helm Client â â
â â â â â â â â
â âââââââââââââââ†âââââââââââââââ†âââââââââââââââ†â
â â Mock: Memory â â Mock: Static â â Mock: Fake â â
â â Prod:Postgresâ â Prod: ORAS â â Prod: Helm â â
â ââââââââââââââââ ââââââââââââââââ ââââââââââââââââ â
â â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
ç®åœç»æ
internal/
âââ domain/ # ð¯ é¢åå±ïŒæ žå¿ïŒ
â âââ entity/ # é¢åå®äœ
â â âââ user.go
â â âââ cluster.go
â â âââ registry.go
â â âââ instance.go
â â âââ artifact.go
â â
â âââ service/ # äžå¡é»èŸæå¡
â â âââ auth_service.go
â â âââ cluster_service.go
â â âââ registry_service.go
â â âââ artifact_service.go
â â âââ instance_service.go
â â âââ monitoring_service.go
â â
â âââ repository/ # æ¥å£å®ä¹ïŒOutput PortsïŒ
â âââ user_repository.go
â âââ cluster_repository.go
â âââ registry_repository.go
â âââ instance_repository.go
â âââ oci_client.go
â âââ helm_client.go
â âââ metrics_client.go
â
âââ adapter/
â âââ input/ # ð¥ èŸå
¥éé
åš
â â âââ http/
â â âââ rest/ # REST API Handlers
â â â âââ auth_handler.go
â â â âââ cluster_handler.go
â â â âââ registry_handler.go
â â â âââ artifact_handler.go
â â â âââ instance_handler.go
â â â âââ monitoring_handler.go
â â â âââ utils.go
â â â
â â âââ dto/ # æ°æ®äŒ èŸå¯¹è±¡
â â âââ auth_dto.go
â â âââ cluster_dto.go
â â âââ registry_dto.go
â â âââ instance_dto.go
â â
â âââ output/ # ð€ èŸåºéé
åš
â âââ persistence/
â â âââ mock/ # â
Mock å®ç°
â â â âââ user_repository_mock.go
â â â âââ cluster_repository_mock.go
â â â âââ registry_repository_mock.go
â â â âââ instance_repository_mock.go
â â â
â â âââ postgres/ # ð PostgreSQL å®ç°
â â âââ user_repository.go
â â âââ cluster_repository.go
â â âââ registry_repository.go
â â âââ instance_repository.go
â â
â âââ oci/
â â âââ mock/ # â
Mock OCI Client
â â â âââ oci_client_mock.go
â â âââ oras_client.go # ORAS SDK å®ç°
â â
â âââ helm/
â â âââ mock/ # â
Mock Helm Client
â â â âââ helm_client_mock.go
â â âââ helm_client.go # Helm SDK å®ç°
â â
â âââ metrics/
â â âââ mock/ # â
Mock Metrics Client
â â â âââ metrics_client_mock.go
â â âââ prometheus_client.go
â â
â âââ factory.go # ð éé
åšå·¥å
â
âââ bootstrap/ # Bootstrap 颿³šå
¥æš¡å
â âââ config.go
â âââ seeder.go
â
âââ pkg/ # ð§ å·¥å
·å
âââ jwt/ # JWT å·¥å
·
âââ password/ # å¯ç ååž
âââ encryption/ # AES å å¯
æ°æ®æµ
1. HTTP Request
â
2. [REST Handler] (Input Adapter)
- éªè¯è¯·æ±åæ°
- 蜬æ¢äžº Domain 对象ïŒEntityïŒ
â
3. [Domain Service] (Business Logic)
- æ§è¡äžå¡é»èŸ
- è°çš Repository æ¥å£ïŒPortïŒ
â
4. [Repository Implementation] (Output Adapter)
- Mock: æäœå
åæ°æ®
- PostgreSQL: æäœæ°æ®åº
- ORAS: äž OCI Registry 亀äº
- Helm: äž Kubernetes 亀äº
â
5. Response
- è¿åç»æå° Service
- Service è¿åå° Handler
- Handler 蜬æ¢äžº HTTP ååº
äŸèµæ³šå ¥
åš cmd/api/main.go äžç»è£
ææç»ä»¶ïŒ
func main() {
// 1. å 蜜é
眮
config := loadConfig()
// 2. å建éé
åšå·¥å
factory := output.NewAdapterFactory(
config.AdapterMode,
config.DatabaseURL,
)
// 3. å建 Output Adapters
repos, _ := factory.CreateAllRepositories()
ociClient, _ := factory.CreateOCIClient()
helmClient, _ := factory.CreateHelmClient()
// 4. å建工å
·ç±»
hasher := password.NewBcryptHasher()
jwtGen := jwt.NewJWTGenerator(config.JWTSecret)
// 5. å建 Domain Services
authService := service.NewAuthService(repos.UserRepo, hasher, jwtGen)
clusterService := service.NewClusterService(repos.ClusterRepo)
registryService := service.NewRegistryService(repos.RegistryRepo)
instanceService := service.NewInstanceService(
repos.InstanceRepo,
repos.ClusterRepo,
repos.RegistryRepo,
helmClient,
)
// 6. å建 Input Adapters (REST Handlers)
authHandler := rest.NewAuthHandler(authService)
clusterHandler := rest.NewClusterHandler(clusterService)
instanceHandler := rest.NewInstanceHandler(instanceService)
// 7. 讟眮路ç±
router := setupRouter(
authHandler,
clusterHandler,
instanceHandler,
)
// 8. å¯åšæå¡åš
http.ListenAndServe(":8080", router)
}
éé åšæš¡åŒ
éé åšå·¥å
// internal/adapter/output/factory.go
type AdapterMode string
const (
ModeMock AdapterMode = "mock"
ModeProduction AdapterMode = "production"
)
type AdapterFactory struct {
mode AdapterMode
dbConnString string
}
func (f *AdapterFactory) CreateUserRepository() (repository.UserRepository, error) {
switch f.mode {
case ModeMock:
return mock.NewUserRepositoryMock(), nil
case ModeProduction:
return postgres.NewUserRepository(f.dbConnString)
default:
return nil, fmt.Errorf("unknown adapter mode: %s", f.mode)
}
}
Mock vs Production
| æ¥å£ | Mock æš¡åŒ | Production æš¡åŒ |
|---|---|---|
| UserRepository | â å å map | ð PostgreSQL |
| ClusterRepository | â å å map | ð PostgreSQL |
| RegistryRepository | â å å map | ð PostgreSQL |
| InstanceRepository | â å å map | ð PostgreSQL |
| OCIClient | â éææ°æ® | ð ORAS SDK v2 |
| HelmClient | â æš¡æéšçœ² | âžïž Helm SDK |
| MetricsClient | â åæ°æ® | ð Prometheus |
2.1.3.2 ææ¯éå
çŒçšè¯èš
Go 1.21+
éåçç±:
- â 髿§èœïŒåç并忝æ
- â éæç±»åïŒçŒè¯æ¶æ£æ¥
- â äž°å¯çäºåççæïŒKubernetes client-goãHelm SDKãORASïŒ
- â ç®åæç»Žæ€ïŒéšçœ²æ¹äŸ¿ïŒåäžäºè¿å¶æä»¶ïŒ
- â 广æ³åºçšäºäºåçé¢å
æ¿ä»£æ¹æ¡: Java/Spring Boot, Python/FastAPI
Web æ¡æ¶
gorilla/mux
éåçç±:
- â 蜻éçº§ïŒæ§èœå¥œ
- â çµæŽ»çè·¯ç±å¹é ïŒæ¯ææ£å衚蟟åŒïŒ
- â
äžæ ååº
net/httpå®çŸå Œå®¹ - â æŽ»è·çç€Ÿåºæ¯æ
䜿çšç€ºäŸ:
router := mux.NewRouter()
api := router.PathPrefix("/api/v1").Subrouter()
api.HandleFunc("/clusters", handler.CreateCluster).Methods(http.MethodPost)
api.HandleFunc("/clusters/{clusterId}", handler.GetCluster).Methods(http.MethodGet)
æ¿ä»£æ¹æ¡: Gin, Echo, Fiber
æ°æ®åº
PostgreSQL 15+
éåçç±:
- â åŒæºãæçãå¯é
- â æ¯æå€ææ¥è¯¢åäºå¡
- â JSONB ç±»åéåååšåšæé 眮
- â äž»ä»å€å¶ãé«å¯ç𿝿
- â äž Go çæéæè¯å¥œ
æ°æ®åºé©±åš: lib/pq æ pgx
æ¿ä»£æ¹æ¡: MySQL, MongoDB
OCI Registry 客æ·ç«¯
ORAS Go SDK v2
éåçç±:
- â 笊å OCI Distribution Specification
- â 宿¹ç»Žæ€ïŒèŽšéå¯é
- â æ¯æææ OCI å Œå®¹ç Registry
- â 宿Žç manifestãblob æäœ
䜿çšç€ºäŸ:
repo, err := remote.NewRepository("harbor.example.com/charts/nginx")
repo.Client = &auth.Client{
Credential: auth.StaticCredential("username", "password"),
}
tags, err := repo.Tags(ctx)
manifest, err := repo.FetchReference(ctx, "1.0.0")
å®çœ: https://oras.land/
æ¿ä»£æ¹æ¡: containerd, go-containerregistry
Kubernetes 客æ·ç«¯
client-go
éåçç±:
- â Kubernetes 宿¹ Go 客æ·ç«¯
- â 宿Žç API æ¯æ
- â åšæå®¢æ·ç«¯æ¯æ
- â äž Helm SDK éæ
䜿çšç€ºäŸ:
config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
clientset, err := kubernetes.NewForConfig(config)
pods, err := clientset.CoreV1().Pods("default").List(ctx, metav1.ListOptions{})
æ¿ä»£æ¹æ¡: æ ïŒæ ååºïŒ
Helm 客æ·ç«¯
Helm SDK (helm.sh/helm/v3)
éåçç±:
- â Helm 宿¹ SDK
- â 宿Žç Helm æäœæ¯æ
- â Chart è§£æåæž²æ
- â Release çåœåšæç®¡ç
䜿çšç€ºäŸ:
actionConfig := new(action.Configuration)
actionConfig.Init(settings.RESTClientGetter(), namespace, os.Getenv("HELM_DRIVER"), log.Printf)
install := action.NewInstall(actionConfig)
install.ReleaseName = "my-release"
install.Namespace = "default"
chart, err := loader.Load(chartPath)
release, err := install.Run(chart, values)
æ¿ä»£æ¹æ¡: åœä»€è¡è°çš helmïŒäžæšèïŒ
讀è¯åææ
JWT (golang-jwt/jwt)
éåçç±:
- â æ ç¶æïŒææ©å±
- â æ ååïŒRFC 7519ïŒ
- â æ¯æè¿ææ¶éŽåå·æ°
- â 广æ³åºçš
䜿çšç€ºäŸ:
token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"user_id": user.ID,
"exp": time.Now().Add(time.Hour * 24).Unix(),
})
tokenString, err := token.SignedString([]byte(jwtSecret))
æ¿ä»£æ¹æ¡: OAuth 2.0, Session
å¯ç ååž
bcrypt (golang.org/x/crypto/bcrypt)
éåçç±:
- â å®å šãææŽåç Žè§£
- â èªåšå ç
- â è®¡ç®ææ¬å¯è°
- â Go æ åæ©å±åº
䜿çšç€ºäŸ:
hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
err = bcrypt.CompareHashAndPassword(hash, []byte(password))
æ¿ä»£æ¹æ¡: argon2, scrypt
æ°æ®å å¯
AES-256 (crypto/aes + crypto/cipher)
éåçç±:
- â 对称å å¯ïŒæ§èœå¥œ
- â 256 äœå¯é¥ïŒå®å šæ§é«
- â Go æ ååºæ¯æ
- â éåæææ°æ®å å¯ïŒè¯ä¹Šãå¯ç ïŒ
äœ¿çšæš¡åŒ: GCMïŒGalois/Counter ModeïŒ
䜿çšç€ºäŸ:
block, err := aes.NewCipher(key) // 32 bytes key
gcm, err := cipher.NewGCM(block)
nonce := make([]byte, gcm.NonceSize())
ciphertext := gcm.Seal(nonce, nonce, plaintext, nil)
æ¿ä»£æ¹æ¡: RSA (é对称å å¯ïŒæ§èœèŸå·®)
容åšå
Docker + Docker Compose
éåçç±:
- â æ ååå®¹åšææ¯
- â ç®åéšçœ²åç¯å¢äžèŽæ§
- â äž°å¯çéåçæ
- â Docker Compose ç®åå€å®¹åšçŒæ
Dockerfile 瀺äŸ:
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY . .
RUN go build -o ocdp-backend cmd/api/main.go
FROM alpine:latest
RUN apk --no-cache add ca-certificates
WORKDIR /root/
COPY --from=builder /app/ocdp-backend .
EXPOSE 8080
CMD ["./ocdp-backend"]
æ¿ä»£æ¹æ¡: Podman, containerd
æ¥å¿è®°åœ
æ ååº log + ç»æåæ¥å¿ïŒæªæ¥ïŒzerolog/zapïŒ
åœåå®ç°:
log.Printf("â
User created: %s", user.Username)
log.Printf("â ïž Warning: %v", err)
log.Printf("â Error: %v", err)
æªæ¥äŒå:
logger.Info().
Str("user_id", user.ID).
Str("username", user.Username).
Msg("User created")
æµè¯æ¡æ¶
testify
éåçç±:
- â äž°å¯çæèšåœæ°
- â Mock æ¯æ
- â æµè¯å¥ä»¶æ¯æ
- â æŽ»è·ç瀟åº
䜿çšç€ºäŸ:
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestCreateUser(t *testing.T) {
user, err := service.CreateUser(ctx, "test", "password")
require.NoError(t, err)
assert.NotEmpty(t, user.ID)
assert.Equal(t, "test", user.Username)
}
çé蜜ïŒåŒåïŒ
Air
éåçç±:
- â Go 项ç®çé蜜
- â ç嬿件ååèªåšéå¯
- â é 眮ç®å
é
眮æä»¶: .air.toml
[build]
cmd = "go build -o ./tmp/main cmd/api/main.go"
bin = "./tmp/main"
include_ext = ["go", "yaml", "json"]
exclude_dir = ["tmp", "vendor"]
å¯åš: air -c .air.toml
ææ¯æ æ»ç»è¡š
| ç»ä»¶ | ææ¯ | çæ¬ | çšé |
|---|---|---|---|
| è¯èš | Go | 1.21+ | äž»èŠçŒçšè¯èš |
| Web æ¡æ¶ | gorilla/mux | latest | HTTP è·¯ç± |
| æ°æ®åº | PostgreSQL | 15+ | æä¹ åååš |
| æ°æ®åºé©±åš | lib/pq æ pgx | latest | Go æ°æ®åºé©±åš |
| OCI 客æ·ç«¯ | ORAS Go SDK | v2 | OCI Registry æäœ |
| Kubernetes | client-go | latest | K8s API äº€äº |
| Helm | Helm SDK | v3 | Helm æäœ |
| JWT | golang-jwt/jwt | v5 | è®€è¯ Token |
| å¯ç ååž | bcrypt | latest | å¯ç å å¯ |
| æ°æ®å å¯ | AES-256 | stdlib | æææ°æ®å å¯ |
| 容åšå | Docker | latest | åºçšå®¹åšå |
| çŒæ | Docker Compose | latest | å€å®¹åšçŒæ |
| æµè¯ | testify | latest | åå æµè¯ |
| çé蜜 | Air | latest | åŒåç¯å¢ |
Bootstrap 颿³šå ¥
æŠè¿°: åšåºçšå¯åšæ¶èªåšåå§åçšæ·ãRegistryãCluster çæ°æ®ã
é
眮æä»¶: config/bootstrap.json
{
"enabled": true,
"users": [
{
"username": "admin",
"password": "admin123",
"email": "admin@example.com"
}
],
"registries": [
{
"name": "Harbor Production",
"url": "https://harbor.example.com",
"username": "admin",
"password": "secret"
}
],
"clusters": [
{
"name": "Production Cluster",
"host": "https://k8s.example.com:6443",
"caData": "LS0tLS...",
"certData": "LS0tLS...",
"keyData": "LS0tLS..."
}
]
}
ç¹æ§:
- â èªåšå å¯æææ°æ®
- â å¹çæ§ïŒéå€å¯åšäžäŒéå€å建ïŒ
- â å¯éè¿ç¯å¢åéé 眮
- â æ¯æçŠçš
ä» kubeconfig æåè¯ä¹Š:
kubectl config view --raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}'
kubectl config view --raw -o jsonpath='{.users[0].user.client-certificate-data}'
kubectl config view --raw -o jsonpath='{.users[0].user.client-key-data}'
åŒåæå
æ·»å æ°åèœçæ¥éª€
- å®ä¹ Entity (
internal/domain/entity/) - å®ä¹ Repository æ¥å£ (
internal/domain/repository/) - å®ç° Domain Service (
internal/domain/service/) - å®ç° Mock Adapter (
internal/adapter/output/persistence/mock/) - å®ç° Production Adapter (
internal/adapter/output/persistence/postgres/) - æ·»å å° Factory (
internal/adapter/output/factory.go) - å建 REST Handler (
internal/adapter/input/http/rest/) - 泚åè·¯ç± (
cmd/api/main.go)
äŸèµæ¹åè§å
- â Input Adapters â Domain Layer
- â Domain Layer â Repository Interfaces
- â Output Adapters â Domain Layer (å®ç°æ¥å£)
- â Domain Layer â Output AdaptersïŒçŠæ¢ïŒ
æµè¯çç¥
- åå æµè¯: æµè¯ Domain ServiceïŒäœ¿çš Mock Repository
- éææµè¯: æµè¯ Handler + ServiceïŒäœ¿çš Mock Adapters
- E2E æµè¯: 宿޿µçšæµè¯ïŒäœ¿çšçå®ç¯å¢
çžå ³ææ¡£
Last Updated: 2025-11-09