kubeadm 安装高可用的 k8s 集群

本贴最后更新于 187 天前,其中的信息可能已经东海扬尘

实验环境规划:

操作系统:centos7.6

配置: 4Gib 内存/6vCPU/100G 硬盘

网络:桥接

开启虚拟机的虚拟化:

image

如果启动虚拟机出现如下报错:

image

就把第二项勾选去掉

image

k8s 集群机器规划

k8s 集群角色 IP 主机名 安装组件
控制节点(master) 192.168.101.41 zzjk8s1 apiserver、controller、manager、scheduler、kubelet、etcd、docker、kube-proxy、keepalived、nginx、calico
控制节点(master) 192.168.101.42 zzjk8s2 apiserver、controller、manager、scheduler、kubelet、etcd、docker、kube-proxy、keepalived、nginx、calico
工作节点(node) 192.168.101.43 zzjk8s3 kubelet、kube-proxy、docker、calico、coredns
VIP 192.168.101.45 zzjk8s4

kubeadm

kubeadm 是官方提供的开源工具,是一个开源项目,用于快速搭建 kubernetes 集群,目前是比较 方便和推荐使用的。kubeadm init 以及 kubeadm join 这两个命令可以快速创建 kubernetes 集群。 Kubeadm 初始化 k8s,所有的组件都是以 pod 形式运行的,具备故障自恢复能力。

kubeadm 是工具,可以快速搭建集群,也就是相当于用程序脚本帮我们装好了集群,属于自动部 署,简化部署操作,自动部署屏蔽了很多细节,使得对各个模块感知很少,如果对 k8s 架构组件理解不 深的话,遇到问题比较难排查。

kubeadm 适合需要经常部署 k8s,或者对自动化要求比较高的场景下使用。

初始化安装 k8s 集群的实验环境

修改机器 IP,变成静态 IP

注意三台机器的 IP 都需要修改,VIP 节点机器暂时不用

vi /etc/sysconfig/network-scripts/ifcfg-ens33
# 修改
BOOTPROTO="static"
ONBOOT="yes"
# 新增
IPADDR="192.168.101.41"
GATEWAY="192.168.101.1"
NETMASK="255.255.255.0"
DNS1="8.8.8.8"
DNS2="114.114.114.114"
ZONE=public

因为我们的虚拟机是克隆出来的需要,克隆出来的虚拟机 MAC 和网络配置文件中的 UUID 会相同,我们需要修改

修改 MAC 地址:

image

生成 UUID

uuidgen ens33

修改 UUID

UUID="657e2c99-ce20-4c7a-b6b2-5cc40261b2f0"

重启网络

systemctl restart network

注:/etc/sysconfig/network-scripts/ifcfg-ens33 文件里的配置说明:

NAME=ens33 #网卡名字,跟 DEVICE 名字保持一致即可

DEVICE=ens33 #网卡设备名,大家 ip addr 可看到自己的这个网卡设备名,每个人的机器可能这个名 字不一样,需要写自己的

BOOTPROTO=static #static 表示静态 ip 地址

ONBOOT=yes #开机自启动网络,必须是 yes

IPADDR=192.168.101.41 #ip 地址,需要跟自己电脑所在网段一致

NETMASK=255.255.255.0 #子网掩码,需要跟自己电脑所在网段一致

GATEWAY=192.168.40.2 #网关,在自己电脑打开 cmd,输入 ipconfig /all 可看到

DNS1=192.168.40.2 #DNS,在自己电脑打开 cmd,输入 ipconfig /all 可看到

配置机器主机名

hostnamectl set-hostname zzjk8s1 && bash # 192.168.101.41 机器上执行
hostnamectl set-hostname zzjk8s2 && bash # 192.168.101.42 机器上执行
hostnamectl set-hostname zzjk8s3 && bash # 192.168.101.43 机器上执行

配置主机 hosts 文件,相互之间通过主机名互相访问

修改每台机器的/etc/hosts 文件,增加如下三行:

vi /etc/hosts
192.168.101.41 zzjk8s1
192.168.101.42 zzjk8s2
192.168.101.43 zzjk8s3

配置完成之后,就可以使用主机名进行通信

ping zzjk8s2

