<$>[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教程
- 一个活跃的Docker Hub(https://hub.docker.com/)帐户来存储应用程序的Docker
步骤 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**选项卡:
您可以看到,每个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。
使用kubectl
将Web
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 应用程序。
您可以通过增加 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。