xr20230518

虚拟机

KVM集成到Linux内核的虚拟机技术

vmware workstaion 给本地虚拟机开发用的

exsi 服务端的需求化技术 生产

xen

容器

Docker

podman

containerd

..

容器:轻量级虚拟机,隔离,

虚拟机提供的功能,容器同样具备

相同

资源隔离

独立的操作的系统,提供隔离的核心是模拟器,而容器的核心是namespace+cgroup

不同

底层的实现技术不一样,虚拟机的核心是模拟器,而容器的核心是namespace+cgroup

虚拟机的宿主机可以不要OS,但容器的宿主机必须有OS,因为对于虚拟机而言,自身有一个完整的操作系统,hypervisor可以直接安装在宿主机上,宿主机不需要有其他的操作系统,典型的是exsi,直接运行在宿主机之上,是一个hypervisor管理器,而不是操作系统,出来的目的是只需要运行虚拟机就行

容器的宿主机必须要有操作系统,docker容器的管理器是软件,软件需要运行在宿主机之上,

虚拟机不需要依赖于操作系统,但是主流的虚拟机也都安装操作系统,KVM直接集成在Linux内核里,vmware workstation客户端直接运行在Windows、macos操作系统之上

exsi是一个独立的hypervisor,可以直接装的

xen不依赖于操作系统,只需要内核,要对内核做修改,

KVM底层是一个操作系统(做了裁剪的),

红帽开源的openstack,底层是一个正常的Linux

虚拟机通过模拟器在真实的硬件上模拟硬件

容器没有模拟硬件

容器没有模拟器,要在宿主机上安装容器的管理软件,不需要在底层模拟硬件,直接将容器创建在硬件之上,不需要模拟硬件之上

容器可以使用全部的32核128G内存,

虚拟机:调用hypervisor创建虚拟机,hypervisor模拟硬件,在其上完成虚拟机创建

容器:docker属于软件,软件帮助创建一个容器,容器会直接运行在宿主机上,而不是运行在有hypervisor接管的模拟器的硬件之上,直接运行在宿主机上。

由于没有模拟硬件,启动多个容器,容器间的隔离性不好

对于虚拟机可以不要OS

要在宿主机上运行虚拟机,要先在宿主机上安装hypervisor监视器(monitor 模拟器),hypervisor监视器在底层模拟硬件,也就是一个模拟器模拟硬件,虚拟化4核8G的资源,在其上安装操作系统,独立的虚拟机对外提供服务

多个容器运行直接运行在宿主机之上,没有hypervisor,docker管理器只负责调用宿主机,让宿主机创建容器

概述

Kubernetes是一个可移植、可扩展的开源平台,用于管理容器化的负载和服务,可促进声明式配置和自动化。Kubernetes拥有一个庞大且快速增长的生态,其服务、支持和工具的使用范围相当广泛。

Kubernetes这个名字源于希腊语,一意为“舵手”或“飞行员”。k8s这个缩写是因为k和s之间有八个字符的关系。Google在2014年开源了Kubernetes项目。Kubernetes建立在Google大规模运行生产工作负载十几年经验的基础上,结合了社区中最优秀的想法和实践。

时光回溯

传统部署时代:

早期,各个组织是在物理服务器上运行应用程序。由于无法限制在物理服务器中运行的应用程序资源使用,因此会导致资源分配问题。例如,如果在同一台物理服务器上运行多个应用程序,则可能会出现一个应用程序占用大部分资源的情况,而导致其他应用程序的性能下降。一种解决方案是将每个应用程序运行在不同的物理服务器上,但是当某个应用程序资源利用率不高时,剩余资源无法被分配给其他应用程序,而且维护许多物理服务器的成本很高。

虚拟化部署时代:

因此,虚拟化技术被引用了。虚拟化技术允许在单个物理服务器的CPU上运行多台虚拟机(VM)。虚拟化能使应用程序在不同VM之间被彼此隔离,且能提供一定程度的安全性,因为一个应用程序的信息不能被另一个应用程序随意访问。

虚拟化技术能够更好地利用物理服务器的资源,并且因为可轻松地添加或更新应用程序,而因此可以具有更高的可扩展性,以及降低硬件陈本等等的好处。通过虚拟化,可以将一组物理资源呈现为可丢弃的虚拟机集群。

每个VM是一台完整的计算机,在虚拟化硬件之上运行所有组件,包括其自己的操作系统。

容器部署时代:

容器类似于VM,但是更宽松的隔离特性,使容器之间可以共享操作系统(OS)。因此,容器比起VM被认为是更轻量级的。且与VM类似,每个容器都具有自己的文件系统、CPU、内存、进程空间等。由于他们与基础架构分离,因此可以跨云和OS发行版本进行移植。

容器因具有许多优势而变得流行起来,例如:

敏捷应用程序的创建和部署:与使用VM镜像相比,提高了容器镜像创建的简便性和效率。

持续开发、集成和部署:通过快速简单的回滚(由于镜像不可变性),提供可靠且频繁的容器镜像构建和部署。

关注开发与运维的分离:在构建、发布时创建应用程序容器镜像,而不是在部署时,从而将应用程序与基础架构分离。

可观察性:不仅可以显示OS级别的信息和指标,还可以显示应用程序的运行状况和其他指标信号。

跨开发、测试和生产的环境一致性:在笔记本吉萨孙继上也可以和在云中运行一样的程序。

跨云和操作系统发行版本的可移植性:可在Ubuntu、RHEL、CoreOS、本地、Google Kubernetes Engine和其他任何地方运行。

以应用程序为中心的管理:提高抽象级别,从在虚拟硬件上运行OS到使用逻辑资源在OS上运行应用程序。

松散耦合、分布式、弹性、解放的微服务:应用程序被分解成较小的独立部分,并且可以动态部署和管理-而不是在一台大型单机上整体运行。

资源隔离:可预测的应用程序性能。

资源利用:高效率和高密度。

为什么需要Kubernetes,它能做什么?

容器是打包和运行应用程序的好方式。在生产环境中,需要管理运行着应用程序的容器, 并确保服务不会下线。例如,如果一个容器发生故障,则需要启动另一个容器。如果此行为交给系统处理,是不是会更容易一些?

这就是Kubernetes要来做的事情!Kubernetes提供了一个可弹性运行分布式系统的框架。Kubernetes会满足扩展要求、故障转移应用、提供部署模式等。例如,Kubernetes可以轻松管理系统的Canary(金丝雀)部署。

Kubernetes提供:

服务发现和负载均衡

Kubernetes可以使用DNS名称或自己的IP地址来暴露部署。如果进入容器的流量很大,Kubernetes可以负载均衡并分配网络资源,从而使部署稳定。

存储编排

Kubernetes允许自动挂载选择的存储系统,例如本地存储、公共云提供商等。

自动部署和回滚

可以使用Kubernetes描述已部署容器的所需状态,它可以以受控的速率将实际状态更改为期望状态。例如:可以自动化Kubernetes来为部署创建新容器,删除现有容器并将他们的所有资源用于新容器。

自动完成装箱计算

为Kubernetes提供许多节点组成的集群,在这个集群上运行容器化的任务。告诉Kubernetes每个容器需要多少CPU和内存(RAM)。Kubernetes可以将这些容器按实际情况调度到节点上,以最佳方式利用资源。

自我修复

Kubernetes将重新启动失败的容器、替换容器、杀死不响应用户定义的运行状况检查的容器,并且在准备好服务之前不将其通告给客户端。

密钥与配置管理

Kubernetes允许存储和管理敏感信息,例如密码、OAuth令牌和ssh密钥。可以在不重建容器镜像的情况下部署和更新密钥和应用程序配置,也无需在堆栈配置中暴露密钥。

Kubernetes不是什么

Kubernetes不是传统的、包罗万象的PaaS(平台及服务)系统。由于Kubernetes是在容器级别运行,而非在硬件级别,提供了PaaS产品共有的一些普遍适用的功能,例如部署、扩展、负载均衡,允许用户集成他们的日志记录、监控和警报方案。但是,Kubernetes不是单体式(monolithic)系统,那些默认解决方案都是可选的、可插拔的。Kuburnetes为构建开发人员平台提供了基础,但是在重要的地方保留了用户的选择权,能有更高的灵活性。

