Kubernetes从零开始

本文最后更新于:2021年5月27日 晚上

本篇blog记录本人学习Kubernetes的全过程,参考资料为官方教程 和 *YouTube教程*。

Kubernetes是什么

本节我们介绍Kubernetes中的若干基本概念,包括control plane, node和could controller manager。

Kubernetes是用来管理container的,container和虚拟机(VM)功能类似,但是更加轻量。

Similar to a VM, a container has its own filesystem, share of CPU, memory, process space, and more. As they are decoupled from the underlying infrastructure, they are portable across clouds and OS distributions.

各个部署方式的示意图如下:

部署方式

可以看到,VM有自己的OS,一个虚拟的完整系统,而container是在OS的上层部署的。

一些基本概念:

  1. Node:一个节点,每个node可以是一台真实的计算机,也可以是一个虚拟机(Virtual machine)。
  2. Cluster:若干node的集合,一个cluster可以只有一个node。
  3. Pods:Cluster中运行的若干container的集合。
  4. Control plane:Control plane用于管理node和Pods。

Control plane是什么

Control plane用来做一些全局的决策,并对系统中发生的事件进行响应。理论上control plane可以部署在任何一台机器上,但习惯上所有control plane都会集中部署在一台机器上。

Control plane由以下几个部分组成:

  1. kube-apiserver:API server是Kubernetes的前端,它提供API与cluster交互,是control plane的主要部件。
  2. etcd:Kubernetes的后端,提供key-value store来存储cluster数据。
  3. kube-scheduler:给Pod分配node。
  4. kube-controller-manager:用于运行各种controller(后面会讲什么是controller),比如用于通知node挂掉了的controller。
  5. cloud-controller-manager:用于管理跟cloud相关的部分。

Controller是什么

上面提到我们可以用kube-controller-manager管理controller,这里介绍一下controller是什么。

在自动化领域,control loop是一个不终止的负反馈调节过程,它控制着系统state的变化。举个例子,某间房屋需要维持特定的温度(desired state),可以让一个controller通过不断开关温度调节设备让房屋的当前温度(current state),从而不断靠近目标温度(desired state)。

Kubernetes中的controller同样会将cluster中的一些state维持在desired state附近。Controller可以通过API server控制,也可以直接控制。

Node是什么

一个node既可以是一台真正的计算机,也可以是virtual machine。每个node中包含以下组件:

  1. kubelet:确保所有container在Pod中成功运行。
  2. kube-proxy:node上的网络代理。
  3. Container runtime: 管理运行中的container,支持Docker, containerd, CRI-O等

Node的注册

我们有两种添加node的方法:

  1. 使用kubelet向API server进行self-registration
  2. 手动添加

Node被创建后,kube-apiserver会检查metadata.name是否匹配。name是该node的标识符,它必须是个DNS Subdomain,且必须唯一。之后,系统会不断检查该node是否成功运行了相关服务。当所有的相关服务都成功运行,该node才会被允许在Pod上运行。

Self-registration:kubelet中--register-node的默认值为true(推荐用默认值),这代表kubelet会尝试向向control plane进行self-register。

Self-registration的相关选项有--kubeconfig、 --cloud-provider--register-node--register-with-taints--node-ip--node-labels

手动添加:我们可以使用 kubectl这个命令行工具手动创建node,此时--register-node的值为false.

Node的status

使用以下命令查看node的status,包括node的Address、Condition(Ready/DiskPressure…)、Capacity and Allocatable(可用资源情况——CPU、内存、Pod数量)和Info(一些通用信息)

1
kubectl describe node <node name>

Node controller

Node controller属于control plane中controller的一种,它有三个作用:

  1. 如果启用了CIDR分配,负责分配CIDR block。
  2. 如果用了cloud,保证Node controller里记录的node在cloud上都是可用的。如果不可用,则将其从记录里删除。
  3. 监控node的健康。

Heartbeats

Node需要不断发送hearbeat报告自己是否存活。有两种heartbeat——NodeStatus以及Lease对象,它们都由kubelet管理。其中,NodeStatus默认每5分钟更新一次,Lease默认每10秒更新一次。

Reliability,Node capacity,Node topology、Graceful node shutdown

Cloud Controller Manager是什么

Kubernetes致力于将管理cloud相关的功能与管理cluster本身的功能解耦。其中,与cloud相关的控制逻辑在control plance中的cloud-controller-manager(c-c-m)里实现。c-c-m以插件的形式存在,并与cloud提供者的API交互。

Kubernetes架构

c-c-m包括以下controller:

  • Node controller:在cloud中创建node,记录could相关信息,获取node的hostname和network address,获取node的健康状态。
  • Route controller:配置路由,使node间可以通信。
  • Service controller:Service在若干Pods上运行,它将Pods对外暴露为network service。Cloud上会提供load balancing、network packet filtering之类的功能。我们使用service controller和could上这些功能的API交互。

基础操作入门

创建一个cluster

