福利

文末留言送 3 本由马哥教育 CEO 马哥(马永亮)撰写的《Kubernetes 进阶实战》,希望大家点击文末的留言小程序积极留言,每个人都有机会。


前言

本文教你如何用一条命令构建 k8s 高可用集群且不依赖 haproxy 和 keepalived,也无需 ansible。通过内核 ipvs 对 apiserver 进行负载均衡,并且带 apiserver 健康检测。架构如下图所示:


本项目名叫 sealos,旨在做一个简单干净轻量级稳定的 kubernetes 安装工具,能很好的支持高可用安装。其实把一个东西做的功能强大并不难,但是做到极简且灵活可扩展就比较难。所以在实现时就必须要遵循这些原则。下面介绍一下 sealos 的设计原则:

点击该项目离线包资源!

设计原则

sealos 特性与优势:

  • 支持离线安装,工具与资源包(二进制程序 配置文件 镜像 yaml文件等)分离,这样不同版本替换不同离线包即可

  • 证书延期

  • 使用简单

  • 支持自定义配置

  • 内核负载,极其稳定,因为简单所以排查问题也极其简单

1为什么不用 ansible?

1.0 版本确实是用 ansible 实现,但是用户还是需要先装 ansile,装 ansible 又需要装 python 和一些依赖等,为了不让用户那么麻烦把 ansible 放到了容器里供用户使用。如果不想配置免密钥使用用户名密码时又需要 ssh-pass 等,总之不能让我满意,不是我想的极简。

所以我想就来一个二进制文件工具,没有任何依赖,文件分发与远程命令都通过调用 sdk 实现所以不依赖其它任何东西,总算让我这个有洁癖的人满意了。

2为什么不用 keepalived haproxy?

haproxy 用 static pod 跑没有太大问题,还算好管理,keepalived 现在大部分开源 ansible 脚本都用 yum 或者 apt 等装,这样非常的不可控,有如下劣势:

  • 源不一致可能导致版本不一致,版本不一直连配置文件都不一样,我曾经检测脚本不生效一直找不到原因,后来才知道是版本原因。

  • 系统原因安装不上,依赖库问题某些环境就直接装不上了。

  • 看了网上很多安装脚本,很多检测脚本与权重调节方式都不对,直接去检测 haproxy 进程在不在,其实是应该去检测 apiserver 是不是 healthz 的,如果 apiserver 挂了,即使 haproxy 进程存在,集群也会不正常了,就是伪高可用了。

  • 管理不方便,通过 prometheus 对集群进行监控,是能直接监控到 static pod 的但是用 systemd 跑又需要单独设置监控,且重启啥的还需要单独拉起。不如 kubelet 统一管理来的干净简洁。

  • 我们还出现过 keepalived 把 CPU 占满的情况。

所以为了解决这个问题,我把 keepalived 跑在了容器中(社区提供的镜像基本是不可用的) 改造中间也是发生过很多问题,最终好在解决了。

总而言之,累觉不爱,所以在想能不能甩开 haproxy 和 keepalived 做出更简单更可靠的方案出来,还真找到了。。。

3本地负载为什么不使用 envoy 或者 nginx?

我们通过本地负载解决高可用问题。

本地负载:在每个 node 节点上都启动一个负载均衡,上游就是三个 master。

如果使用 envoy 之类的负载均衡器,则需要在每个节点上都跑一个进程,消耗的资源更多,这是我不希望的。ipvs 实际也多跑了一个进程 lvscare,但是 lvscare 只是负责管理 ipvs 规则,和 kube-proxy 类似,真正的流量还是从很稳定的内核走的,不需要再把包丢到用户态中去处理。

在架构实现上有个问题会让使用 envoy 等变得非常尴尬,就是 join 时如果负载均衡没有建立那是会卡住的,kubelet 就不会起来,所以为此你需要先启动 envoy,意味着你又不能用 static pod 去管理它,同上面 keepalived 宿主机部署一样的问题,用 static pod 就会相互依赖,逻辑死锁,鸡说要先有蛋,蛋说要先有鸡,最后谁都没有。

使用 ipvs 就不一样,我可以在 join 之前先把 ipvs 规则建立好,再去 join 就可以了,然后对规则进行守护即可。一旦 apiserver 不可访问了,会自动清理掉所有 node 上对应的 ipvs 规则, 等到 master 恢复正常时添加回来。

4为什么要定制 kubeadm?

首先是由于 kubeadm 把证书过期时间写死了,所以需要定制把它改成 99 年,虽然大部分人可以自己去签个新证书,但是我们还是不想再依赖个别的工具,就直接改源码了。

其次就是做本地负载时修改 kubeadm 代码是最方便的,因为在 join 时我们需要做两个事,第一是 join 之前先创建好 ipvs 规则,第二是创建 static pod。如果这块不去定制 kubeadm 就把报静态 pod 目录已存在的错误,忽略这个错误很不优雅。而且 kubeadm 中已经提供了一些很好用的 sdk 供我们去实现这个功能。

且这样做之后最核心的功能都集成到 kubeadm 中了,sealos 就单单变成分发和执行上层命令的轻量级工具了,增加节点时我们也就可以直接用 kubeadm 了。

使用教程

1安装依赖

  • 安装并启动 docker

  • 下载 kubernetes 离线安装包

  • 下载最新版本 sealos

  • 支持 kubernetes 1.14.0+

2安装

多 master HA 只需执行以下命令:

$ sealos init --master 192.168.0.2 \  --master 192.168.0.3 \  --master 192.168.0.4 \  --node 192.168.0.5 \  --user root \  --passwd your-server-password \  --version v1.14.1 \  --pkg-url /root/kube1.14.1.tar.gz 

然后,就没有然后了。。。没错,你的高可用集群已经装好了,是不是觉得一脸懵逼?就是这么简单快捷!

单 master 多 node:

$ sealos init --master 192.168.0.2 \  --node 192.168.0.5 \   --user root \  --passwd your-server-password \  --version v1.14.1 \  --pkg-url /root/kube1.14.1.tar.gz 

使用免密钥或者密钥对:

$ sealos init --master 172.16.198.83 \  --node 172.16.198.84 \  --pkg-url https://sealyun.oss-cn-beijing.aliyuncs.com/free/kube1.15.0.tar.gz \  --pk /root/kubernetes.pem # this is your ssh private key file \  --version v1.15.0

参数解释:

--master   master服务器地址列表--node     node服务器地址列表--user     服务器ssh用户名--passwd   服务器ssh用户密码--pkg-url  离线包位置,可以放在本地目录,也可以放在一个 http 服务器上,sealos 会 wget 到安装目标机--version  kubernetes 版本--pk       ssh 私钥地址,配置免密钥默认就是 /root/.ssh/id_rsa

其他参数:

--kubeadm-config string   kubeadm-config.yaml kubeadm 配置文件,可自定义 kubeadm 配置文件--vip string              virtual ip (default "10.103.97.2") 本地负载时虚拟 ip,不推荐修改,集群外不可访问

检查安装是否正常:

$ kubectl get nodeNAME                      STATUS   ROLES    AGE     VERSIONizj6cdqfqw4o4o9tc0q44rz   Ready    master   2m25s   v1.14.1izj6cdqfqw4o4o9tc0q44sz   Ready    master   119s    v1.14.1izj6cdqfqw4o4o9tc0q44tz   Ready    master   63s     v1.14.1izj6cdqfqw4o4o9tc0q44uz   Ready       38s     v1.14.1$ kubectl get pod --all-namespacesNAMESPACE     NAME                                              READY   STATUS    RESTARTS   AGEkube-system   calico-kube-controllers-5cbcccc885-9n2p8          1/1     Running   0          3m1skube-system   calico-node-656zn                                 1/1     Running   0          93skube-system   calico-node-bv5hn                                 1/1     Running   0          2m54skube-system   calico-node-f2vmd                                 1/1     Running   0          3m1skube-system   calico-node-tbd5l                                 1/1     Running   0          118skube-system   coredns-fb8b8dccf-8bnkv                           1/1     Running   0          3m1skube-system   coredns-fb8b8dccf-spq7r                           1/1     Running   0          3m1skube-system   etcd-izj6cdqfqw4o4o9tc0q44rz                      1/1     Running   0          2m25skube-system   etcd-izj6cdqfqw4o4o9tc0q44sz                      1/1     Running   0          2m53skube-system   etcd-izj6cdqfqw4o4o9tc0q44tz                      1/1     Running   0          118skube-system   kube-apiserver-izj6cdqfqw4o4o9tc0q44rz            1/1     Running   0          2m15skube-system   kube-apiserver-izj6cdqfqw4o4o9tc0q44sz            1/1     Running   0          2m54skube-system   kube-apiserver-izj6cdqfqw4o4o9tc0q44tz            1/1     Running   1          47skube-system   kube-controller-manager-izj6cdqfqw4o4o9tc0q44rz   1/1     Running   1          2m43skube-system   kube-controller-manager-izj6cdqfqw4o4o9tc0q44sz   1/1     Running   0          2m54skube-system   kube-controller-manager-izj6cdqfqw4o4o9tc0q44tz   1/1     Running   0          63skube-system   kube-proxy-b9b9z                                  1/1     Running   0          2m54skube-system   kube-proxy-nf66n                                  1/1     Running   0          3m1skube-system   kube-proxy-q2bqp                                  1/1     Running   0          118skube-system   kube-proxy-s5g2k                                  1/1     Running   0          93skube-system   kube-scheduler-izj6cdqfqw4o4o9tc0q44rz            1/1     Running   1          2m43skube-system   kube-scheduler-izj6cdqfqw4o4o9tc0q44sz            1/1     Running   0          2m54skube-system   kube-scheduler-izj6cdqfqw4o4o9tc0q44tz            1/1     Running   0          61skube-system   kube-sealyun-lvscare-izj6cdqfqw4o4o9tc0q44uz      1/1     Running   0          86s

3增加节点

先获取 join command,在 master 上执行:

print-join-command

可以使用超级 kubeadm,但是 join 时需要增加一个 --master 参数:

cd kube/shell && init.sh

也可以用 sealos join 命令:

$ sealos join --master 192.168.0.2 \  --master 192.168.0.3 \  --master 192.168.0.4 \  --vip 10.103.97.2 \  --node 192.168.0.5 \  --user root \  --passwd your-server-password \  --pkg-url /root/kube1.15.0.tar.gz

4使用自定义 kubeadm 配置文件

有时你可能需要自定义 kubeadm 的配置文件,比如要在证书里加入域名 sealyun.com

首先需要获取配置文件模板:

$ sealos config -t kubeadm >>  kubeadm-config.yaml.tmpl

然后修改 kubeadm-config.yaml.tmpl 即可,将 sealyun.com 添加到配置中:


注意:其它部分不用修改,sealos 会自动填充模板里面的内容。

最后在部署时使用 --kubeadm-config 指定配置文件模板即可:

$ sealos init --kubeadm-config kubeadm-config.yaml.tmpl \  --master 192.168.0.2 \  --master 192.168.0.3 \  --master 192.168.0.4 \  --node 192.168.0.5 \  --user root \  --passwd your-server-password \  --version v1.14.1 \  --pkg-url /root/kube1.14.1.tar.gz 

5版本升级

本教程以 1.14 版本升级到 1.15 为例,其它版本原理类似,懂了这个其它的参考官方教程即可。

升级过程

  1. 升级 kubeadm,所有节点导入镜像

  2. 升级控制节点

  3. 升级 master(控制节点)上的 kubelet

  4. 升级其它 master(控制节点)

  5. 升级 node

  6. 验证集群状态

升级 kubeadm

把离线包拷贝到所有节点执行 cd kube/shell && sh init.sh。这里会把 kubeadm、kubectl、kubelet 的二进制文件都更新掉,而且会导入高版本镜像。

升级控制节点

$ kubeadm upgrade plan$ kubeadm upgrade apply v1.15.0

重启 kubelet:

$ systemctl restart kubelet

其实 kubelet 升级很简单粗暴,我们只需要把新版本的 kubelet 拷贝到 /usr/bin 下面,重启 kubelet service 即可,如果程序正在使用不让覆盖那么就停一下 kubelet 再进行拷贝,kubelet bin 文件在 conf/bin 目录下。

