-
-
Save jayunit100/cfcae32ff28752ee0fbf to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# Copyright 2014 The Kubernetes Authors 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 command builds and runs a local kubernetes cluster. It's just like | |
# local-up.sh, but this one launches the three separate binaries. | |
# You may need to run this as root to allow kubelet to open docker's socket. | |
DOCKER_OPTS=${DOCKER_OPTS:-""} | |
DOCKER_NATIVE=${DOCKER_NATIVE:-""} | |
DOCKER=(docker ${DOCKER_OPTS}) | |
DOCKERIZE_KUBELET=${DOCKERIZE_KUBELET:-""} | |
ALLOW_PRIVILEGED=${ALLOW_PRIVILEGED:-""} | |
RUNTIME_CONFIG=${RUNTIME_CONFIG:-""} | |
KUBE_ROOT=$(dirname "${BASH_SOURCE}")/.. | |
cd "${KUBE_ROOT}" | |
if [ "$(id -u)" != "0" ]; then | |
echo "WARNING : This script MAY be run as root for docker socket / iptables functionality; if failures occur, retry as root." 2>&1 | |
fi | |
# Stop right away if the build fails | |
set -e | |
source "${KUBE_ROOT}/hack/lib/init.sh" | |
function usage { | |
echo "This script starts a local kube cluster. " | |
echo "Example 1: hack/local-up-cluster.sh -o _output/dockerized/bin/linux/amd64/ (run from docker output)" | |
echo "Example 2: hack/local-up-cluster.sh (build a local copy of the source)" | |
} | |
### Allow user to supply the source directory. | |
GO_OUT="" | |
while getopts "o:" OPTION | |
do | |
case $OPTION in | |
o) | |
echo "skipping build" | |
echo "using source $OPTARG" | |
GO_OUT="$OPTARG" | |
if [ $GO_OUT == "" ]; then | |
echo "You provided an invalid value for the build output directory." | |
exit | |
fi | |
;; | |
?) | |
usage | |
exit | |
;; | |
esac | |
done | |
if [ "x$GO_OUT" == "x" ]; then | |
"${KUBE_ROOT}/hack/build-go.sh" cmd/kube-proxy cmd/kube-apiserver cmd/kube-controller-manager cmd/kubelet plugin/cmd/kube-scheduler | |
else | |
echo "skipped the build." | |
fi | |
function test_docker { | |
${DOCKER[@]} ps 2> /dev/null 1> /dev/null | |
if [ "$?" != "0" ]; then | |
echo "Failed to successfully run 'docker ps', please verify that docker is installed and \$DOCKER_HOST is set correctly." | |
exit 1 | |
fi | |
} | |
# Shut down anyway if there's an error. | |
set +e | |
API_PORT=${API_PORT:-8080} | |
API_HOST=${API_HOST:-127.0.0.1} | |
# By default only allow CORS for requests on localhost | |
API_CORS_ALLOWED_ORIGINS=${API_CORS_ALLOWED_ORIGINS:-"/127.0.0.1(:[0-9]+)?$,/localhost(:[0-9]+)?$"} | |
KUBELET_PORT=${KUBELET_PORT:-10250} | |
LOG_LEVEL=${LOG_LEVEL:-3} | |
CONTAINER_RUNTIME=${CONTAINER_RUNTIME:-"docker"} | |
RKT_PATH=${RKT_PATH:-""} | |
RKT_STAGE1_IMAGE=${RKT_STAGE1_IMAGE:-""} | |
CHAOS_CHANCE=${CHAOS_CHANCE:-0.0} | |
function test_apiserver_off { | |
# For the common local scenario, fail fast if server is already running. | |
# this can happen if you run local-up-cluster.sh twice and kill etcd in between. | |
curl $API_HOST:$API_PORT | |
if [ ! $? -eq 0 ]; then | |
echo "API SERVER port is free, proceeding..." | |
else | |
echo "ERROR starting API SERVER, exiting. Some host on $API_HOST is serving already on $API_PORT" | |
exit 1 | |
fi | |
} | |
function detect_binary { | |
# Detect the OS name/arch so that we can find our binary | |
case "$(uname -s)" in | |
Darwin) | |
host_os=darwin | |
;; | |
Linux) | |
host_os=linux | |
;; | |
*) | |
echo "Unsupported host OS. Must be Linux or Mac OS X." >&2 | |
exit 1 | |
;; | |
esac | |
case "$(uname -m)" in | |
x86_64*) | |
host_arch=amd64 | |
;; | |
i?86_64*) | |
host_arch=amd64 | |
;; | |
amd64*) | |
host_arch=amd64 | |
;; | |
arm*) | |
host_arch=arm | |
;; | |
i?86*) | |
host_arch=x86 | |
;; | |
*) | |
echo "Unsupported host arch. Must be x86_64, 386 or arm." >&2 | |
exit 1 | |
;; | |
esac | |
GO_OUT="${KUBE_ROOT}/_output/local/bin/${host_os}/${host_arch}" | |
} | |
cleanup_dockerized_kubelet() | |
{ | |
if [[ -e $KUBELET_CIDFILE ]]; then | |
docker kill $(<$KUBELET_CIDFILE) > /dev/null | |
rm -f $KUBELET_CIDFILE | |
fi | |
} | |
cleanup() | |
{ | |
echo "Cleaning up..." | |
# Check if the API server is still running | |
[[ -n "${APISERVER_PID-}" ]] && APISERVER_PIDS=$(pgrep -P ${APISERVER_PID} ; ps -o pid= -p ${APISERVER_PID}) | |
[[ -n "${APISERVER_PIDS-}" ]] && sudo kill ${APISERVER_PIDS} | |
# Check if the controller-manager is still running | |
[[ -n "${CTLRMGR_PID-}" ]] && CTLRMGR_PIDS=$(pgrep -P ${CTLRMGR_PID} ; ps -o pid= -p ${CTLRMGR_PID}) | |
[[ -n "${CTLRMGR_PIDS-}" ]] && sudo kill ${CTLRMGR_PIDS} | |
if [[ -n "$DOCKERIZE_KUBELET" ]]; then | |
cleanup_dockerized_kubelet | |
else | |
# Check if the kubelet is still running | |
[[ -n "${KUBELET_PID-}" ]] && KUBELET_PIDS=$(pgrep -P ${KUBELET_PID} ; ps -o pid= -p ${KUBELET_PID}) | |
[[ -n "${KUBELET_PIDS-}" ]] && sudo kill ${KUBELET_PIDS} | |
fi | |
# Check if the proxy is still running | |
[[ -n "${PROXY_PID-}" ]] && PROXY_PIDS=$(pgrep -P ${PROXY_PID} ; ps -o pid= -p ${PROXY_PID}) | |
[[ -n "${PROXY_PIDS-}" ]] && sudo kill ${PROXY_PIDS} | |
# Check if the scheduler is still running | |
[[ -n "${SCHEDULER_PID-}" ]] && SCHEDULER_PIDS=$(pgrep -P ${SCHEDULER_PID} ; ps -o pid= -p ${SCHEDULER_PID}) | |
[[ -n "${SCHEDULER_PIDS-}" ]] && sudo kill ${SCHEDULER_PIDS} | |
# Check if the etcd is still running | |
[[ -n "${ETCD_PID-}" ]] && kube::etcd::stop | |
[[ -n "${ETCD_DIR-}" ]] && kube::etcd::clean_etcd_dir | |
exit 0 | |
} | |
function createUsers { | |
### Example token file. Obviously you wouldn't use this in production. | |
cat << EOF > /tmp/kubehack-token | |
kubelet,kubelet,1 | |
EOF | |
cat << EOF > /tmp/kubehack-kubeconfig | |
apiVersion: v1 | |
kind: Config | |
current-context: mycontext | |
clusters: | |
- cluster: | |
insecure-skip-tls-verify: true | |
# Warning, this is not used if kubelet takes --api-servers option. | |
server: https://127.0.0.1:30279 | |
name: myserver | |
contexts: | |
- context: | |
cluster: myserver | |
user: kubelet | |
name: mycontext | |
preferences: {} | |
users: | |
- name: kubelet | |
user: | |
token: kubelet | |
- name: myuser | |
user: {} | |
EOF | |
chmod 777 /tmp/kubehack-* | |
} | |
function startETCD { | |
echo "Starting etcd" | |
kube::etcd::start | |
} | |
function set_service_accounts { | |
SERVICE_ACCOUNT_LOOKUP=${SERVICE_ACCOUNT_LOOKUP:-false} | |
SERVICE_ACCOUNT_KEY=${SERVICE_ACCOUNT_KEY:-"/tmp/kube-serviceaccount.key"} | |
# Generate ServiceAccount key if needed | |
if [[ ! -f "${SERVICE_ACCOUNT_KEY}" ]]; then | |
mkdir -p "$(dirname ${SERVICE_ACCOUNT_KEY})" | |
openssl genrsa -out "${SERVICE_ACCOUNT_KEY}" 2048 2>/dev/null | |
fi | |
} | |
function start_apiserver { | |
# Admission Controllers to invoke prior to persisting objects in cluster | |
ADMISSION_CONTROL=NamespaceLifecycle,NamespaceAutoProvision,LimitRanger,SecurityContextDeny,ServiceAccount,DenyEscalatingExec,ResourceQuota | |
# This is the default dir and filename where the apiserver will generate a self-signed cert | |
# which should be able to be used as the CA to verify itself | |
CERT_DIR=/var/run/kubernetes | |
ROOT_CA_FILE=$CERT_DIR/apiserver.crt | |
priv_arg="" | |
if [[ -n "${ALLOW_PRIVILEGED}" ]]; then | |
priv_arg="--allow-privileged " | |
fi | |
runtime_config="" | |
if [[ -n "${RUNTIME_CONFIG}" ]]; then | |
runtime_config="--runtime-config=${RUNTIME_CONFIG}" | |
fi | |
APISERVER_LOG=/tmp/kube-apiserver.log | |
# We provide a token auth, so that kubelets can access the api-server | |
# through a service endpoint. This allows for highly available api-server | |
# setups. | |
sudo -E "${GO_OUT}/kube-apiserver" ${priv_arg} ${runtime_config} \ | |
--v=${LOG_LEVEL} \ | |
--cert-dir="${CERT_DIR}" \ | |
--service-account-key-file="${SERVICE_ACCOUNT_KEY}" \ | |
--authorization-mode=AlwaysAllow \ | |
--service-account-lookup="${SERVICE_ACCOUNT_LOOKUP}" \ | |
--admission-control="${ADMISSION_CONTROL}" \ | |
--insecure-bind-address="${API_HOST}" \ | |
--token-auth-file="/tmp/kubehack-token" \ | |
--insecure-port="${API_PORT}" \ | |
--etcd-servers="http://127.0.0.1:4001" \ | |
--service-cluster-ip-range="10.0.0.0/24" \ | |
--apiserver-node-port="30279" \ | |
--cors-allowed-origins="${API_CORS_ALLOWED_ORIGINS}" >"${APISERVER_LOG}" 2>&1 & | |
APISERVER_PID=$! | |
# Wait for kube-apiserver to come up before launching the rest of the components. | |
echo "Waiting for apiserver to come up" | |
kube::util::wait_for_url "http://${API_HOST}:${API_PORT}/api/v1/pods" "apiserver: " 1 10 || exit 1 | |
} | |
function start_controller_manager { | |
CTLRMGR_LOG=/tmp/kube-controller-manager.log | |
sudo -E "${GO_OUT}/kube-controller-manager" \ | |
--v=${LOG_LEVEL} \ | |
--service-account-private-key-file="${SERVICE_ACCOUNT_KEY}" \ | |
--root-ca-file="${ROOT_CA_FILE}" \ | |
--master="${API_HOST}:${API_PORT}" >"${CTLRMGR_LOG}" 2>&1 & | |
CTLRMGR_PID=$! | |
} | |
function start_kubelet { | |
echo "Start kubelet" | |
KUBELET_LOG=/tmp/kubelet.log | |
# The kubelet in this example access the API Server through a service endpoint, | |
# in order for this to happen, we need to provide kubeconfig credentials as well. | |
if [[ -z "${DOCKERIZE_KUBELET}" ]]; then | |
sudo -E "${GO_OUT}/kubelet" ${priv_arg} \ | |
--v=${LOG_LEVEL} \ | |
--chaos-chance="${CHAOS_CHANCE}" \ | |
--container-runtime="${CONTAINER_RUNTIME}" \ | |
--rkt-path="${RKT_PATH}" \ | |
--hostname-override="127.0.0.1" \ | |
--rkt-stage1-image="${RKT_STAGE1_IMAGE}" \ | |
--api-servers="https://127.0.0.1:30279" \ | |
--kubeconfig="/tmp/kubehack-kubeconfig" \ | |
--port="$KUBELET_PORT" >"${KUBELET_LOG}" 2>&1 & | |
KUBELET_PID=$! | |
else | |
# Docker won't run a container with a cidfile (container id file) | |
# unless that file does not already exist; clean up an existing | |
# dockerized kubelet that might be running. | |
cleanup_dockerized_kubelet | |
docker run \ | |
--volume=/:/rootfs:ro \ | |
--volume=/var/run:/var/run:rw \ | |
--volume=/sys:/sys:ro \ | |
--volume=/var/lib/docker/:/var/lib/docker:ro \ | |
--volume=/var/lib/kubelet/:/var/lib/kubelet:rw \ | |
--net=host \ | |
--privileged=true \ | |
-i \ | |
--cidfile=$KUBELET_CIDFILE \ | |
gcr.io/google_containers/kubelet \ | |
/kubelet --v=3 --containerized ${priv_arg}--chaos-chance="${CHAOS_CHANCE}" --hostname-override="127.0.0.1" --address="127.0.0.1" --api-servers="${API_HOST}:${API_PORT}" --port="$KUBELET_PORT" --resource-container="" &> $KUBELET_LOG & | |
fi | |
} | |
function start_kubeproxy { | |
PROXY_LOG=/tmp/kube-proxy.log | |
sudo -E "${GO_OUT}/kube-proxy" \ | |
--v=${LOG_LEVEL} \ | |
--master="http://${API_HOST}:${API_PORT}" >"${PROXY_LOG}" 2>&1 & | |
PROXY_PID=$! | |
SCHEDULER_LOG=/tmp/kube-scheduler.log | |
sudo -E "${GO_OUT}/kube-scheduler" \ | |
--v=${LOG_LEVEL} \ | |
--master="http://${API_HOST}:${API_PORT}" >"${SCHEDULER_LOG}" 2>&1 & | |
SCHEDULER_PID=$! | |
} | |
function print_success { | |
cat <<EOF | |
Local Kubernetes cluster is running. Press Ctrl-C to shut it down. | |
Logs: | |
${APISERVER_LOG} | |
${CTLRMGR_LOG} | |
${PROXY_LOG} | |
${SCHEDULER_LOG} | |
${KUBELET_LOG} | |
To start using your cluster, open up another terminal/tab and run: | |
cluster/kubectl.sh config set-cluster local --server=http://${API_HOST}:${API_PORT} --insecure-skip-tls-verify=true | |
cluster/kubectl.sh config set-context local --cluster=local | |
cluster/kubectl.sh config use-context local | |
cluster/kubectl.sh | |
EOF | |
} | |
# Users allow the kubelet to access service endpoints | |
createUsers | |
test_docker | |
test_apiserver_off | |
### IF the user didn't supply an output/ for the build... Then we detect. | |
if [ "$GO_OUT" == "" ]; then | |
detect_binary | |
fi | |
echo "Detected host and ready to start services. Doing some housekeeping first..." | |
echo "Using GO_OUT $GO_OUT" | |
KUBELET_CIDFILE=/tmp/kubelet.cid | |
trap cleanup EXIT | |
echo "Starting services now!" | |
startETCD | |
set_service_accounts | |
start_apiserver | |
start_kubeproxy | |
start_kubelet | |
start_controller_manager | |
print_success | |
while true; do sleep 1; done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment