Quellcode durchsuchen

Use ansible playbook to initialize openshift cluster

* Added playbooks/gce/openshift-cluster
* Added bin/cluster (will replace cluster.sh)
Jhon Honce vor 10 Jahren
Ursprung
Commit
7c7cb82fdd

+ 100 - 0
bin/cluster

@@ -0,0 +1,100 @@
+#!/usr/bin/env python
+# vim: expandtab:tabstop=4:shiftwidth=4
+
+import argparse
+import ConfigParser
+import sys
+import os
+
+
+class Cluster(object):
+    """Python wrapper to ensure environment is correct for running ansible playbooks
+    """
+
+    def __init__(self, args):
+        self.args = args
+
+        # setup ansible ssh environment
+        if 'ANSIBLE_SSH_ARGS' not in os.environ:
+            os.environ['ANSIBLE_SSH_ARGS'] = (
+                '-o ForwardAgent=yes'
+                '-o StrictHostKeyChecking=no'
+                '-o UserKnownHostsFile=/dev/null'
+                '-o ControlMaster=auto'
+                '-o ControlPersist=600s'
+            )
+
+    def apply(self):
+        # setup ansible playbook environment
+        config = ConfigParser.ConfigParser()
+        if 'gce' == self.args.provider:
+            config.readfp(open('inventory/gce/gce.ini'))
+
+            for key in config.options('gce'):
+                os.environ[key] = config.get('gce', key)
+
+            inventory = '-i inventory/gce/gce.py'
+        elif 'aws' == self.args.provider:
+            config.readfp(open('inventory/aws/ec2.ini'))
+
+            for key in config.options('ec2'):
+                os.environ[key] = config.get('ec2', key)
+
+            inventory = '-i inventory/aws/ec2.py'
+        else:
+            assert False, "invalid PROVIDER {}".format(self.args.provider)
+
+        env = {'cluster_id': self.args.cluster_id}
+
+        if 'create' == self.args.action:
+            playbook = "playbooks/{}/openshift-cluster/launch.yml".format(self.args.provider)
+            env['masters'] = self.args.masters
+            env['nodes'] = self.args.nodes
+
+        elif 'terminate' == self.args.action:
+            playbook = "playbooks/{}/openshift-cluster/terminate.yml".format(self.args.provider)
+        elif 'list' == self.args.action:
+            # todo: implement cluster list
+            argparse.ArgumentError("ACTION {} not implemented".format(self.args.action))
+        elif 'update' == self.args.action:
+            # todo: implement cluster update
+            argparse.ArgumentError("ACTION {} not implemented".format(self.args.action))
+        else:
+            assert False, "invalid ACTION {}".format(self.args.action)
+
+        verbose = ''
+        if self.args.verbose > 0:
+            verbose = '-{}'.format('v' * self.args.verbose)
+
+        ansible_env = '-e \'{}\''.format(
+            ' '.join(['%s=%s' % (key, value) for (key, value) in env.items()])
+        )
+
+        command = 'ansible-playbook {} {} {} {}'.format(
+            verbose, inventory, ansible_env, playbook
+        )
+
+        if self.args.verbose > 1:
+            command = 'time {}'.format(command)
+
+        if self.args.verbose > 0:
+            sys.stderr.write('RUN [{}]\n'.format(command))
+            sys.stderr.flush()
+
+        os.system(command)
+
+
+if __name__ == '__main__':
+    parser = argparse.ArgumentParser(description='Manage OpenShift Cluster')
+    parser.add_argument('-p', '--provider', default='gce', choices=['gce', 'aws'],
+                        help='One of the supported cloud providers')
+    parser.add_argument('-m', '--masters', default=1, type=int, help='number of masters to create in cluster')
+    parser.add_argument('-n', '--nodes', default=2, type=int, help='number of nodes to create in cluster')
+    parser.add_argument('-v', '--verbose', action='count', help='Multiple -v options increase the verbosity')
+    parser.add_argument('--version', action='version', version='%(prog)s 0.1')
+    parser.add_argument('action', choices=['create', 'terminate', 'update', 'list'])
+    parser.add_argument('provider', choices=['gce', 'aws'])
+    parser.add_argument('cluster_id', help='prefix for cluster VM names')
+    args = parser.parse_args()
+
+    Cluster(args).apply()

+ 1 - 0
playbooks/gce/openshift-cluster/filter_plugins

@@ -0,0 +1 @@
+../../../filter_plugins

