k8s学习之路 | Day16 k8s 中的容器初探

news2024/11/18 19:27:30

文章目录

  • 容器镜像
    • 镜像名称
    • 镜像拉取策略
    • 私有仓库的拉取策略
  • 容器的环境变量和启动命令
    • 容器的环境变量
    • 容器的启动命令
  • 容器的生命周期钩子
    • postStart
    • preStop
  • 容器的探针
    • startupProbe
    • livenessProbe
    • readinessProbe

k8s 集群中最小的管理单元就是一个Pod,而Pod里面才是容器,但是容器里面到底应该怎么写yaml呢?这个就是我今天学习的目标

  • 一个最简单的Pod资源清单类似于以下这种:
##pod-demo.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-demo
  labels: 
    app: MYAPP
spec:
  containers:
  - name: pod-demo
    image: nginx

image-20230223150750157

  • 我们通过kubectl explain pod.spec.containers解释了容器到底里面能写什么忒多了
[root@k8s-01 k8s-yaml]# kubectl explain pod.spec.containers
KIND:     Pod
VERSION:  v1

RESOURCE: containers <[]Object>

DESCRIPTION:
     List of containers belonging to the pod. Containers cannot currently be
     added or removed. There must be at least one container in a Pod. Cannot be
     updated.

     A single application container that you want to run within a pod.

FIELDS:
   args <[]string>
     Arguments to the entrypoint. The docker image's CMD is used if this is not
     provided. Variable references $(VAR_NAME) are expanded using the
     container's environment. If a variable cannot be resolved, the reference in
     the input string will be unchanged. The $(VAR_NAME) syntax can be escaped
     with a double $$, ie: $$(VAR_NAME). Escaped references will never be
     expanded, regardless of whether the variable exists or not. Cannot be
     updated. More info:
     https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell
...

容器镜像

镜像名称

kubectl explain pod.spec.containers中的【image 】解释了有关镜像名称的含义和写法

image-20230223152202307

  • Docker image 的镜像名称
  • string 数据类型
##所以在写yaml文件的时候,就应该以这种形式来确认你这个容器启动用的镜像
apiVersion: v1
kind: Pod
metadata:
  name: pod-demo
  labels: 
    app: MYAPP
spec:
  containers:
  - name: pod-demo
    image: nginx
    #image: nginx:1.21-alpine
    #image: tomcat:latest

镜像拉取策略

kubectl explain pod.spec.containers中的【imagePullPolicy】解释的就是镜像拉取策略

kubectl explain pod.spec.containers.imagePullPolicy拉取策略

image-20230223164237141

  • Always:每当 kubelet 启动一个容器时,kubelet 会查询容器的镜像仓库, 将名称解析为一个镜像摘要。 如果 kubelet 有一个容器镜像,并且对应的摘要已在本地缓存,kubelet 就会使用其缓存的镜像; 否则,kubelet 就会使用解析后的摘要拉取镜像,并使用该镜像来启动容器。这也是默认拉取策略
  • Never:Kubelet 不会尝试获取镜像。如果镜像已经以某种方式存在本地, kubelet 会尝试启动容器;否则,会启动失败。
  • IfNotPresent:只有当镜像在本地不存在时才会拉取。
##所以在写yaml文件的时候,就应该以这种形式来确认要启动容器的镜像的来源
apiVersion: v1
kind: Pod
metadata:
  name: pod-demo
  labels: 
    app: MYAPP
spec:
  containers:
  - name: pod-demo
    image: nginx
    imagePullPolicy: Always ## 默认拉取策略:总是去下载

举个栗子

我有下面这个pod文件,我尝试启动一下试试:

#####pod-test1.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-demo
  labels: 
    app: MYAPP
spec:
  containers:
  - name: pod-demo
    image: wordpress
    imagePullPolicy: Never

image-20230225220247465

私有仓库的拉取策略

如果我们需要从自己的阿里云私人镜像仓库拉取镜像,又应该如何操作呢?看一下官方帮助文档kubectl explain pod.spec中的【imagePullSecrets <[]Object>】

image-20230225220917430

官方地址:

https://kubernetes.io/zh-cn/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod

官方是这样说的:

  1. 要创建一个Secret

  2. 然后在 Pod 中引用 ImagePullSecrets

举个栗子

我要拉取我自己阿里云镜像仓库的镜像:

  • 我需要先创建一个Secret,这个怎么创建呢?官方是这样说的
kubectl create secret docker-registry <name> \
  --docker-server=DOCKER_REGISTRY_SERVER \
  --docker-username=DOCKER_USER \
  --docker-password=DOCKER_PASSWORD \
  --docker-email=DOCKER_EMAIL

我就创建一个试试:

kubectl create secret docker-registry test \
  --docker-server=registry.cn-hangzhou.aliyuncs.com \
  --docker-username=tb330504_33 \
  --docker-password=xxxxxxxx \
  --docker-email=565616251@qq.com

image-20230225222046858

我在准备一个Pod文件

apiVersion: v1
kind: Pod
metadata:
  name: pod-demo
  labels: 
    app: MYAPP
spec:
  imagePullSecrets:
  - name: test
  containers:
  - name: pod-demo
    image: registry.cn-hangzhou.aliyuncs.com/publiclibrary/tomcat:8.5-jdk11-temurin-focal
    imagePullPolicy: IfNotPresent

运行一下,看是否能拉取后正常运行:

  • 正在拉取镜像

image-20230225222729867

  • 拉取成功,运行成功

image-20230225222907947

容器的环境变量和启动命令

容器的环境变量

  • kubectl explain pod.spec.containers.env

image-20230226182054008

  • 按照官方描述,有关容器的环境变量就应该这样写了
####以mysql镜像为例
apiVersion: v1
kind: Pod
metadata:
  name: pod-demo
  labels: 
    app: MYAPP
spec:
  containers:
  - name: pod-mysql-demo
    image: mysql
    imagePullPolicy: Always
    env:
      - name: MYSQL_DATABASE
        value: my-test
      - name: MYSQL_ROOT_PASSWORD
        value: admin@123
  • 尝试并验证一下:OK

image-20230226183241856

容器的启动命令

  • kubectl explain pod.spec.containers.command

https://kubernetes.io/zh-cn/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell

image-20230227133904452

image-20230227135528022

  • 尝试一下(覆盖容器默认的启动命令)
apiVersion: v1
kind: Pod
metadata:
  name: pod-demo
  labels:
    app: MYAPP
spec:
  containers:
  - name: pod-demo
    image: nginx
    command:
      - /bin/sh
      - -c
      - "echo hello world;sleep 3600;"

image-20230227134820426

  • 可以看到,如果设置了command字段信息,就会覆盖默认的容器启动命令,对于这个,官方有明确的说明:

    1. 如果在配置文件中设置了容器启动时要执行的命令及其参数,那么容器镜像中自带的命令与参数将会被覆盖而不再执行。
    2. 如果配置文件中只是设置了参数,却没有设置其对应的命令,那么容器镜像中自带的命令会使用该新参数作为其执行时的参数。

    image-20230227135440569

  • 从最新的文档发现,有些内容有所出入

容器的生命周期钩子

https://kubernetes.io/zh-cn/docs/concepts/containers/container-lifecycle-hooks/#container-hooks

kubectl explain pod.spec.containers.lifecycle

image-20230227142655173

kubectl explain pod.spec.containers.lifecycle.postStart

image-20230227143050232

kubectl explain pod.spec.containers.lifecycle.preStop

image-20230227143147357

k8s 中提供了二个关于容器的生命周期钩子

  • postStart

在容器创建后将立刻执行。但是,并不能保证该钩子函数在容器的 ENTRYPOINT 之前

执行。该钩子函数没有输入参数。

  • preStop

在容器被 terminate(终止)之前执行

postStart

k8s 在容器启动后立刻发送postStart事件,但是并不能确保postStart事件处理程序在容器的EntryPoint之前执行,意思就是容器启动了就会触发,不管容器执行是否成功?在 k8s 管理容器的时候,将一直等待 postStart事件处理程序结束后,才会将容器的状态标记为Running

  • exec:容器创建以后,钩子函数执行一个命令
  • httpGet:容器创建以后,钩子函数发送一个http的get请求
  • tcpSocket:容器创建以后,钩子函数连上一个TCP端口

我们以httpGet为例

我们先启动一个 nginx pod

##pod-demo.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-demo
  labels: 
    app: MYAPP
spec:
  containers:
  - name: pod-demo
    image: nginx

image-20230227152057674

我们在准备一个示例yaml

##lifecycle-demo.yaml
apiVersion: v1
kind: Pod
metadata:
  name: lifecycle-demo
  labels: 
    app: MYAPP
spec:
  containers:
  - name: lifecycle-demo
    image: nginx
    lifecycle:
      postStart:
        httpGet:
          host: 192.168.0.190
          path: /lifecycle-test
          port: 80
          scheme: HTTP  ####注意这个地方是大写

启动一下

image-20230227153045576

查看一下钩子的设置是否生效

  • 是有相关请求,证明是生效的

image-20230227153136409

preStop

钩子函数在容器被terminate之前执行,执行是同步的,执行完才删除容器,写法也是和postStart一样

##lifecycle-demo.yaml
apiVersion: v1
kind: Pod
metadata:
  name: lifecycle-demo
  labels: 
    app: MYAPP
spec:
  containers:
  - name: lifecycle-demo
    image: nginx
    lifecycle:
      preStop:
        httpGet:
          host: 192.168.0.190
          path: /lifecycle-test
          port: 80
          scheme: HTTP  ####注意这个地方是大写

我们先启动一个这样的 pod

image-20230227153727455

我将这个pod杀死

kubectl delete -f lifecycle-demo.yaml

看下是否生效

image-20230227153826868

容器的探针

健康检查机制

probe 是由 kubelet 对容器执行的定期诊断。 要执行诊断,kubelet 既可以在容器内执行代码,也可以发出一个网络请求。

  • startupProbe:启动探针

    指示容器中的应用是否已经启动。如果提供了启动探针,则所有其他探针都会被禁用,直到此探针成功为止。如果启动探测失败,kubelet 将杀死容器, 而容器依其重启策略进行重启。 如果容器没有提供启动探测,则默认状态为 Success。

  • livenessProbe:存活探针

    指示容器是否正在运行。如果存活态探测失败,则 kubelet 会杀死容器, 并且容器将根据其重启策略决定未来。如果容器不提供存活探针, 则默认状态为 Success。

  • readinessProbe:就绪探针

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

  • 写法是一致的 kubectl explain pod.spec.containers.startupProbe

    • initialDelaySeconds:容器启动后要等待多少秒后才启动启动、存活和就绪探针, 默认是 0 秒,最小值是 0。

    • periodSeconds:执行探测的时间间隔(单位是秒)。默认是 10 秒。最小值是 1。

    • timeoutSeconds:探测的超时后等待多少秒。默认值是 1 秒。最小值是 1。

    • successThreshold:探针在失败后,被视为成功的最小连续成功数。默认值是 1。 存活和启动探测的这个值必须是 1。最小值是 1。

    • failureThreshold:探针连续失败了 failureThreshold 次之后, Kubernetes 认为总体上检查已失败:容器状态未就绪、不健康、不活跃。 对于启动探针或存活探针而言,如果至少有 failureThreshold 个探针已失败, Kubernetes 会将容器视为不健康并为这个特定的容器触发重启操作。 kubelet 会考虑该容器的 terminationGracePeriodSeconds 设置。 对于失败的就绪探针,kubelet 继续运行检查失败的容器,并继续运行更多探针; 因为检查失败,kubelet 将 Pod 的 Ready 状况设置为 false

    • terminationGracePeriodSeconds:为 kubelet 配置从为失败的容器触发终止操作到强制容器运行时停止该容器之前等待的宽限时长。 默认值是继承 Pod 级别的 terminationGracePeriodSeconds 值(如果不设置则为 30 秒),最小值为 1。

  • 检查机制

    • exec
      在容器内执行指定命令。如果命令退出时返回码为 0 则认为诊断成功

    • httpGet

      对容器的 IP 地址上指定端口和路径执行 HTTP GET 请求。如果响应的状态码大于等于 200 且小于 400,则诊断被认为是成功的

    • tcpSocket

      对容器的 IP 地址上的指定端口执行 TCP 检查。如果端口打开,则诊断被认为是成功的。 如果远程系统(容器)在打开连接后立即将其关闭,这算作是健康的

  • 探测结果

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

startupProbe

我先启动了一个 pod-demo 的容器:

image-20230227165026071

我现在准备一个另一个 pod:

apiVersion: v1
kind: Pod
metadata:
  name: probe-demo
  labels: 
    app: MYAPP
spec:
  containers:
  - name: probe-demo
    image: nginx
    startupProbe:
      httpGet:
          host: 192.168.0.190
          path: /index2.html
          port: 80
          scheme: HTTP  ####注意这个地方是大写
      initialDelaySeconds: 60
      failureThreshold: 3
      periodSeconds: 10

我们启动验证一下:

  • 最开始肯定是失败的,因为探针设置的路径不存在的,所以pod的状态也是未就绪的

image-20230227165632242

  • 我们对pod-demo中的文件进行一个操作,让测试pod可以探针成功

image-20230227165724162

image-20230227165829042

livenessProbe

我们还是以上面的为例,准备一个测试 yaml

###每个1秒就去检查特定服务器的服务是否正常访问,
apiVersion: v1
kind: Pod
metadata:
  name: probe-demo
  labels: 
    app: MYAPP
spec:
  containers:
  - name: probe-demo
    image: nginx
    livenessProbe:
      httpGet:
          host: 192.168.0.190
          path: /index.html
          port: 80
          scheme: HTTP  ####注意这个地方是大写
      initialDelaySeconds: 60
      failureThreshold: 3
      periodSeconds: 1
  • 查看一下各状态

image-20230227170427680

  • 我们删除探针里面需要用到的pod,再看下状态

image-20230227170534804

  • 看下探针的事件:检查失败就会一直重启

image-20230227170658527

image-20230227170839132

但是我不知道为啥pod还是处于READY的状态

readinessProbe

就绪探针,理论是和上面一样的

有时候,应用会暂时性地无法为请求提供服务。 例如,应用在启动时可能需要加载大量的数据或配置文件,或是启动后要依赖等待外部服务。 在这种情况下,既不想杀死应用,也不想给它发送请求。 Kubernetes 提供了就绪探针来发现并缓解这些情况。 容器所在 Pod 上报还未就绪的信息,并且不接受通过 Kubernetes Service 的流量。

后续实际应用中,我再来探一下更多的用法场景

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/374835.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

linux下devmem访问物理寄存器MT7621 mdio控制

在同专栏的mdio访问phy的三种方式篇&#xff0c;我们着重介绍了通过ioctrl的方式将mdio总线与网卡绑定进行访问&#xff0c;但是实时上数据接口和管理接口可以独立去控制&#xff0c;很不幸&#xff0c;作者现在必须把mdio与网卡解除绑定并独立操控&#xff0c;因此接下来将详细…

【elementUI】基于elementUI自定义封装分页内容

文章目录前端分页的封装后端进行分页的封装&#xff0c;利用el-pagination网页获取数据进行分页主要有前端分页和后端分页&#xff0c;对于数据量较小的数据&#xff0c;可以使用前端分页进行实现。但是一般的分页都是后端获取分页实现前端分页的封装 思路&#xff1a; 1.假设一…

Mybatis源码学习笔记(五)之Mybatis框架缓存机制原理解析

1 Mybatis框架的缓存模块 MyBatis 内置了一个强大的事务性查询缓存机制&#xff0c;它可以非常方便地配置和定制。Mybatis框架中的缓存分为一级缓存和二级缓存&#xff0c;三级缓存基本都要借助自定义缓存或第三方服务来进行实现。但本质上是一样的&#xff0c;都是借助Cache接…

只会手工测试,裸辞后怎么才能找到工作

我们可以从以下几个方面来具体分析下&#xff0c;想通了&#xff0c;理解透了&#xff0c;才能更好的利用资源提升自己。 一、我会什么&#xff1f; 先说第一个我会什么&#xff1f;第一反应&#xff1a;我只会功能测试&#xff0c;在之前的4年的中我只做了功能测试。内心存在…

如何改变照片的大小kb?照片怎么改到100kb?

在平时的日常工作生活当中&#xff0c;我们都会遇到需要上传照片的情况&#xff0c;但是随着拍摄的照片越来越清晰照片体积也越来越大&#xff0c;很容易遇到图片太大上传不成功的情况&#xff0c;那么这时候应该怎么办呢&#xff1f;今天来给大家分享一款照片压缩器&#xff0…

TCP/IP协议,网络工程部分

这个博客参考了许多up主的视频和网上其他的博主的文章&#xff0c;还有我老师的ppt 这里是目录一、osi七层模型&#xff08;参考模型&#xff09;1.物理层2.数据链路层&#xff08;数据一跳一跳进行传递&#xff09;3.网络层&#xff08;端到端传输&#xff09;4.传输层&#x…

synchronized底层如何实现?什么是锁的升级、降级?

第16讲 | synchronized底层如何实现&#xff1f;什么是锁的升级、降级&#xff1f; 我在上一讲对比和分析了 synchronized 和 ReentrantLock&#xff0c;算是专栏进入并发编程阶段的热身&#xff0c;相信你已经对线程安全&#xff0c;以及如何使用基本的同步机制有了基础&#…

Web Spider案例 网洛者 第一题 JS混淆加密 - 反hook操作 练习(五)

文章目录一、资源推荐二、第一题 JS混淆加密 - 反hook操作2.1 过控制台反调试(debugger)2.2 开始逆向分析三、python具体实现代码四、记录一下&#xff0c;execjs调用混淆JS报错的问题总结提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、资源推荐 …

Echarts 实现电池效果的柱状图

第022个点击查看专栏目录本示例是解决显示电池电量状态的柱状图&#xff0c;具体的核心代码请参考源代码。 文章目录示例效果示例源代码&#xff08;共102行&#xff09;相关资料参考专栏介绍示例效果 示例源代码&#xff08;共102行&#xff09; /* * Author: 还是大剑师兰特…

aws ecs 使用application autoscaling自动扩缩ecs服务

参考资料 https://aws.amazon.com/cn/blogs/china/microservices-on-amazon-ecs-1/ https://aws.amazon.com/cn/blogs/china/microservices-on-amazon-ecs-2/ https://zhuanlan.zhihu.com/p/355383555 https://docs.amazonaws.cn/en_us/AmazonECS/latest/developerguide/ser…

YOOV人事管理|2023年面临7大职场趋势,关系到管理者和HR

各种停摆浪潮席卷了2022年的职场生态&#xff0c;对于人力资源工作者来说&#xff0c;无论是判断员工的意向&#xff0c;或是组织面对的挑战&#xff0c;都愈来愈复杂。YOOV人事管理针对2023年&#xff0c;提出了7项观察&#xff0c;提醒雇主和HR应留意的未来工作趋势。 1.安静…

95.【操作系统-第一章】

操作系统(一)、操作系统概述1.1_操作系统的概念、功能和目标(1).操作系统的定义(2).操作系统的功能和目标——作为系统资源的管理者(3).操作系统的功能和目标——向上层提供方便易用的服务(4).操作系统的功能和目标--作为用户和计算机硬件之间的接口(5).操作系统的功能和目标—…

腾讯前端二面常考vue面试题(附答案)

虚拟DOM真的比真实DOM性能好吗 首次渲染大量DOM时&#xff0c;由于多了一层虚拟DOM的计算&#xff0c;会比innerHTML插入慢。正如它能保证性能下限&#xff0c;在真实DOM操作的时候进行针对性的优化时&#xff0c;还是更快的。 MVVM的优缺点? 优点: 分离视图&#xff08;V…

PowerCommand康明斯发电机控制屏维修HMI211

康明斯柴油发电机的监控系统分为普通机组控制屏和智能化机组控制界面。普通操作界面实用于普通的康明斯柴油发电机的控制&#xff0c;康明斯柴油发电机的起动与停止、供电与断电、状态调整等均由手动操作&#xff1b;自动化康明斯柴油发电机控制系统适合于智能化康明斯柴油发电…

JavaWeb 基本概念

JavaWeb Java Web 1、基本概念 1.1、前言 web开发&#xff1a; web&#xff0c;网页的意思 &#xff0c; www.baidu.com静态web html&#xff0c;css提供给所有人看的数据始终不会发生变化&#xff01; 动态web 淘宝&#xff0c;几乎是所有的网站&#xff1b;提供给所有人…

ActiveMQ RabbitMQ Kafka RocketMQ

消息中间件的作用 1.正向作用 应用解耦/事件驱动 异步通信 流量削峰 2.反向作用 系统可用性降低 系统复杂性提高 一致性问题 ---------------------------------------------------------------------------------------------------------…

C语言数据结构(3)----无头单向非循环链表

目录 1. 链表的概念及结构 2. 链表的分类 3. 无头单向非循环链表的实现(下面称为单链表) 3.1 SListNode* BuySListNode(SLTDateType x) 的实现 3.2 void SListPrint(SListNode* plist) 的实现 3.3 void SListPushBack(SListNode** pplist, SLTDateType x) 的实现 3.4 voi…

【分布式】分布式场景下的稳定性保障

文章目录1、什么是稳定性保障2、明确稳定性保障目标2.1、明确一级目标2.2、拆解二级目标3、如何进行稳定性保障3.1、全链路梳理3.2、全链路压测3.3、集群扩容3.4、服务限流3.5、提前预案3.6、紧急预案3.7、系统监控4、大促稳定性保障4.1、制定大促计划4.2、大促准备4.3、大促值…

kubeadm方式安装k8s高可用集群(版本1.26x)

K8S官网&#xff1a;https://kubernetes.io/docs/setup/ 高可用Kubernetes集群规划 配置备注系统版本CentOS 7.9Docker版本20.10.xPod网段172.16.0.0/12Service网段10.103.10.0/16 主机IP说明k8s-master01 ~ 03192.168.77.101 ~ 103master节点 * 3k8s-master-lb192.168.77.2…

Tina_Linux配网开发指南

OpenRemoved_Tina_Linux_配网_开发指南 1 概述 1.1 编写目的 介绍Allwinner 平台上基于wifimanager-v2.0 的WiFi 配网方式&#xff0c;包括softap(WiFi ap 模式热点配网),soundwave(声波配网),BLE(蓝牙低功耗配网)。 1.2 适用范围 • allwinner 软件平台tina v5.0 版本及以…