
Sets up openvpn for container to container communication. Azure deploy scripts create certs used for openvpn conneciton. Salt installs and configures openvpn.
289 lines
9.5 KiB
Bash
289 lines
9.5 KiB
Bash
#!/bin/bash
|
|
|
|
# Copyright 2014 Google Inc. All rights reserved.
|
|
#
|
|
# 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.
|
|
|
|
SCRIPT_DIR=$(CDPATH="" cd $(dirname $0); pwd)
|
|
|
|
# Use the config file specified in $KUBE_CONFIG_FILE, or default to
|
|
# config-default.sh.
|
|
source ${SCRIPT_DIR}/azure/${KUBE_CONFIG_FILE-"config-default.sh"}
|
|
|
|
function detect-minions () {
|
|
ssh_ports=($(eval echo "2200{1..$NUM_MINIONS}"))
|
|
for (( i=0; i<${#MINION_NAMES[@]}; i++)); do
|
|
MINION_NAMES[$i]=$(ssh -i $AZ_SSH_KEY -p ${ssh_ports[$i]} $AZ_CS.cloudapp.net hostname -f)
|
|
done
|
|
}
|
|
|
|
function detect-master () {
|
|
KUBE_MASTER_IP=${AZ_CS}.cloudapp.net
|
|
echo "Using master: $KUBE_MASTER (external IP: $KUBE_MASTER_IP)"
|
|
}
|
|
|
|
function get-password {
|
|
file=${HOME}/.kubernetes_auth
|
|
if [ -e ${file} ]; then
|
|
user=$(cat $file | python -c 'import json,sys;print json.load(sys.stdin)["User"]')
|
|
passwd=$(cat $file | python -c 'import json,sys;print json.load(sys.stdin)["Password"]')
|
|
return
|
|
fi
|
|
user=admin
|
|
passwd=$(python -c 'import string,random; print "".join(random.SystemRandom().choice(string.ascii_letters + string.digits) for _ in range(16))')
|
|
|
|
# Store password for reuse.
|
|
cat << EOF > ~/.kubernetes_auth
|
|
{
|
|
"User": "$user",
|
|
"Password": "$passwd"
|
|
}
|
|
EOF
|
|
chmod 0600 ~/.kubernetes_auth
|
|
}
|
|
|
|
# Verify prereqs
|
|
function verify-prereqs {
|
|
echo "OK"
|
|
# Already done in sourcing config-default, which sources
|
|
# release/azure/config.sh
|
|
}
|
|
|
|
# Instantiate a kubernetes cluster
|
|
function kube-up {
|
|
KUBE_TEMP=$(mktemp -d -t kubernetes.XXXXXX)
|
|
trap "rm -rf ${KUBE_TEMP}" EXIT
|
|
|
|
get-password
|
|
echo "Using password: $user:$passwd"
|
|
python $SCRIPT_DIR/../third_party/htpasswd/htpasswd.py -b -c \
|
|
${KUBE_TEMP}/htpasswd $user $passwd
|
|
HTPASSWD=$(cat ${KUBE_TEMP}/htpasswd)
|
|
|
|
# Generate openvpn certs
|
|
echo 01 > ${KUBE_TEMP}/ca.srl
|
|
openssl genrsa -out ${KUBE_TEMP}/ca.key
|
|
openssl req -new -x509 -days 1095 \
|
|
-key ${KUBE_TEMP}/ca.key \
|
|
-out ${KUBE_TEMP}/ca.crt \
|
|
-subj "/CN=openvpn-ca"
|
|
openssl genrsa -out ${KUBE_TEMP}/server.key
|
|
openssl req -new \
|
|
-key ${KUBE_TEMP}/server.key \
|
|
-out ${KUBE_TEMP}/server.csr \
|
|
-subj "/CN=server"
|
|
openssl x509 -req -days 1095 \
|
|
-in ${KUBE_TEMP}/server.csr \
|
|
-CA ${KUBE_TEMP}/ca.crt \
|
|
-CAkey ${KUBE_TEMP}/ca.key \
|
|
-CAserial ${KUBE_TEMP}/ca.srl \
|
|
-out ${KUBE_TEMP}/server.crt
|
|
for (( i=0; i<${#MINION_NAMES[@]}; i++)); do
|
|
openssl genrsa -out ${KUBE_TEMP}/${MINION_NAMES[$i]}.key
|
|
openssl req -new \
|
|
-key ${KUBE_TEMP}/${MINION_NAMES[$i]}.key \
|
|
-out ${KUBE_TEMP}/${MINION_NAMES[$i]}.csr \
|
|
-subj "/CN=${MINION_NAMES[$i]}"
|
|
openssl x509 -req -days 1095 \
|
|
-in ${KUBE_TEMP}/${MINION_NAMES[$i]}.csr \
|
|
-CA ${KUBE_TEMP}/ca.crt \
|
|
-CAkey ${KUBE_TEMP}/ca.key \
|
|
-CAserial ${KUBE_TEMP}/ca.srl \
|
|
-out ${KUBE_TEMP}/${MINION_NAMES[$i]}.crt
|
|
done
|
|
|
|
# Build up start up script for master
|
|
(
|
|
echo "#!/bin/bash"
|
|
echo "MASTER_NAME=${MASTER_NAME}"
|
|
echo "MASTER_RELEASE_TAR=${FULL_URL}"
|
|
echo "MASTER_HTPASSWD='${HTPASSWD}'"
|
|
echo "CA_CRT=\"$(cat ${KUBE_TEMP}/ca.crt)\""
|
|
echo "SERVER_CRT=\"$(cat ${KUBE_TEMP}/server.crt)\""
|
|
echo "SERVER_KEY=\"$(cat ${KUBE_TEMP}/server.key)\""
|
|
grep -v "^#" $SCRIPT_DIR/azure/templates/download-release.sh
|
|
grep -v "^#" $SCRIPT_DIR/azure/templates/salt-master.sh
|
|
) > ${KUBE_TEMP}/master-start.sh
|
|
|
|
echo "Starting VMs"
|
|
|
|
if [ ! -f $AZ_SSH_KEY ]; then
|
|
ssh-keygen -f $AZ_SSH_KEY -N ''
|
|
fi
|
|
|
|
if [ ! -f $AZ_SSH_CERT ]; then
|
|
openssl req -new -x509 -days 1095 -key $AZ_SSH_KEY -out $AZ_SSH_CERT \
|
|
-subj "/CN=azure-ssh-key"
|
|
fi
|
|
|
|
if [ -z "$(azure network vnet show $AZ_VNET 2>/dev/null | grep data)" ]; then
|
|
#azure network vnet create with $AZ_SUBNET
|
|
#FIXME not working
|
|
echo error create vnet $AZ_VNET with subnet $AZ_SUBNET
|
|
exit 1
|
|
fi
|
|
|
|
azure vm create \
|
|
-w $AZ_VNET \
|
|
-n $MASTER_NAME \
|
|
-l "$AZ_LOCATION" \
|
|
-t $AZ_SSH_CERT \
|
|
-e 22000 -P \
|
|
-d ${KUBE_TEMP}/master-start.sh \
|
|
-b $AZ_SUBNET \
|
|
$AZ_CS $AZ_IMAGE $USER
|
|
|
|
ssh_ports=($(eval echo "2200{1..$NUM_MINIONS}"))
|
|
|
|
for (( i=0; i<${#MINION_NAMES[@]}; i++)); do
|
|
(
|
|
echo "#!/bin/bash"
|
|
echo "MASTER_NAME=${MASTER_NAME}"
|
|
echo "MINION_IP_RANGE=${MINION_IP_RANGES[$i]}"
|
|
echo "CA_CRT=\"$(cat ${KUBE_TEMP}/ca.crt)\""
|
|
echo "CLIENT_CRT=\"$(cat ${KUBE_TEMP}/${MINION_NAMES[$i]}.crt)\""
|
|
echo "CLIENT_KEY=\"$(cat ${KUBE_TEMP}/${MINION_NAMES[$i]}.key)\""
|
|
grep -v "^#" $SCRIPT_DIR/azure/templates/salt-minion.sh
|
|
) > ${KUBE_TEMP}/minion-start-${i}.sh
|
|
|
|
azure vm create \
|
|
-c -w $AZ_VNET \
|
|
-n ${MINION_NAMES[$i]} \
|
|
-l "$AZ_LOCATION" \
|
|
-t $AZ_SSH_CERT \
|
|
-e ${ssh_ports[$i]} -P \
|
|
-d ${KUBE_TEMP}/minion-start-${i}.sh \
|
|
-b $AZ_SUBNET \
|
|
$AZ_CS $AZ_IMAGE $USER
|
|
done
|
|
|
|
azure vm endpoint create $MASTER_NAME 443
|
|
|
|
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
|
|
|
|
until $(curl --insecure --user ${user}:${passwd} --max-time 5 \
|
|
--fail --output /dev/null --silent https://$AZ_CS.cloudapp.net/api/v1beta1/pods); do
|
|
printf "."
|
|
sleep 2
|
|
done
|
|
|
|
# Basic sanity checking
|
|
for (( i=0; i<${#MINION_NAMES[@]}; i++)); do
|
|
# Make sure docker is installed
|
|
ssh -i $AZ_SSH_KEY -p ${ssh_ports[$i]} $AZ_CS.cloudapp.net which docker > /dev/null
|
|
if [ "$?" != "0" ]; then
|
|
echo "Docker failed to install on ${MINION_NAMES[$i]}. Your cluster is unlikely to work correctly."
|
|
echo "Please run ./cluster/kube-down.sh and re-create the cluster. (sorry!)"
|
|
exit 1
|
|
fi
|
|
|
|
# Make sure the kubelet is running
|
|
ssh -i $AZ_SSH_KEY -p ${ssh_ports[$i]} $AZ_CS.cloudapp.net /etc/init.d/kubelet status
|
|
if [ "$?" != "0" ]; then
|
|
echo "Kubelet failed to install on ${MINION_NAMES[$i]}. Your cluster is unlikely to work correctly."
|
|
echo "Please run ./cluster/kube-down.sh and re-create the cluster. (sorry!)"
|
|
exit 1
|
|
fi
|
|
done
|
|
|
|
echo
|
|
echo "Kubernetes cluster is running. Access the master at:"
|
|
echo
|
|
echo " https://${user}:${passwd}@$AZ_CS.cloudapp.net"
|
|
echo
|
|
echo "Security note: The server above uses a self signed certificate. This is"
|
|
echo " subject to \"Man in the middle\" type attacks."
|
|
}
|
|
|
|
# Delete a kubernetes cluster
|
|
function kube-down {
|
|
echo "Bringing down cluster"
|
|
set +e
|
|
azure vm delete $MASTER_NAME -b -q
|
|
for (( i=0; i<${#MINION_NAMES[@]}; i++)); do
|
|
azure vm delete ${MINION_NAMES[$i]} -b -q
|
|
done
|
|
}
|
|
|
|
# # Update a kubernetes cluster with latest source
|
|
# function kube-push {
|
|
|
|
# # 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.
|
|
# find-release $1
|
|
|
|
# # Detect the project into $PROJECT
|
|
# detect-master
|
|
|
|
# (
|
|
# echo MASTER_RELEASE_TAR=$RELEASE_NORMALIZED/master-release.tgz
|
|
# grep -v "^#" $(dirname $0)/templates/download-release.sh
|
|
# echo "echo Executing configuration"
|
|
# echo "sudo salt '*' mine.update"
|
|
# echo "sudo salt --force-color '*' state.highstate"
|
|
# ) | gcutil ssh --project ${PROJECT} --zone ${ZONE} $KUBE_MASTER bash
|
|
|
|
# get-password
|
|
|
|
# echo "Kubernetes cluster is updated. Access the master at:"
|
|
# echo
|
|
# echo " https://${user}:${passwd}@${KUBE_MASTER_IP}"
|
|
# echo
|
|
|
|
# }
|
|
|
|
# # Execute prior to running tests to build a release if required for env
|
|
# function test-build-release {
|
|
# # Build source
|
|
# ${KUBE_REPO_ROOT}/hack/build-go.sh
|
|
# # Make a release
|
|
# $(dirname $0)/../release/release.sh
|
|
# }
|
|
|
|
# # Execute prior to running tests to initialize required structure
|
|
# function test-setup {
|
|
|
|
# # Detect the project into $PROJECT if it isn't set
|
|
# # gce specific
|
|
# detect-project
|
|
|
|
# if [[ ${ALREADY_UP} -ne 1 ]]; then
|
|
# # Open up port 80 & 8080 so common containers on minions can be reached
|
|
# gcutil addfirewall \
|
|
# --norespect_terminal_width \
|
|
# --project ${PROJECT} \
|
|
# --target_tags ${MINION_TAG} \
|
|
# --allowed tcp:80,tcp:8080 \
|
|
# --network ${NETWORK} \
|
|
# ${MINION_TAG}-${INSTANCE_PREFIX}-http-alt
|
|
# fi
|
|
|
|
# }
|
|
|
|
# # Execute after running tests to perform any required clean-up
|
|
# function test-teardown {
|
|
# echo "Shutting down test cluster in background."
|
|
# gcutil deletefirewall \
|
|
# --project ${PROJECT} \
|
|
# --norespect_terminal_width \
|
|
# --force \
|
|
# ${MINION_TAG}-${INSTANCE_PREFIX}-http-alt || true > /dev/null
|
|
# $(dirname $0)/../cluster/kube-down.sh > /dev/null
|
|
# }
|