feat: Добавлена универсальная лаборатория для тестирования Ansible ролей
- Создана структура molecule/universal/ с поддержкой DinD и DOoD - Добавлена поддержка Kind кластеров для Kubernetes тестирования - Интегрированы Helm charts (nginx, prometheus-stack) - Добавлена поддержка Istio service mesh с Kiali - Создан Makefile с lab-целями для управления лабораторией - Добавлена поддержка Prometheus + Grafana с автопровижинингом - Создан README с подробной документацией Автор: Сергей Антропов Сайт: https://devops.org.ru
This commit is contained in:
209
molecule/universal/create.yml
Normal file
209
molecule/universal/create.yml
Normal file
@@ -0,0 +1,209 @@
|
||||
---
|
||||
# Создание инфраструктуры универсальной лаборатории
|
||||
# Автор: Сергей Антропов
|
||||
# Сайт: https://devops.org.ru
|
||||
|
||||
- hosts: localhost
|
||||
gather_facts: false
|
||||
vars_files:
|
||||
- vars.yml
|
||||
tasks:
|
||||
- name: Ensure network exists
|
||||
community.docker.docker_network:
|
||||
name: "{{ docker_network }}"
|
||||
state: present
|
||||
|
||||
- name: Pull systemd images
|
||||
community.docker.docker_image:
|
||||
name: "{{ images[item.family] }}"
|
||||
source: pull
|
||||
loop: "{{ hosts | selectattr('type','undefined') | list }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }}"
|
||||
|
||||
- name: Start systemd nodes
|
||||
community.docker.docker_container:
|
||||
name: "{{ item.name }}"
|
||||
image: "{{ images[item.family] }}"
|
||||
networks:
|
||||
- name: "{{ docker_network }}"
|
||||
privileged: "{{ systemd_defaults.privileged }}"
|
||||
command: "{{ systemd_defaults.command }}"
|
||||
volumes: "{{ systemd_defaults.volumes }}"
|
||||
tmpfs: "{{ systemd_defaults.tmpfs }}"
|
||||
capabilities: "{{ systemd_defaults.capabilities }}"
|
||||
published_ports: "{{ item.publish | default([]) }}"
|
||||
state: started
|
||||
restart_policy: unless-stopped
|
||||
loop: "{{ hosts | selectattr('type','undefined') | list }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }}"
|
||||
|
||||
- name: Start DinD nodes
|
||||
community.docker.docker_container:
|
||||
name: "{{ item.name }}"
|
||||
image: "docker:27-dind"
|
||||
privileged: true
|
||||
environment:
|
||||
DOCKER_TLS_CERTDIR: ""
|
||||
networks:
|
||||
- name: "{{ docker_network }}"
|
||||
published_ports: "{{ item.publish | default([]) }}"
|
||||
volumes:
|
||||
- "{{ item.name }}-docker:/var/lib/docker"
|
||||
state: started
|
||||
restart_policy: unless-stopped
|
||||
loop: "{{ hosts | selectattr('type','defined') | selectattr('type','equalto','dind') | list }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }}"
|
||||
|
||||
- name: Start DOoD nodes
|
||||
community.docker.docker_container:
|
||||
name: "{{ item.name }}"
|
||||
image: "{{ images[item.family] }}"
|
||||
networks:
|
||||
- name: "{{ docker_network }}"
|
||||
privileged: "{{ systemd_defaults.privileged }}"
|
||||
command: "{{ systemd_defaults.command }}"
|
||||
volumes:
|
||||
- "{{ systemd_defaults.volumes | default([]) }}"
|
||||
- "/var/run/docker.sock:/var/run/docker.sock"
|
||||
tmpfs: "{{ systemd_defaults.tmpfs }}"
|
||||
capabilities: "{{ systemd_defaults.capabilities }}"
|
||||
published_ports: "{{ item.publish | default([]) }}"
|
||||
state: started
|
||||
restart_policy: unless-stopped
|
||||
loop: "{{ hosts | selectattr('type','defined') | selectattr('type','equalto','dood') | list }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }}"
|
||||
|
||||
# ---------- Build multi-group map ----------
|
||||
- name: Init groups map
|
||||
set_fact:
|
||||
groups_map: {}
|
||||
|
||||
- name: Append hosts to groups
|
||||
set_fact:
|
||||
groups_map: >-
|
||||
{{
|
||||
groups_map | combine(
|
||||
{ item_group: (groups_map[item_group] | default([])) + [item_name] }
|
||||
)
|
||||
}}
|
||||
loop: "{{ (hosts | default([])) | subelements('groups', skip_missing=True) }}"
|
||||
loop_control:
|
||||
label: "{{ item.0.name }}"
|
||||
vars:
|
||||
item_name: "{{ item.0.name }}"
|
||||
item_group: "{{ item.1 }}"
|
||||
when: item.0.groups is defined
|
||||
|
||||
- name: Append hosts to single group
|
||||
set_fact:
|
||||
groups_map: >-
|
||||
{{
|
||||
groups_map | combine(
|
||||
{ item.group: (groups_map[item.group] | default([])) + [item.name] }
|
||||
)
|
||||
}}
|
||||
loop: "{{ hosts | default([]) }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }}"
|
||||
when: item.group is defined and item.groups is not defined
|
||||
|
||||
# ---------- INI inventory ----------
|
||||
- name: Render inventory.ini
|
||||
set_fact:
|
||||
inv_ini: |
|
||||
[all:vars]
|
||||
ansible_connection=community.docker.docker
|
||||
ansible_python_interpreter=/usr/bin/python3
|
||||
|
||||
{% for group, members in (groups_map | dictsort) %}
|
||||
[{{ group }}]
|
||||
{% for h in members %}{{ h }}
|
||||
{% endfor %}
|
||||
|
||||
{% endfor %}
|
||||
[all]
|
||||
{% for h in (hosts | default([])) %}{{ h.name }}
|
||||
{% endfor %}
|
||||
|
||||
- name: Write hosts.ini
|
||||
copy:
|
||||
dest: "{{ generated_inventory }}"
|
||||
content: "{{ inv_ini }}"
|
||||
mode: "0644"
|
||||
|
||||
# ---------- Kind clusters (если определены) ----------
|
||||
- name: Create kind cluster configs
|
||||
community.docker.docker_container_exec:
|
||||
container: ansible-controller
|
||||
command: >
|
||||
bash -lc '
|
||||
mkdir -p /ansible/.kind;
|
||||
cat > /ansible/.kind/{{ item.name }}.yaml <<EOF
|
||||
kind: Cluster
|
||||
apiVersion: kind.x-k8s.io/v1alpha4
|
||||
nodes:
|
||||
- role: control-plane
|
||||
{% if (item.addons|default({})).ingress_nginx|default(false) %}
|
||||
extraPortMappings:
|
||||
- containerPort: 80
|
||||
hostPort: {{ item.ingress_host_http_port | default(8081) }}
|
||||
protocol: TCP
|
||||
- containerPort: 443
|
||||
hostPort: {{ item.ingress_host_https_port | default(8443) }}
|
||||
protocol: TCP
|
||||
{% endif %}
|
||||
{% for i in range(item.workers | default(0)) %}
|
||||
- role: worker
|
||||
{% endfor %}
|
||||
networking:
|
||||
apiServerAddress: "0.0.0.0"
|
||||
apiServerPort: {{ item.api_port | default(0) }}
|
||||
EOF
|
||||
'
|
||||
loop: "{{ kind_clusters | default([]) }}"
|
||||
when: (kind_clusters | default([])) | length > 0
|
||||
|
||||
- name: Create kind clusters
|
||||
community.docker.docker_container_exec:
|
||||
container: ansible-controller
|
||||
command: >
|
||||
bash -lc '
|
||||
set -e;
|
||||
for n in {{ (kind_clusters | default([]) | map(attribute="name") | list) | map('quote') | join(' ') }}; do
|
||||
if kind get clusters | grep -qx "$$n"; then
|
||||
echo "[kind] cluster $$n already exists";
|
||||
else
|
||||
echo "[kind] creating $$n";
|
||||
kind create cluster --name "$$n" --config "/ansible/.kind/$$n.yaml";
|
||||
fi
|
||||
done
|
||||
'
|
||||
when: (kind_clusters | default([])) | length > 0
|
||||
|
||||
- name: Install Ingress NGINX and Metrics Server (per cluster, if enabled)
|
||||
community.docker.docker_container_exec:
|
||||
container: ansible-controller
|
||||
command: >
|
||||
bash -lc '
|
||||
set -e;
|
||||
for n in {{ (kind_clusters | default([]) | map(attribute="name") | list) | map('quote') | join(' ') }}; do
|
||||
# ingress-nginx
|
||||
if {{ (kind_clusters | items2dict(key_name="name", value_name="addons")).get(n, {}).get("ingress_nginx", False) | to_json }}; then
|
||||
echo "[addons] ingress-nginx on $$n";
|
||||
kubectl --context kind-$$n apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/main/deploy/static/provider/kind/deploy.yaml || true;
|
||||
kubectl --context kind-$$n -n ingress-nginx rollout status deploy/ingress-nginx-controller --timeout=180s || true;
|
||||
fi
|
||||
# metrics-server
|
||||
if {{ (kind_clusters | items2dict(key_name="name", value_name="addons")).get(n, {}).get("metrics_server", False) | to_json }}; then
|
||||
echo "[addons] metrics-server on $$n";
|
||||
kubectl --context kind-$$n apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml || true;
|
||||
kubectl --context kind-$$n -n kube-system patch deploy metrics-server -p \
|
||||
"{\"spec\":{\"template\":{\"spec\":{\"containers\":[{\"name\":\"metrics-server\",\"args\":[\"--kubelet-insecure-tls\",\"--kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname\"]}]}}}}}" || true;
|
||||
fi
|
||||
done
|
||||
'
|
||||
when: (kind_clusters | default([])) | length > 0
|
||||
Reference in New Issue
Block a user