K8S创建Pod的YAML文件详解(亲和性和节点选择器)

艺帆风顺 发布于 2025-04-02 23 次阅读


一、yaml文件的语法规则

    大小写敏感使用缩进表示层级关系缩进时不允许使用Tal键,只允许使用空格缩进的空格数目不重要,只要相同层级的元素左侧对齐即可#” 表示注释,从这个字符一直到行尾,都会被解析器忽略注:- - - 为可选的分隔符 ,当需要在一个文件中定义多个结构的时候需要使用

    二、结构类型

    在Kubernetes中,只需要知道两种结构类型即可

    • Lists

    • Maps

    1、YAML Maps

    Map顾名思义指的是字典,即一个Key:Value 的键值对信息。

      例如:---apiVersion: v1kind: Pod注:上述内容表示有两个键apiVersion和kind,分别对应的值为v1和Pod。

      Maps的value既能够对应字符串也能够对应一个Maps。

        例如:---apiVersion: v1kind: Podmetadata: name: kube100-site labels: app: web注:上述的YAML文件中,metadata这个KEY对应的值为一个Maps,而嵌套的labels这个KEY的值又是一个Map。实际使用中可视情况进行多层嵌套。YAML处理器根据行缩进来知道内容之间的关联。上述例子中,使用两个空格作为缩进,但空格的数据量并不重要,只是至少要求一个空格并且所有缩进保持一致的空格数 。例如,name和labels是相同缩进级别,因此YAML处理器知道他们属于同一map;它知道app是lables的值因为app的缩进更大。

        2、YAML Lists

        List即列表,说白了就是数组。

          例如:args -beijing -shanghai -shenzhen -guangzhou 注: 可以指定任何数量的项在列表中,每个项的定义以破折号(-)开头,并且与父元素之间存在缩进。

           当然Lists的子项也可以是Maps,Maps的子项也可以是List。

             例如: ---apiVersion: v1kind: Podmetadata: name: kube100-site labels: app: webspec: containers: - name: front-end image: nginx ports: - containerPort: 80 - name: flaskapp-demo image: jcdemo/flaskapp ports: 8080注:如上述文件所示,定义一个containers的List对象,每个子项都由name、image、ports组成,每个ports都有一个KEY为containerPort的Map组成。

            三、YAML常见语法

            1、apiversion

              #查看apiversion版本kubectl apiversions#列出集群中所有可用的api资源kubectl api-resources常用apiversionv1:Kubernetes API的稳定版本,包含很多核心对象:pod、service等。apps/v1:包含一些通用的应用层的api组合,如:Deployments, RollingUpdates, and ReplicaSets。batch/v1:包含与批处理和类似作业的任务相关的对象,如:job、cronjob。autoscaling/v1:允许根据不同的资源使用指标自动调整容器。networking.k8s.io/v1:用于Ingress。rbac.authorization.k8s.io/v1:用于RBAC。

              2、kind

                kind指定这个资源对象的类型,如 pod、deployment、statefulset、job、cronjob#可以使用kubectl api-resources查看有那些资源对象类型

                3、metadata(Pod的元数据)

                  metadata常用的配置项有 name,namespace,即配置其显示的名字与归属的命名空间。常用以下选项annotations:添加注释信息creationTimestamp:创建时间戳name: pod名称namespace:名称空间labels:标签例如:vim my-tomcat.yaml ---  apiVersion: v1  kind: Pod  #Pod的P必须大写  metadata:   annotations:      version: v1.0.0 #设置注释信息为版本    name: my-tomcat  #设置pod的名称    namespace: default #设置命名空间为默认的,即kubectl get pods不需要加-n=    labels: #设置标签      a: b  #设置标签的键值对,可以使用kubectl describe pod 查看  spec   containers:#设置容器参数   - name: tomcat-pod #设置容器名字    ports:    - containerPort:8080 #设置容器要映射的端口     image: docker.io/library/tomcat:8.5-jre-alpine #设置镜像名字     imagePullPolicy: IfNotPresent  #设置镜像拉取策略

                  四、spec(规格)

                  因为这个比较多,所以我就单列一大段

                  1、常用

                    一个嵌套字典与列表的配置项,也是主要的配置项,支持的子项非常多,根据资源对象的不同,子项会有不同的配置。字段详解:activeDeadlineSecond:定义了Pod的最长运行时间,一旦Pod超过这个时间,Pod就会自动终止dnsConfig: dnsConfig 字段用于设置Pod内部DNS解析的相关参数dnsPolicy:值为 Default、ClusterFirst、ClusterFirstWithHostNet、None Default:继承自所在Node的DNS配置          ClusterFirst:优先使用K8S的DNS配置,如果失败在用Node的DNS配置          ClusterFirstWithHostNet:优先使用K8S的DNS配置,如果失败在用主机上的DNS配置          None:禁用DNS配置hostAliases:允许在pod内部定义一个主机别名列表,类似于hosts文件hostNetwork: 如果参数设置为True时,那么这个Pod中的容器将会和宿主机共享网络命名空间,即它们将会使用宿主机网络配置containers:containers是一个对象列表,containers下的字段需要用-连接         字段必填:name、image         name:容器名称            image: 容器所需的镜像            imagePullPolicy:镜像拉取策略,值为IfNotPresent、Always、Never              IfNotPresent:如果本地镜像有,则用本地的,没有则去镜像仓库拉取              Never: 从不拉取,如果本地没有镜像,则进入等待              Always:总是拉取,无论本地有没有这个镜像            command:自定义容器内需要允许的cmd命令

                    2、节点选择器和nodeName

                      nodeName:nodename是每个node节点的唯一标识符,他是一个字符串,通常是节点的主机名(hostname)。所以在创建Pod的时候可以指定nodeName字段来将Pod调度到特定的Node节点上例:vim pod-node.yaml---apiVersion: v1kind: Podmetadata:   name: pod-name  namespace: defaultspec:  nodeName: lx252 #指定调度到的主机名为lx252的node节点 containers: - name: pod-name-containers image:tomcat:8.5-jre-alpine    imagePullPolicy: IfNotPresent验证:kubectl get pods -owide-owide: 查看pod的IP,调度到的节点等信息
                      节点选择器:节点选择器(NodeSelector)是用来将Pod调度到特定节点的一种机制,它基于Node节点的标签(node labels)来进行筛选和匹配,从而使pod能够被分配到满足其要求的节点上例:给节点打标签kubectl label nodes "节点名字" 标签键=标签值给节点lx252打memory=high的标签kubectl label nodes lx252 memory=high编写yamlvim pod-label.yaml---apiVersion: v1kind: Podmetadata: name: pod-name namespace: defaultspec: nodeSelector:    memory: high #将Pod调度到拥有memory=high标签的节点  containers: - name: pod-name-containers image:tomcat:8.5-jre-alpine imagePullPolicy: IfNotPresent

                      3、亲和性和反亲和性

                      亲和性

                        节点亲和性: nodeAffinity查看帮助:kubectl explain pod.spec.affinity.nodeAffinitypreferredDuringSchedulingIgnoreDuringExecution(软亲和性)它允许用户指定Pod调度器尽可能讲Pod调度到与指定节点亲和的节点上,但是如果没有可用的这样的节点,Pod也可以调度到其他节点上硬亲和性requireDuringSchedulingIgnoredDuringExecution(硬亲和性)它只能被调度到满足这个节点选择器的节点上,如果没有节点满足这个要求,Pod就无法被调度例:---apiVersion: v1kind: Podmetadata: name: affinityspec:  containers:  - name:pod-affinity    image: tomcat:8.5-jre-alpine  affinity:   nodeAffinity:      requiredDuringSchedulingIgnoredDuringExecution:        nodeSelectorTerms:        - matchExpressions:         - key: a         operator: In         values:            - b如果没有找到拥有标签a=b的node,那pod会一直是pending状态给node节点增加a=b标签kubectl label node lx253 a=b就会发现调度到了lx253 node节点上查看:kubectl get pods -owide
                        Pod亲和性pod亲和性分为两种Podaffinity(pod亲和性)是指一组Pod可以被调度到同一节点上,即它们互相吸引,倾向于被调度在同一台节点上Podunaffinity(Pod反亲和性):Pod反亲和性是一组Pod不应该被调度到同一节点上,即它们互相排斥,避免被调度到同一节点上requiredDuringSchedulingIgnoredDuringExecution(软亲和性)preferredDuringSchedulingIgnoredDuringExecution(硬亲和性)例:定义两个Pod调度到同一个位置pod1:---apiVersion: v1kind: podmetadata:  name: first labels:    app: first #以这个标签进行亲和spec: containers:  - name: first    image: ikubernetes/myapp:v1    imagePullPolicy: IfNotPresentpod2:---apiVersion: v1kind: podmetadata:   name: second labels:    app: secondspec: containers: - name: second image: ikubernetes/myapp:v1 imagePullPolicy: IfNotPresent    affinity:    podAffinity:    requiredDuringSchedulingIgnoreDuringExecution    - labelSelector:    matchExpressions:    - {key: app, operator: In, Values: ["first"]}    topologyKey: kubernetes.io/hostname kubectl get pods -owide #会发现两个Pod(first、second)在一个主机上  pod反亲和性例:定义两个Pod调度到不同位置Pod1:vim podunaffinity-1.yaml---apiVersion: v1kind: podmetadata: name: first-1 labels: app: first-1 #以这个标签进行反亲和spec: containers: - name: first-1 image: ikubernetes/myapp:v1 imagePullPolicy: IfNotPresentPod2:---apiVersion: v1kind: podmetadata: name: second-1 labels: app: second-1spec: containers: - name: second-1 image: ikubernetes/myapp:v1 imagePullPolicy: IfNotPresent affinity: podAntiAffinity: requiredDuringSchedulingIgnoreDuringExecution - labelSelector: matchExpressions: - {key: app, operator: In, Values: ["first-1"]} topologyKey: kubernetes.io/hostname kubectl get pods -owide #会发现两个Pod(first-1、second-1)不在一个主机上