Kubernetes in Action 笔记


从DevOps到NoOps

过去,开发负责开发,开发完了交给op去部署。但现在人们发现开发也应该参与到部署的过程中来,开发也应该负责部署。这意味着开发者,qa,op在整个产品生命周期中都需要写作。这种事件方法就叫做DevOps.

理想化的,如果开发团队可以当不用关心底层实现的情况下放心的进行软件部署的话,这种方式就叫做NoOps. 这就是k8s可以大展手脚的地方,K8s将硬件抽象化,集群抽象成一个平台,使得开发者可以不需要op帮助自己去配置自己需要的系统资源,也不用去了解底层的硬件情况。

如果集群上都用K8s,op就不用在帮你部署了(容器化了)。开发也不用关心底层硬件,因为k8s将整个集群抽象成了一个单节点

 

Container技术

简单来说,容器是对应用程序及其依赖库的一种封装。

相比于传统的虚拟机,容器的优势主要在以下几个方面:

  • 容器与宿主机共享资源,使得其效率有了很大的提升。与主机中运行的应用程序相比,在容器中运行的应用程序几乎没有任何额外的开销。

  • 容器可移植的特性可以解决由于运行环境的微小变化引发的一系列问题。

  • 容器的轻量级特性意味着开发人员可以同时运行数十个容器,从而可以模拟出生产级别的分布式系统

 

实现Container的技术主要有2个:

  • Linux Namespaces: 使得各个进程间完全隔离(包括文件,进程,网络Port,hostname等等)
  • Linux Control Groups (cgroups):可以限制每一个进程能够consume的系统资源(CPU, memory, network bandwidth, and so on)

默认来说,每一个Linux系统初始都有单一一个namespace,包括所有的system resources, 像是filesystems, process IDs, user IDs, network interfaces。我们可以在这基础上增加额外的namespaces,同时配资源。在跑一个进程时,可以直接在namespace里跑,进程中的应用将只能看到并使用自己被分配到的资源。

namespaces一般会有以下几种:

  • Mount (mnt)
  • Process ID (pid)
  • Network (net)
  • Inter-process communication (ipc)
  • UTS
  • User ID (user)

namespace

Linux 在很早的版本中就实现了部分的 namespace,比如内核 2.4 就实现了 mount namespace。大多数的 namespace 支持是在内核 2.6 中完成的,比如 IPC、Network、PID、和 UTS。还有个别的 namespace 比较特殊,比如 User,从内核 2.6 就开始实现了,但在内核 3.8 中才宣布完成。同时,随着 Linux 自身的发展以及容器技术持续发展带来的需求,也会有新的 namespace 被支持,比如在内核 4.6 中就添加了 Cgroup namespace。

 

 

 

仓库、镜像、容器是什么

  • 镜像: 镜像是什么呢?通俗地讲,它是 一个只读的文件和文件夹组合 。它包含了容器运行时所需要的所有基础文件和配置信息,是容器启动的基础。所以你想启动一个容器,那首先必须要有一个镜像。镜像是 Docker 容器启动的先决条件。

  • 容器: 容器是镜像的运行实体 。镜像是静态的只读文件,而容器带有运行时需要的可写文件层,并且容器中的进程属于运行状态。 即容器运行着真正的应用进程,容器有初建、运行、停止、暂停和 删除五种状态。

  • 仓库: Docker 的镜像仓库类似于代码仓库,用来存储和分发 Docker 镜像。 镜像仓库分为公共镜像仓库和私有镜像仓库 。

 

Docker 架构

Docker 整体架构采用 C/S(客户端 / 服务器)模式,主要由客户端和服务端两大部分组成。客户端负责发送操作指令,服务端负责接收和处理指令。

 

 

 

 

  • Docker 客户端

Docker 客户端其实是一种泛称。其中 docker 命令是 Docker 用户与 Docker 服务端交互的主要方式。

除了使用 docker 命令的方式,还可以使用直接请求 REST API 的方式与 Docker 服务端交互,甚至还可以使用各种语言的 SDK 与 Docker 服务端交互。

 

  • Docker 服务端

Docker 服务端是 Docker 所有后台服务的统称。其中 dockerd 是一个非常重要的后台管理进程,它负责响应和处理来自 Docker 客户端的请求,然后将客户端的请求转化为 Docker 的具体操作。

