一、引言

目录

一、引言

Kubernetes(K8S)基本概念

K8S是什么?

K8S对象管理

对象规约(Spec)与状态(Status) 

标签和选择算符

理解命名空间

名字空间

何时使用多个名字空间

三、尝试使用K8S管理容器

容器化的工作负载


原本的学习知识可能偏重于IaaS平台的内容,比如说OpenStack或者说VMware这样的技术,会接触到更多虚机层面的东西。因为IaaS解决的东西是怎样将物理的算力和存储网络资源,转化成可以直接被上游操作系统调用的虚拟资源,相当于从物理主机转化为虚拟主机。 

但由于近期工作接触PaaS平台的内容越来越多,在容器化的基础上引入了更为丰富的容器管理机制,所以自然也就绕不开当前的主流选择Kubernetes(下文简称K8S)。PaaS平台上,开发者仅需要关注上层运行的数据,以主流的容器引擎docker为例,开发者仅需提供一个cimage镜像还有一个描述容器资源的文件,就可以在PaaS平台上部署自己的应用。

本文会简单地对K8S当前的容器管理机制做一个学习记录,非常粗浅,看看就好。

======================正文分割线 更新中==========================

二、Kubernetes(K8S)基本概念

K8S是什么?

借用官方的定义,描述如下。

Kubernetes 是一个可移植的,可扩展的开源平台,用于管理容器化的工作负载和服务,方便了声明式配置和自动化。它拥有一个庞大且快速增长的生态系统。Kubernetes 的服务,支持和工具广泛可用。

我们主要关注K8S的管理对象,这里有2个关键的点,“工作负载”和“服务”,下面会分别进行解释。

另外就是声明式配置和自动化,后面只要看到容器是如何在K8S上完成部署的,就可以理解这两个特性的概念。

K8S对象管理

在谈具体的容器管理之前,我们先认识一下什么是K8S对象,这是一个更为基础的概念。

引用官方文档说明如下是:

在 Kubernetes 系统中,Kubernetes 对象 是持久化的实体。 Kubernetes 使用这些实体去表示整个集群的状态。特别地,它们描述了如下信息:

  • 哪些容器化应用在运行(以及在哪些节点上)
  • 可以被应用使用的资源
  • 关于应用运行时表现的策略,比如重启策略、升级策略,以及容错策略

也就是说,K8S对象是用来表现整个集群状态的实体,实现了K8S对容器化应用的管理。

K8S管理的核心对象就是容器化的应用,而K8S对象则是被定义出来用于管理容器化应用的实体。

K8S对象的基本特征

引用官方文档说明如下:

对象规约(Spec)与状态(Status) 

几乎每个 Kubernetes 对象包含两个嵌套的对象字段,它们负责管理对象的配置: 对象 spec(规约) 和 对象 status(状态) 。 对于具有 spec 的对象,你必须在创建对象时设置其内容,描述你希望对象所具有的特征: 期望状态(Desired State) 。

status 描述了对象的 当前状态(Current State),它是由 Kubernetes 系统和组件 设置并更新的。在任何时刻,Kubernetes 控制平面 都一直积极地管理着对象的实际状态,以使之与期望状态相匹配。

顺便延伸一下K8S提出的这个控制器的概念,也是比较有意思的。

控制器

在机器人技术和自动化领域,控制回路(Control Loop)是一个非终止回路,用于调节系统状态。

这是一个控制环的例子:房间里的温度自动调节器。

当你设置了温度,告诉了温度自动调节器你的期望状态(Desired State)。 房间的实际温度是当前状态(Current State)。 通过对设备的开关控制,温度自动调节器让其当前状态接近期望状态。

在 Kubernetes 中,控制器通过监控集群 的公共状态,并致力于将当前状态转变为期望的状态。

如何描述K8S对象

核心就是如何定义一个对象的期望状态基本信息,引用官方文档说明如下:

创建 Kubernetes 对象时,必须提供对象的规约,用来描述该对象的期望状态, 以及关于对象的一些基本信息(例如名称)。 当使用 Kubernetes API 创建对象时(或者直接创建,或者基于kubectl), API 请求必须在请求体中包含 JSON 格式的信息。 大多数情况下,需要在 .yaml 文件中为 kubectl 提供这些信息。 kubectl 在发起 API 请求时,将这些信息转换成 JSON 格式。

这里有一个 .yaml 示例文件,展示了 Kubernetes Deployment 的必需字段和对象规约:

application/deployment.yaml 

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2 # tells deployment to run 2 pods matching the template
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80

标签和选择算符

标签就是一个加到K8S对象上的键值对,用于标识这个对象的特征。不同的对象在交互时,可以使用对应的标签进行匹配,且可以设置匹配规则。举例来说,一个容器能不能在对应的节点被调度起来,就可以通过选择算符在节点和pod之间的标签匹配关系进行选择。

