# 官方提供@yunTaoScripts POD && 节点调度 🔥🔥

loading

# 创建POD

  • 生成pod简单yaml文件 kubectl run xx --image=nginx --dry-run=client -o yaml
  • 生成pod完整yaml文件 kubectl run xx --image=nginx --dry-run=server -o yaml
  • 通过命令运行pod
kubectl run 名字 --image=镜像 --image-pull-policy=镜像下载策略
# 镜像的下载策略
# Always 每次都下载最新镜像 
# Never 只使用本地镜像,从不下载 
# IfNotPresent 本地没有才下载
  • 查看帮助信息
kubectl explain --help
kubectl explain pods.spec.containers
  • 安装ns/context切换工具
=======(方法一)===============
kubectl krew install ctx
kubectl krew install ns
=======(方法二)=============
sudo git clone https://github.com/ahmetb/kubectx /opt/kubectx
sudo ln -s /opt/kubectx/kubectx /usr/local/bin/kubectx
sudo ln -s /opt/kubectx/kubens /usr/local/bin/kubens

# pod的基本操作

kubectl exec 命令
kubectl exec -it pod sh 
#如果pod里有多个容器,则命令是在第一个容器里执行 
kubectl exec -it demo -c demo1 sh
kubectl describe pod pod名 
kubectl logs pod名 -c 容器名 #如果有多个容器的话 
kubectl edit pod pod名

# pod里运行命令及生命周期

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: myapp
  name: myapp
spec:
  containers:
  - image: busybox
    name: myapp
    command: ['sh','-c','echo ok && sleep 100']
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: myapp1
  name: myapp1
spec:
  containers:
  - image: busybox
    name: myapp1
    command: 
    - sh
    - -c 
    - echo  what && sleep 100
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: myapp2
  name: myapp2
spec:
  containers:
  - image: busybox
    name: myapp2
    args: 
    - sh
    - -c 
    - echo  hi siri && sleep 100
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

# pod生命周期lifecycle

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: myapp
  name: myapp
spec:
  terminationGracePeriodSeconds: 6000  ### 在此时间内发出关闭信号,但是不强制关闭。
  containers:
  - image: busybox
    name: myapp
    command: ['sh','-c','echo ok && sleep 1000']
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: myapp5
  name: myapp5
spec:
  terminationGracePeriodSeconds: 100  ### 在此时间内发出关闭信号,但是不强制关闭。
  containers:
  - image: busybox
    imagePullPolicy: IfNotPresent 
    lifecycle:
      postStart: 
        exec:
          command: ['bin/sh','-c','mkdir /xx']  容器开始运行后执行
      preStop:
        exec:
          command: ["/bin/sh","-c","mkdir /yy"] 容器结束运行前执行
    command: ["/bin/sh","-c","echo '开始了' && sleep 10000"]
    name: myapp5
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

# 在pod中使用变量

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: myapp4
  name: myapp4
spec:
  terminationGracePeriodSeconds: 100  ### 在此时间内发出关闭信号,但是不强制关闭。
  containers:
  - image: nginx
    imagePullPolicy: IfNotPresent 
    env:                              ###增加环境变量
    - name: DEMOx    
      value: "Hello x sir" 
    - name: DEMOy
      value: "Hello y sir"
    name: myapp4
    command: ["/bin/echo"] 
    args: ["$(DEMOx)"]
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Always
status: {}

# pod的重启策略--单个容器正常退出

#Always 总是重启
#OnFailure 非正常退出才重启 
#Never 从不重启

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: myapp4
  name: myapp4
spec:
  terminationGracePeriodSeconds: 100  ### 在此时间内发出关闭信号,但是不强制关闭。
  containers:
  - image: nginx
    imagePullPolicy: IfNotPresent 
    env:                              ###增加环境变量
    - name: DEMOx    
      value: "Hello x sir" 
    - name: DEMOy
      value: "Hello y sir"
    name: myapp4
    command: ["/bin/echo"] 
    args: ["$(DEMOx)"]
    resources: {}
  dnsPolicy: ClusterFirst
  restartPolicy: Never               ### 从不重启

# POD的状态说明

  • Pending 因为其他的原因导致pod准备开始创建 还没有创建(卡住了)
  • Running pod已经被调度到节点上,且容器工作正常
  • Completed pod里所有容器正常退出 error
  • CrashLoopBackOff 创建的时候就出错,属于内部原因
  • imagePullBackoff 创建pod的时候,镜像下载失败

# 初始化容器

初始化容器的概念 比如一个容器A依赖其他容器,可以为A设置多个依赖容易A1,A2,A3,A1,A2,A3要按照顺序启动,A1没有启动启动起来的 话,A2,A3是不会启动的,直到所有的静态容器全部启动完毕,主容器A才会启动。一般用于A容器运行之前,先做一些准备工作。如果初始化容器失败,则会一直重启,pod不会创建