Docker 服务端的两个至关重要的组件:runC 和 containerd。

  1. runC 是 Docker 官方按照 OCI 容器运行时标准的一个实现。通俗地讲,runC 是一个用来运行容器的轻量级工具,是真正用来运行容器的。

  2. containerd 是 Docker 服务端的一个核心组件,它是从 dockerd 中剥离出来的 ,它的诞生完全遵循 OCI 标准,是容器标准化后的产物。containerd 通过 containerd-shim 启动并管理 runC,可以说 containerd 真正管理了容器的生命周期。

 

Kubernetes技术

k8s是一个可以让你非常方便的部署以及管理容器化的应用的平台。他使得开发者可以在一个上千个节点的集群上部署应用就像在一个单机节点部署一样方便。k8s将底层的硬件抽象化,极大的简化了开发,部署,运维工作。

 

生态系统

 

  • Kubernetes外部:日志、监控、配置管理、CI、CD、Workflow、FaaS、OTS应用、ChatOps等
  • Kubernetes内部:CRI、CNI、CVI、镜像仓库、Cloud Provider、集群自身的配置和管理等

k8s核心技术概念和API对象
API对象是k8s集群中的管理操作单元。

每个API对象都有三大类属性:

  1. 元数据metadata

用于标识API对象,每个对象至少有3个元数据
namespace,name和uid

2.规范spec

所有的配置都是通过API对象的spec去设置,所有的操作都是声明式的。
声明式操作在分布式系统中好处是稳定,不怕丢操作或者运行多次。

3. 状态 status
例如用户可以通过复制控制器Replication Controller设置期望的Pod副本数为3;status描述了系统实际当前达到的状态(Status),例如系统当前实际的Pod副本数为2;那么复制控制器当前的程序逻辑就是自动启动新的Pod,争取达到副本数为3

 

核心对象:

RC(复制控制器)

通过监控运行中的Pod来保证集群中运行指定数目的Pod副本。指定的数目可以是多个也可以是1个;少于指定数目,RC就会启动运行新的Pod副本;多于指定数目,RC就会杀死多余的Pod副本。

即使只运行一个pod,用RC也是明智的选择,因为其可以保证永远有一个pod在运行。

 

副本集(Replica Set,RS)

提供同样的高可用能力。副本集对象一般不单独使用,而是作为Deployment的理想状态参数使用。

 

部署(Deployment)

  • 支持定义一组pod的期望数量,Controller会为我们维持Pod的数量在期望的版本以及期望的数量。
  • 支持配置Pod的发布方式,配置完成后Controler会按照我们给出的策略来更新Pod。
  • 支持滚动升级,滚动升级一个服务,实际是创建一个新的RS,然后逐渐将新RS中副本数增加到理想状态,
  • 支持一键回滚

 

Kubernetes集群的架构

 

 

k8s采用主从式分布式架构

master node

  1. API server 与所有组件进行通信
  2. Scheduler 调度应用,为应用的每个部署组件分配一个节点
  3. Controller Manager 执行集群级别的功能,如复制,跟踪工作节点,处理节点失败
  4. etcd 分布式数据存储,持久化存储集群配置

worker node

  1. kubelet 与API服务器通信,管理它所在节点的容器
  2. kube-proxy 负责组件之间的负载均衡

组件之间的通信

  1. 组件之间只能通过 API Server 进行通信
  2. 其中etcd 不会和其他组件直接通信

单组件运行多实例

  1. 工作节点的组件都需要运行在同一个节点上
  2. master的组件可以分布在不同的节点上运行
  3. 而且master的每个组件都可以有多个实例,其中etcd和API Server可以多实例并行工作
  4. 但是调度器和controller manager 只能运行一个实例,其他实例待命

组件的运行

  1. master的组件与kube-proxy既可以直接部署在系统上,也可以直接作为pod来运行
  2. 如果要把master的组件作为pod来运行,kubelet需要部署在master节点上
  3. Kubelet是唯一作为常规系统组件运行的组件,把其他组件作为pod来运行

