作为一个应用开发者,你需要了解Kubernetes 里面与开发者关系最密切的几个概念:
首先,是制作容器的镜像;
其次,你需要按照 Kubernetes 项目的规范和要求,将你的镜像组织为它能够“认识”的方式,然后提交上去。
这就是使用 Kubernetes 的必备技能:编写配置文件。
在这篇文章中,我们来扮演一个应用开发者的角色,使用 Kubernetes 集群发布第一个容器化应用。
Kubernetes 跟 Docker 等很多项目最大的不同,就在于它不推荐你使用命令行的方式直接运行容器,而是希望你用 YAML 文件的方式,即:把容器的定义、参数、配置,统统记录在一个 YAML 文件中,然后用这样一句指令把它运行起来:
$ kubectl create -f 我的配置文件
这么做最直接的好处是,你会有一个文件能记录下 Kubernetes 到底做了什么?
例子
1 | apiVersion: apps/v1 |
一个 Kubernetes 的 API 对象的定义,大多可以分为 Metadata 和 Spec 两个部分。
- Metadata :存放的是对象的元数据
- Spec :对象独有的定义,用来描述它所要表达的功能。
如何定义 Pod :
spec.replicas
:指定副本个数为 2,Deployment 是一个定义多副本Pod的对象,负责在 Pod 定义发生变化时,对每个副本进行滚动更新(Rolling Update)。spec.template
: 定义 Pod 模版,描述要创建的 Pod 的细节,镜像(spec.containers.image
)是nginx:1.7.9
,这个容器监听端口(containerPort
)是 80。Metadata
: API 对象的“标识”,即元数据,它是从 Kubernetes 里找到这个对象的主要依据。常用的是Labels
,一组key-value
格式的标签,Deployment 控制器对象通过这个 Labels 字段从 Kubernetes 中过滤出它所关心的被控制对象。
我们可以这样理解两个”一致性”:
- 容器镜像,保证 应用本身 在开发与部署环境里的一致性
- YAML 文件,保证了应用的 部署参数 在开发与部署环境中的一致性
Demo
Kubernetes 有一个非常有意思的项目,叫 minikube
,也就是启动一个最小的 local 的 Kubernetes 的一个环境。
minikube 我们推荐使用阿里云的版本,它和官方 minikube 的主要区别就是把 minikube 中所需要的 Google 上的依赖换成国内访问比较快的一些镜像,这样就方便了大家的安装工作;
如果大家不是 Mac 系统,其他操作系统请访问这个 链接,查看其它操作系统如何安装 minikube 沙箱环境。
启动:
minikube start
接下来,我们来做三件事情:
首先,查看 minikube
的 status,可以看到 kubelet master
和 kubectl
都是配置好的。
1 | GZ05032MLdeMacBook-Pro:~/workspace/k8s $ minikube status |
接下来,我们利用 kubectl
来看一下这个集群中节选的状态,可以看到这个master 的节点已经是 running
状态:
1 | GZ05032MLdeMacBook-Pro:~/workspace/k8s $ kubectl get nodes |
就以这个为节点,下面我们尝试去看一下现在集群中 Deployment 这个资源:
1 | GZ05032MLdeMacBook-Pro:~/workspace/k8s $ kubectl get deployments |
创建一个 Deploment 的 YAML 文件 nginx-deployment.yaml
:
1 | GZ05032MLdeMacBook-Pro:~/workspace/k8s $ cat nginx-deployment.yaml |
第一步,我们提交一个 nginx 的 Deployment:
1 | GZ05032MLdeMacBook-Pro:~/workspace/k8s $ kubectl apply -f nginx-deployment.yaml |
可以看到:有一个 nginx-deployment 已经被生成了,它的 replicas 数目也是我们想要的、selector 也是我们想要的、它的 image 的版本也是 1.7.9。
第二步,对这个 Deployment 进行一次版本升级,将 Pod 的版本从 nginx 的镜像由 1.7.9 升级到 1.8。
1 | GZ05032MLdeMacBook-Pro:~/workspace/k8s $ cat nginx-update-deployment.yaml |
如下看到:这里面 nginx 的 image 版本号从 1.7.9 升级到 1.8。
1 | GZ05032MLdeMacBook-Pro:~/workspace/k8s $ kubectl apply -f nginx-update-deployment.yaml |
你可以通过 kubectl get 指令,查看两个 Pod 被逐一更新的过程:
1 | GZ05032MLdeMacBook-Pro:~/workspace/k8s $ kubectl get pods |
第三步,尝试对 nginx 进行一次扩容,进行一次水平的伸缩,将 nginx 的 Pod 实例扩展到 4 个:
1 | GZ05032MLdeMacBook-Pro:~/workspace/k8s $ cat nginx-scale-deployment.yaml |
如下看到: nginx 的 Pod 实例有 4 个,同时也可以看到 controller 又做了几次新的操作,这个 scale up 成功了。
1 | GZ05032MLdeMacBook-Pro:~/workspace/k8s $ kubectl apply -f nginx-scale-deployment.yaml |
第四步,移除 Deployment。我们再去重新 get 这个 Deployment,也会显示这个资源不再存在,这个集群又回到了最开始干净的状态。
1 | GZ05032MLdeMacBook-Pro:~/workspace/k8s $ kubectl delete deployment nginx-deployment |
在实际使用 Kubernetes 的过程中,相比于编写一个单独的 Pod 的 YAML 文件,官方更推荐你使用一个 replicas=1
的 Deployment。为什么呢?
主要原因是当 Pod 所在的节点出故障的时候,
replicas=1
的 Deployment 可以将 Pod 调度到其它健康的节点上,单独的 Pod只能在节点健康的情况下由Kubelet 保证其健康状况。
总结
从 docker run
这样的命令行操作,向 kubectl apply YAML
文件这样的声明式 API 的转变,是每一个容器技术学习者,必须要跨过的第一道门槛。
如果你想要快速熟悉 Kubernetes,请按照下面的流程进行练习:
首先,在本地通过 Docker 测试代码,制作镜像;
然后,选择合适的 Kubernetes API 对象,编写对应 YAML 文件(比如,Pod,Deployment);
最后,在 Kubernetes 上部署这个 YAML 文件。
更重要的是,在部署到 Kubernetes 之后,接下来的所有操作,要么通过 kubectl 来执行,要么通过修改 YAML 文件来实现,就尽量不要再碰 Docker 的命令行了。