公司有多个 k8s 环境,在自己办公电脑上连接、切换多个 k8s 集群会比较麻烦,所以想到使用 shell 函数来比较方便的在多个 k8s 集群之间切换

完整配置

使用的电脑是 Mac,shell 用的是 zsh

下面是完整的配置,放在~/.kube.zsh

alias k='kubectl'
alias kc='kubecolor'

source <(kubectl completion zsh)

compdef k=kubectl
compdef kc=kubectl
compdef kubecolor=kubectl

# 设置语言,如果是 zh_CN.UTF-8 k9s 边框会“断裂”
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8

# add kubeconfig
function add-kube() {
    set -u
    kubeconfig_file=$1
    cluster_name=$2

    profile_file="${HOME}/.kube.zsh"
    mkdir -p ${HOME}/.kube

    echo "Copy kubeconfig: ${kubeconfig_file} -> ~/.kube/kubeconfig-${cluster_name}"
    cp -fv ${kubeconfig_file} ~/.kube/kubeconfig-${cluster_name}

    echo "Add a-${cluster_name} function(for activate kubeconfig) to ${profile_file} "
    sed -i '' "/${cluster_name} CONFIG START/,/${cluster_name} CONFIG END/d" ${profile_file}
    cat >> ${profile_file} <<EOF

# ${cluster_name} CONFIG START
# use k8s ${cluster_name} env
function a-${cluster_name}() { ka ${cluster_name}; }
# ${cluster_name} CONFIG END
EOF

    echo "All done."
    echo "Please execute following command manually:"
    echo "  source ${profile_file}"
}


# kubectl activate
function ka() {
    export CURRENT_KUBE_ENV=$1
    export KUBECONFIG="${HOME}/.kube/kubeconfig-${CURRENT_KUBE_ENV}"
    alias k9s="k9s --kubeconfig=${KUBECONFIG}"
    kc get nodes
}

# kubectl de-activate
function d-ka() {
    unset CURRENT_KUBE_ENV
    unset KUBECONFIG
}

# prompt 信息函数
function kube_prompt_info() {
    local kube_env=${CURRENT_KUBE_ENV:-}
    if [[ -z "$kube_env" ]]; then
        return
    fi

    blue_color="%F{blue}"
    red_color="%F{red}"

    echo " %{☸️%} ${blue_color}K8S:(%f${red_color}${kube_env}%f${blue_color})%f "
}

if [[ $PROMPT != *'$(kube_prompt_info)'* ]]; then
    PROMPT="${PROMPT}\$(kube_prompt_info)"
fi