etcd

  1. k8s中创建的所有对象:pod,ReplicationController,服务和私密凭据等,都需要持久化存储在底层,这样当API Server重启失败的时候,能够迅速找到这些对象的信息
  2. etcd是一个分布式,一致的key-value存储
  3. k8s架构里面,只有api server能够与它通信,这样可以增加乐观锁系统的健壮性
  4. etcd是k8s存储集群状态和元数据的唯一的地方
  5. 一个etcd条目代表一个对象(如pod),API Server把资源的完整Json形式存储到etcd中.Json的层级关系就对应了etcd的层级建空间
  6. 乐观锁机制
  7. 确保etcd集群的一致性
  8. 为了实现高可用,多个etcd实例会同时运行,这时候需要RAFT一致性算法来保证这一点.

 

API-Server

  1. API server负责存储资源到etcd和通知客户端有变更的工作
  2. 作为K8s的中心组件,由其他组件或者客户端都会调用它
  3. 以RESTful API形式提供了可以查询,修改集群状态的CRUD,然后把状态存储到etcd中

调度器

  1. 任务是通过API Server 更新Pod的定义,然后API Server再去通知Kubelet这个Pod已经被调度过,当目标节点上的Kubelet发现这个pod被调度到本节点的时候,就会创建并且运行pod的容器

Controller-Manager

  1. 确保系统的真实状态朝API服务器定义的期望状态收敛
  2. 通过API Server监听资源,然后执行相应的变更操作

Kubelet

  1. 负责所有运行在工作节点上的内容的组件
  2. 第一个任务就是在API Server服务器中创建一个Node资源,然后注册这个节点
  3. 持续监控API Server判断是否把pod分配到该节点
  4. 启动pod容器,然后kubelet持续监控运行的容器,并且向API Server 报告他们的状态,事件和资源消耗
  5. Kubelet也是运行容器存活探针的组件,探针报错的时候会重启容器,最后当Pod从API Server删除的时候,由Kubelet来执行终止容器的任务,并且告知API Server,pod已经终止了

K8s Service Proxy的作用

  1. 每个工作节点还会运行kube-proxy,用于确保客户端可以通过K8s API来连接到定义的服务
  2. kube-proxy确保对服务IP和端口的链接最终能到达支持服务的某个Pod处,如果有多个Pod支撑一个服务,那么代理就会发挥对pod的负载均衡作用
  3. userspace代理模式
  4. 请求要经过kube-proxy,请求会轮训选择后端Pod
  5. iptables代理模式
    1.   请求不需要经过kube-proxy,仅仅通过iptables规则重定向数据包到一个随机选择的后端pod,而不会传递到一个实际的代理服务器。

DNS服务器

  1. 集群中的pod默认配置使用集群内部的DNS服务器,使得pod能够轻松通过名称查询到服务

Ingress控制器

  1. 运行一个反向代理服务器,根据集群定义的Ingress,Service以及Endpoint资源来配置控制器,需要通过监听机制订阅这些资源。然后每次发生变化的时候更新代理服务器的配置。
  2. 尽管Ingress资源定义指向一个Service,Ingress控制器会直接把流量转到服务的pod而不经过服务IP,当外部客户端通过Ingress控制器连接的时候,还会对客户端的IP进行保存。

 

 

理解 Pods

Pod 可以包含一个或多个有协作关系的容器,是 Kubernetes 中最基本的构造单位。

  • 容器只能借助 Pod 进行部署,无法独立运行
  • 一个 Pod 可以包含多个容器,但只包含一个容器的 Pod 也是很常见的
  • Pod 中的多个容器只允许在同一个工作节点上运行,即单个 Pod 不能跨节点部署
 
 

 

 

Pod优势:
 

为什么要在一个 Pod 中运行多个容器,而不是在一个容器中运行多个进程。

一个容器不应该包含多个进程
容器就像是一台隔离的虚拟机,因此是可以同时运行多个进程的。但这样会使得容器难于管理。
容器被设计成只会运行一个进程(子进程不计算在内),大多数容器管理工具也都是基于这个原则去设计的。
比如容器中运行的进程有时候会向标准输出打印其日志信息,Kubernetes 中查看日志的命令就只会显示从这个输出中捕获到的内容。如果容器中同时运行多个进程,都向外输出日志信息,Kubernetes 捕获到的日志内容就会变得错综复杂。

另一个原因在于,容器运行时只会在容器的根进程挂掉时重启该容器。
为了充分利用容器运行时提供的特性,应该在每个容器中只运行一个进程。

 

Pod的隔离:

  1. 一个pod内的容器能够共享相同的host和网络接口
  2. 容器能够通过进程间通信
  3. PID也可以共享,共享之后能够看到彼此运行的进程
  4. 但是文件系统是没有共享的,要靠Volume来实现共享文件目录
  5. 一个Pod中所有容器都有相同的回环网络接口,因此容器可以通过localhost和同一个pod的其他容器进行通信
  6. Pod之间的网络是平坦的(无需NAT进行网络地址转换),就是说pod之间的关系类似于局域网中的主机,每个pod都有相应的IP地址,并且可以通过这个网络实现Pod之间的相互访问

 

Pod 如何组合多个容器
不应该在同一个容器中运行多个进程。与此同时,将分散在多个容器中相互关联的进程结合成一个单位,统一进行管理也是很有必要的。
因此引入了 Pod 机制。

Pod 可以同时运行多个关系紧密的进程(容器),给它们(几乎)相同的运行环境,使得它们就像是运行在同一个容器中那样。
这些进程是相互独立、隔离的,但也会共享某些资源。因而既可以使用容器提供的各种隔离特性,又能够促使多个进程相互协作。


 

 

 

如上图所示,Pod 中的多个容器共享同一个 Network 命名空间,因而共享该命名空间的网络接口、IP 地址、端口空间等。这些容器能够使用 loopback 设备进行通信,但不能绑定同一个网络端口。

同一个 Pod 中的多个容器还会共享相同的 UTS 命名空间,因而能看到同一个主机名;共享相同的 IPC 命名空间,因而不同容器中的多个进程之间可以通过 IPC 进行通信;还可以配置成共享同一个 PID 命名空间,使得这些容器中的进程使用同一个进程树

 
单容器 or 多容器

可以将 Pod 看作一台独立的计算机。不同于虚拟机通常需要同时运行多个应用,每个 Pod 中一般只运行一个应用。 Pod 几乎没有额外的资源开销,因而在同一个 Pod 中运行多个应用并不是必须的。

将多个容器放置在同一个 Pod 中的唯一场景,就是某个应用包含一个基础进程以及一个或者多个对基础进程有补充作用的附加进程。运行附加进程称为 sidecar container。包含如下常用的两个Demo。

 

 

查看应用日志

 Kubernetes 会为每一个容器都保留一个独立的日志文件。它们通常保存在容器运行节点的 /var/log/containers 路径下,容器重启后其日志会写入到一个新的文件中。

查看日志命令:

kubectl logs kubia
kubectl logs kubia  --timestamps=true
kubectl logs kubia --since=2h


//文件传输

//将 kubia 容器中的 /etc/hosts 文件复制到本地 /tmp 路径下。
kubectl cp kubia:/etc/hosts /tmp/kubia-hosts

//将本地文件复制到 kubia 容器。
kubectl cp /path/to/local/file kubia:path/in/container 

 

 

 

Pod不稳定性

  1. 由于pod随时可能被抹除,更新,所以hardcode pod服务的方式是不可行的。
  2. k8s在部署一个pod时,只有确定node节点之后才会真正分配一个ip,所以我们也没法提前知道pods的ip.
  3. 横向扩展一个服务意味着同时会有多个pod提供同一个服务,每个pod都有自己独立的ip地址。客户不应该care后端有多少pod在提供服务。

为什么要有Service?

  • service为一组功能相同的pod提供单一不变的接入点的资源,外界只需要通过IP与端口与service建立连接,这些链接会被路由到提供该服务的任意一个Pod上,通过这种方式,客户端不需要知道每个单独的Pod提供服务的Pod地址

 

service负载分发策略

那么service如何决定由哪个pod来提供服务?

1.RoundRobin: 轮询模式,轮询把请求转发到后端的各个Pod上

2.SessionAffinity: 基于客户端IP地址进程会话保持,第一次客户端访问后端某个pod,之后的请求都会转发到这个pod上

 

服务发现:

1. 环境变量

当一个Pod被启动时候,k8s会初始化一系列在当前节点已经存在的服务,并嵌入到这个Pod的环境变量中。

 

2.使用DNS server 

