emptyDir
的用法有:PersistentVolume
(PV)PersistentVolumeClaim
(PVC)ConfigMap 功能在 Kubernetes1.2 版本中引入,许多应用程序会从配置文件、命令行参数或环境变量中读取配置信息。ConfigMap API 给我们提供了向容器中注入配置信息的机制,ConfigMap 可以被用来保存单个属性,也可以用来保存整个配置文件或者 JSON 二进制等对象
Ⅰ、使用目录创建
$ ls docs/user-guide/configmap/kubectl/ game.file ui.file $ cat docs/user-guide/configmap/kubectl/game.file version=1.17 name=dave age=18 $ cat docs/user-guide/configmap/kubectl/ui.properties level=2 color=yellow $ kubectl create configmap game-config --from-file=docs/user-guide/configmap/kubectl
—from-file
指定在目录下的所有文件都会被用在 ConfigMap 里面创建一个键值对,键的名字就是文件名,值就是文件的内容
只要指定为一个文件就可以从单个文件中创建 ConfigMap
$ kubectl create configmap game-config-2 --from-file=./game.file
—from-file
这个参数可以使用多次,你可以使用两次分别指定上个实例中的那两个配置文件,效果就跟指定整个目录是一样的
使用文字值创建,利用 —from-literal
参数传递配置信息,该参数可以使用多次,格式如下
$ kubectl create configmap literal-config --from-literal=name=dave --from-literal=password=pass $ kubectl get configmaps literal-config -o yaml
Ⅰ、使用 ConfigMap 来替代环境变量
apiVersion: v1 kind: ConfigMap metadata: name: literal-config namespace: default data: name: dave password: pass
apiVersion: v1 kind: ConfigMap metadata: name: env-config namespace: default data: log_level: INFO
apiVersion: v1 kind: Pod metadata: name: cm-env-test-pod spec: containers: - name: test-container image: wangyanglinux/myapp:v1 command: [ "/bin/sh", "-c", "env" ] env: - name: USERNAME valueFrom: configMapKeyRef: name: literal-config key: name - name: PASSWORD valueFrom: configMapKeyRef: name: literal-config key: password envFrom: - configMapRef: name: env-config restartPolicy: Never
apiVersion: v1 kind: Pod metadata: name: cm-command-dapi-test-pod spec: containers: - name: test-container image: wangyanglinux/myapp:v1 command: [ "/bin/sh", "-c", "echo $(USERNAME) $(PASSWORD)" ] env: - name: USERNAME valueFrom: configMapKeyRef: name: literal-config key: name - name: PASSWORD valueFrom: configMapKeyRef: name: literal-config key: password restartPolicy: Never
在数据卷里面使用这个 ConfigMap,有不同的选项。最基本的就是将文件填入数据卷,在这个文件中,键就是文件名,键值就是文件内容
apiVersion: v1 kind: Pod metadata: name: cm-volume-test-pod spec: containers: - name: test-container image: wangyanglinux/myapp:v1 volumeMounts: - name: config-volume mountPath: /etc/config volumes: - name: config-volume configMap: name: literal-config restartPolicy: Never
apiVersion: v1 kind: ConfigMap metadata: name: log-config namespace: default data: log_level: INFO --- apiVersion: extensions/v1beta1 kind: Deployment metadata: name: hot-update spec: replicas: 1 template: metadata: labels: run: my-nginx spec: containers: - name: my-nginx image: wangyanglinux/myapp:v1 ports: - containerPort: 80 volumeMounts: - name: config-volume mountPath: /etc/config volumes: - name: config-volume configMap: name: log-config
$ kubectl exec `kubectl get pods -l run=my-nginx -o=name|cut -d "/" -f2` cat /etc/config/log_level INFO
修改 ConfigMap
$ kubectl edit configmap log-config
修改 log_level
的值为 DEBUG
等待大概 10 秒钟时间,再次查看环境变量的值
$ kubectl exec `kubectl get pods -l run=my-nginx -o=name|cut -d "/" -f2` cat /tmp/log_level DEBUG
<!--!!! 特别注意 configMap 如果以 ENV 的方式挂载至容器,修改 configMap 并不会实现热更新-->
ConfigMap 更新后滚动更新 Pod
更新 ConfigMap 目前并不会触发相关 Pod 的滚动更新,可以通过修改 pod annotations 的方式强制触发滚动更新
$ kubectl patch deployment my-nginx --patch '{"spec": {"template": {"metadata": {"annotations": {"version/config": "20190411" }}}}}'
这个例子里我们在 .spec.template.metadata.annotations
中添加 version/config
,每次通过修改 version/config
来触发滚动更新
!!! 更新 ConfigMap 后:
使用该 ConfigMap 挂载的 Env 不会同步更新
使用该 ConfigMap 挂载的 Volume 中的数据需要一段时间(实测大概10秒)才能同步更新
Secret 解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者 Pod Spec 中。Secret 可以以 Volume 或者环境变量的方式使用
Secret 有三种类型:
/run/secrets/kubernetes.io/serviceaccount
目录中Service Account 用来访问 Kubernetes API,由 Kubernetes 自动创建,并且会自动挂载到 Pod的 /run/secrets/kubernetes.io/serviceaccount
目录中
$ kubectl run nginx --image nginx deployment "nginx" created $ kubectl get pods NAME READY STATUS RESTARTS AGE nginx-3137573019-md1u2 1/1 Running 0 13s $ kubectl exec nginx-3137573019-md1u2 ls /run/secrets/kubernetes.io/serviceaccount ca.crt namespace token
Opaque 类型的数据是一个 map 类型,要求 value 是 base64 编码格式:
$ echo -n "admin" | base64 YWRtaW4= $ echo -n "1f2d1e2e67df" | base64 MWYyZDFlMmU2N2Rm
secrets.yml
apiVersion: v1 kind: Secret metadata: name: mysecret type: Opaque data: password: MWYyZDFlMmU2N2Rm username: YWRtaW4=
1、将 Secret 挂载到 Volume 中
apiVersion: v1 kind: Pod metadata: labels: name: seret-test name: seret-test spec: volumes: - name: volumes12 secret: secretName: mysecret containers: - image: wangyanglinux/myapp:v1 name: db volumeMounts: - name: volumes12 mountPath: "/data"
2、将 Secret 导出到环境变量中
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: pod-deployment spec: replicas: 2 template: metadata: labels: app: pod-deployment spec: containers: - name: pod-1 image: wangyanglinux/myapp:v1 ports: - containerPort: 80 env: - name: TEST_USER valueFrom: secretKeyRef: name: mysecret key: username - name: TEST_PASSWORD valueFrom: secretKeyRef: name: mysecret key: password
使用 Kuberctl 创建 docker 仓库认证的 secret
$ kubectl create secret docker-registry myregistrykey --docker-server=DOCKER_REGISTRY_SERVER --docker-username=DOCKER_USER --docker-password=DOCKER_PASSWORD --docker-email=DOCKER_EMAIL secret "myregistrykey" created.
在创建 Pod 的时候,通过 imagePullSecrets
来引用刚创建的 myregistrykey
apiVersion: v1 kind: Pod metadata: name: foo spec: containers: - name: foo image: hub.hongfu.com/wangyang/myapp:v1 imagePullSecrets: - name: myregistrykey
容器磁盘上的文件的生命周期是短暂的,这就使得在容器中运行重要应用时会出现一些问题。首先,当容器崩溃时,kubelet 会重启它,但是容器中的文件将丢失——容器以干净的状态(镜像最初的状态)重新启动。其次,在 Pod
中同时运行多个容器时,这些容器之间通常需要共享文件。Kubernetes 中的 Volume
抽象就很好的解决了这些问题
Kubernetes 中的卷有明确的寿命 —— 与封装它的 Pod 相同。所f以,卷的生命比 Pod 中的所有容器都长,当这个容器重启时数据仍然得以保存。当然,当 Pod 不再存在时,卷也将不复存在。也许更重要的是,Kubernetes 支持多种类型的卷,Pod 可以同时使用任意数量的卷
Kubernetes 支持以下类型的卷:
awsElasticBlockStore
azureDisk
azureFile
cephfs
csi
downwardAPI
emptyDir
fc
flocker
gcePersistentDisk
gitRepo
glusterfs
hostPath
iscsi
local
nfs
persistentVolumeClaim
projected
portworxVolume
quobyte
rbd
scaleIO
secret
storageos
vsphereVolume
当 Pod 被分配给节点时,首先创建 emptyDir
卷,并且只要该 Pod 在该节点上运行,该卷就会存在。正如卷的名字所述,它最初是空的。Pod 中的容器可以读取和写入 emptyDir
卷中的相同文件,尽管该卷可以挂载到每个容器中的相同或不同路径上。当出于任何原因从节点中删除 Pod 时,emptyDir
中的数据将被永久删除
emptyDir
的用法有:apiVersion: batch/v1 kind: Job metadata: name: jobs-empty spec: template: spec: restartPolicy: Never initContainers: - name: job-1 image: busybox:1.34.1 command: - 'sh' - '-c' - > for i in 1 2 3; do echo "job-1 `date`"; sleep 1s; done; echo job-1 GG > /srv/input/code volumeMounts: - mountPath: /srv/input/ name: input - name: job-2 image: busybox:1.34.1 command: - 'sh' - '-c' - > for i in 1 2 3; do echo "job-2 `date`"; sleep 1s; done; cat /srv/input/code && echo job-2 GG > /srv/input/output/file resources: requests: cpu: 3 volumeMounts: - mountPath: /srv/input/ name: input - mountPath: /srv/input/output/ name: output containers: - name: job-3 image: busybox:1.34.1 command: - 'sh' - '-c' - > echo "job-1 and job-2 completed"; sleep 3s; cat /srv/output/file volumeMounts: - mountPath: /srv/output/ name: output volumes: - name: input emptyDir: {} - name: output emptyDir: {}
hostPath
卷将主机节点的文件系统中的文件或目录挂载到集群中
hostPath
的用途如下:
/var/lib/docker
的 hostPath
/dev/cgroups
的 hostPath
除了所需的 path
属性之外,用户还可以为 hostPath
卷指定 type
值 | 行为 |
---|---|
空字符串(默认)用于向后兼容,这意味着在挂载 hostPath 卷之前不会执行任何检查。 | |
DirectoryOrCreate |
如果在给定的路径上没有任何东西存在,那么将根据需要在那里创建一个空目录,权限设置为 0755,与 Kubelet 具有相同的组和所有权。 |
Directory |
给定的路径下必须存在目录 |
FileOrCreate |
如果在给定的路径上没有任何东西存在,那么会根据需要创建一个空文件,权限设置为 0644,与 Kubelet 具有相同的组和所有权。 |
File |
给定的路径下必须存在文件 |
Socket |
给定的路径下必须存在 UNIX 套接字 |
CharDevice |
给定的路径下必须存在字符设备 |
BlockDevice |
给定的路径下必须存在块设备 |
使用这种卷类型是请注意,因为:
hostPath
使用的资源hostPath
卷apiVersion: v1 kind: Pod metadata: name: test-pd spec: containers: - image: wangyanglinux/myapp:v1 name: test-container volumeMounts: - mountPath: /test-pd name: test-volume volumes: - name: test-volume hostPath: # directory location on host path: /data # this field is optional type: Directory
PersistentVolume
(PV)是由管理员设置的存储,它是群集的一部分。就像节点是集群中的资源一样,PV 也是集群中的资源。 PV 是 Volume 之类的卷插件,但具有独立于使用 PV 的 Pod 的生命周期。此 API 对象包含存储实现的细节,即 NFS、iSCSI 或特定于云供应商的存储系统
PersistentVolumeClaim
(PVC)是用户存储的请求。它与 Pod 相似。Pod 消耗节点资源,PVC 消耗 PV 资源。Pod 可以请求特定级别的资源(CPU 和内存)。声明可以请求特定的大小和访问模式(例如,可以以读/写一次或 只读多次模式挂载)
集群管理员创建一些 PV。它们带有可供群集用户使用的实际存储的细节。它们存在于 Kubernetes API 中,可用于消费
当管理员创建的静态 PV 都不匹配用户的 PersistentVolumeClaim
时,集群可能会尝试动态地为 PVC 创建卷。此配置基于 StorageClasses
:PVC 必须请求 [存储类],并且管理员必须创建并配置该类才能进行动态创建。声明该类为 ""
可以有效地禁用其动态配置
要启用基于存储级别的动态存储配置,集群管理员需要启用 API server 上的 DefaultStorageClass
[准入控制器] 。例如,通过确保 DefaultStorageClass
位于 API server 组件的 --admission-control
标志,使用逗号分隔的有序值列表中,可以完成此操作
master 中的控制环路监视新的 PVC,寻找匹配的 PV(如果可能),并将它们绑定在一起。如果为新的 PVC 动态调配 PV,则该环路将始终将该 PV 绑定到 PVC。否则,用户总会得到他们所请求的存储,但是容量可能超出要求的数量。一旦 PV 和 PVC 绑定后,PersistentVolumeClaim
绑定是排他性的,不管它们是如何绑定的。 PVC 跟 PV 绑定是一对一的映射
PVC 保护的目的是确保由 pod 正在使用的 PVC 不会从系统中移除,因为如果被移除的话可能会导致数据丢失
当启用PVC 保护 alpha 功能时,如果用户删除了一个 pod 正在使用的 PVC,则该 PVC 不会被立即删除。PVC 的删除将被推迟,直到 PVC 不再被任何 pod 使用
PersistentVolume
类型以插件形式实现。Kubernetes 目前支持以下插件类型:
持久卷演示代码
apiVersion: v1 kind: PersistentVolume metadata: name: pv0003 spec: capacity: storage: 5Gi volumeMode: Filesystem accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Recycle storageClassName: slow mountOptions: - hard - nfsvers=4.1 nfs: path: /tmp server: 172.17.0.2
PersistentVolume
可以以资源提供者支持的任何方式挂载到主机上。如下表所示,供应商具有不同的功能,每个 PV 的访问模式都将被设置为该卷支持的特定模式。例如,NFS 可以支持多个读/写客户端,但特定的 NFS PV 可能以只读方式导出到服务器上。每个 PV 都有一套自己的用来描述特定功能的访问模式
在命令行中,访问模式缩写为:
Volume 插件 | ReadWriteOnce | ReadOnlyMany | ReadWriteMany |
---|---|---|---|
AWSElasticBlockStoreAWSElasticBlockStore | ✓ | - | - |
AzureFile | ✓ | ✓ | ✓ |
AzureDisk | ✓ | - | - |
CephFS | ✓ | ✓ | ✓ |
Cinder | ✓ | - | - |
FC | ✓ | ✓ | - |
FlexVolume | ✓ | ✓ | - |
Flocker | ✓ | - | - |
GCEPersistentDisk | ✓ | ✓ | - |
Glusterfs | ✓ | ✓ | ✓ |
HostPath | ✓ | - | - |
iSCSI | ✓ | ✓ | - |
PhotonPersistentDisk | ✓ | - | - |
Quobyte | ✓ | ✓ | ✓ |
NFS | ✓ | ✓ | ✓ |
RBD | ✓ | ✓ | - |
VsphereVolume | ✓ | - | - (当 pod 并列时有效) |
PortworxVolume | ✓ | - | ✓ |
ScaleIO | ✓ | ✓ | - |
StorageOS | ✓ | - | - |
rm -rf /thevolume/*
)当前,只有 NFS 和 HostPath 支持回收策略。AWS EBS、GCE PD、Azure Disk 和 Cinder 卷支持删除策略
卷可以处于以下的某种状态:
命令行会显示绑定到 PV 的 PVC 的名称
yum install -y nfs-common nfs-utils rpcbind mkdir /nfsdata chmod 666 /nfsdata chown nfsnobody /nfsdata cat /etc/exports /nfsdata *(rw,no_root_squash,no_all_squash,sync) systemctl start rpcbind systemctl start nfs
apiVersion: v1 kind: PersistentVolume metadata: name: nfspv1 spec: capacity: storage: 1Gi accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Recycle storageClassName: nfs nfs: path: /data/nfs server: 10.66.66.10
apiVersion: v1 kind: Service metadata: name: nginx labels: app: nginx spec: ports: - port: 80 name: web clusterIP: None selector: app: nginx --- apiVersion: apps/v1 kind: StatefulSet metadata: name: web spec: selector: matchLabels: app: nginx serviceName: "nginx" replicas: 3 template: metadata: labels: app: nginx spec: containers: - name: nginx image: wangyanglinux/myapp:v1 ports: - containerPort: 80 name: web volumeMounts: - name: www mountPath: /usr/share/nginx/html volumeClaimTemplates: - metadata: name: www spec: accessModes: [ "ReadWriteOnce" ] storageClassName: "nfs" resources: requests: storage: 1Gi
Statefulset的启停顺序:
有序部署:部署StatefulSet时,如果有多个Pod副本,它们会被顺序地创建(从0到N-1)并且,在下一个Pod运行之前所有之前的Pod必须都是Running和Ready状态。
有序删除:当Pod被删除时,它们被终止的顺序是从N-1到0。
有序扩展:当对Pod执行扩展操作时,与部署一样,它前面的Pod必须都处于Running和Ready状态。
StatefulSet使用场景:
Scheduler 是 kubernetes 的调度器,主要的任务是把定义的 pod 分配到集群的节点上。听起来非常简单,但有很多要考虑的问题:
Sheduler 是作为单独的程序运行的,启动之后会一直坚挺 API Server,获取 PodSpec.NodeName
为空的 pod,对每个 pod 都会创建一个 binding,表明该 pod 应该放到哪个节点上
调度分为几个部分:首先是过滤掉不满足条件的节点,这个过程称为 预选
;然后对通过的节点按照优先级排序,这个是 优选
;最后从中选择优先级最高的节点。如果中间任何一步骤有错误,就直接返回错误
预选 有一系列的算法可以使用:
PodFitsResources
:节点上剩余的资源是否大于 pod 请求的资源PodFitsHost
:如果 pod 指定了 NodeName,检查节点名称是否和 NodeName 匹配PodFitsHostPorts
:节点上已经使用的 port 是否和 pod 申请的 port 冲突PodSelectorMatches
:过滤掉和 pod 指定的 label 不匹配的节点NoDiskConflict
:已经 mount 的 volume 和 pod 指定的 volume 不冲突,除非它们都是只读如果在 预选
过程中没有合适的节点,pod 会一直在 pending
状态,不断重试调度,直到有节点满足条件。经过这个步骤,如果有多个节点满足条件,就继续 优选
过程: 按照优先级大小对节点排序
优先级由一系列键值对组成,键是该优先级项的名称,值是它的权重(该项的重要性)。这些优先级选项包括:
LeastRequestedPriority
:通过计算 CPU 和 Memory 的使用率来决定权重,使用率越低权重越高。换句话说,这个优先级指标倾向于资源使用比例更低的节点BalancedResourceAllocation
:节点上 CPU 和 Memory 使用率越接近,权重越高。这个应该和上面的一起使用,不应该单独使用ImageLocalityPriority
:倾向于已经有要使用镜像的节点,镜像总大小值越大,权重越高通过算法对所有的优先级项目和权重进行计算,得出最终的结果
除了 kubernetes 自带的调度器,你也可以编写自己的调度器。通过 spec:schedulername
参数指定调度器的名字,可以为 pod 选择某个调度器进行调度。比如下面的 pod 选择 my-scheduler
进行调度,而不是默认的 default-scheduler
:
apiVersion: v1 kind: Pod metadata: name: test-scheduler labels: name: test-scheduler spec: schedulername: test-scheduler containers: - name: pod-with-second-annotation-container image: wangyanglinux/myapp:v2
apiVersion: v1 kind: Pod metadata: name: affinity labels: app: node-affinity-pod spec: containers: - name: with-node-affinity image: wangyanglinux/myapp:v1 affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: NotIn values: - k8s-node02
preferredDuringSchedulingIgnoredDuringExecution
apiVersion: v1 kind: Pod metadata: name: affinity labels: app: node-affinity-pod spec: containers: - name: with-node-affinity image: wangyanglinux/myapp:v1 affinity: nodeAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: source operator: In values: - qikqiak
合体
apiVersion: v1 kind: Pod metadata: name: affinity labels: app: node-affinity-pod spec: containers: - name: with-node-affinity image: wangyanglinux/myapp:v1 affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: NotIn values: - k8s-node02 preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 preference: matchExpressions: - key: source operator: In values: - qikqiak
pod.spec.affinity.podAffinity/podAntiAffinity
apiVersion: v1 kind: Pod metadata: name: pod-3 labels: app: pod-3 spec: containers: - name: pod-3 image: wangyanglinux/myapp:v1 affinity: podAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchExpressions: - key: app operator: In values: - pod-1 topologyKey: kubernetes.io/hostname podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 1 podAffinityTerm: labelSelector: matchExpressions: - key: app operator: In values: - pod-2 topologyKey: kubernetes.io/hostname
亲和性/反亲和性调度策略比较如下:
调度策略 | 匹配标签 | 操作符 | 拓扑域支持 | 调度目标 |
---|---|---|---|---|
nodeAffinity | 主机 | In, NotIn, Exists, DoesNotExist, Gt, Lt | 否 | 指定主机 |
podAffinity | POD | In, NotIn, Exists, DoesNotExist | 是 | POD与指定POD同一拓扑域 |
podAnitAffinity | POD | In, NotIn, Exists, DoesNotExist | 是 | POD与指定POD不在同一拓扑域 |
节点亲和性,是 pod 的一种属性(偏好或硬性要求),它使 pod 被吸引到一类特定的节点。Taint 则相反,它使 节点 能够 排斥 一类特定的 pod
Taint 和 toleration 相互配合,可以用来避免 pod 被分配到不合适的节点上。每个节点上都可以应用一个或多个 taint ,这表示对于那些不能容忍这些 taint 的 pod,是不会被该节点接受的。如果将 toleration 应用于 pod 上,则表示这些 pod 可以(但不要求)被调度到具有匹配 taint 的节点上
使用 kubectl taint
命令可以给某个 Node 节点设置污点,Node 被设置上污点之后就和 Pod 之间存在了一种相斥的关系,可以让 Node 拒绝 Pod 的调度执行,甚至将 Node 已经存在的 Pod 驱逐出去
每个污点的组成如下:
key=value:effect
每个污点有一个 key 和 value 作为污点的标签,其中 value 可以为空,effect 描述污点的作用。当前 taint effect 支持如下三个选项:
NoSchedule
:表示 k8s 将不会将 Pod 调度到具有该污点的 Node 上PreferNoSchedule
:表示 k8s 将尽量避免将 Pod 调度到具有该污点的 Node 上NoExecute
:表示 k8s 将不会将 Pod 调度到具有该污点的 Node 上,同时会将 Node 上已经存在的 Pod 驱逐出去# 设置污点 kubectl taint nodes node1 key1=value1:NoSchedule # 节点说明中,查找 Taints 字段 kubectl describe pod pod-name # 去除污点 kubectl taint nodes node1 key1:NoSchedule-
设置了污点的 Node 将根据 taint 的 effect:NoSchedule、PreferNoSchedule、NoExecute 和 Pod 之间产生互斥的关系,Pod 将在一定程度上不会被调度到 Node 上。 但我们可以在 Pod 上设置容忍 ( Toleration ) ,意思是设置了容忍的 Pod 将可以容忍污点的存在,可以被调度到存在污点的 Node 上
tolerations: - key: "key1" operator: "Equal" value: "value1" effect: "NoSchedule" - key: "key1" operator: "Equal" value: "value1" effect: "NoExecute" tolerationSeconds: 3600 - key: "key2" operator: "Exists" effect: "NoSchedule"
Ⅰ、当不指定 key 值时,表示容忍所有的污点 key:
tolerations: - operator: "Exists"
Ⅱ、当不指定 effect 值时,表示容忍所有的污点作用
tolerations: - key: "key" operator: "Exists"
kubectl taint nodes Node-Name node-role.kubernetes.io/master=:PreferNoSchedule
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: myweb spec: replicas: 7 template: metadata: labels: app: myweb spec: nodeName: k8s-node01 containers: - name: myweb image: wangyanglinux/myapp:v1 ports: - containerPort: 80
Ⅱ、Pod.spec.nodeSelector:通过 kubernetes 的 label-selector 机制选择节点,由调度器调度策略匹配 label,而后调度 Pod 到目标节点,该匹配规则属于强制约束
apiVersion: extensions/v1beta1 kind: Deployment metadata: name: myweb spec: replicas: 2 template: metadata: labels: app: myweb spec: nodeSelector: type: backEndNode1 containers: - name: myweb image: harbor/tomcat:8.5-jre8 ports: - containerPort: 80