K8s架构与核心组件

K8S核心组件介绍

image-20231017210542411

master组件

  • API server
  • 集群对外的统一入口,以RESTful API方式做操作。

  • scheduler

  • 通过算法算出pod调度到哪个节点

  • controller manager

  • 管理一系列的controller(deployment、stateful set、namespace等)

  • etcd

  • 存储系统
  • Calico:网络插件(给pod提供IP、提供网络policy等)
  • kubeproxy

Worker Node组件

  • kubelet
  • kubeproxy
  • coredns
  • calico
  • runtime(docker/containerd)

制作k8s安装需要的离线yum源

要全内网环境安装docker、k8s和相关依赖,需要在内部提供安装k8s、docker需要的yum源。首先需要在联网机器上把镜像拉下来。

制作安装docker需要的离线yum源

1、添加docker在线源

yum-config-manager --add-repo https://download.docker.com/linux/centos/dockerce.repo

2、通过如下命令download远程yum源文件,建立本地docker repo库

yum install --downloadonly --downloaddir=/mnt/docker-ce docker-ce
createrepo -d /mnt/docker-ce

3、把/mnt/docker-c下自动下载的rpm打包,传到内网机器,用过如下方法安装:

rpm -Uvh *.rpm --nodeps --force #这是强制安装当前文件夹中所有的rpm包,忽略依赖去安装

制作安装k8s命令行工具需要的离线yum源

1、添加k8s在线源

cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg
https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

2、通过如下命令download远程yum源文件,建立本地k8s repo库

yum install --downloadonly --resolve kubeadm kubelet kubectl --destdir /mnt/k8s
createrepo -d /mnt/k8s

3、把/mnt/k8s下自动下载的rpm打包,传到内网机器,用过如下方法安装:

rpm -Uvh *.rpm --nodeps --force #这是强制安装当前文件夹中所有的rpm包,忽略依赖去安装

制作不同版本k8s集群需要的离线镜像

#如果用docker做容器,按照下面方面制作离线镜像
kubeadm config print init-defaults > kubeadm.yaml
#修改kubeadm.yaml配置文件如下:
imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers
#上述配置表示,安装k8s需要的镜像要从阿里云镜像仓库拉取

#通过如下命令下载镜像:
kubeadm config images pull --config kubeadm.yaml
#然后把下载好的镜像打包镜像:
docker save -o a.tar.gz registry.aliyuncs.com/google_containers/pause:3.7 jenkins/jenkins:latest ....
#传到内网k8s节点,通过如下命令导出镜像:
ctr -n=k8s.io images import a.tar.gz
docker load -i a.tar.gz
#如果用containerd做容器,按照下面方面制作离线镜像
kubeadm config print init-defaults > kubeadm.yaml
#修改kubeadm.yaml配置文件如下:
imageRepository: registry.cn-hangzhou.aliyuncs.com/google_containers
#上述配置表示,安装k8s需要的镜像要从阿里云镜像仓库拉取
#通过如下命令下载镜像:
kubeadm config images pull --config kubeadm.yaml

ctr -n=k8s.io images ls
#ls出来的的所有镜像做到离线文件里
ctr -n=k8s.io images export k8s1.28.0.tar.gz
#导入到内网环境解压
ctr -n=k8s.io images import k8s1.28.0.tar.gz

kubeadm安装多master集群

kubedam和二进制安装k8s

  • kubeadm是官方提供的开源工具,是一个开源项目,用于快速搭建kubernetes集群,目前是比较方便和推荐使用的。kubeadm init 以及 kubeadm join 这两个命令可以快速创建 kubernetes 集群。Kubeadm初始化k8s,所有的组件都是以pod形式运行的,具备故障自恢复能力。kubeadm适合需要经常部署k8s,或者对自动化要求比较高的场景下使用。

  • 二进制:在官网下载相关组件的二进制包,如果手动安装,对kubernetes理解也会更全面。

  • Kubeadm和二进制都适合生产环境,在生产环境运行都很稳定,具体如何选择,可以根据实际项目进行评估。

安装准备步骤

  • 修改机器IP,变成静态IP (云主机无需配置这个)
vim /etc/sysconfig/network-scripts/ifcfg-ens33
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=static #static表示静态ip地址
IPADDR=192.168.40.180 #ip地址,需要跟自己电脑所在网段一致
NETMASK=255.255.255.0  #子网掩码,需要跟自己电脑所在网段一致
GATEWAY=192.168.40.2 #网关,在自己电脑打开cmd,输入ipconfig /all可看到
DNS1=192.168.40.2 #DNS,在自己电脑打开cmd,输入ipconfig /all可看到 
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME=ens33 #网卡名字,跟DEVICE名字保持一致即可
DEVICE=ens33 #网卡设备名,大家ip addr可看到自己的这个网卡设备名,每个人的机器可能这个名字不一样,需要写自己的
ONBOOT=yes #开机自启动网络,必须是yes

#修改配置文件之后需要重启网络服务才能使配置生效,重启网络服务命令如下:
service network restart
  • 关闭selinux
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config #修改selinux配置文件之后,重启机器,selinux配置才能永久生效
reboot -f
getenforce #显示Disabled说明selinux已经关闭
  • 修改hostname
hostnamectl set-hostname master1 && bash
  • 升级系统,7.6 - 7.9
yum update -y
cat /etc/redhat-release
#CentOS Linux release 7.9.2009 (Core)
  • 关闭交换分区
#临时关闭
swapoff -a
#永久关闭:注释掉fatab的swap挂载
vim /etc/fstab
#/dev/mapper/centos-swap swap      swap    defaults        0 0

#Swap交换分区是一种在计算机中使用的虚拟内存技术。当物理内存不足以容纳当前运行的程序时,操作系统将会把一部分内存空间暂时转移到硬盘上,以便为当前程序提供运行所需的内存空间。这个过程就称为交换。交换分区(Swap Partition)就是硬盘上专门预留给操作系统进行交换的一块空间。交换分区的使用可以有效避免程序因为内存不足而崩溃或运行缓慢的问题,但是硬盘的读写速度比内存要慢得多,因此交换分区的使用会对系统的性能产生一定的影响。当系统内存不足时,会将部分内存数据转移到交换分区中,以释放内存空间。但是,交换分区的读写速度较慢,会影响系统的性能。在 Kubernetes 运行过程中,需要频繁地使用内存和磁盘等系统资源。如果使用了交换分区,会导致 Kubernetes 的运行速度变慢,从而影响整个集群的性能。因此,在安装 Kubernetes 时,通常会建议关闭交换分区。
  • Swap是交换分区,如果机器内存不够,会使用swap分区,但是swap分区的性能较低,k8s设计的时候为了能提升性能,默认是不允许使用交换分区的。
  • Kubeadm初始化的时候会检测swap是否关闭,如果没关闭,那就初始化失败。如果不想要关闭交换分区,安装k8s的时候可以指定--ignore-preflight-errors=Swap来解决。
  • 修改内核参数,开路由转发
modprobe br_netfilter 
# 这个模块是 Linux 网桥的核心模块,它提供了网络包转发和过滤的功能。当我们使用 Kubernetes 的时候,需要使用网络插件(如 Flannel、Calico 等)来实现容器之间的网络通信,而这些网络插件通常会使用 Linux 网桥来进行数据包的转发和过滤。因此,在安装 Kubernetes 之前需要确保 br_netfilter 模块已经加载到内核中,以便 Kubernetes 能够正常使用网络插件。
# 加载br_netfilter模块可以使 iptables 规则可以在 Linux Bridges 上面工作,用于将桥接的流量转发至iptables链,k8s如果没有加载br_netfilter模块,会影响同node内的pod之间通过service来通信。
# 加载这个模块也是为了可以正常开启iptables和ip6tables参数
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
#net.bridge.bridge-nf-call-ip6tables 和 net.bridge.bridge-nf-call-iptables 用于开启Linux的网络包过滤功能。当ubernetes 使用网络插件进行容器之间的通信时,需要通过 Linux 网桥进行数据包的转发和过滤。这些参数可以确保 Linux 系统的网络包过滤功能正常工作,以便 Kubernetes 能够正确地进行网络通信和路由。
#net.ipv4.ip_forward 用于开启 Linux 系统的 IP 转发功能。这个参数是1,则说明IP转发功能已经打开,Kubernetes 能够正确地进行网络路由。
##出于安全考虑,Linux系统默认是禁止数据包转发的。所谓转发即当主机拥有多于一块的网卡时,其中一块收到数据包,根据数据包的目的ip地址将数据包发往本机另一块网卡,该网卡根据路由表继续继续发送数据包。这通常是路由器所要实现的功能。

sysctl -p /etc/sysctl.d/k8s.conf 
#在运行时配置内核参数,-p:从指定的文件加载系统参数,如不指定即从/etc/sysctl.conf中加载
  • 禁用firewalld防火墙
systemctl stop firewalld && systemctl disable firewalld
  • 配置阿里云的repo源
#安装rzsz命令
yum install lrzsz -y
#安装scp:
yum install -y openssh-clients
#备份基础repo源
mkdir /root/repo.bak
cd /etc/yum.repos.d/
mv * /root/repo.bak/

#下载阿里云的repo源
###注意:用GLobalAzure的VM就不需要这面手动修改源了,用自带的源即可###
#把CentOS-Base.repo和epel.repo文件上传到master1主机的/etc/yum.repos.d/目录下
chmod 777 /etc/yum.repos.d/
#通过vscode拖进来
  • 配置国内阿里云docker的repo源
yum install yum-utils -y
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
  • 配置安装k8s组件需要的阿里云的repo源
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

#这个仓库是Kubernetes针对CentOS 7 x86_64架构的yum仓库,当你在CentOS 7系统上使用yum安装Kubernetes时,yum会从这个指定的URL地址获取Kubernetes的安装包和依赖包。
  • 配置时间同步
#安装ntpdate命令
yum install ntpdate -y
#跟网络时间做同步
ntpdate cn.pool.ntp.org
#把时间同步做成计划任务
crontab -e
* */1 * * * /usr/sbin/ntpdate   cn.pool.ntp.org
#重启crond服务
service crond restart

#因为Kubernetes集群的正常运行需要时间同步,否则会出现各种问题。例如,在Kubernetes中使用到了TLS证书,而TLS证书的验证是基于时间戳的,如果节点之间时间不同步,就会导致证书验证失败。另外,Kubernetes中的各种组件之间也需要时间同步,否则可能会出现无法调度Pod、Pod网络异常等问题。
  • 安装基础软件包
##这一步如果是国外的VM不需要修改源,用自带的源安装即可成功。
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 zlib-devel  python-devel epel-release openssh-server socat  ipvsadm conntrack ntpdate telnet ipvsadm
  • 安装docker服务并配置docker镜像加速器和驱动
yum install docker-ce-20.10.6 docker-ce-cli-20.10.6 containerd.io -y
systemctl start docker --now && systemctl status docker #--now相当于 start+enable

#配置docker镜像加速器和驱动
vim /etc/docker/daemon.json 
{
 "registry-mirrors":["https://docker.m.daocloud.io"],
  "exec-opts": ["native.cgroupdriver=systemd"]
} 
#修改docker文件驱动为systemd,默认为cgroupfs,kubelet默认使用systemd,两者必须一致才可以。
systemctl daemon-reload && systemctl restart docker && systemctl status docker
  • 安装初始化k8s需要的软件包
yum install -y kubelet-1.20.6 kubeadm-1.20.6 kubectl-1.20.6
systemctl enable kubelet 
  • 到这里,复制一下master1 VM的OS盘,再创建两台VM出来。
# 分别修改hostname
hostnamectl set-hostname master2 && bash
hostnamectl set-hostname node1 && bash
  • 配Hosts文件
#修改每台机器的/etc/hosts文件,增加如下三行:
192.168.40.4 master1
192.168.40.5 master2
192.168.40.6 node1
  • 配主机间无密码登录
passwd root #设一个root密码
ssh-keygen #一路回车,生成公钥+私钥
ssh-copy-id master1 #把公钥拷贝到另一台机器,需要输入root密码
ssh-copy-id master2
ssh-copy-id node1
#在另外两台上也执行同样操作#

keepalive+nginx实现k8s master节点高可用

配置nginx和keepalived

image-20231020171124147

  • 安装nginx主备
#在master1和2上装nginx和keeplived
yum install nginx keepalived -y
  • 修改nginx配置文件
vim /etc/nginx/nginx.conf
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.40.4:6443 weight=5 max_fails=3 fail_timeout=30s;   # Master1 APISERVER IP:PORT
       server 192.168.40.5:6443 weight=5 max_fails=3 fail_timeout=30s;   # 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 / {
        }
    }
}
  • 修改keeplived配置文件
#########主:master1#################
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 eth0  # 修改为实际网卡名
    virtual_router_id 51 # VRRP 路由 ID实例,每个实例是唯一的 
    unicast_src_ip 192.168.40.4         ##source ip,当前keepalive机器的ip
    unicast_peer {
          192.168.40.5               ##dest ip,另一台keepalive机器的ip
    }
    #如果不加unicase的参数,识别peer ip,那么BACKUP的机器会自动进入MASTER STATE
    priority 100    # 优先级,备服务器设置 90 
    advert_int 1    # 指定VRRP 心跳包通告间隔时间,默认1秒 
    authentication { 
        auth_type PASS      
        auth_pass 1111 
    }  
    # 虚拟IP
    virtual_ipaddress { 
        192.168.40.10 #需要和VM的IP处于一个网段
    } 
    track_script {
        check_nginx
    } 
}

########备master2############
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 BACKUP 
    interface eth0  # 修改为实际网卡名
    virtual_router_id 51 # VRRP 路由 ID实例,每个实例是唯一的
    unicast_src_ip 192.168.40.5         ##source ip,当前keepalive机器的ip
    unicast_peer {
          192.168.40.4               ##dest ip,另一台keepalive机器的ip
    }
    priority 90    # 优先级,备服务器设置 90 
    advert_int 1    # 指定VRRP 心跳包通告间隔时间,默认1秒 
    authentication { 
        auth_type PASS      
        auth_pass 1111 
    }  
    # 虚拟IP
    virtual_ipaddress { 
        192.168.40.10 #需要和VM的IP处于一个网段
    } 
    track_script {
        check_nginx
    } 
}
  • 写检查nginx工作状态脚本
vim /etc/keepalived/check_nginx.sh 
#!/bin/bash
#1、判断Nginx是否存活
counter=$(ps -ef |grep nginx | grep sbin | egrep -cv "grep|$$" )
if [ $counter -eq 0 ]; then
    #2、如果不存活则尝试启动Nginx
    service nginx start
    sleep 2
    #3、等待2秒后再次获取一次Nginx状态
    counter=$(ps -ef |grep nginx | grep sbin | egrep -cv "grep|$$" )
    #4、再次进行判断,如Nginx还不存活则停止Keepalived,让地址进行漂移
    if [ $counter -eq 0 ]; then
        service keepalived stop
    fi
fi
#注:keepalived根据脚本返回状态码(0为工作正常,非0不正常)判断是否故障转移。
  • 启动nginx和keepalived
yum install nginx-mod-stream -y
chmod +x /etc/keepalived/check_nginx.sh
chmod 644 /etc/keepalived/keepalived.conf
systemctl daemon-reload
systemctl start nginx
systemctl start keepalived
systemctl enable nginx keepalived && systemctl status keepalived

#在nginx里面设置了监听端口16443
#在keeplived里面配了VIP 192.168.40.10
#==>访问192.168.40.10:16443的流量就会被反向代理到两个master:
#192.168.40.4:6443
#192.168.40.5:6443
  • 检查keepalived主备切换情况
#主机
systemctl stop keepalived
ip addr #看到VIP已经没了
#备机
ip addr #有了VIP
systemctl status keepalived #看到提升为Master了

配置kubeadm

  • 创建kubeadm配置文件
#在master1上配置:
cd /root/
vim kubeadm-config.yaml 

apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: v1.20.6
controlPlaneEndpoint: 192.168.40.4:16443
imageRepository: registry.aliyuncs.com/google_containers
apiServer:
 certSANs:
 - 192.168.40.4
 - 192.168.40.5
 - 192.168.40.6
 - 192.168.40.10
networking:
  podSubnet: 10.244.0.0/16
  serviceSubnet: 10.96.0.0/16
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind:  KubeProxyConfiguration
mode: ipvs

注意:

  1. 参数image-repository: registry.aliyuncs.com/google_containers
  2. 为保证拉取镜像不到国外站点拉取,手动指定仓库地址为registry.aliyuncs.com/google_containers。
  3. kubeadm默认从k8s.gcr.io拉取镜像。
  4. 如果本地有导入的离线镜像,会优先使用本地的镜像。

  5. kubeproxy模式采用ipvs:

  6. 如果不指定ipvs,会默认使用iptables.开启IPVS可以提高Kubernetes集群的性能和可靠性。IPVS是一个高性能的负载均衡器,与Kubernetes Service一起使用,可以在Pod之间分配负载。相比于Kubernetes自带的iptables模式,IPVS模式在处理大量流量时具有更好的性能和可靠性。此外,IPVS还支持四层和七层协议的负载均衡,能够满足更多的应用场景需求,所以我们生产环境建议开启ipvs。
  7. controlPlaneEndpoint: 192.168.40.10:16443,16443是把请求代理给nginx的配置。

初始化集群

加载master组件的镜像

#在master1、master2、node1上都解压
docker load -i k8simage-1-20-6.tar.gz
#没有离线包的话,后面执行kubeadm init也会自动从镜像源下载这些image包

kubeadm初始化k8s集群

#在master1上执行:
cd /root/
kubeadm init --config kubeadm-config.yaml --ignore-preflight-errors=SystemVerification

对kubectl授权

mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubectl get nodes
#notready是因为还没有安装网络插件

kubectl 修改 alias为k并添加补全

#1. 设置kubectl的alias为k:
whereis kubectl # kubectl: /usr/bin/kubectl
echo "alias k=/usr/bin/kubectl">>/etc/profile
source /etc/profile
#2. 设置alias的自动补全:
source <(kubectl completion bash | sed 's/kubectl/k/g')
#3. 解决每次启动k都会失效,要重新刷新环境变量(source /etc/profile)的问题:在~/.bashrc文件中添加以下代码:source /etc/profile
echo "source /etc/profile" >> ~/.bashrc
#4. 给alias k也配置补全
vim ~/.bashrc
##加入以下
alias k='kubectl'
complete -o default -F __start_kubectl k
source <(kubectl completion bash)
##使命令生效
source ~/.bashrc

kubectl机理解释:

  • kubectl走的是 /root/.kube/config 文件中的配置,如何查看:

  • kubectl config view

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: https://192.168.40.4:16443
  name: kubernetes
contexts:
- context:
    cluster: kubernetes
    user: kubernetes-admin #声明了当前用户,这个是安装k8s的时候自动生成的admin用户
  name: kubernetes-admin@kubernetes
current-context: kubernetes-admin@kubernetes
kind: Config
preferences: {}
users:
- name: kubernetes-admin
  user:
    client-certificate-data: REDACTED
    client-key-data: REDACTED
  • 如果想要在别的机器上运行kubectl,只需要保证这个机器能连通到master,再把/root/.kube/config拷过去就行了。
#目标机器
mkdir -p /root/.kube/
#master上
scp /root/.kube/config node1:/root/.kube/

扩容集群-添加master节点

#master2上创建证书目录
cd /root && mkdir -p /etc/kubernetes/pki/etcd && mkdir -p ~/.kube/
#把master1的证书拷贝到master2
scp /etc/kubernetes/pki/ca.crt master2:/etc/kubernetes/pki/
scp /etc/kubernetes/pki/ca.key master2:/etc/kubernetes/pki/
scp /etc/kubernetes/pki/sa.key master2:/etc/kubernetes/pki/
scp /etc/kubernetes/pki/sa.pub master2:/etc/kubernetes/pki/
scp /etc/kubernetes/pki/front-proxy-ca.crt master2:/etc/kubernetes/pki/
scp /etc/kubernetes/pki/front-proxy-ca.key master2:/etc/kubernetes/pki/
scp /etc/kubernetes/pki/etcd/ca.crt master2:/etc/kubernetes/pki/etcd/
scp /etc/kubernetes/pki/etcd/ca.key master2:/etc/kubernetes/pki/etcd/
#在master1上查看join节点的命令
kubeadm token create --print-join-command
#在master2上执行这个join命令
#查看节点状况
kubectl get nodes
  • Issue: 用VM来做,keepalived的VIP无法接收到流量,无法用做k8s-apiserver暴露的IP。节点扩容会失败。

扩容集群-添加node节点

#在master1上查看join节点的命令
kubeadm token create --print-join-command
#在node1上执行这个join命令
#因为是加master节点,需要加上 --control-plane --ignore-preflight-errors=SystemVerification
#查看节点状况
kubectl get nodes

#master1上get node看到node1的role为none
#可以把node1的ROLES变成worker,按照如下方法:
kubectl label node node1 node-role.kubernetes.io/worker=worker
kubectl get pod -n kube-system
#看到corends pod是pending,因为还没装网络插件

安装网络插件calico

#上传了Caclio.yaml
kubectl apply -f calico.yaml
#在线下载地址为:https://docs.projectcalico.org/manifests/calico.yaml
  • 测试caclio是否正常工作
#上传busybox并解压
docker load -i busybox-1-28.tar.gz
kubectl run busybox --image busybox:1.28 --restart=Never --rm -it busybox -- sh
#测试是否能联网
ping www.baidu.com
#测试是否能解析dns
nslookup kubernetes.default.svc.cluster.local #这个域名是默认创建的service的FQDN

Server:    10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local

Name:      kubernetes.default.svc.cluster.local
Address 1: 10.96.0.1 kubernetes.default.svc.cluster.local
#k8s内部解析域名用的dns server是coreDNS(coredns的svc ip就是这里的10.96.0.10)
k get svc -A
NAMESPACE     NAME         TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)                  AGE
default       kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP                  4h21m
kube-system   kube-dns     ClusterIP   10.96.0.10   <none>        53/UDP,53/TCP,9153/TCP   4h21m

延长证书有效期

#查看ca证书过期时间
openssl x509 -in /etc/kubernetes/pki/ca.crt -noout -text | grep Not
# 查看apiserver证书过期时间
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -text | grep Not
#可以看到apiserver证书的有效期是1年
#把延长的脚本上传:update-kubeadm-cert.sh并赋权执行
chmod +x update-kubeadm-cert.sh
./update-kubeadm-cert.sh all

卸载kubeadm安装的集群

#装错了需要重新初始化
kubeadm reset

kubeadm安装单master集群

安装装备步骤

安装集群

生成并修改配置文件

kubeadm config print init-defaults > kubeadm.yaml

apiVersion: kubeadm.k8s.io/v1beta2
bootstrapTokens:
- groups:
  - system:bootstrappers:kubeadm:default-node-token
  token: abcdef.0123456789abcdef
  ttl: 24h0m0s
  usages:
  - signing
  - authentication
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 192.168.40.4 #控制节点的ip
  bindPort: 6443
nodeRegistration:
  criSocket: /var/run/dockershim.sock
  name: master1 #控制节点主机名
  taints:
  - effect: NoSchedule
    key: node-role.kubernetes.io/master
---
apiServer:
  timeoutForControlPlane: 4m0s
apiVersion: kubeadm.k8s.io/v1beta2
certificatesDir: /etc/kubernetes/pki
clusterName: kubernetes
controllerManager: {}
dns:
  type: CoreDNS
etcd:
  local:
    dataDir: /var/lib/etcd
imageRepository: registry.aliyuncs.com/google_containers #修改默认镜像仓库为阿里云
kind: ClusterConfiguration
kubernetesVersion: v1.20.6
networking:
  dnsDomain: cluster.local
  serviceSubnet: 10.96.0.0/12
  podSubnet: 10.244.0.0/16 #指定pod网段, 需要新增加这个
scheduler: {}
---
apiVersion: kubeproxy.config.k8s.io/v1alpha1
kind: KubeProxyConfiguration
mode: ipvs
---
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
cgroupDriver: systemd

初始化集群

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

授权kubectl

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

扩容节点

#master1查看join命令
kubeadm token create --print-join-command
#node1上把命令添加参数:--ignore-preflight-errors=SystemVerification

mkdir -p $HOME/.kube
##master1的kubectl的config文件拷到node1上
scp $HOME/.kube/config node1:/root/.kube/

#node1打标签
kubectl label node node1 node-role.kubernetes.io/worker=worker
##同样方法扩容node2

安装Caclio

方法同前面多master的步骤

延长证书有效期

方法同前面多master的步骤