配置主机之间无密码登录

下面这段配置需要分分别在 zzjk8s1、zzjk8s2、zzjk8s3 上执行

ssh-keygen # 一路回车,不输入密码

把本地生成的密钥文件和私钥文件拷贝到远程主机

ssh-copy-id zzjk8s1
ssh-copy-id zzjk8s2
ssh-copy-id zzjk8s3

image

关闭交换分区 swap,提升性能

下面这段配置需要分分别在 zzjk8s1、zzjk8s2、zzjk8s3 上执行

临时关闭

swapoff -a

永久关闭:注释 swap 挂载,给 swap 这行开头加一下注释

vim /etc/fstab
#/dev/mapper/centos-swap swap swap defaults 0 0

如果是克隆的虚拟机,需要删除 UUID

image

问题 1:为什么要关闭 swap 交换分区?

Swap 是交换分区,如果机器内存不够,会使用 swap 分区,但是 swap 分区的性能较低,k8s 设计的 时候为了能提升性能,默认是不允许使用交换分区的。Kubeadm 初始化的时候会检测 swap 是否关 闭,如果没关闭,那就初始化失败。如果不想要关闭交换分区,安装 k8s 的时候可以指定--ignorepreflight-errors=Swap 来解决。

修改机器内核参数

下面这段配置需要分别在 zzjk8s1、zzjk8s2、zzjk8s3 上执行

modprobe br_netfilter
echo "modprobe br_netfilter" >> /etc/profile
cat > /etc/sysctl.d/k8s.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
sysctl -p /etc/sysctl.d/k8s.conf

问题 1:sysctl 是做什么的?

在运行时配置内核参数 -p 从指定的文件加载系统参数,如不指定即从/etc/sysctl.conf 中加载

问题 2:为什么要执行 modprobe br_netfilter?

修改/etc/sysctl.d/k8s.conf 文件,增加如下三行参数:

net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1

问题 3:为什么开启 net.bridge.bridge-nf-call-iptables 内核参数?

在 centos 下安装 docker,执行 docker info 出现如下警告:

WARNING: bridge-nf-call-iptables is disabled

WARNING: bridge-nf-call-ip6tables is disabled

解决办法:

vim /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1

问题 4:为什么要开启 net.ipv4.ip_forward = 1 参数?

kubeadm 初始化 k8s 如果报错:

image

就表示没有开启 ip_forward,需要开启。

net.ipv4.ip_forward 是数据包转发:

出于安全考虑,Linux 系统默认是禁止数据包转发的。所谓转发即当主机拥有多于一块的网卡时, 其中一块收到数据包,根据数据包的目的 ip 地址将数据包发往本机另一块网卡,该网卡根据路由表继 续发送数据包。这通常是路由器所要实现的功能。

要让 Linux 系统具有路由转发功能,需要配置一个 Linux 的内核参数 net.ipv4.ip_forward。这个 参数指定了 Linux 系统当前对路由转发功能的支持情况;其值为 0 时表示禁止进行 IP 转发;如果是 1, 则说明 IP 转发功能已经打开。

关闭 firewalld 防火墙

下面这段配置需要分分别在 zzjk8s1、zzjk8s2、zzjk8s3 上执行

systemctl stop firewalld && systemctl disable firewalld

关闭 selinux

下面这段配置需要分分别在 zzjk8s1、zzjk8s2、zzjk8s3 上执行

sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config 

修改 selinux 配置文件之后,重启机器,selinux 配置才能永久生效

验证是否生效

getenforce

配置阿里云的 repo 源

下面这段配置需要分分别在 zzjk8s1、zzjk8s2、zzjk8s3 上执行

安装 rzsz 命令

yum install lrzsz -y #上传下载命令

安装 scp:

yum install openssh-clients -y

备份基础 repo 源

mkdir /root/repo.bak
cd /etc/yum.repos.d/
mv * /root/repo.bak/

下载阿里云的 repo 源

https://mirrors.aliyun.com/repo

把 下载的 repo 文件上传到主机的/etc/yum.repos.d/目录下

cd /etc/yum.repos.d/

或者

wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
yum makecache

配置国内阿里云 docker 的 repo 源

安装 docker 需要的软件基础包

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

