KubeEdge详解

注意:

KubeEdge 是一个开源的系统,可将本机容器化应用编排和管理扩展到边缘端设备。 它构建在Kubernetes之上,为网络和应用程序提供核心基础架构支持,并在云端和边缘端部署应用,同步元数据。兼容K8S API,可以使用K8S API原语管理边缘和设备。KubeEdge 还支持 MQTT 协议,允许开发人员编写客户逻辑,并在边缘端启用设备通信的资源约束。

kubectl 指定配置文件_kubelet配置文件kubectl 指定配置文件_kubelet配置文件


kubectl 指定配置文件_kubelet配置文件


/opt/heketi/bin/heketi-cli --user admin --server --secret adminkey --json node add --cluster "bb1362c3360d80419c822b9994381608" --mament-host-name node145 --storage-host-name 10.14.151.145 --zone 1

kubernetes + 容器的组合大大提高了用户创建部署应用的效率。kubernetes 可以把 n 台主机整合成一个集群,用户在 上通过编写一个 yaml 或者 json 格式的配置文件,也可以通过命令等请求 Kubernetes API 创建应用,就直接将应用部署到集群上的各个上,该配置文件中还包含了用户想要应用程序保持的状态,从而生成用户想要的环境。

Kubernetes 作为容器编排的标准,自然会想把它应用到边缘计算上,即通过 kubernetes 在边缘侧部署应用,但是 kubernetes 在边缘侧部署应用时遇到了一些问题,例如:

为了解决包含但不限于以上 Kubernetes 在物联网边缘场景下的问题,从而产生了KubeEdge 。对应以上问题:

KubeConShanghai2018——KubeEdge开源首秀

KubeEdge 向左,K3S 向右

KubeEdge实现原理

KubeEdge 由以下组件构成:

如何配置通信协议

初始化命令说明

安装Pod网络插件(CNI)

在完成 Kubernetes 的初始化后, 我们需要暴露 Kubernetes apiserver 的 端口8080用于与 cloudcore/kubectl 交互。请按照以下步骤在 Kubernetes apiserver 中启用 端口。这样可以在边缘执行 kubectl get nodes -s 192.169.0.10:8080 等命令,就像在 上一样。

KubeEdge 的边缘部分在 devTwin 和设备之间使用 MQTT 进行通信。KubeEdge 支持3个 MQTT 模式:

可以使用 kubeedge/edge/conf/edge.yaml 中的 mode 字段去配置期望的模式。

使用 KubeEdge 的 mqtt 内部或外部模式,您都需要确保在边缘上安装 mosquitto 或 emqx edge 作为 MQTT Broker。

KubeEdge 在云和边缘之间基于证书进行身份验证/授权。证书可以使用 openssl 生成。请按照以下步骤生成证书。

证书和密钥会分别自动生成在 /etc/kubeedge/ca 和 /etc/kubeedge/certs 目录下。

我们提供了一个示例 node.json 来在 Kubernetes 中添加一个。

请确保在 Kubernetes 中添加了边缘 edge-node。运行以下步骤以添加边缘 edge-node。

在 Cloud 和 Edge 被启动之后,通过如下的命令去检查边缘的状态。

请确保您创建的边缘状态是 ready 。

像使用普通k8s一样部署你的应用到edge

示例:

提示: 目前对于边缘端,必须在 Pod 配置中使用 hostPort,不然 Pod 会一直处于 ContainerCreating 状态。 hostPort 必须等于 containerPort 而且不能为 0。

然后可以使用下面的命令检查应用程序是否正常运行。

K8S 使用 Deployment 运行一个无状态应用:Nginx

你必须拥有一个 Kubernetes 的集群,同时你的 Kubernetes 集群必须带有 kubectl 命令行工具。

如果你还没有集群,参考 用 kubeadm 在 Debian 或 Ubuntu 中创建 k8s 集群 。

你可以通过创建一个 Kubernetes Deployment 对象来运行一个应用,且你使用 yaml 格式的文件创建一个 Deployment 的配置文件。例如, 下面是一个运行 nginx:1.14.2 Docker 镜像的 Deployment 的配置文件:

deployment.yaml

使用 yaml 文件创建一个 Deployment:

显示Scheduler : 调度器,负责Pod在集群中的调度分配。 Deployment 相关信息:

输出:

列出 Deployment 创建的 Pods:

输出:

显示某一个 Pod 信息:

这里的

是某一 Pod 的名称。mkdir /glusterfs/storage1/rep_vol1

你可以通过更新一个新的 YAML 文件来更新 Deployment。下面的 YAML 文件指定该 Deployment 镜像更新为 nginx 1.16.1。

应用新的 YAML:

