kubernetes/cluster/gce/coreos/configure-node.sh
Zihong Zheng d961190e6f Deployed DNS horizontal autoscaler as an addon
DNS horizontal autoscaling feature is turned on by default on gce.
The corresponding env var is piped into almost all other cloud
providers.
2016-11-07 10:44:44 -08:00

348 lines
13 KiB
Bash
Executable File

#!/bin/bash
# Copyright 2015 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.
set -o errexit
set -o nounset
set -o pipefail
readonly KNOWN_TOKENS_FILE="/srv/salt-overlay/salt/kube-apiserver/known_tokens.csv"
readonly BASIC_AUTH_FILE="/srv/salt-overlay/salt/kube-apiserver/basic_auth.csv"
# evaluate-manifest evalutes the source manifest with the environment variables.
function evaluate-manifest() {
local src=$1
local dst=$2
cp ${src} ${dst}
sed -i 's/\"/\\\"/g' ${dst} # eval will remove the double quotes if they are not escaped
eval "echo \"$(< ${dst})\"" > ${dst}
}
# evaluate-manifests-dir evalutes the source manifests within $1 and put the result
# in $2.
function evaluate-manifests-dir() {
local src=$1
local dst=$2
mkdir -p ${dst}
for f in ${src}/*
do
evaluate-manifest $f ${dst}/${f##*/}
done
}
function configure-kube-proxy() {
echo "Configuring kube-proxy"
mkdir -p /var/lib/kube-proxy
evaluate-manifest ${MANIFESTS_DIR}/kubeproxy-config.yaml /var/lib/kube-proxy/kubeconfig
}
function configure-logging() {
if [[ "${LOGGING_DESTINATION}" == "gcp" ]];then
echo "Configuring fluentd-gcp"
# fluentd-gcp
evaluate-manifest ${MANIFESTS_DIR}/fluentd-gcp.yaml /etc/kubernetes/manifests/fluentd-gcp.yaml
elif [[ "${LOGGING_DESTINATION}" == "elasticsearch" ]];then
echo "Configuring fluentd-es"
# fluentd-es
evaluate-manifest ${MANIFESTS_DIR}/fluentd-es.yaml /etc/kubernetes/manifests/fluentd-es.yaml
fi
}
function configure-admission-controls() {
echo "Configuring admission controls"
mkdir -p /etc/kubernetes/admission-controls
cp -r ${SALT_DIR}/salt/kube-admission-controls/limit-range /etc/kubernetes/admission-controls/
}
function configure-etcd() {
echo "Configuring etcd"
touch /var/log/etcd.log
evaluate-manifest ${MANIFESTS_DIR}/etcd.yaml /etc/kubernetes/manifests/etcd.yaml
}
function configure-etcd-events() {
echo "Configuring etcd-events"
touch /var/log/etcd-events.log
evaluate-manifest ${MANIFESTS_DIR}/etcd-events.yaml /etc/kubernetes/manifests/etcd-events.yaml
}
function configure-addon-manager() {
echo "Configuring addon-manager"
evaluate-manifest ${MANIFESTS_DIR}/kube-addon-manager.yaml /etc/kubernetes/manifests/kube-addon-manager.yaml
}
function configure-kube-apiserver() {
echo "Configuring kube-apiserver"
# Wait for etcd to be up.
wait-url-up http://127.0.0.1:2379/version
touch /var/log/kube-apiserver.log
# Copying known_tokens and basic_auth file.
cp ${SALT_OVERLAY}/salt/kube-apiserver/*.csv /srv/kubernetes/
evaluate-manifest ${MANIFESTS_DIR}/kube-apiserver.yaml /etc/kubernetes/manifests/kube-apiserver.yaml
}
function configure-kube-scheduler() {
echo "Configuring kube-scheduler"
touch /var/log/kube-scheduler.log
evaluate-manifest ${MANIFESTS_DIR}/kube-scheduler.yaml /etc/kubernetes/manifests/kube-scheduler.yaml
}
function configure-kube-controller-manager() {
# Wait for api server.
wait-url-up http://127.0.0.1:8080/version
echo "Configuring kube-controller-manager"
touch /var/log/kube-controller-manager.log
evaluate-manifest ${MANIFESTS_DIR}/kube-controller-manager.yaml /etc/kubernetes/manifests/kube-controller-manager.yaml
}
# Wait until $1 become reachable.
function wait-url-up() {
until curl --silent $1
do
sleep 5
done
}
# Configure addon yamls, and run salt/kube-addons/kube-addons.sh
function configure-master-addons() {
echo "Configuring master addons"
local addon_dir=/etc/kubernetes/addons
mkdir -p ${addon_dir}
# Copy namespace.yaml
evaluate-manifest ${MANIFESTS_DIR}/addons/namespace.yaml ${addon_dir}/namespace.yaml
if [[ "${ENABLE_L7_LOADBALANCING}" == "glbc" ]]; then
evaluate-manifests-dir ${MANIFESTS_DIR}/addons/cluster-loadbalancing/glbc ${addon_dir}/cluster-loadbalancing/glbc
fi
if [[ "${ENABLE_CLUSTER_DNS}" == "true" ]]; then
evaluate-manifests-dir ${MANIFESTS_DIR}/addons/dns ${addon_dir}/dns
if [[ "${ENABLE_DNS_HORIZONTAL_AUTOSCALER}" == "true" ]]; then
evaluate-manifests-dir ${MANIFESTS_DIR}/addons/dns-horizontal-autoscaler ${addon_dir}/dns-horizontal-autoscaler
fi
fi
if [[ "${ENABLE_CLUSTER_UI}" == "true" ]]; then
evaluate-manifests-dir ${MANIFESTS_DIR}/addons/dashboard ${addon_dir}/dashboard
fi
if [[ "${ENABLE_CLUSTER_LOGGING}" == "true" ]]; then
evaluate-manifests-dir ${MANIFESTS_DIR}/addons/fluentd-elasticsearch ${addon_dir}/fluentd-elasticsearch
fi
if [[ "${ENABLE_CLUSTER_MONITORING}" == "influxdb" ]]; then
evaluate-manifests-dir ${MANIFESTS_DIR}/addons/cluster-monitoring/influxdb ${addon_dir}/cluster-monitoring/influxdb
elif [[ "${ENABLE_CLUSTER_MONITORING}" == "google" ]]; then
evaluate-manifests-dir ${MANIFESTS_DIR}/addons/cluster-monitoring/google ${addon_dir}/cluster-monitoring/google
elif [[ "${ENABLE_CLUSTER_MONITORING}" == "standalone" ]]; then
evaluate-manifests-dir ${MANIFESTS_DIR}/addons/cluster-monitoring/standalone ${addon_dir}/cluster-monitoring/standalone
elif [[ "${ENABLE_CLUSTER_MONITORING}" == "googleinfluxdb" ]]; then
evaluate-manifests-dir ${MANIFESTS_DIR}/addons/cluster-monitoring/googleinfluxdb ${addon_dir}/cluster-monitoring/googleinfluxdb
fi
# Note that, KUBE_ENABLE_INSECURE_REGISTRY is not supported yet.
if [[ "${ENABLE_CLUSTER_REGISTRY}" == "true" ]]; then
CLUSTER_REGISTRY_DISK_SIZE=$(convert-bytes-gce-kube "${CLUSTER_REGISTRY_DISK_SIZE}")
evaluate-manifests-dir ${MANIFESTS_DIR}/addons/registry ${addon_dir}/registry
fi
if [[ "${ENABLE_NODE_PROBLEM_DETECTOR}" == "true" ]]; then
evaluate-manifests-dir ${MANIFESTS_DIR}/addons/node-problem-detector ${addon_dir}/node-problem-detector
fi
}
function configure-master-components() {
configure-admission-controls
configure-etcd
configure-etcd-events
configure-kube-apiserver
configure-kube-scheduler
configure-kube-controller-manager
configure-master-addons
configure-addon-manager
}
# TODO(yifan): Merge this with mount-master-pd() in configure-vm.sh
# Pass ${save_format_and_mount} as an argument.
function mount-master-pd() {
if [[ ! -e /dev/disk/by-id/google-master-pd ]]; then
return
fi
device_info=$(ls -l /dev/disk/by-id/google-master-pd)
relative_path=${device_info##* }
device_path="/dev/disk/by-id/${relative_path}"
# Format and mount the disk, create directories on it for all of the master's
# persistent data, and link them to where they're used.
echo "Mounting master-pd"
mkdir -p /mnt/master-pd
safe_format_and_mount=${SALT_DIR}/salt/helpers/safe_format_and_mount
chmod +x ${safe_format_and_mount}
${safe_format_and_mount} -m "mkfs.ext4 -F" "${device_path}" /mnt/master-pd &>/var/log/master-pd-mount.log || \
{ echo "!!! master-pd mount failed, review /var/log/master-pd-mount.log !!!"; return 1; }
# Contains all the data stored in etcd
mkdir -m 700 -p /mnt/master-pd/var/etcd
# Contains the dynamically generated apiserver auth certs and keys
mkdir -p /mnt/master-pd/srv/kubernetes
# Contains the cluster's initial config parameters and auth tokens
mkdir -p /mnt/master-pd/srv/salt-overlay
# Directory for kube-apiserver to store SSH key (if necessary)
mkdir -p /mnt/master-pd/srv/sshproxy
ln -s -f /mnt/master-pd/var/etcd /var/etcd
ln -s -f /mnt/master-pd/srv/kubernetes /srv/kubernetes
ln -s -f /mnt/master-pd/srv/sshproxy /srv/sshproxy
ln -s -f /mnt/master-pd/srv/salt-overlay /srv/salt-overlay
# This is a bit of a hack to get around the fact that salt has to run after the
# PD and mounted directory are already set up. We can't give ownership of the
# directory to etcd until the etcd user and group exist, but they don't exist
# until salt runs if we don't create them here. We could alternatively make the
# permissions on the directory more permissive, but this seems less bad.
if ! id etcd &>/dev/null; then
useradd -s /sbin/nologin -d /var/etcd etcd
fi
chown -R etcd /mnt/master-pd/var/etcd
chgrp -R etcd /mnt/master-pd/var/etcd
}
# The job of this function is simple, but the basic regular expression syntax makes
# this difficult to read. What we want to do is convert from [0-9]+B, KB, KiB, MB, etc
# into [0-9]+, Ki, Mi, Gi, etc.
# This is done in two steps:
# 1. Convert from [0-9]+X?i?B into [0-9]X? (X denotes the prefix, ? means the field
# is optional.
# 2. Attach an 'i' to the end of the string if we find a letter.
# The two step process is needed to handle the edge case in which we want to convert
# a raw byte count, as the result should be a simple number (e.g. 5B -> 5).
#
# TODO(yifan): Reuse the one defined in configure-vm.sh to remove duplication.
function convert-bytes-gce-kube() {
local -r storage_space=$1
echo "${storage_space}" | sed -e 's/^\([0-9]\+\)\([A-Z]\)\?i\?B$/\1\2/g' -e 's/\([A-Z]\)$/\1i/'
}
# TODO(yifan): Use create-salt-master-auth() in configure-vm.sh
function create-salt-master-auth() {
if [[ ! -e /srv/kubernetes/ca.crt ]]; then
if [[ ! -z "${CA_CERT:-}" ]] && [[ ! -z "${MASTER_CERT:-}" ]] && [[ ! -z "${MASTER_KEY:-}" ]]; then
mkdir -p /srv/kubernetes
(umask 077;
echo "${CA_CERT}" | base64 --decode > /srv/kubernetes/ca.crt;
echo "${MASTER_CERT}" | base64 --decode > /srv/kubernetes/server.cert;
echo "${MASTER_KEY}" | base64 --decode > /srv/kubernetes/server.key;
# Kubecfg cert/key are optional and included for backwards compatibility.
# TODO(roberthbailey): Remove these two lines once GKE no longer requires
# fetching clients certs from the master VM.
echo "${KUBECFG_CERT:-}" | base64 --decode > /srv/kubernetes/kubecfg.crt;
echo "${KUBECFG_KEY:-}" | base64 --decode > /srv/kubernetes/kubecfg.key)
fi
fi
if [ ! -e "${BASIC_AUTH_FILE}" ]; then
mkdir -p /srv/salt-overlay/salt/kube-apiserver
(umask 077;
echo "${KUBE_PASSWORD},${KUBE_USER},admin" > "${BASIC_AUTH_FILE}")
fi
if [ ! -e "${KNOWN_TOKENS_FILE}" ]; then
mkdir -p /srv/salt-overlay/salt/kube-apiserver
(umask 077;
echo "${KUBE_BEARER_TOKEN},admin,admin" > "${KNOWN_TOKENS_FILE}";
echo "${KUBELET_TOKEN},kubelet,kubelet" >> "${KNOWN_TOKENS_FILE}";
echo "${KUBE_PROXY_TOKEN},kube_proxy,kube_proxy" >> "${KNOWN_TOKENS_FILE}")
# Generate tokens for other "service accounts". Append to known_tokens.
#
# NB: If this list ever changes, this script actually has to
# change to detect the existence of this file, kill any deleted
# old tokens and add any new tokens (to handle the upgrade case).
local -r service_accounts=("system:scheduler" "system:controller_manager" "system:logging" "system:monitoring")
for account in "${service_accounts[@]}"; do
token=$(dd if=/dev/urandom bs=128 count=1 2>/dev/null | base64 | tr -d "=+/" | dd bs=32 count=1 2>/dev/null)
echo "${token},${account},${account}" >> "${KNOWN_TOKENS_FILE}"
done
fi
}
# $1 is the directory containing all of the docker images
function load-docker-images() {
local success
local restart_docker
while true; do
success=true
restart_docker=false
for image in "$1/"*; do
timeout 30 docker load -i "${image}" &>/dev/null
rc=$?
if [[ "$rc" == 124 ]]; then
restart_docker=true
elif [[ "$rc" != 0 ]]; then
success=false
fi
done
if [[ "$success" == "true" ]]; then break; fi
if [[ "$restart_docker" == "true" ]]; then systemctl restart docker; fi
sleep 15
done
}
function load-master-components-images() {
echo "Loading images for master components"
export RKT_BIN=/opt/rkt/rkt
export DOCKER2ACI_BIN=/opt/docker2aci/docker2aci
${SALT_DIR}/install.sh ${KUBE_BIN_TAR}
${SALT_DIR}/salt/kube-master-addons/kube-master-addons.sh
# Get the image tags.
KUBE_APISERVER_DOCKER_TAG=$(cat ${KUBE_BIN_DIR}/kube-apiserver.docker_tag)
KUBE_CONTROLLER_MANAGER_DOCKER_TAG=$(cat ${KUBE_BIN_DIR}/kube-controller-manager.docker_tag)
KUBE_SCHEDULER_DOCKER_TAG=$(cat ${KUBE_BIN_DIR}/kube-scheduler.docker_tag)
}
##########
# main #
##########
KUBE_BIN_TAR=/opt/downloads/kubernetes-server-linux-amd64.tar.gz
KUBE_BIN_DIR=/opt/kubernetes/server/bin
SALT_DIR=/opt/kubernetes/saltbase
SALT_OVERLAY=/srv/salt-overlay
MANIFESTS_DIR=/opt/kube-manifests/kubernetes
# On CoreOS, the hosts is in /usr/share/baselayout/hosts
# So we need to manually populdate the hosts file here on gce.
echo "127.0.0.1 localhost" >> /etc/hosts
echo "::1 localhost" >> /etc/hosts
if [[ "${KUBERNETES_MASTER}" == "true" ]]; then
mount-master-pd
create-salt-master-auth
load-master-components-images
configure-master-components
else
configure-kube-proxy
fi
if [[ "${ENABLE_NODE_LOGGING}" == "true" ]];then
configure-logging
fi
echo "Finish configuration successfully!"