めもめも

このブログに記載の内容は個人の見解であり、必ずしも所属組織の立場、戦略、意見を代表するものではありません。

OpenShiftインストール用Ansibleプレイブックの解析

何の話かと言うと

いろいろ便利そうなテクニックが学べるかと思って、OpenShift OriginをインストールするAnsibleのプレイブックを覗いてみました。

(参考資料)
OpenShift Origin / Advanced Installation

全体構成

/etc/ansible/hosts

[OSEv3:children]   # ここで指定されたグループのノードには、[OSEv3:vars] セクションの変数がセットされる。
masters
nodes

[OSEv3:vars]
ansible_ssh_user=root
deployment_type=origin   # Origin / OSE などでインストール手順を切り替える仕組み。

[masters]
oso-master01.example.com

[nodes]
oso-master01.example.com openshift_node_labels="{'region':'infra','zone':'default'}" openshift_schedulable=false
oso-node01.example.com openshift_node_labels="{'region': 'primary', 'zone': 'zone01'}"
oso-node02.example.com openshift_node_labels="{'region': 'primary', 'zone': 'zone02'}"

byo/config.yml

---
- include: openshift-cluster/config.yml

byo/openshift-cluster/config.yml

---
- include: ../../common/openshift-cluster/config.yml
  vars:
    g_etcd_hosts: "{{ groups.etcd | default([]) }}"
    g_master_hosts: "{{ groups.masters | default([]) }}"  # [masters] グループのノード
    g_node_hosts: "{{ groups.nodes | default([]) }}"      # [nodes] グループのノード
    g_lb_hosts: "{{ groups.lb | default([]) }}"
    openshift_cluster_id: "{{ cluster_id | default('default') }}"
    openshift_debug_level: 2
    openshift_deployment_type: "{{ deployment_type }}"

common/openshift-cluster/config.yml

---
- include: evaluate_groups.yml             # インストール対象ノードをインベントリーに登録する

- include: ../openshift-docker/config.yml  # dockerを初期設定する

- include: ../openshift-etcd/config.yml

- include: ../openshift-master/config.yml

- include: ../openshift-node/config.yml

インベントリー登録

common/openshift-cluster/evaluate_groups.yml # インストール対象ノードをインベントリーに登録する

---
- name: Populate config host groups
  hosts: localhost
  connection: local
  become: no
  gather_facts: no
  tasks:
  - fail:
      msg: This playbook requires g_etcd_hosts to be set
    when: g_etcd_hosts is not defined

  - fail:
      msg: This playbook requires g_master_hosts to be set
    when: g_master_hosts is not defined

  - fail:
      msg: This playbook requires g_node_hosts or g_new_node_hosts to be set
    when: g_node_hosts is not defined and g_new_node_hosts is not defined

  - fail:
      msg: This playbook requires g_lb_hosts to be set
    when: g_lb_hosts is not defined

  - name: Evaluate oo_etcd_to_config
    add_host:
      name: "{{ item }}"
      groups: oo_etcd_to_config
      ansible_ssh_user: "{{ g_ssh_user | default(omit) }}"
      ansible_sudo: "{{ g_sudo | default(omit) }}"
    with_items: "{{ g_etcd_hosts | default([]) }}"

  - name: Evaluate oo_masters_to_config
    add_host:
      name: "{{ item }}"
      groups: oo_masters_to_config
      ansible_ssh_user: "{{ g_ssh_user | default(omit) }}"
      ansible_sudo: "{{ g_sudo | default(omit) }}"
    with_items: "{{ g_master_hosts | default([]) }}"

  # Use g_new_node_hosts if it exists otherwise g_node_hosts
  - set_fact:
      g_node_hosts_to_config: "{{ g_new_node_hosts | default(g_node_hosts | default([])) }}"

  - name: Evaluate oo_nodes_to_config
    add_host:
      name: "{{ item }}"
      groups: oo_nodes_to_config
      ansible_ssh_user: "{{ g_ssh_user | default(omit) }}"
      ansible_sudo: "{{ g_sudo | default(omit) }}"
    with_items: "{{ g_node_hosts_to_config | default([]) }}"

  # Skip adding the master to oo_nodes_to_config when g_new_node_hosts is
  - name: Evaluate oo_nodes_to_config
    add_host:
      name: "{{ item }}"
      groups: oo_nodes_to_config
      ansible_ssh_user: "{{ g_ssh_user | default(omit) }}"
      ansible_sudo: "{{ g_sudo | default(omit) }}"
    with_items: "{{ g_master_hosts | default([]) }}"
    when: g_nodeonmaster | default(false) == true and g_new_node_hosts is not defined

  - name: Evaluate oo_first_etcd
    add_host:
      name: "{{ g_etcd_hosts[0] }}"
      groups: oo_first_etcd
      ansible_ssh_user: "{{ g_ssh_user | default(omit) }}"
    when: g_etcd_hosts|length > 0

  - name: Evaluate oo_first_master
    add_host:
      name: "{{ g_master_hosts[0] }}"
      groups: oo_first_master
      ansible_ssh_user: "{{ g_ssh_user | default(omit) }}"
      ansible_sudo: "{{ g_sudo | default(omit) }}"
    when: g_master_hosts|length > 0

  - name: Evaluate oo_lb_to_config
    add_host:
      name: "{{ item }}"
      groups: oo_lb_to_config
      ansible_ssh_user: "{{ g_ssh_user | default(omit) }}"
      ansible_sudo: "{{ g_sudo | default(omit) }}"
    with_items: "{{ g_lb_hosts | default([]) }}"

