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

摘要:
配置文件forkeepalidglobal_defs{router_idmaster01}vrrp_ instanceVI_1{stateMASTERinterfaces33virtual_router_id50priority150advert_int1身份验证{auth_typePASSauth_pass1111}虚拟IP地址{192.168.213.200}}master02[root@master02~]#cat/etc/keepalived/keepalived.conf!
高可用架构

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 ”

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

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

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

免责声明:文章转载自《kubeadm实现k8s高可用集群环境部署与配置》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇python之递归函数、二分查找、面向对象、封装(6)bootstrap-datepicker的简单使用下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

C/C++迭代器使用具体解释

迭代器是一种检查容器内元素并遍历元素的数据类型。能够替代下标訪问vector对象的元素。 每种容器类型都定义了自己的迭代器类型,如 vector: vector<int>::iterator iter;这符语句定义了一个名为 iter 的变量。它的数据类型是 vector<int> 定义的 iterator 类型。每一个标准库容器...

Android APP性能测试笔记(一)

Android APP性能测试笔记(一) (1)工具使用       Android Studio  GT, root的真机 (2)记录apk大小(对比竞品)       使用Android Studio导入需要测试的apk 导入后,页面显示apk的大小   如果希望可以优化前后apk进行对比   (3)启动时间   冷启动:无数据的首次启动;...

6.深入k8s:守护进程DaemonSet

转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com 最近也一直在加班,处理项目中的事情,发现问题越多越是感觉自己的能力不足,希望自己能多学点。我觉得人生的意义就是在于能够不断的寻求突破吧。 这篇文章会讲DaemonSet和Job与CronJob一起。在讲其中某一块内容的时候,我会将一些其他内容也...

React Native环境搭建

最近组里老大开始招RN的一些开发人员,也从最近的一些动向表明将来的功能有可能会由RN来编写了,而对于我是从事纯Native的android开发工作已经N多年了,对于RN组里面也有一些同事的技术分享,说实话对它是非常之抗拒的,觉着这玩意不会就像几年前出的PhoneGap那样鸡肋的技术吧,也就是用Webview去加载h5页面嘛,不可能代替Native的,直到最...

k8s v1.19.1 修改系统镜像地址过程记录

1.系统镜像列表 k8s.gcr.io/kube-apiserver:v1.19.1 k8s.gcr.io/kube-scheduler:v1.19.1 k8s.gcr.io/kube-controller-manager:v1.19.1 k8s.gcr.io/kube-proxy:v1.19.1 k8s.gcr.io/pause:3.2 k8s.gcr....

jenkins pipeline实现自动构建并部署至k8s

在日常开发中,经常会有发布的需求,而且经常会碰到各种环境,比如:开发环境、测试环境、生产环境。虽然可以使用手动构建、上传服务器部署的方式,但在微服务架构下一个项目经常包含多个微服务的部署,如果用手动方式就会非常繁琐而且容易出错。使用jenkins结合SCM可以实现代码的整个自动化构建部署过程。 本文中自动构建部署过程大致完成了以下步骤: 提交spring...