如何将DockerCompose工作流迁移到Kubernetes
介绍
在构建现代的无状态应用程序时, 将应用程序的组件容器化 是在分布式平台上部署和扩展的第一步。 如果您在开发中使用了 Docker Compose,您将通过以下方式对您的应用程序进行现代化和容器化:
- 从代码中提取必要的配置信息。
- 卸载应用程序的状态。
- 打包您的应用程序以供重复使用。
您还将编写指定容器映像应如何运行的服务定义。
要在 Kubernetes 等分布式平台上运行您的服务,您需要将 Compose 服务定义转换为 Kubernetes 对象。 这将允许您 以弹性 扩展您的应用程序。 kompose 是一种可以加快向 Kubernetes 的转换过程的工具,它是一种转换工具,可帮助开发人员将 Compose 工作流迁移到 Kubernetes 或 OpenShift 等容器编排器。
在本教程中,您将使用 kompose 将 Compose 服务转换为 Kubernetes objects。 您将使用 kompose 提供的对象定义作为起点并进行调整,以确保您的设置将使用 Secrets、Services 和 PersistentVolumeClaims Kubernetes 所期望的。 在本教程结束时,您将拥有一个单实例 Node.js 应用程序,其中包含在 Kubernetes 集群上运行的 MongoDB 数据库。 此设置将反映 使用 Docker Compose 将 Node.js 应用程序容器化 中描述的代码的功能,并将成为构建可根据您的需求扩展的生产就绪解决方案的良好起点。
先决条件
- 启用了基于角色的访问控制 (RBAC) 的 Kubernetes 1.10+ 集群。 此设置将使用 DigitalOcean Kubernetes 集群,但您可以自由地 使用另一种方法 创建集群。
kubectl
命令行工具安装在您的本地机器或开发服务器上并配置为连接到您的集群。 您可以在官方文档中阅读更多关于安装kubectl
的信息。- Docker 安装在本地机器或开发服务器上。 如果您使用的是 Ubuntu 18.04,请按照 如何在 Ubuntu 18.04 上安装和使用 Docker 的步骤 1 和 2; 否则,请按照 官方文档 了解有关在其他操作系统上安装的信息。 确保将您的非 root 用户添加到
docker
组,如链接教程的第 2 步所述。 - 一个 Docker Hub 帐户。 有关如何设置的概述,请参阅 this Introduction to Docker Hub。
第 1 步 — 安装 kompose
要开始使用 kompose,请导航到 项目的 GitHub 发布页面 ,并将链接复制到当前版本(撰写本文时版本 1.18.0)。 将此链接粘贴到以下 curl
命令中以下载最新版本的 kompose:
curl -L https://github.com/kubernetes/kompose/releases/download/v1.18.0/kompose-linux-amd64 -o kompose
关于在非Linux系统上安装的详细信息,请参考【X71X】安装说明【X100X】。
使二进制可执行文件:
chmod +x kompose
将其移至您的 PATH
:
sudo mv ./kompose /usr/local/bin/kompose
要验证它是否已正确安装,您可以进行版本检查:
kompose version
如果安装成功,您将看到如下输出:
Output1.18.0 (06a2e56)
安装 kompose
并准备好使用后,您现在可以克隆您将要翻译到 Kubernetes 的 Node.js 项目代码。
第 2 步 — 克隆和打包应用程序
要将我们的应用程序与 Kubernetes 一起使用,我们需要克隆项目代码并打包应用程序,以便 kubelet
服务可以拉取镜像。
我们的第一步是从 DigitalOcean 社区 GitHub 帐户 克隆 node-mongo-docker-dev 存储库。 此存储库包含 Containerizing a Node.js Application for Development With Docker Compose 中描述的设置中的代码,它使用演示 Node.js 应用程序来演示如何使用 Docker Compose 设置开发环境。 您可以在 From Containers to Kubernetes with Node.js 系列中找到有关应用程序本身的更多信息。
将存储库克隆到名为 node_project
的目录中:
git clone https://github.com/do-community/node-mongo-docker-dev.git node_project
导航到 node_project
目录:
cd node_project
node_project
目录包含用于处理用户输入的鲨鱼信息应用程序的文件和目录。 它已经现代化,可以与容器一起使用:敏感和特定的配置信息已从应用程序代码中删除并重构为在运行时注入,应用程序的状态已卸载到 MongoDB 数据库。
有关设计现代无状态应用程序的更多信息,请参阅 为 Kubernetes 构建应用程序 和 为 Kubernetes 现代化应用程序。
项目目录包含一个 Dockerfile
,其中包含构建应用程序映像的说明。 现在让我们构建映像,以便您可以将其推送到您的 Docker Hub 帐户并在您的 Kubernetes 设置中使用它。
使用 docker build 命令,使用 -t
标志构建映像,这允许您使用易于记忆的名称对其进行标记。 在这种情况下,使用您的 Docker Hub 用户名标记图像并将其命名为 node-kubernetes
或您自己选择的名称:
docker build -t your_dockerhub_username/node-kubernetes .
命令中的 .
指定构建上下文是当前目录。
构建映像需要一两分钟。 完成后,检查您的图像:
docker images
您将看到以下输出:
OutputREPOSITORY TAG IMAGE ID CREATED SIZE your_dockerhub_username/node-kubernetes latest 9c6f897e1fbc 3 seconds ago 90MB node 10-alpine 94f3c8956482 12 days ago 71MB
接下来,登录到您在先决条件中创建的 Docker Hub 帐户:
docker login -u your_dockerhub_username
出现提示时,输入您的 Docker Hub 帐户密码。 以这种方式登录将使用您的 Docker Hub 凭据在用户的主目录中创建一个 ~/.docker/config.json
文件。
使用 docker push 命令 将应用程序镜像推送到 Docker Hub。 请记住将 your_dockerhub_username
替换为您自己的 Docker Hub 用户名:
docker push your_dockerhub_username/node-kubernetes
您现在有一个应用程序映像,您可以拉取该映像以使用 Kubernetes 运行您的应用程序。 下一步是将您的应用程序服务定义转换为 Kubernetes 对象。
第 3 步 — 使用 kompose 将 Compose 服务转换为 Kubernetes 对象
我们的 Docker Compose 文件(此处称为 docker-compose.yaml
)列出了将使用 Compose 运行我们的服务的定义。 Compose 中的 服务 是一个正在运行的容器,而 服务定义 包含有关每个容器映像将如何运行的信息。 在这一步中,我们将通过使用 kompose 创建 yaml
文件将这些定义转换为 Kubernetes 对象。 这些文件将包含 Kubernetes 对象的 specs,描述它们的 期望状态 。
我们将使用这些文件来创建不同类型的对象:Services,这将确保运行我们容器的 Pods 保持可访问性; Deployments,它将包含有关我们的 Pod 所需状态的信息; PersistentVolumeClaim 为我们的数据库数据提供存储; 一个 ConfigMap 用于在运行时注入的环境变量; 以及我们应用程序的数据库用户和密码的 Secret。 其中一些定义将在 kompose 为我们创建的文件中,而其他定义则需要我们自己创建。
首先,我们需要修改 docker-compose.yaml
文件中的一些定义以使用 Kubernetes。 我们将在我们的 nodejs
服务定义中包含对我们新建应用程序映像的引用,并删除 绑定 mounts、volumes 和其他 命令[X183X ] 我们曾经使用 Compose 在开发中运行应用程序容器。 此外,我们将重新定义两个容器的重启策略以符合 Kubernetes 期望的行为 。
使用 nano
或您喜欢的编辑器打开文件:
nano docker-compose.yaml
nodejs
应用程序服务的当前定义如下所示:
~/node_project/docker-compose.yaml
... services: nodejs: build: context: . dockerfile: Dockerfile image: nodejs container_name: nodejs restart: unless-stopped env_file: .env environment: - MONGO_USERNAME=$MONGO_USERNAME - MONGO_PASSWORD=$MONGO_PASSWORD - MONGO_HOSTNAME=db - MONGO_PORT=$MONGO_PORT - MONGO_DB=$MONGO_DB ports: - "80:8080" volumes: - .:/home/node/app - node_modules:/home/node/app/node_modules networks: - app-network command: ./wait-for.sh db:27017 -- /home/node/app/node_modules/.bin/nodemon app.js ...
对您的服务定义进行以下编辑:
- 使用您的
node-kubernetes
图像而不是本地Dockerfile
。 - 将容器
restart
策略从unless-stopped
更改为always
。 - 删除
volumes
列表和command
指令。
完成的服务定义现在将如下所示:
~/node_project/docker-compose.yaml
... services: nodejs: image: your_dockerhub_username/node-kubernetes container_name: nodejs restart: always env_file: .env environment: - MONGO_USERNAME=$MONGO_USERNAME - MONGO_PASSWORD=$MONGO_PASSWORD - MONGO_HOSTNAME=db - MONGO_PORT=$MONGO_PORT - MONGO_DB=$MONGO_DB ports: - "80:8080" networks: - app-network ...
接下来,向下滚动到 db
服务定义。 在这里,进行以下编辑:
- 将服务的
restart
策略更改为always
。 - 删除
.env
文件。 我们将使用 步骤 4 中创建的 Secret 将MONGO_INITDB_ROOT_USERNAME
和MONGO_INITDB_ROOT_PASSWORD
的值传递给数据库容器,而不是使用.env
文件中的值。
db
服务定义现在看起来像这样:
~/node_project/docker-compose.yaml
... db: image: mongo:4.1.8-xenial container_name: db restart: always environment: - MONGO_INITDB_ROOT_USERNAME=$MONGO_USERNAME - MONGO_INITDB_ROOT_PASSWORD=$MONGO_PASSWORD volumes: - dbdata:/data/db networks: - app-network ...
最后,在文件底部,从顶级 volumes
键中删除 node_modules
卷。 密钥现在看起来像这样:
~/node_project/docker-compose.yaml
... volumes: dbdata:
完成编辑后保存并关闭文件。
在翻译我们的服务定义之前,我们需要编写 .env
文件,kompose 将使用它来使用我们的非敏感信息创建 ConfigMap。 请参阅 Containerizing a Node.js Application for Development With Docker Compose 的 Step 2 以了解此文件的详细说明。
在那个教程中,我们将 .env
添加到我们的 .gitignore
文件中,以确保它不会复制到版本控制中。 这意味着当我们在本教程的 步骤 2 中克隆 node-mongo-docker-dev 存储库 时,它没有复制。 因此,我们现在需要重新创建它。
创建文件:
nano .env
kompose 将使用这个文件为我们的应用程序创建一个 ConfigMap。 但是,我们不会在 Compose 文件中分配来自 nodejs
服务定义的所有变量,而是仅添加 MONGO_DB
数据库名称和 MONGO_PORT
。 我们在Step 4手动创建Secret对象时,会分别分配数据库用户名和密码。
将以下端口和数据库名称信息添加到 .env
文件中。 如果您愿意,请随意重命名您的数据库:
~/node_project/.env
MONGO_PORT=27017 MONGO_DB=sharkinfo
完成编辑后保存并关闭文件。
您现在已准备好使用您的对象规范创建文件。 kompose 提供 多种选项 用于翻译您的资源。 你可以:
- 根据
docker-compose.yaml
文件和kompose convert
中的服务定义创建yaml
文件。 - 直接使用
kompose up
创建 Kubernetes 对象。 - 使用
kompose convert -c
创建一个 Helm 图表。
现在,我们将我们的服务定义转换为 yaml
文件,然后添加和修改 kompose 创建的文件。
使用以下命令将您的服务定义转换为 yaml
文件:
kompose convert
您还可以使用 -f
标志命名特定或多个 Compose 文件。
运行此命令后,kompose 将输出有关它创建的文件的信息:
OutputINFO Kubernetes file "nodejs-service.yaml" created INFO Kubernetes file "db-deployment.yaml" created INFO Kubernetes file "dbdata-persistentvolumeclaim.yaml" created INFO Kubernetes file "nodejs-deployment.yaml" created INFO Kubernetes file "nodejs-env-configmap.yaml" created
其中包括 yaml
文件,其中包含 Node 应用程序服务、部署和 ConfigMap 以及 dbdata
PersistentVolumeClaim 和 MongoDB 数据库部署的规范。
这些文件是一个很好的起点,但是为了使我们的应用程序的功能与 Containerizing a Node.js Application for Development With Docker Compose 中描述的设置相匹配,我们需要对kompose 生成的文件。
第 4 步 — 创建 Kubernetes 机密
为了让我们的应用程序以我们期望的方式运行,我们需要对 kompose 创建的文件进行一些修改。 这些更改中的第一个将为我们的数据库用户和密码生成一个 Secret,并将其添加到我们的应用程序和数据库部署中。 Kubernetes 提供了两种使用环境变量的方式:ConfigMaps 和 Secrets。 kompose 已经使用我们在 .env
文件中包含的非机密信息创建了一个 ConfigMap,因此我们现在将使用我们的机密信息创建一个 Secret:我们的数据库用户名和密码。
手动创建 Secret 的第一步是将您的用户名和密码转换为 base64,这是一种允许您统一传输数据(包括二进制数据)的编码方案。
转换您的数据库用户名:
echo -n 'your_database_username' | base64
记下您在输出中看到的值。
接下来,转换您的密码:
echo -n 'your_database_password' | base64
还要注意此处输出中的值。
打开 Secret 文件:
nano secret.yaml
注意:Kubernetes对象是通常使用YAML定义,严格禁止制表符,缩进需要两个空格。 如果您想检查任何 yaml
文件的格式,可以使用 linter 或使用 kubectl create
和 --dry-run
和 --validate
标志:
kubectl create -f your_yaml_file.yaml --dry-run --validate=true
通常,在使用 kubectl
创建资源之前验证您的语法是个好主意。
将以下代码添加到文件中以创建一个 Secret,它将使用您刚刚创建的编码值定义您的 MONGO_USERNAME
和 MONGO_PASSWORD
。 请务必将此处的虚拟值替换为您的 编码 用户名和密码:
~/node_project/secret.yaml
apiVersion: v1 kind: Secret metadata: name: mongo-secret data: MONGO_USERNAME: your_encoded_username MONGO_PASSWORD: your_encoded_password
我们已将 Secret 对象命名为 mongo-secret
,但您可以随意命名它。
完成编辑后保存并关闭此文件。 正如您对 .env
文件所做的那样,请务必将 secret.yaml
添加到 .gitignore
文件中以使其不受版本控制。
编写 secret.yaml
后,下一步将确保我们的应用程序和数据库 Pod 都使用我们添加到文件中的值。 让我们首先将对 Secret 的引用添加到我们的应用程序部署中。
打开名为 nodejs-deployment.yaml
的文件:
nano nodejs-deployment.yaml
该文件的容器规范包括在 env
键下定义的以下环境变量:
~/node_project/nodejs-deployment.yaml
apiVersion: extensions/v1beta1 kind: Deployment ... spec: containers: - env: - name: MONGO_DB valueFrom: configMapKeyRef: key: MONGO_DB name: nodejs-env - name: MONGO_HOSTNAME value: db - name: MONGO_PASSWORD - name: MONGO_PORT valueFrom: configMapKeyRef: key: MONGO_PORT name: nodejs-env - name: MONGO_USERNAME
我们需要将 Secret 的引用添加到此处列出的 MONGO_USERNAME
和 MONGO_PASSWORD
变量中,以便我们的应用程序可以访问这些值。 我们将包含一个 configMapKeyRef
键来指向我们的 nodejs-env
ConfigMap,而不是像 MONGO_DB
和 MONGO_PORT
的值那样包含一个secretKeyRef
键指向我们的 mongo-secret
密钥中的值。
将以下 Secret 引用添加到 MONGO_USERNAME
和 MONGO_PASSWORD
变量:
~/node_project/nodejs-deployment.yaml
apiVersion: extensions/v1beta1 kind: Deployment ... spec: containers: - env: - name: MONGO_DB valueFrom: configMapKeyRef: key: MONGO_DB name: nodejs-env - name: MONGO_HOSTNAME value: db - name: MONGO_PASSWORD valueFrom: secretKeyRef: name: mongo-secret key: MONGO_PASSWORD - name: MONGO_PORT valueFrom: configMapKeyRef: key: MONGO_PORT name: nodejs-env - name: MONGO_USERNAME valueFrom: secretKeyRef: name: mongo-secret key: MONGO_USERNAME
完成编辑后保存并关闭文件。
接下来,我们将相同的值添加到 db-deployment.yaml
文件中。
打开文件进行编辑:
nano db-deployment.yaml
在此文件中,我们将为以下变量键添加对 Secret 的引用:MONGO_INITDB_ROOT_USERNAME
和 MONGO_INITDB_ROOT_PASSWORD
。 mongo
图像使这些变量可用,以便您可以修改数据库实例的初始化。 MONGO_INITDB_ROOT_USERNAME
和MONGO_INITDB_ROOT_PASSWORD
一起在admin
鉴权数据库中创建一个root
用户,并保证在数据库容器启动时启用鉴权。
使用我们在 Secret 中设置的值可确保我们将拥有一个在数据库实例上具有 root 权限 的应用程序用户,并可以访问该角色的所有管理和操作权限。 在生产中工作时,您需要创建一个具有适当范围权限的专用应用程序用户。
在 MONGO_INITDB_ROOT_USERNAME
和 MONGO_INITDB_ROOT_PASSWORD
变量下,添加对 Secret 值的引用:
~/node_project/db-deployment.yaml
apiVersion: extensions/v1beta1 kind: Deployment ... spec: containers: - env: - name: MONGO_INITDB_ROOT_PASSWORD valueFrom: secretKeyRef: name: mongo-secret key: MONGO_PASSWORD - name: MONGO_INITDB_ROOT_USERNAME valueFrom: secretKeyRef: name: mongo-secret key: MONGO_USERNAME image: mongo:4.1.8-xenial ...
完成编辑后保存并关闭文件。
有了 Secret,您可以继续创建数据库服务,并确保您的应用程序容器仅在完全设置和初始化后才尝试连接到数据库。
第 5 步 — 创建数据库服务和应用程序初始化容器
现在我们有了 Secret,我们可以继续创建我们的数据库服务和一个 Init 容器,它将轮询此服务以确保我们的应用程序仅在数据库启动任务后尝试连接到数据库,包括创建 MONGO_INITDB
用户和密码,完成。
有关如何在 Compose 中实现此功能的讨论,请参阅 Containerizing a Node.js Application for Development with Docker Compose 的 Step 4。
打开一个文件来定义数据库服务的规范:
nano db-service.yaml
将以下代码添加到文件中以定义服务:
~/node_project/db-service.yaml
apiVersion: v1 kind: Service metadata: annotations: kompose.cmd: kompose convert kompose.version: 1.18.0 (06a2e56) creationTimestamp: null labels: io.kompose.service: db name: db spec: ports: - port: 27017 targetPort: 27017 selector: io.kompose.service: db status: loadBalancer: {}
我们在此处包含的 selector
将将此 Service 对象与我们的数据库 Pod 匹配,这些 Pod 已由 kompose 在 db-deployment.yaml
文件中使用标签 io.kompose.service: db
定义。 我们还将此服务命名为 db
。
完成编辑后保存并关闭文件。
接下来,让我们在 nodejs-deployment.yaml
中的 containers
数组中添加一个 Init Container 字段。 这将创建一个 Init 容器,我们可以使用它来延迟我们的应用程序容器的启动,直到使用可访问的 Pod 创建了 db
服务。 这是初始化容器的可能用途之一; 了解更多其他用例,请查看【X106X】官方文档【X132X】。
打开nodejs-deployment.yaml
文件:
nano nodejs-deployment.yaml
在 Pod 规范中和 containers
数组旁边,我们将添加一个带有容器的 initContainers
字段,该容器将轮询 db
服务。
在 ports
和 resources
字段下方以及 nodejs
containers
数组中的 restartPolicy
上方添加以下代码:
~/node_project/nodejs-deployment.yaml
apiVersion: extensions/v1beta1 kind: Deployment ... spec: containers: ... name: nodejs ports: - containerPort: 8080 resources: {} initContainers: - name: init-db image: busybox command: ['sh', '-c', 'until nc -z db:27017; do echo waiting for db; sleep 2; done;'] restartPolicy: Always ...
此 Init Container 使用 BusyBox 映像 ,这是一个包含许多 UNIX 实用程序的轻量级映像。 在这种情况下,我们将使用 netcat 实用程序来轮询与 db
服务关联的 Pod 是否在端口 27017
上接受 TCP 连接。
这个容器 command
复制了我们在 Step 3 中从 docker-compose.yaml
文件中删除的 wait-for 脚本的功能。 有关在使用 Compose 时我们的应用程序如何以及为何使用 wait-for
脚本的详细讨论,请参阅 容器化 Node.js 应用程序以使用 Docker Compose 进行开发的 步骤 4[ X214X]。
初始化容器运行完成; 在我们的例子中,这意味着我们的 Node 应用程序容器在数据库容器运行并接受端口 27017
上的连接之前不会启动。 db
服务定义允许我们保证这个功能,而不管数据库容器的确切位置是可变的。
完成编辑后保存并关闭文件。
创建数据库服务并使用 Init Container 来控制容器的启动顺序后,您可以继续检查 PersistentVolumeClaim 中的存储要求并使用 LoadBalancer 公开您的应用程序服务。
第 6 步 — 修改 PersistentVolumeClaim 并公开应用程序前端
在运行我们的应用程序之前,我们将进行两项最终更改,以确保我们的数据库存储将被正确配置,并且我们可以使用 LoadBalancer 公开我们的应用程序前端。
首先,让我们修改 kompose 为我们创建的 PersistentVolumeClaim 中定义的 storage
resource。 这个声明允许我们动态配置存储来管理我们应用程序的状态。
要使用 PersistentVolumeClaims,您必须创建并配置一个 StorageClass 以供应存储资源。 在我们的例子中,因为我们正在使用 DigitalOcean Kubernetes,我们的默认 StorageClass provisioner
设置为 dobs.csi.digitalocean.com
— DigitalOcean Block Storage。
我们可以通过键入以下内容进行检查:
kubectl get storageclass
如果您使用的是 DigitalOcean 集群,您将看到以下输出:
OutputNAME PROVISIONER AGE do-block-storage (default) dobs.csi.digitalocean.com 76m
如果您不使用 DigitalOcean 集群,则需要创建一个 StorageClass 并配置您选择的 provisioner
。 具体操作方法请参见【X49X】官方文档【X75X】。
当 kompose 创建 dbdata-persistentvolumeclaim.yaml
时,它会将 storage
resource
设置为不符合我们的 provisioner
的最小尺寸要求的尺寸。 因此,我们需要修改 PersistentVolumeClaim 以使用 最小可行的 DigitalOcean 块存储单元 :1GB。 请随意修改它以满足您的存储要求。
打开dbdata-persistentvolumeclaim.yaml
:
nano dbdata-persistentvolumeclaim.yaml
将 storage
值替换为 1Gi
:
~/node_project/dbdata-persistentvolumeclaim.yaml
apiVersion: v1 kind: PersistentVolumeClaim metadata: creationTimestamp: null labels: io.kompose.service: dbdata name: dbdata spec: accessModes: - ReadWriteOnce resources: requests: storage: 1Gi status: {}
另请注意 accessMode
:ReadWriteOnce
表示由于此声明而配置的卷将只能由单个节点读写。 有关不同访问模式的更多信息,请参阅 文档。
完成后保存并关闭文件。
接下来,打开nodejs-service.yaml
:
nano nodejs-service.yaml
我们将使用 DigitalOcean 负载平衡器 在外部公开此服务。 如果您没有使用 DigitalOcean 集群,请查阅您的云提供商的相关文档以获取有关其负载均衡器的信息。 或者,您可以按照 Kubernetes 官方文档 使用 kubeadm 设置高可用性集群,但在这种情况下,您将无法使用 PersistentVolumeClaims 来配置存储。
在服务规范中,将 LoadBalancer
指定为服务 type
:
~/node_project/nodejs-service.yaml
apiVersion: v1 kind: Service ... spec: type: LoadBalancer ports: ...
当我们创建 nodejs
服务时,将自动创建一个负载均衡器,为我们提供一个外部 IP,我们可以访问我们的应用程序。
完成编辑后保存并关闭文件。
准备好所有文件后,我们就可以开始并测试应用程序了。
第 7 步 — 启动和访问应用程序
是时候创建我们的 Kubernetes 对象并测试我们的应用程序是否按预期工作了。
要创建我们定义的对象,我们将使用带有 -f
标志的 kubectl create,这将允许我们指定 kompose 为我们创建的文件,以及我们创建的文件写道。 运行以下命令以创建 Node 应用程序和 MongoDB 数据库服务和部署,以及您的 Secret、ConfigMap 和 PersistentVolumeClaim:
kubectl create -f nodejs-service.yaml,nodejs-deployment.yaml,nodejs-env-configmap.yaml,db-service.yaml,db-deployment.yaml,dbdata-persistentvolumeclaim.yaml,secret.yaml
您将看到以下输出,表明对象已创建:
Outputservice/nodejs created deployment.extensions/nodejs created configmap/nodejs-env created service/db created deployment.extensions/db created persistentvolumeclaim/dbdata created secret/mongo-secret created
要检查您的 Pod 是否正在运行,请键入:
kubectl get pods
您无需在此处指定 Namespace,因为我们已经在 default
命名空间中创建了对象。 如果您正在使用多个命名空间,请确保在运行此命令时包含 -n
标志以及命名空间的名称。
当您的 db
容器正在启动并且您的应用程序 Init Container 正在运行时,您将看到以下输出:
OutputNAME READY STATUS RESTARTS AGE db-679d658576-kfpsl 0/1 ContainerCreating 0 10s nodejs-6b9585dc8b-pnsws 0/1 Init:0/1 0 10s
一旦该容器运行并且您的应用程序和数据库容器已启动,您将看到以下输出:
OutputNAME READY STATUS RESTARTS AGE db-679d658576-kfpsl 1/1 Running 0 54s nodejs-6b9585dc8b-pnsws 1/1 Running 0 54s
Running
STATUS
表示您的 Pod 已绑定到节点,并且与这些 Pod 关联的容器正在运行。 READY
表示一个 Pod 中有多少个容器正在运行。 有关详细信息,请参阅有关 Pod 生命周期的 文档。
注意: 如果您在 STATUS
列中看到意外的阶段,请记住您可以使用以下命令对 Pod 进行故障排除:
kubectl describe pods your_pod kubectl logs your_pod
随着您的容器运行,您现在可以访问该应用程序。 要获取 LoadBalancer 的 IP,请键入:
kubectl get svc
您将看到以下输出:
OutputNAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE db ClusterIP 10.245.189.250 <none> 27017/TCP 93s kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 25m12s nodejs LoadBalancer 10.245.15.56 your_lb_ip 80:30729/TCP 93s
与 nodejs
服务关联的 EXTERNAL_IP
是您可以访问应用程序的 IP 地址。 如果您在 EXTERNAL_IP
列中看到 <pending>
状态,这意味着您的负载均衡器仍在创建中。
在该列中看到 IP 后,在浏览器中导航到它:http://your_lb_ip
。
您应该看到以下登录页面:
单击获取鲨鱼信息按钮。 您将看到一个带有输入表单的页面,您可以在其中输入鲨鱼名称和对该鲨鱼一般特征的描述:
在表格中,添加您选择的鲨鱼。 为了演示,我们将 Megalodon Shark
添加到 Shark Name 字段,并将 Ancient
添加到 Shark Character 字段:
单击提交按钮。 您将看到一个页面,其中向您显示此鲨鱼信息:
您现在拥有一个 Node.js 应用程序的单实例设置,其中包含在 Kubernetes 集群上运行的 MongoDB 数据库。
结论
您在本教程中创建的文件是您在进入生产阶段时构建的良好起点。 在开发应用程序时,您可以着手实现以下内容:
- 集中记录和监控。 请参阅 Kubernetes 的现代化应用程序 中的 相关讨论 以获得一般概述。 您还可以查看 如何在 Kubernetes 上设置 Elasticsearch、Fluentd 和 Kibana (EFK) 日志记录堆栈 以了解如何使用 Elasticsearch、Fluentd 设置日志记录堆栈 和 Kibana。 另请查看 An Introduction to Service Meshes 以了解有关 Istio 等服务网格如何实现此功能的信息。
- 将流量路由到集群的入口资源。 如果您正在运行多个服务,每个服务都需要自己的 LoadBalancer,或者您希望实现应用程序级路由策略(例如 A/B 和金丝雀测试),这是 LoadBalancer 的一个很好的替代方案。 更多信息请查看How to Set Up an Nginx Ingress with Cert-Manager on DigitalOcean Kubernetes和An Introduction to Service Mesh context中路由的相关讨论服务网格。
- Kubernetes 对象的备份策略。 有关使用 DigitalOcean 的 Kubernetes 产品使用 Velero(以前的 Heptio Ark)实施备份的指南,请参阅 如何使用 Heptio Ark 在 DigitalOcean 上备份和恢复 Kubernetes 集群。