摘要
本文内容转自网络,个人学习记录使用,请勿传播
Kubernets存在的意义
Docker解决什么问题
Docker实现了从代码到镜像、从镜像到容器的容器生命周期管理。但是Docker本身无法解决容器调度、虚拟网络通信、容器集群化的问题。通常我们可以使用传统的部署架构+Docker的容器化管理来实现线上集群的管理,这样的管理方式相对于传统管理方式还是有一些优势的:
- 解决了环境描述问题,保障从开发到测试,再到线上的环境一致性
- 解决了服务混部时对单个服务的资源限制
- 持续集成效率的提升,更快的部署速度
- 更好的可迁移性
为什么要用Kubernets
Kubernets作为容器化集群管理平台,在容器化部署的基础上解决了容器调度,集群管理的能力,为业务高并发、高可用提供的便捷的管理方式:
- 打通容器虚拟网络,实现多容器跨主机提供服务
- 多容器调度、分布式多节点部署
- 多容器升级、管理等
同类产品
- Swarm
- Mesos Marathon
Kubernets是什么
- Kubernetes是Google在2014年开源的一个容器集群管理系统,Kubernetes简称K8S。
- Kubernetes用于容器化应用程序的部署,扩展和管理,目标是让部署容器化应用简单高效。
Kubernets的集群架构和组件
核心组件
Master组件
- kube-apiserver:Kubernetes API,集群的统一入口,对外提供集群管理的RestFul API接口,负责与其他模块间的数据交互,所有对象资源的增删改查和监听操作都交给APIServer处理后再提交给Etcd存储。
- kube-controller-manager:控制器,处理集群中常规后台任务,一个资源对应一个控制器,而ControllerManager就是负责管理这些控制器的。监控整个集群的状态,确保集群处于预期工作状态(node、deploy、service、volume、job)
- kube-scheduler:调度器,根据调度算法为新创建的Pod选择一个Node节点,可以任意部署,可以部署在同一个节点上,也可以部署在不同的节点上。
- etcd:配置存储中心,分布式键值存储系统。用于保存集群状态数据,比如Pod、Service等对象信息。
Node组件
kubelet:node节点上的容器管理者,集群的agent,管理本机运行的所有容器的生命周期,会定时的获取、上报本机pod期望状态,负责:
- 创建容器、拉起容器、Pod挂载数据卷、下载secret、获取容器和节点状态等所有和容器相关的工作
kube-proxy:在node节点上负责建立pod网络和集群网络的关系,维护网络规则和四层负载均衡工作,servie资源的载体
- docker或rocket:容器引擎,运行容器
客户端组件
- kubectl:客户端
其他组件
- 网络:flannel/calico
- 服务发现:kubedns、coredns
- gui:dashboard
Kubernets的基本概念
pod && pod控制器
- pod是k8s中运行的最小单元,一个pod中会存在多个容器;一个pod是一个应用部署的一个完整副本
- pod控制器是pod启动的一种模板,包括:副本数、生命周期、健康检查、资源限制等
- Deployment
- DaemonSet
- Job
- Cronjob
label && label选择器
k8s中通过label来分类管理资源对象,通过label选择器来过滤所需的资源,附加到某个资源上,用于关联对象、查询和筛选
service
为一组提供相同服务的pod的提供负载均衡,对外提供统一访问入口
Deployment
最常见的pod控制器,用于更高级别的pod管理和部署
DeployMent 声明式更新
什么是声明式更新?
声明式区别于命令式,它描述目标性质,让计算机明白目标,而非流程。而命令式则需要用具体的做法来明确的指出每一步该怎么做。
声明式更新指的是DeployMent更新服务时只会针对声明的字段对应的资源属性进行更新。比如:apply 命令可以用yaml文件中声明的字段来更新Deployment。不仅更新镜像,而且还添加了就绪探针,以及在yaml中添加或修改的其他声明。
如果新的yaml也包含 replicas 字段,当它与现有Deployment中的数量不一致时,那么 apply 操作才会对Deployment进行扩容。也就是说:
使用 kubectl apply 更新Deployment时如果不期望副本数被更改,则不用在YAML文件中添加 replicas 这个字段。
Namespace
命令空间,和容器使用的内核namespace没有任何关系,从逻辑上将资源对象隔离,从而形成多个虚拟集群,也利于权限控制
应用场景
- 根据不同业务对空间进行划分
- 根据不同团队对空间进行划分
- 根据不同环境对空间进行划分
自带的命名空间
1 | kubectl get namespace |
- default:默认命名空间
- kube-system:k8s系统命名空间
- kube-public:公开的命名空间,谁都可以访问
- kube-node-lease:k8s内部命名空间
两种方法指定资源所属命名空间
- 命令行加
-n
参数 - yaml资源清单中指定namespaces字段
查看资源的配置文件
1 | kubectl get service nginx -o yaml |
查看资源的标签
1 | kubectl get pods --show-labels |
查看k8s所有资源
1 | kubectl api-resources |
Kubernets如何实现容器网络交互
CNI网络模型
K8s是一个扁平化网络。cni组件是k8s对接第三方网络组件的接口
即所有部署的网络组件都必须满足如下要求:
- 一个Pod一个IP
- 所有的 Pod 可以与任何其他 Pod 直接通信
- 所有节点可以与所有 Pod 直接通信
- Pod 内部获取到的 IP 地址与其他 Pod 或节点与其通信时的 IP 地址是同一个
目前主流网络组件有:Flannel、Calico等
Kubernets为什么要弃用docker
Kubernets作为容器管理平台的佼佼者、作为容器行业的先驱者,为了防止容器化技术发展过程中技术标准不统一导致出现五花八门的容器技术,防止在周边组件与容器集成时可能面临的适配问题。因此在早期成立社区,促使docker公司制定了CRI(Container Runtime Interface,容器运行时接口),以此作为容器化技术的标准。也再次为容器技术可以横向替换打下了基础。
Kubernets使用docker作为底层容器技术的架构
Kubernets计划弃用的就是与dockerd交互的dockershim组件(即 Kubernetes kubelet 实现中的组件之一,它能够与 Docker Engine 进行通信。),未来Kubernets将直接与containerd直接进行交互。
为什么要这样做
- Docker内部调用链比较复杂,多层封装和调用,导致性能降低、提升故障率、不易排查
- Docker还会在宿主机创建网络规则、存储卷,也带来了安全隐患
如何应对
在未来的 Kubernetes 版本彻底放弃 Docker 支持之前,引入受支持的容器运行时。
除了docker之外,CRI还支持很多容器运行时,例如:
- containerd:containerd与Docker相兼容,相比Docker轻量很多,目前较为成熟
- cri-o,podman:都是红帽(RedHat)项目,目前红帽主推podman