+ 62 - 0
playbooks/gce/openshift-cluster/launch.yml

@@ -0,0 +1,62 @@
+---
+- name: Launch instance(s)
+  hosts: localhost
+  connection: local
+  gather_facts: no
+
+  vars_files:
+      - vars.yml
+
+  tasks:
+    - set_fact: k8s_type="master"
+
+    - name: "Generate master instance names(s)"
+      set_fact: scratch="{{ cluster_id }}-{{ k8s_type }}-{{ '%05x' |format( 1048576 |random) }}"
+      register: instance_names_output
+      with_sequence: start=1 end={{ masters }}
+
+    # These set_fact's cannot be combined
+    - set_fact:
+        instance_names_string: "{% for item in instance_names_output.results %}{{item.ansible_facts.scratch}} {% endfor %}"
+
+    - set_fact:
+        master_names: "{{ instance_names_string.strip().split(' ') }}"
+
+    - include: launch_instances.yml
+      vars:
+        instances: "{{ master_names }}"
+        cluster: "{{ cluster_id }}"
+        type: "{{ k8s_type }}"
+        group_name: "tag_env-host-type-{{ cluster_id }}-openshift-master"
+
+    - set_fact: k8s_type="node"
+
+    - name: "Generate node instance names(s)"
+      set_fact: scratch="{{ cluster_id }}-{{ k8s_type }}-{{ '%05x' |format( 1048576 |random) }}"
+      register: instance_names_output
+      with_sequence: start=1 end={{ nodes }}
+
+    # These set_fact's cannot be combined
+    - set_fact:
+        instance_names_string: "{% for item in instance_names_output.results %}{{item.ansible_facts.scratch}} {% endfor %}"
+
+    - set_fact:
+        node_names: "{{ instance_names_string.strip().split(' ') }}"
+
+    - include: launch_instances.yml
+      vars:
+        instances: "{{ node_names }}"
+        cluster: "{{ cluster_id }}"
+        type: "{{ k8s_type }}"
+        group_name: "tag_env-host-type-{{ cluster_id }}-openshift-node"
+
+
+- include: ../openshift-master/config.yml
+  vars:
+    oo_host_group_exp: "{{ master_names }}"
+    oo_env: "{{ cluster_id }}"
+
+- include: ../openshift-node/config.yml
+  vars:
+    oo_host_group_exp: "{{ node_names }}"
+    oo_env: "{{ cluster_id }}"

+ 37 - 0
playbooks/gce/openshift-cluster/launch_instances.yml

@@ -0,0 +1,37 @@
+
+- set_fact:
+    machine_type: "{{ lookup('env', 'gce_machine_type') |default('n1-standard-1', true) }}"
+    machine_image: "{{ lookup('env', 'gce_machine_image') |default('libra-rhel7', true) }}"
+
+- name: Launch instance(s)
+  gce:
+    instance_names: "{{ instances }}"
+    machine_type: "{{ machine_type }}"
+    image: "{{ machine_image }}"
+    service_account_email: "{{ lookup('env', 'gce_service_account_email_address') }}"
+    pem_file: "{{ lookup('env', 'gce_service_account_pem_file_path') }}"
+    project_id: "{{ lookup('env', 'gce_project_id') }}"
+    tags:
+      - "created-by-{{ cluster }}"
+      - "env-{{ cluster }}"
+      - "host-type-{{ type }}"
+      - "env-host-type-{{ cluster }}-openshift-{{ type }}"
+  register: gce
+
+- name: Add new instances public IPs
+  add_host: "hostname={{ item.name }} ansible_ssh_host={{ item.public_ip }} groups={{ group_name }}"
+  with_items: gce.instance_data
+
+- name: Wait for ssh
+  wait_for: "port=22 host={{ item.public_ip }}"
+  with_items: gce.instance_data
+
+- debug: var=gce
+
+- name: Wait for root user setup
+  command: "ssh -o StrictHostKeyChecking=no -o PasswordAuthentication=no -o ConnectTimeout=10 -o UserKnownHostsFile=/dev/null root@{{ item.public_ip }} echo root user is setup"
+  register: result
+  until: result.rc == 0
+  retries: 20
+  delay: 10
+  with_items: gce.instance_data

+ 25 - 0
playbooks/gce/openshift-cluster/terminate.yml

