Interactions between Pod priority and quality of service(Qos)

[TOC] Pod 优先级和服务质量之间的相互作用 集群中为了保障核心服务正常运行,有时候会舍弃掉不那么核心的服务。在通过Kubernetes实现的时候发现有两个手段: 设置pod的服务质量。Guaranteed, Burstable, BestEffort 设置pod的优先级 可是当这两个发生冲突的时候,优先考虑谁呢?比如现在这种情况: 在资源不够用的情况下,一个高优先级,但是Qos属于Burstable或BestEffort的pod会抢占,低优先级但Qos属于Guaranteed的pod吗? 挠头不? 进过查找资料,发现官方给出的答案是这样的: 其实这里是要分情况来看,简单来说是两个环节:pod调度环节 和 节点压力驱逐环节 pod调度环节 这里有最核心的一句话。 The scheduler's preemption logic does not consider QoS when choosing preemption targets. 调度器的抢占逻辑在选择抢占目标时不考虑 QoS。只看pod的优先级,所以无论Guaranteed, Burstable, BestEffort,只要你的优先级最低,并且能腾出空间给新的pod运行,那很可能就是你了。 节点压力驱逐环节 而对于节点压力驱逐环节可能会繁琐一点 As a result, kubelet ranks and evicts pods in the following order: BestEffort or Burstable pods where the usage exceeds requests. These pods are evicted based on their Priority and then by how much their usage level exceeds the request. Guaranteed pods and Burstable pods where the usage is less than requests are evicted last, based on their Priority. 第一条:usage exceeds requests ...

May 1, 2022

kubernetes常见问题

[TOC] Rancher平台使用问题记录 平台问题 详细说明 备注 rancher与k8s 异常断连 1.在查看大量日志时出现过该问题 2.一些官方组织的交流群中建议优化 k8s系统参数,增加ip port range k8s grpc-lb无效 方案有4种: 1、grpc-client + k8s headless 2、envoy (grpc proxy) 3、server mesh (istio/linkerd) 4、 rancher平台部署 节点亲和性 pod亲和性/反亲和性 删除deployment,对应service未删除 headless服务部署 节点选择/在页面打污点 k3s部署 指定reserve预留资源 agent 无法设置reserve? https://docs.rancher.cn/docs/k3s/installation/install-options/server-config/_index/#agent-%E7%BD%91%E7%BB%9C https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/ zoomkeeper更新pod始终有一个没有update rollingUpdatePartition: 0 即可 https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions Kafka部署extralaccess longhorn storage 在etcd恢复中是否可用? Kubernetes在在删除namespace后的恢复问题? 1.通过etcd恢复所有的资源配置 2.配置所有的storageclass创建pv的回收策略为:retain 开发人员使用需求汇总 需求内容 详细说明 时间 备注 pod对cpu/memery资源可见性限制 pod支持绑定宿主机CPU核 api-gateway nuclio pod 统一对外开放访问 有状态数据库服务更新手动确认 更新要求: 1.先只更新一个pod 2.手动确认第一个pod运行正常之后再更新其他pod 3.pod确认时间几分钟到数小时不等,无法使用readness进行确认 https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#partitions k3s 在混用docker/containerd之后,重启docker导致的pod hostport模式中iptables路由混乱问题测试验证 hostport添加分析 ...

May 1, 2021

k3s 安装

[TOC] k3s 简介 K3s 是一个轻量级的 Kubernetes 发行版,它针对边缘计算、物联网等场景进行了高度优化。由于运行 K3s 所需的资源相对较少,所以 K3s 也适用于开发和测试场景。 部署起来非常简单,所有服务打包为单个二进制文件,同时启动程序自动处理了众多TLS认证的内容,存储也是用轻量级数据库或者内置etcd等。 k3s安装 第一个master # first master curl -sfL http://rancher-mirror.cnrancher.com/k3s/k3s-install.sh | \ K3S_TOKEN='262c73d1ac2e7a8179c861a8a47640f8' \ INSTALL_K3S_EXEC="server --cluster-init" \ INSTALL_K3S_MIRROR=cn \ INSTALL_K3S_VERSION=v1.20.4+k3s1 sh -s - # check systemctl status k3s.service kubectl get nodes 第二个master 只需要在第一个master的基础上,指定第一个master的IP K3S_URL="https://${first_master_ip}:6443" ,同时去掉初始化选项 --cluster-init 即可。如下: # other master first_master_ip=172.26.186.176 curl -sfL http://rancher-mirror.cnrancher.com/k3s/k3s-install.sh | \ K3S_TOKEN='262c73d1ac2e7a8179c861a8a47640f8' \ K3S_URL="https://${first_master_ip}:6443" \ INSTALL_K3S_EXEC="server" \ INSTALL_K3S_MIRROR=cn \ INSTALL_K3S_VERSION=v1.20.4+k3s1 sh -s - # check systemctl status k3s.service kubectl get nodes node节点 计算节点再去掉 INSTALL_K3S_EXEC 参数,直接去加入集群即可 ...

