专栏首页Liusy01深入理解Pod(一)

深入理解Pod(一)

上文说了一下k8s的简单使用,接下来就让我们来具体深入了解一下Pod。为了避免篇幅太长,所以会分成几篇。

目录:

  • Pod定义详解
  • 静态Pod
  • Pod容器共享Volume

Pod定义详解

先看一个简单的nginx的Pod定义:

apiVersion: v1
kind: Pod
metadata:
  nam: nginx-test
  labels:
    app: nginx-test
spec:
  containers:
  - name: nginx-test
    image: nginx:latest
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80

上述是一个Pod内包含一个容器,容器中运行nginx,容器对外暴漏80端口

Pod定义主要分成四大块:

(1)api

apiVersion: v1

(2)kind

kind: Pod

(3)metadata

metadata是Pod的元数据定义

metadata: #元数据
  name: string #Pod名称
  namespace: string #Pod所属命名空间,缺省默认是default
  labels:  #自定义标签列表
    - key: value
  annotations:  #自定义注解列表
    - key: value

(4)spec

spec是Pod中容器的详细定义,主要分成以下几块

containers

containers是Pod中的容器列表,数组类型。

spec:
  containers:  #容器列表
  - name: string  #容器名称
    image: string  #所用镜像
    imagePullPolicy: [Always|Never|IfNotPresent]  #镜像拉取策略
    command: [string]  #容器的启动命令列表
    args: [string]  #启动命令参数列表
    workingDir: string  #工作目录
    volumeMounts:  #挂载在容器内部的存储卷配置
    - name: string  #共享存储卷名称
      mountPath: string  #存储卷绝对路径
      readOnly: boolean  #是否只读
    ports:  #容器需要暴露的端口号列表
    - name: string  #端口名称
      containerPort: int  #容器监听端口
      hostPort: int  #映射宿主机端口
      protocol: string  #端口协议
    env:  #环境变量
    - name: string
      value: string
    resources:  #资源限制
      limits:
        cpu: string  #单位是core
        memory: string  #单位是MiB、GiB
    livenessProbe:  #探针,对Pod各容器健康检查的设置,如几次无回应,则会自动重启
      exec:
        command: [string]
      httpGet:
        path: string
        port: number
        host: string
        scheme: string
        httpHeaders:
        - name: string
          value: string
      tcpSocket:
        port: number
      initialDelaySeconds: 0  #启动后多久进行检测
      timeoutSeconds: 0  #超时时间
      periodSeconds: 0  #间隔时间
      successThreshold: 0  #
      failureThreshold: 0
    securityContext: #权限设置
      privileged: false  #是否允许创建特权模式的Pod

探针测试:

列出文件或文件夹aaa(此目录是不存在的),容器启动后5s开始执行探针,每隔5s执行一次,

apiVersion: v1
kind: Pod
metadata:
  name: nginx-test
  labels:
    app: nginx-test
spec:
  containers:
  - name: nginx-test
    image: nginx:latest
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80
    livenessProbe:
      exec:
        command: ["ls","aaa"]
      initialDelaySeconds: 5
      timeoutSeconds: 5

查看探针三次失败后是否有重启容器:

使用如下命令查看容器的Event项

kubectl describe pods/nginx-test

从上图可以看到,容器重启了5次

restartPolicy

容器重启策略:

spec:
  restartPolicy: [Always|Never|OnFailure]  
  • Always:Pod一旦终止运行,kubelet都会进行重启,这也是默认值
  • Never:不会进行重启
  • OnFailure:容器非正常退出(即是退出码不为0),kubelet会重启容器,反之不会重启。

nodeSelector

指定Pod被调度到哪个节点运行。

spec:
  nodeSelector: 
    K: V

比如想把一个Pod调度给cnode-2节点运行:

获取集群中所有节点列表:

给cnode-2节点打标签:

kubectl label nodes/cnode-2 name=cnode-2

查看cnode-2节点标签信息:

定义Pod的yaml文件:nginx-ns.yaml

apiVersion: v1
kind: Pod
metadata:
  name: nginx-test
  labels:
    app: nginx-test
spec:
  containers:
  - name: nginx-test
    image: nginx:latest
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80
  nodeSelector:
    name: cnode-2