查看该 Deployment 以新的名称创建 Pods 同时删除旧的 Pods:

你可以通过应用新的 YAML 文件来增加 Deployment 中 Pods 的数量。 下面的 YAML 文件将 replicas 设置为 4,指定该 Deployment 应有 4 个 Pods:

deployment-scale.yaml

应用新的 YAML 文件:

验证 Deployment 有 4 个 Pods:

输出:

通过名称删除 Deployment:

Kubernetes--应用滚动升级

Pod保活的重要手段。

滚动升级(rolling update)是每一次只更新一小部分的副本,成功后再继续更新更多的副本,最终把所有副本更新。

好处:不用停机,实现平滑的升级。

如下图所示(网上找的),

2.执行部署并查看

注意当前d的版本为:2.2.31 ,下面开始升级

更新完成后,d的镜像变为了d:2.2.32了。

从Message中可以看出,两个Replica Set是逐步更新Pod的,

d-9658687dd是最开始的,有3个Pod,d-76c8bd9f65是新生成,有0个Pod,依次

d-76c8bd9f65 up 为1,d-9658687dd down 为2

d-76c8bd9f65 up 为2,d-9658687dd down 为1

d-76c8bd9f65 up 为3,d-9658687dd down 为0

当然,滚动升级每次更新的Pod数量是可以指定的,通过两个参数 maxSurge 和 maxUnailable 控制。

kubectl apply在每次更新应用的时候,都会记录下当前的配置,保存为一个版本revision,默认情况kubernetes只会保留最近的几个revision,但可以在Deployment的配置文件中指定保存的revision的数量,通过 revisionHistoryLimit 属性设置。

将上面的d.yaml文件三份,分别命名为d1.yaml,d2.yaml,d3.yaml,对应镜像修改为d:2.4.16,d:2.4.17,d:2.4.18.

由上面信息可知,这一次版本从2.4.16升级到2.4.17再升级到2.4.18,总共有三次作,而且这一次执行kubectl apply时候加上了 --record .

查看历史版deployment-update.yaml本

这里的CHANGE_CAUSE就是加上了--record的结果。REVISION就是版本,如果想回退到revision=1,可以执行命令:

kubectl rollout undo deployment d --to-revision=1

如果是想回退到上一个版本,则可以不用指定--to-revision

2021-10-这一篇 K8S(Kubernetes)我觉得可以了解一下!!!28

可以看到该版本被标记为stable,而且STATUS为healthy。还可以在命令后面加一个--watch来实时服务状态,完整命令为kubectl argo rollouts get rollout rollouts-demo --watch。

Kubernetes 是Google开源的分布式容器管理平台,是为了更方便的在中管理我们的容器化应用。

servs.yaml

Kubernetes 简称 K8S,为什么会有这个称号?因为K和S是 Kubernetes 首字母和尾字母,而K和S中间有八个字母,所以简称 K8S,加上 Kubernetes 比较绕口,所以一般使用简称 K8S。

Kubernetes 即是一款容器编排工具,也是一个全新的基于容器技术的分布式架构方案,在基于Docker的基础上,可以提供从 创建应用>应用部署>提供服务>动态伸缩>应用更新 一系列服务,提高了容器集群管理的便捷性。

大家可以先看一下,下面一张图,里面有我们的 mysql,redis,tomcat,nginx 等配置信息,如果我们想要安装里面的数据,我们需要一个一个手动安装,好像也可以,反正也就一个,虽然麻烦了一点,但也不耽误。

但是随着技术的发展和业务的需要,单台已经不能满足我们日常的需要了,越来越多的公司,更多需要的是集群环境和多容器部署,那么如果还是一个一个去部署,运维恐怕要疯掉了,一天啥也不干就去部署机器了,有时候,可能因为某一个环节出错,要重新,那真的是吐血。。。。。,如下图所示:

如果我想要部署,以下几台机器:

如果要一个一个去部署,人都要傻掉了,这什么时候是个头,如果是某里巴的两万台机器,是不是要当场提交辞职信,所以 K8S 就是帮助我们来做这些事情的,方便我们对容器的管理和应用的自动化部署,减少重复劳动,并且能够自动化部署应用和故障自愈。

并且如果 K8S 对于微服务有很好的支持,并且一个微服务的副本可以跟着系统的负荷变化进行调整,K8S 内在的服务弹性扩容机制也能够很好的应对突发流量。

Docker-Come 是用来管理容器的,类似用户容器管家,我们有N多台容器或者应用需要启动的时候,如果手动去作,是非常耗费时间的,如果有了 Docker-Come 只需要一个配置文件就可以帮我们搞定,但是 Docker-Come 只能管理当前主机上的 Docker,不能去管理其他上的服务。意思就是单机环境。

