浅谈K8S的容器管理
原本的学习知识可能偏重于IaaS平台的内容,比如说OpenStack或者说VMware这样的技术,会接触到更多虚机层面的东西。因为IaaS解决的东西是怎样将物理的算力和存储网络资源,转化成可以直接被上游操作系统调用的虚拟资源,相当于从物理主机转化为虚拟主机。但由于近期工作接触PaaS平台的内容越来越多,在容器化的基础上引入了更为丰富的容器管理机制,所以自然也就绕不开当前的主流选择Kubernete
一、引言
目录
原本的学习知识可能偏重于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 的必需字段和对象规约: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
更多推荐
所有评论(0)