Dockerの初期設定

※dockerパッケージは事前インストール済みの前提

common/openshift-docker/config.yml

- name: Configure docker hosts
  hosts: oo_masters_to_config:oo_nodes_to_config:oo_etcd_to_config
  vars:
    docker_additional_registries: "{{ lookup('oo_option', 'docker_additional_registries') | oo_split }}" # oo_optionsは、ローカルの「lookup_plugins」ディレクトリーに配置した独自のLookupプラグイン。oo_splitは、ローカルの「filter_plugins」ディレクトリーに配置した独自のフィルタープラグイン
    docker_insecure_registries: "{{ lookup('oo_option',  'docker_insecure_registries') | oo_split }}"
    docker_blocked_registries: "{{ lookup('oo_option', 'docker_blocked_registries') | oo_split }}"
  roles:
  - openshift_facts   # ノードの情報を収集
  - openshift_docker  # Dockerの初期設定

common/openshift-docker/roles/openshift_facts/tasks/main.yml

---
- name: Verify Ansible version is greater than 1.8.0 and not 1.9.0 and not 1.9.0.1
  assert:
    that:
    - ansible_version | version_compare('1.8.0', 'ge')
    - ansible_version | version_compare('1.9.0', 'ne')
    - ansible_version | version_compare('1.9.0.1', 'ne')
    
- name: Detecting Operating System
  shell: ls /run/ostree-booted
  ignore_errors: yes
  failed_when: false
  register: ostree_output   # コマンド実行結果を変数に保存する

# Locally setup containerized facts for now
- set_fact:                                     # 変数をタスク内でセットする
    l_is_atomic: "{{ ostree_output.rc == 0 }}" 
- set_fact:
    l_is_containerized: "{{ l_is_atomic or containerized | default(false) | bool }}"

- name: Ensure PyYaml is installed
  action: "{{ ansible_pkg_mgr }} name=PyYAML state=present"  # {{ ansible_pkg_mgr }} はyum等のモジュール名。モジュール名を変数にして実行するために、actionモジュールを使用している。
  when: not l_is_atomic | bool

- name: Gather Cluster facts and set is_containerized if needed
  openshift_facts:    # 「library」ディレクトリーに配置した独自モジュール「openshift_facts.py」を使用する
    role: common
    local_facts:
      is_containerized: "{{ containerized | default(None) }}"

common/openshift-docker/roles/openshift_docker/tasks/main.yml

---
- name: Set docker facts
  openshift_facts:
    role: "{{ item.role }}"
    local_facts: "{{ item.local_facts }}"
  with_items:
  - role: common
    local_facts:
      deployment_type: "{{ openshift_deployment_type }}"
      docker_additional_registries: "{{ docker_additional_registries }}"
      docker_insecure_registries: "{{ docker_insecure_registries }}"
      docker_blocked_registries: "{{ docker_blocked_registries }}"
  - role: node
    local_facts:
      portal_net: "{{ openshift_master_portal_net | default(None) }}"
      docker_log_driver:  "{{ lookup( 'oo_option' , 'docker_log_driver'  )  | default('',True) }}"
      docker_log_options: "{{ lookup( 'oo_option' , 'docker_log_options' )  | default('',True) }}"

- stat: path=/etc/sysconfig/docker
  register: docker_check
  
- name: Set registry params
  lineinfile:       # ファイルの内容(一行)を書き換えるモジュール
    dest: /etc/sysconfig/docker
    regexp: '^{{ item.reg_conf_var }}=.*$'
    line: "{{ item.reg_conf_var }}='{{ item.reg_fact_val | oo_prepend_strings_in_list(item.reg_flag ~ ' ') | join(' ') }}'"
  when: "'docker_additional_registries' in openshift.common and docker_check.stat.isreg"
  with_items:
  - reg_conf_var: ADD_REGISTRY
    reg_fact_val: "{{ openshift.common.docker_additional_registries }}"
    reg_flag: --add-registry
  - reg_conf_var: BLOCK_REGISTRY
    reg_fact_val: "{{ openshift.common.docker_blocked_registries }}"
    reg_flag: --block-registry
  - reg_conf_var: INSECURE_REGISTRY
    reg_fact_val: "{{ openshift.common.docker_insecure_registries }}"
    reg_flag: --insecure-registry
  notify:
  - restart docker

# TODO: Enable secure registry when code available in origin
# TODO: perhaps move this to openshift_docker?
- name: Secure Registry and Logs Options     # /etc/sysconfig/dockerのOPTIONSに--insecure-registry=を突っ込む部分。
  lineinfile:
    dest: /etc/sysconfig/docker
    regexp: '^OPTIONS=.*$'
    line: "OPTIONS='--insecure-registry={{ openshift.node.portal_net }} \
      {% if ansible_selinux and ansible_selinux.status == '''enabled''' %}--selinux-enabled{% endif %} \
      {% if openshift.node.docker_log_driver is defined  %} --log-driver {{ openshift.node.docker_log_driver }}  {% endif %} \
      {% if openshift.node.docker_log_options is defined %}   {{ openshift.node.docker_log_options |  oo_split() | oo_prepend_strings_in_list('--log-opt ') | join(' ')}}  {% endif %} '"
  when: docker_check.stat.isreg
  notify:
    - restart docker

続く。。。。。。。。。。。。。