
前面我们分享了集群的集群,现在我们来折腾一下应用的部署。k8s部署应用相对比较简单,一个yaml文件即可搞定。但是想要理解这个yaml文件,就需要先了解k8s中的两个概念:deployment和pod。
我们先来看一下k8s官方文档(https://kubernetes.io/zh/docs/concepts/workloads/controllers/deployment/)对于deployment和pod的定义以及一个简单的架构图:
一个 Deployment 为 Pods 和 ReplicaSets 提供声明式的更新能力。 你负责描述 Deployment 中的 目标状态,而 Deployment 控制器(Controller) 以受控速率更改实际状态, 使其变为期望状态。你可以定义 Deployment 以创建新的 ReplicaSet,或删除现有 Deployment, 并通过新的 Deployment 收养其资源。
Pod 是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元。 Pod (就像在鲸鱼荚或者豌豆荚中)是一组(一个或多个) 容器; 这些容器共享存储、网络、以及怎样运行这些容器的声明。 Pod 中的内容总是并置(colocated)的并且一同调度,在共享的上下文中运行。 Pod 所建模的是特定于应用的“逻辑主机”,其中包含一个或多个应用容器, 这些容器是相对紧密的耦合在一起的。 在非云环境中,在相同的物理机或虚拟机上运行的应用类似于 在同一逻辑主机上运行的云应用。

从官方文档可以得出,deployment负责pod的创建、销毁等,而pod是一组共享存储、网络等的容器集合,且所有容器均运行在同一台服务器上(相当于一个pod就是一台主机)。有些人可能会有疑问,为什么会需要deployment和pod,这里先解释一下:
deployment:这个很简单,k8s关注的是应用部署本身,而一个应用可能包含很多组件,某些组件还需要对外暴漏服务等,如果某个组件挂了还需要被拉起来,而这个总的管理着就是deployment。对用户来说,我只关心我的deployment是如何写的,至于你如何按我的deployment去部署应用,那是deployment的事情。你可能会说这样的说deployment岂不是会功能太多、太复杂,对,如果这样做是很复杂,所以k8s有了pod、ReplicaSet(这里引入ReplicaSet,先不用管)等,让其协助管理更细节的东西。
首先看一些最简单的事例,部署nginx:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx-deploy
spec:
selector:
matchLabels:
app: nginx-pod
template:
metadata:
labels:
app: nginx-pod
spec:
containers:
- name: nginx
image: ustc-edu-cn.mirror.aliyuncs.com/library/nginx:1.19-alpine下面我们来解释说明一下各个键的作用:
apiVersion这个配置。Deployment、Pod、DaemonSet等。Deployment的一些信息,如metadata.name指定该Deployment的名称,labels用于给当前Deployment打标签,方便查询定位。Deployment部署的核心,所以这里会展开说明一下。spec.selector是为了确定需要部署的pod,这里的matchLabels是在下面spec.template中指定的labels。pod的信息,其下的spec.template.metadata.labels就是用于指定该pod的标签信息。而spec.template.spec则用于说明pod中要创建的容器的信息。以上只是部分配置文件的值的说明,更多关于Deployment文件的说明,请参考:https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.19/#deployment-v1-apps
将上面的yaml代码保存为文件,如nginx.yml,然后运行如下命令:
kubectl apply -f nginx.yml然后使用kubectl get deployments命令查看部署状态,kubectl get pods命令查看所有创建的pod的状态信息,刚开始执行的时候,可以看到pod的STATUS为ContainerCreating,Deployment的的信息中AVAILABLE为0,但是果断时间再此查看,会发现AVAILABLE和STATUS已经正常。


通过kubectl get events --sort-by=.metadata.creationTimestamp可以看到具体的执行信息:

暴漏k8s服务(端口)我们下一节介绍,但是我们现在需要验证服务,这就需要通过另外一种途径了。根据docker php镜像文档,我们可以知道,默认情况下,nginx监听80端口,那我们只需要知道容器的IP即可访问,想要知道容器的IP,只需要describe pod的详情即可:
kubectl get pods
kubectl describe pods <pod-name>
上图中获取的是pod的IP,但我们知道pod中所有的container共享同一网络,那container的IP也是pod的IP,即:10.244.3.4。然后我们直接在某一节点上(master节点也可以)curl -v http://10.244.3.4即可验证。

可以看到服务可以正常访问。至此部署应用的任务已经完成,下一节我们将介绍k8s如何对外暴漏服务。
PS:为什么从任何一个节点可以直接访问pod IP呢?回顾一下我们搭建集群那篇文章,我们使用了flannel网络插件,这个插件会将k8s中每个节点生成的pod与改节点都都放在同一个网段下,即10.244.x.0/24,而每个节点都会有指向其它网络的路由表:

相当于所有pod和节点都在一张平面网络上(都在同一个网段10.244.0.0/16),所以可以直接访问。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。