网络研讨会系列:在 Kubernetes 中部署有状态服务

<$>[note] 本文补充了关于部署和管理云中的集装箱工作负载的Webinar系列(https://go.digitalocean.com/containers-and-microservices-webinars-series)。该系列涵盖了集装箱的基本内容,包括管理集装箱生命周期,部署多集装箱应用程序,扩展工作负载,以及与Kubernetes合作。

本教程包括系列第五个会话中的概念和命令,在Kubernetes中部署国家服务 <$>

[youtube _zPuVGh2z9c 480 854 ]

介绍

Kubernetes是一个开源集装箱编排工具,用于管理集装箱应用程序. 在本系列的以前部分中,您了解了Kubernetes和包装集装箱的构建块,作为Kubernetes ReplicaSets。

虽然在 Kubernetes 中包装,部署,管理和扩展当代云原生应用程序可能很容易,但在集装箱化环境中部署和管理传统工作负载,如数据库和内容管理系统,需要采取不同的方法。

在本教程系列的最后一部分中,您将部署一个高度可用的MongoDB ReplicaSet在Kubernetes中作为一个StatefulSet使用 Helm,一个流行的开源包管理器为Kubernetes。

前提条件

要完成本教程,您将需要:

通过 StackPointCloud安装,在DigitalOcean上运行的活跃的Kubernetes群集,您可以通过使用教程 Getting Started with Kubernetes来完成此操作。 *本教程中引入的示例Web应用程序 Deploying and Scaling Microservices in Kubernetes,该教程基于Node.js和MongoDB,以便为数据库带来高可用性。有关应用程序设计的详细信息,请参阅教程 Building Containerized Applications教程

步骤 1 – 在开发机器上安装头盔客户端

使用Helm,管理员可以使用单个命令部署复杂的Kubernetes应用程序。应用程序包装为图表,定义、安装和升级Kubernetes应用程序。

赫尔姆有两个组件:服务器和客户端.赫尔姆的服务器侧运行在Kubernetes中作为一个名为Tiller的服务。

由于您将部署 MongoDB ReplicaSet Helm 图表,您需要与 Helm 的服务器端组件 Tiller 交谈的 CLI。

<$>[注] :此说明适用于 macOS. 如果您正在使用其他操作系统,请参阅 Helm 安装指南

假设您在 Mac 上安装并配置了 Homebrew,请运行以下命令来安装 Helm:

1brew install kubernetes-helm
1[secondary_label Output]
2==> Downloading https://homebrew.bintray.com/bottles/kubernetes-helm-2.8.2.high_sierra.bottle.tar.gz
3...
4==> Summary
5🍺  /usr/local/Cellar/kubernetes-helm/2.8.2: 50 files, 121.7MB

一旦 Helm 安装,请通过检查其当前版本来验证您是否可以运行它。

1helm version
1[secondary_label Output]
2Client: &version.Version{SemVer:"v2.7.2", GitCommit:"8478fb4fc723885b155c924d1c8c410b7a9444e6", GitTreeState:"clean"}
3Server: &version.Version{SemVer:"v2.8.2", GitCommit:"a80231648a1473929271764b920a8e346f6de844", GitTreeState:"clean"}

这确认客户端已正确安装并能够与Tiller交谈。

在下一步中,我们将使用Helm在Kubernetes中部署MongoDB ReplicaSet。

步骤 2 – 在 Kubernetes 中部署 MongoDB ReplicaSet

Kubernetes 中的 StorageClass 为管理员提供了描述他们提供的存储的方法,例如,当用户要求存储量时,StorageClass 会确定他们提供的存储备份类别。

由于您需要永久性存储来存储 MongoDB 数据,您可能需要将 DigitalOcean Block Storage 容量附加到工作节点,并指向 MongoDB Pod 将存储容量用于永久性。

在这种情况下,StorageClass 作为 Pod 和 DigitalOcean 区块存储服务之间的接口。当您请求区块存储量时,StorageClass 会与预配置的驱动程序交谈,该驱动程序知道如何分配区块存储量。

StackPointCloud 安装了 DigitalOcean 存储驱动程序,并在安装过程中在 Kubernetes 中注册 StorageClass,从而节省了安装和配置驱动程序和 StorageClass 的步骤。

在部署 MongoDB 集群之前,让我们确保为 DigitalOcean 卷配置 StorageClass:

1kubectl get storageclass

输出确认 StorageClass 已配置并准备好。

1[secondary_label Output
2NAME PROVISIONER AGE
3digitalocean (default)   digitalocean/flex-volume-provisioner 1d

接下来,您将根据DigitalOcean StorageClass配置和部署MongoDB ReplicaSet。

为您的项目创建一个新目录,然后切换到新目录:

1mkdir ~/mongo-rs
2cd ~/mongo-rs

从 GitHub 克隆 Helm Chart 存储:

1git clone https://github.com/kubernetes/charts.git

导航到 MongoDB ReplicaSet 目录(charts/stable/mongodb-replicaset/)并验证文件 values.yaml 是否存在。

1cd charts/stable/mongodb-replicaset/
2ls values.yaml
1[secondary_label Output]
2values.yaml

此文件包含图表的参数和配置. 您需要修改此文件以配置 MongoDB ReplicaSet 以使用 DigitalOcean StorageClass。

此分類上一篇: values.yaml

1nano values.yaml

查找和删除下列部分:

1[label values.yaml]
2...
3# storageClass: "-" 
4...

digitalocean来代替"-,如下:

1[label values.yaml]
2...
3storageClass: "digitalocean"
4...

保存文件并离开编辑器。

现在导航到~/mongo-rs文件夹。

1cd ~/mongo-rs

您现在已经准备好将 MongoDB ReplicaSet 部署到您的 Kubernetes 集群中,该集群由 DigitalOcean 的区块存储提供支持。

1helm install --name=todo -f charts/stable/mongodb-replicaset/values.yaml stable/mongodb-replicaset

在之前的命令中, --name 指的是 Helm 图表的名称. 开关 -f' 指的是在 values.yaml' 中存储的配置设置。

您将立即看到输出,确认图表创建已经开始。

 1[secondary_label Output]
 2NAME:   todo
 3LAST DEPLOYED: Sat Mar 31 10:37:06 2018
 4NAMESPACE: default
 5STATUS: DEPLOYED
 6
 7RESOURCES:
 8==> v1/Service
 9NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)    AGE
10todo-mongodb-replicaset ClusterIP None        <none>       27017/TCP 1s
11
12==> v1beta1/StatefulSet
13NAME DESIRED CURRENT AGE
14todo-mongodb-replicaset 3 1 0s
15
16==> v1/Pod(related)
17NAME READY STATUS RESTARTS AGE
18todo-mongodb-replicaset-0 0/1 Init:0/2 0 0s
19
20==> v1/ConfigMap
21NAME DATA AGE
22todo-mongodb-replicaset 1 1s
23todo-mongodb-replicaset-tests 1 1s
24
25NOTES:
261. After the statefulset is created completely, one can check which instance is primary by running:
27
28    $ for ((i = 0; i < 3; ++i)); do kubectl exec --namespace default todo-mongodb-replicaset-$i -- sh -c 'mongo --eval="printjson(rs.isMaster())"'; done
29
302. One can insert a key into the primary instance of the mongodb replica set by running the following:
31    MASTER_POD_NAME must be replaced with the name of the master found from the previous step.
32
33    $ kubectl exec --namespace default MASTER_POD_NAME -- mongo --eval="printjson(db.test.insert({key1: 'value1'}))"
34
353. One can fetch the keys stored in the primary or any of the slave nodes in the following manner.
36    POD_NAME must be replaced by the name of the pod being queried.
37
38    $ kubectl exec --namespace default POD_NAME -- mongo --eval="rs.slaveOk(); db.test.find().forEach(printjson)"

现在,让我们运行一系列命令来跟踪集群的状态。

首先,看看国家实习:

1kubectl get statefulset

此命令确认 MongoDB ReplicaSet 是作为 Kubernetes StatefulSet 创建的。

1[secondary_label Output]
2NAME DESIRED CURRENT AGE
3todo-mongodb-replicaset 3 2 2m

现在探索Pods:

1kubectl get pods

Pod 的数量及其命名公约表明 MongoDB ReplicaSet 已成功配置:

1[secondary_label Output]
2NAME READY STATUS RESTARTS AGE
3todo-mongodb-replicaset-0 1/1 Running 0 3m
4todo-mongodb-replicaset-1 1/1 Running 0 1m
5todo-mongodb-replicaset-2 1/1 Running 0 54s

请注意,每个Pod都有一个序列号结束的序列,这是一个StatefulSet的独特特性。

现在让我们检查MongoDB实例是否彼此通信,我们将通过在一个Pod中运行MongoDB壳中的命令来做到这一点。

使用kubectl在其中一个主机上启动mongo控制台:

1kubectl exec -it todo-mongodb-replicaset-0 mongo

连接后,你会在MongoDB壳中找到自己:

1[secondary_label Output]
2MongoDB shell version v3.6.3
3connecting to: mongodb://127.0.0.1:27017
4MongoDB server version: 3.6.3
5Welcome to the MongoDB shell.
6For interactive help, type "help".
7...
8
92018-03-31T05:08:20.239+0000 I CONTROL  [initandlisten]

通过以下命令检查 ReplicaSet 的配置:

1rs.conf()

输出确认有三个 MongoDB 实例作为 ReplicaSet 运行。

 1[secondary_label Output]
 2{
 3    "_id" : "rs0",
 4    "version" : 3,
 5    "protocolVersion" : NumberLong(1),
 6    "members" : [
 7    	{
 8    		"_id" : 0,
 9    		"host" : "todo-mongodb-replicaset-0.todo-mongodb-replicaset.default.svc.cluster.local:27017",
10    		"arbiterOnly" : false,
11    		"buildIndexes" : true,
12    		"hidden" : false,
13    		"priority" : 1,
14    		"tags" : {
15
16    		},
17    		"slaveDelay" : NumberLong(0),
18    		"votes" : 1
19    	},
20    	{
21    		"_id" : 1,
22    		"host" : "todo-mongodb-replicaset-1.todo-mongodb-replicaset.default.svc.cluster.local:27017",
23    		"arbiterOnly" : false,
24    		"buildIndexes" : true,
25    		"hidden" : false,
26    		"priority" : 1,
27    		"tags" : {
28
29    		},
30    		"slaveDelay" : NumberLong(0),
31    		"votes" : 1
32    	},
33    	{
34    		"_id" : 2,
35    		"host" : "todo-mongodb-replicaset-2.todo-mongodb-replicaset.default.svc.cluster.local:27017",
36    		"arbiterOnly" : false,
37    		"buildIndexes" : true,
38    		"hidden" : false,
39    		"priority" : 1,
40    		"tags" : {
41
42    		},
43    		"slaveDelay" : NumberLong(0),
44    		"votes" : 1
45    	}
46    ],
47    "settings" : {
48    	"chainingAllowed" : true,
49    	"heartbeatIntervalMillis" : 2000,
50    	"heartbeatTimeoutSecs" : 10,
51    	"electionTimeoutMillis" : 10000,
52    	"catchUpTimeoutMillis" : -1,
53    	"catchUpTakeoverDelayMillis" : 30000,
54    	"getLastErrorModes" : {
55
56    	},
57    	"getLastErrorDefaults" : {
58    		"w" : 1,
59    		"wtimeout" : 0
60    	},
61    	"replicaSetId" : ObjectId("5abdb4f61d952afc4b0b8218")
62    }
63}

退出 MongoDB 控制台:

1exit

这也将使您与远程主机断开连接。

让我们切换变速器,并在DigitalOcean控制面板上查找与集群相关的区块存储量。登录您的DigitalOcean帐户并选择 ** Volumes**选项卡:

Dashboard showing volumes

您可以看到,每个10GB的3卷都附加到Kubernetes工作节点上。MongoDB StatefulSet的每个Pod都将数据存储在其中一个区块存储量中。

 1[label values.yaml]
 2persistentVolume:
 3  enabled: true
 4  ## mongodb-replicaset data Persistent Volume Storage Class
 5  ## If defined, storageClassName: <storageClass>
 6  ## If set to "-", storageClassName: "", which disables dynamic provisioning
 7  ## If undefined (the default) or set to null, no storageClassName spec is
 8  ##   set, choosing the default provisioner.  (gp2 on AWS, standard on
 9  ##   GKE, AWS & OpenStack)
10  ##
11  storageClass: digitalocean
12  accessModes:
13    - ReadWriteOnce
14  size: 10Gi
15  annotations: {}

您已成功配置在 Kubernetes 中运行的高可用性 MongoDB ReplicaSet。

现在让我们部署与 MongoDB 集群交谈的 Web 应用程序。

步骤 3 – 在 Kubernetes 中部署和扩展 Web 应用程序

让我们扩展我们在本教程系列前部分使用的 ToDo Node.js 应用程序,以利用 MongoDB 集群。

<$>[注] :您也可以从源代码构建容器图像或直接使用 Kubernetes 文件中的 YAML 文件。 请参阅教程 在 Kubernetes 中部署和扩展微服务 有关构建图像和部署应用程序到 Kubernetes 的步骤。

开始创建一个新的工作目录:

1mkdir ~/web-app
2cd ~/web-app

然后克隆包含代码和 Kubernetes 文物的 ToDo 应用程序存储库。

1git clone https://github.com/janakiramm/todo.git

切换到包含 Kubernetes 配置文件的todo-app/kubernetes目录。

1cd todo-app/kubernetes

在您的编辑器中打开文件 web-rs-ss.yaml

1nano web-rs-ss.yaml

请注意 YAML 文件上的env部分。

1[label web-rs-ss.yaml]
2      containers:
3      - name: web 
4        image: janakiramm/todo
5        env:
6          - name: "DBHOST"
7            value: "mongodb://todo-mongodb-replicaset-0.todo-mongodb-replicaset,todo-mongodb-replicaset-1.todo-mongodb-replicaset,todo-mongodb-replicaset-2.todo-mongodb-replicaset:27017"
8        ports:
9        - containerPort: 3000

这将数据库连接字符串作为环境变量在运行时传递给应用程序,而不是将应用程序指向一个简单的MongoDB Pod,该版本的应用程序使用您创建的StatefulSet。

使用kubectlWeb ReplicaSet 与Web服务一起部署

1kubectl create -f web-rs-ss.yaml -f web-service.yaml

你会看到这两者都是创造的:

1[secondary_label Output]
2replicaset "web" created
3service "web" created

再次列出子:

1kubectl get pods

现在你可以看到所有属于MongoDB和Web应用程序的Pods。

 1[secondary_label Output]
 2NAME READY STATUS RESTARTS AGE
 3todo-mongodb-replicaset-0 1/1 Running 0 26m
 4todo-mongodb-replicaset-1 1/1 Running 0 24m
 5todo-mongodb-replicaset-2 1/1 Running 0 23m
 6web-t5zzk 1/1 Running 0 17s
 7web-x6dh8 1/1 Running 0 17s
 8
 9Let’s check out the Kubernetes services
10
11​```command
12kubectl get svc
1[secondary_label Output]
2NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)          AGE
3kubernetes ClusterIP 10.3.0.1     <none>        443/TCP 1d
4todo-mongodb-replicaset ClusterIP None         <none>        27017/TCP 27m
5web NodePort 10.3.0.167   <none>        3000:31201/TCP 14s

web Pods 通过todo-mongodb-replicaset服务与 MongoDB 集群进行交谈。

在任何工人节点上访问此端口显示 Web 应用程序。

The live Todo list app

您可以通过增加 ReplicaSet 中的 Pods 数量来扩展 Web 应用程序。

1kubectl scale rs/web --replicas=10
1[secondary_label Output]
2replicaset "web" scaled

然后,您可以将应用程序扩展到两个Pod。

1kubectl scale rs/web --replicas=2
1[secondary_label Output]
2replicaset "web" scaled

现在让我们运行一些可用性测试。

步骤 4 – 测试 MongoDB ReplicaSet 以获得高可用性

运行 StatefulSet 的优点之一是工作负载的高可用性. 让我们通过在 MongoDB StatefulSet 中删除一个 Pods 来测试这一点。

1kubectl delete pod todo-mongodb-replicaset-2
1[secondary_label Output]
2pod "todo-mongodb-replicaset-2" deleted

点击查看 Pods 的数量:

1kubectl get pods

你会看到‘todo-mongodb-replicaset-2’正在终止:

1[secondary_label Output]
2NAME READY STATUS RESTARTS AGE
3todo-mongodb-replicaset-0 1/1 Running 0 33m
4todo-mongodb-replicaset-1 1/1 Running 0 32m
5todo-mongodb-replicaset-2 0/1 Terminating 0 31m
6web-t5zzk 1/1 Running 0 8m
7web-x6dh8 1/1 Running 0 8m

在几分钟内,你会看到Kubernetes会初始化另一个Pod,以取代已删除的Pod。

1kubectl get pods

您将看到todo-mongodb-replicaset-2正在初始化:

1NAME READY STATUS RESTARTS AGE
2todo-mongodb-replicaset-0 1/1 Running 0 34m
3todo-mongodb-replicaset-1 1/1 Running 0 33m
4todo-mongodb-replicaset-2 0/1 Init:0/2 0 29s
5web-t5zzk 1/1 Running 0 8m
6web-x6dh8 1/1 Running 0 8m

现在你知道一切都起作用了,你可以清理事情。

使用以下命令删除本教程中创建的所有对象:

1helm delete --purge todo
1kubectl delete -f web-rs-ss.yaml -f web-service.yaml
1[secondary_label Output]
2replicaset "web" deleted
3service "web" deleted

要删除Kubernetes集群本身,请访问StackPointCloud,并通过其控制面板进行删除。

结论

在本教程中,您部署了耐用,持久,高度可用的 MonogDB ReplicaSet 作为 Kubernetes StatefulSet。

Published At
Categories with 技术
Tagged with
comments powered by Disqus