|
| 1 | +#!/usr/bin/env bash |
| 2 | +# Copyright 2024 The Karmada Authors. |
| 3 | +# |
| 4 | +# Licensed under the Apache License, Version 2.0 (the "License"); |
| 5 | +# you may not use this file except in compliance with the License. |
| 6 | +# You may obtain a copy of the License at |
| 7 | +# |
| 8 | +# http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | +# |
| 10 | +# Unless required by applicable law or agreed to in writing, software |
| 11 | +# distributed under the License is distributed on an "AS IS" BASIS, |
| 12 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 13 | +# See the License for the specific language governing permissions and |
| 14 | +# limitations under the License. |
| 15 | + |
| 16 | +# This script works for both linux and macOS. |
| 17 | + |
| 18 | +set -o errexit |
| 19 | +set -o nounset |
| 20 | +set -o pipefail |
| 21 | + |
| 22 | +REPO_ROOT=$(dirname "${BASH_SOURCE[0]}")/.. |
| 23 | +source "${REPO_ROOT}"/hack/util.sh |
| 24 | + |
| 25 | +# variable define |
| 26 | +KUBECONFIG_PATH=${KUBECONFIG_PATH:-"${HOME}/.kube"} |
| 27 | +MAIN_KUBECONFIG=${MAIN_KUBECONFIG:-"${KUBECONFIG_PATH}/karmada.config"} |
| 28 | +HOST_CLUSTER_NAME=${HOST_CLUSTER_NAME:-"karmada-host"} |
| 29 | +MEMBER_CLUSTER_KUBECONFIG=${MEMBER_CLUSTER_KUBECONFIG:-"${KUBECONFIG_PATH}/members.config"} |
| 30 | +MEMBER_CLUSTER_1_NAME=${MEMBER_CLUSTER_1_NAME:-"member1"} |
| 31 | +MEMBER_CLUSTER_2_NAME=${MEMBER_CLUSTER_2_NAME:-"member2"} |
| 32 | +PULL_MODE_CLUSTER_NAME=${PULL_MODE_CLUSTER_NAME:-"member3"} |
| 33 | +MEMBER_TMP_CONFIG_PREFIX="member-tmp" |
| 34 | +MEMBER_CLUSTER_1_TMP_CONFIG="${KUBECONFIG_PATH}/${MEMBER_TMP_CONFIG_PREFIX}-${MEMBER_CLUSTER_1_NAME}.config" |
| 35 | +MEMBER_CLUSTER_2_TMP_CONFIG="${KUBECONFIG_PATH}/${MEMBER_TMP_CONFIG_PREFIX}-${MEMBER_CLUSTER_2_NAME}.config" |
| 36 | +PULL_MODE_CLUSTER_TMP_CONFIG="${KUBECONFIG_PATH}/${MEMBER_TMP_CONFIG_PREFIX}-${PULL_MODE_CLUSTER_NAME}.config" |
| 37 | +HOST_IPADDRESS=${HOST_IPADDRESS:-} |
| 38 | +BUILD_FROM_SOURCE=${BUILD_FROM_SOURCE:-"true"} |
| 39 | +EXTRA_LOAD_IMAGES=${EXTRA_LOAD_IMAGES:-""} |
| 40 | + |
| 41 | +CLUSTER_VERSION=${CLUSTER_VERSION:-"${DEFAULT_CLUSTER_VERSION}"} |
| 42 | +KIND_LOG_FILE=${KIND_LOG_FILE:-"/tmp/karmada"} |
| 43 | + |
| 44 | +#step0: prepare |
| 45 | +# proxy setting in China mainland |
| 46 | +if [[ -n ${CHINA_MAINLAND:-} ]]; then |
| 47 | + util::set_mirror_registry_for_china_mainland ${REPO_ROOT} |
| 48 | +fi |
| 49 | + |
| 50 | +# make sure go exists and the go version is a viable version. |
| 51 | +util::cmd_must_exist "go" |
| 52 | +util::verify_go_version |
| 53 | + |
| 54 | +# make sure docker exists |
| 55 | +util::cmd_must_exist "docker" |
| 56 | + |
| 57 | +# install kind and kubectl |
| 58 | +kind_version=v0.25.0 |
| 59 | +echo -n "Preparing: 'kind' existence check - " |
| 60 | +if util::cmd_exist kind; then |
| 61 | + echo "passed" |
| 62 | +else |
| 63 | + echo "not pass" |
| 64 | + util::install_tools "sigs.k8s.io/kind" $kind_version |
| 65 | +fi |
| 66 | + |
| 67 | +# get arch name and os name in bootstrap |
| 68 | +BS_ARCH=$(go env GOARCH) |
| 69 | +BS_OS=$(go env GOOS) |
| 70 | +# check arch and os name before installing |
| 71 | +util::install_environment_check "${BS_ARCH}" "${BS_OS}" |
| 72 | +echo -n "Preparing: 'kubectl' existence check - " |
| 73 | +if util::cmd_exist kubectl; then |
| 74 | + echo "passed" |
| 75 | +else |
| 76 | + echo "not pass" |
| 77 | + util::install_kubectl "" "${BS_ARCH}" "${BS_OS}" |
| 78 | +fi |
| 79 | + |
| 80 | +#step1. create host cluster and member clusters in parallel |
| 81 | +# host IP address: script parameter ahead of macOS IP |
| 82 | +if [[ -z "${HOST_IPADDRESS}" ]]; then |
| 83 | + util::get_macos_ipaddress # Adapt for macOS |
| 84 | + HOST_IPADDRESS=${MAC_NIC_IPADDRESS:-} |
| 85 | +fi |
| 86 | +#prepare for kindClusterConfig |
| 87 | +TEMP_PATH=$(mktemp -d) |
| 88 | +trap '{ rm -rf ${TEMP_PATH}; }' EXIT |
| 89 | +echo -e "Preparing kindClusterConfig in path: ${TEMP_PATH}" |
| 90 | +cp -rf "${REPO_ROOT}"/artifacts/kindClusterConfig/member1.yaml "${TEMP_PATH}"/member1.yaml |
| 91 | +cp -rf "${REPO_ROOT}"/artifacts/kindClusterConfig/member2.yaml "${TEMP_PATH}"/member2.yaml |
| 92 | +cp -rf "${REPO_ROOT}"/artifacts/kindClusterConfig/member3.yaml "${TEMP_PATH}"/member3.yaml |
| 93 | + |
| 94 | +util::delete_necessary_resources "${MAIN_KUBECONFIG},${MEMBER_CLUSTER_KUBECONFIG}" "${HOST_CLUSTER_NAME},${MEMBER_CLUSTER_1_NAME},${MEMBER_CLUSTER_2_NAME},${PULL_MODE_CLUSTER_NAME}" "${KIND_LOG_FILE}" |
| 95 | + |
| 96 | +if [[ -n "${HOST_IPADDRESS}" ]]; then # If bind the port of clusters(karmada-host, member1 and member2) to the host IP |
| 97 | + util::verify_ip_address "${HOST_IPADDRESS}" |
| 98 | + cp -rf "${REPO_ROOT}"/artifacts/kindClusterConfig/karmada-host.yaml "${TEMP_PATH}"/karmada-host.yaml |
| 99 | + sed -i'' -e "s/{{host_ipaddress}}/${HOST_IPADDRESS}/g" "${TEMP_PATH}"/karmada-host.yaml |
| 100 | + sed -i'' -e 's/networking:/&\'$'\n'' apiServerAddress: "'${HOST_IPADDRESS}'"/' "${TEMP_PATH}"/member1.yaml |
| 101 | + sed -i'' -e 's/networking:/&\'$'\n'' apiServerAddress: "'${HOST_IPADDRESS}'"/' "${TEMP_PATH}"/member2.yaml |
| 102 | + sed -i'' -e 's/networking:/&\'$'\n'' apiServerAddress: "'${HOST_IPADDRESS}'"/' "${TEMP_PATH}"/member3.yaml |
| 103 | + util::create_cluster "${HOST_CLUSTER_NAME}" "${MAIN_KUBECONFIG}" "${CLUSTER_VERSION}" "${KIND_LOG_FILE}" "${TEMP_PATH}"/karmada-host.yaml |
| 104 | +else |
| 105 | + util::create_cluster "${HOST_CLUSTER_NAME}" "${MAIN_KUBECONFIG}" "${CLUSTER_VERSION}" "${KIND_LOG_FILE}" |
| 106 | +fi |
| 107 | +util::create_cluster "${MEMBER_CLUSTER_1_NAME}" "${MEMBER_CLUSTER_1_TMP_CONFIG}" "${CLUSTER_VERSION}" "${KIND_LOG_FILE}" "${TEMP_PATH}"/member1.yaml |
| 108 | +util::create_cluster "${MEMBER_CLUSTER_2_NAME}" "${MEMBER_CLUSTER_2_TMP_CONFIG}" "${CLUSTER_VERSION}" "${KIND_LOG_FILE}" "${TEMP_PATH}"/member2.yaml |
| 109 | +util::create_cluster "${PULL_MODE_CLUSTER_NAME}" "${PULL_MODE_CLUSTER_TMP_CONFIG}" "${CLUSTER_VERSION}" "${KIND_LOG_FILE}" "${TEMP_PATH}"/member3.yaml |
| 110 | + |
| 111 | +#step2. make images and get karmadactl |
| 112 | +export VERSION="latest" |
| 113 | +export REGISTRY="docker.io/karmada" |
| 114 | +if [[ "${BUILD_FROM_SOURCE}" == "true" ]]; then |
| 115 | + export KARMADA_IMAGE_LABEL_VALUE="May_be_pruned_in_local_up_environment" |
| 116 | + export DOCKER_BUILD_ARGS="${DOCKER_BUILD_ARGS:-} --label=image.karmada.io=${KARMADA_IMAGE_LABEL_VALUE}" |
| 117 | +# make images GOOS="linux" --directory="${REPO_ROOT}" |
| 118 | +# #clean up dangling images |
| 119 | +# docker image prune --force --filter "label=image.karmada.io=${KARMADA_IMAGE_LABEL_VALUE}" |
| 120 | +fi |
| 121 | +GO111MODULE=on go install "github.com/karmada-io/karmada/cmd/karmadactl" |
| 122 | + |
| 123 | +#step3. wait until clusters ready |
| 124 | +echo "Waiting for the clusters to be ready..." |
| 125 | +util::check_clusters_ready "${MAIN_KUBECONFIG}" "${HOST_CLUSTER_NAME}" |
| 126 | +util::check_clusters_ready "${MEMBER_CLUSTER_1_TMP_CONFIG}" "${MEMBER_CLUSTER_1_NAME}" |
| 127 | +util::check_clusters_ready "${MEMBER_CLUSTER_2_TMP_CONFIG}" "${MEMBER_CLUSTER_2_NAME}" |
| 128 | +util::check_clusters_ready "${PULL_MODE_CLUSTER_TMP_CONFIG}" "${PULL_MODE_CLUSTER_NAME}" |
| 129 | + |
| 130 | +#step4. load components images to kind cluster |
| 131 | +if [[ "${BUILD_FROM_SOURCE}" == "true" ]]; then |
| 132 | + # host cluster |
| 133 | + kind load docker-image "${REGISTRY}/karmada-controller-manager:${VERSION}" --name="${HOST_CLUSTER_NAME}" |
| 134 | + kind load docker-image "${REGISTRY}/karmada-scheduler:${VERSION}" --name="${HOST_CLUSTER_NAME}" |
| 135 | + kind load docker-image "${REGISTRY}/karmada-descheduler:${VERSION}" --name="${HOST_CLUSTER_NAME}" |
| 136 | + kind load docker-image "${REGISTRY}/karmada-webhook:${VERSION}" --name="${HOST_CLUSTER_NAME}" |
| 137 | + kind load docker-image "${REGISTRY}/karmada-scheduler-estimator:${VERSION}" --name="${HOST_CLUSTER_NAME}" |
| 138 | + kind load docker-image "${REGISTRY}/karmada-aggregated-apiserver:${VERSION}" --name="${HOST_CLUSTER_NAME}" |
| 139 | + kind load docker-image "${REGISTRY}/karmada-search:${VERSION}" --name="${HOST_CLUSTER_NAME}" |
| 140 | + kind load docker-image "${REGISTRY}/karmada-metrics-adapter:${VERSION}" --name="${HOST_CLUSTER_NAME}" |
| 141 | + for img in ${EXTRA_LOAD_IMAGES//,/ }; do |
| 142 | + kind load docker-image "$img" --name="${HOST_CLUSTER_NAME}" |
| 143 | + done |
| 144 | + # pull mode member cluster |
| 145 | + kind load docker-image "${REGISTRY}/karmada-agent:${VERSION}" --name="${PULL_MODE_CLUSTER_NAME}" |
| 146 | +fi |
| 147 | + |
| 148 | +#step5. connecting networks between karmada-host, member1 and member2 clusters |
| 149 | +echo "connecting cluster networks..." |
| 150 | +util::add_routes "${MEMBER_CLUSTER_1_NAME}" "${MEMBER_CLUSTER_2_TMP_CONFIG}" "${MEMBER_CLUSTER_2_NAME}" |
| 151 | +util::add_routes "${MEMBER_CLUSTER_2_NAME}" "${MEMBER_CLUSTER_1_TMP_CONFIG}" "${MEMBER_CLUSTER_1_NAME}" |
| 152 | + |
| 153 | +util::add_routes "${HOST_CLUSTER_NAME}" "${MEMBER_CLUSTER_1_TMP_CONFIG}" "${MEMBER_CLUSTER_1_NAME}" |
| 154 | +util::add_routes "${MEMBER_CLUSTER_1_NAME}" "${MAIN_KUBECONFIG}" "${HOST_CLUSTER_NAME}" |
| 155 | + |
| 156 | +util::add_routes "${HOST_CLUSTER_NAME}" "${MEMBER_CLUSTER_2_TMP_CONFIG}" "${MEMBER_CLUSTER_2_NAME}" |
| 157 | +util::add_routes "${MEMBER_CLUSTER_2_NAME}" "${MAIN_KUBECONFIG}" "${HOST_CLUSTER_NAME}" |
| 158 | +echo "cluster networks connected" |
| 159 | + |
| 160 | +#step6. merge temporary kubeconfig of member clusters by kubectl |
| 161 | +export KUBECONFIG=$(find ${KUBECONFIG_PATH} -maxdepth 1 -type f | grep ${MEMBER_TMP_CONFIG_PREFIX} | tr '\n' ':') |
| 162 | +kubectl config view --flatten > ${MEMBER_CLUSTER_KUBECONFIG} |
| 163 | +rm $(find ${KUBECONFIG_PATH} -maxdepth 1 -type f | grep ${MEMBER_TMP_CONFIG_PREFIX}) |
0 commit comments