kubeasz/ezctl

685 lines
26 KiB
Plaintext
Raw Permalink Normal View History

#!/bin/bash
2021-01-07 09:30:50 +08:00
# Create & manage k8s clusters
set -o nounset
set -o errexit
#set -o xtrace
function usage() {
2020-12-25 11:53:00 +08:00
echo -e "\033[33mUsage:\033[0m ezctl COMMAND [args]"
cat <<EOF
2020-12-25 11:53:00 +08:00
-------------------------------------------------------------------------------------
Cluster setups:
list to list all of the managed clusters
2021-01-07 09:30:50 +08:00
checkout <cluster> to switch default kubeconfig of the cluster
2020-12-25 11:53:00 +08:00
new <cluster> to start a new k8s deploy with name 'cluster'
2020-12-30 11:25:54 +08:00
setup <cluster> <step> to setup a cluster, also supporting a step-by-step way
start <cluster> to start all of the k8s services stopped by 'ezctl stop'
stop <cluster> to stop all of the k8s services temporarily
upgrade <cluster> to upgrade the k8s cluster
destroy <cluster> to destroy the k8s cluster
2021-01-07 09:30:50 +08:00
backup <cluster> to backup the cluster state (etcd snapshot)
restore <cluster> to restore the cluster state from backups
2022-11-26 10:56:52 +08:00
start-aio to quickly setup an all-in-one cluster with default settings
2020-12-25 11:53:00 +08:00
Cluster ops:
2020-12-30 11:25:54 +08:00
add-etcd <cluster> <ip> to add a etcd-node to the etcd cluster
add-master <cluster> <ip> to add a master node to the k8s cluster
add-node <cluster> <ip> to add a work node to the k8s cluster
2020-12-25 11:53:00 +08:00
del-etcd <cluster> <ip> to delete a etcd-node from the etcd cluster
del-master <cluster> <ip> to delete a master node from the k8s cluster
del-node <cluster> <ip> to delete a work node from the k8s cluster
Extra operation:
2022-11-26 10:56:52 +08:00
kca-renew <cluster> to force renew CA certs and all the other certs (with caution)
kcfg-adm <cluster> <args> to manage client kubeconfig of the k8s cluster
2020-12-30 11:25:54 +08:00
Use "ezctl help <command>" for more information about a given command.
2020-12-30 11:25:54 +08:00
EOF
}
2020-12-25 11:53:00 +08:00
function logger() {
TIMESTAMP=$(date +'%Y-%m-%d %H:%M:%S')
case "$1" in
debug)
echo -e "$TIMESTAMP \033[36mDEBUG\033[0m $2"
;;
info)
echo -e "$TIMESTAMP \033[32mINFO\033[0m $2"
;;
warn)
echo -e "$TIMESTAMP \033[33mWARN\033[0m $2"
;;
error)
echo -e "$TIMESTAMP \033[31mERROR\033[0m $2"
;;
*)
;;
esac
}
function help-info() {
case "$1" in
2020-12-30 11:25:54 +08:00
(setup)
usage-setup
;;
2019-06-08 16:07:46 +08:00
(add-etcd)
2021-01-07 09:30:50 +08:00
echo -e "read more > 'https://github.com/easzlab/kubeasz/blob/master/docs/op/op-etcd.md'"
;;
(add-master)
2021-01-07 09:30:50 +08:00
echo -e "read more > 'https://github.com/easzlab/kubeasz/blob/master/docs/op/op-master.md'"
;;
2019-06-08 16:07:46 +08:00
(add-node)
2021-01-07 09:30:50 +08:00
echo -e "read more > 'https://github.com/easzlab/kubeasz/blob/master/docs/op/op-node.md'"
;;
(del-etcd)
2021-01-07 09:30:50 +08:00
echo -e "read more > 'https://github.com/easzlab/kubeasz/blob/master/docs/op/op-etcd.md'"
;;
2019-06-03 11:25:05 +08:00
(del-master)
2021-01-07 09:30:50 +08:00
echo -e "read more > 'https://github.com/easzlab/kubeasz/blob/master/docs/op/op-master.md'"
2019-06-03 11:25:05 +08:00
;;
(del-node)
2021-01-07 09:30:50 +08:00
echo -e "read more > 'https://github.com/easzlab/kubeasz/blob/master/docs/op/op-node.md'"
2019-06-03 11:25:05 +08:00
;;
2022-11-26 10:56:52 +08:00
(kca-renew)
echo -e "WARNNING: this command should be used with caution"
echo -e "force to recreate CA certs and all of the others certs used in the cluster"
echo -e "it should be used only when the admin.conf leaked"
;;
(kcfg-adm)
usage-kcfg-adm
;;
(*)
2021-01-07 09:30:50 +08:00
echo -e "todo: help info $1"
;;
esac
}
function usage-kcfg-adm(){
echo -e "\033[33mUsage:\033[0m ezctl kcfg-adm <cluster> <args>"
cat <<EOF
available <args>:
-A to add a client kubeconfig with a newly created user
-D to delete a client kubeconfig with the existed user
-L to list all of the users
-e to set expiry of the user certs in hours (ex. 24h, 8h, 240h)
-t to set a user-type (admin or view)
-u to set a user-name prefix
examples: ./ezctl kcfg-adm test-k8s -L
./ezctl kcfg-adm default -A -e 240h -t admin -u jack
./ezctl kcfg-adm default -D -u jim-202101162141
EOF
}
function usage-setup(){
echo -e "\033[33mUsage:\033[0m ezctl setup <cluster> <step>"
cat <<EOF
available steps:
2021-03-27 20:47:03 +08:00
01 prepare to prepare CA/certs & kubeconfig & other system settings
02 etcd to setup the etcd cluster
03 container-runtime to setup the container runtime(docker or containerd)
04 kube-master to setup the master nodes
05 kube-node to setup the worker nodes
06 network to setup the network plugin
07 cluster-addon to setup other useful plugins
90 all to run 01~07 all at once
10 ex-lb to install external loadbalance for accessing k8s from outside
11 harbor to install a new harbor server or to integrate with an existed one
examples: ./ezctl setup test-k8s 01 (or ./ezctl setup test-k8s prepare)
./ezctl setup test-k8s 02 (or ./ezctl setup test-k8s etcd)
./ezctl setup test-k8s all
./ezctl setup test-k8s 04 -t restart_master
EOF
}
2020-12-25 11:53:00 +08:00
### Cluster setups functions ##############################
function new() {
# check if already existed
2021-10-15 12:50:34 +08:00
[[ -d "clusters/$1" ]] && { logger error "cluster:$1 already existed, if cluster:$1 setup failed, try 'rm -rf $BASE/clusters/$1' first!"; exit 1; }
2020-12-25 11:53:00 +08:00
2021-01-19 14:42:37 +08:00
logger debug "generate custom cluster files in $BASE/clusters/$1"
2020-12-25 11:53:00 +08:00
mkdir -p "clusters/$1"
cp example/hosts.multi-node "clusters/$1/hosts"
sed -i "s/_cluster_name_/$1/g" "clusters/$1/hosts"
cp example/config.yml "clusters/$1/config.yml"
logger debug "set versions"
k8sVer=$(grep 'K8S_BIN_VER=v' ezdown|cut -d'v' -f2)
2020-12-30 11:25:54 +08:00
calicoVer=$(grep 'calicoVer=' ezdown|cut -d'=' -f2)
ciliumVer=$(grep 'ciliumVer=' ezdown|cut -d'=' -f2)
flannelVer=$(grep 'flannelVer=' ezdown|cut -d'=' -f2)
kubeRouterVer=$(grep 'kubeRouterVer=' ezdown|cut -d'=' -f2)
kubeOvnVer=$(grep 'kubeOvnVer=' ezdown|cut -d'=' -f2)
corednsVer=$(grep 'corednsVer=' ezdown|cut -d'=' -f2)
2021-01-13 21:27:18 +08:00
dnsNodeCacheVer=$(grep 'dnsNodeCacheVer=' ezdown|cut -d'=' -f2)
2020-12-30 11:25:54 +08:00
dashboardVer=$(grep 'dashboardVer=' ezdown|cut -d'=' -f2)
dashboardMetricsScraperVer=$(grep 'dashboardMetricsScraperVer=' ezdown|cut -d'=' -f2)
metricsVer=$(grep 'metricsVer=' ezdown|cut -d'=' -f2)
2023-05-19 21:45:24 +08:00
localpathProvisionerVer=$(grep 'localpathProvisionerVer=' ezdown|cut -d'=' -f2)
2021-03-27 00:09:42 +08:00
nfsProvisionerVer=$(grep 'nfsProvisionerVer=' ezdown|cut -d'=' -f2)
2021-04-15 20:43:54 +08:00
pauseVer=$(grep 'pauseVer=' ezdown|cut -d'=' -f2)
2021-01-11 11:12:14 +08:00
promChartVer=$(grep 'promChartVer=' ezdown|cut -d'=' -f2)
2023-05-28 12:06:42 +08:00
kubeappsVer=$(grep 'kubeappsVer=' ezdown|cut -d'=' -f2)
2021-02-08 21:23:00 +08:00
harborVer=$(grep 'HARBOR_VER=' ezdown|cut -d'=' -f2)
2021-01-11 22:58:59 +08:00
registryMirror=true
grep registry-mirrors /etc/docker/daemon.json > /dev/null 2>&1 || { logger debug "disable registry mirrors"; registryMirror=false; }
2020-12-30 11:25:54 +08:00
sed -i -e "s/__k8s_ver__/$k8sVer/g" \
-e "s/__flannel__/$flannelVer/g" \
2020-12-30 11:25:54 +08:00
-e "s/__calico__/$calicoVer/g" \
-e "s/__cilium__/$ciliumVer/g" \
-e "s/__kube_ovn__/$kubeOvnVer/g" \
-e "s/__kube_router__/$kubeRouterVer/g" \
-e "s/__coredns__/$corednsVer/g" \
2021-04-15 20:43:54 +08:00
-e "s/__pause__/$pauseVer/g" \
2021-01-13 21:27:18 +08:00
-e "s/__dns_node_cache__/$dnsNodeCacheVer/g" \
2020-12-30 11:25:54 +08:00
-e "s/__dashboard__/$dashboardVer/g" \
-e "s/__dash_metrics__/$dashboardMetricsScraperVer/g" \
2023-05-19 21:45:24 +08:00
-e "s/__local_path_provisioner__/$localpathProvisionerVer/g" \
2021-03-27 00:09:42 +08:00
-e "s/__nfs_provisioner__/$nfsProvisionerVer/g" \
2021-01-11 11:12:14 +08:00
-e "s/__prom_chart__/$promChartVer/g" \
2023-05-28 12:06:42 +08:00
-e "s/__kubeapps_chart__/$kubeappsVer/g" \
2021-02-08 21:23:00 +08:00
-e "s/__harbor__/$harborVer/g" \
2021-01-11 22:58:59 +08:00
-e "s/^ENABLE_MIRROR_REGISTRY.*$/ENABLE_MIRROR_REGISTRY: $registryMirror/g" \
2020-12-30 11:25:54 +08:00
-e "s/__metrics__/$metricsVer/g" "clusters/$1/config.yml"
2020-12-25 11:53:00 +08:00
logger debug "cluster $1: files successfully created."
2021-01-19 14:42:37 +08:00
logger info "next steps 1: to config '$BASE/clusters/$1/hosts'"
logger info "next steps 2: to config '$BASE/clusters/$1/config.yml'"
2020-12-25 11:53:00 +08:00
}
function setup() {
[[ -d "clusters/$1" ]] || { logger error "invalid config, run 'ezctl new $1' first"; return 1; }
[[ -f "bin/kube-apiserver" ]] || { logger error "no binaries founded, run 'ezdown -D' fist"; return 1; }
# for extending usage
EXTRA_ARGS=$(echo "$*"|sed "s/$1 $2//g"|sed "s/^ *//g")
2020-12-30 11:25:54 +08:00
PLAY_BOOK="dummy.yml"
case "$2" in
2021-03-27 20:47:03 +08:00
(01|prepare)
2020-12-30 11:25:54 +08:00
PLAY_BOOK="01.prepare.yml"
;;
2021-03-27 20:47:03 +08:00
(02|etcd)
2020-12-30 11:25:54 +08:00
PLAY_BOOK="02.etcd.yml"
;;
2021-03-27 20:47:03 +08:00
(03|container-runtime)
2020-12-30 11:25:54 +08:00
PLAY_BOOK="03.runtime.yml"
;;
2021-03-27 20:47:03 +08:00
(04|kube-master)
2020-12-30 11:25:54 +08:00
PLAY_BOOK="04.kube-master.yml"
;;
2021-03-27 20:47:03 +08:00
(05|kube-node)
2020-12-30 11:25:54 +08:00
PLAY_BOOK="05.kube-node.yml"
;;
2021-03-27 20:47:03 +08:00
(06|network)
2020-12-30 11:25:54 +08:00
PLAY_BOOK="06.network.yml"
;;
2021-03-27 20:47:03 +08:00
(07|cluster-addon)
2020-12-30 11:25:54 +08:00
PLAY_BOOK="07.cluster-addon.yml"
;;
2021-03-27 20:47:03 +08:00
(90|all)
2020-12-30 11:25:54 +08:00
PLAY_BOOK="90.setup.yml"
;;
2021-03-27 20:47:03 +08:00
(10|ex-lb)
PLAY_BOOK="10.ex-lb.yml"
2020-12-30 11:25:54 +08:00
;;
2021-03-27 20:47:03 +08:00
(11|harbor)
2021-02-08 21:23:00 +08:00
PLAY_BOOK="11.harbor.yml"
;;
2020-12-30 11:25:54 +08:00
(*)
usage-setup
exit 1
;;
esac
COMMAND="ansible-playbook -i clusters/$1/hosts -e @clusters/$1/config.yml $EXTRA_ARGS playbooks/$PLAY_BOOK"
echo "$COMMAND"
k8s_ver=$(bin/kube-apiserver --version|cut -d' ' -f2)
etcd_ver=v$(bin/etcd --version|grep 'etcd Version'|cut -d' ' -f3)
2023-05-16 16:07:22 +08:00
network_cni=$(grep CLUSTER_NETWORK "clusters/$1/hosts"|cut -d'"' -f2|sed 's/-//g')
network_cni_ver=$(grep -i "${network_cni}Ver" ezdown|cut -d'=' -f2|head -n1)
cat <<EOF
*** Component Version *********************
*******************************************
2023-05-16 16:07:22 +08:00
* kubernetes: ${k8s_ver}
* etcd: ${etcd_ver}
* ${network_cni}: ${network_cni_ver}
*******************************************
EOF
2021-01-07 09:30:50 +08:00
logger info "cluster:$1 setup step:$2 begins in 5s, press any key to abort:\n"
! (read -r -t5 -n1) || { logger warn "setup abort"; return 1; }
2020-12-25 11:53:00 +08:00
${COMMAND} || return 1
2020-12-30 11:25:54 +08:00
}
function cmd() {
[[ -d "clusters/$1" ]] || { logger error "invalid config, run 'ezctl new $1' first"; return 1; }
PLAY_BOOK="dummy.yml"
case "$2" in
(start)
PLAY_BOOK="91.start.yml"
;;
(stop)
PLAY_BOOK="92.stop.yml"
;;
(upgrade)
PLAY_BOOK="93.upgrade.yml"
;;
(backup)
PLAY_BOOK="94.backup.yml"
;;
(restore)
PLAY_BOOK="95.restore.yml"
;;
(destroy)
PLAY_BOOK="99.clean.yml"
;;
(*)
usage
exit 1
;;
esac
2021-04-24 20:23:06 +08:00
COMMAND="ansible-playbook -i clusters/$1/hosts -e @clusters/$1/config.yml playbooks/$PLAY_BOOK"
echo "$COMMAND"
2020-12-30 11:25:54 +08:00
logger info "cluster:$1 $2 begins in 5s, press any key to abort:\n"
2021-01-07 09:30:50 +08:00
! (read -r -t5 -n1) || { logger warn "$2 abort"; return 1; }
2020-12-30 11:25:54 +08:00
2021-04-24 20:23:06 +08:00
${COMMAND} || return 1
2020-12-25 11:53:00 +08:00
}
2020-12-30 11:25:54 +08:00
2020-12-25 11:53:00 +08:00
function list() {
2021-01-07 09:30:50 +08:00
[[ -d ./clusters ]] || { logger error "cluster not found, run 'ezctl new' first"; return 1; }
[[ -f ~/.kube/config ]] || { logger error "kubeconfig not found, run 'ezctl setup' first"; return 1; }
which md5sum > /dev/null 2>&1 || { logger error "md5sum not found"; return 1; }
CLUSTERS=$(cd clusters && echo -- *)
CFG_MD5=$(sed '/server/d' ~/.kube/config|md5sum|cut -d' ' -f1)
2021-01-07 09:30:50 +08:00
cd "$BASE"
logger info "list of managed clusters:"
i=1; for c in $CLUSTERS;
2020-12-25 11:53:00 +08:00
do
2021-01-07 09:30:50 +08:00
if [[ -f "clusters/$c/kubectl.kubeconfig" ]];then
c_md5=$(sed '/server/d' "clusters/$c/kubectl.kubeconfig"|md5sum|cut -d' ' -f1)
2021-01-07 09:30:50 +08:00
if [[ "$c_md5" = "$CFG_MD5" ]];then
echo -e "==> cluster $i:\t$c (\033[32mcurrent\033[0m)"
else
echo -e "==> cluster $i:\t$c"
fi
2023-05-11 22:50:06 +08:00
((i++))
2020-12-25 11:53:00 +08:00
fi
done
}
2020-12-25 11:53:00 +08:00
2021-01-07 09:30:50 +08:00
function checkout() {
[[ -d "clusters/$1" ]] || { logger error "invalid config, run 'ezctl new $1' first"; return 1; }
[[ -f "clusters/$1/kubectl.kubeconfig" ]] || { logger error "invalid kubeconfig, run 'ezctl setup $1' first"; return 1; }
logger info "set default kubeconfig: cluster $1 (\033[32mcurrent\033[0m)"
/bin/cp -f "clusters/$1/kubectl.kubeconfig" ~/.kube/config
}
2020-12-25 11:53:00 +08:00
### in-cluster operation functions ##############################
function add-node() {
# check new node's address regexp
2021-01-07 09:30:50 +08:00
[[ $2 =~ ^(2(5[0-5]{1}|[0-4][0-9]{1})|[0-1]?[0-9]{1,2})(\.(2(5[0-5]{1}|[0-4][0-9]{1})|[0-1]?[0-9]{1,2})){3}$ ]] || { logger error "Invalid ip add:$2"; return 1; }
# check if the new node already exsited
sed -n '/^\[kube_master/,/^\[harbor/p' "$BASE/clusters/$1/hosts"|grep -E "^$2$|^$2 " && { logger error "node $2 already existed in $BASE/clusters/$1/hosts"; return 2; }
logger info "add $2 into 'kube_node' group"
NODE_INFO="${@:2}"
sed -i "/\[kube_node/a $NODE_INFO" "$BASE/clusters/$1/hosts"
2021-01-07 09:30:50 +08:00
logger info "start to add a work node:$2 into cluster:$1"
ansible-playbook -i "$BASE/clusters/$1/hosts" "$BASE/playbooks/22.addnode.yml" -e "NODE_TO_ADD=$2" -e "@clusters/$1/config.yml"
}
function add-master() {
# check new master's address regexp
2021-01-07 09:30:50 +08:00
[[ $2 =~ ^(2(5[0-5]{1}|[0-4][0-9]{1})|[0-1]?[0-9]{1,2})(\.(2(5[0-5]{1}|[0-4][0-9]{1})|[0-1]?[0-9]{1,2})){3}$ ]] || { logger error "Invalid ip add:$2"; return 1; }
# check if the new master already exsited
sed -n '/^\[kube_master/,/^\[kube_node/p' "$BASE/clusters/$1/hosts"|grep -E "^$2$|^$2 " && { logger error "master $2 already existed!"; return 2; }
logger info "add $2 into 'kube_master' group"
MASTER_INFO="${@:2}"
sed -i "/\[kube_master/a $MASTER_INFO" "$BASE/clusters/$1/hosts"
2021-01-07 09:30:50 +08:00
logger info "start to add a master node:$2 into cluster:$1"
ansible-playbook -i "$BASE/clusters/$1/hosts" "$BASE/playbooks/23.addmaster.yml" -e "NODE_TO_ADD=$2" -e "@clusters/$1/config.yml"
logger info "reconfigure and restart 'kube-lb' service"
ansible-playbook -i "$BASE/clusters/$1/hosts" "$BASE/playbooks/90.setup.yml" -t restart_kube-lb -e "@clusters/$1/config.yml"
logger info "reconfigure and restart 'ex-lb' service"
ansible-playbook -i "$BASE/clusters/$1/hosts" "$BASE/playbooks/10.ex-lb.yml" -t restart_lb -e "@clusters/$1/config.yml"
}
function add-etcd() {
# check new node's address regexp
2021-01-07 09:30:50 +08:00
[[ $2 =~ ^(2(5[0-5]{1}|[0-4][0-9]{1})|[0-1]?[0-9]{1,2})(\.(2(5[0-5]{1}|[0-4][0-9]{1})|[0-1]?[0-9]{1,2})){3}$ ]] || { logger error "Invalid ip add:$2"; return 1; }
# check if the new node already exsited
sed -n '/^\[etcd/,/^\[kube_master/p' "$BASE/clusters/$1/hosts"|grep -E "^$2$|^$2 " && { logger error "etcd $2 already existed!"; return 2; }
2021-01-07 09:30:50 +08:00
logger info "add $2 into 'etcd' group"
ETCD_INFO="${@:2}"
sed -i "/\[etcd/a $ETCD_INFO" "$BASE/clusters/$1/hosts"
2021-01-07 09:30:50 +08:00
logger info "start to add a etcd node:$2 into cluster:$1"
ansible-playbook -i "$BASE/clusters/$1/hosts" "$BASE/playbooks/21.addetcd.yml" -e "NODE_TO_ADD=$2" -e "@clusters/$1/config.yml"
2021-01-07 09:30:50 +08:00
logger info "reconfig &restart the etcd cluster"
ansible-playbook -i "$BASE/clusters/$1/hosts" "$BASE/playbooks/02.etcd.yml" -t restart_etcd -e "@clusters/$1/config.yml"
logger info "restart apiservers to use the new etcd cluster"
ansible-playbook -i "$BASE/clusters/$1/hosts" "$BASE/playbooks/04.kube-master.yml" -t restart_master -e "@clusters/$1/config.yml"
}
function del-etcd() {
# check node's address regexp
2021-01-07 09:30:50 +08:00
[[ $2 =~ ^(2(5[0-5]{1}|[0-4][0-9]{1})|[0-1]?[0-9]{1,2})(\.(2(5[0-5]{1}|[0-4][0-9]{1})|[0-1]?[0-9]{1,2})){3}$ ]] || { logger error "Invalid ip add:$2"; return 1; }
# check if the deleting node exsited
sed -n '/^\[etcd/,/^\[kube_master/p' "$BASE/clusters/$1/hosts"|grep -E "^$2$|^$2 " || { logger error "etcd $2 not existed!"; return 2; }
2021-01-07 09:30:50 +08:00
logger warn "start to delete the etcd node:$2 from cluster:$1"
ansible-playbook -i "$BASE/clusters/$1/hosts" "$BASE/playbooks/31.deletcd.yml" -e "ETCD_TO_DEL=$2" -e "CLUSTER=$1" -e "@clusters/$1/config.yml"
2021-01-07 09:30:50 +08:00
logger info "reconfig &restart the etcd cluster"
ansible-playbook -i "$BASE/clusters/$1/hosts" "$BASE/playbooks/02.etcd.yml" -t restart_etcd -e "@clusters/$1/config.yml"
logger info "restart apiservers to use the new etcd cluster"
ansible-playbook -i "$BASE/clusters/$1/hosts" "$BASE/playbooks/04.kube-master.yml" -t restart_master -e "@clusters/$1/config.yml"
}
2019-06-03 11:25:05 +08:00
function del-node() {
# check node's address regexp
[[ $2 =~ ^(2(5[0-5]{1}|[0-4][0-9]{1})|[0-1]?[0-9]{1,2})(\.(2(5[0-5]{1}|[0-4][0-9]{1})|[0-1]?[0-9]{1,2})){3}$ ]] || { logger error "Invalid ip add:$2"; return 2; }
2019-06-03 11:25:05 +08:00
# check if the deleting node exsited
sed -n '/^\[kube_master/,/^\[harbor/p' "$BASE/clusters/$1/hosts"|grep -E "^$2$|^$2 " || { logger error "node $2 not existed in $BASE/clusters/$1/hosts"; return 2; }
2021-01-07 09:30:50 +08:00
logger warn "start to delete the node:$2 from cluster:$1"
ansible-playbook -i "$BASE/clusters/$1/hosts" "$BASE/playbooks/32.delnode.yml" -e "NODE_TO_DEL=$2" -e "CLUSTER=$1" -e "@clusters/$1/config.yml"
2019-06-03 11:25:05 +08:00
}
function del-master() {
# check node's address regexp
2021-01-07 09:30:50 +08:00
[[ $2 =~ ^(2(5[0-5]{1}|[0-4][0-9]{1})|[0-1]?[0-9]{1,2})(\.(2(5[0-5]{1}|[0-4][0-9]{1})|[0-1]?[0-9]{1,2})){3}$ ]] || { logger error "Invalid ip add:$2"; return 2; }
2019-06-03 11:25:05 +08:00
# check if the deleting master exsited
sed -n '/^\[kube_master/,/^\[kube_node/p' "$BASE/clusters/$1/hosts"|grep -E "^$2$|^$2 " || { logger error "master $2 not existed!"; return 2; }
2021-01-07 09:30:50 +08:00
logger warn "start to delete the master:$2 from cluster:$1"
ansible-playbook -i "$BASE/clusters/$1/hosts" "$BASE/playbooks/33.delmaster.yml" -e "NODE_TO_DEL=$2" -e "CLUSTER=$1" -e "@clusters/$1/config.yml"
2019-06-04 13:06:11 +08:00
2021-01-07 09:30:50 +08:00
logger info "reconfig kubeconfig in ansible manage node"
ansible-playbook -i "$BASE/clusters/$1/hosts" "$BASE/roles/deploy/deploy.yml" -t create_kctl_cfg -e "@clusters/$1/config.yml"
2019-06-04 23:46:12 +08:00
logger info "reconfigure and restart 'kube-lb' service"
ansible-playbook -i "$BASE/clusters/$1/hosts" "$BASE/playbooks/90.setup.yml" -t restart_kube-lb -e "@clusters/$1/config.yml"
logger info "reconfigure and restart 'ex-lb' service"
ansible-playbook -i "$BASE/clusters/$1/hosts" "$BASE/playbooks/10.ex-lb.yml" -t restart_lb -e "@clusters/$1/config.yml"
}
2019-03-22 08:38:45 +08:00
function start-aio(){
set +u
2021-01-07 09:30:50 +08:00
# Check ENV 'HOST_IP', exists if the CMD 'ezctl' running in a docker container
2019-03-22 08:38:45 +08:00
if [[ -z $HOST_IP ]];then
2021-01-07 09:30:50 +08:00
# ezctl runs in a host machine, get host's ip
HOST_IF=$(ip route|grep default|head -n1|cut -d' ' -f5)
2021-01-07 09:30:50 +08:00
HOST_IP=$(ip a|grep "$HOST_IF$"|head -n1|awk '{print $2}'|cut -d'/' -f1)
2019-03-22 08:38:45 +08:00
fi
set -u
2021-01-07 09:30:50 +08:00
logger info "get local host ipadd: $HOST_IP"
2021-02-04 22:00:22 +08:00
# allow ssh login using key locally
if [[ ! -e /root/.ssh/id_rsa ]]; then
logger debug "generate ssh key pair"
ssh-keygen -t rsa -b 2048 -N '' -f /root/.ssh/id_rsa > /dev/null
cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys
ssh-keyscan -t ecdsa -H "$HOST_IP" >> /root/.ssh/known_hosts
fi
2021-01-07 09:30:50 +08:00
new default
/bin/cp -f example/hosts.allinone "clusters/default/hosts"
sed -i "s/_cluster_name_/default/g" "clusters/default/hosts"
sed -i "s/192.168.1.1/$HOST_IP/g" "clusters/default/hosts"
setup default all
2019-04-07 20:38:23 +08:00
}
### Extra functions #############################################
2022-11-26 10:56:52 +08:00
function renew-ca() {
[[ -d "clusters/$1" ]] || { logger error "invalid cluster, run 'ezctl new $1' first"; return 1; }
logger warn "WARNNING: this script should be used with greate caution"
logger warn "WARNNING: it will recreate CA certs and all of the others certs used in the cluster"
2022-11-28 20:49:31 +08:00
COMMAND="ansible-playbook -i clusters/$1/hosts -e @clusters/$1/config.yml -e CHANGE_CA=true playbooks/96.update-certs.yml -t force_change_certs"
2022-11-26 10:56:52 +08:00
echo "$COMMAND"
logger info "cluster:$1 process begins in 5s, press any key to abort:\n"
! (read -r -t5 -n1) || { logger warn "process abort"; return 1; }
${COMMAND} || return 1
}
2023-05-11 22:50:06 +08:00
EXPIRY="4800h" # default cert will expire in 200 days
USER_TYPE="admin" # admin/view, admin=clusterrole:cluster-admin view=clusterrole:view
USER_NAME="user"
function kcfg-adm() {
OPTIND=2
ACTION=""
while getopts "ADLe:t:u:" OPTION; do
case $OPTION in
A)
ACTION="add-kcfg $1"
;;
D)
ACTION="del-kcfg $1"
;;
L)
ACTION="list-kcfg $1"
;;
e)
EXPIRY="$OPTARG"
[[ $OPTARG =~ ^[1-9][0-9]*h$ ]] || { logger error "'-e' must be set like '2h, 5h, 50000h, ...'"; exit 1; }
;;
t)
USER_TYPE="$OPTARG"
[[ $OPTARG =~ ^(admin|view)$ ]] || { logger error "'-t' can only be set as 'admin' or 'view'"; exit 1; }
;;
u)
USER_NAME="$OPTARG"
;;
?)
help-info kcfg-adm
return 1
;;
esac
done
[[ "$ACTION" == "" ]] && { logger error "illegal option"; help-info kcfg-adm; exit 1; }
logger info "$ACTION"
${ACTION} || { logger error "$ACTION fail"; return 1; }
logger info "$ACTION success"
}
function add-kcfg(){
USER_NAME="$USER_NAME"-$(date +'%Y%m%d%H%M')
logger info "add-kcfg in cluster:$1 with user:$USER_NAME"
ansible-playbook -i "clusters/$1/hosts" -e "@clusters/$1/config.yml" -e "CUSTOM_EXPIRY=$EXPIRY" \
-e "USER_TYPE=$USER_TYPE" -e "USER_NAME=$USER_NAME" -e "ADD_KCFG=true" \
-t add-kcfg "roles/deploy/deploy.yml"
}
function del-kcfg(){
logger info "del-kcfg in cluster:$1 with user:$USER_NAME"
CRB=$(bin/kubectl --kubeconfig="clusters/$1/kubectl.kubeconfig" get clusterrolebindings -ojsonpath="{.items[?(@.subjects[0].name == '$USER_NAME')].metadata.name}") && \
bin/kubectl --kubeconfig="clusters/$1/kubectl.kubeconfig" delete clusterrolebindings "$CRB" && \
/bin/rm -f "clusters/$1/ssl/users/$USER_NAME"*
}
function list-kcfg(){
logger info "list-kcfg in cluster:$1"
ADMINS=$(bin/kubectl --kubeconfig="clusters/$1/kubectl.kubeconfig" get clusterrolebindings -ojsonpath='{.items[?(@.roleRef.name == "cluster-admin")].subjects[*].name}')
VIEWS=$(bin/kubectl --kubeconfig="clusters/$1/kubectl.kubeconfig" get clusterrolebindings -ojsonpath='{.items[?(@.roleRef.name == "view")].subjects[*].name}')
2021-01-25 00:07:18 +08:00
ALL=$(bin/kubectl --kubeconfig="clusters/$1/kubectl.kubeconfig" get clusterrolebindings -ojsonpath='{.items[*].subjects[*].name}')
printf "\n%-30s %-15s %-20s\n" USER TYPE "EXPIRY(+8h if in Asia/Shanghai)"
echo "---------------------------------------------------------------------------------"
for u in $ADMINS; do
if [[ $u =~ ^.*-[0-9]{12}$ ]];then
t=$(bin/cfssl-certinfo -cert "clusters/$1/ssl/users/$u.pem"|grep not_after|awk '{print $2}'|sed 's/"//g'|sed 's/,//g')
printf "%-30s %-15s %-20s\n" "$u" cluster-admin "$t"
fi
done;
2021-01-25 00:07:18 +08:00
for u in $VIEWS; do
if [[ $u =~ ^.*-[0-9]{12}$ ]];then
t=$(bin/cfssl-certinfo -cert "clusters/$1/ssl/users/$u.pem"|grep not_after|awk '{print $2}'|sed 's/"//g'|sed 's/,//g')
printf "%-30s %-15s %-20s\n" "$u" view "$t"
fi
done;
2021-01-25 00:07:18 +08:00
for u in $ALL; do
if [[ $u =~ ^.*-[0-9]{12}$ ]];then
[[ $ADMINS == *$u* ]] || [[ $VIEWS == *$u* ]] || {
t=$(bin/cfssl-certinfo -cert "clusters/$1/ssl/users/$u.pem"|grep not_after|awk '{print $2}'|sed 's/"//g'|sed 's/,//g')
printf "%-30s %-15s %-20s\n" "$u" unknown "$t"
}
fi
done;
echo ""
}
2021-01-07 09:30:50 +08:00
2021-01-25 00:07:18 +08:00
### Main Lines ##################################################
2020-12-30 11:25:54 +08:00
function main() {
2021-01-07 09:30:50 +08:00
BASE="/etc/kubeasz"
[[ -d "$BASE" ]] || { logger error "invalid dir:$BASE, try: 'ezdown -D'"; exit 1; }
cd "$BASE"
2020-12-30 11:25:54 +08:00
# check bash shell
2022-09-08 09:36:05 +08:00
readlink /proc/$$/exe|grep -q "bash" || { logger error "you should use bash shell only"; exit 1; }
2020-12-30 11:25:54 +08:00
# check 'ansible' executable
2021-01-20 17:42:46 +08:00
which ansible > /dev/null 2>&1 || { logger error "need 'ansible', try: 'pip install ansible'"; usage; exit 1; }
2020-12-30 11:25:54 +08:00
[ "$#" -gt 0 ] || { usage >&2; exit 2; }
case "$1" in
### in-cluster operations #####################
(add-etcd)
2021-01-07 09:30:50 +08:00
[ "$#" -gt 2 ] || { usage >&2; exit 2; }
add-etcd "${@:2}"
2020-12-30 11:25:54 +08:00
;;
(add-master)
2021-01-07 09:30:50 +08:00
[ "$#" -gt 2 ] || { usage >&2; exit 2; }
add-master "${@:2}"
2020-12-30 11:25:54 +08:00
;;
(add-node)
2021-01-07 09:30:50 +08:00
[ "$#" -gt 2 ] || { usage >&2; exit 2; }
add-node "${@:2}"
2020-12-30 11:25:54 +08:00
;;
(del-etcd)
2021-01-07 09:30:50 +08:00
[ "$#" -eq 3 ] || { usage >&2; exit 2; }
del-etcd "$2" "$3"
2020-12-30 11:25:54 +08:00
;;
(del-master)
2021-01-07 09:30:50 +08:00
[ "$#" -eq 3 ] || { usage >&2; exit 2; }
del-master "$2" "$3"
2020-12-30 11:25:54 +08:00
;;
(del-node)
2021-01-07 09:30:50 +08:00
[ "$#" -eq 3 ] || { usage >&2; exit 2; }
del-node "$2" "$3"
2020-12-30 11:25:54 +08:00
;;
### cluster-wide operations #######################
2021-01-07 09:30:50 +08:00
(checkout)
[ "$#" -eq 2 ] || { usage >&2; exit 2; }
checkout "$2"
;;
2020-12-30 11:25:54 +08:00
(list)
2021-01-07 09:30:50 +08:00
[ "$#" -eq 1 ] || { usage >&2; exit 2; }
list
2020-12-30 11:25:54 +08:00
;;
(new)
[ "$#" -eq 2 ] || { usage >&2; exit 2; }
new "$2"
;;
(setup)
[ "$#" -ge 3 ] || { usage-setup >&2; exit 2; }
2020-12-30 11:25:54 +08:00
setup "${@:2}"
;;
(start)
[ "$#" -eq 2 ] || { usage >&2; exit 2; }
cmd "$2" start
;;
(stop)
[ "$#" -eq 2 ] || { usage >&2; exit 2; }
cmd "$2" stop
;;
(upgrade)
[ "$#" -eq 2 ] || { usage >&2; exit 2; }
cmd "$2" upgrade
;;
(backup)
[ "$#" -eq 2 ] || { usage >&2; exit 2; }
cmd "$2" backup
;;
(restore)
[ "$#" -eq 2 ] || { usage >&2; exit 2; }
cmd "$2" restore
;;
(destroy)
[ "$#" -eq 2 ] || { usage >&2; exit 2; }
cmd "$2" destroy
;;
(start-aio)
2021-01-07 09:30:50 +08:00
[ "$#" -eq 1 ] || { usage >&2; exit 2; }
start-aio
2020-12-30 11:25:54 +08:00
;;
### extra operations ##############################
2022-11-26 10:56:52 +08:00
(kca-renew)
[ "$#" -eq 2 ] || { usage >&2; exit 2; }
renew-ca "$2"
;;
(kcfg-adm)
[ "$#" -gt 2 ] || { usage-kcfg-adm >&2; exit 2; }
kcfg-adm "${@:2}"
;;
2020-12-30 11:25:54 +08:00
(help)
[ "$#" -gt 1 ] || { usage >&2; exit 2; }
2021-01-07 09:30:50 +08:00
help-info "$2"
2020-12-30 11:25:54 +08:00
exit 0
;;
(*)
usage
exit 0
;;
esac
}
2020-12-30 11:25:54 +08:00
main "$@"