Shell脚本快速部署Kubernetes(K8S v1.1版本)集群系统

简介: Shell脚本快速部署Kubernetes(K8S v1.1版本)集群系统

本文紧跟上节所讲的手动部署Kubernetes管理Docker篇所写,本篇主要内容利用Shell脚本完成快速部署Kubernetes集群。上节博文看过的朋友也能感觉到部署过程相对比较简单,那么,出于简化工作流程,推进运维自动化角度来说,于是花了2/3天时间写这个部署Kubernetes脚本。

 运维工作中,常常会遇到部署各种各样的服务,建议:常规部署都应该尽量使用脚本完成,一方面提高自身脚本编写能力,另一方面推进运维自动化。

详细部署说明文档 http://lizhenliang.blog.51cto.com/7876557/1736572

提醒:即使按照本篇文章一步一步做,也不一定部署成功。原因你懂得!如果失败,也建议你仔细看看脚本内容,从中寻找解决办法。同时,相信你也会从脚本中获取到其他有价值的信息。

实验环境:

操作系统:Ubuntu14.04_x64

master:192.168.1.150

minion01 : 192.168.1.151  容器网段:172.17.1.0/24

minion02 : 192.168.1.152  容器网段:172.17.2.0/24

安装包下载:

etcd: http://pan.baidu.com/s/1c1wITMw

kubernetes: http://pan.baidu.com/s/1kUoxgYb

相关脚本下载: http://pan.baidu.com/s/1o7nEaca

脚本说明:

config_ssh_root_remote.sh     #配置root SSH登录(默认ubuntu系统禁止root SSH登录)

ssh_keypair_auth.sh         #配置master主机与minion主机SSH免交互认证

kubernetes-install.sh        #安装kubernetes的master端与minion端

config_gre_channel.sh        #配置两台Docker主机容器实现跨主机访问(OVS)

安装步骤(请按照步骤做):

1)在minion主机root权限开启root允许SSH远程登录

操作命令:$ sudo bash config_ssh_root_remote.sh

脚本内容:$ cat config_ssh_root_remote.sh

#!/bin/bash
# Description: configuration root account ssh remote login
if [ $USER != "root" ]; then
    echo "Please use root account operation or sudo!"
    exit 1
fi
function color_echo() {
    if [ $1 == "green" ]; then
        echo -e "\033[32;40m$2\033[0m"
    elif [ $1 == "red" ]; then
        echo -e "\033[31;40m$2\033[0m"
    fi
}
function check_pkg() {
    if ! $(dpkg -l $PKG_NAME >/dev/null 2>&1); then
        echo no
    else
        echo yes
    fi
}
function install_pkg() {
    local PKG_NAME=$1
    if [ $(check_pkg $PKG_NAME) == "no" ]; then
        apt-get install $PKG_NAME -y
        if [ $(check_pkg $PKG_NAME) == "no" ]; then
            color_echo green "$PKG_NAME installation failure! Try to install again."
            apt-get autoremove && apt-get update
            apt-get install $PKG_NAME --force-yes -y
            [ $(check_pkg $PKG_NAME) == "no" ] && color_echo red "The $PKG_NAME installation failure!" && exit 1
        fi
    fi
}
install_pkg expect
# modify ssh config file
sed -r -i 's/(PermitRootLogin).*/\1 yes/' /etc/ssh/sshd_config
service ssh restart >/dev/null
# set root account password
echo "------------------------------------------------------>"
while true; do
    read -p "Please enter you want to set the root account password: " ROOT_PASS
    if [ -n "$ROOT_PASS" ]; then
        break
    else
        color_echo red "Password cannot be empty!"
        continue
    fi
done
expect -c "
    spawn passwd root
    expect {
        \"Enter new UNIX password:\" {send \"$ROOT_PASS\r\"; exp_continue}
        \"Retype new UNIX password:\" {send \"$ROOT_PASS\r\"}
    }
    expect eof
" >/dev/null
color_echo green "The root account password is: $ROOT_PASS"

2)在master主机切换到root用户执行脚本与minion主机root用户建立SSH免交互登录

操作命令:# bash ssh_keypair_auth.sh root@192.168.1.151-152@123

脚本内容:# cat ssh_keypair_auth.sh