Kubernetes:

不限制支持的应用程序类型。Kubernetes旨在支持极其多种多样的工作负载,包括无状态、有状态和数据处理工作负载。如果应用程序可以在容器中运行,那么它应该可以在Kubernetes上很好的运行。

不部署源代码,也不构建应用程序。持续集成(CI)、交付和部署(CI/CD)工作流取决于组织的文化和偏好以及技术要求。

不提供应用程序级别的服务作为内置服务,例如中间件(例如消息中间件)、数据处理框架(例如Spark)、数据库(例如MySQL)、缓存、集群存储系统(例如Ceph)。这样的组件可以在Kubernetes上运行,并且/或者可以由运行在Kubernetes上的应用程序通过可移植性机制(例如开放服务代理)来访问。

不是日志记录、监视或警报的解决方案。它集成了一些功能作为概念证明,并提供了收集和导出指标的机制。

不提供也不要求配置用的语言、系统(例如jsonnet),它提供了声明性API,该声明性API可以由任意形式的生命规范所构成。

不提供也不采用任何全面的机器配置、维护、管理或自我修复系统。

此外,Kubernetes不仅仅是一个编排系统,实际上它消除了编排的需要。编排的技术定义是执行已定义的工作流程:首先执行A,然后执行B,再执行C。而Kubernetes包含了一组独立可组合的控制过程,可以持续地将当前状态驱动到所提供的与其状态。不需要在乎如何从A移动到C,也不需要集中控制,这使得系统更易于使用且功能更强大、系统更健壮,更为弹性和扩展。

20230517

3.1.1_搭建k8s集群-kubeadm搭建:初始化master节点_bilibili_哔哩哔哩_bilibili

1 核心概念篇

1.1 认识Kubernetes

1.1.1 什么是Kubernetes

Kubernetes是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署化的应用简单并且高效(powerful),Kubernetes提供了应用部署,规划,更新,维护的一种机制。

kubernetes这个名字源于希腊语,意为“舵手”或“飞行员”。k8s这个缩写是因为k和s之间有八个字符的关系。Google在2014年开源了Kubernetes项目。Kubernetes建立在Google大规模运行生产工作负载十几年经验的基础上,结合了社区中最优秀的想法和实践。

1.1.2 为什么需要Kubernetes

1.1.2.1 应用部署的三大阶段

1.1.2.1.1 传统部署

程序员/运维工程师手动操作部署应用,直接将应用部署在目标机器上,由于资源不隔离,容易出现资源争抢、依赖冲突等各方面问题。

1.1.2.1.2 虚拟化部署

利用OpenStask/VMware等虚拟化技术,将一台目标机器虚拟化为多个虚拟机器,按照要求将应用部署到不同的虚拟机中,对虚拟机进行动态的水平扩容等管理操作。

相对传统部署自动化、资源隔离的能力了提升了,带来的问题是虚拟化的逻辑过重,导致效率不高,且稿费资源较多。

1.1.2.1.3 容器化部署

可以理解为轻量级的虚拟化,完美弥补虚拟化技术过重的问题,且由于直接共享主机硬件资源,只是通过系统提供的命令空间等技术实现资源隔离,损耗更小,且效率更高。

1.1.2.2 k8s的特点

自我修复

弹性伸缩

自动部署和回滚

服务发现和负载均衡

机密和配置管理

存储编排

批处理

1.1.3 企业级容器调度平台

1.1.3.1 Apache Mesos

1.1.3.1.1 基本概念

Mesos是一个分布式调度系统内核,早于Docker产生,Mesos作为资源管理器,从DC/OS(数据中心操作系统)的角度提供资源视图。主/从结构工作模式,主节点分配任务,并用从节点上的Executor负责执行,通过Zookeper给主节点提供服务注册、服务发现功能。通过Zookeper Marathon提供容器调度的能力。

1.1.3.1.2 优势

经过时间的检验,作为资源管理器的Apache Mesos在容器之前就已经出现很久了,支持运行容器优化和非容器优化的工作负载。可以支持应用程序的健康检查,开放的架构。支持多个框架和多个调度器,通过不同的framework可以运行Haddop/Spark/MPI等多种不同的任务。

支持超大型规模的节点管理,模拟测试支持超过5w+节点,在大规模上拥有较大优势。

1.1.3.2 Docker Swarm

1.1.3.2.1 基本概念

Docker Swarm是一个由Docker开发的调度框架。由Docker自身开发的好处之一就是标准Docker API的使用,Swarm由多个代理(Agent)组成,把这些代理称之为节点(Node)。这些节点就是主机,这些主机在启动Docker Daemon的时候就会打开相应的端口,以此支持Docker远程API。这些机器会根据Swarm调度器分配给他们的任务,拉取和运行不同的镜像。

1.1.3.2.2 优势

从Docker1.12版本开始,Swarm随Docker一起默认安装发布。由于随Docker引擎一起发布,无需额外安装,配置简单。支持服务注册、服务发现,内置Overlay Network以及Load Balance。与Docker CLI非常类似的操作命令,对熟悉Docker的人非常容易上手学习。

入门门槛、学习成本低,使用更便捷,适用于中小型系统。

1.1.3.3 Google Kubernetes

1.1.3.3.1 基本概念

Kubernetes是基于Google在过去十五年来大量生产环境中运行工作负载的经验。Kubernetes的实现参考了Google内部的资源调度框架,但并不是Borg的内部容器编排系统的开源,而是借鉴Google从运行Borg获得的经验教训,形成了Kubernetes项目。

它使用Label和Pod的概念来将容器划分为逻辑单元。Pods是同地协作(co-located)容器的集合,这些容器被共同部署和调度,形成了一个服务,这是Kubernetes和其他两个框架的主要区别。相比于基于相似度的容器调度方式(就像Swarm和Mesos),这个方法简化了对集群的管理。

1.1.3.3.2 优势

最流行的容器编排解决方案框架,基于Google庞大的生态圈及社区产生的产品。通过Pods这一抽象的概念,解决Container之间的依赖于通信问题。Pods,Service,Deployments是独立部署的部分,可以通过Selector提供更多的灵活性。内置服务注册和负载平衡。

适用度更广,功能更强大,相较于Mesos来说节点规模更小。

1.2 集群架构与组件

1.2.1 相关组件

1.2.1.1 控制面板组件(Master)

1.2.1.1.1 kube-apiserver

API服务器是Kubernetes控制平台的组件,该组件负责公开了Kubernetes API,负责处理接受请求的工作。API服务器是Kubernetes控制平面的前端。

Kubernetes服务器的主要实现是kube-apiserver。kube-server设计上考虑了水平扩缩,也就是说,它可以通过部署多个实例来进行扩缩。可以运行kube-apiserver的多个实例,并在这些实例之间平衡流量。

1.2.1.1.2 kube-controller-manager

kube-contriller-manager是控制平面的组件,负责运行控制器进程。

从逻辑上讲,每个控制器都是一个单独的进程,但是为了降低复杂性,他们都被编译到同一个可执行文件,并在同一个进程中运行。

这些控制器包括:

节点控制器(Node Controller):负责在节点出现故障时进行通知和响应

任务控制器(Job Controller):监控代表一次性任务的Job对象,然后创建Pods来运行这些任务直至完成

端点分片控制器(EndpointSlicecontroller):填充端点分片(EndpointSlice)对象(以提供Service和Pod之间的链接)。

服务账号控制器(ServiceAccount Controller):为新的命名空间创建默认的服务账号(ServiceAccount)。

1.2.1.1.3 cloud-controller-manager

嵌入了特定于云平台的控制逻辑。云控制器管理器(Cloud Controller Manager

)允许讲集群连接到云服务提供商的API之上,并讲于该云平台交互的组件同与你的集交互的组件分离开来。

cloud-controller-manager仅运行特定于云平台的控制器。因此如果在自己的环境中Kubernetes,或者在本地计算机中运行学习环境,所部署的集群不需要有云控制器管理器。

