K8s基本入门
| 阅读 | 共 4021 字,阅读约
Overview
分享的内容包括
- k8s demo部署示例
- k8s基本架构和原理
- k8s资源对象
- k8s网络模型
- 总结
k8s就像图中的货船,管理各种集装箱(容器)
一. k8s demo部署示例
说明
- 先通过一个hello world程序直观感受一下k8s
- 程序部署在宿主机,容器和k8s三种环境,对比他们的差异
- 代码大致是这个样子
1@RestController 2public class K8sDemoController { 3 4 @GetMapping("/hello") 5 public String hello(){ 6 return "hello k8s demo."; 7 } 8}
1. 宿主机上如何运行
- mvn编译代码打成jar包
- 执行
java -jar k8s-demo.jar &
- 浏览器中输入 http://10.1.69.101:8080/hello 地址访问服务
2. Docker容器上如何运行
- mvn编译代码打成jar包
- 将jar包打成docker镜像
- 执行
docker run --name k8s-demo -d -p 8080:8080 k8s-demo:0.0.1-SNAPSHOT
- 浏览器中输入 http://10.1.69.101:8080/hello 地址访问服务
3. 在k8s中如何运行
这一步大致感受一下yaml的样子,不需要关心脚本的细节,后面介绍资源时会细说。只需要有个大体的印象,部署一个k8s服务的基本流程。
- mvn编译代码打成jar包
- 将jar包打成docker镜像
- 构建一个运行服务的yaml文件
- 执行kubectl apply -f k8s-demo.yaml
- 浏览器中输入 http://www.k8s-demo.com/hello 地址访问服务
-
yaml文件内容
1# 文件名为k8s-demo.yaml
2apiVersion: extensions/v1beta1
3kind: Deployment
4metadata:
5 name: k8s-demo
6 namespace: spring-test
7spec:
8 replicas: 3
9 template:
10 metadata:
11 labels:
12 app: k8s-demo
13 spec:
14 containers:
15 - name: k8s-demo
16 image: k8s-demo:0.0.1-SNAPSHOT
17 ports:
18 - containerPort: 8080
19
20---
21apiVersion: v1
22kind: Service
23metadata:
24 name: k8s-demo
25 namespace: spring-test
26spec:
27 type: NodePort
28 selector:
29 app: k8s-demo
30 ports:
31 - protocol: TCP
32 port: 8888
33 targetPort: 8080
34 nodePort: 30003
35
36---
37apiVersion: extensions/v1beta1
38kind: Ingress
39metadata:
40 name: k8s-demo
41 namespace: spring-test
42spec:
43 rules:
44 - host: www.k8s-demo.com
45 http:
46 paths:
47 - path: /hello
48 backend:
49 serviceName: k8s-demo
50 servicePort: 8888
4. 总结三种部署方式
为了减少部署复杂度,代码并没有使用redis,只是实例图增加了redis
5. 流程越来越复杂,为什么不直接部署在宿主机?
5.1 容器比宿主机优势在哪?
- 可移植性:容器提供了运行应用程序的基本包装,可以在任何支持容器的云上部署
- 高效率:启动一个容器只需一个镜像,且启动时间非常短
- 隔离性:宿主机上往往安装很多服务,且各自依赖不一样。而一个容器只跑一个服务
- 版本控制:方便追溯不同版本差异,方便快速回滚,只需替换镜像版本,无需宿主机上一套复杂的流程
- 低成本:小巧轻便,不需要像宿主机或虚拟机一样占用很多资源
5.2 k8s的出现又解决了容器的什么问题?
- 自动编排调度:大量容器剧增后,如何管理、如何调度的问题
- 分布式解决方案:节点可水平扩展,容器可方便扩缩容
- 自愈能力:故障自动发现,并进行自我修复
我们说容器实现了单个应用程序的基本包装实现可移植。上图中,宿主机部署的方式如果加上一个nginx做反向代理,就和k8s中ingress的部署方式是一样的。也就是k8s实现了整套分布式应用的可移植
二. 基本架构和原理
1. Master节点的组件
apiServer
- 提供资源操作的唯一入口,提供api注册、发现、认证、访问控制等功能
etcd
- 一个key-value数据库
- 保存整个机器的状态
controller-manager
- 负责维护机器状态,比如:自动扩容、故障检查、滚动更新
- 实现集群自动化的关键组件
scheduler
- 负责资源调度
- 将未分配节点的pod调度到合适的节点上
2. Node节点的组件
kubelet
- 负责容器生命周期管理,比如:创建、删除
- 同时负责Volume,网络的管理
kube-proxy
- 负责为Service提供负载均衡、服务发现
Container Runtime
- 容器运行环境
- 默认是Docker,同时还支持其他容器引擎
三. 资源对象
概述
- k8s中大部分概念,如Node,Pod,Service都可以看做一种资源对象
- 资源的描述:yaml文件或json文件
- 资源的操作:对象可以通过kubectl(或者api)执行增、删、改、查
- 资源的存储:信息在etcd中持久化
k8s通过对比资源的“实际状态”和etcd中的“期望状态”,实现自动化控制
1. Pod
- Pod是k8s中最重要最基本的资源
- pod是在容器之外又封装的一层概念
- pod是容器调度的基本单元(不是docker容器)
- 每个pod包含一个特殊的根容器:Pause容器,和一个或多个业务容器
- 每个pod有唯一的ip,pod内的容器可通过localhost通讯
为什么要新增pod这个概念?
- 一组容器作为一个单元,很难判断整体状态,以及对整体进行管控。新增业务无关的pause容器,用于管控整体
- 简化了关联容器通信和共享的问题
2. Deployment
- 实现Pod自动编排:创建、删除、扩容、缩容
- 通过replicas控制pod数量,template控制要创建的pod的模板
1apiVersion: extensions/v1beta1
2kind: Deployment
3metadata:
4 name: k8s-demo
5 namespace: spring-test
6spec:
7 replicas: 3
8 template:
9 metadata:
10 labels:
11 app: k8s-demo
12 spec:
13 containers:
14 - name: k8s-demo
15 image: k8s-demo:0.0.1-SNAPSHOT
16 ports:
17 - containerPort: 8080
3. Service
- pod异常时,可能会被调度到另一台机器,导致pod的ip改变,使用ip访问服务不可靠
3.1概述
- k8s里最核心的资源之一,类似微服务架构中的“微服务”
- 前端应用通过入口地址访问服务,服务通过label对接到后端的pod,即使pod的ip变了
- kube-proxy负责把service请求转发到后端,并做负载均衡
- service整个生命周期内,ClusterIp不会变,对外提供的服务地址也就不会变
1apiVersion: v1
2kind: Service
3metadata:
4 name: k8s-demo
5 namespace: spring-test
6spec:
7 type: NodePort
8 selector:
9 app: k8s-demo
10 ports:
11 - protocol: TCP
12 port: 8888
13 targetPort: 8080
14 nodePort: 30003
4. Ingress
service提供了ip:port的访问方式,即工作在tcp/ip层,而http服务需要将不同的url对应到不同的后端服务,service是无法实现这一功能的。
- Ingress提供http层的负载分发功能
- Ingress可以实现不同的请求,分发到不同的后端服务
- Ingress定义后,需要结合Ingress Controller,才能形成完整的功能
1apiVersion: extensions/v1beta1
2kind: Ingress
3metadata:
4 name: k8s-demo
5 namespace: spring-test
6spec:
7 rules:
8 - host: www.k8s-demo.com
9 http:
10 paths:
11 - path: /hello
12 backend:
13 serviceName: k8s-demo
14 servicePort: 8888
4.1 Ingress Controller定义
- 可以使用公有云提供的Ingress Controller
- 也可以使用google提供的Ingress Controller,以pod形式运行,功能如下:
- 监听apiserver,获取ingress的定义
- 基于ingress定义,生成nginx的配置文件的内容
- 执行nginx -s reload,重新加载配置
4.2 Ingress定义
- 创建类型为Ingress的yaml文件
- 配置spec.rules,指定hostname中url和service的对应关系
四. k8s网络模型
前面hello world程序中,对于如何访问到服务,有必要了解一下k8s的网络模型,在这之前先介绍docker的网络模型
1. Docker网络模型
- docker第一次启动时,会创建虚拟网桥docker0
- 为docker0分配一个子网
- docker创建每个容器时,会创建veth设备对,一端关联到网桥上,另一端使用linux的网络命名空间技术连接到容器内,并给容器内eth0设备分配一个ip地址
2. Docker网络的局限性
- Docker网络模型没有考虑到多主机互联的网络解决方案,崇尚简单为美
- 同一机器内的容器之间可以直接通讯,但是不同机器之间的容器无法通讯
- 为了跨节点通讯,必须在主机的地址上分配端口,通过端口路由或代理到容器
- 分配和管理容器特别困难,特别是水平扩展时
3. k8s网络模型概述
3.1 k8s网络模型的原则:
- 每个pod都拥有唯一个独立的ip地址,称IP-Per-Pod模型
- 所有pod都在一个可连通的网络环境中
- 不管是否在同一个node,都可以通过ip直接通讯
- pod被看作一台独立的物理机或虚拟机
目前原生docker和kubernetes还不能打通多节点容器与容器的通讯,要支持该模型,必须依靠第三方网络插件实现,比如:flannel
3.2 设计这个原则的原因:
- 用户不需要额外考虑如何建立pod之间的连接
- 用户不需要考虑将容器端口映射到主机端口的问题
- 可以兼容过去跑在宿主机和KVM的应用
3.3 IP-Per-Pod与Docker端口映射的区别
- docker端口映射到宿主机会引入端口管理的复杂性
- docker最终被访问的ip和端口,与提供的不一致,引起配置的复杂性
4. k8s网络模型详解
4.1 容器与容器的通讯
- 同一个容器的pod直接共享同一个linux协议栈
- 就像在同一台机器上,可通过localhost访问
- 可类比一个物理机上不同应用程序的情况
4.2 pod与pod的通讯
同一Node内的pod之间通讯
- 同一Node内的pod都是通过veth连接在同一个docker0网桥上,地址段相同,所以可以直接通讯
不同Node的pod之间通讯
- docker0网段与宿主机不在同一个网段,所以不同pod之间的pod不能直接通讯
- 不同node之间通讯只能通过宿主机物理网卡
- 前面说过k8s网络模型需要不同的pod之间能通讯,所以ip不能重复,这就要求k8s部署时要规划好docker0的网段
- 同时,要记录每个pod的ip地址挂在哪个具体的node上
- 为了达到这个目的,有很多开源软件增强了docker和k8s的网络
4. 开源网络组件Flannel
4.1 实现的功能
- 协助k8s给每个Node上的docker容器分配互不冲突的ip地址
- 能在这些ip地址之间建立覆盖网络(Overlay Network),将数据传递到目标容器
4.2 底层原理
- Flannel创建名为flannel0的网桥
- flannel0网桥一端连接docker0网桥,另一端连接flanneld进程
- flanneld进程一端连接etcd,利用etcd管理分配的ip地址资源,同时监控pod地址,建立pod节点路由表
- flanneld进程一端连接docker0和物理网络,配合路由表,完成数据包投递,完成pod之间通讯
4.3 缺点
- 引入多个网络组件,带来网络时延和损耗
- 默认使用udp作为底层传输协议,具有不可靠性
五. 总结
- 本文先通过一个demo,部署在不同的环境中,直观感受了如何使用k8s。这个过程我们需要思考k8s诞生解决了什么问题?核心的提供了一个平台,主要负责容器的自动调度和编排
- 对k8s有直观感受后,介绍了下k8s的基本架构。各个组件是如何交互的,在使用k8s过程中不断回想架构图,能加深对k8s的了解
- 掌握了基本架构后,想要将服务部署到k8s中,需要对常用的资源对象有一定了解,因此接着介绍了主要的资源对象。k8s中其他的资源对象可类比学习
- 当你把一个服务部署到k8s之后,如何做验证呢,如何暴露你的服务呢?需要对k8s的网络模型有一定了解,才能真正掌握它暴露服务的方式。因此最后部分着重介绍了k8s的网络模型
参考
- 《kubernetes权威指南》