summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--playbooks/provisioning/openstack/README.md41
-rw-r--r--playbooks/provisioning/openstack/sample-inventory/group_vars/all.yml34
-rw-r--r--playbooks/provisioning/openstack/stack_params.yaml26
-rw-r--r--roles/openstack-stack/defaults/main.yml1
-rw-r--r--roles/openstack-stack/templates/heat_stack.yaml.j250
-rw-r--r--roles/openstack-stack/templates/heat_stack_server.yaml.j21
-rw-r--r--roles/openstack-stack/templates/heat_stack_server_nofloating.yaml.j21
-rw-r--r--roles/static_inventory/defaults/main.yml8
-rw-r--r--roles/static_inventory/tasks/main.yml7
-rw-r--r--roles/static_inventory/tasks/openstack.yml20
-rw-r--r--roles/static_inventory/tasks/sshtun.yml15
-rw-r--r--roles/static_inventory/templates/ssh-tunnel.service.j220
12 files changed, 187 insertions, 37 deletions
diff --git a/playbooks/provisioning/openstack/README.md b/playbooks/provisioning/openstack/README.md
index c7b2ea975..afaeb430b 100644
--- a/playbooks/provisioning/openstack/README.md
+++ b/playbooks/provisioning/openstack/README.md
@@ -78,6 +78,10 @@ your servers will be under. With the default values, this will be
That sudomain can be set as well by the `openshift_app_domain` variable in
the inventory.
+The `openstack_<role name>_hostname` is a set of variables used for customising
+hostnames of servers with a given role. When such a variable stays commented,
+default hostname (usually the role name) is used.
+
The `public_dns_nameservers` is a list of DNS servers accessible from all
the created Nova servers. These will be serving as your DNS forwarders for
external FQDNs that do not belong to the cluster's DNS domain and its subdomains.
@@ -98,18 +102,29 @@ as a default nameserver that comes from the NetworkManager and cloud-init.
`openstack keypair list`. This guide assumes that its corresponding private
key is `~/.ssh/openshift`, stored on the ansible admin (control) node.
-`openstack_default_image_name` is the name of the Glance image the
-servers will use. You can
-see your images with `openstack image list`.
+`openstack_default_image_name` is the default name of the Glance image the
+servers will use. You can see your images with `openstack image list`.
+In order to set a different image for a role, uncomment the line with the
+corresponding variable (e.g. `openstack_lb_image_name` for load balancer) and
+set its value to another available image name. `openstack_default_image_name`
+must stay defined as it is used as a default value for the rest of the roles.
-`openstack_default_flavor` is the Nova flavor the servers will use.
+`openstack_default_flavor` is the default Nova flavor the servers will use.
You can see your flavors with `openstack flavor list`.
+In order to set a different flavor for a role, uncomment the line with the
+corresponding variable (e.g. `openstack_lb_flavor` for load balancer) and
+set its value to another available flavor. `openstack_default_flavor` must
+stay defined as it is used as a default value for the rest of the roles.
`openstack_external_network_name` is the name of the Neutron network
providing external connectivity. It is often called `public`,
`external` or `ext-net`. You can see your networks with `openstack
network list`.
+`openstack_private_network_name` is the name of the private Neutron network
+providing admin/control access for ansible. It can be merged with other
+cluster networks, there are no special requirements for networking.
+
The `openstack_num_masters`, `openstack_num_infra` and
`openstack_num_nodes` values specify the number of Master, Infra and
App nodes to create.
@@ -240,6 +255,24 @@ Once it succeeds, you can install openshift by running:
ansible-playbook openshift-ansible/playbooks/byo/config.yml
+### Access UI
+
+OpenShift UI may be accessed via the 1st master node FQDN, port 8443.
+
+When using a bastion, you may want to make an SSH tunnel from your control node
+to access UI on the `https://localhost:8443`, with this inventory variable:
+
+ openshift_ui_ssh_tunnel: True
+
+Note, this requires sudo rights on the ansible control node and an absolute path
+for the `openstack_private_ssh_key`. You should also update the control node's
+`/etc/hosts`:
+
+ 127.0.0.1 master-0.openshift.example.com
+
+In order to access UI, the ssh-tunnel service will be created and started on the
+control node. Make sure to remove these changes and the service manually, when not
+needed anymore.
## License
diff --git a/playbooks/provisioning/openstack/sample-inventory/group_vars/all.yml b/playbooks/provisioning/openstack/sample-inventory/group_vars/all.yml
index 8f337546c..19f916508 100644
--- a/playbooks/provisioning/openstack/sample-inventory/group_vars/all.yml
+++ b/playbooks/provisioning/openstack/sample-inventory/group_vars/all.yml
@@ -3,15 +3,45 @@ env_id: "openshift"
public_dns_domain: "example.com"
public_dns_nameservers: []
+# # Used Hostnames
+# # - set custom hostnames for roles by uncommenting corresponding lines
+#openstack_master_hostname: "master"
+#openstack_infra_hostname: "infra-node"
+#openstack_node_hostname: "app-node"
+#openstack_lb_hostname: "lb"
+#openstack_etcd_hostname: "etcd"
+#openstack_dns_hostname: "dns"
+
openstack_ssh_public_key: "openshift"
-openstack_default_image_name: "centos7"
-openstack_default_flavor: "m1.medium"
openstack_external_network_name: "public"
+#openstack_private_network_name: "openshift-ansible-{{ stack_name }}-net"
+
+# # Used Images
+# # - set specific images for roles by uncommenting corresponding lines
+# # - note: do not remove openstack_default_image_name definition
+#openstack_master_image_name: "centos7"
+#openstack_infra_image_name: "centos7"
+#openstack_node_image_name: "centos7"
+#openstack_lb_image_name: "centos7"
+#openstack_etcd_image_name: "centos7"
+#openstack_dns_image_name: "centos7"
+openstack_default_image_name: "centos7"
openstack_num_masters: 1
openstack_num_infra: 1
openstack_num_nodes: 2
+# # Used Flavors
+# # - set specific flavors for roles by uncommenting corresponding lines
+# # - note: do note remove openstack_default_flavor definition
+#openstack_master_flavor: "m1.medium"
+#openstack_infra_flavor: "m1.medium"
+#openstack_node_flavor: "m1.medium"
+#openstack_lb_flavor: "m1.medium"
+#openstack_etcd_flavor: "m1.medium"
+#openstack_dns_flavor: "m1.medium"
+openstack_default_flavor: "m1.medium"
+
# # Numerical index of nodes to remove
# openstack_nodes_to_remove: []
diff --git a/playbooks/provisioning/openstack/stack_params.yaml b/playbooks/provisioning/openstack/stack_params.yaml
index c3a42ab06..27fa5ec8c 100644
--- a/playbooks/provisioning/openstack/stack_params.yaml
+++ b/playbooks/provisioning/openstack/stack_params.yaml
@@ -3,14 +3,27 @@ stack_name: "{{ env_id }}.{{ public_dns_domain }}"
dns_domain: "{{ public_dns_domain }}"
dns_nameservers: "{{ public_dns_nameservers }}"
subnet_prefix: "{{ openstack_subnet_prefix }}"
+master_hostname: "{{ openstack_master_hostname | default('master') }}"
+infra_hostname: "{{ openstack_infra_hostname | default('infra-node') }}"
+node_hostname: "{{ openstack_node_hostname | default('app-node') }}"
+lb_hostname: "{{ openstack_lb_hostname | default('lb') }}"
+etcd_hostname: "{{ openstack_etcd_hostname | default('etcd') }}"
+dns_hostname: "{{ openstack_dns_hostname | default('dns') }}"
ssh_public_key: "{{ openstack_ssh_public_key }}"
openstack_image: "{{ openstack_default_image_name }}"
-lb_flavor: "{{ openstack_default_flavor | default('m1.small') }}"
-etcd_flavor: "{{ openstack_default_flavor | default('m1.small') }}"
-master_flavor: "{{ openstack_default_flavor | default('m1.medium') }}"
-node_flavor: "{{ openstack_default_flavor | default('m1.medium') }}"
-infra_flavor: "{{ openstack_default_flavor | default('m1.medium') }}"
-dns_flavor: "{{ openstack_default_flavor | default('m1.small') }}"
+lb_flavor: "{{ openstack_lb_flavor | default(openstack_default_flavor) }}"
+etcd_flavor: "{{ openstack_etcd_flavor | default(openstack_default_flavor) }}"
+master_flavor: "{{ openstack_master_flavor | default(openstack_default_flavor) }}"
+node_flavor: "{{ openstack_node_flavor | default(openstack_default_flavor) }}"
+infra_flavor: "{{ openstack_infra_flavor | default(openstack_default_flavor) }}"
+dns_flavor: "{{ openstack_dns_flavor | default(openstack_default_flavor) }}"
+openstack_master_image: "{{ openstack_master_image_name | default(openstack_default_image_name) }}"
+openstack_infra_image: "{{ openstack_infra_image_name | default(openstack_default_image_name) }}"
+openstack_node_image: "{{ openstack_node_image_name | default(openstack_default_image_name) }}"
+openstack_lb_image: "{{ openstack_lb_image_name | default(openstack_default_image_name) }}"
+openstack_etcd_image: "{{ openstack_etcd_image_name | default(openstack_default_image_name) }}"
+openstack_dns_image: "{{ openstack_dns_image_name | default(openstack_default_image_name) }}"
+openstack_private_network: "{{ openstack_private_network_name | default ('openshift-ansible-' + stack_name + '-net') }}"
external_network: "{{ openstack_external_network_name }}"
num_etcd: "{{ openstack_num_etcd | default(0) }}"
num_masters: "{{ openstack_num_masters }}"
@@ -22,3 +35,4 @@ app_volume_size: "{{ docker_volume_size }}"
infra_volume_size: "{{ docker_volume_size }}"
nodes_to_remove: "{{ openstack_nodes_to_remove | default([]) | to_yaml }}"
use_bastion: "{{ openstack_use_bastion|default(False) }}"
+ui_ssh_tunnel: "{{ openshift_ui_ssh_tunnel|default(False) }}"
diff --git a/roles/openstack-stack/defaults/main.yml b/roles/openstack-stack/defaults/main.yml
index 803a96389..c8529612e 100644
--- a/roles/openstack-stack/defaults/main.yml
+++ b/roles/openstack-stack/defaults/main.yml
@@ -13,3 +13,4 @@ num_infra: 1
nodes_to_remove: []
etcd_volume_size: 2
use_bastion: False
+ui_ssh_tunnel: False
diff --git a/roles/openstack-stack/templates/heat_stack.yaml.j2 b/roles/openstack-stack/templates/heat_stack.yaml.j2
index 524f466ff..3623035c6 100644
--- a/roles/openstack-stack/templates/heat_stack.yaml.j2
+++ b/roles/openstack-stack/templates/heat_stack.yaml.j2
@@ -439,7 +439,7 @@ resources:
port_range_min: 53
port_range_max: 53
remote_ip_prefix: "{{ openstack_subnet_prefix }}.0/24"
-{% if num_masters > 1 %}
+{% if num_masters > 1 or ui_ssh_tunnel|bool %}
lb-secgrp:
type: OS::Neutron::SecurityGroup
properties:
@@ -450,14 +450,21 @@ resources:
protocol: tcp
port_range_min: {{ openshift_master_api_port | default(8443) }}
port_range_max: {{ openshift_master_api_port | default(8443) }}
- remote_ip_prefix: {{ lb_ingress_cidr }}
- {% if openshift_master_console_port is defined and openshift_master_console_port != openshift_master_api_port %}
+ remote_ip_prefix: {{ lb_ingress_cidr | default(bastion_ingress_cidr) }}
+{% if ui_ssh_tunnel|bool %}
+ - direction: ingress
+ protocol: tcp
+ port_range_min: {{ openshift_master_api_port | default(8443) }}
+ port_range_max: {{ openshift_master_api_port | default(8443) }}
+ remote_ip_prefix: {{ ssh_ingress_cidr }}
+{% endif %}
+{% if openshift_master_console_port is defined and openshift_master_console_port != openshift_master_api_port %}
- direction: ingress
protocol: tcp
port_range_min: {{ openshift_master_console_port | default(8443) }}
port_range_max: {{ openshift_master_console_port | default(8443) }}
- remote_ip_prefix: {{ lb_ingress_cidr }}
- {% endif %}
+ remote_ip_prefix: {{ lb_ingress_cidr | default(bastion_ingress_cidr) }}
+{% endif %}
{% endif %}
etcd:
@@ -476,7 +483,7 @@ resources:
template: k8s_type-%index%.cluster_id
params:
cluster_id: {{ stack_name }}
- k8s_type: etcd
+ k8s_type: {{ etcd_hostname }}
cluster_env: {{ public_dns_domain }}
cluster_id: {{ stack_name }}
group:
@@ -486,7 +493,7 @@ resources:
k8s_type: etcds
cluster_id: {{ stack_name }}
type: etcd
- image: {{ openstack_image }}
+ image: {{ openstack_etcd_image }}
flavor: {{ etcd_flavor }}
key_name: {{ ssh_public_key }}
net: { get_resource: net }
@@ -519,7 +526,7 @@ resources:
template: k8s_type-%index%.cluster_id
params:
cluster_id: {{ stack_name }}
- k8s_type: lb
+ k8s_type: {{ lb_hostname }}
cluster_env: {{ public_dns_domain }}
cluster_id: {{ stack_name }}
group:
@@ -529,7 +536,7 @@ resources:
k8s_type: lb
cluster_id: {{ stack_name }}
type: lb
- image: {{ openstack_image }}
+ image: {{ openstack_lb_image }}
flavor: {{ lb_flavor }}
key_name: {{ ssh_public_key }}
net: { get_resource: net }
@@ -564,7 +571,7 @@ resources:
template: k8s_type-%index%.cluster_id
params:
cluster_id: {{ stack_name }}
- k8s_type: master
+ k8s_type: {{ master_hostname }}
cluster_env: {{ public_dns_domain }}
cluster_id: {{ stack_name }}
group:
@@ -574,7 +581,7 @@ resources:
k8s_type: masters
cluster_id: {{ stack_name }}
type: master
- image: {{ openstack_image }}
+ image: {{ openstack_master_image }}
flavor: {{ master_flavor }}
key_name: {{ ssh_public_key }}
net: { get_resource: net }
@@ -617,11 +624,10 @@ resources:
properties:
name:
str_replace:
- template: subtype-k8s_type-%index%.cluster_id
+ template: sub_type_k8s_type-%index%.cluster_id
params:
cluster_id: {{ stack_name }}
- k8s_type: node
- subtype: app
+ sub_type_k8s_type: {{ node_hostname }}
cluster_env: {{ public_dns_domain }}
cluster_id: {{ stack_name }}
group:
@@ -636,7 +642,7 @@ resources:
{% for k, v in openshift_cluster_node_labels.app.iteritems() %}
{{ k|e }}: {{ v|e }}
{% endfor %}
- image: {{ openstack_image }}
+ image: {{ openstack_node_image }}
flavor: {{ node_flavor }}
key_name: {{ ssh_public_key }}
net: { get_resource: net }
@@ -665,11 +671,10 @@ resources:
properties:
name:
str_replace:
- template: subtypek8s_type-%index%.cluster_id
+ template: sub_type_k8s_type-%index%.cluster_id
params:
cluster_id: {{ stack_name }}
- k8s_type: node
- subtype: infra
+ sub_type_k8s_type: {{ infra_hostname }}
cluster_env: {{ public_dns_domain }}
cluster_id: {{ stack_name }}
group:
@@ -684,7 +689,7 @@ resources:
{% for k, v in openshift_cluster_node_labels.infra.iteritems() %}
{{ k|e }}: {{ v|e }}
{% endfor %}
- image: {{ openstack_image }}
+ image: {{ openstack_infra_image }}
flavor: {{ infra_flavor }}
key_name: {{ ssh_public_key }}
net: { get_resource: net }
@@ -696,6 +701,9 @@ resources:
{% else %}
- { get_resource: node-secgrp }
{% endif %}
+{% if ui_ssh_tunnel|bool and num_masters < 2 %}
+ - { get_resource: lb-secgrp }
+{% endif %}
- { get_resource: infra-secgrp }
- { get_resource: common-secgrp }
floating_network: {{ external_network }}
@@ -720,7 +728,7 @@ resources:
template: k8s_type-%index%.cluster_id
params:
cluster_id: {{ stack_name }}
- k8s_type: dns
+ k8s_type: {{ dns_hostname }}
cluster_env: {{ public_dns_domain }}
cluster_id: {{ stack_name }}
group:
@@ -730,7 +738,7 @@ resources:
k8s_type: dns
cluster_id: {{ stack_name }}
type: dns
- image: {{ openstack_image }}
+ image: {{ openstack_dns_image }}
flavor: {{ dns_flavor }}
key_name: {{ ssh_public_key }}
net: { get_resource: net }
diff --git a/roles/openstack-stack/templates/heat_stack_server.yaml.j2 b/roles/openstack-stack/templates/heat_stack_server.yaml.j2
index 85af311ec..32fb166f6 100644
--- a/roles/openstack-stack/templates/heat_stack_server.yaml.j2
+++ b/roles/openstack-stack/templates/heat_stack_server.yaml.j2
@@ -134,6 +134,7 @@ resources:
user_data:
get_file: user-data
user_data_format: RAW
+ user_data_update_policy: IGNORE
metadata:
group: { get_param: group }
environment: { get_param: cluster_env }
diff --git a/roles/openstack-stack/templates/heat_stack_server_nofloating.yaml.j2 b/roles/openstack-stack/templates/heat_stack_server_nofloating.yaml.j2
index a22b7c6d0..638fc8b45 100644
--- a/roles/openstack-stack/templates/heat_stack_server_nofloating.yaml.j2
+++ b/roles/openstack-stack/templates/heat_stack_server_nofloating.yaml.j2
@@ -119,6 +119,7 @@ resources:
user_data:
get_file: user-data
user_data_format: RAW
+ user_data_update_policy: IGNORE
metadata:
group: { get_param: group }
environment: { get_param: cluster_env }
diff --git a/roles/static_inventory/defaults/main.yml b/roles/static_inventory/defaults/main.yml
index 63de45646..871700f8c 100644
--- a/roles/static_inventory/defaults/main.yml
+++ b/roles/static_inventory/defaults/main.yml
@@ -19,3 +19,11 @@ private_ssh_key: ~/.ssh/openshift
# The patch to store the generated config to access bastion/hosts
ssh_config_path: /tmp/ssh.config.ansible
+
+# The IP:port to make an SSH tunnel to access UI on the 1st master
+# via bastion node (requires sudo on the ansible control node)
+ui_ssh_tunnel: False
+ui_port: "{{ openshift_master_api_port | default(8443) }}"
+target_ip: "{{ hostvars[groups['masters.' + stack_name|quote][0]].private_v4 }}"
+
+openstack_private_network: private
diff --git a/roles/static_inventory/tasks/main.yml b/roles/static_inventory/tasks/main.yml
index b58866017..24e11beb6 100644
--- a/roles/static_inventory/tasks/main.yml
+++ b/roles/static_inventory/tasks/main.yml
@@ -8,3 +8,10 @@
- name: Generate SSH config for accessing hosts via bastion
include: sshconfig.yml
when: use_bastion|bool
+
+- name: Configure SSH tunneling to access UI
+ include: sshtun.yml
+ become: true
+ when:
+ - use_bastion|bool
+ - ui_ssh_tunnel|bool
diff --git a/roles/static_inventory/tasks/openstack.yml b/roles/static_inventory/tasks/openstack.yml
index 499adf08c..75d0ee6d5 100644
--- a/roles/static_inventory/tasks/openstack.yml
+++ b/roles/static_inventory/tasks/openstack.yml
@@ -29,12 +29,20 @@
add_host:
name: '{{ item.name }}'
groups: '{{ item.metadata.group }}'
- ansible_host: "{% if use_bastion|bool %}{{ item.name }}{% else %}{{ item.private_v4 }}{% endif %}"
+ ansible_host: >-
+ {% if use_bastion|bool -%}
+ {{ item.name }}
+ {%- else -%}
+ {%- set node = registered_nodes | json_query("[?name=='" + item.name + "']") -%}
+ {{ node[0].addresses[openstack_private_network|quote][0].addr }}
+ {%- endif %}
ansible_fqdn: '{{ item.name }}'
ansible_user: '{{ ssh_user }}'
ansible_private_key_file: '{{ private_ssh_key }}'
ansible_ssh_extra_args: '-F {{ ssh_config_path }}'
- private_v4: '{{ item.private_v4 }}'
+ private_v4: >-
+ {% set node = registered_nodes | json_query("[?name=='" + item.name + "']") -%}
+ {{ node[0].addresses[openstack_private_network|quote][0].addr }}
- name: Add cluster nodes with floating IPs to inventory
with_items: "{{ registered_nodes_floating }}"
@@ -46,7 +54,9 @@
ansible_user: '{{ ssh_user }}'
ansible_private_key_file: '{{ private_ssh_key }}'
ansible_ssh_extra_args: '-F {{ ssh_config_path }}'
- private_v4: '{{ item.private_v4 }}'
+ private_v4: >-
+ {% set node = registered_nodes | json_query("[?name=='" + item.name + "']") -%}
+ {{ node[0].addresses[openstack_private_network|quote][0].addr }}
public_v4: '{{ item.public_v4 }}'
- name: Add bastion node to inventory
@@ -58,7 +68,9 @@
ansible_user: '{{ ssh_user }}'
ansible_private_key_file: '{{ private_ssh_key }}'
ansible_ssh_extra_args: '-F {{ ssh_config_path }}'
- private_v4: '{{ registered_bastion_nodes[0].private_v4 }}'
+ private_v4: >-
+ {% set node = registered_nodes | json_query("[?name=='" + registered_bastion_nodes[0].name + "']") -%}
+ {{ node[0].addresses[openstack_private_network|quote][0].addr }}
public_v4: '{{ registered_bastion_nodes[0].public_v4 }}'
when:
- registered_bastion_nodes is defined
diff --git a/roles/static_inventory/tasks/sshtun.yml b/roles/static_inventory/tasks/sshtun.yml
new file mode 100644
index 000000000..b0e4c832c
--- /dev/null
+++ b/roles/static_inventory/tasks/sshtun.yml
@@ -0,0 +1,15 @@
+---
+- name: Create ssh tunnel systemd service
+ template:
+ src: ssh-tunnel.service.j2
+ dest: /etc/systemd/system/ssh-tunnel.service
+ mode: 0644
+
+- name: reload the systemctl daemon after file update
+ command: systemctl daemon-reload
+
+- name: Enable ssh tunnel service
+ service:
+ name: ssh-tunnel
+ enabled: true
+ state: restarted
diff --git a/roles/static_inventory/templates/ssh-tunnel.service.j2 b/roles/static_inventory/templates/ssh-tunnel.service.j2
new file mode 100644
index 000000000..0d1cf8f79
--- /dev/null
+++ b/roles/static_inventory/templates/ssh-tunnel.service.j2
@@ -0,0 +1,20 @@
+[Unit]
+Description=Set up ssh tunneling for OpenShift cluster UI
+After=network.target
+
+[Service]
+ExecStart=/usr/bin/ssh -NT -o \
+ ServerAliveInterval=60 -o \
+ UserKnownHostsFile=/dev/null -o \
+ StrictHostKeyChecking=no -o \
+ ExitOnForwardFailure=no -i \
+ {{ private_ssh_key }} {{ ssh_user }}@{{ hostvars['bastion'].ansible_host }} \
+ -L 0.0.0.0:{{ ui_port }}:{{ target_ip }}:{{ ui_port }}
+
+
+# Restart every >2 seconds to avoid StartLimitInterval failure
+RestartSec=5
+Restart=always
+
+[Install]
+WantedBy=multi-user.target