升级其它控制节点

$ kubeadm upgrade apply

升级 node

驱逐节点(要不要驱逐看情况, 喜欢粗暴的直接来也没啥):

$NODE --ignore-daemonsets

更新 kubelet 配置:

$ kubeadm upgrade node config --kubelet-version v1.15.0

然后升级 kubelet。同样是替换二进制再重启 kubelet service。

$ systemctl restart kubelet

召回失去的爱情:

$NODE

验证

$ kubectl get nodes

如果版本信息都对的话基本就升级成功了。

kubeadm upgrade apply 干了啥?

  1. 检查集群是否可升级

  2. 执行版本升级策略 哪些版本之间可以升级

  3. 确认镜像是否存在

  4. 执行控制组件升级,如果失败就回滚,其实就是 apiserver、controller manager、scheduler 等这些容器

  5. 升级 kube-dns 和 kube-proxy

  6. 创建新的证书文件,备份老的如果其超过 180 天

6源码编译

因为使用了 netlink 库,所以推荐在容器内进行编译,只需一条命令:

$GOPATH/src/github.com/fanux/sealos:/go/src/github.com/fanux/sealos -w /go/src/github.com/fanux/sealos -it golang:1.12.7  go build

如果你使用的是 go mod,则需要指定通过 vendor 编译:

$ go build -mod vendor

7卸载

$ sealos clean \  --master 192.168.0.2 \  --master 192.168.0.3 \  --master 192.168.0.4 \  --node 192.168.0.5 \  --user root \  --passwd your-server-password

sealos 实现原理

1执行流程

  • 通过 sftp或者 wget 把离线安装包拷贝到目标机器上(masters 和 nodes)。

  • 在 master0 上执行 kubeadm init

  • 在其它 master 上执行 kubeadm join 并设置控制面,这个过程会在其它 master 上起动 etcd 并与 master0 的 etcd 组成集群,并启动控制平面的组件(apiserver、controller 等)。

  • join node 节点,会在 node 上配置 ipvs 规则,配置 /etc/hosts 等。

所有对 apiserver 的请求都是通过域名进行访问,因为 node 需要通过虚拟 ip 连接多个 master,每个节点的 kubelet 与 kube-proxy 访问 apiserver 的虚拟地址是不一样的,而 kubeadm 又只能在配置文件中指定一个地址,所以使用一个域名但是每个节点解析的 IP 不同。当 IP 地址发生变化时仅需要修改解析地址即可。

2本地内核负载

通过这样的方式实现每个 node 上通过本地内核负载均衡访问 masters:


在 node 上起了一个 lvscare 的 static pod 去守护这个 ipvs,一旦 apiserver 不可访问了,会自动清理掉所有 node 上对应的 ipvs 规则, master 恢复正常时添加回来。

所以在你的 node 上加了三个东西,可以直观的看到:

# 这下面增加了 lvscare 的 static pod

3定制 kubeadm

sealos 对 kubeadm 改动非常少,主要是延长了证书过期时间和扩展了 join 命令。下面主要讲讲对 join 命令的改造。

首先 join 命令增加 --master 参数用于指定 master 地址列表:

lagSet.StringSliceVar(    &locallb.LVScare.Masters, "master", []string{},    "A list of ha masters, --master 192.168.0.2:6443  --master 192.168.0.2:6443  --master 192.168.0.2:6443",)

这样就可以拿到 master 地址列表去做 ipvs 负载均衡了。

如果不是控制节点且不是单 master,那么就只创建一条 ipvs 规则,控制节点上不需要创建,连自己的 apiserver 即可:

if data.cfg.ControlPlane == 

然后再去创建 lvscare static pod 来守护 ipvs:

if 

所以哪怕你不使用 sealos,也可以直接用定制过的 kubeadm 去部署集群,只是麻烦一些。下面给出安装步骤。

kubeadm 配置文件:


在 master0(假设 vip 地址为 10.103.97.100)上执行以下命令:

echo 

在 master1(假设 vip 地址为 10.103.97.101)上执行以下命令:

