zoukankan      html  css  js  c++  java
  • Kubernetes 1.11.2概述和搭建(多节点)

    一、Kubernetes整体概述和架构

    Kubernetes是什么

    Kubernetes是一个轻便的和可扩展的开源平台,用于管理容器化应用和服务。通过Kubernetes能够进行应用的自动化部署和扩缩容。在Kubernetes中,会将组成应用的容器组合成一个逻辑单元以更易管理和发现。Kubernetes积累了作为Google生产环境运行工作负载15年的经验,并吸收了来自于社区的最佳想法和实践。Kubernetes经过这几年的快速发展,形成了一个大的生态环境,Google在2014年将Kubernetes作为开源项目。Kubernetes的关键特性包括:

    • 自动化装箱:在不牺牲可用性的条件下,基于容器对资源的要求和约束自动部署容器。同时,为了提高利用率和节省更多资源,将关键和最佳工作量结合在一起。
    • 自愈能力:当容器失败时,会对容器进行重启;当所部署的Node节点有问题时,会对容器进行重新部署和重新调度;当容器未通过监控检查时,会关闭此容器;直到容器正常运行时,才会对外提供服务。
    • 水平扩容:通过简单的命令、用户界面或基于CPU的使用情况,能够对应用进行扩容和缩容。
    • 服务发现和负载均衡:开发者不需要使用额外的服务发现机制,就能够基于Kubernetes进行服务发现和负载均衡。
    • 自动发布和回滚:Kubernetes能够程序化的发布应用和相关的配置。如果发布有问题,Kubernetes将能够回归发生的变更。
    • 保密和配置管理:在不需要重新构建镜像的情况下,可以部署和更新保密和应用配置。
    • 存储编排:自动挂接存储系统,这些存储系统可以来自于本地、公共云提供商(例如:GCP和AWS)、网络存储(例如:NFS、iSCSI、Gluster、Ceph、Cinder和Floker等)。

    Kubernetes的整体架构

    Kubernetes属于主从分布式架构,主要由Master Node和Worker Node组成,以及包括客户端命令行工具kubectl和其它附加项。

    • Master Node:作为控制节点,对集群进行调度管理;Master Node由API Server、Scheduler、Cluster State Store和Controller-Manger Server所组成;
    • Worker Node:作为真正的工作节点,运行业务应用的容器;Worker Node包含kubelet、kube proxy和Container Runtime;
    • kubectl:用于通过命令行与API Server进行交互,而对Kubernetes进行操作,实现在集群中进行各种资源的增删改查等操作;
    • Add-on:是对Kubernetes核心功能的扩展,例如增加网络和网络策略等能力。

    Master Node(主节点)

    API Server(API服务器)

    API Server主要用来处理REST的操作,确保它们生效,并执行相关业务逻辑,以及更新etcd(或者其他存储)中的相关对象。API Server是所有REST命令的入口,它的相关结果状态将被保存在etcd(或其他存储)中。API Server的基本功能包括:

    • REST语义,监控,持久化和一致性保证,API 版本控制,放弃和生效
    • 内置准入控制语义,同步准入控制钩子,以及异步资源初始化
    • API注册和发现

    另外,API Server也作为集群的网关。默认情况,客户端通过API Server对集群进行访问,客户端需要通过认证,并使用API Server作为访问Node和Pod(以及service)的堡垒和代理/通道。

    Cluster state store(集群状态存储)

    Kubernetes默认使用etcd作为集群整体存储,当然也可以使用其它的技术。etcd是一个简单的、分布式的、一致的key-value存储,主要被用来共享配置和服务发现。etcd提供了一个CRUD操作的REST API,以及提供了作为注册的接口,以监控指定的Node。集群的所有状态都存储在etcd实例中,并具有监控的能力,因此当etcd中的信息发生变化时,就能够快速的通知集群中相关的组件。
    View Code

    Controller-Manager Server(控制管理服务器)

    Controller-Manager Serve用于执行大部分的集群层次的功能,它既执行生命周期功能(例如:命名空间创建和生命周期、事件垃圾收集、已终止垃圾收集、级联删除垃圾收集、node垃圾收集),也执行API业务逻辑(例如:pod的弹性扩容)。控制管理提供自愈能力、扩容、应用生命周期管理、服务发现、路由、服务绑定和提供。Kubernetes默认提供Replication Controller、Node Controller、Namespace Controller、Service Controller、Endpoints Controller、Persistent Controller、DaemonSet Controller等控制器。
    View Code

    Scheduler(调度器)

    scheduler组件为容器自动选择运行的主机。依据请求资源的可用性,服务请求的质量等约束条件,scheduler监控未绑定的pod,并将其绑定至特定的node节点。Kubernetes也支持用户自己提供的调度器,Scheduler负责根据调度策略自动将Pod部署到合适Node中,调度策略分为预选策略和优选策略,Pod的整个调度过程分为两步:
    
    1)预选Node:遍历集群中所有的Node,按照具体的预选策略筛选出符合要求的Node列表。如没有Node符合预选策略规则,该Pod就会被挂起,直到集群中出现符合要求的Node。
    
    2)优选Node:预选Node列表的基础上,按照优选策略为待选的Node进行打分和排序,从中获取最优Node。
    View Code

    Worker Node(从节点)

    Kubelet

    Kubelet是Kubernetes中最主要的控制器,它是Pod和Node API的主要实现者,Kubelet负责驱动容器执行层。在Kubernetes中,应用容器彼此是隔离的,并且与运行其的主机也是隔离的,这是对应用进行独立解耦管理的关键点。
    
    在Kubernets中,Pod作为基本的执行单元,它可以拥有多个容器和存储数据卷,能够方便在每个容器中打包一个单一的应用,从而解耦了应用构建时和部署时的所关心的事项,已经能够方便在物理机/虚拟机之间进行迁移。API准入控制可以拒绝或者Pod,或者为Pod添加额外的调度约束,但是Kubelet才是Pod是否能够运行在特定Node上的最终裁决者,而不是scheduler或者DaemonSet。kubelet默认情况使用cAdvisor进行资源监控。负责管理Pod、容器、镜像、数据卷等,实现集群对节点的管理,并将容器的运行状态汇报给Kubernetes API Server。
    View Code

    Container Runtime(容器运行时)

    每一个Node都会运行一个Container Runtime,其负责下载镜像和运行容器。Kubernetes本身并不停容器运行时环境,但提供了接口,可以插入所选择的容器运行时环境。kubelet使用Unix socket之上的gRPC框架与容器运行时进行通信,kubelet作为客户端,而CRI shim作为服务器。
    View Code

    protocol buffers API提供两个gRPC服务,ImageService和RuntimeService。ImageService提供拉取、查看、和移除镜像的RPC。RuntimeSerivce则提供管理Pods和容器生命周期管理的RPC,以及与容器进行交互(exec/attach/port-forward)。容器运行时能够同时管理镜像和容器(例如:Docker和Rkt),并且可以通过同一个套接字提供这两种服务。在Kubelet中,这个套接字通过–container-runtime-endpoint和–image-service-endpoint字段进行设置。Kubernetes CRI支持的容器运行时包括docker、rkt、cri-o、frankti、kata-containers和clear-containers等。
    View Code

    kube proxy

    基于一种公共访问策略(例如:负载均衡),服务提供了一种访问一群pod的途径。此方式通过创建一个虚拟的IP来实现,客户端能够访问此IP,并能够将服务透明的代理至Pod。每一个Node都会运行一个kube-proxy,kube proxy通过iptables规则引导访问至服务IP,并将重定向至正确的后端应用,通过这种方式kube-proxy提供了一个高可用的负载均衡解决方案。服务发现主要通过DNS实现。
    
    在Kubernetes中,kube proxy负责为Pod创建代理服务;引到访问至服务;并实现服务到Pod的路由和转发,以及通过应用的负载均衡。
    View Code

    kubectl

    kubectl是Kubernetes集群的命令行接口。运行kubectl命令的语法如下所示:

    $ kubectl [command] [TYPE] [NAME] [flags]

    这里的command,TYPE、NAME和flags为:

    • comand:指定要对资源执行的操作,例如create、get、describe和delete
    • TYPE:指定资源类型,资源类型是大小学敏感的,开发者能够以单数、复数和缩略的形式。例如:
    • NAME:指定资源的名称,名称也大小写敏感的。如果省略名称,则会显示所有的资源,例如:
     $kubectl get pods
    • flags:指定可选的参数。例如,可以使用-s或者–server参数指定Kubernetes API server的地址和端口。

    另外,可以通过运行kubectl help命令获取更多的信息。

    附加项和其他依赖

    在Kunbernetes中可以以附加项的方式扩展Kubernetes的功能,目前主要有网络、服务发现和可视化这三大类的附加项,下面是可用的一些附加项:

    网络和网络策略

    • ACI 通过与Cisco ACI集成的容器网络和网络安全。
    • Calico 是一个安全的3层网络和网络策略提供者。
    • Canal 联合Fannel和Calico,通过网络和网络侧。
    • Cilium 是一个3层网络和网络侧插件,它能够透明的加强HTTP/API/L7 策略。其即支持路由,也支持overlay/encapsultion模式。
    • Flannel 是一个overlay的网络提供者。

    服务发现

    • CoreDNS 是一个灵活的,可扩展的DNS服务器,它能够作为Pod集群内的DNS进行安装。
    • Ingress 提供基于Http协议的路由转发机制。

    可视化&控制

    • Dashboard 是Kubernetes的web用户界面。

    二、k8s搭建

    kubeadm是Kubernetes官方提供的用于快速安装Kubernetes集群的工具,伴随Kubernetes每个版本的发布都会同步更新,kubeadm会对集群配置方面的一些实践做调整,通过实验kubeadm可以学习到Kubernetes官方在集群配置上一些新的最佳实践。

    在Kubernetes的文档Creating a single master cluster with kubeadm中已经给出了目前kubeadm的主要特性已经处于beta状态了,在2018年将进入GA状态,说明kubeadm离可以在生产环境中使用的距离越来越近了。

    当然我们线上稳定运行的Kubernetes集群是使用ansible以二进制形式的部署的高可用集群,这里体验Kubernetes 1.11中的kubeadm是为了跟随官方对集群初始化和配置方面的最佳实践,进一步完善我们的ansible部署脚本。

    环境准备

    环境说明

    操作系统 主机名 IP地址 功能
    ubuntu-16.04.5-server-amd64 k8s-master001 192.168.91.128 主节点
    ubuntu-16.04.5-server-amd64 k8s-node001 192.168.91.129 从节点,etcd
    ubuntu-16.04.5-server-amd64 k8s-node002 192.168.91.131 从节点,docker registry,Ubuntu私有源

    3台服务器的配置均为:1核2G,硬盘20G

    请确保主节点能ssh免密登录2个从节点。3台服务器,主要使用root用户操作 

    etcd这里只用1个,如果要做高可用,请保证节点数量是奇数。比如3,5,7。偶数节点,会无法选举Leader

    由于k8s需要的docker镜像和deb包被墙了。所以需要构建私有的docker仓库

    相关软件包已经上传到百度云,下载方式为:

    链接:https://pan.baidu.com/s/1Z31IcS2f15ufoqDw19-i3Q   提取码:tlex

    其中deb包,是ubuntu的软件包,其他压缩包,全部都是docker镜像!

    docker镜像都是从google下载的,如果不放心,可自行下载!

    如果你使用的是Centos 7系统,可以不用这么麻烦,使用开源Breeze工具部署Kubernetes。

    Breeze项目是深圳睿云智合所开源的Kubernetes图形化部署工具,大大简化了Kubernetes部署的步骤,其最大亮点在于支持全离线环境的部署,且不需要翻墙获取Google的相应资源包,尤其适合某些不便访问互联网的服务器场景。

    具体操作,请参考链接:

    https://www.kubernetes.org.cn/4623.html

    主机名

    登录3台服务器,查看主机名

    cat /etc/hostname

    如果输出不是上面表格中的主机名,请务必修改!

    修改完成之后,必须要重启服务器才行!

    由于这里并没有使用私有的DNS,所以直接用hosts文件来强制解析。

    务必保证3台服务器的hosts文件有如下3条记录

    192.168.91.128 k8s-master001
    192.168.91.129 k8s-node001
    192.168.91.131 k8s-node002

    时间设置

    务必保证3台服务器的时区是一样的,强制更改时区为上海,执行以下命令

    ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
    bash -c "echo 'Asia/Shanghai' > /etc/timezone"

    安装ntpdate

    apt-get install -y ntpdate

    如果出现以下错误

    E: Could not get lock /var/lib/dpkg/lock - open (11: Resource temporarily unavailable)
    E: Unable to lock the administration directory (/var/lib/dpkg/), is another process using it?

    执行2个命令解决

    sudo rm /var/cache/apt/archives/lock
    sudo rm /var/lib/dpkg/lock

    使用阿里云的时间服务器更新

    ntpdate ntp1.aliyun.com

    3台服务器都执行一下,确保时间一致!

    请确保防火墙都关闭了!

    ssh免密登录

    3台服务器生成秘钥,并写入到authorized_keys

    ssh-keygen -t rsa -P "" -f ~/.ssh/id_rsa
    cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys

    登录到主节点服务器,copy秘钥,执行以下命令

    ssh-copy-id k8s-master001
    ssh-copy-id k8s-node001
    ssh-copy-id k8s-node002

    测试ssh免密登录

    登录到主节点服务器,测试ssh免密登录

    ssh k8s-master001
    exit
    
    ssh k8s-node001
    exit
    
    ssh k8s-node002
    exit

    请确保以上3个命令,不需要输入密码

    更新ubuntu数据库

    使用阿里云的更新源,默认的太慢了

    vi /etc/apt/sources.list

    清空文件内容,添加如下内容:

    deb http://mirrors.aliyun.com/ubuntu/ xenial main restricted
    deb http://mirrors.aliyun.com/ubuntu/ xenial-updates main restricted
    deb http://mirrors.aliyun.com/ubuntu/ xenial universe
    deb http://mirrors.aliyun.com/ubuntu/ xenial-updates universe
    deb http://mirrors.aliyun.com/ubuntu/ xenial multiverse
    deb http://mirrors.aliyun.com/ubuntu/ xenial-updates multiverse
    deb http://mirrors.aliyun.com/ubuntu/ xenial-backports main restricted universe multiverse
    deb http://mirrors.aliyun.com/ubuntu xenial-security main restricted
    deb http://mirrors.aliyun.com/ubuntu xenial-security universe
    deb http://mirrors.aliyun.com/ubuntu xenial-security multiverse

    使用apt-get update来更新一下

    apt-get update

    确保3台都是使用阿里云的更新源 

    3台服务器,都需要安装docker

    apt-get install -y docker.io

    修改daemon.json

    vim /etc/docker/daemon.json 

    内容如下:

    {
       "registry-mirrors": [
          "https://kv3qfp85.mirror.aliyuncs.com"
       ],
       "insecure-registries": [
          "192.168.91.131:5000"
        ]
    }

    重启docker服务

    systemctl restart docker

     确保3台服务器,都修改了daemon.json

    etcd部署

    登录到k8s-node001服务器,直接运行etcd_v3.3.10.sh即可。请注意前置条件!

    etcd_v3.3.10.sh

    说明:本脚本,只能在本地服务器安装。请确保etcd-v3.3.10-linux-amd64.tar.gz文件和shell脚本在同一目录下。

    脚本附带了使用systemctl命令启动etcd服务

    #/bin/bash
    # 单击版etcd安装脚本
    # 本脚本,只能在本地服务器安装。
    # 请确保etcd-v3.3.10-linux-amd64.tar.gz文件和当前脚本在同一目录下。
    # 务必使用root用户执行此脚本!
    # 确保可以直接执行python3,因为倒数第4行,有一个json格式化输出。如果不需要可以忽略
    #set -e
    
    # 输入本机ip
    while true
    do
        echo '请输入本机ip'
        echo 'Example: 192.168.0.1'
        echo -e "etcd server ip=c"
        read ETCD_Server
        if [ "$ETCD_Server" == "" ];then
            echo 'No input etcd server IP'
        else
                #echo 'No input etcd server IP'
                break
        fi
    done
    
    # etcd启动服务
    cat > /lib/systemd/system/etcd.service <<EOF
    [Unit]
    Description=etcd - highly-available key value store
    Documentation=https://github.com/coreos/etcd
    Documentation=man:etcd
    After=network.target
    Wants=network-online.target
    
    [Service]
    Environment=DAEMON_ARGS=
    Environment=ETCD_NAME=%H
    Environment=ETCD_DATA_DIR=/var/lib/etcd/default
    EnvironmentFile=-/etc/default/%p
    Type=notify
    User=etcd
    PermissionsStartOnly=true
    #ExecStart=/bin/sh -c "GOMAXPROCS=$(nproc) /usr/bin/etcd $DAEMON_ARGS"
    ExecStart=/usr/bin/etcd $DAEMON_ARGS
    Restart=on-abnormal
    #RestartSec=10s
    #LimitNOFILE=65536
    
    [Install]
    WantedBy=multi-user.target
    Alias=etcd3.service
    EOF
    
    
    # 主机名
    name=`hostname`
    # etcd的http连接地址
    initial_cluster="http://$ETCD_Server:2380"
    
    
    # 判断进程是否启动
    A=`ps -ef|grep /usr/bin/etcd|grep -v grep|wc -l`
    if [ $A -ne 0 ];then
        # 杀掉进程
        killall etcd
    fi 
    
    # 删除etcd相关文件
    rm -rf /var/lib/etcd/*
    rm -rf /etc/default/etcd
    
    # 设置时区
    ln -snf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
    
    # 判断压缩文件
    if [ ! -f "etcd-v3.3.10-linux-amd64.tar.gz" ];then
        echo "当前目录etcd-v3.3.10-linux-amd64.tar.gz文件不存在"
        exit
    fi
    
    # 安装etcd
    tar zxf etcd-v3.3.10-linux-amd64.tar.gz -C /tmp/
    cp -f /tmp/etcd-v3.3.10-linux-amd64/etcd /usr/bin/
    cp -f /tmp/etcd-v3.3.10-linux-amd64/etcdctl /usr/bin/
    
    
    # etcd配置文件
    cat > /etc/default/etcd <<EOF
    ETCD_NAME=$name
    ETCD_DATA_DIR="/var/lib/etcd/"
    ETCD_LISTEN_PEER_URLS="http://$ETCD_Server:2380"
    ETCD_LISTEN_CLIENT_URLS="http://$ETCD_Server:2379,http://127.0.0.1:4001"
    ETCD_INITIAL_ADVERTISE_PEER_URLS="http://$ETCD_Server:2380"
    ETCD_INITIAL_CLUSTER="$ETCD_Servernitial_cluster"
    ETCD_INITIAL_CLUSTER_STATE="new"
    ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster-sdn"
    ETCD_ADVERTISE_CLIENT_URLS="http://$ETCD_Server:2379"
    EOF
    
    
    # 临时脚本,添加用户和组
    cat  > /tmp/foruser <<EOF
    #!/bin/bash
    if [ \`cat /etc/group|grep etcd|wc -l\` -eq 0 ];then groupadd -g 217 etcd;fi
    if [ \`cat /etc/passwd|grep etcd|wc -l\` -eq 0 ];then mkdir -p /var/lib/etcd && useradd -g 217 -u 111 etcd -d /var/lib/etcd/ -s /bin/false;fi
    if [ \`cat /etc/profile|grep ETCDCTL_API|wc -l\` -eq 0 ];then bash -c "echo 'export ETCDCTL_API=3' >> /etc/profile" && bash -c "source /etc/profile";fi
    EOF
    
    # 执行脚本
    bash /tmp/foruser
    
    # 启动服务
    systemctl daemon-reload
    systemctl enable etcd.service
    chown -R etcd:etcd /var/lib/etcd
    systemctl restart etcd.service
    #netstat -anpt | grep 2379
    # 查看版本
    etcdctl -v
    # 访问API, -s 去掉curl的统计信息. python3 -m json.tool 表示json格式化
    curl $initial_cluster/version -s | python3 -m json.tool
    
    # 删除临时文件
    rm -rf /tmp/foruser /tmp/etcd-v3.3.10-linux-amd64
    View Code

    执行脚本

    bash etcd_v3.3.10.sh

    输出:

    请输入本机ip
    Example: 192.168.0.1
    etcd server ip=192.168.91.129
    Created symlink from /etc/systemd/system/etcd3.service to /lib/systemd/system/etcd.service.
    Created symlink from /etc/systemd/system/multi-user.target.wants/etcd.service to /lib/systemd/system/etcd.service.
    etcdctl version: 3.3.10
    API version: 2
    {
        "etcdserver": "3.3.10",
        "etcdcluster": "3.3.0"
    }

    搭建 docker 私有仓库

    登录到k8s-node002服务器,安装docker

    apt-get install -y docker.io

    拉取registry镜像

    docker pull registry

    创建registry docker进程

    docker run -d --name docker-registry --restart=always -p 5000:5000 registry

    上面已经修改过了 /etc/docker/daemon.json,所以这里不需要修改了!

    创建目录/reop,将百度云的k8s-1.11下载下来,上传到/repo目录。

    mkdir /repo

    repo的目录结构如下:

    /repo/
    └── k8s-1.11
        ├── calico_cni_v1.11.4.tar.gz
        ├── calico_kube-controllers_v1.0.3.tar.gz
        ├── calico_node_v2.6.8.tar.gz
        ├── calico.yaml
        ├── coredns-1.1.3.tar.gz
        ├── cri-tools_1.11.0-00_amd64_768e5551f9badfde12b10c42c88afb45c412c1bf307a5985a4b29f4499d341bd.deb
        ├── kubeadm_1.11.2-00_amd64_7602f5c4362b9c17aba83e8424830a98ca66074e36dead31d239f2beda91f1ff.deb
        ├── kube-apiserver.tar.gz
        ├── kube-controller-manager.tar.gz
        ├── kubectl_1.11.2-00_amd64_49e2a857e4852da0c27e3e92bc92fef4d33db7c93c2a4628cb9374e3a486bc92.deb
        ├── kubelet_1.11.2-00_amd64_7537d39713573280e1cc245915fc7565ac49d041fbd0e0515daa1ea2ac659dbb.deb
        ├── kube-proxy.tar.gz
        ├── kubernetes-cni_0.6.0-00_amd64_43460dd3c97073851f84b32f5e8eebdc84fadedb5d5a00d1fc6872f30a4dd42c.deb
        ├── kube-scheduler.tar.gz
        └── pause3.1.tar.gz
    View Code

    测试etcd的状态,运行是否正常

    测试docker私有仓库,运行是否正常

    kubernetes Master 配置

    以下都是主节点操作,从节点不需要做任何操作!

    安装kubernetes 服务器

     复制软件包

    scp -r 192.168.91.131:/repo/k8s-1.11 ./

    安装相关组件

    apt-get install -y docker.io ipvsadm ebtables socat --allow-unauthenticated

    安装k8s的deb包

    dpkg -i k8s-1.11/*.deb

    开启cadvisor

    sed -i 's?config.yaml?config.yaml --cadvisor-port=4194?g' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

    这条命令的意思就是将 config.yaml替换为config.yaml --cadvisor-port=4194

    添加cgroup驱动程序

    sed -i 8i'Environment="KUBELET_CGROUP_ARGS=--cgroup-driver=cgroupfs"' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf

    8i表示 在第8行之前插入文本,文本的内容就是Environment="KUBELET_CGROUP_ARGS=--cgroup-driver=cgroupfs

    重新应用配置

    systemctl daemon-reload

    导入k8s镜像

    for i in k8s-1.11/*.gz; do sudo docker load < $i; done

    查看当前镜像

    root@k8s-master001:~# docker images
    REPOSITORY                                 TAG                 IMAGE ID            CREATED             SIZE
    k8s.gcr.io/kube-apiserver-amd64            v1.11.2             214c48e87f58        4 months ago        187 MB
    k8s.gcr.io/kube-controller-manager-amd64   v1.11.2             55b70b420785        4 months ago        155 MB
    k8s.gcr.io/kube-proxy-amd64                v1.11.2             1d3d7afd77d1        4 months ago        97.8 MB
    k8s.gcr.io/kube-scheduler-amd64            v1.11.2             0e4a34a3b0e6        4 months ago        56.8 MB
    k8s.gcr.io/coredns                         1.1.3               b3b94275d97c        5 months ago        45.6 MB
    quay.io/calico/node                        v2.6.8              e96a297310fd        8 months ago        282 MB
    quay.io/calico/cni                         v1.11.4             4c4cb67d7a88        9 months ago        70.8 MB
    quay.io/calico/kube-controllers            v1.0.3              34aebe64326d        10 months ago       52.3 MB
    k8s.gcr.io/pause                           3.1                 da86e6ba6ca1        10 months ago       742 kB

    将包含quay.io镜像推送到私有仓库

    docker tag quay.io/calico/cni:v1.11.4 192.168.91.131:5000/calico/cni:v1.11.4
    docker push 192.168.91.131:5000/calico/cni:v1.11.4
    
    docker tag quay.io/calico/kube-controllers:v1.0.3 192.168.91.131:5000/calico/kube-controllers:v1.0.3
    docker push 192.168.91.131:5000/calico/kube-controllers:v1.0.3
    
    docker tag quay.io/calico/node:v2.6.8 192.168.91.131:5000/calico/node:v2.6.8
    docker push 192.168.91.131:5000/calico/node:v2.6.8
    View Code

    这一步操作,可能有点麻烦,可以使用shell脚本完成

    push_mirror.sh

    #!/bin/bash
    
    # 私有仓库地址
    dockerREG="192.168.91.131:5000"
    
    # 查询包含calico的镜像
    CalicoPro=$(sudo docker images|grep quay.io|awk -F 'quay.io/' '{print $2}'|awk '{print $1}'|sort|uniq)
    for i in $CalicoPro;do
            # 查询镜像的tag版本
            Proversion=$(docker images|grep quay.io|grep $i|awk '{print $2}')
            for j in $Proversion;do
                    # 打tag并推送镜像到私有仓库
                    sudo docker tag quay.io/$i:$j $dockerREG/$i:$j
                    sudo docker push $dockerREG/$i:$j
            done
    done

    执行脚本

    bash push_mirror.sh

    暂时关闭kubelet

    # 重新设置kubelet服务开机启动
    systemctl enable kubelet.service
    # 停止kubelet服务
    systemctl stop kubelet.service

    关闭swap

    Kubernetes 1.8开始要求关闭系统的Swap,如果不关闭,默认配置下kubelet将无法启动。

    关闭系统的Swap方法如下

    swapoff -a

    修改 /etc/fstab 文件,注释掉 SWAP 的自动挂载,使用free -m确认swap已经关闭

    fswap=`cat /etc/fstab |grep swap|awk '{print $1}'`
    for i in $fswap;do
        sed -i "s?$i?#$i?g" /etc/fstab
    done

    上面这段代码表示,包含swap的行前面添加#

    删除默认的k8s文件

    rm -rf /etc/kubernetes/*
    rm -rf /var/lib/kubelet/*

    重置k8s集群

    kubeadm reset -f

    编辑临时配置文件

    vim /tmp/kubeadm-conf.yaml

    内容如下:

    apiVersion: kubeadm.k8s.io/v1alpha1
    kind: MasterConfiguration
    networking:
      podSubnet: 192.138.0.0/16
    #apiServerCertSANs:
    #- master01
    #- master02
    #- master03
    #- 172.16.2.1
    #- 172.16.2.2
    #- 172.16.2.3
    #- 172.16.2.100
    etcd:
      endpoints:
      - http://192.168.91.129:2379
    #token: 67e411.zc3617bb21ad7ee3
    kubernetesVersion: v1.11.2
    api:
      advertiseAddress: 192.168.91.128

    注意修改主节点的IP和etcd的IP地址

    定义podSubnet为192.138.0.0/16 

    初始化集群

    使用kubeadm init初始化集群

    kubeadm init --config=/tmp/kubeadm-conf.yaml| sudo tee /etc/kube-server-key

    执行输出:

    [init] using Kubernetes version: v1.11.2
    [preflight] running pre-flight checks
    I1113 11:56:57.910361   20411 kernel_validator.go:81] Validating kernel version
    I1113 11:56:57.910897   20411 kernel_validator.go:96] Validating kernel config
    [preflight/images] Pulling images required for setting up a Kubernetes cluster
    [preflight/images] This might take a minute or two, depending on the speed of your internet connection
    [preflight/images] You can also perform this action in beforehand using 'kubeadm config images pull'
    [kubelet] Writing kubelet environment file with flags to file "/var/lib/kubelet/kubeadm-flags.env"
    [kubelet] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml"
    [preflight] Activating the kubelet service
    [certificates] Generated ca certificate and key.
    [certificates] Generated apiserver certificate and key.
    [certificates] apiserver serving cert is signed for DNS names [k8s-master001 kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 192.168.91.128]
    [certificates] Generated apiserver-kubelet-client certificate and key.
    [certificates] Generated sa key and public key.
    [certificates] Generated front-proxy-ca certificate and key.
    [certificates] Generated front-proxy-client certificate and key.
    [certificates] valid certificates and keys now exist in "/etc/kubernetes/pki"
    [kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/admin.conf"
    [kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/kubelet.conf"
    [kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/controller-manager.conf"
    [kubeconfig] Wrote KubeConfig file to disk: "/etc/kubernetes/scheduler.conf"
    [controlplane] wrote Static Pod manifest for component kube-apiserver to "/etc/kubernetes/manifests/kube-apiserver.yaml"
    [controlplane] wrote Static Pod manifest for component kube-controller-manager to "/etc/kubernetes/manifests/kube-controller-manager.yaml"
    [controlplane] wrote Static Pod manifest for component kube-scheduler to "/etc/kubernetes/manifests/kube-scheduler.yaml"
    [init] waiting for the kubelet to boot up the control plane as Static Pods from directory "/etc/kubernetes/manifests" 
    [init] this might take a minute or longer if the control plane images have to be pulled
    [apiclient] All control plane components are healthy after 44.009208 seconds
    [uploadconfig] storing the configuration used in ConfigMap "kubeadm-config" in the "kube-system" Namespace
    [kubelet] Creating a ConfigMap "kubelet-config-1.11" in namespace kube-system with the configuration for the kubelets in the cluster
    [markmaster] Marking the node k8s-master001 as master by adding the label "node-role.kubernetes.io/master=''"
    [markmaster] Marking the node k8s-master001 as master by adding the taints [node-role.kubernetes.io/master:NoSchedule]
    [patchnode] Uploading the CRI Socket information "/var/run/dockershim.sock" to the Node API object "k8s-master001" as an annotation
    [bootstraptoken] using token: 8kjvh8.jc3kjgjepz06ptxl
    [bootstraptoken] configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials
    [bootstraptoken] configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token
    [bootstraptoken] configured RBAC rules to allow certificate rotation for all node client certificates in the cluster
    [bootstraptoken] creating the "cluster-info" ConfigMap in the "kube-public" namespace
    [addons] Applied essential addon: CoreDNS
    [addons] Applied essential addon: kube-proxy
    
    Your Kubernetes master has initialized successfully!
    
    To start using your cluster, you need to run the following as a regular user:
    
      mkdir -p $HOME/.kube
      sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
      sudo chown $(id -u):$(id -g) $HOME/.kube/config
    
    You should now deploy a pod network to the cluster.
    Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at:
      https://kubernetes.io/docs/concepts/cluster-administration/addons/
    
    You can now join any number of machines by running the following on each node
    as root:
    
      kubeadm join 192.168.91.128:6443 --token 8kjvh8.jc3kjgjepz06ptxl --discovery-token-ca-cert-hash sha256:98ad46e571ba9ce4f759fb8e00a93bf992f43862af0efb2fc544bc881eb8e192
    View Code

    出现Your Kubernetes master has initialized successfully! 就表示成功了

    查看/etc/kube-server-key文件,就是刚刚输出的内容

    添加Nodrport端口范围

    添加端口范围1000-62000

    line_conf=`cat /etc/kubernetes/manifests/kube-apiserver.yaml|grep -n "allow-privileged=true"|cut -f 1 -d ":"`
    sed -i -e "$line_conf"i'    - --service-node-port-range=1000-62000' /etc/kubernetes/manifests/kube-apiserver.yaml

    line_conf的执行结果是18,下面sed的意思就是,在18行之前添加指定内容

    apiserver绑定主机的非安全端口,这里绑定的是主节点IP

    line_conf=`grep -n "insecure-port" /etc/kubernetes/manifests/kube-apiserver.yaml|awk -F ":" '{print $1}'`
    sed -i -e "$line_conf"i"    - --insecure-bind-address=192.168.91.128" /etc/kubernetes/manifests/kube-apiserver.yaml

     line_conf的执行结果是25,下面sed的意思就是,在18行之前添加指定内容

    apiserver绑定主机的非安全端口号,默认为8080

    sed -i -e 's?insecure-port=0?insecure-port=8080?g' /etc/kubernetes/manifests/kube-apiserver.yaml

    sed的意思就是,将insecure-port=0替换为insecure-port=8080

    设置kubectl权限

    mkdir -p $HOME/.kube
    sudo cp -f /etc/kubernetes/admin.conf $HOME/.kube/config
    sudo chown $(id -u):$(id -g) $HOME/.kube/config

    这里的$HOME指的就是当前登录用户的宿主目录,也就是/root

    部署CalICO网络插件

    修改etcd端点的IP

    line=`grep "etcd_endpoints:" -n k8s-1.11/calico.yaml | cut -f 1 -d ":"`
    sed -i "$line c   etcd_endpoints: "http://192.168.91.129:2379"" k8s-1.11/calico.yaml

    line的执行结果是17,$line后面的c表示用新文本替换当前行中的文本

    修改CIDR

    Kubernetes集群中service的虚拟IP地址范围,以CIDR表示,该IP范围不能与物理机的真实IP段有重合。

    将192.168.0.0替换为192.138.0.0

    sed -i -e 's/192.168.0.0/192.138.0.0/g' k8s-1.11/calico.yaml

    将quay.io修改为私有库地址

    sed -i -e "s?quay.io?192.168.91.131:5000?g" k8s-1.11/calico.yaml

    除了Kube DNS,它需要一个网络插件

    kubectl --kubeconfig=/etc/kubernetes/admin.conf apply -f k8s-1.11/calico.yaml

    Kubernetes node配置

    还是在主节点操作,编写脚本

    client.sh

    #!/bin/bash
    
    # 安装组件
    sudo apt-get update
    sudo apt-get install -y docker.io ipvsadm --allow-unauthenticated
    sudo apt-get install -y ebtables socat --allow-unauthenticated
    
    # 关闭swap
    sudo swapoff -a
    fswap=`cat /etc/fstab |grep swap|awk '{print $1}'`
    for i in $fswap;do
        sudo sed -i "s?$i?#$i?g" /etc/fstab
    done
    
    # 手动加载IPVS的基本模块
    sudo modprobe ip_vs
    sudo modprobe ip_vs_rr
    sudo modprobe ip_vs_sh
    sudo modprobe ip_vs_wrr
    
    # 安装deb软件包
    sudo dpkg -i k8s-1.11/cri-tools*.deb
    sudo dpkg -i k8s-1.11/kubernetes-cni*.deb
    sudo dpkg -i k8s-1.11/kubelet*.deb
    sudo dpkg -i k8s-1.11/kubectl*.deb
    sudo dpkg -i k8s-1.11/kubeadm*.deb
    
    # 开启cadvisor
    sudo sed -i 's?config.yaml?config.yaml --cadvisor-port=4194?g' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
    
    # 添加cgroup驱动程序
    sudo sed -i 8i'Environment="KUBELET_CGROUP_ARGS=--cgroup-driver=cgroupfs"' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
    
    # 重新应用配置
    sudo systemctl daemon-reload
    
    # 导入k8s镜像
    for i in k8s-1.11/*.tar.gz; do sudo docker load < $i; done
    # 停止kubelet
    sudo systemctl enable kubelet.service
    sudo systemctl stop kubelet.service
    # 重置k8s集群
    sudo kubeadm reset -f
    
    # 新增集群集工作节点的命令
    View Code

    将新增集群集工作节点的命令,写入到client.sh

    echo "`tail -n2 /etc/kube-server-key`" >> client.sh

    执行echo之后,那么client.sh的完整内容为

    #!/bin/bash
    
    # 安装组件
    sudo apt-get update
    sudo apt-get install -y docker.io ipvsadm --allow-unauthenticated
    sudo apt-get install -y ebtables socat --allow-unauthenticated
    
    # 关闭swap
    sudo swapoff -a
    fswap=`cat /etc/fstab |grep swap|awk '{print $1}'`
    for i in $fswap;do
        sudo sed -i "s?$i?#$i?g" /etc/fstab
    done
    
    # 手动加载IPVS的基本模块
    sudo modprobe ip_vs
    sudo modprobe ip_vs_rr
    sudo modprobe ip_vs_sh
    sudo modprobe ip_vs_wrr
    
    # 安装deb软件包
    sudo dpkg -i k8s-1.11/cri-tools*.deb
    sudo dpkg -i k8s-1.11/kubernetes-cni*.deb
    sudo dpkg -i k8s-1.11/kubelet*.deb
    sudo dpkg -i k8s-1.11/kubectl*.deb
    sudo dpkg -i k8s-1.11/kubeadm*.deb
    
    # 开启cadvisor
    sudo sed -i 's?config.yaml?config.yaml --cadvisor-port=4194?g' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
    
    # 添加cgroup驱动程序
    sudo sed -i 8i'Environment="KUBELET_CGROUP_ARGS=--cgroup-driver=cgroupfs"' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
    
    # 重新应用配置
    sudo systemctl daemon-reload
    
    # 导入k8s镜像
    for i in k8s-1.11/*.tar.gz; do sudo docker load < $i; done
    # 停止kubelet
    sudo systemctl enable kubelet.service
    sudo systemctl stop kubelet.service
    # 重置k8s集群
    sudo kubeadm reset -f
    
    # 新增集群集工作节点的命令
    sudo   kubeadm join 192.168.91.128:6443 --token bei68w.iovq9kr5w0kwcet3 --discovery-token-ca-cert-hash sha256:9ecbd6024fd9c66beee434cf277a69cfa2b325f4bcbf96d11e91a2a1f896fd62
    View Code

    远程执行客户端脚本

    编写install_client.sh脚本

    #!/bin/bash
    
    # node节点的IP地址
    minions="192.168.91.129 192.168.91.131"
    
    for i in $minions; do
            # 复制软件包
            scp -r k8s-1.11/ $i:/$HOME/
            # 复制daemon.json
            ssh $i sudo mkdir -p /etc/docker
            scp /etc/docker/daemon.json $i:/$HOME/daemon.json
            ssh $i sudo cp /$HOME/daemon.json /etc/docker/daemon.json
            ssh $i sudo rm -f /$HOME/daemon.json
            # 复制cilent.sh
            scp client.sh $i:/$HOME/
            # node节点执行client.sh
            ssh $i sudo bash /$HOME/client.sh
    done
    echo 'please check kubenetes DNS server is runing or not ......'
    echo 'command: kubectl get po -n kube-system|grep dns'

    执行脚本

    bash install_client.sh 

    查看k8s的DNS服务状态

    root@k8s-master001:~# kubectl get po -n kube-system|grep dns
    coredns-78fcdf6894-9cmnz                   0/1       ContainerCreating   0          3h
    coredns-78fcdf6894-zs6zb                   0/1       ContainerCreating   0          3h

    等待5秒,查看集群中的节点

    root@k8s-master001:~# kubectl get nodes
    NAME            STATUS    ROLES     AGE       VERSION
    k8s-master001   Ready     master    3h        v1.11.2
    k8s-node001     Ready     <none>    27m       v1.11.2
    k8s-node002     Ready     <none>    27m       v1.11.2

    如果状态都是Ready,表示正常!

    三、一键部署脚本

    请确保已经满足了 上面说的环境准备条件

    k8s-v1.11.sh

    #!/bin/bash
    set -e
    
    # 运行前置条件
    # 请确保主节点能ssh免密登录从节点。所有服务器,主要使用root用户操作
    # 确保etcd已经部署好,节点数量为奇数,运行正常
    # 确保docker私有仓库运行正常
    # 确保所有服务器的时间一致
    # 确保所有服务器已经安装好docker服务,并且已经修改了/etc/docker/daemon.json,能够正常推送到私有仓库
    # 本脚本只能在主节点操作
    # 具体操作,请参考链接:https://www.cnblogs.com/xiao987334176/articles/9947548.html
    
    ##########################################################################
    #                         INPUT
    ##########################################################################
    
    #setting kubernets master
    while true
    do 
        if [ "$masterIP" == "" ]; then
            echo '请输入k8s主节点ip'
            echo -e "K8S_MASTER_IP=c"
            read masterIP
        else
            break
        fi
    done
    #setting docker registry
    echo '请输入docker私有仓库ip,默认端口是5000'
    echo '如果端口不是5000,请输入ip:端口,比如: 192.168.0.50:8888'
    echo -e "dockerREG=c"
    read dockerREG
    echo '请输入etcd服务器ip'
    echo '如果有多个,用空格隔开。比如:"192.168.0.100 192.168.0.101 192.168.0.102"'
    echo -e "ETCD_Severs=c"
    read ETCD_Server
    
    #setting minions
    while true
    do 
        if [ "$k8minions" == "" ]; then
            echo '请输入k8s从节点ip'
            echo '如果有多个,用空格隔开。比如:"192.168.0.100 192.168.0.101 192.168.0.102"'
            echo -e "minions=c"
            read k8minions
        else
            break
        fi
    done
    ######################################################################################
    #                                 Settings
    ######################################################################################
    # 判断etcd的ip变量
    if [ "$ETCD_Server" == "" ];then
            EXTERNAL_ETCD_ENDPOINTS=""
    else
        EXTERNAL_ETCD_ENDPOINTS=""
        for i in $ETCD_Server;do
                EXTERNAL_ETCD_ENDPOINTS="http://$i:2379,$EXTERNAL_ETCD_ENDPOINTS"
        done
        EXTERNAL_ETCD_ENDPOINTS=${EXTERNAL_ETCD_ENDPOINTS%?}
    fi
    
    # 判断docker仓库ip
    if [ "$dockerREG" == "" ];then
            dockerREG="$masterIP:5000"
    else
        if [ `echo $dockerREG|grep ":"|wc -l` -eq 0 ];then
          dockerREG="$dockerREG:5000"
        fi
    fi
    
    MASTERIP="$masterIP"
    REPO=`echo $dockerREG | cut -d ":" -f 1`
    K8S_MASTER_IP="$MASTERIP"
    minions="$k8minions"
    
    echo "REPO=$REPO"
    echo "K8S_MASTER_IP=$MASTERIP"
    echo "DOCKERREG=$dockerREG"
    echo "minions=$k8minions"
    echo "etcds=$EXTERNAL_ETCD_ENDPOINTS"
    ######################################################################################
    #                                 正式安装
    ######################################################################################
    # 复制软件包
    scp -r $REPO:/repo/k8s-1.11 ./
    
    # 安装相关组件
    apt-get install -y docker.io ipvsadm ebtables socat --allow-unauthenticated
    
    # 安装k8s的deb包
    dpkg -i k8s-1.11/*.deb
    
    # 开启cadvisor
    sed -i 's?config.yaml?config.yaml --cadvisor-port=4194?g' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
    
    
    # 添加cgroup驱动程序
    sed -i 8i'Environment="KUBELET_CGROUP_ARGS=--cgroup-driver=cgroupfs"' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
    
    # 重新应用配置
    systemctl daemon-reload
    
    # 导入k8s镜像
    for i in k8s-1.11/*.gz; do sudo docker load < $i; done
     
    # 将包含quay.io镜像推送到私有仓库
    # 查询包含calico的镜像
    CalicoPro=$(sudo docker images|grep quay.io|awk -F 'quay.io/' '{print $2}'|awk '{print $1}'|sort|uniq)
    for i in $CalicoPro;do
            # 查询镜像的tag版本
            Proversion=$(docker images|grep quay.io|grep $i|awk '{print $2}')
            for j in $Proversion;do
                    # 打tag并推送镜像到私有仓库
                    sudo docker tag quay.io/$i:$j $dockerREG/$i:$j
                    sudo docker push $dockerREG/$i:$j
            done
    done
    
    
    # 暂时关闭kubelet
    # 重新设置kubelet服务开机启动
    systemctl enable kubelet.service
    # 停止kubelet服务
    systemctl stop kubelet.service
    
    # 关闭swap
    swapoff -a
    fswap=`cat /etc/fstab |grep swap|awk '{print $1}'`
    for i in $fswap;do
        sed -i "s?$i?#$i?g" /etc/fstab
    done
    
    # 删除默认的k8s文件
    rm -rf /etc/kubernetes/*
    rm -rf /var/lib/kubelet/*
    
    # 重置k8s集群
    kubeadm reset -f
    
    # k8s临时配置文件
    cat > /tmp/kubeadm-conf.yaml <<EOF
    apiVersion: kubeadm.k8s.io/v1alpha1
    kind: MasterConfiguration
    networking:
      podSubnet: 192.138.0.0/16
    #apiServerCertSANs:
    #- master01
    #- master02
    #- master03
    #- 172.16.2.1
    #- 172.16.2.2
    #- 172.16.2.3
    #- 172.16.2.100
    etcd:
      endpoints:
    #token: 67e411.zc3617bb21ad7ee3
    kubernetesVersion: v1.11.2
    api:
      advertiseAddress: $masterIP
    
    EOF
    
    # 将etcd添加到/tmp/kubeadm-conf.yaml
    for i in `echo $EXTERNAL_ETCD_ENDPOINTS|sed 's?,? ?g'`;do
        sudo sed -i "15i  - $i" /tmp/kubeadm-conf.yaml    
    done
    
    # 初始化集群
    # 使用kubeadm init初始化集群
    kubeadm init --config=/tmp/kubeadm-conf.yaml| sudo tee /etc/kube-server-key
    
    # 添加Nodrport端口范围
    # 添加端口范围1000-62000
    line_conf=`cat /etc/kubernetes/manifests/kube-apiserver.yaml|grep -n "allow-privileged=true"|cut -f 1 -d ":"`
    sed -i -e "$line_conf"i'    - --service-node-port-range=1000-62000' /etc/kubernetes/manifests/kube-apiserver.yaml
    
    # apiserver绑定主机的非安全端口,这里绑定的是主节点IP
    line_conf=`grep -n "insecure-port" /etc/kubernetes/manifests/kube-apiserver.yaml|awk -F ":" '{print $1}'`
    sed -i -e "$line_conf"i"    - --insecure-bind-address=$masterIP" /etc/kubernetes/manifests/kube-apiserver.yaml
    
    # apiserver绑定主机的非安全端口号,默认为8080
    sed -i -e 's?insecure-port=0?insecure-port=8080?g' /etc/kubernetes/manifests/kube-apiserver.yaml
    
    # 设置kubectl权限,$HOME是内置变量,表示宿主目录
    mkdir -p $HOME/.kube
    sudo cp -f /etc/kubernetes/admin.conf $HOME/.kube/config
    sudo chown $(id -u):$(id -g) $HOME/.kube/config
    
    # 部署CalICO网络插件
    # 修改etcd端点的IP
    line=`grep "etcd_endpoints:" -n k8s-1.11/calico.yaml | cut -f 1 -d ":"`
    sed -i "$line c   etcd_endpoints: "$EXTERNAL_ETCD_ENDPOINTS"" k8s-1.11/calico.yaml
    
    # 修改CIDR
    # 将192.168.0.0替换为192.138.0.0
    sed -i -e 's/192.168.0.0/192.138.0.0/g' k8s-1.11/calico.yaml
    #将quay.io修改为私有库地址
    sed -i -e "s?quay.io?$dockerREG?g" k8s-1.11/calico.yaml
    
    # 等待15秒
    sleep 15
    # 除了Kube DNS,它需要一个网络插件
    kubectl --kubeconfig=/etc/kubernetes/admin.conf apply -f k8s-1.11/calico.yaml
    
    # Kubernetes node配置
    cat >client.sh <<EOF
    # 安装组件
    sudo apt-get update
    sudo apt-get install -y docker.io ipvsadm --allow-unauthenticated
    sudo apt-get install -y ebtables socat --allow-unauthenticated
    
    # 关闭swap
    sudo swapoff -a
    fswap=\`cat /etc/fstab |grep swap|awk '{print $1}'\`
    for i in $fswap;do
        sudo sed -i "s?$i?#$i?g" /etc/fstab
    done
    
    # 手动加载IPVS的基本模块
    Dline=\`sudo grep -n LimitNOFILE /lib/systemd/system/docker.service|cut -f 1 -d ":" \`
    sudo sed -i "$Dline cLimitNOFILE=1048576" /lib/systemd/system/docker.service 
    sudo systemctl restart docker
    if [ \`dpkg -l|grep kube|wc -l\` -ne 0 ];then
        sudo apt purge -y \`dpkg -l|grep kube|awk '{print $2}'\`
    fi
    
    # 安装deb软件包
    sudo modprobe ip_vs
    sudo modprobe ip_vs_rr
    sudo modprobe ip_vs_sh
    sudo modprobe ip_vs_wrr
    sudo dpkg -i k8s-1.11/cri-tools*.deb
    sudo dpkg -i k8s-1.11/kubernetes-cni*.deb
    sudo dpkg -i k8s-1.11/kubelet*.deb
    sudo dpkg -i k8s-1.11/kubectl*.deb
    sudo dpkg -i k8s-1.11/kubeadm*.deb
    
    # 开启cadvisor
    sudo sed -i 's?config.yaml?config.yaml --cadvisor-port=4194?g' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
    if [ \`cat /etc/systemd/system/kubelet.service.d/10-kubeadm.conf|grep cgroup-driver|wc -l\` -eq 0 ];then
        # 添加cgroup驱动程序
        sudo sed -i 8i'Environment="KUBELET_CGROUP_ARGS=--cgroup-driver=cgroupfs"' /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
        sudo sed -i "s?\`tail -n1 /etc/systemd/system/kubelet.service.d/10-kubeadm.conf\`?& $KUBELET_CGROUP_ARGS?g" /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
    fi
    # 重新应用配置
    sudo systemctl daemon-reload
    
    # 导入k8s镜像
    for i in k8s-1.11/*.tar.gz; do sudo docker load < $i; done
    # 停止kubelet
    sudo systemctl enable kubelet.service
    sudo systemctl stop kubelet.service
    # 重置k8s集群
    sudo kubeadm reset -f
    # 新增集群集工作节点的命令
    EOF
    
    # 新增集群集工作节点的命令,追加到最后一行
    sudo echo "sudo `tail -n2 /etc/kube-server-key`" >> client.sh
    
    # 安装客户端
    for i in $minions; do
            # 复制软件包
            scp -r k8s-1.11/ $i:/$HOME/
            # 复制daemon.json
            ssh $i sudo mkdir -p /etc/docker
            scp /etc/docker/daemon.json $i:/$HOME/daemon.json
            ssh $i sudo cp /$HOME/daemon.json /etc/docker/daemon.json
            ssh $i sudo rm -f /$HOME/daemon.json
            # 复制cilent.sh
            scp client.sh $i:/$HOME/
            # node节点执行client.sh
            ssh $i sudo bash /$HOME/client.sh
    done
    echo 'please check kubenetes DNS server is runing or not ......'
    echo 'command: kubectl get po -n kube-system|grep dns'
    
    # 查看k8s的DNS服务状态
    kubectl get po -n kube-system|grep dns
    # 睡眠25秒
    sleep 25
    # 查看集群中的节点
    kubectl get nodes
    View Code

    运行之前,查看etcd的状态

    root@k8s-master001:~# curl http://192.168.91.129:2379/version -s | python3 -m json.tool
    {
        "etcdserver": "3.3.10",
        "etcdcluster": "3.3.0"
    }

    查看docker私有仓库的状态

    root@k8s-master001:~# curl http://192.168.91.131:5000/v2/_catalog -s | python3 -m json.tool
    {
        "repositories": [
            "calico/cni",
            "calico/kube-controllers",
            "calico/node"
        ]
    }

    登录到docker私有仓库服务器,查看/repo目录

    root@k8s-node002:~# ll /repo/
    total 12
    drwxr-xr-x  3 root root 4096 Nov 13 16:50 ./
    drwxr-xr-x 24 root root 4096 Nov 13 16:50 ../
    drwxr-xr-x  2 root root 4096 Nov 13 16:50 k8s-1.11/

    正式运行脚本

    bash k8s-v1.11.sh

    输入如下:

    请输入k8s主节点ip
    K8S_MASTER_IP=192.168.91.128
    请输入docker私有仓库ip,默认端口是5000
    如果端口不是5000,请输入ip:端口,比如: 192.168.0.50:8888
    dockerREG=192.168.91.131
    请输入etcd服务器ip
    如果有多个,用空格隔开。比如:"192.168.0.100 192.168.0.101 192.168.0.102"
    ETCD_Severs=192.168.91.129
    请输入k8s从节点ip
    如果有多个,用空格隔开。比如:"192.168.0.100 192.168.0.101 192.168.0.102"
    minions=192.168.91.129 192.168.91.131
    
    中间输出略....
    
    NAME            STATUS    ROLES     AGE       VERSION
    k8s-master001   Ready     master    4m        v1.11.2
    k8s-node001     Ready     <none>    2m        v1.11.2
    k8s-node002     Ready     <none>    1m        v1.11.2

    上面的红色部分,请根据环境需求填写。

    末尾的k8s节点状态都是Ready,表示安装成功了!

    查看所有命名空间

    root@k8s-master001:~# kubectl get ds --all-namespaces 
    NAMESPACE     NAME          DESIRED   CURRENT   READY     UP-TO-DATE   AVAILABLE   NODE SELECTOR                   AGE
    kube-system   calico-node   3         3         3         3            3           <none>                          8m
    kube-system   kube-proxy    3         3         3         3            3           beta.kubernetes.io/arch=amd64   8m

    查看calico网络状态

    kubectl get pods -o wide -n kube-system | grep calico-node

    确保都是Running 状态

    至此k8s,安装就完成了!

    本文参考链接:

    https://www.kubernetes.org.cn/4047.html

  • 相关阅读:
    Java实现“睡排序”——线程池Executors的使用
    浅谈HashMap与线程安全 (JDK1.8)
    Ubuntu 16 Java Develop环境快速搭建
    Spring Boot在反序列化过程中:jackson.databind.exc.InvalidDefinitionException cannot deserialize from Object value
    Java 8 – Map排序
    vue指令优化网络图片加载速度
    如何实现小于12px的字体效果
    两种以上方式实现已知或者未知宽度的垂直水平居中
    C# winform窗体间传值(使用委托或事件)
    C#栈Stack的使用
  • 原文地址:https://www.cnblogs.com/xiao987334176/p/9947548.html
Copyright © 2011-2022 走看看