mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-21 19:01:49 +00:00
AWS support draft
Fix calling function before declaration Set Name tags on instances Hide import-key-pair error Fix instances names resolution Implement kube-down for AWS provider Add cluster validation routines. Make changes according to #1255 Implement post-deployment cluster validation Set proper master name in userdata scripts Fix kube-down path in hint Add getting started for AWS
This commit is contained in:
parent
4a21dbbb0a
commit
1ff79fdeb0
@ -18,6 +18,7 @@ While the concepts and architecture in Kubernetes represent years of experience
|
||||
* [Google Compute Engine](docs/getting-started-guides/gce.md)
|
||||
* [Locally](docs/getting-started-guides/locally.md)
|
||||
* [Vagrant](docs/getting-started-guides/vagrant.md)
|
||||
* [AWS](docs/getting-started-guides/aws.md)
|
||||
* Fedora (w/ [Ansible](docs/getting-started-guides/fedora/fedora_ansible_config.md) or [manual](docs/getting-started-guides/fedora/fedora_manual_config.md))
|
||||
* [Circle CI](https://circleci.com/docs/docker#google-compute-engine-and-kubernetes)
|
||||
* [Digital Ocean](https://github.com/bketelsen/coreos-kubernetes-digitalocean)
|
||||
@ -29,6 +30,7 @@ While the concepts and architecture in Kubernetes represent years of experience
|
||||
|
||||
* The following clouds are currently broken at Kubernetes head. Please sync your client to `v0.3` (`git checkout v0.3`) to use these:
|
||||
* [Microsoft Azure](docs/getting-started-guides/azure.md)
|
||||
|
||||
* [Kubernetes 101](https://github.com/GoogleCloudPlatform/kubernetes/tree/master/examples/walkthrough)
|
||||
* [kubecfg command line tool](https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/cli.md)
|
||||
* [Kubernetes API Documentation](http://cdn.rawgit.com/GoogleCloudPlatform/kubernetes/31a0daae3627c91bc96e1f02a6344cd76e294791/api/kubernetes.html)
|
||||
|
31
cluster/aws/config-default.sh
Normal file
31
cluster/aws/config-default.sh
Normal file
@ -0,0 +1,31 @@
|
||||
#!/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.
|
||||
|
||||
ZONE=eu-west-1
|
||||
MASTER_SIZE=t2.small
|
||||
MINION_SIZE=t2.small
|
||||
NUM_MINIONS=4
|
||||
|
||||
IMAGE=ami-0307d674
|
||||
INSTANCE_PREFIX=kubernetes
|
||||
AWS_SSH_KEY=$HOME/.ssh/kube_aws_rsa
|
||||
|
||||
MASTER_NAME="ip-172-20-0-9.$ZONE.compute.internal"
|
||||
MASTER_TAG="${INSTANCE_PREFIX}-master"
|
||||
MINION_TAG="${INSTANCE_PREFIX}-minion"
|
||||
MINION_NAMES=($(eval echo ip-172-20-0-1{0..$(($NUM_MINIONS-1))}.$ZONE.compute.internal))
|
||||
MINION_IP_RANGES=($(eval echo "10.244.{1..${NUM_MINIONS}}.0/24"))
|
||||
MINION_SCOPES=""
|
30
cluster/aws/kube-down.sh
Executable file
30
cluster/aws/kube-down.sh
Executable file
@ -0,0 +1,30 @@
|
||||
#!/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.
|
||||
|
||||
# Tear down a Kubernetes cluster.
|
||||
|
||||
# exit on any error
|
||||
set -e
|
||||
|
||||
source $(dirname $0)/../kube-env.sh
|
||||
source $(dirname $0)/../$KUBERNETES_PROVIDER/util.sh
|
||||
|
||||
echo "Bringing down cluster using provider: $KUBERNETES_PROVIDER"
|
||||
|
||||
verify-prereqs
|
||||
kube-down
|
||||
|
||||
echo "Done"
|
36
cluster/aws/kube-up.sh
Executable file
36
cluster/aws/kube-up.sh
Executable file
@ -0,0 +1,36 @@
|
||||
#!/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.
|
||||
|
||||
# Bring up a Kubernetes cluster.
|
||||
#
|
||||
# If the full release name (s3://<bucket>/<release>) is passed in then we take
|
||||
# that directly. If not then we assume we are doing development stuff and take
|
||||
# the defaults in the release config.
|
||||
|
||||
# exit on any error
|
||||
set -e
|
||||
|
||||
source $(dirname $0)/../kube-env.sh
|
||||
source $(dirname $0)/../$KUBERNETES_PROVIDER/util.sh
|
||||
|
||||
echo "Starting cluster using provider: $KUBERNETES_PROVIDER"
|
||||
|
||||
verify-prereqs
|
||||
kube-up
|
||||
|
||||
source $(dirname $0)/validate-cluster.sh
|
||||
|
||||
echo "Done"
|
32
cluster/aws/templates/download-release.sh
Normal file
32
cluster/aws/templates/download-release.sh
Normal file
@ -0,0 +1,32 @@
|
||||
#!/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.
|
||||
|
||||
# Download and install release
|
||||
|
||||
# This script assumes that the environment variable MASTER_RELEASE_TAR contains
|
||||
# the release tar to download and unpack. It is meant to be pushed to the
|
||||
# master and run.
|
||||
|
||||
echo "Downloading release ($MASTER_RELEASE_TAR)"
|
||||
wget $MASTER_RELEASE_TAR
|
||||
|
||||
|
||||
echo "Unpacking release"
|
||||
rm -rf master-release || false
|
||||
tar xzf master-release.tgz
|
||||
|
||||
echo "Running release install script"
|
||||
master-release/src/scripts/master-release-install.sh
|
54
cluster/aws/templates/salt-master.sh
Executable file
54
cluster/aws/templates/salt-master.sh
Executable file
@ -0,0 +1,54 @@
|
||||
#!/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.
|
||||
|
||||
# Prepopulate the name of the Master
|
||||
mkdir -p /etc/salt/minion.d
|
||||
echo "master: $MASTER_NAME" > /etc/salt/minion.d/master.conf
|
||||
|
||||
cat <<EOF >/etc/salt/minion.d/grains.conf
|
||||
grains:
|
||||
roles:
|
||||
- kubernetes-master
|
||||
cloud: aws
|
||||
EOF
|
||||
|
||||
# Auto accept all keys from minions that try to join
|
||||
mkdir -p /etc/salt/master.d
|
||||
cat <<EOF >/etc/salt/master.d/auto-accept.conf
|
||||
auto_accept: True
|
||||
EOF
|
||||
|
||||
cat <<EOF >/etc/salt/master.d/reactor.conf
|
||||
# React to new minions starting by running highstate on them.
|
||||
reactor:
|
||||
- 'salt/minion/*/start':
|
||||
- /srv/reactor/start.sls
|
||||
EOF
|
||||
|
||||
mkdir -p /srv/salt/nginx
|
||||
echo $MASTER_HTPASSWD > /srv/salt/nginx/htpasswd
|
||||
|
||||
# Install Salt
|
||||
#
|
||||
# We specify -X to avoid a race condition that can cause minion failure to
|
||||
# install. See https://github.com/saltstack/salt-bootstrap/issues/270
|
||||
#
|
||||
# -M installs the master
|
||||
set +x
|
||||
curl -L --connect-timeout 20 --retry 6 --retry-delay 10 http://bootstrap.saltstack.com | sh -s -- -M -X
|
||||
set -x
|
||||
|
||||
echo $MASTER_HTPASSWD > /srv/salt/nginx/htpasswd
|
37
cluster/aws/templates/salt-minion.sh
Executable file
37
cluster/aws/templates/salt-minion.sh
Executable file
@ -0,0 +1,37 @@
|
||||
#!/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.
|
||||
|
||||
# Prepopulate the name of the Master
|
||||
mkdir -p /etc/salt/minion.d
|
||||
echo "master: $MASTER_NAME" > /etc/salt/minion.d/master.conf
|
||||
|
||||
# Turn on debugging for salt-minion
|
||||
# echo "DAEMON_ARGS=\"\$DAEMON_ARGS --log-file-level=debug\"" > /etc/default/salt-minion
|
||||
|
||||
# Our minions will have a pool role to distinguish them from the master.
|
||||
cat <<EOF >/etc/salt/minion.d/grains.conf
|
||||
grains:
|
||||
roles:
|
||||
- kubernetes-pool
|
||||
cbr-cidr: $MINION_IP_RANGE
|
||||
cloud: aws
|
||||
EOF
|
||||
|
||||
# Install Salt
|
||||
#
|
||||
# We specify -X to avoid a race condition that can cause minion failure to
|
||||
# install. See https://github.com/saltstack/salt-bootstrap/issues/270
|
||||
curl -L --connect-timeout 20 --retry 6 --retry-delay 10 https://bootstrap.saltstack.com | sh -s -- -X
|
317
cluster/aws/util.sh
Normal file
317
cluster/aws/util.sh
Normal file
@ -0,0 +1,317 @@
|
||||
#!/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.
|
||||
|
||||
# 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.
|
||||
source $(dirname ${BASH_SOURCE})/${KUBE_CONFIG_FILE-"config-default.sh"}
|
||||
|
||||
AWS_CMD="aws --output json ec2"
|
||||
|
||||
# Find the release to use. If passed in, go with that and validate. If not use
|
||||
# the release/config.sh version assuming a dev workflow.
|
||||
function find-release() {
|
||||
if [ -n "$1" ]; then
|
||||
RELEASE_NORMALIZED=$1
|
||||
else
|
||||
local RELEASE_CONFIG_SCRIPT=$(dirname $0)/../../release/aws/config.sh
|
||||
if [ -f $(dirname $0)/../../release/aws/config.sh ]; then
|
||||
. $RELEASE_CONFIG_SCRIPT
|
||||
normalize_release
|
||||
fi
|
||||
fi
|
||||
|
||||
# Do one final check that we have a good release
|
||||
if ! aws s3 ls $RELEASE_NORMALIZED/$RELEASE_TAR_FILE | grep $RELEASE_TAR_FILE > /dev/null; then
|
||||
echo "Could not find release tar. If developing, make sure you have run src/release/release.sh to create a release."
|
||||
exit 1
|
||||
fi
|
||||
echo "Release: ${RELEASE_NORMALIZED}"
|
||||
}
|
||||
|
||||
function json_val {
|
||||
python -c 'import json,sys;obj=json.load(sys.stdin);print obj'$1''
|
||||
}
|
||||
|
||||
# TODO (ayurchuk) Refactor the get_* functions to use filters
|
||||
function get_instance_ids {
|
||||
python -c 'import json,sys; lst = [str(instance["InstanceId"]) for reservation in json.load(sys.stdin)["Reservations"] for instance in reservation["Instances"] for tag in instance["Tags"] if tag["Value"].startswith("kubernetes-minion") or tag["Value"].startswith("kubernetes-master")]; print " ".join(lst)'
|
||||
}
|
||||
|
||||
function get_vpc_id {
|
||||
python -c 'import json,sys; lst = [str(vpc["VpcId"]) for vpc in json.load(sys.stdin)["Vpcs"] for tag in vpc["Tags"] if tag["Value"] == "kubernetes-vpc"]; print "".join(lst)'
|
||||
}
|
||||
|
||||
function get_subnet_id {
|
||||
python -c "import json,sys; lst = [str(subnet['SubnetId']) for subnet in json.load(sys.stdin)['Subnets'] if subnet['VpcId'] == '$1']; print ''.join(lst)"
|
||||
}
|
||||
|
||||
function get_igw_id {
|
||||
python -c "import json,sys; lst = [str(igw['InternetGatewayId']) for igw in json.load(sys.stdin)['InternetGateways'] for attachment in igw['Attachments'] if attachment['VpcId'] == '$1']; print ''.join(lst)"
|
||||
}
|
||||
|
||||
function get_route_table_id {
|
||||
python -c "import json,sys; lst = [str(route_table['RouteTableId']) for route_table in json.load(sys.stdin)['RouteTables'] if route_table['VpcId'] == '$1']; print ''.join(lst)"
|
||||
}
|
||||
|
||||
function get_sec_group_id {
|
||||
python -c 'import json,sys; lst = [str(group["GroupId"]) for group in json.load(sys.stdin)["SecurityGroups"] if group["GroupName"] == "kubernetes-sec-group"]; print "".join(lst)'
|
||||
}
|
||||
|
||||
function expect_instance_states {
|
||||
python -c "import json,sys; lst = [str(instance['InstanceId']) for reservation in json.load(sys.stdin)['Reservations'] for instance in reservation['Instances'] if instance['State']['Name'] != '$1']; print ' '.join(lst)"
|
||||
}
|
||||
|
||||
function get_instance_public_ip {
|
||||
python -c "import json,sys; lst = [str(instance['NetworkInterfaces'][0]['Association']['PublicIp']) for reservation in json.load(sys.stdin)['Reservations'] for instance in reservation['Instances'] for tag in instance['Tags'] if tag['Value'] == '$1' and instance['State']['Name'] == 'running']; print ' '.join(lst)"
|
||||
}
|
||||
|
||||
function detect-master () {
|
||||
KUBE_MASTER=${MASTER_NAME}
|
||||
if [ -z "$KUBE_MASTER_IP" ]; then
|
||||
KUBE_MASTER_IP=$($AWS_CMD describe-instances | get_instance_public_ip $MASTER_NAME)
|
||||
fi
|
||||
if [ -z "$KUBE_MASTER_IP" ]; then
|
||||
echo "Could not detect Kubernetes master node. Make sure you've launched a cluster with 'kube-up.sh'"
|
||||
exit 1
|
||||
fi
|
||||
echo "Using master: $KUBE_MASTER (external IP: $KUBE_MASTER_IP)"
|
||||
}
|
||||
|
||||
function detect-minions () {
|
||||
KUBE_MINION_IP_ADDRESSES=()
|
||||
for (( i=0; i<${#MINION_NAMES[@]}; i++)); do
|
||||
local minion_ip=$($AWS_CMD describe-instances --filters Name=tag-value,Values=${MINION_NAMES[$i]} Name=instance-state-name,Values=running | get_instance_public_ip ${MINION_NAMES[$i]})
|
||||
echo "Found ${MINION_NAMES[$i]} at ${minion_ip}"
|
||||
KUBE_MINION_IP_ADDRESSES+=("${minion_ip}")
|
||||
done
|
||||
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'"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
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 {
|
||||
if [ "$(which aws)" == "" ]; then
|
||||
echo "Can't find aws in PATH, please fix and retry."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function kube-up {
|
||||
|
||||
# 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
|
||||
|
||||
# Build up start up script for master
|
||||
KUBE_TEMP=$(mktemp -d -t kubernetes.XXXXXX)
|
||||
trap "rm -rf ${KUBE_TEMP}" EXIT
|
||||
|
||||
get-password
|
||||
echo "Using password: $user:$passwd"
|
||||
python $(dirname $0)/../../third_party/htpasswd/htpasswd.py -b -c ${KUBE_TEMP}/htpasswd $user $passwd
|
||||
HTPASSWD=$(cat ${KUBE_TEMP}/htpasswd)
|
||||
|
||||
if [ ! -f $AWS_SSH_KEY ]; then
|
||||
ssh-keygen -f $AWS_SSH_KEY -N ''
|
||||
fi
|
||||
|
||||
$AWS_CMD import-key-pair --key-name kubernetes --public-key-material file://$AWS_SSH_KEY.pub > /dev/null 2>&1 || true
|
||||
VPC_ID=$($AWS_CMD create-vpc --cidr-block 172.20.0.0/16 | json_val '["Vpc"]["VpcId"]')
|
||||
$AWS_CMD modify-vpc-attribute --vpc-id $VPC_ID --enable-dns-support '{"Value": true}' > /dev/null
|
||||
$AWS_CMD modify-vpc-attribute --vpc-id $VPC_ID --enable-dns-hostnames '{"Value": true}' > /dev/null
|
||||
$AWS_CMD create-tags --resources $VPC_ID --tags Key=Name,Value=kubernetes-vpc > /dev/null
|
||||
SUBNET_ID=$($AWS_CMD create-subnet --cidr-block 172.20.0.0/24 --vpc-id $VPC_ID | json_val '["Subnet"]["SubnetId"]')
|
||||
IGW_ID=$($AWS_CMD create-internet-gateway | json_val '["InternetGateway"]["InternetGatewayId"]')
|
||||
$AWS_CMD attach-internet-gateway --internet-gateway-id $IGW_ID --vpc-id $VPC_ID > /dev/null
|
||||
ROUTE_TABLE_ID=$($AWS_CMD describe-route-tables --filters Name=vpc-id,Values=$VPC_ID | json_val '["RouteTables"][0]["RouteTableId"]')
|
||||
$AWS_CMD associate-route-table --route-table-id $ROUTE_TABLE_ID --subnet-id $SUBNET_ID > /dev/null
|
||||
$AWS_CMD describe-route-tables --filters Name=vpc-id,Values=$VPC_ID > /dev/null
|
||||
$AWS_CMD create-route --route-table-id $ROUTE_TABLE_ID --destination-cidr-block 0.0.0.0/0 --gateway-id $IGW_ID > /dev/null
|
||||
SEC_GROUP_ID=$($AWS_CMD create-security-group --group-name kubernetes-sec-group --description kubernetes-sec-group --vpc-id $VPC_ID | json_val '["GroupId"]')
|
||||
$AWS_CMD authorize-security-group-ingress --group-id $SEC_GROUP_ID --protocol -1 --port all --cidr 0.0.0.0/0 > /dev/null
|
||||
|
||||
(
|
||||
echo "#!/bin/bash"
|
||||
echo "MASTER_NAME=${MASTER_NAME}"
|
||||
echo "MASTER_RELEASE_TAR=${RELEASE_FULL_HTTP_PATH}/master-release.tgz"
|
||||
echo "MASTER_HTPASSWD='${HTPASSWD}'"
|
||||
grep -v "^#" $(dirname $0)/templates/download-release.sh
|
||||
grep -v "^#" $(dirname $0)/templates/salt-master.sh
|
||||
) > ${KUBE_TEMP}/master-start.sh
|
||||
|
||||
master_id=$($AWS_CMD run-instances \
|
||||
--image-id $IMAGE \
|
||||
--instance-type $MASTER_SIZE \
|
||||
--subnet-id $SUBNET_ID \
|
||||
--private-ip-address 172.20.0.9 \
|
||||
--key-name kubernetes \
|
||||
--security-group-ids $SEC_GROUP_ID \
|
||||
--associate-public-ip-address \
|
||||
--user-data file://${KUBE_TEMP}/master-start.sh | json_val '["Instances"][0]["InstanceId"]')
|
||||
|
||||
$AWS_CMD create-tags --resources $master_id --tags Key=Name,Value=$MASTER_NAME > /dev/null
|
||||
$AWS_CMD create-tags --resources $master_id --tags Key=Role,Value=$MASTER_TAG > /dev/null
|
||||
|
||||
for (( i=0; i<${#MINION_NAMES[@]}; i++)); do
|
||||
(
|
||||
echo "#! /bin/bash"
|
||||
echo "MASTER_NAME=${MASTER_NAME}"
|
||||
echo "MINION_IP_RANGE=${MINION_IP_RANGES[$i]}"
|
||||
grep -v "^#" $(dirname $0)/templates/salt-minion.sh
|
||||
) > ${KUBE_TEMP}/minion-start-${i}.sh
|
||||
|
||||
minion_id=$($AWS_CMD run-instances \
|
||||
--image-id $IMAGE \
|
||||
--instance-type $MINION_SIZE \
|
||||
--subnet-id $SUBNET_ID \
|
||||
--private-ip-address 172.20.0.1${i} \
|
||||
--key-name kubernetes \
|
||||
--security-group-ids $SEC_GROUP_ID \
|
||||
--associate-public-ip-address \
|
||||
--user-data file://${KUBE_TEMP}/minion-start-${i}.sh | json_val '["Instances"][0]["InstanceId"]')
|
||||
|
||||
$AWS_CMD create-tags --resources $minion_id --tags Key=Name,Value=${MINION_NAMES[$i]} > /dev/null
|
||||
$AWS_CMD create-tags --resources $minion_id --tags Key=Role,Value=$MINION_TAG > /dev/null
|
||||
$AWS_CMD modify-instance-attribute --instance-id $minion_id --source-dest-check '{"Value": false}' > /dev/null
|
||||
|
||||
# We are not able to add a route to the instance until that instance is in "running" state.
|
||||
# This is quite an ugly solution to this problem. In Bash 4 we could use assoc. arrays to do this for
|
||||
# all instances at once but we can't be sure we are running Bash 4.
|
||||
while true; do
|
||||
instance_state=$($AWS_CMD describe-instances --instance-ids $minion_id | expect_instance_states running)
|
||||
if [[ "$instance_state" == "" ]]; then
|
||||
echo "Minion ${MINION_NAMES[$i]} running"
|
||||
$AWS_CMD create-route --route-table-id $ROUTE_TABLE_ID --destination-cidr-block "10.244.$i.0/24" --instance-id $minion_id > /dev/null
|
||||
break
|
||||
else
|
||||
echo "Waiting for minion ${MINION_NAMES[$i]} to spawn"
|
||||
echo "Sleeping for 3 seconds..."
|
||||
sleep 3
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
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
|
||||
|
||||
|
||||
detect-master > /dev/null
|
||||
detect-minions > /dev/null
|
||||
|
||||
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://${KUBE_MASTER_IP}/api/v1beta1/pods); do
|
||||
printf "."
|
||||
sleep 2
|
||||
done
|
||||
|
||||
echo "Kubernetes cluster created."
|
||||
echo "Sanity checking cluster..."
|
||||
|
||||
sleep 5
|
||||
|
||||
# Don't bail on errors, we want to be able to print some info.
|
||||
set +e
|
||||
|
||||
# Basic sanity checking
|
||||
for i in ${KUBE_MINION_IP_ADDRESSES[@]}; do
|
||||
# Make sure docker is installed
|
||||
ssh -oStrictHostKeyChecking=no ubuntu@$i -i ~/.ssh/kube_aws_rsa which docker > /dev/null 2>&1
|
||||
if [ "$?" != "0" ]; then
|
||||
echo "Docker failed to install on $i. Your cluster is unlikely to work correctly."
|
||||
echo "Please run ./cluster/aws/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}@${KUBE_MASTER_IP}"
|
||||
echo
|
||||
echo "Security note: The server above uses a self signed certificate. This is"
|
||||
echo " subject to \"Man in the middle\" type attacks."
|
||||
}
|
||||
|
||||
function kube-down {
|
||||
AWS_CMD="aws --output json ec2"
|
||||
instance_ids=$($AWS_CMD describe-instances | get_instance_ids)
|
||||
$AWS_CMD terminate-instances --instance-ids $instance_ids > /dev/null
|
||||
echo "Waiting for instances deleted"
|
||||
while true; do
|
||||
instance_states=$($AWS_CMD describe-instances --instance-ids $instance_ids | expect_instance_states terminated)
|
||||
if [[ "$instance_states" == "" ]]; then
|
||||
echo "All instances terminated"
|
||||
break
|
||||
else
|
||||
echo "Instances not yet terminated: $instance_states"
|
||||
echo "Sleeping for 3 seconds..."
|
||||
sleep 3
|
||||
fi
|
||||
done
|
||||
|
||||
echo "Deleting VPC"
|
||||
vpc_id=$($AWS_CMD describe-vpcs | get_vpc_id)
|
||||
subnet_id=$($AWS_CMD describe-subnets | get_subnet_id $vpc_id)
|
||||
igw_id=$($AWS_CMD describe-internet-gateways | get_igw_id $vpc_id)
|
||||
route_table_id=$($AWS_CMD describe-route-tables | get_route_table_id $vpc_id)
|
||||
sec_group_id=$($AWS_CMD describe-security-groups | get_sec_group_id)
|
||||
|
||||
$AWS_CMD delete-subnet --subnet-id $subnet_id > /dev/null
|
||||
$AWS_CMD detach-internet-gateway --internet-gateway-id $igw_id --vpc-id $vpc_id > /dev/null
|
||||
$AWS_CMD delete-internet-gateway --internet-gateway-id $igw_id > /dev/null
|
||||
$AWS_CMD delete-security-group --group-id $sec_group_id > /dev/null
|
||||
$AWS_CMD delete-route --route-table-id $route_table_id --destination-cidr-block 0.0.0.0/0 > /dev/null
|
||||
$AWS_CMD delete-vpc --vpc-id $vpc_id > /dev/null
|
||||
}
|
47
cluster/aws/validate-cluster.sh
Normal file
47
cluster/aws/validate-cluster.sh
Normal file
@ -0,0 +1,47 @@
|
||||
#!/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.
|
||||
|
||||
# exit on any error
|
||||
set -e
|
||||
|
||||
source $(dirname $0)/../kube-env.sh
|
||||
source $(dirname $0)/../$KUBERNETES_PROVIDER/util.sh
|
||||
|
||||
get-password
|
||||
detect-master > /dev/null
|
||||
detect-minions > /dev/null
|
||||
|
||||
MINIONS_FILE=/tmp/minions
|
||||
$(dirname $0)/../kubecfg.sh -template '{{range.Items}}{{.ID}}:{{end}}' list minions > ${MINIONS_FILE}
|
||||
|
||||
for (( i=0; i<${#MINION_NAMES[@]}; i++)); do
|
||||
# Grep returns an exit status of 1 when line is not found, so we need the : to always return a 0 exit status
|
||||
count=$(grep -c ${MINION_NAMES[i]} ${MINIONS_FILE}) || :
|
||||
if [ "$count" == "0" ]; then
|
||||
echo "Failed to find ${MINION_NAMES[i]}, cluster is probably broken."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Make sure the kubelet is healthy
|
||||
if [ "$(curl --insecure --user ${user}:${passwd} https://${KUBE_MASTER_IP}/proxy/minion/${MINION_NAMES[$i]}/healthz)" != "ok" ]; 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
|
||||
else
|
||||
echo "Kubelet is successfully installed on ${MINION_NAMES[$i]}"
|
||||
fi
|
||||
done
|
||||
echo "Cluster validation succeeded"
|
@ -18,6 +18,6 @@
|
||||
# You can override the default provider by exporting the KUBERNETES_PROVIDER
|
||||
# variable in your bashrc
|
||||
#
|
||||
# The valid values: 'gce', 'azure', 'vagrant', 'local', 'vsphere'
|
||||
# The valid values: 'gce', 'aws', 'azure', 'vagrant', 'local', 'vsphere'
|
||||
|
||||
KUBERNETES_PROVIDER=${KUBERNETES_PROVIDER:-gce}
|
||||
|
26
hack/aws/dev-build-and-up.sh
Executable file
26
hack/aws/dev-build-and-up.sh
Executable file
@ -0,0 +1,26 @@
|
||||
#!/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.
|
||||
|
||||
# This script will build a dev release and bring up a new cluster with that
|
||||
# release.
|
||||
|
||||
SCRIPT_DIR=$(CDPATH="" cd $(dirname $0); pwd)
|
||||
|
||||
# First build a release
|
||||
$SCRIPT_DIR/../../release/aws/release.sh
|
||||
|
||||
# Now bring a new cluster up with that release.
|
||||
$SCRIPT_DIR/../../cluster/aws/kube-up.sh
|
69
release/aws/config.sh
Normal file
69
release/aws/config.sh
Normal file
@ -0,0 +1,69 @@
|
||||
# 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.
|
||||
|
||||
if which md5 > /dev/null 2>&1; then
|
||||
MD5_FUNC=md5
|
||||
else
|
||||
MD5_FUNC=md5sum
|
||||
fi
|
||||
|
||||
function json_val () {
|
||||
python -c 'import json,sys;obj=json.load(sys.stdin);print obj'$1''
|
||||
}
|
||||
|
||||
INSTANCE_PREFIX=kubernetes
|
||||
|
||||
AWS_HASH=$(aws --output json iam list-access-keys | json_val '["AccessKeyMetadata"][0]["AccessKeyId"]' | $MD5_FUNC)
|
||||
AWS_HASH=${AWS_HASH:0:5}
|
||||
RELEASE_BUCKET=${RELEASE_BUCKET-s3://kubernetes-releases-$AWS_HASH/}
|
||||
RELEASE_PREFIX=${RELEASE_PREFIX-devel/$USER/}
|
||||
RELEASE_NAME=${RELEASE_NAME-r$(date -u +%Y%m%d-%H%M%S)}
|
||||
|
||||
# This is a 'soft link' to the release in question. It is a single line file to
|
||||
# the full GS path for a release.
|
||||
RELEASE_TAG=${RELEASE_TAG-testing}
|
||||
|
||||
RELEASE_TAR_FILE=master-release.tgz
|
||||
|
||||
RELEASE_FULL_PATH=$RELEASE_BUCKET$RELEASE_PREFIX$RELEASE_NAME
|
||||
RELEASE_FULL_TAG_PATH=$RELEASE_BUCKET$RELEASE_PREFIX$RELEASE_TAG
|
||||
|
||||
# Takes a release path ($1 if passed, otherwise $RELEASE_FULL_TAG_PATH) and
|
||||
# computes the normalized release path. Results are stored in
|
||||
# $RELEASE_NORMALIZED. Returns 0 if a valid release can be found.
|
||||
function normalize_release() {
|
||||
RELEASE_NORMALIZED=${1-$RELEASE_FULL_TAG_PATH}
|
||||
|
||||
# First test to see if there is a valid release at this path.
|
||||
if aws s3 ls $RELEASE_NORMALIZED/$RELEASE_TAR_FILE | grep $RELEASE_TAR_FILE > /dev/null; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Check if this is a simple file. If so, read it and use the result as the
|
||||
# new RELEASE_NORMALIZED.
|
||||
if aws s3 ls $RELEASE_NORMALIZED | grep $RELEASE_TAG > /dev/null; then
|
||||
RELEASE_NORMALIZED=$(aws s3 cp $RELEASE_NORMALIZED >(cat) > /dev/null)
|
||||
normalize_release $RELEASE_NORMALIZED
|
||||
RELEASE_FULL_HTTP_PATH=${RELEASE_NORMALIZED/s3:\/\//https:\/\/s3-$ZONE.amazonaws.com/}
|
||||
return
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
# Sets a tag ($1) to a release ($2)
|
||||
function set_tag() {
|
||||
TMPFILE=$(mktemp -t release_tag 2>/dev/null || mktemp -t release_tag.XXXX)
|
||||
echo $2 > $TMPFILE
|
||||
aws s3 cp $TMPFILE $1 > /dev/null
|
||||
}
|
46
release/aws/launch-kubernetes-base.sh
Normal file
46
release/aws/launch-kubernetes-base.sh
Normal file
@ -0,0 +1,46 @@
|
||||
# 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.
|
||||
|
||||
# Prerequisites
|
||||
# TODO (ayurchuk): Perhaps install cloud SDK automagically if we can't find it?
|
||||
|
||||
# Exit on any error
|
||||
set -e
|
||||
|
||||
echo "Auto installer for launching Kubernetes"
|
||||
echo "Release: $RELEASE_PREFIX$RELEASE_NAME"
|
||||
|
||||
# Make sure that prerequisites are installed.
|
||||
if [ "$(which aws)" == "" ]; then
|
||||
echo "Can't find aws in PATH, please fix and retry."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# TODO(jbeda): Provide a way to install this in to someplace beyond a temp dir
|
||||
# so that users have access to local tools.
|
||||
TMPDIR=$(mktemp -d /tmp/installer.kubernetes.XXXXXX)
|
||||
|
||||
cd $TMPDIR
|
||||
|
||||
echo "Downloading support files"
|
||||
aws s3 cp $RELEASE_FULL_PATH/launch-kubernetes.tgz .
|
||||
|
||||
tar xzf launch-kubernetes.tgz
|
||||
|
||||
./src/scripts/kube-up.sh $RELEASE_FULL_PATH
|
||||
|
||||
cd /
|
||||
|
||||
# clean up
|
||||
# rm -rf $TMPDIR
|
65
release/aws/release.sh
Executable file
65
release/aws/release.sh
Executable file
@ -0,0 +1,65 @@
|
||||
#!/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.
|
||||
|
||||
# This script will build and release Kubernetes.
|
||||
#
|
||||
# The main parameters to this script come from the config.sh file. This is set
|
||||
# up by default for development releases. Feel free to edit it or override some
|
||||
# of the variables there.
|
||||
|
||||
# exit on any error
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR=$(CDPATH="" cd $(dirname $0); pwd)
|
||||
|
||||
source $SCRIPT_DIR/config.sh
|
||||
$SCRIPT_DIR/../build-release.sh $INSTANCE_PREFIX
|
||||
|
||||
echo "Building launch script"
|
||||
# Create the local install script. These are the tools to install the local
|
||||
# tools and launch a new cluster.
|
||||
LOCAL_RELEASE_DIR=$SCRIPT_DIR/../../_output/release/local-release
|
||||
mkdir -p $LOCAL_RELEASE_DIR/src/scripts
|
||||
|
||||
cp -r $SCRIPT_DIR/../../cluster/templates $LOCAL_RELEASE_DIR/src/templates
|
||||
cp -r $SCRIPT_DIR/../../cluster/*.sh $LOCAL_RELEASE_DIR/src/scripts
|
||||
|
||||
tar cz -C $LOCAL_RELEASE_DIR -f $SCRIPT_DIR/../../_output/release/launch-kubernetes.tgz .
|
||||
|
||||
echo "#!/bin/bash" >> $SCRIPT_DIR/../../_output/release/launch-kubernetes.sh
|
||||
echo "RELEASE_TAG=$RELEASE_TAG" >> $SCRIPT_DIR/../../_output/release/launch-kubernetes.sh
|
||||
echo "RELEASE_PREFIX=$RELEASE_PREFIX" >> $SCRIPT_DIR/../../_output/release/launch-kubernetes.sh
|
||||
echo "RELEASE_NAME=$RELEASE_NAME" >> $SCRIPT_DIR/../../_output/release/launch-kubernetes.sh
|
||||
echo "RELEASE_FULL_PATH=$RELEASE_FULL_PATH" >> $SCRIPT_DIR/../../_output/release/launch-kubernetes.sh
|
||||
cat $SCRIPT_DIR/launch-kubernetes-base.sh >> $SCRIPT_DIR/../../_output/release/launch-kubernetes.sh
|
||||
chmod a+x $SCRIPT_DIR/../../_output/release/launch-kubernetes.sh
|
||||
|
||||
echo "Uploading to Amazon S3"
|
||||
if ! aws s3 ls $RELEASE_BUCKET > /dev/null 2>&1 ; then
|
||||
echo "Creating $RELEASE_BUCKET"
|
||||
aws s3 mb $RELEASE_BUCKET > /dev/null
|
||||
fi
|
||||
|
||||
aws s3api put-bucket-acl --bucket kubernetes-releases-$AWS_HASH --acl public-read
|
||||
|
||||
for x in master-release.tgz launch-kubernetes.tgz launch-kubernetes.sh; do
|
||||
aws s3 cp $SCRIPT_DIR/../../_output/release/$x $RELEASE_FULL_PATH/$x > /dev/null
|
||||
aws s3api put-object-acl --bucket kubernetes-releases-$AWS_HASH --key $RELEASE_PREFIX$RELEASE_NAME/$x --acl public-read
|
||||
done
|
||||
|
||||
set_tag $RELEASE_FULL_TAG_PATH $RELEASE_FULL_PATH
|
||||
|
||||
echo "Release pushed ($RELEASE_PREFIX$RELEASE_NAME)."
|
Loading…
Reference in New Issue
Block a user