容器技术已经存在了很多年,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 学习更多!
y
网友评论