feat: добавлены аддоны Jenkins, Gitea Actions, NetBird VPN

Jenkins:
- Helm chart jenkins/jenkins, dynamic k8s Pod agents, JCasC конфигурация
- 14 предустановленных плагинов (k8s, pipeline, git, blueocean, github/gitlab/gitea)
- Prometheus ServiceMonitor, Ingress с TLS

Gitea Actions:
- Флаг gitea_actions_enabled (default: false) в gitea Helm values
- act_runner Deployment с Docker-in-Docker sidecar (gitea_actions_runner_enabled)
- Job автоматически по��учает registration token через Gitea API и сохраняет в Secret
- Настраиваемые labels, replicas, DinD on/off

NetBird VPN (self-hosted WireGuard mesh):
- Management server (Helm netbirdio/management) — gRPC API + peer management
- Signal server (Helm netbirdio/signal) — WebRTC peer discovery
- Coturn — STUN/TURN с hostNetwork (корректный внешний IP)
- Все компоненты через kube-vip LoadBalancer (авто-назначение IP из pool)
- Subnet Router Deployment (hostNetwork + NET_ADMIN + ip_forward)
  — VPN-клиенты получают ��оступ к подсетям кластера
- Exit Node Deployment (hostNetwork + MASQUERADE iptables)
  — весь интернет-трафик VPN-клиентов через ноду кластера
- Static LB IPs через kube-vip annotation (опционально)
This commit is contained in:
Sergey Antropoff
2026-04-25 18:41:54 +03:00
parent 684fc25908
commit e57e676392
20 changed files with 1213 additions and 0 deletions

View File

@@ -0,0 +1,7 @@
---
- name: Install Jenkins
hosts: k3s_master[0]
gather_facts: false
become: true
roles:
- role: "{{ playbook_dir }}/../addons/jenkins/role"

View File

@@ -0,0 +1,64 @@
---
jenkins_version: "" # "" = автоматически последняя версия чарта
jenkins_namespace: "jenkins"
jenkins_chart_repo: "https://charts.jenkins.io"
# Администратор
jenkins_admin_user: "admin"
# Пароль задаётся в vault.yml: vault_jenkins_admin_password
jenkins_admin_password: "{{ vault_jenkins_admin_password | default('changeme-jenkins') }}"
# ── Plugins ───────────────────────────────────────────────────────────────────
jenkins_plugins:
- kubernetes # динамические агенты в k8s подах
- workflow-aggregator # Pipeline (Scripted + Declarative)
- git # Git SCM
- configuration-as-code # JCasC — конфиг как код
- pipeline-stage-view # визуализация стадий Pipeline
- blueocean # современный UI (опционально)
- credentials-binding # переменные окружения из Credentials
- ssh-agent # SSH ключи в Pipeline
- docker-workflow # docker.build/push в Pipeline
- ansicolor # цветной вывод консоли
- build-timeout # таймаут сборки
- timestamper # временные метки в логах
- github # GitHub интеграция и webhooks
- gitlab-plugin # GitLab интеграция (опционально)
- gitea-plugin # Gitea интеграция (опционально)
- matrix-auth # ролевые права доступа
# ── Ingress ───────────────────────────────────────────────────────────────────
jenkins_ingress_enabled: true
jenkins_ingress_host: "jenkins.example.com"
jenkins_ingress_class: "{{ ingress_nginx_class_name | default('nginx') }}"
jenkins_ingress_tls: true
jenkins_ingress_cert_issuer: "{{ cert_manager_default_issuer_name | default('letsencrypt-prod') }}"
# ── Хранилище (Jenkins Home) ──────────────────────────────────────────────────
jenkins_storage_size: "20Gi"
jenkins_storage_class: ""
# ── Kubernetes агенты ─────────────────────────────────────────────────────────
# Dynamic Pod agents — Jenkins создаёт Pod для каждой сборки и удаляет после
jenkins_agent_enabled: true
jenkins_agent_default_image: "jenkins/inbound-agent:latest"
# ── Метрики ───────────────────────────────────────────────────────────────────
jenkins_metrics_enabled: true # Prometheus metrics plugin (port 8080/prometheus)
# ── Ресурсы ───────────────────────────────────────────────────────────────────
jenkins_resources:
requests:
cpu: 200m
memory: 512Mi
limits:
cpu: 2000m
memory: 4Gi
jenkins_agent_resources:
requests:
cpu: 200m
memory: 256Mi
limits:
cpu: 1000m
memory: 1Gi

View File