选择算符在这里不展开说,直接参考官方文档,简单来说就是以下4种算符

1)等于

2)不等于

3)在..范围内

4)不在..范围内

引用官方文档说明如下

标签(Labels) 是附加到 Kubernetes 对象(比如 Pods)上的键值对。 标签旨在用于指定对用户有意义且相关的对象的标识属性,但不直接对核心系统有语义含义。 标签可以用于组织和选择对象的子集。标签可以在创建时附加到对象,随后可以随时添加和修改。 每个对象都可以定义一组键/值标签。每个键对于给定对象必须是唯一的。

"metadata": {
  "labels": {
    "key1" : "value1",
    "key2" : "value2"
  }
}

理解命名空间

简单的来说,引用虚拟化的概念,命名空间也可以被叫做租户tenant。不同的命名空间之间是逻辑隔离的,不同的命名空间中会管理各自的容器化应用。

引用官方文档说明如下

名字空间

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

何时使用多个名字空间

名字空间适用于存在很多跨多个团队或项目的用户的场景。对于只有几到几十个用户的集群,根本不需要创建或考虑名字空间。当需要名称空间提供的功能时,请开始使用它们。

名字空间为名称提供了一个范围。资源的名称需要在名字空间内是唯一的,但不能跨名字空间。 名字空间不能相互嵌套,每个 Kubernetes 资源只能在一个名字空间中。

名字空间是在多个用户之间划分集群资源的一种方法(通过资源配额)。

不必使用多个名字空间来分隔仅仅轻微不同的资源,例如同一软件的不同版本: 应该使用标签 来区分同一名字空间中的不同资源。

到这里为止,一些基本的概念就已经阐述完毕,下面我们开始实操。

三、尝试使用K8S管理容器

Kubernetes 提供若干种内置的工作负载资源:

  • Deployment 和 ReplicaSet (替换原来的资源 ReplicationController)。 Deployment 很适合用来管理你的集群上的无状态应用Deployment 中的所有 Pod 都是相互等价的,并且在需要的时候被换掉。Deployment可以将集群上的pod维护在一个符合期望的状态

  • StatefulSet 让你能够运行一个或者多个以某种方式跟踪应用状态的 Pods,适合用于管理集群上的有状态应用(比如MongDB、Kafka)。 例如,如果你的负载会将数据作持久存储,你可以运行一个 StatefulSet,将每个 Pod 与某个 PersistentVolume 对应起来。你在 StatefulSet 中各个 Pod 内运行的代码可以将数据复制到同一 StatefulSet 中的其它 Pod 中以提高整体的服务可靠性。

  • DaemonSet 定义提供节点本地支撑设施的 Pods。这些 Pods 可能对于你的集群的运维是 非常重要的,例如作为网络链接的辅助工具或者作为网络 插件 的一部分等等。每次你向集群中添加一个新节点时,如果该节点与某 DaemonSet 的规约匹配,则控制面会为该 DaemonSet 调度一个 Pod 到该新节点上运行。这些Pod仅在每个节点上调度运行1个副本,所以非常适合用于监控日志以及网络插件等应用的部署。

  • Job 和 CronJob。 定义一些一直运行到结束并停止的任务。Job 用来表达的是一次性的任务,而 CronJob 会根据其时间规划反复运行。

容器化的工作负载

首先,截取一张K8S dashboard的图片,能够看到首页展示的前两个重要资源就是Workloads和Service,下面我们就先看一下workload是究竟是个啥。

能够看到,这里能够查看对应的workload资源,包含如上描述的各类内置类型资源,但由于这是1个空环境所以没有东西。

参考官方文档,Basic controls | minikube

我们尝试部署1个deoloyment资源hello-minikube

同样,在dashboard的界面也能够看到,1个Replica Set类型的workload被部署在default的命名空间下,关联了1个pod ,但部署失败了。

想要进一步查看部署失败的原因,就需要查看pod部署失败的原因,主要关注pod描述中的events,这些内容在dashboard中也可以看到。

[wangjunjie@localhost Documents]$ kubectl  get pod
NAME                              READY   STATUS             RESTARTS   AGE
hello-minikube-7bc9d7884c-zjns4   0/1     ImagePullBackOff   0          7m58s
[wangjunjie@localhost Documents]$ kubectl describe pod hello-minikube-7bc9d7884c-zjns4

报错很明显,Failed to pull image "k8s.gcr.io/echoserver:1.4",下载镜像失败,因为国内的网络是不同的,导致容器无法被正常拉起。

无法直接在国内网络环境下从k8s.gcr.io下载镜像问题 - 散尽浮华 - 博客园

这次改成使用国内的阿里代理仓库进行创建,即可创建成功。能够看到,这样创建出来的容器是没有对外暴露端口的。

kubectl create deployment hello-minikube --image=registry.aliyuncs.com/google_containers/echoserver:1.4

 

Logo

开源、云原生的融合云平台

更多推荐