Skip to content

Commit

Permalink
Make service-account secrets in kubectl form.
Browse files Browse the repository at this point in the history
Changes approach taken in kubernetes#5470
Instead of creating a kubernetes_auth file,
which we are tring to get away from, creates
a kubeconfig file, which is the new hotness.

Instead of creating the kubeconfig file in the
kube-addon script on the master, it creates
it at the time of salt-overlay generation.
More information is available at this time.

In particular, the master certs and master address
are handy at this point, so those are included in
the kubeconfig file.

The kube-addons script is simplified because the secret objects
are now just plain olf yaml files, which it knows how to
create, just like it creates pods and services.

Kubectl is used to generate the kubeconfig file.
This ensures correct format and is more self-documenting,
and matches how the admin credentials are done.

TODO(erictune): do this for kubelet.
  • Loading branch information
erictune committed Apr 17, 2015
1 parent f6238fa commit 73111da
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 36 deletions.
48 changes: 47 additions & 1 deletion cluster/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ KUBE_ROOT=$(dirname "${BASH_SOURCE}")/..

DEFAULT_KUBECONFIG="${HOME}/.kube/config"

# Generate kubeconfig data for the created cluster.
# Generate kubeconfig data for admin user for the created cluster.
# Assumed vars:
# KUBE_USER
# KUBE_PASSWORD
Expand Down Expand Up @@ -58,6 +58,52 @@ function create-kubeconfig() {
echo "Wrote config for ${CONTEXT} to ${KUBECONFIG}"
}

# Generate kubeconfig data for a specific service account
# (non-admin builtin user) for the created cluster.
# Arguments:
# $1 path of generated kubeconfig file.
# $2 username of service account
# $3 token
#
# Assumed vars:
# KUBE_MASTER_IP
#
# KUBE_CERT
# KUBE_KEY
# CA_CERT
function create-service-account-kubeconfig() {
local kubectl="${KUBE_ROOT}/cluster/kubectl.sh"
local kubeconfig=$1
local kube_user=$2
local token=$3
local context="pod" # Any string would do here because a service account kubeconfig
# is generated per-cluster and stored as a secret in that cluster.

# kubeconfig determines the file we write to, but it may not exist yet
if [[ ! -e "${kubeconfig}" ]]; then
mkdir -p $(dirname "${kubeconfig}")
touch "${kubeconfig}"
fi
local context="local"
"${kubectl}" config set-cluster "${context}" --kubeconfig="${kubeconfig}" \
--server="https://${KUBE_MASTER_IP}" \
--certificate-authority="${CA_CERT}" \
--embed-certs=true
"${kubectl}" config set-credentials "${context}" --kubeconfig="${kubeconfig}" \
--username="${kube_user}" \
--token="${token}" \
--client-certificate="${KUBE_CERT}" \
--client-key="${KUBE_KEY}" \
--embed-certs=true
"${kubectl}" config set-context "${context}" --kubeconfig="${kubeconfig}" \
--cluster="${context}" \
--user="${context}"
"${kubectl}" config use-context "${context}" --kubeconfig="${kubeconfig}" \
--cluster="${context}"

echo "Wrote config for ${context} to ${kubeconfig}"
}

# Clear kubeconfig data for a context
# Assumed vars:
# KUBECONFIG
Expand Down
23 changes: 22 additions & 1 deletion cluster/gce/configure-vm.sh
Original file line number Diff line number Diff line change
Expand Up @@ -268,15 +268,36 @@ function create-salt-auth() {
(umask 077;
echo "{\"BearerToken\": \"${KUBELET_TOKEN}\", \"Insecure\": true }" > "${kubelet_auth_file}")

mkdir -p /srv/salt-overlay/salt/kube-addons
# Generate tokens for other "service accounts". Append to known_tokens.
# Also, for each account, generate a kubeconfig containing the secret
# for that account, and other info needed to reach the master.
# The kubeconfigs go into the salt overlay so they can be used
# by the kube-addons component, which loads them as secrets.
#
# NB: If this list ever changes, this script actually has to
# change to detect the existence of this file, kill any deleted
# change to detect the known_tokens file, 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" "system:dns")
for account in "${service_accounts[@]}"; do
local -r munged_username=$(tr -s ':_' '--' <<< "${account}")
# Generate random token
token=$(dd if=/dev/urandom bs=128 count=1 2>/dev/null | base64 | tr -d "=+/" | dd bs=32 count=1 2>/dev/null)
# Put in master's list of known tokens.
echo "${token},${account},${account}" >> "${KNOWN_TOKENS_FILE}"
# Generate a kubeconfig for the service account that will use this token.
local -r kubeconfig="/srv/salt-overlay/salt/kube-addons/${munged_username}.kubeconfig"
create-service-account-kubeconfig "${kubeconfig}" "${account}" "${token}"
# Generate a "secret" kind yaml file that embeds the kubeconfig file.
local -r kubeconfig_base64=$(cat "${kubeconfig}" | base64 -w0)
local -r kubeconfig="/srv/salt-overlay/salt/kube-addons/${munged_username}.secret.yaml"
cat > $secret_yaml <<EOF
apiVersion: v1beta1
kind: Secret
id: token-${munged_username}
data:
kubeconfig: ${kubeconfig_base64}
EOF
done
fi
}
Expand Down
34 changes: 0 additions & 34 deletions cluster/saltbase/salt/kube-addons/kube-addons.sh
Original file line number Diff line number Diff line change
Expand Up @@ -19,26 +19,6 @@
# managed result is of that. Start everything below that directory.
KUBECTL=/usr/local/bin/kubectl

function create-kubernetesauth-secret() {
local -r token=$1
local -r username=$2
local -r safe_username=$(tr -s ':_' '--' <<< "${username}")

# Make secret with a kubernetes_auth file with a token.
# TODO(etune): put apiserver certs into secret too, and reference from authfile,
# so that "Insecure" is not needed.
kafile=$(echo "{\"BearerToken\": \"${token}\", \"Insecure\": true }" | base64 -w0)
read -r -d '' secretjson <<EOF
apiVersion: v1beta1
kind: Secret
id: token-${safe_username}
data:
kubernetes-auth: ${kafile}
EOF
create-resource-from-string "${secretjson}" 100 10 "Secret-for-token-for-user-${username}" &
# TODO: label the secrets with special label so kubectl does not show these?
}

# $1 filename of addon to start.
# $2 count of tries to start the addon.
# $3 delay in seconds between two consecutive tries
Expand Down Expand Up @@ -75,20 +55,6 @@ function create-resource-from-string() {
# managed result is of that. Start everything below that directory.
echo "== Kubernetes addon manager started at $(date -Is) =="

# Generate secrets for "internal service accounts".
# TODO(etune): move to a completely yaml/object based
# workflow so that service accounts can be created
# at the same time as the services that use them.
# NOTE: needs to run as root to read this file.
# Read each line in the csv file of tokens.
while read line; do
# Split each line into the token and username.
IFS=',' read -a parts <<< "${line}"
token=${parts[0]}
username=${parts[1]}
create-kubernetesauth-secret "${token}" "${username}"
done < /srv/kubernetes/known_tokens.csv

for obj in $(find /etc/kubernetes/addons -name \*.yaml); do
start_addon ${obj} 100 10 &
echo "++ addon ${obj} starting in pid $! ++"
Expand Down

0 comments on commit 73111da

Please sign in to comment.