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

目录

    • 前言
    • 下载k8s二进制包
    • 下载etcd安装包
    • 主机规划
    • 设置主机名(所有主机都执行)
    • 关闭防火墙(所有主机都执行)
    • 禁用selinux(所有主机都执行)
    • 关闭swap分区(所有主机都执行,因为k8s官网要求关闭swap)
    • 时间同步(所有主机都执行)
    • 将桥接的IPv4流量传递到iptables的链(所有主机都执行)
    • 升级linux内核到5.4.221-1
    • 安装docker
    • 安装cfssl证书生成工具
    • 生成Etcd证书
    • 部署etcd集群
    • 拷贝证书到etcd证书目录下
    • 使用systemd管理etcd服务
    • 分发etcd配置到各节点
    • 启动etcd
    • 验证etcd是否正常
    • 部署master节点的组件
    • 生成kube-apiserver证书
    • 创建工作目录,解压k8s源码包
    • 部署kube-apiserver
    • 部署kube-controller-manager
    • 部署kube-scheduler
    • 配置kubectl连接集群
    • 通过kubectl工具查看当前集群组件状态
    • 授权kubelet-bootstrap用户允许请求证书
    • 部署Node节点组件
    • 部署kubelet(只部署在node1、node2节点)
    • master节点批准kubelet证书申请并加入集群
    • 部署kube-proxy
    • 部署calico网络插件
    • 部署coredns
    • DNS解析测试
    • 至此,单master节点的k8s集群搭建完毕
    • master节点ping不通podIP
    • master节点部署kubelet、kube-proxy
    • kube-proxy出现无法代理的情况
    • kubectl exec -it 进入pod报错
    • 修改集群节点的角色
    • 总结

前言

环境: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

主机规划

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

主机 说明
master 192.168.118.140,能连外网,centos7.9版本,内核:5.4.216-1.el7.elrepo.x86_64,至少2核CPU,2G内存
node1 192.168.118.141,能连外网,centos7.9版本,内核:5.4.216-1.el7.elrepo.x86_64,至少2核CPU,2G内存
node2 192.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

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

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

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

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

关闭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

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

[root@master ~]# yum -y install ntp	 				#安装ntpd服务
[root@master ~]# systemctl start ntpd				#开始ntpd服务,或者做定时任务如:*/5 * * * * /usr/sbin/ntpdate -u 192.168.11.100
[root@master ~]# systemctl enable ntpd

将桥接的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亦可

升级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 ~]#

安装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

生成Etcd证书

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

mkdir -p /opt/TLS/etcd		#创建etcd证书存放目录
#自签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
# 生成证书,会生成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]#

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

生成证书:

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

查看所有证书:

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]# 

部署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"

备注: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/

使用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

分发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  #编辑文件,修改其中的地址为本机地址,节点名称也要改

启动etcd

3台etcd节点同时启动etcd:

systemctl daemon-reload
systemctl start etcd.service
systemctl status etcd.service
systemctl enable etcd.service

验证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集群搭建完成

部署master节点的组件

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

生成kube-apiserver证书

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

mkdir -p /opt/TLS/k8s/		#创建k8s证书存放目录
cd /opt/TLS/k8s/
#自签证书颁发机构(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
#生成证书(会生成ca.pem和ca-key.pem文件)
cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
#查看现在的证书
[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]# 

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
# 生成证书(会生成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
#现在有这些证书
[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]# 

创建工作目录,解压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/

部署kube-apiserver

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

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

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

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

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

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

systemctl daemon-reload
systemctl start kube-apiserver
systemctl status kube-apiserver 		#状态正常
systemctl enable kube-apiserver

部署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文件了

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保持一致

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

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

systemctl daemon-reload
systemctl start kube-controller-manager
 systemctl status  kube-controller-manager	#状态正常
systemctl enable kube-controller-manager

部署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

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)

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

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

systemctl daemon-reload
systemctl start kube-scheduler
systemctl status kube-scheduler	#状态正常
systemctl enable kube-scheduler

配置kubectl连接集群

生成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配置文件

通过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]# 

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

kubectl create clusterrolebinding kubelet-bootstrap \
--clusterrole=system:node-bootstrapper \
--user=kubelet-bootstrap

部署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/

部署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/

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

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:根容器

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

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

#在node1、node2分别启动kubelet服务
systemctl daemon-reload
systemctl start kubelet 
systemctl status kubelet 
systemctl enable kubelet

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

部署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

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

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/

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

5、启动并设置开机启动

systemctl daemon-reload
systemctl start kube-proxy
systemctl status kube-proxy
systemctl enable kube-proxy

部署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 	#自行解决镜像下载的问题

部署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

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
/ # 

至此,单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。

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 后没有报错

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

修改集群节点的角色

#查看有哪些节点
[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 ~]# 

总结

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

你可能感兴趣的:(kubernetes,kubernetes,docker,容器)