Kubernetes in Action 笔记 —— 部署第一个应用

Kubernetes in Action 笔记 —— 部署第一个应用,第1张

Minikube 是一个能够在本地环境搭建 Kubernetes 集群的工具,支持 Windows、Linux 和 MacOS 等平台,由 Kubernetes 社区进行维护。

它通常在 Linux 虚拟机中运行 Kubernetes。如果宿主机是基于 Linux 的系统,也可以通过 Docker 实现。

即为了运行 Minikube,需要先安装 Hypervisor 比如 Virtualbox;对于 Linux 系统,也可以直接使用 Docker。

具体的安装配置步骤可以参考官方文档 Getting Started Guide 。

kubectl 是一个命令行工具,能够向 Kubernetes 集群发送命令并执行,支持的功能包括部署应用、查询和管理资源、查看日志等。

安装步骤可参考官方文档 Install Tools 。

通常情况下,部署应用时要准备一个 JSON 或者 YAML 文件,里面包含对该应用的所有组件的描述信息,再把该描述文件应用到 Kubernetes 集群。

从演示的角度来看,也可以通过单行命令的方式部署简单的应用。

可以使用 kubectl create deployment 命令部署应用。

其中 kubia 表示创建的 deployment 对象的名称, luksa/kubia:1.0 指代需要使用的容器镜像。

kubia 对象的存在告诉 Kubernetes luksa/kubia:1.0 容器必须运行在集群中。它定义了一种用户期待的状态,而 Kubernetes 负责确保实际的状态一定会满足该期望。

kubectl get deployment 命令可以列出当前集群中存在的所有 deployment 对象及其状态。

容器并不是 Kubernetes 中部署的最小单位。不同于直接部署独立的容器,Kubernetes 实际上会部署一组相互关联的容器,称为 pod

pod 包含一组一个或一个以上关系密切的容器实例,同时运行在同一个工作节点上,并共享特定的 Linux 命名空间。

同一个 pod 中的容器共享相同的网络和 UTS 命名空间,因而共享同样的网络接口、IP 地址、端口空间和主机名等。也可以在描述文件中定义其他需要共享的命名空间。

每个 pod 都有自己的 IP、机器名、进程、网络接口以及其他资源。同一个 pod 中的容器都会将自己看作是 pod 中唯一运行的容器,它们并不能看到其他容器中的进程。

创建 Deployment 对象后就表示已经部署了 pod,Kubernetes 会基于 Deployment 对象创建一个或多个 pod。

可以使用 kubectl get pods 来列出系统中的 pod:

如果某些 issue 导致 pod 运行失败,或者单纯想查看更多 pod 相关的信息,可以使用 kubectl describe pod 命令:

输出的最后就包含 pod 创建和启动时触发的一系列事件(Events)。

应用已经成功运行了,接下来就是控制燃世它如何被外部访问。每个 pod 都会获得一个专属的 IP 地址,但该地址是只有集群内部可见的。为滚凳了使 pod 能够从外部访问,还需要创建一个 Service 对象。

Service 对象有好几种类型,其中一种 LoadBalancer 会生成一个外部的负载均衡器,令服务能够从集群外部访问。

可以使用 kubectl expose 命令创建 Service:

使用 kubectl get svc 命令查看当前系统中存在的 Service:

创建 LoadBalancer 服务时,正常情况下 Kubernetes 会访问云服务皮备肢提供商,令其创建负载均衡器并获取公共 IP。

Minikube 是本地模拟的集群环境,因而无法完成上述 *** 作。kubia Service 的 EXTERNAL-IP 会一直处于 <pending>状态。

在没有获取到外部 IP 的情况下,minikube 可以使用下面的方法获取服务的 url:

打开一个新的命令行窗口,可以成功访问上面的 url:

在容器中部署应用的一个主要好处就是,横向扩展应用变得非常简单和直观。

可以使用下列命令扩展 kubia 应用,令其同时运行 3 个实例副本。

