将Node.js应用程序部署到适用于初学者的IBM Cloud Kubernetes集群中
首先
大家好,2020年已经到来,大家过得如何呢?
据说,2020年代将是5G网络完善、物联网和自动驾驶技术广泛渗透的10年,但2010年代也是一个充满变革的10年。
特别是从2013年左右开始开发的Kubernetes最终达到GA阶段,并在各个云服务提供商中作为托管服务进行部署,这是一个重大的突破。
这使得容器技术和微服务更加易于管理,未来将诞生和发展各种各样的服务。
这次,我为那些想要尝试使用Kubernetes的初学者准备了一些文献和技术书籍。我自己也是初次投稿,但我很想要学习并尝试使用Kubernetes!
将应用程序外部公开的步骤在Kubernetes上执行
我打算用IBM Cloud来介绍。
另外,筆者也是剛開始學習,對於詳細的技術和邏輯還在理解中,如果您想深入了解,請參考本文後面的資料。
這篇文章僅介紹了開發應用並將其部署至Kubernetes的流程。
Kubernetes是什么?

1. 阅读方式
起初它该怎么读?是“くべ…くば…くばねってす”吗?是哪种语言?我也有同样的困惑。
从观看各种视频来看,开发者们似乎称其为“クーバネ(ー)ティス”。クーバネティス。我完全不懂。
据说在希腊语中是指“操舵员”或者“航海长”之类的意思。
那么,它到底是什么技术呢?
2. Kubernetes是什么?
根据维基百科的说法,这被描述为一个开源的容器编排系统,用于部署、扩展和管理容器化的应用程序。
在我最信赖的一本技术书中(请参阅后面的参考资料以了解详细信息),这也被介绍为“为合理运营容器化应用程序而设计的开源软件平台”。
换句话说,Kubernetes是一个开源平台,用于运营和管理像Docker等容器化的应用程序。听起来很厉害对吧。
我们现在立刻开始进入正题。
开发环境
macOS 操作系统
node.js 版本 12.2.0
npm 版本 6.13.4
docker 命令行界面版本 19.03.5
前提条件
-
- 已经安装了Node.js和npm。
-
- 可以运行Git命令。
- 已创建了Docker账号。
1. 准备事先做好
1-1. 创建 IBM Cloud账户
首先,让我们创建一个IBM Cloud账户。
在中国语境下的拍摄地,有很多使用Kubernetes的方法,但如果使用云服务提供商提供的Kubernetes托管服务,则所有所需资源都已整合在一起,非常方便。
没有理由不使用它。
请注意,在这里IBM Cloud的Kubernetes服务(以下简称IKS)不能在免费账户中使用,必须注册信用卡并升级为按量计费账户。
然而,并不意味着需要支付费用,虽然有诸多限制,如仅限制一个月使用或只有一个工作节点等,但IKS提供了免费集群,您可以完全放心地尝试使用Kubernetes!
就像是临时加入一个俱乐部一样。
哎呀,Kubernetes俱乐部,也可以说是简单地交会费正式加入。
请首先访问此处,跳转到IBM Cloud的账户创建页面。
順利地创建账号后,我认为将进入以下界面。

请点击右上角的账户升级选项。输入必要的信息,并勾选接受云服务条款即可完成。嗯,很快。
请保持原样不要操作这个仪表盘屏幕,稍后会进行操作。
1-2. 安装IBM Cloud CLI
接下来我们来安装IBM Cloud CLI。
这是一个命令行界面,可以在您自己的PC终端或命令提示符中管理IBM Cloud资源,并同时安装Kubernetes CLI,从而使得可以通过命令操作Kubernetes。
基本上,今后将主要通过命令操作Kubernetes,请务必先完成IBM Cloud CLI的安装。
由于我已经安装完成,所以只需要提供安装命令。(请查看详细说明。)
#Mac, Linux用
$ curl -sL https://ibm.biz/idt-installer | bash
根据环境的不同,我认为安装可能需要相当长的时间。
$ ibmcloud -v
ibmcloud version 0.21.0+f5d1134-2019-12-16T07:34:45+00:00
$ kubectl version --short
Client Version: v1.14.8
如果成功执行上述两个命令并且能够正确显示版本信息,那么安装就完成了!
创建网页应用程序
用Node.js创建应用。
事前准备完成后,让我们立即制作一个用于部署的应用程序!
这次我在GitHub上创建了一个简单的练习应用程序。
请务必试用一下。
这是一个Node.js应用程序。
※前提条件是已经安装了Node.js和npm。
$ git clone https://github.com/rikkyrice/kube-sample-app
Cloning into 'kube-sample-app'...
remote: Enumerating objects: 14, done.
remote: Counting objects: 100% (14/14), done.
remote: Compressing objects: 100% (9/9), done.
remote: Total 14 (delta 0), reused 0 (delta 0), pack-reused 0
Unpacking objects: 100% (14/14), done.
现在,我们已经成功创建了一个名为kube-sample-app的Node.js应用程序的目录。该应用程序本身非常简单,在浏览器中可以显示以下内容的网站。

现在Web应用的创建已经完成了,非常快。
创建Docker容器
接下来,在Docker中创建生成的应用程序容器。
假设已经安装了Docker。
创建Dockerfile文件
那么,让我们创建一个在进行容器化时所需的Dockerfile文件吧。
在Dockerfile中,我们将记录容器的运行配置信息。
已经从GitHub克隆了kube-sample-app的人可能已经在目录中有Dockerfile文件了。
FROM node:12
WORKDIR /usr/src/app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 8080
CMD ["node", "app.js"]
创建一个容器的镜像,并推送到DockerHub上。
接下来,在Terminal中,从kube-sample-app目录的文件中创建容器镜像。
请在kube-sample-app目录上执行以下命令。
请将${用户名}替换为您的DockerHub用户名。
对我来说,用户名应为rikkyrice/kube-sample-app:0.1。
$ docker build --tag ${ユーザ名}/kube-sample-app:0.1 .
Sending build context to Docker daemon 106kB
Step 1/7 : FROM node:12
---> 6b5991bf650f
Step 2/7 : WORKDIR /usr/src/app
---> Running in 02ac3c501da8
Removing intermediate container 02ac3c501da8
---> 7e8b2f94b323
Step 3/7 : COPY package*.json ./
---> 90cd726f65d3
Step 4/7 : RUN npm install
---> Running in 3abe5e4c5677
> ejs@3.0.1 postinstall /usr/src/app/node_modules/ejs
> node ./postinstall.js
Thank you for installing EJS: built with the Jake JavaScript build tool (https://jakejs.com/)
added 64 packages from 39 contributors and audited 139 packages in 3.197s
found 2 moderate severity vulnerabilities
run `npm audit fix` to fix them, or `npm audit` for details
Removing intermediate container 3abe5e4c5677
---> 6882306b5a87
Step 5/7 : COPY . .
---> 4085a1edc12c
Step 6/7 : EXPOSE 8080
---> Running in 794847f8f427
Removing intermediate container 794847f8f427
---> f8147522bc79
Step 7/7 : CMD ["node", "app.js"]
---> Running in dadc7ad0b91e
Removing intermediate container dadc7ad0b91e
---> 1d08c3fe706c
Successfully built 1d08c3fe706c
Successfully tagged ${ユーザ名}/kube-sample-app:0.1
使用以下命令在本地仓库中创建名为${用户名}/kube-sample-app:0.1的Docker镜像,并保存下来。
然后登录Docker,并将镜像推送到您自己的DockerHub远程仓库中。
请执行以下命令。
$ docker login
Authenticating with existing credentials...
Login Succeeded
$ docker push ${ユーザ名}/kube-sample-app:0.1
The push refers to repository [docker.io/${ユーザ名}/kube-sample-app]
485558bdae5c: Pushed
fe34ac93a512: Pushed
91da8ffeb073: Pushed
e204a1f85920: Pushed
af817f759558: Pushed
b5aa4fb76f12: Pushed
f68782bbfa17: Pushed
42f9c2f9c08e: Pushed
99e8bd3efaaf: Pushed
bee1e39d7c3a: Pushed
1f59a4b2e206: Pushed
0ca7f54856c0: Pushed
ebb9ae013834: Pushed
0.1: digest: sha256:15270113aa252fedf81d41066dd21a2cd7143fed7dc27649971bd9a6f2901ded size: 3051
你现在可以将镜像存储到你的DockerHub上了。
终于开始接触Kubernetes了!
创建 Kubernetes 集群
那么,让我们创建一个Kubernetes集群吧。
基本上,应用程序会在这个Kubernetes集群的工作节点上执行。
使用IBM Cloud来创建Kubernetes集群。
请再次打开之前进行了预先准备的IBM Cloud账户仪表板。

点击位于右上方的”创建资源”或”目录”按钮,可以进入选择IBM Cloud服务的页面。在那里,输入”kubernetes”进行目录搜索,并选择Kubernetes服务。

当画面移动时,请直接点击“Create”。

我们将切换到创建集群的页面。
默认情况下,我认为选择的是Standard,但是让我们选择Free。
您可以随意为每个账户选择一个唯一的名称,但这次我们将使用“mycluster”。
按下“创建集群”按钮,创建Kubernetes集群!

创建Kubernetes集群大约需要10分钟左右。
在等待的时候,您可以边吃着剩下的年糕,边耐心地等待。
现在集群的创建已经完成。
从下一步开始,我们将最终将容器部署到集群中!
将容器部署到Kubernetes。
现在,是最终章了。
我们将部署容器到Kubernetes!
5-1. 登录IBM Cloud
首先,请打开终端并登录到ibmcloud。
$ ibmcloud login
输入这个命令后,将启动一个交互式登录过程。
请提供您事先准备的IBM Cloud账户的邮箱和密码,完成登录。
如果看到OK,则表示登录成功。
5-2. 使用终端操作Kubernetes
接下来,我们将准备在IBM Cloud的仪表板上操作创建的Kubernetes集群的终端。首先打开创建的IBM Cloud Kubernetes集群界面的Access选项卡,然后依次执行After your cluster provisions, gain access。

请打开终端,执行以下代码即可。
只需将Kubernetes集群的屏幕上的代码复制粘贴即可。
$ ibmcloud ks cluster config --cluster ${クラスタid}
如果正常运行,我认为会输出环境变量。
然后将其导出。
OK
mycluster の構成は正常にダウンロードされました。
環境変数をエクスポートして Kubernetes の使用を開始してください。
export KUBECONFIG=/Users/hashikiriku/.bluemix/plugins/container-service/clusters/mycluster/kube-config-hou02-mycluster.yml
$ export KUBECONFIG=/Users/hashikiriku/.bluemix/plugins/container-service/clusters/mycluster/kube-config-hou02-mycluster.yml
现在,您可以在终端上操作指定的Kubernetes集群!让我们试着运行以下命令。
$ kubectl get node
NAME STATUS ROLES AGE VERSION
10.76.215.133 Ready <none> 6m45s v1.14.9+IKS
你的工作节点显示得很好。
创建并运行 deployment.yml 和 service.yml
现在,我们已经可以访问Kubernetes集群了,所以终于开始部署容器。
为了部署容器,需要创建Pod并将容器放置在其中。用于创建和管理该Pod以及调整运行数量的是部署。这次我们将在名为deployment.yml的清单文件中记录此部署。如果您已经从GitHub克隆了kube-sample-app,它应该已经存在于目录中。请将deployment.yml中spec.template.spec.containers[1].image的${用户名}替换为您自己的DockerHub帐户用户名。
apiVersion: apps/v1
kind: Deployment
metadata:
name: kube-sample-app
spec:
replicas: 5
selector:
matchLabels:
app: kube-sample-app
template:
metadata:
labels:
app: kube-sample-app
spec:
containers:
- name: kube-sample-app
image: ${ユーザ名}/kube-sample-app:0.1
command:
ports:
- containerPort: 8080
我会在终端上执行这个。
$ kubectl apply -f deployment.yml
deployment.apps/kube-sample-app created
這樣就建立了一個Pod。
我們這次將複本(replicas)設置為5,以生成5個正在運行的Pod。
我們來試試看有沒有生成了5個運行中的Pod。
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
kube-sample-app-f6478fbcc-74s4t 1/1 Running 0 3m18s
kube-sample-app-f6478fbcc-bbncl 1/1 Running 0 3m18s
kube-sample-app-f6478fbcc-lgk79 1/1 Running 0 3m18s
kube-sample-app-f6478fbcc-tplh6 1/1 Running 0 3m18s
kube-sample-app-f6478fbcc-znxq5 1/1 Running 0 3m18s
我能夠明白它的運作很順利。
不过,仅仅这样是无法通过浏览器访问的。
因此我们需要一个服务来接收来自客户端的请求。
服务有几种类型,但这次我们将使用NodePort类型,在节点的IP地址上开放一个公开的端口号。
这样外部客户端就可以访问到Pod。
这次我们将配置写入service.yml文件中。
kind: Service
apiVersion: v1
metadata:
name: kube-sample-app-service
spec:
type: NodePort
selector:
app: kube-sample-app
ports:
- name: webserver
protocol: TCP
port: 8080
请在终端上执行这个命令。
$ kubectl apply -f service.yml
service/kube-sample-app-service created
现在已经准备好将其发布到外部网络。
访问URL以Kubernetes集群的公共IP地址提供,并附带发布端口。
IBM Cloud的Kubernetes集群管理界面可以查看Kubernetes集群的公共IP地址,也可以使用以下命令进行确认。
$ ibmcloud ks workers ${クラスタ名}
OK
ID パブリック IP プライベート IP フレーバー 状態 状況 ゾーン バージョン
kube-bo6of95d0e80ipchv6ag-mycluster-default-000000a8 184.***.***.** 10.76.215.133 free normal Ready hou02 1.14.9_1544
这个公共IP就是Kubernetes集群的公共IP地址。
您还可以通过以下命令查看服务所开放的公共端口。
$ kubectl get service kube-sample-app-service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-sample-app-service NodePort 172.21.213.190 <none> 8080:32175/TCP 28s
我找到了位于这个端口(们)的公开端口号码是32175。
我知道了相应的公开URL。
在我的环境中,应用已经在http://184.***.***.**:32175/上公开。
让我们立即在浏览器中确认一下功能。

你成功地访问了!
Kubernetes不仅拥有各种功能,还有其他功能。
例如,通过使用Ingress功能,可以将应用程序映射到公开URL路径上,还可以实现HTTPS通信。
不过,Ingress功能只能在标准群集中使用…遗憾啊。
如果希望使用的话,最好新建一个标准群集,而不是自由群集!
除了这个之外,Kubernetes还有许多其他功能。
我也计划通过在Qiita上持续学习并介绍各种技术。
以下是可以供参考的资料。
学习Docker并进入Kubernetes的15步骤 – 作者高良真穗

・IBM 日本频道(YouTube)

我参考了很多其他资料(例如IBM官方的资料等),我想介绍我最受启发的两个要点。
到最后
我这次是第一次写Qiita的文章。
我知道有很多不足之处。
如果你发现有什么错误或者不对的地方,请务必指出来。
我会立即进行修正,并以此为动力继续努力。
非常感谢您一直阅读到最后。
祝您新年快乐。