灰烬

Kubernetes入门指南:部署一个Node.js Docker应用 — SitePoint

灰烬 · 2017-07-05翻译 · 1740阅读 原文链接

A team of workers with a crane loading containers onto the back of a whale. Kubernetes and Docker.

容器技术已经存在了很多年,Docker使它真正成为主流。因为Docker提供了一套简单易用的接口来使用容器,现在已有许多的公司和开发者使用容器来装载他们的应用。

然而,对于任何有一定规模的应用程序,你一定不会只要部署“一个容器”,而是部署在大量主机上的许多容器。 这这篇文章中,我们会来看一看 Kubernetes, 一个用来自动化部署、控制容器扩展/收缩以及管理容器化应用程序的开源系统。

预备知识: 本文假定你对 Docker 有一定了解,如果你需要复习一下,请查看 Understanding Docker, Containers and Safer Software Delivery.

Kubernetes解决了什么问题?

查看作者的更多文章

在Docker中,你有一些像是docker run 和 docker stop 这样简单的命令来启动或关闭一个容器。不像这些让你在一个容器上操作的简单命令,并没有docker deploy这样的命令来向大量的主机推送新的镜像。

最近出现了很多工具来解决这个“容器编排”问题;流行的有 Mesos, Docker Swarm (现在成了 Docker 引擎的一部分), Nomad, 和 Kubernetes。 他们都有各自的利弊,但是,可以说,Kubernetes在解决“容器编排”问题这一点上走的最远.

Kubernetes (也被称为 ‘k8s’) 提供了强大的数据抽象,可以完全的解耦各种应用程序操作,比如通过基础架构操作实现服务部署和控制容器扩展/收缩。所以,有了Kubernetes,你的代码不用在个人主机或虚拟机上运行,而是运行在被Kubernetes连接成基础架构的装载着容器的海量计算机上。

Kubernetes 概念学习

Kubernetes 是C/S架构,Kubernetes 的服务运行在你部署应用程序的集群(大量主机)上,而通常你和集群的交互是通过一个客户端完成的,比如 kubectl 终端。

Pods

豆粒 (pod)是Kubernetes处理大量容器的基本单位。如果有两个或多个容器总是需要一起工作,并且需要在一台机器上,那么就把它们定义为一个 pod。豆粒是一个有用的数据抽象,甚至有人 建议 让pod成为docker中的第一类对象。

Node

一个节点(node)是一台运行着Kubernetes,可以安排pods到上面的物理机或虚拟机。

Label

标签(label)是一个用来标识资源的键值对。你可以用lebel标识所有你所有的pods,比如“role=production”标识production业务。

Selector

选择器(Selections)可以让你用lebel来搜索/过滤资源。 比如像上边的例子里, 要获得所有production相关的pods你的selector应该是 “role=production”。

Service

一项服务(Service)定义了一系列的pods (通常由一个“selector”选定)和一种访问它们的方法,比如一个稳定的IP地址和对映的DNS名称。

使用Kubernetes在GKE上部署一个 Node.js 应用

现在,我们对Kubernetes的基本概念有了些认识,再来实际操作下看看。比如在谷歌容器引擎 Google Container Engine (也称GKE)上部署一个Node.js应用程序。你要有一个Google Cloud Platform 账号 (谷歌提供了 300美元试用赠金).

1. 安装 Google Cloud SDK and Kubernetes 客户端

kubectl 是用来运行命令连接Kubernetes集群的命令行工具. 你可以把它当作Google Cloud SDK的一部分来安装。在安装好Google Cloud SDK 后,运行下面的命令来安装kubectl:

`$ gcloud components install kubectl`

如果你使用的是 Mac则运行 brew install kubectl 。运行kubectl version命令来验证是否安装成功.

你也需要用你谷歌云账号的证书安装 Google cloud SDK ,只需要运行 gcloud init命令然后跟着提示说明操作就可以了。

2. 创建一个 GCP工程

所有的Google Cloud Platform资源都被创建在一个工程里, 所以 在网页UI上创建一个.

在使用CLI时设置一个默认的工程ID通过运行:

`gcloud config set project {PROJECT_ID}`

3. 创建一个你的应用程序的Docker镜像

这里是一个我们一会儿会用到的应用程序: express-hello-world。从 Dockerfile 里你会知道,我们正在使用一个现有的Node.js镜像,它来自 dockerhub。现在,我们将会创建自己的应用镜像,通过运行命令:

`$ docker build -t hello-world-image .`

在本地运行应用,通过:

`docker run --name hello-world -p 3000:3000 hello-world-image`

如果你访问 localhost:3000 你就会得到响应。

4. 创建一个集群

现在我们将会用三个实例(虚拟机)创建一个集群, 在实例上会部署我们的应用程序。 你可以在 容器引擎页面 用相当直观的网页UI来操作,也可以通过执行下面的命令行:

`$ gcloud container clusters create {NAME} --zone {ZONE}`

让我们在us-east1-b里创建一个叫做 hello-world-cluster的集群通过执行命令:

`$ gcloud container clusters create hello-world-cluster --zone us-east1-b --machine-type f1-micro`

这样就启动了一个三个节点的集群。我们使用 f1-micro 当作机器类型是因为它是可用的最小值,可以确保最小开销。

kubectl 客户端和你的集群连接起来,通过运行:

`gcloud container clusters get-credentials hello-world-cluster --zone us-east1-b`

这样,现在我们就有了一个docker镜像和一个集群。我们要将镜像部署到集群上并且启动容器,它们将响应服务请求。

5. 上传 Docker镜像到Google Container Image Registry

谷歌容器镜像注册中心是一个云注册中心,你可以推送你的镜像到这里,这些镜像将自动适用于你的容器引擎集群。 要推送一个镜像,你需要在创建它时使用一个合适的名字。

要创建这个应用的容器镜像并打标签准备上传,运行下面的命令:

`$ docker build -t gcr.io/{PROJECT_ID}/hello-world-image:v1 .`

v1 是镜像的 tag (标签)。

下一步是上传我们刚才创建的镜像:

`$ gcloud docker -- push gcr.io/{PROJECT_ID}/hello-world-image:v1`

6. 第一次部署

现在我们在云服务器上有了一个集群和一个镜像,让我们用Kubernetes将镜像部署到集群上吧。我们会通过创建一个 deployment 规格文件来实现。 部署配置是一种kubernetes资源而所有的kubernetes资源都可以通过一个规格文件被声明性定义。这个规格文件规定了资源的期望状态,而Kubernetes 则会计算出怎样从当前状态到达期望状态 。

让我们为第一次部署创建一个规格文件:

deployment.yml

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  name: hello-world-deployment
spec:
  replicas: 2
  template:
    metadata:
      labels: # labels to select/identify the deployment
        app: hello-world  
    spec:     # pod spec
      containers: 
      - name: hello-world 
        image: hello-world-image:v1 # image we pushed
        ports:
        - containerPort: 3000

这个规格文件表示: 启动两个pods,每个pod都被给出的pod的规格定义,并且都应该有一个包含着我们推送过的 hello-world-image:v1镜像的容器。

现在, 执行:

`$ kubectl create -f deployment.yml --save-config`

你可以通过运行 kubectl get deployments查看部署状态。如果想查看部署创建的pod,运行这个命令: kubectl get pods。你可以看到正在运行的pods:

$ kubectl get pods
NAME                                     READY     STATUS    RESTARTS   AGE
hello-world-deployment-629197995-ndmrf   1/1       Running   0          27s
hello-world-deployment-629197995-tlx41   1/1       Running   0          27s

注意我们有两个pods正在运行,因为我们在deployment.yml文件中设置的副本个数是2。

为确保服务已经启动,查看日志通过运行:

`$ kubectl logs {pod-name}  # kubectl logs hello-world-deployment-629197995-ndmrf`

7. 向互联网公开服务

要向互联网公开服务,你必须将你的虚拟机置于负载均衡器之下。为此我们创建一个 Kubernetes Service

`$ kubectl expose deployment hello-world-deployment --type="LoadBalancer"`

这种场景下, 它创建了一个service 对象 (一个service也是一种Kubernetes资源, 就像是 Deployment) 和一个Google Cloud 负载均衡器.

执行 kubectl get services 来查看你服务的公开IP, 控制台输出看起来应该是这样:

NAME                     CLUSTER-IP       EXTERNAL-IP      PORT(S)          AGE
hello-world-deployment   10.103.254.137   35.185.127.224   3000:30877/TCP   9m
kubernetes               10.103.240.1     <none>           443/TCP          17d

访问 http://: 获得服务。 你也可以购买一个自定义域名并将它指向这个IP。

8. 控制服务的扩展/收缩

假设你的服务开始有了更多的流量,你需要启动更多你应用程序的实例。要在这种情形下扩展服务,只需要编辑你的 deployment.yml 文件,改变 replicas 的数值为, 比如说3,接着执行 kubectl apply -f deployment.yml ,然后你立刻就会有三个pods在运行。这个也可以设置成自动扩展,不过那就超出这篇教程的范围了。

9. 清理

做完后别忘了清理资源,否则他们将会继续吃掉你的谷歌积分!

$ kubectl delete service/hello-world-deployment
$ kubectl delete deployment/hello-world-deployment
$ gcloud container clusters delete hello-world-cluster --zone us-east1-b

总结

在这篇教程中我们已经覆盖了很多知识,但是就Kubernetes来看,这还只是九牛一毛。还有很多东西你可以做,比如通过一条语句将你的服务扩展到更多pods,或者在pods上为亚马逊网络服务证书之类的东西增加secret,等等。 当然,这已经足够让你有个好的开始。关注 kubernetes.io 学习更多!

相关文章