echo 

在 master2(假设 vip 地址为 10.103.97.102)上执行以下命令:

echo 

在 node 上 join 时加上 --master 参数指定 master 地址列表:

echo 

4离线包结构分析


  • init.sh 脚本会将 bin 目录下的二进制文件拷贝到 $PATH 下面,并配置好 systemd,关闭 swap 和防火墙等等,然后导入集群所需要的镜像。

  • master.sh 主要执行了 kubeadm init。

  • conf 目录下面包含了 kubeadm 的配置文件,calico yaml 文件等等。

  • sealos 会调用上面的两个脚本,所以大部分兼容。不同版本都可以通过微调脚本来保持兼容。

==留言赠书==

本次联合【机械工业出版社华章公司】为大家带来 3 本非常适合云原生工程师阅读的《Kubernetes 进阶实战》

规则:比较简单,大家可以留言说说想要这本书的原因,或者你对 Kubernetes 的理解最为真诚留言的前 3 名获得此书。时间截止至 8.27 (明天下午)18:00 为止。大家快快留言吧,每个人都有机会的!

大家如果不想参与也可以直接通过下面的链接前往购买:

内容简介

本书涵盖 Kubernetes 架构、部署、核心资源类型、系统扩缩容、存储卷、网络插件与网络策略、安全(认证、授权与准入控制等)、自定义资源、监控与日志系统等话题,大量实操案例,随时动手验证。概括来说,本书内容从逻辑上分为5部分。

第一部分详细讲解 Kubernetes 系统基础架构及核心概念,并提供快速部署和应用入门指南。第二部分深度剖析 Kubernetes 系统核心组件与应用,帮助读者解决日常业务应用问题。第三部分介绍存储卷及 StatefulSet 控制器。第四部分介绍安全相关的的话题,为容器应用提供配置信息与敏感信息的方式,动态扩缩容与更新机制等。第五部分介绍 Kubernetes 系统调度策略、自定义资源类型和自定义资源、监控系统等高级话题。

作者简介马哥(马永亮),北京马哥教育科技有限公司创始人兼 CEO,泛 Linux 运维技术及云计算技术培训先驱者和引领者,10 年间累计直接培养业内 Linux 运维从业人员近万人,录制的相关领域的系列视频播放量500万人次以上。熟悉泛 Linux 云计算、高并发架构、运维自动化、DevOps 和容器及容器编排等领域相关技术应用。如果大家想购买其他云计算领域相关书籍,可以点击该链接查看优惠策略。

你可能错过的精彩内容(每日更新)

⊙高颜值 K8S Dashboard - K8Dash

⊙使用 Docker 和 Jenkins 持续交付(新书免费获取!)

⊙这些用来审计 Kubernetes RBAC 策略的方法你都见过吗?

⊙kustomize 颤抖吧helm!

云原生是一种信仰 