April 1, 2021

k8s学习笔记-26-kubeasz+ansible部署集群

[TOC] 官方学习文档:https://github.com/easzlab/kubeasz 1、环境说明 IP 主机名 角色 虚拟机配置 192.168.56.11 k8s-master deploy、master1、lb1、etcd 4c4g 192.168.56.12 k8s-master2 master2、lb2 4c4g 192.168.56.13 k8s-node01 etcd、node 2c2g 192.168.56.14 k8s-node02 etcd、node 2c2g 192.168.56.110 vip 系统内核 3.10 docker版本 18.09 k8s版本 1.13 etcd版本 3.0 2、准备工作 四台机器,全部执行: yum install -y epel-release yum update -y yum install python -y deploy节点安装ansible并配置密钥认证 yum install -y ansible ssh-keygen for ip in 11 12 13 14;do ssh-copy-id 192.168.56.$ip;done deploy节点编排K8S [root@k8s-master ~]# git clone https://github.com/gjmzj/kubeasz.git [root@k8s-master ~]# mv kubeasz/* /etc/ansible/ 可以根据自己所需版本,下载对应的tar包,这里我下载1.13 经过一番折腾,最终把k8s.1-13-5.tar.gz的tar包放到了depoly上 ...

October 5, 2018

k8s学习笔记-25-Helm程序包管理器

[TOC] 1、Helm的概念和架构 每个成功的软件平台都有一个优秀的打包系统,比如 Debian、Ubuntu 的 apt,Redhat、Centos 的 yum。而 Helm 则是 Kubernetes 上的包管理器。 **思考??**Helm 到底解决了什么问题?为什么 Kubernetes 需要 Helm? Kubernetes 能够很好地组织和编排容器,但它缺少一个更高层次的应用打包工具,而 Helm 就是来干这件事的。 举个例子,我们需要部署一个MySQL服务,Kubernetes则需要部署以下对象: ① 为了能够让外界访问到MySQL,需要部署一个mysql的service; ②需要进行定义MySQL的密码,则需要部署一个Secret; ③Mysql的运行需要持久化的数据存储,此时还需要部署PVC; ④保证后端mysql的运行,还需要部署一个Deployment,以支持以上的对象。 针对以上对象,我们可以使用YAML文件进行定义并部署,但是仅仅对于单个的服务支持,如果应用需要由一个甚至几十个这样的服务组成,并且还需要考虑各种服务的依赖问题,可想而知,这样的组织管理应用的方式就显得繁琐。为此就诞生了一个工具Helm,就是为了解决Kubernetes这种应用部署繁重的现象。 Helm的核心术语: Chart:一个helm程序包,是创建一个应用的信息集合,包含各种Kubernetes对象的配置模板、参数定义、依赖关系、文档说明等。可以将Chart比喻为yum中的软件安装包; Repository:Charts仓库,用于集中存储和分发Charts; Config:应用程序实例化安装运行时所需要的配置信息; Release:特定的Chart部署于目标集群上的一个实例,代表这一个正在运行的应用。当chart被安装到Kubernetes集群,就会生成一个release,chart可以多次安装到同一个集群,每次安装都是一个release。 Helm的程序架构: Helm主要由Helm客户端、Tiller服务器和Charts仓库组成,如下图: helm:客户端,GO语言编写,实现管理本地的Chart仓库,可管理Chart,与Tiller服务进行交互,用于发送Chart,实例安装、查询、卸载等操作。 Tiller:服务端,通常运行在K8S集群之上。用于接收helm发来的Charts和Conifg,合并生成release,完成部署。 简单的说:Helm 客户端负责管理 chart;Tiller 服务器负责管理 release。 2、部署Helm helm部署文档 Helm的部署方式有两种:预编译的二进制程序和源码编译安装,这里使用二进制的方式进行安装 (1)下载helm [root@k8s-master ~]# wget https://storage.googleapis.com/kubernetes-helm/helm-v2.9.1-linux-amd64.tar.gz --no-check-certificate [root@k8s-master ~]# tar -xf helm-v2.9.1-linux-amd64.tar.gz [root@k8s-master ~]# cd linux-amd64/ [root@k8s-master linux-amd64]# ls helm LICENSE README.md [root@k8s-master linux-amd64]# mv helm /usr/bin [root@k8s-master linux-amd64]# helm version Client: &version.Version{SemVer:"v2.9.1", GitCommit:"20adb27c7c5868466912eebdf6664e7390ebe710", GitTreeState:"clean"} (2)部署Tiller helm第一次init时,需要链接api-server并进行认证,所以在运行helm时,会去读取kube-config文件,所以必须确认当前用户存在kube-config文件。 ...

September 25, 2018

k8s学习笔记-24-Prometheus监控

[TOC] 1、Prometheus概述 除了前面的资源指标(如CPU、内存)以外,用户或管理员需要了解更多的指标数据,比如Kubernetes指标、容器指标、节点资源指标以及应用程序指标等等。自定义指标API允许请求任意的指标,其指标API的实现要指定相应的后端监视系统。而Prometheus是第一个开发了相应适配器的监控系统。这个适用于Prometheus的Kubernetes Customm Metrics Adapter是属于Github上的k8s-prometheus-adapter项目提供的。其原理图如下: 要知道的是prometheus本身就是一监控系统,也分为server端和agent端,server端从被监控主机获取数据,而agent端需要部署一个node_exporter,主要用于数据采集和暴露节点的数据,那么 在获取Pod级别或者是mysql等多种应用的数据,也是需要部署相关的exporter。我们可以通过PromQL的方式对数据进行查询,但是由于本身prometheus属于第三方的 解决方案,原生的k8s系统并不能对Prometheus的自定义指标进行解析,就需要借助于k8s-prometheus-adapter将这些指标数据查询接口转换为标准的Kubernetes自定义指标。 Prometheus是一个开源的服务监控系统和时序数据库,其提供了通用的数据模型和快捷数据采集、存储和查询接口。它的核心组件Prometheus服务器定期从静态配置的监控目标或者基于服务发现自动配置的目标中进行拉取数据,新拉取到的数据大于配置的内存缓存区时,数据就会持久化到存储设备当中。Prometheus组件架构图如下: 如上图,每个被监控的主机都可以通过专用的exporter程序提供输出监控数据的接口,并等待Prometheus服务器周期性的进行数据抓取。如果存在告警规则,则抓取到数据之后会根据规则进行计算,满足告警条件则会生成告警,并发送到Alertmanager完成告警的汇总和分发。当被监控的目标有主动推送数据的需求时,可以以Pushgateway组件进行接收并临时存储数据,然后等待Prometheus服务器完成数据的采集。 任何被监控的目标都需要事先纳入到监控系统中才能进行时序数据采集、存储、告警和展示,监控目标可以通过配置信息以静态形式指定,也可以让Prometheus通过服务发现的机制进行动态管理。下面是组件的一些解析: 监控代理程序:如node_exporter:收集主机的指标数据,如平均负载、CPU、内存、磁盘、网络等等多个维度的指标数据。 kubelet(cAdvisor):收集容器指标数据,也是K8S的核心指标收集,每个容器的相关指标数据包括:CPU使用率、限额、文件系统读写限额、内存使用率和限额、网络报文发送、接收、丢弃速率等等。 API Server:收集API Server的性能指标数据,包括控制队列的性能、请求速率和延迟时长等等 etcd:收集etcd存储集群的相关指标数据 kube-state-metrics:该组件可以派生出k8s相关的多个指标数据,主要是资源类型相关的计数器和元数据信息,包括制定类型的对象总数、资源限额、容器状态以及Pod资源标签系列等。 Prometheus 能够直接把 Kubernetes API Server作为服务发现系统使用进而动态发现和监控集群中的所有可被监控的对象。这里需要特别说明的是,Pod 资源需要添加下列注解信息才能被Prometheus 系统自动发现并抓取其内建的指标数据。 1) prometheus. io/ scrape: 用于 标识 是否 需要 被 采集 指标 数据, 布尔 型 值, true 或 false。 2) prometheus. io/ path: 抓取 指标 数据 时 使用 的 URL 路径, 一般 为/ metrics。 3) prometheus. io/ port: 抓取 指标 数据 时 使 用的 套 接 字 端口, 如 8080。 另外, 仅 期望 Prometheus 为 后端 生成 自定义 指标 时 仅 部署 Prometheus 服务器 即可, 它 甚至 也不 需要 数据 持久 功能。 但 若要 配置 完整 功能 的 监控 系统, 管理员 还需 要在 每个 主机 上 部署 node_exporter、 按需部署其他特有类型的 exporter 以及Alertmanager。 ...

September 19, 2018

k8s学习笔记-23-资源指标和集群监控

[TOC] 1、资源指标和资源监控 一个集群系统管理离不开监控,同样的Kubernetes也需要根据数据指标来采集相关数据,从而完成对集群系统的监控状况进行监测。这些指标总体上分为两个组成:监控集群本身和监控Pod对象,通常一个集群的衡量性指标包括以下几个部分: 节点资源状态:主要包括网络带宽、磁盘空间、CPU和内存使用率 节点的数量:即时性了解集群的可用节点数量可以为用户计算服务器使用的费用支出提供参考。 运行的Pod对象:正在运行的Pod对象数量可以评估可用节点数量是否足够,以及节点故障时是否能平衡负载。 另一个方面,对Pod资源对象的监控需求大概有以下三类: Kubernetes指标:监测特定应用程序相关的Pod对象的部署过程、副本数量、状态信息、健康状态、网络等等。 容器指标:容器的资源需求、资源限制、CPU、内存、磁盘空间、网络带宽的实际占用情况。 应用程序指标:应用程序自身的内建指标,和业务规则相关 2、Weave Scope监控集群 Weave Scope 是 Docker 和 Kubernetes 可视化监控工具。Scope 提供了至上而下的集群基础设施和应用的完整视图,用户可以轻松对分布式的容器化应用进行实时监控和问题诊断。 对于复杂的应用编排和依赖关系,scope可以使用清晰的图标一览应用状态和拓扑关系。 (1)Weave Scope部署 [root@k8s-master mainfests]# kubectl apply -f "https://cloud.weave.works/k8s/scope.yaml?k8s-version=$(kubectl version | base64 | tr -d '\n')" namespace/weave created #创建名称空间weave,也可以在创建时指定名称空间 serviceaccount/weave-scope created #创建serviceaccount clusterrole.rbac.authorization.k8s.io/weave-scope created clusterrolebinding.rbac.authorization.k8s.io/weave-scope created deployment.apps/weave-scope-app created #创建deployment service/weave-scope-app created #创建service daemonset.extensions/weave-scope-agent created #创建deamonset [root@k8s-master mainfests]# kubectl get ns NAME STATUS AGE default Active 68d ingress-nginx Active 28d kube-public Active 68d kube-system Active 68d weave Active 1m [root@k8s-master mainfests]# kubectl get deployment -n weave NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE weave-scope-app 1 1 1 1 1m [root@k8s-master mainfests]# kubectl get svc -n weave NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE weave-scope-app ClusterIP 10.97.229.215 <none> 80/TCP 33s [root@k8s-master mainfests]# kubectl get pod -n weave NAME READY STATUS RESTARTS AGE weave-scope-agent-5876w 1/1 Running 0 1m weave-scope-agent-d6jgt 1/1 Running 0 1m weave-scope-agent-t9p5g 1/1 Running 0 1m weave-scope-app-578556559-nfxrf 1/1 Running 0 1m DaemonSet weave-scope-agent,集群每个节点上都会运行的 scope agent 程序,负责收集数据。 Deployment weave-scope-app,scope 应用,从 agent 获取数据,通过 Web UI 展示并与用户交互。 Service weave-scope-app,默认是 ClusterIP 类型,为了方便已通过 kubectl edit 修改为 NodePort。 [root@k8s-master mainfests]# kubectl edit svc/weave-scope-app -n weave 将service的type改为NodePort service/weave-scope-app edited [root@k8s-master mainfests]# kubectl get svc -n weave NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE weave-scope-app NodePort 10.97.229.215 <none> 80:32313/TCP 11m (2)使用 Scope 浏览器访问 http://192.168.56.11:32313/,Scope 默认显示当前所有的 Controller(Deployment、DaemonSet 等)。 ...

September 18, 2018

k8s学习笔记-20-K8S组件运行原理详解总结

[TOC] 一、看图说K8S 先从一张大图来观看一下K8S是如何运作的,再具体去细化K8S的概念、组件以及网络模型。 从上图,我们可以看到K8S组件和逻辑及其复杂,但是这并不可怕,我们从宏观上先了解K8S是怎么用的,再进行庖丁解牛。从上图我们可以看出: Kubernetes集群主要由Master和Node两类节点组成 Master的组件包括:apiserver、controller-manager、scheduler和etcd等几个组件,其中apiserver是整个集群的网关。 Node主要由kubelet、kube-proxy、docker引擎等组件组成。kubelet是K8S集群的工作与节点上的代理组件。 一个完整的K8S集群,还包括CoreDNS、Prometheus(或HeapSter)、Dashboard、Ingress Controller等几个附加组件。其中cAdivsor组件作用于各个节点(master和node节点)之上,用于收集及收集容器及节点的CPU、内存以及磁盘资源的利用率指标数据,这些统计数据由Heapster聚合后,可以通过apiserver访问。 要了解K8S的所有组件,没去走一遍,永远不知道它是怎么跑起来的,那么下面就带着几个新手疑问来看K8S 1、K8S是如何对容器编排? 在K8S集群中,容器并非最小的单位,K8S集群中最小的调度单位是Pod,容器则被封装在Pod之中。由此可知,一个容器或多个容器可以同属于在一个Pod之中。 2、Pod是怎么创建出来的? Pod并不是无缘无故跑出来的,它是一个抽象的l逻辑概念,那么Pod是如何创建的呢?Pod是由Pod控制器进行管理控制,其代表性的Pod控制器有Deployment、StatefulSet等。这里我们先有这样的一个概念,后面再详细解刨。 3、Pod资源组成的应用如何提供外部访问的? Pod组成的应用是通过Service这类抽象资源提供内部和外部访问的,但是service的外部访问需要端口的映射,带来的是端口映射的麻烦和操作的繁琐。为此还有一种提供外部访问的资源叫做Ingress。 4、Service又是怎么关联到Pod呢? 在上面说的Pod是由Pod控制器进行管理控制,对Pod资源对象的期望状态进行自动管理。而在Pod控制器是通过一个YAML的文件进行定义Pod资源对象的。在该文件中,还会对Pod资源对象进行打标签,用于Pod的辨识,而Servcie就是通过标签选择器,关联至同一标签类型的Pod资源对象。这样就实现了从service–>pod–>container的一个过程。 5、Pod的怎么创建逻辑流程是怎样的? (1)客户端提交创建请求,可以通过API Server的Restful API,也可以使用kubectl命令行工具。支持的数据类型包括JSON和YAML。 (2)API Server处理用户请求,存储Pod数据到etcd。 (3)调度器通过API Server查看未绑定的Pod。尝试为Pod分配主机。 (4)过滤主机 (调度预选):调度器用一组规则过滤掉不符合要求的主机。比如Pod指定了所需要的资源量,那么可用资源比Pod需要的资源量少的主机会被过滤掉。 (5)主机打分(调度优选):对第一步筛选出的符合要求的主机进行打分,在主机打分阶段,调度器会考虑一些整体优化策略,比如把容一个Replication Controller的副本分布到不同的主机上,使用最低负载的主机等。 (6)选择主机:选择打分最高的主机,进行binding操作,结果存储到etcd中。 (7)kubelet根据调度结果执行Pod创建操作: 绑定成功后,scheduler会调用APIServer的API在etcd中创建一个boundpod对象,描述在一个工作节点上绑定运行的所有pod信息。运行在每个工作节点上的kubelet也会定期与etcd同步boundpod信息,一旦发现应该在该工作节点上运行的boundpod对象没有更新,则调用Docker API创建并启动pod内的容器。 从上面的几个疑问,大致了解了K8S怎么工作的,那么现在再从三个面去了解Kubernetes,分别是Kubernetes概念和术语、集群组件、网络模型。 二、K8S的概念和术语 Kubernetes是利用共享网络将多个物理机或者虚拟机组成一个集群,在各个服务器之间进行通信,该集群是配置Kubernetes的所有租金啊啊、功能和负载的物理平台。 一个Kubernetes集群由master和node组成。如下图: Master:是集群的网关和中枢枢纽,主要作用:暴露API接口,跟踪其他服务器的健康状态、以最优方式调度负载,以及编排其他组件之间的通信。单个的Master节点可以完成所有的功能,但是考虑单点故障的痛点,生产环境中通常要部署多个Master节点,组成Cluster。 Node:是Kubernetes的工作节点,负责接收来自Master的工作指令,并根据指令相应地创建和销毁Pod对象,以及调整网络规则进行合理路由和流量转发。生产环境中,Node节点可以有N个。 Kubernetes从宏观上看分为2个角色:Master和Node,但是在Master节点和Node节点上都存在着多个组件来支持内部的业务逻辑,其包括:运行应用、应用编排、服务暴露、应用恢复等等,在Kubernetes中这些概念被抽象为Pod、Service、Controller等资源类型。先来了解一下这些常用概念和术语: (1)Pod 从上图,我们可以看到K8S并不直接地运行容器,而是被一个抽象的资源对象–Pod所封装,它是K8S最小的调度单位。这里要注意的是,Pod可以封装一个活多个容器!同一个Pod中共享网络名称空间和存储资源,而容器之间可以通过本地回环接口:lo 直接通信,但是彼此之间又在Mount、User和Pid等名称空间上保持了隔离。 (2)资源标签(Label) 标签(Label)是将资源进行分类的标识符,就好像超市的商品分类一般。资源标签具体化的就是一个键值型(key/values)数据,相信了解redis的友友应该知道什么是键值数据。使用标签是为了对指定对象进行辨识,比如Pod对象。标签可以在对象创建时进行附加,也可以创建后进行添加或修改。要知道的是一个对象可以有多个标签,一个标签页可以附加到多个对象。如图: (3)标签选择器(Selector) 有标签,当然就有标签选择器,它是根据Label进行过滤符合条件的资源对象的一种 机制。比如将含有标签role: backend的所有Pod对象挑选出来归并为一组。通常在使用过程中,会通过标签对资源对象进行分类,然后再通过标签选择器进行筛选,最常见的应用就是讲一组这样的Pod资源对象创建为某个Service的端点。如图: (4)Pod控制器(Controller) 虽然Pod是K8S的最小调度单位,但是K8S并不会直接地部署和管理Pod对象,而是要借助于另外一个抽象资源–Controller进行管理。其实一种管理Pod生命周期的资源抽象,并且它是一类对象,并非单个的资源对象,其中包括:ReplicationController、ReplicaSet、Deployment、StatefulSet、Job等。 以Deployment为例,它负责确保定义的Pod对象的副本数量符合预期的设置,这样用户只需要声明应用的期望状态,控制器就会自动地对其进行管理。如图: (5)服务资源(Service) Service是建立在一组Pod对象之上的资源对象,在前面提过,它是通过标签选择器选择一组Pod对象,并为这组Pod对象定义一个统一的固定访问入口(通常是一个IP地址),如果K8S存在DNS附件(如coredns)它就会在Service创建时为它自动配置一个DNS名称,用于客户端进行服务发现。 通常我们直接请求Service IP,该请求就会被负载均衡到后端的端点,即各个Pod对象,从这点上,是不是有点像负载均衡器呢,因此Service本质上是一个4层的代理服务,另外Service还可以将集群外部流量引入至集群,这就需要节点对Service的端口进行映射了。 (6)存储卷(Volume) 在使用容器时,我们知道,当数据存放于容器之中,容器销毁后,数据也会随之丢失。这就是需要一个外部存储,以保证数据的持久化存储。而存储卷就是这样的一个东西。 存储卷(Volume)是独立于容器文件系统之外的存储空间,常用于扩展容器的存储空间并为其提供持久存储能力。存储卷在K8S中的分类为:临时卷、本地卷和网络卷。临时卷和本地卷都位于Node本地,一旦Pod被调度至其他Node节点,此类型的存储卷将无法被访问,因为临时卷和本地卷通常用于数据缓存,持久化的数据通常放置于持久卷(persistent volume)之中。 (7)Name和Namespace 名称(Name)是K8S集群中资源对象的标识符,通常作用于名称空间(Namespace),因此名称空间是名称的额外的限定机制。在同一个名称空间中,同一类型资源对象的名称必须具有唯一性。 ...

September 15, 2018

k8s学习笔记-22-Pod资源调度

[TOC] API Server在接受客户端提交Pod对象创建请求后,然后是通过调度器(kube-schedule)从集群中选择一个可用的最佳节点来创建并运行Pod。而这一个创建Pod对象,在调度的过程当中有3个阶段:节点预选、节点优选、节点选定,从而筛选出最佳的节点。如图: 节点预选:基于一系列的预选规则对每个节点进行检查,将那些不符合条件的节点过滤,从而完成节点的预选 节点优选:对预选出的节点进行优先级排序,以便选出最合适运行Pod对象的节点 节点选定:从优先级排序结果中挑选出优先级最高的节点运行Pod,当这类节点多于1个时,则进行随机选择 当我们有需求要将某些Pod资源运行在特定的节点上时,我们可以通过组合节点标签,以及Pod标签或标签选择器来匹配特定的预选策略并完成调度,如MatchInterPodAfinity、MatchNodeSelector、PodToleratesNodeTaints等预选策略,这些策略常用于为用户提供自定义Pod亲和性或反亲和性、节点亲和性以及基于污点及容忍度的调度机制。 1、常用的预选策略 预选策略实际上就是节点过滤器,例如节点标签必须能够匹配到Pod资源的标签选择器(MatchNodeSelector实现的规则),以及Pod容器的资源请求量不能大于节点上剩余的可分配资源(PodFitsResource规则)等等。执行预选操作,调度器会逐一根据规则进行筛选,如果预选没能选定一个合适的节点,此时Pod会一直处于Pending状态,直到有一个可用节点完成调度。其常用的预选策略如下: CheckNodeCondition:检查是否可以在节点报告磁盘、网络不可用或未准备好的情况下将Pod对象调度其上。 HostName:如果Pod对象拥有spec.hostname属性,则检查节点名称字符串是否和该属性值匹配。 PodFitsHostPorts:如果Pod对象定义了ports.hostPort属性,则检查Pod指定的端口是否已经被节点上的其他容器或服务占用。 MatchNodeSelector:如果Pod对象定义了spec.nodeSelector属性,则检查节点标签是否和该属性匹配。 NoDiskConflict:检查Pod对象请求的存储卷在该节点上可用。 PodFitsResources:检查节点上的资源(CPU、内存)可用性是否满足Pod对象的运行需求。 PodToleratesNodeTaints:如果Pod对象中定义了spec.tolerations属性,则需要检查该属性值是否可以接纳节点定义的污点(taints)。 PodToleratesNodeNoExecuteTaints:如果Pod对象定义了spec.tolerations属性,检查该属性是否接纳节点的NoExecute类型的污点。 CheckNodeLabelPresence:仅检查节点上指定的所有标签的存在性,要检查的标签以及其可否存在取决于用户的定义。 CheckServiceAffinity:根据当前Pod对象所属的Service已有其他Pod对象所运行的节点调度,目前是将相同的Service的Pod对象放在同一个或同一类节点上。 MaxEBSVolumeCount:检查节点上是否已挂载EBS存储卷数量是否超过了设置的最大值,默认值:39 MaxGCEPDVolumeCount:检查节点上已挂载的GCE PD存储卷是否超过了设置的最大值,默认值:16 MaxAzureDiskVolumeCount:检查节点上已挂载的Azure Disk存储卷数量是否超过了设置的最大值,默认值:16 CheckVolumeBinding:检查节点上已绑定和未绑定的PVC是否满足Pod对象的存储卷需求。 NoVolumeZoneConflct:在给定了区域限制的前提下,检查在该节点上部署Pod对象是否存在存储卷冲突。 CheckNodeMemoryPressure:在给定了节点已经上报了存在内存资源压力过大的状态,则需要检查该Pod是否可以调度到该节点上。 CheckNodePIDPressure:如果给定的节点已经报告了存在PID资源压力过大的状态,则需要检查该Pod是否可以调度到该节点上。 CheckNodeDiskPressure:如果给定的节点存在磁盘资源压力过大,则检查该Pod对象是否可以调度到该节点上。 MatchInterPodAffinity:检查给定的节点能否可以满足Pod对象的亲和性和反亲和性条件,用来实现Pod亲和性调度或反亲和性调度。 在上面的这些预选策略里面,CheckNodeLabelPressure和CheckServiceAffinity可以在预选过程中结合用户自定义调度逻辑,这些策略叫做可配置策略。其他不接受参数进行自定义配置的称为静态策略。 2、优选函数 预选策略筛选出一个节点列表就会进入优选阶段,在这个过程调度器会向每个通过预选的节点传递一系列的优选函数来计算其优先级分值,优先级分值介于0-10之间,其中0表示不适用,10表示最适合托管该Pod对象。 另外,调度器还支持给每个优选函数指定一个简单的值,表示权重,进行节点优先级分值计算时,它首先将每个优选函数的计算得分乘以权重,然后再将所有优选函数的得分相加,从而得出节点的最终优先级分值。权重可以让管理员定义优选函数倾向性的能力,其计算优先级的得分公式如下: finalScoreNode = (weight1 * priorityFunc1) + (weight2 * priorityFunc2) + ...... 下图是关于优选函数的列表图: 3、节点亲和调度 节点亲和性是用来确定Pod对象调度到哪一个节点的规则,这些规则基于节点上的自定义标签和Pod对象上指定的标签选择器进行定义。 定义节点亲和性规则有2种:硬亲和性(require)和软亲和性(preferred) 硬亲和性:实现的是强制性规则,是Pod调度时必须满足的规则,否则Pod对象的状态会一直是Pending 软亲和性:实现的是一种柔性调度限制,在Pod调度时可以尽量满足其规则,在无法满足规则时,可以调度到一个不匹配规则的节点之上。 定义节点亲和规则的两个要点:一是节点配置是否合乎需求的标签,而是Pod对象定义合理的标签选择器,这样才能够基于标签选择出期望的目标节点。 需要注意的是preferredDuringSchedulingIgnoredDuringExecution和requiredDuringSchedulingIgnoredDuringExecution名字中后半段字符串IgnoredDuringExecution表示的是,在Pod资源基于节点亲和性规则调度到某个节点之后,如果节点的标签发生了改变,调度器不会讲Pod对象从该节点上移除,因为该规则仅对新建的Pod对象有效。 3.1、节点硬亲和性 下面的配置清单中定义的Pod对象,使用节点硬亲和性和规则定义将当前Pod调度到标签为zone=foo的节点上: apiVersion: v1 kind: Pod metadata: name: with-require-nodeaffinity spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - {key: zone,operator: In,values: ["foo"]} containers: - name: myapp image: ikubernetes/myapp:v1 #创建Pod对象 [root@k8s-master ~]# kubectl apply -f require-nodeAffinity-pod.yaml pod/with-require-nodeaffinity created #由于集群中并没有节点含有节点标签为zone=foo,所以创建的Pod一直处于Pending状态 [root@k8s-master ~]# kubectl get pods with-require-nodeaffinity NAME READY STATUS RESTARTS AGE with-require-nodeaffinity 0/1 Pending 0 35s #查看Pending具体的原因 [root@k8s-master ~]# kubectl describe pods with-require-nodeaffinity ...... Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 3s (x21 over 1m) default-scheduler 0/3 nodes are available: 3 node(s) didn't match node selector. #给node01节点打上zone=foo的标签,可以看到成功调度到node01节点上 [root@k8s-master ~]# kubectl label node k8s-node01 zone=foo node/k8s-node01 labeled [root@k8s-master ~]# kubectl describe pods with-require-nodeaffinity Events: Type Reason Age From Message ---- ------ ---- ---- ------- Warning FailedScheduling 58s (x25 over 2m) default-scheduler 0/3 nodes are available: 3 node(s) didn't match node selector. Normal Pulled 4s kubelet, k8s-node01 Container image "ikubernetes/myapp:v1" already present on machine Normal Created 4s kubelet, k8s-node01 Created container Normal Started 4s kubelet, k8s-node01 Started container [root@k8s-master ~]# kubectl get pods with-require-nodeaffinity -o wide NAME READY STATUS RESTARTS AGE IP NODE with-require-nodeaffinity 1/1 Running 0 6m 10.244.1.12 k8s-node01 在定义节点亲和性时,requiredDuringSchedulingIgnoredDuringExecution字段的值是一个对象列表,用于定义节点硬亲和性,它可以由一个或多个nodeSelectorTerms定义的对象组成,此时值需要满足其中一个nodeSelectorTerms即可。 ...

