入门系列之Kubernetes部署

欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~

本文由林岑影 发表于云+社区专栏

容器实例服务(Container Instance Service , CIS)可以帮您在云上快捷、灵活的部署容器,让您专注于构建程序和使用容器而非管理设备上。无需预购 CVM,您就可以在几秒内启动一批容器来执行任务。您也可以通过 kubernetes API 把已有 kubernetes 集群的 pod 调度到 CIS 上以处理突增业务。CIS 根据您实际使用的资源计费,可以帮您节约计算成本。使用 CIS 可以极大降低您部署容器的门槛,降低您执行 batch 型任务或处理业务突增的成本。

本文将介绍Kubernetes部署和容器工作负载的相关内容。包含管理容器生命周期,部署多容器应用程序,扩展工作负载以及与Kubernetes进行协同工作。本文包括一些概念和命令,教大家快速入门Kubernetes,并入门CIS。

介绍

Kubernetes是一个用于管理容器化应用程序的开源容器资源编排工具。

本文中,您将应用一些容器化的概念来构建、部署和管理Kubernetes中端到端的微服务应用程序。本文中使用的示例Web应用程序是一个用Node.js编写的“待办事项列表”应用程序,它使用MongoDB作为数据库。

本次将从Dockerfile中为此应用程序构建容器镜像,将镜像推送到Docker Hub,然后部署到您的集群。以便在未来您将扩展应用程序以满足不断增长的需求。

准备

要完成本文,您需要:

Kubernetes集群,您可以参考腾讯云开发者实验室产品进行入门。用于存储镜像的Docker Hub帐户。在本地机器安装docker,您也可以参考腾讯云开发者实验室产品进行入门。

第一步,使用Dockerfile构建镜像

首先我们将通过Web应用打包到Docker镜像中。

首先切换到您的主目录,然后使用Git从GitHub上的克隆本文的示例Web应用程序。

cd ~ git clone https://github.com/janakiramm/todo-app.git

从Dockerfile构建容器镜像。使用-t命令注册用户名,镜像名称和可选标记标记镜像。

docker build -t sammy/todo .

确认镜像已成功构建并正确标记。

Sending build context to Docker daemon 8.238MB ​ Step 1/7 : FROM node:slim ​ —> 286b1e0e7d3f ​ Step 2/7 : LABEL maintainer = “jani@janakiram.com” ​ —> Using cache ​ —> ab0e049cf6f8 ​ Step 3/7 : RUN mkdir -p /usr/src/app ​ —> Using cache ​ —> 897176832f4d ​ Step 4/7 : WORKDIR /usr/src/app ​ —> Using cache ​ —> 3670f0147bed ​ Step 5/7 : COPY ./app/ ./ ​ —> Using cache ​ —> e28c7c1be1a0 ​ Step 6/7 : RUN npm install ​ —> Using cache ​ —> 7ce5b1d0aa65 ​ Step 7/7 : CMD node app.js ​ —> Using cache ​ —> 2cef2238de24 ​ Successfully built 2cef2238de24 ​ Successfully tagged sammy/todo-app:latest

通过运行docker images命令验证是否已创建镜像。

$ docker images

您可以看到镜像的大小以及创建的时间。

REPOSITORY TAG IMAGE ID CREATED SIZE ​ sammy/todo-app latest 81f5f605d1ca 9 minutes ago 236MB

接下来,将您的镜像推送到Docker Hub上。请登录Docker Hub帐户:

docker login

输入正确的用户名及密码,使用Docker Hub用户名存储您的镜像:

docker tag your_docker_hub_username/todo-app

然后将镜像推送到Docker Hub:

docker push

您可以登录Docker Hub官网搜索查看你的镜像,来验证新镜像是否可用。

将Docker镜像推送到Docker Hub后,接下来我们可以将应用程序打包为Kubernetes。

第二步,在Kubernetes中部署MongoDB Pod

这个应用程序使用MongoDB存储通过Web应用程序创建的待办事项列表。要在Kubernetes中运行MongoDB,我们需要将其打包为Pod。当我们启动这个Pod时,它将运行一个MongoDB实例。

创建一个名为db-pod.yaml的新YAML文件:

nano db-pod.yaml

添加以下代码,该代码使用基于MongoDB的一个容器定义Pod。同时,我们打开了MongoDB使用的标准端口port。请注意,定义包含名为name和app的标签。我们将使用这些标签来识别和配置特定的Pod。

apiVersion: v1 kind: Pod metadata: name: db labels: name: mongo app: todoapp ​ spec: containers: – image: mongo name: mongo ports: – name: mongo containerPort: 27017 ​ volumeMounts: – name: mongo-storage mountPath: /data/db ​ volumes: – name: mongo-storage hostPath: path: /data/db

数据存储在调用的卷中,该卷映射到节点的位置。有关卷的更多信息,请参阅Kubernetes官方文档

运行以下命令以创建Pod。

kubectl create -f db-pod.yml

你会看到这个输出:

pod “db” created

现在我们看看Pod是否创建。

kubectl get pods

显示这个Pod正在运行:

NAME READY STATUS RESTARTS AGE db 1/1 Running 0 2m

接下来我们让集群的内部人员可以管理访问这个Pod。

创建一个名为db-service.yaml的新文件,其中包含定义了MongoDB服务的代码:

apiVersion: v1 kind: Service metadata: name: db labels: name: mongo app: todoapp ​ spec: selector: name: mongo ​ type: ClusterIP ports: – name: db port: 27017 targetPort: 27017

此服务将能够发现与name:db标签相匹配的同一命名空间中的所有Pod 。YAML文件中的selector部分明确地定义了这种关联关系。

我们通过声明type: ClusterIP可以使服务在集群中可见 。

保存文件并退出编辑器。然后使用kubectl将其提交到集群。

kubectl create -f db-service.yml

您将看到此输出指示服务已成功创建:

service “db” created

让我们来看看Pod可用的端口。

kubectl get services

您将看到以下的输出结果:

NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE db ClusterIP 10.109.114.243 <none> 27017/TCP 14s kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 47m

从上图的输出结果中,您可以看到该服务在端口27017上。Web应用程序可以通过此服务访问MongoDB。当它使用主机名db的时候,在Kubernetes中运行的DNS服务将解析与服务关联的IP的地址。这种机制允许Pod之间相互检测并通信。

接下来我们可以使用数据库Pod和Service,为Web应用程序创建一个额外的Pod。

第三步,将Node.JS Web App部署为Pod

我们将在本文第一步中创建的Docker镜像打包为Pod并将其部署到集群。这将被作为最终用户可访问的前端Web应用程序层。

创建一个名为的新YAML文件:web-pod.yaml

nano web-pod.yaml

添加以下代码,该代码根据sammy/todo-app的Docker镜像定义具有一个容器的Pod 。它通过TCP协议展现在端口3000上。

apiVersion: v1 kind: Pod ​ metadata: name: web labels: name: web app: todoapp ​ spec: containers: – image: sammy/todo-app name: myweb ports: – containerPort: 3000

运行以下命令以创建Pod:

kubectl create -f web-pod.yaml pod “web” created

看看pod是否创建?

kubectl get pods NAME READY STATUS RESTARTS AGE db 1/1 Running 0 8m web 1/1 Running 0 9s

我们将MongoDB数据库和Web应用程序都作为Pod运行。

现在,我们将使web Pod可以访问互联网。

服务会在内部或外部公开一组Pod。让我们定义一个使web Pod可以公开使用的服务。我们将通过NodePort公开它。NodePort是一种通过在集群的每个节点上打开任意端口用来访问Pod的方案。

创建一个名为web-service.yaml的新文件,其中包含定义应用服务的代码:

apiVersion: v1 kind: Service metadata: name: web labels: name: web app: todoapp ​ spec: selector: name: web type: NodePort ports: – name: http port: 3000 targetPort: 3000 protocol: TCP

服务发现同一名称空间中与Label匹配的所有Pod都具有名称web。YAML文件的选择器部分定义了此关联。

我们通过声明type: NodePort指定NodePort的服务类型。

用kubectl将此提交到群集。

kubectl create -f web-service.yml

您将看到此输出指示服务已成功创建:

service “web” created

让我们来看看Pod可用的端口。

kubectl get services NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE db ClusterIP 10.109.114.243 <none> 27017/TCP 12m kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 59m web NodePort 10.107.206.92 <none> 3000:30770/TCP 12s

从此输出中,我们看到该服务在端口30770上可用。让我们尝试连接到其中一个工作节点。

使用腾讯云控制台获取与你服务器的IP地址:

获得IP地址后,使用curl命令向端口30770上的一个节点发出HTTP请求:

curl http://your_worker_ip_address:30770

您将看到如下的输出:

<!DOCTYPE html> <html> <head> <title>Containers Todo Example</title> <link rel=stylesheet href=/stylesheets/screen.css /> <!–[if lt IE 9]> <script src=”http://html5shiv.googlecode.com/svn/trunk/html5.js”></script> <![endif]–> </head> <body> <div id=”layout”> <h1 id=”page-title”>Containers Todo Example</h1> <div id=”list”> <form action=”/create” method=”post” accept-charset=”utf-8″> <div class=”item-new”> <input class=”input” type=”text” name=”content” /> </div> </form> </div> <div id=”layout-footer”></div> </div> <script src=”/javascripts/ga.js”></script> </body> </html>

截至到此,您已经定义了Web Pod和服务。现在让我们看看如何使用副本集来缩放它。

第5步 – 扩展Web应用程序

副本集可以确保始终在群集中运行最少数量的Pod。当Pod被打包为副本集时,Kubernetes将始终运行规范中定义的最小数量的Pod。

让我们删除当前的Pod并通过副本集重新创建两个Pod。如果我们让当前的Pod运行,它将不会是副本集的一部分。因此,我们最好通过副本集启动Pod,即使只有一个Pod。

首先,删除现有的Pod。

kubectl delete pod web pod “web” deleted

现在创建一个新的副本集声明。副本集的定义与Pod相同。关键的区别在于它包含定义需要运行的Pod数量的replica元素。与Pod一样,它还包含有助于服务发现的元数据来作为标签。

创建web-rs.yaml文件并将此代码添加到文件中

apiVersion: extensions/v1beta1 kind: ReplicaSet metadata: name: web labels: name: web app: todoapp spec: replicas: 2 template: metadata: labels: name: web spec: containers: – name: web image: sammy/todo-app ports: – containerPort: 3000

保存并关闭文件。

现在创建副本集:

kubectl create -f web-rs.yaml replicaset “web” created

然后检查Pod的数量:

kubectl get pods NAME READY STATUS RESTARTS AGE db 1/1 Running 0 18m web-n5l5h 1/1 Running 0 25s web-wh6nf 1/1 Running 0 25s

当我们通过NodePort访问服务时,请求将被发送到由副本集管理一个Pod中。

让我们通过删除其中一个Pod,并查看发生的情况来测试副本集的功能:

kubectl delete pod web-wh6nf pod “web-wh6nf” deleted

让我们再来看一下Pods:

kubectl get pods NAME READY STATUS RESTARTS AGE db 1/1 Running 0 19m web-n5l5h 1/1 Running 0 1m web-wh6nf 1/1 Terminating 0 1m web-ws59m 0/1 ContainerCreating 0 2s

删除Pod后,Kubernetes会创建另一个Pod副本,以确保其能够维持所需的计数。

我们可以扩展副本集以运行其他的Web Pod。

运行以下命令将Web应用程序扩展为10个Pod。

kubectl scale rs/web –replicas=10 replicaset “web” scaled

检查Pod计数:

kubectl get pods

您将会会看到如下输出:

NAME READY STATUS RESTARTS AGE db 1/1 Running 0 22m web-4nh4g 1/1 Running 0 21s web-7vbb5 1/1 Running 0 21s web-8zd55 1/1 Running 0 21s web-f8hvq 0/1 ContainerCreating 0 21s web-ffrt6 1/1 Running 0 21s web-k6zv7 0/1 ContainerCreating 0 21s web-n5l5h 1/1 Running 0 3m web-qmdxn 1/1 Running 0 21s web-vc45m 1/1 Running 0 21s web-ws59m 1/1 Running 0 2m

此时,Kubernetes已经启动了扩展web Pod 的过程。当请求通过NodePort到达服务时,它将被路由到副本集中的一个Pod。

当流量和负载消退时,我们可以恢复到两个Pod的原始配置。

kubectl scale rs/web –replicas=2 replicaset “web” scaled

此命令将终止其余所有的Pod。

kubectl get pods NAME READY STATUS RESTARTS AGE db 1/1 Running 0 24m web-4nh4g 1/1 Terminating 0 2m web-7vbb5 1/1 Terminating 0 2m web-8zd55 1/1 Terminating 0 2m web-f8hvq 1/1 Terminating 0 2m web-ffrt6 1/1 Terminating 0 2m web-k6zv7 1/1 Terminating 0 2m web-n5l5h 1/1 Running 0 5m web-qmdxn 1/1 Terminating 0 2m web-vc45m 1/1 Terminating 0 2m web-ws59m 1/1 Running 0 4m

要验证副本集的可用性,请尝试删除其中一个Pod并检查计数。

kubectl delete pod web-ws59m pod “web-ws59m” deleted kubectl get pods NAME READY STATUS RESTARTS AGE db 1/1 Running 0 25m web-n5l5h 1/1 Running 0 7m web-ws59m 1/1 Terminating 0 5m web-z6r2g 0/1 ContainerCreating 0 5s

一旦Pod计数发生变化,Kubernetes就会调整它以匹配YAML文件中定义的计数。删除副本集中的一个Web Pod时,会立即创建另一个Pod以保持所需的计数。这是通过确保最小数量的Pod能够持续运行来确保应用程序的高可用性。

您可以使用以下命令删除在本文中创建的所有对象:

kubectl delete -f db-pod.yaml -f db-service.yaml -f web-rs.yaml -f web-service.yaml pod “db” deleted service “db” deleted replicaset “web” deleted service “web” deleted

本文就先写到这里,欢迎大家使用腾讯云CIS产品,产品链接:https://cloud.tencent.com/document/product/858

参考文献:《Webinar Series: Deploying and Scaling Microservices in Kubernetes》

翻译:Zach展,审校:Techeek问答

如何使用Kubernetes?

相关阅读

GAME-TECH降落长沙,腾讯游戏云全面解析游戏技术生态MySQL 8.0 版本功能变更介绍为你的网站加一道防线,腾讯云服务器安装配置SimpleSAMLphp指南

此文已由作者授权腾讯云+社区发布,原文链接:https://cloud.tencent.com/developer/article/1158254?fromSource=waitui

欢迎大家前往腾讯云+社区或关注云加社区微信公众号(QcloudCommunity),第一时间获取更多海量技术实践干货哦~

海量技术实践经验,尽在云加社区

    THE END
    喜欢就支持一下吧
    点赞10 分享
    评论 抢沙发
    头像
    欢迎您留下宝贵的见解!
    提交
    头像

    昵称

    取消
    昵称表情代码图片

      暂无评论内容