@@ -0,0 +1,25 @@
+---
+- name: Terminate instance(s)
+  hosts: localhost
+
+  vars_files:
+    - vars.yml
+
+  tasks:
+    - debug: msg="Retrieve node names"
+    - debug: msg="Retrieve master names"
+    - debug: var=groups
+
+- include: ../openshift-node/terminate.yml
+  vars:
+    oo_host_group_exp: 'groups["tag_env-host-type-{{ cluster_id }}-openshift-node"]'
+    gce_service_account_email: "1043659492591-r0tpbf8q4fbb9dakhjfhj89e4m1ld83t@developer.gserviceaccount.com"
+    gce_pem_file: "~/.gce/openshift-gce-devel_priv_key.pem"
+    gce_project_id: "openshift-gce-devel"
+
+- include: ../openshift-master/terminate.yml
+  vars:
+    oo_host_group_exp: 'groups["tag_env-host-type-{{ cluster_id }}-openshift-master"]'
+    gce_service_account_email: "1043659492591-r0tpbf8q4fbb9dakhjfhj89e4m1ld83t@developer.gserviceaccount.com"
+    gce_pem_file: "~/.gce/openshift-gce-devel_priv_key.pem"
+    gce_project_id: "openshift-gce-devel"

+ 1 - 0
playbooks/gce/openshift-cluster/vars.yml

@@ -0,0 +1 @@
+---

+ 11 - 2
playbooks/gce/openshift-master/config.yml

@@ -1,5 +1,4 @@
----
-- name: "populate oo_hosts_to_config host group if needed"
+- name: "master/config.yml, populate oo_hosts_to_config host group if needed"
   hosts: localhost
   gather_facts: no
   tasks:
@@ -13,6 +12,16 @@
   connection: ssh
   user: root
 
+- name: "Retrieve public ip"
+  hosts: oo_hosts_to_config
+  connection: ssh
+  user: root
+  gather_facts: yes
+  tasks:
+    - command: 'curl "http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip" -H "Metadata-Flavor: Google"'
+      register: output
+    - set_fact: gce_public_ip="{{ output.stdout }}"
+
 - name: "Set Origin specific facts on localhost (for later use)"
   hosts: localhost
   gather_facts: no

+ 1 - 1
playbooks/gce/openshift-master/terminate.yml

@@ -12,7 +12,7 @@
     - debug: msg="{{ groups['oo_hosts_to_terminate'] }}"
 
 
-- name: Terminate instances
+- name: Terminate master instances
   hosts: localhost
   connection: local
   tasks:

+ 10 - 2
playbooks/gce/openshift-node/config.yml

@@ -1,5 +1,4 @@
----
-- name: "populate oo_hosts_to_config host group if needed"
+- name: "node/config.yml, populate oo_hosts_to_config host group if needed"
   hosts: localhost
   gather_facts: no
   tasks:
@@ -12,6 +11,11 @@
   hosts: "tag_env-host-type-{{ oo_env }}-openshift-master"
   connection: ssh
   user: root
+  gather_facts: yes
+  tasks:
+    - command: 'curl "http://metadata.google.internal/computeMetadata/v1/instance/network-interfaces/0/access-configs/0/external-ip" -H "Metadata-Flavor: Google"'
+      register: output
+    - set_fact: gce_public_ip="{{ output.stdout }}"
 
 - name: "Set OO sepcific facts on localhost (for later use)"
   hosts: localhost
@@ -36,6 +40,10 @@
   user: root
   vars_files:
     - vars.yml
+
+  tasks:
+    - debug: var=gce_public_ip
+
   roles:
     - {
         role: openshift_node,

+ 1 - 1
playbooks/gce/openshift-node/terminate.yml

@@ -12,7 +12,7 @@
     - debug: msg="{{ groups['oo_hosts_to_terminate'] }}"
 
 
-- name: Terminate instances
+- name: Terminate node instances
   hosts: localhost
   connection: local
   tasks:

+ 1 - 1
roles/docker/tasks/main.yml

@@ -11,5 +11,5 @@
 # From the origin rpm there exists instructions on how to
 # setup origin properly.  The following steps come from there
 - name: Change root to be in the Docker group
-  user: name=root groups=docker append=yes
+  user: name=root groups=dockerroot append=yes
 

+ 3 - 0
roles/openshift_common/tasks/main.yml

@@ -2,6 +2,9 @@
 - name: Set hostname
   hostname: name={{ openshift_hostname }}
 
+- name: Update all packages
+  yum: name=* state=latest
+
 - name: Configure local facts file
   file: path=/etc/ansible/facts.d/ state=directory mode=0750