(三)k8s资源清单

一、k8s中的资源

K8s中所有的内容都抽象为资源,资源实例化之后,叫做对象,那么这些资源不能在同一空间下重名

  • 名称空间级别(namespace)

    • 工作负载型资源( workload):Pod、 ReplicaSet、 Deployment、 StatefulSet、 DaemonSet、Job、CronJob( ReplicationController在v1.11版本被废弃)
    • 服务发现及负载均衡型资源( ServiceDiscovery LoadBalance): Service、 Ingress
    • 配置与存储型资源: Volume(存储卷)、CSI(容器存储接口,可以扩展各种各样的第三方存储卷)
    • 特殊类型的存储卷: ConfigMap(当配置中心来使用的资源类型)、 Secret(保存敏感数据) DownwardAPI(把外部环境中的信息输出给容器)
  • 集群级资源:

    • Namespace、node、 Role ClusterRole、 RoleBinding、 ClusterRoleBinding
    • 元数据型资源: HPA、 PodTemplate、 LimitRange

二、资源清单

在k8s中,一般使用yam格式的文件来创建符合我们预期期望的pod,这样的yaml文件我们一般
称为资源清单。

2.1、资源清单yaml 语法

(三)k8s资源清单_第1张图片
(三)k8s资源清单_第2张图片
(三)k8s资源清单_第3张图片
(三)k8s资源清单_第4张图片
(三)k8s资源清单_第5张图片
(三)k8s资源清单_第6张图片
(三)k8s资源清单_第7张图片
(三)k8s资源清单_第8张图片

三、字段解释

3.1、必须存在的属性

参数名 字段说明 类型
version String 这里是指的是K8SAPl的版本,目前基本上是v1,可以用 kubectl api versions命令查询
kind String 这里指的是yam文件定义的资源类型和角色,比如:od
metadata Object 元数据对象,下面是它的属性
metadata. name String 元数据对象的名字,这里由我们编写,比如命名pod的名字
metadata. namespace String 元数据对象的命名空间,由我们自身定义
Spec Object 详细定义对象,下面是它的属性
spec.containers[] list 这里是Spec对象的容器列表定义,是个列表
spec. containers.name String 这里定义容器的名字
spec.containers.image String 这里定义要用到的镜像名称

3.2、主要属性

参数名 字段说明 类型
spec. containers.name String 这里定义容器的名字
spec.containers.image String 这里定义要用到的镜像名称
spec.containers[]. imagePullPolicy String 定义镜像拉取策略,有 Always、 Never 、IfNotPresent三个值可选(1) Always:意思是每次都尝试重新拉取镜像;(2) Never:表示仅使用本地镜像 ;(3)、IfNotPresent:如果本地有镜像就使用本地镜像,没有就拉取在线镜像。上面三个值都没设置的话,默认是 Always
spec.containers[].command[] List 指定容器启动命令,因为是数组可以指定多个,不指定则使用镜像打包时使用的启动命
spec.containers[].args[] List 指定容器启动命令参数,因为是数组可以指定多个。
spec.containers[].workingDir String 指容器的工作目录
spec.containers[]. volumeMounts[] List 指定容器内部的存储卷配置
spec.containers[].volumeMounts[].name String 指定可以被容器挂载的存储卷的名称
spec.containers[].volumeMounts[].mountPath String 指可以被容器挂载的存储卷的路径
spec.containers[].volumeMounts[]. readOnly String 设置存储卷路径的读写模式,ture或者 false,
spec.containers[].ports[] List 指定容器需要用到的端口列表
spec.containers[].ports[].name String 指定端口名称
spec.containers[].ports[].containerPort String 指定容器需要监听的端口号
spec. containers[.ports[].hostPort String 指定容器所在主机需要监听的端口号,默认跟上面 icontainerPort相同,注意设置了 hostPort,同一台主机无法启动该容器的相同副本(因为主机的端口号不能相同,这样会冲突)
spec. containers[]-ports[.protocol String 指定端口协议,支持TCP和UDP,默认值为 TCP
spec. containers[]. env[] List 指定容器运行前需设置的环境变量列表
spec. containers[].env[].name String 指环境变量名称
spec.containers[].env].value String 指定环境变量值
spec.containers[].resources Object 指定资源限制和资源请求的值(这里开始就是设置容器的资源上限)
spec.containers[].resources.limits Object 指设置容器运行时资源的运行上限
spec.containers[].resources.limits.cpu String 指定CPU的限制,单位为core数,将用于docker run-cpu-shares参数(这里前面文章 Pod资源限制有讲过 HAP 那个啥的,哈哈 主要我也忘记具体名字了)
spec.containers[].resources. limits.memory String 指定MEM内存的限制,单位为MB、GiB spec.containers[].resources.requests
spec.containers[].resources.requests.cpu string cpu请求,单位为core数,容器启动时初始化可用数量
spec.containers.resources.requests.memory String 内存请求,单位为MB、GB,容器启动的初始化可用数量

3.2、额外属性

参数名 字段说明 类型
spec.restartPolicy String 定义Pod的重启策略,可选值为 Always、 OnFailure,默认值为Always;1、Always:pod一旦终止运行,则无论容器是如何终止的, kubelet服务都将重启它。如果容器正常结束(退出码为0),则 kubelet将不会重启它; 2、OnFailure:只有pod以非零退出码终止时, kubelet会重启该容;3、Never:pod终止后, kubeletMast将退出码报告给,会重启该Pod.
spec.nodeSelector Object 定义node的 Label过滤标签,以 key value格式指定
spec.imagePullSecrets Object 定义pull镜像时 secret使用名称,以 name secretkey格式指定
spec.hostNetwork Boolean 定义是否使用主机网络模式,默认值为 false,设置true表示使用宿主机网络,不使用 docker网桥,同时设置了true将无法在同一台宿主机上启动第二个副本。

3.3、模板 yaml 文件

  • 资源清单格式
apiVersion: group/apiVersion #如果没有给定group名称,那么默认为core,可以使用kubectl api-versions  获取当前k8s版本上所有的 apiVersion版本信息(每个版本可能不同)
kind:  #资源类别  Pod,Deploment,rs 等等  #goupcorekubect1ap-:group/apiversion
metadata:  #资源元数据
  name: 
  namespace: 
  lables: 
  annotations:   #主要目的是方便用户阅读查找
spec: #期望的状态(disired state)
status: #当前状态,本字段有 Kubernetes自身维护,用户不能去定义,查看的时候可以看下当前的状态
  • 获取资源的 apiVersion 版本信息
kubectl explain pod
kubectl explain Ingress

(三)k8s资源清单_第9张图片

  • 获取字段帮助文档
kubectl explain pod

(三)k8s资源清单_第10张图片

  • 字段配置格式
apiVersion           #表示字符串类型
metadata             #表示需要嵌套多层字段
labels    #表示由k:v组成的映射
finalizers <[]string>        #表示字串列表
ownerReferences <[]Object>   #表示对象列表
hostPID             #布尔类型
priority            #整型
name  -required-     #如果类型后面接 -required-,表示为必填字段
 
  
  • 通过定义清单文件创建 Pod(当然根据你的 kind 来创建)
# 创建命令
kutectl create -f xxx.yaml
# 使用 -o 参数 加 yaml,可以将资源的配置以 yaml的格式输出出来,也可以使用json,输出为json格式
kubectl get pod podName -o yaml  
apiVersion: v1
kind: Pod
metadata:
  name: pod-demo
  namespace: default
  labels:
    app: myapp
    name: gkj-test
spec:
  containers:
  - name: myapp-1
    image: hub.atguigu.com/library/myapp:v1
  - name: busybox-1
    image: busybox:latest
    command:
    - "/bin/sh"
    - "-c"
    - "sleep 3600"

四、容器生命周期

4.1、Pod 生命周期

这只是一个main C (即一个镜像)的周期,如果一个Pod中有多个main C (即多个镜像),则也会有多个下列视图对象,可以为每一个 Main C 设置 init C、START、readiness、STOP 、Liveness
(三)k8s资源清单_第11张图片
Pod能够具有多个容器,应用运行在容器里面但是它也可能有一个或多个先于应用容器启动的Init
容器,并且Init 容器与普通的容器非常像,除了如下两点:

  • Init容器总是运行到成功完成为止
  • 每个Init容器都必须在下一个Init容器启动之前成功完成

如果Pod的Init容器失败,Kubernetes会不断地重启该Pod,直到Init容器成功为止。然而,如果Pod对应的 restartPolicy为 Never,它不会重新启动。

因为Init容器具有与应用程序容器分离的单独镜像,所以它们的启动相关代码具有如下优势:

  • 它们可以包含并运行实用工具(因为执行完成Init C 之后就会把Init C 销毁),但是出于安全考虑,是不建议在应用程序容器镜像中包含这
    些实用工具的
  • 它们可以包含使用工具和定制化代码来安装,但是不能出现在应用程序镜像中。例如,创建
    镜像没必要FROM另一个镜像,只需要在安装过程中使用类似sed、awk、 python或dig
    这样的工具。
  • 应用程序镜像可以分离出创建和部署的角色,而没有必要联合它们构建一个单独的镜像。
  • Init容器使用 Linux Namespace,所以相对应用程序容器来说具有不同的文件系统视图。因
    此,它们能够具有访问 Secret的权限,而应用程序容器则不能。
  • 它们必须在应用程序容器启动之前运行完成,而应用程序容器是并行运行的,所以Init容
    器能够提供了一种简单的阻塞或延迟应用容器的启动的方法,直到满足了一组先决条件。

4.2、init C 示例

这个yaml 文件,创建了一个pod,并且这个pod里面只有一个 main C,这个main C 有两个 init C,
当创建的时候,会先按照顺序创建 init C(即第一个Init C 先创建,如果失败,则不会创建第二个),最后只有两个Init C 都是成功的,才会创建 main C。

busybox 镜像只是封装了一些工具的镜像

# 内容就是如下
vim ini-pod.yaml  
# 根据文件创建 
kubectl create -f ini-pod.yaml

如果有名称相同的可以把之前的删除,可以使用 --all 或者指定具体的名称删除,都是可以的

# 如果有资源是deployment的 不要删pod和Rs,因为这样是删不干净的,可以直接删除 deployment ,这样 rs和pod都会被删除
kubectl delete deployment --all  # 这里没有指定namespace 默认是名称空间是default
kubectl delete pod --all
kubectl delete svc --all 

(三)k8s资源清单_第12张图片

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  containers:
  - name: myapp-container  # 定义一个容器,
    image: busybox
    command: ['sh', '-c', 'echo The app is running! && sleep 3600'] # 启动时执行 ,即输出一句话  The app is running 然后 休眠 6分钟,不退出镜像
  initContainers:   #这里就是配置 init C 了,下面为这个main C配置了两个init C
  - name: init-myservice
    image: busybox
    command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;'] # 这个的作用是检测 myservice(会在后面定义) 容器是否启动起来了
  - name: init-mydb
    image: busybox
    command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;'] # 这个的作用是检测 mydb (会在后面定义)容器是否启动起来了

创建完成后,查看pod状态,如下,可以看到init 是有2个的,因为我们定义了2个init C,而main C 只有一个 0/1。
(三)k8s资源清单_第13张图片
后面你一直 kubectl get pod 会发现init c一直无法成功,这时我们可以看下当前这个pod 的详情,你会发现执行了第一个init c init-myservice,然后没有执行第二个init C,只是分配了myapp-pod的节点,然后没有下文了,说明第一个 init C init-myservice有问题。

kubectl describe pod myapp-pod

(三)k8s资源清单_第14张图片
所以我们需要看下第一个init C init-myservice的日志

# -c 的作用是指定这个pod 的哪一个具体的容器,因为一个pod里面有多个容器的
kubtctl log myapp-pod -c init-myservice 

在这里插入图片描述
最后看到日志就会明白了,因为没有myservice这个服务,所以init C 过不去,对于另一种检测mydb的就不再演示了,两个必须都通过才行,才会到创建pod哪里,创建main C。
(三)k8s资源清单_第15张图片

当你创建完第一个 service时,第一个init C 就已经通过了,也可以在svc中看到我们的myservice了,至于为什么我们的pod可以ping myservice,而不是使用ip,是因为一旦我们service创建成功,会被coredns-xxxx 记录,这样k8s内部的机器都是可以通过域名访问的
(三)k8s资源清单_第16张图片
分别创建 myservice 和 mydb 的 svc 即可

kubectl create -f myservice.yaml
kubectl create -f mydb.yaml
  • myservice.yaml
kind: Service
apiVersion: v1
metadata:
  name: myservice
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9376
  • mydb.yaml
kind: Service
apiVersion: v1
metadata:
  name: mydb
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 9377

最后结果
在这里插入图片描述

4.3、init C 特殊说明/总结

  • 在 Pod 启动过程中,Init 容器会按顺序在网络和数据卷初始化之后启动(网络和数据初始化会在每一个pod的pause中处理完成,这个pause是我们不可控的)。每个容器必须在下一个
    容器启动之前成功退出
  • 如果由于运行时或失败退出,将导致容器启动失败,它会根据 Pod 的 restartPolicy 指定的策略
    进行重试。然而,如果 Pod 的 restartPolicy 设置为 Always,Init 容器失败时会使用
    RestartPolicy 策略,尝试最大次数后如果还是失败则就是失败。
  • 在所有的 Init 容器没有成功之前,Pod 将不会变成 Ready 状态(前面的实验图已经说的很清楚了)。Init 容器的端口将不会在
    Service 中进行聚集,这样客户端或者浏览器是不能通过svc来访问到它的。 正在初始化中的 Pod 处于 Pending 状态,但应该会将 Initializing 状态设置为 true
  • 如果 Pod 重启,所有 Init 容器必须重新执行(所以init 容器必须要保证幂等性,当然你也可以不设置init 容器
  • 对 Init 容器 spec 的修改被限制在容器 image 字段,修改其他字段都不会生效。更改 Init
    容器的 image 字段,等价于重启该 Pod
  • Init 容器具有应用容器的所有字段。除了 readinessProbe和liveNess,因为 Init 容器无法定义不同于完成(completion)的就绪(readiness)之外的其他状态(init 容器本身就是检测其它容器准备就绪的前置条件,所以它不会存在准备就绪状态,而已检测完成就会销毁,所以不存在livenesss,所以通过这一点我们可以知道,在同一个main C的init C中的init C的端口是可以重复的,因为会按照顺序创建,通过就会删除,不会影响第二个)。这会在验证过程中强制执行
  • 在 Pod 中的每个 app 和 Init 容器的名称必须唯一;与任何其它容器共享同一个名称,会在验证
    时抛出错误,这是肯定的,比较init C也是容器啊。

4.4、探针

探针是由 kubelet 对容器执行的定期诊断。要执行诊断,kubelet 调用由容器实现的 Handler。有三
种类型的处理程序:

  • ExecAction:在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功。
  • TCPSocketAction:对指定端口上的容器的 IP 地址进行 TCP 检查。如果端口打开,则诊断
    被认为是成功的。
  • HTTPGetAction:对指定的端口和路径上的容器的 IP 地址执行 HTTP Get 请求。如果响应的
    状态码大于等于200 且小于 400,则诊断被认为是成功的

每次探测都将获得以下三种结果之一:

  • 成功:容器通过了诊断。
  • 失败:容器未通过诊断。
  • 未知:诊断失败,因此不会采取任何行动

注意失败之后pod在指定策略下会重启,一些指令就会重新执行了

4.4.1、探测方式

  • livenessProbe:指示容器是否正在运行。如果存活探测失败,则 kubelet 会杀死容器,并且容器将受到其重启策略的影响。如果容器不提供存活探针,则默认状态为 Success

  • readinessProbe:指示容器是否准备好服务请求。如果就绪探测失败,端点控制器将从与 Pod 匹配的所有 Service 的端点中删除该 Pod 的 IP 地址。初始延迟之前的就绪状态默认为 Failure。如果容器不提供就绪探针,则默认状态为 Success

4.4.2、示例说明

4.4.2.1、检测探针 - 就绪检测

对就绪状态使用 httpget方式(至于其它的几种方式会在下面的就绪状态文章里面)检测 readinessProbe-httpget

vim readinessProbe-httpget.yaml 

具体内容如下

apiVersion: v1
kind: Pod
metadata:
  name: readiness-httpget-pod
  namespace: default
spec:
  containers:
  - name: readiness-httpget-container
    image: wangyanglinux/myapp:v1
    imagePullPolicy: IfNotPresent
    readinessProbe:
      httpGet:
        port: 80
        path: /index1.html  # 这个文件是不存在的
      initialDelaySeconds: 1 # 容器创建启动一秒后开始检测
      periodSeconds: 3  # 每隔3秒检测一次,直到就绪状态结束

可以看到 READ 状态一直都是失败的,因为index1.html在80端口是不存的,状态码不会所在200多
在这里插入图片描述
再仔细查看pod的日志,可以看到 readiness 探针失败了。

kubectl describe pod  readinessProbe-httpget

(三)k8s资源清单_第17张图片
我们进入这个容器,因为当前这个pod只有一个main C容器,所以我们不需要使用 - c 指定具体那个容器,然后增加一个 index1.html即可

#kubectl exec readinessProbe-httpget -c xxx pod -it -- /bin/sh
kubectl exec readinessProbe-httpget pod -it -- /bin/sh

(三)k8s资源清单_第18张图片
再监控这个pod的状态

# w的意思是 watch 监听
lubectl get pod -w 

在这里插入图片描述

4.4.2.2、检测探针 - 存活检测
4.4.2.2.1、存活检测 使用 exec 来检测

livenessProbe-exec

vim livenessProbe-exec.yaml

内容如下

apiVersion: v1
kind: Pod
metadata:
  name: liveness-exec-pod
  namespace: default
spec:
  containers:
  - name: liveness-exec-container
    image: hub.atguigu.com/library/busybox
    imagePullPolicy: IfNotPresent
    command: ["/bin/sh","-c","touch /tmp/live ; sleep 60; rm -rf /tmp/live; sleep 3600"] # 启动完成后创建一个文件/tmp/live 睡眠60秒后再把这个文件删除后睡眠6分钟
    livenessProbe:
      exec:
        command: ["test","-e","/tmp/live"]  # 检测这个文件是否存在
      initialDelaySeconds: 1
      periodSeconds: 3

可以想到,这个容器前面的一段时间是可以通过存活检测的,因为前60秒这个文件是一直都在的,但是60秒之后就没了,所以会失败,就会重启,如下,虽然ready状态是ok的,但是存活检测是失败的,已经重启2次了。

kubectl get pod -w

(三)k8s资源清单_第19张图片

4.4.2.2.2、存活检测 使用 httpget 来检测

livenessProbe-httpget

vim livenessProbe-httpget.yaml

内容如下

apiVersion: v1
kind: Pod
metadata:
  name: liveness-httpget-pod
  namespace: default
spec:
  containers:
  - name: liveness-httpget-container
    image: hub.atguigu.com/library/myapp:v1
    imagePullPolicy: IfNotPresent
    ports:
    - name: http   # 定义80 端口的名称为http ,后面使用的时候,不用写80,可以用http这个名称代替
      containerPort: 80
    livenessProbe:
      httpGet:
        port: http  # 那这里其实就是80端口啦
        path: /index.html
      initialDelaySeconds: 1
      periodSeconds: 3
      timeoutSeconds: 10
4.4.2.2.2、存活检测 使用 tcp 来检测

livenessProbe-tcp

vim livenessProbe-tcp.yaml

内容如下

apiVersion: v1
kind: Pod
metadata:
  name: probe-tcp
spec:
  containers:
  - name: nginx
    image: hub.atguigu.com/library/myapp:v1
    livenessProbe:
      initialDelaySeconds: 5
      timeoutSeconds: 1
      tcpSocket:
        port: 80
4.4.2.3、组合就绪和存活-探针

组合的话,其实也是很简单的,就是把对于的配置copy再一起就行了。
liveness-readness-Probe

vim liveness-readness-Probe.yaml

内容如下

apiVersion: v1
kind: Pod
metadata:
  name: probe-tcp
spec:
  containers:
  - name: nginx
    image: hub.atguigu.com/library/myapp:v1
    readinessProbe:
      httpGet:
        port: 80
        path: /index1.html
      initialDelaySeconds: 1
      periodSeconds: 3
    livenessProbe:
      initialDelaySeconds: 5
      timeoutSeconds: 1
      tcpSocket:
        port: 80
4.4.2.4、start 和 stop - 阶段

其实就是和上面差不多,都是一个回调的阶段。

vim start-stop-probe.yaml

这里的关键字就是 lifecycle ,内容如下

apiVersion: v1
kind: Pod
metadata:
  name: lifecycle-demo
spec:
  containers:
  - name: lifecycle-demo-container
    image: nginx
    lifecycle:
      postStart:
        exec:
          command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"]
      preStop:
        exec:
           command: ["/bin/sh", "-c", "echo bybe from the preStop handler > /usr/share/message"]

你可能感兴趣的:(k8s,docker,k8s)