#!/bin/bash
# Description: configuration local host and remote host ssh keypair authentication, Support Ubuntu and CentOS operation system.
function color_echo() {
    if [ $1 == "green" ]; then
        echo -e "\033[32;40m$2\033[0m"
    elif [ $1 == "red" ]; then
        echo -e "\033[31;40m$2\033[0m"
    fi
}
function os_version() {
    local OS_V=$(cat /etc/issue |awk 'NR==1{print $1}')
    if [ $OS_V == "\S" -o $OS_V == "CentOS" ]; then
        echo "CentOS"
    elif [ $OS_V == "Ubuntu" ]; then
        echo "Ubuntu"
    fi
}
function check_ssh_auth() {
    if $(grep "Permission denied" $EXP_TMP_FILE >/dev/null); then
        color_echo red "Host $IP SSH authentication failure! Login password error."
        exit 1
    elif $(ssh $INFO 'echo yes >/dev/null'); then
        color_echo green "Host $IP SSH authentication successfully."
    fi
    rm $EXP_TMP_FILE >/dev/null
}
function check_pkg() {
    local PKG_NAME=$1
    if [ $(os_version) == "CentOS" ]; then
        if ! $(rpm -ql $PKG_NAME >/dev/null 2>&1); then
            echo no
        else
            echo yes
        fi
    elif [ $(os_version) == "Ubuntu" ]; then
        if ! $(dpkg -l $PKG_NAME >/dev/null 2>&1); then
            echo no
        else
            echo yes
        fi
    fi
}
function install_pkg() {
    local PKG_NAME=$1
    if [ $(os_version) == "CentOS" ]; then
        if [ $(check_pkg $PKG_NAME) == "no" ]; then
            yum install $PKG_NAME -y
            if [ $(check_pkg $PKG_NAME) == "no" ]; then
                color_echo green "The $PKG_NAME installation failure! Try to install again."
                yum makecache
                yum install $PKG_NAME -y
                [ $(check_pkg $PKG_NAME) == "no" ] && color_echo red "The $PKG_NAME installation failure!" && exit 1
            fi
        fi
    elif [ $(os_version) == "Ubuntu" ]; then
        if [ $(check_pkg $PKG_NAME) == "no" ]; then
            apt-get install $PKG_NAME -y
            if [ $(check_pkg $PKG_NAME) == "no" ]; then
                color_echo green "$PKG_NAME installation failure! Try to install again."
                apt-get autoremove && apt-get update
                apt-get install $PKG_NAME --force-yes -y
                [ $(check_pkg $PKG_NAME) == "no" ] && color_echo red "The $PKG_NAME installation failure!" && exit 1
            fi
        fi
    fi
}
function generate_keypair() {
    if [ ! -e ~/.ssh/id_rsa.pub ]; then
        color_echo green "The public/private rsa key pair not exist, start Generating..."
        expect -c "
            spawn ssh-keygen
            expect {
                \"ssh/id_rsa):\" {send \"\r\";exp_continue}
                \"passphrase):\" {send \"\r\";exp_continue}
                \"again:\" {send \"\r\";exp_continue}
            }
        " >/dev/null 2>&1
        if [ -e ~/.ssh/id_rsa.pub ]; then
            color_echo green "Generating public/private rsa key pair successfully."
        else
            color_echo red "Generating public/private rsa key pair failure!"
            exit 1
        fi
    fi
}
EXP_TMP_FILE=/tmp/expect_ssh.tmp
if [[ $1 =~ ^[a-z]+@[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}@.* ]]; then
    install_pkg expect ; generate_keypair
    for i in $@; do
        USER=$(echo $i|cut -d@ -f1)
        IP=$(echo $i|cut -d@ -f2)
        PASS=$(echo $i|cut -d@ -f3)
        INFO=$USER@$IP
        expect -c "
            spawn ssh-copy-id $INFO
            expect {
                \"(yes/no)?\" {send \"yes\r\";exp_continue}
                \"password:\" {send \"$PASS\r\";exp_continue}
            }
        " > $EXP_TMP_FILE  # if login failed, login error info append temp file
        check_ssh_auth
    done
elif [[ $1 =~ ^[a-z]+@[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}-[0-9]{1,3}@.* ]]; then
    install_pkg expect ; generate_keypair
    START_IP_NUM=$(echo $1|sed -r 's/.*\.(.*)-(.*)@.*/\1/')
    END_IP_NUM=$(echo $1|sed -r 's/.*\.(.*)-(.*)@.*/\2/')
    for ((i=$START_IP_NUM;i<=$END_IP_NUM;i++)); do
        USER=$(echo $1|cut -d@ -f1)
        PASS=$(echo $1|cut -d@ -f3)
        IP_RANGE=$(echo $1|sed -r 's/.*@(.*\.).*/\1/')
        IP=$IP_RANGE$i
        INFO=$USER@$IP_RANGE$i
        expect -c "
            spawn ssh-copy-id $INFO
            expect {
                \"(yes/no)?\" {send \"yes\r\";exp_continue}
                \"password:\" {send \"$PASS\r\";exp_continue}
            }
        " > $EXP_TMP_FILE
        check_ssh_auth
    done
else
    echo "Example1: $0 <root@192.168.1.10-15@password>"
    echo "Example2: $0 <root@192.168.1.10@password>"
    echo "Example3: $0 [root@192.168.1.10@password root@192.168.1.11@password root@192.168.1.12@password ...]"
fi

3)在master主机root权限执行脚本安装master端服务

操作命令:$ sudo bash kubernetes-install.sh master

脚本内容:$ cat kubernetes-install.sh

#!/bin/bash
# Description: Installation Kubernetes1.1.3
# Etcd Download: https://github.com/coreos/etcd/releases/download/v2.2.2/etcd-v2.2.2-linux-amd64.tar.gz
# K8S Download: https://storage.googleapis.com/kubernetes-release/release/v1.1.3/kubernetes.tar.gz
. /lib/lsb/init-functions
if [ $(cat /etc/issue |awk '{print $1}') != "Ubuntu" ]; then
    echo "Only support ubuntu operating system!"
    exit 1
fi
if [ $USER != "root" ]; then
    echo "Please use root account operation!"
    exit 1
fi
function color_echo() {
    if [ $1 == "green" ]; then
        echo -e "\033[32;40m$2\033[0m"
    elif [ $1 == "red" ]; then
        echo -e "\033[31;40m$2\033[0m"
    fi
}
function check_install_pkg() {
    if [ ! -e $ETCD_FILE -a ! -e $K8S_FILE ]; then
        color_echo red "$ETCD_FILE and $K8S_FILE file not exist!"
        exit 1
    elif [ ! -e $ETCD_FILE ]; then
        color_echo red "$ETCD_FILE file not exist!"
        exit 1
    elif [ ! -e $K8S_FILE ]; then
        color_echo red "$K8S_FILE file not exist!"
        exit 1
    fi
}
function local_ip() {
    local NUM ARRAY_LENGTH 
    NUM=0
    for NIC_NAME in $(ls /sys/class/net|grep -vE "lo|docker0"); do
        NIC_IP=$(ifconfig $NIC_NAME |awk -F'[: ]+' '/inet addr/{print $4}')
        if [ -n "$NIC_IP" ]; then
            NIC_IP_ARRAY[$NUM]="$NIC_NAME:$NIC_IP"
            let NUM++
        fi
    done
    ARRAY_LENGTH=${#NIC_IP_ARRAY[*]}
    if [ $ARRAY_LENGTH -eq 1 ]; then
        LOCAL_IP=${NIC_IP_ARRAY[0]#*:}
        return 0
    elif [ $ARRAY_LENGTH -eq 0 ]; then
        color_echo red "No available network card!"
        exit 1
    else
        # multi network card select
        for NIC in ${NIC_IP_ARRAY[*]}; do
            echo $NIC
        done
        while true; do
            read -p "Please enter local use to network card name: " INPUT_NIC_NAME
            for NIC in ${NIC_IP_ARRAY[*]}; do
                NIC_NAME=${NIC%:*}
                if [ $NIC_NAME == "$INPUT_NIC_NAME" ]; then
                    LOCAL_IP=${NIC_IP_ARRAY[0]#*:}
                    return 0
                fi
            done
            echo "Not match! Please input again."
        done
    fi
}
function check_ip() {
    local IP=$1
    VALID_CHECK=$(echo $IP|awk -F. '$1<=255&&$2<=255&&$3<=255&&$4<=255{print "yes"}')
    if echo $IP|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$" >/dev/null; then
        if [ ${VALID_CHECK:-no} == "yes" ]; then
            return 0
        else
            echo "IP $IP not available!"
            return 1
        fi
    else
        echo "IP format error!"
        return 1
    fi
}
function cluster_ip() {
    if [ $1 == "master" ]; then
        while true; do
            read -p "Please enter master IP: " MASTER_IP
            check_ip $MASTER_IP
            [ $? -eq 0 ] && break
        done
    elif [ $1 == "minion" ]; then
        while true; do
            local MINION_NUM
            read -p "Please enter cluster minion node number: " MINION_NUM
            if [[ $MINION_NUM =~ ^[0-9]+$ ]]; then
                break
            else
                color_echo red "Format error!"
            fi
        done
        NUM=1
        while [ $NUM -le $MINION_NUM ]; do
            local MINION_IP
            read -p "Please enter minion host $NUM IP: " MINION_IP
            check_ip $MINION_IP
            if [ $? -eq 0 ]; then
                let NUM++
                MINION_IP_ARRAY+=($MINION_IP)
            fi
        done
    fi
}
function modify_init_script() {
    if [ $1 == "master" ]; then
        cd $MASTER_MODULE_INIT_SCRIPT_DIR
    elif [ $1 == "minion" ]; then
        cd $MINION_MODULE_INIT_SCRIPT_DIR
    fi
    for MODULE_INIT_SCRIPT in $(ls|grep -v etcd); do
        if [ -x $MODULE_INIT_SCRIPT ]; then
            sed -r -i '/\/sbin\/initctl/{s/(if)(.*)/\1 false \&\&\2/}' $MODULE_INIT_SCRIPT
        fi
    done
}
function check_service_status() {
    sleep 1
    if [ $(ps -ef |grep -v grep|grep -c "$BIN_DIR/$MODULE_INIT_SCRIPT") -eq 1 ]; then
        log_begin_msg "Starting $MODULE_INIT_SCRIPT"
        log_end_msg 0 # 0 is the right command execution status
    else
        log_failure_msg "$(color_echo red "Starting $MODULE_INIT_SCRIPT")"
        log_end_msg 1 # 1 is the wrong command execution status
    fi
}
function check_exec_status() {
    if [ $? -ne 0 ]; then
        color_echo green "Please try to run the script!"
        exit 1
    fi
}
BASE_DIR=$PWD
ETCD_FILE=$BASE_DIR/etcd-v2.2.2-linux-amd64.tar.gz
K8S_FILE=$BASE_DIR/kubernetes.tar.gz
BIN_DIR=/opt/bin
INIT_SCRIPT_DIR=/etc/init.d
OPTS_FILE_DIR=/etc/default
MODULE_BIN_DIR=$BASE_DIR/kubernetes/server/bin
MASTER_MODULE_INIT_SCRIPT_DIR=$BASE_DIR/kubernetes/cluster/ubuntu/master/init_scripts
MINION_MODULE_INIT_SCRIPT_DIR=$BASE_DIR/kubernetes/cluster/ubuntu/minion/init_scripts
case $1 in
master)
    check_install_pkg
    pkill etcd ; pkill kube
    cluster_ip minion
    # Create binary file directory
    [ ! -d $BIN_DIR ] && mkdir $BIN_DIR
    # Installation storage system etcd
    log_action_msg "Unzip the $ETCD_FILE"
    tar zxf $ETCD_FILE ; check_exec_status
    cp $BASE_DIR/etcd-v2.2.2-linux-amd64/etc* $BIN_DIR ; check_exec_status
    echo "
    ETCD_OPTS=\"\
    --listen-client-urls http://0.0.0.0:4001 \
    --advertise-client-urls http://0.0.0.0:4001 \
    --data-dir /var/lib/etcd/default.etcd\"
    " > $OPTS_FILE_DIR/etcd
    # Installation module kube-apiserver kube-scheduler and kube-controller-manager
    log_action_msg "Unzip the $K8S_FILE"
    tar zxf $BASE_DIR/kubernetes.tar.gz ; check_exec_status
    tar zxf $BASE_DIR/kubernetes/server/kubernetes-server-linux-amd64.tar.gz ; check_exec_status
    cd $MODULE_BIN_DIR && cp -a kubectl kube-apiserver kube-scheduler kube-controller-manager $BIN_DIR ; check_exec_status
    # Configure init scripts
    modify_init_script master
    cp -a etcd kube-* $INIT_SCRIPT_DIR ; check_exec_status
    sed -i '63s/.*/"/' $INIT_SCRIPT_DIR/etcd  #Remove the append log file,Otherwise etcd may cannot be started
    # Module Configure option
    log_action_msg "Create $OPTS_FILE_DIR/kube-apiserver startup options file ..."
    echo "
    KUBE_APISERVER_OPTS=\"\
    --insecure-bind-address=0.0.0.0 \
    --insecure-port=8080 \
    --service-cluster-ip-range=10.0.0.0/16 \
    --etcd_servers=http://127.0.0.1:4001 \
    --logtostderr=true\"
    " > $OPTS_FILE_DIR/kube-apiserver
    check_exec_status
    log_action_msg "Create $OPTS_FILE_DIR/kube-controller-manager startup options file ..."
    echo "
    KUBE_CONTROLLER_MANAGER_OPTS=\"\
    --master=127.0.0.1:8080 \
    --logtostderr=true\"
    " > $OPTS_FILE_DIR/kube-controller-manager
    log_action_msg "Create $OPTS_FILE_DIR/kube-scheduler startup options file ..."
    echo "
    KUBE_SCHEDULER_OPTS=\"\
    --master=127.0.0.1:8080 \
    --logtostderr=true\"
    " > $OPTS_FILE_DIR/kube-scheduler
    # Starting module
    for MODULE_INIT_SCRIPT in $(ls $INIT_SCRIPT_DIR|grep -E "(etcd|kube.*)"); do
        service $MODULE_INIT_SCRIPT start >/dev/null
        check_service_status
    done
    # set variable
    echo "export PATH=$PATH:$BIN_DIR" >> /etc/profile
    . /etc/profile
    # Copy module kubelet and kube-proxy to minion
    SSH_OPTS="-o ConnectTimeout=1 -o ConnectionAttempts=3"
    cd $MODULE_BIN_DIR
    for MINION_IP in ${MINION_IP_ARRAY[*]}; do
        log_action_msg "Copy module to $MINION_IP:$BIN_DIR ..."
        ssh $SSH_OPTS root@$MINION_IP "mkdir $BIN_DIR 2>/dev/null" ; check_exec_status
        scp $SSH_OPTS kubelet kube-proxy root@$MINION_IP:$BIN_DIR
    done
    # Copy module init scripts to minion
    modify_init_script minion
    cd $MINION_MODULE_INIT_SCRIPT_DIR
    for MINION_IP in ${MINION_IP_ARRAY[*]}; do
        log_action_msg "Copy module init scripts to $MINION_IP:$INIT_SCRIPT_DIR ..."
        scp $SSH_OPTS kubelet kube-proxy root@$MINION_IP:$INIT_SCRIPT_DIR ; check_exec_status
    done
    color_echo green "Kubernetes master installation complete."
    ;;
minion)
    cluster_ip master # Notice input master ip
    local_ip
    pkill kube
    # Install Docker
    if ! $(dpkg -l docker-engine >/dev/null 2>&1) && ! $(docker info >/dev/null 2>&1); then
        log_action_msg "Start the installation Docker ..."
        apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D >/dev/null 2>&1
        [ $? -ne 0 ] && echo "Docker source secret key register failure!"
        DOCKER_U_SOURCE=/tmp/docker_source.tmp
        echo "
        deb https://apt.dockerproject.org/repo ubuntu-precise main
        deb https://apt.dockerproject.org/repo ubuntu-trusty main
        deb https://apt.dockerproject.org/repo ubuntu-vivid main
        deb https://apt.dockerproject.org/repo ubuntu-wily main
        " > $DOCKER_U_SOURCE
        OS_CODE_V=$(lsb_release -cs)
        DOKER_SOURCE=$(grep $OS_CODE_V $DOCKER_U_SOURCE)
        echo "$DOKER_SOURCE" > /etc/apt/sources.list.d/docker.list
        rm $DOCKER_U_SOURCE
        apt-get update
        apt-get install docker-engine  -y
        if $(dpkg -l docker-engine >/dev/null) && $(docker info >/dev/null); then
            color_echo green "Docker installation successfully."
        else
            apt-get remove ; apt-get install docker-engine --force-yes -y
            if ! $(dpkg -l docker-engine >/dev/null) && ! $(docker info >/dev/null); then
                color_echo red "Docker installation failure!"
                exit 1
            fi
        fi
    fi
    # Module Configure option
    log_action_msg "Create $OPTS_FILE_DIR/kubelet startup options file ..."
    echo "
    KUBELET_OPTS=\"\
    --address=0.0.0.0 \
    --port=10250 \
    --hostname_override=$LOCAL_IP \
    --api_servers=http://$MASTER_IP:8080 \
    --pod-infra-container-p_w_picpath=docker.io/kubernetes/pause:latest \
    --logtostderr=true\"
    " > $OPTS_FILE_DIR/kubelet
    log_action_msg "Create $OPTS_FILE_DIR/kube-proxy startup options file ..."
    echo "
    KUBE_PROXY_OPTS=\"\
    --master=http://$MASTER_IP:8080 \
    --proxy-mode=iptables \
    --logtostderr=true\"
    " > $OPTS_FILE_DIR/kube-proxy
    # Starting module
    for MODULE_INIT_SCRIPT in $(ls $INIT_SCRIPT_DIR|grep kube.*); do
        service $MODULE_INIT_SCRIPT start >/dev/null
        check_service_status
    done
    color_echo green "Kubernetes minion installation complete."
    ;;
*)
    echo "Usage: $0 {master|minion}"
    exit 1
    ;;
