前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Kubernetes部署应用的几种方式

Kubernetes部署应用的几种方式

作者头像
云原生
发布2021-05-31 11:20:02
2.1K0
发布2021-05-31 11:20:02
举报
文章被收录于专栏:云原生实践

在本文中,我们将使用示例微服务应用程序VotingApp来说明可在Kubernetes集群中部署应用程序的几种方式:

  • 使用Yaml规范
  • 通过Helm chart
  • 使用Kustomize

VotingApp

VotingApp是由Docker创建的应用程序,它主要是用来说明docker和Kubernetes的功能。该应用程序遵循微服务架构,由五个服务组成,如下图所示。

VotingApp的整体架构

该应用程序通常用于演示和演示,这是一个很好的示例,因为它使用了多种语言和数据库技术:

  • vote:使用Python开发的前端,允许用户在猫和狗之间进行选择
  • redis:存储投票的数据库
  • worker:从Redis获得投票并将结果存储在Postgres数据库中的服务。该服务存在Java和.NET两个版本
  • db:Postgres数据库,worker在该数据库中合并票数
  • result:Node.js开发的前端,用于显示结果

原始应用程序托管在GitHub中,本文所用到的,使用3种不同的方式定义该应用程序 的配置在公众号云原生的github代码库里:

  • 使用Yaml规范
  • 通过helm chart
  • 通过kustomize结构

在下文中,我们将使用这三种方式来部署VotingApp,并说明它们之间的区别。

设置演示集群

首先,我们将在本地计算机上快速设置一个Kubernetes集群。在本地运行Kubernetes真的很容易,因为那里有许多可用的解决方案。仅举几个:

  • k0s
  • k3s
  • microK8s
  • miniKube
  • kind

在本文中,我们使用最新版本的k0s(2021年4月为0.12),并使用vagrant和VirtualBox进行安装。

首先,我们创建一个新文件夹,并Vagrantfile在其中添加以下内容。

代码语言:javascript
复制
Vagrant.configure("2") do |config|
  config.vm.box = "hashicorp/bionic64"
  config.vm.network "private_network", ip: "192.168.33.11"
  config.vm.provision "shell", inline: <<-SHELL
    curl -sSLf https://get.k0s.sh | sudo sh
    sudo k0s install controller --single
    sudo systemctl start k0scontroller.service
  SHELL
end

接下来,在该文件夹中,运行以下命令,以创建一个VM并在其中安装k0s:

代码语言:javascript
复制
$ vagrant up

接下来,我们在这个新创建的VM中运行一个root shell:

代码语言:javascript
复制
$ vagrant ssh
代码语言:javascript
复制
vagrant @ vagrant:〜$ sudo su-
代码语言:javascript
复制
root @ vagrant:〜#

使用k0s附带的客户端kubectl,我们可以使用以下命令查看我们的单节点集群(节点进入“Ready ”状态大约需要一分钟):

代码语言:javascript
复制
# k0s kubectl get nodes
NAME      STATUS   ROLES    AGE   VERSION
vagrant   Ready    <none>   40s   v1.20.5-k0s1

然后,在公众号云原生的github代码库里找到配置文件,在20210403目录下

下一步,我们将使用原始Yaml规范部署VotingApp。

Yaml规格

清单文件夹中包含了每个微服务的yaml:

代码语言:javascript
复制
# tree manifests/
manifests/
├── db-deployment.yaml
├── db-service.yaml
├── redis-deployment.yaml
├── redis-service.yaml
├── result-deployment.yaml
├── result-service.yaml
├── vote-deployment.yaml
├── vote-service.yaml
└── worker-deployment.yaml
  • voteresultredisdb都有一个DeploymentService资源
  • worker仅具有一种Deployment资源,因为它不需要公开:worker是一种连接redisdb的启动服务

以下命令使用yaml所有创建应用程序:

代码语言:javascript
复制
#k0s kubectl apply -f manifests/

注意:该命令kubectl apply -f会作用于该文件夹的所有yaml

同样我们需要确保一切正常:

代码语言:javascript
复制
# k0s kubectl get deploy
NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/worker   1/1     1            1           102s
deployment.apps/db       1/1     1            1           103s
deployment.apps/result   1/1     1            1           102s
deployment.apps/vote     1/1     1            1           102s
deployment.apps/redis    1/1     1            1           102s

然后,我们可以使用VM的IP以及在vote-service.yamlresult-service.yaml中指定的nodePort来访问Web界面:vote可在端口31001,端口31001result上访问。我们可以对项目进行投票并查看结果,确认整个应用程序运行良好。

使用原始 manifests部署VotingApp

然后可以使用以下命令删除该应用程序:

代码语言:javascript
复制
# k0s kubectl delete -f manifests

使用yaml清单直接部署应用程序很简单,但是它不提供方便的功能来完全管理应用程序的生命周期或动态配置应用程序(Helm真正发挥作用的领域)。

Helm

通过Helm,我们可以管理(定义,安装,升级)复杂的Kubernetes应用程序。通过Chart的概念,该工具可以轻松地创建,版本控制,共享和发布整个应用程序,Chart是一个包含整个应用程序规范的软件包。Helm还提供了一种模板语言来动态配置应用程序。

在配置库中,helm文件夹包含VotingApp的最简单图表。

代码语言:javascript
复制
# tree helm
helm
├── Chart.yaml
├── templates
│   ├── db-deployment.yaml
│   ├── db-service.yaml
│   ├── _helpers.tpl
│   ├── redis-deployment.yaml
│   ├── redis-service.yaml
│   ├── result-deployment.yaml
│   ├── result-service.yaml
│   ├── vote-deployment.yaml
│   ├── vote-service.yaml
│   └── worker-deployment.yaml
└── values.yaml

模板文件夹中包含相当多,我们在上一步中使用(当我们部署了从应用程序的同一规格清单文件夹),除了几件事情:

  • voteresult服务使用heml模板语言来定义nodePort而不是使用文本值。每个值都是对values.yaml中定义的值的引用(稍后会对此进行详细介绍):
代码语言:javascript
复制
# cat templates/vote-service.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: vote
  name: vote
spec:
  type: NodePort
  ports:
  - name: "vote-service"
    port: 5000
    targetPort: 80
    nodePort: {{ .Values.vote.port }}
  selector:
    app: vote
# cat templates/result-service.yaml
apiVersion: v1
kind: Service
metadata:
  labels:
    app: result
  name: result
spec:
  type: NodePort
  ports:
  - name: "result-service"
    port: 5001
    targetPort: 80
    nodePort: {{ .Values.result.port }}
  selector:
    app: result
  • heml模板还用于worker指定用于此特定服务的图像(版本Java.NET版本均可用):
代码语言:javascript
复制
# cat templates/worker-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: worker
  name: worker
spec:
  replicas: 1
  selector:
    matchLabels:
      app: worker
  template:
    metadata:
      labels:
        app: worker
    spec:
      containers:
      - image: {{ .Values.worker.image }}
        name: worker
  • 在以上模板中引用的值在values.yaml中定义
代码语言:javascript
复制
# cat values.yaml
vote:
  port: 31002
result:
  port: 31003
worker:
  image: lucj/voting:worker.java

现在让我们使用Helm部署VotingApp。

首先,我们需要helm按照以下说明安装二进制文件

接下来,我们votinghelm文件夹中运行以下命令来创建发行版的第一个修订版:

代码语言:javascript
复制
# helm upgrade voting --install --values values.yaml .

我们得到的结果类似于以下内容:

代码语言:javascript
复制
Release "voting" does not exist. Installing it now.
NAME: voting
LAST DEPLOYED: Wed Mar 31 21:02:07 2021
NAMESPACE: default
STATUS: deployed
REVISION: 1
TEST SUITE: None

后台,helm读取templates文件夹中的规范,使用来自values.yaml的值创建真实的Yaml清单(Kubernetes可以执行),并要求API服务器创建相应的资源。

创建发行版的第一个修订版后,我们确保所有Pod都处于“运行”状态,以确保一切运行良好:

代码语言:javascript
复制
# k0s kubectl get deploy,pod
NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/worker   1/1     1            1           24s
deployment.apps/vote     1/1     1            1           24s
deployment.apps/db       1/1     1            1           24s
deployment.apps/redis    1/1     1            1           24s
deployment.apps/result   1/1     1            1           24s
NAME                          READY   STATUS    RESTARTS   AGE
pod/db-684b9b49fd-t7k74       1/1     Running   0          23s
pod/vote-767f6d6d79-5qlhd     1/1     Running   0          23s
pod/worker-79bb99bfc6-jhn5r   1/1     Running   0          23s
pod/redis-67db9bd79b-99vs2    1/1     Running   0          23s
pod/result-8cfbc4889-c4z8c    1/1     Running   0          23s

然后,我们可以使用VM的IP和values.yaml中指定的nodePort(用于的31002,用于的31003 )访问voteandresult接口vote``result

使用Helm部署VotingApp

默认情况下worker使用java版本,我们可以通过查看worker规范来验证这一点:

代码语言:javascript
复制
# k0s kubectl get deploy/worker \
  -o jsonpath="{ .spec.template.spec.containers[0].image }"
lucj/voting:worker.java

如果我们想尝试一下dotnet版本,我们只需要升级发行版以提供我们想要更改的值,此操作将创建一个新的修订版:

代码语言:javascript
复制
# helm upgrade voting --set worker.image=lucj/voting:worker.dotnet .

然后,我们确保已正确更新部署,并且现在使用dotnet映像的版本:

代码语言:javascript
复制
# k0s kubectl get deploy/worker \
  -o jsonpath="{ .spec.template.spec.containers[0].image }"
lucj/voting:worker.dotnet

通过访问voteresultWeb界面,我们可以轻松地验证此新修订版本是否按预期工作。

如果我们想回到以前的版本,Helm也可以通过rollback使用以前的值创建该发行版的新修订的命令来提供帮助:

代码语言:javascript
复制
# helm rollback voting
Rollback was a success! Happy Helming!

再一次,我们可以验证worker的java镜像已经被使用,并且该应用程序可以正常工作。

然后,我们可以删除该应用程序:

代码语言:javascript
复制
# helm uninstall voting

我们仅通过一个简单的示例对Helm进行了说明,并使用了模板语言定义了几个属性,但是Helm确实具有更多功能,如您在文档中所看到的。在下一步中,我们将说明如何使用Kustomize部署应用程序。

Kustomize

Kustomize引入了一种无模板的方式来定制应用程序配置。它既可以作为独立二进制文件,也可以作为native功能使用kubectl。它基本上从yaml规范列表中定义了一个基准,并允许我们使用其他资源来重载该基准。让我们看看在VotingApp的上下文中这是如何工作的。

在配置库中,kustomize文件夹包含2个子文件夹:

代码语言:javascript
复制
# tree kustomize
kustomize/
├── base
│   ├── db-deployment.yaml
│   ├── db-service.yaml
│   ├── kustomization.yaml
│   ├── redis-deployment.yaml
│   ├── redis-service.yaml
│   ├── result-deployment.yaml
│   ├── result-service.yaml
│   ├── vote-deployment.yaml
│   ├── vote-service.yaml
│   └── worker-deployment.yaml
└── overlays
    └── demo
        ├── front-services.yaml
        ├── kustomization.yaml
        └── vote-ns.yaml
  • base子文件夹包含我们部署原始heml应用时我们所使用的那些YAML规范。该文件夹还包含kustomization.yaml基本上列出了构成基线的规范的文件夹。
代码语言:javascript
复制
# cat base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- db-deployment.yaml
- db-service.yaml
- redis-deployment.yaml
- redis-service.yaml
- result-deployment.yaml
- result-service.yaml
- vote-deployment.yaml
- vote-service.yaml
- worker-deployment.yaml

以下命令使用标准来部署此基准,kubectl apply但使用的是-k标志:

代码语言:javascript
复制
#k0s kubectl apply -k base /

在这里,我们可以检查所有Pod是否运行良好并可以与VotingApp一起运行:为我们最喜欢的动物投票并查看结果。

然后,我们可以使用相同的-k标志删除该应用程序:

代码语言:javascript
复制
#k0s kubectl delete -k base /
  • base文件夹旁边是overlays文件夹,其中包含一个demo子文件夹。最后一个包含几个文件,这些文件用于使base文件夹中现有的内容超载。基本上,从overlays/demo文件夹中部署应用程序就像使用来自基线的资源,对其进行修改,然后根据这些更改运行新版本的应用程序

demo文件夹包含一个定义vote名称空间的规范,

代码语言:javascript
复制
# cat overlays/demo/vote-ns.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: vote

另一个规范front-services.yaml用于重载voteresult服务,以重新定义nodePort的值,

代码语言:javascript
复制
# cat overlays/demo/front-services.yaml
apiVersion: v1
kind: Service
metadata:
  name: vote
spec:
  ports:
  - name: "vote-service"
    port: 5000
    targetPort: 80
    nodePort: 31010
---
apiVersion: v1
kind: Service
metadata:
  name: result
spec:
  ports:
  - name: "result-service"
    port: 5001
    targetPort: 80
    nodePort: 31011

最后,该kustomization.yaml文件定义了从demo文件夹部署应用程序时要考虑的资源:使用了基本清单,将投票清单添加到此列表,应用了战略合并来修改端口号,并且整个应用程序是进入vote命名空间。

代码语言:javascript
复制
# cat overlays/demo/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
bases:
- ../../base
resources:
- vote-ns.yaml
namespace: vote
patchesStrategicMerge:
- front-services.yaml

以下命令从overlays / demo部署VotingApp folder

代码语言:javascript
复制
#k0s kubectl apply -k overlays / demo /

然后,我们可以访问VotingApp并再次投票选出我们最喜欢的动物。该vote接口在端口31010上可用,而在端口31011上则可用result

通过Kustomize通过overlays/demo部署VotingApp

完成后,我们可以-k使用用于创建的相同标志删除应用程序。

代码语言:javascript
复制
#k0s kubectl delete -k base /

关键要点

在本文中,我们概述了可以在Kubernetes中部署应用程序的主要方式:

  • 使用原始Yaml specifications是管理应用程序的最简单但配置更少的方法
  • Heml是一种更可配置的方法。它使用模板语言,动态值,并简化了管理应用程序整个生命周期的过程。除了可以轻松分发Helm chart外,通过Helm chart还可以使用许多应用程序
  • Kustomize是另一种方法,它允许通过基本文件夹定义同一应用程序的多个版本,而该基本文件夹可以通过使用其他资源来重载。Kustomize使通过多个覆盖子文件夹轻松管理应用程序的多个版本

文丨Soundhearer

图丨来源于网络

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-04-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 云原生 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • VotingApp
  • 设置演示集群
  • Yaml规格
  • Helm
  • Kustomize
  • 关键要点
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档