• 二进制部署k8s v1.22.15(玩就玩最难的)


    前言

    环境:centos 7.9 、内核:5.4.216-1.el7.elrepo.x86_64、k8s v1.22.15、etcd-v3.4.21

    众所周知,kubeadm部署的k8s是以pod运行组件的,而二进制部署k8s是以系统服务运行组件,所以,二进制部署的k8s更利于后期的k8s维护。让你排查问题更有底气。

    Dockerv1.23 版本时被从 Kubelet 中移除,取而代之的将是containerd作为容器运行时,所以本次安装k8s的v1.22版本,还是使用我们熟悉的docker作为容器运行时。

    下载k8s二进制包

    下载一个包就够了,里面包含了master和node的组件:
    进入 https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.22.md ,我们选择v1.22.15版本点击Server Binaries,然后就会跳转到https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.22.md#server-binaries
    我们选择kubernetes-server-linux-amd64.tar.gz进行下载。
    完整的下载URL为:https://dl.k8s.io/v1.22.15/kubernetes-server-linux-amd64.tar.gz

    下载etcd安装包

    打开下载页面:https://github.com/etcd-io/etcd/releases/tag/v3.4.21
    完整下载URL:https://github.com/etcd-io/etcd/releases/download/v3.4.21/etcd-v3.4.21-linux-amd64.tar.gz
    
    • 1
    • 2

    主机规划

    准备3台虚拟机,1个master,2个node节点,如下:

    主机说明
    master192.168.118.140,能连外网,centos7.9版本,内核:5.4.216-1.el7.elrepo.x86_64,至少2核CPU,2G内存
    node1192.168.118.141,能连外网,centos7.9版本,内核:5.4.216-1.el7.elrepo.x86_64,至少2核CPU,2G内存
    node2192.168.118.142,能连外网,centos7.9版本,内核:5.4.216-1.el7.elrepo.x86_64,至少2核CPU,2G内存

    设置主机名(所有主机都执行)

    hostnamectl set-hostname master  192.168.118.140	#在master主机执行
    hostnamectl set-hostname node1   192.168.118.141	#在node1主机执行
    hostnamectl set-hostname node2   192.168.118.142	#在node2主机执行
    
    #写入配置文件进行本地域名解析,在所有主机执行
    cat >> /etc/hosts <<EOF
    192.168.118.140 master
    192.168.118.141 node1
    192.168.118.142 node2
    EOF
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    关闭防火墙(所有主机都执行)

    [root@master ~]# systemctl stop firewalld			#关闭防火墙
    [root@master ~]# systemctl disable firewalld		#设置开机不启动
    
    • 1
    • 2

    禁用selinux(所有主机都执行)

    [root@master ~]# setenforce 0						#临时关闭selinux
    [root@master ~]# getenforce 						#查看selinux状态
    Permissive
    [root@master ~]# vim /etc/selinux/config			#永久关闭selinux
    SELINUX=disabled
    
    • 1
    • 2
    • 3
    • 4
    • 5

    关闭swap分区(所有主机都执行,因为k8s官网要求关闭swap)

    [root@master ~]# swapoff -a							#禁用所有swap交换分区
    [root@master ~]# free -h
                  total        used        free      shared  buff/cache   available
    Mem:           1.8G        280M        1.2G        9.6M        286M        1.4G
    Swap:            0B          0B          0B
    [root@master ~]# vim /etc/fstab						#永久禁用swap,删除或注释掉/etc/fstab里的swap设备的挂载命令即可
    #/dev/mapper/centos-swap swap                    swap    defaults        0 0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    时间同步(所有主机都执行)

    yum install chrony -y && systemctl enable --now chronyd
    
    • 1

    桥接的IPv4流量传递到iptables的链(所有主机都执行)

    将桥接的IPv4流量传递到iptables的链(有一些ipv4的流量不能走iptables链,因为linux内核的一个过滤器,每个流量都会经过他,然后再匹配是否可进入当前应用进程去处理,所以会导致流量丢失),配置k8s.conf文件(k8s.conf文件原来不存在,需要自己创建的)

    [root@master sysctl.d]# touch /etc/sysctl.d/k8s.conf				#创建k8s.conf文件
    [root@master sysctl.d]# cat >> /etc/sysctl.d/k8s.conf <
    > net.bridge.bridge-nf-call-ip6tables=1
    > net.bridge.bridge-nf-call-iptables=1
    > net.ipv4.ip_forward=1
    > vm.swappiness=0
    > EOF
    [root@master sysctl.d]# sysctl --system								#重新加载系统全部参数,或者使用sysctl -p亦可
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    升级linux内核到5.4.221-1

    参考链接:https://blog.csdn.net/MssGuo/article/details/127184206

    安装docker

    在所有节点服务器上都执行,因为k8s默认CRI为docker,cri称之为容器运行时:
    #在所有3台虚拟机上都要安装docker

    [root@master ~]# yum remove docker 									#先删除旧的docker版本
                       docker-client \
                       docker-client-latest \
                       docker-common \
                       docker-latest \
                       docker-latest-logrotate \
                       docker-logrotate \
                       docker-engine
    [root@master ~]# yum install -y yum-utils							#安装yum-utils,主要提供yum-config-manager命令
    [root@master ~]# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo	#下载并安装docker的repo仓库
    [root@master ~]# yum list docker-ce --showduplicates | sort -r							#查看可获取的docker版本
    [root@master ~]# yum -y install docker-ce docker-ce-cli containerd.io					#直接安装最新的docker版本
    [root@master ~]# yum -y install docker-ce-20.10.9 docker-ce-cli-20.10.9 containerd.io	#或者安装指定版本
    [root@master ~]# systemctl enable docker												#设置开机自启
    [root@master ~]# systemctl start docker													#启动docker
    [root@master ~]# cat /etc/docker/daemon.json 											#设置镜像加速器
    {
        "registry-mirrors": ["https://b9pmyelo.mirror.aliyuncs.com"],
        "exec-opts": ["native.cgroupdriver=systemd"]
    }
    [root@master ~]# systemctl restart docker												#重启docker
    [root@master ~]# docker info |tail -5													#检查加速器配置是否成功
      127.0.0.0/8
     Registry Mirrors:
      https://b9pmyelo.mirror.aliyuncs.com/													#加速器配置成功,仓库已经是阿里云
     Live Restore Enabled: false
    
    [root@master ~]#
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    安装cfssl证书生成工具

    cfssl是一个开源的证书管理工具,使用json文件生成证书,相比openssl更方便使用,找任意一台服务器操作来安装,生成证书即可,这里用Master节点。

    wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64
    wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64
    wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64
    chmod +x cfssl_linux-amd64 cfssljson_linux-amd64 cfssl-certinfo_linux-amd64
    mv cfssl_linux-amd64 /usr/local/bin/cfssl
    mv cfssljson_linux-amd64 /usr/local/bin/cfssljson
    mv cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    生成Etcd证书

    1、自签证书颁发机构(CA)

    mkdir -p /opt/TLS/etcd		#创建etcd证书存放目录
    
    • 1
    #自签CA
    cd /opt/TLS/etcd
    cat > ca-config.json << EOF
    {
      "signing": {
        "default": {
          "expiry": "87600h"
        },
        "profiles": {
          "www": {
             "expiry": "87600h",
             "usages": [
                "signing",
                "key encipherment",
                "server auth",
                "client auth"
            ]
          }
        }
      }
    }
    EOF
    
    cat > ca-csr.json << EOF
    {
        "CN": "etcd CA",
        "key": {
            "algo": "rsa",
            "size": 2048
        },
        "names": [
            {
                "C": "CN",
                "L": "Shenzhen",
                "ST": "Shenzhen"
            }
        ]
    }
    EOF
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    # 生成证书,会生成ca.pem和ca-key.pem文件
    cd /opt/TLS/etcd
    cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
    
    [root@matser etcd]# ll				#生成了好多ca证书
    -rw-r--r--. 1 root root  287 111 15:23 ca-config.json
    -rw-r--r--. 1 root root  956 111 15:25 ca.csr
    -rw-r--r--. 1 root root  211 111 15:23 ca-csr.json
    -rw-------. 1 root root 1679 111 15:25 ca-key.pem
    -rw-r--r--. 1 root root 1273 111 15:25 ca.pem
    [root@matser etcd]#
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2、 使用自签CA签发Etcd HTTPS证书
    创建证书申请文件:

    注:下面文件hosts字段中IP为所有etcd节点的集群内部通信IP,一个都不能少,为了方便后期扩容可以多写几个预留的IP
    cd /opt/TLS/etcd
    cat > server-csr.json << EOF
    {
        "CN": "etcd",
        "hosts": [
        "192.168.118.140",
        "192.168.118.141",
        "192.168.118.142"
        ],
        "key": {
            "algo": "rsa",
            "size": 2048
        },
        "names": [
            {
                "C": "CN",
                "L": "Shenzhen",
                "ST": "Shenzhen"
            }
        ]
    }
    EOF
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    生成证书:

    cd /opt/TLS/etcd
    #会生成server.pem和server-key.pem文件
    cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=www server-csr.json | cfssljson -bare server
    
    • 1
    • 2
    • 3

    查看所有证书:

    root@matser etcd]# ll
    总用量 36
    -rw-r--r--. 1 root root  287 111 15:23 ca-config.json
    -rw-r--r--. 1 root root  956 111 15:25 ca.csr
    -rw-r--r--. 1 root root  211 111 15:23 ca-csr.json
    -rw-------. 1 root root 1679 111 15:25 ca-key.pem
    -rw-r--r--. 1 root root 1273 111 15:25 ca.pem
    -rw-r--r--. 1 root root 1017 111 15:37 server.csr
    -rw-r--r--. 1 root root  298 111 15:34 server-csr.json
    -rw-------. 1 root root 1675 111 15:37 server-key.pem
    -rw-r--r--. 1 root root 1342 111 15:37 server.pem
    [root@matser etcd]# 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    部署etcd集群

    为了节省资源,我们直接在master、node1、node2、3台服务器上部署etcd集群,在企业生产环境中建议另外分配服务器来部署etcd集群:

    #创建etcd的目录,bin目录存放可执行文件,config存放配置文件,ssl存放证书文件,data存放数据文件
    mkdir  -p /opt/etcd/{bin,config,ssl,data}
    #解压源码包
    tar  -zxvf etcd-v3.4.21-linux-amd64.tar.gz
    #复制可执行文件到etcd的目录
    cp etcd-v3.4.21-linux-amd64/{etcd,etcdctl} /opt/etcd/bin/
    
    #编写一个etcd配置文件
    vim /opt/etcd/config/etcd.conf
    #[Member]
    #1.节点名称,必须唯一
    ETCD_NAME="etcd-1"
    #2.设置数据保存的目录
    ETCD_DATA_DIR="/opt/etcd/data"
    #3.用于监听其他etcd member的url(集群通信监听地址)
    ETCD_LISTEN_PEER_URLS="https://192.168.118.130:2380"
    #4.该节点对外提供服务的地址(客户端访问的监听地址)
    ETCD_LISTEN_CLIENT_URLS="https://192.168.118.130:2379"
    
    #[Clustering]
    #5.客户端访问的监听地址
    ETCD_ADVERTISE_CLIENT_URLS="https://192.168.118.130:2379"
    #6.该节点成员对等URL地址,且会通告集群的其余成员节点(集群通告的监听地址)
    ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.118.130:2380"
    #7.集群中所有节点的信息
    ETCD_INITIAL_CLUSTER="etcd-1=https://192.168.118.130:2380,etcd-2=https://192.168.118.140:2380,etcd-3=https://192.168.118.141:2380"
    #8.创建集群的token,这个值每个集群保持唯一
    ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
    #9.初始集群状态,新建集群的时候,这个值为new;
    ETCD_INITIAL_CLUSTER_STATE="new"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    备注:etcd默认使用2379端口提供http服务,使用2380作为peer彼此之间的通信端口。

    拷贝证书到etcd证书目录下

    之前证书在master节点上/opt/TLS/etcd生成好了,需要把etcd证书复制到etcd存放证书/opt/etcd/ssl目录下,如下:

    [root@matser ~]# cp /opt/TLS/etcd/ca*pem /opt/etcd/ssl/
    [root@matser ~]# cp /opt/TLS/etcd/server*pem /opt/etcd/ssl/
    
    • 1
    • 2

    使用systemd管理etcd服务

    cat > /usr/lib/systemd/system/etcd.service << EOF
    [Unit]
    Description=Etcd Server
    After=network.target
    After=network-online.target
    Wants=network-online.target
    
    [Service]
    Type=notify
    EnvironmentFile=/opt/etcd/config/etcd.conf
    ExecStart=/opt/etcd/bin/etcd \
    --cert-file=/opt/etcd/ssl/server.pem \
    --key-file=/opt/etcd/ssl/server-key.pem \
    --peer-cert-file=/opt/etcd/ssl/server.pem \
    --peer-key-file=/opt/etcd/ssl/server-key.pem \
    --trusted-ca-file=/opt/etcd/ssl/ca.pem \
    --peer-trusted-ca-file=/opt/etcd/ssl/ca.pem \
    --logger=zap
    Restart=on-failure
    LimitNOFILE=65536
    
    [Install]
    WantedBy=multi-user.target
    EOF
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    分发etcd配置到各节点

    #将etcd服务文件分发到node1、node2上
    scp /usr/lib/systemd/system/etcd.service  root@node1:/usr/lib/systemd/system/
    scp /usr/lib/systemd/system/etcd.service  root@node2:/usr/lib/systemd/system/
    #将etcd目录复制到其它节点上
    scp -r /opt/etcd root@node1:/opt/
    scp -r /opt/etcd root@node2:/opt/
    #注意修改etcd的配置文件
    vim /opt/etcd/config/etcd.conf  #编辑文件,修改其中的地址为本机地址,节点名称也要改
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    启动etcd

    3台etcd节点同时启动etcd:

    systemctl daemon-reload
    systemctl start etcd.service
    systemctl status etcd.service
    systemctl enable etcd.service
    
    • 1
    • 2
    • 3
    • 4

    验证etcd是否正常

    [root@matser 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.118.140:2379,https://192.168.118.141:2379,https://192.168.118.142:2379" endpoint health --write-out=table
    +------------------------------+--------+-------------+-------+
    |           ENDPOINT           | HEALTH |    TOOK     | ERROR |
    +------------------------------+--------+-------------+-------+
    | https://192.168.118.140:2379 |   true | 10.092418ms |       |
    | https://192.168.118.142:2379 |   true | 10.197676ms |       |
    | https://192.168.118.141:2379 |   true | 11.615945ms |       |
    +------------------------------+--------+-------------+-------+
    [root@matser etcd]# 
    #如上输出信息,3节点健康状态都是true
    
    [root@matser 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.118.140:2379,https://192.168.118.141:2379,https://192.168.118.142:2379"
    endpoint status  -w table
    +------------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
    |           ENDPOINT           |        ID        | VERSION | DB SIZE | IS LEADER | IS LEARNER | RAFT TERM | RAFT INDEX | RAFT APPLIED INDEX | ERRORS |
    +------------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
    | https://192.168.118.140:2379 | 149c70449070d22c |  3.4.21 |   20 kB |      true |      false |         2 |          8 |                  8 |        |
    | https://192.168.118.141:2379 | 6e7fe5435dd833e7 |  3.4.21 |   20 kB |     false |      false |         2 |          8 |                  8 |        |
    | https://192.168.118.142:2379 | e4ac8c73eea28716 |  3.4.21 |   25 kB |     false |      false |         2 |          8 |                  8 |        |
    +------------------------------+------------------+---------+---------+-----------+------------+-----------+------------+--------------------+--------+
    
    #如上输出信息,现在只有一个节点是leader,即140节点
    
    #如果有问题第一步先看日志:/var/log/message 或 journalctl -u etcd
    # 至此,etcd集群搭建完成
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    部署master节点的组件

    下面开始部署master节点相关的组件。

    生成kube-apiserver证书

    1、自签证书颁发机构(CA)

    mkdir -p /opt/TLS/k8s/		#创建k8s证书存放目录
    cd /opt/TLS/k8s/
    
    • 1
    • 2
    #自签证书颁发机构(CA)
    cat > ca-config.json << EOF
    {
      "signing": {
        "default": {
          "expiry": "87600h"		#10年
        },
        "profiles": {
          "kubernetes": {
             "expiry": "87600h",	#10年
             "usages": [
                "signing",
                "key encipherment",
                "server auth",
                "client auth"
            ]
          }
        }
      }
    }
    EOF
    cat > ca-csr.json << EOF
    {
        "CN": "kubernetes",
        "key": {
            "algo": "rsa",
            "size": 2048
        },
        "names": [
            {
                "C": "CN",
                "L": "Shenzhen",
                "ST": " Shenzhen",
                "O": "k8s",
                "OU": "System"
            }
        ]
    }
    EOF
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    #生成证书(会生成ca.pem和ca-key.pem文件)
    cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
    
    • 1
    • 2
    #查看现在的证书
    [root@matser k8s]# ll
    总用量 20
    -rw-r--r--. 1 root root  294 111 16:42 ca-config.json	#我们自己创建的
    -rw-r--r--. 1 root root 1005 111 16:43 ca.csr			#生成证书时创建的
    -rw-r--r--. 1 root root  267 111 16:42 ca-csr.json		#我们自己创建的
    -rw-------. 1 root root 1679 111 16:43 ca-key.pem		#生成证书时创建的
    -rw-r--r--. 1 root root 1367 111 16:43 ca.pem			#生成证书时创建的
    [root@matser k8s]# 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    2、使用自签CA签发kube-apiserver HTTPS证书

    注:下面文件hosts字段中IP为所有Master/LB/VIP IP和service的第一个地址,service的地址分配范围段等下载下面为了方便后期扩容可以多写几个预留的IP。

    cat > server-csr.json << EOF
    {
        "CN": "kubernetes",
        "hosts": [
          "192.168.118.140",	#这个是主机IP地址,必须写上
          "10.0.0.1",		#这个是service的第一个地址,必须写上,在下面会定义--service-cluster-ip-range=10.0.0.0/24 
    	  "10.11.0.1"		#这个是预留的
        ],
        "key": {
            "algo": "rsa",
            "size": 2048
        },
        "names": [
            {
                "C": "CN",
                "L": "Shenzhen",
                "ST": "Shenzhen",
                "O": "k8s",
                "OU": "System"
            }
        ]
    }
    EOF
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    # 生成证书(会生成server.pem和server-key.pem文件)
    cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes server-csr.json | cfssljson -bare server
    
    • 1
    • 2
    #现在有这些证书
    [root@matser k8s]# ll
    -rw-r--r--. 1 root root  294 111 16:42 ca-config.json
    -rw-r--r--. 1 root root 1005 111 16:43 ca.csr
    -rw-r--r--. 1 root root  267 111 16:42 ca-csr.json
    -rw-------. 1 root root 1679 111 16:43 ca-key.pem
    -rw-r--r--. 1 root root 1367 111 16:43 ca.pem
    -rw-r--r--. 1 root root 1058 111 17:09 server.csr
    -rw-r--r--. 1 root root  331 111 17:08 server-csr.json
    -rw-------. 1 root root 1679 111 17:09 server-key.pem
    -rw-r--r--. 1 root root 1432 111 17:09 server.pem
    [root@matser k8s]# 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    创建工作目录,解压k8s源码包

    #创建k8s的目录
    mkdir -p /opt/kubernetes/{bin,config,ssl,logs}
    #解压源码包
    tar  -zxvf kubernetes-server-linux-amd64.tar.gz
    #复制可执行文件到k8s的bin目录
    cd kubernetes/server/bin/
    cp kube-apiserver  /opt/kubernetes/bin/
    cp kube-controller-manager /opt/kubernetes/bin/
    cp kube-scheduler /opt/kubernetes/bin/
    #复制客户端命令工具到PATH能识别的路径下
    cp kubectl /usr/bin/
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    部署kube-apiserver

    1、先拷贝过程给api-server生成的证书到k8s的证书目录

     cp /opt/TLS/k8s/ca*.pem /opt/kubernetes/ssl/
     cp /opt/TLS/k8s/server*.pem /opt/kubernetes/ssl/
    
    • 1
    • 2

    2、创建kube-apiserver配置文件

    cat > /opt/kubernetes/config/kube-apiserver.conf << EOF
    KUBE_APISERVER_OPTS="--logtostderr=false \\
    --v=2 \\
    --log-dir=/opt/kubernetes/logs \\
    --etcd-servers=https://192.168.118.140:2379,https://192.168.118.141:2379,https://192.168.118.142:2379 \\
    --bind-address=192.168.118.140 \\
    --secure-port=6443 \\
    --advertise-address=192.168.118.140 \\
    --allow-privileged=true \\
    --service-cluster-ip-range=10.0.0.0/24 \\	#这个是service的分配ip地址范围段
    --enable-admission-plugins=NodeRestriction \\
    --authorization-mode=RBAC,Node \\
    --enable-bootstrap-token-auth=true \\
    --token-auth-file=/opt/kubernetes/config/token.csv \\
    --service-node-port-range=30000-32767 \\
    --kubelet-client-certificate=/opt/kubernetes/ssl/server.pem \\
    --kubelet-client-key=/opt/kubernetes/ssl/server-key.pem \\
    --tls-cert-file=/opt/kubernetes/ssl/server.pem  \\
    --tls-private-key-file=/opt/kubernetes/ssl/server-key.pem \\
    --client-ca-file=/opt/kubernetes/ssl/ca.pem \\
    --service-account-key-file=/opt/kubernetes/ssl/ca-key.pem \\
    --service-account-issuer=api \\
    --service-account-signing-key-file=/opt/kubernetes/ssl/ca-key.pem \\
    --etcd-cafile=/opt/etcd/ssl/ca.pem \\
    --etcd-certfile=/opt/etcd/ssl/server.pem \\
    --etcd-keyfile=/opt/etcd/ssl/server-key.pem \\
    --requestheader-client-ca-file=/opt/kubernetes/ssl/ca.pem \\
    --proxy-client-cert-file=/opt/kubernetes/ssl/server.pem \\
    --proxy-client-key-file=/opt/kubernetes/ssl/server-key.pem \\
    --requestheader-allowed-names=kubernetes \\
    --requestheader-extra-headers-prefix=X-Remote-Extra- \\
    --requestheader-group-headers=X-Remote-Group \\
    --requestheader-username-headers=X-Remote-User \\
    --enable-aggregator-routing=true \\
    --audit-log-maxage=30 \\
    --audit-log-maxbackup=3 \\
    --audit-log-maxsize=100 \\
    --audit-log-path=/opt/kubernetes/logs/k8s-audit.log"
    EOF
    
    #说明
    注:上面两个\\第一个是转义符,第二个是换行符,这是为了等下创建好文件之后还能留有换行符
    --logtostderr:启用日志
    ---v:日志等级
    --log-dir:日志目录
    --etcd-servers:etcd集群地址
    --bind-address:监听地址
    --secure-port:https安全端口
    --advertise-address:集群通告地址
    --allow-privileged:是否允许特权
    --service-cluster-ip-range:Service虚拟IP地址段
    --enable-admission-plugins:准入控制模块
    --authorization-mode:认证授权,启用RBAC授权和节点自管理
    --enable-bootstrap-token-auth:启用TLS bootstrap机制
    --token-auth-file:bootstrap token文件
    --service-node-port-range:Service nodeport类型默认分配端口范围
    --kubelet-client-xxx:apiserver访问kubelet客户端证书
    --tls-xxx-file:apiserver https证书
    --etcd-xxxfile:连接Etcd集群证书
    --audit-log-xxx:审计日志
    启动聚合层相关配置:--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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63

    3、启用 TLS Bootstrapping 机制
    TLS Bootstraping:Master apiserver启用TLS认证后,Node节点kubelet和kube-proxy要与kube-apiserver进行通信,必须使用CA签发的有效证书才可以,当Node节点很多时,这种客户端证书颁发需要大量工作,同样也会增加集群扩展复杂度。为了简化流程,Kubernetes引入了TLS bootstraping机制来自动颁发客户端证书,kubelet会以一个低权限用户自动向apiserver申请证书,kubelet的证书由apiserver动态签署。所以强烈建议在Node上使用这种方式,目前主要用于kubelet,kube-proxy还是由我们统一颁发一个证书。

    创建上述配置文件中token文件:

    #先生成token
    head -c 16 /dev/urandom | od -An -t x | tr -d ' '
    0afaef30853f159692ab4485e3d12a32
    
    # 创建token文件
    # 格式:token,用户名,UID,用户组
    cat > /opt/kubernetes/config/token.csv << EOF
    0afaef30853f159692ab4485e3d12a32,kubelet-bootstrap,10001,"system:node-bootstrapper"
    EOF
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    4、使用systemd管理api-server

    cat > /usr/lib/systemd/system/kube-apiserver.service << EOF
    [Unit]
    Description=Kubernetes API Server
    Documentation=https://github.com/kubernetes/kubernetes
    
    [Service]
    EnvironmentFile=/opt/kubernetes/config/kube-apiserver.conf
    ExecStart=/opt/kubernetes/bin/kube-apiserver \$KUBE_APISERVER_OPTS
    Restart=on-failure
    
    [Install]
    WantedBy=multi-user.target
    EOF
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    5、启动api-server并设置开机启动

    systemctl daemon-reload
    systemctl start kube-apiserver
    systemctl status kube-apiserver 		#状态正常
    systemctl enable kube-apiserver
    
    • 1
    • 2
    • 3
    • 4

    部署kube-controller-manager

    1、生成kubeconfig文件

    #要先去生成kube-controller-manager证书
    cd /opt/TLS/k8s/
    # 创建证书请求文件
    cat > kube-controller-manager-csr.json << EOF
    {
      "CN": "system:kube-controller-manager",
      "hosts": [],
      "key": {
        "algo": "rsa",
        "size": 2048
      },
      "names": [
        {
          "C": "CN",
          "L": "Shenzhen", 
          "ST": " Shenzhen",
          "O": "system:masters",
          "OU": "System"
        }
      ]
    }
    EOF
    # 生成证书
    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
    
    #查看现在的证书有哪些
    [root@matser k8s]# ll 
    -rw-r--r--. 1 root root  294 111 16:42 ca-config.json	#ca的是自签机构
    -rw-r--r--. 1 root root 1005 111 16:43 ca.csr
    -rw-r--r--. 1 root root  267 111 16:42 ca-csr.json
    -rw-------. 1 root root 1679 111 16:43 ca-key.pem
    -rw-r--r--. 1 root root 1367 111 16:43 ca.pem
    -rw-r--r--. 1 root root 1050 111 18:21 kube-controller-manager.csr	#kube-controller-manager就是我们上面生成的
    -rw-r--r--. 1 root root  258 111 18:20 kube-controller-manager-csr.json
    -rw-------. 1 root root 1679 111 18:21 kube-controller-manager-key.pem
    -rw-r--r--. 1 root root 1444 111 18:21 kube-controller-manager.pem
    -rw-r--r--. 1 root root 1058 111 17:09 server.csr				#service开头的是kube-apiserver HTTPS证书
    -rw-r--r--. 1 root root  331 111 17:08 server-csr.json
    -rw-------. 1 root root 1679 111 17:09 server-key.pem
    -rw-r--r--. 1 root root 1432 111 17:09 server.pem
    [root@matser k8s]# 
    
    #生成kubeconfig文件(直接在shell命令行执行)
    KUBE_CONFIG="/opt/kubernetes/config/kube-controller-manager.kubeconfig"
    KUBE_APISERVER="https://192.168.118.140:6443"
    
    kubectl config set-cluster kubernetes \
      --certificate-authority=/opt/kubernetes/ssl/ca.pem \
      --embed-certs=true \
      --server=${KUBE_APISERVER} \
      --kubeconfig=${KUBE_CONFIG}
    kubectl config set-credentials kube-controller-manager \
      --client-certificate=/opt/TLS/k8s/kube-controller-manager.pem \
      --client-key=/opt/TLS/k8s/kube-controller-manager-key.pem \
      --embed-certs=true \
      --kubeconfig=${KUBE_CONFIG}
    kubectl config set-context default \
      --cluster=kubernetes \
      --user=kube-controller-manager \
      --kubeconfig=${KUBE_CONFIG}
    kubectl config use-context default --kubeconfig=${KUBE_CONFIG}
    
    #这时就生成了/opt/kubernetes/config/kube-controller-manager.kubeconfig文件了
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63

    2、创建controller-manager配置文件

    cat > /opt/kubernetes/config/kube-controller-manager.conf << EOF
    KUBE_CONTROLLER_MANAGER_OPTS="--logtostderr=false \\
    --v=2 \\
    --log-dir=/opt/kubernetes/logs \\
    --leader-elect=true \\
    --kubeconfig=/opt/kubernetes/config/kube-controller-manager.kubeconfig \\
    --bind-address=192.168.118.140 \\
    --allocate-node-cidrs=true \\
    --cluster-cidr=10.244.0.0/16 \\
    --service-cluster-ip-range=10.0.0.0/24 \\
    --cluster-signing-cert-file=/opt/kubernetes/ssl/ca.pem \\
    --cluster-signing-key-file=/opt/kubernetes/ssl/ca-key.pem  \\
    --root-ca-file=/opt/kubernetes/ssl/ca.pem \\
    --service-account-private-key-file=/opt/kubernetes/ssl/ca-key.pem \\
    --cluster-signing-duration=87600h0m0s"
    EOF
    #参数说明
    --kubeconfig:连接apiserver的配置文件,就是kubeconfig证书
    --cluster-cidr:用于给pod分配的ip范围段
    --service-cluster-ip-range:用于给service分配的ip范围段
    --leader-elect:当该组件启动多个时,自动选举(HA)
    --cluster-signing-cert-file/--cluster-signing-key-file:自动为kubelet颁发证书的CA,与apiserver保持一致
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    3、systemd管理controller-manager

    cat > /usr/lib/systemd/system/kube-controller-manager.service << EOF
    [Unit]
    Description=Kubernetes Controller Manager
    Documentation=https://github.com/kubernetes/kubernetes
    
    [Service]
    EnvironmentFile=/opt/kubernetes/config/kube-controller-manager.conf
    ExecStart=/opt/kubernetes/bin/kube-controller-manager \$KUBE_CONTROLLER_MANAGER_OPTS
    Restart=on-failure
    
    [Install]
    WantedBy=multi-user.target
    EOF
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    4、启动controller-manager并设置开机自启

    systemctl daemon-reload
    systemctl start kube-controller-manager
     systemctl status  kube-controller-manager	#状态正常
    systemctl enable kube-controller-manager
    
    • 1
    • 2
    • 3
    • 4

    部署kube-scheduler

    1、先生成kubeconfig文件

    cd /opt/TLS/k8s/
    cat > kube-scheduler-csr.json << EOF
    {
      "CN": "system:kube-scheduler",
      "hosts": [],
      "key": {
        "algo": "rsa",
        "size": 2048
      },
      "names": [
        {
          "C": "CN",
          "L": "Shenzhen",
          "ST": "Shenzhen",
          "O": "system:masters",
          "OU": "System"
        }
      ]
    }
    EOF
    # 生成证书
    cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-scheduler-csr.json | cfssljson -bare kube-scheduler
    
    #查看现在有哪些证书
    [root@matser k8s]# ll
    总用量 68
    -rw-r--r--. 1 root root  294 111 16:42 ca-config.json
    -rw-r--r--. 1 root root 1005 111 16:43 ca.csr
    -rw-r--r--. 1 root root  267 111 16:42 ca-csr.json
    -rw-------. 1 root root 1679 111 16:43 ca-key.pem
    -rw-r--r--. 1 root root 1367 111 16:43 ca.pem
    -rw-r--r--. 1 root root 1050 111 18:21 kube-controller-manager.csr
    -rw-r--r--. 1 root root  258 111 18:20 kube-controller-manager-csr.json
    -rw-------. 1 root root 1679 111 18:21 kube-controller-manager-key.pem
    -rw-r--r--. 1 root root 1444 111 18:21 kube-controller-manager.pem
    -rw-r--r--. 1 root root 1033 111 18:35 kube-scheduler.csr	#刚创建的
    -rw-r--r--. 1 root root  247 111 18:34 kube-scheduler-csr.json
    -rw-------. 1 root root 1675 111 18:35 kube-scheduler-key.pem
    -rw-r--r--. 1 root root 1428 111 18:35 kube-scheduler.pem
    -rw-r--r--. 1 root root 1058 111 17:09 server.csr
    -rw-r--r--. 1 root root  331 111 17:08 server-csr.json
    -rw-------. 1 root root 1679 111 17:09 server-key.pem
    -rw-r--r--. 1 root root 1432 111 17:09 server.pem
    [root@matser k8s]# 
    
    # 生成kubeconfig文件(在shell命令终端执行)
    KUBE_CONFIG="/opt/kubernetes/config/kube-scheduler.kubeconfig"
    KUBE_APISERVER="https://192.168.118.140:6443"
    
    kubectl config set-cluster kubernetes \
      --certificate-authority=/opt/kubernetes/ssl/ca.pem \
      --embed-certs=true \
      --server=${KUBE_APISERVER} \
      --kubeconfig=${KUBE_CONFIG}
    kubectl config set-credentials kube-scheduler \
      --client-certificate=./kube-scheduler.pem \
      --client-key=./kube-scheduler-key.pem \
      --embed-certs=true \
      --kubeconfig=${KUBE_CONFIG}
    kubectl config set-context default \
      --cluster=kubernetes \
      --user=kube-scheduler \
      --kubeconfig=${KUBE_CONFIG}
    kubectl config use-context default --kubeconfig=${KUBE_CONFIG}
    
    #kubeconfig文件就生成好了,位于/opt/kubernetes/config/kube-scheduler.kubeconfig
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66

    2、创建kube-scheduler配置文件

    cat > /opt/kubernetes/config/kube-scheduler.conf << EOF
    KUBE_SCHEDULER_OPTS="--logtostderr=false \\
    --v=2 \\
    --log-dir=/opt/kubernetes/logs \\
    --leader-elect \\
    --kubeconfig=/opt/kubernetes/config/kube-scheduler.kubeconfig \\
    --bind-address=192.168.118.140"
    EOF
    
    #参数说明
    --kubeconfig:连接apiserver配置文件
    --leader-elect:当该组件启动多个时,自动选举(HA)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    3、使用systemd管理kube-scheduler

    cat > /usr/lib/systemd/system/kube-scheduler.service << EOF
    [Unit]
    Description=Kubernetes Scheduler
    Documentation=https://github.com/kubernetes/kubernetes
    
    [Service]
    EnvironmentFile=/opt/kubernetes/config/kube-scheduler.conf
    ExecStart=/opt/kubernetes/bin/kube-scheduler \$KUBE_SCHEDULER_OPTS
    Restart=on-failure
    
    [Install]
    WantedBy=multi-user.target
    EOF
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    4、启动kube-scheduler并设置开机自启

    systemctl daemon-reload
    systemctl start kube-scheduler
    systemctl status kube-scheduler	#状态正常
    systemctl enable kube-scheduler
    
    • 1
    • 2
    • 3
    • 4

    配置kubectl连接集群(生成kubeconfig文件)

    生成kubectl连接集群的证书:

    cd /opt/TLS/k8s/
    cat > admin-csr.json <<EOF
    {
      "CN": "admin",
      "hosts": [],
      "key": {
        "algo": "rsa",
        "size": 2048
      },
      "names": [
        {
          "C": "CN",
          "L": "Shenzhen",
          "ST": "Shenzhen",
          "O": "system:masters",
          "OU": "System"
        }
      ]
    }
    EOF
    #生成证书
    cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes admin-csr.json | cfssljson -bare admin
    
    #生成kubeconfig文件
    mkdir /root/.kube    #创建一个隐藏目录
    #下面这段直接在shell命令终端执行
    KUBE_CONFIG="/root/.kube/config"
    KUBE_APISERVER="https://192.168.118.140:6443"
    
    kubectl config set-cluster kubernetes \
      --certificate-authority=/opt/kubernetes/ssl/ca.pem \
      --embed-certs=true \
      --server=${KUBE_APISERVER} \
      --kubeconfig=${KUBE_CONFIG}
    kubectl config set-credentials cluster-admin \
      --client-certificate=/opt/TLS/k8s/admin.pem \
      --client-key=/opt/TLS/k8s/admin-key.pem \
      --embed-certs=true \
      --kubeconfig=${KUBE_CONFIG}
    kubectl config set-context default \
      --cluster=kubernetes \
      --user=cluster-admin \
      --kubeconfig=${KUBE_CONFIG}
    kubectl config use-context default --kubeconfig=${KUBE_CONFIG}
    
    #在/root/.kube下生成了一个config配置文件
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    通过kubectl工具查看当前集群组件状态

    [root@matser config]# kubectl get cs
    NAME                 STATUS      MESSAGE                                                                                        ERROR
    controller-manager   Unhealthy   Get "https://127.0.0.1:10257/healthz": dial tcp 127.0.0.1:10257: connect: connection refused   
    scheduler            Healthy     ok                                                                                             
    etcd-1               Healthy     {"health":"true"}                                                                              
    etcd-0               Healthy     {"health":"true"}                                                                              
    etcd-2               Healthy     {"health":"true"}                                                                              
    [root@matser config]# ll
    #这里发现controller-manager不健康,不知道为什么,临时解决办法:
    vim /opt/kubernetes/config/kube-controller-manager.conf 
    --bind-address=0.0.0.0 \		#修改这个为0.0.0.0,之前是192.168.118.140
    
    #重启controller
    [root@matser config]# systemctl restart kube-controller-manager
    #再次查看,现在全部组件状态是健康的
    [root@matser config]# kubectl  get cs
    NAME                 STATUS    MESSAGE             ERROR
    scheduler            Healthy   ok                  
    controller-manager   Healthy   ok                  
    etcd-0               Healthy   {"health":"true"}   
    etcd-1               Healthy   {"health":"true"}   
    etcd-2               Healthy   {"health":"true"}   
    [root@matser config]# 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    授权kubelet-bootstrap用户允许请求证书

    kubectl create clusterrolebinding kubelet-bootstrap \
    --clusterrole=system:node-bootstrapper \
    --user=kubelet-bootstrap
    
    • 1
    • 2
    • 3

    部署Node节点组件

    在node节点上创建工作目录并拷贝二进制文件:

    #在node1、node2节点上创建目录
    mkdir -p /opt/kubernetes/{bin,config,ssl,logs} 
    #去master节点拷贝对应的node节点上需要的组件的二进制文件过来
    scp /root/software/kubernetes/server/bin/kube-proxy root@node1:/opt/kubernetes/bin/
    scp /root/software/kubernetes/server/bin/kubelet root@node1:/opt/kubernetes/bin/
    scp /root/software/kubernetes/server/bin/kube-proxy root@node2:/opt/kubernetes/bin/
    scp /root/software/kubernetes/server/bin/kubelet root@node2:/opt/kubernetes/bin/
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    部署kubelet(只部署在node1、node2节点)

    下面开始部署kubelet,kubelet暂时只部署在node1、node2节点,master节点不部署kubelet服务,但是这样当我们使用kubectl get nodes 时就无法看到master节点,这里先留一个坑,先继续往下看吧。

    1、先在master节点上生成kubelet初次加入集群时的引导kubeconfig文件

    KUBE_CONFIG="/opt/kubernetes/config/bootstrap.kubeconfig"
    KUBE_APISERVER="https://192.168.118.140:6443"	# apiserver IP:PORT
    TOKEN="0afaef30853f159692ab4485e3d12a32"		# 与/opt/kubernetes/config/token.csv里保持一致
    
    kubectl config set-cluster kubernetes \
      --certificate-authority=/opt/kubernetes/ssl/ca.pem \
      --embed-certs=true \
      --server=${KUBE_APISERVER} \
      --kubeconfig=${KUBE_CONFIG}
    kubectl config set-credentials "kubelet-bootstrap" \
      --token=${TOKEN} \
      --kubeconfig=${KUBE_CONFIG}
    kubectl config set-context default \
      --cluster=kubernetes \
      --user="kubelet-bootstrap" \
      --kubeconfig=${KUBE_CONFIG}
    kubectl config use-context default --kubeconfig=${KUBE_CONFIG}
    
    #执行完就生成了/opt/kubernetes/config/bootstrap.kubeconfig文件,把这个文件复制到node节点上
    scp /opt/kubernetes/config/bootstrap.kubeconfig root@node1:/opt/kubernetes/config/
    scp /opt/kubernetes/config/bootstrap.kubeconfig root@node2:/opt/kubernetes/config/
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    2、 配置参数文件

    #先去master节点上把/opt/kubernetes/ssl/ca.pem文件复制到node1、node2节点
    scp /opt/kubernetes/ssl/ca.pem root@node1:/opt/kubernetes/ssl/
    scp /opt/kubernetes/ssl/ca.pem root@node2:/opt/kubernetes/ssl/
    
    #在node1、node2节点创建kubelet-config.yml文件
    cat > /opt/kubernetes/config/kubelet-config.yml << EOF
    kind: KubeletConfiguration
    apiVersion: kubelet.config.k8s.io/v1beta1
    address: 0.0.0.0
    port: 10250
    readOnlyPort: 10255
    cgroupDriver: systemd	#这个参数要与docker的Cgroup Driver保持一致
    clusterDNS:
    - 10.0.0.2
    clusterDomain: cluster.local 
    failSwapOn: false
    authentication:
      anonymous:
        enabled: false
      webhook:
        cacheTTL: 2m0s
        enabled: true
      x509:
        clientCAFile: /opt/kubernetes/ssl/ca.pem
    authorization:
      mode: Webhook
      webhook:
        cacheAuthorizedTTL: 5m0s
        cacheUnauthorizedTTL: 30s
    evictionHard:
      imagefs.available: 15%
      memory.available: 100Mi
      nodefs.available: 10%
      nodefs.inodesFree: 5%
    maxOpenFiles: 1000000
    maxPods: 110
    EOF
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    3、创建kubelet配置文件

    #在node1、node2节点创建kubelet.conf
    cat > /opt/kubernetes/config/kubelet.conf << EOF
    KUBELET_OPTS="--logtostderr=false \\
    --v=2 \\
    --log-dir=/opt/kubernetes/logs \\
    --hostname-override=node1 \\			#node2节点的注意修改名称
    --network-plugin=cni \\
    --kubeconfig=/opt/kubernetes/config/kubelet.kubeconfig \\	#空路径,不用创建该文件
    --bootstrap-kubeconfig=/opt/kubernetes/config/bootstrap.kubeconfig \\
    --config=/opt/kubernetes/config/kubelet-config.yml \\
    --cert-dir=/opt/kubernetes/ssl \\
    --pod-infra-container-image=registry.aliyuncs.com/google_containers/pause:3.5"
    EOF
    #参数说明
    --hostname-override:显示名称,集群中唯一
    --network-plugin:启用CNI
    --kubeconfig:空路径,等下master节点批准加入集群之后自动生成的,该文件是用于连接apiserver的
    --bootstrap-kubeconfig:首次启动向apiserver申请证书
    --config:配置参数文件
    --cert-dir:kubelet证书生成目录
    --pod-infra-container-image:根容器
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    5、设置systemd管理kubelet服务

    #在node1、node2节点创建kubelet.service文件
    cat > /usr/lib/systemd/system/kubelet.service << EOF
    [Unit]
    Description=Kubernetes Kubelet
    After=docker.service
    
    [Service]
    EnvironmentFile=/opt/kubernetes/config/kubelet.conf
    ExecStart=/opt/kubernetes/bin/kubelet \$KUBELET_OPTS
    Restart=on-failure
    LimitNOFILE=65536
    
    [Install]
    WantedBy=multi-user.target
    EOF
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    6、启动kubelet 并设置开机启动

    #在node1、node2分别启动kubelet服务
    systemctl daemon-reload
    systemctl start kubelet 
    systemctl status kubelet 
    systemctl enable kubelet
    
    • 1
    • 2
    • 3
    • 4
    • 5

    master节点批准kubelet证书申请并加入集群

    在master节点批准kubelet证书申请并加入集群:

    # 查看kubelet证书请求
    [root@matser ~]# kubectl get csr
    NAME                                                   AGE     SIGNERNAME                                    REQUESTOR           REQUESTEDDURATION   CONDITION
    node-csr-YEXLBuOKa7n839h6fcC_nF1K6vilyCyj8Gqf5D7lhLo   7m30s   kubernetes.io/kube-apiserver-client-kubelet   kubelet-bootstrap   <none>              Pending
    [root@matser ~]# 
    
    # 批准申请
    kubectl certificate approve node-csr-YEXLBuOKa7n839h6fcC_nF1K6vilyCyj8Gqf5D7lhLo
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    部署kube-proxy

    先在node1、node2节点部署kube-proxy服务。

    1、配置参数文件

    cat > /opt/kubernetes/config/kube-proxy-config.yml << EOF
    kind: KubeProxyConfiguration
    apiVersion: kubeproxy.config.k8s.io/v1alpha1
    bindAddress: 0.0.0.0
    metricsBindAddress: 0.0.0.0:10249
    clientConnection:
      kubeconfig: /opt/kubernetes/config/kube-proxy.kubeconfig
    hostnameOverride: node1				#node2节点改成对应的node2
    clusterCIDR: 10.244.0.0/16
    EOF
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2、创建kube-proxy配置文件

    cat > /opt/kubernetes/config/kube-proxy.conf << EOF
    KUBE_PROXY_OPTS="--logtostderr=false \\
    --v=2 \\
    --log-dir=/opt/kubernetes/logs \\
    --config=/opt/kubernetes/config/kube-proxy-config.yml"
    EOF
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    3、在master节点上生成kube-proxy.kubeconfig文件

    #去到master节点
    # 切换工作目录
    cd /opt/TLS/k8s/
    # 创建证书请求文件
    cat > kube-proxy-csr.json << EOF
    {
      "CN": "system:kube-proxy",
      "hosts": [],
      "key": {
        "algo": "rsa",
        "size": 2048
      },
      "names": [
        {
          "C": "CN",
          "L": "Shenzhen",
          "ST": "Shenzhen",
          "O": "k8s",
          "OU": "System"
        }
      ]
    }
    EOF
    
    # 生成证书
    cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy
    
    #生成kubeconfig文件
    KUBE_CONFIG="/opt/kubernetes/config/kube-proxy.kubeconfig"
    KUBE_APISERVER="https://192.168.118.140:6443"
    
    kubectl config set-cluster kubernetes \
      --certificate-authority=/opt/kubernetes/ssl/ca.pem \
      --embed-certs=true \
      --server=${KUBE_APISERVER} \
      --kubeconfig=${KUBE_CONFIG}
    kubectl config set-credentials kube-proxy \
      --client-certificate=/opt/TLS/k8s/kube-proxy.pem \
      --client-key=/opt/TLS/k8s/kube-proxy-key.pem \
      --embed-certs=true \
      --kubeconfig=${KUBE_CONFIG}
    kubectl config set-context default \
      --cluster=kubernetes \
      --user=kube-proxy \
      --kubeconfig=${KUBE_CONFIG}
    kubectl config use-context default --kubeconfig=${KUBE_CONFIG}
    
    #生成了/opt/kubernetes/config/kube-proxy.kubeconfig,把这文件复制到node上
    scp /opt/kubernetes/config/kube-proxy.kubeconfig root@node1:/opt/kubernetes/config/
    scp /opt/kubernetes/config/kube-proxy.kubeconfig root@node2:/opt/kubernetes/config/
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    4、使用systemd管理kube-proxy

    cat > /usr/lib/systemd/system/kube-proxy.service << EOF
    [Unit]
    Description=Kubernetes Proxy
    After=network.target
    
    [Service]
    EnvironmentFile=/opt/kubernetes/config/kube-proxy.conf
    ExecStart=/opt/kubernetes/bin/kube-proxy \$KUBE_PROXY_OPTS
    Restart=on-failure
    LimitNOFILE=65536
    
    [Install]
    WantedBy=multi-user.target
    EOF
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    5、启动并设置开机启动

    systemctl daemon-reload
    systemctl start kube-proxy
    systemctl status kube-proxy
    systemctl enable kube-proxy
    
    • 1
    • 2
    • 3
    • 4

    部署calico网络插件

    wget https://docs.projectcalico.org/manifests/calico.yaml
    vim calico.yaml			#找到这么这两句,去掉注释,修改ip为当前你设置的pod ip段
    - name: CALICO_IPV4POOL_CIDR
      value: "10.244.0.0/16"
    
    kubectl apply -f calico.yaml 	#自行解决镜像下载的问题
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    部署coredns

    打开网站:https://github.com/kubernetes/kubernetes/tree/master/cluster/addons/dns/coredns/
    选择第一个文件并打开它:coredns.yaml.base,复制内容出来到服务器上,执行即可。
    可以尝试直接 wget https://github.com/kubernetes/kubernetes/blob/master/cluster/addons/dns/coredns/coredns.yaml.base,不过发现下载到的是html文件,所以才手动复制的。

    #修改k8s集群后缀名称__DNS__DOMAIN__,一般为cluster.local
    #77         kubernetes __DNS__DOMAIN__ in-addr.arpa ip6.arpa {
    kubernetes cluster.local in-addr.arpa ip6.arpa {
    
    #修改coredns谷歌地址为dockerhub地址,容易下载
    image: k8s.gcr.io/coredns/coredns:v1.8.6   
    image: coredns/coredns:latest
    #修改pod启动内存限制大小,300Mi即可
    #146             memory: __DNS__MEMORY__LIMIT__
    memory: 300Mi
    #修改coredns的svcIP地址,一般为svc网段的第二位,10.100.0.2,第一位为apiserver的svc
    #212   clusterIP: __DNS__SERVER__
    clusterIP: 10.0.0.2
    
    #修改coredns副本数,默认是1,且没有replicas字段
    replicas: 3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    DNS解析测试

    [root@master ~]#  vim busybox-test.yaml 
    apiVersion: v1
    kind: Pod
    metadata:
      name: busybox
      labels:
        app: busybox
    spec:
      containers:
      - image: busybox:1.24.1
        command: [ "/bin/sh","-c" ]
        args: [ "echo '555'>/555.txt;sleep 99999990" ]
        imagePullPolicy: IfNotPresent
        name: busybox
        stdin: true
      restartPolicy: Always
    
    [root@master ~]# kubectl  exec -it busybox -- sh	#进入容器
    / # nslookup kubernetes			#能解析service的名称(kubernetes是k8s集群中的第一个service的名称),说明coredns正常
    Server:    10.0.0.2
    Address 1: 10.0.0.2 kube-dns.kube-system.svc.cluster.local
    
    Name:      kubernetes
    Address 1: 10.0.0.1 kubernetes.default.svc.cluster.local
    / # 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    至此,单master节点的k8s集群搭建完毕

    细心的人可能会发现:

    [root@matser ~]# kubectl  get node
    NAME    STATUS   ROLES    AGE     VERSION
    node1   Ready    <none>   7h33m   v1.22.15
    node2   Ready    <none>   7h32m   v1.22.15
    [root@matser ~]#
    #只有2个节点?是的,因为我们没有在master节点上部署kubelet,kube-proxy,所以显示不出来,因为我们只需要把master节点保持单纯的管理功
    #能,不需要跑pod,在kubeadm方式安装的k8s中,也会把master作为节点显示出来,因为master节点上安装kubelet,其实master节点上还跑了
    #kube-apiserver.service kube-controller-manager.service  kube-scheduler.service  静态的pod。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    master节点ping不通podIP

    创建pods资源后发现在master节点上无法ping 通podIP,而在node节点上可以ping 通podIP,pod都运行在node节点上。
    排查后发现,calico的pod只在node节点上,并没有在master节点上,route -n发现master节点上没有calico的路由,这导致了在master节点上无法ping 通podIP,所以我们在master节点上创建、部署、curl podIP、curl serviceIP等测试都无法ping通。
    原因就是,上面我们没有把master节点加入集群,(没有安装kubelet)。

    master节点部署kubelet、kube-proxy

    好好看上面node节点的部署过程,在node节点上把对应的文件复制到mater节点上对应的位置,然后主要修改文件内容里面对应的名称,同时注意不用把kubelet.kubeconfig 复制过去,这个文件是自动生成的,记得也要把kubelet 、kube-proxy可执行文件命令放到/opt/kubernetes/bin/目录下。安装完成kubelet之后再把master加入集群,安装完kube-proxy看下集群状态是否正常,calico这时就会在master节点上运行一个pod,查看pod状态是否正常。

    kube-proxy出现无法代理的情况

     systemctl  status  kube-proxy.service
    11月 02 23:50:32 node1 systemd[1]: Started Kubernetes Proxy.
    11月 02 23:50:32 node1 kube-proxy[73327]: E1102 23:50:32.618027   73327 proxier.go:1564] "Failed to delete stale service connections" err="error deleting connection tracking state for UDP service IP: 10.0.0.2, error: error looking for path of conntrack: exec: \"conntrack\": executable file not found in $PATH" ip="10.0.0.2"
    
     yum install conntrack -y 
     systemctl  restart kube-proxy.service 后没有报错
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    kubectl exec -it 进入pod报错

    root@master ~]# kubectl  exec -it busybox -- sh
    error: unable to upgrade connection: Forbidden (user=kubernetes, verb=create, resource=nodes, subresource=proxy)
    
    解决办法:
    kubectl create clusterrolebinding kube-apiserver:kubelet-apis --clusterrole=system:kubelet-api-admin --user kubernetes
    
    • 1
    • 2
    • 3
    • 4
    • 5

    修改集群节点的角色

    #查看有哪些节点
    [root@matser ~]# kubectl  get nodes
    NAME     STATUS   ROLES    AGE     VERSION
    master   Ready    <none>   4d21h   v1.22.15
    node1    Ready    <none>   5d21h   v1.22.15
    node2    Ready    <none>   5d21h   v1.22.15
    [root@matser ~]# 
    #我们看到上面显示的ROLES都是
    #修改方法:
    kubectl  label nodes master  node-role.kubernetes.io/control-plane=
    kubectl  label nodes master  node-role.kubernetes.io/master=
    kubectl  label nodes node1  node-role.kubernetes.io/node=
    kubectl  label nodes node2  node-role.kubernetes.io/node=
    [root@matser ~]# kubectl  get nodes		#查看,已经有标签了
    NAME     STATUS   ROLES                  AGE     VERSION
    master   Ready    control-plane,master   4d21h   v1.22.15
    node1    Ready    node                   5d21h   v1.22.15
    node2    Ready    node                   5d21h   v1.22.15
    [root@matser ~]# 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    总结

    k8s集群二进制的搭建繁琐,很多问题需要自己解决,期间也出现了很多问题,比如,各个组件都搭建完成了,还没安装网络创建,kubectl get node 发现not resource found,排查了很久,发现是etcd集群搭建完成之后发现存在两个leader,具体什么原因也没排查的出来,重新搭建etcd集群之后才正常。
    很多镜像下载失败,比如创建calico、coredns镜像下载失败。calico一致安装不上,kubelet一致报cni未就绪等等问题。

  • 相关阅读:
    主应用窗口
    激励是改善业绩的关键
    RabbitMQ的七种工作模式和分别概述
    深度学习之CNN宫颈癌预测
    小白量化《穿云箭集群量化》(2)量化策略编写(1)
    现代气象仪器 | 太阳辐射测量
    KMP算法详解(Python&Java代码)
    深入解析Spring Boot中最常用注解的使用方式(上篇)
    vscode提取扩展出错xhr
    警惕看不见的重试机制:为什么使用RPC必须考虑幂等性
  • 原文地址:https://blog.csdn.net/MssGuo/article/details/124678952