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 version | kubeadm version | kubectl version |
---|---|---|
v1.15.1 | v1.15.1 | v1.15.1 |
主机配置
Centos版本 | 系统内核 | docker version | flannel version | Keepalived version |
---|---|---|---|---|
7.8.2003 | 4.4.223 | 19.03.9 | v0.11.0 | v1.3.5 |
主机列表
主机名 | ip | 主机配置 | 备注 |
---|---|---|---|
master01 | 192.168.213.181 | 4U4G | control plane |
master02 | 192.168.213.182 | 4U4G | control plane |
master03 | 192.168.213.183 | 4U4G | control plane |
node01 | 192.168.213.192 | 2U2G | node |
node02 | 192.168.213.192 | 2U2G | node |
VIP | 192.168.213.200 | 4U4G | 在control plane上浮动 |
私有仓库
主机名 | ip | 主机配置 | 备注 |
---|---|---|---|
docker-registry | 192.168.213.129 | 2U1G | reg.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 ens160
virtual_router_id 50
priority 150
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.27.34.130
}
}
master02
[root@master02 ~]# cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id master02
}
vrrp_instance VI_1 {
state BACKUP
interface ens160
virtual_router_id 50
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.27.34.130
}
}
master03
[root@master03 ~]# cat /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id master03
}
vrrp_instance VI_1 {
state BACKUP
interface ens160
virtual_router_id 50
priority 80
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.27.34.130
}
}
启动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
组件名 | 所在节点 |
---|---|
apiserver | master01 |
controller-manager | master01 |
scheduler | master01 |
关闭master01,模拟宕机,master01状态为NotReady
[root@master01 ~]# init 0
VIP飘到了master02,controller-manager和scheduler也发生了迁移
组件名 | 所在节点 |
---|---|
apiserver | master02 |
controller-manager | master03 |
scheduler | master02 |
测试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格式->保存
即可
kubeadm实现k8s高可用集群环境部署与配置的更多相关文章
- ProxySQL Cluster 高可用集群环境部署记录
ProxySQL在早期版本若需要做高可用,需要搭建两个实例,进行冗余.但两个ProxySQL实例之间的数据并不能共通,在主实例上配置后,仍需要在备用节点上进行配置,对管理来说非常不方便.但是Proxy ...
- Centos7.5基于MySQL5.7的 InnoDB Cluster 多节点高可用集群环境部署记录
一. MySQL InnoDB Cluster 介绍MySQL的高可用架构无论是社区还是官方,一直在技术上进行探索,这么多年提出了多种解决方案,比如MMM, MHA, NDB Cluster, G ...
- 大数据高可用集群环境安装与配置(09)——安装Spark高可用集群
1. 获取spark下载链接 登录官网:http://spark.apache.org/downloads.html 选择要下载的版本 2. 执行命令下载并安装 cd /usr/local/src/ ...
- 大数据高可用集群环境安装与配置(06)——安装Hadoop高可用集群
下载Hadoop安装包 登录 https://mirrors.tuna.tsinghua.edu.cn/apache/hadoop/common/ 镜像站,找到我们要安装的版本,点击进去复制下载链接 ...
- 大数据高可用集群环境安装与配置(07)——安装HBase高可用集群
1. 下载安装包 登录官网获取HBase安装包下载地址 https://hbase.apache.org/downloads.html 2. 执行命令下载并安装 cd /usr/local/src/ ...
- 大数据高可用集群环境安装与配置(03)——设置SSH免密登录
Hadoop的NameNode需要启动集群中所有机器的Hadoop守护进程,这个过程需要通过SSH登录来实现 Hadoop并没有提供SSH输入密码登录的形式,因此,为了能够顺利登录每台机器,需要将所有 ...
- 大数据高可用集群环境安装与配置(08)——安装Ganglia监控集群
1. 安装依赖包和软件 在所有服务器上输入命令进行安装操作 yum install epel-release -y yum install ganglia-web ganglia-gmetad gan ...
- 大数据高可用集群环境安装与配置(04)——安装JAVA运行环境
Hadoop运行在java环境,所以在安装Hadoop之前,需要安装好jdk 提前下载好jdk安装包(jdk-8u161-linux-x64.tar.gz),将它上传到指定的安装目录当中,然后运行安装 ...
- 大数据高可用集群环境安装与配置(02)——配置ntp服务
NTP服务概述 NTP服务器[Network Time Protocol(NTP)]是用来使计算机时间同步化的一种协议,它可以使计算机对其服务器或时钟源(如石英钟,GPS等等)做同步化,它可以提供高精 ...
随机推荐
- Java 常用API(一)
目录 Java 常用API(一) 1. Scanner类 引用类型的一般使用步骤 Scanner的使用步骤 例题 2. 匿名对象 概述 匿名对象作为方法的参数 匿名对象作为方法的返回值 3. Rand ...
- web概念简述,HTML学习笔记
今日内容 1. web概念概述 2. HTML web概念概述 * JavaWeb: * 使用Java语言开发基于互联网的项目 * 软件架构: 1. C/S: Client/Server 客户端/服务 ...
- kubernetes部署redis主从高可用集群
1.redis主从高可用集群结构 2.k8s部署有状态的服务选择 对于K8S集群有状态的服务,我们可以选择deployment和statefulset statefulset service& ...
- vue实现音乐播放器实战笔记
原文链接:https://blog.csdn.net/Forever201295/article/details/80266600 一.项目说明该播放器的是基于学习vue的实战练习,不用于其他途径.应 ...
- box-sizing 可以使border padding不影响设置的盒子尺寸
- C#硬件开发业务流程调试技巧
C#硬件开发,一种是调用厂家提供的api;另一种就是通过com口,发送命令,和硬件通信.这2种方法,如果有硬件,业务流程很好调试.但是大部分硬件,只有和客户联调才会有硬件调试的机会.那业务流程没有硬件 ...
- 黑马程序员_毕向东_Java基础视频教程——常量(随笔)
常量 常量表示不能被改变的数值. Java常量的分类 整型常量.所有整数 小数常量.所有小数 布尔型常量.特殊只有两个值:true.false. 字符常量.将一个数字字母或者符号用单引号(' ')标识 ...
- 小程序使用模板template
小程序使用模板template 1.介绍:模板就是代码的高度复用,将在很多页面使用了相同的部分可以使用模板封装 <!-- 在页面组件中使用 --> <!-- 此时定义了一个模板 -- ...
- php5.2安装memcached 扩展
需要注意版本号,好坑. libmemcached release 1.0.16 - installed from sourcephp-memcached release 2.1.0 - install ...
- 轻松扩展机器学习能力:如何在Rancher上安装Kubeflow
随着机器学习领域不断发展,对于处理机器学习的团队来说,在1台机器上训练1个模型已经有些难以为继,并且现在业界的共识是机器学习已经不仅仅是简单的模型训练. 在模型训练之前.过程中和之后,需要进行许多活动 ...