使用如下命令创建Pod:

kubectl create -f nginx-ns.yaml

查看这个Pod运行在哪个节点:

imagePullSecrets

拉取镜像时使用的Secret名称,以name:secretKey格式指定

spec:
  imagePullSecrets:
    name: secretKey

Secret是用来保存私密凭据的,比如密码等信息

hostNetwork

是否使用主机网络模式

spec:
  hostNetwork: true|false

如果使用主机网络模式的话,Pod的IP就是跟宿主机IP是一样的

例如:创建下列Pod

apiVersion: v1
kind: Pod
metadata:
  name: nginx-test
  labels:
    app: nginx-test
spec:
  containers:
  - name: nginx-test
    image: nginx:latest
    imagePullPolicy: IfNotPresent
    ports:
    - containerPort: 80
  nodeSelector:
    name: cnode-3
  hostNetwork: true

然后查看Pod被分配的IP与主机IP是否相同

volumes

Pod上定义的共享存储列表:

spec:
  volumes:  #存储卷
  - name: string
    emptyDir: {}  #表示与Pod同生命周期的一个临时目录
    hostPath:  #宿主机Host
      path: string
    secret: #挂载集群预定义的secret对象到容器内部
      secretName: string
      items:
      - key: string
        path: string
    configMap: #挂载集群预定义的configMap对象到容器内部
      name: string
      items:
      - key: string
        path: string

静态Pod

由kubelet管理的仅存在于特定Node上的Pod,不能通过API Service进行管理,无法与RC、deployment或DaemonSet进行关联,并且kubelet也无法对他们进行健康检查,有kubelet创建并运行在kubelet所在的Node上运行。

静态Pod的yaml文件在修改之后,kubelet会进行自动重启该Pod至配置文件生效

创建静态Pod有两种方式:配置文件或者HTTP方式。

下面说一下配置文件的创建方式:

配置文件

需要设置kubelet启动参数“--config”,指定kubelet需要监控的配置文件所在的目录,kubelet会定期扫描该目录,并根据目录中的yaml或json文件进行创建操作

(1)如果集群是通过kubeadm创建的,那么已经配置好了静态pod的路径

查看kubelet的启动参数配置文件路径:

systemctl status kubelet

查看配置文件:

启动参数配置在一个叫/var/lib/kubelet/config.yaml的文件中

在此文件中会发现由下图中的配置,也就是静态Pod路径配置为/etc/kubernetes/manifests路径

所以只需要将静态Pod的yaml文件放置在此目录下即可。

这四个Master上运行的核心组件就是通过此方式进行创建的。

例如上图中我将static-nginx.yaml放到/etc/kubernetes/manifests目录下:

apiVersion: v1
kind: Pod
metadata:
  name: static-nginx
  labels:
    name: static-nginx
spec:
  containers:
  - name: static-nginx
    image: nginx
    ports:
    - containerPort: 80

此时使用kubelet get pods就可以查看到相应的Pod

(2)如果不是由kubeadm创建的集群,则需要在kubelet启动参数配置文件中添加如下一行:

Environment="KUBELET_SYSTEM_PODS_ARGS=--pod-manifest-path=/etc/kubernetes/manifests --allow-privileged=true

修改配置之后需要重启kubelet

systemctl stop kubelet
systemctl daemon-reload
systemctl start kubelet

例如我在cnode-2上配置了kubelet的启动参数,将静态Pod文件目录设置为/usr/soft/k8s/yaml/staticPod,然后重启kubelet

此时在目录下放置一个yaml文件

保存后就可以查看到相应的Pod是否已创建

【注意】如果Pod没创建成功,可以使用如下命令查看日志

systemctl status kubelet -l

我这边因为是之前配置了Pod安全策略,所以导致无法创建,我排查了一天啊我天

,痛苦的教训

Http方式

通过设置kubelet的启动参数“--manifest-url”,kubelet将会定期从该URL地址下载Pod的定义文件,并以.yaml或.json文件的格式进行解析, 然后创建Pod。其实现方式与配置文件方式是一致的。

【注意】静态Pod无法通过kubectl delete进行删除,只能删除对应的yaml文件

Pod容器共享Volume

在同一个Pod中的多个容器能够共享Pod级别的存储卷Volume,可以定义为各种类型,至于Volume是何种类型,在k8s基本概念中已有提到,多个容器各自进行挂载,将一个Volume挂在为容器内部需要的目录

比如:Pod里面有两个容器,分别是tomcat和busybox,tomcat往/usr/local/tomcat/logs写日志,busybox从/logs目录读取日志。

新建一个yaml文件:

这里设置的Volume名为app-logs,类型为emptyDir,挂载到tomcat容器内 的/usr/local/tomcat/logs目录,同时挂载到busybox容器内的/logs目录。

apiVersion: v1
kind: Pod
metadata:
  name: volume-pod
spec:
  containers:
  - name: tomcat
    image: tomcat
    ports:
    - containerPort: 8080
    volumeMounts:
    - name: app-logs
      mountPath: /usr/local/tomcat/logs
  - name: busybox
    image: busybox
    command: ["sh","-c","tail -f /logs/catalina*.log"]
    volumeMounts:
    - name: app-logs
      mountPath: /logs
  volumes:
  - name: app-logs
    emptyDir: {}

创建之后查看busybox的日志输出:

kubectl logs pods/volume-pod -c busybox

进入tomcat容器中查看日志文件:

#进入tomcat容器,-c参数指明是哪个容器
kubectl exec -it pods/volume-pod -c tomcat /bin/bash

进入在Pod创建时设置的日志目录:

/usr/local/tomcat/logs

本文分享自微信公众号 - Liusy01(Liusy_01),作者:Liusy01

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-09-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • k8s基础概念及术语

    上一篇简单介绍了一下k8s是什么以及如何使用kubeadm快捷安装,今儿来聊一下k8s的几个基础概念及术语。k8s中的资源都可以使用yaml文件进行描述。(文章...

    Liusy
  • 深入理解Pod(二)

    将应用所需的配置信息与程序进行分离,可以使应用程序更好的被复用,通过不同的配置实现更灵活的功能。如果将应用打包成镜像,再用环境变量或者外挂文件的方式挂载配置,在...

    Liusy
  • 深入理解Pod(三)

    Pod只是容器的载体,通常需要通过RC、Deployment、DaemonSet、Job等对象来完成Pod的调度和自动控制功能。

    Liusy
  • k8s基本概念和术语

    Master是集群的控制节点,每个K8s集群里需要有一个Master节点来负责整个集群的管理和控制。基本上k8s的所有控制命令都发给它,它来负责整个具体的执行过...

    分母为零
  • 十分钟了解Kubernetes

    最简单的一句话来概括Kubernetes。 它就是一套成熟的商用服务编排解决方案。Kubernetes定位在Saas层,重点解决了微服务大规模部署时的服务编排问...

    随机来个数
  • Kubernetes 中如何保证优雅地停止 Pod

    一直以来我对优雅地停止 Pod 这件事理解得很单纯:不就利用是 PreStop Hook 做优雅退出吗?但最近发现很多场景下 PreStop Hook 并不能很...

    CNCF
  • 021.掌握Pod-Pod调度策略

    Pod重启策略(RestartPolicy)应用于Pod内的所有容器,并且仅在Pod所处的Node上由kubelet进行判断和重启操作。当某个容器异常退出或者健...

    木二
  • 人生苦短,我用k8s--------------Pod概念与Pod网络通讯方式详解

    Pod是kubernetes中你可以创建和部署的最小也是最简的单位。Pod代表着集群中运行的进程。 Pod中封装着应用的容器(数量大于等于1,docker最常...

    不吃小白菜
  • kubernetes 权威指南学习笔记(2) -- 基本概念和术语

    Master 只的是集群控制节点,每个集群需要一个检点来负责整个集群的管理和控制。 基本上所有控制命令都发给它,它来负责具体的执行过程。

    solate
  • Kubernetes模式:容量规划

    一个优秀的云原生应用程序设计应该声明它需要正确操作的任何特定资源。Kubernetes使用这些需求来做出最有效的决策,以确保应用程序的最大性能和可用性。

    CNCF

扫码关注云+社区

领取腾讯云代金券