diff options
Diffstat (limited to 'roles/openshift_master')
29 files changed, 1495 insertions, 0 deletions
diff --git a/roles/openshift_master/README.md b/roles/openshift_master/README.md new file mode 100644 index 000000000..2dcc56e3f --- /dev/null +++ b/roles/openshift_master/README.md @@ -0,0 +1,49 @@ +OpenShift Master +================================== + +Master service installation + +Requirements +------------ + +* Ansible 2.2 +* A RHEL 7.1 host pre-configured with access to the rhel-7-server-rpms, +rhel-7-server-extras-rpms, and rhel-7-server-ose-3.0-rpms repos. + +Role Variables +-------------- + +From this role: + +| Name | Default value | | +|---------------------------------------------------|-----------------------|-------------------------------------------------------------------------------| +| openshift_node_ips | [] | List of the openshift node ip addresses to pre-register when master starts up | +| oreg_url | UNDEF | Default docker registry to use | +| oreg_url_master | UNDEF | Default docker registry to use, specifically on the master | +| openshift_master_api_port | UNDEF | | +| openshift_master_console_port | UNDEF | | +| openshift_master_api_url | UNDEF | | +| openshift_master_console_url | UNDEF | | +| openshift_master_public_api_url | UNDEF | | +| openshift_master_public_console_url | UNDEF | | +| openshift_master_saconfig_limit_secret_references | false | | + + +Dependencies +------------ + + +Example Playbook +---------------- + +TODO + +License +------- + +Apache License, Version 2.0 + +Author Information +------------------ + +TODO diff --git a/roles/openshift_master/defaults/main.yml b/roles/openshift_master/defaults/main.yml new file mode 100644 index 000000000..f861a8e4d --- /dev/null +++ b/roles/openshift_master/defaults/main.yml @@ -0,0 +1,56 @@ +--- +# openshift_master_defaults_in_use is a workaround to detect if we are consuming +# the plays from the role or outside of the role. +openshift_master_defaults_in_use: True +openshift_master_debug_level: "{{ debug_level | default(2) }}" + +r_openshift_master_firewall_enabled: "{{ os_firewall_enabled | default(True) }}" +r_openshift_master_use_firewalld: "{{ os_firewall_use_firewalld | default(False) }}" + +openshift_node_ips: [] +r_openshift_master_clean_install: false +r_openshift_master_etcd3_storage: false +r_openshift_master_os_firewall_enable: true +r_openshift_master_os_firewall_deny: [] +r_openshift_master_os_firewall_allow: +- service: api server https + port: "{{ openshift.master.api_port }}/tcp" +- service: api controllers https + port: "{{ openshift.master.controllers_port }}/tcp" +- service: skydns tcp + port: "{{ openshift.master.dns_port }}/tcp" +- service: skydns udp + port: "{{ openshift.master.dns_port }}/udp" +- service: etcd embedded + port: 4001/tcp + cond: "{{ groups.oo_etcd_to_config | default([]) | length == 0 }}" + +# oreg_url is defined by user input +oreg_host: "{{ oreg_url.split('/')[0] if (oreg_url is defined and '.' in oreg_url.split('/')[0]) else '' }}" +oreg_auth_credentials_path: "{{ r_openshift_master_data_dir }}/.docker" +oreg_auth_credentials_replace: False +l_bind_docker_reg_auth: False + +containerized_svc_dir: "/usr/lib/systemd/system" +ha_svc_template_path: "native-cluster" + +# NOTE +# r_openshift_master_*_default may be defined external to this role. +# openshift_use_*, if defined, may affect other roles or play behavior. +r_openshift_master_use_openshift_sdn_default: "{{ openshift_use_openshift_sdn | default(True) }}" +r_openshift_master_use_openshift_sdn: "{{ r_openshift_master_use_openshift_sdn_default }}" + +r_openshift_master_use_nuage_default: "{{ openshift_use_nuage | default(False) }}" +r_openshift_master_use_nuage: "{{ r_openshift_master_use_nuage_default }}" + +r_openshift_master_use_contiv_default: "{{ openshift_use_contiv | default(False) }}" +r_openshift_master_use_contiv: "{{ r_openshift_master_use_contiv_default }}" + +r_openshift_master_data_dir_default: "{{ openshift_data_dir | default('/var/lib/origin') }}" +r_openshift_master_data_dir: "{{ r_openshift_master_data_dir_default }}" + +r_openshift_master_sdn_network_plugin_name_default: "{{ os_sdn_network_plugin_name | default('redhat/openshift-ovs-subnet') }}" +r_openshift_master_sdn_network_plugin_name: "{{ r_openshift_master_sdn_network_plugin_name_default }}" + +openshift_master_image_config_latest_default: "{{ openshift_image_config_latest | default(False) }}" +openshift_master_image_config_latest: "{{ openshift_master_image_config_latest_default }}" diff --git a/roles/openshift_master/handlers/main.yml b/roles/openshift_master/handlers/main.yml new file mode 100644 index 000000000..d5094c2c9 --- /dev/null +++ b/roles/openshift_master/handlers/main.yml @@ -0,0 +1,39 @@ +--- +- name: restart master api + systemd: + name: "{{ openshift.common.service_type }}-master-api" + state: restarted + when: + - not (master_api_service_status_changed | default(false) | bool) + - openshift.master.cluster_method == 'native' + notify: + - Verify API Server + +- name: restart master controllers + systemd: + name: "{{ openshift.common.service_type }}-master-controllers" + state: restarted + when: + - not (master_controllers_service_status_changed | default(false) | bool) + - openshift.master.cluster_method == 'native' + +- name: Verify API Server + # Using curl here since the uri module requires python-httplib2 and + # wait_for port doesn't provide health information. + command: > + curl --silent --tlsv1.2 + {% if openshift.common.version_gte_3_2_or_1_2 | bool %} + --cacert {{ openshift.common.config_base }}/master/ca-bundle.crt + {% else %} + --cacert {{ openshift.common.config_base }}/master/ca.crt + {% endif %} + {{ openshift.master.api_url }}/healthz/ready + args: + # Disables the following warning: + # Consider using get_url or uri module rather than running curl + warn: no + register: l_api_available_output + until: l_api_available_output.stdout == 'ok' + retries: 120 + delay: 1 + changed_when: false diff --git a/roles/openshift_master/meta/main.yml b/roles/openshift_master/meta/main.yml new file mode 100644 index 000000000..a657668a9 --- /dev/null +++ b/roles/openshift_master/meta/main.yml @@ -0,0 +1,16 @@ +--- +galaxy_info: + author: Jhon Honce + description: Master + company: Red Hat, Inc. + license: Apache License, Version 2.0 + min_ansible_version: 2.2 + platforms: + - name: EL + versions: + - 7 + categories: + - cloud +dependencies: +- role: lib_openshift +- role: lib_os_firewall diff --git a/roles/openshift_master/tasks/bootstrap.yml b/roles/openshift_master/tasks/bootstrap.yml new file mode 100644 index 000000000..0013f5289 --- /dev/null +++ b/roles/openshift_master/tasks/bootstrap.yml @@ -0,0 +1,28 @@ +--- + +- name: ensure the node-bootstrap service account exists + oc_serviceaccount: + name: node-bootstrapper + namespace: openshift-infra + state: present + run_once: true + +- name: grant node-bootstrapper the correct permissions to bootstrap + oc_adm_policy_user: + namespace: openshift-infra + user: system:serviceaccount:openshift-infra:node-bootstrapper + resource_kind: cluster-role + resource_name: system:node-bootstrapper + state: present + run_once: true + +# TODO: create a module for this command. +# oc_serviceaccounts_kubeconfig +- name: create service account kubeconfig with csr rights + command: "oc serviceaccounts create-kubeconfig node-bootstrapper -n openshift-infra" + register: kubeconfig_out + +- name: put service account kubeconfig into a file on disk for bootstrap + copy: + content: "{{ kubeconfig_out.stdout }}" + dest: "{{ openshift_master_config_dir }}/bootstrap.kubeconfig" diff --git a/roles/openshift_master/tasks/check_master_api_is_ready.yml b/roles/openshift_master/tasks/check_master_api_is_ready.yml new file mode 100644 index 000000000..7e8a7a596 --- /dev/null +++ b/roles/openshift_master/tasks/check_master_api_is_ready.yml @@ -0,0 +1,14 @@ +--- +- name: Wait for API to become available + # Using curl here since the uri module requires python-httplib2 and + # wait_for port doesn't provide health information. + command: > + curl --silent --tlsv1.2 + --cacert {{ openshift.common.config_base }}/master/ca-bundle.crt + {{ openshift.master.api_url }}/healthz/ready + register: l_api_available_output + until: l_api_available_output.stdout == 'ok' + retries: 120 + delay: 1 + run_once: true + changed_when: false diff --git a/roles/openshift_master/tasks/clean_systemd_units.yml b/roles/openshift_master/tasks/clean_systemd_units.yml new file mode 100644 index 000000000..e641f84d4 --- /dev/null +++ b/roles/openshift_master/tasks/clean_systemd_units.yml @@ -0,0 +1,9 @@ +--- + +- name: Disable master service + systemd: + name: "{{ openshift.common.service_type }}-master" + state: stopped + enabled: no + masked: yes + ignore_errors: true diff --git a/roles/openshift_master/tasks/configure_external_etcd.yml b/roles/openshift_master/tasks/configure_external_etcd.yml new file mode 100644 index 000000000..b0590ac84 --- /dev/null +++ b/roles/openshift_master/tasks/configure_external_etcd.yml @@ -0,0 +1,17 @@ +--- +- name: Remove etcdConfig section + yedit: + src: /etc/origin/master/master-config.yaml + key: "etcdConfig" + state: absent +- name: Set etcdClientInfo.ca to master.etcd-ca.crt + yedit: + src: /etc/origin/master/master-config.yaml + key: etcdClientInfo.ca + value: master.etcd-ca.crt +- name: Set etcdClientInfo.urls to the external etcd + yedit: + src: /etc/origin/master/master-config.yaml + key: etcdClientInfo.urls + value: + - "{{ etcd_peer_url_scheme }}://{{ etcd_ip }}:{{ etcd_peer_port }}" diff --git a/roles/openshift_master/tasks/firewall.yml b/roles/openshift_master/tasks/firewall.yml new file mode 100644 index 000000000..38afb6764 --- /dev/null +++ b/roles/openshift_master/tasks/firewall.yml @@ -0,0 +1,44 @@ +--- +- when: r_openshift_master_firewall_enabled | bool and not r_openshift_master_use_firewalld | bool + block: + - name: Add iptables allow rules + os_firewall_manage_iptables: + name: "{{ item.service }}" + action: add + protocol: "{{ item.port.split('/')[1] }}" + port: "{{ item.port.split('/')[0] }}" + when: + - item.cond | default(True) + with_items: "{{ r_openshift_master_os_firewall_allow }}" + + - name: Remove iptables rules + os_firewall_manage_iptables: + name: "{{ item.service }}" + action: remove + protocol: "{{ item.port.split('/')[1] }}" + port: "{{ item.port.split('/')[0] }}" + when: + - item.cond | default(True) + with_items: "{{ r_openshift_master_os_firewall_deny }}" + +- when: r_openshift_master_firewall_enabled | bool and r_openshift_master_use_firewalld | bool + block: + - name: Add firewalld allow rules + firewalld: + port: "{{ item.port }}" + permanent: true + immediate: true + state: enabled + when: + - item.cond | default(True) + with_items: "{{ r_openshift_master_os_firewall_allow }}" + + - name: Remove firewalld allow rules + firewalld: + port: "{{ item.port }}" + permanent: true + immediate: true + state: disabled + when: + - item.cond | default(True) + with_items: "{{ r_openshift_master_os_firewall_deny }}" diff --git a/roles/openshift_master/tasks/main.yml b/roles/openshift_master/tasks/main.yml new file mode 100644 index 000000000..824a5886e --- /dev/null +++ b/roles/openshift_master/tasks/main.yml @@ -0,0 +1,389 @@ +--- +# TODO: add ability to configure certificates given either a local file to +# point to or certificate contents, set in default cert locations. + +# Authentication Variable Validation +# TODO: validate the different identity provider kinds as well +- fail: + msg: > + Invalid OAuth grant method: {{ openshift_master_oauth_grant_method }} + when: + - openshift_master_oauth_grant_method is defined + - openshift_master_oauth_grant_method not in openshift_master_valid_grant_methods + +# HA Variable Validation +- fail: + msg: "openshift_master_cluster_method must be set to either 'native' or 'pacemaker' for multi-master installations" + when: + - openshift.master.ha | bool + - (openshift.master.cluster_method is not defined) or (openshift.master.cluster_method is defined and openshift.master.cluster_method not in ["native", "pacemaker"]) +- fail: + msg: "'native' high availability is not supported for the requested OpenShift version" + when: + - openshift.master.ha | bool + - openshift.master.cluster_method == "native" + - not openshift.common.version_gte_3_1_or_1_1 | bool +- fail: + msg: "openshift_master_cluster_password must be set for multi-master installations" + when: + - openshift.master.ha | bool + - openshift.master.cluster_method == "pacemaker" + - openshift_master_cluster_password is not defined or not openshift_master_cluster_password +- fail: + msg: "Pacemaker based HA is not supported at this time when used with containerized installs" + when: + - openshift.master.ha | bool + - openshift.master.cluster_method == "pacemaker" + - openshift.common.is_containerized | bool + +- name: Open up firewall ports + include: firewall.yml + static: yes + +- name: Install Master package + package: + name: "{{ openshift.common.service_type }}-master{{ openshift_pkg_version | default('') | oo_image_tag_to_rpm_version(include_dash=True) }}" + state: present + when: + - not openshift.common.is_containerized | bool + +- name: Create r_openshift_master_data_dir + file: + path: "{{ r_openshift_master_data_dir }}" + state: directory + mode: 0755 + owner: root + group: root + when: + - openshift.common.is_containerized | bool + +- name: Reload systemd units + command: systemctl daemon-reload + when: + - openshift.common.is_containerized | bool + +- name: Re-gather package dependent master facts + openshift_facts: + +- name: Create config parent directory if it does not exist + file: + path: "{{ openshift_master_config_dir }}" + state: directory + +- name: Create the policy file if it does not already exist + command: > + {{ openshift.common.client_binary }} adm create-bootstrap-policy-file + --filename={{ openshift_master_policy }} + args: + creates: "{{ openshift_master_policy }}" + notify: + - restart master api + - restart master controllers + +- name: Create the scheduler config + copy: + content: "{{ scheduler_config | to_nice_json }}" + dest: "{{ openshift_master_scheduler_conf }}" + backup: true + notify: + - restart master api + - restart master controllers + +- name: Install httpd-tools if needed + package: name=httpd-tools state=present + when: + - item.kind == 'HTPasswdPasswordIdentityProvider' + - not openshift.common.is_atomic | bool + with_items: "{{ openshift.master.identity_providers }}" + +- name: Ensure htpasswd directory exists + file: + path: "{{ item.filename | dirname }}" + state: directory + when: + - item.kind == 'HTPasswdPasswordIdentityProvider' + with_items: "{{ openshift.master.identity_providers }}" + +- name: Create the htpasswd file if needed + template: + dest: "{{ item.filename }}" + src: htpasswd.j2 + backup: yes + when: + - item.kind == 'HTPasswdPasswordIdentityProvider' + - openshift.master.manage_htpasswd | bool + with_items: "{{ openshift.master.identity_providers }}" + +- name: Ensure htpasswd file exists + copy: + dest: "{{ item.filename }}" + force: no + content: "" + mode: 0600 + when: + - item.kind == 'HTPasswdPasswordIdentityProvider' + with_items: "{{ openshift.master.identity_providers }}" + +- name: Create the ldap ca file if needed + copy: + dest: "{{ item.ca if 'ca' in item and '/' in item.ca else openshift_master_config_dir ~ '/' ~ item.ca | default('ldap_ca.crt') }}" + content: "{{ openshift.master.ldap_ca }}" + mode: 0600 + backup: yes + when: + - openshift.master.ldap_ca is defined + - item.kind == 'LDAPPasswordIdentityProvider' + with_items: "{{ openshift.master.identity_providers }}" + +- name: Create the openid ca file if needed + copy: + dest: "{{ item.ca if 'ca' in item and '/' in item.ca else openshift_master_config_dir ~ '/' ~ item.ca | default('openid_ca.crt') }}" + content: "{{ openshift.master.openid_ca }}" + mode: 0600 + backup: yes + when: + - openshift.master.openid_ca is defined + - item.kind == 'OpenIDIdentityProvider' + - item.ca | default('') != '' + with_items: "{{ openshift.master.identity_providers }}" + +- name: Create the request header ca file if needed + copy: + dest: "{{ item.clientCA if 'clientCA' in item and '/' in item.clientCA else openshift_master_config_dir ~ '/' ~ item.clientCA | default('request_header_ca.crt') }}" + content: "{{ openshift.master.request_header_ca }}" + mode: 0600 + backup: yes + when: + - openshift.master.request_header_ca is defined + - item.kind == 'RequestHeaderIdentityProvider' + - item.clientCA | default('') != '' + with_items: "{{ openshift.master.identity_providers }}" + +# This is an ugly hack to verify settings are in a file without modifying them with lineinfile. +# The template file will stomp any other settings made. +- block: + - name: check whether our docker-registry setting exists in the env file + command: "awk '/^OPENSHIFT_DEFAULT_REGISTRY=docker-registry.default.svc:5000/' /etc/sysconfig/{{ openshift.common.service_type }}-master" + failed_when: false + changed_when: false + register: l_already_set + + - set_fact: + openshift_push_via_dns: "{{ openshift.common.version_gte_3_6 or (l_already_set.stdout is defined and l_already_set.stdout | match('OPENSHIFT_DEFAULT_REGISTRY=docker-registry.default.svc:5000')) }}" + +- name: Set fact of all etcd host IPs + openshift_facts: + role: common + local_facts: + no_proxy_etcd_host_ips: "{{ openshift_no_proxy_etcd_host_ips }}" + +- name: Install the systemd units + include: systemd_units.yml + +- name: Checking for journald.conf + stat: path=/etc/systemd/journald.conf + register: journald_conf_file + +- name: Update journald setup + replace: + dest: /etc/systemd/journald.conf + regexp: '^(\#| )?{{ item.var }}=\s*.*?$' + replace: ' {{ item.var }}={{ item.val }}' + backup: yes + with_items: "{{ journald_vars_to_replace | default([]) }}" + when: journald_conf_file.stat.exists + register: journald_update + +# I need to restart journald immediatelly, otherwise it gets into way during +# further steps in ansible +- name: Restart journald + systemd: + name: systemd-journald + state: restarted + when: journald_update | changed + +- name: Install Master system container + include: system_container.yml + when: + - openshift.common.is_containerized | bool + - openshift.common.is_master_system_container | bool + +- name: Create session secrets file + template: + dest: "{{ openshift.master.session_secrets_file }}" + src: sessionSecretsFile.yaml.v1.j2 + owner: root + group: root + mode: 0600 + when: + - openshift.master.session_auth_secrets is defined + - openshift.master.session_encryption_secrets is defined + notify: + - restart master api + +- set_fact: + translated_identity_providers: "{{ openshift.master.identity_providers | translate_idps('v1') }}" + +# TODO: add the validate parameter when there is a validation command to run +- name: Create master config + template: + dest: "{{ openshift_master_config_file }}" + src: master.yaml.v1.j2 + backup: true + owner: root + group: root + mode: 0600 + notify: + - restart master api + - restart master controllers + +- name: modify controller args + yedit: + src: /etc/origin/master/master-config.yaml + edits: + - key: kubernetesMasterConfig.controllerArguments.cluster-signing-cert-file + value: + - /etc/origin/master/ca.crt + - key: kubernetesMasterConfig.controllerArguments.cluster-signing-key-file + value: + - /etc/origin/master/ca.key + notify: + - restart master controllers + when: openshift_master_bootstrap_enabled | default(False) + +- include: set_loopback_context.yml + when: + - openshift.common.version_gte_3_2_or_1_2 + +- name: Start and enable master api on first master + systemd: + name: "{{ openshift.common.service_type }}-master-api" + enabled: yes + state: started + when: + - openshift.master.cluster_method == 'native' + - inventory_hostname == openshift_master_hosts[0] + register: l_start_result + until: not l_start_result | failed + retries: 1 + delay: 60 + +- name: Dump logs from master-api if it failed + command: journalctl --no-pager -n 100 -u {{ openshift.common.service_type }}-master-api + when: + - l_start_result | failed + +- set_fact: + master_api_service_status_changed: "{{ l_start_result | changed }}" + when: + - openshift.master.cluster_method == 'native' + - inventory_hostname == openshift_master_hosts[0] + +- pause: + seconds: 15 + when: + - openshift.master.ha | bool + - openshift.master.cluster_method == 'native' + +- name: Start and enable master api all masters + systemd: + name: "{{ openshift.common.service_type }}-master-api" + enabled: yes + state: started + when: + - openshift.master.cluster_method == 'native' + - inventory_hostname != openshift_master_hosts[0] + register: l_start_result + until: not l_start_result | failed + retries: 1 + delay: 60 + +- name: Dump logs from master-api if it failed + command: journalctl --no-pager -n 100 -u {{ openshift.common.service_type }}-master-api + when: + - l_start_result | failed + +- set_fact: + master_api_service_status_changed: "{{ l_start_result | changed }}" + when: + - openshift.master.cluster_method == 'native' + - inventory_hostname != openshift_master_hosts[0] + +# A separate wait is required here for native HA since notifies will +# be resolved after all tasks in the role. +- include: check_master_api_is_ready.yml + when: + - openshift.master.cluster_method == 'native' + - master_api_service_status_changed | bool + +- name: Start and enable master controller on first master + systemd: + name: "{{ openshift.common.service_type }}-master-controllers" + enabled: yes + state: started + when: + - openshift.master.cluster_method == 'native' + - inventory_hostname == openshift_master_hosts[0] + register: l_start_result + until: not l_start_result | failed + retries: 1 + delay: 60 + +- name: Dump logs from master-controllers if it failed + command: journalctl --no-pager -n 100 -u {{ openshift.common.service_type }}-master-controllers + when: + - l_start_result | failed + +- name: Wait for master controller service to start on first master + pause: + seconds: 15 + when: + - openshift.master.cluster_method == 'native' + +- name: Start and enable master controller on all masters + systemd: + name: "{{ openshift.common.service_type }}-master-controllers" + enabled: yes + state: started + when: + - openshift.master.cluster_method == 'native' + - inventory_hostname != openshift_master_hosts[0] + register: l_start_result + until: not l_start_result | failed + retries: 1 + delay: 60 + +- name: Dump logs from master-controllers if it failed + command: journalctl --no-pager -n 100 -u {{ openshift.common.service_type }}-master-controllers + when: + - l_start_result | failed + +- set_fact: + master_controllers_service_status_changed: "{{ l_start_result | changed }}" + when: + - openshift.master.cluster_method == 'native' + +- name: Install cluster packages + package: name=pcs state=present + when: + - openshift.master.cluster_method == 'pacemaker' + - not openshift.common.is_containerized | bool + register: l_install_result + +- name: Start and enable cluster service + systemd: + name: pcsd + enabled: yes + state: started + when: + - openshift.master.cluster_method == 'pacemaker' + - not openshift.common.is_containerized | bool + +- name: Set the cluster user password + shell: echo {{ openshift_master_cluster_password | quote }} | passwd --stdin hacluster + when: + - l_install_result | changed + +- name: node bootstrap settings + include: bootstrap.yml + when: openshift_master_bootstrap_enabled | default(False) diff --git a/roles/openshift_master/tasks/registry_auth.yml b/roles/openshift_master/tasks/registry_auth.yml new file mode 100644 index 000000000..63d483760 --- /dev/null +++ b/roles/openshift_master/tasks/registry_auth.yml @@ -0,0 +1,25 @@ +--- +- name: Check for credentials file for registry auth + stat: + path: "{{ oreg_auth_credentials_path }}" + when: oreg_auth_user is defined + register: master_oreg_auth_credentials_stat + +- name: Create credentials for registry auth + command: "docker --config={{ oreg_auth_credentials_path }} login -u {{ oreg_auth_user }} -p {{ oreg_auth_password }} {{ oreg_host }}" + when: + - oreg_auth_user is defined + - (not master_oreg_auth_credentials_stat.stat.exists or oreg_auth_credentials_replace) | bool + register: master_oreg_auth_credentials_create + notify: + - restart master api + - restart master controllers + +# Container images may need the registry credentials +- name: Setup ro mount of /root/.docker for containerized hosts + set_fact: + l_bind_docker_reg_auth: True + when: + - openshift.common.is_containerized | bool + - oreg_auth_user is defined + - (master_oreg_auth_credentials_stat.stat.exists or oreg_auth_credentials_replace or master_oreg_auth_credentials_create.changed) | bool diff --git a/roles/openshift_master/tasks/set_loopback_context.yml b/roles/openshift_master/tasks/set_loopback_context.yml new file mode 100644 index 000000000..308b2f4cd --- /dev/null +++ b/roles/openshift_master/tasks/set_loopback_context.yml @@ -0,0 +1,34 @@ +--- +- name: Test local loopback context + command: > + {{ openshift.common.client_binary }} config view + --config={{ openshift_master_loopback_config }} + changed_when: false + register: l_loopback_config + +- command: > + {{ openshift.common.client_binary }} config set-cluster + --certificate-authority={{ openshift_master_config_dir }}/ca.crt + --embed-certs=true --server={{ openshift.master.loopback_api_url }} + {{ openshift.master.loopback_cluster_name }} + --config={{ openshift_master_loopback_config }} + when: + - loopback_context_string not in l_loopback_config.stdout + register: set_loopback_cluster + +- command: > + {{ openshift.common.client_binary }} config set-context + --cluster={{ openshift.master.loopback_cluster_name }} + --namespace=default --user={{ openshift.master.loopback_user }} + {{ openshift.master.loopback_context_name }} + --config={{ openshift_master_loopback_config }} + when: + - set_loopback_cluster | changed + register: l_set_loopback_context + +- command: > + {{ openshift.common.client_binary }} config use-context {{ openshift.master.loopback_context_name }} + --config={{ openshift_master_loopback_config }} + when: + - l_set_loopback_context | changed + register: set_current_context diff --git a/roles/openshift_master/tasks/system_container.yml b/roles/openshift_master/tasks/system_container.yml new file mode 100644 index 000000000..91332acfb --- /dev/null +++ b/roles/openshift_master/tasks/system_container.yml @@ -0,0 +1,27 @@ +--- +- name: Pre-pull master system container image + command: > + atomic pull --storage=ostree {{ 'docker:' if openshift.common.system_images_registry == 'docker' else openshift.common.system_images_registry + '/' }}{{ openshift.master.master_system_image }}:{{ openshift_image_tag }} + register: l_pull_result + changed_when: "'Pulling layer' in l_pull_result.stdout" + +- name: Check Master system container package + command: > + atomic containers list --no-trunc -a -f container={{ openshift.common.service_type }}-master + +# HA +- name: Install or Update HA api master system container + oc_atomic_container: + name: "{{ openshift.common.service_type }}-master-api" + image: "{{ 'docker:' if openshift.common.system_images_registry == 'docker' else openshift.common.system_images_registry + '/' }}{{ openshift.master.master_system_image }}:{{ openshift_image_tag }}" + state: latest + values: + - COMMAND=api + +- name: Install or Update HA controller master system container + oc_atomic_container: + name: "{{ openshift.common.service_type }}-master-controllers" + image: "{{ 'docker:' if openshift.common.system_images_registry == 'docker' else openshift.common.system_images_registry + '/' }}{{ openshift.master.master_system_image }}:{{ openshift_image_tag }}" + state: latest + values: + - COMMAND=controllers diff --git a/roles/openshift_master/tasks/systemd_units.yml b/roles/openshift_master/tasks/systemd_units.yml new file mode 100644 index 000000000..fcc66044b --- /dev/null +++ b/roles/openshift_master/tasks/systemd_units.yml @@ -0,0 +1,140 @@ +--- +# systemd_units.yml is included both in the openshift_master role and in the upgrade +# playbooks. + +- include: upgrade_facts.yml + when: openshift_master_defaults_in_use is not defined + +- name: Set HA Service Info for containerized installs + set_fact: + containerized_svc_dir: "/etc/systemd/system" + ha_svc_template_path: "docker-cluster" + when: + - openshift.common.is_containerized | bool + +- include: registry_auth.yml + +- name: Remove the legacy master service if it exists + include: clean_systemd_units.yml + +# This is the image used for both HA and non-HA clusters: +- name: Pre-pull master image + command: > + docker pull {{ openshift.master.master_image }}:{{ openshift_image_tag }} + register: l_pull_result + changed_when: "'Downloaded newer image' in l_pull_result.stdout" + when: + - openshift.common.is_containerized | bool + - not openshift.common.is_master_system_container | bool + +- name: Create the ha systemd unit files + template: + src: "{{ ha_svc_template_path }}/atomic-openshift-master-{{ item }}.service.j2" + dest: "{{ containerized_svc_dir }}/{{ openshift.common.service_type }}-master-{{ item }}.service" + when: + - openshift.master.cluster_method == "native" + - not openshift.common.is_master_system_container | bool + with_items: + - api + - controllers + register: l_create_ha_unit_files + +- command: systemctl daemon-reload + when: + - l_create_ha_unit_files | changed +# end workaround for missing systemd unit files + +- name: Preserve Master API Proxy Config options + command: grep PROXY /etc/sysconfig/{{ openshift.common.service_type }}-master-api + register: l_master_api_proxy + when: + - openshift.master.cluster_method == "native" + failed_when: false + changed_when: false + +- name: Preserve Master API AWS options + command: grep AWS_ /etc/sysconfig/{{ openshift.common.service_type }}-master-api + register: master_api_aws + when: + - openshift.master.cluster_method == "native" + failed_when: false + changed_when: false + +- name: Create the master api service env file + template: + src: "{{ ha_svc_template_path }}/atomic-openshift-master-api.j2" + dest: /etc/sysconfig/{{ openshift.common.service_type }}-master-api + backup: true + when: + - openshift.master.cluster_method == "native" + notify: + - restart master api + +- name: Restore Master API Proxy Config Options + when: + - openshift.master.cluster_method == "native" + - l_master_api_proxy.rc == 0 + - "'http_proxy' not in openshift.common" + - "'https_proxy' not in openshift.common" + lineinfile: + dest: /etc/sysconfig/{{ openshift.common.service_type }}-master-api + line: "{{ item }}" + with_items: "{{ l_master_api_proxy.stdout_lines | default([]) }}" + +- name: Restore Master API AWS Options + when: + - openshift.master.cluster_method == "native" + - master_api_aws.rc == 0 + - not (openshift_cloudprovider_kind is defined and openshift_cloudprovider_kind == 'aws' and openshift_cloudprovider_aws_access_key is defined and openshift_cloudprovider_aws_secret_key is defined) + lineinfile: + dest: /etc/sysconfig/{{ openshift.common.service_type }}-master-api + line: "{{ item }}" + with_items: "{{ master_api_aws.stdout_lines | default([]) }}" + no_log: True + +- name: Preserve Master Controllers Proxy Config options + command: grep PROXY /etc/sysconfig/{{ openshift.common.service_type }}-master-controllers + register: master_controllers_proxy + when: + - openshift.master.cluster_method == "native" + failed_when: false + changed_when: false + +- name: Preserve Master Controllers AWS options + command: grep AWS_ /etc/sysconfig/{{ openshift.common.service_type }}-master-controllers + register: master_controllers_aws + when: + - openshift.master.cluster_method == "native" + failed_when: false + changed_when: false + +- name: Create the master controllers service env file + template: + src: "{{ ha_svc_template_path }}/atomic-openshift-master-controllers.j2" + dest: /etc/sysconfig/{{ openshift.common.service_type }}-master-controllers + backup: true + when: + - openshift.master.cluster_method == "native" + notify: + - restart master controllers + +- name: Restore Master Controllers Proxy Config Options + lineinfile: + dest: /etc/sysconfig/{{ openshift.common.service_type }}-master-controllers + line: "{{ item }}" + with_items: "{{ master_controllers_proxy.stdout_lines | default([]) }}" + when: + - openshift.master.cluster_method == "native" + - master_controllers_proxy.rc == 0 + - "'http_proxy' not in openshift.common" + - "'https_proxy' not in openshift.common" + +- name: Restore Master Controllers AWS Options + lineinfile: + dest: /etc/sysconfig/{{ openshift.common.service_type }}-master-controllers + line: "{{ item }}" + with_items: "{{ master_controllers_aws.stdout_lines | default([]) }}" + when: + - openshift.master.cluster_method == "native" + - master_controllers_aws.rc == 0 + - not (openshift_cloudprovider_kind is defined and openshift_cloudprovider_kind == 'aws' and openshift_cloudprovider_aws_access_key is defined and openshift_cloudprovider_aws_secret_key is defined) diff --git a/roles/openshift_master/tasks/update_etcd_client_urls.yml b/roles/openshift_master/tasks/update_etcd_client_urls.yml new file mode 100644 index 000000000..1ab105808 --- /dev/null +++ b/roles/openshift_master/tasks/update_etcd_client_urls.yml @@ -0,0 +1,8 @@ +--- +- yedit: + src: "{{ openshift.common.config_base }}/master/master-config.yaml" + key: 'etcdClientInfo.urls' + value: "{{ openshift.master.etcd_urls }}" + notify: + - restart master api + - restart master controllers diff --git a/roles/openshift_master/tasks/upgrade_facts.yml b/roles/openshift_master/tasks/upgrade_facts.yml new file mode 100644 index 000000000..f6ad438aa --- /dev/null +++ b/roles/openshift_master/tasks/upgrade_facts.yml @@ -0,0 +1,33 @@ +--- +# This file exists because we call systemd_units.yml from outside of the role +# during upgrades. When we remove this pattern, we can probably +# eliminate most of these set_fact items. + +- name: Set openshift_master_config_dir if unset + set_fact: + openshift_master_config_dir: '/etc/origin/master' + when: openshift_master_config_dir is not defined + +- name: Set r_openshift_master_data_dir if unset + set_fact: + r_openshift_master_data_dir: "{{ openshift_data_dir | default('/var/lib/origin') }}" + when: r_openshift_master_data_dir is not defined + +- set_fact: + oreg_auth_credentials_path: "{{ r_openshift_master_data_dir }}/.docker" + when: oreg_auth_credentials_path is not defined + +- set_fact: + oreg_host: "{{ oreg_url.split('/')[0] if (oreg_url is defined and '.' in oreg_url.split('/')[0]) else '' }}" + when: oreg_host is not defined + +- name: Set openshift_master_debug_level + set_fact: + openshift_master_debug_level: "{{ debug_level | default(2) }}" + when: + - openshift_master_debug_level is not defined + +- name: Init HA Service Info + set_fact: + containerized_svc_dir: "{{ containerized_svc_dir | default('/usr/lib/systemd/system') }}" + ha_svc_template_path: "{{ ha_svc_template_path | default('native-cluster') }}" diff --git a/roles/openshift_master/templates/atomic-openshift-master.j2 b/roles/openshift_master/templates/atomic-openshift-master.j2 new file mode 100644 index 000000000..7ec26ceb7 --- /dev/null +++ b/roles/openshift_master/templates/atomic-openshift-master.j2 @@ -0,0 +1,44 @@ +OPTIONS=--loglevel={{ openshift_master_debug_level }} +CONFIG_FILE={{ openshift_master_config_file }} +{# Preserve existing OPENSHIFT_DEFAULT_REGISTRY settings in scale up runs #} +{% if openshift_master_is_scaleup_host %} +{{ openshift_master_default_registry_value }} +{% elif openshift_push_via_dns | default(false) %} +OPENSHIFT_DEFAULT_REGISTRY=docker-registry.default.svc:5000 +{% endif %} +{% if openshift.common.is_containerized | bool %} +IMAGE_VERSION={{ openshift_image_tag }} +{% endif %} + +{% if openshift_cloudprovider_kind | default('') == 'aws' and openshift_cloudprovider_aws_access_key is defined and openshift_cloudprovider_aws_secret_key is defined %} +AWS_ACCESS_KEY_ID={{ openshift_cloudprovider_aws_access_key }} +AWS_SECRET_ACCESS_KEY={{ openshift_cloudprovider_aws_secret_key }} +{% endif %} +{% if not (openshift_cloudprovider_kind is defined and openshift_cloudprovider_kind == 'aws' and openshift_cloudprovider_aws_access_key is defined and openshift_cloudprovider_aws_secret_key is defined) %} +{% for item in master_aws %} +{{ item }} +{% endfor %} +{% endif %} + +{% if 'api_env_vars' in openshift.master or 'controllers_env_vars' in openshift.master -%} +{% for key, value in openshift.master.api_env_vars.items() | default([]) | union(openshift.master.controllers_env_vars.items() | default([])) -%} +{{ key }}={{ value }} +{% endfor -%} +{% endif -%} + +# Proxy configuration +# See https://docs.openshift.com/enterprise/latest/install_config/install/advanced_install.html#configuring-global-proxy +{% if 'http_proxy' in openshift.common %} +HTTP_PROXY={{ openshift.common.http_proxy | default('') }} +{% endif %} +{% if 'https_proxy' in openshift.common %} +HTTPS_PROXY={{ openshift.common.https_proxy | default('')}} +{% endif %} +{% if 'no_proxy' in openshift.common %} +NO_PROXY={{ openshift.common.no_proxy | default('') }},{{ openshift.common.portal_net }},{{ openshift.master.sdn_cluster_network_cidr }} +{% endif %} +{% if not ('https_proxy' in openshift.common or 'https_proxy' in openshift.common or 'no_proxy' in openshift.common) %} +{% for item in master_proxy %} +{{ item }} +{% endfor %} +{% endif %} diff --git a/roles/openshift_master/templates/docker-cluster/atomic-openshift-master-api.j2 b/roles/openshift_master/templates/docker-cluster/atomic-openshift-master-api.j2 new file mode 120000 index 000000000..4bb7095ee --- /dev/null +++ b/roles/openshift_master/templates/docker-cluster/atomic-openshift-master-api.j2 @@ -0,0 +1 @@ +../native-cluster/atomic-openshift-master-api.j2
\ No newline at end of file diff --git a/roles/openshift_master/templates/docker-cluster/atomic-openshift-master-api.service.j2 b/roles/openshift_master/templates/docker-cluster/atomic-openshift-master-api.service.j2 new file mode 100644 index 000000000..5d4a99c97 --- /dev/null +++ b/roles/openshift_master/templates/docker-cluster/atomic-openshift-master-api.service.j2 @@ -0,0 +1,37 @@ +[Unit] +Description=Atomic OpenShift Master API +Documentation=https://github.com/openshift/origin +After=etcd_container.service +Wants=etcd_container.service +Before={{ openshift.common.service_type }}-node.service +After={{ openshift.docker.service_name }}.service +PartOf={{ openshift.docker.service_name }}.service +Requires={{ openshift.docker.service_name }}.service + +[Service] +EnvironmentFile=/etc/sysconfig/{{ openshift.common.service_type }}-master-api +Environment=GOTRACEBACK=crash +ExecStartPre=-/usr/bin/docker rm -f {{ openshift.common.service_type}}-master-api +ExecStart=/usr/bin/docker run --rm --privileged --net=host \ + --name {{ openshift.common.service_type }}-master-api \ + --env-file=/etc/sysconfig/{{ openshift.common.service_type }}-master-api \ + -v {{ r_openshift_master_data_dir }}:{{ r_openshift_master_data_dir }} \ + -v /var/log:/var/log -v /var/run/docker.sock:/var/run/docker.sock \ + -v {{ openshift.common.config_base }}:{{ openshift.common.config_base }} \ + {% if openshift_cloudprovider_kind | default('') != '' -%} -v {{ openshift.common.config_base }}/cloudprovider:{{ openshift.common.config_base}}/cloudprovider {% endif -%} \ + -v /etc/pki:/etc/pki:ro \ + {% if l_bind_docker_reg_auth | default(False) %} -v {{ oreg_auth_credentials_path }}:/root/.docker:ro{% endif %}\ + {{ openshift.master.master_image }}:${IMAGE_VERSION} start master api \ + --config=${CONFIG_FILE} $OPTIONS +ExecStartPost=/usr/bin/sleep 10 +ExecStop=/usr/bin/docker stop {{ openshift.common.service_type }}-master-api +LimitNOFILE=131072 +LimitCORE=infinity +WorkingDirectory={{ r_openshift_master_data_dir }} +SyslogIdentifier={{ openshift.common.service_type }}-master-api +Restart=always +RestartSec=5s + +[Install] +WantedBy={{ openshift.docker.service_name }}.service +WantedBy={{ openshift.common.service_type }}-node.service diff --git a/roles/openshift_master/templates/docker-cluster/atomic-openshift-master-controllers.j2 b/roles/openshift_master/templates/docker-cluster/atomic-openshift-master-controllers.j2 new file mode 120000 index 000000000..8714ebbae --- /dev/null +++ b/roles/openshift_master/templates/docker-cluster/atomic-openshift-master-controllers.j2 @@ -0,0 +1 @@ +../native-cluster/atomic-openshift-master-controllers.j2
\ No newline at end of file diff --git a/roles/openshift_master/templates/docker-cluster/atomic-openshift-master-controllers.service.j2 b/roles/openshift_master/templates/docker-cluster/atomic-openshift-master-controllers.service.j2 new file mode 100644 index 000000000..f93f3b565 --- /dev/null +++ b/roles/openshift_master/templates/docker-cluster/atomic-openshift-master-controllers.service.j2 @@ -0,0 +1,35 @@ +[Unit] +Description=Atomic OpenShift Master Controllers +Documentation=https://github.com/openshift/origin +Wants={{ openshift.common.service_type }}-master-api.service +After={{ openshift.common.service_type }}-master-api.service +After={{ openshift.docker.service_name }}.service +Requires={{ openshift.docker.service_name }}.service +PartOf={{ openshift.docker.service_name }}.service + +[Service] +EnvironmentFile=/etc/sysconfig/{{ openshift.common.service_type }}-master-controllers +Environment=GOTRACEBACK=crash +ExecStartPre=-/usr/bin/docker rm -f {{ openshift.common.service_type}}-master-controllers +ExecStart=/usr/bin/docker run --rm --privileged --net=host \ + --name {{ openshift.common.service_type }}-master-controllers \ + --env-file=/etc/sysconfig/{{ openshift.common.service_type }}-master-controllers \ + -v {{ r_openshift_master_data_dir }}:{{ r_openshift_master_data_dir }} \ + -v /var/run/docker.sock:/var/run/docker.sock \ + -v {{ openshift.common.config_base }}:{{ openshift.common.config_base }} \ + {% if openshift_cloudprovider_kind | default('') != '' -%} -v {{ openshift.common.config_base }}/cloudprovider:{{ openshift.common.config_base}}/cloudprovider {% endif -%} \ + -v /etc/pki:/etc/pki:ro \ + {% if l_bind_docker_reg_auth | default(False) %} -v {{ oreg_auth_credentials_path }}:/root/.docker:ro{% endif %}\ + {{ openshift.master.master_image }}:${IMAGE_VERSION} start master controllers \ + --config=${CONFIG_FILE} $OPTIONS +ExecStartPost=/usr/bin/sleep 10 +ExecStop=/usr/bin/docker stop {{ openshift.common.service_type }}-master-controllers +LimitNOFILE=131072 +LimitCORE=infinity +WorkingDirectory={{ r_openshift_master_data_dir }} +SyslogIdentifier={{ openshift.common.service_type }}-master-controllers +Restart=always +RestartSec=5s + +[Install] +WantedBy={{ openshift.docker.service_name }}.service diff --git a/roles/openshift_master/templates/htpasswd.j2 b/roles/openshift_master/templates/htpasswd.j2 new file mode 100644 index 000000000..ba2c02e20 --- /dev/null +++ b/roles/openshift_master/templates/htpasswd.j2 @@ -0,0 +1,5 @@ +{% if 'htpasswd_users' in openshift.master %} +{% for user,pass in openshift.master.htpasswd_users.iteritems() %} +{{ user ~ ':' ~ pass }} +{% endfor %} +{% endif %} diff --git a/roles/openshift_master/templates/master.yaml.v1.j2 b/roles/openshift_master/templates/master.yaml.v1.j2 new file mode 100644 index 000000000..7159ccc7f --- /dev/null +++ b/roles/openshift_master/templates/master.yaml.v1.j2 @@ -0,0 +1,279 @@ +admissionConfig: +{% if 'admission_plugin_config' in openshift.master %} + pluginConfig:{{ openshift.master.admission_plugin_config | to_padded_yaml(level=2) }} +{% endif %} +apiLevels: +{% if not openshift.common.version_gte_3_1_or_1_1 | bool %} +- v1beta3 +{% endif %} +- v1 +apiVersion: v1 +assetConfig: + logoutURL: "{{ openshift.master.logout_url | default('') }}" + masterPublicURL: {{ openshift.master.public_api_url }} + publicURL: {{ openshift.master.public_console_url }}/ +{% if 'logging_public_url' in openshift.master %} + loggingPublicURL: {{ openshift.master.logging_public_url }} +{% endif %} +{% if openshift_hosted_metrics_deploy_url is defined %} + metricsPublicURL: {{ openshift_hosted_metrics_deploy_url }} +{% endif %} +{% if 'extension_scripts' in openshift.master %} + extensionScripts: {{ openshift.master.extension_scripts | to_padded_yaml(1, 2) }} +{% endif %} +{% if 'extension_stylesheets' in openshift.master %} + extensionStylesheets: {{ openshift.master.extension_stylesheets | to_padded_yaml(1, 2) }} +{% endif %} +{% if 'extensions' in openshift.master %} + extensions: {{ openshift.master.extensions | to_padded_yaml(1, 2) }} +{% endif %} + servingInfo: + bindAddress: {{ openshift.master.bind_addr }}:{{ openshift.master.console_port }} + bindNetwork: tcp4 + certFile: master.server.crt + clientCA: "" + keyFile: master.server.key + maxRequestsInFlight: 0 + requestTimeoutSeconds: 0 +{% if openshift_master_min_tls_version is defined %} + minTLSVersion: {{ openshift_master_min_tls_version }} +{% endif %} +{% if openshift_master_cipher_suites is defined %} + cipherSuites: +{% for cipher_suite in openshift_master_cipher_suites %} + - {{ cipher_suite }} +{% endfor %} +{% endif %} +{% if openshift.master.audit_config | default(none) is not none and openshift.common.version_gte_3_2_or_1_2 | bool %} +auditConfig:{{ openshift.master.audit_config | to_padded_yaml(level=1) }} +{% endif %} +{% if openshift.common.version_gte_3_3_or_1_3 | bool %} +controllerConfig: + election: + lockName: openshift-master-controllers + serviceServingCert: + signer: + certFile: service-signer.crt + keyFile: service-signer.key +{% endif %} +controllers: '*' +corsAllowedOrigins: +{% for origin in ['127.0.0.1', 'localhost', openshift.common.ip, openshift.common.public_ip] | union(openshift.common.all_hostnames) | unique %} + - {{ origin }} +{% endfor %} +{% for custom_origin in openshift.master.custom_cors_origins | default("") %} + - {{ custom_origin }} +{% endfor %} +{% if 'disabled_features' in openshift.master %} +disabledFeatures: {{ openshift.master.disabled_features | to_json }} +{% endif %} +{% if openshift.master.embedded_dns | bool %} +dnsConfig: + bindAddress: {{ openshift.master.bind_addr }}:{{ openshift.master.dns_port }} + bindNetwork: tcp4 +{% endif %} +etcdClientInfo: +{% if openshift.common.version_gte_3_2_or_1_2 | bool %} + ca: {{ "ca-bundle.crt" if (openshift.master.embedded_etcd | bool) else "master.etcd-ca.crt" }} +{% else %} + ca: {{ "ca.crt" if (openshift.master.embedded_etcd | bool) else "master.etcd-ca.crt" }} +{% endif %} + certFile: master.etcd-client.crt + keyFile: master.etcd-client.key + urls: +{% for etcd_url in openshift.master.etcd_urls %} + - {{ etcd_url }} +{% endfor %} +{% if openshift.master.embedded_etcd | bool %} +etcdConfig: + address: {{ openshift.common.hostname }}:{{ openshift.master.etcd_port }} + peerAddress: {{ openshift.common.hostname }}:7001 + peerServingInfo: + bindAddress: {{ openshift.master.bind_addr }}:7001 + certFile: etcd.server.crt +{% if openshift.common.version_gte_3_2_or_1_2 | bool %} + clientCA: ca-bundle.crt +{% else %} + clientCA: ca.crt +{% endif %} + keyFile: etcd.server.key + servingInfo: + bindAddress: {{ openshift.master.bind_addr }}:{{ openshift.master.etcd_port }} + certFile: etcd.server.crt +{% if openshift.common.version_gte_3_2_or_1_2 | bool %} + clientCA: ca-bundle.crt +{% else %} + clientCA: ca.crt +{% endif %} + keyFile: etcd.server.key + storageDirectory: {{ r_openshift_master_data_dir }}/openshift.local.etcd +{% endif %} +etcdStorageConfig: + kubernetesStoragePrefix: kubernetes.io + kubernetesStorageVersion: v1 + openShiftStoragePrefix: openshift.io + openShiftStorageVersion: v1 +imageConfig: + format: {{ openshift.master.registry_url }} + latest: {{ openshift_master_image_config_latest }} +{% if 'image_policy_config' in openshift.master %} +imagePolicyConfig:{{ openshift.master.image_policy_config | to_padded_yaml(level=1) }} +{% endif %} +kind: MasterConfig +kubeletClientInfo: +{# TODO: allow user specified kubelet port #} +{% if openshift.common.version_gte_3_2_or_1_2 | bool %} + ca: ca-bundle.crt +{% else %} + ca: ca.crt +{% endif %} + certFile: master.kubelet-client.crt + keyFile: master.kubelet-client.key + port: 10250 +{% if openshift.master.embedded_kube | bool %} +kubernetesMasterConfig: +{% if not openshift.common.version_gte_3_1_or_1_1 | bool %} + apiLevels: + - v1beta3 + - v1 +{% endif %} + apiServerArguments: {{ openshift.master.api_server_args | default(None) | to_padded_yaml( level=2 ) }} +{% if r_openshift_master_etcd3_storage or ( r_openshift_master_clean_install and openshift.common.version_gte_3_6 ) %} + storage-backend: + - etcd3 + storage-media-type: + - application/vnd.kubernetes.protobuf +{% endif %} + controllerArguments: {{ openshift.master.controller_args | default(None) | to_padded_yaml( level=2 ) }} + masterCount: {{ openshift.master.master_count if openshift.master.cluster_method | default(None) == 'native' else 1 }} + masterIP: {{ openshift.common.ip }} + podEvictionTimeout: {{ openshift.master.pod_eviction_timeout | default("") }} + proxyClientInfo: + certFile: master.proxy-client.crt + keyFile: master.proxy-client.key + schedulerArguments: {{ openshift_master_scheduler_args | default(None) | to_padded_yaml( level=3 ) }} + schedulerConfigFile: {{ openshift_master_scheduler_conf }} + servicesNodePortRange: "{{ openshift_node_port_range | default("") }}" + servicesSubnet: {{ openshift.common.portal_net }} + staticNodeNames: {{ openshift_node_ips | default([], true) }} +{% endif %} +masterClients: +{# TODO: allow user to set externalKubernetesKubeConfig #} +{% if openshift.common.version_gte_3_3_or_1_3 | bool %} + externalKubernetesClientConnectionOverrides: + acceptContentTypes: application/vnd.kubernetes.protobuf,application/json + contentType: application/vnd.kubernetes.protobuf + burst: {{ openshift_master_external_ratelimit_burst | default(400) }} + qps: {{ openshift_master_external_ratelimit_qps | default(200) }} +{% endif %} + externalKubernetesKubeConfig: "" +{% if openshift.common.version_gte_3_3_or_1_3 | bool %} + openshiftLoopbackClientConnectionOverrides: + acceptContentTypes: application/vnd.kubernetes.protobuf,application/json + contentType: application/vnd.kubernetes.protobuf + burst: {{ openshift_master_loopback_ratelimit_burst | default(600) }} + qps: {{ openshift_master_loopback_ratelimit_qps | default(300) }} +{% endif %} + openshiftLoopbackKubeConfig: openshift-master.kubeconfig +masterPublicURL: {{ openshift.master.public_api_url }} +networkConfig: + clusterNetworkCIDR: {{ openshift.master.sdn_cluster_network_cidr }} + hostSubnetLength: {{ openshift.master.sdn_host_subnet_length }} +{% if r_openshift_master_use_openshift_sdn or r_openshift_master_use_nuage or r_openshift_master_use_contiv or r_openshift_master_sdn_network_plugin_name == 'cni' %} + networkPluginName: {{ r_openshift_master_sdn_network_plugin_name_default }} +{% endif %} +# serviceNetworkCIDR must match kubernetesMasterConfig.servicesSubnet + serviceNetworkCIDR: {{ openshift.common.portal_net }} + externalIPNetworkCIDRs: {{ openshift_master_external_ip_network_cidrs | default(["0.0.0.0/0"]) | to_padded_yaml(1,2) }} +{% if openshift_master_ingress_ip_network_cidr is defined %} + ingressIPNetworkCIDR: {{ openshift_master_ingress_ip_network_cidr }} +{% endif %} +oauthConfig: +{% if 'oauth_always_show_provider_selection' in openshift.master %} + alwaysShowProviderSelection: {{ openshift.master.oauth_always_show_provider_selection }} +{% endif %} +{% if 'oauth_templates' in openshift.master %} + templates:{{ openshift.master.oauth_templates | to_padded_yaml(level=2) }} +{% endif %} + assetPublicURL: {{ openshift.master.public_console_url }}/ + grantConfig: + method: {{ openshift.master.oauth_grant_method }} + identityProviders: +{% for line in translated_identity_providers.splitlines() %} + {{ line }} +{% endfor %} +{% if openshift.common.version_gte_3_2_or_1_2 | bool %} + masterCA: ca-bundle.crt +{% else %} + masterCA: ca.crt +{% endif %} + masterPublicURL: {{ openshift.master.public_api_url }} + masterURL: {{ openshift.master.api_url }} + sessionConfig: + sessionMaxAgeSeconds: {{ openshift.master.session_max_seconds }} + sessionName: {{ openshift.master.session_name }} +{% if openshift.master.session_auth_secrets is defined and openshift.master.session_encryption_secrets is defined %} + sessionSecretsFile: {{ openshift.master.session_secrets_file }} +{% endif %} + tokenConfig: + accessTokenMaxAgeSeconds: {{ openshift.master.access_token_max_seconds }} + authorizeTokenMaxAgeSeconds: {{ openshift.master.auth_token_max_seconds }} +pauseControllers: false +policyConfig: + bootstrapPolicyFile: {{ openshift_master_policy }} + openshiftInfrastructureNamespace: openshift-infra + openshiftSharedResourcesNamespace: openshift +projectConfig: + defaultNodeSelector: "{{ openshift.master.default_node_selector }}" + projectRequestMessage: "{{ openshift.master.project_request_message }}" + projectRequestTemplate: "{{ openshift.master.project_request_template }}" + securityAllocator: + mcsAllocatorRange: "{{ openshift.master.mcs_allocator_range }}" + mcsLabelsPerProject: {{ openshift.master.mcs_labels_per_project }} + uidAllocatorRange: "{{ openshift.master.uid_allocator_range }}" +routingConfig: + subdomain: "{{ openshift_master_default_subdomain | default("") }}" +serviceAccountConfig: + limitSecretReferences: {{ openshift_master_saconfig_limitsecretreferences | default(false) }} + managedNames: + - default + - builder + - deployer +{% if openshift.common.version_gte_3_2_or_1_2 | bool %} + masterCA: ca-bundle.crt +{% else %} + masterCA: ca.crt +{% endif %} + privateKeyFile: serviceaccounts.private.key + publicKeyFiles: + - serviceaccounts.public.key +servingInfo: + bindAddress: {{ openshift.master.bind_addr }}:{{ openshift.master.api_port }} + bindNetwork: tcp4 + certFile: master.server.crt + clientCA: ca.crt + keyFile: master.server.key + maxRequestsInFlight: {{ openshift.master.max_requests_inflight }} + requestTimeoutSeconds: 3600 +{% if openshift.master.named_certificates | default([]) | length > 0 %} + namedCertificates: +{% for named_certificate in openshift.master.named_certificates %} + - certFile: {{ named_certificate['certfile'] }} + keyFile: {{ named_certificate['keyfile'] }} + names: +{% for name in named_certificate['names'] %} + - "{{ name }}" +{% endfor %} +{% endfor %} +{% endif %} +{% if openshift_master_min_tls_version is defined %} + minTLSVersion: {{ openshift_master_min_tls_version }} +{% endif %} +{% if openshift_master_cipher_suites is defined %} + cipherSuites: +{% for cipher_suite in openshift_master_cipher_suites %} + - {{ cipher_suite }} +{% endfor %} +{% endif %} +volumeConfig: + dynamicProvisioningEnabled: {{ openshift.master.dynamic_provisioning_enabled }} diff --git a/roles/openshift_master/templates/native-cluster/atomic-openshift-master-api.j2 b/roles/openshift_master/templates/native-cluster/atomic-openshift-master-api.j2 new file mode 100644 index 000000000..cc21b37af --- /dev/null +++ b/roles/openshift_master/templates/native-cluster/atomic-openshift-master-api.j2 @@ -0,0 +1,34 @@ +OPTIONS=--loglevel={{ openshift_master_debug_level }} --listen={{ 'https' if openshift.master.api_use_ssl else 'http' }}://{{ openshift.master.bind_addr }}:{{ openshift.master.api_port }} --master={{ openshift.master.loopback_api_url }} +CONFIG_FILE={{ openshift_master_config_file }} +{# Preserve existing OPENSHIFT_DEFAULT_REGISTRY settings in scale up runs #} +{% if openshift_master_is_scaleup_host %} +{{ openshift_master_default_registry_value_api }} +{% elif openshift_push_via_dns | default(false) %} +OPENSHIFT_DEFAULT_REGISTRY=docker-registry.default.svc:5000 +{% endif %} +{% if openshift.common.is_containerized | bool %} +IMAGE_VERSION={{ openshift_image_tag }} +{% endif %} + +{% if openshift_cloudprovider_kind | default('') == 'aws' and openshift_cloudprovider_aws_access_key is defined and openshift_cloudprovider_aws_secret_key is defined %} +AWS_ACCESS_KEY_ID={{ openshift_cloudprovider_aws_access_key }} +AWS_SECRET_ACCESS_KEY={{ openshift_cloudprovider_aws_secret_key }} +{% endif %} + +{% if 'api_env_vars' in openshift.master -%} +{% for key, value in openshift.master.api_env_vars.items() -%} +{{ key }}={{ value }} +{% endfor -%} +{% endif -%} + +# Proxy configuration +# See https://docs.openshift.com/enterprise/latest/install_config/install/advanced_install.html#configuring-global-proxy +{% if 'http_proxy' in openshift.common %} +HTTP_PROXY={{ openshift.common.http_proxy | default('') }} +{% endif %} +{% if 'https_proxy' in openshift.common %} +HTTPS_PROXY={{ openshift.common.https_proxy | default('')}} +{% endif %} +{% if 'no_proxy' in openshift.common %} +NO_PROXY={{ openshift.common.no_proxy | default('') }},{{ openshift.common.portal_net }},{{ openshift.master.sdn_cluster_network_cidr }} +{% endif %} diff --git a/roles/openshift_master/templates/native-cluster/atomic-openshift-master-api.service.j2 b/roles/openshift_master/templates/native-cluster/atomic-openshift-master-api.service.j2 new file mode 100644 index 000000000..02bfd6f62 --- /dev/null +++ b/roles/openshift_master/templates/native-cluster/atomic-openshift-master-api.service.j2 @@ -0,0 +1,23 @@ +[Unit] +Description=Atomic OpenShift Master API +Documentation=https://github.com/openshift/origin +After=network-online.target +After=etcd.service +Before={{ openshift.common.service_type }}-node.service +Requires=network-online.target + +[Service] +Type=notify +EnvironmentFile=/etc/sysconfig/{{ openshift.common.service_type }}-master-api +Environment=GOTRACEBACK=crash +ExecStart=/usr/bin/openshift start master api --config=${CONFIG_FILE} $OPTIONS +LimitNOFILE=131072 +LimitCORE=infinity +WorkingDirectory={{ r_openshift_master_data_dir }} +SyslogIdentifier=atomic-openshift-master-api +Restart=always +RestartSec=5s + +[Install] +WantedBy=multi-user.target +WantedBy={{ openshift.common.service_type }}-node.service diff --git a/roles/openshift_master/templates/native-cluster/atomic-openshift-master-controllers.j2 b/roles/openshift_master/templates/native-cluster/atomic-openshift-master-controllers.j2 new file mode 100644 index 000000000..493fc510e --- /dev/null +++ b/roles/openshift_master/templates/native-cluster/atomic-openshift-master-controllers.j2 @@ -0,0 +1,34 @@ +OPTIONS=--loglevel={{ openshift_master_debug_level }} --listen={{ 'https' if openshift.master.api_use_ssl else 'http' }}://{{ openshift.master.bind_addr }}:{{ openshift.master.controllers_port }} +CONFIG_FILE={{ openshift_master_config_file }} +{# Preserve existing OPENSHIFT_DEFAULT_REGISTRY settings in scale up runs #} +{% if openshift_master_is_scaleup_host %} +{{ openshift_master_default_registry_value_controllers }} +{% elif openshift_push_via_dns | default(false) %} +OPENSHIFT_DEFAULT_REGISTRY=docker-registry.default.svc:5000 +{% endif %} +{% if openshift.common.is_containerized | bool %} +IMAGE_VERSION={{ openshift_image_tag }} +{% endif %} + +{% if openshift_cloudprovider_kind | default('') == 'aws' and openshift_cloudprovider_aws_access_key is defined and openshift_cloudprovider_aws_secret_key is defined %} +AWS_ACCESS_KEY_ID={{ openshift_cloudprovider_aws_access_key }} +AWS_SECRET_ACCESS_KEY={{ openshift_cloudprovider_aws_secret_key }} +{% endif %} + +{% if 'controllers_env_vars' in openshift.master -%} +{% for key, value in openshift.master.controllers_env_vars.items() -%} +{{ key }}={{ value }} +{% endfor -%} +{% endif -%} + +# Proxy configuration +# See https://docs.openshift.com/enterprise/latest/install_config/install/advanced_install.html#configuring-global-proxy +{% if 'http_proxy' in openshift.common %} +HTTP_PROXY={{ openshift.common.http_proxy | default('') }} +{% endif %} +{% if 'https_proxy' in openshift.common %} +HTTPS_PROXY={{ openshift.common.https_proxy | default('')}} +{% endif %} +{% if 'no_proxy' in openshift.common %} +NO_PROXY={{ openshift.common.no_proxy | default('') }},{{ openshift.common.portal_net }},{{ openshift.master.sdn_cluster_network_cidr }} +{% endif %} diff --git a/roles/openshift_master/templates/native-cluster/atomic-openshift-master-controllers.service.j2 b/roles/openshift_master/templates/native-cluster/atomic-openshift-master-controllers.service.j2 new file mode 100644 index 000000000..e284413f7 --- /dev/null +++ b/roles/openshift_master/templates/native-cluster/atomic-openshift-master-controllers.service.j2 @@ -0,0 +1,26 @@ +[Unit] +Description=Atomic OpenShift Master Controllers +Documentation=https://github.com/openshift/origin +After=network-online.target +After={{ openshift.common.service_type }}-master-api.service +Wants={{ openshift.common.service_type }}-master-api.service +Requires=network-online.target + +[Service] +{% if openshift.common.version_gte_3_1_1_or_1_1_1 | bool %} +Type=notify +{% else %} +Type=simple +{% endif %} +EnvironmentFile=/etc/sysconfig/{{ openshift.common.service_type }}-master-controllers +Environment=GOTRACEBACK=crash +ExecStart=/usr/bin/openshift start master controllers --config=${CONFIG_FILE} $OPTIONS +LimitNOFILE=131072 +LimitCORE=infinity +WorkingDirectory={{ r_openshift_master_data_dir }} +SyslogIdentifier={{ openshift.common.service_type }}-master-controllers +Restart=always +RestartSec=5s + +[Install] +WantedBy=multi-user.target diff --git a/roles/openshift_master/templates/sessionSecretsFile.yaml.v1.j2 b/roles/openshift_master/templates/sessionSecretsFile.yaml.v1.j2 new file mode 100644 index 000000000..3d4b573a9 --- /dev/null +++ b/roles/openshift_master/templates/sessionSecretsFile.yaml.v1.j2 @@ -0,0 +1,7 @@ +apiVersion: v1 +kind: SessionSecrets +secrets: +{% for secret in openshift.master.session_auth_secrets %} +- authentication: "{{ openshift.master.session_auth_secrets[loop.index0] }}" + encryption: "{{ openshift.master.session_encryption_secrets[loop.index0] }}" +{% endfor %} diff --git a/roles/openshift_master/vars/main.yml b/roles/openshift_master/vars/main.yml new file mode 100644 index 000000000..0c681c764 --- /dev/null +++ b/roles/openshift_master/vars/main.yml @@ -0,0 +1,41 @@ +--- +openshift_master_loopback_config: "{{ openshift_master_config_dir }}/openshift-master.kubeconfig" +loopback_context_string: "current-context: {{ openshift.master.loopback_context_name }}" +openshift_master_session_secrets_file: "{{ openshift_master_config_dir }}/session-secrets.yaml" +openshift_master_policy: "{{ openshift_master_config_dir }}/policy.json" + +scheduler_config: + kind: Policy + apiVersion: v1 + predicates: "{{ openshift_master_scheduler_predicates + | default(openshift_master_scheduler_current_predicates + | default(openshift_master_scheduler_default_predicates)) }}" + priorities: "{{ openshift_master_scheduler_priorities + | default(openshift_master_scheduler_current_priorities + | default(openshift_master_scheduler_default_priorities)) }}" + +openshift_master_valid_grant_methods: +- auto +- prompt +- deny + +openshift_master_is_scaleup_host: False + +# These defaults assume forcing journald persistence, fsync to disk once +# a second, rate-limiting to 10,000 logs a second, no forwarding to +# syslog or wall, using 8GB of disk space maximum, using 10MB journal +# files, keeping only a days worth of logs per journal file, and +# retaining journal files no longer than a month. +journald_vars_to_replace: +- { var: Storage, val: persistent } +- { var: Compress, val: yes } +- { var: SyncIntervalSec, val: 1s } +- { var: RateLimitInterval, val: 1s } +- { var: RateLimitBurst, val: 10000 } +- { var: SystemMaxUse, val: 8G } +- { var: SystemKeepFree, val: 20% } +- { var: SystemMaxFileSize, val: 10M } +- { var: MaxRetentionSec, val: 1month } +- { var: MaxFileSec, val: 1day } +- { var: ForwardToSyslog, val: no } +- { var: ForwardToWall, val: no } |