Docker Swarm 是由Docker 公司研发的一款用来管理集群上的Docker容器工具,弥补了 Docker-Come 单的缺陷, Docker Swarm 可以帮助我们启动容器,容器的状态,如果容器服务挂掉会重新启动一个新的容器,保证正常的对外提供服务,也支持服务之间的负载均衡。而且这些东西 Docker-Come 是不支持的,

Kubernetes 它本身的角色定位是和 Docker Swarm 是一样的,也就是说他们负责的工作在容器领域来说是相同的部分,当然也要一些不一样的特点, Kubernetes 是谷歌自己的产品,经过大量的实践和宿主机的实验,非常的成熟,所以 Kubernetes 正在成为容器编排领域的,其 可配置性、可靠性和社区的广大支持,从而超越了 Docker Swarm ,作为谷歌的开源项目,它和整个谷歌的云平台协调工作。

在下图中,是K8S的一个集群,在这个集群中包含三台宿主机,这里的每一个方块都是我们的物理虚拟机,通过这三个物理机,我们形成了一个完整的集群,从角色划分,可以分为两种

打一个比较形象的比喻,我们可以把Pod理解成一个豆荚,容器就是里面的豆子,是一个共生体。

Pod里面到底装的是什么?

具体怎么部署Pod里面的容器,是按照我们项目的特性和资源的分配进行合理选择的。

pause容器:

Pause容器 全称infrastucture container(又叫infra)基础容器,作为init pod存在,其他pod都会从pause 容器中fork出来,这个容器对于Pod来说是必备的

一个Pod中的应用容器共享同一个资源:

在上图中如果没有 pause容器 ,我们的Nginx和Ghost,Pod内的容器想要彼此通信的话,都需要使用自己的IP地址和端口,才可以彼此进行访问,如果有 pause容器 ,对于整个Pod来说,我们可以看做一个整体,也就是我们的Nginx和Ghost直接使用localhost就可以进行访问了,他们不同的就只是端口,这里面可能看着觉得比较简单,但其实是使用了很多网络底层的东西才实现的,感兴趣的小伙伴可以自行了解一下。

在 Kubernetes 中,每个Pod都会被分配一个单独的IP地址,但是Pod和Pod之间,是无法直接进行交互的,如果想要进行网络通信,必须要通过另外一个组件才能交流,也就是我们的 Serv

Serv 是服务的意思,在K8S中 Serv 主要工作就是将多个不同主机上的Pod,通过 Serv 进行连通,让Pod和Pod之间可以正常的通信

我们可以把 Serv 看做一个域名,而相同服务的Pod集群就是不同的ip地址, Serv 是通过 Label Selector 来进行定义的。

使用NodePort提供外部访问,只需要在每个Node上打开一个主机的真实端口,这样就可以通过Node的客户端访问到内部的Serv。

Label 一般以 kv的方式附件在各种对象上,Label 是一个说明性的标签,它有着很重要的作用,我们在部署容器的时候,在哪些Pod进行作,都需要根据Label进行查找和筛选,我们可以理解Label是每一个Pod的别名,只有取了名称,作为K8S的Master主才能找到对应的Pod进行作。

用户通过 Kubectl 提交一个创建 Replication Controller 请求,这个请求通过 API 写入 etcd 中,这个时候 Controller Mar 通过 API 的到了创建的命名,经过它认真仔细的分析以后,发现当前集群里面居然还没有对应的Pod实例,赶紧根据 Replication Controller 模板定义造一个Pod对象,再通 过Api 写到我们 etcd 里面

到下面,如果被 Scheduler 发现了,好家伙不告诉我???,无业游民,这家伙一看就不是一个好人啊,它就会立即运行一个复杂的调度流程,为这个新的Pod选一个可以落户的Node,总算有个身份了,真是让人心,然后通过 API 将这个结果也写到etcd中,随后,我们的 Node 上运行的小管家 Kubelet 进程通过 API 检测到这个 新生的小宝宝——“Pod”,就会按照它,就会按照这个小宝宝的特性,启动这个Pod并任劳任怨的负责它的下半生,直到Pod的生命结束。

然后我们通过 Kubectl 提交一个新的映射到这个Pod的Serv的创建请求, Controller Mar 会通过Label标签查询到相关联的Pod实例,生成Serv的Endpoints的信息,并通过 API 写入到etcd中,接下来,所有 Node 上运行的Proxy进程通过 Api 查询并 Serv对象 与其对应的 Endpoints 信息,建立一个软件方式的负载均衡器来实现 Serv 访问到后端Pod的流量转发功能。

