• k8s 1.14.8 二进制离线部署


    k8s 1.14.8 二进制离线部署

    • 参考
    https://www.kubernetes.org.cn/5163.html
    

    1,kubernetes 介绍

    • Kubernetes(K8S)是Google开源的容器集群管理系统,K8S在Docker容器技术的基础之上,大大地提高了容器化部署应用简单高效。并且具备了完整的集群管理能力,涵盖项目周期的各个环节。
    • Docker与Kubernetes联系:Docker是一个容器引擎,用于运行容器,Kubernetes是一个容器编排系统,不具备容器引擎功能,相比Docker是一个更高级封装,而他们在一起堪称珠联璧合。

    2,集群环境规划

    2.1 软件环境

    服务 版本
    CentOS 7.6 CentOS Linux release 7.6.1810 (Core)
    kubernetes v1.14.8
    Docker v18.09
    etcd v3.3.17
    Calico v3.10.1
    CoreDNS v1.5.2

    2.2 服务器角色

    IP hostname application CPU Memory
    192.168.154.130 VIP
    192.168.154.131 k8s-m1 etcd,kube-apiserver,kube-controller-manager,kube-scheduler,haproxy,keepalived,nginx,docker-distribution 2C 2G
    192.168.154.132 k8s-m2 etcd,kube-apiserver,kube-controller-manager,kube-scheduler,haproxy,keepalived 2C 2G
    192.168.154.133 k8s-m3 etcd,kube-apiserver,kube-controller-manager,kube-scheduler,haproxy,keepalived 2C 2G
    192.168.154.134 k8s-n1 docker,kubelet,kube-proxy 2C 2G
    192.168.154.135 k8s-n2 docker,kubelet,kube-proxy 2C 2G

    3,部署前环境准备

    • 所有的操作都在master1上进行

    • 登录maser1服务器

    • 创建k8s模板目录

    mkdir -p /etc/kubernetes/template
    
    • 上传 k8s 相关包
    链接:https://pan.baidu.com/s/1lZIVuafZ8ohFtKLa1r7fSA 
    提取码:3fra
    
    • 进入 k8s 模板目录,解压相关包
    cd  /etc/kubernetes/template
    # 配置文件
    tar zxvf k8s-Binary_deployment_1.14.8_cfg.tar.gz
    # 命令
    tar zxvf k8s-Binary_deployment_1.14.8_bin.tar.gz
    # 镜像
    tar zxvf k8s-Binary_deployment_1.14.8_images.tar.gz
    # rpm 包
    tar zxvf k8s-Binary_deployment_1.14.8_k8s-centos76-repo.tar.gz
    
    • 在k8s集群环境变量文件修改配置IP,网段等:k8s_env
    # 声明集群成员信息
    declare -A MasterArray otherMaster NodeArray AllNode Other
    MasterArray=(['k8s-m1']=192.168.154.131 ['k8s-m2']=192.168.154.132 ['k8s-m3']=192.168.154.133)
    Master1=(['k8s-m1']=192.168.154.131)
    otherMaster=(['k8s-m2']=192.168.154.132 ['k8s-m3']=192.168.154.133)
    NodeArray=(['k8s-n1']=192.168.154.134 ['k8s-n2']=192.168.154.135)
    # 下面复制上面的信息粘贴即可
    AllNode=(['k8s-m1']=192.168.154.131 ['k8s-m2']=192.168.154.132 ['k8s-m3']=192.168.154.133 ['k8s-n1']=192.168.154.134 ['k8s-n2']=192.168.154.135)
    Other=(['k8s-m2']=192.168.154.132 ['k8s-m3']=192.168.154.133 ['k8s-n1']=192.168.154.134 ['k8s-n2']=192.168.154.135)
    
    # 高可用集群haproxy+keepalived虚拟IP
    export VIP=192.168.154.130
    #export INGRESS_VIP=192.168.154.129
    [ "${#MasterArray[@]}" -eq 1 ] && export VIP=${MasterArray[@]} || export API_PORT=8443
    export KUBE_APISERVER=https://${VIP}:${API_PORT:=6443}
    
    # 节点密码
    export HOST_PWD="root"
    
    # 声明需要安装的的k8s版本
    export KUBE_VERSION=v1.14.8
    
    # k8s 模板目录
    export TEMP_DIR=/etc/kubernetes/template/k8s-Binary_deployment_1.14.8
    
    # k8s 项目目录
    export PROJECT_DIR=/etc/kubernetes/k8s-Binary_deployment_1.14.8
    
    # k8s 日志路径
    export LOG_DIR=/var/log/kubernetes
    
    # k8s 工作目录
    export WORK_DIR=/var/lib/kubernetes
    
    # 节点间互联网络接口名称
    export IFACE="ens33"
    
    # 服务网段,部署前路由不可达,部署后集群内路由可达
    export SERVICE_CIDR="10.254.0.0/16"
    
    # Pod 网段,建议 /16 段地址,部署前路由不可达,部署后集群内路由可达
    export CLUSTER_CIDR="172.30.0.0/16"
    
    # 服务端口范围 (NodePort Range)
    export NODE_PORT_RANGE="1024-32700"
    
    # kubernetes 服务 IP (一般是 SERVICE_CIDR 中第一个IP)
    export CLUSTER_KUBERNETES_SVC_IP="10.254.0.1"
    
    # 集群 DNS 服务 IP (从 SERVICE_CIDR 中预分配)
    export CLUSTER_DNS_SVC_IP="10.254.0.2"
    
    # 集群 DNS 域名(末尾不带点号)
    export CLUSTER_DNS_DOMAIN="cluster.local"
    
    # etcd
    export ETCD_VERSION=v3.3.17
    export ETCD_DATA_DIR=/var/lib/etcd/data
    export ETCD_WAL_DIR=/var/lib/etcd/wal
    export ETCD_SVC=$( xargs -n1<<<${MasterArray[@]} | sort | sed 's#^#https://#;s#$#:2379#;$s#
    ##' | paste -d, -s - )
    export ETCD_INITIAL_CLUSTER=$( for i in ${!MasterArray[@]};do echo $i=https://${MasterArray[$i]}:2380; done | sort | paste -d, -s - )
    
    # docker registry
    export DOCKER_REGISTRY_PORT=8888
    export DOCKER_REGISTRY="registry.k8s.com:${DOCKER_REGISTRY_PORT}"
    
    # yum repo
    export YUM_REPO_PORT=88
    export YUM_REPO="http://${Master1}:${YUM_REPO_PORT}"
    
    • 加载集群变量
    source /etc/kubernetes/template/k8s-Binary_deployment_1.14.8/k8s_env
    
    • 配置本地repo
    cd /etc/yum.repos.d/
    mkdir bak
    mv *repo bak
    cp ${TEMP_DIR}/cfg/k8s.repo .
    sed -i "s@##YUM_REPO##@file://${TEMP_DIR}/k8s-centos76-repo@g" k8s.repo
    

    3.1 配置节点互信

    yum install -y sshpass
    
    #分发公钥
    ssh-keygen -t rsa -P "" -f /root/.ssh/id_rsa
    for NODE in ${!AllNode[@]};do
        echo "--- $NODE ${AllNode[$NODE]} ---" 
        sshpass -p ${HOST_PWD} ssh-copy-id -i /root/.ssh/id_rsa.pub -o StrictHostKeyChecking=no root@${AllNode[$NODE]}
        ssh root@${AllNode[$NODE]} "hostname"
    done 
    

    3.2 所有节点设置永久主机名

    for NODE in "${!AllNode[@]}"; do
        echo "--- $NODE ${AllNode[$NODE]} ---"
        ssh ${AllNode[$NODE]} "hostnamectl set-hostname ${NODE}"
    done
    

    3.3 添加所有节点信息到hosts文件

    echo "### k8s cluster ###" >> /etc/hosts
    for NODE in ${!AllNode[@]};do echo ${AllNode[$NODE]} ${NODE} ; done | sort | paste -d -s - >> /etc/hosts
    
    • 分发hosts文件
    for NODE in "${!Other[@]}"; do
        echo "--- $NODE ${Other[$NODE]} ---"
        scp /etc/hosts ${Other[$NODE]}:/etc/hosts
    done
    

    3.4 关闭 firewalld 防火墙 以及 swap 分区

    for NODE in "${!AllNode[@]}"; do
        echo "--- $NODE ${AllNode[$NODE]} ---"
        ssh ${AllNode[$NODE]} " systemctl disable --now firewalld NetworkManager "
        ssh ${AllNode[$NODE]} " sed -ri 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config "
        ssh ${AllNode[$NODE]} " sed -ri '/^[^#]*swap/s@^@#@' /etc/fstab "
    done
    

    3.5 部署集群内网yum仓库

    • 安装 nginx
    yum -y install nginx createrepo
    
    • 修改配置文件
    cd ${TEMP_DIR}/cfg
    sed -i "s@##YUM_REPO_PORT##@${YUM_REPO_PORT}@g"  ${TEMP_DIR}/cfg/k8srepo.conf
    sed -i "s@##TEMP_DIR##@${TEMP_DIR}@g"  ${TEMP_DIR}/cfg/k8srepo.conf
    cp ${TEMP_DIR}/cfg/k8srepo.conf /etc/nginx/conf.d/
    
    • 启动 nginx
    nginx
    
    • 分发 yum repo文件

    • 生成repo索引

    createrepo ${TEMP_DIR}/k8s-centos76-repo/
    
    • 配置 yum repo
    cd ${TEMP_DIR}/cfg
    sed -i "s@##YUM_REPO##@${YUM_REPO}@g"  ${TEMP_DIR}/cfg/k8s.repo
    
    • 分发 yum repo
    for NODE in "${!AllNode[@]}"; do
        echo "--- $NODE ${AllNode[$NODE]} ---"
        ssh ${AllNode[$NODE]} "mkdir -p /etc/yum.repos.d/bak && mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/bak/"
        scp ${TEMP_DIR}/cfg/k8s.repo ${AllNode[$NODE]}:/etc/yum.repos.d/
        ssh ${AllNode[$NODE]} "yum makecache"
    done
    
    • 所有节点安装命令
    for NODE in "${!AllNode[@]}"; do
        echo "--- $NODE ${AllNode[$NODE]} ---"
        ssh ${AllNode[$NODE]} " yum -y install vim tree wget lrzsz net-tools expect unzip yum-utils device-mapper-persistent-data lvm2  conntrack ipvsadm ipset jq iptables curl sysstat libseccomp bash-completion socat ntp ntpdate  docker-distribution  docker-ce-18.09.9-3.el7 perl "
    done
    

    3.6 配置ipvs内核模块

    • 加载集群变量
    source /etc/kubernetes/template/k8s-Binary_deployment_1.14.8/k8s_env
    
    • 所有机器选择需要开机加载的内核模块,以下是 ipvs 模式需要加载的模块并设置开机自动加载
    for NODE in "${!AllNode[@]}"; do
        echo "--- $NODE ${AllNode[$NODE]} ---"
        ssh ${AllNode[$NODE]} " yum install ipvsadm ipset sysstat conntrack libseccomp -y " 
        scp ${TEMP_DIR}/cfg/ipvs.conf ${AllNode[$NODE]}:/etc/modules-load.d/ipvs.conf
        ssh ${AllNode[$NODE]} " systemctl enable --now systemd-modules-load.service "
        ssh ${AllNode[$NODE]} " systemctl status systemd-modules-load.service | grep active "
    done
    
    # 上面如果systemctl enable命令报错可以systemctl status -l systemd-modules-load.service看看哪个内核模块加载不了,在/etc/modules-load.d/ipvs.conf里注释掉它再enable试试
    

    3.7 配置系统参数

    • 所有机器需要设定/etc/sysctl.d/k8ssysctl.conf的系统参数。
    for NODE in "${!AllNode[@]}"; do
        echo "--- $NODE ${AllNode[$NODE]} ---"
        scp ${TEMP_DIR}/cfg/k8ssysctl.conf ${AllNode[$NODE]}:/etc/sysctl.d/k8ssysctl.conf
        ssh ${AllNode[$NODE]} " sysctl --system "
    done
    

    3.8 安装docker-ce

    • 检查系统内核和模块是否适合运行 docker (仅适用于 linux 系统)
    bash ${TEMP_DIR}/bin/check-config.sh
    
    • 安装 docker-ce
    for NODE in "${!AllNode[@]}"; do
        echo "--- $NODE ${AllNode[$NODE]} ---"
        ssh ${AllNode[$NODE]} " mkdir -p /etc/docker/  && yum -y install yum-utils device-mapper-persistent-data lvm2 docker-ce-18.09.9-3.el7 "
    done
    
    • 配置 daemon.json
    sed -i "s@##DOCKER_REGISTRY##@${DOCKER_REGISTRY}@g"  ${TEMP_DIR}/cfg/daemon.json
    
    
    • 设置docker开机启动,CentOS安装完成后docker需要手动设置docker命令补全
    for NODE in "${!AllNode[@]}"; do
        echo "--- $NODE ${AllNode[$NODE]} ---"
        ssh ${AllNode[$NODE]} " yum install -y bash-completion && cp /usr/share/bash-completion/completions/docker /etc/bash_completion.d/ "
        scp ${TEMP_DIR}/cfg/daemon.json ${AllNode[$NODE]}:/etc/docker/daemon.json
        ssh ${AllNode[$NODE]} " systemctl enable --now docker "
        ssh ${AllNode[$NODE]} " systemctl status docker | grep active "
    done
    

    3.9 部署集群内网docker镜像仓库

    • 参考:docker 镜像搭建 文档
    yum -y install docker-distribution
    systemctl enable --now docker-distribution
    systemctl status docker-distribution
    
    • 配置TLS
      • 为了启用TLS协议传输,需要生成自签名证书。命令如下:
    mkdir ${TEMP_DIR}/crts/ && cd ${TEMP_DIR}/crts
    openssl req 
      -newkey rsa:2048 -nodes -keyout k8s.com.key 
      -x509 -days 3650 -out k8s.com.crt -subj 
      "/C=CN/ST=GD/L=SZ/O=Global Security/OU=IT Department/CN=*.k8s.com"
    
    • 编辑镜像仓库服务配置文件/etc/docker-distribution/registry/config.yml。
    cat > /etc/docker-distribution/registry/config.yml << EOF
    version: 0.1
    log:
      fields:
        service: registry
    storage:
        cache:
            layerinfo: inmemory
        filesystem:
            rootdirectory: /var/lib/registry
    http:
       addr: :${DOCKER_REGISTRY_PORT}
       tls:
           certificate: ${TEMP_DIR}/crts/k8s.com.crt
           key: ${TEMP_DIR}/crts/k8s.com.key
    EOF
    
    • 修改完毕后,刷新systemd配置。命令如下:
    systemctl daemon-reload
    
    • 重启Docker Distribution服务。命令如下:
    systemctl restart docker-distribution
    
    • 分发配置自签名证书
    for NODE in "${!AllNode[@]}"; do
        echo "--- $NODE ${AllNode[$NODE]} ---"
        scp ${TEMP_DIR}/crts/k8s.com.crt ${AllNode[$NODE]}:/etc/pki/ca-trust/source/anchors/
        ssh ${AllNode[$NODE]} " update-ca-trust extract "
    done
    
    • 重启docker
    for NODE in "${!AllNode[@]}"; do
        echo "--- $NODE ${AllNode[$NODE]} ---"
        ssh ${AllNode[$NODE]} " systemctl restart docker "
    done
    
    • 添加hosts解析
    for NODE in "${!AllNode[@]}"; do
        echo "--- $NODE ${AllNode[$NODE]} ---"
        ssh ${AllNode[$NODE]} "echo "$(hostname -i) $(echo ${DOCKER_REGISTRY}| awk -F '[:]' '{print $1}')" >> /etc/hosts"
    done
    
    • 导入镜像
    cd ${TEMP_DIR}/images/
    for i in `ls`;do docker load -i $i ;done
    
    • 打tag
    docker images | awk '{print "docker tag "$1":"$2" ""'"${DOCKER_REGISTRY}"'""/"$1":"$2}' | xargs -i bash -c "{}"
    docker images | awk '{print "docker push ""'"${DOCKER_REGISTRY}"'""/"$1":"$2}' | xargs -i bash -c "{}"
    

    3.10 重启更新加载

    # 重启其他所有节点
    for NODE in "${!Other[@]}"; do
        echo "--- $NODE ${Other[$NODE]} ---"
        ssh ${Other[$NODE]} " reboot "
    done
    # 重启当前master节点
    reboot
    

    4,部署 ETCD

    • 加载集群变量
    source /etc/kubernetes/template/k8s-Binary_deployment_1.14.8/k8s_env
    
    • 安装证书工具
    cp ${TEMP_DIR}/bin/cfssl ${TEMP_DIR}/bin/cfssljson ${TEMP_DIR}/bin/cfssl-certinfo /usr/local/bin/
    
    • 生成 CA 证书
    cd ${TEMP_DIR}/pki/
    cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
    

    4.1 生成 etcd 证书

    • 创建 Etcd 服务器 CA 证书签名请求 etcd-csr.json
    cd ${TEMP_DIR}/pki/
    sed -i '/"hosts":/r '<(xargs -n1<<<${MasterArray[@]} | sort | sed 's#^w.*+#    "&",#')  etcd-csr.json
    
    • 生成证书
    cd ${TEMP_DIR}/pki/
    cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes etcd-csr.json | cfssljson -bare etcd
    # ls *.pem
    ca-key.pem  ca.pem  etcd-key.pem  etcd.pem
    

    4.2 创建分发etcd 配置文件证书

    sed -i "s@##PROJECT_DIR##@${PROJECT_DIR}@g" ${TEMP_DIR}/systemd/etcd.service 
    sed -i "s@##ETCD_DATA_DIR##@${ETCD_DATA_DIR}@g" ${TEMP_DIR}/cfg/etcd
    sed -i "s@##ETCD_WAL_DIR##@${ETCD_WAL_DIR}@g" ${TEMP_DIR}/cfg/etcd
    sed -i "s@##ETCD_INITIAL_CLUSTER##@${ETCD_INITIAL_CLUSTER}@g" ${TEMP_DIR}/cfg/etcd
    
    for NODE in "${!MasterArray[@]}"; do
        echo "--- $NODE ${MasterArray[$NODE]} ---"
        ssh ${MasterArray[$NODE]} "mkdir -p ${PROJECT_DIR}/{pki,etcd} ${ETCD_DATA_DIR} ${ETCD_WAL_DIR}"
        scp ${TEMP_DIR}/bin/{etcd,etcdctl}  ${MasterArray[$NODE]}:/usr/local/bin/
        scp ${TEMP_DIR}/pki/*.pem ${MasterArray[$NODE]}:${PROJECT_DIR}/pki/
        scp ${TEMP_DIR}/systemd/etcd.service ${MasterArray[$NODE]}:/usr/lib/systemd/system/etcd.service
        scp ${TEMP_DIR}/cfg/etcd ${MasterArray[$NODE]}:${PROJECT_DIR}/etcd/etcd
        ssh ${MasterArray[$NODE]} "sed -i "s@##ETCD_NAME##@${NODE}@g"  ${PROJECT_DIR}/etcd/etcd"
        ssh ${MasterArray[$NODE]} "sed -i "s@##PUBLIC_IP##@${MasterArray[$NODE]}@g"  ${PROJECT_DIR}/etcd/etcd"
        ssh ${MasterArray[$NODE]} 'systemctl daemon-reload'
    done
    

    4.3 启动 etcd

    for NODE in "${!MasterArray[@]}"; do
        echo "--- $NODE ${MasterArray[$NODE]} ---"
        ssh ${MasterArray[$NODE]} 'systemctl enable --now etcd' &
    done
    wait
    

    4.4 验证etcd

    • 加载集群变量
    source /etc/kubernetes/template/k8s-Binary_deployment_1.14.8/k8s_env
    
    # 验证命令
    etcdctl 
    --ca-file=${PROJECT_DIR}/pki/ca.pem 
    --cert-file=${PROJECT_DIR}/pki/etcd.pem 
    --key-file=${PROJECT_DIR}/pki/etcd-key.pem 
    --endpoints="${ETCD_SVC}" 
    cluster-health
    
    # 查看 etcd 主节点
    ETCDCTL_API=3 
        etcdctl   
       --cert ${PROJECT_DIR}/pki/etcd.pem  
       --key ${PROJECT_DIR}/pki/etcd-key.pem 
       --cacert ${PROJECT_DIR}/pki/ca.pem 
        --endpoints ${ETCD_SVC} endpoint status
    
    # 查看 etcd key
    ETCDCTL_API=3 
        etcdctl   
       --cert ${PROJECT_DIR}/pki/etcd.pem  
       --key ${PROJECT_DIR}/pki/etcd-key.pem 
       --cacert ${PROJECT_DIR}/pki/ca.pem 
        --endpoints ${ETCD_SVC} get / --prefix --keys-only
    

    5,部署 master 节点

    5.1 Haproxy+keepalived配置k8s master高可用

    • keepalived 提供 kube-apiserver 对外服务的 VIP;
    • haproxy 监听 VIP,后端连接所有 kube-apiserver 实例,提供健康检查和负载均衡功能;
    • 运行 keepalived 和 haproxy 的节点称为 LB 节点。由于 keepalived 是一主多备运行模式,故至少两个 LB 节点。
    • 本文档复用 master 节点的三台机器,haproxy 监听的端口(8443) 需要与 kube-apiserver 的端口 6443 不同,避免冲突。
    • keepalived 在运行过程中周期检查本机的 haproxy 进程状态,如果检测到 haproxy 进程异常,则触发重新选主的过程,VIP 将飘移到新选出来的主节点,从而实现 VIP 的高可用。
    • 所有组件(如 kubeclt、apiserver、controller-manager、scheduler 等)都通过 VIP 和 haproxy 监听的 8443 端口访问 kube-apiserver 服务。

    5.1.1 配置 haproxy分发配置文件

    • 注入master信息
    sed -i '$r '<(paste <( seq -f'    server k8s-m%g' ${#MasterArray[@]} ) <( xargs -n1<<<${MasterArray[@]} | sort | sed 's#$#:6443 check inter 2000 fall 2 rise 2 weight 1#')) ${TEMP_DIR}/cfg/haproxy.cfg
    
    • 分发配置文件
    for NODE in "${!MasterArray[@]}"; do
        echo "--- $NODE ${MasterArray[$NODE]} ---"
        ssh ${MasterArray[$NODE]} "yum install -y keepalived haproxy"
        scp ${TEMP_DIR}/cfg/haproxy.cfg ${MasterArray[$NODE]}:/etc/haproxy/haproxy.cfg
    done
    

    5.1.2 配置 keepalived分发配置文件

    • 修改配置文件
    sed -i "s@##VIP##@${VIP}@g"  ${TEMP_DIR}/cfg/keepalived.conf 
    sed -i "s@##eth0##@${IFACE}@g"  ${TEMP_DIR}/cfg/keepalived.conf
    cp ${TEMP_DIR}/cfg/keepalived.conf  /etc/keepalived/keepalived.conf
    sed -i "s@##120##@120@g"  /etc/keepalived/keepalived.conf
    
    • 分发配置文件
    Num=120
    for NODE in "${!otherMaster[@]}"; do
        echo "--- $NODE ${otherMaster[$NODE]} ---"
        scp ${TEMP_DIR}/cfg/keepalived.conf ${otherMaster[$NODE]}:/etc/keepalived/keepalived.conf  
        ssh ${otherMaster[$NODE]} "sed -i "s@MASTER@BACKUP@g" /etc/keepalived/keepalived.conf"
        for (( i=0; i<${#otherMaster[@]};i++));do
        ssh ${otherMaster[$NODE]} "sed -i "s@##120##@$(($Num-10))@g" /etc/keepalived/keepalived.conf"
        Num=$(($Num-10))
        done
    done
    

    5.1.3 启动haproxy和keepalived服务

    for NODE in "${!MasterArray[@]}"; do
        echo "--- $NODE ${MasterArray[$NODE]} ---"
        ssh ${MasterArray[$NODE]} 'systemctl enable --now haproxy' &
        ssh ${MasterArray[$NODE]} 'systemctl enable --now keepalived' &
    done
    wait
    

    5.1.4 查看服务状态以及VIP情况

    for NODE in "${!MasterArray[@]}"; do
        echo "--- $NODE ${MasterArray[$NODE]} ---"
        ssh ${MasterArray[$NODE]} 'systemctl status haproxy|grep Active'
        ssh ${MasterArray[$NODE]} 'systemctl status keepalived|grep Active' 
        ssh ${MasterArray[$NODE]} "ip addr show | grep ${VIP}"
    done
    

    5.2 部署 kubectl 命令工具

    • kubectl 是 kubernetes 集群的命令行管理工具,本文档介绍安装和配置它的步骤。
    • kubectl 默认从 ~/.kube/config 文件读取 kube-apiserver 地址、证书、用户名等信息,如果没有配置,执行 kubectl 命令时可能会出错。

    5.2.1 分发 MASTER 命令文件

    for NODE in "${!MasterArray[@]}"; do
        echo "--- $NODE ${MasterArray[$NODE]} ---"
        scp ${TEMP_DIR}/bin/kube{-apiserver,-scheduler,-controller-manager,ctl,adm}  ${MasterArray[$NODE]}:/usr/local/bin/
    done
    

    5.2.2 创建请求证书

    cd ${TEMP_DIR}/pki/
    cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin
    
    • 分发证书
    for NODE in "${!MasterArray[@]}"; do
        echo "--- $NODE ${MasterArray[$NODE]} ---"
        scp ${TEMP_DIR}/pki/admin*.pem  ${MasterArray[$NODE]}:${PROJECT_DIR}/pki/
    done
    

    5.2.3 创建 ~/.kube/config 文件

    cd ${TEMP_DIR}/cfg/
    kubectl config set-cluster kubernetes 
      --certificate-authority=${PROJECT_DIR}/pki/ca.pem 
      --embed-certs=true 
      --server=${KUBE_APISERVER} 
      --kubeconfig=kubectl.kubeconfig
    
    # 设置客户端认证参数
    kubectl config set-credentials admin 
      --client-certificate=${PROJECT_DIR}/pki/admin.pem 
      --client-key=${PROJECT_DIR}/pki/admin-key.pem 
      --embed-certs=true 
      --kubeconfig=kubectl.kubeconfig
    
    # 设置上下文参数
    kubectl config set-context kubernetes 
      --cluster=kubernetes 
      --user=admin 
      --kubeconfig=kubectl.kubeconfig
      
    # 设置默认上下文
    kubectl config use-context kubernetes --kubeconfig=kubectl.kubeconfig
    
    • 分发 kubeconfig
    for NODE in "${!MasterArray[@]}"; do
        echo "--- $NODE ${MasterArray[$NODE]} ---"
        ssh ${MasterArray[$NODE]} " mkdir -p ~/.kube/ "
        scp ${TEMP_DIR}/cfg/kubectl.kubeconfig  ${MasterArray[$NODE]}:~/.kube/config
        ssh ${MasterArray[$NODE]} "kubectl completion bash > /etc/bash_completion.d/kubectl"
    done
    

    5.3 部署 apiserver 组件

    5.3.1 配置 apiserver 证书

    • apiserver-csr.json
    cd ${TEMP_DIR}/pki/
    sed -i '/"hosts":/r '<(echo ${CLUSTER_KUBERNETES_SVC_IP} | sed 's#^w.*+#      "&",#') apiserver-csr.json
    sed -i '/"hosts":/r '<(xargs -n1<<<${MasterArray[@]} | sort | sed 's#^w.*+#      "&",#') apiserver-csr.json
    sed -i '/"hosts":/r '<(echo ${VIP}| sed 's#^w.*+#      "&",#') apiserver-csr.json
    
    • 生成 apiserver 证书和私钥
    cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes apiserver-csr.json | cfssljson -bare apiserver
    
    • 生成 front-proxy 证书和私钥
    cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes front-proxy-csr.json | cfssljson -bare front-proxy
    

    5.3.2 创建加密配置文件

    cat > ${TEMP_DIR}/cfg/encryption-config.yaml <<EOF
    kind: EncryptionConfig
    apiVersion: v1
    resources:
      - resources:
          - secrets
        providers:
          - aescbc:
              keys:
                - name: key1
                  secret: $(head -c 32 /dev/urandom | base64)
          - identity: {}
    EOF
    

    5.3.3 kube-apiserver 配置文件

    sed -i "s@##PROJECT_DIR##@${PROJECT_DIR}@g" ${TEMP_DIR}/cfg/kube-apiserver 
    sed -i "s@##SERVICE_CIDR##@${SERVICE_CIDR}@g" ${TEMP_DIR}/cfg/kube-apiserver 
    sed -i "s@##NODE_PORT_RANGE##@${NODE_PORT_RANGE}@g" ${TEMP_DIR}/cfg/kube-apiserver 
    sed -i "s@##ETCD_SVC##@${ETCD_SVC}@g" ${TEMP_DIR}/cfg/kube-apiserver 
    sed -i "s@##LOG_DIR##@${LOG_DIR}@g" ${TEMP_DIR}/cfg/kube-apiserver
    sed -i "s@##PROJECT_DIR##@${PROJECT_DIR}@g" ${TEMP_DIR}/systemd/kube-apiserver.service
    

    5.3.4 分发配置文件

    for NODE in "${!MasterArray[@]}"; do
        echo "--- $NODE ${MasterArray[$NODE]} ---"
        ssh ${MasterArray[$NODE]} "mkdir -p ${PROJECT_DIR}/server/ ${LOG_DIR}"
        scp ${TEMP_DIR}/pki/apiserver*.pem ${MasterArray[$NODE]}:${PROJECT_DIR}/pki/
        scp ${TEMP_DIR}/pki/front-proxy*.pem ${MasterArray[$NODE]}:${PROJECT_DIR}/pki/
        scp ${TEMP_DIR}/cfg/encryption-config.yaml   ${MasterArray[$NODE]}:${PROJECT_DIR}/server/
        scp ${TEMP_DIR}/cfg/kube-apiserver   ${MasterArray[$NODE]}:${PROJECT_DIR}/server/
        scp ${TEMP_DIR}/cfg/kubectl.kubeconfig   ${MasterArray[$NODE]}:${PROJECT_DIR}/server/
        scp ${TEMP_DIR}/systemd/kube-apiserver.service ${MasterArray[$NODE]}:/usr/lib/systemd/system/kube-apiserver.service
        ssh ${MasterArray[$NODE]} "sed -i "s@##PUBLIC_IP##@${MasterArray[$NODE]}@g"  ${PROJECT_DIR}/server/kube-apiserver"
        ssh ${MasterArray[$NODE]} 'systemctl daemon-reload'
    done
    

    5.3.5 启动 api-server

    for NODE in "${!MasterArray[@]}"; do
        echo "--- $NODE ${MasterArray[$NODE]} ---"
        ssh ${MasterArray[$NODE]} 'systemctl enable --now kube-apiserver' &
    done
    wait
    

    5.3.6 检查kube-apiserve服务

    for NODE in "${!MasterArray[@]}"; do
        echo "--- $NODE ${MasterArray[$NODE]} ---"
        ssh ${MasterArray[$NODE]} 'netstat -ptln | grep kube-apiserve' 
    done
    
    • 集群状态
    kubectl cluster-info
    

    5.3.7 授予kubernetes证书访问kubelet api权限

    kubectl create clusterrolebinding kube-apiserver:kubelet-apis --clusterrole=system:kubelet-api-admin --user kubernetes
    

    5.4 部署 controllers-manager 组件

    • 该集群包含 3 个节点,启动后将通过竞争选举机制产生一个 leader 节点,其它节点为阻塞状态。当 leader 节点不可用后,剩余节点将再次进行选举产生新的 leader 节点,从而保证服务的可用性。

      为保证通信安全,本文档先生成 x509 证书和私钥,kube-controller-manager 在如下两种情况下使用该证书:

      • 与 kube-apiserver 的安全端口通信时;
      • 在安全端口(https,10252) 输出 prometheus 格式的 metrics;

    5.4.1 创建kube-controller-manager证书请求

    cd ${TEMP_DIR}/pki/
    sed -i '/"hosts":/r '<(xargs -n1<<<${MasterArray[@]} | sort | sed 's#^w.*+#      "&",#') kube-controller-manager-csr.json
    
    • 生成证书和私钥
    cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-controller-manager-csr.json | cfssljson -bare kube-controller-manager
    
    • 分发证书
    for NODE in "${!MasterArray[@]}"; do
        echo "--- $NODE ${MasterArray[$NODE]} ---"
        ssh ${MasterArray[$NODE]} "mkdir -p ${PROJECT_DIR}/server/ ${LOG_DIR}"
        scp ${TEMP_DIR}/pki/kube-controller-manager*.pem ${MasterArray[$NODE]}:${PROJECT_DIR}/pki/
    done
    

    5.4.2 创建 kube-controller-manager.kubeconfig 文件

    cd ${TEMP_DIR}/cfg/
    kubectl config set-cluster kubernetes 
      --certificate-authority=${PROJECT_DIR}/pki/ca.pem 
      --embed-certs=true 
      --server=${KUBE_APISERVER} 
      --kubeconfig=kube-controller-manager.kubeconfig
    
    kubectl config set-credentials system:kube-controller-manager 
      --client-certificate=${PROJECT_DIR}/pki/kube-controller-manager.pem 
      --client-key=${PROJECT_DIR}/pki/kube-controller-manager-key.pem 
      --embed-certs=true 
      --kubeconfig=kube-controller-manager.kubeconfig
    
    kubectl config set-context system:kube-controller-manager 
      --cluster=kubernetes 
      --user=system:kube-controller-manager 
      --kubeconfig=kube-controller-manager.kubeconfig
    
    kubectl config use-context system:kube-controller-manager --kubeconfig=kube-controller-manager.kubeconfig
    

    5.4.3 controller-manager 配置文件

    sed -i "s@##PROJECT_DIR##@${PROJECT_DIR}@g" ${TEMP_DIR}/cfg/kube-controller-manager
    sed -i "s@##SERVICE_CIDR##@${SERVICE_CIDR}@g" ${TEMP_DIR}/cfg/kube-controller-manager
    sed -i "s@##LOG_DIR##@${LOG_DIR}@g" ${TEMP_DIR}/cfg/kube-controller-manager
    sed -i "s@##PROJECT_DIR##@${PROJECT_DIR}@g" ${TEMP_DIR}/systemd/kube-controller-manager.service
    

    5.4.4 分发配置文件

    for NODE in "${!MasterArray[@]}"; do
        echo "--- $NODE ${MasterArray[$NODE]} ---"
        ssh ${MasterArray[$NODE]} "mkdir -p ${PROJECT_DIR}/server/ ${LOG_DIR}"
        scp ${TEMP_DIR}/cfg/kube-controller-manager.kubeconfig   ${MasterArray[$NODE]}:${PROJECT_DIR}/server/
        scp ${TEMP_DIR}/cfg/kube-controller-manager   ${MasterArray[$NODE]}:${PROJECT_DIR}/server/
        scp ${TEMP_DIR}/systemd/kube-controller-manager.service ${MasterArray[$NODE]}:/usr/lib/systemd/system/kube-controller-manager.service
        ssh ${MasterArray[$NODE]} 'systemctl daemon-reload'
    done
    

    5.4.5 启动kube-controller-manager服务

    for NODE in "${!MasterArray[@]}"; do
        echo "--- $NODE ${MasterArray[$NODE]} ---"
        ssh ${MasterArray[$NODE]} 'systemctl enable --now kube-controller-manager.service' &
    done
    wait
    

    5.4.6 检查kube-controller-manage服务

    for NODE in "${!MasterArray[@]}"; do
        echo "--- $NODE ${MasterArray[$NODE]} ---"
        ssh ${MasterArray[$NODE]} 'netstat -ptln | grep kube-controll' 
    done
    
    • 查看当前kube-controller-manager的leader

    kubectl get endpoints kube-controller-manager --namespace=kube-system  -o yaml
    

    5.5 部署kube-scheduler组件

    • 该集群包含 3 个节点,启动后将通过竞争选举机制产生一个 leader 节点,其它节点为阻塞状态。当 leader 节点不可用后,剩余节点将再次进行选举产生新的 leader 节点,从而保证服务的可用性。
    • 为保证通信安全,本文档先生成 x509 证书和私钥,kube-scheduler 在如下两种情况下使用该证书:
      • 与 kube-apiserver 的安全端口通信;
      • 在安全端口(https,10251) 输出 prometheus 格式的 metrics;

    5.5.1 创建kube-scheduler证书请求

    cd ${TEMP_DIR}/pki/
    sed -i '/"hosts":/r '<(xargs -n1<<<${MasterArray[@]} | sort | sed 's#^w.*+#      "&",#') kube-scheduler-csr.json
    
    • 生成证书和私钥
    cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes  kube-scheduler-csr.json | cfssljson -bare  kube-scheduler
    
    • 分发证书
    for NODE in "${!MasterArray[@]}"; do
        echo "--- $NODE ${MasterArray[$NODE]} ---"
        ssh ${MasterArray[$NODE]} "mkdir -p ${PROJECT_DIR}/server/ ${LOG_DIR}"
        scp ${TEMP_DIR}/pki/kube-scheduler*.pem ${MasterArray[$NODE]}:${PROJECT_DIR}/pki/
    done
    

    5.5.2 创建 kube-scheduler.kubeconfig 文件

    cd ${TEMP_DIR}/cfg/
    kubectl config set-cluster kubernetes 
      --certificate-authority=${PROJECT_DIR}/pki/ca.pem 
      --embed-certs=true 
      --server=${KUBE_APISERVER} 
      --kubeconfig=kube-scheduler.kubeconfig
    
    kubectl config set-credentials system:kube-scheduler 
      --client-certificate=${PROJECT_DIR}/pki/kube-scheduler.pem 
      --client-key=${PROJECT_DIR}/pki/kube-scheduler-key.pem 
      --embed-certs=true 
      --kubeconfig=kube-scheduler.kubeconfig
    
    kubectl config set-context system:kube-scheduler 
      --cluster=kubernetes 
      --user=system:kube-scheduler 
      --kubeconfig=kube-scheduler.kubeconfig
    
    kubectl config use-context system:kube-scheduler --kubeconfig=kube-scheduler.kubeconfig
    

    5.5.3 kube-scheduler 配置文件

    sed -i "s@##PROJECT_DIR##@${PROJECT_DIR}@g" ${TEMP_DIR}/cfg/kube-scheduler
    sed -i "s@##LOG_DIR##@${LOG_DIR}@g" ${TEMP_DIR}/cfg/kube-scheduler
    sed -i "s@##PROJECT_DIR##@${PROJECT_DIR}@g" ${TEMP_DIR}/systemd/kube-scheduler.service
    

    5.5.4 分发证书与配置文件

    for NODE in "${!MasterArray[@]}"; do
        echo "--- $NODE ${MasterArray[$NODE]} ---"
        ssh ${MasterArray[$NODE]} "mkdir -p ${PROJECT_DIR}/server/ ${LOG_DIR}"
        scp ${TEMP_DIR}/cfg/kube-scheduler   ${MasterArray[$NODE]}:${PROJECT_DIR}/server/
        scp ${TEMP_DIR}/cfg/kube-scheduler.kubeconfig   ${MasterArray[$NODE]}:${PROJECT_DIR}/server/
        scp ${TEMP_DIR}/systemd/kube-scheduler.service ${MasterArray[$NODE]}:/usr/lib/systemd/system/kube-scheduler.service
        ssh ${MasterArray[$NODE]} 'systemctl daemon-reload'
    done
    

    5.5.5 启动kube-scheduler服务

    for NODE in "${!MasterArray[@]}"; do
        echo "--- $NODE ${MasterArray[$NODE]} ---"
        ssh ${MasterArray[$NODE]} 'systemctl enable --now kube-scheduler.service' &
    done
    wait
    

    5.5.6 检查kube-scheduler服务

    for NODE in "${!MasterArray[@]}"; do
        echo "--- $NODE ${MasterArray[$NODE]} ---"
        ssh ${MasterArray[$NODE]} 'netstat -ptln | grep kube-schedule' 
    done
    
    • 查看当前kube-scheduler的leader

    kubectl get endpoints kube-scheduler --namespace=kube-system  -o yaml
    

    5.6 在所有master节点上验证功能是否正常

    # kubectl get componentstatuses
    NAME                 STATUS      MESSAGE                                                                                                                       
    controller-manager   Healthy     ok
    scheduler            Healthy     ok
    etcd-2               Healthy     {"health":"true"}
    etcd-0               Healthy     {"health":"true"}
    etcd-1               Healthy     {"health":"true"}
    

    6, 部署 kubernetes node节点

    6.1 部署kubelet组件

    • kublet 运行在每个 worker 节点上,接收 kube-apiserver 发送的请求,管理 Pod 容器,执行交互式命令,如 exec、run、logs 等。
    • kublet 启动时自动向 kube-apiserver 注册节点信息,内置的 cadvisor 统计和监控节点的资源使用情况。
    • 为确保安全,本文档只开启接收 https 请求的安全端口,对请求进行认证和授权,拒绝未授权的访问(如 apiserver、heapster)。

    6.1.1 分发 kubelet 命令文件

    for NODE in "${!AllNode[@]}"; do
        echo "--- $NODE ${AllNode[$NODE]} ---"
        scp ${TEMP_DIR}/bin/kube{let,-proxy} ${AllNode[$NODE]}:/usr/local/bin/
        ssh ${AllNode[$NODE]} "yum install -y  wget conntrack ipvsadm ipset jq iptables curl sysstat libseccomp"
    done
    

    6.1.2 创建kubelet bootstrap kubeconfig文件 (k8s-master1上执行)

    #创建 token
    cd ${TEMP_DIR}/cfg/
    export BOOTSTRAP_TOKEN=$(kubeadm token create 
      --description kubelet-bootstrap-token 
      --groups system:bootstrappers:k8s-bootstrap 
      --kubeconfig ~/.kube/config)
    
    # 设置集群参数
    kubectl config set-cluster kubernetes 
      --certificate-authority=${PROJECT_DIR}/pki/ca.pem 
      --embed-certs=true 
      --server=${KUBE_APISERVER} 
      --kubeconfig=kubelet-bootstrap.kubeconfig
    
    # 设置客户端认证参数
    kubectl config set-credentials kubelet-bootstrap 
      --token=${BOOTSTRAP_TOKEN} 
      --kubeconfig=kubelet-bootstrap.kubeconfig
    
    # 设置上下文参数
    kubectl config set-context default 
      --cluster=kubernetes 
      --user=kubelet-bootstrap 
      --kubeconfig=kubelet-bootstrap.kubeconfig
    
    # 设置默认上下文
    kubectl config use-context default --kubeconfig=kubelet-bootstrap.kubeconfig
    
    • 证书中写入 Token 而非证书,证书后续由 controller-manager 创建。

    • 创建的 token 有效期为 1 天,超期后将不能再被使用,且会被 kube-controller-manager 的 tokencleaner 清理(如果启用该 controller 的话);

    • kube-apiserver 接收 kubelet 的 bootstrap token 后,将请求的 user 设置为 system:bootstrap:,group 设置为 system:bootstrappers;

    • 查看 kubeadm 为各节点创建的 token kubeadm token list --kubeconfig ~/.kube/config

    6.1.3 创建 kubelet 参数配置文件

    sed -i "s@##PROJECT_DIR##@${PROJECT_DIR}@g" ${TEMP_DIR}/cfg/kubelet-config.yaml
    sed -i "s@##CLUSTER_DNS_DOMAIN##@${CLUSTER_DNS_DOMAIN}@g" ${TEMP_DIR}/cfg/kubelet-config.yaml
    sed -i "s@##CLUSTER_DNS_SVC_IP##@${CLUSTER_DNS_SVC_IP}@g" ${TEMP_DIR}/cfg/kubelet-config.yaml
    sed -i "s@##CLUSTER_CIDR##@${CLUSTER_CIDR}@g" ${TEMP_DIR}/cfg/kubelet-config.yaml
    sed -i "s@##PROJECT_DIR##@${PROJECT_DIR}@g" ${TEMP_DIR}/systemd/kubelet.service
    sed -i "s@##WORK_DIR##@${WORK_DIR}@g" ${TEMP_DIR}/systemd/kubelet.service
    sed -i "s@##DOCKER_REGISTRY##@${DOCKER_REGISTRY}@g" ${TEMP_DIR}/systemd/kubelet.service
    

    6.1.4 分发配置文件与kubelet-bootstrap.kubeconfig

    for NODE in "${!AllNode[@]}"; do
        echo "--- $NODE ${AllNode[$NODE]} ---"
        ssh ${AllNode[$NODE]} "mkdir -p ${PROJECT_DIR}/{server,pki}/ ${WORK_DIR}/kubelet/logs "
        scp ${TEMP_DIR}/pki/ca.pem   ${AllNode[$NODE]}:${PROJECT_DIR}/pki/
        scp ${TEMP_DIR}/cfg/kubelet-bootstrap.kubeconfig   ${AllNode[$NODE]}:${PROJECT_DIR}/server/
        scp ${TEMP_DIR}/cfg/kubelet-config.yaml   ${AllNode[$NODE]}:${PROJECT_DIR}/server/
        scp ${TEMP_DIR}/systemd/kubelet.service ${AllNode[$NODE]}:/usr/lib/systemd/system/kubelet.service
        ssh ${AllNode[$NODE]} "sed -i "s@##PUBLIC_IP##@${AllNode[$NODE]}@g"  ${PROJECT_DIR}/server/kubelet-config.yaml"   
        ssh ${AllNode[$NODE]} "sed -i "s@##NODE_NAME##@${NODE}@g"  /usr/lib/systemd/system/kubelet.service"  
        ssh ${AllNode[$NODE]} 'systemctl daemon-reload'
    done
    

    6.1.5 创建user和group的CSR权限,不创建kubelet会启动失败

    kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --group=system:bootstrappers
    

    6.1.7 启动 kubelet 服务

    for NODE in "${!AllNode[@]}"; do
        echo "--- $NODE ${AllNode[$NODE]} ---"
        ssh ${AllNode[$NODE]} 'systemctl enable --now kubelet.service' &
    done
    wait
    
    • 检查服务端口
    for NODE in "${!AllNode[@]}"; do
        echo "--- $NODE ${AllNode[$NODE]} ---"
        ssh ${AllNode[$NODE]} 'systemctl status kubelet.service | grep active'
        ssh ${AllNode[$NODE]} 'netstat -lntup | grep  kubele'
    done
    
    • 10248: healthz http 服务;
    • 10250: https 服务,访问该端口时需要认证和授权(即使访问 /healthz 也需要);
    • 未开启只读端口 10255;
    • 从 K8S v1.10 开始,去除了 –cadvisor-port 参数(默认 4194 端口),不支持访问 cAdvisor UI & API
    • kubelet 启动后使用 –bootstrap-kubeconfig 向 kube-apiserver 发送 CSR 请求,当这个CSR 被 approve 后,kube-controller-manager 为 kubelet 创建 TLS 客户端证书、私钥和 –kubeletconfig 文件。 注意:kube-controller-manager 需要配置 –cluster-signing-cert-file 和 –cluster-signing-key-file 参数,才会为 TLS Bootstrap 创建证书和私钥。
    • 此时kubelet的进程存在,但是监听端口还未启动,需要进行下面步骤!

    6.1.8 自动approve CSR请求

    • 创建三个ClusterRoleBinding,分别用于自动approve client、renew client、renew server证书
    for NODE in "${!MasterArray[@]}"; do
        echo "--- $NODE ${MasterArray[$NODE]} ---"
        scp ${TEMP_DIR}/cfg/csr-crb.yaml   ${MasterArray[$NODE]}:${PROJECT_DIR}/server/
    done
    kubectl apply -f ${PROJECT_DIR}/server/csr-crb.yaml
    
    • auto-approve-csrs-for-group 自动approve node的第一次CSR,注意第一次CSR时,请求的Group为system:bootstrappers
    • node-client-cert-renewal 自动approve node后续过期的client证书,自动生成的证书Group为system:nodes
    • node-server-cert-renewal 自动approve node后续过期的server证书,自动生成的证书Group

    6.1.9 手动approve server cert csr

    • 基于安全考虑,CSR approving controllers不会自动approve kubelet server证书签名请求,需要手动approve
    kubectl get csr | grep Pending | awk '{print $1}' | xargs kubectl certificate approve
    

    6.1.10 bear token认证和授权

    • 创建一个ServiceAccount,将它和ClusterRole system:kubelet-api-admin绑定,从而具有调用kubelet API的权限
    kubectl create sa kubelet-api-test
    kubectl create clusterrolebinding kubelet-api-test --clusterrole=system:kubelet-api-admin --serviceaccount=default:kubelet-api-test
    SECRET=$(kubectl get secrets | grep kubelet-api-test | awk '{print $1}')
    TOKEN=$(kubectl describe secret ${SECRET} | grep -E '^token' | awk '{print $2}')
    echo ${TOKEN}
    

    6.1.11 查看kubelet状态

    for NODE in "${!AllNode[@]}"; do
        echo "--- $NODE ${AllNode[$NODE]} ---"
        ssh ${AllNode[$NODE]} 'netstat -ptln | grep kubelet' 
    done
    
    # 查看csr请求状态
    kubectl get csr
    
    # 查看节点信息
    kubectl get node
    

    6.2 部署 kube-proxy 组件

    • kube-proxy运行在所有worker节点上,它监听apiserver中service和endpoint的变化情况,创建路由规则提供服务IP和负载均衡功能。这里使用ipvs模式的kube-proxy进行部署
    • 在各个节点需要安装ipvsadm和ipset命令,加载ip_vs内核模块

    6.2.1 创建kube-proxy 证书

    • 生成证书
    cd ${TEMP_DIR}/pki/
    cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy
    
    • 分发证书
    for NODE in "${!AllNode[@]}"; do
        echo "--- $NODE ${AllNode[$NODE]} ---"
        ssh ${AllNode[$NODE]} "mkdir -p ${PROJECT_DIR}/{server,pki}/ ${LOG_DIR}"
        scp ${TEMP_DIR}/pki/kube-proxy*.pem ${AllNode[$NODE]}:${PROJECT_DIR}/pki/
    done
    

    6.2.2 创建和分发kubeconfig文件

    cd ${TEMP_DIR}/cfg/
    kubectl config set-cluster kubernetes 
      --certificate-authority=${PROJECT_DIR}/pki/ca.pem 
      --embed-certs=true 
      --server=${KUBE_APISERVER} 
      --kubeconfig=kube-proxy.kubeconfig
    
    kubectl config set-credentials kube-proxy 
      --client-certificate=${PROJECT_DIR}/pki/kube-proxy.pem 
      --client-key=${PROJECT_DIR}/pki/kube-proxy-key.pem 
      --embed-certs=true 
      --kubeconfig=kube-proxy.kubeconfig
    
    kubectl config set-context default 
      --cluster=kubernetes 
      --user=kube-proxy 
      --kubeconfig=kube-proxy.kubeconfig
    
    kubectl config use-context default --kubeconfig=kube-proxy.kubeconfig
    
    • -embed-certs=true:将 ca.pem 和 admin.pem 证书内容嵌入到生成的 kubectl-proxy.kubeconfig 文件中(不加时,写入的是证书文件路径)

    6.2.3 创建 kube-proxy systemd unit 文件

    sed -i "s@##PROJECT_DIR##@${PROJECT_DIR}@g" ${TEMP_DIR}/systemd/kube-proxy.service
    sed -i "s@##WORK_DIR##@${WORK_DIR}@g" ${TEMP_DIR}/systemd/kube-proxy.service
    sed -i "s@##CLUSTER_CIDR##@${CLUSTER_CIDR}@g" ${TEMP_DIR}/systemd/kube-proxy.service
    
    • bind-address: 监听地址;
    • clientConnection.kubeconfig: 连接 apiserver 的 kubeconfig 文件;
    • clusterCIDR: kube-proxy 根据 --cluster-cidr 判断集群内部和外部流量,指定 --cluster-cidr 或 --masquerade-all选项后 kube-proxy 才会对访问 Service IP 的请求做 SNAT;
    • hostname-override: 参数值必须与 kubelet 的值一致,否则 kube-proxy 启动后会找不到该 Node,从而不会创建任何 ipvs 规则;
    • proxy-mode: 使用 ipvs 模式;
    • 修改改对应主机的信息。其中clusterc idr为docker0网络地址。

    6.2.4 分发配置文件

    for NODE in "${!AllNode[@]}"; do
        echo "--- $NODE ${AllNode[$NODE]} ---"
        ssh ${AllNode[$NODE]} "mkdir -p ${PROJECT_DIR}/{server,pki}/ ${WORK_DIR}/kube-proxy/logs "
        scp ${TEMP_DIR}/cfg/kube-proxy.kubeconfig   ${AllNode[$NODE]}:${PROJECT_DIR}/server/
        scp ${TEMP_DIR}/systemd/kube-proxy.service ${AllNode[$NODE]}:/usr/lib/systemd/system/kube-proxy.service
        ssh ${AllNode[$NODE]} "sed -i "s@##PUBLIC_IP##@${AllNode[$NODE]}@g"  /usr/lib/systemd/system/kube-proxy.service"   
        ssh ${AllNode[$NODE]} "sed -i "s@##NODE_NAME##@${NODE}@g"  /usr/lib/systemd/system/kube-proxy.service"  
        ssh ${AllNode[$NODE]} 'systemctl daemon-reload'
    done
    

    6.2.5 启动kube-proxy服务

    for NODE in "${!AllNode[@]}"; do
        echo "--- $NODE ${AllNode[$NODE]} ---"
        ssh ${AllNode[$NODE]} 'systemctl enable --now kube-proxy.service' &
    done
    wait
    

    6.2.6 查看 kube-proxy 状态

    for NODE in "${!AllNode[@]}"; do
        echo "--- $NODE ${AllNode[$NODE]} ---"
        ssh ${AllNode[$NODE]} 'netstat -ptln | grep kube-proxy' 
    done
    

    7,其他组件安装部署

    7.1 calico安装

    7.1.1 配置文件

    cp -a ${TEMP_DIR}/calico ${PROJECT_DIR}/
    cd ${PROJECT_DIR}/calico/
    

    7.1.2 配置 calico 文件

    • etcd 地址
    sed -i "s#.*etcd_endpoints:.*#  etcd_endpoints: "${ETCD_SVC}"#g" calico.yaml
    sed -i "s#__ETCD_ENDPOINTS__#${ETCD_SVC}#g" calico.yaml
    
    • etcd 证书
    ETCD_CERT=`cat ${PROJECT_DIR}/pki/etcd.pem | base64 | tr -d '
    '`
    ETCD_KEY=`cat ${PROJECT_DIR}/pki/etcd-key.pem | base64 | tr -d '
    '`
    ETCD_CA=`cat ${PROJECT_DIR}/pki/ca.pem | base64 | tr -d '
    '`
    
    sed -i "s#.*etcd-cert:.*#  etcd-cert: ${ETCD_CERT}#g" calico.yaml
    sed -i "s#.*etcd-key:.*#  etcd-key: ${ETCD_KEY}#g" calico.yaml
    sed -i "s#.*etcd-ca:.*#  etcd-ca: ${ETCD_CA}#g" calico.yaml
    
    sed -i 's#.*etcd_ca:.*#  etcd_ca: "/calico-secrets/etcd-ca"#g' calico.yaml
    sed -i 's#.*etcd_cert:.*#  etcd_cert: "/calico-secrets/etcd-cert"#g' calico.yaml
    sed -i 's#.*etcd_key:.*#  etcd_key: "/calico-secrets/etcd-key"#g' calico.yaml
    
    sed -i "s#__ETCD_KEY_FILE__#${PROJECT_DIR}/pki/etcd-key.pem#g" calico.yaml
    sed -i "s#__ETCD_CERT_FILE__#${PROJECT_DIR}/pki/etcd.pem#g" calico.yaml
    sed -i "s#__ETCD_CA_CERT_FILE__#${PROJECT_DIR}/pki/ca.pem#g" calico.yaml
    sed -i "s#__KUBECONFIG_FILEPATH__#/etc/cni/net.d/calico-kubeconfig#g" calico.yaml
    
    • 配置calico bgp 并且修改ip cidr:
    sed -i "/CLUSTER_TYPE/{n;s@##IFACE##@${IFACE}@g}" calico.yaml
    sed -i '/CALICO_IPV4POOL_IPIP/{n;s/Always/off/g}' calico.yaml
    sed -i "/CALICO_IPV4POOL_CIDR/{n;s@192.168.0.0/16@${CLUSTER_CIDR}@g}" calico.yaml
    sed -i "s#image: calico#image: ${DOCKER_REGISTRY}/quay.io/calico#g" calico.yaml
    
    • 配置 caicoctl
    sed -i "s#image: quay.io#image: ${DOCKER_REGISTRY}/quay.io#g" calicoctl.yaml
    

    7.1.3 部署 calico

    kubectl apply -f ${PROJECT_DIR}/calico
    

    7.2,部署kubernetes DNS

    7.2.1 配置文件

    cp -a ${TEMP_DIR}/coredns ${PROJECT_DIR}/
    cd ${PROJECT_DIR}/coredns/
    

    7.2.2 修改配置文件

    sed -i "s#kubernetes __PILLAR__DNS__DOMAIN__#kubernetes ${CLUSTER_DNS_DOMAIN}#g" coredns.yaml
    sed -i "s#clusterIP: __PILLAR__DNS__SERVER__#clusterIP: ${CLUSTER_DNS_SVC_IP}#g" coredns.yaml
    sed -i "s#image: k8s.gcr.io#image: ${DOCKER_REGISTRY}/coredns#g" coredns.yaml
    

    7.2.3 部署coreDNS

    kubectl apply -f ${PROJECT_DIR}/coredns/
    

    7.2.4 验证 dns

    cat > ${PROJECT_DIR}/buxybox.yaml <<EOF
    apiVersion: v1
    kind: Pod
    metadata:
      name: busybox
      namespace: default
    spec:
      containers:
      - name: busybox
        image: ${DOCKER_REGISTRY}/busybox:1.28.3
        command:
          - sleep
          - "3600"
        imagePullPolicy: IfNotPresent
      restartPolicy: Always
    EOF
    
    • 使用 nslookup 查看
    # kubectl exec -ti busybox -- nslookup kubernetes
    Server:    10.254.0.2
    Address 1: 10.254.0.2 kube-dns.kube-system.svc.cluster.local
    
    Name:      kubernetes
    Address 1: 10.254.0.1 kubernetes.default.svc.cluster.local
    

    7.3 部署 metrics

    7.3.1 metrics 配置文件

    • 使用官方配置文件
    cp -a ${TEMP_DIR}/metrics-server ${PROJECT_DIR}/
    cd ${PROJECT_DIR}/metrics-server
    

    7.3.2 更改配置文件

    sed -i "s#image: k8s.gcr.io#image: ${DOCKER_REGISTRY}/registry.cn-hangzhou.aliyuncs.com/google_containers#g" metrics-server-deployment.yaml
    

    7.3.3 配置权限

    kubectl create clusterrolebinding cluster-front-proxy --clusterrole=cluster-admin --user=system:front-proxy
    

    7.3.3 部署 metrics

    kubectl apply -f ${PROJECT_DIR}/metrics-server
    

    7.4 部署 dashboard

    7.4.1 配置文件

    cp -a ${TEMP_DIR}/dashboard ${PROJECT_DIR}/
    cd ${PROJECT_DIR}/dashboard
    

    7.4.2 创建dashboard证书

    cd ${PROJECT_DIR}/pki/
    #生成证书
    dashboard_ip=$(echo "$VIP,${MasterArray[@]}" | tr " " ",")
    openssl genrsa -out dashboard.key 2048 
    openssl req -days 3650 -new -out dashboard.csr -key dashboard.key -subj "/CN=${dashboard_ip}"
    openssl x509 -req -in dashboard.csr -signkey dashboard.key -out dashboard.crt 
    #创建新的证书secret
    kubectl create secret generic kubernetes-dashboard-certs --from-file="${PROJECT_DIR}/pki/dashboard.key,${PROJECT_DIR}/pki/dashboard.crt" -n kube-system
    

    7.4.3 修改配置文件

    cd ${PROJECT_DIR}/dashboard
    sed -i "s#image: k8s.gcr.io#image: ${DOCKER_REGISTRY}/registry.cn-hangzhou.aliyuncs.com/google_containers#g" kubernetes-dashboard.yaml
    

    7.4.4 部署 dashboard

    kubectl apply -f ${PROJECT_DIR}/dashboard
    

    7.4.5 获取token

    kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep user-admin | awk '{print $1}')
    

    7.5 部署 Nginx ingress

    7.5.1 配置文件

    cp -a ${TEMP_DIR}/ingress-nginx ${PROJECT_DIR}/
    cd ${PROJECT_DIR}/ingress-nginx
    

    7.5.2 修改配置文件

    cd ${PROJECT_DIR}/ingress-nginx
    sed -i "s#image: quay.io#image: ${DOCKER_REGISTRY}/quay.io#g"  mandatory.yaml
    

    7.5.3 部署 nginx-ingress

    cd ${PROJECT_DIR}/ingress-nginx
    kubectl create -f mandatory.yaml
    
  • 相关阅读:
    R函数
    R 读取excel的方法
    R 数据框的操作
    R apply()函数
    怎么更改Rstudio中的默认目录
    【转】R函数-diag()函数
    《学习R》笔记:科学计算器、检查变量和工作区、向量、矩阵和数组、列表和数据框
    IDEA快速创建maven项目
    idea 在创建maven时没有src的解决方法
    maven编译 出现Process terminated
  • 原文地址:https://www.cnblogs.com/xiaoqshuo/p/11967887.html
Copyright © 2020-2023  润新知