docs: полная документация проекта — docs/ и README.md для каждого аддона
- README.md: перепиcан как компактный обзор (98 строк) с навигацией по docs/ - docs/: 13 файлов — getting-started, architecture, configuration, addons, storage, security, cicd, observability, networking, operations, make-reference, molecule-testing, troubleshooting - addons/*/README.md: 31 новый файл — описание, параметры, примеры кода для каждого из 34 аддонов (vault и external-secrets уже существовали)
This commit is contained in:
283
docs/cicd.md
Normal file
283
docs/cicd.md
Normal file
@@ -0,0 +1,283 @@
|
||||
# CI/CD
|
||||
|
||||
Инструменты непрерывной интеграции и доставки: Jenkins, Gitea Actions, ArgoCD.
|
||||
|
||||
## Jenkins
|
||||
|
||||
CI/CD сервер с dynamic Kubernetes Pod agents и JCasC. Подробнее: [addons/jenkins/README.md](../addons/jenkins/README.md).
|
||||
|
||||
### Быстрый старт
|
||||
|
||||
```yaml
|
||||
# group_vars/all/addons.yml
|
||||
addon_jenkins: true
|
||||
jenkins_ingress_host: "jenkins.example.com"
|
||||
jenkins_ingress_tls: true
|
||||
```
|
||||
|
||||
```bash
|
||||
make addon-jenkins
|
||||
```
|
||||
|
||||
### Dynamic k8s agents
|
||||
|
||||
Jenkins создаёт Pod для каждой сборки и удаляет после завершения. Шаблон Pod задаётся прямо в Jenkinsfile:
|
||||
|
||||
```groovy
|
||||
pipeline {
|
||||
agent {
|
||||
kubernetes {
|
||||
yaml """
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
spec:
|
||||
containers:
|
||||
- name: maven
|
||||
image: maven:3.9-eclipse-temurin-17
|
||||
command: ['cat']
|
||||
tty: true
|
||||
- name: kaniko
|
||||
image: gcr.io/kaniko-project/executor:debug
|
||||
command: ['cat']
|
||||
tty: true
|
||||
"""
|
||||
}
|
||||
}
|
||||
stages {
|
||||
stage('Build') {
|
||||
steps {
|
||||
container('maven') {
|
||||
sh 'mvn clean package -DskipTests'
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Docker Push') {
|
||||
steps {
|
||||
container('kaniko') {
|
||||
sh '''
|
||||
/kaniko/executor \
|
||||
--context=. \
|
||||
--destination=harbor.example.com/library/myapp:${BUILD_NUMBER}
|
||||
'''
|
||||
}
|
||||
}
|
||||
}
|
||||
stage('Deploy') {
|
||||
steps {
|
||||
container('maven') {
|
||||
sh 'kubectl apply -f k8s/'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
post {
|
||||
always { cleanWs() }
|
||||
failure {
|
||||
emailext subject: "Failed: ${env.JOB_NAME}",
|
||||
body: "${env.BUILD_URL}",
|
||||
to: "team@example.com"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Интеграция с Vault
|
||||
|
||||
При `addon_vault: true` JCasC автоматически настраивает Vault URL.
|
||||
|
||||
1. Создай AppRole в Vault:
|
||||
```bash
|
||||
vault write auth/approle/role/jenkins \
|
||||
token_policies="jenkins-policy" \
|
||||
token_ttl=1h
|
||||
```
|
||||
|
||||
2. Создай credentials в Jenkins: Manage → Credentials → Add → Vault App Role Credential
|
||||
- ID: `vault-approle`
|
||||
|
||||
3. Использование в Pipeline:
|
||||
```groovy
|
||||
withVault(configuration: [
|
||||
vaultCredentialId: 'vault-approle'
|
||||
], vaultSecrets: [
|
||||
[path: 'secret/myapp', secretValues: [
|
||||
[envVar: 'DB_PASSWORD', vaultKey: 'db_password']
|
||||
]]
|
||||
]) {
|
||||
sh 'deploy.sh --db-password "$DB_PASSWORD"'
|
||||
}
|
||||
```
|
||||
|
||||
### SMTP уведомления (через smtp-relay)
|
||||
|
||||
Jenkins → Manage → Configure → Extended E-mail:
|
||||
- SMTP server: `smtp-relay.smtp-relay.svc.cluster.local`
|
||||
- Port: `25`
|
||||
|
||||
---
|
||||
|
||||
## Gitea Actions
|
||||
|
||||
GitHub Actions-совместимая CI/CD встроенная в Gitea. Подробнее: [addons/gitea/README.md](../addons/gitea/README.md).
|
||||
|
||||
### Быстрый старт
|
||||
|
||||
```yaml
|
||||
addon_gitea: true
|
||||
gitea_actions_enabled: true
|
||||
gitea_actions_runner_enabled: true
|
||||
gitea_actions_runner_replicas: 2
|
||||
gitea_actions_runner_dind_enabled: true # Docker-in-Docker
|
||||
```
|
||||
|
||||
```bash
|
||||
make addon-gitea
|
||||
```
|
||||
|
||||
### Workflow пример
|
||||
|
||||
```yaml
|
||||
# .gitea/workflows/ci.yml
|
||||
name: CI/CD Pipeline
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: '20'
|
||||
|
||||
- name: Install & Test
|
||||
run: |
|
||||
npm install
|
||||
npm test
|
||||
|
||||
build-push:
|
||||
needs: test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Build & Push Docker Image
|
||||
run: |
|
||||
docker build -t harbor.example.com/library/myapp:${{ gitea.sha }} .
|
||||
echo "${{ secrets.HARBOR_PASSWORD }}" | \
|
||||
docker login harbor.example.com -u admin --password-stdin
|
||||
docker push harbor.example.com/library/myapp:${{ gitea.sha }}
|
||||
|
||||
deploy:
|
||||
needs: build-push
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
|
||||
- name: Deploy to K3S
|
||||
run: |
|
||||
kubectl set image deployment/myapp \
|
||||
myapp=harbor.example.com/library/myapp:${{ gitea.sha }}
|
||||
env:
|
||||
KUBECONFIG: ${{ secrets.KUBECONFIG }}
|
||||
```
|
||||
|
||||
### Секреты в Gitea Actions
|
||||
|
||||
В Gitea → Repository → Settings → Secrets:
|
||||
- `HARBOR_PASSWORD` — пароль Harbor
|
||||
- `KUBECONFIG` — base64 из kubeconfig
|
||||
|
||||
---
|
||||
|
||||
## ArgoCD — GitOps
|
||||
|
||||
Непрерывный деплой на основе Git. Подробнее: [addons/argocd/README.md](../addons/argocd/README.md).
|
||||
|
||||
### Быстрый старт
|
||||
|
||||
```yaml
|
||||
addon_argocd: true
|
||||
argocd_ingress_enabled: true
|
||||
argocd_ingress_host: "argocd.example.com"
|
||||
```
|
||||
|
||||
```bash
|
||||
make addon-argocd
|
||||
```
|
||||
|
||||
### Application manifest
|
||||
|
||||
```yaml
|
||||
apiVersion: argoproj.io/v1alpha1
|
||||
kind: Application
|
||||
metadata:
|
||||
name: my-app
|
||||
namespace: argocd
|
||||
spec:
|
||||
project: default
|
||||
source:
|
||||
repoURL: https://gitea.example.com/org/repo.git
|
||||
targetRevision: main
|
||||
path: k8s/
|
||||
destination:
|
||||
server: https://kubernetes.default.svc
|
||||
namespace: my-app
|
||||
syncPolicy:
|
||||
automated:
|
||||
prune: true
|
||||
selfHeal: true
|
||||
syncOptions:
|
||||
- CreateNamespace=true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## CI/CD + GitOps схема
|
||||
|
||||
```
|
||||
Gitea (code)
|
||||
│
|
||||
├── Gitea Actions (CI) ──→ Build Docker Image ──→ Harbor (registry)
|
||||
│ │
|
||||
└── ArgoCD (CD) ←── обнаруживает изменение в Git ←───┘
|
||||
│
|
||||
└──→ kubectl apply ──→ K3S кластер
|
||||
```
|
||||
|
||||
**Рабочий процесс:**
|
||||
1. Push в Gitea → запускает Gitea Actions workflow
|
||||
2. Actions: тест → build → push в Harbor
|
||||
3. Actions обновляет `image: harbor.example.com/myapp:${SHA}` в k8s-манифестах
|
||||
4. ArgoCD обнаруживает изменение в Git → автоматически деплоит в кластер
|
||||
|
||||
### Интеграция Jenkins + Gitea
|
||||
|
||||
В Gitea → Repository → Webhooks → Add Webhook:
|
||||
- URL: `https://jenkins.example.com/gitea-webhook/post`
|
||||
- Content-Type: `application/json`
|
||||
|
||||
В Jenkins: плагин `gitea-plugin` уже установлен.
|
||||
|
||||
### Интеграция ArgoCD + Gitea
|
||||
|
||||
```yaml
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: gitea-repo
|
||||
namespace: argocd
|
||||
labels:
|
||||
argocd.argoproj.io/secret-type: repository
|
||||
stringData:
|
||||
type: git
|
||||
url: https://gitea.example.com/org/repo.git
|
||||
username: argocd-bot
|
||||
password: "gitea-token"
|
||||
```
|
||||
Reference in New Issue
Block a user