Docker和k8s核心概念(理解友好版) | 木戈手机站

木戈手机站

当前位置: 首页 » 攻略 » Docker和k8s核心概念(理解友好版)

Docker和k8s核心概念(理解友好版)



背景

这是在HWL负责网校云业务线测试时,给同事分享的基础概念文档。

目录:




.

Docker

核心概念






. Kubernetes

是什么及架构





. Kubernetes

核心概念





. Deployment

部署

Pod

操作






一、Docker

核心概念




1、

为什么是Docker



虚拟机:

基础设施(

Infrastructure)。服务器,或者是云主机。


主操作系统(Host Operating System

)。服务器上运行的操作系统

虚拟机管理系统(

Hypervisor)。利用

Hypervisor,可以在主操作系统之上运行多个不同的从操作系统。

从操作系统(

Guest Operating System)。假设你需要运行

3个相互隔离的应用,则需要使用

Hypervisor启动

3个从操作系统,也就是

3个虚拟机。这些虚拟机都非常大,也许有

700MB,这就意味着它们将占用

2.1GB的磁盘空间。更糟糕的是,它们还会消耗很多

CPU和内存。







各种依赖。每一个从操作系统都需要安装许多依赖。

应用。安装依赖之后,就可以在各个从操作系统分别运行应用了,这样各个应用就是相互隔离的。


Docker





Docker

守护进程(Docker Daemon

)。Docker

守护进程取代了Hypervisor

,它是运行在操作系统之上的后台进程,负责管理Docker

容器。




各种依赖。对于

Docker,应用的所有依赖都打包在

Docker镜像中,

Docker容器是基于

Docker镜像创建的。



应用。应用的源代码与它的依赖都打包在

Docker镜像中,不同的应用需要不同的

Docker镜像。不同的应用运行在不同的

Docker容器中,它们是相互隔离的。




对比虚拟机与


Docker


Docker守护进程可以直接与主操作系统进行通信,为各个

Docker容器分配资源;它还可以将容器与主操作系统隔离,并将各个容器互相隔离。虚拟机启动需要数分钟,而

Docker容器可以在数毫秒内启动。由于没有臃肿的从操作系统,

Docker可以节省大量的磁盘空间以及其他系统资源。




2、

Docker



架构



Docker使用客户端

– 服务器(

C/S)架构,使用远程

API管理和创建

Docker 容器。

Docker 客户端与

Docker 守护进程通信,后者负责构建、运行和分发

Docker容器。








Docker客户端和守护进程可以在同一系统上运行,也可以将

Docker客户端连接到远程

Docker守护进程。

Docker客户端和守护进程使用

REST API,通过

UNIX套接字或网络接口进行通信。






Client

客户端通过命令行或其他工具与守护进程通信,客户端会将这些命令发送给守护进程,然后执行这些命令。命令使用

Docker API,

Docker客户端可以与多个守护进程通信。



Docker daemon


Docker守护进程(

docker daemon)监听

Docker API请求并管理

Docker对象,如镜像,容器,网络和卷。守护程序还可以与其他守护程序通信以管理

Docker服务。






Docker Host


Docker Host是物理机或虚拟机,用于执行

Docker守护进程的仓库。



Docker Registry


Docker仓库用于存储

Docker镜像,可以是

Docker Hub这种公共仓库,也可以是个人搭建的私有仓库。使用

docker pull或

docker run命令时,将从配置的仓库中提取所需的镜像。使用

docker push命令时,镜像将被推送到配置的仓库。







Docker Image


Docker 镜像可以看作是一个特殊的文件系统,除了提供容器运行时所需的程序、库、资源、配置等文件外,还包含了一些为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。

镜像可以用来创建

Docker 容器,一个镜像可以创建很多容器。

Docker 提供了一个很简单的机制来创建镜像或者更新现有的镜像,用户甚至可以直接从其他人那里下载一个已经做好的镜像来直接使用。


Docker Container


Docker 利用容器来运行应用。容器是从镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。

可以把容器看做是一个简易版的

