kubeadm实现k8s高可用集群环境部署与配置

高可用架构

k8s集群的高可用实际是k8s各核心组件高可用,这里使用主备模式,架构如下:
在这里插入图片描述
主备模式高可用架构说明:

核心组件高可用模式高可用实现方式
apiserver主备keepalived
controller-manager主备leader election
scheduler主备leader election
etcd集群kubeadm
  • apiserver 通过keepalived实现高可用,当某个节点故障时触发keepalived vip 转移;
  • controller-manager k8s内部通过选举方式产生领导者(由leader-elect 选型控制,默认为true),同一时刻集群内只有一个controller-manager组件运行;
  • scheduler k8s内部通过选举方式产生领导者(由leader-elect 选型控制,默认为true),同一时刻集群内只有一个scheduler组件运行;
  • etcd 通过运行kubeadm方式自动创建集群来实现高可用,部署的节点数为奇数,3节点方式最多容忍一台机器宕机。

部署环境

k8s版本

kubelet versionkubeadm versionkubectl version
v1.15.1v1.15.1v1.15.1

主机配置

Centos版本系统内核docker versionflannel versionKeepalived version
7.8.20034.4.22319.03.9v0.11.0v1.3.5

主机列表

主机名ip主机配置备注
master01192.168.213.1814U4Gcontrol plane
master02192.168.213.1824U4Gcontrol plane
master03192.168.213.1834U4Gcontrol plane
node01192.168.213.1922U2Gnode
node02192.168.213.1922U2Gnode
VIP192.168.213.2004U4G在control plane上浮动

私有仓库

主机名ip主机配置备注
docker-registry192.168.213.1292U1Greg.zhao.com

其他准备

系统初始化,docker安装,k8s(kubelet、kubeadm和kubectl)安装省略

  • kubelet 运行在集群所有节点上,用于启动Pod和容器
  • kubeadm 用于初始化集群,启动集群
  • kubectl 用于和集群通信,部署和管理应用,查看各种资源,创建、删除和更新各种组件

启动kubelet并设置开机启动 systemctl enable kubelet && systemctl start kubelet

keepalived安装

在所有master节点上安装

安装keepalived

[root@master01 ~]# yum -y install keepalived

keepalived配置

master01

[root@master01 ~]# cat /etc/keepalived/keepalived.conf 
! Configuration File for keepalived
global_defs {
   router_id master01
}
vrrp_instance VI_1 {
    state MASTER 
    interface ens33
    virtual_router_id 50
    priority 150
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.213.200
    }
}

master02

[root@master02 ~]# cat /etc/keepalived/keepalived.conf 
! Configuration File for keepalived
global_defs {
   router_id master02
}
vrrp_instance VI_1 {
    state BACKUP 
    interface ens33
    virtual_router_id 50
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.213.200
    }
}

master03

[root@master03 ~]# cat /etc/keepalived/keepalived.conf 
! Configuration File for keepalived
global_defs {
   router_id master03
}
vrrp_instance VI_1 {
    state BACKUP 
    interface ens33
    virtual_router_id 50
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.213.200
    }
}

启动keepalived并设置开机启动

[root@master01 ~]# systemctl start keepalived
[root@master01 ~]# systemctl enable keepalived

VIP查看

在这里插入图片描述

配置master节点

初始化master01节点

master01初始化

#初始化的配置文件
[root@master01 ~]# cat kubeadm-config.yaml
apiVersion: kubeadm.k8s.io/v1beta2
kind: ClusterConfiguration
kubernetesVersion: v1.15.1
apiServer:
  certSANs:		##填写所有kube-apiserver节点的hostname、IP、VIP
  - master01
  - master02
  - master03
  - node01
  - node02
  - 192.168.213.181
  - 192.168.213.182
  - 192.168.213.183
  - 192.168.213.191
  - 192.168.213.192
  - 192.168.213.200
controlPlaneEndpoint: "192.168.213.200:6443"
networking:
  podSubnet: "10.244.0.0/16"
[root@master01 ~]# kubeadm init --config=kubeadm-config.yaml|tee kubeadim-init.log

记录kubeadm join的输出,后面需要这个命令将备master节点和node节点加入集群中

Then you can join any number of worker nodes by running the following on each as root:

kubeadm join 192.168.213.200:6443 --token ebx4uz.9y3twsnoj9yoscoo \
    --discovery-token-ca-cert-hash sha256:1bc280548259dd8f1ac53d75e918a8ec99c234b13f4fe18a71435bbbe8cb26f3

加载环境变量

[root@master01 ~]# echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
[root@master01 ~]# source .bash_profile

安装flannel网络