@@ -0,0 +1,82 @@
---
- name: Add Jenkins Helm repo
kubernetes.core.helm_repository:
name: jenkins
repo_url: "{{ jenkins_chart_repo }}"
environment:
KUBECONFIG: "{{ k3s_kubeconfig_path }}"
- name: Get latest Jenkins chart version
ansible.builtin.shell: |
helm search repo jenkins/jenkins --output json | \
python3 -c "import sys,json; print(json.load(sys.stdin)[0]['version'])"
register: _jenkins_latest_version
changed_when: false
when: jenkins_version == ""
environment:
KUBECONFIG: "{{ k3s_kubeconfig_path }}"
- name: Set Jenkins chart version
ansible.builtin.set_fact:
_jenkins_version: "{{ jenkins_version if jenkins_version != '' else _jenkins_latest_version.stdout | trim }}"
- name: Template Jenkins values
ansible.builtin.template:
src: jenkins-values.yaml.j2
dest: /tmp/jenkins-values.yaml
mode: '0600'
- name: Install Jenkins via Helm
kubernetes.core.helm:
name: jenkins
chart_ref: jenkins/jenkins
chart_version: "{{ _jenkins_version }}"
release_namespace: "{{ jenkins_namespace }}"
create_namespace: true
wait: true
timeout: "10m0s"
values_files:
- /tmp/jenkins-values.yaml
environment:
KUBECONFIG: "{{ k3s_kubeconfig_path }}"
- name: Wait for Jenkins to be ready
ansible.builtin.command: >
k3s kubectl -n {{ jenkins_namespace }}
rollout status statefulset/jenkins --timeout=300s
changed_when: false
retries: 3
delay: 15
- name: Create Prometheus ServiceMonitor for Jenkins
kubernetes.core.k8s:
state: present
definition:
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: jenkins
namespace: "{{ jenkins_namespace }}"
labels:
release: kube-prometheus-stack
spec:
selector:
matchLabels:
app.kubernetes.io/component: jenkins-controller
endpoints:
- port: http
path: /prometheus
interval: 30s
when: jenkins_metrics_enabled | bool and addon_prometheus_stack | default(false) | bool
- name: Show Jenkins access info
ansible.builtin.debug:
msg:
- "Jenkins установлен в namespace: {{ jenkins_namespace }}"
- "{% if jenkins_ingress_enabled %}URL: http{{ 's' if jenkins_ingress_tls else '' }}://{{ jenkins_ingress_host }}{% else %}Port-forward: kubectl port-forward -n {{ jenkins_namespace }} svc/jenkins 8080:8080{% endif %}"
- "Логин: {{ jenkins_admin_user }} / {{ jenkins_admin_password }}"
- "Kubernetes agents: {{ 'включены' if jenkins_agent_enabled else 'отключены' }}"
- "Plugins ({{ jenkins_plugins | length }}): {{ jenkins_plugins | join(', ') }}"
- ""
- "Первый запуск займёт 3-5 мин (установка plugins). Следи за логами:"
- " kubectl logs -n {{ jenkins_namespace }} jenkins-0 -c jenkins -f"

View File

@@ -0,0 +1,89 @@
controller:
# Учётные данные администратора
adminUser: "{{ jenkins_admin_user }}"
adminPassword: "{{ jenkins_admin_password }}"
# Plugins устанавливаются при первом старте
installPlugins:
{% for plugin in jenkins_plugins %}
- {{ plugin }}
{% endfor %}
{% if jenkins_metrics_enabled %}
- prometheus
{% endif %}
# Ресурсы
resources:
requests:
cpu: "{{ jenkins_resources.requests.cpu }}"
memory: "{{ jenkins_resources.requests.memory }}"
limits:
cpu: "{{ jenkins_resources.limits.cpu }}"
memory: "{{ jenkins_resources.limits.memory }}"
# Тип сервиса (ClusterIP — доступ через Ingress)
serviceType: ClusterIP
# Ingress
ingress:
enabled: {{ jenkins_ingress_enabled | lower }}
{% if jenkins_ingress_enabled %}
ingressClassName: "{{ jenkins_ingress_class }}"
hostName: "{{ jenkins_ingress_host }}"
{% if jenkins_ingress_tls %}
tls:
- secretName: jenkins-tls
hosts:
- "{{ jenkins_ingress_host }}"
annotations:
nginx.ingress.kubernetes.io/proxy-body-size: "50m"
nginx.ingress.kubernetes.io/proxy-read-timeout: "300"
cert-manager.io/cluster-issuer: "{{ jenkins_ingress_cert_issuer }}"
{% endif %}
{% endif %}
# Prometheus metrics
prometheus:
enabled: {{ jenkins_metrics_enabled | lower }}
# JCasC — базовая конфигурация
JCasC:
defaultConfig: true
configScripts:
jenkins-config: |
jenkins:
systemMessage: "Managed by Ansible k3s-ansible"
numExecutors: 0
unclassified:
location:
url: "http{{ 's' if jenkins_ingress_tls else '' }}://{{ jenkins_ingress_host }}/"
# Хранилище Jenkins Home
persistence:
enabled: true
size: "{{ jenkins_storage_size }}"
{% if jenkins_storage_class %}
storageClass: "{{ jenkins_storage_class }}"
{% endif %}
# Kubernetes Pod Agents
agent:
enabled: {{ jenkins_agent_enabled | lower }}
image:
repository: "jenkins/inbound-agent"
tag: "latest"
resources:
requests:
cpu: "{{ jenkins_agent_resources.requests.cpu }}"
memory: "{{ jenkins_agent_resources.requests.memory }}"
limits:
cpu: "{{ jenkins_agent_resources.limits.cpu }}"
memory: "{{ jenkins_agent_resources.limits.memory }}"
# Отдельный PVC для Jenkins home (master)
persistence:
enabled: true
size: "{{ jenkins_storage_size }}"
{% if jenkins_storage_class %}
storageClass: "{{ jenkins_storage_class }}"
{% endif %}