k8s-二进制安装
1、准备环境
服务器要求:
- 建议最小硬件配置: 2核CPU\2G内存\30G硬盘。
- 服务器最好可以访问外网,会有从网上拉取镜像的需求,如果服务器不能上网,需要提前下载对应镜像导入节点。、
- 服务器内核在4.4之上
软件环境:

服务器规划:

须知:
考虑到有些朋友电脑配置较低,一次性开四台虚拟机电脑跑不动, 所以搭建这套k8s高可用集群分两部分实施,先部署一套单Master架构,
再扩容为多Master架构, 顺便再熟悉下Master扩容流程。
单Master架构图
单Master服务器规划:
2、操作系统初始化配置(所有节点)
2.1系统初始化
#关闭系统防火墙 systemctl stop firewalld systemctl disable firewalld #关闭selinux sed -i 's/enforcing/disabled/' /etc/selinux/config #永久 setenforce 0 # 临时 #关闭swap swapoff -a #临时 sed -ri 's/.*swap.*/#&/' /etc/fstab #永久
#配置用户最大打开文件数和进程数
cat > /etc/security/limits.conf <<EOF
* soft nofile 100000
* hard nofile 100000
* soft nproc 100000
* hard nproc 100000
EOF
#根据规划设置主机名 hostnamectl set-hostname k8s-master1 hostnamectl set-hostname k8s-master2 hostnamectl set-hostname k8s-node1 hostnamectl set-hostname k8s-node2 #添加hosts cat >> /etc/hosts << EOF 192.168.242.51 k8s-master1 192.168.242.52 k8s-node1 192.168.242.53 k8s-node2 192.168.242.54 k8s-master2 EOF #将桥接的IPV4流量传递到iptables的链 cat > /etc/sysctl.d/k8s.conf << EOF net.bridge.bridge-nf-call-ip6tables = 1 net.bridge.bridge-nf-call-iptables = 1 EOF sysctl --system #立即生效 #时间同步,很重要 yum install ntpdate -y
systemctl enable ntpdate --now
systemctl status ntpdate && date
2.2升级内核
centos 7.x系统自带的3.10.x内核存在一些bugs,导致运行docker、k8s不稳定。K8S安装必须升级内核版本到4.4以上
2.2.1查看当前内核版本和操作系统版本
[root@hecs-92531-0002 ~]# uname -r 3.10.0-1160.53.1.el7.x86_64
[root@hecs-92531-0002 ~]# cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)
2.2.2安装 ELRepo
ElRepo 是一个分发企业版Linux内核的社区仓库,在系统中导入ElRepo仓库的公钥,后续将从这个仓库中获取升级内核相关的资源。
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org #导入ElRepo仓库公钥 yum -y install https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm #Centos 7 安装 ELRepo yum install https://www.elrepo.org/elrepo-release-8.el8.elrepo.noarch.rpm #Centos 8 安装 ELRepo yum install https://www.elrepo.org/elrepo-release-9.el9.elrepo.noarch.rpm #Centos 9 安装 ElRepo
yum --disablerepo="*" --enablerepo="elrepo-kernel" list available #查看可用的稳定版镜像
输出信息是:
Available Packages kernel-lt.x86_64 5.4.207-1.el7.elrepo elrepo-kernel kernel-lt-devel.x86_64 5.4.207-1.el7.elrepo elrepo-kernel kernel-lt-doc.noarch 5.4.207-1.el7.elrepo elrepo-kernel kernel-lt-headers.x86_64 5.4.207-1.el7.elrepo elrepo-kernel kernel-lt-tools.x86_64 5.4.207-1.el7.elrepo elrepo-kernel kernel-lt-tools-libs.x86_64 5.4.207-1.el7.elrepo elrepo-kernel kernel-lt-tools-libs-devel.x86_64 5.4.207-1.el7.elrepo elrepo-kernel kernel-ml.x86_64 5.18.14-1.el7.elrepo elrepo-kernel kernel-ml-devel.x86_64 5.18.14-1.el7.elrepo elrepo-kernel kernel-ml-doc.noarch 5.18.14-1.el7.elrepo elrepo-kernel kernel-ml-headers.x86_64 5.18.14-1.el7.elrepo elrepo-kernel kernel-ml-tools.x86_64 5.18.14-1.el7.elrepo elrepo-kernel kernel-ml-tools-libs.x86_64 5.18.14-1.el7.elrepo elrepo-kernel kernel-ml-tools-libs-devel.x86_64 5.18.14-1.el7.elrepo elrepo-kernel perf.x86_64 5.18.14-1.el7.elrepo elrepo-kernel python-perf.x86_64 5.18.14-1.el7.elrepo elrepo-kernel
2.2.3升级内核
yum --enablerepo=elrepo-kernel install kernel-ml #安装最新版内核 yum --enablerepo=elrepo-kernel install -y kernel-lt #安装最新长期支持版内核(推荐) awk -F\' '$1=="menuentry " {print i++ " : " $2}' /etc/grub2.cfg # 查看当前系统已安装内核 输出信息是:
0 : CentOS Linux (5.4.207-1.el7.elrepo.x86_64) 7 (Core) 1 : CentOS Linux (3.10.0-1160.53.1.el7.x86_64) 7 (Core) 2 : CentOS Linux (3.10.0-1160.el7.x86_64) 7 (Core) 3 : CentOS Linux (0-rescue-acca19161ce94d449c58923b12797030) 7 (Core)
2.2.4切换新内核启动
修改 /etc/default/grub 文件,设置GRUB_DEFAULT的值为2.2.3中输出的最新版内核对应的序号。CentOS Linux (5.4.207-1.el7.elrepo.x86_64) 7 (Core) 前边的序号是0,所以设置GRUB_DEFAULT = 0 。
vi /etc/default/grub GRUB_TIMEOUT=5 GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)" GRUB_DEFAULT=saved #修改后为0 GRUB_DISABLE_SUBMENU=true GRUB_TERMINAL_OUTPUT="console" GRUB_CMDLINE_LINUX="net.ifnames=0 consoleblank=600 console=tty0 console=ttyS0,115200n8 spectre_v2=off nopti crashkernel=auto spectre_v2=retpoline " GRUB_DISABLE_RECOVERY="true"
2.2.5重新配置内核参数
[root@hecs-92531-0002 ~]# grub2-mkconfig -o /boot/grub2/grub.cfg
Generating grub configuration file ... Found linux image: /boot/vmlinuz-5.4.207-1.el7.elrepo.x86_64 Found initrd image: /boot/initramfs-5.4.207-1.el7.elrepo.x86_64.img Found linux image: /boot/vmlinuz-3.10.0-1160.53.1.el7.x86_64 Found initrd image: /boot/initramfs-3.10.0-1160.53.1.el7.x86_64.img Found linux image: /boot/vmlinuz-3.10.0-1160.el7.x86_64 Found initrd image: /boot/initramfs-3.10.0-1160.el7.x86_64.img Found linux image: /boot/vmlinuz-0-rescue-acca19161ce94d449c58923b12797030 Found initrd image: /boot/initramfs-0-rescue-acca19161ce94d449c58923b12797030.img done
2.2.6重启系统,检查系统内核更改是否生效
reboot [root@hecs-92531-0002 ~]# uname -r 5.4.207-1.el7.elrepo.x86_64 #已生效
3、部署etcd集群
3.1 etcd简介
Etcd 是一个分布式键值存储系统,Kubernetes使用Etcd进行数据存储,所以先准备一个Etcd数据库,为解决Etcd单点故障,应采用集群方式部署,这里使用3台组建集群,可容忍1台机器故障,当然,你也可以使用5台组建集群,可容忍2台机器故障。
每个 etcd cluster 都是有若千个 member 组成的,每个 member 是一个独立运行的 etcd 实例单台机器上可以运行多个 member。
在正常运行的状态下,集群中会有一个leader,其余的 member 都是 followers。leader向 followers 同步日志,保证数据在各个 member都有副本。
leader 还会定时向所有的 member 发送心跳报文,如果在规定的时间里 follower 没有收到心跳,就会重新进行选举。
客户端所有的请求都会先发送给 leader,leader 向所有的 followers 同步日志,等收到超过半数的确认后就把该日志存储到磁盘,并返回响应客户端。
每个 etcd 服务有三大主要部分组成: raft实现、WAL日志存储、数据的存储和索引。
3.2 服务器规划

