Kubernetes 和 Virtual Kubelet 简介
了解更多💡
今天,您将学习如何获取 Web 应用程序(可以是任何编程语言,我们使用 Java 和 Kotlin)并使用 Kubernetes(K8s)和 Virtual Kubelet(VK)进行分发。
好吧,如果您还不知道为什么您应该考虑分发您的网络应用程序 - 请阅读我在这里的帖子。
所以你可能会问自己
“什么是 Kubernetes?我能用它做什么?”
继续阅读
Kubernetes 是一个开源容器编排系统,用于自动化应用程序的部署、扩展和管理。它用于构建分布式、可扩展的微服务。它带来了许多我们需要熟悉的新概念和术语,以下是最基础的:
基本词汇表:
节点- 硬件组件。通常是托管在云上的虚拟机,为 Kubernetes 集群提供 CPU 和 RAM 资源。
Kubernetes Master - 负责管理 Kubernetes 集群状态的一个或多个节点。
Kubelet - 在每个节点上运行的主要“节点代理”。它管理由 Kubernetes 创建的容器,并在其管理的节点上运行。它与 Kubernetes 主节点进行通信。
Pod - 容纳一个或多个容器。共享同一 Pod 的容器也共享资源和网络。Pod 可以管理不同节点(不同的物理机或虚拟机)上的容器。它充当部署、水平扩展和复制的单元。
PodSpec - 描述 Pod 规范的 Yaml 或 JSON 文件。kubelet 使用它来确保容器健康且按预期运行。
集群——连接在一起的一系列节点。
还有许多其他概念和术语,但这是我们理解虚拟 kubelet 和开始使用 K8S 所需的基础。
Kubernetes API - 在主节点上运行并直接与节点上运行的 kubelet 对话的服务器(REST)。
在Kubernetes.io的图表中,我们可以看到节点和主节点:
嘿,Pod 在哪儿?
Pod 可以是 Deployment 或 ReplicaSet 的一部分。ReplicaSet/Deployment 定义了分布在多个节点上的副本。以下是来自新 Stack官网的另一张显示 Pod 工作情况的图表:
另一张图展示了 ReplicaSet 如何与 Deployment 协同工作,其中 Deployment 可以看作是 ReplicaSet 的模板,其副本默认为 3。该图来自 Nir Mata网站:
Kubernetes 如何工作?
Kubernetes 管理着 N 个节点,这些节点中运行着 kubelet。kubelet 管理与节点及其上运行的 Pod 相关的一切。Pod 只是容器的集合。
当我们将应用程序放入容器中,上传到容器注册表并部署到 Kubernetes 中时,它会被部署到由 Kubernetes 集群(在我们的例子中是Azure Kubernetes 服务 (AKS))管理的虚拟机上。我们可以从 CLI 和 UI 查看并跟踪该虚拟机——此时,不再有按秒或按量计费,因为这是托管 K8S 服务的经典场景,即使最终不使用,我们也要为正在使用的机器付费。
那么虚拟 Kubelet(VK)怎么样?
使用 Virtual Kubelet,我们看不到实际节点,每个服务只有一个虚拟节点。它充当我们的抽象层,可以根据需要运行任意数量的 Pod。在后台,我们可以拥有多个虚拟机,但对于我们正在使用的特定服务,我们只会看到一个虚拟机。我们不会从 Virtual Kubelet 中看到正在使用的托管服务中运行的虚拟机。Virtual Kubelet 充当一个替代节点,帮助我们代理到具有更高抽象级别的其他托管服务。
Virtual Kubelet 是 Kubernetes kubelet 的一个开源实现,旨在将 Kubernetes 连接到其他 API。它将自身注册为节点,允许我们部署无限数量的 Pod 和容器。它还使我们能够连接到无服务器容器平台。这意味着我们可以将任何无状态应用程序容器化并通过 Pod 进行配置,Virtual Kubelet 将为我们管理它并将其迁移到托管服务。我们无需管理基础设施。它可以扩展或缩减——所有这些都由服务管理。根据所使用的托管服务,我们可以享受按需付费账户、灵活的自动扩展等诸多优势。
将 AKS 与 Azure 容器实例 (ACI) 结合使用,您将受益于容器的快速编排。我们使用虚拟节点将两者结合起来,从而实现容器调度的自动化。容器上下文中的调度是指管理员将服务加载到定义了如何运行特定容器的主机系统上的能力。将 ACI 与虚拟节点结合使用可以更快地配置 Pod。
虚拟节点可与 AKS 一起使用,并由开源 Virtual Kubelet 提供支持。
优点:
✅ Kubernetes 之上的完全托管解决方案
允许我们连接到来自不同地区的不同云提供商的许多托管解决方案。
✅ 按实际使用量付费ACI或AWS Fargate
等托管解决方案可帮助我们根据需要扩大或缩小规模,而无需我们进行干预。
✅可移植性
在 K8S 运行的任何地方,您都可以运行虚拟 Kubelet 并将其与您的托管服务连接起来。
✅ 区域和其他集群
从 Virtual Kubelet,您可以利用在其他区域甚至其他云提供商上运行的服务。
缺点:
❗️ 安全性
总的来说,你应该时刻考虑安全性。记住,安全是每个人的责任!
使用 Kubernetes 的整体安全性本来就相当复杂。添加虚拟 Kubelet 时,应该注意与 Kubernetes 集群外部以及区域/云提供商外部的其他服务通信可能引发的安全问题。
如果我们决定使用 ACI 或其他内部服务,我们可以建立一个从 Kubernetes 集群到 ACI 的内部虚拟网络。这样就可以消除这种安全隐患。
让我们通过教程来实践一下
在 JVM 领域,有许多框架可以帮助我们快速创建 Web 应用。这些框架包含服务器和 UI。我们的应用使用 Spring Boot。Spring Boot 拥有许多内置功能,例如服务器等等。服务器方面,我们可以从 Tomcat、Jetty 或 Undertow 中选择。
所以你可能会问自己,如何开始使用 Spring Boot?转到 Spring 初始化站点并下载模板或从此github 存储库下载演示应用程序。
在本教程中,我们将把一个 kotlin-spring 应用部署到 K8s 集群上的虚拟节点。
我们将使用以下服务:AKS、ACR 和 ACI。
对于本教程,您将需要:
这是第一阶段
目前,我们已经拥有一个 AKS 集群、一个要部署到集群的应用程序以及已安装的 CLI 工具。
在第二阶段,我们需要一个 ACI 帐户和一个 Docker 镜像仓库来存储我们的应用程序镜像(我们将使用 Azure 容器镜像仓库 - ACR)
我们的演示应用程序附带一个已定义该应用程序的 docker 文件,因此我们可以将其推送到 ACR。
在终端或 CMD 中导航到您的应用程序目录并运行:
set ACR_NAME={acr name}
az login
az acr login --name $ACR_NAME
docker build --no-cache -t demo .
docker tag demo $ACR_NAME.azurecr.io/samples/demo
docker push $ACR_NAME.azurecr.io/samples/demo
测试一下自己——用远程镜像运行本地docker
docker run -it --rm -p 8080:80 $ACR_NAME.azurecr.io/samples/demo
docker 容器将开始在本地运行,您将看到类似这样的内容:您可以使用ctrl+C 来停止它。
现在让我们连接到我们的 AKS 集群,为此我们需要我们的资源组名称和我们的 AKS 集群名称:
set RES_GROUP={resource group name}
set AKS_NAME={AKS name}
az aks get-credentials --resource-group $RES_GROUP --name $AKS_NAME
验证与集群的连接
kubectl get nodes
我们将获得我们的节点、版本、状态等的列表。
接下来,我们将在容器注册表 (ACR) 和 AKS 之间创建身份验证。这是非常重要的一步,如果没有身份验证,AKS 集群将无法从注册表中提取镜像。
我们将使用 secret 来完成此操作 - 请参阅
在本教程中,您正在运行这个 - 记得记下它们两者!
# Output used when creating Kubernetes secret.
echo "Service principal ID: $CLIENT_ID"
echo "Service principal password: $SP_PASSWD"
通过登录 docker 验证您的连接和密码 -
docker login $ACR_LOGIN_SERVER --username $CLIENT_ID --password $SP_PASSWD
如果失败,AKS 将无法拉取镜像,并且在本教程的后面部分,您将收到此错误got HTTP response status code 400 error code “InaccessibleImage”
。请务必逐步按照链接
中的教程进行操作。
安装连接器:
为了安装连接器并启用虚拟节点,我们将在网络中创建一个子网,并在其中安装一个 AKS 集群以及虚拟节点的附加组件。这种方式更安全,因为我们创建了一个与更大的 K8s 集群隔离的内部网络。请按照此处的
步骤操作,但不要部署应用程序——我们将部署我们的应用程序。
要部署应用程序运行:
kubectl apply -f kotlin-spring-virtual-kublet-linux.yaml
此 YAML 文件向 K8s、pod 和 kubelet 描述了我们希望我们的应用程序如何运行,部署是什么以及正在使用的服务是什么。我们文件中的每个部署组件都以 开头,apiVersion
后跟kind
,metadata
并且spec
在我们的文件中,我们有一个名为-的服务azure-spring-kotlin-front-virtual-service
和一个名为的部署:azure-spring-kotlin-front-virtual
。
在和deployment
下spec -> template -> spec
我们有节点选择器的配置,我们的集群中可能有许多节点,我们希望将此应用程序部署到我们的虚拟节点一而不是其余节点。为了实现这一点,在 下我们通过赋予其值来nodeSelector
描述它。这指定了 pod 和 kubelet,我们将仅在此特定类型的节点上部署此应用程序,而不会在其他节点上部署。type
virtual-kubelet
我们的第二个组件是kind
service
,它的规范类型是 ,loadBalancer
并且会External API
为应用程序提供一个接口,以便我们可以在浏览器中加载它。为此,我们需要先公开它——请注意,我们公开的是应用程序,而不是 LoadBalancer 本身,因为我们可以公开一个部署:
kubectl expose deployment azure-spring-kotlin-front-virtual --type=LoadBalancer --port 80 --target-port 8080
要查找External API
运行:
kubectl get services
External API
并在azure-spring-kotlin-front-virtual入口处搜索。
如何调试:
使用下一个命令进行调试并了解集群中发生的情况:
kubectl get services
kubectl get pods
kubectl get deployment
从上面的命令中,我们将获得各个组件的数据和初始状态,在弄清楚失败的原因后,我们可以运行:
kubectl describe {pod/service/node} {name of pod/service/node}
这将返回一个 JSON,其中包含事件等信息,在事件下,我们将看到失败的原因,可能是FailedSynch
应用程序状态Terminated
- 通常反映应用程序崩溃,我们应该使用以下方法检查节点日志
kubectl logs {name of node}
还有很多命令可以调试 K8s 集群,以上只是冰山一角。欢迎大家自行尝试并研究 API。
还有什么我忘了说的吗?想讨论更多选项吗?请在评论区留言或在推特上私信我。
了解更多💡
👉🏼 观看Ria Bhatia 和 Scott Hanselman 制作的有关 Virtual Kubelet 的视频
👉🏼快速入门:使用 Azure Dev Spaces 在 Kubernetes 上使用 Java 进行开发
👉🏼 Java 和Azure
👉🏼 Azure 上的 Kubernetes 和 Apache Spark教程
文章来源:https://dev.to/adipolak/kubernetes-and-virtual-kubelet-in-a-nutshell-gn4