配置安装 k8s 组件需要的阿里云的 repo 源

下面这段配置需要分分别在 zzjk8s1、zzjk8s2、zzjk8s3 上执行

vim /etc/yum.repos.d/kubernetes.repo

内容如下:

[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64/
enabled=1
gpgcheck=0

将 zzjk8s1 上 Kubernetes 的 repo 源复制给 zzjk8s2 和 zzjk8s3

scp /etc/yum.repos.d/kubernetes.repo zzjk8s2:/etc/yum.repos.d/
scp /etc/yum.repos.d/kubernetes.repo zzjk8s3:/etc/yum.repos.d/

配置时间同步

下面这段配置需要分分别在 zzjk8s1、zzjk8s2、zzjk8s3 上执行

安装 ntpdate 命令

yum install ntpdate -y

跟网络时间做同步

ntpdate cn.pool.ntp.org

把时间同步做成计划任务

crontab -e

内容如下

* */1 * * * /usr/sbin/ntpdate cn.pool.ntp.org

重启 crond 服务

systemctl restart crond

开启 ipvs

下面这段配置需要分分别在 zzjk8s1、zzjk8s2、zzjk8s3 上执行

把 ipvs.modules 上传到 zzjk8s1 机器的/etc/sysconfig/modules/目录下

ipvs.modules

拷贝到另外两台机器

scp /etc/sysconfig/modules/ipvs.modules zzjk8s2:/etc/sysconfig/modules/
scp /etc/sysconfig/modules/ipvs.modules zzjk8s3:/etc/sysconfig/modules/
chmod 755 /etc/sysconfig/modules/ipvs.modules && bash
/etc/sysconfig/modules/ipvs.modules && lsmod | grep ip_vs

问题 1:ipvs 是什么?

ipvs (IP Virtual Server) 实现了传输层负载均衡,也就是我们常说的 4 层 LAN 交换,作为 Linux 内核的一部分。ipvs 运行在主机上,在真实服务器集群前充当负载均衡器。ipvs 可以将基于 TCP 和 UDP 的服务请求转发到真实服务器上,并使真实服务器的服务在单个 IP 地址上显示为虚拟服务。

问题 2:ipvs 和 iptable 对比分析

kube-proxy 支持 iptables 和 ipvs 两种模式, 在 kubernetes v1.8 中引入了 ipvs 模式,在 v1.9 中处于 beta 阶段,在 v1.11 中已经正式可用了。iptables 模式在 v1.1 中就添加支持了,从 v1.2 版本开始 iptables 就是 kube-proxy 默认的操作模式,ipvs 和 iptables 都是基于 netfilter 的,但是 ipvs 采用的是 hash 表,因此当 service 数量达到一定规模时,hash 查表的速度优势就会显现 出来,从而提高 service 的服务性能。那么 ipvs 模式和 iptables 模式之间有哪些差异呢?

1、ipvs 为大型集群提供了更好的可扩展性和性能

2、ipvs 支持比 iptables 更复杂的复制均衡算法(最小负载、最少连接、加权等等)

3、ipvs 支持服务器健康检查和连接重试等功能

安装基础软件包

下面这段配置需要分分别在 zzjk8s1、zzjk8s2、zzjk8s3 上执行

yum install -y yum-utils device-mapper-persistent-data lvm2 wget net-tools nfs-utils lrzsz gcc gcc-c++ make cmake libxml2-devel openssl-devel curl curl-devel unzip sudo ntp libaio-devel wget vim ncurses-devel autoconf automake zlibdevel python-devel epel-release openssh-server socat ipvsadm conntrack ntpdate telnet ipvsadm

安装 iptables

如果用 firewalld 不习惯,可以安装 iptables ,在 zzjk8s1、zzjk8s2、 zzjk8s3 上操作:

安装 iptables

yum install iptables-services -y

禁用 iptables

service iptables stop && systemctl disable iptables

清空防火墙规则

iptables -F

内核升级

在 zzjk8s1、zzjk8s2、 zzjk8s3 上操作:

https://elrepo.org/linux/kernel/el7/x86_64/RPMS/ 内核版本地址

# 下载内核包
wget https://elrepo.org/linux/kernel/el7/x86_64/RPMS/kernel-ml-6.9.4-1.el7.elrepo.x86_64.rpm
# npm 安装该包
rpm -ivh kernel-ml-6.9.4-1.el7.elrepo.x86_64.rpm
# 编辑grub文件,把GRUB_DEFAULT=saved改成GRUB_DEFAULT=0
vim /etc/default/grub
# 根据/etc/default/grub自动生成开机配置文件
grub2-mkconfig -o /boot/grub2/grub.cfg
# 重启机器生效
reboot
# 查看内核版本
uname -r

安装 docker 服务

安装 docker-ce

下面这段配置需要分分别在 zzjk8s1、zzjk8s2、zzjk8s3 上执行

yum install docker-ce containerd.io -y
systemctl start docker && systemctl enable docker && systemctl status docker

如果安装 docker 出现如下问题,更新 yum

image

查看 docker-ce.repo 是否为空,如果为空则重新添加

https://developer.aliyun.com/mirror/docker-ce?spm=a2c6h.13651102.0.0.57e31b11a0OGp1

配置 docker 镜像加速器和驱动

下面这段配置需要分分别在 zzjk8s1、zzjk8s2、zzjk8s3 上执行

sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["https://dqk40brb.mirror.aliyuncs.com","https://registry.dockercn.com","https://docker.mirrors.ustc.edu.cn","https://dockerhub.azk8s.cn","http://hubmirror.c.163.com","http://qtid6917.mirror.aliyuncs.com", "https://rncxm540.mirror.aliyuncs.com"],
  "exec-opts": ["native.cgroupdriver=systemd"]
}
EOF
systemctl daemon-reload && systemctl restart docker