每个service都会在internal dns server上有一个DNS entry.那么知道service 名称的客户端就可以通过qualified domain name (FQDN)来访问服务。

 

Endpoint

服务不是和pod直接相连的。service和pod是通过endpoint来进行相连的。Endpoint资源就是暴露一个服务的IP地址和端口的列表。

 

服务暴露给外部客户端

Service 对外暴露方式分三种,nodepod,loadbalance,ingress

  1. NodePort 每个集群节点都会在节点上打开一个端口,并且把端口上接收到的流量重定向到基础服务,服务仅仅在内部集群IP和端口上才能够访问,现在也可以通过所有节点上的专用端口访问
  2. LoadBalance 服务可以通过一个专用的负载均衡器访问,负载均衡器把流量重定向到跨所有节点的节点端口,客户端通过负载均衡器的IP连接到服务
  3. Ingress资源,通过一个IP地址公开多个服务,这是运行在HTTP层上面的

 

 

 

 

为什么需要Ingress

  • 因为每个LoadBalancer都要有自己的公有IP地址,而Ingress只需要一个公网IP就能为许多服务提供访问.
  • 当客户端向Ingress发送HTTP请求的时候,Ingress会根据请求的主机名和路径决定请求转发到的服务

Ingress执行原理:

  • 客户端首先对域名执行DNS查找,DNS服务器会返回Ingress控制器的IP
  • 客户端然后向Ingress控制器发送HTTP请求
  • 通过查看Endpoint对象来查看pod IP
  • 然后把客户端的请求转发给其中一个Pod
  • Ingress控制器不会把请求转发给该服务,只用它来选择一个Pod

 

 

 

 

网络通讯

跨pod网络

同一个节点的pod怎么通信?

 

容器会创建一个虚拟的以太网接口对,其中一个对的接口会在物理主机的命名空间中。而其他的对会被移入容器的网络命名空间。

如果pod A发送网络包到pod B, 报文首先会经过pod A的veth对到网桥然后经过pod B的veth对。 所有节点上的容器都会连接到同一个网桥, 意味着它们都能够互相通信。 但是要让运行在不同节点上的容器之间能够通信, 这些节点的网桥需要以某种方式连接起来

不同节点上的pod通信

 

 当报文从一个节点上容器发送到其他节点上的容器, 报文先通过veth pair, 通过网桥到节点物理适配器,然后通过网线传到其他节点的物理适配器,再通过其他节点的网桥,最终经过vethpair到达目标容器。

 

 

服务对外暴露 port-forward原理

通过 Kubectl 端口转发访问 Pod

在开发过程中,最简单的访问容器中应用的方法是使用 kubectl port-forward 命令。该命令可以通过绑定到本地机器端口上的代理来访问特定的 Pod。
此方式甚至不需要知道 Pod 的 IP 地址,只需要指定 Pod 的名字和端口号即可


$ kubectl port-forward kubia 8080
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080

 

上述命令会在本地机器的 8080 端口开启一个代理,指向 kubia 容器的 8080 端口。
此时打开另一个命令行窗口,运行 curl localhost:8080 命令即等同于访问 kubia 容器的 8080 端口:

 

 

Service实现——Kube-proxy

在k8s集群中微服务的负载均衡是由kube-proxy实现的。kube-proxy是k8s集群内部的负载均衡器,是一个分布式代理服务器,在每个k8s节点上都有一个。

采用kube-proxy负责service的实现,使用iptables的方法配置负载均衡,主要职责包括:

1.监听service
(service的创建删除与修改)

当在API服务器中创建一个服务 时, 虚拟 IP地址立刻就会分配给它。之后很短时间内, API服务器会 通知所有 运行在工作节点上的kube-proxy客户端有 一个新服务已经被创建了。然后 ,每个知be-proxy都会让该服务 在自己的运行 节点上可寻址。原理是通过建立一 些iptables规则, 确保每个目的地为服务的 IP/端口对的数据
包 被解析, 目的地址被修改, 这样数据包就会被重定向到支持服务的一个pod.

2.监听endpoint

Endpoint对象保存所有支持服务的pod的IP/端口对( 一
个IP/端口对也可以指向除pod之外的其他对象)。
(pod的扩容与缩容)

