2014-07-14 17:50:04 +00:00
#!/bin/bash
2015-05-01 16:19:44 +00:00
# Copyright 2014 The Kubernetes Authors All rights reserved.
2014-07-14 17:50:04 +00:00
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# A library of helper functions and constant for the local config.
# Use the config file specified in $KUBE_CONFIG_FILE, or default to
# config-default.sh.
2014-10-03 21:58:49 +00:00
KUBE_ROOT = $( dirname " ${ BASH_SOURCE } " ) /../..
source " ${ KUBE_ROOT } /cluster/gce/ ${ KUBE_CONFIG_FILE - "config-default.sh" } "
2015-03-06 22:49:25 +00:00
source " ${ KUBE_ROOT } /cluster/common.sh "
2014-07-14 17:50:04 +00:00
2015-04-28 15:50:43 +00:00
if [ [ " ${ OS_DISTRIBUTION } " = = "debian" || " ${ OS_DISTRIBUTION } " = = "coreos" ] ] ; then
2015-04-28 08:22:25 +00:00
source " ${ KUBE_ROOT } /cluster/gce/ ${ OS_DISTRIBUTION } /helper.sh "
2015-04-28 15:50:43 +00:00
else
2015-05-08 22:53:09 +00:00
echo " Cannot operate on cluster using os distro: ${ OS_DISTRIBUTION } " >& 2
exit 1
2015-04-28 08:22:25 +00:00
fi
2015-01-28 14:57:10 +00:00
NODE_INSTANCE_PREFIX = " ${ INSTANCE_PREFIX } -minion "
2015-04-28 15:02:45 +00:00
ALLOCATE_NODE_CIDRS = true
2015-03-27 20:53:26 +00:00
KUBE_PROMPT_FOR_UPDATE = y
2015-04-21 23:11:15 +00:00
KUBE_SKIP_UPDATE = ${ KUBE_SKIP_UPDATE - "n" }
2015-06-12 22:18:47 +00:00
# Suffix to append to the staging path used for the server tars. Useful if
# multiple versions of the server are being used in the same project
# simultaneously (e.g. on Jenkins).
KUBE_GCS_STAGING_PATH_SUFFIX = ${ KUBE_GCS_STAGING_PATH_SUFFIX - "" }
2015-03-27 20:53:26 +00:00
2015-06-01 15:59:12 +00:00
# VERSION_REGEX matches things like "v0.13.1"
readonly KUBE_VERSION_REGEX = " ^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*) $"
# CI_VERSION_REGEX matches things like "v0.14.1-341-ge0c9d9e"
readonly KUBE_CI_VERSION_REGEX = " ^v(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)\\.(0|[1-9][0-9]*)-(.*) $"
2015-05-23 04:07:09 +00:00
function join_csv {
local IFS = ',' ; echo " $* " ;
}
2014-09-23 22:54:27 +00:00
# Verify prereqs
function verify-prereqs {
2014-10-06 20:25:27 +00:00
local cmd
2014-11-25 18:32:27 +00:00
for cmd in gcloud gsutil; do
2015-03-27 20:46:28 +00:00
if ! which " ${ cmd } " >/dev/null; then
local resp
2015-03-31 21:03:18 +00:00
if [ [ " ${ KUBE_PROMPT_FOR_UPDATE } " = = "y" ] ] ; then
2015-03-30 17:20:29 +00:00
echo " Can't find ${ cmd } in PATH. Do you wish to install the Google Cloud SDK? [Y/n] "
read resp
else
resp = "y"
fi
2015-03-27 20:46:28 +00:00
if [ [ " ${ resp } " != "n" && " ${ resp } " != "N" ] ] ; then
curl https://sdk.cloud.google.com | bash
fi
if ! which " ${ cmd } " >/dev/null; then
echo " Can't find ${ cmd } in PATH, please fix and retry. The Google Cloud "
echo "SDK can be downloaded from https://cloud.google.com/sdk/."
exit 1
fi
2015-04-02 00:23:00 +00:00
fi
2014-09-23 22:54:27 +00:00
done
2015-04-22 17:11:08 +00:00
if [ [ " ${ KUBE_SKIP_UPDATE } " = = "y" ] ] ; then
2015-04-21 23:11:15 +00:00
return
fi
2015-03-27 20:46:28 +00:00
# update and install components as needed
2015-03-27 20:53:26 +00:00
if [ [ " ${ KUBE_PROMPT_FOR_UPDATE } " != "y" ] ] ; then
gcloud_prompt = "-q"
fi
2015-04-22 17:19:46 +00:00
local sudo_prefix = ""
2015-04-21 23:11:15 +00:00
if [ ! -w $( dirname ` which gcloud` ) ] ; then
sudo_prefix = "sudo"
fi
${ sudo_prefix } gcloud ${ gcloud_prompt :- } components update preview || true
${ sudo_prefix } gcloud ${ gcloud_prompt :- } components update alpha || true
${ sudo_prefix } gcloud ${ gcloud_prompt :- } components update || true
2014-09-23 22:54:27 +00:00
}
2014-10-06 20:25:27 +00:00
# Create a temp dir that'll be deleted at the end of this bash session.
#
# Vars set:
# KUBE_TEMP
function ensure-temp-dir {
if [ [ -z ${ KUBE_TEMP - } ] ] ; then
KUBE_TEMP = $( mktemp -d -t kubernetes.XXXXXX)
trap 'rm -rf "${KUBE_TEMP}"' EXIT
fi
}
2014-09-23 22:54:27 +00:00
# Verify and find the various tar files that we are going to use on the server.
#
# Vars set:
# SERVER_BINARY_TAR
# SALT_TAR
function find-release-tars {
2014-10-03 21:58:49 +00:00
SERVER_BINARY_TAR = " ${ KUBE_ROOT } /server/kubernetes-server-linux-amd64.tar.gz "
2014-09-23 22:54:27 +00:00
if [ [ ! -f " $SERVER_BINARY_TAR " ] ] ; then
2014-10-03 21:58:49 +00:00
SERVER_BINARY_TAR = " ${ KUBE_ROOT } /_output/release-tars/kubernetes-server-linux-amd64.tar.gz "
2014-09-23 22:54:27 +00:00
fi
if [ [ ! -f " $SERVER_BINARY_TAR " ] ] ; then
echo "!!! Cannot find kubernetes-server-linux-amd64.tar.gz"
exit 1
2014-07-14 17:50:04 +00:00
fi
2014-10-03 21:58:49 +00:00
SALT_TAR = " ${ KUBE_ROOT } /server/kubernetes-salt.tar.gz "
2014-09-23 22:54:27 +00:00
if [ [ ! -f " $SALT_TAR " ] ] ; then
2014-10-03 21:58:49 +00:00
SALT_TAR = " ${ KUBE_ROOT } /_output/release-tars/kubernetes-salt.tar.gz "
2014-09-23 22:54:27 +00:00
fi
if [ [ ! -f " $SALT_TAR " ] ] ; then
echo "!!! Cannot find kubernetes-salt.tar.gz"
2014-07-14 17:50:04 +00:00
exit 1
fi
}
# Use the gcloud defaults to find the project. If it is already set in the
# environment then go with that.
2014-09-23 22:54:27 +00:00
#
# Vars set:
# PROJECT
2015-01-15 19:21:42 +00:00
# PROJECT_REPORTED
2014-07-14 17:50:04 +00:00
function detect-project ( ) {
2014-10-06 20:25:27 +00:00
if [ [ -z " ${ PROJECT - } " ] ] ; then
2014-07-14 17:50:04 +00:00
PROJECT = $( gcloud config list project | tail -n 1 | cut -f 3 -d ' ' )
fi
2014-10-06 20:25:27 +00:00
if [ [ -z " ${ PROJECT - } " ] ] ; then
echo "Could not detect Google Cloud Platform project. Set the default project using " >& 2
echo "'gcloud config set project <PROJECT>'" >& 2
2014-07-14 17:50:04 +00:00
exit 1
fi
2015-01-15 19:21:42 +00:00
if [ [ -z " ${ PROJECT_REPORTED - } " ] ] ; then
echo " Project: ${ PROJECT } " >& 2
echo " Zone: ${ ZONE } " >& 2
PROJECT_REPORTED = true
fi
2014-07-14 17:50:04 +00:00
}
2015-05-01 17:50:18 +00:00
function sha1sum-file( ) {
if which shasum >/dev/null 2>& 1; then
shasum -a1 " $1 " | awk '{ print $1 }'
else
sha1sum " $1 " | awk '{ print $1 }'
fi
}
function already-staged( ) {
local -r file = $1
local -r newsum = $2
2015-05-28 03:33:29 +00:00
[ [ -e " ${ file } .uploaded.sha1 " ] ] || return 1
2015-05-01 17:50:18 +00:00
local oldsum
2015-05-28 03:33:29 +00:00
oldsum = $( cat " ${ file } .uploaded.sha1 " )
2015-05-01 17:50:18 +00:00
[ [ " ${ oldsum } " = = " ${ newsum } " ] ]
}
# Copy a release tar, if we don't already think it's staged in GCS
function copy-if-not-staged( ) {
local -r staging_path = $1
local -r gs_url = $2
local -r tar = $3
local -r hash = $4
if already-staged " ${ tar } " " ${ hash } " ; then
echo " +++ $( basename ${ tar } ) already staged ('rm ${ tar } .sha1' to force) "
else
2015-06-18 18:31:21 +00:00
echo " ${ hash } " > " ${ tar } .sha1 "
2015-05-01 17:50:18 +00:00
gsutil -m -q -h "Cache-Control:private, max-age=0" cp " ${ tar } " " ${ tar } .sha1 " " ${ staging_path } "
gsutil -m acl ch -g all:R " ${ gs_url } " " ${ gs_url } .sha1 " >/dev/null 2>& 1
2015-06-18 18:31:21 +00:00
echo " ${ hash } " > " ${ tar } .uploaded.sha1 "
echo " +++ $( basename ${ tar } ) uploaded (sha1 = ${ hash } ) "
2015-05-01 17:50:18 +00:00
fi
}
2014-12-09 23:37:06 +00:00
2014-09-23 22:54:27 +00:00
# Take the local tar files and upload them to Google Storage. They will then be
# downloaded by the master as part of the start up script for the master.
#
# Assumed vars:
# PROJECT
# SERVER_BINARY_TAR
# SALT_TAR
# Vars set:
# SERVER_BINARY_TAR_URL
2015-06-18 18:31:21 +00:00
# SERVER_BINARY_TAR_HASH
2014-09-23 22:54:27 +00:00
# SALT_TAR_URL
2015-06-18 18:31:21 +00:00
# SALT_TAR_HASH
2014-09-23 22:54:27 +00:00
function upload-server-tars( ) {
SERVER_BINARY_TAR_URL =
2015-06-18 18:31:21 +00:00
SERVER_BINARY_TAR_HASH =
2014-09-23 22:54:27 +00:00
SALT_TAR_URL =
2015-06-18 18:31:21 +00:00
SALT_TAR_HASH =
2014-09-23 22:54:27 +00:00
local project_hash
if which md5 > /dev/null 2>& 1; then
project_hash = $( md5 -q -s " $PROJECT " )
else
2014-11-12 07:04:01 +00:00
project_hash = $( echo -n " $PROJECT " | md5sum | awk '{ print $1 }' )
2014-09-23 22:54:27 +00:00
fi
2015-05-01 17:50:18 +00:00
2015-04-09 04:51:50 +00:00
# This requires 1 million projects before the probability of collision is 50%
# that's probably good enough for now :P
project_hash = ${ project_hash : 0 : 10 }
2014-09-23 22:54:27 +00:00
local -r staging_bucket = " gs://kubernetes-staging- ${ project_hash } "
# Ensure the bucket is created
if ! gsutil ls " $staging_bucket " > /dev/null 2>& 1 ; then
echo " Creating $staging_bucket "
gsutil mb " ${ staging_bucket } "
fi
2015-06-12 22:18:47 +00:00
local -r staging_path = " ${ staging_bucket } /devel ${ KUBE_GCS_STAGING_PATH_SUFFIX } "
2014-09-23 22:54:27 +00:00
2015-06-18 18:31:21 +00:00
SERVER_BINARY_TAR_HASH = $( sha1sum-file " ${ SERVER_BINARY_TAR } " )
SALT_TAR_HASH = $( sha1sum-file " ${ SALT_TAR } " )
2015-05-01 17:50:18 +00:00
2014-09-23 22:54:27 +00:00
echo " +++ Staging server tars to Google Storage: ${ staging_path } "
2014-11-08 00:16:45 +00:00
local server_binary_gs_url = " ${ staging_path } / ${ SERVER_BINARY_TAR ##*/ } "
local salt_gs_url = " ${ staging_path } / ${ SALT_TAR ##*/ } "
2015-06-18 18:31:21 +00:00
copy-if-not-staged " ${ staging_path } " " ${ server_binary_gs_url } " " ${ SERVER_BINARY_TAR } " " ${ SERVER_BINARY_TAR_HASH } "
copy-if-not-staged " ${ staging_path } " " ${ salt_gs_url } " " ${ SALT_TAR } " " ${ SALT_TAR_HASH } "
2014-11-08 00:16:45 +00:00
# Convert from gs:// URL to an https:// URL
SERVER_BINARY_TAR_URL = " ${ server_binary_gs_url /gs : \/ \/ /https : //storage.googleapis.com/ } "
SALT_TAR_URL = " ${ salt_gs_url /gs : \/ \/ /https : //storage.googleapis.com/ } "
2014-09-23 22:54:27 +00:00
}
2015-01-28 14:57:10 +00:00
# Detect minions created in the minion group
2014-09-23 22:54:27 +00:00
#
# Assumed vars:
2015-01-28 14:57:10 +00:00
# NODE_INSTANCE_PREFIX
# Vars set:
2014-09-23 22:54:27 +00:00
# MINION_NAMES
2015-01-28 14:57:10 +00:00
function detect-minion-names {
detect-project
MINION_NAMES = ( $( gcloud preview --project " ${ PROJECT } " instance-groups \
--zone " ${ ZONE } " instances --group " ${ NODE_INSTANCE_PREFIX } -group " list \
| cut -d'/' -f11) )
2015-06-17 07:13:26 +00:00
echo " MINION_NAMES= ${ MINION_NAMES [*] } " >& 2
2015-01-28 14:57:10 +00:00
}
# Waits until the number of running nodes in the instance group is equal to NUM_NODES
#
# Assumed vars:
# NODE_INSTANCE_PREFIX
# NUM_MINIONS
function wait-for-minions-to-run {
detect-project
local running_minions = 0
while [ [ " ${ NUM_MINIONS } " != " ${ running_minions } " ] ] ; do
echo -e -n " ${ color_yellow } Waiting for minions to run. "
echo -e " ${ running_minions } out of ${ NUM_MINIONS } running. Retrying. ${ color_norm } "
sleep 5
2015-04-22 14:37:22 +00:00
running_minions = $(( gcloud preview - - project " ${ PROJECT } " instance-groups \
2015-01-28 14:57:10 +00:00
--zone " ${ ZONE } " instances --group " ${ NODE_INSTANCE_PREFIX } -group " list \
2015-04-22 14:37:22 +00:00
--running || true ) | wc -l | xargs)
2015-01-28 14:57:10 +00:00
done
}
# Detect the information about the minions
#
# Assumed vars:
2014-09-23 22:54:27 +00:00
# ZONE
# Vars set:
2015-01-28 14:57:10 +00:00
# MINION_NAMES
2014-12-09 23:07:54 +00:00
# KUBE_MINION_IP_ADDRESSES (array)
2014-07-14 17:50:04 +00:00
function detect-minions ( ) {
2014-12-09 23:07:54 +00:00
detect-project
2015-01-28 14:57:10 +00:00
detect-minion-names
2014-07-14 17:50:04 +00:00
KUBE_MINION_IP_ADDRESSES = ( )
for ( ( i = 0; i<${# MINION_NAMES [@] } ; i++) ) ; do
2014-12-03 05:14:18 +00:00
local minion_ip = $( gcloud compute instances describe --project " ${ PROJECT } " --zone " ${ ZONE } " \
2014-11-25 18:32:27 +00:00
" ${ MINION_NAMES [ $i ] } " --fields networkInterfaces[ 0] .accessConfigs[ 0] .natIP \
--format= text | awk '{ print $2 }' )
2014-10-06 20:25:27 +00:00
if [ [ -z " ${ minion_ip - } " ] ] ; then
echo " Did not find ${ MINION_NAMES [ $i ] } " >& 2
2014-09-22 17:25:25 +00:00
else
echo " Found ${ MINION_NAMES [ $i ] } at ${ minion_ip } "
KUBE_MINION_IP_ADDRESSES += ( " ${ minion_ip } " )
fi
2014-07-14 17:50:04 +00:00
done
2014-10-06 20:25:27 +00:00
if [ [ -z " ${ KUBE_MINION_IP_ADDRESSES - } " ] ] ; then
echo "Could not detect Kubernetes minion nodes. Make sure you've launched a cluster with 'kube-up.sh'" >& 2
2014-07-14 17:50:04 +00:00
exit 1
fi
}
2014-09-23 22:54:27 +00:00
# Detect the IP for the master
#
# Assumed vars:
# MASTER_NAME
# ZONE
# Vars set:
# KUBE_MASTER
# KUBE_MASTER_IP
2014-07-14 17:50:04 +00:00
function detect-master ( ) {
2014-12-09 23:07:54 +00:00
detect-project
2014-07-14 17:50:04 +00:00
KUBE_MASTER = ${ MASTER_NAME }
2014-10-06 20:25:27 +00:00
if [ [ -z " ${ KUBE_MASTER_IP - } " ] ] ; then
2014-12-03 05:14:18 +00:00
KUBE_MASTER_IP = $( gcloud compute instances describe --project " ${ PROJECT } " --zone " ${ ZONE } " \
2014-11-25 18:32:27 +00:00
" ${ MASTER_NAME } " --fields networkInterfaces[ 0] .accessConfigs[ 0] .natIP \
--format= text | awk '{ print $2 }' )
2014-07-14 17:50:04 +00:00
fi
2014-10-06 20:25:27 +00:00
if [ [ -z " ${ KUBE_MASTER_IP - } " ] ] ; then
echo "Could not detect Kubernetes master node. Make sure you've launched a cluster with 'kube-up.sh'" >& 2
2014-07-14 17:50:04 +00:00
exit 1
fi
echo " Using master: $KUBE_MASTER (external IP: $KUBE_MASTER_IP ) "
}
2014-09-23 22:54:27 +00:00
# Ensure that we have a password created for validating to the master. Will
2015-03-13 19:22:49 +00:00
# read from kubeconfig for the current context if available.
2015-02-04 03:38:24 +00:00
#
# Assumed vars
# KUBE_ROOT
2014-09-23 22:54:27 +00:00
#
# Vars set:
# KUBE_USER
# KUBE_PASSWORD
2014-07-14 17:50:04 +00:00
function get-password {
2015-03-13 19:22:49 +00:00
get-kubeconfig-basicauth
2015-03-06 22:49:25 +00:00
if [ [ -z " ${ KUBE_USER } " || -z " ${ KUBE_PASSWORD } " ] ] ; then
KUBE_USER = admin
KUBE_PASSWORD = $( python -c 'import string,random; print "".join(random.SystemRandom().choice(string.ascii_letters + string.digits) for _ in range(16))' )
2014-07-14 17:50:04 +00:00
fi
}
2015-04-17 21:04:14 +00:00
# Ensure that we have a bearer token created for validating to the master.
# Will read from kubeconfig for the current context if available.
#
# Assumed vars
# KUBE_ROOT
2014-10-20 20:49:24 +00:00
#
# Vars set:
2015-04-17 21:04:14 +00:00
# KUBE_BEARER_TOKEN
function get-bearer-token( ) {
get-kubeconfig-bearertoken
if [ [ -z " ${ KUBE_BEARER_TOKEN :- } " ] ] ; then
KUBE_BEARER_TOKEN = $( dd if = /dev/urandom bs = 128 count = 1 2>/dev/null | base64 | tr -d "=+/" | dd bs = 32 count = 1 2>/dev/null)
2014-10-20 20:49:24 +00:00
fi
}
2014-12-09 23:37:06 +00:00
# Wait for background jobs to finish. Exit with
# an error status if any of the jobs failed.
function wait-for-jobs {
local fail = 0
local job
for job in $( jobs -p) ; do
wait " ${ job } " || fail = $(( fail + 1 ))
done
if ( ( fail != 0 ) ) ; then
echo -e " ${ color_red } ${ fail } commands failed. Exiting. ${ color_norm } " >& 2
# Ignore failures for now.
# exit 2
fi
}
# Robustly try to create a firewall rule.
# $1: The name of firewall rule.
# $2: IP ranges.
2014-12-16 18:22:29 +00:00
# $3: Target tags for this firewall rule.
2014-12-09 23:37:06 +00:00
function create-firewall-rule {
2014-12-09 23:07:54 +00:00
detect-project
2014-12-09 23:37:06 +00:00
local attempt = 0
while true; do
if ! gcloud compute firewall-rules create " $1 " \
--project " ${ PROJECT } " \
--network " ${ NETWORK } " \
--source-ranges " $2 " \
2014-12-16 18:22:29 +00:00
--target-tags " $3 " \
2015-05-23 04:07:09 +00:00
--allow tcp,udp,icmp,esp,ah,sctp; then
2014-12-09 23:37:06 +00:00
if ( ( attempt > 5 ) ) ; then
echo -e " ${ color_red } Failed to create firewall rule $1 ${ color_norm } "
exit 2
fi
echo -e " ${ color_yellow } Attempt $(( $attempt + 1 )) failed to create firewall rule $1 . Retrying. ${ color_norm } "
attempt = $(( $attempt + 1 ))
else
2015-01-28 14:57:10 +00:00
break
2014-12-09 23:37:06 +00:00
fi
done
}
2015-01-28 14:57:10 +00:00
# Robustly try to create an instance template.
# $1: The name of the instance template.
2014-12-09 23:37:06 +00:00
# $2: The scopes flag.
2015-01-28 14:57:10 +00:00
# $3: The minion start script metadata from file.
Change GCE to use standalone Saltstack config:
Change provisioning to pass all variables to both master and node. Run
Salt in a masterless setup on all nodes ala
http://docs.saltstack.com/en/latest/topics/tutorials/quickstart.html,
which involves ensuring Salt daemon is NOT running after install. Kill
Salt master install. And fix push to actually work in this new flow.
As part of this, the GCE Salt config no longer has access to the Salt
mine, which is primarily obnoxious for two reasons: - The minions
can't use Salt to see the master: this is easily fixed by static
config. - The master can't see the list of all the minions: this is
fixed temporarily by static config in util.sh, but later, by other
means (see
https://github.com/GoogleCloudPlatform/kubernetes/issues/156, which
should eventually remove this direction).
As part of it, flatten all of cluster/gce/templates/* into
configure-vm.sh, using a single, separate piece of YAML to drive the
environment variables, rather than constantly rewriting the startup
script.
2015-03-02 22:38:58 +00:00
# $4: The kube-env metadata.
2015-01-28 14:57:10 +00:00
function create-node-template {
2014-12-09 23:07:54 +00:00
detect-project
2015-05-08 00:41:22 +00:00
# First, ensure the template doesn't exist.
# TODO(mbforbes): To make this really robust, we need to parse the output and
# add retries. Just relying on a non-zero exit code doesn't
# distinguish an ephemeral failed call from a "not-exists".
2015-06-11 23:40:21 +00:00
if gcloud compute instance-templates describe " $1 " --project " ${ PROJECT } " & >/dev/null; then
2015-06-12 03:56:01 +00:00
echo " Instance template ${ 1 } already exists; deleting. " >& 2
if ! gcloud compute instance-templates delete " $1 " --project " ${ PROJECT } " & >/dev/null; then
echo -e " ${ color_yellow } Failed to delete existing instance template ${ color_norm } " >& 2
exit 2
fi
2015-05-08 00:41:22 +00:00
fi
2015-06-17 07:13:26 +00:00
local attempt = 1
2014-12-09 23:37:06 +00:00
while true; do
2015-06-17 07:13:26 +00:00
echo " Attempt ${ attempt } to create ${ 1 } " >& 2
2015-01-28 14:57:10 +00:00
if ! gcloud compute instance-templates create " $1 " \
2014-12-09 23:37:06 +00:00
--project " ${ PROJECT } " \
--machine-type " ${ MINION_SIZE } " \
2015-01-04 00:56:54 +00:00
--boot-disk-type " ${ MINION_DISK_TYPE } " \
--boot-disk-size " ${ MINION_DISK_SIZE } " \
2015-04-28 07:25:43 +00:00
--image-project= " ${ MINION_IMAGE_PROJECT } " \
--image " ${ MINION_IMAGE } " \
2014-12-09 23:37:06 +00:00
--tags " ${ MINION_TAG } " \
--network " ${ NETWORK } " \
$2 \
--can-ip-forward \
2015-06-17 07:13:26 +00:00
--metadata-from-file " $3 " ," $4 " >& 2; then
2014-12-09 23:37:06 +00:00
if ( ( attempt > 5 ) ) ; then
2015-05-08 00:41:22 +00:00
echo -e " ${ color_red } Failed to create instance template $1 ${ color_norm } " >& 2
2014-12-09 23:37:06 +00:00
exit 2
fi
2015-06-17 07:13:26 +00:00
echo -e " ${ color_yellow } Attempt ${ attempt } failed to create instance template $1 . Retrying. ${ color_norm } " >& 2
2014-12-09 23:37:06 +00:00
attempt = $(( $attempt + 1 ))
2015-01-28 14:57:10 +00:00
else
break
fi
done
}
# Robustly try to add metadata on an instance.
# $1: The name of the instace.
2015-04-17 17:58:26 +00:00
# $2...$n: The metadata key=value pairs to add.
2015-01-28 14:57:10 +00:00
function add-instance-metadata {
2015-04-17 17:58:26 +00:00
local -r instance = $1
shift 1
local -r kvs = ( " $@ " )
2015-01-28 14:57:10 +00:00
detect-project
local attempt = 0
while true; do
2015-04-17 17:58:26 +00:00
if ! gcloud compute instances add-metadata " ${ instance } " \
2015-01-28 14:57:10 +00:00
--project " ${ PROJECT } " \
--zone " ${ ZONE } " \
2015-04-17 17:58:26 +00:00
--metadata " ${ kvs [@] } " ; then
2015-01-28 14:57:10 +00:00
if ( ( attempt > 5 ) ) ; then
2015-04-17 17:58:26 +00:00
echo -e " ${ color_red } Failed to add instance metadata in ${ instance } ${ color_norm } "
2015-01-28 14:57:10 +00:00
exit 2
fi
2015-04-17 17:58:26 +00:00
echo -e " ${ color_yellow } Attempt $(( $attempt + 1 )) failed to add metadata in ${ instance } . Retrying. ${ color_norm } "
2015-01-28 14:57:10 +00:00
attempt = $(( $attempt + 1 ))
else
break
2014-12-09 23:37:06 +00:00
fi
done
}
Change GCE to use standalone Saltstack config:
Change provisioning to pass all variables to both master and node. Run
Salt in a masterless setup on all nodes ala
http://docs.saltstack.com/en/latest/topics/tutorials/quickstart.html,
which involves ensuring Salt daemon is NOT running after install. Kill
Salt master install. And fix push to actually work in this new flow.
As part of this, the GCE Salt config no longer has access to the Salt
mine, which is primarily obnoxious for two reasons: - The minions
can't use Salt to see the master: this is easily fixed by static
config. - The master can't see the list of all the minions: this is
fixed temporarily by static config in util.sh, but later, by other
means (see
https://github.com/GoogleCloudPlatform/kubernetes/issues/156, which
should eventually remove this direction).
As part of it, flatten all of cluster/gce/templates/* into
configure-vm.sh, using a single, separate piece of YAML to drive the
environment variables, rather than constantly rewriting the startup
script.
2015-03-02 22:38:58 +00:00
# Robustly try to add metadata on an instance, from a file.
2015-04-17 17:58:26 +00:00
# $1: The name of the instance.
# $2...$n: The metadata key=file pairs to add.
Change GCE to use standalone Saltstack config:
Change provisioning to pass all variables to both master and node. Run
Salt in a masterless setup on all nodes ala
http://docs.saltstack.com/en/latest/topics/tutorials/quickstart.html,
which involves ensuring Salt daemon is NOT running after install. Kill
Salt master install. And fix push to actually work in this new flow.
As part of this, the GCE Salt config no longer has access to the Salt
mine, which is primarily obnoxious for two reasons: - The minions
can't use Salt to see the master: this is easily fixed by static
config. - The master can't see the list of all the minions: this is
fixed temporarily by static config in util.sh, but later, by other
means (see
https://github.com/GoogleCloudPlatform/kubernetes/issues/156, which
should eventually remove this direction).
As part of it, flatten all of cluster/gce/templates/* into
configure-vm.sh, using a single, separate piece of YAML to drive the
environment variables, rather than constantly rewriting the startup
script.
2015-03-02 22:38:58 +00:00
function add-instance-metadata-from-file {
2015-04-17 17:58:26 +00:00
local -r instance = $1
shift 1
local -r kvs = ( " $@ " )
Change GCE to use standalone Saltstack config:
Change provisioning to pass all variables to both master and node. Run
Salt in a masterless setup on all nodes ala
http://docs.saltstack.com/en/latest/topics/tutorials/quickstart.html,
which involves ensuring Salt daemon is NOT running after install. Kill
Salt master install. And fix push to actually work in this new flow.
As part of this, the GCE Salt config no longer has access to the Salt
mine, which is primarily obnoxious for two reasons: - The minions
can't use Salt to see the master: this is easily fixed by static
config. - The master can't see the list of all the minions: this is
fixed temporarily by static config in util.sh, but later, by other
means (see
https://github.com/GoogleCloudPlatform/kubernetes/issues/156, which
should eventually remove this direction).
As part of it, flatten all of cluster/gce/templates/* into
configure-vm.sh, using a single, separate piece of YAML to drive the
environment variables, rather than constantly rewriting the startup
script.
2015-03-02 22:38:58 +00:00
detect-project
local attempt = 0
while true; do
2015-04-17 17:58:26 +00:00
echo " ${ kvs [@] } "
if ! gcloud compute instances add-metadata " ${ instance } " \
Change GCE to use standalone Saltstack config:
Change provisioning to pass all variables to both master and node. Run
Salt in a masterless setup on all nodes ala
http://docs.saltstack.com/en/latest/topics/tutorials/quickstart.html,
which involves ensuring Salt daemon is NOT running after install. Kill
Salt master install. And fix push to actually work in this new flow.
As part of this, the GCE Salt config no longer has access to the Salt
mine, which is primarily obnoxious for two reasons: - The minions
can't use Salt to see the master: this is easily fixed by static
config. - The master can't see the list of all the minions: this is
fixed temporarily by static config in util.sh, but later, by other
means (see
https://github.com/GoogleCloudPlatform/kubernetes/issues/156, which
should eventually remove this direction).
As part of it, flatten all of cluster/gce/templates/* into
configure-vm.sh, using a single, separate piece of YAML to drive the
environment variables, rather than constantly rewriting the startup
script.
2015-03-02 22:38:58 +00:00
--project " ${ PROJECT } " \
--zone " ${ ZONE } " \
2015-05-23 04:07:09 +00:00
--metadata-from-file " $( join_csv ${ kvs [@] } ) " ; then
Change GCE to use standalone Saltstack config:
Change provisioning to pass all variables to both master and node. Run
Salt in a masterless setup on all nodes ala
http://docs.saltstack.com/en/latest/topics/tutorials/quickstart.html,
which involves ensuring Salt daemon is NOT running after install. Kill
Salt master install. And fix push to actually work in this new flow.
As part of this, the GCE Salt config no longer has access to the Salt
mine, which is primarily obnoxious for two reasons: - The minions
can't use Salt to see the master: this is easily fixed by static
config. - The master can't see the list of all the minions: this is
fixed temporarily by static config in util.sh, but later, by other
means (see
https://github.com/GoogleCloudPlatform/kubernetes/issues/156, which
should eventually remove this direction).
As part of it, flatten all of cluster/gce/templates/* into
configure-vm.sh, using a single, separate piece of YAML to drive the
environment variables, rather than constantly rewriting the startup
script.
2015-03-02 22:38:58 +00:00
if ( ( attempt > 5 ) ) ; then
2015-04-17 17:58:26 +00:00
echo -e " ${ color_red } Failed to add instance metadata in ${ instance } ${ color_norm } "
Change GCE to use standalone Saltstack config:
Change provisioning to pass all variables to both master and node. Run
Salt in a masterless setup on all nodes ala
http://docs.saltstack.com/en/latest/topics/tutorials/quickstart.html,
which involves ensuring Salt daemon is NOT running after install. Kill
Salt master install. And fix push to actually work in this new flow.
As part of this, the GCE Salt config no longer has access to the Salt
mine, which is primarily obnoxious for two reasons: - The minions
can't use Salt to see the master: this is easily fixed by static
config. - The master can't see the list of all the minions: this is
fixed temporarily by static config in util.sh, but later, by other
means (see
https://github.com/GoogleCloudPlatform/kubernetes/issues/156, which
should eventually remove this direction).
As part of it, flatten all of cluster/gce/templates/* into
configure-vm.sh, using a single, separate piece of YAML to drive the
environment variables, rather than constantly rewriting the startup
script.
2015-03-02 22:38:58 +00:00
exit 2
fi
2015-04-17 17:58:26 +00:00
echo -e " ${ color_yellow } Attempt $(( $attempt + 1 )) failed to add metadata in ${ instance } . Retrying. ${ color_norm } "
Change GCE to use standalone Saltstack config:
Change provisioning to pass all variables to both master and node. Run
Salt in a masterless setup on all nodes ala
http://docs.saltstack.com/en/latest/topics/tutorials/quickstart.html,
which involves ensuring Salt daemon is NOT running after install. Kill
Salt master install. And fix push to actually work in this new flow.
As part of this, the GCE Salt config no longer has access to the Salt
mine, which is primarily obnoxious for two reasons: - The minions
can't use Salt to see the master: this is easily fixed by static
config. - The master can't see the list of all the minions: this is
fixed temporarily by static config in util.sh, but later, by other
means (see
https://github.com/GoogleCloudPlatform/kubernetes/issues/156, which
should eventually remove this direction).
As part of it, flatten all of cluster/gce/templates/* into
configure-vm.sh, using a single, separate piece of YAML to drive the
environment variables, rather than constantly rewriting the startup
script.
2015-03-02 22:38:58 +00:00
attempt = $(( $attempt + 1 ))
else
break
fi
done
}
2015-03-10 23:19:05 +00:00
# Quote something appropriate for a yaml string.
Change GCE to use standalone Saltstack config:
Change provisioning to pass all variables to both master and node. Run
Salt in a masterless setup on all nodes ala
http://docs.saltstack.com/en/latest/topics/tutorials/quickstart.html,
which involves ensuring Salt daemon is NOT running after install. Kill
Salt master install. And fix push to actually work in this new flow.
As part of this, the GCE Salt config no longer has access to the Salt
mine, which is primarily obnoxious for two reasons: - The minions
can't use Salt to see the master: this is easily fixed by static
config. - The master can't see the list of all the minions: this is
fixed temporarily by static config in util.sh, but later, by other
means (see
https://github.com/GoogleCloudPlatform/kubernetes/issues/156, which
should eventually remove this direction).
As part of it, flatten all of cluster/gce/templates/* into
configure-vm.sh, using a single, separate piece of YAML to drive the
environment variables, rather than constantly rewriting the startup
script.
2015-03-02 22:38:58 +00:00
#
2015-03-10 23:19:05 +00:00
# TODO(zmerlynn): Note that this function doesn't so much "quote" as
# "strip out quotes", and we really should be using a YAML library for
# this, but PyYAML isn't shipped by default, and *rant rant rant ... SIGH*
function yaml-quote {
echo " ' $( echo " ${ @ } " | sed -e "s/'/''/g" ) ' "
Change GCE to use standalone Saltstack config:
Change provisioning to pass all variables to both master and node. Run
Salt in a masterless setup on all nodes ala
http://docs.saltstack.com/en/latest/topics/tutorials/quickstart.html,
which involves ensuring Salt daemon is NOT running after install. Kill
Salt master install. And fix push to actually work in this new flow.
As part of this, the GCE Salt config no longer has access to the Salt
mine, which is primarily obnoxious for two reasons: - The minions
can't use Salt to see the master: this is easily fixed by static
config. - The master can't see the list of all the minions: this is
fixed temporarily by static config in util.sh, but later, by other
means (see
https://github.com/GoogleCloudPlatform/kubernetes/issues/156, which
should eventually remove this direction).
As part of it, flatten all of cluster/gce/templates/* into
configure-vm.sh, using a single, separate piece of YAML to drive the
environment variables, rather than constantly rewriting the startup
script.
2015-03-02 22:38:58 +00:00
}
function write-master-env {
build-kube-env true " ${ KUBE_TEMP } /master-kube-env.yaml "
}
function write-node-env {
build-kube-env false " ${ KUBE_TEMP } /node-kube-env.yaml "
}
2015-05-11 18:43:44 +00:00
# Create certificate pairs for the cluster.
# $1: The public IP for the master.
#
# These are used for static cert distribution (e.g. static clustering) at
# cluster creation time. This will be obsoleted once we implement dynamic
# clustering.
#
# The following certificate pairs are created:
#
# - ca (the cluster's certificate authority)
# - server
# - kubelet
# - kubecfg (for kubectl)
#
# TODO(roberthbailey): Replace easyrsa with a simple Go program to generate
# the certs that we need.
#
# Assumed vars
# KUBE_TEMP
#
# Vars set:
# CERT_DIR
# CA_CERT_BASE64
# MASTER_CERT_BASE64
# MASTER_KEY_BASE64
# KUBELET_CERT_BASE64
# KUBELET_KEY_BASE64
# KUBECFG_CERT_BASE64
# KUBECFG_KEY_BASE64
function create-certs {
2015-06-19 20:04:16 +00:00
local -r cert_ip = " ${ 1 } "
2015-07-04 14:36:44 +00:00
local octets = ( $( echo " $SERVICE_CLUSTER_IP_RANGE " | sed -e 's|/.*||' -e 's/\./ /g' ) )
( ( octets[ 3] += 1) )
local -r service_ip = $( echo " ${ octets [*] } " | sed 's/ /./g' )
2015-06-19 20:04:16 +00:00
local -r sans = " IP: ${ cert_ip } ,IP: ${ service_ip } ,DNS:kubernetes,DNS:kubernetes.default,DNS:kubernetes.default.svc,DNS:kubernetes.default.svc. ${ DNS_DOMAIN } ,DNS: ${ MASTER_NAME } "
2015-05-11 18:43:44 +00:00
# Note: This was heavily cribbed from make-ca-cert.sh
( cd " ${ KUBE_TEMP } "
curl -L -O https://storage.googleapis.com/kubernetes-release/easy-rsa/easy-rsa.tar.gz > /dev/null 2>& 1
tar xzf easy-rsa.tar.gz > /dev/null 2>& 1
cd easy-rsa-master/easyrsa3
./easyrsa init-pki > /dev/null 2>& 1
./easyrsa --batch " --req-cn= ${ cert_ip } @ $( date +%s) " build-ca nopass > /dev/null 2>& 1
2015-06-19 20:04:16 +00:00
./easyrsa --subject-alt-name= " ${ sans } " build-server-full " ${ MASTER_NAME } " nopass > /dev/null 2>& 1
2015-05-11 18:43:44 +00:00
./easyrsa build-client-full kubelet nopass > /dev/null 2>& 1
./easyrsa build-client-full kubecfg nopass > /dev/null 2>& 1) || {
# If there was an error in the subshell, just die.
# TODO(roberthbailey): add better error handling here
echo "=== Failed to generate certificates: Aborting ==="
exit 2
}
CERT_DIR = " ${ KUBE_TEMP } /easy-rsa-master/easyrsa3 "
2015-06-10 00:02:35 +00:00
# By default, linux wraps base64 output every 76 cols, so we use 'tr -d' to remove whitespaces.
# Note 'base64 -w0' doesn't work on Mac OS X, which has different flags.
2015-05-14 22:39:26 +00:00
CA_CERT_BASE64 = $( cat " ${ CERT_DIR } /pki/ca.crt " | base64 | tr -d '\r\n' )
MASTER_CERT_BASE64 = $( cat " ${ CERT_DIR } /pki/issued/ ${ MASTER_NAME } .crt " | base64 | tr -d '\r\n' )
MASTER_KEY_BASE64 = $( cat " ${ CERT_DIR } /pki/private/ ${ MASTER_NAME } .key " | base64 | tr -d '\r\n' )
KUBELET_CERT_BASE64 = $( cat " ${ CERT_DIR } /pki/issued/kubelet.crt " | base64 | tr -d '\r\n' )
KUBELET_KEY_BASE64 = $( cat " ${ CERT_DIR } /pki/private/kubelet.key " | base64 | tr -d '\r\n' )
KUBECFG_CERT_BASE64 = $( cat " ${ CERT_DIR } /pki/issued/kubecfg.crt " | base64 | tr -d '\r\n' )
KUBECFG_KEY_BASE64 = $( cat " ${ CERT_DIR } /pki/private/kubecfg.key " | base64 | tr -d '\r\n' )
2015-05-11 18:43:44 +00:00
}
2014-07-14 17:50:04 +00:00
# Instantiate a kubernetes cluster
2014-09-23 22:54:27 +00:00
#
# Assumed vars
2014-10-03 21:58:49 +00:00
# KUBE_ROOT
2014-09-23 22:54:27 +00:00
# <Various vars set in config file>
2014-07-14 17:50:04 +00:00
function kube-up {
Change GCE to use standalone Saltstack config:
Change provisioning to pass all variables to both master and node. Run
Salt in a masterless setup on all nodes ala
http://docs.saltstack.com/en/latest/topics/tutorials/quickstart.html,
which involves ensuring Salt daemon is NOT running after install. Kill
Salt master install. And fix push to actually work in this new flow.
As part of this, the GCE Salt config no longer has access to the Salt
mine, which is primarily obnoxious for two reasons: - The minions
can't use Salt to see the master: this is easily fixed by static
config. - The master can't see the list of all the minions: this is
fixed temporarily by static config in util.sh, but later, by other
means (see
https://github.com/GoogleCloudPlatform/kubernetes/issues/156, which
should eventually remove this direction).
As part of it, flatten all of cluster/gce/templates/* into
configure-vm.sh, using a single, separate piece of YAML to drive the
environment variables, rather than constantly rewriting the startup
script.
2015-03-02 22:38:58 +00:00
ensure-temp-dir
2014-07-14 17:50:04 +00:00
detect-project
2015-04-28 05:39:39 +00:00
get-password
2015-04-17 21:04:14 +00:00
get-bearer-token
Change GCE to use standalone Saltstack config:
Change provisioning to pass all variables to both master and node. Run
Salt in a masterless setup on all nodes ala
http://docs.saltstack.com/en/latest/topics/tutorials/quickstart.html,
which involves ensuring Salt daemon is NOT running after install. Kill
Salt master install. And fix push to actually work in this new flow.
As part of this, the GCE Salt config no longer has access to the Salt
mine, which is primarily obnoxious for two reasons: - The minions
can't use Salt to see the master: this is easily fixed by static
config. - The master can't see the list of all the minions: this is
fixed temporarily by static config in util.sh, but later, by other
means (see
https://github.com/GoogleCloudPlatform/kubernetes/issues/156, which
should eventually remove this direction).
As part of it, flatten all of cluster/gce/templates/* into
configure-vm.sh, using a single, separate piece of YAML to drive the
environment variables, rather than constantly rewriting the startup
script.
2015-03-02 22:38:58 +00:00
2014-09-23 22:54:27 +00:00
# Make sure we have the tar files staged on Google Storage
find-release-tars
upload-server-tars
2014-09-24 17:55:58 +00:00
2015-06-15 16:21:27 +00:00
local running_in_terminal = false
# May be false if tty is not allocated (for example with ssh -T).
if [ -t 1 ] ; then
running_in_terminal = true
fi
2015-06-19 20:04:16 +00:00
if [ [ ${ running_in_terminal } = = "true" || ${ KUBE_UP_AUTOMATIC_CLEANUP } = = "true" ] ] ; then
2015-06-15 16:21:27 +00:00
if ! check-resources; then
local run_kube_down = "n"
echo " ${ KUBE_RESOURCE_FOUND } found. " >& 2
# Get user input only if running in terminal.
if [ [ ${ running_in_terminal } = = "true" && ${ KUBE_UP_AUTOMATIC_CLEANUP } = = "false" ] ] ; then
read -p "Would you like to shut down the old cluster (call kube-down)? [y/N] " run_kube_down
fi
if [ [ ${ run_kube_down } = = "y" || ${ run_kube_down } = = "Y" || ${ KUBE_UP_AUTOMATIC_CLEANUP } = = "true" ] ] ; then
echo "... calling kube-down" >& 2
kube-down
fi
fi
fi
2015-01-07 23:02:35 +00:00
if ! gcloud compute networks --project " ${ PROJECT } " describe " ${ NETWORK } " & >/dev/null; then
2014-11-25 18:32:27 +00:00
echo " Creating new network: ${ NETWORK } "
2014-09-24 17:55:58 +00:00
# The network needs to be created synchronously or we have a race. The
# firewalls can be added concurrent with instance creation.
2015-01-07 23:02:35 +00:00
gcloud compute networks create --project " ${ PROJECT } " " ${ NETWORK } " --range "10.240.0.0/16"
2014-10-28 20:47:49 +00:00
fi
2015-01-07 23:02:35 +00:00
if ! gcloud compute firewall-rules --project " ${ PROJECT } " describe " ${ NETWORK } -default-internal " & >/dev/null; then
2014-11-25 18:32:27 +00:00
gcloud compute firewall-rules create " ${ NETWORK } -default-internal " \
2014-09-24 23:03:38 +00:00
--project " ${ PROJECT } " \
--network " ${ NETWORK } " \
2014-11-25 18:32:27 +00:00
--source-ranges "10.0.0.0/8" \
2015-05-23 04:07:09 +00:00
--allow "tcp:1-65535,udp:1-65535,icmp" &
2014-10-28 20:47:49 +00:00
fi
2015-01-07 23:02:35 +00:00
if ! gcloud compute firewall-rules describe --project " ${ PROJECT } " " ${ NETWORK } -default-ssh " & >/dev/null; then
2014-11-25 18:32:27 +00:00
gcloud compute firewall-rules create " ${ NETWORK } -default-ssh " \
2014-09-24 23:03:38 +00:00
--project " ${ PROJECT } " \
--network " ${ NETWORK } " \
2014-11-25 18:32:27 +00:00
--source-ranges "0.0.0.0/0" \
--allow "tcp:22" &
2014-09-24 23:03:38 +00:00
fi
Change GCE to use standalone Saltstack config:
Change provisioning to pass all variables to both master and node. Run
Salt in a masterless setup on all nodes ala
http://docs.saltstack.com/en/latest/topics/tutorials/quickstart.html,
which involves ensuring Salt daemon is NOT running after install. Kill
Salt master install. And fix push to actually work in this new flow.
As part of this, the GCE Salt config no longer has access to the Salt
mine, which is primarily obnoxious for two reasons: - The minions
can't use Salt to see the master: this is easily fixed by static
config. - The master can't see the list of all the minions: this is
fixed temporarily by static config in util.sh, but later, by other
means (see
https://github.com/GoogleCloudPlatform/kubernetes/issues/156, which
should eventually remove this direction).
As part of it, flatten all of cluster/gce/templates/* into
configure-vm.sh, using a single, separate piece of YAML to drive the
environment variables, rather than constantly rewriting the startup
script.
2015-03-02 22:38:58 +00:00
echo "Starting master and configuring firewalls"
2014-11-25 18:32:27 +00:00
gcloud compute firewall-rules create " ${ MASTER_NAME } -https " \
2014-10-06 20:25:27 +00:00
--project " ${ PROJECT } " \
--network " ${ NETWORK } " \
2014-11-25 18:32:27 +00:00
--target-tags " ${ MASTER_TAG } " \
--allow tcp:443 &
2014-07-14 17:50:04 +00:00
2015-02-23 21:57:09 +00:00
# We have to make sure the disk is created before creating the master VM, so
# run this in the foreground.
gcloud compute disks create " ${ MASTER_NAME } -pd " \
--project " ${ PROJECT } " \
--zone " ${ ZONE } " \
2015-05-11 12:30:57 +00:00
--type " ${ MASTER_DISK_TYPE } " \
--size " ${ MASTER_DISK_SIZE } "
2015-02-23 21:57:09 +00:00
2015-04-22 17:55:08 +00:00
# Generate a bearer token for this cluster. We push this separately
# from the other cluster variables so that the client (this
Change GCE to use standalone Saltstack config:
Change provisioning to pass all variables to both master and node. Run
Salt in a masterless setup on all nodes ala
http://docs.saltstack.com/en/latest/topics/tutorials/quickstart.html,
which involves ensuring Salt daemon is NOT running after install. Kill
Salt master install. And fix push to actually work in this new flow.
As part of this, the GCE Salt config no longer has access to the Salt
mine, which is primarily obnoxious for two reasons: - The minions
can't use Salt to see the master: this is easily fixed by static
config. - The master can't see the list of all the minions: this is
fixed temporarily by static config in util.sh, but later, by other
means (see
https://github.com/GoogleCloudPlatform/kubernetes/issues/156, which
should eventually remove this direction).
As part of it, flatten all of cluster/gce/templates/* into
configure-vm.sh, using a single, separate piece of YAML to drive the
environment variables, rather than constantly rewriting the startup
script.
2015-03-02 22:38:58 +00:00
# computer) can forget it later. This should disappear with
# https://github.com/GoogleCloudPlatform/kubernetes/issues/3168
KUBELET_TOKEN = $( dd if = /dev/urandom bs = 128 count = 1 2>/dev/null | base64 | tr -d "=+/" | dd bs = 32 count = 1 2>/dev/null)
Generate a token for kube-proxy.
Tested on GCE.
Includes untested modifications for AWS and Vagrant.
No changes for any other distros.
Probably will work on other up-to-date providers
but beware. Symptom would be that service proxying
stops working.
1. Generates a token kube-proxy in AWS, GCE, and Vagrant setup scripts.
1. Distributes the token via salt-overlay, and salt to /var/lib/kube-proxy/kubeconfig
1. Changes kube-proxy args:
- use the --kubeconfig argument
- changes --master argument from http://MASTER:7080 to https://MASTER
- http -> https
- explicit port 7080 -> implied 443
Possible ways this might break other distros:
Mitigation: there is an default empty kubeconfig file.
If the distro does not populate the salt-overlay, then
it should get the empty, which parses to an empty
object, which, combined with the --master argument,
should still work.
Mitigation:
- azure: Special case to use 7080 in
- rackspace: way out of date, so don't care.
- vsphere: way out of date, so don't care.
- other distros: not using salt.
2015-04-24 16:27:11 +00:00
KUBE_PROXY_TOKEN = $( dd if = /dev/urandom bs = 128 count = 1 2>/dev/null | base64 | tr -d "=+/" | dd bs = 32 count = 1 2>/dev/null)
2014-09-24 17:55:58 +00:00
2015-04-17 17:35:19 +00:00
# Reserve the master's IP so that it can later be transferred to another VM
# without disrupting the kubelets. IPs are associated with regions, not zones,
# so extract the region name, which is the same as the zone but with the final
# dash and characters trailing the dash removed.
local REGION = ${ ZONE %-* }
MASTER_RESERVED_IP = $( gcloud compute addresses create " ${ MASTER_NAME } -ip " \
--project " ${ PROJECT } " \
--region " ${ REGION } " -q --format yaml | awk '/^address:/ { print $2 }' )
2015-05-11 18:43:44 +00:00
create-certs " ${ MASTER_RESERVED_IP } "
create-master-instance " ${ MASTER_RESERVED_IP } " &
2014-07-14 17:50:04 +00:00
2014-12-16 18:22:29 +00:00
# Create a single firewall rule for all minions.
create-firewall-rule " ${ MINION_TAG } -all " " ${ CLUSTER_IP_RANGE } " " ${ MINION_TAG } " &
2014-12-09 23:37:06 +00:00
2015-02-23 21:57:09 +00:00
# Report logging choice (if any).
if [ [ " ${ ENABLE_NODE_LOGGING - } " = = "true" ] ] ; then
echo " +++ Logging using Fluentd to ${ LOGGING_DESTINATION :- unknown } "
fi
Change GCE to use standalone Saltstack config:
Change provisioning to pass all variables to both master and node. Run
Salt in a masterless setup on all nodes ala
http://docs.saltstack.com/en/latest/topics/tutorials/quickstart.html,
which involves ensuring Salt daemon is NOT running after install. Kill
Salt master install. And fix push to actually work in this new flow.
As part of this, the GCE Salt config no longer has access to the Salt
mine, which is primarily obnoxious for two reasons: - The minions
can't use Salt to see the master: this is easily fixed by static
config. - The master can't see the list of all the minions: this is
fixed temporarily by static config in util.sh, but later, by other
means (see
https://github.com/GoogleCloudPlatform/kubernetes/issues/156, which
should eventually remove this direction).
As part of it, flatten all of cluster/gce/templates/* into
configure-vm.sh, using a single, separate piece of YAML to drive the
environment variables, rather than constantly rewriting the startup
script.
2015-03-02 22:38:58 +00:00
# Wait for last batch of jobs
2014-12-09 23:37:06 +00:00
wait-for-jobs
Change GCE to use standalone Saltstack config:
Change provisioning to pass all variables to both master and node. Run
Salt in a masterless setup on all nodes ala
http://docs.saltstack.com/en/latest/topics/tutorials/quickstart.html,
which involves ensuring Salt daemon is NOT running after install. Kill
Salt master install. And fix push to actually work in this new flow.
As part of this, the GCE Salt config no longer has access to the Salt
mine, which is primarily obnoxious for two reasons: - The minions
can't use Salt to see the master: this is easily fixed by static
config. - The master can't see the list of all the minions: this is
fixed temporarily by static config in util.sh, but later, by other
means (see
https://github.com/GoogleCloudPlatform/kubernetes/issues/156, which
should eventually remove this direction).
As part of it, flatten all of cluster/gce/templates/* into
configure-vm.sh, using a single, separate piece of YAML to drive the
environment variables, rather than constantly rewriting the startup
script.
2015-03-02 22:38:58 +00:00
echo "Creating minions."
2014-12-09 23:37:06 +00:00
2015-05-08 00:41:22 +00:00
# TODO(mbforbes): Refactor setting scope flags.
2015-06-29 23:47:36 +00:00
local scope_flags =
if [ -n " ${ MINION_SCOPES } " ] ; then
scope_flags = " --scopes ${ MINION_SCOPES } "
2014-12-09 23:37:06 +00:00
else
2015-06-29 23:47:36 +00:00
scope_flags = "--no-scopes"
2014-12-09 23:37:06 +00:00
fi
2015-01-28 14:57:10 +00:00
Change GCE to use standalone Saltstack config:
Change provisioning to pass all variables to both master and node. Run
Salt in a masterless setup on all nodes ala
http://docs.saltstack.com/en/latest/topics/tutorials/quickstart.html,
which involves ensuring Salt daemon is NOT running after install. Kill
Salt master install. And fix push to actually work in this new flow.
As part of this, the GCE Salt config no longer has access to the Salt
mine, which is primarily obnoxious for two reasons: - The minions
can't use Salt to see the master: this is easily fixed by static
config. - The master can't see the list of all the minions: this is
fixed temporarily by static config in util.sh, but later, by other
means (see
https://github.com/GoogleCloudPlatform/kubernetes/issues/156, which
should eventually remove this direction).
As part of it, flatten all of cluster/gce/templates/* into
configure-vm.sh, using a single, separate piece of YAML to drive the
environment variables, rather than constantly rewriting the startup
script.
2015-03-02 22:38:58 +00:00
write-node-env
2015-04-28 08:22:25 +00:00
create-node-instance-template
2015-01-28 14:57:10 +00:00
gcloud preview managed-instance-groups --zone " ${ ZONE } " \
create " ${ NODE_INSTANCE_PREFIX } -group " \
--project " ${ PROJECT } " \
--base-instance-name " ${ NODE_INSTANCE_PREFIX } " \
--size " ${ NUM_MINIONS } " \
--template " ${ NODE_INSTANCE_PREFIX } -template " || true;
# TODO: this should be true when the above create managed-instance-group
# command returns, but currently it returns before the instances come up due
# to gcloud's deficiency.
wait-for-minions-to-run
detect-minion-names
2015-03-10 15:59:19 +00:00
detect-master
2015-07-08 14:48:33 +00:00
# Create autoscaler for nodes if requested
if [ [ " ${ ENABLE_NODE_AUTOSCALER } " = = "true" ] ] ; then
METRICS = ""
METRICS += "--custom-metric-utilization metric=custom.cloudmonitoring.googleapis.com/kubernetes.io/cpu/node_utilization,"
METRICS += " utilization-target= ${ TARGET_NODE_UTILIZATION } ,utilization-target-type=GAUGE "
METRICS += "--custom-metric-utilization metric=custom.cloudmonitoring.googleapis.com/kubernetes.io/memory/node_utilization,"
METRICS += " utilization-target= ${ TARGET_NODE_UTILIZATION } ,utilization-target-type=GAUGE "
echo "Creating node autoscaler."
gcloud preview autoscaler --zone " ${ ZONE } " create " ${ NODE_INSTANCE_PREFIX } -autoscaler " --target " ${ NODE_INSTANCE_PREFIX } -group " \
--min-num-replicas " ${ AUTOSCALER_MIN_NODES } " --max-num-replicas " ${ AUTOSCALER_MAX_NODES } " ${ METRICS } || true
fi
2014-07-14 17:50:04 +00:00
echo "Waiting for cluster initialization."
echo
echo " This will continually check to see if the API for kubernetes is reachable."
echo " This might loop forever if there was some uncaught error during start"
echo " up."
echo
2015-05-28 02:53:24 +00:00
# curl in mavericks is borked.
secure = ""
if which sw_vers > /dev/null; then
if [ [ $( sw_vers | grep ProductVersion | awk '{print $2}' ) = "10.9." * ] ] ; then
secure = "--insecure"
fi
fi
2015-05-11 18:43:44 +00:00
until curl --cacert " ${ CERT_DIR } /pki/ca.crt " \
-H " Authorization: Bearer ${ KUBE_BEARER_TOKEN } " \
2015-05-28 02:53:24 +00:00
${ secure } \
2015-04-17 21:04:14 +00:00
--max-time 5 --fail --output /dev/null --silent \
2015-06-30 02:30:14 +00:00
" https:// ${ KUBE_MASTER_IP } /api/v1/pods " ; do
2014-07-14 17:50:04 +00:00
printf "."
sleep 2
done
echo "Kubernetes cluster created."
2014-08-06 16:57:00 +00:00
2015-05-11 18:43:44 +00:00
export KUBE_CERT = " ${ CERT_DIR } /pki/issued/kubecfg.crt "
export KUBE_KEY = " ${ CERT_DIR } /pki/private/kubecfg.key "
export CA_CERT = " ${ CERT_DIR } /pki/ca.crt "
2015-03-06 22:49:25 +00:00
export CONTEXT = " ${ PROJECT } _ ${ INSTANCE_PREFIX } "
2015-02-02 21:49:03 +00:00
(
umask 077
2015-03-06 22:49:25 +00:00
create-kubeconfig
2014-09-23 22:54:27 +00:00
)
2014-12-09 23:37:06 +00:00
echo
echo -e " ${ color_green } Kubernetes cluster is running. The master is running at: "
echo
echo -e " ${ color_yellow } https:// ${ KUBE_MASTER_IP } "
echo
2015-03-06 22:49:25 +00:00
echo -e " ${ color_green } The user name and password to use is located in ${ KUBECONFIG } . ${ color_norm } "
2014-12-09 23:37:06 +00:00
echo
2014-07-14 17:50:04 +00:00
}
2014-12-09 23:07:54 +00:00
# Delete a kubernetes cluster. This is called from test-teardown.
2014-12-09 00:52:43 +00:00
#
# Assumed vars:
# MASTER_NAME
2015-01-28 14:57:10 +00:00
# NODE_INSTANCE_PREFIX
2014-12-09 00:52:43 +00:00
# ZONE
# This function tears down cluster resources 10 at a time to avoid issuing too many
# API calls and exceeding API quota. It is important to bring down the instances before bringing
# down the firewall rules and routes.
2014-07-14 17:50:04 +00:00
function kube-down {
detect-project
echo "Bringing down cluster"
2015-05-12 23:12:15 +00:00
set +e # Do not stop on error
2014-12-09 00:52:43 +00:00
2015-07-08 14:48:33 +00:00
# Delete autoscaler for nodes if present.
local autoscaler
autoscaler = ( $( gcloud preview autoscaler --zone " ${ ZONE } " list \
| awk 'NR >= 2 { print $1 }' \
| grep " ${ NODE_INSTANCE_PREFIX } -autoscaler " ) )
if [ [ " ${ autoscaler :- } " != "" ] ] ; then
gcloud preview autoscaler --zone " ${ ZONE } " delete " ${ NODE_INSTANCE_PREFIX } -autoscaler "
fi
2015-07-09 19:01:06 +00:00
# Get the name of the managed instance group template before we delete the
# managed instange group. (The name of the managed instnace group template may
# change during a cluster upgrade.)
local template = $( get-template " ${ PROJECT } " " ${ ZONE } " " ${ NODE_INSTANCE_PREFIX } -group " )
2015-07-03 20:29:14 +00:00
# The gcloud APIs don't return machine parseable error codes/retry information. Therefore the best we can
2015-05-12 23:12:15 +00:00
# do is parse the output and special case particular responses we are interested in.
2015-06-12 16:27:54 +00:00
if gcloud preview managed-instance-groups --project " ${ PROJECT } " --zone " ${ ZONE } " describe " ${ NODE_INSTANCE_PREFIX } -group " & >/dev/null; then
2015-05-29 18:46:10 +00:00
deleteCmdOutput = $( gcloud preview managed-instance-groups --zone " ${ ZONE } " delete \
--project " ${ PROJECT } " \
--quiet \
" ${ NODE_INSTANCE_PREFIX } -group " )
if [ [ " $deleteCmdOutput " != "" ] ] ; then
2015-07-03 20:29:14 +00:00
# Managed instance group deletion is done asynchronously, we must wait for it to complete, or subsequent steps fail
2015-05-29 18:46:10 +00:00
deleteCmdOperationId = $( echo $deleteCmdOutput | grep "Operation:" | sed "s/.*Operation:[[:space:]]*\([^[:space:]]*\).*/\1/g" )
if [ [ " $deleteCmdOperationId " != "" ] ] ; then
deleteCmdStatus = "PENDING"
while [ [ " $deleteCmdStatus " != "DONE" ] ]
do
sleep 5
2015-06-12 20:43:29 +00:00
deleteCmdOperationOutput = $( gcloud preview managed-instance-groups --zone " ${ ZONE } " --project " ${ PROJECT } " get-operation $deleteCmdOperationId )
2015-05-29 18:46:10 +00:00
deleteCmdStatus = $( echo $deleteCmdOperationOutput | grep -i "status:" | sed "s/.*status:[[:space:]]*\([^[:space:]]*\).*/\1/g" )
echo "Waiting for MIG deletion to complete. Current status: " $deleteCmdStatus
done
fi
2015-05-12 01:51:59 +00:00
fi
fi
2015-01-28 14:57:10 +00:00
2015-07-09 19:01:06 +00:00
if gcloud compute instance-templates describe --project " ${ PROJECT } " " ${ template } " & >/dev/null; then
2015-05-29 18:46:10 +00:00
gcloud compute instance-templates delete \
--project " ${ PROJECT } " \
--quiet \
2015-07-09 19:01:06 +00:00
" ${ template } "
2015-05-29 18:46:10 +00:00
fi
2015-01-28 14:57:10 +00:00
2014-12-09 00:52:43 +00:00
# First delete the master (if it exists).
2015-06-12 20:43:29 +00:00
if gcloud compute instances describe " ${ MASTER_NAME } " --zone " ${ ZONE } " --project " ${ PROJECT } " & >/dev/null; then
2015-05-29 18:46:10 +00:00
gcloud compute instances delete \
--project " ${ PROJECT } " \
--quiet \
--delete-disks all \
--zone " ${ ZONE } " \
" ${ MASTER_NAME } "
fi
Change GCE to use standalone Saltstack config:
Change provisioning to pass all variables to both master and node. Run
Salt in a masterless setup on all nodes ala
http://docs.saltstack.com/en/latest/topics/tutorials/quickstart.html,
which involves ensuring Salt daemon is NOT running after install. Kill
Salt master install. And fix push to actually work in this new flow.
As part of this, the GCE Salt config no longer has access to the Salt
mine, which is primarily obnoxious for two reasons: - The minions
can't use Salt to see the master: this is easily fixed by static
config. - The master can't see the list of all the minions: this is
fixed temporarily by static config in util.sh, but later, by other
means (see
https://github.com/GoogleCloudPlatform/kubernetes/issues/156, which
should eventually remove this direction).
As part of it, flatten all of cluster/gce/templates/* into
configure-vm.sh, using a single, separate piece of YAML to drive the
environment variables, rather than constantly rewriting the startup
script.
2015-03-02 22:38:58 +00:00
2015-05-29 18:46:10 +00:00
# Delete the master pd (possibly leaked by kube-up if master create failed).
2015-06-12 20:43:29 +00:00
if gcloud compute disks describe " ${ MASTER_NAME } " -pd --zone " ${ ZONE } " --project " ${ PROJECT } " & >/dev/null; then
2015-05-29 18:46:10 +00:00
gcloud compute disks delete \
--project " ${ PROJECT } " \
--quiet \
--zone " ${ ZONE } " \
" ${ MASTER_NAME } " -pd
fi
Change GCE to use standalone Saltstack config:
Change provisioning to pass all variables to both master and node. Run
Salt in a masterless setup on all nodes ala
http://docs.saltstack.com/en/latest/topics/tutorials/quickstart.html,
which involves ensuring Salt daemon is NOT running after install. Kill
Salt master install. And fix push to actually work in this new flow.
As part of this, the GCE Salt config no longer has access to the Salt
mine, which is primarily obnoxious for two reasons: - The minions
can't use Salt to see the master: this is easily fixed by static
config. - The master can't see the list of all the minions: this is
fixed temporarily by static config in util.sh, but later, by other
means (see
https://github.com/GoogleCloudPlatform/kubernetes/issues/156, which
should eventually remove this direction).
As part of it, flatten all of cluster/gce/templates/* into
configure-vm.sh, using a single, separate piece of YAML to drive the
environment variables, rather than constantly rewriting the startup
script.
2015-03-02 22:38:58 +00:00
2014-12-09 00:52:43 +00:00
# Find out what minions are running.
local -a minions
minions = ( $( gcloud compute instances list \
--project " ${ PROJECT } " --zone " ${ ZONE } " \
2015-01-28 14:57:10 +00:00
--regexp " ${ NODE_INSTANCE_PREFIX } -.+ " \
2014-12-09 00:52:43 +00:00
| awk 'NR >= 2 { print $1 }' ) )
# If any minions are running, delete them in batches.
while ( ( " ${# minions [@] } " > 0 ) ) ; do
echo Deleting nodes " ${ minions [*] : : 10 } "
gcloud compute instances delete \
2014-11-25 18:32:27 +00:00
--project " ${ PROJECT } " \
--quiet \
2014-12-09 23:37:06 +00:00
--delete-disks boot \
2014-12-09 00:52:43 +00:00
--zone " ${ ZONE } " \
2015-05-12 23:12:15 +00:00
" ${ minions [@] : : 10 } "
2014-12-09 00:52:43 +00:00
minions = ( " ${ minions [@] : 10 } " )
done
2014-08-13 20:26:03 +00:00
2014-12-09 00:52:43 +00:00
# Delete firewall rule for the master.
2015-06-12 20:43:29 +00:00
if gcloud compute firewall-rules describe --project " ${ PROJECT } " " ${ MASTER_NAME } -https " & >/dev/null; then
2015-05-29 18:46:10 +00:00
gcloud compute firewall-rules delete \
--project " ${ PROJECT } " \
--quiet \
" ${ MASTER_NAME } -https "
fi
2014-12-09 00:52:43 +00:00
2014-12-16 18:22:29 +00:00
# Delete firewall rule for minions.
2015-06-17 12:59:12 +00:00
if gcloud compute firewall-rules describe --project " ${ PROJECT } " " ${ MINION_TAG } -all " & >/dev/null; then
2015-05-29 18:46:10 +00:00
gcloud compute firewall-rules delete \
--project " ${ PROJECT } " \
--quiet \
" ${ MINION_TAG } -all "
fi
2014-07-14 17:50:04 +00:00
2014-12-09 00:52:43 +00:00
# Delete routes.
local -a routes
2015-06-02 17:54:35 +00:00
# Clean up all routes w/ names like "<cluster-name>-<node-GUID>"
# e.g. "kubernetes-12345678-90ab-cdef-1234-567890abcdef". The name is
# determined by the node controller on the master.
# Note that this is currently a noop, as synchronously deleting the node MIG
# first allows the master to cleanup routes itself.
local TRUNCATED_PREFIX = " ${ INSTANCE_PREFIX : 0 : 26 } "
2014-12-09 00:52:43 +00:00
routes = ( $( gcloud compute routes list --project " ${ PROJECT } " \
2015-06-02 17:54:35 +00:00
--regexp " ${ TRUNCATED_PREFIX } -.{8}-.{4}-.{4}-.{4}-.{12} " | awk 'NR >= 2 { print $1 }' ) )
2014-12-09 00:52:43 +00:00
while ( ( " ${# routes [@] } " > 0 ) ) ; do
echo Deleting routes " ${ routes [*] : : 10 } "
gcloud compute routes delete \
2014-11-25 18:32:27 +00:00
--project " ${ PROJECT } " \
--quiet \
2015-05-12 23:12:15 +00:00
" ${ routes [@] : : 10 } "
2014-12-09 00:52:43 +00:00
routes = ( " ${ routes [@] : 10 } " )
2014-11-25 18:32:27 +00:00
done
2014-07-14 17:50:04 +00:00
2015-02-22 19:27:16 +00:00
# Delete the master's reserved IP
local REGION = ${ ZONE %-* }
2015-06-12 20:43:29 +00:00
if gcloud compute addresses describe " ${ MASTER_NAME } -ip " --region " ${ REGION } " --project " ${ PROJECT } " & >/dev/null; then
2015-05-29 18:46:10 +00:00
gcloud compute addresses delete \
--project " ${ PROJECT } " \
--region " ${ REGION } " \
--quiet \
" ${ MASTER_NAME } -ip "
fi
2015-02-22 19:27:16 +00:00
2015-03-06 22:49:25 +00:00
export CONTEXT = " ${ PROJECT } _ ${ INSTANCE_PREFIX } "
clear-kubeconfig
2015-05-12 23:12:15 +00:00
set -e
2014-07-14 17:50:04 +00:00
}
2015-07-09 19:01:06 +00:00
# Gets the instance template for the managed instance group with the provided
# project, zone, and group name. It echos the template name so that the function
# output can be used.
#
# $1: project
# $2: zone
# $3: managed instance group name
function get-template {
# url is set to https://www.googleapis.com/compute/v1/projects/$1/global/instanceTemplates/<template>
local url = $( gcloud preview managed-instance-groups --project= " ${ 1 } " --zone= " ${ 2 } " describe " ${ 3 } " | grep instanceTemplate)
# template is set to <template> (the pattern strips off all but last slash)
local template = " ${ url ##*/ } "
echo " ${ template } "
}
2015-06-15 16:21:27 +00:00
# Checks if there are any present resources related kubernetes cluster.
#
# Assumed vars:
# MASTER_NAME
# NODE_INSTANCE_PREFIX
# ZONE
# Vars set:
# KUBE_RESOURCE_FOUND
function check-resources {
detect-project
echo "Looking for already existing resources"
KUBE_RESOURCE_FOUND = ""
if gcloud preview managed-instance-groups --project " ${ PROJECT } " --zone " ${ ZONE } " describe " ${ NODE_INSTANCE_PREFIX } -group " & >/dev/null; then
KUBE_RESOURCE_FOUND = " Managed instance group ${ NODE_INSTANCE_PREFIX } -group "
return 1
fi
2015-06-17 12:59:12 +00:00
if gcloud compute instance-templates describe --project " ${ PROJECT } " " ${ NODE_INSTANCE_PREFIX } -template " & >/dev/null; then
2015-06-15 16:21:27 +00:00
KUBE_RESOURCE_FOUND = " Instance template ${ NODE_INSTANCE_PREFIX } -template "
return 1
fi
2015-06-17 12:59:12 +00:00
if gcloud compute instances describe --project " ${ PROJECT } " " ${ MASTER_NAME } " --zone " ${ ZONE } " & >/dev/null; then
2015-06-15 16:21:27 +00:00
KUBE_RESOURCE_FOUND = " Kubernetes master ${ MASTER_NAME } "
return 1
fi
2015-06-17 12:59:12 +00:00
if gcloud compute disks describe --project " ${ PROJECT } " " ${ MASTER_NAME } " -pd --zone " ${ ZONE } " & >/dev/null; then
2015-06-15 16:21:27 +00:00
KUBE_RESOURCE_FOUND = " Persistent disk ${ MASTER_NAME } -pd "
return 1
fi
# Find out what minions are running.
local -a minions
minions = ( $( gcloud compute instances list \
--project " ${ PROJECT } " --zone " ${ ZONE } " \
--regexp " ${ NODE_INSTANCE_PREFIX } -.+ " \
| awk 'NR >= 2 { print $1 }' ) )
if ( ( " ${# minions [@] } " > 0 ) ) ; then
KUBE_RESOURCE_FOUND = " ${# minions [@] } matching matching ${ NODE_INSTANCE_PREFIX } -.+ "
return 1
fi
2015-06-17 12:59:12 +00:00
if gcloud compute firewall-rules describe --project " ${ PROJECT } " " ${ MASTER_NAME } -https " & >/dev/null; then
2015-06-19 15:17:06 +00:00
KUBE_RESOURCE_FOUND = " Firewall rules for ${ MASTER_NAME } -https "
2015-06-15 16:21:27 +00:00
return 1
fi
2015-06-17 12:59:12 +00:00
if gcloud compute firewall-rules describe --project " ${ PROJECT } " " ${ MINION_TAG } -all " & >/dev/null; then
2015-06-19 15:17:06 +00:00
KUBE_RESOURCE_FOUND = " Firewall rules for ${ MASTER_NAME } -all "
2015-06-15 16:21:27 +00:00
return 1
fi
local -a routes
routes = ( $( gcloud compute routes list --project " ${ PROJECT } " \
--regexp " ${ INSTANCE_PREFIX } -minion-.{4} " | awk 'NR >= 2 { print $1 }' ) )
if ( ( " ${# routes [@] } " > 0 ) ) ; then
KUBE_RESOURCE_FOUND = " ${# routes [@] } routes matching ${ INSTANCE_PREFIX } -minion-.{4} "
return 1
fi
local REGION = ${ ZONE %-* }
2015-06-17 12:59:12 +00:00
if gcloud compute addresses describe --project " ${ PROJECT } " " ${ MASTER_NAME } -ip " --region " ${ REGION } " & >/dev/null; then
2015-06-15 16:21:27 +00:00
KUBE_RESOURCE_FOUND = "Master's reserved IP"
return 1
fi
# No resources found.
return 0
}
2015-06-01 15:59:12 +00:00
# Prepare to push new binaries to kubernetes cluster
# $1 - whether prepare push to node
function prepare-push( ) {
2015-04-28 15:50:43 +00:00
#TODO(dawnchen): figure out how to upgrade coreos node
if [ [ " ${ OS_DISTRIBUTION } " != "debian" ] ] ; then
echo " Updating a kubernetes cluster with ${ OS_DISTRIBUTION } is not supported yet. " >& 2
2015-06-01 15:59:12 +00:00
exit 1
2015-04-28 15:50:43 +00:00
fi
Change GCE to use standalone Saltstack config:
Change provisioning to pass all variables to both master and node. Run
Salt in a masterless setup on all nodes ala
http://docs.saltstack.com/en/latest/topics/tutorials/quickstart.html,
which involves ensuring Salt daemon is NOT running after install. Kill
Salt master install. And fix push to actually work in this new flow.
As part of this, the GCE Salt config no longer has access to the Salt
mine, which is primarily obnoxious for two reasons: - The minions
can't use Salt to see the master: this is easily fixed by static
config. - The master can't see the list of all the minions: this is
fixed temporarily by static config in util.sh, but later, by other
means (see
https://github.com/GoogleCloudPlatform/kubernetes/issues/156, which
should eventually remove this direction).
As part of it, flatten all of cluster/gce/templates/* into
configure-vm.sh, using a single, separate piece of YAML to drive the
environment variables, rather than constantly rewriting the startup
script.
2015-03-02 22:38:58 +00:00
OUTPUT = ${ KUBE_ROOT } /_output/logs
mkdir -p ${ OUTPUT }
ensure-temp-dir
2014-09-23 22:54:27 +00:00
detect-project
2014-07-14 17:50:04 +00:00
detect-master
Change GCE to use standalone Saltstack config:
Change provisioning to pass all variables to both master and node. Run
Salt in a masterless setup on all nodes ala
http://docs.saltstack.com/en/latest/topics/tutorials/quickstart.html,
which involves ensuring Salt daemon is NOT running after install. Kill
Salt master install. And fix push to actually work in this new flow.
As part of this, the GCE Salt config no longer has access to the Salt
mine, which is primarily obnoxious for two reasons: - The minions
can't use Salt to see the master: this is easily fixed by static
config. - The master can't see the list of all the minions: this is
fixed temporarily by static config in util.sh, but later, by other
means (see
https://github.com/GoogleCloudPlatform/kubernetes/issues/156, which
should eventually remove this direction).
As part of it, flatten all of cluster/gce/templates/* into
configure-vm.sh, using a single, separate piece of YAML to drive the
environment variables, rather than constantly rewriting the startup
script.
2015-03-02 22:38:58 +00:00
detect-minion-names
2015-04-28 05:39:39 +00:00
get-password
2015-04-17 21:04:14 +00:00
get-bearer-token
2014-07-14 17:50:04 +00:00
2014-09-23 22:54:27 +00:00
# Make sure we have the tar files staged on Google Storage
2015-06-01 15:59:12 +00:00
tars_from_version
# Prepare node env vars and update MIG template
if [ [ " ${ 1 - } " = = "true" ] ] ; then
write-node-env
# TODO(mbforbes): Refactor setting scope flags.
2015-06-29 23:47:36 +00:00
local scope_flags =
if [ -n " ${ MINION_SCOPES } " ] ; then
scope_flags = " --scopes ${ MINION_SCOPES } "
2015-06-01 15:59:12 +00:00
else
2015-06-29 23:47:36 +00:00
scope_flags = "--no-scopes"
2015-06-01 15:59:12 +00:00
fi
# Ugly hack: Since it is not possible to delete instance-template that is currently
# being used, create a temp one, then delete the old one and recreate it once again.
create-node-instance-template "tmp"
gcloud preview managed-instance-groups --zone " ${ ZONE } " \
set-template " ${ NODE_INSTANCE_PREFIX } -group " \
--project " ${ PROJECT } " \
--template " ${ NODE_INSTANCE_PREFIX } -template-tmp " || true;
gcloud compute instance-templates delete \
--project " ${ PROJECT } " \
--quiet \
" ${ NODE_INSTANCE_PREFIX } -template " || true
create-node-instance-template
gcloud preview managed-instance-groups --zone " ${ ZONE } " \
set-template " ${ NODE_INSTANCE_PREFIX } -group " \
--project " ${ PROJECT } " \
--template " ${ NODE_INSTANCE_PREFIX } -template " || true;
2014-09-23 22:54:27 +00:00
2015-06-01 15:59:12 +00:00
gcloud compute instance-templates delete \
--project " ${ PROJECT } " \
--quiet \
" ${ NODE_INSTANCE_PREFIX } -template-tmp " || true
fi
}
2014-09-23 22:54:27 +00:00
2015-06-01 15:59:12 +00:00
# Push binaries to kubernetes master
function push-master {
2015-04-17 17:58:26 +00:00
echo "Updating master metadata ..."
Change GCE to use standalone Saltstack config:
Change provisioning to pass all variables to both master and node. Run
Salt in a masterless setup on all nodes ala
http://docs.saltstack.com/en/latest/topics/tutorials/quickstart.html,
which involves ensuring Salt daemon is NOT running after install. Kill
Salt master install. And fix push to actually work in this new flow.
As part of this, the GCE Salt config no longer has access to the Salt
mine, which is primarily obnoxious for two reasons: - The minions
can't use Salt to see the master: this is easily fixed by static
config. - The master can't see the list of all the minions: this is
fixed temporarily by static config in util.sh, but later, by other
means (see
https://github.com/GoogleCloudPlatform/kubernetes/issues/156, which
should eventually remove this direction).
As part of it, flatten all of cluster/gce/templates/* into
configure-vm.sh, using a single, separate piece of YAML to drive the
environment variables, rather than constantly rewriting the startup
script.
2015-03-02 22:38:58 +00:00
write-master-env
2015-04-17 17:58:26 +00:00
add-instance-metadata-from-file " ${ KUBE_MASTER } " " kube-env= ${ KUBE_TEMP } /master-kube-env.yaml " " startup-script= ${ KUBE_ROOT } /cluster/gce/configure-vm.sh "
2015-06-01 15:59:12 +00:00
echo " Pushing to master (log at ${ OUTPUT } /push- ${ KUBE_MASTER } .log) ... "
cat ${ KUBE_ROOT } /cluster/gce/configure-vm.sh | gcloud compute ssh --ssh-flag= "-o LogLevel=quiet" --project " ${ PROJECT } " --zone " ${ ZONE } " " ${ KUBE_MASTER } " --command "sudo bash -s -- --push" & > ${ OUTPUT } /push-" ${ KUBE_MASTER } " .log
}
# Push binaries to kubernetes node
function push-node( ) {
node = ${ 1 }
echo " Updating node ${ node } metadata... "
add-instance-metadata-from-file " ${ node } " " kube-env= ${ KUBE_TEMP } /node-kube-env.yaml " " startup-script= ${ KUBE_ROOT } /cluster/gce/configure-vm.sh "
echo " Start upgrading node ${ node } (log at ${ OUTPUT } /push- ${ node } .log) ... "
cat ${ KUBE_ROOT } /cluster/gce/configure-vm.sh | gcloud compute ssh --ssh-flag= "-o LogLevel=quiet" --project " ${ PROJECT } " --zone " ${ ZONE } " " ${ node } " --command "sudo bash -s -- --push" & > ${ OUTPUT } /push-" ${ node } " .log
}
# Push binaries to kubernetes cluster
function kube-push {
prepare-push true
2014-07-14 17:50:04 +00:00
2015-06-01 15:59:12 +00:00
push-master
2014-07-14 17:50:04 +00:00
2015-06-01 15:59:12 +00:00
for ( ( i = 0; i<${# MINION_NAMES [@] } ; i++) ) ; do
push-node " ${ MINION_NAMES [ $i ] } " &
done
wait-for-jobs
Change GCE to use standalone Saltstack config:
Change provisioning to pass all variables to both master and node. Run
Salt in a masterless setup on all nodes ala
http://docs.saltstack.com/en/latest/topics/tutorials/quickstart.html,
which involves ensuring Salt daemon is NOT running after install. Kill
Salt master install. And fix push to actually work in this new flow.
As part of this, the GCE Salt config no longer has access to the Salt
mine, which is primarily obnoxious for two reasons: - The minions
can't use Salt to see the master: this is easily fixed by static
config. - The master can't see the list of all the minions: this is
fixed temporarily by static config in util.sh, but later, by other
means (see
https://github.com/GoogleCloudPlatform/kubernetes/issues/156, which
should eventually remove this direction).
As part of it, flatten all of cluster/gce/templates/* into
configure-vm.sh, using a single, separate piece of YAML to drive the
environment variables, rather than constantly rewriting the startup
script.
2015-03-02 22:38:58 +00:00
# TODO(zmerlynn): Re-create instance-template with the new
# node-kube-env. This isn't important until the node-ip-range issue
# is solved (because that's blocking automatic dynamic nodes from
2015-04-23 14:41:56 +00:00
# working). The node-kube-env has to be composed with the KUBELET_TOKEN
Generate a token for kube-proxy.
Tested on GCE.
Includes untested modifications for AWS and Vagrant.
No changes for any other distros.
Probably will work on other up-to-date providers
but beware. Symptom would be that service proxying
stops working.
1. Generates a token kube-proxy in AWS, GCE, and Vagrant setup scripts.
1. Distributes the token via salt-overlay, and salt to /var/lib/kube-proxy/kubeconfig
1. Changes kube-proxy args:
- use the --kubeconfig argument
- changes --master argument from http://MASTER:7080 to https://MASTER
- http -> https
- explicit port 7080 -> implied 443
Possible ways this might break other distros:
Mitigation: there is an default empty kubeconfig file.
If the distro does not populate the salt-overlay, then
it should get the empty, which parses to an empty
object, which, combined with the --master argument,
should still work.
Mitigation:
- azure: Special case to use 7080 in
- rackspace: way out of date, so don't care.
- vsphere: way out of date, so don't care.
- other distros: not using salt.
2015-04-24 16:27:11 +00:00
# and KUBE_PROXY_TOKEN. Ideally we would have
Change GCE to use standalone Saltstack config:
Change provisioning to pass all variables to both master and node. Run
Salt in a masterless setup on all nodes ala
http://docs.saltstack.com/en/latest/topics/tutorials/quickstart.html,
which involves ensuring Salt daemon is NOT running after install. Kill
Salt master install. And fix push to actually work in this new flow.
As part of this, the GCE Salt config no longer has access to the Salt
mine, which is primarily obnoxious for two reasons: - The minions
can't use Salt to see the master: this is easily fixed by static
config. - The master can't see the list of all the minions: this is
fixed temporarily by static config in util.sh, but later, by other
means (see
https://github.com/GoogleCloudPlatform/kubernetes/issues/156, which
should eventually remove this direction).
As part of it, flatten all of cluster/gce/templates/* into
configure-vm.sh, using a single, separate piece of YAML to drive the
environment variables, rather than constantly rewriting the startup
script.
2015-03-02 22:38:58 +00:00
# https://github.com/GoogleCloudPlatform/kubernetes/issues/3168
# implemented before then, though, so avoiding this mess until then.
2014-07-14 17:50:04 +00:00
echo
2014-09-29 20:11:31 +00:00
echo "Kubernetes cluster is running. The master is running at:"
echo
echo " https:// ${ KUBE_MASTER_IP } "
echo
2015-04-28 05:39:39 +00:00
echo "The user name and password to use is located in ~/.kube/config"
2014-07-14 17:50:04 +00:00
echo
}
2014-09-23 22:54:27 +00:00
# -----------------------------------------------------------------------------
# Cluster specific test helpers used from hack/e2e-test.sh
# Execute prior to running tests to build a release if required for env.
#
# Assumed Vars:
2014-10-03 21:58:49 +00:00
# KUBE_ROOT
2014-07-14 17:50:04 +00:00
function test-build-release {
# Make a release
2014-10-06 20:25:27 +00:00
" ${ KUBE_ROOT } /build/release.sh "
2014-07-14 17:50:04 +00:00
}
2014-09-23 22:54:27 +00:00
# Execute prior to running tests to initialize required structure. This is
2014-12-09 23:07:54 +00:00
# called from hack/e2e.go only when running -up (it is run after kube-up).
2014-09-23 22:54:27 +00:00
#
# Assumed vars:
# Variables from config.sh
2014-07-14 17:50:04 +00:00
function test-setup {
# Detect the project into $PROJECT if it isn't set
detect-project
2014-10-23 00:49:40 +00:00
# Open up port 80 & 8080 so common containers on minions can be reached
2015-03-02 18:15:34 +00:00
# TODO(roberthbailey): Remove this once we are no longer relying on hostPorts.
2015-06-11 09:39:22 +00:00
local start = ` date +%s`
2014-11-25 18:32:27 +00:00
gcloud compute firewall-rules create \
2014-10-23 00:49:40 +00:00
--project " ${ PROJECT } " \
2014-11-25 18:32:27 +00:00
--target-tags " ${ MINION_TAG } " \
2015-05-25 07:46:24 +00:00
--allow tcp:80,tcp:8080 \
2014-10-23 00:49:40 +00:00
--network " ${ NETWORK } " \
2015-06-11 09:39:22 +00:00
" ${ MINION_TAG } - ${ INSTANCE_PREFIX } -http-alt " 2> /dev/null || true
# As there is no simple way to wait longer for this operation we need to manually
# wait some additional time (20 minutes altogether).
2015-06-12 20:43:29 +00:00
until gcloud compute firewall-rules describe --project " ${ PROJECT } " " ${ MINION_TAG } - ${ INSTANCE_PREFIX } -http-alt " 2> /dev/null || [ $(( $start + 1200 )) -lt ` date +%s` ]
2015-06-11 09:39:22 +00:00
do sleep 5
done
# Check if the firewall rule exists and fail if it does not.
2015-06-12 20:43:29 +00:00
gcloud compute firewall-rules describe --project " ${ PROJECT } " " ${ MINION_TAG } - ${ INSTANCE_PREFIX } -http-alt "
2015-05-23 02:39:40 +00:00
# Open up the NodePort range
# TODO(justinsb): Move to main setup, if we decide whether we want to do this by default.
2015-06-11 09:39:22 +00:00
start = ` date +%s`
2015-05-23 02:39:40 +00:00
gcloud compute firewall-rules create \
--project " ${ PROJECT } " \
--target-tags " ${ MINION_TAG } " \
--allow tcp:30000-32767,udp:30000-32767 \
--network " ${ NETWORK } " \
2015-06-11 09:39:22 +00:00
" ${ MINION_TAG } - ${ INSTANCE_PREFIX } -nodeports " 2> /dev/null || true
# As there is no simple way to wait longer for this operation we need to manually
# wait some additional time (20 minutes altogether).
2015-06-12 20:43:29 +00:00
until gcloud compute firewall-rules describe --project " ${ PROJECT } " " ${ MINION_TAG } - ${ INSTANCE_PREFIX } -nodeports " 2> /dev/null || [ $(( $start + 1200 )) -lt ` date +%s` ]
2015-06-11 09:39:22 +00:00
do sleep 5
done
# Check if the firewall rule exists and fail if it does not.
2015-06-12 20:43:29 +00:00
gcloud compute firewall-rules describe --project " ${ PROJECT } " " ${ MINION_TAG } - ${ INSTANCE_PREFIX } -nodeports "
2014-07-14 17:50:04 +00:00
}
2014-12-09 23:07:54 +00:00
# Execute after running tests to perform any required clean-up. This is called
# from hack/e2e.go
2014-07-14 17:50:04 +00:00
function test-teardown {
2014-12-09 23:07:54 +00:00
detect-project
2014-07-14 17:50:04 +00:00
echo "Shutting down test cluster in background."
2014-11-25 18:32:27 +00:00
gcloud compute firewall-rules delete \
2014-10-06 20:25:27 +00:00
--project " ${ PROJECT } " \
2014-11-25 18:32:27 +00:00
--quiet \
" ${ MINION_TAG } - ${ INSTANCE_PREFIX } -http-alt " || true
2015-05-23 02:39:40 +00:00
gcloud compute firewall-rules delete \
--project " ${ PROJECT } " \
--quiet \
" ${ MINION_TAG } - ${ INSTANCE_PREFIX } -nodeports " || true
2014-11-25 18:32:27 +00:00
" ${ KUBE_ROOT } /cluster/kube-down.sh "
2014-07-14 17:50:04 +00:00
}
2014-10-10 05:38:00 +00:00
# SSH to a node by name ($1) and run a command ($2).
function ssh-to-node {
local node = " $1 "
local cmd = " $2 "
2015-04-21 22:27:38 +00:00
# Loop until we can successfully ssh into the box
2015-01-29 23:50:46 +00:00
for try in $( seq 1 5) ; do
2015-04-22 21:19:15 +00:00
if gcloud compute ssh --ssh-flag= "-o LogLevel=quiet" --project " ${ PROJECT } " --zone= " ${ ZONE } " " ${ node } " --command "echo test > /dev/null" ; then
2015-01-29 23:50:46 +00:00
break
fi
2015-04-21 22:27:38 +00:00
sleep 5
2015-01-29 23:50:46 +00:00
done
2015-04-21 22:27:38 +00:00
# Then actually try the command.
gcloud compute ssh --ssh-flag= "-o LogLevel=quiet" --project " ${ PROJECT } " --zone= " ${ ZONE } " " ${ node } " --command " ${ cmd } "
2014-10-10 05:38:00 +00:00
}
# Restart the kube-proxy on a node ($1)
function restart-kube-proxy {
ssh-to-node " $1 " "sudo /etc/init.d/kube-proxy restart"
}
2014-11-06 19:35:33 +00:00
2015-03-04 20:34:02 +00:00
# Restart the kube-apiserver on a node ($1)
2015-02-11 21:41:42 +00:00
function restart-apiserver {
2015-04-22 22:21:13 +00:00
ssh-to-node " $1 " "sudo docker ps | grep /kube-apiserver | cut -d ' ' -f 1 | xargs sudo docker kill"
2015-02-11 21:41:42 +00:00
}
2014-11-11 19:03:07 +00:00
# Perform preparations required to run e2e tests
function prepare-e2e( ) {
detect-project
}