第一次部署Kubernetes


【编者的话】学习Kubernetes从动手开始,跟随本文动手创建Pod和Deployment吧。

如果阅读过这篇Kubernetes介绍,那么你应该已经很好地理解了组成Kubernetes的基础组件。如果你和我一样的话,那么不真正动手用用Kubernetes,其实无法彻底地理解它的理念。这是本系列文章的第一篇,会实际在云上部署一个服务。本文还会介绍如何使用Google Kubernetes Engine来部署Gitea,一个开源的git托管服务。

其实Gitea没有什么特别之处,但是在云上实际部署一个开源应用程序能够帮助我们获得Kubernetes的实际操作经验。另外,部署完成之后你还可以使用这个很好的可以自服务的服务来托管你以后的项目!

搭建集群

kubectl和gcloud

搭建Kubernetes环境所需的最重要工具是kubectl命令。该命令让用户可以和Kubernetes API交互。可以用来创建,更新以及删除Kubernetes资源,比如pod,deployment和负载均衡器。

但是注意:kubectl不能直接用来预配负责pod运行的节点或者集群。这是因为Kubernetes设计目标是平台无关。Kubernetes不知道也不关心自己在哪里运行,因此没有内置任何方法和用户所选择的云供应商通信,去代替用户租用节点。因为本文使用的是Google Kubernetes Engine,我们需要使用gcloud命令来完成节点创建的工作。

简单来说,gcloud用来预配列在Kubernetes 101文章里介绍的“Hardware”下面的资源,kubectl用来管理“Software”下的资源。

本文假定用户系统里已经安装了kubectl和gcloud。如果你完全是从零开始的,请先查看Google Kubernetes Engine Quickstart里的第一部分,先注册一个GCP用户,建立一个项目,启用账单,并且安装命令行工具。

当环境准备好之后,可以使用如下命令创建一个集群:
# create the cluster
# by default, 3 standard nodes are created for our cluster
gcloud container clusters create my-cluster --zone us-west1-a

# get the credentials so we can manage it locally through kubectl
# creating a cluster can take a few minutes to complete
gcloud container clusters get-credentials my-cluster \
 --zone us-west1-a

01.png

除了使用gcloud命令行工具,还可以通过Google Cloud Console来管理资源。运行完上述命令后,可以看到集群出现在GKE下面。还应该能在GCE下面看到预配为节点的VM列表。注意虽然GCE UI允许用户从这里删除VM,但是它们是由集群管理的,当集群发现VM消失了就会重新创建VM。当完成本文试验之后,想要永久删除VM的话,可以通过删除集群从而移除集群里的所有资源。
2.png

部署应用

YAML:声明式基础架构

集群已经准备好,现在可以开始工作了。有两种方式可以向Kubernetes上添加资源:使用kubectl add命令交互式添加,或者通过定义资源的YAML文件。

虽然使用kubectl add命令交互式添加很适合用来做实验,但是YAML是想要构建可维护的资源的方式。通过将所有Kubernetes资源写到YAML文件里,可以在一系列便于维护的文件里记录下集群的整个状态,然后做版本控制来加以管理。这样,托管服务所需的所有指令都可以和代码本身一起保存管理。

添加Pod

我们通过往集群里添加一个Pod来演示Kubernetes YAML文件。创建一个新的名为gitea.yaml的文件,内容如下:
apiVersion: v1
kind: Pod
metadata:
name: gitea-pod
spec:
containers:
- name: gitea-container
image: gitea/gitea:1.4

这个Pod很基本,第2行声明资源的类型是Pod;第1行说明该资源是用Kubernetes API v1定义的。第3-8行描述Pod的属性。这里,Pod命名为“gitea-pod”,并且它包含一个名为“gitea-container”的容器。

第8行是最有意思的部分。这一行定义了想要运行的容器镜像;这里,镜像是gitea/gitea repository里的1.4版本。

Kubernetes会告诉内置的容器运行时去找到所要求的容器镜像,并且pull到Pod里。因为默认容器运行时是Docker,它会去找Dockerhub上的gitea repository,并且将需要的镜像pull下来。

现在我们写好了YAML文件,将其apply到集群上:
kubectl apply -f gitea.yaml

该命令会让Kubernetes读取YAML文件,并且相应更新集群里的资源。要看到新创建的Pod,可以运行kubectl get pods。你应该能看到pod已经在运行了。
$ kubectl get pods

NAME        READY     STATUS    RESTARTS   AGE
gitea-pod   1/1       Running   0          9m

如果需要更多信息,可以使用如下命令查看容器的标准输出:
$ kubectl logs -f gitea-pod