kube-proxy只是作为controller,真正提供服务的是内核的netfilter模块,体现在用户态的就是iptables。

iptables的负载分发策略下面介绍,就是轮询以及会话亲和性。

 

 

 

 

Pod就绪探针

有时候Pod启动之后需要一定时间来加载配置或者数据,这时候不希望pod立即开始接受请求,尤其是在运行的实例可以正确快速地处理请求的情况下,不要把请求转发到正在启动的Pod中,直到完全准备就绪

readiness probe会定期调用,确定特定的pod是否接受客户端请求,当容器准备就绪探测返回成功的时候,表示容器已经准备好接受请求

大概工作过程:

  • 启动容器的时候,为k8s配置一个等待时间,经过等待时间后才可以执行第一次准备检查
  • 之后周期性调用探针,根据就绪探针的结果采取行动
  • 如果探测失败,就把容器从Endpoint中删除

 

存活指针 liveness probe

如果没有设置初始延迟,那么探针将会在启动的时候立即开始探测容器,通常会导致探测失败,因为应用程序还没有准备好开始接受请求.

因此通常在创建探测指针的时候,需要设定初始延迟时间

K8s有三种探测容器的机制:

  1. HTTP GET探测 尝试对容器的ip地址发起HTTP GET请求,根据响应码来判断容器是否健康
  2. TCP套接字探针 尝试与容器指定端口建立TCP链接,如果链接成功建立,则说明成功建立
  3. Exec探针 在容器内执行任意命令,并且检查命令的退出状态吗,如果退出状态码是0,说明探测成功

创建探针 

 

使用headless服务来发现独立的Pod

通过把yaml文件中的service的clusterIP设置为"None",那么该服务就变成headless服务了

因为没有ClusterIP,kube-proxy 并不处理此类服务,因为没有load balancing或 proxy 代理设置,在访问服务的时候回返回后端的全部的Pods IP地址

DNS直接返回所有PodIp, 客户端直接链接该podIp,不再需要服务代理。

 

资源控制

在创建pod时,你可以声明他需要(request)的cpu和内存资源

调度器scheduler在接到请求防止pod时首先会排除资源量已经不满足pod资源需求的node,然后会按照LeastRequestedPriority and MostRequestedPriority 两种排序逻辑来对剩余的节点进行优先级排序

如果不对cpu的使用做限制的话,他是可能打满的,为了机器的健康和规避潜在的风险,我们能设limit的时候还是一定要设置limit。

 

cpu是可压缩的资源,内存是不可压缩资源,过多占用内存则可能导致OOM killed

 

OOM kill优先级分三种

  • BestEffort (the lowest priority),未设置request,limit
  • Burstable, request,limit不相等
  • Guaranteed (the highest):reqest=limit

优先级最低的是BestEffort class,它适用于完全没有任何资源需求或者限制的pod(any of the container级别)。运行在此类pod中的容器没有任何的资源保证。最坏的情况下他的所有资源可能会被其他pod抢光,在资源竞争时也会被头一个干掉。但是因为此类class没有内存限制,他也可能在没有资源竞争的情况下吃光节点的内存资源。

Guaranteed:

每个容器的resource requests默认是与limit相等的,所以对所有资源声明limit就足够将pod变为Guaranteed。此类容器会保证收到他们请求的资源,但不会被分配到额外的资源(以为limit不比requests高。

 

如果都是Burstable级别,则比较OOM分数,OOM分数等 当前QoS/Request数量,分数越高越容易被kill.

 

 

 

 

 

附录: 完整的Pod示例:

apiVersion: v1                    #必选,版本号,例如v1,版本号必须可以用 kubectl api-versions 查询到 .
kind: Pod                      #必选,Pod
metadata:                      #必选,元数据
  name: string                    #必选,Pod名称
  namespace: string               #必选,Pod所属的命名空间,默认为"default"
  labels:                       #自定义标签
    - name: string                 #自定义标签名字
  annotations:                           #自定义注释列表
    - name: string
spec:                            #必选,Pod中容器的详细定义
  containers:                       #必选,Pod中容器列表
  - name: string                        #必选,容器名称,需符合RFC 1035规范
    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

 

posted @ 2022-02-11 23:01  龘人上天  阅读(157)  评论(0编辑  收藏  举报