Kubernetes部署应用的几种方式

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: Kubernetes部署应用的几种方式

在本文中,我们将使用示例微服务应用程序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),并使用vagrantVirtualBox进行安装。

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

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:

$ vagrant up

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

$ vagrant ssh
vagrant @ vagrant:〜$ sudo su-
root @ vagrant:〜#


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

# k0s kubectl get nodes

NAME     STATUS   ROLES   AGE   VERSION

vagrant   Ready   <none>   40s   v1.20.5-k0s1

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

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

Yaml规格

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

# 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所有创建应用程序:

#k0s kubectl apply -f manifests/

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

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

# 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

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

# k0s kubectl delete -f manifests

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

Helm

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

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


# 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中定义的值的引用(稍后会对此进行详细介绍):
# 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版本均可用):
# 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中定义
# cat values.yaml
vote:
port: 31002
result:
port: 31003
worker:
image: lucj/voting:worker.java

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

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

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

# helm upgrade voting --install --values values.yaml .

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

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都处于“运行”状态,以确保一切运行良好:

# 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规范来验证这一点:

# k0s kubectl get deploy/worker \

-o jsonpath="{ .spec.template.spec.containers[0].image }"

lucj/voting:worker.java

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

# helm upgrade voting --set worker.image=lucj/voting:worker.dotnet .

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

# k0s kubectl get deploy/worker \

-o jsonpath="{ .spec.template.spec.containers[0].image }"

lucj/voting:worker.dotnet

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

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

# helm rollback voting
Rollback was a success! Happy Helming!

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

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

# helm uninstall voting


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

Kustomize

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

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

# 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基本上列出了构成基线的规范的文件夹。


# 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标志:

#k0s kubectl apply -k base /

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

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

#k0s kubectl delete -k base /

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

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

# cat overlays/demo/vote-ns.yaml
apiVersion: v1
kind: Namespace
metadata:
name: vote

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

# 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命名空间。

# 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

#k0s kubectl apply -k overlays / demo /

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

通过Kustomize通过overlays/demo部署VotingApp

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

#k0s kubectl delete -k base /

关键要点

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

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


相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
28天前
|
存储 Kubernetes 持续交付
介绍一下Kubernetes的应用场景
【10月更文挑战第18天】介绍一下Kubernetes的应用场景。
125 3
|
1月前
|
Kubernetes 持续交付 Docker
利用 Docker 和 Kubernetes 实现微服务部署
【10月更文挑战第2天】利用 Docker 和 Kubernetes 实现微服务部署
|
1月前
|
Prometheus Kubernetes 监控
k8s部署针对外部服务器的prometheus服务
通过上述步骤,您不仅成功地在Kubernetes集群内部署了Prometheus,还实现了对集群外服务器的有效监控。理解并实施网络配置是关键,确保监控数据的准确无误传输。随着监控需求的增长,您还可以进一步探索Prometheus生态中的其他组件,如Alertmanager、Grafana等,以构建完整的监控与报警体系。
122 60
|
1月前
|
Prometheus Kubernetes 监控
k8s部署针对外部服务器的prometheus服务
通过上述步骤,您不仅成功地在Kubernetes集群内部署了Prometheus,还实现了对集群外服务器的有效监控。理解并实施网络配置是关键,确保监控数据的准确无误传输。随着监控需求的增长,您还可以进一步探索Prometheus生态中的其他组件,如Alertmanager、Grafana等,以构建完整的监控与报警体系。
213 62
|
9天前
|
监控 持续交付 Docker
Docker 容器化部署在微服务架构中的应用有哪些?
Docker 容器化部署在微服务架构中的应用有哪些?
|
9天前
|
监控 持续交付 Docker
Docker容器化部署在微服务架构中的应用
Docker容器化部署在微服务架构中的应用
|
17天前
|
JavaScript 持续交付 Docker
解锁新技能:Docker容器化部署在微服务架构中的应用
【10月更文挑战第29天】在数字化转型中,微服务架构因灵活性和可扩展性成为企业首选。Docker容器化技术为微服务的部署和管理带来革命性变化。本文探讨Docker在微服务架构中的应用,包括隔离性、可移植性、扩展性、版本控制等方面,并提供代码示例。
54 1
|
26天前
|
JSON Kubernetes 容灾
ACK One应用分发上线:高效管理多集群应用
ACK One应用分发上线,主要介绍了新能力的使用场景
|
1月前
|
应用服务中间件 调度 nginx
Kubernetes的Pod调度:让你的应用像乘坐头等舱!
Kubernetes的Pod调度:让你的应用像乘坐头等舱!
|
28天前
|
存储 Kubernetes 监控
深度解析Kubernetes在微服务架构中的应用与优化
【10月更文挑战第18天】深度解析Kubernetes在微服务架构中的应用与优化
103 0
下一篇
无影云桌面