kube-proxy: 是一个,充当这多主机通信的人,前面我们讲过Serv实现了跨主机、跨容器之间的网络通信,在技术上就是通过 kube-proxy 来实现的,serv是在逻辑上对Pod进行了分组,底层是通过 kube-proxy 进行通信的

kubelet: 用于执行K8S的命令,也是K8S的核心命令,用于执行K8S的相关指令,负责当前Node上的Pod的创建、修改、、删除等生命周期管理,同时Kubelet定时“上报”本Node的状态信息到API 里

etcd: 用于持久化存储集群中所有的资源对象,API 提供了作 etcd的封装接口API,这些API基本上都是对资源对象的作和资源变化的接口

API : 提供资源对象的作入口,其他组件都需要通过它提供作的API来作资源数据,通过对相关的资源数据“全量查询”+ “变化”,可以实时的完成相关的业务功能。

Controller Mar: 集群内部管理控制中心,主要是实现 Kubernetes 集群的故障检测和恢复的自动化工作。比如Pod的和移除,Endpoints对象的创建和更新,Node的发现、管理和状态等等都是由 Controller Mar 完成。

到这里K8S的基本情况我们就讲解完毕了,有喜欢的小伙伴记得 点赞关注 ,相比如Docker来说K8S有着更成熟的功能,经过谷歌大量实践的产物,是一个比较成熟和完善的系统。

关于K8S大家有什么想要了解或者疑问的地方欢迎大家留言告诉我。

我是牧小农,一个卑微的打工人,如果觉得文中的内容对你有帮助,记得一键三连,你们的三连是小农的动力。

k8s The connection to the server was refused 问题解决记录

yum -y install flex bison openssl openssl-dl libxml2-dl gcc lrzsz vim

最近公司的 k8s 集群出现了一个问题:在执行任何 kubectl 命令时都会出现以下错误,本文就记录一下该问题的溯源过程以及解决方式,希望对大家有帮助:

首先revision为1的版本标记没有,重新创建了一个为5的标记,而且步处于暂停状态,然后我们执行promote命令继续后续的更新,如下:

相信很多朋友都遇到过这个问题, 6443 是 k8s API 的默认端口,出现访问被拒绝肯定是 kubelet 有问题或者被防火墙拦截了,这里先看一下这个端口上的 kubelet 是不是还或者:

运行之后什么都没有返回,也就是说 API 完全没有提供服务 ,那我们就去查看一下 kubelet 的日志,大家都知道使用 kubeadm 搭建的 k8s集群里,API 都是在 docker 里运行的,这里我们先找到对应的容器,记得加 -a ,因为该容器可能已经处于非正常状态了:

这里能看到两个容器,可以看到 容器的状态已经是 Exited 了 ,注意下面的 pause 容器,这个只是用来 API 的,并不是服务的实际运行容器,所以看不到日志,所以查看日志时不要输错容器 id 了。接下来查看 API 的日志:

从一行可以看到,是 API 在尝试创建存储时出现了问题,导致无确启动服务,由于 k8s 是使用 etcd 作为存储的,所以我们再来查看 etcd 的日志。

注意,我这里 etcd 也是运行在 docker 里的,如果你是直接以 serv 的形式运行的话需要使用 ctl status etcd 来查看日志,下面是 docker 的 etcd 日志查看:

可以看到 etcd 一直在循环输出上面的错误日志直到超时退出,从里面可以提取到一条关键错误,就是 error "tls: failed to verify client's certificate: x509: certificate has expired or is not yet valid 。这个错误对于经常维护 k8s 集群的朋友可能很熟悉了,又是证书到期了。

这个集群有三台 ,分别是 171 、 181 和 1 ,可以从错误信息前看到是在请求 181 时出现了证书验证失败的问题,我们登陆 181 机器来验证错误:

经过排查,发现 k8s 的相关证书都没事,但是 etcd 的证书都到期了。关于 k8s 需要的证书可以看这篇文章,接下来我们就来解决问题:

Kubeadm安装的K8S集群1年证书过期问题的解决思路

注意,由于 k8s 版本问题,这一部分的内容可能和你的不太一样,我所使用的版本如下:

如果版本相过大的话请进行百度,相关的解决方案还是挺多的,下面解决方案请先配合 -h 使用, 注意:以下作会导致服务停止,请谨慎执行 :

重新生成证书

重新生成证书需要集群初始化时的配置文件,我的配置文件 kubeadm.yaml 如下:

其中 192.168.100.170 是 VIP, 171 、 181 、 1 分别对应 1 、 2 、 3 主机。接下来使用配置文件重新签发证书,每个管理都要执行:

重新生成配置文件