3.3 cfssl证书生成工具准备
cfssl简介:
cfssl是一个开源的证书管理工具,使用json文件生成证书,相比openssl更方便使用。
找任意一台服务器操作,这里用Master1节点。
#创建目录存放cfssl工具 mkdir /software-cfssl #下载相关工具 wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 -P /software-cfssl/ wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 -P /software-cfssl/ wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 -P /software-cfssl/ cd /software-cfssl/ chmod +x * cp cfssl_linux-amd64 /usr/local/bin/cfssl cp cfssljson_linux-amd64 /usr/local/bin/cfssljson cp cfssl-certinfo_linux-amd64 /usr/bin/cfssl-certinfo
3.4 自签证书颁发机构(CA)
在 Kubernetes 中,使用自签名根证书颁发机构可以为 Kubernetes API Server、etcd 和 kubelet 等组件提供安全通信。一般情况下,我们需要将自签名根证书 CA.pem 分发给所有工作节点,并将其添加到容器镜像中,以便后续在 Kubernetes 集群中进行节点间的安全通信验证。
3.4.1 创建工作目录
mkdir -p ~/TLS/{etcd,k8s} cd ~/TLS/etcd/
3.4.2 生成自签CA配置
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", #指定生成的证书的 Common Name(通用名称)为 "etcd CA"。通用名称通常用于标识证书所属的实体或主体 "key": { "algo": "rsa", #RSA 密钥类型 "size": 2048 #密钥大小为 2048 位,密钥越大,安全性越高,但也会增加计算量 }, "names": [ { "C": "CN", #指定证书颁发机构的名称和所在地,国家/地区(Country/C),CN中国 "L": "YuMingYu", #城市(Locality/L) "ST": "YuMingYu" #州/省(State/ST) } ] } EOF
3.4.3 生成自签CA证书
cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
说明:
当前目录下会生成 ca.pem和ca-key.pem文件
[root@k8s-master1 etcd]# ls . ca-config.json(定义生成该根证书所需配置信息的 JSON 格式文件,包括有效期、使用场景)
ca.csr(生成 CA 证书签名请求的文件,包含了需要签名的信息,如组织名和国家代码等)
ca-csr.json(定义 CA 签名请求的配置信息,如公钥算法和密钥长度等)
ca-key.pem(根证书私钥文件,用于对由该 CA 签名的证书进行签名)
ca.pem(根证书公钥文件,用于验证由该 CA 签名的证书的有效性)
3.5 使用自签CA签发etcd https证书
3.5.1 创建证书申请文件
cat > server-csr.json << EOF { "CN": "etcd", "hosts": [ "192.168.242.51", "192.168.242.52", "192.168.242.53", "192.168.242.54" ], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "YuMingYu", "ST": "YuMingYu" } ] } EOF
说明:
上述文件hosts字段中ip为所有etcd节点的集群内部通信ip,一个都不能少,为了方便后期扩容可以多写几个预留的ip。
3.5.2 生成证书
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=www server-csr.json | cfssljson -bare server
说明:
当前目录下会生成 server.pem 和 server-key.pem
[root@k8s-master1 etcd]# ls ca-config.json ca-csr.json ca.pem server-csr.json server.pem ca.csr ca-key.pem server.csr server-key.pem
3.6 下载etcd二进制文件
#下载后上传到服务器任意位置即可 https://github.com/etcd-io/etcd/releases/download/v3.4.9/etcd-v3.4.9-linux-amd64.tar.gz
3.7 部署etcd集群
3.7.1 创建工作目录并解压二进制包
mkdir /opt/etcd/{bin,cfg,ssl} -p tar -xf etcd-v3.4.9-linux-amd64.tar.gz mv etcd-v3.4.9-linux-amd64/{etcd,etcdctl} /opt/etcd/bin/
3.7.2 创建etcd配置文件
cat > /opt/etcd/cfg/etcd.conf << EOF #[Member] ETCD_NAME="etcd-1" ETCD_DATA_DIR="/var/lib/etcd/default.etcd" ETCD_LISTEN_PEER_URLS="https://192.168.242.51:2380" ETCD_LISTEN_CLIENT_URLS="https://192.168.242.51:2379" #[Clustering] ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.242.51:2380" ETCD_ADVERTISE_CLIENT_URLS="https://192.168.242.51:2379" ETCD_INITIAL_CLUSTER="etcd-1=https://192.168.242.51:2380,etcd-2=https://192.168.242.52:2380,etcd-3=https://192.168.242.53:2380" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"
ETCD_INITIAL_CLUSTER_STATE="new" EOF
#注释
ETCD_NAME="etcd-1" #节点名称,集群中唯一 ETCD_DATA_DIR="/var/lib/etcd/default.etcd" #数据目录 ETCD_LISTEN_PEER_URLS="https://192.168.242.51:2380" #集群通讯监听地址 ETCD_LISTEN_CLIENT_URLS="https://192.168.242.51:2379" #客户端访问监听地址 #[Clustering] ETCD_INITIAL_CLUSTER="etcd-1=https://192.168.242.51:2380,etcd-2=https://192.168.242.52:2380,etcd-3=https://192.168.242.53:2380" #集群节点地址 ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" #集群token,用于验证 etcd 集群中的节点,只有使用相同的 token 才能加入到同一个 etcd 集群中;用于控制 etcd 集群的访问权限,只有持有正确的 token 才能对 etcd 集群进行操作(例如写入、读取、删除等) ETCD_INITIAL_CLUSTER_STATE="new" #加入集群的状态:new是新集群,existing表示加入已有集群
3.8 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/cfg/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
3.9 将master1节点所有生成的文件拷贝到节点2和节点3
for i in {2..3} do scp -r /opt/etcd/ root@192.168.242.5$i:/opt/ scp /usr/lib/systemd/system/etcd.service root@192.168.242.5$i:/usr/lib/systemd/system/ done
3.10 修改节点2,节点3 ,etcd.conf配置文件中的节点名称和当前服务器IP:
#[Member] ETCD_NAME="etcd-1" #节点2修改为: etcd-2;节点3修改为: etcd-3 ETCD_DATA_DIR="/var/lib/etcd/default.etcd" ETCD_LISTEN_PEER_URLS="https://192.168.242.51:2380" #修改为对应节点IP ETCD_LISTEN_CLIENT_URLS="https://192.168.242.51:2379" #修改为对应节点IP #[Clustering] ETCD_INITIAL_ADVERTISE_PEER_URLS="https://192.168.242.51:2380" #修改为对应节点IP ETCD_ADVERTISE_CLIENT_URLS="https://192.168.242.51:2379" #修改为对应节点IP ETCD_INITIAL_CLUSTER="etcd-1=https://192.168.242.51:2380,etcd-2=https://192.168.242.52:2380,etcd-3=https://192.168.242.53:2380" ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster" ETCD_INITIAL_CLUSTER_STATE="new"
3.11 启动etcd并设置开机自启
etcd须多个节点同时启动,不然执行systemctl start etcd会一直卡在前台,连接其他节点,建议通过批量管理工具,或者脚本同时启动etcd。
systemctl daemon-reload
systemctl enable etcd --now
systemctl status etcd
3.12 检查etcd集群状态
#查看集群健康状态
[root@k8s-master1 ~]# 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.242.51:2379,https://192.168.242.52:2379,https://192.168.242.53:2379" endpoint health --write-out=table +-----------------------------+--------+-------------+-------+ | ENDPOINT | HEALTH | TOOK | ERROR | +-----------------------------+--------+-------------+-------+ | https://192.168.242.52:2379 | true | 67.267851ms | | | https://192.168.242.51:2379 | true | 67.374967ms | | | https://192.168.242.53:2379 | true | 69.244918ms | | +-----------------------------+--------+-------------+-------+
#查看集群主节点及节点
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.242.51:2379,https://192.168.242.52:2379,https://192.168.242.53:2379" endpoint status --write-out=table
3.13 etcd问题排查(日志)
less /var/log/message journalctl -u etcd
4、安装Docker(所有节点)
4.1 解压二进制包
wget https://download.docker.com/linux/static/stable/x86_64/docker-19.03.9.tgz tar -xf docker-19.03.9.tgz mv docker/* /usr/bin/
4.2 配置镜像加速
sudo mkdir -p /etc/docker sudo tee /etc/docker/daemon.json <<-'EOF' { "data-root": "/var/lib/docker", #存储数据的根目录 "exec-opts": ["native.cgroupdriver=systemd"], #使用 systemd 作为 cgroup driver,用于隔离系统资源 "registry-mirrors": [ #使用 SSL/TLS 加密通信的镜像加速器,是安全可靠的。拉取镜像时,会优先从镜像加速器中获取所需镜像 "https://3s9106.mirror.alncs.com" ], "insecure-registries": ["http://仓库1","http://仓库2"], #用于配置不安全的 Docker 镜像仓库 "max-concurrent-downloads": 10, #最大并发下载数为 10。 "live-restore": true, #开启容器的 live restore 功能,即使在 Docker daemon 关闭的情况下也可以保持容器运行。 "log-driver": "json-file", #使用 json-file 作为 Docker 日志驱动程序。 "log-level": "warn", #指定 Docker 日志级别为 warn,即只记录警告和错误信息。 "log-opts": { #日志选项,包含最大文件大小为 50MB,最大文件数量为 1 "max-size": "50m", "max-file": "1" }, "storage-driver": "overlay2" #指定使用 overlay2 存储驱动程序来管理 Docker 镜像和容器的存储。 } EOF
4.3 systemd管理docker
cat > /usr/lib/systemd/system/docker.service << EOF [Unit] Description=Docker Application Container Engine Documentation=http://docs.docker.io [Service] Environment="PATH=/opt/kube/bin:/bin:/sbin:/usr/bin:/usr/sbin" ExecStart=/usr/bin/dockerd ExecStartPost=/sbin/iptables -I FORWARD -s 0.0.0.0/0 -j ACCEPT ExecReload=/bin/kill -s HUP $MAINPID Restart=always RestartSec=5 LimitNOFILE=infinity LimitNPROC=infinity LimitCORE=infinity Delegate=yes KillMode=process [Install] WantedBy=multi-user.target EOF
4.4 启动并设置开机启动
systemctl daemon-reload systemctl enable docker --now systemctl status docker
5、部署Master节点
5.1 生成kube-apiserver证书
etcd 的 CA 和 kube-apiserver 的 CA 并不是同一个证书颁发机构
5.1.1 自签证书颁发机构(CA)
cd ~/TLS/k8s cat > ca-config.json << EOF { "signing": { "default": { "expiry": "87600h" }, "profiles": { "kubernetes": { "expiry": "87600h", "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": "Beijing", "ST": "Beijing", "O": "k8s", #组织名(Organization/O) "OU": "System" #组织单位名(Organizational Unit/OU) } ] } EOF
生成证书:
cfssl gencert -initca ca-csr.json | cfssljson -bare ca -
目录下会生成 ca.pem 和 ca-key.pem
5.1.2 使用自签CA签发kube-apiserver https证书
创建证书申请文件:
cat > server-csr.json << EOF { "CN": "kubernetes", "hosts": [ "10.0.0.1", "127.0.0.1", "192.168.242.51", "192.168.242.52", "192.168.242.53", "192.168.242.54", "192.168.242.55", "kubernetes", "kubernetes.default", "kubernetes.default.svc", "kubernetes.default.svc.cluster", "kubernetes.default.svc.cluster.local" ], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "BeiJing", "ST": "BeiJing", "O": "k8s", "OU": "System" } ] } EOF
说明:
上述文件中hosts字段中IP为所有Master/LB/VIP IP,一个都不能少,为了方便后期扩容可以多写几个预留的IP。如果后续新增了ip,只能重新申请证书。
生成证书:
cfssl gencert -ca=ca.pem -ca-key=ca-key.pem -config=ca-config.json -profile=kubernetes server-csr.json | cfssljson -bare server
说明:
当前目录下会生成server.pem 和 server-key.pem文件。
5.2 下载k8s二进制包
https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG-1.20.md #1.20版本,版本自选
5.3 解压二进制包
mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs} tar zxvf kubernetes-server-linux-amd64.tar.gz cd kubernetes/server/bin cp kube-apiserver kube-scheduler kube-controller-manager /opt/kubernetes/bin cp kubectl /usr/bin/
5.4 部署kube-apiserver
5.4.1 创建配置文件
cat > /opt/kubernetes/cfg/kube-apiserver.conf << EOF KUBE_APISERVER_OPTS="--logtostderr=false \\ --v=2 \\ --log-dir=/opt/kubernetes/logs \\ --etcd-servers=https://192.168.242.51:2379,https://192.168.242.52:2379,https://192.168.242.53:2379 \\ --bind-address=192.168.242.51 \\ --secure-port=6443 \\ --advertise-address=192.168.242.51 \\ --allow-privileged=true \\ --service-cluster-ip-range=10.0.0.0/24 \\ --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,NodeRestriction \\ --authorization-mode=RBAC,Node \\ --enable-bootstrap-token-auth=true \\ --token-auth-file=/opt/kubernetes/cfg/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/server-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
说明:
上面两个\\第一个是转义符,第二个是换行符,使用转义符是为了使用EOF保留换行符。
参数详解如下:
--logtostderr=false: 将日志输出到文件而不是标准输出。 --v=2: 日志级别,2 表示 Info 级别。 --log-dir=/opt/kubernetes/logs: 指定日志文件的输出目录。 --etcd-servers=https://192.168.242.51:2379,https://192.168.242.52:2379,https://192.168.242.53:2379: 指定 Kubernetes API Server 用来连接 etcd 集群的地址,多个地址之间用逗号分隔。 --bind-address=192.168.242.51: 指定 API Server 监听的 IP 地址。 --secure-port=6443: 指定 Kubernetes API Server 监听的端口,默认为 6443。 --advertise-address=192.168.242.51: 指定 API Server 的访问地址,用于和其他组件通信。 --allow-privileged=true: 允许容器使用特权模式,默认为 true。 --service-cluster-ip-range=10.0.0.0/24: 指定 Service IP 地址段,通过此 IP 地址段进行 Service 的请求转发。 --enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,ResourceQuota,NodeRestriction: 启用 Admission Controller 插件,决策 Kubernetes API Server 是否能够创建和更新资源对象。 --authorization-mode=RBAC,Node: 指定授权模式,RBAC 表示使用 Role-Based Access Control 进行授权,Node 表示使用节点名称进行授权。 --enable-bootstrap-token-auth=true: 允许使用 Bootstrap Token 进行身份验证。 --token-auth-file=/opt/kubernetes/cfg/token.csv: 指定 Token 文件的存放路径。 --service-node-port-range=30000-32767: 指定节点端口范围,用于 NodePort 类型的 Service。 --kubelet-client-certificate=/opt/kubernetes/ssl/server.pem: 指定 API Server 向 kubelet 发送请求时使用的客户端证书。 --kubelet-client-key=/opt/kubernetes/ssl/server-key.pem: 指定客户端证书的私钥。 --tls-cert-file=/opt/kubernetes/ssl/server.pem: 指定 API Server 的 TLS 证书文件。 --tls-private-key-file=/opt/kubernetes/ssl/server-key.pem: 指定 TLS 证书的私钥文件。 --client-ca-file=/opt/kubernetes/ssl/ca.pem: 指定客户端证书颁发机构的证书,用于验证客户端证书的有效性。 --service-account-key-file=/opt/kubernetes/ssl/ca-key.pem: 指定 Service Account 的私钥文件。 --service-account-issuer=api: 指定发出 Service Account Token 的 Issuer。 --service-account-signing-key-file=/opt/kubernetes/ssl/server-key.pem: 指定 Service Account Token 签名密钥文件。 --etcd-cafile=/opt/etcd/ssl/ca.pem: 指定 etcd 集群 CA 证书文件。 --etcd-certfile=/opt/etcd/ssl/server.pem: 指定 etcd 集群客户端证书文件。 --etcd-keyfile=/opt/etcd/ssl/server-key.pem: 指定 etcd 集群客户端证书的私钥文件。 --requestheader-client-ca-file=/opt/kubernetes/ssl/ca.pem: 指定客户端请求 API Server 使用的 CA 证书。 --proxy-client-cert-file=/opt/kubernetes/ssl/server.pem: 指定 kube-proxy 向 API Server 发送请求时使用的客户端证书。 --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: 启用 kube-aggregator 插件。 --audit-log-maxage=30: 指定审计日志保留的时间,单位天 --audit-log-maxbackup=3: 指定审计日志保留的个数。 --audit-log-maxsize=100: 指定审计日志文件的最大大小,单位为 MB。 --audit-log-path=/opt/kubernetes/logs/k8s-audit.log: 指定审计日志输出的路径。
5.4.2 把刚才生成的证书放在配置文件中的路径
cp ~/TLS/k8s/ca*pem ~/TLS/k8s/server*pem /opt/kubernetes/ssl/
5.4.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还是由我们统一颁发一个证书。
TLS bootstraping 工作流程:
创建上述配置文件中token文件:
#文件与kube-apiserver.conf的token-auth-file相对应
cat > /opt/kubernetes/cfg/token.csv << EOF 4136692876ad4b01bb9dd0988480ebba,kubelet-bootstrap,10001,"system:node-bootstrapper" EOF
格式:token,用户名,UID,用户组
token可自行生成替换:
head -c 16 /dev/urandom | od -An -t x | tr -d ' '
5.4.4 systemd管理apiserver
cat > /usr/lib/systemd/system/kube-apiserver.service << EOF [Unit] Description=Kubernetes API Server Documentation=https://github.com/kubernetes/kubernetes [Service] EnvironmentFile=/opt/kubernetes/cfg/kube-apiserver.conf ExecStart=/opt/kubernetes/bin/kube-apiserver \$KUBE_APISERVER_OPTS Restart=on-failure [Install] WantedBy=multi-user.target EOF
5.4.5 启动并设置开机启动
systemctl daemon-reload systemctl enable kube-apiserver --now systemctl status kube-apiserver
5.5 部署kube-controller-manager
5.5.1 创建配置文件
cat > /opt/kubernetes/cfg/kube-controller-manager.conf << EOF KUBE_CONTROLLER_MANAGER_OPTS="--logtostderr=false \\ --v=2 \\ --log-dir=/opt/kubernetes/logs \\ --leader-elect=true \\ --kubeconfig=/opt/kubernetes/cfg/kube-controller-manager.kubeconfig \\ --bind-address=127.0.0.1 \\ --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
参数详解:
--logtostderr=false:将日志输出到文件而非标准输出。 --v=2:设置日志级别为 2,即输出信息和警告,不包括调试和错误级别的日志。 --log-dir=/opt/kubernetes/logs:设置日志输出目录为 /opt/kubernetes/logs。 --leader-elect=true:开启 leader 选举机制,确保只有一个 kube-controller-manager 作为主节点运行。 --kubeconfig=/opt/kubernetes/cfg/kube-controller-manager.kubeconfig:指定 kube-controller-manager 的配置文件路径,用于从 API Server 获取集群状态。 --bind-address=127.0.0.1:绑定 IP 地址,仅允许本地访问。 --allocate-node-cidrs=true:开启节点 CIDR 分配,可以在集群中自动为每个节点分配一个唯一的 CIDR 子网。 --cluster-cidr=10.244.0.0/16:设置集群 Pod 网络的 CIDR 子网地址。 --service-cluster-ip-range=10.0.0.0/24:设置服务的虚拟 IP 地址范围,为服务提供一个固定的 IP 地址,方便使用者访问和发现服务。 --cluster-signing-cert-file=/opt/kubernetes/ssl/ca.pem:设置集群签名 CA 证书文件路径,用于签署 TLS 证书等。 --cluster-signing-key-file=/opt/kubernetes/ssl/ca-key.pem:设置集群签名 CA 私钥文件路径,用于签署 TLS 证书等。 --root-ca-file=/opt/kubernetes/ssl/ca.pem:指定根证书文件路径,用于验证 kubelet 发送的 CSR 请求。 --service-account-private-key-file=/opt/kubernetes/ssl/ca-key.pem:设置 Service Account 的私钥文件路径,用于生成和签署 Service Account Token。 --cluster-signing-duration=87600h0m0s:设置集群签名证书的有效期为 10 年。
5.5.2 创建kube-controller-manager证书请求文件 :
cd ~/TLS/k8s cat > kube-controller-manager-csr.json << EOF { "CN": "system:kube-controller-manager", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "BeiJing", "ST": "BeiJing", "O": "system:masters", "OU": "System" } ] } EOF
5.5.3 生成kubeconfig证书
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
5.5.4 生成kube-controller-manager.kubeconfig文件
以下是shell命令,直接在shell终端执行
#这里只配置了单个apiserver地址,后面从单主扩为多主要改为负载地址,后面有教程
KUBE_CONFIG="/opt/kubernetes/cfg/kube-controller-manager.kubeconfig" KUBE_APISERVER="https://192.168.242.51: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=./kube-controller-manager.pem \ --client-key=./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}
#kubectl config使用介绍
Kubernetes 配置文件通常位于 ~/.kube/config,它包含了连接到 Kubernetes 集群所需的信息,如集群的地址、认证凭据、上下文等。
可在/etc/profile添加变量export KUBECONFIG=/root/.kube/config1 更改配置文件引用,source变量即时生效。 以下是 kubectl config 命令中一些常用的子命令和功能: kubectl config view:查看当前配置文件的内容。可以显示当前使用的上下文、集群、用户等信息。 kubectl config get-contexts:获取所有的上下文列表,显示当前可用的上下文及其所关联的集群和用户。 kubectl config use-context <context-name>:设置当前使用的上下文。通过指定上下文名称,可以切换到不同的 Kubernetes 集群。 kubectl config set-context <context-name> --cluster=<cluster-name> --user=<user-name> --namespace=<namespace>:创建或修改上下文。可以设置不同的集群、用户和命名空间来定位到特定的环境。 kubectl config delete-context <context-name>:删除指定的上下文。 kubectl config set-cluster <cluster-name> --server=<server-url> --certificate-authority=<ca-file>:设置集群连接信息,包括集群名称、服务器地址和证书等。 kubectl config set-credentials <user-name> --username=<username> --password=<password>:设置用户认证凭据,包括用户名和密码。 kubectl config set-credentials <user-name> --client-certificate=<cert-file> --client-key=<key-file>:设置用户认证凭据,使用客户端证书和密钥。 通过 kubectl config 命令,你可以轻松管理和配置 Kubernetes 集群的连接信息、凭据和上下文等内容,方便在不同环境中切换和操作 Kubernetes 集群。
5.5.5 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/cfg/kube-controller-manager.conf ExecStart=/opt/kubernetes/bin/kube-controller-manager \$KUBE_CONTROLLER_MANAGER_OPTS Restart=on-failure [Install] WantedBy=multi-user.target EOF
5.5.6 启动并设置开机自启
systemctl daemon-reload systemctl enable kube-controller-manager --now systemctl status kube-controller-manager
5.6 部署 kube-scheduler
5.6.1 创建kube-scheduler配置文件
cat > /opt/kubernetes/cfg/kube-scheduler.conf << EOF KUBE_SCHEDULER_OPTS="--logtostderr=false \\ --v=2 \\ --log-dir=/opt/kubernetes/logs \\ --leader-elect \\ --kubeconfig=/opt/kubernetes/cfg/kube-scheduler.kubeconfig \\ --bind-address=127.0.0.1" EOF
- --kubeconfig :连接apiserver配置文件
- --leader-elect :当该组件启动多个时,自动选举(HA)。
5.6.2 生成kube-scheduler证书
# 切换工作目录 cd ~/TLS/k8s # 创建证书请求文件 cat > kube-scheduler-csr.json << EOF { "CN": "system:kube-scheduler", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "BeiJing", "ST": "BeiJing", "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
5.6.3生成kube-scheduler.kubeconfig文件
KUBE_CONFIG="/opt/kubernetes/cfg/kube-scheduler.kubeconfig" KUBE_APISERVER="https://192.168.242.51: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}
5.6.4 systemd管理scheduler
cat > /usr/lib/systemd/system/kube-scheduler.service << EOF [Unit] Description=Kubernetes Scheduler Documentation=https://github.com/kubernetes/kubernetes [Service] EnvironmentFile=/opt/kubernetes/cfg/kube-scheduler.conf ExecStart=/opt/kubernetes/bin/kube-scheduler \$KUBE_SCHEDULER_OPTS Restart=on-failure [Install] WantedBy=multi-user.target EOF
5.6.5 启动并设置开机启动
systemctl daemon-reload systemctl enable kube-scheduler --now systemctl status kube-scheduler
5.7 查看集群状态
通过kubectl工具查看当前集群组件状态 :
[root@k8s-master1 k8s]# kubectl get cs Warning: v1 ComponentStatus is deprecated in v1.19+ NAME STATUS MESSAGE ERROR scheduler Healthy ok controller-manager Healthy ok etcd-2 Healthy {"health":"true"} etcd-0 Healthy {"health":"true"} etcd-1 Healthy {"health":"true"}
5.8配置kubelet-bootstrap用户请求证书
5.8.1生成kubectl连接集群的证书
cat > admin-csr.json <<EOF { "CN": "admin", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "BeiJing", "ST": "BeiJing", "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
5.8.2生成kubeconfig文件
mkdir /root/.kube KUBE_CONFIG="/root/.kube/config" KUBE_APISERVER="https://192.168.242.51:6443" kubectl config set-cluster kubernetes \ --certificate-authority=/opt/kubernetes/ssl/ca.pem \ --embed-certs=true \ --server=${KUBE_APISERVER} \ --kubeconfig=${KUBE_CONFIG}
#cluster-admin是k8s内置的具有最高权限的集群角色,对整个集群具有完全权限,不是自定义。 kubectl config set-credentials cluster-admin \ --client-certificate=./admin.pem \ --client-key=./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}
5.8.3 授权kubelet-bootstrap用户允许请求证书
kubectl create clusterrolebinding kubelet-bootstrap \ --clusterrole=system:node-bootstrapper \ --user=kubelet-bootstrap
6、部署Work Node
下面还是在master node上面操作,即当Master节点,也当Work Node节点
6.1 创建工作目录并拷贝二进制文件
注: 在所有work node创建工作目录
mkdir -p /opt/kubernetes/{bin,cfg,ssl,logs}
从k8s-server软件包中拷贝到所有work节点:
#进入到k8s-server软件包目录 cd /k8s-software/kubernetes/server/bin/ for i in {1..3} do scp kubelet kube-proxy root@192.168.242.5$i:/opt/kubernetes/bin/ done
6.2 部署kubelet
6.2.1 创建配置文件
cat > /opt/kubernetes/cfg/kubelet.conf << EOF KUBELET_OPTS="--logtostderr=false \\ --v=2 \\ --log-dir=/opt/kubernetes/logs \\ --hostname-override=k8s-master1 \\ --network-plugin=cni \\ --kubeconfig=/opt/kubernetes/cfg/kubelet.kubeconfig \\ --bootstrap-kubeconfig=/opt/kubernetes/cfg/bootstrap.kubeconfig\\
--config=/opt/kubernetes/cfg/kubelet-config.yml \\
--cert-dir=/opt/kubernetes/ssl \\
--pod-infra-container-image=registry.cn-hangzhou.aliyuncs.com/google-containers/pause-amd64:3.0"
EOF
注释
--hostname-override :显示名称,集群唯一(不可重复),可设置为节点的hostname --network-plugin :启用CNI。 --kubeconfig : 空路径,会自动生成,后面用于连接apiserver。 --bootstrap-kubeconfig :首次启动向apiserver申请证书 --config :配置文件参数。 --cert-dir :kubelet证书目录。 --pod-infra-container-image :管理Pod网络容器的镜像 init container
6.2.2 配置文件
cat > /opt/kubernetes/cfg/kubelet-config.yml << EOF kind: KubeletConfiguration apiVersion: kubelet.config.k8s.io/v1beta1 address: 0.0.0.0 port: 10250 readOnlyPort: 10255 cgroupDriver: cgroupfs 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
6.2.3 生成kubelet初次加入集群引导kubeconfig文件
以下是shell命令,直接在shell终端执行
KUBE_CONFIG="/opt/kubernetes/cfg/bootstrap.kubeconfig" KUBE_APISERVER="https://192.168.242.51:6443" # apiserver IP:PORT TOKEN="4136692876ad4b01bb9dd0988480ebba" # 与token.csv里保持一致 /opt/kubernetes/cfg/token.csv # 生成 kubelet bootstrap kubeconfig 配置文件 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}
6.2.4 systemd管理kubelet
cat > /usr/lib/systemd/system/kubelet.service << EOF [Unit] Description=Kubernetes Kubelet After=docker.service [Service] EnvironmentFile=/opt/kubernetes/cfg/kubelet.conf ExecStart=/opt/kubernetes/bin/kubelet \$KUBELET_OPTS Restart=on-failure LimitNOFILE=65536 [Install] WantedBy=multi-user.target EOF
6.2.5 启动并设置开机启动
systemctl daemon-reload systemctl enable kubelet --now systemctl status kubelet
6.2.6 允许kubelet证书申请并加入集群
#查看kubelet证书请求 [root@k8s-master1 bin]# kubectl get csr NAME AGE SIGNERNAME REQUESTOR CONDITION node-csr-KbHieprZUMOvTFMHGQ1RNTZEhsSlT5X6wsh2lzfUry4 107s kubernetes.io/kube-apiserver-client-kubelet kubelet-bootstrap Pending ## 状态为pending,表示并未批准,状态为Approved,Issued,表示已经批准
#批准kubelet节点申请 [root@k8s-master1 bin]# kubectl certificate approve node-csr-KbHieprZUMOvTFMHGQ1RNTZEhsSlT5X6wsh2lzfUry4 certificatesigningrequest.certificates.k8s.io/node-csr-KbHieprZUMOvTFMHGQ1RNTZEhsSlT5X6wsh2lzfUry4 approved #代表批准成功 #查看申请 [root@k8s-master1 bin]# kubectl get csr NAME AGE SIGNERNAME REQUESTOR CONDITION node-csr-KbHieprZUMOvTFMHGQ1RNTZEhsSlT5X6wsh2lzfUry4 2m35s kubernetes.io/kube-apiserver-client-kubelet kubelet-bootstrap Approved,Issued #查看节点 [root@k8s-master1 bin]# kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-master1 NotReady <none> 2m11s v1.20.10
说明:
由于网络插件还没有部署,节点会没有准备就绪NotReady
6.3 部署kube-proxy
6.3.1 创建配置文件
cat > /opt/kubernetes/cfg/kube-proxy.conf << EOF KUBE_PROXY_OPTS="--logtostderr=false \\ --v=2 \\ --log-dir=/opt/kubernetes/logs \\ --config=/opt/kubernetes/cfg/kube-proxy-config.yml" EOF
6.3.2 配置参数文件
cat > /opt/kubernetes/cfg/kube-proxy-config.yml << EOF kind: KubeProxyConfiguration apiVersion: kubeproxy.config.k8s.io/v1alpha1 bindAddress: 0.0.0.0 metricsBindAddress: 0.0.0.0:10249 #指定 kube-proxy 暴露的 Prometheus 监控指标的地址和端口号。 clientConnection: kubeconfig: /opt/kubernetes/cfg/kube-proxy.kubeconfig hostnameOverride: k8s-master1 #指定 kube-proxy 的主机名 clusterCIDR: 10.244.0.0/16 #与kube-controller-manager.conf中的参数--cluster-cidr 的值相同,为集群Pod网络的CIDR子网地址
EOF
6.3.3 生成kube-proxy证书文件
# 切换工作目录 cd ~/TLS/k8s # 创建证书请求文件 cat > kube-proxy-csr.json << EOF { "CN": "system:kube-proxy", "hosts": [], "key": { "algo": "rsa", "size": 2048 }, "names": [ { "C": "CN", "L": "BeiJing", "ST": "BeiJing", "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
6.3.4 生成kube-proxy.kubeconfig文件
KUBE_CONFIG="/opt/kubernetes/cfg/kube-proxy.kubeconfig" KUBE_APISERVER="https://192.168.242.51: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=./kube-proxy.pem \ --client-key=./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}
6.3.5 systemd管理kube-proxy
cat > /usr/lib/systemd/system/kube-proxy.service << EOF [Unit] Description=Kubernetes Proxy After=network.target [Service] EnvironmentFile=/opt/kubernetes/cfg/kube-proxy.conf ExecStart=/opt/kubernetes/bin/kube-proxy \$KUBE_PROXY_OPTS Restart=on-failure LimitNOFILE=65536 [Install] WantedBy=multi-user.target EOF
6.3.6 启动并设置开机自启
systemctl daemon-reload systemctl enable kube-proxy --now systemctl status kube-proxy
6.4 部署网络组件(Calico)
Calico是一个纯三层的数据中心网络方案,是目前Kubernetes主流的网络方案。
下载calico.yaml,版本按需替换
wget https://docs.projectcalico.org/v3.23/manifests/calico.yaml --no-check-certificate
修改calico.yaml
修改1:默认的Calico清单文件中所使用的镜像来源于docker.io国外镜像源,上面我们配置了Docker镜像加速,应删除docker.io前缀以使镜像从国内镜像加速站点下载。 [root@k8s-master01 ~]# cat calico.yaml |grep 'image:' image: docker.io/calico/cni:v3.23.0 image: docker.io/calico/cni:v3.23.0 image: docker.io/calico/node:v3.23.0 image: docker.io/calico/kube-controllers:v3.23.0 [root@k8s-master01 ~]# sed -i 's#docker.io/##g' calico.yaml [root@k8s-master01 ~]# cat calico.yaml |grep 'image:' image: calico/cni:v3.23.0 image: calico/cni:v3.23.0 image: calico/node:v3.23.0 image: calico/kube-controllers:v3.23.0 修改2: 修改配置文件中定义的Pod网络(CALICO_IPV4POOL_CIDR), # - name: CALICO_IPV4POOL_CIDR # value: "192.168.0.0/16" #将这两行取消注释,然后将192.168.0.0/16这个网段替换成上方kube-controller-manager配置文件指定的cluster-cidr网段一样
应用calico.yaml
kubectl apply -f calico.yaml
kubectl get pods -n kube-system
等Calico Pod都Running,节点也会准备就绪Ready状态。
[root@k8s-master1 yaml]# kubectl get pods -n kube-system NAME READY STATUS RESTARTS AGE calico-kube-controllers-97769f7c7-zcz5d 1/1 Running 0 3m11s calico-node-5tnll 1/1 Running 0 3m11s [root@k8s-master1 yaml]# kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-master1 Ready <none> 21m v1.20.10
6.5 授权apiserver访问kubelet
cat > apiserver-to-kubelet-rbac.yaml << EOF apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: annotations: rbac.authorization.kubernetes.io/autoupdate: "true" labels: kubernetes.io/bootstrapping: rbac-defaults name: system:kube-apiserver-to-kubelet rules: - apiGroups: - "" resources: - nodes/proxy - nodes/stats - nodes/log - nodes/spec - nodes/metrics - pods/log verbs: - "*" --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: system:kube-apiserver namespace: "" roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: system:kube-apiserver-to-kubelet subjects: - apiGroup: rbac.authorization.k8s.io kind: User name: kubernetes EOF kubectl apply -f apiserver-to-kubelet-rbac.yaml
7、新增加Work Node
7.1 拷贝以部署好的相关文件到新节点
在Master节点将Work Node涉及文件拷贝到新节点 242.52/242.53
for i in {2..3}; do scp -r /opt/kubernetes root@192.168.242.5$i:/opt/; done for i in {2..3}; do scp -r /usr/lib/systemd/system/{kubelet,kube-proxy}.service root@192.168.242.5$i:/usr/lib/systemd/system; done for i in {2..3}; do scp -r /opt/kubernetes/ssl/ca.pem root@192.168.242.5$i:/opt/kubernetes/ssl/; done
7.2 删除kubelet证书和kubeconfig文件
rm -f /opt/kubernetes/cfg/kubelet.kubeconfig rm -f /opt/kubernetes/ssl/kubelet*
说明:
这几个文件是证书申请审批后自动生成的,每个Node不同,必须删除。
7.3 修改复制文件中的主机名
vi /opt/kubernetes/cfg/kubelet.conf --hostname-override=k8s-node1 vi /opt/kubernetes/cfg/kube-proxy-config.yml hostnameOverride: k8s-node1
7.4 启动并设置开机自启
systemctl daemon-reload systemctl enable kubelet kube-proxy --now systemctl status kubelet kube-proxy
7.5 在Master上同意新的Node kubelet证书申请
#查看证书请求 [root@k8s-master1 kubernetes]# kubectl get csr
#状态为pending,表示并未批准,状态为Approved,Issued,表示已经批准 NAME AGE SIGNERNAME REQUESTOR CONDITION node-csr-2vKShQc_wlqPrTPAwT5MHpdRWIX-oyr9NyBXu1XNwxg 12s kubernetes.io/kube-apiserver-client-kubelet kubelet-bootstrap Pending node-csr-KbHieprZUMOvTFMHGQ1RNTZEhsSlT5X6wsh2lzfUry4 47h kubernetes.io/kube-apiserver-client-kubelet kubelet-bootstrap Approved,Issued #执行批准命令 [root@k8s-master1 kubernetes]# kubectl certificate approve node-csr-2vKShQc_wlqPrTPAwT5MHpdRWIX-oyr9NyBXu1XNwxg
certificatesigningrequest.certificates.k8s.io/node-csr-2vKShQc_wlqPrTPAwT5MHpdRWIX-oyr9NyBXu1XNwxg approved #代表批准成功
7.6 查看Node状态(要稍等会才会变成ready,会下载一些初始化镜像)
[root@k8s-master1 kubernetes]# kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-master1 Ready <none> 46h v1.20.10 k8s-node1 Ready <none> 77s v1.20.10
8、部署Dashboard和CoreDNS
coredns是kubernetes的默认DNS服务器。是利用watch Kubernetes的Service和Pod生成NDS记录,然后通过配置kubelet的DNS选项让新启动的Pod使用CoreDNS提供的kubernetes集群内域名解析服务。
8.1 部署CoreDNS
cd kubernetes #解压后的k8s软件包
tar -zxvf kubernetes-src.tar.gz
cp cluster/addons/dns/coredns/coredns.yaml.base cluster/addons/dns/coredns/coredns.yaml
#或者自行下载https://github.com/kubernetes/kubernetes/blob/master/cluster/addons/dns/coredns/coredns.yaml.base
修改coredns.yaml
#修改1:k8s集群后缀名称__DNS__DOMAIN__,一般为cluster.local #77行 kubernetes __DNS__DOMAIN__ in-addr.arpa ip6.arpa { 修改后kubernetes cluster.local in-addr.arpa ip6.arpa { #修改2:coredns谷歌地址为dockerhub地址,容易下载 #142行 image: k8s.gcr.io/coredns/coredns:v1.8.6 修改后image: coredns/coredns:1.8.6 #修改3:pod启动内存限制大小,300Mi即可 #146行 memory: __DNS__MEMORY__LIMIT__ 修改后memory: 300Mi #修改4:coredns的svcIP地址,一般为svc网段的第二位,10.100.0.2,第一位为apiserver的svc #212行 clusterIP: __DNS__SERVER__ 修改后clusterIP: 10.0.0.2 #此为kubelet-config.yml中的clusterDNS地址
应用coredns.yaml
[root@k8s-master1 yaml]# kubectl apply -f coredns.yaml [root@k8s-master1 yaml]# kubectl get pods -n kube-system NAME READY STATUS RESTARTS AGE calico-kube-controllers-97769f7c7-zcz5d 1/1 Running 1 47h calico-node-5tnll 1/1 Running 1 47h calico-node-m8sdg 1/1 Running 0 42m calico-node-pqvk9 1/1 Running 0 56m coredns-6cc56c94bd-5hvfb 1/1 Running 0 37s
测试解析是否正常
[root@k8s-master1 yaml]# kubectl run -it --rm dns-test --image=busybox:1.28.4 sh If you don't see a command prompt, try pressing enter. / # ns nsenter nslookup / # nslookup kubernetes Server: 10.0.0.2 Address 1: 10.0.0.2 kube-dns.kube-system.svc.cluster.local
8.2部署Dashboard
获取dashboard.yaml
cd kubernetes #解压后的k8s软件包 路径:cluster/addons/dashboard/dashboard.yaml #解压kubernetes-src.tar.gz后的路径
#或者自行下载,版本号按需替换https://raw.githubusercontent.com/kubernetes/dashboard/v2.4.0/aio/deploy/recommended.yaml
应用dashboard.yaml
kubectl apply -f kubernetes-dashboard.yaml #查看部署情况 [root@k8s-master1 yaml]# kubectl get pods,svc -n kubernetes-dashboard NAME READY STATUS RESTARTS AGE pod/dashboard-metrics-scraper-7b59f7d4df-k49t9 1/1 Running 0 10m pod/kubernetes-dashboard-74d688b6bc-l9jz4 1/1 Running 0 10m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/dashboard-metrics-scraper ClusterIP 10.0.0.206 <none> 8000/TCP 10m service/kubernetes-dashboard NodePort 10.0.0.10 <none> 443:30001/TCP 10m
访问地址: https://NodeIP:30001
创建service account并绑定默认cluster-admin管理员集群角色
kubectl create serviceaccount dashboard-admin -n kube-system kubectl create clusterrolebinding dashboard-admin --clusterrole=cluster-admin --serviceaccount=kube-system:dashboard-admin kubectl describe secrets -n kube-system $(kubectl -n kube-system get secret | awk '/dashboard-admin/{print $1}')
使用输出的token登陆Dashboard(如访问提示不是私密连接异常,直接输入“thisisunsafe”即可)
至此一个单Master的k8s节点就已经完成了
9、增加Master节点(高可用架构)
Kubernetes作为容器集群系统,通过健康检查+重启策略实现了Pod故障自我修复能力,通过调度算法实现将Pod分布式部署,并保持预期副本数,根据Node失效状态自动在其他Node拉起Pod,实现了应用层的高可用性。
针对Kubernetes集群,高可用性还应包含以下两个层面的考虑:Etcd数据库的高可用性和Kubernetes Master组件的高可用性。 而Etcd我们已经采用3个节点组建集群实现高可用,本节将对Master节点高可用进行说明和实施。
Master节点扮演着总控中心的角色,通过不断与工作节点上的Kubelet和kube-proxy进行通信来维护整个集群的健康工作状态。如果Master节点故障,将无法使用kubectl工具或者API做任何集群管理。
Master节点主要有三个服务kube-apiserver、kube-controller-manager和kube-scheduler,其中kube-controller-manager和kube-scheduler组件自身通过选择机制已经实现了高可用,所以Master高可用主要针对kube-apiserver组件,而该组件是以HTTP API提供服务,因此对他高可用与Web服务器类似,增加负载均衡器对其负载均衡即可,并且可水平扩容。
9.1 部署Master2 Node
现在需要再增加一台新服务器,作为Master2和Node节点,IP是192.168.242.54。
Master2 与已部署的Master1所有操作一致。所以我们只需将Master1所有K8s文件拷贝过来,再修改下服务器IP和主机名启动即可。
9.1.1 安装Docker(Master1上拷贝文件)
scp /usr/bin/docker* root@192.168.242.54:/usr/bin scp /usr/bin/runc root@192.168.242.54:/usr/bin scp /usr/bin/containerd* root@192.168.242.54:/usr/bin scp /usr/lib/systemd/system/docker.service root@192.168.242.54:/usr/lib/systemd/system scp -r /etc/docker root@192.168.242.54:/etc
9.1.2 启动Docker、设置开机自启(Master2)
systemctl daemon-reload
systemctl start docker
systemctl enable docker
9.1.3 创建etcd证书目录(Master2)
mkdir -p /opt/etcd/ssl
9.1.4 拷贝文件(Master1上操作)
拷贝Master1上所有k8s文件和etcd证书到Master2:
scp -r /opt/kubernetes root@192.168.242.54:/opt scp -r /opt/etcd/ssl root@192.168.242.54:/opt/etcd scp /usr/lib/systemd/system/kube* root@192.168.242.54:/usr/lib/systemd/system scp /usr/bin/kubectl root@192.168.242.54:/usr/bin scp -r ~/.kube root@192.168.242.54:~
9.1.5 删除证书(Master2)
删除kubelet和kubeconfig文件
rm -f /opt/kubernetes/cfg/kubelet.kubeconfig rm -f /opt/kubernetes/ssl/kubelet*
说明:
这几个文件是证书申请审批后自动生成的,每个Node不同,必须删除。
9.1.6 修改配置文件和主机名(Master2)
修改apiserver、kubelet和kube-proxy配置文件为本地IP,主机名:
vi /opt/kubernetes/cfg/kube-apiserver.conf ... --bind-address=192.168.242.54 \ --advertise-address=192.168.242.54 \ ... vi /opt/kubernetes/cfg/kube-controller-manager.kubeconfig server: https://192.168.242.54:6443 vi /opt/kubernetes/cfg/kube-scheduler.kubeconfig server: https://192.168.242.54:6443 vi /opt/kubernetes/cfg/kubelet.conf --hostname-override=k8s-master2 vi /opt/kubernetes/cfg/kube-proxy-config.yml hostnameOverride: k8s-master2 vi ~/.kube/config ... server: https://192.168.242.54:6443
9.1.7 启动并设置开机自启(Master2)
systemctl daemon-reload systemctl start kube-apiserver kube-controller-manager kube-scheduler kubelet kube-proxy systemctl enable kube-apiserver kube-controller-manager kube-scheduler kubelet kube-proxy
9.1.8查看集群状态(Master2)
kubectl get cs NAME STATUS MESSAGE ERROR scheduler Healthy ok controller-manager Healthy ok etcd-1 Healthy {"health":"true"} etcd-2 Healthy {"health":"true"} etcd-0 Healthy {"health":"true"}
9.1.9审批kubelet证书申请
此部署master2也作为node节点部署kubelet,所以也要批准证书
# 查看证书请求 [root@k8s-master1 ~]# kubectl get csr NAME AGE SIGNERNAME REQUESTOR CONDITION node-csr-EQoVFfTbo6DcvcWfaRzBbMst4BXmdyds99DEYk2oDDE 33m kubernetes.io/kube-apiserver-client-kubelet kubelet-bootstrap Pending # 同意请求指令 kubectl certificate approve node-csr-EQoVFfTbo6DcvcWfaRzBbMst4BXmdyds99DEYk2oDDE
#代表批准成功
certificatesigningrequest.certificates.k8s.io/node-csr-EQoVFfTbo6DcvcWfaRzBbMst4BXmdyds99DEYk2oDDE approved
# 查看Node [root@k8s-master1 ~]# kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-master1 Ready <none> 6d23h v1.20.10 k8s-master2 Ready <none> 9m11s v1.20.10 k8s-node1 Ready <none> 5d v1.20.10 k8s-node2 Ready <none> 5d v1.20.10
至此一个双Master节点k8s集群已经部署完毕
9.2 部署Nginx+Keepalived高可用负载均衡器
- Nginx是一个主流Web服务和反向代理服务器,这里用四层实现对apiserver实现负载均衡。
- Keepalived是一个主流高可用软件,基于VIP绑定实现服务器双机热备,在上述拓扑中,Keepalived主要根据Nginx运行状态判断是否需要故障转移(漂移VIP),例如当Nginx主节点挂掉,VIP会自动绑定在Nginx备节点,从而保证VIP一直可用,实现Nginx高可用。
- 如果你是在公有云上,一般都不支持keepalived,那么你可以直接用它们的负载均衡器产品,直接负载均衡多台Master kube-apiserver,架构与上面一样。
- 此部署配置为非抢占模式,主备切换后,主的恢复后,不要主动切回 VIP。
9.2.1 安装软件包(Master1/Master2)
yum install epel-release -y yum install nginx keepalived -y
yum install psmisc -y #需要用到killall指令做健康检查
9.2.2 Nginx配置文件(主备相同)
cat > /etc/nginx/nginx.conf << "EOF" user nginx; worker_processes auto; error_log /var/log/nginx/error.log; pid /run/nginx.pid; include /usr/share/nginx/modules/*.conf; events { worker_connections 1024; } # 四层负载均衡,为两台Master apiserver组件提供负载均衡 stream { log_format main '$remote_addr $upstream_addr - [$time_local] $status $upstream_bytes_sent'; access_log /var/log/nginx/k8s-access.log main; upstream k8s-apiserver { server 192.168.242.51:6443; # Master1 APISERVER IP:PORT server 192.168.242.54:6443; # Master2 APISERVER IP:PORT } server { listen 16443; # 由于nginx与master节点复用,这个监听端口不能是6443,否则会冲突 proxy_pass k8s-apiserver; } } http { log_format main '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log /var/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; server { listen 80 default_server; server_name _; location / { } } } EOF
9.2.3 keepalived配置文件
master1配置
cat > /etc/keepalived/keepalived.conf << EOF ! Configuration File for keepalived global_defs { vrrp_skip_check_adv_addr } vrrp_script check_nginx { script "killall -0 nginx" #mysqld为system服务名 interval 2 # 检测间隔时间,即两秒检测一次 fall 2 # 检测失败的最大次数,超过两次认为节点资源发生故障 rise 2 # 请求两次成功认为节点恢复正常 weight -50 #一个正整数或负整数。权重值,关系到整个集群角色选举 } vrrp_instance VI_1 { state BACKUP #非抢占模式都为BACKUP,抢占模式主节点配置MASTER interface ens33 #网卡 virtual_router_id 66 #取值在0-255之间,keepalived集群同一id nopreempt #非抢占模式参数,只在主节点配置 priority 100 #主备优先级不一致 advert_int 1 authentication { auth_type PASS auth_pass Aa123456 } virtual_ipaddress { 192.168.242.55/24 #vip,注意填写真实网段 } track_script { check_nginx #对应上方vrrp_script } } EOF
master2配置
cat > /etc/keepalived/keepalived.conf << EOF ! Configuration File for keepalived global_defs { vrrp_skip_check_adv_addr } vrrp_script check_nginx { script "killall -0 nginx" #mysqld为system服务名 interval 2 # 检测间隔时间,即两秒检测一次 fall 2 # 检测失败的最大次数,超过两次认为节点资源发生故障 rise 2 # 请求两次成功认为节点恢复正常 weight -50 #一个正整数或负整数。权重值,关系到整个集群角色选举 } vrrp_instance VI_1 { state BACKUP #非抢占模式都为BACKUP,抢占模式主节点配置MASTER interface ens33 #网卡 virtual_router_id 66 #取值在0-255之间,keepalived集群同一id priority 90 #主备优先级不一致 advert_int 1 authentication { auth_type PASS auth_pass Aa123456 } virtual_ipaddress { 192.168.242.55/24 #vip,注意填写真实网段 } track_script { check_nginx #对应上方vrrp_script } } EOF
9.2.5 Nginx增加Steam模块
9.2.5.1 查看Nginx版本模块
如果已经安装 --with-stream模块,后面的步骤可以跳过
[root@k8s-master2 nginx-1.20.1]# nginx -V nginx version: nginx/1.20.1 built by gcc 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) configure arguments: --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --with-stream
9.2.5.2 下载同一个版本的nginx,备份原nginx文件
下载地址 : http://nginx.org/download/
mv /usr/sbin/nginx /usr/sbin/nginx.bak
cp -r /etc/nginx{,.bak}
9.2.5.3 重新编译Nginx
##检查模块是否支持,比如这次添加 limit 限流模块 和 stream 模块: ./configure –help | grep limit ##ps:-without-http_limit_conn_module disable 表示已有该模块,编译时,不需要添加 ./configure –help | grep stream ##ps:–with-stream enable 表示不支持,编译时要自己添加该模块 ##根据第9.2.5.1步查到已有的模块,加上本次需新增的模块: --with-stream
编译环境准备
yum -y install libxml2 libxml2-dev libxslt-devel yum -y install gd-devel yum -y install perl-devel perl-ExtUtils-Embed yum -y install GeoIP GeoIP-devel GeoIP-data yum -y install pcre-devel yum -y install openssl openssl-devel yum -y install gcc make
编译
tar -xf nginx-1.20.1.tar.gz cd nginx-1.20.1/ ./configure --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --with-stream make
说明:
make完成后不要继续输入“make install”,以免现在的nginx出现问题
以上完成后,会在objs目录下生成一个nginx文件,先验证:
[root@k8s-master2 nginx-1.20.1]# ./objs/nginx -t nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
9.2.5.4 替换nginx到Master1/Master2
cp ./objs/nginx /usr/sbin/ scp objs/nginx root@192.168.242.51:/usr/sbin/
9.2.5.5 修改nginx服务文件
vim /usr/lib/systemd/system/nginx.service [Unit] Description=The nginx HTTP and reverse proxy server After=network.target remote-fs.target nss-lookup.target [Service] Type=forking PIDFile=/run/nginx.pid ExecStartPre=/usr/bin/rm -rf /run/nginx.pid ExecStartPre=/usr/sbin/nginx -t ExecStart=/usr/sbin/nginx ExecStop=/usr/sbin/nginx -s stop ExecReload=/usr/sbin/nginx -s reload PrivateTmp=true [Install] WantedBy=multi-user.target
9.2.6 启动并设置开机自启(master1/master2)
systemctl daemon-reload systemctl enable nginx keepalived --now systemctl status nginx keepalived
9.2.7 查看keepalived工作状态
[root@k8s-master1 ~]# ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000 link/ether 00:0c:29:40:1a:d8 brd ff:ff:ff:ff:ff:ff inet 192.168.242.51/24 brd 192.168.242.255 scope global noprefixroute ens33 valid_lft forever preferred_lft forever inet 192.168.242.55/24 scope global secondary ens33 valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:fe40:1ad8/64 scope link valid_lft forever preferred_lft forever 3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default link/ether 02:42:f3:e1:d2:e6 brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 valid_lft forever preferred_lft forever 4: tunl0@NONE: <NOARP,UP,LOWER_UP> mtu 1440 qdisc noqueue state UNKNOWN group default qlen 1000 link/ipip 0.0.0.0 brd 0.0.0.0 inet 10.244.159.128/32 brd 10.244.159.128 scope global tunl0 valid_lft forever preferred_lft forever 5: calia231fca418b@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1440 qdisc noqueue state UP group default link/ether ee:ee:ee:ee:ee:ee brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet6 fe80::ecee:eeff:feee:eeee/64 scope lin
可以看到,在ens33网卡绑定了192.168.242.55 虚拟IP,说明工作正常。
9.2.8 Nginx+keepalived高可用测试
#关闭主节点Nginx,测试VIP是否漂移到备节点服务器。
在Nginx Master停止nginx: systemctl stop nginx
在Nginx Backup,ip addr命令查看已成功绑定VIP.
注:此时backup节点nginx再停止后,vip不会重回master节点,需要手动重启backup的keepalived才可以
9.2.9 访问负载均衡器测试
找K8s集群中任意一个节点,使用curl查看K8s版本测试,使用VIP访问:
[root@k8s-master1 ~]# curl -k https://192.168.242.55:16443/version { "major": "1", "minor": "20", "gitVersion": "v1.20.10", "gitCommit": "8152330a2b6ca3621196e62966ef761b8f5a61bb", "gitTreeState": "clean", "buildDate": "2021-08-11T18:00:37Z", "goVersion": "go1.15.15", "compiler": "gc", "platform": "linux/amd64" }[root@k8s-master1 ~]# curl -k https://192.168.242.55:16443/version ^[[A{ "major": "1", "minor": "20", "gitVersion": "v1.20.10", "gitCommit": "8152330a2b6ca3621196e62966ef761b8f5a61bb", "gitTreeState": "clean", "buildDate": "2021-08-11T18:00:37Z", "goVersion": "go1.15.15", "compiler": "gc", "platform": "linux/amd64" }[root@k8s-master1 ~]# curl -k https://192.168.242.55:16443/version { "major": "1", "minor": "20", "gitVersion": "v1.20.10", "gitCommit": "8152330a2b6ca3621196e62966ef761b8f5a61bb", "gitTreeState": "clean", "buildDate": "2021-08-11T18:00:37Z", "goVersion": "go1.15.15", "compiler": "gc", "platform": "linux/amd64" }[root@k8s-master1 ~]# curl -k https://192.168.242.55:16443/version { "major": "1", "minor": "20", "gitVersion": "v1.20.10", "gitCommit": "8152330a2b6ca3621196e62966ef761b8f5a61bb", "gitTreeState": "clean", "buildDate": "2021-08-11T18:00:37Z", "goVersion": "go1.15.15", "compiler": "gc", "platform": "linux/amd64"
可以正确获取到K8s版本信息,说明负载均衡器搭建正常。该请求数据流程:curl -> vip(nginx) -> apiserver
通过查看Nginx日志也可以看到转发apiserver IP:
[root@k8s-master1 ~]# tailf /var/log/nginx/k8s-access.log 192.168.242.51 192.168.242.51:6443 - [14/Sep/2021:23:53:07 +0800] 200 424 192.168.242.51 192.168.242.54:6443 - [14/Sep/2021:23:53:09 +0800] 200 424 192.168.242.51 192.168.242.51:6443 - [14/Sep/2021:23:53:10 +0800] 200 424 192.168.242.51 192.168.242.54:6443 - [14/Sep/2021:23:53:11 +0800] 200 424
9.3 修改所有的Work Node连接LB VIP
因此接下来就是要改所有Worker Node(kubectl get node命令查看到的节点)组件配置文件,由原来192.168.242.51修改为192.168.242.55(VIP)。
在所有Worker Node执行:
sed -i 's#192.168.242.51:6443#192.168.242.55:16443#' /opt/kubernetes/cfg/* systemctl restart kubelet kube-proxy
检查节点状态
[root@k8s-master1 ~]# kubectl get nodes NAME STATUS ROLES AGE VERSION k8s-master1 Ready <none> 7d v1.20.10 k8s-master2 Ready <none> 90m v1.20.10 k8s-node1 Ready <none> 5d1h v1.20.10 k8s-node2 Ready <none> 5d1h v1.20.10
至此,一套高可用的k8s二进制可用集群就部署完成了~
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!