Linux 环境(包括

root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。



3、Docker CLI



4、Dockerfile



5、Docker Compose


Compose 是用于定义和运行多容器

Docker 应用程序的工具。通过

Compose,您可以使用

YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从

YML 文件配置中创建并启动所有服务。






6、Docker Swarm

集群管理



Swarm是

Docker 引擎内置(原生)的集群管理和编排工具,它将

Docker 主机池转变为单个虚拟

Docker 主机。




Docker Swarm 适用于简单和快速开发至关重要的环境,而

Kubernetes 适合大中型集群运行复杂应用程序的环境。

两者不是竞争对手,各有利弊,因需选择。



二、Kubernetes

是什么及架构




1、k8s

是什么


先来一张

Kubernetes官网的截图,可以看到,官方对

Kubernetes的定义:

Kubernetes(

k8s)是一个自动化部署、扩展和管理容器化应用程序的开源系统。




Kubernetes

这个单词是希腊语,它的中文翻译是



舵手



或者



飞行员



。在一些常见的资料中也会看到

“ks”

这个词,也就是

“k8s”

,它是通过将

8

个字母

“ubernete ”

替换为

“8”

而导致的一个缩写。

Kubernetes

为什么要用



舵手



来命名呢?


























这是一艘载着一堆集装箱的轮船,轮船在大海上运着集装箱奔波,把集装箱送到它们该去的地方。

Container

这个英文单词也有另外的一个意思就是



集装箱





Kubernetes

也就借着这个寓意,希望成为运送集装箱的一个轮船,来帮助我们管理这些集装箱,也就是管理这些容器。









这个就是为什么会选用

Kubernetes

这个词来代表这个项目的原因。更具体一点地来说:

Kubernetes

是一个自动化的容器编排平台,它负责应用的部署、应用的弹性以及应用的管理。







2、k8s

能做什么





  • 服务的发现与负载的均衡





  • 容器的自动装箱,也会把它叫做

    scheduling

    ,就是



    调度



    ,把一个容器放到一个集群的某一个机器上,

    Kubernetes

    会帮助我们去做存储的编排,让存储的声明周期与容器的生命周期建立连接











  • 容器的自动化恢复。在一个集群中,经常会出现宿主机的问题,导致容器本身的不可用,

    Kubernetes

    会自动地对这些不可用的容器进行恢复





  • 应用的自动发布与应用的回滚,以及与应用相关的配置密文的管理


  • 对于

    job

    类型任务,

    Kubernetes

    可以去做批量的执行






  • 为了让这个集群、这个应用更富有弹性,

    Kubernetes

    支持容器的水平伸缩





2.1

调度



Kubernetes

可以把用户提交的容器放到

Kubernetes

管理的集群的某一台节点上去。

Kubernetes

的调度器是执行这项能力的组件,它会观察正在被调度的这个容器的大小、规格。








比如,容器所需要的

CPU

以及它所需要的内存,然后在集群中找一台相对比较空闲的机器来进行一次放置的操作。



2.2

自动修复


Kubernetes

有节点健康检查的功能,它会监测这个集群中所有的宿主机,当宿主机本身出现故障,或者软件出现故障的时候,这个节点健康检查会自动对它进行发现。


接下来

Kubernetes

会把运行在这些失败节点上的容器进行自动迁移,迁移到一个正在健康运行的宿主机上,来完成集群内容器的自动恢复。




2.3

水平伸缩



Kubernetes

有业务负载检查的能力,它会监测业务上所承担的负载,如果这个业务本身的

CPU

利用率或内存占用过高,或者响应时间过长,它可以对这个业务进行一次扩容。




比如,下面的例子中,黄颜色的过度忙碌,

Kubernetes

就可以把黄颜色负载从一份变为三份。接下来,它就可以通过负载均衡把原来打到第一个黄颜色上的负载平均分到三个黄颜色的负载上去,以此来提高响应速度。





3、k8s

的架构




Kubernetes

架构是一个比较典型的二层架构和

server-client

架构。

Master

作为中央管控节点,与

Node

建立连接。








所有

UI

的、

clients



user

侧的组件,只会和

Master

进行连接,把希望的状态或者想执行的命令下发给

Master



Master

会把这些命令或者状态下发给相应的节点,进行最终的执行。





















































  • Master















Kubernetes



Master

包含四个主要的组件:

API Server



Controller



Scheduler

以及

etcd














API Server


:提供了资源操作的唯一入口,并提供认证、授权、访问控制、

API注册和发现等机制。


Kubernetes

中所有的组件都会和

API Server

进行连接,组件与组件之间一般不进行独立的连接,都依赖于

API Server

进行消息的传送;







Controller


:控制器,它

负责维护集群的状态,比如故障检测、自动扩展、滚动更新等。

上面的

2

个例子,第

1

个自动对容器进行修复、第

2

个自动水平扩张,都是由

Controller

完成的;













Scheduler


:是调度器,

负责资源的调度,按照预定的调度策略将

Pod

调度到相应的机器上。

例如上面的例子,把用户提交的

pod

,依据它对

CPU



memory

请求的大小,找一台合适的节点,进行放置;













etcd


:是一个分布式的存储系统,保存了整个集群的状态,比如

Pod、

Service等对象信息。

API Server

中所需要的原信息都被放置在

etcd

中,

etcd

本身是一个高可用系统,通过

etcd

保证整个

Kubernetes



Master

组件的高可用性。

















  • Node

Kubernetes



Node

是真正运行业务负载的,每个业务负载会以

Pod

的形式运行。一个

Pod

中运行的一个或者多个容器。








kubelet




Master在

Node节点上的

Agent,是

真正去运行

Pod

的组件,

也是

Node

上最关键的组件,负责本

Node节点上

Pod的创建、修改、监控、删除等生命周期管理,同时

Kubelet定时



上报





Node

的状态信息到

API

Server

























它通过

API Server

接收到所需要

Pod

运行的状态。然后提交到

Container Runtime

组件中。








Container Runtime


:容器运行时。

负责镜像管理以及

Pod

和容器的真正运行(

CRI

),

可以理解为类似

JVM










Storage Plugin



或者



Network Plugin


:对存储跟网络进行管理






OS

上去创建容器所需要运行的环境,最终把容器或者

Pod

运行起来,也需要对存储跟网络进行管理。

Kubernetes

并不会直接进行网络存储的操作,他们会靠

Storage Plugin

或者

Network Plugin

来进行操作。用户自己或者云厂商都会去写相应的

Storage Plugin

或者



Network Plugin

,去完成存储操作或网络操作。
















Kube-proxy




负责为Service

提供cluster

内部的服务发现和负载均衡,

完成

service

组网










Kubernetes

自己的环境中,也会有

Kubernetes



Network

,它是为了提供

Service network

来进行搭网组网的。真正完成

service

组网的组件是

Kube-proxy

,它是利用了

iptable

的能力来进行组建

Kubernetes



Network

,就是

cluster network
























组件间的通信







步骤说明:


1.

通过

UI

或者

CLI

提交

1



Pod



Kubernetes

进行部署,这个

Pod

请求首先会提交给

API Server

,下一步

API Server

会把这个信息写入到存储系统

etcd

,之后

Scheduler

会通过

API Server



watch

机制得到这个信息:有

1



Pod

需要被调度。






























2. Scheduler

会根据

node

集群的内存状态进行

1

次调度决策,在完成这次调度之后,它会向

API Server

报告:

“OK

!这个

Pod

需要被调度到

XX

节点上。

















API Server

接收后,会把这次的操作结果再次写到

etcd

中。




3. API Server

通知相应的节点进行这个

Pod

真正的执行启动。相应节点的

kubelet

会得到通知,然后

kubelet

会去调

Container runtime

来真正去启动配置这个容器和这个容器的运行环境,去调度

Storage Plugin

来去配置存储,

network Plugin

去配置网络。















三、Kubernetes

核心概念



第一个概念:

Pod


Pod



Kubernetes

的最小调度以及资源单元。可以通过

Kubernetes



Pod API

生产一个

Pod

,让

Kubernetes

对这个

Pod

进行调度,也就是把它放在某一个

Kubernetes

管理的节点上运行起来。

一个



Pod



简单来说是对一组容器的抽象,它里面会包含一个或多个容器




















比如下图,它包含了两个容器,每个容器可以指定它所需要资源大小


当然,在这个

Pod

中也可以包含一些其他所需要的资源:比如说我们所看到的

Volume

卷这个存储资源。






第二个概念:Volume


管理

Kubernetes

存储,用来声明在

Pod

中的容器可以访问的文件目录,一个卷可以被挂载在

Pod

中一个或者多个容器的指定路径下面。









Volume

本身是一个抽象的概念,一个

Volume

可以去支持多种的后端的存储。

Kubernetes



Volume

支持很多存储插件,可以支持本地的存储和分布式的存储,比如像

ceph



GlusterFS

;也可以支持云存储,比如阿里云上的云盘、

AWS

上的云盘、

Google

上的云盘等等。


















第三个概念:Deployment


Deployment

是在

Pod

上更为上层的一个抽象,它可以定义一组

Pod

的副本数目、以及

Pod

的版本。一般用

Deployment

来做应用的真正的管理,而

Pod

是组成

Deployment

最小的单元。














Kubernetes

通过

Controller

(控制器)维护

Deployment



Pod

的数目,

Controller

也会去帮助

Deployment

自动恢复失败的

Pod
















比如,可以定义一个

Deployment

,这个

Deployment

里面需要

2



Pod

,当

1



Pod

失败的时候,控制器就会监测到,再去新生成

1



Pod

,把

Deployment

中的

Pod

数目从

1

个恢复到

2

个。通过控制器,也可以完成发布策略,比如进行滚动升级、重新生成的升级或者进行版本回滚。


























第四个概念:Service


Service



提供



1



个或者多个



Pod



实例的稳定访问地址







比如,一个

Deployment

可能有

2

个甚至更多个完全相同的

Pod

。对于外部的用户来讲,访问哪个

Pod

都是一样的,所以希望做一次负载均衡,在做负载均衡的同时,只需要访问某一个固定的

VIP

,也就是

Virtual IP

地址,而不需要得知每一个具体的

Pod



IP

地址。

















如果

1



Pod

失败了,可能会换成另外一个新的。提供了多个具体的

Pod

地址,对外部用户来说,要不停地去更新

Pod

地址。当这个

Pod

再失败重启之后,如果有一个抽象,把所有

Pod

的访问能力抽象成

1

个第三方的

IP

地址,实现这个的

Kubernetes

的抽象就叫

Service























实现

Service

有多种入口方式:





  • ClusterIP:

    Service 在集群内的唯一

    ip 地址,我们可以通过这个

    ip,均衡的访问到后端的

    Pod,而无须关心具体的

    Pod。






  • NodePort:

    Service 会在集群的每个

    Node 上都启动一个端口,我们可以通过任意

    Node 的这个端口来访问到

    Pod。




  • LoadBalancer

    :在 NodePort

    的基础上,借助公有云环境创建一个外部的负载均衡器,并将请求转发到 NodeIP:NodePort




  • ExternalName

    :将服务通过 DNS CNAME

    记录方式转发到指定的域名(通过 spec.externlName

    设定)







第五个概念:Namespace


Namespace

:用来做一个集群内部的逻辑隔离,包括鉴权、资源管理等。

Kubernetes

的每个资源,比如

Pod



Deployment



Service

都属于一个

Namespace

,同一个

Namespace

中的资源需要命名的唯一性,不同的

Namespace

中的资源可以重名。
















K8S






API


Kubernetes API

是由

HTTP+JSON

组成的:用户访问的方式是

HTTP

,访问

API



content

的内容是

JSON

格式的。














Kubectl

命令、

Kubernetes UI

或者

Curl

,直接与

Kubernetes

交互都是使用

HTTP + JSON

的形式。











如下图,对于这个

Pod

类型的资源,它的


HTTP



访问的路径就是



API




apiVesion: V1,

之后是相应的

Namespaces

,以及

Pods

资源,最终是

Podname

,也就是

Pod

的名字。

















当提交一个

Pod

,或者

get

一个

Pod

的时候,它的

content

内容都是用

JSON

或者是

YAML

表达的。上图中

YAML

的例子,在这个

YAML

文件中,对

Pod

资源的描述分为几个部分。



















第一个部分,一般是

API



version

。比如在这个例子中是

V1

,它也会描述我在操作哪个资源;

kind

如果是

pod

,在

Metadata

中,就写上这个

Pod

的名字;比如

nginx

。也会给

pod

打一些

label

,在

Metadata

中,有时候也会去写

annotation

,也就是对资源的额外的一些用户层次的描述。

























比较重要的一个部分叫

Spec



Spec

也就是希望

Pod

达到的一个预期的状态。比如

pod

内部需要有哪些

container

被运行;这里是一个

name



nginx



container

,它的

image

是什么?它暴露的

port

是什么?





















当从

Kubernetes API

中去获取这个资源的时候,一般在

Spec

下面会有一个

status

字段


,它表达了这个资源当前的状态;比如一个

Pod

的状态可能是正在被调度、或者是已经

running

、或者是已经被

terminates

(被执行完毕)。















Label

是一个比较有意思的

metadata

,可以是一组

KeyValue

的集合。






如下图,第一个

pod

中,

label

就可能是一个

color

等于

red

,即它的颜色是红颜色。当然也可以加其他

label

,比如说

size: big

就是大小,定义为大的,它可以是一组

label

















这些

label

是可以被

selector

(选择器)所查询的。就好比

sql

类型的

select

语句。









通过

label



kubernetes



API

层就可以对这些资源进行筛选。







例如,

Deployment

可能代表一组

Pod

,是一组

Pod

的抽象,一组

Pod

就是通过

label selector

来表达的。当然

Service

对应的一组

Pod

来对它们进行统一的访问,这个描述也是通过

label selector

来选取的一组

Pod






















四、Depolyment

部署pod

操作




屏幕。。。

猜你喜欢
本类排行