kubernetes(k8s)中YAML文件编写与使用
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了kubernetes(k8s)中YAML文件编写与使用相关的知识,希望对你有一定的参考价值。
参考技术A 它的基本语法规则如下:在k8s中只需要两种结构类型就行了:
Maps就是一个key:value的键值对,Maps 可以更加方便的去书写配置信息,例如:
第一行的---是分隔符,是可选的,在单一yaml文件中,可用连续三个连字号---区分多个文件。这里我们可以看到,我们有两个键:kind 和 apiVersion,他们对应的值分别是:v1 和Pod。
创建一个相对复杂一点的 YAML 文件,一个 KEY 对应的值不是字符串而是一个 Maps:
上面的 YAML 文件,metadata 这个 KEY 对应的值就是一个 Maps 了,而且嵌套的 labels 这个 KEY 的值又是一个 Map,你可以根据你自己的情况进行多层嵌套。
上面我们也提到了 YAML 文件的语法规则,YAML 处理器是根据行缩进来知道内容之间的关联性的。比如我们上面的 YAML 文件,我用了两个空格作为缩进,空格的数量并不重要,但是你得保持一致,并且至少要求一个空格(什么意思?就是你别一会缩进两个空格,一会缩进4个空格)。
我们可以看到 name 和 labels 是相同级别的缩进,所以 YAML 处理器就知道了他们属于同一个 MAP,而 app 是 labels 的值是因为 app 的缩进更大。
Lists 就是列表,说白了就是数组,在 YAML 文件中我们可以这样定义:
当然,list 的子项也可以是 Maps,Maps 的子项也可以是list如下所示:
比如这个 YAML 文件,我们定义了一个叫 containers 的 List 对象,每个子项都由 name、image、ports 组成,每个 ports 都有一个 key 为 containerPort 的 Map 组成。
API 说明: https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.10/
创建 Pod
这是我们上面定义的一个普通的 POD 文件,我们先来简单分析下文件内容:
·apiVersion,这里它的值是 v1,这个版本号需要根据我们安装的 kubernetes 版本和资源类型进行变化的,记住不是写死的。
·kind,这里我们创建的是一个 Pod,当然根据你的实际情况,这里资源类型可以是 Deployment、Job、Ingress、Service 等等。
·metadata:包含了我们定义的 Pod 的一些 meta 信息,比如名称、namespace、标签等等信息。
·spec:包括一些 containers,storage,volumes,或者其他 Kubernetes 需要知道的参数,以及诸如是否在容器失败时重新启动容器的属性。你可以在特定 Kubernetes API 找到完整的 Kubernetes Pod 的属性。
让我们来看一个典型的容器的定义:
在这个例子中,这是一个简单的最小定义:一个名字(front-end),基于 nginx 的镜像,以及容器 将会监听的一个端口(80)。在这些当中,只有名字是非常需要的,你也可以指定一个更加复杂的属性,例如在容器启动时运行的命令,应使用的参数,工作目录,或每次实例化时是否拉取映像的新副本。以下是一些容器可选的设置属性:
name
image
command
args
workingDir
ports
env
resources
volumeMounts
livenessProbe
readinessProbe
livecycle
terminationMessagePath
imagePullPolicy
securityContext
stdin
stdinOnce
tty
明白了 POD 的定义后,我们将上面创建 POD 的 YAML 文件保存成 pod.yaml,然后使用kubectl创建 POD:
然后我们就可以使用我们前面比较熟悉的 kubectl 命令来查看 POD 的状态了:
到这里我们的 POD 就创建成功了,如果你在创建过程中有任何问题,我们同样可以使用前面的kubectl describe 进行排查。我们先删除上面创建的 POD:
现在我们可以来创建一个真正的 Deployment。在上面的例子中,我们只是单纯的创建了一个 POD 实例,但是如果这个 POD 出现了故障的话,我们的服务也就挂掉了,所以 kubernetes 提供了一个Deployment的概念,可以让 kubernetes 去管理一组 POD 的副本,也就是副本集,这样就可以保证一定数量的副本一直可用的,不会因为一个 POD 挂掉导致整个服务挂掉。我们可以这样定义一个 Deployment:
注意这里的 apiVersion 对应的值是 extensions/v1beta1 ,当然 kind 要指定为 Deployment,因为这就是我们需要的,然后我们可以指定一些 meta 信息,比如名字,或者标签之类的。最后,最重要的是 spec 配置选项,这里我们定义需要两个副本,当然还有很多可以设置的属性,比如一个 Pod 在没有任何错误变成准备的情况下必须达到的最小秒数。 我们可以在 Kubernetes v1beta1 API 参考中找到一个完整的 Depolyment 可指定的参数列表。 现在我们来定义一个完整的 Deployment 的 YAML 文件:
看起来是不是和我们上面的 pod.yaml 很类似啊,注意其中的 template,其实就是对 POD 对象的定义。将上面的 YAML 文件保存为 deployment.yaml,然后创建 Deployment:
同样的,想要查看它的状态,我们可以检查 Deployment的列表:
我们可以看到所有的 Pods 都已经正常运行了。
到这里我们就完成了使用 YAML 文件创建 Kubernetes Deployment 的过程,在了解了 YAML 文件的基础后,定义 YAML 文件其实已经很简单了,最主要的是要根据实际情况去定义 YAML 文件,所以查阅 Kubernetes 文档很重要。
如何不编写 YAML 管理 Kubernetes 应用?
Kubernetes 将自身边界内的事物都抽象为资源。其中的主要部分,是以 Deployment、StatefulSet 为代表的 workload 工作负载控制器,其他各类资源都围绕这些主要的资源工作。这些资源合并起来,可以为 IT 技术工作者展现出一个以 workload 为中心的模型。Kubernetes 中所有的资源,都通过声明式配置文件来编辑描述,一条条的 Yaml 字段定义,给了 IT 技术人员最大的自由度的同时,也对技术人员的能力提出了极高的要求。
通过应用模型简化Kubernetes管理
当你的团队已经使用原生的 Kubernetes 一段时间,你多半会发现,并非每个 IT 技术人员都擅长编写复杂的 Kubernetes 声明式配置文件(YAML)。特别是对于开发人员他们的主要职责是业务开发,学习和编写YAML会增加他们的负担,甚至会抵触使用。
开源项目Rainbond 是一个 云原生应用管理平台,它使用 以应用为中心 的设计模式。基于这一设计模式重新抽象出了比 workload 更高层次的应用模型。从使用的体验上不需要学习和编写YAML,实现业务应用的全生命周期管理。应用对应一个完整的业务系统,由若干个可以单独管理的服务组件组成,部署业务组件可以从源代码和容器镜像,通过“拖拉拽”的方式编辑服务调用关系。每一个服务组件,可以基于图形化界面定义使用常见的一些运维特征。在此基础之上,用户还可以利用应用模型这一核心概念,做出更多高级操作,如将整个业务系统以应用模板的形式发布出来,业务系统可以基于该模板一键安装/升级。在软件交付这个领域,这种能力十分有用,无论最终交付环境在线或离线,都可以基于应用模板进行快速交付,甚至个性化交付。
Rainbond 使用的应用模型,让开发人员关注应用和业务本身,更易于被人所接受。对裁剪后保留下来的运维特征通过图形界面展示和交互,极大的降低了使用的难度,通过应用模版绝大多数开发者不必编辑复杂声明式配置文件就可以顺畅使用 Kubernetes 了。
将Kubernetes的YAML转换成应用模型
整个转化的过程,可以概括为三个步骤:
- 对于开发人员最常用Workload,可以从源码和容器镜像向导式的自动生成,或导入已有YAML和运行应用,导入过程自动识别所有可转化的 Workload 类型资源,包括 Deployment、StatefulSet, Job、CronJob 类型。这些资源会被转化成应用模型,转化后会以服务组件的形式运行。
- 导入生成的服务组件后,基本的Workload属性通过界面就可以查看和编辑,如环境变量、镜像地址等。转化过程中会将识别到的高级Workload 属性添加给服务组件,以Key/Value 或 Yaml 形式查看和管理。
- 非 Workload 的资源类型,如 Secret、ServiceAccount、Role 等资源,会被分类识别和加载到应用界面的
k8s资源
页面中,供操作人员以交互体验方式进行编辑。
可被纳管和转化的 高级Workload 属性包括:
属性名称 | 作用 |
---|---|
nodeSelector | 节点选择器:指定某种类型节点调度时使用。 |
labels | 标签:用于为服务组件自定义标签以被选择器使用。 |
volumes | 存储卷:用于定义不被 Rainbond 管理的卷类型的挂载。 |
volumeMounts | 挂载卷:与 volumes 搭配使用,将卷挂载给容器。 |
affinity | 亲和性:更高级的调度方式,包括节点亲和性和Pod亲和性。 |
tolerations | 容忍度:与节点污点搭配使用,具备指定容忍度的Pod才可以调度到指定节点上。 |
serviceAccountName | 服务账户名:为服务组件指定某个已存在的SA,使对应的Pod具备某些权限。 |
privileged | 特权模式:名副其实的配置,非必要不开启。 |
env | 环境变量:用于定义不被 Rainbond 管理的环境变量,支持引用操作。 |
值得注意的是,扩展后的 RAM 模型,依然能够发布为应用模板,供后续一键安装/升级/交付整套业务系统之用。
导入已有Kubernetes应用的测试和实践
以下测试是基于Rainbond v5.8进行的,为了测试 Kubernetes 已有应用导入,我计划使用已经在 wp
命名空间中部署完成的 Wordpress
建站系统来进行一次导入测试。这套系统由以下资源组成:
[root@localhost ~]# kubectl get secret,service,deployment,statefulset,pod -n wp
NAME TYPE DATA AGE
secret/default-token-nq5rs kubernetes.io/service-account-token 3 27m
secret/mysql-secret Opaque 2 27m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/wordpress NodePort 10.43.157.40 <none> 8080:30001/TCP 5m19s
service/wp-mysql ClusterIP 10.43.132.223 <none> 3306/TCP 27m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/wordpress 1/1 1 1 5m19s
NAME READY AGE
statefulset.apps/wp-mysql 1/1 27m
NAME READY STATUS RESTARTS AGE
pod/wordpress-66bc999449-qv97v 1/1 Running 0 5m19s
pod/wp-mysql-0 1/1 Running 0 27m
访问 Rainbond ,在集群处选择导入,在这个页面中,可以选择要导入资源的命名空间 wp
。平台会根据 label 来对资源进行分组:
Rainbond 根据资源定义的 label
来划分应用,如符合 app.kubernetes.io/name:wp-mysql
或 app:wordpress
的资源,会分布到图中两个不同的应用中去,而不具备上述 label
的资源,则会统一划分到一个未分组的应用中去。应用的划分非常关键,因为应用模型的高级应用是针对一个应用整体而言的,所以导入之前一定要仔细规划,添加合理的 label
。
导入过程中,Rainbond 将不同的属性,交由扩展后的模型管理,大部分运维操作已经变得很易用了,而另一部分,则交由 Kubernetes 属性页面进行管理。
一旦完成导入,wordpress
和 wp-mysql
两个应用就可以使用 Rainbond 进行管理了。
- 端口管理
wordpress
在导入之前依靠 NodePort
类型的 Service
对外暴露,但导入 Rainbond 管理之后,就可以借助网关对外暴露自己的 80 端口了。需要注意的是,你必须重启一次 wordpress
服务组件,来让访问策略生效。
对于某些业务而言,访问的入口不支持动态指定,这就需要业务侧也做出一些改动,来适应新的访问入口。对于 Wordpress
而言,需要重新定义常规选项中的站点地址。
- 存储管理
我部署的这套 wordpress
系统,所有组件的存储都使用的 hostpath
模式,这种配置虽说简单,但是并不适用于 Pod
可能发生漂移的大规模 Kubernetes 环境。Rainbond 部署后,会提供易用的共享存储,这种存储支持多个 Pod 间共享数据,以及 Pod 跨主机的迁移。原有的 hostpath 存储,可以重新进行定义。重新定义后的存储路径会变为空,所以记得找到新旧不同的路径,进行一次数据迁移。
实际意义
通过应用模型,让IT 技术人员可以更多的关心业务本身,而不是底层复杂工具的使用问题。最终的效果是简化操作成本和理解难度,让Kubernetes更加容易落地。
以上是关于kubernetes(k8s)中YAML文件编写与使用的主要内容,如果未能解决你的问题,请参考以下文章