2014-07-22 22:43:41 +00:00
#!/bin/bash
2016-06-03 00:25:58 +00:00
# Copyright 2014 The Kubernetes Authors.
2014-07-22 22:43:41 +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 for deploying on Rackspace
# Use the config file specified in $KUBE_CONFIG_FILE, or default to
# config-default.sh.
2014-10-12 00:32:53 +00:00
KUBE_ROOT = $( dirname " ${ BASH_SOURCE } " ) /../..
2014-07-22 22:43:41 +00:00
source $( dirname ${ BASH_SOURCE } ) /${ KUBE_CONFIG_FILE - "config-default.sh" }
2015-04-10 00:07:24 +00:00
source " ${ KUBE_ROOT } /cluster/common.sh "
2015-05-07 01:48:30 +00:00
source " ${ KUBE_ROOT } /cluster/rackspace/authorization.sh "
2014-07-22 22:43:41 +00:00
verify-prereqs( ) {
# Make sure that prerequisites are installed.
2014-10-20 17:12:39 +00:00
for x in nova swiftly; do
2014-07-22 22:43:41 +00:00
if [ " $( which $x ) " = = "" ] ; then
echo " cluster/rackspace/util.sh: Can't find $x in PATH, please fix and retry. "
exit 1
fi
done
2014-10-20 17:12:39 +00:00
if [ [ -z " ${ OS_AUTH_URL - } " ] ] ; then
2014-10-20 17:18:34 +00:00
echo "cluster/rackspace/util.sh: OS_AUTH_URL not set."
2014-10-20 17:12:39 +00:00
echo -e "\texport OS_AUTH_URL=https://identity.api.rackspacecloud.com/v2.0/"
return 1
fi
if [ [ -z " ${ OS_USERNAME - } " ] ] ; then
2014-10-20 17:18:34 +00:00
echo "cluster/rackspace/util.sh: OS_USERNAME not set."
2014-10-20 17:12:39 +00:00
echo -e "\texport OS_USERNAME=myusername"
return 1
fi
if [ [ -z " ${ OS_PASSWORD - } " ] ] ; then
2014-10-20 17:18:34 +00:00
echo "cluster/rackspace/util.sh: OS_PASSWORD not set."
2014-10-20 17:12:39 +00:00
echo -e "\texport OS_PASSWORD=myapikey"
return 1
fi
2014-07-22 22:43:41 +00:00
}
rax-ssh-key( ) {
if [ ! -f $HOME /.ssh/${ SSH_KEY_NAME } ] ; then
echo " cluster/rackspace/util.sh: Generating SSH KEY ${ HOME } /.ssh/ ${ SSH_KEY_NAME } "
ssh-keygen -f ${ HOME } /.ssh/${ SSH_KEY_NAME } -N '' > /dev/null
fi
if ! $( nova keypair-list | grep $SSH_KEY_NAME > /dev/null 2>& 1) ; then
echo "cluster/rackspace/util.sh: Uploading key to Rackspace:"
echo -e " \tnova keypair-add ${ SSH_KEY_NAME } --pub-key ${ HOME } /.ssh/ ${ SSH_KEY_NAME } .pub "
nova keypair-add ${ SSH_KEY_NAME } --pub-key ${ HOME } /.ssh/${ SSH_KEY_NAME } .pub > /dev/null 2>& 1
else
echo " cluster/rackspace/util.sh: SSH key ${ SSH_KEY_NAME } .pub already uploaded "
fi
}
2014-10-20 17:12:39 +00:00
rackspace-set-vars( ) {
CLOUDFILES_CONTAINER = " kubernetes-releases- ${ OS_USERNAME } "
CONTAINER_PREFIX = ${ CONTAINER_PREFIX -devel/ }
find-release-tars
}
# Retrieves a tempurl from cloudfiles to make the release object publicly accessible temporarily.
2014-10-12 00:32:53 +00:00
find-object-url( ) {
2014-07-22 22:43:41 +00:00
2014-10-20 17:12:39 +00:00
rackspace-set-vars
2014-10-17 23:05:11 +00:00
2014-10-20 17:12:39 +00:00
KUBE_TAR = ${ CLOUDFILES_CONTAINER } /${ CONTAINER_PREFIX } /kubernetes-server-linux-amd64.tar.gz
2014-10-12 00:32:53 +00:00
2015-03-22 04:34:35 +00:00
# Create temp URL good for 24 hours
RELEASE_TMP_URL = $( swiftly -A ${ OS_AUTH_URL } -U ${ OS_USERNAME } -K ${ OS_PASSWORD } tempurl GET ${ KUBE_TAR } 86400 )
2014-07-22 22:43:41 +00:00
echo "cluster/rackspace/util.sh: Object temp URL:"
2014-10-17 20:10:08 +00:00
echo -e " \t ${ RELEASE_TMP_URL } "
2014-07-22 22:43:41 +00:00
}
2014-10-20 17:12:39 +00:00
ensure_dev_container( ) {
SWIFTLY_CMD = " swiftly -A ${ OS_AUTH_URL } -U ${ OS_USERNAME } -K ${ OS_PASSWORD } "
if ! ${ SWIFTLY_CMD } get ${ CLOUDFILES_CONTAINER } > /dev/null 2>& 1 ; then
2015-02-17 10:48:48 +00:00
echo " cluster/rackspace/util.sh: Container doesn't exist. Creating container ${ CLOUDFILES_CONTAINER } "
2014-10-20 17:12:39 +00:00
${ SWIFTLY_CMD } put ${ CLOUDFILES_CONTAINER } > /dev/null 2>& 1
fi
}
# Copy kubernetes-server-linux-amd64.tar.gz to cloud files object store
copy_dev_tarballs( ) {
echo "cluster/rackspace/util.sh: Uploading to Cloud Files"
2015-10-16 18:28:00 +00:00
${ SWIFTLY_CMD } put -i ${ SERVER_BINARY_TAR } \
2014-10-20 17:12:39 +00:00
${ CLOUDFILES_CONTAINER } /${ CONTAINER_PREFIX } /kubernetes-server-linux-amd64.tar.gz > /dev/null 2>& 1
2015-05-07 01:48:30 +00:00
2014-10-20 17:12:39 +00:00
echo "Release pushed."
}
2015-05-07 01:48:30 +00:00
prep_known_tokens( ) {
2015-09-30 08:17:25 +00:00
for ( ( i = 0; i<${# NODE_NAMES [@] } ; i++) ) ; do
generate_kubelet_tokens ${ NODE_NAMES [i] }
cat ${ KUBE_TEMP } /${ NODE_NAMES [i] } _tokens.csv >> ${ KUBE_TEMP } /known_tokens.csv
2015-05-07 01:48:30 +00:00
done
# Generate tokens for other "service accounts". Append to known_tokens.
#
# NB: If this list ever changes, this script actually has to
# change to detect the existence of this file, kill any deleted
# old tokens and add any new tokens (to handle the upgrade case).
local -r service_accounts = ( "system:scheduler" "system:controller_manager" "system:logging" "system:monitoring" "system:dns" )
for account in " ${ service_accounts [@] } " ; do
echo " $( create_token) , ${ account } , ${ account } " >> ${ KUBE_TEMP } /known_tokens.csv
done
generate_admin_token
}
2014-07-22 22:43:41 +00:00
rax-boot-master( ) {
2016-07-08 08:16:39 +00:00
DISCOVERY_URL = $( curl https://discovery.etcd.io/new?size= 1)
2014-10-12 00:32:53 +00:00
DISCOVERY_ID = $( echo " ${ DISCOVERY_URL } " | cut -f 4 -d /)
echo " cluster/rackspace/util.sh: etcd discovery URL: ${ DISCOVERY_URL } "
# Copy cloud-config to KUBE_TEMP and work some sed magic
sed -e " s|DISCOVERY_ID| ${ DISCOVERY_ID } | " \
2014-12-11 20:18:45 +00:00
-e " s|CLOUD_FILES_URL| ${ RELEASE_TMP_URL //&/ \\ & } | " \
2014-10-12 00:32:53 +00:00
-e " s|KUBE_USER| ${ KUBE_USER } | " \
-e " s|KUBE_PASSWORD| ${ KUBE_PASSWORD } | " \
2015-05-24 05:17:55 +00:00
-e " s|SERVICE_CLUSTER_IP_RANGE| ${ SERVICE_CLUSTER_IP_RANGE } | " \
2016-07-08 08:16:39 +00:00
-e " s|KUBE_NETWORK| ${ KUBE_NETWORK } | " \
2015-02-17 10:48:48 +00:00
-e " s|OS_AUTH_URL| ${ OS_AUTH_URL } | " \
-e " s|OS_USERNAME| ${ OS_USERNAME } | " \
-e " s|OS_PASSWORD| ${ OS_PASSWORD } | " \
-e " s|OS_TENANT_NAME| ${ OS_TENANT_NAME } | " \
-e " s|OS_REGION_NAME| ${ OS_REGION_NAME } | " \
2014-10-12 00:32:53 +00:00
$( dirname $0 ) /rackspace/cloud-config/master-cloud-config.yaml > $KUBE_TEMP /master-cloud-config.yaml
2014-07-22 22:43:41 +00:00
2014-10-20 17:12:39 +00:00
MASTER_BOOT_CMD = " nova boot \
2014-07-22 22:43:41 +00:00
--key-name ${ SSH_KEY_NAME } \
--flavor ${ KUBE_MASTER_FLAVOR } \
--image ${ KUBE_IMAGE } \
--meta ${ MASTER_TAG } \
2014-10-12 00:32:53 +00:00
--meta ETCD = ${ DISCOVERY_ID } \
2014-07-22 22:43:41 +00:00
--user-data ${ KUBE_TEMP } /master-cloud-config.yaml \
--config-drive true \
--nic net-id= ${ NETWORK_UUID } \
${ MASTER_NAME } "
2014-09-29 20:11:31 +00:00
2014-07-22 22:43:41 +00:00
echo " cluster/rackspace/util.sh: Booting ${ MASTER_NAME } with following command: "
echo -e " \t $MASTER_BOOT_CMD "
$MASTER_BOOT_CMD
}
2015-09-30 08:17:25 +00:00
rax-boot-nodes( ) {
2014-07-22 22:43:41 +00:00
2015-09-30 08:17:25 +00:00
cp $( dirname $0 ) /rackspace/cloud-config/node-cloud-config.yaml \
${ KUBE_TEMP } /node-cloud-config.yaml
2014-09-29 20:11:31 +00:00
2015-09-30 08:17:25 +00:00
for ( ( i = 0; i<${# NODE_NAMES [@] } ; i++) ) ; do
2014-07-22 22:43:41 +00:00
2015-09-30 08:17:25 +00:00
get_tokens_from_csv ${ NODE_NAMES [i] }
2015-05-07 01:48:30 +00:00
2014-10-12 00:32:53 +00:00
sed -e " s|DISCOVERY_ID| ${ DISCOVERY_ID } | " \
2014-12-11 21:01:05 +00:00
-e " s|CLOUD_FILES_URL| ${ RELEASE_TMP_URL //&/ \\ & } | " \
2015-05-07 01:48:30 +00:00
-e " s|DNS_SERVER_IP| ${ DNS_SERVER_IP :- } | " \
-e " s|DNS_DOMAIN| ${ DNS_DOMAIN :- } | " \
-e " s|ENABLE_CLUSTER_DNS| ${ ENABLE_CLUSTER_DNS :- false } | " \
2014-11-14 07:07:43 +00:00
-e " s|ENABLE_NODE_LOGGING| ${ ENABLE_NODE_LOGGING :- false } | " \
2015-05-07 01:48:30 +00:00
-e " s|INDEX| $(( i + 1 )) |g " \
2015-05-14 02:38:29 +00:00
-e " s|KUBELET_TOKEN| ${ KUBELET_TOKEN } | " \
2015-05-08 21:13:11 +00:00
-e " s|KUBE_NETWORK| ${ KUBE_NETWORK } | " \
2015-06-04 18:15:36 +00:00
-e " s|KUBELET_TOKEN| ${ KUBELET_TOKEN } | " \
2015-05-07 01:48:30 +00:00
-e " s|KUBE_PROXY_TOKEN| ${ KUBE_PROXY_TOKEN } | " \
2014-11-14 07:07:43 +00:00
-e " s|LOGGING_DESTINATION| ${ LOGGING_DESTINATION :- } | " \
2015-09-30 08:17:25 +00:00
$( dirname $0 ) /rackspace/cloud-config/node-cloud-config.yaml > $KUBE_TEMP /node-cloud-config-$(( $i + 1 )) .yaml
2014-10-12 00:32:53 +00:00
2014-09-29 20:11:31 +00:00
2015-09-30 08:17:25 +00:00
NODE_BOOT_CMD = " nova boot \
2014-07-22 22:43:41 +00:00
--key-name ${ SSH_KEY_NAME } \
2015-09-30 08:17:25 +00:00
--flavor ${ KUBE_NODE_FLAVOR } \
2014-07-22 22:43:41 +00:00
--image ${ KUBE_IMAGE } \
2015-09-30 08:17:25 +00:00
--meta ${ NODE_TAG } \
--user-data ${ KUBE_TEMP } /node-cloud-config-$(( i + 1 )) .yaml \
2014-07-22 22:43:41 +00:00
--config-drive true \
--nic net-id= ${ NETWORK_UUID } \
2015-09-30 08:17:25 +00:00
${ NODE_NAMES [ $i ] } "
2014-09-29 20:11:31 +00:00
2015-09-30 08:17:25 +00:00
echo " cluster/rackspace/util.sh: Booting ${ NODE_NAMES [ $i ] } with following command: "
echo -e " \t $NODE_BOOT_CMD "
$NODE_BOOT_CMD
2014-07-22 22:43:41 +00:00
done
}
rax-nova-network( ) {
if ! $( nova network-list | grep $NOVA_NETWORK_LABEL > /dev/null 2>& 1) ; then
SAFE_CIDR = $( echo $NOVA_NETWORK_CIDR | tr -d '\\' )
NETWORK_CREATE_CMD = " nova network-create $NOVA_NETWORK_LABEL $SAFE_CIDR "
2014-09-29 20:11:31 +00:00
2014-07-22 22:43:41 +00:00
echo "cluster/rackspace/util.sh: Creating cloud network with following command:"
echo -e " \t ${ NETWORK_CREATE_CMD } "
2014-09-29 20:11:31 +00:00
2014-07-22 22:43:41 +00:00
$NETWORK_CREATE_CMD
else
echo " cluster/rackspace/util.sh: Using existing cloud network $NOVA_NETWORK_LABEL "
fi
}
2015-09-30 08:17:25 +00:00
detect-nodes( ) {
KUBE_NODE_IP_ADDRESSES = ( )
for ( ( i = 0; i<${# NODE_NAMES [@] } ; i++) ) ; do
local node_ip = $( nova show --minimal ${ NODE_NAMES [ $i ] } \
2014-07-22 22:43:41 +00:00
| grep accessIPv4 | awk '{print $4}' )
2015-09-30 08:17:25 +00:00
echo " cluster/rackspace/util.sh: Found ${ NODE_NAMES [ $i ] } at ${ node_ip } "
KUBE_NODE_IP_ADDRESSES += ( " ${ node_ip } " )
2014-07-22 22:43:41 +00:00
done
2015-09-30 08:17:25 +00:00
if [ -z " $KUBE_NODE_IP_ADDRESSES " ] ; then
echo "cluster/rackspace/util.sh: Could not detect Kubernetes node nodes. Make sure you've launched a cluster with 'kube-up.sh'"
2014-07-22 22:43:41 +00:00
exit 1
fi
}
detect-master( ) {
KUBE_MASTER = ${ MASTER_NAME }
2014-12-15 22:38:30 +00:00
echo " Waiting for ${ MASTER_NAME } IP Address. "
echo
echo " This will continually check to see if the master node has an IP address."
echo
2014-07-22 22:43:41 +00:00
KUBE_MASTER_IP = $( nova show $KUBE_MASTER --minimal | grep accessIPv4 | awk '{print $4}' )
2014-12-15 22:38:30 +00:00
while [ " ${ KUBE_MASTER_IP -| } " = = "|" ] ; do
KUBE_MASTER_IP = $( nova show $KUBE_MASTER --minimal | grep accessIPv4 | awk '{print $4}' )
printf "."
sleep 2
done
echo " ${ KUBE_MASTER } IP Address is ${ KUBE_MASTER_IP } "
2014-07-22 22:43:41 +00:00
}
# $1 should be the network you would like to get an IP address for
detect-master-nova-net( ) {
KUBE_MASTER = ${ MASTER_NAME }
MASTER_IP = $( nova show $KUBE_MASTER --minimal | grep $1 | awk '{print $5}' )
}
kube-up( ) {
2014-09-29 20:11:31 +00:00
2014-07-22 22:43:41 +00:00
SCRIPT_DIR = $( CDPATH = "" cd $( dirname $0 ) ; pwd )
2014-10-20 17:12:39 +00:00
rackspace-set-vars
ensure_dev_container
copy_dev_tarballs
2014-07-22 22:43:41 +00:00
# Find the release to use. Generally it will be passed when doing a 'prod'
# install and will default to the release/config.sh version when doing a
# developer up.
2014-10-17 20:10:08 +00:00
find-object-url
2014-09-29 20:11:31 +00:00
2015-09-30 08:17:25 +00:00
# Create a temp directory to hold scripts that will be uploaded to master/nodes
2014-07-22 22:43:41 +00:00
KUBE_TEMP = $( mktemp -d -t kubernetes.XXXXXX)
trap " rm -rf ${ KUBE_TEMP } " EXIT
2014-09-29 20:11:31 +00:00
2015-10-26 17:38:53 +00:00
load-or-gen-kube-basicauth
2015-05-05 06:44:27 +00:00
python2.7 $( dirname $0 ) /../third_party/htpasswd/htpasswd.py -b -c ${ KUBE_TEMP } /htpasswd $KUBE_USER $KUBE_PASSWORD
2014-07-22 22:43:41 +00:00
HTPASSWD = $( cat ${ KUBE_TEMP } /htpasswd)
2014-09-29 20:11:31 +00:00
2014-07-22 22:43:41 +00:00
rax-nova-network
NETWORK_UUID = $( nova network-list | grep -i ${ NOVA_NETWORK_LABEL } | awk '{print $2}' )
2014-09-29 20:11:31 +00:00
2014-07-22 22:43:41 +00:00
# create and upload ssh key if necessary
rax-ssh-key
2014-09-29 20:11:31 +00:00
2014-07-22 22:43:41 +00:00
echo "cluster/rackspace/util.sh: Starting Cloud Servers"
2015-05-07 01:48:30 +00:00
prep_known_tokens
2014-07-22 22:43:41 +00:00
rax-boot-master
2015-09-30 08:17:25 +00:00
rax-boot-nodes
2014-09-29 20:11:31 +00:00
2015-06-04 18:15:36 +00:00
detect-master
# TODO look for a better way to get the known_tokens to the master. This is needed over file injection since the files were too large on a 4 node cluster.
2015-06-08 18:45:39 +00:00
$( scp -o StrictHostKeyChecking = no -i ~/.ssh/${ SSH_KEY_NAME } ${ KUBE_TEMP } /known_tokens.csv core@${ KUBE_MASTER_IP } :/home/core/known_tokens.csv)
$( sleep 2)
2015-07-27 23:01:59 +00:00
$( ssh -o StrictHostKeyChecking = no -i ~/.ssh/${ SSH_KEY_NAME } core@${ KUBE_MASTER_IP } sudo /usr/bin/mkdir -p /var/lib/kube-apiserver)
2015-06-04 18:15:36 +00:00
$( ssh -o StrictHostKeyChecking = no -i ~/.ssh/${ SSH_KEY_NAME } core@${ KUBE_MASTER_IP } sudo mv /home/core/known_tokens.csv /var/lib/kube-apiserver/known_tokens.csv)
2017-01-26 21:15:12 +00:00
$( ssh -o StrictHostKeyChecking = no -i ~/.ssh/${ SSH_KEY_NAME } core@${ KUBE_MASTER_IP } sudo chown root:root /var/lib/kube-apiserver/known_tokens.csv)
2015-06-04 18:15:36 +00:00
$( ssh -o StrictHostKeyChecking = no -i ~/.ssh/${ SSH_KEY_NAME } core@${ KUBE_MASTER_IP } sudo systemctl restart kube-apiserver)
2014-07-22 22:43:41 +00:00
FAIL = 0
for job in ` jobs -p`
do
wait $job || let "FAIL+=1"
done
if ( ( $FAIL != 0 ) ) ; then
echo " ${ FAIL } commands failed. Exiting. "
exit 2
fi
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
2014-09-29 20:11:31 +00:00
2014-07-22 22:43:41 +00:00
#This will fail until apiserver salt is updated
2014-10-12 00:32:53 +00:00
until $( curl --insecure --user ${ KUBE_USER } :${ KUBE_PASSWORD } --max-time 5 \
2015-05-13 18:01:35 +00:00
--fail --output /dev/null --silent https://${ KUBE_MASTER_IP } /healthz) ; do
2014-08-29 22:40:25 +00:00
printf "."
sleep 2
done
2014-09-29 20:11:31 +00:00
2014-07-22 22:43:41 +00:00
echo "Kubernetes cluster created."
2014-09-29 20:11:31 +00:00
2015-04-10 00:07:24 +00:00
export KUBE_CERT = ""
export KUBE_KEY = ""
export CA_CERT = ""
export CONTEXT = " rackspace_ ${ INSTANCE_PREFIX } "
create-kubeconfig
2014-07-22 22:43:41 +00:00
# Don't bail on errors, we want to be able to print some info.
set +e
2015-09-30 08:17:25 +00:00
detect-nodes
2014-07-22 22:43:41 +00:00
2015-08-22 01:47:31 +00:00
# ensures KUBECONFIG is set
get-kubeconfig-basicauth
2015-09-30 08:17:25 +00:00
echo "All nodes may not be online yet, this is okay."
2014-07-22 22:43:41 +00:00
echo
2014-09-29 20:11:31 +00:00
echo "Kubernetes cluster is running. The master is running at:"
2014-07-22 22:43:41 +00:00
echo
2014-09-29 20:11:31 +00:00
echo " https:// ${ KUBE_MASTER_IP } "
echo
2015-08-14 05:47:03 +00:00
echo " The user name and password to use is located in ${ KUBECONFIG :- $DEFAULT_KUBECONFIG } . "
2014-07-22 22:43:41 +00:00
echo
echo "Security note: The server above uses a self signed certificate. This is"
echo " subject to \"Man in the middle\" type attacks."
2014-09-29 20:11:31 +00:00
echo
2014-07-22 22:43:41 +00:00
}
2014-11-07 01:23:14 +00:00
2014-11-11 19:03:07 +00:00
# Perform preparations required to run e2e tests
function prepare-e2e( ) {
echo "Rackspace doesn't need special preparations for e2e tests"
}