Kubernetes杂记

两个月前我在看《k8s in action》这本书,因为中间有段时间比较忙,没有能认真看完。最近准备开始重新学习,并打算以深入到部分组件源码的方式来学习。不过看源码之前,我还是想再理清一下k8s的相关知识点,同时也能更好理解一下其设计思想。

我发现《k8s in action》这本书真的很好,很多理念都阐述得非常清楚,并在每章末尾附上了那一章的知识总结。当你需要回忆一下某个章节的大致内容时,只需要到那一章的末尾看看Summary那一节就可以了。把所有章节的总结内容放在一起,就基本概括了Kubernetes的大部分知识点。因此,下面我将书中这些总结性的文字大致翻译过来,以便于经常回顾这些知识点和设计理念,但你看起来,就是没有系统没有逻辑的内容,因为都是一个个的知识点,没有连成线、画成面。

1

单体应用容易部署,但随着时间的推移变得难维护,甚至不可扩展。

基于微服务的应用架构可以让每个组件更容易部署,但难以配置和部署让应用运行起来像一个单一的系统。

Linux容器提供了传统虚拟机相似的好处,但更轻量级,硬件资源利用率更高。

Docker给之前已有的Linux容器技术带来的变化是,增加了容器应用的部署速度和降低部署复杂性。

Kubernetes把整个数据中心抽象成一个资源池提供给应用程序。

开发者可以将应用部署到Kubernetes集群上,不需要运维人员辅助。

Kubernetes具有failover功能,系统运维人员可以睡好觉。

2

Pod可以运行多个进程,就像在没有容器时候的物理主机一样。

使用YAML或JSON描述符来创建Pod,然后可以查看Pod状态。

Lable和Lable Selector是用来组织Pod,并使得对多个Pod进行操作变得容易,同时可以将Pod调度到满足某些特性的节点。

Annotations允许将更大块的数据附加到Pod,无论是通过人为手动的,还是通过工具或者类库。

Namespaces使得不同的team可以共享同一个Kubernetes集群,而看起来却像是在使用不同的集群一样。

你可以指定liveness探测方法,让Kubernetes在你的容器处于非健康状态(是否健康,由你的应用来定义)时重启。

3

不要直接创建Pod,这样它们会在误删除、节点失效时得不到重建。ReplicationController总是保证正在运行的Pod数等于所指定的数目。Pod的水平扩展就是修改ReplicationController上指定的副本数那么简单。

Pod不被ReplicationController拥有,如需,可在ReplicationController键进行迁移。

ReplicationController通过Pod的模板来创建一个新的Pod,修改模板对已经在运行的Pod没有影响。

ReplicationController应该被ReplicaSet和Deployment替代,它们具有相同的功能,并有额外更强的特性。

ReplicationController和ReplicaSet将Pod随机调度到某个节点,而DaemonSet保证每个节点上都运行单一实例的Pod,Pod在DaemonSet中定义。

运行批处理的Pod可以通过Kubernetes的Job资源来创建,而不是直接使用ReplicationController创建。

需要偶尔或定时运行的Jobs,可通过CronJob资源来创建。

4

将匹配某个Lable selector的多个Pod通过单一的IP、端口暴露出去。

从集群外部访问Service,需要将Service的type设置为NodePort或者LoadBalancer。

Pod可以通过环境变量来找到Service的IP和端口。

通过一个Ingress暴露多个HTTP Service。

使用Pod容器的readiness探测来决定一个Pod是否应该包含在service endpoints中。

创建一个包含多个容器的Pod,并让这些容器操作同一个文件的方法是给这个Pod添加一个Volume并mount到每一个容器中。

使用emptyDir卷来保存临时的、非持久化的数据,使用gitRepo卷来让某个目录在Pod启动时被填充以Git仓库上的内容。

使用hostPath卷来访问位于主机上的文件。

将外部存储mount到一个卷,这样这些数据在Pod重启后依然存在。

将Pod和存储设施解耦的办法,是使用PersistentVolumes和PersistentVolumeClaims。

将配置信息放到ConfigMap,使得配置和Pod的模板解耦。

将敏感的数据信息保持在Secret以便安全传送到容器内部。创建一个Docker-registry Secret,并使用它从私有镜像库中拉取镜像。

通过maxSurge和maxUnavailable来控制滚动更新的比率。

5

API Server的客户包括用户(人)和运行在Pod中的应用。

运行在Pod的应用都有一个ServiceAccount。

Users、ServiceAccount和groups关联。默认的,Pod运行在默认的ServiceAccount下,这是默认为每个namespace创建的。也已创建额外的ServiceAccount并与Pod关联。

Roles和ClusterRoles定义了对每个resource可进行的操作。

RoleBindings和ClusterRoleBindings将Role和ClusterRoles绑定到users、groups、ServiceAccounts。每个Cluster都具有默认的ClusterRoles和默认的ClusterRoleBindings。

6

Pod可以使用节点的Linux 命名空间而不是自己的。

容器可以被配置成以某个user/group的身份运行,而不是用定义在容器镜像中的身份。

容器可以运行在privileged模式,可以直接访问所在节点的设备。容器可以只读运行,这样就无法往其文件系统写东西。

集群级别的PodSecurityPolicy资源可以限制用户创建对主机节点有安全威胁的Pod。

NetworkPolicy用来限制Pod的进、出网络包。

7

根据容器的CPU需求,未使用的CPU时间会被分配给容器,容器不会因为使用CPU过多而被杀掉,但会因为使用内存过多被杀掉。

在运行overcommit的系统,容器可能会被杀掉以释放内存给更重要的Pod使用,具体是由Pod的QoS级别和真实内存使用情况来决定。

可以使用LimitRange对象来定义一个Pod最小、最大和默认的资源需求。

可以使用ResourceQuota对象来限制一个命名空间内所有Pod对资源的需求。

要使得Pod可自动横向扩展,可通过创建一个HorizontalPodAutoscaler对象并将其指向Deployment、ReplicaSet或ReplicationController并指定Pod对CPU的需求,同时还可以进行条件的自定义,然后在满足条件时自动伸缩。目前不支持Pod垂直扩展。

8

自定义资源可以通过创建CustomResourceDefinition对象来注册到API Server。自定义对象可被存储、更新、返回、删除,同时需要一个自定义的controller来让这些对象得以生成。

Helm是一个包管理器,它使得部署已经存在的应用时不需要你构建资源的manifest,其实就是类似于yum。

微信扫码,进入【技术人成长】社群逛逛。