修改 docker 文件驱动为 systemd("exec-opts": ["native.cgroupdriver=systemd"]),默认为 cgroupfs,kubelet 默认使用 systemd,两者必须一致才可 以。

安装初始化 k8s 需要的软件包

下面这段配置需要分分别在 zzjk8s1、zzjk8s2、zzjk8s3 上执行

yum install -y kubelet-1.20.6 kubeadm-1.20.6 kubectl-1.20.6
systemctl enable kubelet && systemctl start kubelet
systemctl status kubelet

image

上面可以看到 kubelet 状态不是 running 状态,这个是正常的,不用管,等 k8s 组件起来这个 kubelet 就正常了。

每个软件包的作用

Kubeadm: kubeadm 是一个工具,用来初始化 k8s 集群的

kubelet: 安装在集群所有节点上,用于启动 Pod 的 kubectl: 通过

kubectl 可以部署和管理应用,查看各种资源,创建、删除和更新各种组件

通过 keepalive+nginx 实现 k8s apiserver 节点高可用

配置 epel 源

把 epel.repo 上传到 zzjk8s1 的/etc/yum.repos.d 目录下,这样才能安装 keepalived 和 nginx

把 epel.repo 拷贝到远程主机 zzjk8s2 和 zzjk8s3 上

scp /etc/yum.repos.d/epel.repo zzjk8s2:/etc/yum.repos.d/
scp /etc/yum.repos.d/epel.repo zzjk8s3:/etc/yum.repos.d/

安装 nginx 主备

在 zzjk8s1 和 zzjk8s2 上做 nginx 主备安装

yum install nginx keepalived nginx-mod-stream -y # 在zzjk8s1 和 zzjk8s2 上执行

修改 nginx 配置文件。主备一样

cp /etc/nginx/nginx.conf /root/nginx.conf.back # 备份nginx配置文件
vim /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
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.101.41:6443;
	  server 192.168.101.42:6443;
    }

	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 4096;

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    server {
        listen       80 default_server;
        server_name  _;
        location / {
        }
    }
}

访问 16443 端口就会代理到 k8s-apiserver;

keepalive 配置

主 keepalived 是 zzjk8s1

