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

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: 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搭建和管理企业级网站应用
相关文章
|
15天前
|
Kubernetes 负载均衡 Cloud Native
云原生应用:Kubernetes在容器编排中的实践与挑战
【10月更文挑战第27天】Kubernetes(简称K8s)是云原生应用的核心容器编排平台,提供自动化、扩展和管理容器化应用的能力。本文介绍Kubernetes的基本概念、安装配置、核心组件(如Pod和Deployment)、服务发现与负载均衡、网络配置及安全性挑战,帮助读者理解和实践Kubernetes在容器编排中的应用。
47 4
|
16天前
|
Kubernetes 监控 Cloud Native
云原生应用:Kubernetes在容器编排中的实践与挑战
【10月更文挑战第26天】随着云计算技术的发展,容器化成为现代应用部署的核心趋势。Kubernetes(K8s)作为容器编排领域的佼佼者,以其强大的可扩展性和自动化能力,为开发者提供了高效管理和部署容器化应用的平台。本文将详细介绍Kubernetes的基本概念、核心组件、实践过程及面临的挑战,帮助读者更好地理解和应用这一技术。
48 3
|
1月前
|
分布式计算 Hadoop Shell
Hadoop-35 HBase 集群配置和启动 3节点云服务器 集群效果测试 Shell测试
Hadoop-35 HBase 集群配置和启动 3节点云服务器 集群效果测试 Shell测试
69 4
|
1月前
|
Kubernetes API 调度
中间层 k8s(Kubernetes) 到底是什么,架构是怎么样的?
中间层 k8s(Kubernetes) 到底是什么,架构是怎么样的?
45 3
|
1月前
|
分布式计算 Hadoop Shell
Hadoop-36 HBase 3节点云服务器集群 HBase Shell 增删改查 全程多图详细 列族 row key value filter
Hadoop-36 HBase 3节点云服务器集群 HBase Shell 增删改查 全程多图详细 列族 row key value filter
57 3
|
1月前
|
运维 Kubernetes Cloud Native
云原生时代的容器编排:Kubernetes入门与实践
【10月更文挑战第4天】在云计算的浪潮中,云原生技术以其敏捷、可扩展和高效的特点引领着软件开发的新趋势。作为云原生生态中的关键组件,Kubernetes(通常被称为K8s)已成为容器编排的事实标准。本文将深入浅出地介绍Kubernetes的基本概念,并通过实际案例引导读者理解如何利用Kubernetes进行高效的容器管理和服务部署。无论你是初学者还是有一定经验的开发者,本文都将为你打开云原生世界的大门,并助你一臂之力在云原生时代乘风破浪。
|
1月前
|
Kubernetes Cloud Native 流计算
Flink-12 Flink Java 3分钟上手 Kubernetes云原生下的Flink集群 Rancher Stateful Set yaml详细 扩容缩容部署 Docker容器编排
Flink-12 Flink Java 3分钟上手 Kubernetes云原生下的Flink集群 Rancher Stateful Set yaml详细 扩容缩容部署 Docker容器编排
73 0
|
1月前
|
Kubernetes 网络协议 安全
[kubernetes]二进制方式部署单机k8s-v1.30.5
[kubernetes]二进制方式部署单机k8s-v1.30.5
|
1月前
|
Shell
一个用于添加/删除定时任务的shell脚本
一个用于添加/删除定时任务的shell脚本
75 1