与kube-controller-manager类似,cloud-controller-manager讲若干逻辑上独立的控制回路组合到同一个可以执行文件中,供以同一进程的方式运行。可以对其之水平扩容(运行不止一个副本)以提升性能或者增强容错能力。

1.2.1.1.4 kube-scheduler

scheduler负责资源的调度,按照预定的调度策略将Pod调度到响应的机器上。

1.2.1.1.5 etcd

一致且高度可用的键值存储,用作Kubernetes的所有集群数据的后台数据库。

如果Kubernetes集群使用etcd作为其后台数据库,请确保针对这些数据有一份备份计划。

可以在官方文档中找到有关etcd的深入知识。

早期数据存放在内存,现在已经是持久化存储的了。

1.2.1.2 节点组件

1.2.1.2.1 kubelet

kubelet负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理。

1.2.1.2.2 kube-proxy

kube-proxy负责为Service提供cluster内部的服务发现和负载均衡。

1.2.1.2.3 container runtime

Container runtime负责镜像管理以及Pod和容器的真正运行(CRI)。

Kubernetes支持许多容器运行环境,例如:containerd、CRI-O以及Kubernetes CRI(容器运行环境接口)的其他任何实现。

1.2.1.3 附加组件

1.2.1.3.1 kube-dns

kube-dns为整个集群提供DNS服务。

1.2.1.3..2 Ingress Controller

Ingress Controller为服务提供外网入口。

1.2.1.3.3 Prometheus

Prometheus提供资源监控。

1.2.1.3.4 Dashboard

Dashboard提供GUI。

1.2.1.3.5 Federation

Federation提供跨可用区的集群。

1.2.1.3.6 Fluentd-elasticsearch

Fluentd-Elasticsearch提供集群日志采集、存储与查询。

1.2.2 分层架构

1.2.2.1 生态系统

在接口层之上的庞大容器集群管理调度的生态系统,可以划分为两个范畴:

Kubernetes外部:日志、监控、配置管理、CL、CD、Workflow、FaaS、OTS应用、ChatOps等

Kubernetes内部:CRI、CNI、CVI、镜像仓库、Cloud Provider、集群自身的配置和管理等。

1.2.2.2 接口层

kubectl命令行工具、客户端SDK以及集群联邦。

1.2.2.3 管理层

系统度量(如基础设施、容器和网络的度量),自动化(如自动扩展、动态Provision等)以及策略管理(RBAC、Quota、PSP、NetworkPolicy等)。

1.2.2.4 应用层

部署(无状态应用、有状态应用、批处理任务、集群应用等)和路由(服务发现、DNS解析等)。

1.2.2.5 核心层

Kubernetes最核心的功能,对外提供API构建高层的应用,对内提供插件式应用执行环境。

1.3 核心概念与专业术语

1.3.1 服务的分类

1.3.1.1 无状态

需要在服务运行环境下存储数据的服务。

1.3.1.1.1 代表应用

Nginx

Apache

1.3.1.1.2 优点

对客服端透明,无依赖关系,可以高效实现扩容、迁移。

1.3.1.1.3 缺点

不能存储数据,需要额外的数据服务支撑。

1.3.1.2 有状态

1.3.1.2.1 代表应用

MySQL

Redis

1.3.1.2.2 优点

可以独立存储数据,实现数据管理。

1.3.1.2.3 缺点

集群环境下需要实现主从、数据同步、备份、水平扩容复杂。

1.3.2 资源和对象

Kubernetes中的所有内容都被抽象为“资源”,如Pod、Service、Node等都是资源。“对象”就是“资源”的实例,是持久化的实体。如某个具体的Pod、某个具体的Node。Kubernetes使用这些实体去表示整个集群的状态。

对象的拆功能键、删除、修改都是通过“Kuberneres API”组件提供的API接口,这些是RESTful风格的Api,与k8s的“万物皆对象”理念相符。命令行工具“kubectl”,实际上也是调用kubernetes api。

K8s中的资源类别有很多中,kubectl可以通过配置文件来创建这些“对象”,配置文件更像是描述对象“属性”的文件,配置文件格式可以是“JSON”或“YAML”,常用“YAML”。

1.3.2.1 资源的分类

1.3.2.1.1 元数据型

1.3.2.1.1.1 Horizontal Pod Autoscaler(HPA)

Pod自动扩容:可以根据CPU使用率或自定义指标(metrics)自动对Pod进行扩/缩容。

控制管理器每隔30s(可以通过-horizontal-pod-autoscaler-sync-period修改)查询metrics的资源使用情况。

支持三种类型

预定义metrics(比如Pod的CPU)以利用率的方式计算。

自定义的Pod metrics,以原始值(rao value)的方式计算。

自定义的object metrics

支持两种metrics查询方式:Heapster和自定义的TEST API支持多metrics

1.3.2.1.1.2 PodTemplate

Pod Templete是关于Pod的定义,但是被包含在其他的Kubernetes对象中(例如Deployment、StatefulSet、DaemonSet等控制器)。控制器通过Pod Templete信息来创建Pod。

1.3.2.1.1.3 LimitRange

可以对集群内Request和Limits的配置做一个全局的统一的限制,相当于批量设置了某一个范围内(某个命名空间)的Pod的资源使用限制。

1.3.2.1.2 集群级

1.3.2.1.2.1 Namespace

Kubernetes支持多个虚拟集群,它们底层依赖于同一个物理集群,这些虚拟集群被称为命名空间。

作用是用于多团队/环境的资源隔离。

命名空间namespace是k8s集群级别的资源,可以给不同的用户、租户、环境或项目创建对应的命名空间。

默认namespace:

kube-system主要用于运行系统级别资源,存放k8s自身的组件

kube-public比命名空间是自动创建的,并且可供所有用户(包括未经过身份验证的用户)读取。此命名空间主要用于集群使用,关联的一些资源在集群中是可见的并且可以公开读取。此命名空间的公共方面知识一个约定,但不是非要这么要求。

default未指定名称空间的资源就是default,即在创建pod时如果没有指定namespace,则会默认使用default。

1.3.2.1.2.2 Node

不像其他的资源(如Pod和Namespace),Node本质上不是Kubernetes来创建的,Kubernetes只是管理Node上的资源。虽然可以通过Manifest创建一个Node对象(如下json所示),但Kubernetes也只是去检查是否真的有这么一个Node,如果检查失败,也不会往上调度Pod。

1.3.2.1.2.3 ClusterRole

ClusterRole是一组权限的集合,但与Role不同的是,ClusterRole可以在包括所有namaspace和集群级别的资源或非资源类型进行鉴权。

1.3.2.1.2.4 ClusterRoleBinding

ClusterRoleBinding:将Subject绑定到ClusterRole,ClusterRoleBinding将规划在所有命名空间中生效。

1.3.2.1.3 命名空间级

1.3.2.1.3.1 工作负载型

Pod

Pod(容器组)是Kubernetes中最小的可部署单元。一个Pod(容器组)包含了一个应用程序容器(某些情况下是多个容器)、存储资源、一个唯一的网络IP地址,以及一些确定容器该如何运行的选项。Pod容器组代表了Kubernetes中一个独立的应用程序运行实例,该实例可能由单个容器或者几个紧耦合在一起的容器组成。

Docker是Kubernetes Pod中使用最广泛的容器殷勤;Kubernetes Pod同时也支持其他类型的容器引擎。

Kubernetes集群中的Pod存在如下两种使用途径:

一个Pod中只运行一个容器。“one-container-per-pod”是Kubernetes中最常见的使用方式。此时,可以认为Pod容器组是该容器的wrapper,Kubernetes通过一个Pod管理容器,而不是直接管理容器。

一个Pod中运行多个需要故乡协作的容器。可以将多个紧密耦合、共享资源且始终在一起运行的容器编排在同一个Pod中,可能的情况有:

1.3.2.1.3.1.1 副本(replicas)

先引入“副本”的概念——一个Pod可以被复制成多份,每一份可被称之为一个“副本”,这些“副本”除了一些描述性的信息(Pod名字、uid等)不一样以外,其他信息都是一样的,譬如Pod内部的容器、容器数量、容器里面运行的应用等的这些信息都是一样的,这些副本提供同样的功能。

Pod的“控制器”通常包含一个名为“replicas”的属性。“replicas”属性则制定了特定Pod的副本的数量,当当前集群中该Pod的数量与该属性指定的值不一致时,k8s会采取一些策略去是的当前状态满足配置的要求。

1.3.2.1.3.1.2 控制器

当Pod被创建出来,Pod会被调度到集群中的节点上运行,Pod会在该节点上一直保持运行状态,直到进程终止、Pod对象被删除、Pod因节点资源不足而被驱逐或者节点失效位置。Pod并不会自愈,当节点失效,或者调度Pod的这一操作失败了,Pod就该被删除。如此,单单用Pod来部署应用,是不稳定不安全的。

Kubernetes使用更高级的资源对象“控制器”来实现对Pod的管理。控制器可以创建和管理多个Pod,管理副本和上线,并在集群范围内提供自修复能力。例如,如果一个节点失败,控制器可以在不同的节点上调度一样的替身来自动替换Pod。

  1. 适用无状态服务

  • ReplicationController(RC)

RepelicationController简称RC,RC是Kubernetes系统中的核心概念之一,简单来说,RC可以保证在任意时间运行Pod的副本数量,能够保证Pod总是可用的。如果实际Pod数量比指定的多那就结束掉多余的,如果实际数量比指定的少就新启动一些Pod,当Pod失败、被删除或者挂掉后,RC都会去自动创建新的Pod来保证副本数量,所以即使只有一个Pod,也应该使用RC来管理Pod。可以说,通过ReplicationController,Kubernetes实现了Pod的高可用性。

  • ReplicaSet(RS)

RC(ReplicationController)主要的作用就是用来确保容器应用的副本数始终保持在用户定义的副本数。即如果优容器异常退出,会自动创建新的Pod来替代;而如果异常多出来的容器也会自动回收(已经成为过去时),在v1.11版本废弃。

Kubernetes官方建议使用RS(ReplicaSet)替代RC(Replication Controller)进行部署,RS跟RC没有本质的不同,只是名字不一样,并且RS支持集合式的selector。

Label和Selector

label(标签)时附加到Kubernetes对象(比如Pods)上的键值对,用于区分对象(比如Pod、Service)。label旨在用于指定对用户有意义且相关的对象的表示属性,但不直接为核心系统有语义含义。label可以用于组织和选择对象的子集。label可以在创建时附加到对象,随后可以随时添加和修改。可以像namespace一样,使用label来获取某类对象,但label可以与selector一起配合使用,用表达式对条件加以限制,实现更精确、更灵活的资源查找。

label与selector配合,可以实现对象的“关联”。“Pod控制器”与Pod是相关联的——“Pod控制器”依赖于Pod,可以给Pod设置label,然后给“控制器”设置对应的selector,这就实现了对象的关联。

  • Deployment

Deployment为Pod和Replica Set提供声明式更新。

只需要在Deployment中描述想要的目标状态是什么,Deployment controller就会帮助将Pod和Replica Set的实际状态改变到目标状态。可以定义一个全新的Deployment,也可以创建一个新的替换旧的Deployment。

  • 创建Replica Set/Pod
  • 滚动升级/回滚

  • 平滑扩容和缩容

  • 暂停与恢复Deployment
  1. 适用有状态服务

StatefulSet

StatefulSet中每个Pod的DNS格式为statefulSetName-(0..N-1).serviceName.namespace.svc.cluster.local

serviceName为Headless Service的名字

0..N-1为Pod所在的序号,从0开始到N-1

statefulSetName为StatefulSet的名字

namespace为服务所在的namespacee,

Headless Service和StatefulSet必须在相同的namespace

.cluster.local为Cluster Domain

  • 主要特点

稳定的持久化存储

即Pod重新调度后还是能访问到相同的持久化书,基于PVC实现。

稳定的网络标志

稳定的网络标志,即Pod重新调度后器PodName和HostName不变,基于Headless Service(即没有Cluster IP的Service)来实现。

有序部署,有序扩展

有序部署,有序扩展,即Pod是有顺序的,在部署或者扩展的时候要依据定义的顺序依次进行(即从0到N-1,在下一个Pod运行之前所有之前的Pod必须是Running和Ready状态),基于init containers来实现。

有序收缩,有序删除

有序收缩,有序删除(即从N-1到0)。

  • 组成

Headless Service

用于定义网络标志(DNS domain)

Domain Name Server:域名服务将域名与ip绑定映射关系

服务名=》访问路径(域名)=》ip。

volumeClaimTemplete

用于创建PersistentVolumes。

  • 注意事项

kubenetes v1.5版本以上才支持;

所有Pod的Volume必须使用PersisterVolume或者是管理员事先创建好;

为了保证数据安全,删除StatefulSet时不会删除Volume;

StatefulSet需要一个Headless Service来定义DNS domain,需要在StatefulSet之前创建好。

  1. 守护进程

DaemonSet

DaemonSet保证在每个Node上都运行一个容器副本,常用来部署一些集群的日志、监控或者其他系统管理应用。典型的应用包括:日志收集,比如fluented,logstash等系统监控,比如Prometheus Node Exporter,collected,New Relic agent,Ganglia gmond等系统程序,比如kube-proxy,kube-dns,glusterd,ceph等。

  1. 任务/定时任务
  • Job

一次性任务,运行完成后Pod销毁,不再重新启动新容器。

  • CronJob

CronJob是在Job基础上加上了定时功能。

1.3.2.1.3.2 服务发现

  1. Service

“Service”简写“svc”。Pod不能直接提供给外网访问,而是应该使用service。Service就是把Pod暴露出来提供服务,Service才是真正的“服务”,它的中文名就叫“服务”。

可以说Service是一个应用服务的抽象,定义了Pod逻辑集合和访问这个Pod集合的策略。Service代理Pod集合,对外表现为一个访问入口,访问该入口的请求将经过负载均衡,转发到后端Pod中的容器。

  1. Imgress

Imgress可以提供外网访问Service的能力。可以把某个请求地址映射、路由到特定的service。

imgress需要配合imgress contoller一起使用才能发挥作用,imgress只是相当于路由规划的集合而已,真正实现路由功能的,是Imgress Controller,imgress controller和其它k8s组件一样,也是在Pod中运行。

1.3.2.1.3.3 存储

  1. Volume

数据卷,共享Pod中容器使用的数据,用来放持久化的数据,比如数据库数据。

  1. CSI

Container Storage Interface是由来自Kubernetes、Mesos、Docker等社区成员联合制定的一个行业标准接口规范,旨在将任意存储系统给容器化应用程序。

CSI规范定义了存储提供商实现CSI兼容的Volume Plugin的最小操作集合部署建议。CSI规范的主要焦点是声明Volume Plugin必须实现的接口。

1.3.2.1.3.4 特殊类型配置

  1. ConfigMap

用来防止,与Secret是类似的,只是ConfigMap放的是明文的数据,Secret是密文存放。

  1. Sercret

Secret解决了密码、token、密钥等敏感数据的配置问题,而不需要把这些敏感数据暴露到镜像或者Pod Spec中。Secret可以以Volume或者环境变量的方式使用。

Secret有三种类型:

Service Account:用来访问Kubernetes API,由Kubernetes自动创建,并且会自动挂载到Pod的/run/secrets/kubernetes.io/serviceaccount目录中;

Opaque:base64编码格式的Secret,用来存储密码、密钥等;

kubernetes.io/dockerconfigison:用来存储私有docker registry的认证信息。

  1. DownwardAPI

downloadAPI这个模式和其他模式不一样的地方在于它不是为了存放容器的数据也不是用来进行容器和宿主机的数据交换的,而是让Pod里的容器能够直接获取到这个Pod对象本身的一些信息。

downwardAPI提供了两种方式用于将Pod的信息注入到容器内部:

环境变量:用于单个变量,可以将pod信息和容器信息直接注入容器内部;

volume挂载:将Pod信息生成为文件,直接改在到容器内部中去。

1.3.2.1.3.5 其他

  1. Role

Role是一组权限的集合,例如Role可以包含列出Pod权限及列出Deployment权限,Role用于给某个Namespace中的资源进行鉴权。

  1. RoleBinding

RoleBinding:将Subject绑定到Role,RoleBinding使规则在命名空间内生效。

1.3.2.2 资源清单

创建k8s的对象都是通过yaml文件的形式进行配置的。

参数名

类型

字段说明

apiVersion

String

k8sAPI的版本,可以用kubectl api versions命令查询

kind

String

yam文件定义的资源类型和角色

metadata

Object

元数据对象,下面是它的属性

metadata.name

String

元数据对象的名字,比如pod的名字

metadata.namespace

String

元数据对象的命名空间

Spec

Object

详细定义对象

spec.containers[]

list

定义Spec对象的容器列表

spec.containers[].image

String

为列表中的某个容器定义需要的镜像名称

spec.containers[].imagePullPolicy

String

定义镜像拉取策略,有Always、Never、IfNotPresent三个值可选

-Always(默认):意思是每次都尝试重新拉取镜像

-Never:表示仅适用本地镜像

-IfNotPresent:如果本地有镜像就使用本地镜像,没有就拉取在线镜像

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

设置存储卷路径的读写模式,true或者false,默认是读写模式

spec.containers[].ports[]

list

指定容器需要用到的端口列表

spec.containers[].ports[].name

String

指定端口的名称

spec.containers[].ports[].containerPort

String

指定容器需要监听的端口号

spec.containers[].ports[].hostPort

String

指定容器所在主机需要监听的端口号,默认跟上面containerPort相同,注意设置了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.limits

Object

指定设置容器运行时资源的运行上限

spec.containers[].resources.linits.cpu

String

指定CPU的限制,单位为Core数,将用于docker run -cpu-shares参数

spec.containers[].resources.limits.memory

String

指定men内存的限制,单位为MIB、GIB

spec.containers[].resources.requests

Object

指定容器启动和调度时的限制设置

spec.containers[].resources.cpu

String

CPU请求,单位为Core数,容器启动时初始化可用数量

spec.containers[].requests.memory

String

内存请求,单位为MIB、GIB,容器启动的初始化可用数量

spec.restartPolicy

String

定义Pod的重启策略,可选值为Always、OnFailure、Never,默认值为Always。

-Always:Pod一旦终止运行,则无论容器是如何终止的,kubelet服务豆浆重启它。

-OnFailure:只有Pod以非零退出码终止时,kubelet才会重启该容器。如果容器正常结束(退出码为0),则kubelet将不会重启它。

-Never:Pod终止后,kubelet将退出码报告给master,不会重启该Pod

spec.nodeSelector

Object

定义Node的label过滤标签,以key:value格式指定

spec.imagePullSecrets

Object

定义pull镜像时使用secret名称,以name:secretkey格式指定

spec.hostNetwork

Boolean

定义是否使用主机网络模式,默认值为false。设置true表示使用宿主机网络,不适用docker网桥,同事设置了true将无法在同一台宿主机上启动第二个副本

1.3.3 对象规约和状态

对象使用来完成一些任务的,是持久的,是由目的性的,因此kubernetes创建一个对象后,将持续的工作以确保对象存在。当然,kubernetes并不只是维持对象的存在这么简单,kubernetes还管理对象的方方面面。每个kubernetes对象包含两个嵌套的对象字段,他们负责管理对象的配置,他们分别是“spec”和“status”。

1.3.3.1 规约(Spec)

“spec”是“规约”,“规格”的意思是,spec是必需的,它描述了对象的期望状态*(Desired State)——希望对象所具有的特征,当创建Kubernetes对象时,必须提供对象的规约,用来描述该对象的期望状态,以及关于对象的一些基本信息(例如名称)。

1.3.3.2 状态(Status)

表示对象的实际状态,该属性由k8s自己维护,k8s会通过一些列的控制器对对应对象进行管理,让对象尽可能地让实际状态与期望状态重合。

1.4 微服务项目k8s环境演示

2 深入k8s实战进阶篇

2.1 搭建Kubernetes集群

2.1.1 搭建方案

2.1.1.1 minikube

minikube是一个工具,能在本地运行Kubernetes。minikube在个人计算机(包括Windows、macOS和Linux PC)上运行一个一体化(all-in-one)或多节点地本地Kubernetes集群,以便来尝试Kubernetes或者开展每天的开发工作。

官方安装文档

2.1.1.2 kubeadm

可以使用kubeadm工具来创建和管理Kubernetes集群。该工具能够执行必要的动作并用一种用户友好的方式启动一个可用的、安全的集群。

安装kubeadm展示了如何安装kubeadm的过程。一旦安装了kubeadm,就可以使用它来创建一个集群。

2.1.1.2.1 服务器要求

3台服务器(虚拟机):

k8s-master:192.168.113.120

k8s-node1:192.168.113.121

k8s-node2:192.168.113.122

最低配置:2核、2G内存、20G硬盘

最好能联网,不能联网的话需要有提供对应镜像的私有仓库

2.1.1.2.2 软件环境

操作系统:CentOS 7

Docker:20+

k8s:1.23.6

2.1.1.2.3 安装步骤

2.1.1.2.3.1 初始操作

# 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld

# 关闭selinux
sed -i 's/enforcing/disabled/' /etc/selinux/config # 永久
setenforce 0 # 临时

# 关闭swap
swapoff -a # 临时
sed -ri 's/.*swap.*/#&/' /etc/fstab  # 永久

# 关闭玩swap后,一定要重启一下虚拟机
# 根据规划设置主机名
hostnamectl set-hostname <hostname>

# 在master添加hosts
cat >> /etc/hosts << EOF
192.168.113.120 k8s-master
192.168.113.121 k8s-node1
192.168.113.122 k8s-node2
EOF

# 将桥接的IPv4流量传递到iptable的链
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
EOF

sysctl -system # 生效

# 时间同步
yun install ntpdate -y
ntpdate time.windows.con

2.1.1.2.3.2 安装基础软件(所有节点)

2.1.1.2.3.2.1 安装Docker

基于文档中的安装Docker文件进行安装

2.1.1.2.3.2.2 添加阿里云yum源

cat > /etc/yum.repos.d/kubernetes.repo << EOF
[kubernetes]
name=Kubernetes
baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=0
repo_gpgcheck=0

gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

2.1.1.2.3.2.3 安装kubeadm、kubelet、kubectl

yum install -y kubelet-1.23.6 kubeadm-1.23.6 kubectl-1.23.6

systemctl enable kubelet

# 配置关闭 Docker 的 cgroups,修改 /etc/docker/daemon.json,加入以下内容
"exec-opts": ["native.cgroupdriver=systemd"]

# 重启 docker
systemctl daemon-reload
systemctl restart docker

2.1.1.2.3.3 部署Kubernetes Master

# 在 Master 节点下执行

kubeadm init \
      --apiserver-advertise-address=192.168.113.120 \
      --image-repository registry.aliyuncs.com/google_containers \
      --kubernetes-version v1.23.6 \
      --service-cidr=10.96.0.0/12 \
      --pod-network-cidr=10.244.0.0/16

# 安装成功后,复制如下配置并执行
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
kubectl get nodes

2.1.1.2.3.4 加入Kubernetes Node

分别在 k8s-node1 和 k8s-node2 执行

# 下方命令可以在 k8s master 控制台初始化成功后复制 join 命令

kubeadm join 192.168.113.120:6443 --token w34ha2.66if2c8nwmeat9o7 --discovery-token-ca-cert-hash sha256:20e2227554f8883811c01edd850f0cf2f396589d32b57b9984de3353a7389477


# 如果初始化的 token 不小心清空了,可以通过如下命令获取或者重新申请
# 如果 token 已经过期,就重新申请
kubeadm token create

# token 没有过期可以通过如下命令获取
kubeadm token list

# 获取 --discovery-token-ca-cert-hash 值,得到值后需要在前面拼接上 sha256:
openssl x509 -pubkey -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubin -outform der 2>/dev/null | \
openssl dgst -sha256 -hex | sed 's/^.* //'

2.1.1.2.3.5 部署CNI网络插件

# 在 master 节点上执行
# 下载 calico 配置文件,可能会网络超时
curl https://docs.projectcalico.org/manifests/calico.yaml -O

# 修改 calico.yaml 文件中的 CALICO_IPV4POOL_CIDR 配置,修改为与初始化的 cidr 相同

# 修改 IP_AUTODETECTION_METHOD 下的网卡名称

# 删除镜像 docker.io/ 前缀,避免下载过慢导致失败
sed -i 's#docker.io/##g' calico.yaml

2.1.1.2.3.6 测试Kubernetes集群

# 创建部署
kubectl create deployment nginx --image=nginx

# 暴露端口
kubectl expose deployment nginx --port=80 --type=NodePort

# 查看 pod 以及服务信息
kubectl get pod,svc

2.1.1.3 二进制安装

利用 k8s 官方 github 仓库下载二进制包安装,安装过程较复杂,但相对较为稳定,推荐生产环境使用。

2.1.1.4 命令行工具

2.1.2 命令行工具kubectl

命令行工具(kubectl)Kubernetes提供kubectl是使用Kubernetes API与Kubernetes集群的控制面进行通信的命令行工具。

这个工具叫做kubectl

2.1.2.1 在任意节点使用kubectl

# 1.将master节点中 /etc/kubernetes/admin.conf拷贝到需要运行的服务器的/etc/kubernetes目录中
scp /etc/kubernetes/admin.conf root@k8s-node1:/etc/kubernetes

# 2.在对应的服务器上配置环境变量
echo "export KUBECONFIG=/etc/kubernetes/admin.conf" >> ~./bash_profile source ~/.bash_profile

2.1.2.2 资源操作

2.1.2.2.1 创建对象

# 创建资源
kubectl create -f ./my-manifest.yaml

# 使用目录下的所有清单文件来创建资源
kubectl create -f ./my1.yaml -f ./my2.yaml

# 使用url来创建资源
kubectl create -f https://git.io/vPieo

# 启动一个nginx实力
kubectl run nginx --image=nginx

# 获取pod和svc的文档
kubectl explain pods,svc
# 从stdin输入中创建多个YAML对象
cat <<EOF | kubectk create -f -
apiVersion:v1
kind: Pod
metadata:
  name: busybox-sleep
spec:
  containers:
  - name: busybox
    image: busybox
    args:
    - sleep
    - "1000000"
---
apiVersion: v1
kind: Pod
metadata:
  name: busybox-sleep-less
spec:
  containers:
  - name: busybox
    image: busybox
    args:
    - sleep
    - "1000"
EOF

# 创建包含几个key的Secret
cat <<EOF | kubectl create -f -
apiVersion: v1
kind: Secret
metadata:
  name: mysecret
type: Opaque
data:
  password: $(echo "s33msi64" | base64)
  username: $(echo "jane" | base64)
EOF

2.1.2.2.2 显示和查找资源

# Get commands with basic output

# 列出所有namespace中的所有service
kubectl get services

# 列出所有namespace中的所有pod
kubectl get pods -all namespaces

# 列出所有Pod并显示详细信息
kubectl get pods -o wide

# 列出指定deployment
kubectl get deloyment my-dep

# 列出该namespace中的所有pod包括未初始化的
kubectl get pods --include-uninitialized
# 使用详细输出来描述命令
kubectl describe nodes my-node
kubectl describe pods my-pod

# List Services Sorted by Name
kubectl get services --sort-by=.metadata.name

# 根据重启次数排列出pod
kubectl get pods --sort-by='.status.containerStatuses[0].restartCount'

# 获取所有具有app=cassanfra的pod中的version标签
kubectl get pods --selector=app=cassandra rc -o \
jsonpath='(.items[*].metadata.labels.version)'

# 获取所有节点的ExternalIP
kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type=="ExternalIP")].address}'

# 列出属于某个PC的Pod的名字
# "jq"命令用于转换复杂的jsonpath,参考:https://stedolan.github.io/jq/
sel=${$kubectl get rc my-rc --out=json | jq -j '.spec.selector | to_entries | .[] | "\(.key)=\(.value),"')%?}
echo $(kubectl get pods --selector=$sel --output=jsonpath={.items.metadata.name})

# 查看那些Pod中使用的Secret
kubectl get -o json | jq '.items[].spec.containers[].env[]?.valueFrom.secreteKeyRef.name' | grep -v null | sort | uniq

2.1.2.2.3 更新资源

# 滚动更新pod frontend-v1
kubectl rolling-update frontend-v1 -f frontend-v2.json

# 更新资源名称并更新镜像
kubectl rolling-update frontend-v1 frontend-v2 --image=image:v2

# 更新frontend pod中的镜像
Kubectl rolling-update frontend --image=image:v2

# 退出已存在的进行中的滚动更新
kubectl rolling-update frontend-v1 frontend-v2 --rollback

# 基于stdin输入的JSON替换pod
cat pod.json | kubectl replace -f -

# 强制替换,删除后重新创建资源。会导致服务中断
kubectl replace --force -f ./pod.json

# 为nginx RC创建服务,启用本地80端口连接到容器上的8000端口
Kubectl expose rs nginx --port=80 --target-port=8000

# 更新单容器pod的镜像版本(tag)到v4
kubectl get pod mypod -o yaml | sed 's/\(image:myimage\):.*$/\1:v4' | kubectl replace -f -

# 添加标签
kubectl label pods my-pod new-label=awesome

# 添加注解
kubectl annotate pods my-pod icon-url=http://goo.gl/XXBTWq

# 自动扩展deployment “foo”
kubectl autoscale deployment foo --min=2 --max=10

2.1.2.2.4 修补资源

# 部分更新节点
kubectl patch node k8s-node-1 -p '{"spec":{"unschedulable":true}}'

# 更新容器镜像:spec.containers[*].name是必须的,因为这是合并的关键字
kubectl patch pod valid-pod -p '{"spec":{"containers":[{"name":"kubernetes-serve-hostname","image":"new image"}]}}'

# 使用具有位置数组的json不定更新容器镜像
kubectl patch pod valid-pod --type='json' -p='[{"op":"replace","path":"/spec/containers/0/image","value":"new image"}]'

# 使用具有位置数组的json不定禁用deployment的livenessProbe
kubectl patch deployment valid-deployment --type json -p='[{"op":"remove","path":"/spec/template/spec/containers/0/livenessProbe"}]'

2.1.2.2.2.5 编辑资源

# 编辑名为docker-registry的service
kubectl edit svc/docker-registry

# 使用其他编辑器
KUBE_EDITOR="nano" kubectl edit svc/docker -registry

2.1.2.2.6 scale资源

# Scale a replicaset named 'foo' to 3
kubectl scale --replicas=3 rs/foo

# Scale a resource specified in "foo.yaml" to 3
kubectl scale --replicas=3 -f foo.yaml

# if the development named mysql's current size is 2,scale mysql to 3
kubectl scale --current-replicas=2 --replicas=3 deployment/mysql

# Scale multiple replication controllers
kubectl scale --replicas=5 rc/foo rc/bar rc/baz

2.1.2.2.7 删除资源

# 删除pod.json文件中定义的类型和名称的pod
kubectl delete -f ./pod.json

 # 删除名为“baz”的pod和名为“foo”的service
 kubectl delete pods,service baz foo

 # 删除具有name=myLabel标签的pod和service
 kubectl delete pods,services -l name=myLabel

 # 删除具有name=myLebel标签的pod和service,包括尚未初始化的
 kubectl delete pods,services -l name=myLabel --include-uninitialized

 # 删除my-ns namespace下的所有pod和service,包括尚未初始化的
 kubectl -n my-ns delete po,sev --all

2.1.2.3 Pod与集群

2.1.2.3.1 与运行的Pod交互

# dump输出pod的日志(stdout)
kubectl logs my-pod

# dump输出pod中容器的日志(stout,pod中有多个容器的情况下使用)
kubectl logs my-pod -c my-container

# 流式输出pod的日志(stout)
kubectl logs -f my-pod

# 流式输出pod中容器的日志(stout,pod中有多个容器的情况下使用)
kubectl logs -f my-pod -c my-container

# 交互式shell的方式运行pod
kubectl run -i --tty busybox --image=busybox -sh

# 连接到运行中的容器
kubectl attach my-pod -i

# 转发pod中的6000端口到本地的5000端口
kubectl port-forward my-pod 5000:6000

# 在已存在的容器中执行命令(只有一个容器的情况下)
kubectl exec my-pod --ls /

# 在已存在的容器中执行命令(pod中有多个容器的情况下)
kubectl exec my-pod -c my-container --ls/

# 显示指定pod和容器的指标度量
kubectl top pod POD_NAME --containers

2.1.2.3.2 与节点和集群交互

# 标记my-node不可调度
Kubectl cordon my-node

# 清空my-node以待维护
kubectl drain my-node

# 标记my-node可调度
kubectl uncordon my-node

# 显示my-node的指标度量
kubectl top node my-node

# 显示master和服务的地址
kubectl cluster-info

# 将当前集群状态输出到stout
kubectl cluster-info dump

# 将当前集群状态输出到/path/to/cluster-state
kubectl cluster-info dump --output-directory=/path/to/cluster-state

# 如果该键和影响的污点(taint)已存在,则使用指定的值替换
kubectl taint nodes foo delicated=special-user:NoSchedule

2.1.2.4 资源类型与别名

pods po

deployments deploy

services svc

namespace ns

nodes no

2.1.2.5 格式化输出

输出json格式 
-o json

仅打印资源名称 
-o name

以纯文本格式输出所有信息
-o wide

输出yaml格式
-o yaml

2.1.3 API概述

官方文档:

REST API是Kubernetes系统的重要部分,组件之间的所有操作和通信均由API Server处理的REST API调用,大多数情况下,API定义和实现都符合标准的HTTP REST格式,可以通过kubectl命令管理工具或其他命令行工具来执行。

2.1.3.1 类型

2.1.3.1.1 Alpha

包含alpha名称的版本(例如v1alpha)。

该软件可能包含错误。启用一个功能可能会导致bug。默认情况下,功能可能会被禁用。

随时可能会丢弃对该功能的支持,数=恕不另行通知。

该软件建议仅在短期测试集群中使用,因为错误的风险增加和缺乏长期支持。

2.1.3.1.2 Beta

包含beta名称的版本(例如v2beta3)。

该软件经过很好的测试。启用功能被认为是安全的。默认情况下功能是开启的。

细节可能会改变,但功能在后续版本不会被删除

对象的模式或语义在随后的beta版本或Stable版本中可能以不兼容的方式发生变化。如果这种情况发生时,官方会提供迁移操作指南。这可能需要删除、编辑和重新创建API对象。

该版本在后续版本可能会更改一些不兼容地方,所以建议用于非关键业务,如果有多个可以独立升级的集群,也可以放宽此限制。

2.1.3.1.3 Stable

该版本名称命令方式:vX这里X是一个整数。

Stable版本的功特性,将出现在后续发布的软件版本中。

2.1.3.2 访问控制

认证

授权

2.1.3.3 废弃api说明

https://

2.2 深入Pod

2.3 资源调度

2.4 服务发布

2.5 配置与存储

2.6 高级调度

2.7 身份认证与权限

3 运维管理篇

Spring Cloud Alibaba微服务DevOps实战

kubectl ls
kubectl get nodes
cat ~/.kube/config    # server: https://192.168.113.120:6443

在任意节点使用kubectl

1.将maste节点中/etc/kubernetes/admin.conf拷贝到需要运行的服务器的/etc/kubernetes目录中

scp /etc/kubernetes/admin.conf root@k8s-node1:/etc/kubernetes

2.在对应的服务器上配置环境变量

echo "export KUBERCONFIG=/etc/kubernetes/admin.conf" >> ~/.bash_profile

source ~/.bash_profile

kubectl get nodes

getting started 通用命令

create

创建

get

获取

run

运行

expose

暴露

delete

删除

app management 常用命令

apply

yaml配置中创建资源对象

autoscale

自动扩容缩容

debug

测试

diff

对比

edit

编辑

label

标签

patch

补丁

replace

替换旧的yaml文件,如果是deployment会自动更新

rollout

滚动

scale

手动扩容缩容

set

修改单个属性

working with apps 进入容器内部的常用命令

attach

进入

auth

认证

cp

拷贝

describe

pod详细信息

exec

执行容器内

logs

port-forward

proxy

top

资源类型与别名

pods po

deployment deploy

service svc

namespaces ns

nodes no

kubectl scale --replicas=3 -f nginx(filename)

--help

kubectl scale deploy --replicas=3 nginx(depname)

kubectl get po -o wide (详细信息(ip、node))

kubectl get deploy nginx -o yaml

kubectl describe po nginx-demo

kubectl get pods -o wide (获取到ip)

curl 10.244.169.131 (上一步获取到的ip)

route -n (Destination 10.244.169.128 Gateway 192.168.113.122)

docker ps

ls

docker ps 查看容器

深入pod

探针

容器内应用的检测机制,根据不同的探针来判断容器应用当前的状态

1、类型

StartupProbe

LivenessProbe

ReadlinessProbe

  • LivenessProbe 故障自动恢复,运行成功后

用于探测容器中的应用是否运行,如果探测失败,kubelet会根据配置的重启策略进行重启,若没有配置,默认为容器启动成功,不会执行重启策略。

livenessProbe:

failureThreshold: 5

httpGet:

path: /health

port: 8080

scheme: HTTP

initialDelaySeconds: 60

periodSeconds: 10

  • ReadlinessProbe 启动成功,并且初始化完成后

用于探测容器内的程序是否健康,它的返回值如果返回success,那么默认为该容器已经完全启动,并且该容器是可以接收外部流量的。

readlinessProbe:

failureThreshold: 3 # 错误次数

httpGet:

path: /ready

port: 8181

scheme: HTTP

periodSecond: 10 # 间隔时间

successThreshold: 1

  • StartupProbe

k8s 1.16 版本新增的探针,用于判断应用程序是否已经启动了

当配置了startupProbe后,会先禁用其他探针,直到startupProbe成功后,其他探针才会继续

作用:由于有时候不能准确预估应用一定时多长时间启动成功,因此配置另外两种方式不方便配置初始化时长来检测,而配置了startupProbe后,只有在应用启动成功了,才会执行两外两种探针,可以更加方便地结合使用另外两种探针使用。

避免无限重启

初始化未完成前,没必要检查

startupProbe

httpGet:

path: /api/startup

port: 80

2、探测方式

ExecAction

在容器内部执行一个命令,如果返回值为0,则任务容器是健康地

livenessProbe: # 在任意一个探针下,执行命令,例如检查某文件夹下是否存在某文件,存在即初始化成功,不存在,即初始化失败

exec:

command:

- cat

- /health

需求偏向于命令行

TCPSocketAction

通过tcp链接检测容器内端口是否开放,如果开放则证明该容器健康

livenessProbe: # 尝试与tcp端口进行连接

topSocket:

port: 80

nginx常用,端口绑定即可接收请求

HTTPGetAction

生产环境用地较多的方式,发送http请求到容器内的应用程序,如果接口返回的状态码在200-400之间,则认为容器健康

livenessProbe:

failureThreshold: 5

httpGet:

path: /health

port: 8080

scheme: HTTP

httpHeaders:

- name: xxx

value: xxx

java应用常用的探针方式,应用启动完成后

3、参数配置

initialDelaySeconds: 60 # 初始化时间 该时间内LivenessProbe 、ReadlinessProbe 探针不执行

timeoutSeconds: 2 # 超时时间

periodSeconds: 5 # 检测间隔时间

successThreshold: 1 # 检查1次成功就表示成功

failureThreshold: 2 # 检测失败2次就表示失败

kubectl get po -n kubeSystem # 指定命名空间

kube-system 默认的命名空间

kubectl edit deploy -n kube-system coredns # 编辑

3.3.1 资源调度-标签和选择器:Label与Selector的使用

  • RS 副本集

管理Pod副本扩容/缩容

  • Deployment 部署

包含RS、创建RS和Pod

对应用进行滚动更新/回滚、动态扩容等

  • Selector 选择器

查询条件:key1=value1、key2=value2

资源调度:

Label和Selector、Deployment、StatefulSet、DaemonSet

Label 标签

  • 配置文件

在各类资源的metadata.labels中进行配置

  • kubectl

临时创建label

修改已经存在的标签

查看label

# 配置文件中的内容:
metadata:  # pod 相关元数据
  labels:  # 定义pod标签
    type: app  # 自定义label标签
    test: 1.0.0  # 自定义label标签

# 查看label
# selector按照label单值查找节点
kubectl get po -A -l app=hello
# 查看所有节点的labels
kubectl get po -n kube-system --show-labels  
kubectl get deploy --show-labels

# 临时创建label
# kubectl label po <资源名称> author=xiaowang -n kube-system 
kubectl label po nginx-po author=xiaowang -n kube-system 
kubectl label deploy nginx-deploy author=xiaowang

# 修改已经存在的标签
# kubectl label po <资源名称> app=hello2,-n kube-system --overwrite
kubectl label po nginx-po auther=zhangsan
kubectl edit po nginx-po

Selector 选择器

  • 配置文件

在各对象的配置spec、selector或其他可以写selector的属性中编写

  • kubectl

匹配单个值,查找app=hello的pod

匹配多个值

查找version=1 and app=nginx的pod信息

不等值+语句

# 匹配单个值,查找app=hello的pod
# kubectl get po -A -l app=hello
kubectl get po -A -l type=app --show-labels

# -A:显示资源的namespace信息
# --show-labels:显示资源的标签信息 


# 匹配多个值
# kubectl get po -A -l 'k8s-app in (metrics-server,kubernetes-dashboard)'
kubectl get po -A -l 'test in (1.0.0 1.0.1 1.0.2)'

# 查找version=1 and app=nginx的pod信息
# kubectl get po -l version=1,app=nginx

# 不等值+语句
# kubectl get po -A -l version=1,'app in (busybox,nginx)'
kubectl get po -l 'test!=1.0.1,type=app,author in (xiaowang,wangwu,zhangsan)'

Deployment-》ReplicaSet-》Pod

📎k8s 入门到微服务项目实战.xmind

apiVersion: apps/v1 # deployment api 版本
kind: Deployment  # 资源类型为deployment
metadata:  # 原信息
  labels:  # 标签
    app: nginx-deploy  # 具体的key:value配置形式
  name: nginx-deploy  # deployment的名字
  namespace: default  # 所在的命名空间
spac:
  replicas: 1  # 期望副本数
  revisionHistoryLimit: 10  # 进行滚动更新,保留的历史版本数
  selector:  # 选择器,用于找到匹配的RS
    matchLabels:  # 按照标签匹配
      app: nginx-deploy  # 匹配的标签key/value
  strategy:  # 更新策略
    rollingUpdate: 25%  # 进行滚动更新时,更新的个数最多可以超过期望副本数的个数/比例
    maxUnavailable: 25%  # 进行滚动更新时,最大不可用比例更新比例,表示在所有副本数中,最多可以由多少个不更新成功
  type: RollingUpdata  # 更新类型,采用滚动更新
templete: # pod 模板
  metadata: # pod的元数据
    labels: # pod的标签
      app: nginx-deploy 
  spec: # pod的期望信息
    containers: # pod的容器
    - image: nginx:1.7.9 # 镜像
      imagePullPolicy: IfNotPresent # 拉取策略
      name: nginx # 容器名称
    restartPolicy: Always # 重启策略
    terminationGracePeriodSeconds: 30 # 删除操作最多宽限多长时间
  

kubectl get po,rs,deploy --show-labels

kubectl set -image deployment/nginx-deploy nginx=nginx:1.7.9

kubectl describe deploy nginx-deloy 查看event

kubectl set image deployment nginx-deploy nginx=nginx:1.9.1 --record=true 可以记录历史

无状态滚动更新特点

StatefulSet

专门针对由状态服务进行部署的一个控制器

# 配置了一个service,主要职责是映射到容器内的80端口,与容器应用做绑定,通过选择器找到app:nginx的应用,做DNS服务
--- # 一个yaml嵌套另一个yaml
 apiVersion: v1
 kind: Service
 netadata:
   name: nginx
   labels:
     app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: Node
  selector:
    app: nginx
---
apiVersion: app/v1
kind: StatefulSet  # StatefulSet类型的资源
metadata:   
  name: web  # StatefulSet对象的名字
spec:
  serviceName: "nginx"  # 使用哪个service来管理dns
  replicates: 2
  selector:
    matchLabels:
      app: nginx
  templete:
    metadata: 
      labels:
        app: nginx
      spec:
        containers:
        - name: nginx
          image: nginx:1.7.9
          ports:  # 容器内部要暴露的端口
          - containerPort: 80  # 具体暴露的端口号
            name: web  # 该端口配置的名字
          ### 以下的先不加上
          volumeMounts: # 加载数据卷
          - name: www  # 指定加载哪个数据卷
          mountPath: /usr/share/nginx/html  # 加载到容器中的哪个目录
volumeClaimTemplates: # 数据卷模板
- metadata: # 数据卷描述
    name: www  # 数据卷的名称
    annotation: # 数据卷的注解
      volume.alpha.kubenetes.io/storage-class: anything
    spec: # 数据卷的规约
      accessModes: ["readWriteOnce"] # 访问模式
      resource:
        requests:
          storage: 1G # 需要1G的存储资源
# 创建
kubectl create -f web.yaml
# 查看statusfulset
kubectl get sts
# 查看service
kubectl get svc
# 查看pods
kubectl get po
# 运行一个容器
kubectl run -it --image busybox:1.28.4 dns-test /bin/bash

nslookup web-0.nginx

kubectl get svc -A  # 可以查看dns

功能

  • 创建
  • 扩容缩容
# 扩容
kubectl scale statefulset web --replicas=3
# 缩容
kubectl scale statefulset web -p '{"spec":{"replicas":3}}'
# 查看sts
kubectl get sts
# 查看sts web信息
kubectl describe sts web
  • 镜像更新
# 打补丁
kubectl patch sts web --type='json' -p='[{"op":"replace","path":"/spec/templete/spec/container/0/image","value":"nginx:1.9.1"}}'
# 查看statesfulset
kubectl get sts
# 查看滚动更新历史
kubectl rollout history sts web
# 查看滚动更新历史具体版本信息
kubectl rollout history sts web --revision=2
# 查看滚动更新状态 进展
kubectl rollout status sts web
# 查看滚动更新具体事件
kubectl deccribe sts web
# 查看pods的状态status  是否都已被更新
kubectl get po
# 通过进入编辑操作界面查看pod的具体信息,查看容器中的镜像版本号信息是否已更新
kubectl edit po web-0
# 查看详细信息
kubectl get statefulset web -o wide	

RollingUpdata 灰度发布、金丝雀服务

目标:将项目上线后产生问题的影响,尽量降到最低

OnDelete

  • 删除

statefulset中没有rs,只有deployment中才有rs

statefulset直接关联到pod

  • 删除pvc

配置文件

DeamonSet

20230520

DaemonSet

配置文件

指定Node节点

DaeminSet会忽略Node的unschedulable状态,有两种方式来指定Pod只运行在指定的Node节点上

nodeSelector:之调度到匹配指定label的Node上

nodeAffinity:功能更丰富的Node选择器,比如支持集合操作

podAffinity:调度到满足条件的Pod所在的Node上

  • nodeSelector
# 先为Node打上标签
kubectl label nodes k8s-nodel svc_typ microsvc 
# 然后在daemonset配置中设置nodeSelector
spec:
  template:
    nodeSelector:
      svc_type:microsvc
  • nodeAffinity

nodeAffinity目前支持两种:requireddDuringSchedulingIgnoreDuringExecution和preferredDuringSchedulingIgnoredDuringExecution,分别代表必须满足条件和优选条件

比如下面的例子代表调度到包含标签wolfcode.cn/freamework-name并且值为spring或springboot的Node上,并且优选还带有标签another-node-label-key=another-node-label-value的Node

  • podAffinity

滚动更新

HPA

# 替换
kubectl replace -f nginx-deploy.yaml

# 
kubectl autoscale deploy nginx-deploy --cpu-percent=20 --min=2 --max=5


# 显示占用资源的情况
kubectl top -h

# 
yam install -y wget

kubectl top pods

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值