当前位置: 首页 > 后端技术 > Node.js

带你了解Kubernetes,部署一个Node应用

时间:2023-04-03 11:53:15 Node.js

什么是Kubernetes?Kubernetes是一个容器集群管理系统,是一个开源平台,可以实现容器集群的自动部署、自动扩缩容、维护等功能。容器化应用程序可以运行在物理机或虚拟机的Kubernetes集群上,Kubernetes可以提供“以容器为中心的基础设施”。如果你曾经使用Docker容器技术部署容器,你可以将Docker视为Kubernetes内部使用的低级组件。Kubernetes不仅支持Docker,还支持另一种容器技术Rocket。使用Kubernetes,您可以:自动化容器部署和复制快速扩展应用程序将容器分组并提供容器之间的负载平衡无缝连接新的应用程序功能要了解Kubernetes集群,您需要了解几个重要概念。DeploymentDeployment负责创建和更新应用程序。Deployment创建后,Kubernetesmaster会将Deployment创建的应用实例调度到集群中的各个节点上。创建应用程序实例后,KubernetesDeploymentController会持续监控这些实例。如果管理实例的节点被关闭或删除,部署控制器将替换它们,从而实现自我修复功能。当Pod创建Deployment时,Kubernetes会创建一个Pod来托管应用程序。Pod是Kubernetes中的一个抽象概念,由一个或多个共享资源的容器组成。Pod是独立运行的基本单元,由一组容器和卷组成。同一个Pod中的容器共享同一个网络命名空间,可以使用localhost相互通信。Pod是短暂的,而不是持久的实体。当在Kubernetes上创建Deployment时,Deployment会创建带有容器的Pod(不直接创建容器),每个Pod会被绑定并调度到Node节点上,并一直保留到终止(根据配置策略)或删除。如果节点出现故障,相同的Pod将被调度到集群中的其他可用节点上。Node一个Pod总是运行在一个(Node)节点上。Node是Kubernetes中的工作节点,可以是虚拟机也可以是物理机。每个Node由Master管理,Node上可以有多个Pod。KubernetesMaster会自动处理集群中Nodes的pod调度,Master的自动调度会考虑到每个Node上的可用资源。ReplicationControllerReplicationController确保指定数量的Pod“副本”在任何时候都在运行。如果你为一个Pod创建一个ReplicationController并指定3个副本,它会创建3个Pod并持续监控它们。如果Pod变得无响应,ReplicationController会替换它。如果在运行过??程中将副本总数改为5,ReplicationController会立即启动2个新的Pod,保证总数为5。Service其实Pod是有生命周期的。当一个工作节点(Node)被销毁时,运行在该节点上的Pod也会被销毁,然后通过ReplicationController动态创建新的Pod来保持应用程序的运行。例如,考虑一个运行3个副本的图像处理后端,这些副本是可以互换的——前端不需要关心它们调用的是哪个后端副本。也就是说,Kubernetes集群中的每个Pod都有一个独立的IP地址,因此需要有一种方法来自动协调各个Pod之间的变化,以便应用程序能够继续运行。Kubernetes中的Service是一个抽象的概念,它定义了Pod的逻辑分组和可以访问它们的策略,这样你的一组Pod就可以被Service访问到。借助Service可以轻松实现服务发现和负载均衡。可以指定四种类型的服务:ClusterIP-在集群的内部IP上公开服务。这种类型使服务只能从集群内部访问。NodePort-通过每个节点上的IP和静态端口(NodePort)公开服务。NodePort服务将被路由到自动创建的ClusterIP服务。可以通过请求:从集群外部访问NodePort服务。LoadBalancer-可以使用云提供商的负载均衡器(如果支持)将服务暴露在外部。外部负载均衡器可以路由到NodePort服务和ClusterIP服务。(一般常用此类型对外暴露端口,做负载均衡)ExternalName-通过返回CNAME及其值,可以将服务映射到externalName字段的内容,不会有任何类型的代理创建。标签您可以分配标签(键值对)来标识您的Pod、Deployment和Service。然后您可以通过选择标签进行具体说明。使用Minikube在kubernetes中部署第一个应用本文以MACOSX为例。目标是部署一个简单的HelloWorldNode.js应用程序以在Kubernetes上运行。所以你可能需要一个Node.js环境。Minikube是Kubernetes社区开发的一个工具,可以方便我们在本地运行kubernetes。准备工作Node.jsDockerVM-VirtualBoxMinikubeKubectlNode.js、Docker、VirtualBox的安装这里不再详细介绍。可以直接到官网下载安装最新的稳定版。创建Minikube集群使用curl下载并安装最新版本的Minikube:$curl-Lominikubehttps://storage.googleapis.com/minikube/releases/latest/minikube-darwin-amd64&&\chmod+xminikube&&\sudomvminikube/usr/local/bin/使用Homebrew下载kubectl命令管理工具:$brewinstallkubectl默认VM驱动是VirtualBox,所以可以直接启动Minikube:$minikubestart接下来会打印类似的信息...启动本地Kubernetesv1.9.4集群...启动VM...获取VMIP地址...将文件移入集群...设置证书...连接到集群...设置kubeconfig...启动集群组件...Kubectl现在配置为使用集群。从配置文件加载缓存图像。验证kubectl是否安装成功:$kubectlcluster-info会打印出类似的信息:Kubernetesmasterisrunningathttps://192.168.99.100:8443创建一个Node.js应用程序编写应用程序。将此代码保存在名为hellonode的文件夹中,文件名为server.js:varhttp=require('http');varhandleRequest=function(request,response){console.log('收到URL请求:'+request.url);响应.writeHead(200);response.end('HelloWorld!');};varwww=http.createServer(handleRequest);www.listen(3000);启动应用程序:$nodeserver.js现在可以看到“HelloWorld!”http://localhost:3000上的消息。Ctrl-C停止正在运行的Node.js服务器。创建Docker容器镜像在hellonode文件夹中创建一个名为Dockerfile的文件。FROMnode:8.10.0EXPOSE3000COPYserver.js.CMDnodeserver.js我们使用Minikube,而不是将Docker镜像推送到registry,我们可以使用与MinikubeVM相同的Docker主机来构建镜像,这样镜像就存在了自动地。为此,请确保使用MinikubeDocker守护进程:$eval$(minikubedocker-env)注意:如果您未使用Minikube主机,则可以通过运行eval$(minikubedocker-env-u)撤消此更改.使用MinikubeDocker守护进程构建Docker镜像:$dockerbuild-thello-node:v1。创建DeploymentKubernetesDeployment是为了检查Pod的健康状况,如果Pod的容器终止,则重新启动它。Deployment管理Pod的创建和扩展。使用kubectlrun命令创建Deployment来管理Pod。$kubectlrunhello-node--image=hello-node:v1--port=3000查看部署:$kubectlgetdeployments输出:NAMEDESIREDCURRENTUP-TO-DATEAVAILABLEAGEhello-node11115s查看Pod:$kubectlgetpods输出:NAMEREADYSTATUSRESTARTSAGEhello-node-6ddb5576c9-644xn1/1Running01m查看部署详情:$kubectldescribedeployment创建的ServicePod只能通过Kubernetes内网IP访问簇。要使hello-node容器可以从Kubernetes虚拟网络外部访问,您需要使用Kubernetes服务来公开Pod。我们可以使用kubectlexpose命令将Pod暴露给外部环境:$kubectlexposedeploymenthello-node--type=LoadBalancer查看服务:$kubectlgetservicesoutput:NAMETYPECLUSTER-IPEXTERNAL-IPPORT(S)AGEhello-节点LoadBalancer10.110.94.178080:32081/TCP2mkubernetesClusterIP10.96.0.1443/TCP6d查看详细信息:$kubectldescribeservicehello-node输出:名称:hello-nodeNamespace:defaultLabels:run=hello-nodeAnnotations:选择器:run=hello-nodeType:LoadBalancerIP:10.110.94.17Port:8080/TCPTargetPort:8080/TCPNodePort:32081/TCPEndpoints:172.17.0.5:8080SessionAffinity:NoneExternalTrafficPolicies:通过--type=LoadBalancer在集群外暴露服务。在支持负载均衡的云服务商上,配置一个外部IP(EXTERNAL-IP,在Minikube中显示为:)地址访问Minikube上的Service。LoadBalancer类型使用的服务可以通过minikubeService命令访问。$minikubeservicehello-node将打开浏览器,在本地IP地址为应用程序提供服务,并显示“HelloWorld”消息。可以查看日志:$kubectllogs//exp:kubectllogshello-node-6ddb5576c9-644xn//可以通过kubectlgetpods查看pod-name扩容实例根据线上需求,扩容和宫缩是常遇到的问题。缩放是通过更改Deployment中的副本数量来实现的。一旦你有多个实例,你可以在不停止服务的情况下滚动。通过kubectlscale命令进行扩缩容。$kubectlscaledeployments/hello-node--replicas=4查看pods:$kubectlgetpods输出:NAMEREADYSTATUSRESTARTSAGEhello-node-9f5f775d6-6qdmn1/1Running03shello-node-9f5f775d6-9mrm61/1Running03shello-node-9f5f775d6-jxb8z1/1Running03shello-node-9f5f775d6-tx8kg1/1Running011m一共有4个实例,那么可以使用Service的--type=LoadBalancer进行负载均衡。更新应用程序编辑server.js文件以返回新消息:response.end('HelloWorldAgain!');dockerbuildnewversionimage:$dockerbuild-thello-node:v2.Deploymentupdateimage:$kubectlsetimagedeployment/hello-nodehello-node=hello-node:v2在浏览器中再次查看消息:$minikubeservicehello-nodecleanupdelete删除集群中创建的资源:$kubectldeleteservicehello-node$kubectldeletedeploymenthello-Nodeviewpods:$kubectlgetpodsoutput:NAMEREADYSTATUSRESTARTSAGEhello-node-9f5f775d6-6qdmn1/1Terminating06mhello-node-9f5f775d6-9mrm61/1Terminating06mhello-node-9f5f775d6-jxb8zTerminating1/1T6mhello-node-9f5f775d6-tx8kg1/1Terminating018mAllarestopping...等一下,检查再次,输出找不到资源。Stop$minikubestop输出:正在停止本地Kubernetes集群...机器已停止。完成的