cp /etc/keepalived/keepalived.conf /root/keepalived.conf.back # 备份keepalived配置文件
vim /etc/keepalived/keepalived.conf
global_defs {
   notification_email {
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id NGINX_MASTER
}

vrrp_script check_nginx {
   script "/etc/keepalived/check_nginx.sh"
}

vrrp_instance VI_1 {
    state MASTER
    interface ens33 # 修改为实际网卡名
    virtual_router_id 51 # VRRP 路由 ID 实例,每个实例是唯一的
    priority 100 # 优先级,备服务器设置 90
    advert_int 1 # 指定 VRRP 心跳包通告间隔时间,默认 1 秒
    authentication {
        auth_type PASS
        auth_pass 1111
    }
	# 虚拟 IP
    virtual_ipaddress {
        192.168.101.45/24
    }

	track_script {
 		check_nginx
 	}
}

vrrp_script:指定检查 nginx 工作状态脚本(根据 nginx 状态判断是否故障转移)

virtual_ipaddress:虚拟 IP(VIP)

vim /etc/keepalived/check_nginx.sh
#!/bin/bash
count=$(ps -ef |grep nginx | grep sbin | egrep -cv "grep|$$")
if [ "$count" -eq 0 ];then
 systemctl stop keepalived
fi 
chmod +x /etc/keepalived/check_nginx.sh

备 keepalived 是 zzjk8s2

cp /etc/keepalived/keepalived.conf /root/keepalived.conf.back # 备份keepalived配置文件
vim /etc/keepalived/keepalived.conf
global_defs {
   notification_email {
     acassen@firewall.loc
     failover@firewall.loc
     sysadmin@firewall.loc
   }
   notification_email_from Alexandre.Cassen@firewall.loc
   smtp_server 127.0.0.1
   smtp_connect_timeout 30
   router_id NGINX_BACKUP
}

vrrp_script check_nginx {
   script "/etc/keepalived/check_nginx.sh"
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens33 # 修改为实际网卡名
    virtual_router_id 51 # VRRP 路由 ID 实例,每个实例是唯一的
    priority 90  # 优先级,备服务器设置 90
    advert_int 1 # 指定 VRRP 心跳包通告间隔时间,默认 1 秒
    authentication {
        auth_type PASS
        auth_pass 1111
    }
	# 虚拟 IP
    virtual_ipaddress {
        192.168.101.45/24
    }

	track_script {
 		check_nginx
 	}
}
vim /etc/keepalived/check_nginx.sh
#!/bin/bash
count=$(ps -ef |grep nginx | grep sbin | egrep -cv "grep|$$")
if [ "$count" -eq 0 ];then
 systemctl stop keepalived
fi
chmod +x /etc/keepalived/check_nginx.sh 

注:keepalived 根据脚本返回状态码(0 为工作正常,非 0 不正常)判断是否故障转移。

启动服务

在 zzjk8s1 和 zzjk8s2 上执行

systemctl daemon-reload
systemctl start nginx
systemctl start keepalived
systemctl enable nginx keepalived
systemctl status keepalived

测试 vip 是否绑定成功

在 zzjk8s1 上查看 VIP 是否绑定成功

image

测试 keepalived

停掉 zzjk8s1 上的 nginx。Vip 会转移到 zzjk8s2

systemctl stop nginx

在 zzjk8s2 主机上查看网络

ip addr

image

启动 zzjk8s1 上的 nginx 和 keepalived,vip 又会转移回来

systemctl daemon-reload
systemctl start nginx
systemctl start keepalived
ip addr

image

kubeadm 初始化 k8s 集群

在 zzjk8s1 上创建 kubeadm-config.yaml 文件:

cd /root/
vim kubeadm-config.yaml

内容如下:

apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: v1.20.6
controlPlaneEndpoint: 192.168.101.45:16443 # 控制节点IP
imageRepository: registry.aliyuncs.com/google_containers # 镜像地址
apiServer:
 certSANs:
 - 192.168.101.41
 - 192.168.101.42
 - 192.168.101.43
 - 192.168.101.45
networking:
  podSubnet: 10.244.0.0/16
  serviceSubnet: 10.10.0.0/16
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs

使用 kubeadm 初始化 k8s 集群

把初始化 k8s 集群需要的离线镜像包上传到 zzjk8s1、zzjk8s2、zzjk8s3 机器上,手动解压:

k8simage-1-20-6.tar.gz

scp k8simage-1-20-6.tar.gz zzjk8s2:/root
scp k8simage-1-20-6.tar.gz zzjk8s3:/root
docker load -i k8simage-1-20-6.tar.gz

在 zzjk8s1 上执行初始化 k8s

kubeadm init --config kubeadm-config.yaml --ignore-preflight-errors=SystemVerification

注:--image-repository registry.aliyuncs.com/google_containers:手动指定仓库地址为 registry.aliyuncs.com/google_containers。kubeadm 默认从 k8s.grc.io 拉取镜像,但是 k8s.gcr.io 访问不到,所以需要指定从 registry.aliyuncs.com/google_containers 仓库拉取镜像。

如果初始化出现如下问题:

image

可以使用 --ignore-preflight-errors=SystemVerification 忽略该错误,也可以选择升级内核

uname -r # 查看内核版本

显示如下,说明安装完成:

image

kubeadm join 192.168.101.45:16443 --token v24mt5.ls9gprj1bol7hyer \
    --discovery-token-ca-cert-hash sha256:c8390b3f8da6cf15aa7265d0b4bbe0c57f3d9e9fdff8ea0ece38c4758c1b5e77 \
    --control-plane

上面命令是把 master 节点加入集群,需要保存下来,每个人的都不一样

kubeadm join 192.168.101.45:16443 --token v24mt5.ls9gprj1bol7hyer \
    --discovery-token-ca-cert-hash sha256:c8390b3f8da6cf15aa7265d0b4bbe0c57f3d9e9fdff8ea0ece38c4758c1b5e77

上面命令是把 node 节点加入集群,需要保存下来,每个人的都不一样

配置 kubectl 的配置文件 config,相当于对 kubectl 进行授权,这样 kubectl 命令可以使用这个证 书对 k8s 集群进行管理

mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
kubectl get nodes

image

此时集群状态还是 NotReady 状态,因为没有安装网络插件。

扩容 k8s 集群-添加 master 节点

把 zzjk8s1 节点的证书拷贝到 zzjk8s2 上

在 zzjk8s2 创建证书存放目录:

cd /root && mkdir -p /etc/kubernetes/pki/etcd && mkdir -p ~/.kube/

把 zzjk8s1 节点的证书拷贝到 zzjk8s2 上:

scp /etc/kubernetes/pki/ca.crt zzjk8s2:/etc/kubernetes/pki/ # zzjk8s1 上执行
scp /etc/kubernetes/pki/ca.key zzjk8s2:/etc/kubernetes/pki/ # zzjk8s1 上执行
scp /etc/kubernetes/pki/sa.key zzjk8s2:/etc/kubernetes/pki/ # zzjk8s1 上执行
scp /etc/kubernetes/pki/sa.pub zzjk8s2:/etc/kubernetes/pki/ # zzjk8s1 上执行
scp /etc/kubernetes/pki/front-proxy-ca.crt zzjk8s2:/etc/kubernetes/pki/ # zzjk8s1 上执行
scp /etc/kubernetes/pki/front-proxy-ca.key zzjk8s2:/etc/kubernetes/pki/ # zzjk8s1 上执行
scp /etc/kubernetes/pki/etcd/ca.crt zzjk8s2:/etc/kubernetes/pki/etcd/ # zzjk8s1 上执行
scp /etc/kubernetes/pki/etcd/ca.key zzjk8s2:/etc/kubernetes/pki/etcd/ # zzjk8s1 上执行

证书拷贝之后在 zzjk8s2 上执行如下命令,大家复制自己的,这样就可以把 zzjk8s2 和加入到集群,成为控制节点:

kubeadm token create --print-join-command

image

上面命令就是查看把节点加入集群的命令,他会生成一个 token 这个 token24 小时有效期:


kubeadm join 192.168.101.45:16443 --token 87aw0w.5x4p8m88lit8rc8g --discovery-token-ca-cert-hash sha256:c8390b3f8da6cf15aa7265d0b4bbe0c57f3d9e9fdff8ea0ece38c4758c1b5e77 --control-plane --ignore-preflight-errors=SystemVerification 

image

看到上面说明 zzjk8s2 节点已经加入到集群了

我们在 zzjk8s2 上执行 kubectl 命令会出现如下问题:

image

我们就需要执行下面三条命令才能在 zzjk8s2 上执行 kubectl 命令

mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
kubectl get nodes

在 zzjk8s1 上查看集群状况:

kubectl get nodes

image

上面可以看到 zzjk8s2 已经加入到集群了

扩容 k8s 集群-添加 node 节点

在 zzjk8s1 上查看加入节点的命令:

kubeadm token create --print-join-command

显示如下:

image

把 zzjk8s3 加入 k8s 集群:

kubeadm join 192.168.101.45:16443 --token 3acxem.tjkpd7x5m5j958d1 --discovery-token-ca-cert-hash sha256:c8390b3f8da6cf15aa7265d0b4bbe0c57f3d9e9fdff8ea0ece38c4758c1b5e77 --ignore-preflight-errors=SystemVerification 

image

看到上面说明 zzjk8s3 节点已经加入到集群了,充当工作节点

在 zzjk8s1 上查看集群节点状况:

kubectl get nodes

image

可以看到 zzjk8s3 的 ROLES 角色为空,就表示这个节点是工作节点。

可以把 zzjk8s3 的 ROLES 变成 work,按照如下方法:

kubectl label node zzjk8s3 node-role.kubernetes.io/worker=worker # zzjk8s1 上执行

image

注意:上面状态都是 NotReady 状态,说明没有安装网络插件

查看 pods,需要指定名称空间:

kubectl get pods -n kube-system -o wide # zzjk8s1 上执行

image

coredns-7f89b7bc75-tdw6q 是 pending 状态,这是因为还没有安装网络插件,等到下面安装好网络插件 之后这个 cordns 就会变成 running 了

安装 kubernetes 网络组件-Calico

上传 calico.yaml 到 zzjk8s1 上的 /home/k8s-yaml-install 目录,使用 yaml 文件安装 calico 网络插件 。

mkdir /home/k8s-yaml-install
cd /home/k8s-yaml-install

calico.yaml

kubectl apply -f calico.yaml

注:在线下载配置文件地址是: https://docs.projectcalico.org/manifests/calico.yaml

kubectl get pod -n kube-system

image

coredns-这个 pod 现在是 running 状态,运行正常

再次查看集群状态。

kubectl get nodes

image

STATUS 状态是 Ready,说明 k8s 集群正常运行了

测试在 k8s 创建 pod 是否可以正常访问网络

把 busybox-1-28.tar.gz 上传到 zzjk8s3 节点,手动解压

busybox-1-28.tar.gz

docker load -i busybox-1-28.tar.gz 

在 zzjk8s1 上运行这个镜像,在 zzjk8s1 会用到 zzjk8s3 上的镜像

kubectl run busybox --image busybox:1.28 --restart=Never --rm -it busybox -- sh

image

通过上面可以看到能访问网络,说明 calico 网络插件已经被正常安装了

测试 k8s 集群中部署 tomcat 服务

把 tomcat.tar.gz 上传到 zzjk8s3 ,手动解压

tomcat.tar.gz

docker load -i tomcat.tar.gz

上传 tomcat.yaml 文件到 zzjk8s1

tomcat.yaml

kubectl apply -f tomcat.yaml
kubectl get pods

image

上传 tomcat-service.yaml 文件到 zzjk8s1

tomcat-service.yaml

kubectl apply -f tomcat-service.yaml
kubectl get svc

image

在浏览器访问 zzjk8s3 节点的 ip:30080 即可请求到浏览器

image

测试 coredns 是否正常

在 zzjk8s1 上执行

kubectl run busybox --image busybox:1.28 --restart=Never --rm -it busybox -- sh

image

nslookup kubernetes.default.svc.cluster.local
nslookup tomcat.default.svc.cluster.local

10.10.209.178 就是我们 coreDNS 的 clusterIP,说明 coreDNS 配置好了。 解析内部 Service 的名称,是通过 coreDNS 去解析的。

10.10.0.10 是创建的 tomcat 的 service ip

注意: busybox 要用指定的 1.28 版本,不能用最新版本,最新版本,nslookup 会解析不到 dns 和 ip

  • Kubernetes

    Kubernetes 是 Google 开源的一个容器编排引擎,它支持自动化部署、大规模可伸缩、应用容器化管理。

    110 引用 • 54 回帖 • 5 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...