From bb55f68f951036a6ea4851ac95f07349fc34966a Mon Sep 17 00:00:00 2001 From: Sebastian Melchior Date: Tue, 29 Nov 2016 10:20:28 +0100 Subject: [PATCH] add basic azure support for kargo --- docs/azure.md | 54 +++++++++++++++++++ inventory/group_vars/all.yml | 15 +++++- .../manifests/kube-apiserver.manifest.j2 | 2 +- .../kube-controller-manager.manifest.j2 | 6 +-- roles/kubernetes/node/templates/kubelet.j2 | 2 +- .../tasks/azure-credential-check.yml | 47 ++++++++++++++++ roles/kubernetes/preinstall/tasks/main.yml | 15 +++++- .../templates/azure-cloud-config.j2 | 12 +++++ 8 files changed, 145 insertions(+), 8 deletions(-) create mode 100644 docs/azure.md create mode 100644 roles/kubernetes/preinstall/tasks/azure-credential-check.yml create mode 100644 roles/kubernetes/preinstall/templates/azure-cloud-config.j2 diff --git a/docs/azure.md b/docs/azure.md new file mode 100644 index 000000000..204a3ce7f --- /dev/null +++ b/docs/azure.md @@ -0,0 +1,54 @@ +Azure +=============== + +To deploy kubespray on [Azure](https://azure.microsoft.com) uncomment the `cloud_provider` option in `group_vars/all.yml` and set it to `'azure'`. + +All your instances are required to run in a resource group and a routing table has to be attached to the subnet your instances are in. + +Not all features are supported yet though, for a list of the current status have a look [here](https://github.com/colemickens/azure-kubernetes-status) + +### Parameters + +Before creating the instances you must first set the `azure_` variables in the `group_vars/all.yml` file. + +All of the values can be retrieved using the azure cli tool which can be downloaded here: https://docs.microsoft.com/en-gb/azure/xplat-cli-install +After installation you have to run `azure login` to get access to your account. + + +#### azure\_tenant\_id + azure\_subscription\_id +run `azure account show` to retrieve your subscription id and tenant id: +`azure_tenant_id` -> Tenant ID field +`azure_subscription_id` -> ID field + + +#### azure\_location +The region your instances are located, can be something like `westeurope` or `westcentralus`. A full list of region names can be retrieved via `azure location list` + + +#### azure\_resource\_group +The name of the resource group your instances are in, can be retrieved via `azure group list` + +#### azure\_vnet\_name +The name of the virtual network your instances are in, can be retrieved via `azure network vnet list` + +#### azure\_subnet\_name +The name of the subnet your instances are in, can be retrieved via `azure network vnet subnet list RESOURCE_GROUP VNET_NAME` + +#### azure\_security\_group\_name +The name of the network security group your instances are in, can be retrieved via `azure network nsg list` + +#### azure\_aad\_client\_id + azure\_aad\_client\_secret +These will have to be generated first: +- Create an Azure AD Application with: +`azure ad app create --name kubernetes --identifier-uris http://kubernetes --home-page http://example.com --password CLIENT_SECRET` +The name, identifier-uri, home-page and the password can be choosen +Note the AppId in the output. +- Create Service principal for the application with: +`azure ad sp create --applicationId AppId` +This is the AppId from the last command +- Create the role assignment with: +`azure role assignment create --spn http://kubernetes -o "Owner" -c /subscriptions/SUBSCRIPTION_ID` + +azure\_aad\_client\_id musst be set to the AppId, azure\_aad\_client\_secret is your choosen secret. + + diff --git a/inventory/group_vars/all.yml b/inventory/group_vars/all.yml index daf641335..229a0d314 100644 --- a/inventory/group_vars/all.yml +++ b/inventory/group_vars/all.yml @@ -125,11 +125,24 @@ dns_server: "{{ kube_service_addresses|ipaddr('net')|ipaddr(2)|ipaddr('address') # There are some changes specific to the cloud providers # for instance we need to encapsulate packets with some network plugins -# If set the possible values are either 'gce', 'aws' or 'openstack' +# If set the possible values are either 'gce', 'aws', 'azure' or 'openstack' # When openstack is used make sure to source in the openstack credentials # like you would do when using nova-client before starting the playbook. +# When azure is used, you need to also set the following variables. # cloud_provider: +# see docs/azure.md for details on how to get these values +#azure_tenant_id: +#azure_subscription_id: +#azure_aad_client_id: +#azure_aad_client_secret: +#azure_resource_group: +#azure_location: +#azure_subnet_name: +#azure_security_group_name: +#azure_vnet_name: + + ## Set these proxy values in order to update docker daemon to use proxies # http_proxy: "" # https_proxy: "" diff --git a/roles/kubernetes/master/templates/manifests/kube-apiserver.manifest.j2 b/roles/kubernetes/master/templates/manifests/kube-apiserver.manifest.j2 index 83c5525b1..530b009c6 100644 --- a/roles/kubernetes/master/templates/manifests/kube-apiserver.manifest.j2 +++ b/roles/kubernetes/master/templates/manifests/kube-apiserver.manifest.j2 @@ -43,7 +43,7 @@ spec: {% endif %} - --v={{ kube_log_level }} - --allow-privileged=true -{% if cloud_provider is defined and cloud_provider == "openstack" %} +{% if cloud_provider is defined and cloud_provider in ["openstack", "azure"] %} - --cloud-provider={{ cloud_provider }} - --cloud-config={{ kube_config_dir }}/cloud_config {% elif cloud_provider is defined and cloud_provider == "aws" %} diff --git a/roles/kubernetes/master/templates/manifests/kube-controller-manager.manifest.j2 b/roles/kubernetes/master/templates/manifests/kube-controller-manager.manifest.j2 index 1cd58d46c..7821ee309 100644 --- a/roles/kubernetes/master/templates/manifests/kube-controller-manager.manifest.j2 +++ b/roles/kubernetes/master/templates/manifests/kube-controller-manager.manifest.j2 @@ -20,7 +20,7 @@ spec: - --root-ca-file={{ kube_cert_dir }}/ca.pem - --enable-hostpath-provisioner={{ kube_hostpath_dynamic_provisioner }} - --v={{ kube_log_level }} -{% if cloud_provider is defined and cloud_provider == "openstack" %} +{% if cloud_provider is defined and cloud_provider in ["openstack", "azure"] %} - --cloud-provider={{cloud_provider}} - --cloud-config={{ kube_config_dir }}/cloud_config {% elif cloud_provider is defined and cloud_provider == "aws" %} @@ -37,7 +37,7 @@ spec: - mountPath: {{ kube_cert_dir }} name: ssl-certs-kubernetes readOnly: true -{% if cloud_provider is defined and cloud_provider == "openstack" %} +{% if cloud_provider is defined and cloud_provider in ["openstack", "azure"] %} - mountPath: {{ kube_config_dir }}/cloud_config name: cloudconfig readOnly: true @@ -46,7 +46,7 @@ spec: - hostPath: path: {{ kube_cert_dir }} name: ssl-certs-kubernetes -{% if cloud_provider is defined and cloud_provider == "openstack" %} +{% if cloud_provider is defined and cloud_provider in ["openstack", "azure"] %} - hostPath: path: {{ kube_config_dir }}/cloud_config name: cloudconfig diff --git a/roles/kubernetes/node/templates/kubelet.j2 b/roles/kubernetes/node/templates/kubelet.j2 index a575f065e..3c1f31ab2 100644 --- a/roles/kubernetes/node/templates/kubelet.j2 +++ b/roles/kubernetes/node/templates/kubelet.j2 @@ -30,7 +30,7 @@ DOCKER_SOCKET="--docker-endpoint=unix:/var/run/weave/weave.sock" {% endif %} # Should this cluster be allowed to run privileged docker containers KUBE_ALLOW_PRIV="--allow-privileged=true" -{% if cloud_provider is defined and cloud_provider == "openstack" %} +{% if cloud_provider is defined and cloud_provider in ["openstack", "azure"] %} KUBELET_CLOUDPROVIDER="--cloud-provider={{ cloud_provider }} --cloud-config={{ kube_config_dir }}/cloud_config" {% elif cloud_provider is defined and cloud_provider == "aws" %} KUBELET_CLOUDPROVIDER="--cloud-provider={{ cloud_provider }}" diff --git a/roles/kubernetes/preinstall/tasks/azure-credential-check.yml b/roles/kubernetes/preinstall/tasks/azure-credential-check.yml new file mode 100644 index 000000000..2ee57202b --- /dev/null +++ b/roles/kubernetes/preinstall/tasks/azure-credential-check.yml @@ -0,0 +1,47 @@ +--- +- name: check azure_tenant_id value + fail: + msg: "azure_tenant_id is missing" + when: azure_tenant_id is not defined or azure_tenant_id == "" + +- name: check openstack_username value + fail: + msg: "azure_subscription_id is missing" + when: azure_subscription_id is not defined or azure_subscription_id == "" + +- name: check azure_aad_client_id value + fail: + msg: "azure_aad_client_id is missing" + when: azure_aad_client_id is not defined or azure_aad_client_id == "" + +- name: check azure_aad_client_secret value + fail: + msg: "azure_aad_client_secret is missing" + when: azure_aad_client_secret is not defined or azure_aad_client_secret == "" + +- name: check azure_resource_group value + fail: + msg: "azure_resource_group is missing" + when: azure_resource_group is not defined or azure_resource_group == "" + +- name: check azure_location value + fail: + msg: "azure_location is missing" + when: azure_location is not defined or azure_location == "" + +- name: check azure_subnet_name value + fail: + msg: "azure_subnet_name is missing" + when: azure_subnet_name is not defined or azure_subnet_name == "" + +- name: check azure_security_group_name value + fail: + msg: "azure_security_group_name is missing" + when: azure_security_group_name is not defined or azure_security_group_name == "" + +- name: check azure_vnet_name value + fail: + msg: "azure_vnet_name is missing" + when: azure_vnet_name is not defined or azure_vnet_name == "" + + diff --git a/roles/kubernetes/preinstall/tasks/main.yml b/roles/kubernetes/preinstall/tasks/main.yml index 5c6520ed3..7e4c2ac48 100644 --- a/roles/kubernetes/preinstall/tasks/main.yml +++ b/roles/kubernetes/preinstall/tasks/main.yml @@ -60,12 +60,15 @@ - name: check cloud_provider value fail: - msg: "If set the 'cloud_provider' var must be set either to 'generic', 'gce', 'aws' or 'openstack'" - when: cloud_provider is defined and cloud_provider not in ['generic', 'gce', 'aws', 'openstack'] + msg: "If set the 'cloud_provider' var must be set either to 'generic', 'gce', 'aws', 'azure' or 'openstack'" + when: cloud_provider is defined and cloud_provider not in ['generic', 'gce', 'aws', 'openstack', 'azure'] - include: openstack-credential-check.yml when: cloud_provider is defined and cloud_provider == 'openstack' +- include: azure-credential-check.yml + when: cloud_provider is defined and cloud_provider == 'azure' + - name: Create cni directories file: path: "{{ item }}" @@ -130,4 +133,12 @@ mode: 0640 when: cloud_provider is defined and cloud_provider == "openstack" +- name: Write azure cloud-config + template: + src: azure-cloud-config.j2 + dest: "{{ kube_config_dir }}/cloud_config" + group: "{{ kube_cert_group }}" + mode: 0640 + when: cloud_provider is defined and cloud_provider == "azure" + - include: etchosts.yml diff --git a/roles/kubernetes/preinstall/templates/azure-cloud-config.j2 b/roles/kubernetes/preinstall/templates/azure-cloud-config.j2 new file mode 100644 index 000000000..139a06cc1 --- /dev/null +++ b/roles/kubernetes/preinstall/templates/azure-cloud-config.j2 @@ -0,0 +1,12 @@ +{ + "tenantId": "{{ azure_tenant_id }}", + "subscriptionId": "{{ azure_subscription_id }}", + "aadClientId": "{{ azure_aad_client_id }}", + "aadClientSecret": "{{ azure_aad_client_secret }}", + "resourceGroup": "{{ azure_resource_group }}", + "location": "{{ azure_location }}", + "subnetName": "{{ azure_subnet_name }}", + "securityGroupName": "{{ azure_security_group_name }}", + "vnetName": "{{ azure_vnet_name }}", + "routeTableName": "{{ azure_route_table_name }}" +} \ No newline at end of file