Kubernetes权威指南:从Docker到Kubernetes实践全接触(第4版)-龚正等
- 书名: Kubernetes权威指南:从Docker到Kubernetes实践全接触(第4版)
- 作者: 龚正等
- 简介: Kubernetes是由谷歌开源的Docker容器集群管理系统,为容器化的应用提供了资源调度、部署运行、服务发现、扩容及缩容等一整套功能。本书从架构师、开发人员和运维人员的角度,阐述了Kubernetes的基本概念、实践指南、核心原理、开发指导、运维指南、新特性演进等内容,图文并茂、内容丰富、由浅入深、讲解全面;并围绕在生产环境中可能出现的问题,给出了大量的典型案例,比如安全配置方案、网络方案、共享存储方案、高可用方案及TroubleShooting技巧等,有很强的实战指导意义。本书内容随着Kubernetes的版本更新不断完善,目前涵盖了Kubernetes从1.0到1.14版本的主要特性,努力为Kubernetes用户提供全方位的Kubernetes技术指南。本书源码已上传至GitHub的kubeguide/K8sDefinitiveGuide-V4-Sourcecode目录,可自行下载本书源码进行练习。无论是对于软件工程师、测试工程师、运维工程师、软件架构师、技术经理,还是对于资深IT人士,本书都极具参考价值。
- 出版时间 2019-05-01 00:00:00
- ISBN: 9787121362354
- 分类: 计算机-理论知识
- 出版社: 电子工业出版社
高亮划线
封面
版权信息
作者介绍
推荐序
自序
第1章 Kubernetes入门
1.2 为什么要用Kubernetes
1.3 从一个简单的例子开始
-
📌 spec.template.metadata. labels指定了该Pod的标签,需要特别注意的是:这里的labels必须匹配之前的spec.selector,否则此RC每创建一个无法匹配Label的Pod,就会不停地尝试创建新的Pod,陷入恶性循环中。 ^8-3155-3282
- ⏱ 2023-02-15 13:51:54
-
📌 根据Service的唯一名称,容器可以从环境变量中获取Service对应的Cluster IP地址和端口,从而发起TCP/IP连接请求。 ^8-6479-6547
- ⏱ 2023-02-15 13:57:02
-
📌 type=NodePort和nodePort=30001的两个属性表明此Service开启了NodePort方式的外网访问模式。在Kubernetes集群之外,比如在本机的浏览器里,可以通过30001这个端口访问myweb(对应到8080的虚端口上) ^8-8211-8336
- ⏱ 2023-02-15 14:00:45
1.4 Kubernetes的基本概念和术语
-
📌 更加优雅的做法是,先采用方法1实现这个新特性,经过几个版本的迭代,等新特性变得稳定成熟了以后,可以在后续版本中采用方法2升级到正式版。为此,Kubernetes为每个资源对象都增加了类似数据库表里备注字段的通用属性Annotations,以实现方法1的升级。 ^9-1989-2118
- ⏱ 2023-02-15 14:15:20
-
📌 Kubernetes集群中的其他机器被称为Node ^9-4641-4666
- ⏱ 2023-02-15 14:17:36
-
📌 Kubernetes要求底层网络支持集群内任意两个Pod之间的TCP/IP直接通信,这通常采用虚拟二层网络技术来实现,例如Flannel、Open vSwitch等,因此我们需要牢记一点:在Kubernetes里,一个Pod里的容器与另外主机上的Pod容器能够直接通信。 ^9-11580-11715
- ⏱ 2023-02-15 14:29:25
-
📌 Pod的IP加上这里的容器端口(containerPort),组成了一个新的概念——Endpoint,它代表此Pod里的一个服务进程的对外通信地址 ^9-13308-13381
- ⏱ 2023-02-15 14:32:03
-
📌 Pod Volume ^9-13524-13534
- ⏱ 2023-02-15 14:40:15
-
📌 这里顺便提一下Kubernetes的Event概念。Event是一个事件的记录,记录了事件的最早产生时间、最后重现时间、重复次数、发起者、类型,以及导致此事件的原因等众多信息。Event通常会被关联到某个具体的资源对象上,是排查故障的重要参考信息,之前我们看到Node的描述信息包括了Event,而Pod同样有Event记录,当我们发现某个Pod迟迟无法创建时,可以用kubectl describe pod xxxx来查看它的描述信息,以定位问题的成因 ^9-13642-13869
- ⏱ 2023-02-15 14:40:26
-
📌 对于绝大多数容器来说,一个CPU的资源配额相当大,所以在Kubernetes里通常以千分之一的CPU配额为最小单位,用m来表示。通常一个容器的CPU配额被定义为100~300m,即占用0.1~0.3个CPU。由于CPU配额是一个绝对值,所以无论在拥有一个Core的机器上,还是在拥有48个Core的机器上,100m这个配额所代表的CPU的使用量都是一样的。与CPU配额类似,Memory配额也是一个绝对值,它的单位是内存字节数 ^9-14625-14838
- ⏱ 2023-02-15 14:41:46
-
📌 Label(标签)是Kubernetes系统中另外一个核心概念。一个Label是一个key=value的键值对,其中key与value由用户自己指定。Label可以被附加到各种资源对象上,例如Node、Pod、Service、RC等,一个资源对象可以定义任意数量的Label,同一个Label也可以被添加到任意数量的资源对象上。Label通常在资源对象定义时确定,也可以在对象创建后动态添加或者删除。 ^9-15996-16196
- ⏱ 2023-02-15 14:50:14
-
📌 当前有两种Label Selector表达式:基于等式的(Equality-based)和基于集合的(Set-based),前者采用等式类表达式匹配标签,下面是一些具体的例子。 ^9-17127-17215
- ⏱ 2023-02-15 15:42:02
-
📌 运行在每个Node上的kube-proxy进程其实就是一个智能的软件负载均衡器,负责把对Service的请求转发到后端的某个Pod实例上,并在内部实现服务的负载均衡与会话保持机制 ^9-35984-36073
- ⏱ 2023-02-15 16:54:09
-
📌 而Service一旦被创建,Kubernetes就会自动为它分配一个可用的Cluster IP,而且在Service的整个生命周期内,它的Cluster IP不会发生改变。于是,服务发现这个棘手的问题在Kubernetes的架构里也得以轻松解决:只要用Service的Name与Service的Cluster IP地址做一个DNS域名映射即可完美解决问题 ^9-36313-36490
- ⏱ 2023-02-15 16:57:23
-
📌 目前,Kubernetes上的大部分应用都已经采用了DNS这种新兴的服务发现机制,后面会讲解如何部署DNS系统 ^9-40956-41011
- ⏱ 2023-02-15 16:47:58
-
📌 PV可以被理解成Kubernetes集群中的某个网络存储对应的一块存储,它与Volume类似,但有以下区别。 ^9-51731-51785
- ⏱ 2023-02-15 17:09:29
-
📌 accessModes属性 ^9-52653-52666
- ⏱ 2023-02-15 17:10:13
-
📌 接下来,Kubernetes提供了一种内建机制,将存储在etcd中的ConfigMap通过Volume映射的方式变成目标Pod内的配置文件,不管目标Pod被调度到哪台服务器上,都会完成自动映射。进一步地,如果ConfigMap中的key-value数据被修改,则映射到Pod中的“配置文件”也会随之自动更新。 ^9-57581-57735
- ⏱ 2023-02-16 15:48:00
-
📌 配置中心 ^9-57797-57801
- ⏱ 2023-02-16 15:48:16
第2章 Kubernetes安装配置指南
2.2 使用kubeadm工具快速安装Kubernetes集群
2.3 以二进制文件方式安装Kubernetes集群
2.4 Kubernetes集群的安全设置
2.5 Kubernetes集群的网络配置
2.6 内网中的Kubernetes相关配置
2.7 Kubernetes的版本升级
2.8 Kubernetes核心服务配置详解
2.9 CRI(容器运行时接口)详解
2.10 kubectl命令行工具用法详解
第3章 深入掌握Pod
3.1 Pod定义详解
3.2 Pod的基本用法
-
📌 Kubernetes系统中对长时间运行容器的要求是:其主程序需要一直在前台执行 ^22-537-576
- ⏱ 2023-02-16 16:03:30
-
📌 Supervisor ^22-1001-1011
- ⏱ 2023-02-16 16:03:54
3.3 静态Pod
3.4 Pod容器共享Volume
3.5 Pod的配置管理
-
📌 通过环境变量获取ConfigMap中的内容 ^25-16731-16752
- ⏱ 2023-02-16 16:47:31
-
📌 通过Volume挂载的方式将ConfigMap中的内容挂载为容器内部的文件或目录。 ^25-16785-16826
- ⏱ 2023-02-16 16:47:35
-
📌 envFrom ^25-19630-19637
- ⏱ 2023-02-16 17:05:14
3.6 在容器内获取Pod信息(Downward API)
3.7 Pod生命周期和重启策略
3.8 Pod健康检查和服务可用性检查
- 📌 对于每种探测方式,都需要设置initialDelaySeconds和timeoutSeconds两个参数,它们的含义分别如下 ^28-3615-3677
- ⏱ 2023-02-17 10:52:22
3.9 玩转Pod调度
-
📌 我们不应该直接使用底层的ReplicaSet来控制Pod副本,而应该使用管理ReplicaSet的Deployment对象来控制副本,这是来自官方的建议 ^29-1651-1727
- ⏱ 2023-02-17 10:56:13
-
📌 NodeAffinity ^29-2429-2441
- ⏱ 2023-02-17 10:57:42
-
📌 在Kubernates 1.9之前,在RC等对象被删除后,它们所创建的Pod副本都不会被删除;在Kubernates 1.9以后,这些Pod副本会被一并删除。如果不希望这样做,则可以通过kubectl命令的--cascade=false参数来取消这一默认特性: ^29-3491-3621
- ⏱ 2023-02-17 11:04:54
-
📌 需要注意的是,如果我们指定了Pod的nodeSelector条件,且在集群中不存在包含相应标签的Node,则即使在集群中还有其他可供使用的Node,这个Pod也无法被成功调度。 ^29-8729-8817
- ⏱ 2023-02-17 11:13:14
-
📌 这种规则可以描述为:如果在具有标签X的Node上运行了一个或者多个符合条件Y的Pod,那么Pod应该(如果是互斥的情况,那么就变成拒绝)运行在这个Node上。 ^29-12542-12621
- ⏱ 2023-02-17 11:54:01
-
📌 Taint则正好相反,它让Node拒绝Pod的运行。 ^29-17905-17931
- ⏱ 2023-02-17 11:59:55
3.10 Init Container(初始化容器)
- 📌 init container与应用容器在本质上是一样的,但它们是仅运行一次就结束的任务,并且必须在成功执行完成后,系统才能继续执行下一个容器 ^30-878-948
- ⏱ 2023-02-17 14:15:29
3.11 Pod的升级和回滚
3.12 Pod的扩缩容
3.13 使用StatefulSet搭建MongoDB集群
第4章 深入掌握Service
4.1 Service定义详解
4.2 Service的基本用法
- 📌 这时可以通过创建一个无Label Selector的Service来实现: ^36-7579-7616
- ⏱ 2023-02-17 14:55:55
4.3 Headless Service
4.4 从集群外部访问Pod或Service
4.5 DNS服务搭建和配置指南
4.6 Ingress:HTTP 7层路由机制
- 📌 从Kubernetes 1.1版本开始新增Ingress资源对象,用于将不同URL的访问请求转发到后端不同的Service,以实现HTTP层的业务路由机制 ^40-602-679
- ⏱ 2023-12-01 15:45:03
第5章 核心组件运行机制
5.2 Controller Manager原理解析
5.3 Scheduler原理解析
5.4 kubelet运行机制解析
5.5 kube-proxy运行机制解析
第6章 深入分析集群安全机制
6.1 API Server认证管理
6.2 API Server授权管理
6.3 Admission Control
6.4 Service Account
6.5 Secret私密凭据
6.6 Pod的安全策略配置
第7章 网络原理
7.1 Kubernetes网络模型
-
📌 IP是以Pod为单位进行分配的 ^54-654-669
- ⏱ 2023-02-17 16:14:46
-
📌 Pod都能够被看作一台独立的虚拟机或物理机。 ^54-1804-1826
- ⏱ 2023-02-17 16:17:17
-
📌 有很多开源组件可以帮助我们打通Docker容器和容器之间的网络,实现满足Kubernetes要求的网络模型。当然,每种方案都有适合的场景,我们要根据自己的实际需要进行选择。 ^54-2618-2704
- ⏱ 2023-02-17 16:22:24
7.2 Docker网络基础
-
📌 在Linux的网络命名空间中可以有自己独立的路由表及独立的iptables设置来提供包转发、NAT及IP包过滤等功能。 ^55-868-927
- ⏱ 2023-02-17 16:24:39
-
📌 物理设备(连接实际硬件的设备)通常只能关联到root这个命名空间中。虚拟的网络设备(虚拟的以太网接口或者虚拟网口对)则可以被创建并关联到一个给定的命名空间中,而且可以在这些命名空间之间移动 ^55-2108-2202
- ⏱ 2023-02-17 16:29:10
-
📌 Veth设备对的一个重要作用就是打通互相看不到的协议栈之间的壁垒,它就像一条管子,一端连着这个网络命名空间的协议栈,一端连着另一个网络命名空间的协议栈。所以如果想在两个命名空间之间通信,就必须有一个Veth设备对 ^55-2356-2462
- ⏱ 2023-02-17 16:32:12
-
📌 具体哪些设备能被转移到不同的命名空间呢?在设备里面有一个重要的属性:NETIF_F_ ETNS_LOCAL,如果这个属性为on,就不能被转移到其他命名空间中。Veth设备属于可以转移的设备,而很多其他设备如lo设备、vxlan设备、ppp设备、bridge设备等都是不可以转移的。将无法转移的设备移动到别的命名空间时,会得到无效参数的错误提示。 ^55-3373-3545
- ⏱ 2023-02-17 16:33:59
-
📌 在Docker的实现里面,它除了将Veth放入容器内,还将它的名字改成了eth0,简直以假乱真,你以为它是一个本地网卡吗 ^55-7543-7603
- ⏱ 2023-02-17 16:40:29
-
📌 一旦将Veth设备对的对端放入另一个命名空间,在本命名空间中就看不到它了。那么我们怎么知道这个Veth设备的对端在哪里呢,也就是说它到底连接到哪个命名空间呢?可以使用ethtool工具来查看(当网络命名空间特别多时,这可不是一件很容易的事情)。首先,在命名空间netns1中查询Veth设备对端接口在设备列表中的序列号: ^55-9169-9405
- ⏱ 2023-12-01 21:41:52
-
📌 Linux内核支持网口的桥接(目前只支持以太网接口)。但是与单纯的交换机不同,交换机只是一个二层设备,对于接收到的报文,要么转发,要么丢弃。运行着Linux内核的机器本身就是一台主机,有可能是网络报文的目的地,其收到的报文除了转发和丢弃,还可能被送到网络协议栈的上层(网络层),从而被自己(这台主机本身的协议栈)消化,所以我们既可以把网桥看作一个二层设备,也可以把它看作一个三层设备。 ^55-10613-10805
- ⏱ 2023-12-01 21:51:49
-
📌 如图7.3所示,网桥设备br0绑定了eth0和eth1。对于网络协议栈的上层来说,只看得到br0就行。因为桥接是在数据链路层实现的,上层不需要关心桥接的细节,所以协议栈上层需要发送的报文被送到br0,网桥设备的处理代码判断报文该被转发到eth0还是eth1,或者两者皆转发;反过来,从eth0或从eth1接收到的报文被提交给网桥的处理代码,在这里会判断报文应该被转发、丢弃还是被提交到协议栈上层。 ^55-11271-11469
- ⏱ 2023-12-01 21:57:53
-
📌 Netfilter负责在内核中执行各种挂接的规则,运行在内核模式中;而iptables是在用户模式下运行的进程,负责协助和维护内核中Netfilter的各种规则表。二者互相配合来实现整个Linux网络协议栈中灵活的数据包处理机制。 ^55-12706-12821
- ⏱ 2023-12-01 22:02:44
-
📌 当Linux协议栈的数据处理运行到挂接点时,它会依次调用挂接点上所有的挂钩函数,直到数据包的处理结果是明确地接受或者拒绝 ^55-13805-13865
- ⏱ 2023-02-17 17:29:18
-
📌 在通常情况下,如果主机与目的主机直接相连,那么主机可以直接发送IP报文到目的主机,这个过程比较简单。例如,通过点对点的链接或网络共享,如果主机与目的主机没有直接相连,那么主机会将IP报文发送给默认的路由器,然后由路由器来决定往哪里发送IP报文。 ^55-15148-15270
- ⏱ 2023-12-01 22:04:36
-
📌 当从网络侧接收到数据报文时,IP层首先会检查报文的IP地址是否与主机自身的地址相同。如果数据报文中的IP地址是主机自身的地址,那么报文将被发送到传输层相应的协议中。如果报文中的IP地址不是主机自身的地址,并且主机配置了路由功能,那么报文将被转发,否则,报文将被丢弃。 ^55-15348-15481
- ⏱ 2023-12-01 22:06:47
7.3 Docker的网络实现
- 📌 在Kubernetes管理模式下通常只会使用bridge模式,所以本节只介绍在bridge模式下Docker是如何支持网络的。 ^56-726-789
- ⏱ 2023-02-17 17:32:44
7.4 Kubernetes的网络实现
-
📌 Pod的地址是与docker0在同一个网段的,我们知道docker0网段与宿主机网卡是两个完全不同的IP网段,并且不同Node之间的通信只能通过宿主机的物理网卡进行,因此要想实现不同Node上Pod容器之间的通信,就必须想办法通过主机的这个IP地址进行寻址和通信 ^57-2902-3033
- ⏱ 2023-12-01 23:02:27
-
📌 综上所述,要想支持不同Node上Pod之间的通信,就要满足两个条件:(1)在整个Kubernetes集群中对Pod的IP分配进行规划,不能有冲突;(2)找到一种办法,将Pod的IP和所在Node的IP关联起来,通过这个关联让Pod可以互相访问 ^57-3394-3573
- ⏱ 2023-12-01 23:06:10
7.5 Pod和Service网络实战
-
📌 在部署了一个Pod时,在同一个集群内,各主机都可以访问其他主机上的Pod IP,并不需要在主机上做端口映射 ^58-1556-1609
- ⏱ 2023-02-17 17:57:20
-
📌 这个IP段可以是任何段,只要不和docker0或者物理网络的子网冲突就可以 ^58-13763-13800
- ⏱ 2023-02-17 18:09:14
-
📌 选择任意其他网段的原因是这个网段将不会在物理网络和docker0网络上进行路由。 ^58-13801-13841
- ⏱ 2023-02-17 18:09:39
-
📌 这个kube-proxy服务给每一个新创建的服务都关联了一个随机的端口号,并且监听那个特定的端口,为服务创建相关的负载均衡对象 ^58-14771-14834
- ⏱ 2023-02-17 18:12:17
-
📌 现在我们知道,所有流量都被导入kube-proxy中了 ^58-15246-15273
- ⏱ 2023-02-17 18:15:33
7.6 CNI网络模型
7.7 Kubernetes网络策略
7.8 开源的网络组件
第8章 共享存储原理
-
📌 PV由管理员创建和配置,它与共享存储的具体实现直接相关,例如GlusterFS、iSCSI、RBD或GCE或AWS公有云提供的共享存储,通过插件式的机制完成与共享存储的对接,以供应用访问和使用 ^62-860-956
- ⏱ 2023-02-22 11:23:03
-
📌 PVC则是用户对存储资源的一个“申请” ^62-986-1005
- ⏱ 2023-02-22 11:23:11
-
📌 Kubernetes从1.4版本开始引入了一个新的资源对象StorageClass,用于标记存储资源的特性和性能。到1.6版本时,StorageClass和动态资源供应的机制得到了完善,实现了存储卷的按需创建,在共享存储的自动化管理进程中实现了重要的一步。 ^62-1173-1301
- ⏱ 2023-02-22 11:23:59
-
📌 (CSI) ^62-1571-1576
- ⏱ 2023-02-22 11:26:09
8.2 PV详解
- 📌 PV可以设定其存储的类别,通过storageClassName参数指定一个StorageClass资源对象的名称。具有特定类别的PV只能与请求了该类别的PVC进行绑定。未设定类别的PV则只能与不请求任何类别的PVC进行绑定。 ^63-4707-4819
- ⏱ 2023-02-22 11:36:38
8.3 PVC详解
-
📌 PVC也可以不设置Class需求。如果storageClassName字段的值被设置为空(storageClassName=""),则表示该PVC不要求特定的Class,系统将只选择未设定Class的PV与之匹配和绑定。PVC也可以完全不设置storageClassName字段,此时将根据系统是否启用了名为DefaultStorageClass的admission controller进行相应的操作。 ^64-1871-2073
- ⏱ 2023-11-30 19:12:05
-
📌 注意,PVC和PV都受限于Namespace,PVC在选择PV时受到Namespace的限制,只有相同Namespace中的PV才可能与PVC绑定。Pod在引用PVC时同样受Namespace的限制,只有相同Namespace中的PVC才能挂载到Pod内。 ^64-2601-2729
- ⏱ 2023-11-30 19:14:48
-
📌 在启用动态供应模式的情况下,一旦用户删除了PVC,与之绑定的PV也将根据其默认的回收策略“Delete”被删除。如果需要保留PV(用户数据),则在动态绑定成功后,用户需要将系统自动生成PV的回收策略从“Delete”改成“Retain”。 ^64-2956-3075
- ⏱ 2023-11-30 19:15:43
8.4 PV和PVC的生命周期
-
📌 PVC可以声明Class为"",说明该PVC禁止使用动态模式。 ^65-1145-1176
- ⏱ 2023-02-22 17:22:17
-
📌 PV。PV一旦绑定到某个PVC上,就会被这个PVC独占,不能再与其他PVC进行绑定了 ^65-1428-1470
- ⏱ 2023-11-30 19:17:41
-
📌 。在这种情况下,当PVC申请的存储空间比PV的少时,整个PV的空间就都能够为PVC所用,可能会造成资源的浪费。如果资源供应使用的是动态模式,则系统在为PVC找到合适的StorageClass后,将自动创建一个PV并完成与PVC的绑定。 ^65-1470-1587
- ⏱ 2023-11-30 19:18:24
-
📌 当用户对存储资源使用完毕后,用户可以删除PVC,与该PVC绑定的PV将会被标记为“已释放”,但还不能立刻与其他PVC进行绑定。通过之前PVC写入的数据可能还被留在存储设备上,只有在清除之后该PV才能再次使用。 ^65-1919-2023
- ⏱ 2023-11-30 19:19:43