前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >k8s基本原理

k8s基本原理

作者头像
kinnylee
发布2020-10-15 10:16:26
2.3K0
发布2020-10-15 10:16:26
举报
文章被收录于专栏:kinnylee钻研技术

分享的内容包括

  • k8s demo部署示例
  • k8s基本架构和原理
  • k8s资源对象
  • k8s网络模型
  • 总结

k8s就像图中的货船,管理各种集装箱(容器)

一. k8s demo部署示例

说明

  • 先通过一个hello world程序直观感受一下k8s
  • 程序部署在宿主机,容器和k8s三种环境,对比他们的差异
  • 代码大致是这个样子@RestController public class K8sDemoController { @GetMapping("/hello") public String hello(){ return "hello k8s demo."; } } 复制代码

1. 宿主机上如何运行

  1. mvn编译代码打成jar包
  2. 执行java -jar k8s-demo.jar &
  3. 浏览器中输入 http://10.1.69.101:8080/hello 地址访问服务

2. Docker容器上如何运行

  1. mvn编译代码打成jar包
  2. 将jar包打成docker镜像
  3. 执行docker run --name k8s-demo -d -p 8080:8080 k8s-demo:0.0.1-SNAPSHOT
  4. 浏览器中输入 http://10.1.69.101:8080/hello 地址访问服务

3. 在k8s中如何运行

这一步大致感受一下yaml的样子,不需要关心脚本的细节,后面介绍资源时会细说。只需要有个大体的印象,部署一个k8s服务的基本流程。

  1. mvn编译代码打成jar包
  2. 将jar包打成docker镜像
  3. 构建一个运行服务的yaml文件
  4. 执行kubectl apply -f k8s-demo.yaml
  5. 浏览器中输入 www.k8s-demo.com/hello 地址访问服务
  • yaml文件内容
代码语言:javascript
复制
# 文件名为k8s-demo.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: k8s-demo
  namespace: spring-test
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: k8s-demo
    spec:
      containers:
      - name: k8s-demo
        image: k8s-demo:0.0.1-SNAPSHOT
        ports:
          - containerPort: 8080

---
apiVersion: v1
kind: Service
metadata:
  name: k8s-demo
  namespace: spring-test
spec:
  type: NodePort
  selector:
    app: k8s-demo
  ports:
   - protocol: TCP
     port: 8888
     targetPort: 8080
     nodePort: 30003

---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: k8s-demo
  namespace: spring-test
spec:
  rules:
  - host: www.k8s-demo.com
    http:
      paths:
      - path: /hello
        backend:
          serviceName: k8s-demo
          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这个概念?

  1. 一组容器作为一个单元,很难判断整体状态,以及对整体进行管控。新增业务无关的pause容器,用于管控整体
  2. 简化了关联容器通信和共享的问题

2. Deployment

  • 实现Pod自动编排:创建、删除、扩容、缩容
  • 通过replicas控制pod数量,template控制要创建的pod的模板
代码语言:javascript
复制
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  name: k8s-demo
  namespace: spring-test
spec:
  replicas: 3
  template:
    metadata:
      labels:
        app: k8s-demo
    spec:
      containers:
      - name: k8s-demo
        image: k8s-demo:0.0.1-SNAPSHOT
        ports:
          - containerPort: 8080

3. Service

  • pod异常时,可能会被调度到另一台机器,导致pod的ip改变,使用ip访问服务不可靠
3.1概述
  • k8s里最核心的资源之一,类似微服务架构中的“微服务”
  • 前端应用通过入口地址访问服务,服务通过label对接到后端的pod,即使pod的ip变了
  • kube-proxy负责把service请求转发到后端,并做负载均衡
  • service整个生命周期内,ClusterIp不会变,对外提供的服务地址也就不会变
代码语言:javascript
复制
apiVersion: v1
kind: Service
metadata:
  name: k8s-demo
  namespace: spring-test
spec:
  type: NodePort
  selector:
    app: k8s-demo
  ports:
   - protocol: TCP
     port: 8888
     targetPort: 8080
     nodePort: 30003

4. Ingress

service提供了ip:port的访问方式,即工作在tcp/ip层,而http服务需要将不同的url对应到不同的后端服务,service是无法实现这一功能的。

  • Ingress提供http层的负载分发功能
  • Ingress可以实现不同的请求,分发到不同的后端服务
  • Ingress定义后,需要结合Ingress Controller,才能形成完整的功能
代码语言:javascript
复制
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: k8s-demo
  namespace: spring-test
spec:
  rules:
  - host: www.k8s-demo.com
    http:
      paths:
      - path: /hello
        backend:
          serviceName: k8s-demo
          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网络模型

  • 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网络模型详解

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权威指南》
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 分享的内容包括
  • 一. k8s demo部署示例
    • 说明
      • 1. 宿主机上如何运行
        • 2. Docker容器上如何运行
          • 3. 在k8s中如何运行
            • 4. 总结三种部署方式
              • 5. 流程越来越复杂,为什么不直接部署在宿主机?
                • 5.1 容器比宿主机优势在哪?
                • 5.2 k8s的出现又解决了容器的什么问题?
            • 二. 基本架构和原理
              • 1. Master节点的组件
                • apiServer
                • etcd
                • controller-manager
                • scheduler
              • 2. Node节点的组件
                • kubelet
                • kube-proxy
                • Container Runtime
            • 三. 资源对象
              • 概述
                • 1. Pod
                  • 2. Deployment
                    • 3. Service
                      • 3.1概述
                    • 4. Ingress
                      • 4.1 Ingress Controller定义
                      • 4.2 Ingress定义
                  • 四. k8s网络模型
                    • 1. Docker网络模型
                      • 2. Docker网络的局限性
                        • 3. k8s网络模型概述
                          • 3.1 k8s网络模型的原则:
                          • 3.2 设计这个原则的原因:
                          • 3.3 IP-Per-Pod与Docker端口映射的区别
                        • 4. k8s网络模型详解
                          • 4.1 容器与容器的通讯
                          • 4.2 pod与pod的通讯
                        • 4. 开源网络组件Flannel
                          • 4.1 实现的功能
                          • 4.2 底层原理
                          • 4.3 缺点
                      • 五. 总结
                      • 参考
                      相关产品与服务
                      容器服务
                      腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档