generated from bing/readnotes
367 lines
11 KiB
Bash
Executable File
367 lines
11 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
##
|
|
HAPASSWORD="4orLcyKqDFWrmGlQ"
|
|
|
|
init_etcd(){
|
|
echo "init etcd cluster: $@"
|
|
echo "create config files..."
|
|
kubeadm reset -f
|
|
if [ ! -d /tmp/kubelet.service.d ];then
|
|
mkdir /tmp/kubelet.service.d
|
|
fi
|
|
cat << EOF > /tmp/kubelet.service.d/20-etcd-service-manager.conf
|
|
[Service]
|
|
ExecStart=
|
|
# Replace "systemd" with the cgroup driver of your container runtime. The default value in the kubelet is "cgroupfs".
|
|
ExecStart=/usr/bin/kubelet --container-runtime=remote --container-runtime-endpoint=unix:///run/containerd/containerd.sock --address=127.0.0.1 --pod-manifest-path=/etc/kubernetes/manifests --pod-infra-container-image=registry.bing89.com/kubernetes/pause:3.2
|
|
Restart=always
|
|
EOF
|
|
if [[ -f etc/kubernetes/pki/etcd/ca.crt ]] && [[ -f etc/kubernetes/pki/etcd/ca.key ]];then
|
|
echo 'using exists key.'
|
|
else
|
|
if [[ -f etc/kubernetes/pki/etcd/ca.crt ]] || [[ -f etc/kubernetes/pki/etcd/ca.key ]]; then
|
|
echo 'ssl key config error, maybe there one key is exists. exit '
|
|
exit 2
|
|
fi
|
|
echo 'init kubernetes ssh keys'
|
|
kubeadm init phase certs etcd-ca
|
|
fi
|
|
NAME_PREFIX="infra"
|
|
INDEX=0
|
|
INIT_CLUSTERS=""
|
|
for ETCD_HOST in $@; do
|
|
if [ "x${INIT_CLUSTERS}" == "x" ]; then
|
|
INIT_CLUSTERS="${NAME_PREFIX}${INDEX}=https://${ETCD_HOST}:2380"
|
|
else
|
|
INIT_CLUSTERS="${INIT_CLUSTERS},${NAME_PREFIX}${INDEX}=https://${ETCD_HOST}:2380"
|
|
fi
|
|
INDEX=$(expr ${INDEX} + 1)
|
|
done
|
|
echo "init_clusters: ${INIT_CLUSTERS}"
|
|
INDEX=0
|
|
for HOST in ${@};
|
|
do
|
|
if [ ! -d /tmp/${HOST} ];then
|
|
mkdir /tmp/${HOST}
|
|
else
|
|
rm -rf /tmp/${HOST}/*
|
|
fi
|
|
cat <<EOF >/tmp/${HOST}/etcdcfg.yaml
|
|
apiVersion: kubelet.config.k8s.io/v1beta1
|
|
kind: KubeletConfiguration
|
|
cgroupDriver: systemd
|
|
---
|
|
apiVersion: "kubeadm.k8s.io/v1beta2"
|
|
kind: ClusterConfiguration
|
|
imageRepository: registry.bing89.com/kubernetes
|
|
etcd:
|
|
local:
|
|
serverCertSANs:
|
|
- "${HOST}"
|
|
peerCertSANs:
|
|
- "${HOST}"
|
|
extraArgs:
|
|
initial-cluster: ${INIT_CLUSTERS}
|
|
initial-cluster-state: new
|
|
name: ${NAME_PREFIX}${INDEX}
|
|
listen-peer-urls: https://${HOST}:2380
|
|
listen-client-urls: https://${HOST}:2379
|
|
advertise-client-urls: https://${HOST}:2379
|
|
initial-advertise-peer-urls: https://${HOST}:2380
|
|
EOF
|
|
|
|
kubeadm init phase certs etcd-server --config=/tmp/${HOST}/etcdcfg.yaml
|
|
kubeadm init phase certs etcd-peer --config=/tmp/${HOST}/etcdcfg.yaml
|
|
kubeadm init phase certs etcd-healthcheck-client --config=/tmp/${HOST}/etcdcfg.yaml
|
|
kubeadm init phase certs apiserver-etcd-client --config=/tmp/${HOST}/etcdcfg.yaml
|
|
cp -R /etc/kubernetes/pki /tmp/${HOST}/
|
|
# 清理不可重复使用的证书
|
|
find /etc/kubernetes/pki -not -name ca.crt -not -name ca.key -type f -delete
|
|
# 清理不应从此主机复制的证书
|
|
if [ "x${INDEX}" != "x0" ];then
|
|
find /tmp/${HOST} -name ca.key -type f -delete
|
|
fi
|
|
INDEX=$(expr ${INDEX} + 1)
|
|
done
|
|
echo "configure etcd hosts"
|
|
for HOST in ${@};
|
|
do
|
|
scp -r /tmp/kubelet.service.d ${HOST}:/etc/systemd/system/
|
|
scp -r /tmp/${HOST}/* ${HOST}:/tmp
|
|
ssh ${HOST} "systemctl daemon-reload"
|
|
ssh ${HOST} "kubeadm reset -f && rsync -ivhPr /tmp/pki /etc/kubernetes/"
|
|
ssh ${HOST} "systemctl restart kubelet && kubeadm init phase etcd local --config=/tmp/etcdcfg.yaml"
|
|
done
|
|
echo "cluster init finished. use this command to check cluster status"
|
|
echo "docker run --rm -it --net host -v /etc/kubernetes:/etc/kubernetes registry.bing89.com/kubernetes/etcd:3.4.13-0 etcdctl --cert /etc/kubernetes/pki/etcd/peer.crt --key /etc/kubernetes/pki/etcd/peer.key --cacert /etc/kubernetes/pki/etcd/ca.crt --endpoints https://${HOST}:2379 endpoint health --cluster"
|
|
}
|
|
|
|
init_controller(){
|
|
echo "init controller: $@"
|
|
echo "warning: your kubelet will reset"
|
|
echo "backup ha pod if exists"
|
|
if [ -f /etc/kubernetes/manifests/haproxy.yaml ];then
|
|
cp /etc/kubernetes/manifests/haproxy.yaml /tmp/haproxy.yaml.backup
|
|
fi
|
|
|
|
|
|
echo "creating kubeadm config file"
|
|
ENDPOINTS="["
|
|
for ETCD_HOST in ${ETCD_HOSTS[@]}; do
|
|
if [ "x${ENDPOINTS}" == "x[" ];then
|
|
ENDPOINTS="${ENDPOINTS}\"https://${ETCD_HOST}:2379\""
|
|
else
|
|
ENDPOINTS="${ENDPOINTS},\"https://${ETCD_HOST}:2379\""
|
|
fi
|
|
done
|
|
ENDPOINTS="${ENDPOINTS}]"
|
|
echo "etcd end points: ${ENDPOINTS}"
|
|
APISERVERSANS="["
|
|
for CONTROLLER_HOST in ${CONTROLLER_HOSTS[@]}
|
|
do
|
|
if [ "x${APISERVERSANS}" == "x[" ];then
|
|
APISERVERSANS="${APISERVERSANS}\"${CONTROLLER_HOST}\""
|
|
else
|
|
APISERVERSANS="${APISERVERSANS},\"${CONTROLLER_HOST}\""
|
|
fi
|
|
done
|
|
APISERVERSANS="${APISERVERSANS}]"
|
|
cat <<EOF >/tmp/kubeadmcfg.yaml
|
|
apiVersion: kubelet.config.k8s.io/v1beta1
|
|
kind: KubeletConfiguration
|
|
cgroupDriver: systemd
|
|
---
|
|
apiVersion: kubeadm.k8s.io/v1beta2
|
|
kind: ClusterConfiguration
|
|
kubernetesVersion: stable
|
|
controlPlaneEndpoint: "${APIHOST}:8443"
|
|
imageRepository: registry.bing89.com/kubernetes
|
|
etcd:
|
|
external:
|
|
endpoints: ${ENDPOINTS}
|
|
caFile: /etc/kubernetes/pki/etcd/ca.crt
|
|
certFile: /etc/kubernetes/pki/apiserver-etcd-client.crt
|
|
keyFile: /etc/kubernetes/pki/apiserver-etcd-client.key
|
|
apiServer:
|
|
certSANs: ${APISERVERSANS}
|
|
EOF
|
|
|
|
kubeadm reset -f
|
|
echo "restore ha pod if exists"
|
|
if [ -f /tmp/haproxy.yaml.backup ];then
|
|
cp /tmp/haproxy.yaml.backup /etc/kubernetes/manifests/haproxy.yaml
|
|
systemctl restart kubelet
|
|
fi
|
|
mkdir /etc/kubernetes/pki/etcd/
|
|
scp /tmp/$1/pki/etcd/ca.crt /etc/kubernetes/pki/etcd/ca.crt
|
|
scp /tmp/$1/pki/apiserver-etcd-client.crt /etc/kubernetes/pki/apiserver-etcd-client.crt
|
|
scp /tmp/$1/pki/apiserver-etcd-client.key /etc/kubernetes/pki/apiserver-etcd-client.key
|
|
kubeadm init --config /tmp/kubeadmcfg.yaml --upload-certs
|
|
}
|
|
|
|
init_haproxy(){
|
|
echo 'init haproxy'
|
|
echo 'install pcs'
|
|
for HOST in ${HA_HOSTS[@]}
|
|
do
|
|
ssh ${HOST} "yum install corosync pacemaker pcs fence-agents resource-agents -y && systemctl enable --now pcsd"
|
|
done
|
|
echo 'config pcs'
|
|
for HOST in ${HA_HOSTS[@]}
|
|
do
|
|
ssh ${HOST} "echo ${HAPASSWORD} | passwd --stdin hacluster && pcs cluster auth -u hacluster -p ${HAPASSWORD} ${HA_HOSTS}"
|
|
ssh ${HOST} "pcs cluster setup --start --name k8s_cluster ${HA_HOSTS}"
|
|
ssh ${HOST} "pcs cluster enable --all && pcs cluster start --all && pcs cluster status && pcs status corosync"
|
|
ssh ${HOST} "pcs property set stonith-enabled=false && pcs property set no-quorum-policy=ignore && crm_verify -L -V"
|
|
done
|
|
ssh ${HA_HOSTS[0]} "pcs resource create vip ocf:heartbeat:IPaddr2 ip=${APIHOSTS} cidr_netmask=28 op monitor interval=28s"
|
|
|
|
echo 'write haproxy config...'
|
|
APISERVERS=""
|
|
INDEX=1
|
|
PREFIX="k8smaster"
|
|
|
|
cat <<EOF >/tmp/haproxy.cfg
|
|
# /etc/haproxy/haproxy.cfg
|
|
#---------------------------------------------------------------------
|
|
# Global settings
|
|
#---------------------------------------------------------------------
|
|
global
|
|
log /dev/log local0
|
|
log /dev/log local1 notice
|
|
daemon
|
|
|
|
#---------------------------------------------------------------------
|
|
# common defaults that all the 'listen' and 'backend' sections will
|
|
# use if not designated in their block
|
|
#---------------------------------------------------------------------
|
|
defaults
|
|
mode http
|
|
log global
|
|
option httplog
|
|
option dontlognull
|
|
option http-server-close
|
|
option forwardfor except 127.0.0.0/8
|
|
option redispatch
|
|
retries 1
|
|
timeout http-request 10s
|
|
timeout queue 20s
|
|
timeout connect 5s
|
|
timeout client 20s
|
|
timeout server 20s
|
|
timeout http-keep-alive 10s
|
|
timeout check 10s
|
|
|
|
#---------------------------------------------------------------------
|
|
# apiserver frontend which proxys to the masters
|
|
#---------------------------------------------------------------------
|
|
frontend apiserver
|
|
bind *:8443
|
|
mode tcp
|
|
option tcplog
|
|
default_backend apiserver
|
|
|
|
#---------------------------------------------------------------------
|
|
# round robin balancing for apiserver
|
|
#---------------------------------------------------------------------
|
|
backend apiserver
|
|
option httpchk GET /healthz
|
|
http-check expect status 200
|
|
mode tcp
|
|
option ssl-hello-chk
|
|
balance roundrobin
|
|
EOF
|
|
INDEX=0
|
|
for HOST in ${HA_HOSTS[@]}
|
|
do
|
|
echo " server ${HOST} ${CONTROLLER_HOSTS[${INDEX}]}:6443 weight 1 maxconn 1000 check inter 2000 rise 2 fall 3\n" >> /tmp/haproxy.cfg
|
|
INDEX=$(expr ${INDEX} + 1)
|
|
done
|
|
echo "write haproxy pod yaml"
|
|
cat <<EOF >/tmp/haproxy.yaml
|
|
apiVersion: v1
|
|
kind: Pod
|
|
metadata:
|
|
name: haproxy
|
|
namespace: kube-system
|
|
spec:
|
|
containers:
|
|
- image: registry.bing89.com/dockerhub/haproxy:lts-alpine
|
|
name: haproxy
|
|
livenessProbe:
|
|
failureThreshold: 8
|
|
httpGet:
|
|
host: localhost
|
|
path: /healthz
|
|
port: 8443
|
|
scheme: HTTPS
|
|
volumeMounts:
|
|
- mountPath: /usr/local/etc/haproxy/haproxy.cfg
|
|
name: haproxyconf
|
|
readOnly: true
|
|
hostNetwork: true
|
|
volumes:
|
|
- hostPath:
|
|
path: /etc/haproxy/haproxy.cfg
|
|
type: FileOrCreate
|
|
name: haproxyconf
|
|
status: {}
|
|
EOF
|
|
for HOST in ${CONTROLLER_HOSTS[@]}
|
|
do
|
|
ssh ${HOST} "if [ ! -d /etc/haproxy ];then mkdir /etc/haproxy; fi"
|
|
scp /tmp/haproxy.cfg ${HOST}:/etc/haproxy/haproxy.cfg
|
|
scp /tmp/haproxy.yaml ${HOST}:/etc/kubernetes/manifests/haproxy.yaml
|
|
done
|
|
echo 'init haproxy finished'
|
|
}
|
|
|
|
init_kube_vip(){
|
|
echo "init kube_vip..."
|
|
echo "exit"
|
|
exit 0
|
|
for HOST in ${CONTROLLER_HOSTS[@]}
|
|
do
|
|
if [ ! -d /tmp/${HOST}/kube-vip ]; then
|
|
mkdir -p /tmp/${HOST}/kube-vip
|
|
fi
|
|
done
|
|
}
|
|
|
|
init_network(){
|
|
echo "init cni: $@"
|
|
|
|
}
|
|
|
|
USAGE_EXITS(){
|
|
echo "this is help message."
|
|
exit 1
|
|
}
|
|
|
|
check_args(){
|
|
if [ "x${ETCD_HOSTS}" == "x" ];then
|
|
USAGE_EXITS
|
|
fi
|
|
if [ "x${CONTROLLER_HOSTS}" == "x" ];then
|
|
USAGE_EXITS
|
|
fi
|
|
if [ "x${APIHOST}" == "x" ];then
|
|
USAGE_EXITS
|
|
fi
|
|
}
|
|
main(){
|
|
COMMAND=$1
|
|
shift
|
|
while getopts "c:e:n:a:p:h" arg
|
|
do
|
|
case ${arg} in
|
|
e)
|
|
ETCD_HOSTS=(${OPTARG//,/ })
|
|
;;
|
|
c)
|
|
CONTROLLER_HOSTS=(${OPTARG//,/ })
|
|
;;
|
|
n)
|
|
NETWORK_CNI=${OPTARG}
|
|
;;
|
|
a)
|
|
APIHOST=${OPTARG}
|
|
;;
|
|
p)
|
|
HA_HOSTS=(${OPTARG//,/ })
|
|
;;
|
|
h)
|
|
USAGE_EXITS
|
|
;;
|
|
esac
|
|
done
|
|
check_args
|
|
case ${COMMAND} in
|
|
etcd)
|
|
# echo ${ETCD_HOSTS[0]}
|
|
init_etcd ${ETCD_HOSTS[@]}
|
|
;;
|
|
controllplane)
|
|
init_controller ${ETCD_HOSTS}
|
|
;;
|
|
network)
|
|
init_network ${NETWORK_CNI}
|
|
;;
|
|
haproxy)
|
|
init_haproxy
|
|
;;
|
|
kubevip)
|
|
init_kube_vip
|
|
;;
|
|
help)
|
|
USAGE_EXITS
|
|
;;
|
|
*)
|
|
USAGE_EXITS
|
|
;;
|
|
esac
|
|
}
|
|
|
|
main $@
|