September 15, 2018

k8s学习笔记-21-k8s的网络模型和网络策略

[TOC] 1、Kubernetes网络模型和CNI插件 在Kubernetes中设计了一种网络模型,要求无论容器运行在集群中的哪个节点,所有容器都能通过一个扁平的网络平面进行通信,即在同一IP网络中。需要注意的是:在K8S集群中,IP地址分配是以Pod对象为单位,而非容器,同一Pod内的所有容器共享同一网络名称空间。 1.1、Docker网络模型 了解Docker的友友们都应该清楚,Docker容器的原生网络模型主要有3种:Bridge(桥接)、Host(主机)、none。 Bridge:借助虚拟网桥设备为容器建立网络连接。 Host:设置容器直接共享当前节点主机的网络名称空间。 none:多个容器共享同一个网络名称空间。 #使用以下命令查看docker原生的三种网络 [root@localhost ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 0efec019c899 bridge bridge local 40add8bb5f07 host host local ad94f0b1cca6 none null local #none网络,在该网络下的容器仅有lo网卡,属于封闭式网络,通常用于对安全性要求较高并且不需要联网的应用 [root@localhost ~]# docker run -it --network=none busybox / # ifconfig lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 UP LOOPBACK RUNNING MTU:65536 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:0 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) #host网络,共享宿主机的网络名称空间,容器网络配置和host一致,但是存在端口冲突的问题 [root@localhost ~]# docker run -it --network=host busybox / # ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000 link/ether 00:0c:29:69:a7:23 brd ff:ff:ff:ff:ff:ff inet 192.168.1.4/24 brd 192.168.1.255 scope global dynamic eth0 valid_lft 84129sec preferred_lft 84129sec inet6 fe80::20c:29ff:fe69:a723/64 scope link valid_lft forever preferred_lft forever 3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue link/ether 02:42:29:09:8f:dd brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 valid_lft forever preferred_lft forever inet6 fe80::42:29ff:fe09:8fdd/64 scope link valid_lft forever preferred_lft forever / # hostname localhost #bridge网络,Docker安装完成时会创建一个名为docker0的linux bridge,不指定网络时,创建的网络默认为桥接网络,都会桥接到docker0上。 [root@localhost ~]# brctl show bridge name bridge id STP enabled interfaces docker0 8000.024229098fdd no [root@localhost ~]# docker run -d nginx #运行一个nginx容器 c760a1b6c9891c02c992972d10a99639d4816c4160d633f1c5076292855bbf2b [root@localhost ~]# brctl show bridge name bridge id STP enabled interfaces docker0 8000.024229098fdd no veth3f1b114 一个新的网络接口veth3f1b114桥接到了docker0上,veth3f1b114就是新创建的容器的虚拟网卡。进入容器查看其网络配置: [root@localhost ~]# docker exec -it c760a1b6c98 bash root@c760a1b6c989:/# apt-get update root@c760a1b6c989:/# apt-get iproute root@c760a1b6c989:/# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 38: eth0@if39: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0 valid_lft forever preferred_lft forever 从上可以看到容器内有一个网卡eth0@if39,实际上eth0@if39和veth3f1b114是一对veth pair。veth pair是一种成对出现的特殊网络设备,可以想象它们由一根虚拟的网线进行连接的一对网卡,eth0@if39在容器中,veth3f1b114挂在网桥docker0上,最终的效果就是eth0@if39也挂在了docker0上。 ...

September 12, 2018