Cluster中包含两种资源,control plane和node。其中,

  • Control plane用来管理cluster中的所有活动,我们使用Control plane中的API server与node进行交互。
  • 每个Node是一台虚拟机或真实计算机。每个node中都有一个Kubelet,用来管理node,以及和control plane交互。Node中也需要支持container相关操作的工具,如containerd和Docker。

示意图如下:

Control plane和node拓扑结构

现在我们用Minikube来入门Kubernetes。Minikube比真正的Kubernetes简单,它会在本地创建只包含一个node的cluster。

使用以下命令启动minikube

1
minikube start

我们使用kubectl来和Kubernetes交互,使用以下命令查看cluster信息

1
kubectl cluster-info

使用以下命令查看node信息

1
kubectl get nodes

kubebtl命令

部署一个App

为了部署containerized application,我们需要配置Deployment controller。它告诉系统如何创建和更新app的实例,并且不断监视app所在的node的状态。当node不可用时,Deployment controller会在›可用的node中再次创建App的instance。

Deployment controller

我们仍然使用Kubectl创建Deployment。kubectl是一个命令行工具,它的基本

语法是:

1
kubectl <action> <resource>

其中,action是要执行的操作,如reate和describe;而resource指定了要操作的资源,如node和container。我们可以在每条kubectl命令后添加--help(如kubectl get nodes --help),来学习这条命令的参数。

使用以下命令创建Deployment:

1
kubectl create deployment <deployment name> <app image location>

Deployment

上图中,我们将新建的Deployment命名为kubernetes-bootcamap,并且指定了一个已有的app image。在执行这条命令时,Kubernetes做了以下几件事:

  1. 找到可用的node
  2. 在node中部署app
  3. 进行了一些设置,使得当该node不再可用时,可以寻找新的可用node

使用以下命令查看已有的Deployment:

1
kubectl get deployments

Deployment

Pod默认情况下只能对同一个cluster内的其他pods可见。

kubectl可以创建一个proxy,用来在cluster中通讯。为此,我们需要新开一个terminal,并键入以下命令:

1
kubectl proxy

另外,我们可以使用ctrl + c结束当前proxy的运行。

image-20210517164635148

当这个proxy在运行时,我们可以在当前host(当前的terminal)使用它暴露出的API,来和kubernetes通信。例如,下面展示了如何使用curl命令查看其版本:

1
curl http://localhost:8001/version

image-20210517164919618

API server会自动为每个pod创建一个endpoint,这个endpoint可以被proxy访问到。如果不想使用代理(Proxy),我们可以使用Service来提供服务。

写到这里,笔者感觉官方教程不太符合初学者学习路线,但对了解基本概念挺有帮助,下面我们跳转到另一个教程,教程链接是:

https://www.youtube.com/watch?v=X48VuDVv0do

Overview

Container很轻量,为小型的服务(Microservice)提供了方便, 当今的一个服务背后,可能需要数百上千个container共同支持。Kubernetes就是用来支持和管理这些container运行的。Kubernetes提供了high availability(不宕机)、scalability(扩展性)和disaster recovery(备份和恢复数据)。

现在我们来简要了解Kubernetes的组成部分:

Kubernetes组成

Kubernetes(k8s)的组成部件众多,一一介绍对新手不友好。下面我们通过一个运行js服务的例子来了解其中一些主要部件。

Pod

Pod是k8s中所操作的最小单位,是对container的一个封装。通常情况下,每个pod中只有一个app(理论上可以有多个)。每个pod有自己的IP,各个Pod间。但很不方便的是,当这个pod崩溃被重新创建时,该ip会发生变化。Pod崩溃的原因有很多,我们可以认为pod会经常“死亡->重建”。

Pod

Service

为了解决IP变化的问题,我们需要使用Service。Service拥有固定不变的ip,并且可以和pod绑定。

Service与pod绑定

Pod和Service的生命周期不一样,所以即使pod奔溃了,与它绑定的Service还是可用的,这样,我们就能获得一个不变的IP了。

我们并不想将所有的service暴露给外部的资源。在这个例子中,我们想要把包含js服务的service(my-app)暴露给用户,但不想把底层包含数据库(DB)的后端service暴露给外部资源。为此,我们在创建Service的时候就需要指定它是internal的还是external的。

External Service和Internal Service

Ingress

上图中external service的urlhttp://my-app-service-ip:port用起来不方便。例如,它可能是http://124.89.101.2:8080。在对外提供服务时,我们需要提供https://my-app.com这样的url。为此,我们需要用到Ingress。在这种情况下,Ingress被用来接收外部请求,然后再将其转发给Service。

image-20210524170644240

ConfigMap and Secret

如前文所说,pod之间通过service进行通信。在这个例子中,my-app通过和mongo-db-service这个服务通信,实现与数据库的交互。

但是,数据库url的配置一般要用一个属性文件或者一些外部的环境变量。这些相关文件通常会内嵌在这个app的image文件当中。


本网站仅作为个人观点的交流平台,博客中讨论内容及引用书籍都有标注。如疑版权问题,请在评论区留言~
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处~