esac

4)在minion主机root权限执行脚本安装minion端服务

操作命令:$ sudo bash kubernetes-install.sh minion

脚本内容:同上

5)在minion主机root权限执行脚本创建GRE通道

操作命令:$ sudo bash config_gre_channel.sh

脚本内容:$ cat config_gre_channel.sh

#!/bin/bash
# Description: configuration docker host between GRE Channel
if [ $(cat /etc/issue |awk '{print $1}') != "Ubuntu" ]; then
    echo "Only support ubuntu operating system!"
    exit 1
fi
if [ $USER != "root" ]; then
    echo "Please use root account operation!"
    exit 1
fi
function color_echo() {
    if [ $1 == "green" ]; then
        echo -e "\033[32;40m$2\033[0m"
    elif [ $1 == "red" ]; then
        echo -e "\033[31;40m$2\033[0m"
    fi
}
function check_ip() {
    local IP=$1
    local VALID_CHECK=$(echo $IP|awk -F. '$1<=255&&$2<=255&&$3<=255&&$4<=255{print "yes"}')
    if echo $IP|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$" >/dev/null; then
        if [ ${VALID_CHECK:-no} == "yes" ]; then
            return 0
        else
            echo "IP $IP not available!"
            return 1
        fi
    else
        echo "IP format error!"
        return 1
    fi
}
function docker_host_ip() {
        color_echo green "Notice: Only support two Docker host configuration GRE Channel!"
        NUM=1
        while [ $NUM -le 2 ]; do
            local DOCKER_IP
            read -p "Please enter Docker host $NUM IP: " DOCKER_HOST_IP
            check_ip $DOCKER_HOST_IP
            if [ $? -eq 0 ]; then
                let NUM++
                DOCKER_HOST_IP_ARRAY+=($DOCKER_HOST_IP)
            fi
        done
}
function local_nic_info() {
    local NUM ARRAY_LENGTH
    NUM=0
    for NIC_NAME in $(ls /sys/class/net|grep -vE "lo|docker0"); do
        NIC_IP=$(ifconfig $NIC_NAME |awk -F'[: ]+' '/inet addr/{print $4}')
        if [ -n "$NIC_IP" ]; then
            NIC_IP_ARRAY[$NUM]="$NIC_NAME:$NIC_IP"
            let NUM++
        fi
    done
    ARRAY_LENGTH=${#NIC_IP_ARRAY[*]}
    if [ $ARRAY_LENGTH -eq 1 ]; then
        LOCAL_NIC=${NIC_IP_ARRAY[0]%:*}
        LOCAL_IP=${NIC_IP_ARRAY[0]#*:}
        return 0
    elif [ $ARRAY_LENGTH -eq 0 ]; then
        color_echo red "No available network card!"
        exit 1
    else
        # multi network card select
        for NIC in ${NIC_IP_ARRAY[*]}; do
            echo $NIC
        done
        while true; do
            read -p "Please enter local use to network card name: " INPUT_NIC_NAME
            for NIC in ${NIC_IP_ARRAY[*]}; do
                NIC_NAME=${NIC%:*}
                if [ $NIC_NAME == "$INPUT_NIC_NAME" ]; then
                    LOCAL_NIC=${NIC_IP_ARRAY[0]%:*}
                    LOCAL_IP=${NIC_IP_ARRAY[0]#*:}
                    return 0
                fi
            done
            echo "Not match! Please input again."
        done
    fi
}
function check_pkg() {
    if ! $(dpkg -l $PKG_NAME >/dev/null 2>&1); then
        echo no
    else
        echo yes
    fi
}
function install_pkg() {
    local PKG_NAME=$1
    if [ $(check_pkg $PKG_NAME) == "no" ]; then
        apt-get install $PKG_NAME -y
        if [ $(check_pkg $PKG_NAME) == "no" ]; then
            color_echo green "The $PKG_NAME installation failure! Try to install again."
            apt-get autoremove && apt-get update
            apt-get install $PKG_NAME --force-yes -y
            [ $(check_pkg $PKG_NAME) == "no" ] && color_echo red "The $PKG_NAME installation failure!" && exit 1
        fi
    fi
}
function config_gre_channel() {
    install_pkg openvswitch-switch
    install_pkg bridge-utils
    if [ ${DOCKER_HOST_IP_ARRAY[0]} == "$LOCAL_IP" ]; then
        REMOTE_HOST_IP=${DOCKER_HOST_IP_ARRAY[1]}  # remote host ip
        REMOTE_DOCKER_IP="172.17.2.0/24"   # remote docker host default container ip range
        LOCAL_DOCKER_IP="172.17.1.0"    # kbr0 gateway
    elif [ ${DOCKER_HOST_IP_ARRAY[1]} == "$LOCAL_IP" ]; then
        REMOTE_HOST_IP=${DOCKER_HOST_IP_ARRAY[0]}
        REMOTE_DOCKER_IP="172.17.1.0/24"
        LOCAL_DOCKER_IP="172.17.2.0"
    else
        echo "IP not match! Please input again."
        exit 1
    fi
    ovs-vsctl add-br obr0 2>/dev/null
    ovs-vsctl add-port obr0 gre0 -- set Interface gre0 type=gre options:remote_ip=$REMOTE_HOST_IP 2>/dev/null
    brctl addbr kbr0 2>/dev/null
    brctl addif kbr0 obr0 2>/dev/null
    ip link set dev kbr0 up
    if [ $(grep -cE "kbr0" /etc/network/interfaces) -ne 2 ]; then
        echo "
auto kbr0
iface kbr0 inet static
    address $(echo $LOCAL_DOCKER_IP|sed 's/0$/1/')
    netmask 255.255.255.0
    gateway $LOCAL_DOCKER_IP
    bridge_ports obr0
        " >> /etc/network/interfaces
    fi
    if $(ls /sys/class/net|grep docker0 >/dev/null); then
        service docker stop >/dev/null
        ip link set dev docker0 down
        ip link delete dev docker0
        echo "DOCKER_OPTS=\"-b=kbr0\"" > /etc/default/docker
        service docker start >/dev/null
    fi
    ifdown kbr0 >/dev/null 2>&1;ifup kbr0 >/dev/null 2>&1
    # reboot invalid
    # ip route add $REMOTE_DOCKER_IP via $REMOTE_HOST_IP dev $LOCAL_NIC 2>/dev/null
    # permanent valid
    if ! $(grep "$REMOTE_DOCKER_IP via $REMOTE_HOST_IP" /etc/rc.local >/dev/null); then
        sed -i "$i\ip route add $REMOTE_DOCKER_IP via $REMOTE_HOST_IP dev $LOCAL_NIC" /etc/rc.local
    fi
}
# main
docker_host_ip
echo "--------------------------------------------"
local_nic_info
config_gre_channel
color_echo green "GRE Channel configuration complete."
brctl show
echo "-------------------------------------------------"
ovs-vsctl show

1、配置minion主机root SSH登录

先将config_gre_channel.sh、config_ssh_root_remote.sh和kubernetes-install.sh这三个文件上传各自的minion主机,以备后用。

wKiom1andkaDYH9eAAD822Zk8Yc240.gif wKioL1andomgjPzmAAD-8-Se6Yg166.gif

说明:操作成功,root密码为123

2、配置master主机与minion主机SSH免交互认证

将kubernetes-install.sh、ssh_keypair_auth.sh和etcd-v2.2.2-linux-amd64.tar.gz、kubernetes.tar.gz安装包上传到master主机

wKioL1anfPHSocP8AAFe0BuIpdE717.gif

3、安装master端

wKiom1anfMOhxMGRAAEnHE9-0xo326.gif

说明:先解压文件,在创建启动选项文件,再启动服务,最后将minion相关包通过scp工具拷贝过去。通过ps工具看到服务进程已经启动。

4、安装minion端 wKioL1anfSThIlsEAAChm8MNlUA958.gif

wKiom1anfODCwaHzAAAJgrqzPOk731.gif

wKiom1anfOHS46TXAABvfDFm83I151.gif

wKiom1anfOLTXeGQAACj6FqqGHM390.gif

wKioL1anfSfCAGSzAABw9U_zMk8117.gif

说明:Docker源秘钥注册失败,没关系,一般不会影响安装。当提示安装docker成功后才能继续,否则报错退出。通过ps 工具看到服务进程都已经启动。

5、配置GRE通道

wKioL1anfT7RPXUTAACwJWoCUv4740.gif

wKiom1anfPqCAWhWAAA51f8PrdE569.gif

wKiom1anfReiSA5vAACzQM6IonA001.gif


wKioL1anfVzTXLJ-AAA5gWNmQtw962.gif

说明:目前配置GRE通道脚本只支持两台Docker主机

6、查看集群是否配置成功

# 通过kubectl命令创建一个pod

wKiom1anfTbTGsCIAABuYAxrgj0402.gif

wKioL1anfXvQkIkuAAA-n25o8cM998.gif

说明:在master端可以看到两台minion端状态是Ready,并且创建的Pod已经成功运行。

注意:如果没有kubectl命令,先尝试执行source /etc/profile下看看,如果还没有,直接使用/opt/bin/kubectl

博客地址: http://lizhenliang.blog.51cto.com

脚本bug有待您的发现,欢迎留言!谢谢


相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
4天前
|
存储 Kubernetes 容器
K8S部署nexus
该配置文件定义了Nexus 3的Kubernetes部署,包括PersistentVolumeClaim、Deployment和服务。PVC请求20Gi存储,使用NFS存储类。Deployment配置了一个Nexus 3容器,内存限制为6G,CPU为1000m,并挂载数据卷。Service类型为NodePort,通过30520端口对外提供服务。所有资源位于`nexus`命名空间中。
|
27天前
|
Kubernetes Cloud Native 微服务
云原生入门与实践:Kubernetes的简易部署
云原生技术正改变着现代应用的开发和部署方式。本文将引导你了解云原生的基础概念,并重点介绍如何使用Kubernetes进行容器编排。我们将通过一个简易的示例来展示如何快速启动一个Kubernetes集群,并在其上运行一个简单的应用。无论你是云原生新手还是希望扩展现有知识,本文都将为你提供实用的信息和启发性的见解。
|
2月前
|
监控 网络协议 Shell
ip和ip网段攻击拦截系统-绿叶结界防火墙系统shell脚本
这是一个名为“小绿叶技术博客扫段攻击拦截系统”的Bash脚本,用于监控和拦截TCP攻击。通过抓取网络数据包监控可疑IP,并利用iptables和firewalld防火墙规则对这些IP进行拦截。同时,该系统能够查询数据库中的白名单,确保合法IP不受影响。此外,它还具备日志记录功能,以便于后续分析和审计。
60 6
|
1月前
|
运维 监控 Shell
深入理解Linux系统下的Shell脚本编程
【10月更文挑战第24天】本文将深入浅出地介绍Linux系统中Shell脚本的基础知识和实用技巧,帮助读者从零开始学习编写Shell脚本。通过本文的学习,你将能够掌握Shell脚本的基本语法、变量使用、流程控制以及函数定义等核心概念,并学会如何将这些知识应用于实际问题解决中。文章还将展示几个实用的Shell脚本例子,以加深对知识点的理解和应用。无论你是运维人员还是软件开发者,这篇文章都将为你提供强大的Linux自动化工具。
|
1月前
|
存储 Kubernetes Devops
Kubernetes集群管理和服务部署实战
Kubernetes集群管理和服务部署实战
51 0
|
2月前
|
NoSQL 关系型数据库 Redis
高可用和性能:基于ACK部署Dify的最佳实践
本文介绍了基于阿里云容器服务ACK,部署高可用、可伸缩且具备高SLA的生产可用的Dify服务的详细解决方案。
|
2月前
|
Shell
一个用于添加/删除定时任务的shell脚本
一个用于添加/删除定时任务的shell脚本
114 1
|
1月前
|
Shell Linux 测试技术
6种方法打造出色的Shell脚本
6种方法打造出色的Shell脚本
68 2
6种方法打造出色的Shell脚本
|
1月前
|
XML JSON 监控
Shell脚本要点和难点以及具体应用和优缺点介绍
Shell脚本在系统管理和自动化任务中扮演着重要角色。尽管存在调试困难、可读性差等问题,但其简洁高效、易于学习和强大的功能使其在许多场景中不可或缺。通过掌握Shell脚本的基本语法、常用命令和函数,并了解其优缺点,开发者可以编写出高效的脚本来完成各种任务,提高工作效率。希望本文能为您在Shell脚本编写和应用中提供有价值的参考和指导。
62 1
|
1月前
|
Ubuntu Shell 开发工具
ubuntu/debian shell 脚本自动配置 gitea git 仓库
这是一个自动配置 Gitea Git 仓库的 Shell 脚本,支持 Ubuntu 20+ 和 Debian 12+ 系统。脚本会创建必要的目录、下载并安装 Gitea,创建 Gitea 用户和服务,确保 Gitea 在系统启动时自动运行。用户可以选择从官方或小绿叶技术博客下载安装包。
54 2