这个命令也需要每个管理都执行一次,被重新生成的配置文件包括下列几个:

重启管理的 k8s

重启 etcd,apiserver,controller-mar,scheduler 容器,一般情况下 kubectl 都可以正常使用了,记得 kubectl get nodes 查看的状态。

重新生成工作的配置文件

如果上一步查看的工作的状态还是为 NotReady 的话,就需要重新进行生成,如果你根证书也更换了的话就会导致这个问题,工作的证书也会失效,直接备份并移除下面的证书并重启 kubelet 即可:

如果不行的话就直接把管理的 /etc/kubernetes/pki/ca.crt 到对应工作的相同目录下然后再次启动 kubelet。等待三分钟左右应该就可以在管理上看到该工作的状态变为 Ready 。

k8s 的证书只有一年的设置确定有点坑,虽然为了让使用者更新到版本的本意是好的。如果你现在 k8s 集群还是正常但是并没有执行过证书更新作的话,请及时查看你的证书到期时间,等到证书到期就为时已晚了。

第二章 使用Kubernetes快速创建个应用

安装二进制包

1. 内容

2. 创建、运行及共享容器镜像

介绍

深入学习前,先看看如何创建一个简单的应用、打包成容器镜像、在远程集群或本地集群运行

步骤

安装并运向镜像仓库推送镜像行Docker

创建一个简单的php应用

为镜像创建Dockerfile

构建容器镜像

运行容器镜像

探索 运行容器的内部

停止和删除容器

3. 配置Kubernetes集群

用Minikube运行一个本地单Kubernetes集群

为kubectl配置别名和命令行补齐

4. 在Kubernetes上运行个应用

介绍

正常来说,部署一个Kubernetes程序需要包含部署的所有组件描述的配置文件,因为次使用,所以用最简单的方法运行Kubernetes程序

部署php应用

访问web应用

系统的逻辑部分

水平伸缩应用

查看应用运行在哪个上

5. 小结

超赞!使用 argo-rollouts 实现kubernetes上的金丝雀、蓝绿发布

Kubernetes中使用GlusterFS作为持久化存储,要提供storageClass使用需要依赖Heketi工具。Heketi是一个具有resetful接口的glusterfs管理程序,作为kubernetes的Storage存储的external provisioner。 “Heketi提供了一个RESTful管理界面,可用于管理GlusterFS卷的生命周期。借助Heketi,像OpenStack Manila,Kubernetes和OpenShift这样的云服务可以动态地配置GlusterFS卷和任何支持的持久性类型。Heketi将自动确定整个集群的brick位置,确保将brick及其副本放置在不同的故障域中。Heketi还支持任意数量的GlusterFS集群,允许云服务提供网络文件存储,而不受限于单个GlusterFS集群。

Argo-Rollout是一个Kubernetes Controller和对应一系列的CRD,提供更强大的Deployment能力。包括灰度发布、蓝绿部署、更新测试(experimentation)、渐进式交付(progressive delivery)等特性。

支持特性如下:

Argo原理和Deployment不多,只是加强rollout的策略和流量控制。当spec.template发送变化时,Argo-Rollout就会根据spec.strategy进行rollout,通常会产生一个新的ReplicaSet,逐步scale down之前的ReplicaSet的pod数量。

按文档进行安装,地址为:

(1)在Kubernetes集群中安装argo-rollouts

(2)安装argo-rollouts的kubectl plugin

金丝雀发布包含Replica Shifting和Traffic Shifting两个过程。

这里使用的demo来进行测试。例子:

使用如下命令部署示例:

我们先看看个rollout.yaml的具体内容,如下:

可以看到除了apiVersion,kind以及strategy之外,其他和Deployment无异。

strategy字段定义的是发布策略,其中:

而serv.yaml文件定义的就是普通的serv,如下:

执行上面命令部署后,会在default命名空间下创建5个pod,如下:

可以使用kubectl-argo-rollouts get rollout rollouts-demo命令来查看部署状态,如下:

接下来对应用进行更新。对应用进行更新和更新用Deployment部署的应用一样,更新镜像即可。argo rollouts插件有一个set image命令来更新镜像,如下:

更新过后,我们可以通过观察kubectl argo rollouts get rollout rollouts-demo --watch服务状态,如下:

可以看到多了一个revision:2,而且该版本被标记为canary,而且状态是Status: Paused,canary接入流量为20%。

部署之所以处于Paused阶段,是因为我们在rollout.yaml中定义了发布个版本后会暂停,这时候需要手动接入接下来的更新。

argo rollouts提供了promote来进行后续的更新,命令如下:

然后我们可以在watch界面,看到如下的更新过程。

因为后续的更新在pause阶段只暂停10s,所以会依次自动更新完,不需要手动介入,待更新完后整体的状态如下:

可以看到个版本已经下线,第二个版本的状态为Healthy,而且镜像被标记为stable。

如果在更新应用的过程中,的应用有问题,需要终止更新需要怎么做呢?

然后更新动作会在次更新的时候处于Paused状态,现在我们可以用abort来终止发布,如下:

待执行完命令后,可以在watch页面,看到如下信息:

最终应用会回退到稳定版本。

但是我们可以看到Status是Degraded状态而并非Healthy状态,我们有必须要将其变成Healthy状态。最简单的办法就是执行如下命令重新发布一下版本:

执行过后,可以看到其状态立即变成Healthy,并且没有创建新的副本、新的版本,如下:

有时候在应用上线过后,有些BUG并没有发现,这时候要回退怎么办呢?argo rollouts有一个undo命令,可以进行回退。

比如我们要将版本回退到个版本,则执行一下命令:

然后通过watch界面可以看到如下信息:

然后我们可以看到如下信息:

从Images可以看到回退到我们最初版本为blue的镜像了。

上面我们并没有接入外部流量,仅仅是在内部使用展示了金丝雀部署过程,下面我们接入外部流量进行测试。

Argo-Rollout主要集成了 Ingress 和 ServMesh 两种流量控制方法。

目前Ingress支持ALB和NGINX ingress。但是我使用的是nginx ingress。

我们依然使用的例子进行展示。

首先删除上面的例子。

然后重新部署一个的例子,如下:

这个例子包含1个rollout,2个serv,1个ingress。

它们的配置文件分别如下。

rollout.yaml,为了便于测试,我将权重改为了50

ingress.yaml

从配置文件可以看出Rollout里分别用canaryServ和stableServ分别定义了该应用灰度的Serv Name(rollouts-demo-canary)和当前版本的Serv Name(rollouts-demo-stable)。而且rollouts-demo-canary 和 rollouts-demo-stable的serv的内容是一样的。selector中暂时没有填上pod-template-hash,Argo-Rollout Controller会根据实际的ReplicaSet hash来修改该值。

当我们创建完ingress后,Rollout Controller会根据ingress rollouts-demo-stable内容,自动创建一个ingress用了灰度的流量,名字为--canary,所以这里多了一个ingress rollouts-demo-rollouts-demo-stable-canary,将流量导向Canary Serv(rollouts-demo-canary)。如下:

rollouts-demo-rollouts-demo-stable-canary的内容如下:

通过域名访问,可以看到如下界面。

现在通过以下命令来进行应用更新作。

然后通过状态窗口可以看到如下信息。

然后可以看到rollouts-demo-rollouts-demo-stable-canary的ingress的annotations中新增了两个参数,如下:

然后通过网页,可以看到如下的输出展示。

image.png

然后可以通过验证结果来判断是否继续还是终止。

如果继续使用如下命令:

如果终止使用如下命令:

目前我还kubernetes storageclass 配置在测试阶段,并没有实际接入使用。通过测试来看,Argo-Rollout提供更加强大的Deployment,包含比较适合运维的金丝雀发布和蓝绿发布功能,要使用蓝绿发布,仅需要配置rollout,如下:

整体使用还是比较丝滑,如果测试通过后续考虑集成进CD中。更多内容可以到s://

kubernetes-8:kibana容器化

--name:指定本次部署的名字,通过helm list可以查看通过helm部署的组件;

受限大小限制,有些不是很清晰,可以到微信公众号查看;

cp heketi/{heketi,heketi-cli} /opt/heketi/bin/

前置阅读:

kubernetes-7:elasticsearch容器化

提供helm和yaml两种部署方式。

Helm部署步骤详见笔者git地址:

yaml部署步骤详见笔者git地址:

1.progressDeadlineSeconds

2.pod滚动升级

3.readinessProbe

4.restartPolicy

容器化成功后的组件:

docker pull kibana:6.4.3

重命名镜像为:

docker images |grep kibana |awk '{print "docker tag ",$1":"$2,$1":"$2}' |sed -e 's#kibana#' |sh -x

Add the elastic helm charts repo:

helm repo add elastic

helm容器化Kibana的命令:

helm install --name es-min-kibana elastic/kibana --namespace es-min-kibana --version 6.4.3 --set elasticsearchHosts=

helm参数详解:

elastic/kibana:指定chart的名字,helm执行过程是先取到chart配置,从chart配置中取到资源的URL;

--namespace:指定kibana部署到容器中所归属的命名空间;

--version:指定kibana版本;

--set:指定Kibana的详细参数;

elasticsearchHosts与elasticsearchUrl:指定kibana要关联的elasticsearch集群的地址;es-min-ingest是容器内部es的serv域名,es.min是指的es集群的命名空间,因为这里涉及到了跨命名空间访问,所以需要带namespace的后缀;

笔者github提供elasticsearch的yaml配置文件:

提供了一个deploy.sh,可以直接运行sh deploy.sh完成容器化;

或者依次执行命令:

kubectl apply -f kibana-min-deployment.yaml

kubectl apply -f kibana-min-serv.yaml

笔者的yaml配置文件中做了详细注释,可以直接进入github去阅读相关yaml配置文件,这里只罗列其中的重点:

1.progressDeadlineSeconds

Deployment失败判定标准,由于elasticsearch相关服务的启动/就绪都挺慢,特别当elasticsearch集群和kibana同时容器的时候,所以需要设置此判定参数。

2.pod滚动升级

支持两种滚动方式:按照比例启动;也可以指定具体个数。

3.readinessProbe

pod就绪判定标准, 很有必要;当es集群负荷过高时,kibana与es的联通会不通畅,需要K8S去识别是kibana pod是不是真的宕机了。

4.restartPolicy

Kubernetes 基于GlusterFS+heketi的高可用动态存储管理StorageClass

备份原始文件

heketi:提供基于RESTful接口管理glusterfs的功能,可以方便的创建集群管理glusterfs的node,dev,volume;与k8s结合可以创建动态的PV,扩展glusterfs存储的动态管理功能。主要用来管理glusterFS volume的生命周期,初始化时候就要分配好磁盘(未格式化)设备.

注意事项:

安装Glusterfs客户端:每个kubernetes集群的需要安装gulsterfs的客户端,如glusterfs-cli,glusterfs-fuse.主要用于在每个node挂载volume。

加载内核模块:每个kubernetes集群的运行modprobe dm_thin_pool,加载内核模块。

高可用(至少三个):至少需要用来部署glusterfs集群,并且这3个每个需要至少一个空余的磁盘。

基础设施要求:

正在运行的glusterfs集群,至少有三个node,每个至少有一个可用的块设备(如EBS卷或本地磁盘,就是没有格式化的).

用于运行GlusterFS必须为GlusterFS通信打开相应的端口(如果开启了防火墙的情况下,没开防火墙就不需要这些作)。

安装依赖及常用工具包:

查找gluster的软件仓库:

yum search centos-release-gluster

安装版本的gluster软件仓库:

yum install centos-release-gluster7.noarch -y

安装gluster源,并安装glusterfs及相关软件包

yum install glusterfs glusterfs-server glusterfs-cli glusterfs-geo-replication glusterfs-rdma -y

客户端安装GlusterFS客户端软件

yum install glusterfs-fuse glusterfs-cli

启动Glusterd服务

ctl start glusterd

ctl enable glusterd --now //设开机自启,并立即启动服务

在任意一个上添加信任

gluster peer probe node99

gluster peer probe node110

gluster peer probe node145

gluster peer probe node108

查看状态:

gluster peer status //查看状态

创建我们先使用下面命令发布新版本应用,如下:卷

gluster volume create rep_vol1 replica 2 node99:/glusterfs/storage1/rep_vol1 node108:/glusterfs/storage1/rep_vol1

创建分布式卷

gluster volume create vdisk1 node108:/brick1 node110:/brick1 brick node145:/brick1 force

创建分布式卷

gluster volume create fbfz replica 2 transport tcp node108:/gluster/fbfz1 node110:/gluster/fbfz1 node145:/gluster/fbfz1 node108:/gluster/fbfz2 node110:/gluster/fbfz2 node145:/gluster/fbfz2 force

启动卷

gluster volume start rep_vol1

查看卷状态

gluster volume status

gluster volume

客户端测试挂载卷

mount -t glusterfs node108:rep_vol /tmp/

mount -t glusterfs node145:fbfz /mnt/fbfz

客户端测试卷数据存储

for i in `seq -w 1 3`;do cp -rp /var/log/messages /tmp//test-$i;done

其他备用作

停止卷:

gluster volume stop vdisk2

删除卷:

gluster volume delete vdisk2

将某个存储主机从信任池中删除:

gluster peer detach node2

Heketi是由golang编写,直接静态编译运行二进制即可,也可以通过yum安装以及docker部署,主要会产生db文件存储cluster、node、dev、volume等信息。

wget -c tar zxvf heketi-v9.0.0.linux.amd64.tar.gz

mkdir -pv /opt/heketi/{bin,conf,data}

cp heketi/heketi.json /opt/heketi/conf/

创建ssh-key

我们glusterFS部署在k8s集群外,所以heketi通过ssh管理glusterFS。需要创建免秘钥登陆到所有glusterFS。

ssh-keygen -f /opt/heketi/conf/heketi_key -t rsa -N ''

ssh-copy-id -i /opt/heketi/conf/heketi_key.pub root@node108 -p 2222

ssh-copy-id -i /opt/heketi/conf/heketi_key.pub root@node110 -p 2222

ssh-copy-id -i /opt/heketi/conf/heketi_key.pub root@node145 -p 2222

配置文件修改

需要说明的是,heketi有三种executor,分别为mock、ssh、kubernetes,建议在测试环境使用mock,生产环境使用ssh,当glusterfs以容器的方式部署在kubernetes上时,才使用kubernetes。我们这里将glusterfs和heketi部署,使用ssh的方式。

使用docker部署的时候,还需将/var/lib/heketi/mounts 挂载至容器里面, heketi 会将此目录作为 gluster volume的挂载点。

d配置

cat /usr/lib/d//heketi.serv

启动heketi服务

ctl start heketi

ctl enable heketi

ctl status heketi

添加cluster

/opt/heketi/bin/heketi-cli --user admin --server --secret adminkey --json cluster create

将3个glusterfs作为node添加到cluster

添加

opt/heketi/bin/heketi-cli --user admin --server --secret adminkey --json node add --cluster "bb1362c3360d80419c822b9994381608" --mament-host-name node108 --storage-host-name 10.14.151.108 --zone 1

/opt/heketi/bin/heketi-cli --user admin --server --secret adminkey --json node add --cluster "bb1362c3360d80419c822b9994381608" --mament-host-name node110 --storage-host-name 10.14.151.110 --zone 1

查看:

/opt/heketi/bin/heketi-cli --user admin --server --secret adminkey node list

添加dev

机器只是作为gluster的运行单元,volume是基于dev创建的。同时需要特别说明的是,目前heketi仅支持使用分区或磁盘(未格式化)添加为dev,不支持文件系统。

/opt/heketi/bin/heketi-cli --user admin --server --secret adminkey --json dev add --name="/dev/sdb" --node "227fd34c519f0a2c9d5a5b7f3d048745"

/opt/heketi/bin/heketi-cli --user admin --server --secret adminkey --json dev add --name="/dev/sdb" --node "5f2d7412f0c874634aa8ee18865533bf"

/opt/heketi/bin/heketi-cli --user admin --server --secret adminkey --json dev add --name="/dev/sdb" --node "e20c47a9d9a31a300ed85ccc37441608"

注:--node参数给出的id是上一步创建node时生成的,实际配置中,要添加每一个的每一块用于存储的硬盘。

生产实际配置

以上ad-hoc命令均可通过配置文件创建然后导入:

$ sudo cat /data/heketi/conf/topology.json

创建:

$ sudo heketi-cli topology load --json topology.json

添加volume

这里仅仅是做一个测试,实际使用中,会由kubernetes自动创建pv.

创建一个大小为3G,副本为2的volume

opt/heketi/bin/heketi-cli --user admin --server --secret adminkey volume create --size 3 --replica 2

创建storageclass

添加storageclass-glusterfs.yaml文件,内容如下:

cat storageclass-glusterfs.yaml

kubectl apply -f storageclass-glusterfs.yaml

kubectl get sc

注意:

: "true" #表示此storageClass作为default sc,创建pvc不指定sc时,默认使用此sc.

reclaimPolicy: Retain #表示pv回收策略为保留,删除pvc时将不删除pv。

更详细的用法参考:

创建pvc

kubectl create -f glusterfs-pvc.yaml

cat glusterfs-pvc.yaml

kubectl create -f glusterfs-pvc.yaml

kubectl get pv

kubectl get pvc

创建pod,使用pvc

cat mysql-deployment.yaml

kubectl create -f mysql-deployment.yaml

kubectl get deploy

kubectl get pods

kubectl exec -ti mysql-b75b5dcfb-cb7qm sh

df -Th

创建statefulset

kubectl apply -f nginx-statefulset.yml

kubectl get pod,pv,pvc

我们可以看到RECLAIM POLICY: Retain ,经过测试

删除pvc,pv status会变成Released状态,且不会被删除

删除pv, 通过heketi-cli volume list查看,volume不会被删除

kubernetes pv和gluster volume不一致时,可使用heketi来统一管理volume.此文档heketi和glusterfs都在kubernetes集群外部署。对于支持AWS EBS的磁盘,可通过EBS storageClass方式将glusterFS heketi部署在容器中管理.参考

参考文档

)

验证测试:

kubectl exec -ti mysql-b75b5dcfb-cb7qm sh

说明挂掉一个是不影响用户使用的。