美文网首页testopsDocker容器软件测试
Testops之路6.Kubernetes之Pod

Testops之路6.Kubernetes之Pod

作者: KalvinDai | 来源:发表于2019-07-04 17:19 被阅读19次

    先来一起回忆一下上节课内容,k8s的几个组成部分:

    image

    研发采用声明式定义自己的应用:

    image

    应用运行在k8s集群上的全景图:

    image

    什么是pod

    Pod,是 Kubernetes 项目中最小的 API 对象。如果换一个更专业的说法,我们可以这样描述:Pod,是 Kubernetes 项目的原子调度单位。

    image

    Kubernetes 项目中的最小编排单位是Pod,而不是容器。

    Pod 扮演的是传统部署环境里“虚拟机”的角色。

    而如果你能把 Pod 看成传统环境里的“机器”、把容器看作是运行在这个“机器”里的“用户程序”,那么很多关于 Pod 对象的设计就非常容易理解了。

    比如,凡是调度、网络、存储,以及安全相关的属性,基本上是 Pod 级别的。

    image

    这些属性的共同特征是,它们描述的是“机器”这个整体,而不是里面运行的“程序”。比如,配置这个“机器”的网卡(即:Pod 的网络定义)。

    image

    配置这个“机器”的磁盘(即:Pod 的存储定义),以及这台“机器”运行在哪个服务器之上(即:Pod 的调度)。

    image

    当容器间存在超紧密协作时,我们可以称为“超亲密关系”。这些具有“超亲密关系”容器的典型特征包括但不限于:互相之间会发生直接的文件交换、使用 localhost 或者 Socket 文件进行本地通信、会发生非常频繁的远程调用等等。

    这也就意味着,并不是所有有“关系”的容器都属于同一个 Pod。比如,Backend 后端容器和 Fronted 前端容器 虽然会发生访问关系,但并没有必要、也不应该部署在同一台机器上,它们更适合做成两个 Pod分开部署。

    那什么时候定义这种“超亲密关系“呢?

    比较典型的例子——容器的日志收集,。

    比如,我现在有一个应用,需要不断地把日志文件输出到容器的 /var/log 目录中。

    这时,我就可以把一个 Pod 里的 Volume 挂载到应用容器的 /var/log 目录上。

    实际上,这个所谓的“组合”操作,正是容器设计模式里最常用的一种模式,它叫:边车模式(sidecar)

    我们在这个 Pod 里同时运行一个 sidecar 容器,它也声明挂载同一个 Volume 到自己的 /var/log 目录上。这样,接下来 sidecar 容器就只需要做一件事儿,那就是不断地从自己的 /var/log 目录里读取日志文件,转发到 MongoDB 或者 Elasticsearch 中存储起来。这样,一个最基本的日志收集工作就完成了。

    Infra容器

    Pod 里的所有容器,共享的是同一个 Network Namespace,并且可以声明共享同一个 Volume。

    在 Kubernetes 项目里,Pod 的实现需要使用一个中间容器,这个容器叫作 Infra 容器。在这个 Pod 中,Infra 容器永远都是第一个被创建的容器,而其他用户定义的容器,则通过 Join Network Namespace 的方式,与 Infra 容器关联在一起。这样的组织关系,可以用下面这样一个示意图来表达:

    image

    创建一个Pod

    配置kube_config

    联系tower配置测试环境kube_config

    通过kubectl创建一个namespace

    kubectl create ns testops
    

    通过kubectl创建一个pod

    apiVersion: v1             
    kind: Pod
    metadata:
      name: kubia-manual  
      namespace: testops
    spec:
      containers:
      - image: luksa/kubia      
        name: kubia             
        ports:
        - containerPort: 8080   
          protocol: TCP
    
    kubectl create -f kubia-manual.yaml
    

    Pod的关键字段

    Kubernetes 项目中对 Container 的定义,和 Docker 相比并没有什么太大区别。Image(镜像)、Command(启动命令)、workingDir(容器的工作目录)、Ports(容器要开发的端口),以及 volumeMounts(容器要挂载的 Volume)都是构成 Kubernetes 项目中 Container 的主要字段。

    看个例子:

    image
    image

    1、这个YAML描述符中使用的Kubernetes API版本。
    2、Kubernetes对象/资源的类型。
    3、Pod元数据(名称、标签、注释等)。
    4、Pod规格/内容(Pod容器、卷等列表)。
    5、Pod和其容器的详细情况。

    接下来,介绍 Pod 中几个重要字段的含义和用法。

    Label

    是一个供用户将 Pod 与 Node 进行绑定的字段

    image

    通常,我们微服务架构下中会有许多个pod,那么如何给这些pod分类呢,这里就要用到 Label 这个概念。

    image
    kubectl get pods -n {namespaces} -a --show-labels=true
    
    image

    NodeSelector

    NodeSelector:是一个供用户将 Pod 与 Node 进行绑定的字段,用法如下所示:

    apiVersion: v1
    kind: Pod
    ...
    spec:
     nodeSelector:
       disktype: ssd
    

    这样的一个配置,意味着这个 Pod 永远只能运行在携带了“disktype: ssd”标签(Label)的节点上;否则,它将调度失败。

    HostAliases

    定义了 Pod 的 hosts 文件(比如 /etc/hosts)里的内容,用法如下:

    apiVersion: v1
    kind: Pod
    ...
    spec:
      hostAliases:
      - ip: "10.1.2.3"
        hostnames:
        - "foo.remote"
        - "bar.remote"
    ...
    

    在这个 Pod 的 YAML 文件中,我设置了一组 IP 和 hostname 的数据。这样,这个 Pod 启动后,/etc/hosts 文件的内容将如下所示:

    cat /etc/hosts
    
    #Kubernetes-managed hosts file.
    127.0.0.1 localhost
    ...
    10.244.135.10 hostaliases-pod
    10.1.2.3 foo.remote
    10.1.2.3 bar.remote
    

    ImagePullPolicy

    它定义了镜像拉取的策略。而它之所以是一个 Container 级别的属性,是因为容器镜像本来就是 Container 定义中的一部分。

    ImagePullPolicy 的值默认是 Always,即每次创建 Pod 都重新拉取一次镜像。另外,当容器的镜像是类似于 nginx 或者 nginx:latest 这样的名字时,ImagePullPolicy 也会被认为 Always。

    Lifecycle

    它定义的是 Container Lifecycle Hooks。顾名思义,Container Lifecycle Hooks 的作用,是在容器状态发生变化时触发一系列“钩子”。我们来看这样一个例子:

    Pending 这个状态意味着,Pod 的 YAML 文件已经提交给了 Kubernetes,API 对象已经被创建并保存在 Etcd 当中。但是,这个 Pod 里有些容器因为某种原因而不能被顺利创建。比如,调度不成功。

    Running 这个状态下,Pod 已经调度成功,跟一个具体的节点绑定。它包含的容器都已经创建成功,并且至少有一个正在运行中。

    Succeeded 这个状态意味着,Pod 里的所有容器都正常运行完毕,并且已经退出了。这种情况在运行一次性任务时最为常见。

    Failed 这个状态下,Pod 里至少有一个容器以不正常的状态(非 0 的返回码)退出。这个状态的出现,意味着你得想办法 Debug 这个容器的应用,比如查看 Pod 的 Events 和日志。

    Unknown 这是一个异常状态,意味着 Pod 的状态不能持续地被 kubelet 汇报给 kube-apiserver,这很有可能是主从节点(Master 和 Kubelet)间的通信出现了问题。

    除了上面的字段,Pod还有一组Condition,它们主要用于描述造成当前 Status 的具体原因是什么。

    Conditions:
      Type              Status
      Initialized       True
      Ready             True
      ContainersReady   True
      PodScheduled      True
    

    作业

    查看Pods其他字段

    1、下载k8s源码

    mkdir -p $GOPATH/src/k8s.io
    

    2、进入目录$GOPATH/src/k8s.io,执行以下命令即可开始下载:

    git clone https://github.com/kubernetes/kubernetes -b release-1.13
    

    3、下载完毕后,k8s.io目录下出现一个名为kubernetes的文件夹。

    cat $GOPATH/src/k8s.io/kubernetes/vendor/k8s.io/api/core/v1/types.go
    

    观察pod

    使用kubectl命令,观察你目前用的测试环境某个服务的pod信息

    kubectl命令表

    http://docs.kubernetes.org.cn/683.html

    Pod其他属性

    # yaml格式的pod定义文件完整内容:
    apiVersion: v1          #必选,版本号,例如v1
    kind: Pod             #必选,Pod
    metadata:             #必选,元数据
      name: string          #必选,Pod名称
      namespace: string       #必选,Pod所属的命名空间
      labels:             #自定义标签
        - name: string       #自定义标签名字
      annotations:          #自定义注释列表
        - name: string
    spec:                #必选,Pod中容器的详细定义
      containers:           #必选,Pod中容器列表
      - name: string        #必选,容器名称
        image: string       #必选,容器的镜像名称
        imagePullPolicy: [Always | Never | IfNotPresent]  #获取镜像的策略 Alawys表示下载镜像 IfnotPresent表示优先使用本地镜像,否则下载镜像,Nerver表示仅使用本地镜像
        command: [string]       #容器的启动命令列表,如不指定,使用打包时使用的启动命令
        args: [string]         #容器的启动命令参数列表
        workingDir: string      #容器的工作目录
        volumeMounts:         #挂载到容器内部的存储卷配置
        - name: string         #引用pod定义的共享存储卷的名称,需用volumes[]部分定义的的卷名
          mountPath: string     #存储卷在容器内mount的绝对路径,应少于512字符
          readOnly: boolean     #是否为只读模式
        ports:              #需要暴露的端口库号列表
        - name: string         #端口号名称
          containerPort: int    #容器需要监听的端口号
          hostPort: int        #容器所在主机需要监听的端口号,默认与Container相同
          protocol: string      #端口协议,支持TCP和UDP,默认TCP
        env:              #容器运行前需设置的环境变量列表
        - name: string        #环境变量名称
          value: string       #环境变量的值
        resources:          #资源限制和请求的设置
          limits:           #资源限制的设置
            cpu: string       #Cpu的限制,单位为core数,将用于docker run --cpu-shares参数
            memory: string      #内存限制,单位可以为Mib/Gib,将用于docker run --memory参数
          requests:         #资源请求的设置
            cpu: string       #Cpu请求,容器启动的初始可用数量
            memory: string      #内存清楚,容器启动的初始可用数量
        livenessProbe:        #对Pod内个容器健康检查的设置,当探测无响应几次后将自动重启该容器,检查方法有exec、httpGet和tcpSocket,对一个容器只需设置其中一种方法即可
          exec:             #对Pod容器内检查方式设置为exec方式
            command: [string]   #exec方式需要制定的命令或脚本
          httpGet:            #对Pod内个容器健康检查方法设置为HttpGet,需要制定Path、port
            path: string
            port: number
            host: string
            scheme: string
            HttpHeaders:
            - name: string
              value: string
          tcpSocket:            #对Pod内个容器健康检查方式设置为tcpSocket方式
             port: number
           initialDelaySeconds: 0   #容器启动完成后首次探测的时间,单位为秒
           timeoutSeconds: 0      #对容器健康检查探测等待响应的超时时间,单位秒,默认1秒
           periodSeconds: 0       #对容器监控检查的定期探测时间设置,单位秒,默认10秒一次
           successThreshold: 0
           failureThreshold: 0
           securityContext:
             privileged: false
        restartPolicy: [Always | Never | OnFailure] #Pod的重启策略,Always表示一旦不管以何种方式终止运行,kubelet都将重启,OnFailure表示只有Pod以非0退出码退出才重启,Nerver表示不再重启该Pod
        nodeSelector: obeject     #设置NodeSelector表示将该Pod调度到包含这个label的node上,以key:value的格式指定
        imagePullSecrets:         #Pull镜像时使用的secret名称,以key:secretkey格式指定
        - name: string
        hostNetwork: false        #是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络
        volumes:              #在该pod上定义共享存储卷列表
        - name: string          #共享存储卷名称 (volumes类型有很多种)
          emptyDir: {}          #类型为emtyDir的存储卷,与Pod同生命周期的一个临时目录。为空值
          hostPath: string        #类型为hostPath的存储卷,表示挂载Pod所在宿主机的目录
            path: string        #Pod所在宿主机的目录,将被用于同期中mount的目录
          secret:             #类型为secret的存储卷,挂载集群与定义的secre对象到容器内部
            scretname: string  
            items:     
            - key: string
              path: string
          configMap:          #类型为configMap的存储卷,挂载预定义的configMap对象到容器内部
            name: string
            items:
            - key: string
              path: string
    

    相关文章

      网友评论

        本文标题:Testops之路6.Kubernetes之Pod

        本文链接:https://www.haomeiwen.com/subject/vmwrhctx.html