From c4d4aff0d3dc57da46cb51a7ec570a565ea14900 Mon Sep 17 00:00:00 2001 From: "Madhusudan.C.S" Date: Fri, 22 Jul 2016 00:32:55 -0700 Subject: [PATCH 01/12] Implement a build and deploy script to turn up/down federation. Also, wrap the script around a Makefile. And also provide a sample config file to describe clusters. The build script implements the following things: 1. Generates the required configs. 2. Builds the hyperkube binary and the corresponding docker image. 3. Pushes the image to a specified repository. 4. Pulls the federation installer docker images. 5. Builds the Kubernetes clusters described the config.json file. 6. Pushes the federation components to one of the Kubernetes clusters built in the previous step. 7. Also turns down the federation components and the Kubernetes clusters. --- federation/Makefile | 26 +++++ federation/build.sh | 170 +++++++++++++++++++++++++++++++++ federation/config.default.json | 83 ++++++++++++++++ 3 files changed, 279 insertions(+) create mode 100644 federation/Makefile create mode 100755 federation/build.sh create mode 100644 federation/config.default.json diff --git a/federation/Makefile b/federation/Makefile new file mode 100644 index 00000000000..2cac8af9b6b --- /dev/null +++ b/federation/Makefile @@ -0,0 +1,26 @@ +# Copyright 2016 The Kubernetes Authors. +# +# 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. + +DBG_MAKEFILE ?= +ifeq ($(DBG_MAKEFILE),1) + $(warning ***** starting makefile for goal(s) "$(MAKECMDGOALS)") + $(warning ***** $(shell date)) +else + # If we're not debugging the Makefile, don't echo recipes. + MAKEFLAGS += -s +endif + +.PHONY: build +build: + ./build.sh $(do) diff --git a/federation/build.sh b/federation/build.sh new file mode 100755 index 00000000000..60cfc255fea --- /dev/null +++ b/federation/build.sh @@ -0,0 +1,170 @@ +#!/usr/bin/env bash + +# Copyright 2016 The Kubernetes Authors. +# +# 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 the hyperkube image and push it to the repository +# referred to by KUBE_REGISTRY. The image will be given a version tag with +# the value from KUBE_VERSION. It also turns up/turns down Kubernetes +# clusters and federation components using the built hyperkube image. +# e.g. run as: +# KUBE_REGISTRY=localhost:5000/anushku \ +# KUBE_VERSION=1.3.0-dev ./build.sh +# +# will deploy the components using +# localhost:5000/anushku/hyperkube-amd64:1.3.0-dev image. + +# TODO(madhusudancs): Separate the dev functions from the deployment +# functions. A lot of code here is to make this work in dev environments. +# The script that we ship to the users as part of a release should be +# much simpler (about 80% of the code here could be removed for non-dev +# environments). + +set -o errexit +set -o nounset +set -o pipefail + +KUBE_ROOT=$(dirname "${BASH_SOURCE}")/.. +CUR_ROOT=$(dirname "${BASH_SOURCE}") + +source "${KUBE_ROOT}/build/util.sh" +source "${KUBE_ROOT}/build/common.sh" + +readonly ACTION="${1:-gen}" + +readonly TMP_DIR="$(mktemp -d)" + +readonly FEDERATION_OUTPUT_ROOT="${LOCAL_OUTPUT_ROOT}/federation" + +readonly KUBE_ANYWHERE_FEDERATION_IMAGE="gcr.io/madhusudancs-containers/kubernetes-anywhere-federation" +readonly KUBE_ANYWHERE_FEDERATION_VERSION="v0.9.0" + +readonly KUBE_ANYWHERE_FEDERATION_CHARTS_IMAGE="gcr.io/madhusudancs-containers/federation-charts" +readonly KUBE_ANYWHERE_FEDERATION_CHARTS_VERSION="v0.9.0" + +KUBE_PROJECT="madhusudancs-k8s" +KUBE_REGISTRY="${KUBE_REGISTRY:-gcr.io/${KUBE_PROJECT}}" +KUBE_VERSION="${KUBE_VERSION:-$(kube::release::semantic_image_tag_version)}" + + +function cleanup { + rm -rf "${TMP_DIR}" + cd "${CUR_ROOT}" +} +trap cleanup EXIT + +function dirty_sha() { + local -r index="${KUBE_ROOT}/.git/index" + local -r objects_dir="${KUBE_ROOT}/.git/objects" + + local -r tmp_dir="${TMP_DIR}/.git" + local -r tmp_index="${tmp_dir}/index" + local -r tmp_objects_dir="${tmp_dir}/objects" + + mkdir -p "${tmp_objects_dir}" + cp "${index}" "${tmp_index}" + + local -r files=$(git ls-files -m -o -d --exclude-standard) + GIT_INDEX_FILE="${tmp_index}" git add ${files} + GIT_ALTERNATE_OBJECT_DIRECTORIES="${objects_dir}" GIT_OBJECT_DIRECTORY="${tmp_objects_dir}" GIT_INDEX_FILE="${tmp_index}" git write-tree +} + +function update_config() { + local -r q="${1:-}" + local -r cfile="${2:-}" + local -r bname="$(basename ${cfile})" + + jq "${q}" "${cfile}" > "${TMP_DIR}/${bname}" + mv "${TMP_DIR}/${bname}" "${cfile}" +} + +function build() { + kube::build::verify_prereqs + kube::build::build_image + kube::build::run_build_command make WHAT=cmd/hyperkube + + BASEIMAGE="ubuntu:16.04" \ + REGISTRY="${KUBE_REGISTRY}" \ + VERSION="${KUBE_VERSION}" \ + make -C "${KUBE_ROOT}/cluster/images/hyperkube" build +} + +function push() { + gcloud docker push "${KUBE_REGISTRY}/hyperkube-amd64:${KUBE_VERSION}" +} + +function pull_installer() { + gcloud docker pull "${KUBE_ANYWHERE_FEDERATION_IMAGE}:${KUBE_ANYWHERE_FEDERATION_VERSION}" + gcloud docker pull "${KUBE_ANYWHERE_FEDERATION_CHARTS_IMAGE}:${KUBE_ANYWHERE_FEDERATION_CHARTS_VERSION}" +} + +function kube_action() { + docker run \ + --user="$(id -u):$(id -g)" \ + -m 12G \ + -v "${HOME}/.config/gcloud/application_default_credentials.json:/.config/gcloud/application_default_credentials.json:ro" \ + -v "${HOME}/.kube:/.kube" \ + -v "${FEDERATION_OUTPUT_ROOT}:/_output" \ + "${KUBE_ANYWHERE_FEDERATION_IMAGE}:${KUBE_ANYWHERE_FEDERATION_VERSION}" \ + "${ACTION}" +} + +function federation_action() { + docker run \ + -m 12G \ + -v "${HOME}/.kube/config:/root/.kube/config:ro" \ + -v "${FEDERATION_OUTPUT_ROOT}:/_output" \ + "${KUBE_ANYWHERE_FEDERATION_CHARTS_IMAGE}:${KUBE_ANYWHERE_FEDERATION_CHARTS_VERSION}" \ + "${ACTION}" +} + +function gen_or_update_config() { + if [[ "${KUBE_VERSION}" == *-dirty ]]; then + KUBE_VERSION+=".$(dirty_sha)" + fi + + mkdir -p "${FEDERATION_OUTPUT_ROOT}" + cp "config.default.json" "${FEDERATION_OUTPUT_ROOT}/config.json" + + update_config \ + '[.[] | .phase1.gce.project |= "'"${KUBE_PROJECT}"'"]' \ + "${FEDERATION_OUTPUT_ROOT}/config.json" + + # Not chaining for readability + update_config \ + '[.[] | .phase2 = { docker_registry: "'"${KUBE_REGISTRY}"'", kubernetes_version: "'"${KUBE_VERSION}"'" } ]' \ + "${FEDERATION_OUTPUT_ROOT}/config.json" + + cat < "${FEDERATION_OUTPUT_ROOT}/values.yaml" +apiserverRegistry: "${KUBE_REGISTRY}" +apiserverVersion: "${KUBE_VERSION}" +controllerManagerRegistry: "${KUBE_REGISTRY}" +controllerManagerVersion: "${KUBE_VERSION}" +EOF +} + +if [[ "${ACTION}" == "gen" || "${ACTION}" == "deploy" ]]; then + gen_or_update_config + + cd "${KUBE_ROOT}" + build + push + pull_installer + + kube_action + federation_action +else + federation_action + kube_action +fi diff --git a/federation/config.default.json b/federation/config.default.json new file mode 100644 index 00000000000..8bcb1f832d4 --- /dev/null +++ b/federation/config.default.json @@ -0,0 +1,83 @@ +[ + { + "phase1": { + "num_nodes": 3, + "cluster_name": "cluster1-kubernetes", + "cloud_provider": "gce", + "cluster_cidr": "10.180.0.0/14", + "gce": { + "os_image": "ubuntu-1604-xenial-v20160420c", + "instance_type": "n1-standard-2", + "project": "", + "region": "us-central1", + "zone": "us-central1-a", + "network": "federation" + } + }, + "phase2": { + "docker_registry": "gcr.io/google-containers", + "kubernetes_version": "v1.3.0" + }, + "phase3": { + "run_addons": true, + "kube_proxy": true, + "dashboard": true, + "heapster": true, + "kube_dns": true + } + }, + { + "phase1": { + "num_nodes": 3, + "cluster_name": "cluster2-kubernetes", + "cloud_provider": "gce", + "cluster_cidr": "10.184.0.0/14", + "gce": { + "os_image": "ubuntu-1604-xenial-v20160420c", + "instance_type": "n1-standard-2", + "project": "", + "region": "us-central1", + "zone": "us-central1-b", + "network": "federation" + } + }, + "phase2": { + "docker_registry": "gcr.io/google-containers", + "kubernetes_version": "v1.3.0" + }, + "phase3": { + "run_addons": true, + "kube_proxy": true, + "dashboard": true, + "heapster": true, + "kube_dns": true + } + }, + { + "phase1": { + "num_nodes": 3, + "cluster_name": "cluster3-kubernetes", + "cloud_provider": "gce", + "cluster_cidr": "10.188.0.0/14", + "gce": { + "os_image": "ubuntu-1604-xenial-v20160420c", + "instance_type": "n1-standard-2", + "project": "", + "region": "us-central1", + "zone": "us-central1-f", + "network": "federation" + } + }, + "phase2": { + "docker_registry": "gcr.io/google-containers", + "kubernetes_version": "v1.3.0" + }, + "phase3": { + "run_addons": true, + "kube_proxy": true, + "dashboard": true, + "heapster": true, + "kube_dns": true + } + } +] From a527204a60f4ec2e99381f9c3673da51c4b13966 Mon Sep 17 00:00:00 2001 From: "Madhusudan.C.S" Date: Fri, 22 Jul 2016 11:35:44 -0700 Subject: [PATCH 02/12] Add some status logging. --- federation/build.sh | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/federation/build.sh b/federation/build.sh index 60cfc255fea..6f8a00c812a 100755 --- a/federation/build.sh +++ b/federation/build.sh @@ -38,6 +38,7 @@ set -o pipefail KUBE_ROOT=$(dirname "${BASH_SOURCE}")/.. CUR_ROOT=$(dirname "${BASH_SOURCE}") +source "${KUBE_ROOT}/cluster/lib/logging.sh" source "${KUBE_ROOT}/build/util.sh" source "${KUBE_ROOT}/build/common.sh" @@ -101,15 +102,18 @@ function build() { } function push() { + kube::log::status "Pushing hyperkube image to the registry" gcloud docker push "${KUBE_REGISTRY}/hyperkube-amd64:${KUBE_VERSION}" } function pull_installer() { + kube::log::status "Pulling installer images" gcloud docker pull "${KUBE_ANYWHERE_FEDERATION_IMAGE}:${KUBE_ANYWHERE_FEDERATION_VERSION}" gcloud docker pull "${KUBE_ANYWHERE_FEDERATION_CHARTS_IMAGE}:${KUBE_ANYWHERE_FEDERATION_CHARTS_VERSION}" } function kube_action() { + kube::log::status "${ACTION} clusters" docker run \ --user="$(id -u):$(id -g)" \ -m 12G \ @@ -121,6 +125,7 @@ function kube_action() { } function federation_action() { + kube::log::status "${ACTION} federation components" docker run \ -m 12G \ -v "${HOME}/.kube/config:/root/.kube/config:ro" \ @@ -168,3 +173,5 @@ else federation_action kube_action fi + +kube::log::status "Successfully completed!" From a78d2851d966d22c3e1d975b43ab454b22dd677c Mon Sep 17 00:00:00 2001 From: "Madhusudan.C.S" Date: Fri, 22 Jul 2016 17:25:58 -0700 Subject: [PATCH 03/12] Installer images are supposed to be public, so we can directly pull without gcloud prefix. --- federation/build.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/federation/build.sh b/federation/build.sh index 6f8a00c812a..dbc47442e07 100755 --- a/federation/build.sh +++ b/federation/build.sh @@ -108,8 +108,8 @@ function push() { function pull_installer() { kube::log::status "Pulling installer images" - gcloud docker pull "${KUBE_ANYWHERE_FEDERATION_IMAGE}:${KUBE_ANYWHERE_FEDERATION_VERSION}" - gcloud docker pull "${KUBE_ANYWHERE_FEDERATION_CHARTS_IMAGE}:${KUBE_ANYWHERE_FEDERATION_CHARTS_VERSION}" + docker pull "${KUBE_ANYWHERE_FEDERATION_IMAGE}:${KUBE_ANYWHERE_FEDERATION_VERSION}" + docker pull "${KUBE_ANYWHERE_FEDERATION_CHARTS_IMAGE}:${KUBE_ANYWHERE_FEDERATION_CHARTS_VERSION}" } function kube_action() { From 2efdc24b7f78464ad84a92d0577b1d6f62a88c42 Mon Sep 17 00:00:00 2001 From: "Madhusudan.C.S" Date: Fri, 22 Jul 2016 17:31:32 -0700 Subject: [PATCH 04/12] Build both kubectl and hypekube together, one is required for the other. --- federation/build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/federation/build.sh b/federation/build.sh index dbc47442e07..a9d673ea6c9 100755 --- a/federation/build.sh +++ b/federation/build.sh @@ -93,7 +93,7 @@ function update_config() { function build() { kube::build::verify_prereqs kube::build::build_image - kube::build::run_build_command make WHAT=cmd/hyperkube + kube::build::run_build_command make WHAT="cmd/kubectl cmd/hyperkube" BASEIMAGE="ubuntu:16.04" \ REGISTRY="${KUBE_REGISTRY}" \ From dbdc91fc791b755f042923be18d70632640fc4b4 Mon Sep 17 00:00:00 2001 From: "Madhusudan.C.S" Date: Fri, 22 Jul 2016 17:38:18 -0700 Subject: [PATCH 05/12] Recompute KUBE_VERSION after rebuild in the dev environment. --- federation/build.sh | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/federation/build.sh b/federation/build.sh index a9d673ea6c9..1d8a8bae8b8 100755 --- a/federation/build.sh +++ b/federation/build.sh @@ -25,6 +25,9 @@ # will deploy the components using # localhost:5000/anushku/hyperkube-amd64:1.3.0-dev image. +# Everything in this script is expected to be executed from the $KUBE_ROOT +# directory. + # TODO(madhusudancs): Separate the dev functions from the deployment # functions. A lot of code here is to make this work in dev environments. # The script that we ship to the users as part of a release should be @@ -56,7 +59,10 @@ readonly KUBE_ANYWHERE_FEDERATION_CHARTS_VERSION="v0.9.0" KUBE_PROJECT="madhusudancs-k8s" KUBE_REGISTRY="${KUBE_REGISTRY:-gcr.io/${KUBE_PROJECT}}" -KUBE_VERSION="${KUBE_VERSION:-$(kube::release::semantic_image_tag_version)}" + +# In dev environments this value must be recomputed after build. See +# the build() function. +KUBE_VERSION="${KUBE_VERSION:-}" function cleanup { @@ -95,6 +101,15 @@ function build() { kube::build::build_image kube::build::run_build_command make WHAT="cmd/kubectl cmd/hyperkube" + # Recompute KUBE_VERSION because it might have changed after rebuild. + KUBE_VERSION="${KUBE_VERSION:-$(kube::release::semantic_image_tag_version)}" + + # Also append the dirty tree SHA to keep the versions unique across + # builds. + if [[ "${KUBE_VERSION}" == *-dirty ]]; then + KUBE_VERSION+=".$(dirty_sha)" + fi + BASEIMAGE="ubuntu:16.04" \ REGISTRY="${KUBE_REGISTRY}" \ VERSION="${KUBE_VERSION}" \ @@ -135,12 +150,8 @@ function federation_action() { } function gen_or_update_config() { - if [[ "${KUBE_VERSION}" == *-dirty ]]; then - KUBE_VERSION+=".$(dirty_sha)" - fi - mkdir -p "${FEDERATION_OUTPUT_ROOT}" - cp "config.default.json" "${FEDERATION_OUTPUT_ROOT}/config.json" + cp "federation/config.default.json" "${FEDERATION_OUTPUT_ROOT}/config.json" update_config \ '[.[] | .phase1.gce.project |= "'"${KUBE_PROJECT}"'"]' \ @@ -160,13 +171,16 @@ EOF } if [[ "${ACTION}" == "gen" || "${ACTION}" == "deploy" ]]; then - gen_or_update_config - cd "${KUBE_ROOT}" build push + pull_installer + # Update config after build and push, but before turning up the clusters + # to ensure the config has the right image version tags. + gen_or_update_config + kube_action federation_action else From 32c181daebfdb313dbf17ca38dab3b8c8f0cd98a Mon Sep 17 00:00:00 2001 From: "Madhusudan.C.S" Date: Fri, 22 Jul 2016 18:37:38 -0700 Subject: [PATCH 06/12] Add a function to ensure that required credential files exist. --- federation/build.sh | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/federation/build.sh b/federation/build.sh index 1d8a8bae8b8..126bc6f64eb 100755 --- a/federation/build.sh +++ b/federation/build.sh @@ -48,15 +48,17 @@ source "${KUBE_ROOT}/build/common.sh" readonly ACTION="${1:-gen}" readonly TMP_DIR="$(mktemp -d)" - readonly FEDERATION_OUTPUT_ROOT="${LOCAL_OUTPUT_ROOT}/federation" readonly KUBE_ANYWHERE_FEDERATION_IMAGE="gcr.io/madhusudancs-containers/kubernetes-anywhere-federation" readonly KUBE_ANYWHERE_FEDERATION_VERSION="v0.9.0" - readonly KUBE_ANYWHERE_FEDERATION_CHARTS_IMAGE="gcr.io/madhusudancs-containers/federation-charts" readonly KUBE_ANYWHERE_FEDERATION_CHARTS_VERSION="v0.9.0" +readonly GOOGLE_APPLICATION_CREDENTIALS="${GOOGLE_APPLICATION_CREDENTIALS:-${HOME}/.config/gcloud/application_default_credentials.json}" +readonly KUBE_CONFIG_DIR="${KUBE_CONFIG_DIR:-${HOME}/.kube}" +readonly KUBE_CONFIG="${KUBE_CONFIG:-${HOME}/.kube/config}" + KUBE_PROJECT="madhusudancs-k8s" KUBE_REGISTRY="${KUBE_REGISTRY:-gcr.io/${KUBE_PROJECT}}" @@ -127,13 +129,26 @@ function pull_installer() { docker pull "${KUBE_ANYWHERE_FEDERATION_CHARTS_IMAGE}:${KUBE_ANYWHERE_FEDERATION_CHARTS_VERSION}" } +function ensure_files() { + kube::log::status "Ensure credential files exist..." + if [[ ! -f "${GOOGLE_APPLICATION_CREDENTIALS}" ]]; then + echo "Please ensure Google credentials file \""${GOOGLE_APPLICATION_CREDENTIALS}"\" exists." + exit 1 + fi + + if [[ ! -f "${KUBE_CONFIG}" ]]; then + echo "Please ensure kubeconfig file \""${KUBE_CONFIG}"\" exists." + exit 1 + fi +} + function kube_action() { kube::log::status "${ACTION} clusters" docker run \ --user="$(id -u):$(id -g)" \ -m 12G \ - -v "${HOME}/.config/gcloud/application_default_credentials.json:/.config/gcloud/application_default_credentials.json:ro" \ - -v "${HOME}/.kube:/.kube" \ + -v "${GOOGLE_APPLICATION_CREDENTIALS}:/.config/gcloud/application_default_credentials.json:ro" \ + -v "${KUBE_CONFIG_DIR}:/.kube" \ -v "${FEDERATION_OUTPUT_ROOT}:/_output" \ "${KUBE_ANYWHERE_FEDERATION_IMAGE}:${KUBE_ANYWHERE_FEDERATION_VERSION}" \ "${ACTION}" @@ -143,7 +158,7 @@ function federation_action() { kube::log::status "${ACTION} federation components" docker run \ -m 12G \ - -v "${HOME}/.kube/config:/root/.kube/config:ro" \ + -v "${KUBE_CONFIG}:/root/.kube/config:ro" \ -v "${FEDERATION_OUTPUT_ROOT}:/_output" \ "${KUBE_ANYWHERE_FEDERATION_CHARTS_IMAGE}:${KUBE_ANYWHERE_FEDERATION_CHARTS_VERSION}" \ "${ACTION}" @@ -171,6 +186,8 @@ EOF } if [[ "${ACTION}" == "gen" || "${ACTION}" == "deploy" ]]; then + ensure_files + cd "${KUBE_ROOT}" build push From 616eab029622a46d1bb40d8e4e7669bc938b12a3 Mon Sep 17 00:00:00 2001 From: "Madhusudan.C.S" Date: Sat, 23 Jul 2016 17:28:56 -0700 Subject: [PATCH 07/12] Add a README.md file for cluster federation. --- federation/README.md | 58 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 federation/README.md diff --git a/federation/README.md b/federation/README.md new file mode 100644 index 00000000000..771dfccda3d --- /dev/null +++ b/federation/README.md @@ -0,0 +1,58 @@ +# Cluster Federation + +Kubernetes Cluster Federation enables users to federate multiple +Kubernetes clusters. Please see the [user guide](http://kubernetes.io/docs/admin/federation/) +and the [admin guide](http://kubernetes.io/docs/user-guide/federation/federated-services/) +for more details about setting up and using the Cluster Federation. + +# Building Kubernetes Cluster Federation + +Please see the [Kubernetes Development Guide](https://github.com/kubernetes/kubernetes/blob/master/docs/devel/development.md) +for initial setup. Once you have the development environment setup +as explained in that guide, you also need to install [`jq`](https://stedolan.github.io/jq/download/) + +Building cluster federation should be as simple as running: + +```shell +make build do=gen +``` + +To deploy clusters and install federation components, edit the +`config.default.json` file to describe your clusters and run + +```shell +make build do=deploy +``` + +To turn down the federation components and tear down the clusters run: + +```shell +make build do=destroy +``` + +# Ideas for improvement + +1. Split the `build` phase (make recipe) into multiple phases: + 1. `init`: pull installer images + 2. `build-binaries` + 3. `build-docker` + 4. `build`: build-binary + build-docker + 5. `push`: to push the built images + 6. `genconfig` + 7. `deploy-clusters` + 8. `deploy-federation` + 9. `deploy`: deploy-clusters + deploy-federation + 10. `destroy-federation` + 11. `destroy-clusters` + 12. `destroy`: destroy-federation + destroy-clusters + 13. `redeploy-federation`: just redeploys the federation components. + +2. Add a `release` phase to run as part of Kubernetes release process + that copies only a part of the `build.sh` script that's relevant to + the users into the release. + +3. Continue with `destroy` phase even in the face of errors. + + The bash script sets `set -e errexit` which causes the script to exit + at the very first error. This should be the default mode for deploying + components but not for destroying/cleanup. From 40642fdd2887edc929b2e7dcdf30c1aa11d02944 Mon Sep 17 00:00:00 2001 From: "Madhusudan.C.S" Date: Sat, 23 Jul 2016 18:04:41 -0700 Subject: [PATCH 08/12] Add detect-project capability. --- federation/build.sh | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/federation/build.sh b/federation/build.sh index 126bc6f64eb..5a249ffa707 100755 --- a/federation/build.sh +++ b/federation/build.sh @@ -41,9 +41,11 @@ set -o pipefail KUBE_ROOT=$(dirname "${BASH_SOURCE}")/.. CUR_ROOT=$(dirname "${BASH_SOURCE}") -source "${KUBE_ROOT}/cluster/lib/logging.sh" -source "${KUBE_ROOT}/build/util.sh" source "${KUBE_ROOT}/build/common.sh" +source "${KUBE_ROOT}/build/util.sh" +# Provides the $KUBERNETES_PROVIDER variable and detect-project function +source "${KUBE_ROOT}/cluster/kube-util.sh" +source "${KUBE_ROOT}/cluster/lib/logging.sh" readonly ACTION="${1:-gen}" @@ -59,11 +61,12 @@ readonly GOOGLE_APPLICATION_CREDENTIALS="${GOOGLE_APPLICATION_CREDENTIALS:-${HOM readonly KUBE_CONFIG_DIR="${KUBE_CONFIG_DIR:-${HOME}/.kube}" readonly KUBE_CONFIG="${KUBE_CONFIG:-${HOME}/.kube/config}" -KUBE_PROJECT="madhusudancs-k8s" -KUBE_REGISTRY="${KUBE_REGISTRY:-gcr.io/${KUBE_PROJECT}}" +detect-project +readonly KUBE_PROJECT="${KUBE_PROJECT:-${PROJECT:-}}" +readonly KUBE_REGISTRY="${KUBE_REGISTRY:-gcr.io/${KUBE_PROJECT}}" # In dev environments this value must be recomputed after build. See -# the build() function. +# the build() function. Not making it readonly KUBE_VERSION="${KUBE_VERSION:-}" From 1c8b418383c18c2142d103017b58655e37f99cf5 Mon Sep 17 00:00:00 2001 From: "Madhusudan.C.S" Date: Wed, 27 Jul 2016 19:31:29 -0700 Subject: [PATCH 09/12] Docs munger and flags verification fixes. --- federation/README.md | 3 +++ hack/verify-flags/exceptions.txt | 12 ++++++++++++ 2 files changed, 15 insertions(+) diff --git a/federation/README.md b/federation/README.md index 771dfccda3d..6c47a4616af 100644 --- a/federation/README.md +++ b/federation/README.md @@ -56,3 +56,6 @@ make build do=destroy The bash script sets `set -e errexit` which causes the script to exit at the very first error. This should be the default mode for deploying components but not for destroying/cleanup. + + +[![Analytics](https://kubernetes-site.appspot.com/UA-36037335-10/GitHub/federation/README.md?pixel)]() diff --git a/hack/verify-flags/exceptions.txt b/hack/verify-flags/exceptions.txt index ab1a6e1de0c..c90ce6f2398 100644 --- a/hack/verify-flags/exceptions.txt +++ b/hack/verify-flags/exceptions.txt @@ -64,6 +64,18 @@ cluster/vsphere/templates/salt-minion.sh: hostname_override: $(ip route get 1.1 examples/cluster-dns/images/frontend/client.py: service_address = socket.gethostbyname(hostname) examples/storage/cassandra/image/run.sh: cluster_name \ examples/storage/vitess/env.sh: node_ip=$(get_node_ip) +federation/config.default.json: "cloud_provider": "gce", +federation/config.default.json: "cloud_provider": "gce", +federation/config.default.json: "cloud_provider": "gce", +federation/config.default.json: "cluster_cidr": "10.180.0.0/14", +federation/config.default.json: "cluster_cidr": "10.184.0.0/14", +federation/config.default.json: "cluster_cidr": "10.188.0.0/14", +federation/config.default.json: "cluster_name": "cluster1-kubernetes", +federation/config.default.json: "cluster_name": "cluster2-kubernetes", +federation/config.default.json: "cluster_name": "cluster3-kubernetes", +federation/config.default.json: "num_nodes": 3, +federation/config.default.json: "num_nodes": 3, +federation/config.default.json: "num_nodes": 3, hack/local-up-cluster.sh: advertise_address="--advertise_address=${API_HOST}" hack/local-up-cluster.sh: runtime_config="--runtime-config=${RUNTIME_CONFIG}" hack/local-up-cluster.sh: advertise_address="" From 7f20effd922dbd6e7002554d3bf4b8f7aacdfb6a Mon Sep 17 00:00:00 2001 From: "Madhusudan.C.S" Date: Wed, 3 Aug 2016 19:41:40 -0700 Subject: [PATCH 10/12] Ensure the provider is supported and exit otherwise. --- federation/build.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/federation/build.sh b/federation/build.sh index 5a249ffa707..f06075b963b 100755 --- a/federation/build.sh +++ b/federation/build.sh @@ -133,6 +133,12 @@ function pull_installer() { } function ensure_files() { + kube::log::status "Ensure provider is supported..." + if [[ "${KUBERNETES_PROVIDER:-}" != "gce" ]]; then + echo "Supported providers: \"gce\"" + exit 1 + fi + kube::log::status "Ensure credential files exist..." if [[ ! -f "${GOOGLE_APPLICATION_CREDENTIALS}" ]]; then echo "Please ensure Google credentials file \""${GOOGLE_APPLICATION_CREDENTIALS}"\" exists." From fd03b9c43e17064680ede6d05edc55d3847a5124 Mon Sep 17 00:00:00 2001 From: "Madhusudan.C.S" Date: Wed, 10 Aug 2016 23:47:29 -0700 Subject: [PATCH 11/12] Add a TODO to re-evaluate jq dependency. --- federation/README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/federation/README.md b/federation/README.md index 6c47a4616af..fcee30ed745 100644 --- a/federation/README.md +++ b/federation/README.md @@ -10,6 +10,12 @@ for more details about setting up and using the Cluster Federation. Please see the [Kubernetes Development Guide](https://github.com/kubernetes/kubernetes/blob/master/docs/devel/development.md) for initial setup. Once you have the development environment setup as explained in that guide, you also need to install [`jq`](https://stedolan.github.io/jq/download/) + Building cluster federation should be as simple as running: From f3c82af6b6e2a6b82c0274cdf43d7c2fde121b18 Mon Sep 17 00:00:00 2001 From: "Madhusudan.C.S" Date: Wed, 10 Aug 2016 23:52:42 -0700 Subject: [PATCH 12/12] Switch tab indentation to two spaces. --- federation/build.sh | 174 ++++++++++++++++++++++---------------------- 1 file changed, 87 insertions(+), 87 deletions(-) diff --git a/federation/build.sh b/federation/build.sh index f06075b963b..0b708f64412 100755 --- a/federation/build.sh +++ b/federation/build.sh @@ -71,122 +71,122 @@ KUBE_VERSION="${KUBE_VERSION:-}" function cleanup { - rm -rf "${TMP_DIR}" - cd "${CUR_ROOT}" + rm -rf "${TMP_DIR}" + cd "${CUR_ROOT}" } trap cleanup EXIT function dirty_sha() { - local -r index="${KUBE_ROOT}/.git/index" - local -r objects_dir="${KUBE_ROOT}/.git/objects" + local -r index="${KUBE_ROOT}/.git/index" + local -r objects_dir="${KUBE_ROOT}/.git/objects" - local -r tmp_dir="${TMP_DIR}/.git" - local -r tmp_index="${tmp_dir}/index" - local -r tmp_objects_dir="${tmp_dir}/objects" + local -r tmp_dir="${TMP_DIR}/.git" + local -r tmp_index="${tmp_dir}/index" + local -r tmp_objects_dir="${tmp_dir}/objects" - mkdir -p "${tmp_objects_dir}" - cp "${index}" "${tmp_index}" + mkdir -p "${tmp_objects_dir}" + cp "${index}" "${tmp_index}" - local -r files=$(git ls-files -m -o -d --exclude-standard) - GIT_INDEX_FILE="${tmp_index}" git add ${files} - GIT_ALTERNATE_OBJECT_DIRECTORIES="${objects_dir}" GIT_OBJECT_DIRECTORY="${tmp_objects_dir}" GIT_INDEX_FILE="${tmp_index}" git write-tree + local -r files=$(git ls-files -m -o -d --exclude-standard) + GIT_INDEX_FILE="${tmp_index}" git add ${files} + GIT_ALTERNATE_OBJECT_DIRECTORIES="${objects_dir}" GIT_OBJECT_DIRECTORY="${tmp_objects_dir}" GIT_INDEX_FILE="${tmp_index}" git write-tree } function update_config() { - local -r q="${1:-}" - local -r cfile="${2:-}" - local -r bname="$(basename ${cfile})" + local -r q="${1:-}" + local -r cfile="${2:-}" + local -r bname="$(basename ${cfile})" - jq "${q}" "${cfile}" > "${TMP_DIR}/${bname}" - mv "${TMP_DIR}/${bname}" "${cfile}" + jq "${q}" "${cfile}" > "${TMP_DIR}/${bname}" + mv "${TMP_DIR}/${bname}" "${cfile}" } function build() { - kube::build::verify_prereqs - kube::build::build_image - kube::build::run_build_command make WHAT="cmd/kubectl cmd/hyperkube" + kube::build::verify_prereqs + kube::build::build_image + kube::build::run_build_command make WHAT="cmd/kubectl cmd/hyperkube" - # Recompute KUBE_VERSION because it might have changed after rebuild. - KUBE_VERSION="${KUBE_VERSION:-$(kube::release::semantic_image_tag_version)}" + # Recompute KUBE_VERSION because it might have changed after rebuild. + KUBE_VERSION="${KUBE_VERSION:-$(kube::release::semantic_image_tag_version)}" - # Also append the dirty tree SHA to keep the versions unique across - # builds. - if [[ "${KUBE_VERSION}" == *-dirty ]]; then - KUBE_VERSION+=".$(dirty_sha)" - fi + # Also append the dirty tree SHA to keep the versions unique across + # builds. + if [[ "${KUBE_VERSION}" == *-dirty ]]; then + KUBE_VERSION+=".$(dirty_sha)" + fi - BASEIMAGE="ubuntu:16.04" \ - REGISTRY="${KUBE_REGISTRY}" \ - VERSION="${KUBE_VERSION}" \ - make -C "${KUBE_ROOT}/cluster/images/hyperkube" build + BASEIMAGE="ubuntu:16.04" \ + REGISTRY="${KUBE_REGISTRY}" \ + VERSION="${KUBE_VERSION}" \ + make -C "${KUBE_ROOT}/cluster/images/hyperkube" build } function push() { - kube::log::status "Pushing hyperkube image to the registry" - gcloud docker push "${KUBE_REGISTRY}/hyperkube-amd64:${KUBE_VERSION}" + kube::log::status "Pushing hyperkube image to the registry" + gcloud docker push "${KUBE_REGISTRY}/hyperkube-amd64:${KUBE_VERSION}" } function pull_installer() { - kube::log::status "Pulling installer images" - docker pull "${KUBE_ANYWHERE_FEDERATION_IMAGE}:${KUBE_ANYWHERE_FEDERATION_VERSION}" - docker pull "${KUBE_ANYWHERE_FEDERATION_CHARTS_IMAGE}:${KUBE_ANYWHERE_FEDERATION_CHARTS_VERSION}" + kube::log::status "Pulling installer images" + docker pull "${KUBE_ANYWHERE_FEDERATION_IMAGE}:${KUBE_ANYWHERE_FEDERATION_VERSION}" + docker pull "${KUBE_ANYWHERE_FEDERATION_CHARTS_IMAGE}:${KUBE_ANYWHERE_FEDERATION_CHARTS_VERSION}" } function ensure_files() { - kube::log::status "Ensure provider is supported..." - if [[ "${KUBERNETES_PROVIDER:-}" != "gce" ]]; then - echo "Supported providers: \"gce\"" - exit 1 - fi + kube::log::status "Ensure provider is supported..." + if [[ "${KUBERNETES_PROVIDER:-}" != "gce" ]]; then + echo "Supported providers: \"gce\"" + exit 1 + fi - kube::log::status "Ensure credential files exist..." - if [[ ! -f "${GOOGLE_APPLICATION_CREDENTIALS}" ]]; then - echo "Please ensure Google credentials file \""${GOOGLE_APPLICATION_CREDENTIALS}"\" exists." - exit 1 - fi + kube::log::status "Ensure credential files exist..." + if [[ ! -f "${GOOGLE_APPLICATION_CREDENTIALS}" ]]; then + echo "Please ensure Google credentials file \""${GOOGLE_APPLICATION_CREDENTIALS}"\" exists." + exit 1 + fi - if [[ ! -f "${KUBE_CONFIG}" ]]; then - echo "Please ensure kubeconfig file \""${KUBE_CONFIG}"\" exists." - exit 1 - fi + if [[ ! -f "${KUBE_CONFIG}" ]]; then + echo "Please ensure kubeconfig file \""${KUBE_CONFIG}"\" exists." + exit 1 + fi } function kube_action() { - kube::log::status "${ACTION} clusters" - docker run \ - --user="$(id -u):$(id -g)" \ - -m 12G \ - -v "${GOOGLE_APPLICATION_CREDENTIALS}:/.config/gcloud/application_default_credentials.json:ro" \ - -v "${KUBE_CONFIG_DIR}:/.kube" \ - -v "${FEDERATION_OUTPUT_ROOT}:/_output" \ - "${KUBE_ANYWHERE_FEDERATION_IMAGE}:${KUBE_ANYWHERE_FEDERATION_VERSION}" \ - "${ACTION}" + kube::log::status "${ACTION} clusters" + docker run \ + --user="$(id -u):$(id -g)" \ + -m 12G \ + -v "${GOOGLE_APPLICATION_CREDENTIALS}:/.config/gcloud/application_default_credentials.json:ro" \ + -v "${KUBE_CONFIG_DIR}:/.kube" \ + -v "${FEDERATION_OUTPUT_ROOT}:/_output" \ + "${KUBE_ANYWHERE_FEDERATION_IMAGE}:${KUBE_ANYWHERE_FEDERATION_VERSION}" \ + "${ACTION}" } function federation_action() { - kube::log::status "${ACTION} federation components" - docker run \ - -m 12G \ - -v "${KUBE_CONFIG}:/root/.kube/config:ro" \ - -v "${FEDERATION_OUTPUT_ROOT}:/_output" \ - "${KUBE_ANYWHERE_FEDERATION_CHARTS_IMAGE}:${KUBE_ANYWHERE_FEDERATION_CHARTS_VERSION}" \ - "${ACTION}" + kube::log::status "${ACTION} federation components" + docker run \ + -m 12G \ + -v "${KUBE_CONFIG}:/root/.kube/config:ro" \ + -v "${FEDERATION_OUTPUT_ROOT}:/_output" \ + "${KUBE_ANYWHERE_FEDERATION_CHARTS_IMAGE}:${KUBE_ANYWHERE_FEDERATION_CHARTS_VERSION}" \ + "${ACTION}" } function gen_or_update_config() { - mkdir -p "${FEDERATION_OUTPUT_ROOT}" - cp "federation/config.default.json" "${FEDERATION_OUTPUT_ROOT}/config.json" + mkdir -p "${FEDERATION_OUTPUT_ROOT}" + cp "federation/config.default.json" "${FEDERATION_OUTPUT_ROOT}/config.json" - update_config \ - '[.[] | .phase1.gce.project |= "'"${KUBE_PROJECT}"'"]' \ + update_config \ + '[.[] | .phase1.gce.project |= "'"${KUBE_PROJECT}"'"]' \ "${FEDERATION_OUTPUT_ROOT}/config.json" - # Not chaining for readability - update_config \ - '[.[] | .phase2 = { docker_registry: "'"${KUBE_REGISTRY}"'", kubernetes_version: "'"${KUBE_VERSION}"'" } ]' \ - "${FEDERATION_OUTPUT_ROOT}/config.json" + # Not chaining for readability + update_config \ + '[.[] | .phase2 = { docker_registry: "'"${KUBE_REGISTRY}"'", kubernetes_version: "'"${KUBE_VERSION}"'" } ]' \ + "${FEDERATION_OUTPUT_ROOT}/config.json" - cat < "${FEDERATION_OUTPUT_ROOT}/values.yaml" + cat < "${FEDERATION_OUTPUT_ROOT}/values.yaml" apiserverRegistry: "${KUBE_REGISTRY}" apiserverVersion: "${KUBE_VERSION}" controllerManagerRegistry: "${KUBE_REGISTRY}" @@ -195,23 +195,23 @@ EOF } if [[ "${ACTION}" == "gen" || "${ACTION}" == "deploy" ]]; then - ensure_files + ensure_files - cd "${KUBE_ROOT}" - build - push + cd "${KUBE_ROOT}" + build + push - pull_installer + pull_installer - # Update config after build and push, but before turning up the clusters - # to ensure the config has the right image version tags. - gen_or_update_config + # Update config after build and push, but before turning up the clusters + # to ensure the config has the right image version tags. + gen_or_update_config - kube_action - federation_action + kube_action + federation_action else - federation_action - kube_action + federation_action + kube_action fi kube::log::status "Successfully completed!"