Proxy cache (harbor_proxy_cache_enabled: true): - Автоматически создаёт registry endpoints + proxy cache проекты для: docker.io, gcr.io, quay.io, ghcr.io, registry.k8s.io, mcr.microsoft.com, public.ecr.aws - При pull образа через harbor.example.com/<registry>/<image> он кэшируется - Реализовано через alpine:3.19 + curl + jq Kubernetes Job (вызывает Harbor REST API изнутри кластера) Tag retention (harbor_retention_enabled: true, harbor_retention_max_tags: 3): - Политика "latestPushedN=3" применяется ко ВСЕМ проектам (включая proxy cache) - Пропускает проекты с уже существующей политикой (idempotent) - Запуск: ежедневно в 03:00 UTC (cron schedule в Harbor) Механизм: Job запускается после Helm install, достучивается до harbor-core по internal service DNS, ждёт API готовности (40 попыток × 15 сек = 10 мин max).
160 lines
6.1 KiB
YAML
160 lines
6.1 KiB
YAML
---
|
|
- name: Add Harbor Helm repo
|
|
kubernetes.core.helm_repository:
|
|
name: harbor
|
|
repo_url: "{{ harbor_chart_repo }}"
|
|
environment:
|
|
KUBECONFIG: "{{ k3s_kubeconfig_path }}"
|
|
|
|
- name: Fetch latest Harbor chart version
|
|
ansible.builtin.command: helm search repo harbor/harbor --output json
|
|
register: _harbor_chart_search
|
|
changed_when: false
|
|
when: harbor_version == ""
|
|
environment:
|
|
KUBECONFIG: "{{ k3s_kubeconfig_path }}"
|
|
|
|
- name: Set effective Harbor chart version
|
|
ansible.builtin.set_fact:
|
|
_harbor_chart_version: >-
|
|
{{ harbor_version if harbor_version != '' else
|
|
(_harbor_chart_search.stdout | from_json)[0].version }}
|
|
|
|
- name: Show Harbor chart version that will be installed
|
|
ansible.builtin.debug:
|
|
msg: "Устанавливаю Harbor chart {{ _harbor_chart_version }}"
|
|
|
|
- name: Create dedicated PostgreSQL user and database for Harbor
|
|
kubernetes.core.k8s:
|
|
state: present
|
|
definition:
|
|
apiVersion: batch/v1
|
|
kind: Job
|
|
metadata:
|
|
name: harbor-pg-provision
|
|
namespace: "{{ postgresql_namespace | default('postgresql') }}"
|
|
spec:
|
|
ttlSecondsAfterFinished: 300
|
|
template:
|
|
spec:
|
|
restartPolicy: OnFailure
|
|
containers:
|
|
- name: psql
|
|
image: postgres:16-alpine
|
|
command:
|
|
- /bin/sh
|
|
- -c
|
|
- |
|
|
PGPASSWORD="$ADMIN_PASS" psql -h "$HOST" -U postgres -c "
|
|
DO \$\$
|
|
BEGIN
|
|
IF NOT EXISTS (SELECT FROM pg_roles WHERE rolname = '${DB_USER}') THEN
|
|
CREATE USER ${DB_USER} WITH PASSWORD '${DB_PASS}';
|
|
END IF;
|
|
END \$\$;
|
|
" &&
|
|
PGPASSWORD="$ADMIN_PASS" psql -h "$HOST" -U postgres -tc \
|
|
"SELECT 1 FROM pg_database WHERE datname = '${DB_NAME}'" \
|
|
| grep -q 1 || \
|
|
PGPASSWORD="$ADMIN_PASS" psql -h "$HOST" -U postgres -c \
|
|
"CREATE DATABASE ${DB_NAME} OWNER ${DB_USER};"
|
|
env:
|
|
- name: HOST
|
|
value: "{{ harbor_db_host }}"
|
|
- name: ADMIN_PASS
|
|
value: "{{ harbor_postgresql_admin_password }}"
|
|
- name: DB_USER
|
|
value: "{{ harbor_db_username }}"
|
|
- name: DB_PASS
|
|
value: "{{ harbor_db_password }}"
|
|
- name: DB_NAME
|
|
value: "{{ harbor_db_name }}"
|
|
environment:
|
|
KUBECONFIG: "{{ k3s_kubeconfig_path }}"
|
|
when: harbor_database_type == 'external'
|
|
|
|
- name: Wait for Harbor PostgreSQL provision Job to complete
|
|
ansible.builtin.command: >
|
|
k3s kubectl -n {{ postgresql_namespace | default('postgresql') }}
|
|
wait job/harbor-pg-provision
|
|
--for=condition=complete --timeout=120s
|
|
changed_when: false
|
|
when: harbor_database_type == 'external'
|
|
|
|
- name: Template Harbor values
|
|
ansible.builtin.template:
|
|
src: harbor-values.yaml.j2
|
|
dest: /tmp/harbor-values.yaml
|
|
mode: '0644'
|
|
|
|
- name: Install Harbor via Helm
|
|
kubernetes.core.helm:
|
|
name: harbor
|
|
chart_ref: harbor/harbor
|
|
chart_version: "{{ _harbor_chart_version }}"
|
|
release_namespace: "{{ harbor_namespace }}"
|
|
create_namespace: true
|
|
wait: true
|
|
timeout: "15m0s"
|
|
values_files:
|
|
- /tmp/harbor-values.yaml
|
|
environment:
|
|
KUBECONFIG: "{{ k3s_kubeconfig_path }}"
|
|
|
|
- name: Template Harbor configuration Job (proxy cache + retention)
|
|
ansible.builtin.template:
|
|
src: harbor-configure-job.yaml.j2
|
|
dest: /tmp/harbor-configure-job.yaml
|
|
mode: '0644'
|
|
when: harbor_proxy_cache_enabled | bool or harbor_retention_enabled | bool
|
|
|
|
- name: Delete previous Harbor configuration Job (если было)
|
|
ansible.builtin.command: >
|
|
k3s kubectl -n {{ harbor_namespace }} delete job harbor-configure --ignore-not-found=true
|
|
changed_when: false
|
|
when: harbor_proxy_cache_enabled | bool or harbor_retention_enabled | bool
|
|
|
|
- name: Apply Harbor configuration Job
|
|
ansible.builtin.command: k3s kubectl apply -f /tmp/harbor-configure-job.yaml
|
|
changed_when: true
|
|
when: harbor_proxy_cache_enabled | bool or harbor_retention_enabled | bool
|
|
|
|
- name: Wait for Harbor configuration Job to complete
|
|
ansible.builtin.command: >
|
|
k3s kubectl -n {{ harbor_namespace }}
|
|
wait job/harbor-configure
|
|
--for=condition=complete --timeout=600s
|
|
changed_when: false
|
|
when: harbor_proxy_cache_enabled | bool or harbor_retention_enabled | bool
|
|
|
|
- name: Show Harbor configuration Job logs
|
|
ansible.builtin.command: >
|
|
k3s kubectl -n {{ harbor_namespace }} logs
|
|
-l job-name=harbor-configure --tail=50
|
|
register: _harbor_configure_logs
|
|
changed_when: false
|
|
failed_when: false
|
|
when: harbor_proxy_cache_enabled | bool or harbor_retention_enabled | bool
|
|
|
|
- name: Harbor configuration output
|
|
ansible.builtin.debug:
|
|
msg: "{{ _harbor_configure_logs.stdout_lines }}"
|
|
when: harbor_proxy_cache_enabled | bool or harbor_retention_enabled | bool
|
|
|
|
- name: Show Harbor access info
|
|
ansible.builtin.debug:
|
|
msg:
|
|
- "Harbor установлен в namespace: {{ harbor_namespace }}"
|
|
- "URL: http{{ 's' if harbor_ingress_tls else '' }}://{{ harbor_ingress_host }}"
|
|
- "Логин: admin / Пароль: {{ harbor_admin_password }}"
|
|
- "Docker login: docker login {{ harbor_ingress_host }} -u admin"
|
|
- "БД: {{ harbor_database_type }}{{ ' (PostgreSQL ' + harbor_db_host + ')' if harbor_database_type == 'external' else '' }}"
|
|
- ""
|
|
- "Proxy cache pull (образ кэшируется в Harbor автоматически):"
|
|
- " docker pull {{ harbor_ingress_host }}/dockerhub/library/nginx:latest"
|
|
- " docker pull {{ harbor_ingress_host }}/gcr/google-containers/pause:3.9"
|
|
- " docker pull {{ harbor_ingress_host }}/ghcr/owner/image:tag"
|
|
- " docker pull {{ harbor_ingress_host }}/k8s-registry/kube-apiserver:v1.30.0"
|
|
- ""
|
|
- "Retention policy: хранить последние {{ harbor_retention_max_tags }} тега, запуск в 03:00 UTC"
|