# 规则

  1. 它们总是运行到完成。
  2. 每个都必须在下一个启动之前成功完成。
  3. 如果 Pod 的 Init 容器失败,Kubernetes 会不断地重启该 Pod,直到 Init 容器成功为止。然而,如果 Pod 对应的 restartPolicy 为 Never,它不会重新启动。
  4. Init 容器支持应用容器的全部字段和特性,但不支持 Readiness Probe,因为它们必须在 Pod 就绪之前运行完 成。
  5. 如果为一个 Pod 指定了多个 Init 容器,那些容器会按顺序一次运行一个。 每个 Init 容器必须运行成功,下一个 才能够运行。
  6. 因为 Init 容器可能会被重启、重试或者重新执行,所以 Init 容器的代码应该是幂等的。 特别地,被写到 EmptyDirs 中文件的代码,应该对输出文件可能已经存在做好准备。
  7. 在 Pod 上使用 activeDeadlineSeconds,在容器上使用 livenessProbe,这样能够避免 Init 容器一直失败。 这就 为 Init 容器活跃设置了一个期限。
  8. 在 Pod 中的每个 app 和 Init 容器的名称必须唯一;与任何其它容器共享同一个名称,会在验证时抛出错误。
  9. 对 Init 容器 spec 的修改,被限制在容器 image 字段中。 更改 Init 容器的 image 字段,等价于重启该 Pod。

# 通过初始化容器完成例如存储卷挂载等准备工作

apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: null
  labels:
    run: myapp
  name: myapp
spec:
  volumes:
  - name: workdir
    emptyDir: {}
  restartPolicy: OnFailure
  containers:
  - image: nginx
    imagePullPolicy: IfNotPresent 
    command: ['/bin/sh','-c','echo hello && sleep 100']
    name: myapp
    volumeMounts:
    - name: workdir
      mountPath: "/xyt"
  initContainers:
  - name: init-poda
    image: busybox
    command: ['sh', '-c', 'touch /work-dir/aa.txt'] 
    volumeMounts:
    - name: workdir
      mountPath: "/work-dir"
    resources: {}
  dnsPolicy: ClusterFirst
status: {}

# 静态pod

  • 所谓静态pod就是,不是master上创建的,而是需要到Node的/etc/kubelet.d/里创建一 个yaml文件,然后根据这个yaml文件,创建一个pod,这样创建出来的node,是不会 接受master的管理的。当然,要是想创建静态pod的话,需要对node的kubelet配置文件进行一些设置才可以。 在指定目录下面创建一个yaml文件,然后改kubelet的systemd配置,reload+重启,检查下

  • /etc/kubernetes/manifests文件下创建静态POD。

# 节点调度

# 调度的三个对象

  • 待调度Pod列表
  • 可用node列表
  • 调度算法
    • 主机过滤
      NoDiskConflict 
      PodFitsResources 
      PodFitsPorts 
      MatchNodeSelector 
      HostName 
      NoVolumeZoneConflict 
      PodToleratesNodeTaints 
      CheckNodeMemoryPressure
      CheckNodeDiskPressure 
      MaxEBSVolumeCount 
      MaxGCEPDVolumeCount 
      MaxAzureDiskVolumeCount 
      MatchInterPodAffinity 
      GeneralPredicates 
      NodeVolumeNodeConflict
    
    • 主机打分
      LeastRequestedPriority
      公式:score=cpu ( ( capacity - sum ( requested ) ) * 10 / capacity) + memory ( ( capacity - sum ( requested) ) * 10 / capacity ) /2
      BalanceResourceAllocation
      公式:score = 10 -abs ( cpuFraction - memoryFraction ) * 10
      CalculateSpreadPriority
      公式:Score = 10 * ((maxCount -counts)/ (maxCount))
    

# 手动指定pod运行位置

  • 为节点指定标签 kubectl get nodes --show-labels kubectl label node node2 disktype=ssd kubectl label node node2 disktype-

  • 指定pod运行在指定节点

spec:
  nodeSelector: 
    disktype: ssd
  containers:

# 主机亲和性

# Exists,DoesNotExist
# In,NotIn
# Gt,Lt
affinity: nodeAffinity:
# requiredDuringSchedulingIgnoredDuringExecution: # 硬策略 # nodeSelectorTerms:
# - matchExpressions:
  # - key: kubernetes.io/hostname
  # operator: In
  # values:
  # - vms63.rhce.cc 
  # - vms62.rhce.cc
preferredDuringSchedulingIgnoredDuringExecution: # 软策略 
- weight: 2
  preference: 
    matchExpressions: 
    - key: bb
      operator: Gt 
      values:
      - "3"

# 调度:警戒线cordon

  • 如果一个node被标记为cordon,新创建的pod不会被调度到此node上 已经调度上去的 不会被移走,需要被删除让其重新生成.

# 调度:节点的drain

  • 如果一个节点被设置为drain,则此节点不再被调度pod, 且此节点上已经运行的pod会被驱逐(evicted)到其他节点 drain包含: cordon,evicted

# 调度:节点taint及pod的tolerations

kubectl describe nodes vms11.rhce.cc | grep -A1 Tain
kubectl taint nodes vms11.rhce.cc keyxx=valuexx:NoSchedule 
kubectl taint nodes vms11.rhce.cc keyxx:NoSchedule-
# 只有标签为keyxx=valuexx的pod才能调度到此node,否则不能
spec:
  restartPolicy: OnFailure
  tolerations:
  - key: "keyxx" 
    operator: "Equal" 
    value: "valuexx" 
    effect: "NoSchedule"
  containers: