三、pod详解


pod基本概念
最小部署单元
可以包含多个容器
一个pod中的容器可以共享网络命名空间
pod是短暂的(可能做一次滚动更新,IP就可能发生变化)
 
适合放在一个pod中的应用
两个应用之间发生文件交互
  比如有两个应用需要共享数据,那么如果通过外部存储共享的方式,受到网络之类的影响,性能较差,可以用到pod中的数据卷进行数据交互
  两个应用需要通过127.0.0.1或者socket通信(比如:nginx+php)
  两个应用需要发生频繁的调用
 
Pod常用命令
查看pod
  kubectl get po
    -o wide 显示较详细信息
    -n 指定命名空间
 
查看service
  kubectl get service
 
删除pod命令
  kubectl delete pod {pod名称}
 
删除当前目录下所有yaml文件生成的pod
  kubectl delete -f .
  kubectl delete -f {yaml文件名}:删除该yaml文件生成的pod,不会删除yaml文件
 如果pod反复重启无法删除,则删除对应控制器
  如:kubectl get deployment 获取对应pod的name
    kubectl delete {控制器类型} {name前缀}
 
删除service
  kubectl delete service {service名称}
 
查看pod创建、启动的信息
  kubectl describe pod TYPE/NAME
  如:kubectl describe pod web-deployment-667d4bd8df-tv2c9
 
查看容器日志,观察有没有异常的日志
  kubectl logs TYPE/NAME
  如:kubectl logs web-deployment-667d4bd8df-tv2c9
  如果有两个容器:
  最后指定[-c CONTAINER]
  如:kubectl logs web-deployment-667d4bd8df-tv2c9 -c web2
 
如果一个pod中有多个容器,想进入不同的容器或看不同容器的日志,使用-c指定
  kubectl exec -ti {pod名称} -c {容器名称} -- sh
  kubectl logs {pod名称} -c {容器名称}
  容器的名称在yaml文件中查看
 
pod已经启动,进入调试应用
  kubectl exec POD [-c CONTAINER] -- COMMAND [args...]
 
 
pod中的容器分类
Infrastructure Container:基础容器
  维护整个Pod网络空间
 
InitContainers:初始化容器
  先于业务容器开始执行,最先启动的容器
 
Containers:业务容器
  并行启动
 
Pod 的实现原理
Pod 里的所有容器,共享的是同一个 Network Namespace,并且可以声明共享同一个 Volume,其实就是一组共享了某些资源的容器
容器的本质是进程,Pod,实际上是在扮演传统基础设施里“虚拟机”的角色;而容器,则是这个虚拟机里运行的用户程序。
 
pod文件释义
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-deployment
  annotations:
    kubernetes.io/change-cause: "django.v1"  #记录到revision中的内容,方便回滚
spec:
  # 副本数,一个副本代表启一个容器,如果一个pod挂了,那么会在其他副本再启一个
  replicas: 3
  selector:
    matchLabels:
      # 标签选择器,一般写两个,上面项目名,下面应用名
      project: blog
      app: django
  template:
    metadata:
      labels:
        project: blog
        app: django
    spec:
      # 打标签,资源调度使用
      nodeSelector:
        disktype: "ssd"
      containers:
      - name: web
        image: django# 镜像拉取策略
        imagePullPolicy: IfNotPresent
        # 资源限制
        resources:
          # 容器最大使用资源,pod内存如果超出limits,会被k8s kill掉
          # 最好都设置资源限制和请求资源值,因为没有限制pod会超出当前node承载能力的话,会造成资源争抢
          limits:
            # 1000m表示一核,500m表示0.5核
            cpu: 1000m
            memory: 512M
          # 请求的资源值,k8s会根据这个值调度到能容纳的node
          requests:
            cpu: 900m
            memory: 500M
        # 存活健康检查
        livenessProbe:
          exec:
            command:
              - cat
              - /tmp/healthy
          # 启动容器后多长时间做健康检查,单位秒
          initialDelaySeconds: 5
          # 检查周期间隔
          periodSeconds: 5
        # 就绪健康检查
        readinessProbe:
          exec:
            command:
              - cat
              - /tmp/healthy
        ports:
        - containerPort: 80
        # 设置容器内的变量
        env:
          - name: ABC
            value: 123
      # 重启策略
      restartPolicy: Always
      # 如果要启动第二个容器,下面继续写
      - name: web2
        image: nginx
      # 如果是私有镜像仓库,必须要登陆,这个为了指定登陆私有镜像仓库的凭据
      imagePullSecrets:
        -name: myregistrykey

 

镜像拉取策略
IfNotPresent:镜像在宿主机上不存在时才拉取
Always:默认值,每次创建Pod都会重新拉取一次镜像(即使镜像已经在宿主机上)
Never:Pod永远不会主动拉取这个镜像
一般都会选择Always
 
资源限制
为了让k8s稳定的运行,防止某一个pod占用资源过大导致连接挂掉
CPU
2 = 2000m
1 = 1000m
0.5 = 500m
0.25 = 250m
 
重启策略(restartPolicy)
Always:当容器终止退出后,总是重启容器,默认策略(比如nginx、mysql等需要使用)
OnFailure:当容器异常退出口(退出码为非0),才重启容器
Never:当容器终止退出,从不重启容器(短期运行的应用)
 
健康检查(Probe)
  Probe有两种类型
    存活检查(livenessProbe)
      如果检查失败,将杀死容器,根据Pod的重启策略来操作
    就绪检查(readinessProbe)
      如果检查失败,k8s会把Pod从service endpoints中剔除
  在生产环境中一般两个检查会一起配置,两个检查除了名称不一样以外,其他都是一样的
 
Probe支持一下三种检查方法(一般通过查进程,端口来判断)
httpGet
  发送HTTP请求,返回200-400范围状态码为存活
# 健康检查
livenessProbe:
  httpGet:
    path: /index.html
    port: 80
  # 启动容器后多长时间做健康检查,单位秒
  initialDelaySeconds: 5
  # 检查周期间隔
  periodSeconds: 5
exec
  执行Shell命令返回状态码是0为成功
tcpSocket
  发起TCP Socket建立成功
 
pod提供数据卷和infra container解决共享存储和网络
共享存储
比如有A、B两个容器,都需要读写同一个存储设备,那么一般会用到共享存储,但共享存储设备可能不在同一个空间内,会消耗过多的网络资源等,这时可以将两个容器部署在同一个Pod内,使用本地的磁盘来做数据交换,比如利用k8s提供的数据卷,A、B两个容器都读写同一个目录文件完成数据交换
 
共享网络
k8s在创建一个pod的时候,会默认创建一个负责网络的容器(infra container),该容器会有自己的网络命名空间,这时候把容器A、B加入到这个容器中,就打通了A、B两个容器的网络
 
nodeName
用于将Pod调度到指定的Node上,因为不经过调度器(scheduler ),所以针对污点之类的,nodeName还是可以分配到已设置污点的node上
apiVersion: v1
kind: Pod
metadata:
  name: pod-example
  labels:
    app: nginx
spec:
  # 指定分配到k8s-node2节点
  nodeName: k8s-node2
  containers:
  - name: nginx
    image: nginx:1.15
影响pod调度的因素
1、根据request的值查找有足够资源的node来调度此node
2、nodeSelector:用于将pod调度到匹配Label的node上
  给node打标签
    kubectl label nodes {node名称} key=value
    如:kubectl label nodes k8s-node1 disktype=ssd
  查看node的标签
    kubectl get node --show-labels
  删除node标签(最后横杠,别忘记)
    kubectl label nodes k8s-node2 {标签键名}-
    如:kubectl label nodes k8s-node1 disktype-
apiVersion: v1
kind: Pod
metadata:
    name: pod-example
spec:
    # 调度到标签为ssd的node上
    nodeSelector:
        disktype: "ssd"
containers:
 - name: nginx
  image: nginx:1.15

 

3、nodeAffinity:类似于nodeSelector,可以根据节点上的标签来约束Pod可以调度到哪些节点
  相比nodeSelector:
    匹配有更多的逻辑组合,不只是字符串的完全相等
    调度分为软策略和硬策略,而不是硬性要求
      硬: 必须满足,否则启动不成功
      软:尝试满足,不保证
  操作符:In、Notln、Exists、DoesNotExist、Gt、Lt
apiVersion: v1
kind: Pod
metadata:
  name: with-node-affinity
spec:
  affinity:
     nodeAffinity:
       #硬性要求,如果没有满足标签的node,那么无法启动
       requiredDuringSchedulingIgnoredDuringExecution:
         nodeSelectorTerms:
         - matchExpressions:
          # gpu是键
          - key: gpu
          # 意思是哪个node节点含有这个键值,就会调度到哪个node
            operator: In
            values:
            # 这是值
            - nvidia-tesla
        #软性要求
        preferredDuringSchedulingIgnoredDuringExecution:
        - weight: 1
          preference:
             matchExpressions:
             - key: group
             operator: In
             values:
             - ai
containers:
- name: web
image: nginx

 

4、污点(Taint)
  避免pod调度到特定的node上
    应用场景:
      专用节点
      配备了特殊硬件的节点
      基于污点的驱逐
    设置污点:
      kubtctl taint node {node名称} key=value:effect
      如:kubtctl taint node k8s-node1 gpu=yes:NoSchedule
      其中[effect]可取值为:
        NoSchedule: 一定不能被调度
        PreferNoSchedule:尽量不要调度
        NoExecute: 不仅不会调度,还会驱逐node上已有的pod,被驱逐的oid自 动分配至别的node
    删除污点:
      kubtctl taint node {node名称} key:[effect]-
    查看污点:
      kubectl describe node | grep -i taint
 
污点容忍(Tolerations)
apiVersion: v1
kind: Pod
metadata:
  name: pod-taints
spec:
  containers:
  - name: pod-taints
     image: busybox:latest
   # 可以容忍污点等于no的污点类型,并且污点类型为NoSchedule
  tolerations:
  - key: "key"
    operator: "Equal"
    value: "no"
    effect: "NoSchedule"
当node设置了污点以后,配置相同的污点容忍就可以分配到该node上

给Pod设置环境变量:
1、自定义变量
2、来自Pod字段,pod本身会携带一些属性值,比如pod名称,分配到哪个节点等,可以从pod中引用这个变量,在容器中使用,比如容器有个程序想知道pod运行在哪个节点上,可以用这个实现
3、来自secret、configmap
具体可查看以下链接


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM