K8S教程(6)Pod的创建与YAML资源清单

Tanglu Kubernetes 2020-09-14 5711 0

一、K8S YAML配置清单介绍

虽然使用kubectl或者dashboard都可以创建Pods,但在实际生产环境中一般都是使用一种YAML语言所创建的配置清单来对资源进行一个声明。Kubernetes 把集群里的一切资源都定义为 API 对象,然后通过 YAML 语言来描述 API 对象,告诉K8S目标最终应该有的一个状态。K8S会将YAML配置清单中的内容自动转换成JSON格式传送给API Server完成创建。在YAML 官网(https://yaml.org/)有对该语言规范的完整介绍。简单来说YAML 是 JSON 的超集,支持整数、浮点数、布尔、字符串、数组和对象等数据类型。任何合法的 JSON 文档也都是 YAML 文档,但和 JSON 比起来,YAML 的语法更简单,比如可以不使用花括号和方括号、Key 不需要使用双引号等

# YAML数组(列表)
OS: 
  - linux
  - macOS 
  - Windows
  
# 对应的 JSON
{
  "OS": ["linux", "macOS", "Windows"]
}


# YAML对象(字典)
Kubernetes:
  master: 1
  worker: 3
  
# 对应的 JSON 
{
  "Kubernetes": {
    "master": 1,
    "worker": 3
  }
}


二、如何编写YAML配置清单

K8S有许多的 API 对象可以写进YAML中,通过Kubernetes 的官方文档(https://kubernetes.io/docs/reference/kubernetes-api/)可以查阅到所有API对象和其支持的所有字段。不过官方文档内容太多,还有一些简单的办法可以帮助编写YAML

1、kubectl api-resources 命令

该命令可以查看当前 Kubernetes 版本支持的所有对象和类型

kubectl api-resources

1.png


2、kubectl explain命令

该命令相当于是 Kubernetes 自带的 API 文档,会给出对象字段的详细说明

kubectl explain pods
kubectl explain pods.metadata   #查看metadata下的子字段,如果带有required是必选字段
kubectl explain pods.spec
kubectl explain pods.spec.containers.livenessProbe.httpGet  #可以一级一级的往下查看,这里最后查看的是httpGet字段的定义方法


3、--dry-run 和 -o yaml

这两个选项都可以帮助我们获取到一份配置模板,其中的--dry-run代表空跑、-o yaml是生成 YAML 格式文件,结合起来就可以实现让 kubectl 不进行实际创建并只生成 YAML 文件的操作

kubectl run ngx --image=nginx:alpine --dry-run=client -o yaml

#生成的配置文件
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: ngx
  name: ngx
spec:
  containers:
  - image: nginx:alpine
    name: ngx
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}


#导出已有的Pod为YAML格式作为模板
kubectl get deployment nginx-test -o yaml


#使用dry-run干跑模式导出YAML
kubectl create deployment test --image=nginx:1.7.9  --dry-run -o yaml > nginx.yaml


三、K8S YAML配置清单字段简介

1、一个最简单的Pod配置清单

因为 Pod 也是 API 对象,所以它也必然具有 apiVersion、kind、metadata、spec 这四个基本组成部分。apiVersion和kind对于 Pod 来说分别是固定的值 "v1" 和 "Pod";metadata里可以配置 name、labels、namespace这几个字段(在 Kubernetes 里Pod 必须要有一个名字)。由于name 只是一个基本的标识,信息有限,所以还可以通过 labels 字段添加任意数量的标签进行管理。比如可以根据运行环境使用标签 env=dev/test/prod、根据所在的数据中心使用标签 region: north/south、根据应用在系统中的层次使用 tier=front/middle/back等等……

vi pod-demo.yaml
kind: Pod
metadata:
  name: pod-demo
  namespace: default
  labels:    
    owner: chrono    
    env: demo    
    region: north    
    tier: back
spec"
  containers:
    name: adminbox
    image: ikubernets/admin-box:v1.0
    imagePullPolicy: IfNotPresent
    command: ["/bin/bash","-c","sleep 3600"]


2、查看导出的deployment配置清单文件,主要有以下五个字段,而需要自己维护的实际只有4个字段

kubectl get deployment nginx-test -o yaml


· apiserver定义API组名和版本,如v1

kubectl api-versions  #查看K8S所支持API版本


pod1.png


· kind:定义资源类别,要创建的是POD就写为pod、Deployment、StatefulSet等

kubectl api-resources  #查看K8S所有资源类型


· metadata:元数据信息,包含资源名称、namespace等。namespace用于给资源进行分类,默认会有一个default名称空间

kubectl get namespaces  #查看namespace
kubectl create namespace myns  #创建一个名为myns的namespace


· spec(核心):该字段用于声明资源的属性状态、管理和维护 Pod(也就是说希望deployment最终是什么样的),spec字段内的属性通常应该和status字段内是一致的


· status(核心):资源当前状态,应该与spec接近才对,本字段无需配置,由K8S集群维护

3、
使用kubectl apply命令应用配置清单创建pod,使用kubectl get pods命令查看资源状态

kubectl apply -f pod-demo.yaml
kubectl get pods  #查看容器是否运行,正常情况应该是Running
kubectl get pods -o wide  #查看pod详细信息,包含了IP、所属Node等
kubectl get pods -n kube-system  #显示指定namespace的pod


4、创建pod后正常状态应该是Running,使用kubectl describe命令可以查看pod的详细信息用于排错,pod常见状态信息如下

· Pending:K8S接受了请求并且正在创建和孵化的过程

· Running:Pod正常运行状态

· Failed:容器运行失败

· Unknown:状态获取失败

kubectl describe pods pod-demo  #指定pod名称后,主要查看state字段


5、使用kubectl delete命令删除有问题的pod,然后重新apply配置清单

kubectl delete pods pod-demo
kubectl apply -f pod-demo.yaml


6、YAML文件经过应用后还会自动生成一些字段


四、K8S YAML应用示例与关键配置

· 编写YAML文件定义容器

vi nginx-test.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  annotations:  #描述信息,但和lable不同于它不能用于节点选择器,只作为元数据展示,使用kubectl describe时可以看到
    linuxe.cn/created-by: "cluster admin"
  namespace: web
  labels: 
    app: nginx
    version: 1.7.9 
spec:
  containers:  #定义容器
  - name: nginx  #pod的名称,可以定义多个
    image: nginx:1.7.9  #使用仓库的哪个镜像
    imagePullPolicy: IfNotPresent
    volumeMounts:  #引用共享存储
      - name: storage  #共享存储名
        mountPath: /tmp/storage  #共享存储在容器中的路径
    ports:  #需要容器暴露的端口
       - name: http
         containerPort: 80  #需要暴露的容器端口,会随机在宿主机中生成一个端口作为映射
         protocol: TCP
    resources:  # 容器资源限制,这里的值会决定服务质量QOS的类型
      requests: 
        cpu: 0.5  # 0.5代表500M
        memory: 500M
      limits:  #容器最大能分配的资源,实际资源是在请求的资源和最大资源之间波动
        cpu: 1
        memory: 1000M 
  volumes:
  - name: storage  #定义存储名,上面有调用
    emptyDir: {}  #数据共享策略,EmptyDir是同Pod中所有容器数据共享,Pod删除后数据也会删除;HostPath是把数据存放在宿主机中共享,删除Pod数据还在;NFS则是网络存储
  command: ["nginx"]   #nginx镜像运行后所执行的命令,如果没写的话则是镜像默认命令
  args: ["-s","reload"]  #command命令接收的参数
  #nodeSelector:  #节点选择器,pod会创建在符合条件的node上,还有一种nodeName可以直接指定某个节点去创建pod而不需要条件。    
  restartPolicy:
    OnFailure


· imagePullPolicy镜像拉取策略

IfNotPresent:默认策略,如果本地不存在镜像就到仓库中进行拉取

Always:不管镜像是否在本地存在都进行拉取

latest:如果本地镜像非最新版本或者没有指定tag,则到仓库进行拉取


· restartPolicy容器失败重启策略

Always:默认策略,不管容器发生什么情况导致不工作都将重启Pod,在该策略下如果一个任务是只运行一次就结束掉的简单任务也会不断被重启

OnFailure:当容器非正常停止时才会自动重启,比如容器内的某个任务状态返回值非0

Never:不管容器出现什么问题都不进行重启


· Pod资源管理

容器在运行过程中需要申请的资源是通过定义resource进行分配的,主要分配的资源是CPU和Memory。在进行资源定义的时候通过requests配置来向系统请求资源,通过limit配置来限制最大可用资源,一旦超过就会OOM,所以容器实际资源是在请求的资源和最大资源之间波动的。资源可以使用小数点或者M、G等单位表示,在对CPU资源进行配额时0.1和100m都等同于一个CPU的1/10


· 服务质量QOS

主要用于Pod调度和驱逐,优先级越低的QOS越容易被驱逐。不同QOS优先级不同,使用kubectl describe命令可以查看Qos Class:

1、BestEffort:默认的QoS级别,该级别是尽可能的为Pod分配资源,优先级最低

2、Burstable:资源可波动,requests小于limit的值就是该QOS,推荐

3、Guaranteed:完全可保障资源,必须使用requests和limit定义内存和CPU两项资源并且相等,优先级最高


· 设置K8S默认驱逐阈值与系统保留资源

通过设置可以为K8S做好资源规划

vi /etc/sysconfig/kubelet
KUBELET_EXTRA_ARGS="--kube-reserved=cpu-200m,memory=500Mi --eviction-hard=memory.available<1Gi"   #在系统资源只剩1个G的时候进行主动驱逐

systemctl restart kubelet


4、应用YAML文件创建资源

kubectl apply -f nginx-test.yaml


5、通过YAML文件删除资源

kubectl delete -f pod-test.yaml  #删除YAML文件中定义的资源

评论