ansible 建 kubernetes 证书签名请求_最简单的 kubernetes 高可用安装方式!(文末送书)...相关推荐

  1. ansible 建 kubernetes 证书签名请求_基于优先级规则、数字证书和信任管理的车联网安全模型...

    1. 背景 1.1 IoV带来的好处 邻近车辆可以通过共享位置,来避免发生车祸; 车辆可以分享位置以及目的地,通过最优化算法,来避免对某条道路得过度使用,协调缓解交通拥堵; 电动汽车可以在电动汽车充电 ...

  2. ansible 建 kubernetes 证书签名请求_基于Kubernetes的云平台存储容器化实践

    本文根据蔡逸煌老师在[Deeplus直播第214期]线上分享演讲内容整理而成.(文末有获取本期PPT&回放的途径,不要错过) 蔡逸煌 OPPO云平台高级后端工程师 主要从事云平台开发工作,擅长 ...

  3. 夺命连环问:一个 TCP 连接可以发多少个 HTTP 请求?|文末送书

    时间有限,快来薅,当当的羊毛!!! 时间有限,快来薅,当当的羊毛!!! 时间有限,快来薅,当当的羊毛!!! 作者:松若章 来源:http://c7.gg/f8txF 曾经有这么一道面试题:从 URL ...

  4. ansible 建 kubernetes 证书签名请求_Java中的微信支付(2):API V3 微信平台证书的获取与刷新...

    1. 前言 在Java 中的微信支付(1):API V3 版本签名详解一文中胖哥讲解了微信支付 V3 版本 API 的签名,当我方(你自己的服务器)请求微信支付服务器时需要根据我方的API 证书对参数 ...

  5. 数据库身份证号用什么类型_【文末送书】MySQL数据库?看这一篇干货文章就够了!...

    前言 为啥学习MySQL呢?因为MySQL是最流行的关系型数据库管理系统之一,在web应用方面,MySQL是最好的软件.MySQL所使用的sql语言是用于访问数据库的最常用标准化语言. 放心,读这期内 ...

  6. 聚类技术---复杂网络社团检测_自然场景中交通标志牌检测~文末送书

    导读:近年来,交通标志牌检测技术已经成为智能驾驶公交车辆视觉导航系统和计算机视觉领域的热点之一. 本文为6月份刚出版的新书<智能驾驶技术:路径规划与导航控制>节选,探讨基于视觉协同显著性的 ...

  7. websockert后台定时向前端发送状态_(文末送书)手把手教你打造属于自己团队的前端小报系统...

    本文首发于政采云前端团队博客:手把手教你打造属于自己团队的前端小报系统 https://www.zoo.team/article/building-a-tabloid-system 前言 经常关注我们 ...

  8. python 活体检测_基于Python+Keras+OpenCV实现实时人脸活体检测 | 文末送书

    你在互联网上找到的大多数人脸识别算法和研究论文都会遭受照片***.这些方法在检测和识别来自网络摄像头的图像.视频和视频流中的人脸方面是很是有效,可是他们没法区分现实生活中的面孔和照片上的面孔.这种没法 ...

  9. mysql 统计 打卡数据_根据考勤机数据,有重复打卡,统计上班天数的简单办法(文末送书)...

    点击上方蓝字「Excel不加班」关注,看下一篇 恭喜下面3位粉丝:天道酬勤.hannah.月光,获得书籍,加卢子微信chenxilu2019,发送姓名电话地址. 为了活跃气氛,在文末点亮"在 ...

最新文章

  1. 2016 linux发行版排行_灵越7590 安装 linux (manjaro-gnome)
  2. 这几个juniper巡检命令超实用
  3. python中写入文件数据及文件定位操作命令
  4. sqoop导入hive时间格式问题解决方案
  5. ipsec *** 的总结性谈论
  6. 如何估算代码量_千万级用户的大型网站,应该如何设计其高并发架构?(彩蛋)...
  7. osquery的认识
  8. 斐波那契 (Fibonacci)数列
  9. 计算机一级专题训练,计算机等级考试一级MSOFFICE综合训练试题
  10. 微软私有云解决方案_毕马威 AI 工厂携手微软云技术 | 共创人工智能发展,共建创新解决方案...
  11. VMware共享文件夹Input/output error解决办法
  12. 文本处理三剑客之gawk
  13. C#之CAD二次开发笔记(1) 开发环境测试
  14. VBS中实现99乘法表的输出
  15. 服务器p盘cpu占用率低,硬盘问题导致的CPU占用率100%解决实例
  16. 嵌入式方向如何转行?
  17. windows下批处理文件的编写
  18. 拓新药业301089
  19. 医疗行业大数据应用的三个案例
  20. Neural Collaborative Filtering复现

热门文章

  1. python IndentationError: unexpected indent
  2. Tomcat源码笔记(八)Context
  3. [转帖]GNU/Linux与开源文化的那些人和事
  4. 谁才是真正的Vlog拍摄“神器”?橙影智能摄像机vs大疆Osmo Pocket
  5. 嵌入式UI开发必备组件——Qt系列全新升级,更多新功能等你来体验
  6. 互联网反垄断的蝴蝶效应:“巨头买下整个赛道”一去不复返
  7. mac下git设置用户名密码
  8. 常见加密方法(持续更新)
  9. select下拉框二级联动
  10. php addslashes没用_php中使用addslashes函数报错问题的解决方法