新書推薦:
《
千万别喝南瓜汤(遵守规则绘本)
》
售價:NT$
203.0
《
大模型启示录
》
售價:NT$
510.0
《
东法西渐:19世纪前西方对中国法的记述与评价
》
售價:NT$
918.0
《
养育男孩:官方升级版
》
售價:NT$
230.0
《
小原流花道技法教程
》
售價:NT$
500.0
《
少女映像室 唯美人像摄影从入门到实战
》
售價:NT$
505.0
《
詹姆斯·伍德系列:不负责任的自我:论笑与小说(“美国图书评论奖”入围作品 当代重要文学批评家詹姆斯·伍德对“文学中的笑与喜剧”的精湛研究)
》
售價:NT$
398.0
《
武当内家散手
》
售價:NT$
230.0
|
編輯推薦: |
我相信这是一本到目前为止对从事云计算领域技术实践的人来说非常有价值的书籍。Kubernetes是容器生态圈中的重要一员,发展速度非常快,现在已经拥有500多名代码贡献者。本书囊括了Kubernetes入门、运行机制、原理和高级案例等内容,由浅入深地介绍了Kubernetes容器云平台,并围绕着生产环境中可能出现的问题,给出了大量的典型案例,有很好的可借鉴性。本书作者全部来自惠普公司云计算实战一线,敏锐地捕获和探索着各种IT前瞻技术,有着全面而扎实的技术架构体系、对创新技术天生的热情、国际技术领先者的视野,还有着对企业级IT架构的深入把握。
|
內容簡介: |
Kubernetes是由谷歌开源的Docker容器集群管理系统,为容器化的应用提供了资源调度、部署运行、服务发现、扩容、缩容等一整套功能。本书从一个开发者的角度去理解、分析和解决问题,囊括了Kubernetes入门、核心原理、实战开发、运维、高级案例及源码分析等方面的内容,图文并茂、内容丰富、由浅入深、讲解全面;并围绕着生产环境中可能出现的问题,给出了大量的典型案例,比如安全问题、网络方案的选择、高可用性方案及Trouble Shooting技巧等,有很好的可借鉴性。
无论对于软件工程师、测试工程师、运维工程师、软件架构师、技术经理还是资深IT人士来说,本书都极具参考价值。
|
關於作者: |
龚正,惠普公司高级顾问,十多年IT行业从业经历,拥有丰富的云计算、大数据分析和大型企业级应用架构设计和实施经验,是电信、金融、互联网等领域的资深行业专家。
|
目錄:
|
第1章 Kubernetes入门1
1.1 Kubernetes是什么1
1.2 为什么要用Kubernetes4
1.3 从一个不简单的Hello World例子说起5
1.3.1 创建redis-master Pod和服务7
1.3.2 创建redis-slave Pod和服务10
1.3.3 创建frontend Pod和服务12
1.3.4 通过浏览器访问网页15
1.4 Kubernetes基本概念和术语16
1.4.1 Node(节点)16
1.4.2 Pod18
1.4.3 Label(标签)20
1.4.4 Replication Controller(RC)24
1.4.5 Service(服务)26
1.4.6 Volume(存储卷)30
1.4.7 Namespace(命名空间)34
1.4.8 Annotation(注解)35
1.4.9 小结36
1.5 Kubernetes总体架构36
1.6 Kubernetes安装与配置38
1.6.1 安装Kubernetes38
1.6.2 配置和启动Kubernetes服务39
1.6.3 Kubernetes的版本升级46
1.6.4 内网中的Kubernetes相关配置46
1.6.5 Kubernetes对Docker镜像的要求——启动命令前台执行48
第2章 Kubernetes核心原理49
2.1 Kubernetes API Server 分析49
2.1.1 如何访问Kubernetes API49
2.1.2 通过API Server 访问Node、Pod和Service52
2.1.3 集群功能模块之间的通信55
2.2 调度控制原理56
2.2.1 Replication Controller57
2.2.2 Node Controller60
2.2.3 ResourceQuota Controller62
2.2.4 Namespace Controller64
2.2.5 ServiceAccount Controller与Token Controller64
2.2.6 Service Controller与Endpoint Controller65
2.2.7 Kubernetes Scheduler71
2.3 Kubelet运行机制分析75
2.3.1 节点管理75
2.3.2 Pod管理76
2.3.3 容器健康检查77
2.3.4 cAdvisor资源监控78
2.4 安全机制的原理80
2.4.1 Authentication认证80
2.4.2 Authorization授权83
2.4.3 Admission Control准入控制84
2.4.4 Secret私密凭据88
2.4.5 Service Account92
2.5 网络原理95
2.5.1 Kubernetes网络模型95
2.5.2 Docker的网络基础97
2.5.3 Docker的网络实现109
2.5.4 Kubernetes的网络实现117
2.5.5 开源的网络组件127
2.5.6 Kubernetes网络试验131
第3章 Kubernetes开发指南145
3.1 REST简述145
3.2 Kubernetes API详解147
3.2.1 Kubernetes API概述147
3.2.2 API版本152
3.2.3 API详细说明152
3.2.4 API响应说明154
3.3 使用Java程序访问Kubernetes API156
3.3.1 Jersey156
3.3.2 Fabric8168
3.3.3 使用说明169
第4章 Kubernetes运维指南191
4.1 Kubernetes核心服务配置详解191
4.1.1 基础公共配置参数191
4.1.2 kube-apiserver192
4.1.3 kube-controller-manager195
4.1.4 kube-scheduler196
4.1.5 Kubelet197
4.1.6 kube-proxy199
4.2 关键对象定义文件详解200
4.2.1 Pod定义文件详解200
4.2.2 RC定义文件详解203
4.2.3 Service定义文件详解204
4.3 常用运维技巧集锦206
4.3.1 Node的隔离和恢复206
4.3.2 Node的扩容207
4.3.3 Pod动态扩容和缩放208
4.3.4 更新资源对象的Label208
4.3.5 将Pod调度到指定的Node209
4.3.6 应用的滚动升级210
4.3.7 Kubernetes集群高可用方案213
4.4 资源配额管理217
4.4.1 指定容器配额217
4.4.2 全局默认配额218
4.4.3 多租户配额管理221
4.5 Kubernetes网络配置方案详解223
4.5.1 直接路由方案224
4.5.2 使用flannel叠加网络226
4.5.3 使用Open vSwitch228
4.6 Kubernetes集群监控232
4.6.1 使用kube-ui查看集群运行状态232
4.6.2 使用cAdvisor查看容器运行状态236
4.7 Trouble Shooting指导241
4.7.1 对象的Event事件242
4.7.2 容器日志243
4.7.3 Kubernetes系统日志244
4.7.4 常见问题246
4.7.5 寻求帮助249
第5章 Kubernetes高级案例进阶250
5.1 Kubernetes DNS服务配置案例250
5.1.1 skydns配置文件251
5.1.2 修改每个Node上的Kubelet启动参数254
5.1.3 创建skydns Pod和服务254
5.1.4 通过DNS查找Service255
5.1.5 DNS服务的工作原理解析256
5.2 Kubernetes集群性能监控案例257
5.2.1 配置Kubernetes集群的ServiceAccount和Secret258
5.2.2 部署Heapster、InfluxDB、Grafana261
5.2.3 查询InfluxDB数据库中的数据265
5.2.4 Grafana页面查看和操作268
5.3 Cassandra集群部署案例269
5.3.1 自定义SeedProvider270
5.3.2 通过Service动态查找Pod271
5.3.3 Cassandra集群新节点的自动添加274
5.4 集群安全配置案例275
5.4.1 双向认证配置275
5.4.2 简单认证配置279
5.5 不同工作组共享Kubernetes集群的案例280
5.5.1 创建namespace281
5.5.2 定义Context(运行环境)281
5.5.3 设置工作组在特定Context环境中工作282
第6章 Kubernetes源码导读285
6.1 Kubernetes源码结构和编译步骤285
6.2 kube-apiserver进程源码分析289
6.2.1 进程启动过程289
6.2.2 关键代码分析291
6.2.3 设计总结306
6.3 kube-controller-manager进程源码分析310
6.3.1 进程启动过程310
6.3.2 关键代码分析313
6.3.3 设计总结321
6.4 kube-scheduler进程源码分析323
6.4.1 进程启动过程323
6.4.2 关键代码分析328
6.4.3 设计总结335
6.5 Kubelet进程源码分析337
6.5.1 进程启动过程337
6.5.2 关键代码分析342
6.5.3 设计总结365
6.6 kube-proxy进程源码分析366
6.6.1 进程启动过程367
6.6.2 关键代码分析368
6.6.3 设计总结383
6.7 Kubectl进程源码分析384
6.7.1 kubectl create命令385
6.7.2 rolling-upate命令389
后记396
|
內容試閱:
|
5.1 Kubernetes DNS服务配置案例
在Kubernetes系统中,Pod在访问其他Pod的Service时,可以通过两种服务发现方式完成,即环境变量和DNS方式。但是使用环境变量是有限制条件的,即Service必须在Pod之前被创建出来,然后系统才能在新建的Pod中自动设置与Service相关的环境变量。DNS则没有这个限制,其通过提供全局的DNS服务器来完成服务的注册与发现。
Kubernetes提供的DNS由以下三个组件组成。
(1)etcd:DNS存储。
(2)kube2sky:将Kubernetes Master中的Service(服务)注册到etcd。
(3)skyDNS:提供DNS域名解析服务。
这三个组件以Pod的方式启动和运行,所以在一个Kubernetes集群中,它们都可能被调度到任意一个Node节点上去。为了能够使它们之间网络互通,需要将各Pod之间的网络打通,如何打通网络请参考第4章网络配置部分的详细说明。
网络配置完成后,通过创建RC和Service来启动DNS服务。
5.1.1skydns配置文件
首先创建DNS服务的ReplicationController配置文件skydns-rc.yaml,在这个RC配置中包含了3个Container的定义:
apiVersion: v1
kind: ReplicationController
metadata:
name: kube-dns-v8
namespace: kube-system
labels:
k8s-app: kube-dns
version: v8
kubernetes.iocluster-service: "true"
spec:
replicas: 1
selector:
k8s-app: kube-dns
version: v8
template:
metadata:
labels:
k8s-app: kube-dns
version: v8
kubernetes.iocluster-service: "true"
spec:
containers:
- name: etcd
image: gcr.iogoogle_containersetcd:2.0.9
resources:
limits:
cpu: 100m
memory: 50Mi
command:
- usrlocalbinetcd
- -data-dir
- varetcddata
- -listen-client-urls
- http:127.0.0.1:2379,http:127.0.0.1:4001
- -advertise-client-urls
- http:127.0.0.1:2379,http:127.0.0.1:4001
- -initial-cluster-token
- skydns-etcd
volumeMounts:
- name: etcd-storage
mountPath: varetcddata
- name: kube2sky
image: gcr.iogoogle_containerskube2sky:1.11
resources:
limits:
cpu: 100m
memory: 50Mi
args:
# command = "kube2sky"
- --kube_master_url=http:192.168.1.128:8080
- -domain=cluster.local
- name: skydns
image: gcr.iogoogle_containersskydns:2015-03-11-001
resources:
limits:
cpu: 100m
memory: 50Mi
args:
# command = "skydns"
- -machines=http:localhost:4001
- -addr=0.0.0.0:53
- -domain=cluster.local
ports:
- containerPort: 53
name: dns
protocol: UDP
- containerPort: 53
name: dns-tcp
protocol: TCP
volumes:
- name: etcd-storage
emptyDir: {}
dnsPolicy: Default
需要修改的几个配置参数如下。
(1)kube2sky容器需要访问Kubernetes Master,需要配置Master所在物理主机的IP地址和端口号,本例中设置参数--kube_master_url的值为http:192.168.1.128:8080。
(2)kube2sky容器和skydns容器的启动参数-domain,设置Kubernetes集群中Service所属的域名,本例中为cluster.local。启动后,kube2sky会监听Kubernetes,当有新的Service创建时,就会生成相应的记录并保存到etcd中。kube2sky为每个Service生成两条记录:
..;
..svc.。
(3)skydns的启动参数-addr=0.0.0.0:53表示使用本机TCP和UDP的53端口提供服务。
创建DNS服务的Service配置文件如下:
skydns-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: kube-dns
namespace: kube-system
labels:
k8s-app: kube-dns
kubernetes.iocluster-service: "true"
kubernetes.ioname: "KubeDNS"
spec:
selector:
k8s-app: kube-dns
clusterIP: 20.1.0.100
ports:
- name: dns
port: 53
protocol: UDP
- name: dns-tcp
port: 53
protocol: TCP
注意,skydns服务使用的clusterIP需要我们指定一个固定的IP地址,每个Node的Kubelet进程都将使用这个IP地址,不能通过Kubernetes自动分配。
另外,这个IP地址需要在kube-apiserver启动参数--service-cluster-ip-range指定的IP地址范围内。
5.1.2修改每个Node上的Kubelet启动参数
修改每台Node上Kubelet的启动参数:
--cluster_dns=20.1.0.100,为DNS服务的ClusterIP地址;
--cluster_domain=cluster.local,为DNS服务中设置的域名。
然后重启Kubelet服务。
5.1.3创建skydns Pod和服务
之后,通过kubectl create完成RC和Service的创建:
#kubectl create -f skydns-rc.yaml
#kubectl create -f skydns-svc.yaml
创建完成后,查看到系统创建的RC、Pod和Service都已创建成功:
# kubectl get rc --namespace=kube-system
CONTROLLER CONTAINERS IMAGES SELECTOR REPLICAS
kube-dns-v8etcdkubeguideetcd:2.0.9 k8s-app=kube-dns,version=v8 1
kube2skykubeguidekube2sky:1.11
skydnskubeguideskydns:2015-03-11-001
# kubectl get pods --namespace=kube-system
NAME READY STATUS RESTARTS AGE
kube-dns-v8-0r71x 33 Running 0 24m
# kubectl get services --namespace=kube-system
NAME LABELS SELECTOR IPS PORTS
kube-dns k8s-app=kube-dns,kubernetes.iocluster-service=true,kubernetes.ioname=KubeDNS k8s-app=kube-dns 20.1.0.100 53UDP
53TCP
然后,我们创建一个普通的Service,以redis-master服务为例:
redis-master-service.yaml
apiVersion: v1
kind: Service
metadata:
name: redis-master
labels:
name: redis-master
spec:
ports:
- port: 6379
targetPort: 6379
selector:
name: redis-master
查看创建出来的Service:
# kubectl get services
NAME LABELS SELECTOR IPS PORTS
redis-master name=redis-master name=redis-master 20.1.231.244 6379TCP
可以看到,系统为redis-master服务分配了一个IP地址:20.1.231.244。
5.1.4通过DNS查找Service
接下来使用一个带有nslookup工具的Pod来验证DNS服务是否能够正常工作:
busybox.yaml
apiVersion: v1
kind: Pod
metadata:
name: busybox
namespace: default
spec:
containers:
- image: gcr.iogoogle_containersbusybox
command:
- sleep
- "3600"
imagePullPolicy: IfNotPresent
name: busybox
restartPolicy: Always
运行kubectl create -f busybox.yaml完成创建。
在该容器成功启动后,通过kubectl execnslookup进行测试:
# kubectl exec busybox -- nslookupredis-master
Server: 20.1.0.100
Address 1: 20.1.0.100
Name: redis-master
Address 1: 20.1.231.244
可以看到,通过DNS服务器20.1.0.100成功找到了名为“redis-master”服务的IP地址:20.1.231.244。
如果某个Service属于自定义的命名空间,那么在进行Service查找时,需要带上namespace的名字。下面以查找kube-dns服务为例:
# kubectl exec busybox -- nslookupkube-dns.kube-system
Server: 20.1.0.100
Address 1: 20.1.0.100 ignencfch3-v804.csc.com
Name: kube-dns.kube-system
Address 1: 20.1.0.100 ignencfch3-v804.csc.com
如果仅使用“kube-dns”来进行查找,则将会失败:
nslookup: can''t resolve ''kube-dns''
5.1.5 DNS服务的工作原理解析
让我们看看DNS服务背后的工作原理。
(1)kube2sky容器应用通过调用Kubernetes Master的API获得集群中所有Service的信息,并持续监控新Service的生成,然后写入etcd中。
查看etcd中存储的Service信息:
# kubectl exec kube-dns-v8-5tpm2 -c etcd --namespace=kube-system etcdctlls skydnslocalcluster
skydnslocalclusterdefault
skydnslocalclustersvc
skydnslocalclusterkube-system
可以看到在skydns键下面,根据我们配置的域名(cluster.local)生成了localcluster子键,接下来是namespace(default和kube-system)和svc(下面也按namespace生成子键)。
查看redis-master服务对应的键值:
# kubectl exec kube-dns-v8-5tpm2 -c etcd --namespace=kube-system etcdctl get skydnslocalclusterdefaultredis-master
{"host":"20.1.231.244","priority":10,"weight":10,"ttl":30,"targetstrip":0}
可以看到,redis-master服务对应的完整域名为redis-master.default.cluster.local,并且其IP地址为20.1.231.244。
(2)根据Kubelet启动参数的设置(--cluster_dns),Kubelet会在每个新创建的Pod中设置DNS域名解析配置文件etcresolv.conf文件,在其中增加了一条nameserver配置和一条search配置:
nameserver 20.1.0.100
searchdefault.svc.cluster.localsvc.cluster.localcluster.locallocaldomain
通过名字服务器20.1.0.100访问的实际上就是skydns在53端口上提供的DNS解析服务。
(3)*后,应用程序就能够像访问网站域名一样,仅仅通过服务的名字就能访问到服务了。
例如,设置redis-slave的启动脚本为:
redis-server --slaveofredis-master 6379
创建redis-slave的Pod并启动它。
之后,我们可以登录redis-slave容器中查看,其通过DNS域名服务找到了redis-master的IP地址20.1.231.244,并成功建立了连接。
通过DNS设置,对于其他Service(服务)的查询将可以不再依赖系统为每个Pod创建的环境变量,而是直接使用Service的名字就能对其进行访问,使得应用程序中的代码更简洁了。
|
|