From d4d02a9028337e41b4f7a76e4e7de50067e8529e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Madis=20N=C3=B5mme?= Date: Wed, 6 May 2015 16:27:17 +0300 Subject: [PATCH 1/3] Optionally associate master instance with AWS Elastic IP When MASTER_RESERVED_IP is set to elastic IP from AWS, then aws/util.sh will associate it with master instance and assign it to KUBE_MASTER_IP. If no MASTER_RESERVED_IP is set, new elastic ip will be requested from amazon. This allows cluster certificates to be generated for an IP that doesn't change between stopping & starting cluster instances. The requested elastic ip is not released when kube-down.sh is run. I think it is good because user could have created DNS records and it would be bad if the IP was removed. He can reuse it next time through MASTER_RESERVED_IP when setting up cluster again. --- cluster/aws/config-default.sh | 4 +++- cluster/aws/util.sh | 30 +++++++++++++++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/cluster/aws/config-default.sh b/cluster/aws/config-default.sh index f8e5430516d..2b01cff8ab6 100644 --- a/cluster/aws/config-default.sh +++ b/cluster/aws/config-default.sh @@ -43,7 +43,9 @@ MINION_SCOPES="" POLL_SLEEP_INTERVAL=3 PORTAL_NET="10.0.0.0/16" MASTER_IP_RANGE="${MASTER_IP_RANGE:-10.246.0.0/24}" - +# If set to Elastic IP, master instance will be associated with this IP. +# Otherwise new Elastic IP will be aquired +MASTER_RESERVED_IP="${MASTER_RESERVED_IP:-}" # When set to true, Docker Cache is enabled by default as part of the cluster bring up. ENABLE_DOCKER_REGISTRY_CACHE=true diff --git a/cluster/aws/util.sh b/cluster/aws/util.sh index 341547e6bd8..ed4eb14abc0 100644 --- a/cluster/aws/util.sh +++ b/cluster/aws/util.sh @@ -365,6 +365,34 @@ function wait-for-instance-running { done } +function allocate-elastic-ip { + $AWS_CMD allocate-address --domain vpc --output text | cut -f3 +} + +function assign-ip-to-instance { + local ip_address=$1 + local instance_id=$2 + local elastic_ip_allocation_id=$($AWS_CMD describe-addresses --public-ips $ip_address --output text | cut -f2) + $AWS_CMD associate-address --instance-id $master_instance_id --allocation-id $elastic_ip_allocation_id > /dev/null + local association_result=$? + + if [[ $association_result -eq 0 ]]; then + echo $ip_address + fi +} + +function assign-elastic-ip { + local assigned_public_ip=$1 + local master_instance_id=$2 + + if [[ -n $MASTER_RESERVED_IP ]]; then + assign-ip-to-instance $MASTER_RESERVED_IP $master_instance_id + else + assign-ip-to-instance $(allocate-elastic-ip) $master_instance_id + fi +} + + function kube-up { find-release-tars upload-server-tars @@ -505,7 +533,7 @@ function kube-up { fi else KUBE_MASTER=${MASTER_NAME} - KUBE_MASTER_IP=${ip} + KUBE_MASTER_IP=$(assign-elastic-ip $ip $master_id) echo -e " ${color_green}[master running @${KUBE_MASTER_IP}]${color_norm}" # We are not able to add a route to the instance until that instance is in "running" state. From eb220f05a6f3b73d527bb22549dd3dd932f09e10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Madis=20N=C3=B5mme?= Date: Fri, 8 May 2015 18:01:04 +0300 Subject: [PATCH 2/3] Properly get return value (considering errexit). Quote variables. --- cluster/aws/util.sh | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/cluster/aws/util.sh b/cluster/aws/util.sh index ed4eb14abc0..9754b3b4e8a 100644 --- a/cluster/aws/util.sh +++ b/cluster/aws/util.sh @@ -354,7 +354,7 @@ function ensure-iam-profiles { function wait-for-instance-running { instance_id=$1 while true; do - instance_state=$($AWS_CMD describe-instances --instance-ids $instance_id | expect_instance_states running) + instance_state=$($AWS_CMD describe-instances --instance-ids ${instance_id} | expect_instance_states running) if [[ "$instance_state" == "" ]]; then break else @@ -365,6 +365,8 @@ function wait-for-instance-running { done } +# Allocates new Elastic IP from Amazon +# Output: allocated IP address function allocate-elastic-ip { $AWS_CMD allocate-address --domain vpc --output text | cut -f3 } @@ -372,23 +374,29 @@ function allocate-elastic-ip { function assign-ip-to-instance { local ip_address=$1 local instance_id=$2 - local elastic_ip_allocation_id=$($AWS_CMD describe-addresses --public-ips $ip_address --output text | cut -f2) - $AWS_CMD associate-address --instance-id $master_instance_id --allocation-id $elastic_ip_allocation_id > /dev/null - local association_result=$? + local fallback_ip=$3 - if [[ $association_result -eq 0 ]]; then - echo $ip_address + local elastic_ip_allocation_id=$($AWS_CMD describe-addresses --public-ips $ip_address --output text | cut -f2) + local association_result=$($AWS_CMD associate-address --instance-id ${master_instance_id} --allocation-id ${elastic_ip_allocation_id} > /dev/null && echo "success" || echo "failure") + + if [[ $association_result = "success" ]]; then + echo "${ip_address}" + else + echo "${fallback_ip}" fi } +# Assigns elastic ip to a Amazon EC2 instance. If assigned public IP is empty, +# then will request new one. +# Output: assigned IP address function assign-elastic-ip { local assigned_public_ip=$1 local master_instance_id=$2 - if [[ -n $MASTER_RESERVED_IP ]]; then - assign-ip-to-instance $MASTER_RESERVED_IP $master_instance_id + if [[ -n "${MASTER_RESERVED_IP}" ]]; then + assign-ip-to-instance "${MASTER_RESERVED_IP}" "${master_instance_id}" "${assigned_public_ip}" else - assign-ip-to-instance $(allocate-elastic-ip) $master_instance_id + assign-ip-to-instance $(allocate-elastic-ip) "${master_instance_id}" "${assigned_public_ip}" fi } From 15643a2c72857c3aa962ee16996d9c3a6025135d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Madis=20N=C3=B5mme?= Date: Wed, 13 May 2015 10:41:51 +0300 Subject: [PATCH 3/3] Add 'auto' option for MASTER_RESERVED_IP. No ElasticIP allocation by default. Default behaviour when setting up a cluster is using the Amazon-assigned public ip. It will change between reboots. If MASTER_RESERVED_IP is set to 'auto', new Elastic IP will be allocated & assigned to master. If MASTER_RESERVED_IP is set to an existing Elastic IP, it will be used. When something fails, original Amazon-given IP will be used. --- cluster/aws/config-default.sh | 3 ++- cluster/aws/util.sh | 12 ++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/cluster/aws/config-default.sh b/cluster/aws/config-default.sh index 2b01cff8ab6..2b7d7045b93 100644 --- a/cluster/aws/config-default.sh +++ b/cluster/aws/config-default.sh @@ -44,7 +44,8 @@ POLL_SLEEP_INTERVAL=3 PORTAL_NET="10.0.0.0/16" MASTER_IP_RANGE="${MASTER_IP_RANGE:-10.246.0.0/24}" # If set to Elastic IP, master instance will be associated with this IP. -# Otherwise new Elastic IP will be aquired +# If set to auto, a new Elastic IP will be aquired +# Otherwise amazon-given public ip will be used (it'll change with reboot). MASTER_RESERVED_IP="${MASTER_RESERVED_IP:-}" # When set to true, Docker Cache is enabled by default as part of the cluster bring up. diff --git a/cluster/aws/util.sh b/cluster/aws/util.sh index 9754b3b4e8a..946aa9d12a6 100644 --- a/cluster/aws/util.sh +++ b/cluster/aws/util.sh @@ -386,17 +386,21 @@ function assign-ip-to-instance { fi } -# Assigns elastic ip to a Amazon EC2 instance. If assigned public IP is empty, -# then will request new one. +# If MASTER_RESERVED_IP looks like IP address, will try to assign it to master instance +# If MASTER_RESERVED_IP is "auto", will allocate new elastic ip and assign that +# If none of the above or something fails, will output originally assigne IP # Output: assigned IP address function assign-elastic-ip { local assigned_public_ip=$1 local master_instance_id=$2 - if [[ -n "${MASTER_RESERVED_IP}" ]]; then + # Check that MASTER_RESERVED_IP looks like an IPv4 address + if [[ "${MASTER_RESERVED_IP}" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then assign-ip-to-instance "${MASTER_RESERVED_IP}" "${master_instance_id}" "${assigned_public_ip}" - else + elif [[ "${MASTER_RESERVED_IP}" = "auto" ]]; then assign-ip-to-instance $(allocate-elastic-ip) "${master_instance_id}" "${assigned_public_ip}" + else + echo "${assigned_public_ip}" fi }