feat: список пользователей cluster_service_users + роль chrony для синхронизации времени
Список пользователей (cluster_service_users): - заменяет отдельные k8s_service_user и devops_service_user переменные - поддерживает неограниченное число пользователей — добавь строку в список - каждый пользователь: name, comment, shell, sudo, key_type, key_bits, key_comment, ssh_dir - playbooks/k8s-user.yml полностью переработан — все plays используют loop: cluster_service_users - generate_keys/distribute_keys/create_user вызываются через include_role + vars - .gitignore: keys/*_id_rsa (паттерн вместо перечисления конкретных имён) Роль chrony — синхронизация времени: - устанавливается ПЕРЕД k3s как обязательный компонент (добавлена в site.yml play 0) - часовой пояс: chrony_timezone: "Europe/Moscow" (переопределяется в group_vars) - NTP серверы: pool.ntp.org (настраиваемые через chrony_ntp_servers) - community.general.timezone: идемпотентная установка TZ - chronyc makestep: принудительная синхронизация при первом деплое - устанавливается также на lab_hosts в playbooks/k8s-user.yml - make chrony — отдельная цель для переустановки/смены TZ (make chrony TZ=UTC) - команда chrony в entrypoint.sh
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -16,9 +16,8 @@ id_rsa
|
||||
id_ed25519
|
||||
id_ecdsa
|
||||
|
||||
# Локально сохранённые приватные ключи (публичные ключи *_id_rsa.pub — ок коммитить)
|
||||
keys/k8s_id_rsa
|
||||
keys/devops_id_rsa
|
||||
# Локально сохранённые приватные ключи из keys/ (публичные *_id_rsa.pub — ок коммитить)
|
||||
keys/*_id_rsa
|
||||
|
||||
# Docker артефакты
|
||||
.docker/
|
||||
|
||||
8
Makefile
8
Makefile
@@ -47,7 +47,7 @@ DOCKER_RUN := docker run --rm -it \
|
||||
$(IMAGE_NAME)
|
||||
|
||||
.PHONY: help setup build rebuild \
|
||||
bootstrap k8s-user mdadm k3s-certs \
|
||||
bootstrap k8s-user mdadm k3s-certs chrony \
|
||||
install install-k3s install-cni install-kubevip install-nfs install-ingress \
|
||||
install-cert-manager install-istio install-monitoring \
|
||||
add-node remove-node \
|
||||
@@ -205,6 +205,12 @@ mdadm: _check_env _check_image ## Найти RAID массив и смонтир
|
||||
$(DOCKER_RUN) ansible-playbook playbooks/mdadm.yml \
|
||||
$(if $(NODE),--limit $(NODE),)
|
||||
|
||||
chrony: _check_env _check_image ## Установить и настроить chrony (синхронизация времени + часовой пояс)
|
||||
@printf "$(CYAN)Настройка chrony (timezone: $(or $(TZ),из group_vars))...$(NC)\n"
|
||||
$(DOCKER_RUN) ansible-playbook playbooks/site.yml --tags chrony \
|
||||
$(if $(TZ),-e chrony_timezone=$(TZ),) \
|
||||
$(if $(NODE),--limit $(NODE),)
|
||||
|
||||
k3s-certs: _check_env _check_image ## Установить systemd таймер автоматической ротации сертификатов K3S
|
||||
@printf "$(CYAN)Настройка автоматической ротации сертификатов K3S...$(NC)\n"
|
||||
$(DOCKER_RUN) ansible-playbook playbooks/k3s-certs.yml \
|
||||
|
||||
@@ -61,6 +61,7 @@ print_help() {
|
||||
echo " bootstrap — создать пользователя + задеплоить SSH ключ"
|
||||
echo " k8s-user — создать k8s пользователя + разложить SSH ключи"
|
||||
echo " mdadm — найти RAID массив и смонтировать в /storage"
|
||||
echo " chrony — установить chrony + настроить timezone"
|
||||
echo " k3s-certs — установить systemd таймер ротации сертификатов"
|
||||
echo " install — полный стек (site.yml)"
|
||||
echo " install-k3s — только K3S"
|
||||
@@ -219,6 +220,12 @@ case "${COMMAND}" in
|
||||
run_playbook playbooks/mdadm.yml "$@"
|
||||
;;
|
||||
|
||||
# ── chrony ────────────────────────────────────────────────────────────────
|
||||
chrony)
|
||||
log "Настройка chrony и синхронизации времени..."
|
||||
run_playbook playbooks/site.yml --tags chrony "$@"
|
||||
;;
|
||||
|
||||
# ── k3s-certs ─────────────────────────────────────────────────────────────
|
||||
k3s-certs)
|
||||
log "Установка systemd таймера ротации сертификатов K3S..."
|
||||
|
||||
@@ -195,32 +195,43 @@ etcd_backup_local_dir: "./etcd-backups"
|
||||
# Отключить на конкретной ноде: задай mdadm_enabled: false в host_vars/<node>/main.yml
|
||||
mdadm_enabled: false
|
||||
|
||||
# ─── k8s-user ─────────────────────────────────────────────────────────────────
|
||||
# Сервисный пользователь k8s — создаётся на всех серверах (кластер + lab_hosts)
|
||||
# RSA 4096 ключ генерируется один раз на первом мастере, затем раскладывается везде
|
||||
k8s_service_user: k8s
|
||||
k8s_service_user_shell: /bin/bash
|
||||
k8s_service_user_comment: "K8S Service Account"
|
||||
k8s_service_user_key_type: rsa
|
||||
k8s_service_user_key_bits: 4096
|
||||
k8s_service_user_key_comment: "k8s@cluster"
|
||||
k8s_service_user_ssh_dir: ".ssh"
|
||||
k8s_service_user_sudo: true
|
||||
|
||||
# ─── devops-user ──────────────────────────────────────────────────────────────
|
||||
# Дополнительный пользователь для инженеров DevOps
|
||||
# Создаётся на тех же серверах что и k8s, та же RSA 4096 схема с ключами
|
||||
devops_service_user: devops
|
||||
devops_service_user_shell: /bin/bash
|
||||
devops_service_user_comment: "DevOps Engineer"
|
||||
devops_service_user_key_comment: "devops@cluster"
|
||||
devops_service_user_sudo: true
|
||||
# ─── Сервисные пользователи ───────────────────────────────────────────────────
|
||||
# Список пользователей, создаваемых на ВСЕХ серверах (кластер + lab_hosts).
|
||||
# Для каждого: RSA 4096 ключевая пара, authorized_keys, sudo NOPASSWD.
|
||||
# Добавь любое количество пользователей — всё остальное Ansible сделает сам.
|
||||
#
|
||||
# Обязательные поля: name
|
||||
# Опциональные: comment, shell, sudo, key_type, key_bits, key_comment, ssh_dir
|
||||
cluster_service_users:
|
||||
- name: k8s
|
||||
comment: "K8S Service Account"
|
||||
key_comment: "k8s@cluster"
|
||||
sudo: true
|
||||
shell: /bin/bash
|
||||
key_type: rsa
|
||||
key_bits: 4096
|
||||
- name: devops
|
||||
comment: "DevOps Engineer"
|
||||
key_comment: "devops@cluster"
|
||||
sudo: true
|
||||
shell: /bin/bash
|
||||
key_type: rsa
|
||||
key_bits: 4096
|
||||
|
||||
# Локальная директория для сохранения сгенерированных SSH ключей
|
||||
# Сохраняется на машине запуска Ansible (./keys/ относительно корня проекта)
|
||||
# Файлы: keys/k8s_id_rsa, keys/k8s_id_rsa.pub, keys/devops_id_rsa, keys/devops_id_rsa.pub
|
||||
# Файлы: keys/<user>_id_rsa, keys/<user>_id_rsa.pub
|
||||
k8s_local_keys_dir: "./keys"
|
||||
|
||||
# ─── Chrony — синхронизация времени ───────────────────────────────────────────
|
||||
# Устанавливается на все ноды кластера и lab_hosts как обязательный компонент.
|
||||
# Критично для корректной работы etcd, TLS и Kubernetes API.
|
||||
chrony_timezone: "Europe/Moscow"
|
||||
chrony_ntp_servers:
|
||||
- 0.pool.ntp.org
|
||||
- 1.pool.ntp.org
|
||||
- 2.pool.ntp.org
|
||||
- 3.pool.ntp.org
|
||||
|
||||
# ─── k3s-certs — автоматическая ротация сертификатов K3S ─────────────────────
|
||||
# K3S выпускает сертификаты с фиксированным сроком жизни 1 год.
|
||||
# Systemd таймер обеспечивает автоматическое обновление до истечения срока,
|
||||
|
||||
@@ -1,50 +1,66 @@
|
||||
---
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# k8s-user: создание сервисных пользователей на всех серверах
|
||||
#
|
||||
# Роль k8s-user универсальна — вызывается дважды:
|
||||
# • для пользователя k8s (автоматизация кластера)
|
||||
# • для пользователя devops (инженеры DevOps)
|
||||
# k8s-user: создание сервисных пользователей из списка cluster_service_users
|
||||
#
|
||||
# Обрабатывает ЛЮБОЕ количество пользователей из списка в group_vars.
|
||||
# Для каждого пользователя:
|
||||
# 1. Создать пользователя + sudo на всех нодах кластера
|
||||
# 2. Сгенерировать RSA 4096 ключевую пару на первом мастере (один раз)
|
||||
# 3. Сохранить ключи локально в ./keys/
|
||||
# 4. Разложить ключи на все ноды кластера (SSH в любую сторону)
|
||||
# 1. Создать на всех нодах кластера (пользователь + sudo)
|
||||
# 2. Сгенерировать RSA 4096 ключевую пару на первом мастере
|
||||
# 3. Сохранить ключи локально в ./keys/<user>_id_rsa
|
||||
# 4. Разложить ключи на все ноды кластера
|
||||
# 5. Обновить /etc/hosts на нодах кластера
|
||||
# 6. То же самое для lab_hosts (через пароль из vault)
|
||||
# 6. То же самое для lab_hosts (через bootstrap credentials из vault)
|
||||
#
|
||||
# Настройка пользователей: group_vars/all/main.yml → cluster_service_users
|
||||
#
|
||||
# Запуск: ansible-playbook playbooks/k8s-user.yml --ask-vault-pass
|
||||
# Только один пользователь: ansible-playbook playbooks/k8s-user.yml --tags k8s
|
||||
# Только кластер: ansible-playbook playbooks/k8s-user.yml --limit k3s_cluster
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
# ════════════════════════════════════════════════════════════════════════════
|
||||
# ПОЛЬЗОВАТЕЛЬ k8s
|
||||
# ════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
- name: "[k8s] Create service user on cluster nodes"
|
||||
# ── 1. Создать всех пользователей на нодах кластера ──────────────────────────
|
||||
- name: Create service users on cluster nodes
|
||||
hosts: k3s_cluster
|
||||
gather_facts: true
|
||||
become: true
|
||||
tags: [k8s, k8s_user]
|
||||
roles:
|
||||
- role: k8s-user
|
||||
tasks:
|
||||
- name: Create user {{ item.name }}
|
||||
ansible.builtin.include_role:
|
||||
name: k8s-user
|
||||
tasks_from: create_user.yml
|
||||
vars:
|
||||
k8s_service_user: "{{ item.name }}"
|
||||
k8s_service_user_comment: "{{ item.comment | default(item.name) }}"
|
||||
k8s_service_user_shell: "{{ item.shell | default('/bin/bash') }}"
|
||||
k8s_service_user_sudo: "{{ item.sudo | default(true) }}"
|
||||
k8s_service_user_ssh_dir: "{{ item.ssh_dir | default('.ssh') }}"
|
||||
loop: "{{ cluster_service_users }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }}"
|
||||
|
||||
- name: "[k8s] Generate SSH key pair (first master only)"
|
||||
# ── 2. Сгенерировать ключевые пары для всех пользователей (первый мастер) ────
|
||||
- name: Generate SSH key pairs for all users
|
||||
hosts: "{{ groups['k3s_master'][0] }}"
|
||||
gather_facts: false
|
||||
become: true
|
||||
tags: [k8s, k8s_user]
|
||||
tasks:
|
||||
- name: Generate RSA key pair and store facts
|
||||
- name: Generate key pair for {{ item.name }}
|
||||
ansible.builtin.include_role:
|
||||
name: k8s-user
|
||||
tasks_from: generate_keys.yml
|
||||
vars:
|
||||
k8s_service_user: "{{ item.name }}"
|
||||
k8s_service_user_key_type: "{{ item.key_type | default('rsa') }}"
|
||||
k8s_service_user_key_bits: "{{ item.key_bits | default(4096) }}"
|
||||
k8s_service_user_key_comment: "{{ item.key_comment | default(item.name + '@cluster') }}"
|
||||
k8s_service_user_ssh_dir: "{{ item.ssh_dir | default('.ssh') }}"
|
||||
loop: "{{ cluster_service_users }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }}"
|
||||
|
||||
- name: "[k8s] Save SSH keys to local machine"
|
||||
# ── 3. Сохранить все ключи локально в ./keys/ ────────────────────────────────
|
||||
- name: Save SSH keys to local machine
|
||||
hosts: "{{ groups['k3s_master'][0] }}"
|
||||
gather_facts: false
|
||||
tags: [k8s, k8s_user]
|
||||
tasks:
|
||||
- name: Create local keys directory
|
||||
ansible.builtin.file:
|
||||
@@ -54,53 +70,68 @@
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
|
||||
- name: Save private key locally
|
||||
- name: Save private key for {{ item.name }}
|
||||
ansible.builtin.copy:
|
||||
content: "{{ lookup('vars', k8s_service_user + '_ssh_private_key') }}"
|
||||
dest: "{{ k8s_local_keys_dir }}/{{ k8s_service_user }}_id_rsa"
|
||||
content: "{{ hostvars[inventory_hostname][item.name + '_ssh_private_key'] }}"
|
||||
dest: "{{ k8s_local_keys_dir }}/{{ item.name }}_id_rsa"
|
||||
mode: '0600'
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
loop: "{{ cluster_service_users }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }}"
|
||||
|
||||
- name: Save public key locally
|
||||
- name: Save public key for {{ item.name }}
|
||||
ansible.builtin.copy:
|
||||
content: "{{ lookup('vars', k8s_service_user + '_ssh_public_key') }}\n"
|
||||
dest: "{{ k8s_local_keys_dir }}/{{ k8s_service_user }}_id_rsa.pub"
|
||||
content: "{{ hostvars[inventory_hostname][item.name + '_ssh_public_key'] }}\n"
|
||||
dest: "{{ k8s_local_keys_dir }}/{{ item.name }}_id_rsa.pub"
|
||||
mode: '0644'
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
loop: "{{ cluster_service_users }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }}"
|
||||
|
||||
- name: Show where keys were saved
|
||||
- name: Show saved key locations
|
||||
ansible.builtin.debug:
|
||||
msg: "SSH keys saved to {{ k8s_local_keys_dir }}/{{ k8s_service_user }}_id_rsa"
|
||||
msg: "Keys saved: {{ k8s_local_keys_dir }}/{{ item.name }}_id_rsa"
|
||||
loop: "{{ cluster_service_users }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }}"
|
||||
|
||||
- name: "[k8s] Distribute SSH keys to all cluster nodes"
|
||||
# ── 4. Разложить ключи на все ноды кластера ──────────────────────────────────
|
||||
- name: Distribute SSH keys to all cluster nodes
|
||||
hosts: k3s_cluster
|
||||
gather_facts: false
|
||||
become: true
|
||||
tags: [k8s, k8s_user]
|
||||
tasks:
|
||||
- name: Deploy keys to node
|
||||
- name: Deploy keys for {{ item.name }}
|
||||
ansible.builtin.include_role:
|
||||
name: k8s-user
|
||||
tasks_from: distribute_keys.yml
|
||||
vars:
|
||||
k8s_service_user: "{{ item.name }}"
|
||||
k8s_service_user_ssh_dir: "{{ item.ssh_dir | default('.ssh') }}"
|
||||
loop: "{{ cluster_service_users }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }}"
|
||||
|
||||
- name: "[k8s] Update /etc/hosts on cluster nodes"
|
||||
# ── 5. Обновить /etc/hosts на нодах кластера (один раз на хост) ──────────────
|
||||
- name: Update /etc/hosts on cluster nodes
|
||||
hosts: k3s_cluster
|
||||
gather_facts: false
|
||||
become: true
|
||||
tags: [k8s, k8s_user]
|
||||
tasks:
|
||||
- name: Update hosts file
|
||||
ansible.builtin.include_role:
|
||||
name: k8s-user
|
||||
tasks_from: update_hosts.yml
|
||||
|
||||
- name: "[k8s] Setup user on lab hosts"
|
||||
# ── 6. Настроить всё на lab_hosts (через bootstrap credentials из vault) ──────
|
||||
- name: Setup service users on lab hosts
|
||||
hosts: lab_hosts
|
||||
gather_facts: true
|
||||
become: true
|
||||
tags: [k8s, k8s_user]
|
||||
vars:
|
||||
ansible_user: "{{ bootstrap_user }}"
|
||||
ansible_password: "{{ bootstrap_password }}"
|
||||
@@ -110,133 +141,47 @@
|
||||
-o PasswordAuthentication=yes
|
||||
-o PubkeyAuthentication=no
|
||||
tasks:
|
||||
- ansible.builtin.include_role:
|
||||
- name: Create user {{ item.name }} on lab host
|
||||
ansible.builtin.include_role:
|
||||
name: k8s-user
|
||||
tasks_from: create_user.yml
|
||||
- ansible.builtin.include_role:
|
||||
vars:
|
||||
k8s_service_user: "{{ item.name }}"
|
||||
k8s_service_user_comment: "{{ item.comment | default(item.name) }}"
|
||||
k8s_service_user_shell: "{{ item.shell | default('/bin/bash') }}"
|
||||
k8s_service_user_sudo: "{{ item.sudo | default(true) }}"
|
||||
k8s_service_user_ssh_dir: "{{ item.ssh_dir | default('.ssh') }}"
|
||||
loop: "{{ cluster_service_users }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }}"
|
||||
|
||||
- name: Deploy keys for {{ item.name }} on lab host
|
||||
ansible.builtin.include_role:
|
||||
name: k8s-user
|
||||
tasks_from: distribute_keys.yml
|
||||
- ansible.builtin.include_role:
|
||||
vars:
|
||||
k8s_service_user: "{{ item.name }}"
|
||||
k8s_service_user_ssh_dir: "{{ item.ssh_dir | default('.ssh') }}"
|
||||
loop: "{{ cluster_service_users }}"
|
||||
loop_control:
|
||||
label: "{{ item.name }}"
|
||||
|
||||
- name: Update /etc/hosts on lab host
|
||||
ansible.builtin.include_role:
|
||||
name: k8s-user
|
||||
tasks_from: update_hosts.yml
|
||||
|
||||
# ════════════════════════════════════════════════════════════════════════════
|
||||
# ПОЛЬЗОВАТЕЛЬ devops
|
||||
# ════════════════════════════════════════════════════════════════════════════
|
||||
|
||||
- name: "[devops] Create service user on cluster nodes"
|
||||
hosts: k3s_cluster
|
||||
- name: Configure time synchronization on lab hosts
|
||||
hosts: lab_hosts
|
||||
gather_facts: true
|
||||
become: true
|
||||
tags: [devops, devops_user]
|
||||
vars:
|
||||
k8s_service_user: "{{ devops_service_user }}"
|
||||
k8s_service_user_comment: "{{ devops_service_user_comment }}"
|
||||
k8s_service_user_key_comment: "{{ devops_service_user_key_comment }}"
|
||||
k8s_service_user_sudo: "{{ devops_service_user_sudo }}"
|
||||
k8s_service_user_shell: "{{ devops_service_user_shell }}"
|
||||
ansible_user: "{{ bootstrap_user }}"
|
||||
ansible_password: "{{ bootstrap_password }}"
|
||||
ansible_become_password: "{{ bootstrap_sudo_password | default(bootstrap_password) }}"
|
||||
ansible_ssh_common_args: >-
|
||||
-o StrictHostKeyChecking=no
|
||||
-o PasswordAuthentication=yes
|
||||
-o PubkeyAuthentication=no
|
||||
roles:
|
||||
- role: k8s-user
|
||||
|
||||
- name: "[devops] Generate SSH key pair (first master only)"
|
||||
hosts: "{{ groups['k3s_master'][0] }}"
|
||||
gather_facts: false
|
||||
become: true
|
||||
tags: [devops, devops_user]
|
||||
vars:
|
||||
k8s_service_user: "{{ devops_service_user }}"
|
||||
tasks:
|
||||
- name: Generate RSA key pair and store facts
|
||||
ansible.builtin.include_role:
|
||||
name: k8s-user
|
||||
tasks_from: generate_keys.yml
|
||||
|
||||
- name: "[devops] Save SSH keys to local machine"
|
||||
hosts: "{{ groups['k3s_master'][0] }}"
|
||||
gather_facts: false
|
||||
tags: [devops, devops_user]
|
||||
vars:
|
||||
k8s_service_user: "{{ devops_service_user }}"
|
||||
tasks:
|
||||
- name: Create local keys directory
|
||||
ansible.builtin.file:
|
||||
path: "{{ k8s_local_keys_dir }}"
|
||||
state: directory
|
||||
mode: '0700'
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
|
||||
- name: Save private key locally
|
||||
ansible.builtin.copy:
|
||||
content: "{{ lookup('vars', k8s_service_user + '_ssh_private_key') }}"
|
||||
dest: "{{ k8s_local_keys_dir }}/{{ k8s_service_user }}_id_rsa"
|
||||
mode: '0600'
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
|
||||
- name: Save public key locally
|
||||
ansible.builtin.copy:
|
||||
content: "{{ lookup('vars', k8s_service_user + '_ssh_public_key') }}\n"
|
||||
dest: "{{ k8s_local_keys_dir }}/{{ k8s_service_user }}_id_rsa.pub"
|
||||
mode: '0644'
|
||||
delegate_to: localhost
|
||||
become: false
|
||||
|
||||
- name: Show where keys were saved
|
||||
ansible.builtin.debug:
|
||||
msg: "SSH keys saved to {{ k8s_local_keys_dir }}/{{ k8s_service_user }}_id_rsa"
|
||||
|
||||
- name: "[devops] Distribute SSH keys to all cluster nodes"
|
||||
hosts: k3s_cluster
|
||||
gather_facts: false
|
||||
become: true
|
||||
tags: [devops, devops_user]
|
||||
vars:
|
||||
k8s_service_user: "{{ devops_service_user }}"
|
||||
tasks:
|
||||
- name: Deploy keys to node
|
||||
ansible.builtin.include_role:
|
||||
name: k8s-user
|
||||
tasks_from: distribute_keys.yml
|
||||
|
||||
- name: "[devops] Update /etc/hosts on cluster nodes"
|
||||
hosts: k3s_cluster
|
||||
gather_facts: false
|
||||
become: true
|
||||
tags: [devops, devops_user]
|
||||
vars:
|
||||
k8s_service_user: "{{ devops_service_user }}"
|
||||
tasks:
|
||||
- name: Update hosts file
|
||||
ansible.builtin.include_role:
|
||||
name: k8s-user
|
||||
tasks_from: update_hosts.yml
|
||||
|
||||
- name: "[devops] Setup user on lab hosts"
|
||||
hosts: lab_hosts
|
||||
gather_facts: true
|
||||
become: true
|
||||
tags: [devops, devops_user]
|
||||
vars:
|
||||
k8s_service_user: "{{ devops_service_user }}"
|
||||
k8s_service_user_comment: "{{ devops_service_user_comment }}"
|
||||
k8s_service_user_key_comment: "{{ devops_service_user_key_comment }}"
|
||||
k8s_service_user_sudo: "{{ devops_service_user_sudo }}"
|
||||
k8s_service_user_shell: "{{ devops_service_user_shell }}"
|
||||
ansible_user: "{{ bootstrap_user }}"
|
||||
ansible_password: "{{ bootstrap_password }}"
|
||||
ansible_become_password: "{{ bootstrap_sudo_password | default(bootstrap_password) }}"
|
||||
ansible_ssh_common_args: >-
|
||||
-o StrictHostKeyChecking=no
|
||||
-o PasswordAuthentication=yes
|
||||
-o PubkeyAuthentication=no
|
||||
tasks:
|
||||
- ansible.builtin.include_role:
|
||||
name: k8s-user
|
||||
tasks_from: create_user.yml
|
||||
- ansible.builtin.include_role:
|
||||
name: k8s-user
|
||||
tasks_from: distribute_keys.yml
|
||||
- ansible.builtin.include_role:
|
||||
name: k8s-user
|
||||
tasks_from: update_hosts.yml
|
||||
- role: chrony
|
||||
|
||||
@@ -2,16 +2,27 @@
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
# K3S Full Stack Playbook
|
||||
# Порядок установки:
|
||||
# 1. K3S cluster (master → workers)
|
||||
# 2. kube-vip (VIP для control plane + LoadBalancer)
|
||||
# 3. NFS Server (на master или отдельном хосте)
|
||||
# 4. CSI NFS Driver (StorageClass для PVC)
|
||||
# 5. ingress-nginx (Ingress controller через Helm)
|
||||
# 0. Chrony (синхронизация времени — ОБЯЗАТЕЛЬНО до k3s)
|
||||
# 1. K3S cluster (master → workers)
|
||||
# 2. kube-vip (VIP для control plane + LoadBalancer)
|
||||
# 3. NFS Server (на master или отдельном хосте)
|
||||
# 4. CSI NFS Driver (StorageClass для PVC)
|
||||
# 5. ingress-nginx (Ingress controller через Helm)
|
||||
#
|
||||
# Запуск: ansible-playbook playbooks/site.yml --ask-vault-pass
|
||||
# Только отдельный компонент: ansible-playbook playbooks/site.yml --tags kube_vip
|
||||
# ─────────────────────────────────────────────────────────────────────────────
|
||||
|
||||
# ── 0. Chrony — синхронизация времени (обязательно до k3s) ───────────────────
|
||||
# Расхождение времени нарушает работу etcd, TLS и Kubernetes API
|
||||
- name: Configure time synchronization (chrony)
|
||||
hosts: k3s_cluster
|
||||
gather_facts: true
|
||||
become: true
|
||||
tags: [chrony, time, prereqs]
|
||||
roles:
|
||||
- role: chrony
|
||||
|
||||
# ── 1. K3S Cluster ────────────────────────────────────────────────────────────
|
||||
# serial: 1 — master01 запускается первым (cluster-init), остальные присоединяются
|
||||
- name: Install K3S cluster (HA embedded etcd)
|
||||
|
||||
17
roles/chrony/defaults/main.yml
Normal file
17
roles/chrony/defaults/main.yml
Normal file
@@ -0,0 +1,17 @@
|
||||
---
|
||||
# ─── chrony — синхронизация времени ──────────────────────────────────────────
|
||||
|
||||
# Часовой пояс (формат IANA: Europe/Moscow, UTC, Asia/Novosibirsk, и т.д.)
|
||||
chrony_timezone: "Europe/Moscow"
|
||||
|
||||
# NTP серверы (iburst — быстрая первоначальная синхронизация)
|
||||
chrony_ntp_servers:
|
||||
- 0.pool.ntp.org
|
||||
- 1.pool.ntp.org
|
||||
- 2.pool.ntp.org
|
||||
- 3.pool.ntp.org
|
||||
|
||||
# Максимальный шаг коррекции при старте (секунды) — важно для k8s кластера
|
||||
# Слишком большое расхождение времени нарушает работу TLS и etcd
|
||||
chrony_makestep_threshold: 1.0
|
||||
chrony_makestep_limit: 3
|
||||
6
roles/chrony/handlers/main.yml
Normal file
6
roles/chrony/handlers/main.yml
Normal file
@@ -0,0 +1,6 @@
|
||||
---
|
||||
- name: restart chrony
|
||||
ansible.builtin.systemd:
|
||||
name: chrony
|
||||
state: restarted
|
||||
become: true
|
||||
47
roles/chrony/tasks/main.yml
Normal file
47
roles/chrony/tasks/main.yml
Normal file
@@ -0,0 +1,47 @@
|
||||
---
|
||||
- name: Install chrony
|
||||
ansible.builtin.apt:
|
||||
name: chrony
|
||||
state: present
|
||||
update_cache: false
|
||||
become: true
|
||||
|
||||
- name: Set system timezone
|
||||
community.general.timezone:
|
||||
name: "{{ chrony_timezone }}"
|
||||
become: true
|
||||
notify: restart chrony
|
||||
|
||||
- name: Deploy chrony configuration
|
||||
ansible.builtin.template:
|
||||
src: chrony.conf.j2
|
||||
dest: /etc/chrony/chrony.conf
|
||||
owner: root
|
||||
group: root
|
||||
mode: '0644'
|
||||
backup: true
|
||||
become: true
|
||||
notify: restart chrony
|
||||
|
||||
- name: Enable and start chrony service
|
||||
ansible.builtin.systemd:
|
||||
name: chrony
|
||||
enabled: true
|
||||
state: started
|
||||
become: true
|
||||
|
||||
- name: Force immediate time synchronization
|
||||
ansible.builtin.command: chronyc makestep
|
||||
become: true
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
|
||||
- name: Show synchronization status
|
||||
ansible.builtin.command: chronyc tracking
|
||||
register: chrony_tracking
|
||||
changed_when: false
|
||||
become: true
|
||||
|
||||
- name: Display time sync status
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ chrony_tracking.stdout_lines }}"
|
||||
11
roles/chrony/templates/chrony.conf.j2
Normal file
11
roles/chrony/templates/chrony.conf.j2
Normal file
@@ -0,0 +1,11 @@
|
||||
# Managed by Ansible — не редактируй вручную
|
||||
# K3S Cluster — Time Synchronization (chrony)
|
||||
|
||||
{% for server in chrony_ntp_servers %}
|
||||
server {{ server }} iburst
|
||||
{% endfor %}
|
||||
|
||||
driftfile /var/lib/chrony/drift
|
||||
makestep {{ chrony_makestep_threshold }} {{ chrony_makestep_limit }}
|
||||
rtcsync
|
||||
logdir /var/log/chrony
|
||||
Reference in New Issue
Block a user