然后在~/.zshrc文件添加,后面打开新的终端后都可以使用这些函数(也可以在当前终端中直接source ~/.zshrcsource ~/.kube.zsh

# vim ~/.zshrc
# 在文件中添加
source ~/.kube.zsh

配置说明

基于 zsh 的配置说明

别名/补全

先给kubectlkubecolor这些命令添加一些别名和补全,使用的电脑是 Mac,shell 用的是 zsh

alias k='kubectl'
alias kc='kubecolor'

source <(kubectl completion zsh)

compdef k=kubectl
compdef kc=kubectl
compdef kubecolor=kubectl

# 设置语言,如果是 zh_CN.UTF-8 k9s 边框会“断裂”
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8

切换集群

切换不同的集群主要是使用下面的函数:

  • ka: 指定KUBECONFIG变量为指定的 kubeconfig 文件,并给 k9s 指定一下使用的 kubeconfig,然后输出一下节点信息

  • a-xxx: 封装了ka函数,通过xxx指定环境并传给ka函数,实现通过执行a-xxx切换到xxx环境的功能。比如在终端执行a-dev即可切换到dev环境

# kubectl activate
function ka() {
    export CURRENT_KUBE_ENV=$1
    export KUBECONFIG="${HOME}/.kube/kubeconfig-${CURRENT_KUBE_ENV}"
    alias k9s="k9s --kubeconfig=${KUBECONFIG}"
    kc get nodes
}

# use k8s dev env
function a-dev() { ka dev; }

# use k8s prod env
function a-prod() { ka prod; }

使用切换集群

# 切换到 dev 集群
a-dev

# 切换到 prod 集群
a-prod

添加kubeconfig与切换集群函数

使用上面的功能,每次要添加集群的时候,都需要手动在${HOME}/.kube/目录下添加kubeconfg-xxx的kubeconfig文件,并且需要在~/.zshrc(或其他文件)中添加a-xxx的函数,虽然可能并不频繁,但是感觉太麻烦,所以使用下面的函数来自动完成这些事情

这里把相关的函数都放在~/.kube.zsh里面了(通过profile_file变量指定),包括上面的那些函数也放在了这个文件里面

# add kubeconfig
function add-kube() {
    set -u
    kubeconfig_file=$1
    cluster_name=$2

    profile_file="${HOME}/.kube.zsh"
    mkdir -p ${HOME}/.kube

    echo "Copy kubeconfig: ${kubeconfig_file} -> ~/.kube/kubeconfig-${cluster_name}"
    cp -fv ${kubeconfig_file} ~/.kube/kubeconfig-${cluster_name}

    echo "Add a-${cluster_name} function(for activate kubeconfig) to ${profile_file} "
    sed -i '' "/${cluster_name} CONFIG START/,/${cluster_name} CONFIG END/d" ${profile_file}
    cat >> ${profile_file} <<EOF

# ${cluster_name} CONFIG START
# use k8s ${cluster_name} env
function a-${cluster_name}() { ka ${cluster_name}; }
# ${cluster_name} CONFIG END
EOF

    echo "All done."
    echo "Please execute following command manually:"
    echo "  source ${profile_file}"
}

然后在~/.zshrc文件添加,后面打开新的终端后都可以使用这些函数

# vim ~/.zshrc
# 在文件中添加
source ~/.kube.zsh

如果需要添加新的环境,只需要执行下面的命令即可

# 1、添加集群信息
## kkk-config: kubeconfig 路径,放在当前目录下即可,会自动复制到 ~/.kube 目录下,并重命名一下
## kkk: 集群名称
add-kube kkk-config kkk

source ~/.kube.zsh
或
source ~/.zshrc

# 2、切换到 kkk 集群
a-kkk

使用这种方式,也可以打开多个终端同时连接多个集群,但是这样就会有一个困扰,不能比较直观的判断当前的终端连接的是哪个集群,有时候还要看下集群节点来判断一下,更严重的可能还会在执行命令的时候出错

在终端命令提示符中显示当前集群信息

当在多个终端连接多个集群时,可以直观的看出当前连接的是哪个集群是非常有必要的

# prompt 信息函数
function kube_prompt_info() {
    local kube_env=${CURRENT_KUBE_ENV:-}
    if [[ -z "$kube_env" ]]; then
        return
    fi

    blue_color="%F{blue}"
    red_color="%F{red}"

    echo " %{☸️%} ${blue_color}K8S:(%f${red_color}${kube_env}%f${blue_color})%f "
}

if [[ $PROMPT != *'$(kube_prompt_info)'* ]]; then
    PROMPT="${PROMPT}\$(kube_prompt_info)"
fi

当使用a-xxx切换不同集群之后,将会在提示符中有☸️ K8S:(dev)这样的提示

退出集群

连接到 k8s 集群之后,想要退出,只需要使用下面函数即可

# kubectl de-activate
function d-ka() {
    unset CURRENT_KUBE_ENV
    unset KUBECONFIG
}

配置-bash

Bash 版本的配置

# alias
alias k='kubectl'
alias kc='kubecolor'

# 启用 kubectl 自动补全(bash)
source <(kubectl completion bash)
# 默认情况下 bash 补全会有问题,需要 source 一下 /etc/profile.d/bash_completion.sh
source /etc/profile.d/bash_completion.sh

complete -F __start_kubectl k
complete -F __start_kubectl kc
complete -F __start_kubectl kubecolor

# 设置语言,避免 k9s 边框问题
export LANG=en_US.UTF-8
export LC_ALL=en_US.UTF-8

# add kubeconfig
function add-kube() {
    set -u
    kubeconfig_file=$1
    cluster_name=$2

    profile_file="${HOME}/.kube.sh"
    mkdir -p ${HOME}/.kube

    echo "Copy kubeconfig: ${kubeconfig_file} -> ~/.kube/kubeconfig-${cluster_name}"
    cp -fv "${kubeconfig_file}" "${HOME}/.kube/kubeconfig-${cluster_name}"

    echo "Add a-${cluster_name} function(for activate kubeconfig) to ${profile_file}"
    sed -i "/${cluster_name} CONFIG START/,/${cluster_name} CONFIG END/d" "${profile_file}"
    cat >> "${profile_file}" <<EOF

# ${cluster_name} CONFIG START
# use k8s ${cluster_name} env
function a-${cluster_name}() { ka ${cluster_name}; }
# ${cluster_name} CONFIG END
EOF

    echo "All done."
    echo "Please execute following command manually:"
    echo "  source ${profile_file}"
}

# kubectl activate
function ka() {
    export CURRENT_KUBE_ENV=$1
    export KUBECONFIG="${HOME}/.kube/kubeconfig-${CURRENT_KUBE_ENV}"
    alias k9s="k9s --kubeconfig=${KUBECONFIG}"
    kc get nodes
}

# kubectl de-activate
function d-ka() {
    unset CURRENT_KUBE_ENV
    unset KUBECONFIG
}

# prompt 信息函数
function kube_prompt_info() {
    local kube_env=${CURRENT_KUBE_ENV:-}
    if [[ -z "$kube_env" ]]; then
        return
    fi

    local blue_color="\033[34m"
    local red_color="\033[31m"
    local reset_color="\033[0m"

    echo -e " ☸️ ${blue_color}K8S:(${red_color}${kube_env}${blue_color})${reset_color} "
}

# 修改 Bash 提示符
if [[ $PS1 != *'$(kube_prompt_info)'* ]]; then
    PS1="${PS1}\$(kube_prompt_info)"
fi