前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >新手学习FFmpeg - 如何编写Kubernetes资源文件

新手学习FFmpeg - 如何编写Kubernetes资源文件

作者头像
随机来个数
发布2019-12-18 17:47:15
1.1K0
发布2019-12-18 17:47:15
举报
文章被收录于专栏:写代码的海盗

Kubernetes API的使用方式

Kubernetes API属于声明式API编程, 它和常用的命令式编程有一些区别。 通俗的说,命令式编程是第一人称,我要做什么,我要怎么做。 操作系统最喜欢这种编程范式了, 操作系统几乎不用"思考", 只要一对一的将代码翻译成指令就可以了。 而声明式编程则类似于"第二人称", 也就是你要做什么。 有点"产品经理"和"开发“之间的关系, "产品经理"只负责提需求,而"开发"怎么实现他不并关心。

用户相对Kubernetes就是"产品经理"的角色, 用户只需要给Kubernetes提需求就可以了,比如说你(Kubernetes)给我(用户)创建一个运行Mysql服务的Demployment,这个Deployment运行的Pod镜像是xxxx,运行参数是xxxxx,挂载的数据卷是xxxxx。。。。。 等等。 开发(Kubernetes)接受到这个需求后,看看需求是否合理(验证Deployment里面的参数是否正确),然后就开始创建了。 等待创建成功后,就告诉"产品经理"(用户)Deployment创建成功。

在创建过程中,用户并没有(也不需要)关心服务是如何创建的。 这种操作方式就是声明式API。

对于Kubernetes来说,声明式API最大的难点就在于如何提一个正确的需求了。 所以下面来看看如何给Kubernetes提需求。

API的载体 -- Yaml

用户可以通过kubectl与Kubernetes交互,使用kubectl会通过读取指定的资源定义文件来要求kubernetes创建各种资源,这里的资源文件指的就是"需求文档",在里面规定了各种资源的"大小","规格"。 为了用户可以方便理解里面的内容(实际使用过程中,感觉使用yaml其实并不方便。尤其是当数据层次多的时候,经常出现空白符不匹配导致解析失败的问题),资源文件使用了yaml格式(yaml对用户友好,kubectl提交需求时,会将yaml转换成json格式,所以Kubernetes其实最终读取的是json格式的需求文档).

我经常在编辑完之后,通过 https://codebeautify.org/yaml-validator 来验证格式是否正确。

编辑Yaml过程中,有如下几个注意事项:

  1. 通过空格控制缩进,不支持Tab
  2. 如果参数是以空格开始,则需要单引号将其包含起来, 如果参数中包括单引号,则需要进行转义操作
  3. 冒号后一定要有空格
  4. 使用一个短横+一个空格表示列表,同样的缩进层级表示属于同一个列表
  5. 空值使用null或者~表示。

API文档总览

Kubernetes的API文档在 https://kubernetes.io/docs/reference/ 点击版本号,就可以看到相对应的API文档说明。

Kubernetes API大致分为以下几类(个人起的名称,未必准确):

  • 计算类
  • 负载类
  • 配置类
  • 管理类

计算类对应是Workload,主要是Pod,Job,Deployment,ReplicaSet之类涉及到CPU计算的各种资源。 负载类指的是LB类资源,配置类指的是ConfigMap之类涉及到外部资源的数据资源, 而管理类指的是对集群的管理,例如创建命名空间,节点隔离等

对Kubernetes的资源操作,绝大多数就是对上面四类资源的操作。

一个标准的Kubernetes 资源文件,其结构大致是下面的样子:

代码语言:javascript
复制
apiVersion:
kind:
metadata:
spec:
status:

apiVersion表示API版本,服务端会通过读取这个版本号,来进行内容验证。 这个版本号可以通过API文档获取,例如要编写一个Deployment资源,首先查看API文档(https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#daemonset-v1-apps)如下

版本号由Group/Version这样的格式组成,因此Deployment的apiVersion就是apps/v1。 需要注意下面一行小字: "Other API versions of this object exist: v1beta2 v1beta1 v1beta1",因此apps/v1beta2apps/v1beta1这样的版本号也是合法的。 具体使用哪个版本号,最终要取决于集群支持哪个版本号。

kind表示操作的是什么资源, 向上面要操作Deployment,kind就是Deployment。 如果要创建Pod,则Kind就是Pod。

metadata则是此资源的一些元数据, 如何设置后面会聊到

spec是具体如何创建这个资源,同样放到后面再聊

status是此资源状态数据,用户不需要设置,即便设置,集群也会过滤掉

总结一下:

用户通过apiversion+kind告之集群,准备按照哪个API版本所规定的协议创建何种资源。 集群确认支持指定版本和资源后,就会读取后面的资源详细参数。 但需要注意,未必所有资源都有这几项,例如Configmap就没有Spec,但却增加了data. 后面会聊到如何通过API文档来组织资源文件

创建资源

来看metadata。每种资源有不同的metadata规范, 大部分场景中可以通用的,也就是说虽然资源不同,但metadata格式相同,只是里面的参数不同。 当需要查看具体metadata时,直接点击metadata下面的ObjectMeta,如下图:

会跳到ObjectMeata定义页面中:

这里仍然假设需要创建一个Deployment,apiVersionkind此时都已经确定了(如果仍然不明白,建议再看一下上面一节)。 然后开始写metedata. 通过ObjectMeta可以看到里面有很多属性,例如annotations表示一些注释信息,类型是obejct,通过后面的链接: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/ 可以得知是一个key=value格式的map。 如果要添加注释信息,可以按照如下方式编写:

代码语言:javascript
复制
apiVersion: apps/v1beta2
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"

在创建任何资源时,name和namesapce都是需要指定的(namespace如果不指定,默认是default,但指定namespace是一个好习惯)。查看name和namespace的定义:

都是字符串格式,因此在上面基础之上在添加name和namespace:

代码语言:javascript
复制
apiVersion: apps/v1beta2
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
  name: envoy-01
  namespace: tio

在某些场景中(其实是大多数场景),需要通过label来筛选对应的workload,所以有必要给我的Deployment添加特定的Label, 查看一下Label的定义:

查看后面的链接 (https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/) 可以看出也是一个key=value格式的map,和annotations一样,所以添加label如下:

代码语言:javascript
复制
apiVersion: apps/v1beta2
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
  labels:
    k8s-app: envoy-01
  name: envoy-01
  namespace: tio

metadata的定义就先看到这里,下面来看spec应该如何定义。

同样,直接点击deploymentspec下面的类型定义,

每个资源的spec都不同,下面是DeploymentSpec的定义:

每个属性都有解释,这里就不逐一翻译了, 我们假设这个Deployment预期两个Pod,因此replicas=2,通过selector来匹配ReplicaSet,设定strategy为滚动更新。 在上面资源文件的基础之上,我们继续定义spec,如下:

代码语言:javascript
复制
apiVersion: apps/v1beta2
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
  labels:
    k8s-app: envoy-01
  name: envoy-01
  namespace: tio
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: envoy-01
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate

selector可以参考(https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#labelselector-v1-meta)规定的规范strategy可以参看(https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.17/#deploymentstrategy-v1-apps)。

这些定义完成后,就剩下Template了,这个用来定义应该如何来创建Pod(或者说表示用户想要一个什么样的Pod)。

点击下面的Pod数据定义:

可以看到Pod Template有两个属性:

因此资源文件大致应该是如下的样子:

代码语言:javascript
复制
apiVersion: apps/v1beta2
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
  labels:
    k8s-app: envoy-01
  name: envoy-01
  namespace: tio
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: envoy-01
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
    spec:

metadataspec. 其中metadata和上面我们所设置的metadata一样,这里就不赘述了。spec通过下面的定义可以得知是podspec

点击podspec后可以看到和经常设置的docker container参数有一些类似了:

我们继续在上面资源文件基础上补充podspec的内容

代码语言:javascript
复制
apiVersion: apps/v1beta2
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "1"
  labels:
    k8s-app: envoy-01
  name: envoy-01
  namespace: tio
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: envoy-01
  strategy:
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
    type: RollingUpdate
  template:
    metadata:
      labels:
        k8s-app: envoy-01
    spec:
      containers:
      - args:
        - -c
        - /etc/envoy/envoy.yaml
        - --service-node
        - sn1
        - --service-cluster
        - sc1
        command:
        - envoy
        image: envoyproxy/envoy
        imagePullPolicy: IfNotPresent
        name: envoy
        resources:
          limits:
            cpu: 500m
            memory: 512Mi
          requests:
            cpu: 250m
            memory: 256Mi
        securityContext:
          privileged: false
          procMount: Default
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /etc/envoy
          name: conf

至此,一个最简单的Deployment资源文件就写好了。 剩下的就是通过kubectl提交这个需求给Kubernetes集群,然后就可以等待Kubernetes慢慢创建资源了。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-12-16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Kubernetes API的使用方式
    • API的载体 -- Yaml
      • API文档总览
        • 创建资源
        相关产品与服务
        容器服务
        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档