В настоящее время я настраиваю несколько ролей Ansible для настройки кластера Kubernetes. На данный момент у меня есть роль для предоставления идемпотентных EC2 (1x Master / 2x Worker) и последующие роли для настройки этих основных/рабочих узлов с зависимостями Docker/Kubernetes. Я использую AWS ec2.ini/.py dynamic-inventory
для обнаружения IP-адресов экземпляров, предоставленных моей ролью create_ec2
.
Я столкнулся с проблемой при попытке присоединить моих рабочих процессов к кластеру с помощью команды присоединения, которую я получаю от главного узла. У меня есть 2 отдельные роли для подготовки мастера и работника. В задачах для мастера я получаю команду соединения с:
kubeadm token create --print-join-command
а затем зарегистрируйте переменную, которую я затем использую для установки факта хоста:
set_fact:
join_command: "{{ join_command_stdout.stdout_lines[0] }}"
Проблема, с которой я сталкиваюсь, заключается в том, что я пытаюсь получить доступ к этому факту на своих рабочих узлах при запуске моей рабочей роли. Я пытаюсь получить доступ к факту с помощью:
"{{ hostvars['tag_Type_master'].join_command }} --ignore-preflight-errors all >> node_joined.txt"
Однако это не удается, поскольку хост, который я предоставляю для hostvars, по-видимому, не определен.
Для справки, у меня есть это значение в моем динамическом инвентаре (IP-адрес опущен):
"tag_Type_master": [
"1.2.3.4"
Ошибка, которую я получаю:
"{"msg": "The task includes an option with an undefined variable. The error was: \"hostvars['tag_Type_master']\" is undefined"
Я изо всех сил пытаюсь понять, как мне получить доступ к фактам хоста экземпляра EC2, определенного в моей динамической инвентаризации.
Я попытался добавить IP-адрес EC2 непосредственно в hostvars (hostvars['1.2.3.4'].join_command
), однако задача просто зависает и ничего не делает.
Я также пытался ввести переменную Magic (hostvars['inventory_hostname].join_command
), но безрезультатно.
Кажется, что людям удалось получить доступ к данным о хостах с хостов, определенных в статическом файле инвентаризации, однако из-за динамического характера серверов EC2 кластер будет создан, я не могу использовать этот подход.
name: Setup K8s master node
hosts: tag_Name_kube_master
gather_facts: true
roles:
- setup_kube_master
name: Setup K8s worker nodes
hosts: tag_Name_kube_worker
gather_facts: true
roles:
- setup_kube_worker
name: Get join command for workers
shell: kubeadm token create --print-join-command
register: join_command_stdout
name: Persist variable for workers
set_fact:
join_command: "{{ join_command_stdout.stdout_lines[0] }}"
name: join cluster
shell: "{{ hostvars['tag_Type_master'].join_command }} --ignore-preflight-errors all >> node_joined.txt"
args:
chdir: $HOME
creates: node_joined.txt
Таким образом, способ устранения неполадок для себя — использовать задачу debug:
, чтобы показать весь кеш фактов и найти взаимосвязь для себя:
- name: show the state of affairs
debug: var=hostvars verbosity=0
Однако, сказав это, я почти уверен, что tag_Type_master
определяется как группа и, следовательно, не будет отображаться в hostvars
, поскольку, как следует из его названия, это vars
для хозяева, а не vars
для группы.
Вы должны сделать один уровень косвенности, чтобы получить хост, который является членом этой группы:
- hosts: tag_Name_kube_worker
tasks:
- name: promote the "join_command" fact from the masters group
set_fact:
join_command: '{{ some_master.join_command }}'
vars:
some_master: '{{ hostvars[groups["tag_Type_master"][0]] }}'
Я позволил себе некоторые вольности с этим определением some_master
для краткости - в рабочем коде вы хотели бы на самом деле проверить, что эта группа существует, и ее содержимое не пусто, и т. д., и т. д., но я примерно на 80% уверен, что это сработает. даже как написано
Вы бы хотели, чтобы это появилось в run.yml
между hosts: tag_Type_master
и hosts: tag_Type_worker
, чтобы преодолеть фактический разрыв между двумя группами и создать впечатление, что у рабочих был этот join_command
факт все время.
Отдельно, хотя это не то, о чем вы спрашивали, если бы вы пометили эти экземпляры с помощью "kubernetes.io/role/master": ""
и/или "kubernetes.io/role": "master"
, вы бы выиграли, если бы у вас уже были теги, которые cloud-provider
ждет. Я понятия не имею, как это будет выглядеть в ec2.py
, но я уверен, что это будет дешево узнать, используя ansible-inventory -i ec2.py --list
Я помечаю рабочих соответствующим kubernetes.io/role: worker
, хотя я почти уверен, что облачный провайдер AWS не заботится об этом, предпочитая вместо этого просто использовать metadata.labels
на существующих узлах для регистрации ELB и др.
Серьезно оценим помощь Мэтью! Найдите решение вместе с методом, как прийти к выводу самостоятельно. Не могу вас отблагодарить (и спасибо за очистку форматирования! - извините, я новичок в публикации на SO)
Отдельно стоит хорошенько подумать над очень-очень при использовании
--ignore-preflight-errors all
, потому что, как следует из опции, она подавляет все проверки, в том числе будущее. Так что ладно, если вам нужно проигнорировать несколько проверок, то перечислите их, но я настоятельно не рекомендую использоватьall