Generating /data/ssh/ssh_host_ed25519_key...
Feb 13 21:22:00 syslogd started: BusyBox v1.27.2
Generating /data/ssh/ssh_host_rsa_key...
Generating /data/ssh/ssh_host_dsa_key...
Generating /data/ssh/ssh_host_ecdsa_key...
/etc/ssh/sshd_config line 32: Deprecated option UsePrivilegeSeparation
Feb 13 21:22:01 sshd[12]: Server listening on :: port 22.
Feb 13 21:22:01 sshd[12]: Server listening on 0.0.0.0 port 22.
2018/02/13 21:22:01 [T] AppPath: /app/gitea/gitea
2018/02/13 21:22:01 [T] AppWorkPath: /app/gitea
2018/02/13 21:22:01 [T] Custom path: /data/gitea
2018/02/13 21:22:01 [T] Log path: /data/gitea/log
2018/02/13 21:22:01 [I] Gitea v1.4.0+rc1-1-gf61ef28 built with: bindata, sqlite
2018/02/13 21:22:01 [I] Log Mode: Console(Info)
2018/02/13 21:22:01 [I] XORM Log Mode: Console(Info)
2018/02/13 21:22:01 [I] Cache Service Enabled
2018/02/13 21:22:01 [I] Session Service Enabled
2018/02/13 21:22:01 [I] SQLite3 Supported
2018/02/13 21:22:01 [I] Run Mode: Development
2018/02/13 21:22:01 Serving [::]:3000 with pid 14
2018/02/13 21:22:01 [I] Listen: http://0.0.0.0:3000

可以看到,集群的容器里有一个服务器在运行了!不幸的是,除非我们打开ingress通道(以后的文章会介绍),否则还没有办法访问它。

Deployment

Kubernetes 101里介绍过,通常Pod并不直接运行在Kubernetes上。相反,我们应该定义一个Deployment来管理Pod。

首先,删除掉正在运行的Pod:
kubectl delete -f gitea.yaml

该命令会从集群里移除掉定义在YAML文件里的所有资源。修改YAML文件如下:
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
name: gitea-deployment
spec:
replicas: 1
selector:
matchLabels:
  app: gitea
template:
metadata:
  labels:
    app: gitea
spec:
  containers:
  - name: gitea-container
    image: gitea/gitea:1.4

这个文件看上去比之前稍微复杂了一点。这是因为这里实际定义了两个不同的对象:Deployment(第1-9行),以及它管理的Pod模板(第10-17行)。

第6行是Deployment的最重要部分。它定义了想要运行的Pod的副本数量。本例仅仅要求一个副本,因为Gitea并非为多个Pod而设计的。

这里有另外一个新概念:Label和Selector。Label就是用户定义的和Kubernetes资源关联的键值对。Selector用来取回和给定label查询匹配的资源。本例中,第13行将这个Deployment创建的所有Pod的Label设置为“app=gitea”。如果Deployment一旦需要取回它创建的所有Pod列表(比如,为了确保Pod都是健康的),它就可以使用第8-9行定义的Selector。这样,Deployment能够通过搜索哪些Pod被指派了“app=gitea”的Label来随时跟踪它所管理的Pod。

大多数情况下,Label是用户定义的。上例中,“app”并不代表任何对于Kubernetes来说特别的东西,仅仅是一种能让我们更方便地管理系统的方式。必须注意,确实有一些label是Kubernetes自动指定的,包含系统的信息。

YAML文件创建好了,可以重新apply到集群里去了:
kubectl apply -f gitea.yaml

至此,如果运行kubectl get pods,我们就可以看到Deployment里指定的新Pod在运行了,如下:
$ kubectl get pods

NAME                               READY     STATUS     RESTARTS
gitea-deployment-8944989b8-5kmn2   0/1       Running    0

也可以查看Deployment本身的信息:
$ kubectl get deployments

NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE
gitea-deployment   1         1         1            1           4m

要想验证一切工作正常,可以尝试用命令kubectl delete pod <pod_name>删除Pod。应该能够看到一个新的Pod迅速地被重新创建了。这正是Deployment的神奇之处!

你也可能注意到了新Pod有点奇怪,名字的一部分是随机生成的字符串。这是因为Pod是Deployment批量创建的,生命周期是短暂的。当在Deployment里面时,Pod应该被当成cattle而不是pet

后续预告

现在集群里已经有Gitea软件在运行了,但是我们必须找到能够通过浏览器与之交互的方式。本系列下一篇文章会介绍Kubernetes网络的基本特性。本系列的后续文章还会介绍持久化存储,环境变量等等。

原文链接:Kubernetes 110: Your First Deployment(翻译:崔婧雯)
===========================
译者介绍
崔婧雯,现就职于IBM,高级软件工程师,负责IBM WebSphere业务流程管理软件的系统测试工作。曾就职于VMware从事桌面虚拟化产品的质量保证工作。对虚拟化,中间件技术,业务流程管理有浓厚的兴趣。

0 个评论

要回复文章请先登录注册