[root@master01 ~]# kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/2140ac876ef134e0ed5af15c65e414cf26827915/Documentation/kube-flannel.yml

备master节点加入集群

配置免密登录

配置master01到master02、master03免密登录

#创建秘钥
[root@master01 ~]# ssh-keygen -t rsa
#将秘钥同步至master02,master03
[root@master01 ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.213.182
[root@master01 ~]# ssh-copy-id -i /root/.ssh/id_rsa.pub root@192.168.213.183
#免密登陆测试
[root@master01 ~]# ssh master02
[root@master01 ~]# ssh 192.168.213.183

master01分发证书

在master01上运行脚本cert-main-master.sh,将证书分发至master02和master03

[root@master01 ~]# cat cert-main-master.sh
USER=root # customizable
CONTROL_PLANE_IPS="192.168.213.182 192.168.213.183"
for host in ${CONTROL_PLANE_IPS}; do
    scp /etc/kubernetes/pki/ca.crt "${USER}"@$host:
    scp /etc/kubernetes/pki/ca.key "${USER}"@$host:
    scp /etc/kubernetes/pki/sa.key "${USER}"@$host:
    scp /etc/kubernetes/pki/sa.pub "${USER}"@$host:
    scp /etc/kubernetes/pki/front-proxy-ca.crt "${USER}"@$host:
    scp /etc/kubernetes/pki/front-proxy-ca.key "${USER}"@$host:
    scp /etc/kubernetes/pki/etcd/ca.crt "${USER}"@$host:etcd-ca.crt
    # Quote this line if you are using external etcd
    scp /etc/kubernetes/pki/etcd/ca.key "${USER}"@$host:etcd-ca.key
done
[root@master01 ~]# ./cert-main-master.sh

备master节点移动证书至指定目录

在master02,master03上运行脚本cert-other-master.sh,将证书移至指定目录

[root@master02 ~]# cat cert-other-master.sh
USER=root # customizable
mkdir -p /etc/kubernetes/pki/etcd
mv /${USER}/ca.crt /etc/kubernetes/pki/
mv /${USER}/ca.key /etc/kubernetes/pki/
mv /${USER}/sa.pub /etc/kubernetes/pki/
mv /${USER}/sa.key /etc/kubernetes/pki/
mv /${USER}/front-proxy-ca.crt /etc/kubernetes/pki/
mv /${USER}/front-proxy-ca.key /etc/kubernetes/pki/
mv /${USER}/etcd-ca.crt /etc/kubernetes/pki/etcd/ca.crt
# Quote this line if you are using external etcd
mv /${USER}/etcd-ca.key /etc/kubernetes/pki/etcd/ca.key
[root@master02 ~]# ./cert-other-master.sh 

备master节点加入集群

在master02和master03节点上运行加入集群的命令

kubeadm join 192.168.213.200:6443 --token ebx4uz.9y3twsnoj9yoscoo \
    --discovery-token-ca-cert-hash sha256:1bc280548259dd8f1ac53d75e918a8ec99c234b13f4fe18a71435bbbe8cb26f3

备master节点加载环境变量

此步骤是为了在备master节点上也能执行kubectl命令

scp master01:/etc/kubernetes/admin.conf /etc/kubernetes/
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile
source .bash_profile

node节点加入集群

加入集群

在node节点运行初始化master生成的加入集群的命令

kubeadm join 192.168.213.200:6443 --token ebx4uz.9y3twsnoj9yoscoo \
    --discovery-token-ca-cert-hash sha256:1bc280548259dd8f1ac53d75e918a8ec99c234b13f4fe18a71435bbbe8cb26f3

集群节点查看

[root@master01 ~]# kubectl get nodes
[root@master01 ~]# kubectl get pod -o wide -n kube-system 

所有control plane节点处于ready状态,所有的系统组件也正常
在这里插入图片描述

对接私有仓库

私有仓库配置省略,在所有节点上执行以下步骤

修改daemon.json

[root@master01 ~]# cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.213.181 master01
192.168.213.182 master02
192.168.213.183 master03
192.168.213.191 node01
192.168.213.192 node02
192.168.213.129 reg.zhao.com
[root@master01 ~]# cat /etc/docker/daemon.json
{
    "registry-mirrors": ["https://sopn42m9.mirror.aliyuncs.com"],
    "exec-opts": ["native.cgroupdriver=systemd"],
    "log-driver": "json-file",
        "log-opts": {
            "max-size": "100m"
        },
    "insecure-registries": ["https://reg.zhao.com"]
}
[root@master01 ~]# systemctl daemon-reload
[root@master01 ~]# systemctl restart docker

创建认证secret

使用Kuberctl创建docker register认证secret

[root@master01 ~]# kubectl create secret docker-registry myregistrykey --docker-server=https://reg.zhao.com --docker-username=admin --docker-password=Harbor12345 --docker-email=""
secret/myregistrykey created
[root@master02 ~]# kubectl get secrets
NAME                  TYPE                                  DATA   AGE
default-token-6mrjd   kubernetes.io/service-account-token   3      18h
myregistrykey         kubernetes.io/dockerconfigjson        1      19s

在创建Pod的时通过imagePullSecret引用myregistrykey

imagePullSecrets:
  - name: myregistrykey

集群功能测试

测试私有仓库

[root@master02 ~]# cat test_sc.yaml
apiVersion: v1
kind: Pod
metadata:
  name: foo
spec:
  containers:
    - name: foo
      image: reg.zhao.com/zhao/myapp:v1.0
#  imagePullSecrets:
#    - name: myregistrykey

在这里插入图片描述在这里插入图片描述打开注释,应用密钥,可以拉取到镜像
在这里插入图片描述

测试集群高可用

测试master节点高可用

通过ip查看apiserver所在节点,通过leader-elect查看scheduler和controller-manager所在节点

[root@master01 ~]# ip a|grep ens33
[root@master01 ~]# kubectl get endpoints kube-scheduler -n kube-system -o yaml |grep holderIdentity
[root@master01 ~]# kubectl get endpoints kube-controller-manager -n kube-system -o yaml |grep holderIdentity

在这里插入图片描述

组件名所在节点
apiservermaster01
controller-managermaster01
schedulermaster01

关闭master01,模拟宕机,master01状态为NotReady

[root@master01 ~]# init 0

VIP飘到了master02,controller-manager和scheduler也发生了迁移
在这里插入图片描述

组件名所在节点
apiservermaster02
controller-managermaster03
schedulermaster02

测试node节点高可用

K8S 的pod-eviction在某些场景下如节点 NotReady,资源不足时,会把 pod 驱逐至其它节点

Kube-controller-manager 周期性检查节点状态,每当节点状态为 NotReady,并且超出 pod-eviction-timeout 时间后,就把该节点上的 pod 全部驱逐到其它节点,其中具体驱逐速度还受驱逐速度参数,集群大小等的影响。最常用的 2 个参数如下:
pod-eviction-timeout:NotReady 状态节点超过该时间后,执行驱逐,默认 5 min
node-eviction-rate:驱逐速度,默认为 0.1 pod/秒

创建pod,维持副本数3

[root@master02 ~]# cat myapp_deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deploy
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
      release: stabel
  template:
    metadata:
      labels:
        app: myapp
        release: stabel
        env: test
    spec:
      containers:
      - name: myapp
        image: library/nginx
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 80

可以看到pod分布在node01和node02节点上
在这里插入图片描述关闭node02,模拟宕机,node02状态为NotReady
在这里插入图片描述可以看到 NotReady 状态节点超过指定时间后,pod被驱逐到 Ready 的节点上,deployment维持运行3个副本

问题

初始化master节点失败

如果初始化失败,可执行kubeadm reset后重新初始化

[root@master01 ~]# kubeadm reset
#非root用户还须执行rm -rf $HOME/.kube/config

flanne文件下载失败

方法一:可以直接下载kube-flannel.yml文件,然后再执行apply
方法二:配置域名解析
在https://site.ip138.com查询服务器IP
在这里插入图片描述echo "151.101.76.133 raw.Githubusercontent.com" >>/etc/hosts

节点状态NotReady

在节点机器上执行journalctl -f -u kubelet查看kubelet的输出日志信息如下:

Container runtime network not ready: NetworkReady=false reason:NetworkPluginNotReady message:docker: network plugin is not ready: cni config uninitialized

出现这个错误的原因是网络插件没有准备好,在节点上执行命令 docker images|grep flannel 查看flannel镜像是否已经成功拉取,这个花费的时间可能会很长

如果很长时间仍然没有拉下来flannel镜像,可以使用如下方法解决

docker save把主节点上的flannel镜像保存为压缩文件(或在官方仓库https://github.com/coreos/flannel/releases下载镜像传到主机上,要注意版本对应),在节点机器上执行docker load加载镜像

[root@master02 ~]# docker save -o my_flannel.tar quay.io/coreos/flannel:v0.11.0-amd64
[root@master02 ~]# scp my_flannel.tar node01:/root
[root@node01 ~]# docker load < my_flannel.tar

unexpected token `$’do\r”

shell,运行出错:syntax error near unexpected token `$’do\r”

原因:Linux和windows下的回车换行符不兼容

解决方法:将windows下面的CR LF,转换为Linux下面的LF
用notepad++打开文件,编辑->档案格式转换->转换为UNIX格式->保存即可

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值