• Kubernetes二进制搭建


    目录

    一、K8S的架构

    二、K8S创建Pod资源的工作流程

    三、K8S资源对象和资源配置信息

    K8S资源对象

    K8S资源配置信息

    四、K8S的的三种网络和三种接口

    三种网络:

    三种节点:

    五、etcd 集群

    etcd 的特点:

    六、flannel

    flannel方案

    K8S 中 Pod 网络通信:

    flannel的模式及工作原理

    flannel的UDP模式工作原理

    flannel的VXLAN模式工作原理

    七、calico

    calico方案

    Calico 主要由三个部分组成

    Calico 工作原理

    IPIP模式和BGP模式工作原理

    calico的IPIP模式工作原理

    calico的BGP模式工作原理

    八、flannel 和 calico 的区别

    九、二进制搭建过程

    九、k8s二进制部署

    单master 

    操作系统初始化配置

    部署 etcd 集群 

    准备签发证书环境:

    部署 docker引擎

    部署 Master 组件

    部署 Worker Node 组件

    部署 CNI 网络组件

    部署 Calico

    部署 CoreDNS

    多master高可用

    负载均衡部署

    附件

    1.k8s-cert.sh脚本

    2.apiserver.sh

    3.scheduler.sh

    4.controller-manager.sh

    5.admin.sh

    总结:

    etcd数据库:

    etcd安装步骤:

    master组件安装步骤:

    1.先安装apiserver

    2.再启动controller-manager 和scheduler

    3.检查集群组件状态

    多master部署步骤:


    一、K8S的架构

    K8S有 master 和 worker node 两类节点
    master节点(负责K8S集群的调度和管理等运维工作)有 apiserver、controller-manager、scheduler、etcd

    • apiserver:是所有服务请求的统一访问入口
    • controller-manager:控制器管理器,负责管理K8S各种资源对象的控制器;通过apiserver监控整个K8S集群资源的状态,并确保资源始终处于预期的工作状态
    • scheduler:资源调度器,负责Pod资源的调度,通过调度算法(预选策略、优选策略)为要部署的Pod选择最适合的node节点
    • etcd:K8S集群的数据库,是一种键值对存储结构的分布式数据库,负责存储K8S集群所有的重要信息,只有apiserver有访问和读写权限

    worker node节点(负责运行工作负载,即容器应用)有 kubelet、kuber-proxy、容器引擎/容器运行时(docker、containerd等)

    • kubelet:接收apiserver发来的请求,创建和管理Pod和容器,跟容器引擎交互实现对容器的生命周期的管理;收集node节点的资源信息和Pod的运行状态发送给apiserver
    • kuber-proxy:作为service资源的载体,实现对Pod的网络代理,负责维护Pod集群网络规则和四层负载均衡工作
    • 容器引擎/容器运行时:运行容器
       

    二、K8S创建Pod资源的工作流程

    1)用户通过客户端发送创建Pod的请求给apiserver
    2)apiserver接收到请求后,会先把请求信息写入到etcd中保存,再找controller-manager根据请求信息中的资源预设模板创建Pod资源
    3)controller-manager会通过apiserver找到scheduler来调度新创建的Pod资源
    4)scheduler通过调度算法的预选策略和优选策略筛选出最适合的node节点进行调度
    5)再通过apiserver找到对应的node节点上的kubelet去创建和管理Pod
    6)kubelet会跟容器引擎交互来管理Pod及容器的生命周期
    7)用户还可以通过apiserver在kube-proxy上写入iptables/ipvs网络规则,创建service资源,实现对Pod集群的网络代理

    三、K8S资源对象和资源配置信息

    K8S资源对象

    Pod:是K8S能够创建和管理的最小单位。一个Pod里可以包含一个或者多个应用容器,Pod里的容器之间共享网络、存储等资源
    Pod控制器:

    • deployment:部署无状态应用(没有实时的数据需要存储);同时也负责管理replicaset(维持Pod副本数量符合预期数量)和Pod(容器化的应用进程)
    • statefulset:部署有状态应用(有实时的数据需要存储)
    • daemonset:在所有的node节点上部署同一类型的Pod
    • job:一次性的部署短期任务的Pod(执行完任务后会自动退出的Pod)
    • cronjob:周期性的部署短期任务的Pod(执行完任务后会自动退出的Pod)

    service:在K8S集群内部,为通过标签选择器相关联的一组Pod提供一个统一的访问入口(clusterIP),只支持四层代理转发
    ingress:作为K8S集群外部接入层,可自定义ingress规则根据用户请求的域名或URL请求路径转发给指定的service,支持七层代理转发

    K8S资源配置信息

    apiversion:资源对象在K8S中使用的api接口版本
    kind:资源对象的类型
    metadata:资源对象的元数据信息,比如 name资源名称、annotation注释、namespace命名空间、label标签
    spec:资源对象的资源配置清单(配置属性),比如 副本数、镜像、数据卷、标签选择器
    status:资源对象的当前运行状态信息

    label:标签,将一个键值对关联到某个资源对象,用于资源对象的分组查询和筛选
    label selector:标签选择器,用于查询和筛选拥有某个标签的资源对象
    annotation:注释,用于作资源对象的注释信息或在一些特殊的资源对象里用于作额外的功能特性配置
    name:资源名称
    namespace:命名空间,在同一个命名空间中,同类型的资源对象的名称是唯一的

    四、K8S的的三种网络和三种接口

    三种网络:

    节点网络:nodeIP

    Pod网络:podIP

    Service网络: clusterIP

    三种节点:

    CRI容器运行时接口dockercontainerd podman cir-0
    CNI容器网终接口flannel calico cilium
    CSI容器存储接口ceph nfs gfs  oss  s3

    五、etcd 集群

    etcd是CoreOS团队于2013年6月发起的开源项目,它的目标是构建一个高可用的分布式键值(key-value)数据库。etcd内部采用raft协议作为一致性算法,etcd是go语言编写的。

    etcd 的特点:

    • 简单:安装配置简单,而且提供了HTTP API进行交互,使用也很简单
    • 安全:支持SSL证书验证
    • 快速:单实例支持每秒2k+读操作
    • 可靠:采用raft算法,实现分布式系统数据的可用性和一致性

    etcd 目前默认使用2379端口提供HTTP API服务, 2380端口和peer通信(这两个端口已经被IANA(互联网数字分配机构)官方预留给etcd)。 即etcd默认使用2379端口对外为客户端提供通讯,使用端口2380来进行服务器间内部通讯。
    etcd 在生产环境中一般推荐集群方式部署。由于etcd 的leader选举机制,要求至少为3台或以上的奇数台。
     

    六、flannel

    flannel方案

    需要在每个节点上把发向容器的数据包进行封装后,再用隧道将封装后的数据包发送到运行着目标Pod的node节点上。目标node节点再负责去掉封装,将去除封装的数据包发送到目标Pod上。数据通信性能则大受影响。

    K8S 中 Pod 网络通信:

    • Flannel 的功能是让集群中的不同节点主机创建的 Docker 容器都具有全集群唯一的虚拟 IP 地址。
    • Flannel 是 Overlay 网络的一种,也是将 TCP 源数据包封装在另一种网络包里面进行路由转发和通信,目前支持 udp、vxlan、 host-GW 3种数据转发方式。
       

    Pod 内容器与容器之间的通信
    在同一个 Pod 内的容器(Pod 内的容器是不会跨宿主机的)共享同一个网络命令空间,相当于它们在同一台机器上一样,可以用 localhost 地址访问彼此的端口。

    同一个 Node 内 Pod 之间的通信
    每个 Pod 都有一个真实的全局 IP 地址,同一个 Node 内的不同 Pod 之间可以直接采用对方 Pod 的 IP 地址进行通信,Pod1 与 Pod2 都是通过 Veth 连接到同一个 docker0 网桥,网段相同,所以它们之间可以直接通信。

    不同 Node 上 Pod 之间的通信
    Pod 地址与 docker0 在同一网段,docker0 网段与宿主机网卡是两个不同的网段,且不同 Node 之间的通信只能通过宿主机的物理网卡进行。
    要想实现不同 Node 上 Pod 之间的通信,就必须想办法通过主机的物理网卡 IP 地址进行寻址和通信。因此要满足两个条件:Pod 的 IP 不能冲突;将 Pod 的 IP 和所在的 Node 的 IP 关联起来,通过这个关联让不同 Node 上 Pod 之间直接通过内网 IP 地址通信。
     

    flannel的模式及工作原理

    UDP:出现最早的模式,但是性能较差,基干flanneld应用程序实现数据包的封装/解封装

    VXLAN:默认模式,是推荐使用的模式,性能比UDP模式更好,基于内核实现数据帧的封装/解封装,配置简单使用

    HOST-GW:性能最好的模式,但是配置复杂,且不能跨网段

    flannel的UDP模式工作原理

    1)原始数据包从源主机的Pod容器发出到cni0网桥接口,再由cni0转发到flannel0虚拟接口
    2)flanneld服务进程会监听flannel0接口收到的数据,flanneld进程会将原始数据包封装到UDP报文里
    3)flanneld进程会根据在etcd中维护的路由表查到目标Pod所在的nodeIP,并在UDP报文外再封装nodeIP报文、MAC报文,再通过物理网卡发送到目标node节点
    4)UDP报文通过8285号端口送到目标node节点的flanneld进程进行解封装,再通过flannel0接口转发到cni0网桥,再由cni0转发到目标Pod容器

    flannel的VXLAN模式工作原理

    1)原始数据帧从源主机的Pod容器发出到cni0网桥接口,再由cni0转发到flannel.1虚拟接口
    2)flannel.1接口收到数据帧后添加VXLAN头部,并在内核将原始数据帧封装到UDP报文里
    3)flanneld进程根据在etcd维护的路由表将UDP报文通过物理网卡发送到目标node节点
    4)UDP报文通过8472号端口送到目标node节点的flannel.1接口在内核进行解封装,再通过flannel.1接口转发到cni0网桥,再由cni0转发到目标Pod容器

    七、calico

    calico方案

    Calico不使用隧道或NAT来实现转发,而是把Host当作Internet中的路由器,使用BGP同步路由,并使用iptables来做安全访问策略,完成跨Host转发来。

    Calico 主要由三个部分组成

    • Calico CNI插件:主要负责与kubernetes对接,供kubelet调用使用。
    • Felix:负责维护宿主机上的路由规则、FIB转发信息库等。
    • BIRD:负责分发路由规则,类似路由器。
    • Confd:配置管理组件。

    Calico 工作原理

    • Calico 是通过路由表来维护每个 pod 的通信。Calico 的 CNI 插件会为每个容器设置一个 veth pair 设备, 然后把另一端接入到宿主机网络空间,由于没有网桥,CNI 插件还需要在宿主机上为每个容器的 veth pair 设备配置一条路由规则,用于接收传入的IP包。
    • 有了这样的 veth pair 设备以后,容器发出的IP包就会通过 veth pair 设备到达宿主机,然后宿主机根据路由规则的下一跳地址, 发送给正确的网关,然后到达目标宿主机,再到达目标容器。
    • 这些路由规则都是 Felix 维护配置的,而路由信息则是 Calico BIRD 组件基于 BGP 分发而来。calico 实际上是将集群里所有的节点都当做边界路由器来处理,他们一起组成了一个全互联的网络,彼此之间通过 BGP 交换路由,这些节点我们叫做 BGP Peer。

    IPIP模式和BGP模式工作原理

    calico的IPIP模式工作原理

    1)原始数据包从源主机的Pod容器发出到tunl0接口,并被内核的IPIP驱动封装到节点网络的IP报文里
    2)再根据tunl0接口的路由经过物理网卡发送到目标node节点
    3)IP数据包到达目标node节点后再通过内核的IPIP驱动解包得到原始IP数据包
    4)然后根据本地的路由规则经过 veth pair 设备送达到目标Pod容器

            

    calico的BGP模式工作原理

    (本质就是通过路由规则来维护Pod之间的通信,Felix负责维护路由规则和网络接口管理,BIRD负责分发路由信息给其它节点)

    1)源主机的Pod容器发出的原始IP数据包会通过 veth pair 设备送达到节点网络空间
    2)然后会根据原始IP数据包的目标IP和节点的路由规则找到目标node节点的IP,再经过物理网卡发送到目标node节点
    3)IP数据包到达目标node节点后会根据本地的路由规则经过 veth pair 设备送达到目标Pod容器

    八、flannel 和 calico 的区别

    flannel: UDP  VXLAN  HOST-GW
    默认网段:10.244.0.0/16
    通常采用VXLAN模式,用的是叠加网络、IP隧道方式传输数据,对性能有一定的影响
    功能简单配置方便利于管理。但是不具备复杂的网络策略规则配置能力

    calico:  IPIP  BGP  混合模式(CrossSubnet)
    默认网段:192.168.0.0/16
    使用IPIP模式可以实现跨子网传输,但是传输过程中需要额外的封包和解包过程,对性能有一定的影响
    使用BGP模式会把每个node节点看做成路由器,通过Felix、BIRD组件来维护和分发路由规则,可实现直接通过BGP协议路由转发,传输过程中不需要额外的封包和解包,因此性能较好,但是只能同一个网段里使用,无法跨子网传输
    它不使用cni0网桥,而是通过路由规则把数据包直接发送到目标网卡,所以性能高;而且还具有更丰富的网络策略配置管理能力,功能更全面,但是维护起来较为复杂

    所以对于较小规模且网络要求简单的K8S集群,可以采用flannel做cni网络插件。对于集群规模较大且要求更多的网络策略配置时,可以采用性能更好功能更全的calico

    九、二进制搭建过程

    1)部署etcd
    使用cfssl工具签发证书和私钥
    解压etcd软件包,获取二进制文件 etcd etcdctl
    准备etcd集群配置文件
    启动etcd服务进程,加入到etcd集群

    #查看etcd集群健康状态
    ETCDCTL_API=3 /opt/etcd/bin/etcdctl --endpoints="https://etcd01IP:2379,https://etcd02IP:2379,https://etcd03IP:2379" --cacert=CA证书 --cert=客户端证书 --key=客户端私钥  endpoint health -wtable
    #查看etcd集群状态信息
    ETCDCTL_API=3 /opt/etcd/bin/etcdctl --endpoints="https://etcd01IP:2379,https://etcd02IP:2379,https://etcd03IP:2379" --cacert=CA证书 --cert=客户端证书 --key=客户端私钥  endpoint status -wtable
    #查看etcd集群成员列表
    ETCDCTL_API=3 /opt/etcd/bin/etcdctl --endpoints="https://etcd01IP:2379" --cacert=CA证书 --cert=客户端证书 --key=客户端私钥  member list -wtable  
    #备份etcd数据库
    ETCDCTL_API=3 /opt/etcd/bin/etcdctl --endpoints="https://etcd01IP:2379" --cacert=CA证书 --cert=客户端证书 --key=客户端私钥 snapshot save 备份文件路径
    #恢复etcd数据库
    ETCDCTL_API=3 /opt/etcd/bin/etcdctl --endpoints="https://etcd01IP:2379" --cacert=CA证书 --cert=客户端证书 --key=客户端私钥 snapshot restore 文件路径
    #查看备份文件的状态信息
    ETCDCTL_API=3 /opt/etcd/bin/etcdctl --endpoints="https://etcd01IP:2379" --cacert=CA证书 --cert=客户端证书 --key=客户端私钥 snapshot status 文件路径

    2)部署master组件
    使用cfssl工具签发证书和私钥
    解压K8S服务端软件包,获取二进制文件 kube-apiserver  kube-controller-manager  kube-scheduler  kubectl
    准备 kube-apiserver 启动时要调用的 bootstrap-token 认证文件(token.csv)
    准备 kube-apiserver  kube-controller-manager  kube-scheduler 的服务进程启动参数配置文件
    准备 kube-controller-manager  kube-scheduler  kubectl 的 kubeconfig 集群引导配置文件(加入K8S集群的引导文件)
    依次启动 kube-apiserver  kube-controller-manager  kube-scheduler 的服务进程
    执行 kubectl get cs 命令查看master组件的健康状态

    3)部署node组件
    获取二进制文件 kubelet  kube-proxy
    准备 kubelet  kube-proxy 的 kubeconfig 集群引导配置文件 kube-proxy.kubeconfig  bootstrap.kubeconfig(kubelet首次访问apiserver加入K8S集群使用引导文件)
    准备 kubelet  kube-proxy 的服务进程启动参数配置文件
    启动 kubelet 服务进程,向 apiserver 发起 CSR 请求颁发证书,master 通过 CSR 请求后 kubelet 方可获取到证书
    加载 ipvs 模块,启动 kube-proxy 服务进程
    安装 cni 网络插件(flannel/calico)和 CoreDNS
    执行 kubectl get nodes 命令查看node的状态
     

    九、k8s二进制部署

    1. k8s集群master01:192.168.30.100,kube-apiserver、kube-controller-manager、kube-scheduler、etcd
    2. k8s集群master02:192.168.30.105
    3. k8s集群master03: 192.168.30.203
    4. etcd集群节点1:192.168.30.100 etcd
    5. etcd集群节点2:192.168.30.200
    6. etcd集群节点3:192.168.30.104
    7.  ​
    8. k8s集群node01:192.168.30.200 kubelet、kube-proxy、docker
    9. k8s集群node02:192.168.30.104
    10.  ​ ​
    11. 负载均衡nginx+keepalive01(master):192.168.30.14
    12. 负载均衡nginx+keepalive02(backup):192.168.30.15

    单master 

    操作系统初始化配置

    关闭防火墙  关闭selinux  关闭swap (所有节点)

    #关闭防火墙 全部
    systemctl stop firewalld
    systemctl disable firewalld
    iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X

    #关闭selinux 全部 
    setenforce 0
    vim /etc/selinux/config  disable
    或sed -i 's/enforcing/disabled/' /etc/selinux/config

    #关闭swap 全部
    swapoff -a
    sed -ri 's/.*swap.*/#&/' /etc/fstab 

    master01(192.168.30.100)

    node01(192.168.30.200)

    node02(192.168.30.104)

    所有节点添加hosts

    cat >> /etc/hosts << EOF
    192.168.80.10 master01
    192.168.80.11 node01
    192.168.80.12 node02
    EOF

    调整内核参数(所有节点)

    cat > /etc/sysctl.d/k8s.conf << EOF
    #开启网桥模式,可将网桥的流量传递给iptables链
    net.bridge.bridge-nf-call-ip6tables = 1
    net.bridge.bridge-nf-call-iptables = 1
    #关闭ipv6协议
    net.ipv6.conf.all.disable_ipv6=1
    net.ipv4.ip_forward=1
    EOF

    sysctl --system

    时间同步(所有节点)

    yum install ntpdate -y
    ntpdate time.windows.com或ntpdate ntp.aliyun.com

    部署 etcd 集群 

    准备签发证书环境:

    CFSSL是CloudFlare公司开源的一款PKI/TLS 工具。CFSSL包含一个命令行工具和一个用于签名、验证和捆绑TLS证书的HTTP API服务。使用Go语言编写。

    CFSSL使用配置文件生成证书,因此自签之前,需要生成它识别的json 格式的配置文件,CFSSL 提供了方便的命令行生成配置文件。

    CFSSL用来为etcd提供TLS证书,它支持签三种类型的证书:

    1. client证书,服务端连接客户端时携带的证书,用于客户端验证服务端身份,如kubeapiserver 访问etcd;
    2. server证书,客户端连接服务端时携带的证书,用于服务端验证客户端身份,如etcd对外提供服务;
    3. peer证书,相互之间连接时使用的证书,如etcd节点之间进行验证和通信。

    这里全部都使用同一套证书认证。

    在 master01 节点上操作

    生成Etcd证书

    #准备cfssl证书生成工具

    上传 cfssl 、cfssljson、cfssl-certinfo到/usr/local/bin/cfssl 或

    wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -O /usr/local/bin/cfssl
    wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -O /usr/local/bin/cfssljson
    wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -O /usr/local/bin/cfssl-certinfo

    mkdir /opt/k8s
    cd /opt/k8s/

    #上传 etcd-cert.sh 、etcd-v3.4.9-linux-amd64.tar.gz和 etcd.sh 到 /opt/k8s/ 目录中
    chmod +x etcd-cert.sh etcd.sh

    创建用于生成CA证书、etcd 服务器证书以及私钥的目录
    mkdir /opt/k8s/etcd-cert
    mv etcd-cert.sh etcd-cert/
    cd /opt/k8s/etcd-cert/

    vim etcd-cert.sh
    ./etcd-cert.sh            #生成CA证书、etcd 服务器证书以及私钥

    ls
    ca-config.json  ca-csr.json  ca.pem        server.csr       server-key.pem
    ca.csr          ca-key.pem   etcd-cert.sh  server-csr.json  server.pem

    cd /opt/k8s/
    tar zxvf etcd-v3.4.9-linux-amd64.tar.gz
    ls etcd-v3.4.9-linux-amd64
    Documentation  etcd  etcdctl  README-etcdctl.md  README.md  READMEv2-etcdctl.md

    创建用于存放 etcd 配置文件,命令文件,证书的目录(master01)

    mkdir -p /opt/etcd/{cfg,bin,ssl}

    cd /opt/k8s/etcd-v3.4.9-linux-amd64/
    mv etcd etcdctl /opt/etcd/bin/
    cp /opt/k8s/etcd-cert/*.pem /opt/etcd/ssl/

    cd /opt/k8s/
    ./etcd.sh etcd01 192.168.30.100 etcd02=https://192.168.30.200:2380,etc03=https

    ://192.168.30.104:2380
    #进入卡住状态等待其他节点加入,这里需要三台etcd服务同时启动,如果只启动其中一台后,服务会卡在那里,直到集群中所有etcd节点都已启动,可忽略这个情况
    #可另外打开一个窗口查看etcd进程是否正常
    ps -ef | grep etcd

    把etcd相关证书文件、命令文件和服务管理文件全部拷贝到另外两个etcd集群节点(master01)

    scp -r /opt/etcd/ root@192.168.30.200:/opt/
    scp -r /opt/etcd/ root@192.168.30.104:/opt/
    scp /usr/lib/systemd/system/etcd.service root@192.168.30.200:/usr/lib/systemd/syste

    m
    scp /usr/lib/systemd/system/etcd.service root@192.168.30.104:/usr/lib/systemd/syste

    m

    在 node01 和node02节点上操作

    在 node01 节点上操作

    vim /opt/etcd/cfg/etcd
    #[Member]
    ETCD_NAME="etcd02"                                            #修改
    ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
    ETCD_LISTEN_PEER_URLS="https://192.168.30.200:2380"            #修改
    ETCD_LISTEN_CLIENT_URLS="https://192.168.30.200:2379"        #修改

    #[Clustering]
    ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.30.200:2380"        #修改
    ETCD_ADVERTISE_CLIENT_URLS="https://192.168.30.200:2379"                #修改
    ETCD_INITIAL_CLUSTER="etcd01=https://192.168.30.100:2380,etcd02=https://192.168.30.200:2380,etcd03=https://192.168.30.104:2380"
    ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
    ETCD_INITIAL_CLUSTER_STATE="new"

    #启动etcd服务
    systemctl start etcd
    systemctl enable etcd
    systemctl status etcd

    在 node02 节点上操作
    vim /opt/etcd/cfg/etcd
    #[Member]
    ETCD_NAME="etcd03"                                            #修改
    ETCD_DATA_DIR="/var/lib/etcd/default.etcd"
    ETCD_LISTEN_PEER_URLS="https://192.168.80.104:2380"            #修改
    ETCD_LISTEN_CLIENT_URLS="https://192.168.80.104:2379"        #修改

    #[Clustering]
    ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.80.12:2380"        #修改
    ETCD_ADVERTISE_CLIENT_URLS="https://192.168.30.104:2379"                #修改
    ETCD_INITIAL_CLUSTER="etcd01=https://192.168.30.100:2380,etcd02=https://192.168.30.200:2380,etcd03=https://192.168.30.104:2380"
    ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
    ETCD_INITIAL_CLUSTER_STATE="new"

    #启动etcd服务
    systemctl start etcd
    systemctl enable etcd
    systemctl status etcd

    #检查etcd群集状态
    ETCDCTL_API=3 /opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.30.100:2379,https://192.168.30.200:2379,https://192.168.30.104:2379" endpoint health --write-out=table

    ------------------------------------------------------------------------------------------

    #查看etcd集群成员列表
    ETCDCTL_API=3 /opt/etcd/bin/etcdctl --cacert=/opt/etcd/ssl/ca.pem --cert=/opt/etcd/ssl/server.pem --key=/opt/etcd/ssl/server-key.pem --endpoints="https://192.168.30.100:2379,https://192.168.30.200:2379,https://192.168.30.104:2379" --write-out=table member list
     

    node01

    node02

    master01

    部署 docker引擎

    所有 node 节点部署docker引擎

    yum install -y yum-utils device-mapper-persistent-data lvm2 
    yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo 
    yum install -y docker-ce docker-ce-cli containerd.io

    node01和node02

    vim /etc/docker/daemon.json

    {

      "registry-mirrors": ["https://6na95ym4.mirror.aliyuncs.com"],

      "exec-opts": ["native.cgroupdriver=systemd"],

      "log-driver": "json-file",

      "log-opts": {

        "max-size": "500m", "max-file": "3"

      }

    }

    systemctl start docker.service
    systemctl enable docker.service 

    部署 Master 组件

    master01 节点上操作

    #上传 master.zip 和 k8s-cert.sh 到 /opt/k8s 目录中,解压 master.zip 压缩包
    cd /opt/k8s/
    unzip master.zip
    chmod +x *.sh

    #创建kubernetes工作目录
    mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs}

    #创建用于生成CA证书、相关组件的证书和私钥的目录
    mkdir /opt/k8s/k8s-cert
    mv /opt/k8s/k8s-cert.sh /opt/k8s/k8s-cert
    cd /opt/k8s/k8s-cert/

    vim k8s-cert.sh
    ./k8s-cert.sh                #生成CA证书、相关组件的证书和私钥

    ls *pem
    admin-key.pem  apiserver-key.pem  ca-key.pem  kube-proxy-key.pem  
    admin.pem      apiserver.pem      ca.pem      kube-proxy.pem

     

    注:节点一开始做错了后转到master01上

    master01

    复制CA证书、apiserver相关证书和私钥到 kubernetes工作目录的 ssl 子目录中
    cp *.pem /opt/kubernetes/ssl/

    #上传 kubernetes-server-linux-amd64.tar.gz 到 /opt/k8s/ 目录中,解压 kubernetes 压缩包
    cd /opt/k8s/
    tar zxvf kubernetes-server-linux-amd64.tar.gz

    #复制master组件的关键命令文件到 kubernetes工作目录的 bin 子目录中
    cd /opt/k8s/kubernetes/server/bin
    cp kube-apiserver kubectl kube-controller-manager kube-scheduler /opt/kubernetes/bin/
    ln -s /opt/kubernetes/bin/* /usr/local/bin/

    #创建 bootstrap token 认证文件,apiserver 启动时会调用,然后就相当于在集群内创建了一个这个用户,接下来就可以用 RBAC 给他授权
    cd /opt/k8s/
    vim token.sh
    #!/bin/bash
    #获取随机数前16个字节内容,以十六进制格式输出,并删除其中空格
    BOOTSTRAP_TOKEN=$(head -c 16 /dev/urandom | od -An -t x | tr -d ' ')
    #生成 token.csv 文件,按照 Token序列号,用户名,UID,用户组 的格式生成
    cat > /opt/kubernetes/cfg/token.csv < ${BOOTSTRAP_TOKEN},kubelet-bootstrap,10001,"system:kubelet-bootstrap"
    EOF

    chmod +x token.sh
    ./token.sh

    cat /opt/kubernetes/cfg/token.csv

    #二进制文件、token、证书都准备好后,开启 apiserver 服务
    cd /opt/k8s/
    ./apiserver.sh 192.168.30.10 https://192.168.30.100:2379,https://192.168.30.200:2379,https://192.168.30.104:2379

    #检查进程是否启动成功
    ps aux | grep kube-apiserver

    netstat -natp | grep 6443   #安全端口6443用于接收HTTPS请求,用于基于Token文件或客户端证书等认证
     

    #二进制文件、token、证书都准备好后,开启 apiserver 服务
    cd /opt/k8s/
    ./apiserver.sh 192.168.30.100 https://192.168.30.100:2379,https://192.168.30.200:2379,https://192.168.30.104:2379

    #检查进程是否启动成功
    ps aux | grep kube-apiserver

    netstat -natp | grep 6443   #安全端口6443用于接收HTTPS请求,用于基于Token文件或客户端证书等认证


    #启动 scheduler 服务
    cd /opt/k8s/
    ./scheduler.sh
    ps aux | grep kube-scheduler

    #启动 controller-manager 服务
    ./controller-manager.sh
    ps aux | grep kube-controller-manager

    #生成kubectl连接集群的kubeconfig文件
    ./admin.sh

    #绑定默认cluster-admin管理员集群角色,授权kubectl访问集群
    kubectl create clusterrolebinding cluster-system-anonymous --clusterrole=cluster-admin --user=system:anonymous

    #通过kubectl工具查看当前集群组件状态
    kubectl get cs
    NAME                 STATUS    MESSAGE             ERROR
    controller-manager   Healthy   ok                  
    scheduler            Healthy   ok                  
    etcd-2               Healthy   {"health":"true"}   
    etcd-1               Healthy   {"health":"true"}   
    etcd-0               Healthy   {"health":"true"}  

    #查看版本信息
    kubectl version

    部署 Worker Node 组件

    在所有 node 节点上操作

    #创建kubernetes工作目录
    mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs}

    #上传 node.zip 到 /opt 目录中,解压 node.zip 压缩包,获得kubelet.sh、proxy.sh
    cd /opt/
    unzip node.zip
    chmod +x kubelet.sh proxy.sh

    master01 节点上操作

    #把 kubelet、kube-proxy 拷贝到 node 节点
    cd /opt/k8s/kubernetes/server/bin
    scp kubelet kube-proxy root@192.168.80.11:/opt/kubernetes/bin/
    scp kubelet kube-proxy root@192.168.80.12:/opt/kubernetes/bin/

    #上传kubeconfig.sh文件到/opt/k8s/kubeconfig目录中,生成kubelet初次加入集群引导kubeconfig文件和kube-proxy.kubeconfig文件
    #kubeconfig 文件包含集群参数(CA 证书、API Server 地址),客户端参数(上面生成的证书和私钥),集群 context 上下文参数(集群名称、用户名)。Kubenetes 组件(如 kubelet、kube-proxy)通过启动时指定不同的 kubeconfig 文件可以切换到不同的集群,连接到 apiserver。
    mkdir /opt/k8s/kubeconfig

    cd /opt/k8s/kubeconfig
    chmod +x kubeconfig.sh
    ./kubeconfig.sh 192.168.80.10 /opt/k8s/k8s-cert/

    #把配置文件 bootstrap.kubeconfig、kube-proxy.kubeconfig 拷贝到 node 节点
    scp bootstrap.kubeconfig kube-proxy.kubeconfig root@192.168.80.11:/opt/kubernetes/cfg/

    scp bootstrap.kubeconfig kube-proxy.kubeconfig root@192.168.80.12:/opt/kubernetes/cfg/

    #RBAC授权,使用户 kubelet-bootstrap 能够有权限发起 CSR 请求证书
    kubectl create clusterrolebinding kubelet-bootstrap --clusterrole=system:node-bootstrapper --user=kubelet-bootstrap
     

    在 所有node 节点上操作

    #启动 kubelet 服务
    cd /opt/
    ./kubelet.sh 192.168.80.11
    ps aux | grep kubelet

    在 master01 节点上操作

    #检查到 node01 节点的 kubelet 发起的 CSR 请求,Pending 表示等待集群给该节点签发证书
    kubectl get csr

    通过 CSR 请求

    kubectl certificate approve node-csr-name名

    #查看节点,由于网络插件还没有部署,节点会没有准备就绪 NotReady
    kubectl get node

    node01节点和node02节点操作

    #加载 ip_vs 模块
    for i in $(ls /usr/lib/modules/$(uname -r)/kernel/net/netfilter/ipvs|grep -o "^[^.]*");do echo $i; /sbin/modinfo -F filename $i >/dev/null 2>&1 && /sbin/modprobe $i;done

    #启动proxy服务
    cd /opt/
    ./proxy.sh 192.168.30.200
    ps aux | grep kube-proxy

     

    部署 CNI 网络组件

    node01和node02节点上操作

    #上传 cni-plugins-linux-amd64-v0.8.6.tgz 和 flannel.tar 到 /opt 目录中
    cd /opt/
    docker load -i flannel.tar

    mkdir /opt/cni/bin
    tar zxvf cni-plugins-linux-amd64-v0.8.6.tgz -C /opt/cni/bin

    将node01节点的 kube-flannel.yml 文件传给master01

    node02

    node01

     master01 节点上操作

    cd /opt

    kubectl get nodes   (若只有一个节点需执行以下步骤到对应节点)

    cat > /etc/docker/daemon.json < {
      "exec-opts": ["native.cgroupdriver=systemd"]
    }
    EOF

    systemctl restart  docker kubelet

    #上传 kube-flannel.yml 文件到 /opt/k8s 目录中,部署 CNI 网络
    cd /opt/k8s
    kubectl apply -f kube-flannel.yml 

    kubectl get pods -n kube-system或kubectl get pods -A

    kubectl get nodes

    master01节点

     node02节点  

    更换dokcer资源限制

    master01节点

    部署 Calico

    1. //在 master01 节点上操作
    2. #上传 calico.yaml 文件到 /opt/k8s 目录中,部署 CNI 网络
    3. cd /opt/k8s
    4. vim calico.yaml
    5. #修改里面定义Pod网络(CALICO_IPV4POOL_CIDR),与前面kube-controller-manager配置文件指定的cluster-cidr网段一样
    6. - name: CALICO_IPV4POOL_CIDR
    7. value: "192.168.0.0/16"
    8. kubectl apply -f calico.yaml
    9. kubectl get pods -n kube-system
    10. NAME READY STATUS RESTARTS AGE
    11. calico-kube-controllers-659bd7879c-4h8vk 1/1 Running 0 58s
    12. calico-node-nsm6b 1/1 Running 0 58s
    13. calico-node-tdt8v 1/1 Running 0 58s
    14. #等 Calico Pod 都 Running,节点也会准备就绪
    15. kubectl get nodes

    部署 CoreDNS

    在所有 node 节点上操作

    //在所有 node 节点上操作
    #上传 coredns.tar 到 /opt 目录中
    cd /opt
    docker load -i coredns.tar

    docker pull busybox:1.28.4

    /在 master01 节点上操作

    #上传 coredns.yaml 文件到 /opt/k8s 目录中,部署 CoreDNS 
    cd /opt/k8s
    kubectl apply -f coredns.yaml

    kubectl get pods -n kube-system 
    NAME                          READY   STATUS    RESTARTS   AGE
    coredns-5ffbfd976d-j6shb      1/1     Running   0          32s

    #DNS 解析测试

    kubectl run -it --rm dns-test --image=busybox:1.28.4 sh
    If you don't see a command prompt, try pressing enter.
    / # nslookup kubernetes

    多master高可用

    操作系统初始化配置 master02和master03设置

    #关闭防火墙 全部
    systemctl stop firewalld
    systemctl disable firewalld
    iptables -F && iptables -t nat -F && iptables -t mangle -F && iptables -X

    #关闭selinux 全部 
    setenforce 0
    vim /etc/selinux/config  disable
    或sed -i 's/enforcing/disabled/' /etc/selinux/config

    #关闭swap 全部
    swapoff -a
    sed -ri 's/.*swap.*/#&/' /etc/fstab 

    cat > /etc/sysctl.d/k8s.conf << EOF
    #开启网桥模式,可将网桥的流量传递给iptables链
    net.bridge.bridge-nf-call-ip6tables = 1
    net.bridge.bridge-nf-call-iptables = 1
    #关闭ipv6协议
    net.ipv6.conf.all.disable_ipv6=1
    net.ipv4.ip_forward=1
    EOF

    sysctl --system

    yum install ntpdate -y
    ntpdate time.windows.com或ntpdate ntp.aliyun.com

    master02

    master03

    所有节点添加更改hosts

    master01 节点上拷贝证书文件、各master组件的配置文件和服务管理文件到 master02 节点
    scp -r /opt/etcd/ root@192.168.80.20:/opt/
    scp -r /opt/kubernetes/ root@192.168.80.20:/opt
    scp /usr/lib/systemd/system/{kube-apiserver,kube-controller-manager,kube-scheduler}.service root@192.168.80.20:/usr/lib/systemd/system/

     

    修改配置文件kube-apiserver中的IP(master02 master03)

    master02设置

    vim /opt/kubernetes/cfg/kube-apiserver
    KUBE_APISERVER_OPTS="--logtostderr=true \
    --v=4 \
    --etcd-servers=https://192.168.30.100:2379,https://192.168.30.200:2379,https://192.168.30.104:2379 \
    --bind-address=192.168.30.105 \                #修改
    --secure-port=6443 \
    --advertise-address=192.168.30.105 \            #修改

    master03设置

    vim /opt/kubernetes/cfg/kube-apiserver
    KUBE_APISERVER_OPTS="--logtostderr=true \
    --v=4 \
    --etcd-servers=https://192.168.30.100:2379,https://192.168.30.200:2379,https://192.168.30.104:2379 \
    --bind-address=192.168.30.203 \                #修改
    --secure-port=6443 \
    --advertise-address=192.168.30.203 \            #修改

    将master01  .kube 复制到 master02和master03上

    scp -r .kube root@192.168.30.105:/opt

    scp -r .kube root@192.168.30.203:/opt

    master01节点

    master02节点

    将/opt中.kube移至家目录

    mv .kube/ ~

    master02节点

    master02 和master03节点上启动各服务并设置开机自启

    systemctl start kube-apiserver.service
    systemctl enable kube-apiserver.service
    systemctl start kube-controller-manager.service
    systemctl enable kube-controller-manager.service
    systemctl start kube-scheduler.service
    systemctl enable kube-scheduler.service

    查看node节点状态

    master02和master03节点

    ln -s /opt/kubernetes/bin/* /usr/local/bin/
    kubectl get nodes
    kubectl get nodes -o wide            #-o=wide:输出额外信息;对于Pod,将输出Pod所在的Node名

    负载均衡部署

     在lb01、lb02节点上操作

    配置load balancer集群双机热备负载均衡(nginx实现负载均衡,keepalived实现双机热备)

    //配置nginx的官方在线yum源,配置本地nginx的yum源
    cat > /etc/yum.repos.d/nginx.repo << 'EOF'
    [nginx]
    name=nginx repo
    baseurl=http://nginx.org/packages/centos/7/$basearch/
    gpgcheck=0
    EOF

    yum install nginx -y

    //修改nginx配置文件,配置四层反向代理负载均衡,指定k8s群集2台master的节点ip和6443端口
    vim /etc/nginx/nginx.conf
    events {
        worker_connections  1024;
    }

    #添加
    stream {

        upstream k8s-apiserver {
            server 192.168.30.100:6443;

            server 192.168.30.203:6443;

            server 192.168.30.105:6443;


        }
        server {
            listen 6443;
            proxy_pass k8s-apiserver;
        }
    }

    http {
    ......


    //检查配置文件语法
    nginx -t   

    //启动nginx服务,查看已监听6443端口
    systemctl start nginx
    systemctl enable nginx
    netstat -natp | grep nginx 

     在lb01、lb02节点上操作

    //部署keepalived服务
    yum install keepalived -y

    //修改keepalived配置文件
    vim /etc/keepalived/keepalived.conf
    ! Configuration File for keepalived

    global_defs {
       # 接收邮件地址
       notification_email {
         acassen@firewall.loc
         failover@firewall.loc
         sysadmin@firewall.loc
       }
       # 邮件发送地址
       notification_email_from Alexandre.Cassen@firewall.loc
       smtp_server 127.0.0.1
       smtp_connect_timeout 30
       router_id NGINX_MASTER    #lb01节点的为 NGINX_MASTER,lb02节点的为 NGINX_BACKUP
    }

    #添加一个周期性执行的脚本
    vrrp_script check_nginx {
        script "/etc/nginx/check_nginx.sh"    #指定检查nginx存活的脚本路径
    }

    vrrp_instance VI_1 {
        state MASTER            #lb01节点的为 MASTER,lb02节点的为 BACKUP
        interface ens33            #指定网卡名称 ens33
        virtual_router_id 51    #指定vrid,两个节点要一致
        priority 100            #lb01节点的为 100,lb02节点的为 90
        advert_int 1
        authentication {
            auth_type PASS
            auth_pass 1111
        }
        virtual_ipaddress {
            192.168.80.100/24    #指定 VIP
        }
        track_script {
            check_nginx            #指定vrrp_script配置的脚本
        }
    }

     

     在lb01、lb02节点上操作

    创建nginx状态检查脚本 
    vim /etc/nginx/check_nginx.sh
    #!/bin/bash
    #egrep -cv "grep|

    "grep" role="presentation" style="text-align: center; position: relative;">"grep
    表示的当前Shell进程ID
    count=$(ps -ef | grep nginx | egrep -cv "grep|$$")

    if [ "$count" -eq 0 ];then
        systemctl stop keepalived
    fi


    chmod +x /etc/nginx/check_nginx.sh

    //启动keepalived服务(一定要先启动了nginx服务,再启动keepalived服务)
    systemctl start keepalived
    systemctl enable keepalived
    ip a                #查看VIP是否生成

    lb02节点

    lb01节点

    node节点配置

    //修改node节点上的bootstrap.kubeconfig,kubelet.kubeconfig配置文件为VIP
    cd /opt/kubernetes/cfg/
    vim bootstrap.kubeconfig 
    server: https://192.168.80.100:6443
                          
    vim kubelet.kubeconfig
    server: https://192.168.80.100:6443
                            
    vim kube-proxy.kubeconfig
    server: https://192.168.80.100:6443

    //重启kubelet和kube-proxy服务
    systemctl restart kubelet.service 
    systemctl restart kube-proxy.service

    node01

    node02

    master02和master03上配置

    lb01 上查看 nginx 和 node 、 master 节点的连接状态

    netstat -natp | grep nginx

    master01 节点上操作

    //测试创建pod
    kubectl run nginx --image=nginx

    //查看Pod的状态信息
    kubectl get pods

     

    kubectl get pods
     

    kubectl get pods -o wide

    //READY为1/1,表示这个Pod中有1个容器

    //在对应网段的node节点上操作,可以直接使用浏览器或者curl命令访问
    curl 172.17.36.2

    //这时在master01节点上查看nginx日志,发现没有权限查看
    kubectl logs nginx-dbddb74b8-nf9sk

    在对应网段的node节点上操作,可以直接使用浏览器或者curl命令访问(node02)

    附件

    1.k8s-cert.sh脚本

    1.  #!/bin/bash
    2.  #配置证书生成策略,让 CA 软件知道颁发有什么功能的证书,生成用来签发其他组件证书的根证书
    3.  cat > ca-config.json <<EOF
    4.  {
    5.    "signing": {
    6.      "default": {
    7.        "expiry": "87600h"
    8.     },
    9.      "profiles": {
    10.        "kubernetes": {
    11.           "expiry": "87600h",
    12.           "usages": [
    13.              "signing",
    14.              "key encipherment",
    15.              "server auth",
    16.              "client auth"
    17.         ]
    18.       }
    19.     }
    20.   }
    21.  }
    22.  EOF
    23.  ​
    24.  #生成CA证书和私钥(根证书和私钥)
    25.  cat > ca-csr.json <<EOF
    26.  {
    27.      "CN": "kubernetes",
    28.      "key": {
    29.          "algo": "rsa",
    30.          "size": 2048
    31.     },
    32.      "names": [
    33.         {
    34.              "C": "CN",
    35.              "L": "Beijing",
    36.              "ST": "Beijing",
    37.              "O": "k8s",
    38.              "OU": "System"
    39.         }
    40.     ]
    41.  }
    42.  EOF
    43.  ​
    44.  cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
    45.  ​
    46.  ​
    47.  #-----------------------
    48.  #生成 apiserver 的证书和私钥(apiserver和其它k8s组件通信使用)
    49.  #hosts中将所有可能作为 apiserver 的 ip 添加进去,后面 keepalived 使用的VIP 也要加入
    50.  cat > apiserver-csr.json <<EOF
    51.  {
    52.      "CN": "kubernetes",
    53.      "hosts": [
    54.        "10.0.0.1",
    55.        "127.0.0.1",
    56.        "192.168.30.100",    #master01。使用脚本时,要将这5行注释删除
    57.        "192.168.30.105",    #master02
    58.        "192.168.30.10",   #vip,后面keepalived要用到
    59.        "192.168.30.14",    #负载均衡器01(master)
    60.        "192.168.30.15",    #负载均衡器02(backup)
    61.        "kubernetes",
    62.        "kubernetes.default",
    63.        "kubernetes.default.svc",
    64.        "kubernetes.default.svc.cluster",
    65.        "kubernetes.default.svc.cluster.local"
    66.     ],
    67.      "key": {
    68.          "algo": "rsa",
    69.          "size": 2048
    70.     },
    71.      "key": {
    72.          "algo": "rsa",
    73.          "size": 2048
    74.     },
    75.      "names": [
    76.         {
    77.              "C": "CN",
    78.              "L": "BeiJing",
    79.              "ST": "BeiJing",
    80.              "O": "k8s",
    81.              "OU": "System"
    82.         }
    83.     ]
    84.  }
    85.  EOF
    86.  ​
    87.  cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes apiserver-csr.json | cfssljson -bare apiserver
    88.  ​
    89.  ​
    90.  #-----------------------
    91.  #生成 kubectl 连接集群的证书和私钥,具有admin权限
    92.  cat > admin-csr.json <<EOF
    93.  {
    94.    "CN": "admin",
    95.    "hosts": [],
    96.    "key": {
    97.      "algo": "rsa",
    98.      "size": 2048
    99.   },
    100.    "names": [
    101.     {
    102.        "C": "CN",
    103.        "L": "BeiJing",
    104.        "ST": "BeiJing",
    105.        "O": "system:masters",
    106.        "OU": "System"
    107.     }
    108.   ]
    109.  }
    110.  EOF
    111.  ​
    112.  cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin
    113.  ​
    114.  ​
    115.  #-----------------------
    116.  #生成 kube-proxy 的证书和私钥
    117.  cat > kube-proxy-csr.json <<EOF
    118.  {
    119.    "CN": "system:kube-proxy",
    120.    "hosts": [],
    121.    "key": {
    122.      "algo": "rsa",
    123.      "size": 2048
    124.   },
    125.    "names": [
    126.     {
    127.        "C": "CN",
    128.        "L": "BeiJing",
    129.        "ST": "BeiJing",
    130.        "O": "k8s",
    131.        "OU": "System"
    132.     }
    133.   ]
    134.  }
    135.  EOF
    136.  ​
    137.  cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy

    2.apiserver.sh

    1.  #!/bin/bash
    2.  #example: apiserver.sh 192.168.30.100 https://192.168.30.100:2379,https://192.168.30.200:2379,https://192.168.30.104:2379
    3.  #创建 kube-apiserver 启动参数配置文件
    4.  MASTER_ADDRESS=$1
    5.  ETCD_SERVERS=$2
    6.  ​
    7.  cat >/opt/kubernetes/cfg/kube-apiserver <<EOF
    8.  KUBE_APISERVER_OPTS="--logtostderr=false \
    9.  --v=2 \
    10.  --log-dir=/opt/kubernetes/logs \
    11.  --etcd-servers=${ETCD_SERVERS} \
    12.  --bind-address=${MASTER_ADDRESS} \
    13.  --secure-port=6443 \
    14.  --advertise-address=${MASTER_ADDRESS} \
    15.  --allow-privileged=true \
    16.  --service-cluster-ip-range=10.0.0.0/24 \
    17.  --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,NodeRestriction \
    18.  --authorization-mode=RBAC,Node \
    19.  --enable-bootstrap-token-auth=true \
    20.  --token-auth-file=/opt/kubernetes/cfg/token.csv \
    21.  --service-node-port-range=30000-50000 \
    22.  --kubelet-client-certificate=/opt/kubernetes/ssl/apiserver.pem \
    23.  --kubelet-client-key=/opt/kubernetes/ssl/apiserver-key.pem \
    24.  --tls-cert-file=/opt/kubernetes/ssl/apiserver.pem \
    25.  --tls-private-key-file=/opt/kubernetes/ssl/apiserver-key.pem \
    26.  --client-ca-file=/opt/kubernetes/ssl/ca.pem \
    27.  --service-account-key-file=/opt/kubernetes/ssl/ca-key.pem \
    28.  --service-account-issuer=api \
    29.  --service-account-signing-key-file=/opt/kubernetes/ssl/apiserver-key.pem \
    30.  --etcd-cafile=/opt/k8s/etcd-cert/ca.pem \
    31.  --etcd-certfile=/opt/k8s/etcd-cert/server.pem \
    32.  --etcd-keyfile=/opt/k8s/etcd-cert/server-key.pem \
    33.  --requestheader-client-ca-file=/opt/kubernetes/ssl/ca.pem \
    34.  --proxy-client-cert-file=/opt/kubernetes/ssl/apiserver.pem \
    35.  --proxy-client-key-file=/opt/kubernetes/ssl/apiserver-key.pem \
    36.  --requestheader-allowed-names=kubernetes \
    37.  --requestheader-extra-headers-prefix=X-Remote-Extra- \
    38.  --requestheader-group-headers=X-Remote-Group \
    39.  --requestheader-username-headers=X-Remote-User \
    40.  --enable-aggregator-routing=true \
    41.  --audit-log-maxage=30 \
    42.  --audit-log-maxbackup=3 \
    43.  --audit-log-maxsize=100 \
    44.  --audit-log-path=/opt/kubernetes/logs/k8s-audit.log"
    45.  EOF
    46.  ​
    47.  #--logtostderr=true:启用日志。输出日志到标准错误控制台,不输出到文件
    48.  #--v=4:日志等级。指定输出日志的级别,v=4为调试级别详细输出
    49.  #--etcd-servers:etcd集群地址。指定etcd服务器列表(格式://ip:port),逗号分隔
    50.  #--bind-address:监听地址。指定 HTTPS 安全接口的监听地址,默认值0.0.0.0
    51.  #--secure-port:https安全端口。指定 HTTPS 安全接口的监听端口,默认值6443
    52.  #--advertise-address:集群通告地址。通过该 ip 地址向集群其他节点公布 api server 的信息,必须能够被其他节点访问
    53.  #--allow-privileged=true:启用授权。允许拥有系统特权的容器运行,默认值false
    54.  #--service-cluster-ip-range:Service虚拟IP地址段。指定 Service Cluster IP 地址段
    55.  #--enable-admission-plugins:准入控制模块。kuberneres集群的准入控制机制,各控制模块以>插件的形式依次生效,集群时必须包含ServiceAccount,运行在认证(Authentication)、授权(Authorization)之后,Admission Control是权限认证链上的最后一环, 对请求API资源对象进行修改和校验
    56.  #--authorization-mode:认证授权,启用RBAC授权和节点自管理。在安全端口使用RBAC,Node授权模式,未通过授权的请求拒绝,默认值AlwaysAllow。RBAC是用户通过角色与权限进行关联的模式>;Node模式(节点授权)是一种特殊用途的授权模式,专门授权由kubelet发出的API请求,在进行认证时,先通过用户名、用户分组验证是否是集群中的Node节点,只有是Node节点的请求才能使用Node模式授权
    57.  #--enable-bootstrap-token-auth:启用TLS bootstrap机制。在apiserver上启用Bootstrap Token 认证
    58.  #--token-auth-file=/opt/kubernetes/cfg/token.csv:指定bootstrap token认证文件路径
    59.  #--service-node-port-range:指定 Service NodePort 的端口范围,默认值30000-32767
    60.  #–-kubelet-client-xxx:apiserver访问kubelet客户端证书
    61.  #--tls-xxx-file:apiserver https证书
    62.  #1.20版本必须加的参数:–-service-account-issuer,–-service-account-signing-key-file
    63.  #--etcd-xxxfile:连接Etcd集群证书
    64.  #–-audit-log-xxx:审计日志
    65.  #启动聚合层相关配置:–requestheader-client-ca-file,–proxy-client-cert-file,–proxy-client-key-file,–requestheader-allowed-names,–requestheader-extra-headers-prefix,–requestheader-group-headers,–requestheader-username-headers,–enable-aggregator-routing
    66.  ​
    67.  #创建 kube-apiserver.service 服务管理文件
    68.  cat >/usr/lib/systemd/system/kube-apiserver.service <<EOF
    69.  [Unit]
    70.  Description=Kubernetes API Server
    71.  Documentation=https://github.com/kubernetes/kubernetes
    72.  ​
    73.  [Service]
    74.  EnvironmentFile=-/opt/kubernetes/cfg/kube-apiserver
    75.  ExecStart=/opt/kubernetes/bin/kube-apiserver $KUBE_APISERVER_OPTS
    76.  Restart=on-failure
    77.  ​
    78.  [Install]
    79.  WantedBy=multi-user.target
    80.  EOF
    81.  ​
    82.  systemctl daemon-reload
    83.  systemctl enable kube-apiserver
    84.  systemctl restart kube-apiserver

    3.scheduler.sh

    1.  #!/bin/bash
    2.  ##创建 kube-scheduler 启动参数配置文件
    3.  MASTER_ADDRESS=$1
    4.  ​
    5.  cat >/opt/kubernetes/cfg/kube-scheduler <<EOF
    6.  KUBE_SCHEDULER_OPTS="--logtostderr=false \
    7.  --v=2 \
    8.  --log-dir=/opt/kubernetes/logs \
    9.  --leader-elect=true \
    10.  --kubeconfig=/opt/kubernetes/cfg/kube-scheduler.kubeconfig \
    11.  --bind-address=127.0.0.1"
    12.  EOF
    13.  ​
    14.  #-–kubeconfig:连接 apiserver 用的配置文件,用于识别 k8s 集群
    15.  #--leader-elect=true:当该组件启动多个时,自动启动 leader 选举
    16.  #k8s中Controller-Manager和Scheduler的选主逻辑:k8s中的etcd是整个集群所有状态信>息的存储,涉及数据的读写和多个etcd之间数据的同步,对数据的一致性要求严格,所以>使用较复杂的 raft 算法来选择用于提交数据的主节点。而 apiserver 作为集群入口,本身是无状态的web服务器,多个 apiserver 服务之间直接负载请求并不需要做选主。Controller-Manager 和 Scheduler 作为任务类型的组件,比如 controller-manager 内置的 k8s 各种资源对象的控制器实时的 watch apiserver 获取对象最新的变化事件做期望状态>和实际状态调整,调度器watch未绑定节点的pod做节点选择,显然多个这些任务同时工作>是完全没有必要的,所以 controller-manager 和 scheduler 也是需要选主的,但是选主逻辑和 etcd 不一样的,这里只需要保证从多个 controller-manager 和 scheduler 之间选出一个 leader 进入工作状态即可,而无需考虑它们之间的数据一致和同步。
    17.  ​
    18.  ​
    19.  ##生成kube-scheduler证书
    20.  cd /opt/k8s/k8s-cert/
    21.  #创建证书请求文件
    22.  cat > kube-scheduler-csr.json << EOF
    23.  {
    24.    "CN": "system:kube-scheduler",
    25.    "hosts": [],
    26.    "key": {
    27.      "algo": "rsa",
    28.      "size": 2048
    29.   },
    30.    "names": [
    31.     {
    32.        "C": "CN",
    33.        "L": "BeiJing",
    34.        "ST": "BeiJing",
    35.        "O": "system:masters",
    36.        "OU": "System"
    37.     }
    38.   ]
    39.  }
    40.  EOF
    41.  ​
    42.  #生成证书
    43.  cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-scheduler-csr.json | cfssljson -bare kube-scheduler
    44.  ​
    45.  ​
    46.  #生成kubeconfig文件
    47.  KUBE_CONFIG="/opt/kubernetes/cfg/kube-scheduler.kubeconfig"
    48.  KUBE_APISERVER="https://192.168.41.10:6443"   #master01的IP
    49.  ​
    50.  kubectl config set-cluster kubernetes \
    51.    --certificate-authority=/opt/kubernetes/ssl/ca.pem \
    52.    --embed-certs=true \
    53.    --server=${KUBE_APISERVER} \
    54.    --kubeconfig=${KUBE_CONFIG}
    55.  kubectl config set-credentials kube-scheduler \
    56.    --client-certificate=./kube-scheduler.pem \
    57.    --client-key=./kube-scheduler-key.pem \
    58.    --embed-certs=true \
    59.    --kubeconfig=${KUBE_CONFIG}
    60.  kubectl config set-context default \
    61.    --cluster=kubernetes \
    62.    --user=kube-scheduler \
    63.    --kubeconfig=${KUBE_CONFIG}
    64.  kubectl config use-context default --kubeconfig=${KUBE_CONFIG}
    65.  ​
    66.  ​
    67.  ##创建 kube-scheduler.service 服务管理文件
    68.  cat >/usr/lib/systemd/system/kube-scheduler.service <<EOF
    69.  [Unit]
    70.  Description=Kubernetes Scheduler
    71.  Documentation=https://github.com/kubernetes/kubernetes
    72.  ​
    73.  [Service]
    74.  EnvironmentFile=-/opt/kubernetes/cfg/kube-scheduler
    75.  ExecStart=/opt/kubernetes/bin/kube-scheduler $KUBE_SCHEDULER_OPTS
    76.  Restart=on-failure
    77.  ​
    78.  [Install]
    79.  WantedBy=multi-user.target
    80.  EOF
    81.  ​
    82.  systemctl daemon-reload
    83.  systemctl enable kube-scheduler
    84.  systemctl restart kube-scheduler

    4.

    1.  #!/bin/bash
    2.  ##创建 kube-scheduler 启动参数配置文件
    3.  MASTER_ADDRESS=$1
    4.  ​
    5.  cat >/opt/kubernetes/cfg/kube-scheduler <<EOF
    6.  KUBE_SCHEDULER_OPTS="--logtostderr=false \
    7.  --v=2 \
    8.  --log-dir=/opt/kubernetes/logs \
    9.  --leader-elect=true \
    10.  --kubeconfig=/opt/kubernetes/cfg/kube-scheduler.kubeconfig \
    11.  --bind-address=127.0.0.1"
    12.  EOF
    13.  ​
    14.  #-–kubeconfig:连接 apiserver 用的配置文件,用于识别 k8s 集群
    15.  #--leader-elect=true:当该组件启动多个时,自动启动 leader 选举
    16.  #k8s中Controller-Manager和Scheduler的选主逻辑:k8s中的etcd是整个集群所有状态信>息的存储,涉及数据的读写和多个etcd之间数据的同步,对数据的一致性要求严格,所以>使用较复杂的 raft 算法来选择用于提交数据的主节点。而 apiserver 作为集群入口,本身是无状态的web服务器,多个 apiserver 服务之间直接负载请求并不需要做选主。Controller-Manager 和 Scheduler 作为任务类型的组件,比如 controller-manager 内置的 k8s 各种资源对象的控制器实时的 watch apiserver 获取对象最新的变化事件做期望状态>和实际状态调整,调度器watch未绑定节点的pod做节点选择,显然多个这些任务同时工作>是完全没有必要的,所以 controller-manager 和 scheduler 也是需要选主的,但是选主逻辑和 etcd 不一样的,这里只需要保证从多个 controller-manager 和 scheduler 之间选出一个 leader 进入工作状态即可,而无需考虑它们之间的数据一致和同步。
    17.  ​
    18.  ​
    19.  ##生成kube-scheduler证书
    20.  cd /opt/k8s/k8s-cert/
    21.  #创建证书请求文件
    22.  cat > kube-scheduler-csr.json << EOF
    23.  {
    24.    "CN": "system:kube-scheduler",
    25.    "hosts": [],
    26.    "key": {
    27.      "algo": "rsa",
    28.      "size": 2048
    29.   },
    30.    "names": [
    31.     {
    32.        "C": "CN",
    33.        "L": "BeiJing",
    34.        "ST": "BeiJing",
    35.        "O": "system:masters",
    36.        "OU": "System"
    37.     }
    38.   ]
    39.  }
    40.  EOF
    41.  ​
    42.  #生成证书
    43.  cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-scheduler-csr.json | cfssljson -bare kube-scheduler
    44.  ​
    45.  ​
    46.  #生成kubeconfig文件
    47.  KUBE_CONFIG="/opt/kubernetes/cfg/kube-scheduler.kubeconfig"
    48.  KUBE_APISERVER="https://192.168.41.10:6443"   #master01的IP
    49.  ​
    50.  kubectl config set-cluster kubernetes \
    51.    --certificate-authority=/opt/kubernetes/ssl/ca.pem \
    52.    --embed-certs=true \
    53.    --server=${KUBE_APISERVER} \
    54.    --kubeconfig=${KUBE_CONFIG}
    55.  kubectl config set-credentials kube-scheduler \
    56.    --client-certificate=./kube-scheduler.pem \
    57.    --client-key=./kube-scheduler-key.pem \
    58.    --embed-certs=true \
    59.    --kubeconfig=${KUBE_CONFIG}
    60.  kubectl config set-context default \
    61.    --cluster=kubernetes \
    62.    --user=kube-scheduler \
    63.    --kubeconfig=${KUBE_CONFIG}
    64.  kubectl config use-context default --kubeconfig=${KUBE_CONFIG}
    65.  ​
    66.  ​
    67.  ##创建 kube-scheduler.service 服务管理文件
    68.  cat >/usr/lib/systemd/system/kube-scheduler.service <<EOF
    69.  [Unit]
    70.  Description=Kubernetes Scheduler
    71.  Documentation=https://github.com/kubernetes/kubernetes
    72.  ​
    73.  [Service]
    74.  EnvironmentFile=-/opt/kubernetes/cfg/kube-scheduler
    75.  ExecStart=/opt/kubernetes/bin/kube-scheduler $KUBE_SCHEDULER_OPTS
    76.  Restart=on-failure
    77.  ​
    78.  [Install]
    79.  WantedBy=multi-user.target
    80.  EOF
    81.  ​
    82.  systemctl daemon-reload
    83.  systemctl enable kube-scheduler
    84.  systemctl restart kube-scheduler

    4.controller-manager.sh

    1. #!/bin/bash
    2.  ##创建 kube-controller-manager 启动参数配置文件
    3.  MASTER_ADDRESS=$1
    4.  ​
    5.  cat >/opt/kubernetes/cfg/kube-controller-manager <<EOF
    6.  KUBE_CONTROLLER_MANAGER_OPTS="--logtostderr=false \
    7.  --v=2 \
    8.  --log-dir=/opt/kubernetes/logs \
    9.  --leader-elect=true \
    10.  --kubeconfig=/opt/kubernetes/cfg/kube-controller-manager.kubeconfig \
    11.  --bind-address=127.0.0.1 \
    12.  --allocate-node-cidrs=true \
    13.  --cluster-cidr=10.244.0.0/16 \
    14.  --service-cluster-ip-range=10.0.0.0/24 \
    15.  --cluster-signing-cert-file=/opt/kubernetes/ssl/ca.pem \
    16.  --cluster-signing-key-file=/opt/kubernetes/ssl/ca-key.pem \
    17.  --root-ca-file=/opt/kubernetes/ssl/ca.pem \
    18.  --service-account-private-key-file=/opt/kubernetes/ssl/ca-key.pem \
    19.  --cluster-signing-duration=87600h0m0s"
    20.  EOF
    21.  ​
    22.  #––leader-elect:当该组件启动多个时,自动选举(HA)
    23.  #-–kubeconfig:连接 apiserver 用的配置文件,用于识别 k8s 集群
    24.  #--cluster-cidr=10.244.0.0/16:pod资源的网段,需与pod网络插件的值设置一致。通常,Flannel网络插件的默认为10.244.0.0/16,Calico插件的默认值为192.168.0.0/16
    25.  #--cluster-signing-cert-file/–-cluster-signing-key-file:自动为kubelet颁发证书>的CA,与apiserver保持一致。指定签名的CA机构根证书,用来签名为 TLS BootStrapping 创建的证书和私钥
    26.  #--root-ca-file:指定根CA证书文件路径,用来对 kube-apiserver 证书进行校验,指定该参数后,才会在 Pod 容器的 ServiceAccount 中放置该 CA 证书文件
    27.  #--experimental-cluster-signing-duration:设置为 TLS BootStrapping 签署的证书有效时间为10年,默认为1年
    28.  ​
    29.  ​
    30.  ##生成kube-controller-manager证书
    31.  cd /opt/k8s/k8s-cert/
    32.  #创建证书请求文件
    33.  cat > kube-controller-manager-csr.json << EOF
    34.  {
    35.    "CN": "system:kube-controller-manager",
    36.    "hosts": [],
    37.    "key": {
    38.      "algo": "rsa",
    39.      "size": 2048
    40.   },
    41.    "names": [
    42.     {
    43.        "C": "CN",
    44.        "L": "BeiJing",
    45.        "ST": "BeiJing",
    46.        "O": "system:masters",
    47.        "OU": "System"
    48.     }
    49.   ]
    50.  }
    51.  EOF
    52.  ​
    53.  ​
    54.  #生成证书
    55.  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
    56.  ​
    57.  #生成kubeconfig文件
    58.  KUBE_CONFIG="/opt/kubernetes/cfg/kube-controller-manager.kubeconfig"
    59.  KUBE_APISERVER="https://192.168.41.10:6443"   #master01的IP
    60.  ​
    61.  kubectl config set-cluster kubernetes \
    62.    --certificate-authority=/opt/kubernetes/ssl/ca.pem \
    63.    --embed-certs=true \
    64.    --server=${KUBE_APISERVER} \
    65.    --kubeconfig=${KUBE_CONFIG}
    66.  kubectl config set-credentials kube-controller-manager \
    67.    --client-certificate=./kube-controller-manager.pem \
    68.    --client-key=./kube-controller-manager-key.pem \
    69.    --embed-certs=true \
    70.    --kubeconfig=${KUBE_CONFIG}
    71.  kubectl config set-context default \
    72.    --cluster=kubernetes \
    73.    --user=kube-controller-manager \
    74.    --kubeconfig=${KUBE_CONFIG}
    75.  kubectl config use-context default --kubeconfig=${KUBE_CONFIG}
    76.  ​
    77.  ​
    78.  ##创建 kube-controller-manager.service 服务管理文件
    79.  cat >/usr/lib/systemd/system/kube-controller-manager.service <<EOF
    80.  [Unit]
    81.  Description=Kubernetes Controller Manager
    82.  Documentation=https://github.com/kubernetes/kubernetes
    83.  ​
    84.  [Service]
    85.  EnvironmentFile=-/opt/kubernetes/cfg/kube-controller-manager
    86.  ExecStart=/opt/kubernetes/bin/kube-controller-manager $KUBE_CONTROLLER_MANAGER_OPTS
    87.  Restart=on-failure
    88.  ​
    89.  [Install]
    90.  WantedBy=multi-user.target
    91.  EOF
    92.  ​
    93.  ​
    94.  systemctl daemon-reload
    95.  systemctl enable kube-controller-manager
    96.  systemctl restart kube-controller-manager

    5.admin.sh

    1.  #!/bin/bash
    2.  mkdir /root/.kube
    3.  KUBE_CONFIG="/root/.kube/config"
    4.  KUBE_APISERVER="https://192.168.30.100:6443"   #master01的IP
    5.  ​
    6.  cd /opt/k8s/k8s-cert/
    7.  ​
    8.  kubectl config set-cluster kubernetes \
    9.    --certificate-authority=/opt/kubernetes/ssl/ca.pem \
    10.    --embed-certs=true \
    11.    --server=${KUBE_APISERVER} \
    12.    --kubeconfig=${KUBE_CONFIG}
    13.  kubectl config set-credentials cluster-admin \
    14.    --client-certificate=./admin.pem \
    15.    --client-key=./admin-key.pem \
    16.    --embed-certs=true \
    17.    --kubeconfig=${KUBE_CONFIG}
    18.  kubectl config set-context default \
    19.    --cluster=kubernetes \
    20.    --user=cluster-admin \
    21.    --kubeconfig=${KUBE_CONFIG}
    22.  kubectl config use-context default --kubeconfig=${KUBE_CONFIG}

    总结:

    etcd数据库:

    • 分布式键值对型的数据库,服务发现系统(之前的docker-consul 就是服务发现)
    • go语言开发的,使用raft-a致性算法
    • 部署集群时需要3台或以上的奇数台
    • 2379 对外(客户端)通信的端口
    • 2380 对内(集群内部节点间)通信的端口

    etcd安装步骤:

    1. 使用CFSSL工具,生成ca证书和私钥文件,再使用ca签发服务端证书和私钥文件
    2. 使用ca证书、服务端证书和私钥文件加上etcd集群配置文件,去启动etcd服务
    3. 解压etcd软件包
    4. 复制etcd工作目录和服务管理文件到另外几个节点上,修改etcd集群配置文件并启动etcd服务
    5. 使用v3版本的接口执行etcdctl +证书选项+ (endpoint health | endpoint status | member list) 查看etcd 集群和节点状态

    正常情况etcd应该生成三套证书:客户端证书,服务端证书,对等体证书(内部)。初学者可以先只生成两套。

    master组件安装步骤:

    1.先安装apiserver

    • 准备组件的相关证书和私钥文件
    • 准备bootstraptoken认证文件(给kubelet启动时签发证书时使用)
    • 准备组件的启动配置文件
    • 启动apiserver 服务、端口号、6443、https

    2.再启动controller-manager 和scheduler

    • 准备启动配置文件
    • 准备证书和私钥文件生成kubeconfig 文件(用于指定对接哪个apiserver,使用什么证书认证)
    • 启动服务

    3.检查集群组件状态

    • 需要准备kubeconfig 文件,把kubectl 加入到集群中( 指定对接哪个apiserver,使用什么证书认证)
    • kubectl get cs

    多master部署步骤:

    1. 先部署master92等其它master节点
    2. 搭建Nginx/Haproxy + keepalived 高可用 负载均衡对接
    3. master节点群集
    4. 修改node 节点上的kubelet kube-proxy 的kubeconfig 配置文件对接vip
    5. kubectl的配置文件也要对接VIP或者当前节点的IP

  • 相关阅读:
    算法:堆排序
    升级 webpack5 + vue-cli5
    Java—字节流
    微信小程序开发17 日志监控:怎样面向业务设计日志方案?
    Golang字符串处理
    【Linux】常见指令汇总
    SpringCloud学习笔记万字整理(无广版在博客)
    竞赛 深度学习交通车辆流量分析 - 目标检测与跟踪 - python opencv
    “我升职的原因是:比同事更早学会这个知识”
    Android 10 分区存储
  • 原文地址:https://blog.csdn.net/Besteady/article/details/134263281