应用程序部署方式演变
传统部署:互联网早期,会直接将应用程序部署在物理机上
不能为应用程序定义资源使用边界,很难合理分配计算机资源,而且程序之间容易产生影响
虚拟化部署:可以在一台物理机上运行多个虚拟机
增加了操作系统,浪费部分资源
容器化部署:与虚拟化类似,但是共享操作系统
可以保证每个容器拥有自己的文件系统、CPU、内存、进程空间 运行应用程序所需要的资源被容器封装,并和底层架构解耦 容器化的应用程序可以跨云服务商、跨linux操作系统发现版进行部署
某个容器宕机,怎么自动让另一个容器去替补
并发量大的时候,容器数量怎么水平扩容
针对这些容器管理编排问题,大量的编排工具也随之诞生,最著名的就是kubernetes
Features(功能)
自我修复
某个容器坏掉,能够迅速启动新的容器,保证高可用
弹性伸缩
自动根据服务器压力调整集群容器运行的数量
服务发现
可以通过服务发现找到依赖的服务
负载均衡
当一个应用启动了多个容器,能够自动实现负载均衡
版本回退
新发布的应用有问题时,可以立即回退到上一个安全的版本
存储编排
可以根据容器自身的需求自动创建存储卷
Component(组件)
控制节点(master)
APIServer
资源操作的唯一入口,接收用户输入的命令,提供认证、授权、API注册和发现等机制
Scheduler
负责集群资源调度,按照预定的调度策略将pod调度到相应的node节点上,一个k8s集群有很多个node节点,master就是通过scheduler进行一系列算法,最终觉决定要在哪个node节点上创建pod
Controller-Manager
负责维护集群的状态,比如程序部署、故障迁移、自动扩展、滚动更新,当一个node节点挂掉后,容器的迁移都是由Controller-Manager来操作
Etcd
负责存储集群中各种资源对象的信息,集群中有多少个node、多少个master、哪个容器运行在哪个node节点等待各种集群信息都是存储在Etcd中
工作节点(node)
Kubelet
负责维护容器的生命周期,调用docker来创建、更新、删除容器
KubeProxy
负责提供集群内部的服务发现和负载均衡,容器运行后肯定是要对外提供访问了,KubeProxy就是将容器对外暴露,让外界能够访问到
Docker
负责节点上容器的各种操作
Run Nginx Demo
K8S启动之后,master和node的信息都会被存储到etcd
发送一个nginx安装请求,首先到达master的apiService
apiService调用scheduler,scheduler从etcd拿到当前的node节点信息,通过一些列的算法计算,最终告知apiService服务要被安装在哪个node上
apiService调用controller-manager调度node做实际的nginx服务的安装
Kubelet接收到安装指令,告知nginx启动一个pod,容器跑于pod之中
nginx服务启动成功之后,外界通过kubeProxy去代理访问pod中的容器服务
Master
Node
集群的控制平面,负责集群的决策
集群的数据平面,负责为容器提供运行环境
Concepts(概念)
Master
集群控制节点,每个集群至少一个master节点负责集群的管理
Node
工作负载节点,由master分配容器到这些node工作节点上,然后node节点上的docker负责创建容器
Pod
kubernetes最小的控制单元,容器都是运行在pod中的,一个pod中可以有1个或多个容器
每一个 Pod 都有一个特殊的被称为”根容器“的 Pause容器
这个“暂停”容器运行一个非常简单的进程,它不执行任何功能,一启动就永远把自己阻塞住了,但是它不会只知道睡觉,会执行另一个重要的功能——即它扮演 PID 1 的角色,并在子进程成为孤儿进程的时候通过调用 wait() 收割这些僵尸子进程。这样我们就不用担心我们的 Pod 的 PID namespace 里会堆满僵尸进程了
Controller
控制器,通过它来实现对pod的管理,启动、停止、伸缩
Service
pod对外服务的统一入口,下面可以维护者同类的多个pod
Label
应用于对pod进行分类,同一类的pod拥有相同的标签,service也是根据标签来判断一组pod
Namespace
命名空间,用来隔离pod的运行环境,一个namespace命令空间下的容器是无法与另一个namespace下的容器进行通讯
Cluster Construction(集群搭建)
类型
一主多从
一台master节点和多台node节点
有单机故障风险
多主多从
多台master节点和多台node节点
安全性高,适合用于生产环境
安装方式
minikube
Kubeadm
用来初始化集群的指令
二进制包
命令行
kubectl
命令行工具管理 Kubernetes 集群
kubectl 在 $HOME/.kube 目录中查找一个名为 config 的配置文件。 可以通过设置 KUBECONFIG 环境变量或设置 --kubeconfig 参数来指定其它 kubeconfig 文件
常用命令
kubectl get nodes
kubectl get deployment
kubectl get service
kubectl get pods
kubectl delete pods xxx
kubectl delete deployment xxx
kubectl apply -f kube-flannel.yaml
Kubectl 常用命令大全
不加-n xxx(命名空间)的话,默认查的default命名空间的
kustomize
kustomize 成为了 kubectl 内置的子命令,kustomize 使用 Kubernetes 原生概念帮助用户创作并复用声明式配置
资源管理方式
命令式对象管理:直接使用命令对资源进行操作
命令式对象配置:通过命令指定配置文件去操作资源
声明式对象配置:通过apply命令和配置文件去操作资源,相当于更新(如果Pod存在则更新,不存在则创建)
Kompose
自动将项目从Docker Compose 带到 Kubernetes
常用资源控制器
Namespace命名空间
namespace是kubernetes中非常重要的资源,它的作用是用来实现多套环境的资源隔离或者多租户的资源隔离
默认情况下,kubernetes集群中所有的pod都是可以相互访问的,但是实际中,可能不想让两个pod之间进行互相访问,那此时就可以将两个pod划分到不同的namespace下,k8s通过将集群内部资源分配到不同的namespace中,可以形成逻辑上的分组,再通过kubernetes中的授权机制,将不同的namespace交给不同租户进行管理,这样就实现了多租户的资源隔离,比如开发和测试,这些都属于多租户,还能结合k8s的资源配合限制,限定不同组合能占用的资源,例如CPU使用量、内存使用量等,来实现租户可用资源的管理
POD资源
pod是kubernetes集群管理的最小单元,程序要运行必须部署在容器中,而容器必须存在于pod中,pod可以认为是容器的封装,一个pod中可以存在一个或多个容器
一个pod中一般只运行一个容器,如果一个容器的程序需要与另一个容器进行管理,就可以把他们放在同一个pod中,一个pod最多可以运行4个容器
Label标签
label标签常作用于多个控制器之间进行关联,也应用于不同容器之间进行分组
label selector
基于等式
name=aaa 当name标签等于aaa
name != aaa 当name标签不等于aaa
基于集合
name in (master,slave) 当name标签值为master或者slave时
name not in (aaa) 当name标签值不为aaa时
多个label selector进行组合,使用逗号","进行分割
name=slave,env!=abc
Deployment控制器资源
一个deployment控制器下面可以有n多个pod
Service资源
pod的ip仅仅是集群内部可以使用的虚拟ip,集群之外无法访问
service可以看作是一组同类pod对外的访问接口,借助service资源也可以实现服务发现和自动负载均衡,比如一个tomcat pod使用service对外提供访问,当压力过高时,对pod进行扩容,增加的pod也会通过标签自动加入service资源,从而实现应用的自动负载均衡
在实际生产中一般都是service关联deployment资源的标签,deployment资源在关联pod的标签,当deployment资源增加pod数量时,service资源也可以自动发现到新的pod
type
ClusterIP(集群内部访问)
NodePort(对外提供访问)
kubernetes的本质是一组服务器集群,它开源在集群的每个节点上运行特定的程序,来对节点中的容器进行管理,它的目的就是实现资源管理的自动化