此时共有 3 个 pod 实例运行:

可以加上 -o wide 选项获取更详细的 pods 信息,比如 IP、运行的节点等:

再次访问 Service 的 URL,可以看到多次访问返回的信息并不一样,可以证实后台提供服务的 pod 并不是同一个,而是 3 个 pod 轮流接收请求并提供服务:

负载均衡架构示意图:

Kubernetes in Action, Second Edition

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

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

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

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

KubeConShanghai2018——KubeEdge开源首秀

KubeEdge 向左,K3S 向右

KubeEdge实现原理

KubeEdge 由以下组件构成:

如何配置通信协议

初始化命令说明

安装Pod网络插件(CNI)

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

KubeEdge 的边缘部分在 deviceTwin 和设备之间使用 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。

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

本文是 Drone 系列文章的第三篇,在第一篇文章中我们介绍了如何在 Kubernetes 集群中使用 Helm 来快速安装 Drone,并且用 cert-manager 给 Drone 应用做了自动化 HTTPS,在第二篇文章中我们介绍了如何在 Drone 中使用 Pipeline 来自动化构建 Docker 镜像。

本文我们将创建一个 Helm Chart 包,然后使用配隐 Drone Pipeline 来进行自动部署或更新应用到 Kubernetes 集群中。

如果对 Helm 如何部署应用还不熟悉的,同样的,可以查看我们前面的 Helm 系列文章。

Helm Chart

在我们的项目https://github.com/cnych/drone-k8s-demo根目录下面创建一个 Helm Chart 包:

对 Helm Chart 比较熟悉的应该清楚上面的helm create命令会创建一个基本的 chart 包,包含两个文件夹和两个文件:

创建完成后项目的结构如下所示:

接下来我们就根据我们项目自己的实际情况去修改 values.yaml 和 templates/ 下面的模板。实际上我们这里的项目很简单,helm create命令创建的默认 chart 已经非常友好了,我们可以在模板文件中查看到metadata部分基本上都是相同的内容:

这样可以确保我们无论部署多少次,应用都不会出现资源冲突,这基本上算是编写 Chart 包的一种最佳实践方式。

Values 文件

我们可以查看默认的values.yaml文件内容:

上面这些 values 值都是模板中直接或间接使用到的,我们可以根据自己的需要去覆盖这些值,比如要使用我们自己镜像,就去覆盖image字段的内容,镜像的地址当然就是上节课我们在 Drone Pipeline 里面最终打包成的镜像地址:

要注意我们将 pullPolicy 设置为了Always,这是因为我们的镜像标签是latest,所以当更新的时候需要强制去拉取镜像。

模板文件

在上一篇文章中我们创建的 Web 服务里面添加了一个/health的路径,所以我们可以用这个路径来做 健康 检查,在默认生成的模板中 deployment.yaml 文件里面默认就有 liveness probe 和 rediness probe 的配置,只是我们需要将检查的路径更改为/health,如下所示:

当探针检查到/health路由的请求返回一个非 200 的状态码的时候,Kubernetes 就会认为应用是不 健康 的状态,liveness probe 检测到就会自动重启 Pod,readiness probe 检测到就会将当前宴斗 Pod 从 Service 的 Endpoints 列表中移除,确保 Service 中都是可以正常接收请求的 Pod。

除此之外,我们的应用是暴露在 8080 端口上的,所以我们也需要将 Deployment 下面的端口号更改:

然后我们可以去调试下,查看我们的更改是否符号我们的期望,我们可以用helm install --dry-run --debug命令来渲染资源清单文件,但不会真正的部署到集群中去:

上面就是通过 values.yaml 文件中的值渲染出来的真正的 Deployment 资源对象,我们可以看到镜像地址和端口以及 健康 检测的内容都是符合我们的预期的。

然后查看模板文件中的 Service.yaml 文件:

该模板文件我们不需要做任何更改,唯一需要注意的说 ports 部分的 targetPort 是 http,而不是一个具体的端口号,这有一个好处就是 Pod 中端口号变了,我们也不需要更改 Service 这边的 targetPort,我们刚刚不是更改了端口号为 8080 吗?这个的 http 就是对应的 Pod 里面的端口名称,晌卖磨另一个就是 selector 部分,是和 Pod 模板里面的 label 标签一致的。

然后就是如果通过 Ingress 对象来暴露我们的服务,就需要配置 Ingress 对象:

查看模板可以看出只要在 values 中设置 ingress.enabled=true 就会开启 Ingress 对象,到这里我们可以在helm目录下面创建一个 my-values.yaml 的文件,用来覆盖默认的 values 文件:

当然同样的,我们可以通过上面的命令来调试渲染模板:

这样我们的 Chart 包就准备好了。

Pipeline

到这里我们就需要在前面文章的 Pipeline 中来添加一个步骤,用来安装我们这里的 Chart 包了,我们知道 Drone Pipeline 的每个步骤都是在一个容器中去执行的,那么我们要去使用 Helm 来安装我们的应用,自然需要容器里面有 helm 的命令,并且要能够和我们的 Kubernetes 集群进行联通,当然我们完全可以自己做一个镜像,把 helm 命令和连接集群的配置文件都内置到里面去,但这样显然也不是很灵活,不具有通用性,实际上 Drone 的插件机制非常简单粗暴,我们可以在 Drone 的插件页面找到和 Helm 相关的插件:http://plugins.drone.io/ipedrazas/drone-helm/,这个插件的基本用法如下:

这个 Pipeline 实际上相当于执行下面的命令:

另外我们可以通过指定 API_SERVER、KUBERNETES_TOKEN 以及 KUBERNETES_CERTIFICATE 这三个环境变量来指定连接 Kubernetes 集群的信息,同样的,我们到 drone 页面的项目设置下面添加这三个 secret,API_SERVER 就是我们集群的 APIServer 地址,那么 TOKEN 呢?这个 TOKEN 其实之前文章中我们已经反复提到过了,我们可以创建一个 ServiceAccount,去绑定一个 cluster-admin 的集群角色权限,然后获取这个 ServiceAccount 对应的 TOKEN 即可,比如我们 Helm 的服务端 Tiller 服务对应的 ServiceAccount,我们可以这样来获取:

证书信息同样可以通过上面的 secret 来获取:

要注意证书信息不需要用 base64 解码。然后将 apiserver 和 token 已经 ca 证书信息 添加到 drone 项目的 secret 里面:

最后我们用于部署 helm 的 pipeline 内容如下:

通过 chart 字段指定 chart 模板的目录, values_files 指定用于部署的 values 文件,release 就是指定安装的应用名称。

现在我们将添加的 chart 包以及部署的步骤提交到 GitHub 中去,在 Drone 页面上就可以看到构建过程了:

然后在本地 /etc/hosts 里面添加上域名 drone-k8s-demo.local 和 nginx-ingress 的 Pod 所在节点的映射,就可以通过域名访问应用了:

到这里我们就实现了在 Drone 中通过 Helm 部署我们的应用到 Kubernetes 集群中,不过需要注意的是 drone-helm 这个插件的官方文档有一些问题,如果在部署过程中遇到了一些问题,可以通过查看对应的源码来解决,仓库地址为:https://github.com/ipedrazas/drone-helm。

完整的项目示例代码可以在 https://github.com/cnych/drone-k8s-demo 获取。

关于 Drone Pipeline 的一些细节使用方法以及插件机制,在后面的文章中再和大家探讨,总体来说 Drone 比 Jenkins 更加轻量级,在使用上更接近 GitLab CI,而且 Drone 的插件机制非常简单粗暴,我们也可以很容易根据自己的需求来包装一个插件。


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/12473092.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-24
下一篇2023-05-24

发表评论

登录后才能评论

评论列表(0条)

    保存