容器化进阶Kubernetes快速入门
一. Kubernetes概述
1.1 Kubernetes介绍
1.1.1 Kubernetes是什么及作用?
-
Kubernets(K8s)是Google在2014年发布的一个开源项目,用于自动化容器化应用程序的部署、扩展和管理。Kubernetes通常结合docker容器工作,并且整合多个运行着docker容器的主机集群。官网地址
-
Kubernetes的目标是让部署容器化的应用简单并且高效,Kubernetes一个核心特点就是能够自主的管理容器来保证云平台中的容器按照用户的期望运行。
-
官网中说明的的特性:
-
使用Kubernetes能做什么?
- Kubernetes是一个全新的基于容器技术的分布式架构领先方案(源于Brog,是Google十几年经验的结晶);
- Kubernetes是一个开放的开发平台(无侵入性,现有系统很容易迁移到Kubernetes上);Kubernetes是一个晚辈的分布式系统支撑平台(完善的集群管理能力)
-
使用Kubernetes可以在物理或虚拟机的Kubernetes集群上运行容器化应用,Kubernetes能够提供一个以容器为中心的基础架构,满足在生产环境汇总运行应用的一些常见需求,如:
- 多个进程协同工作
- 存储系统挂载
- Distributing secrets
- 应用健康监测
- 应用实例的复制
- Pod自动伸缩/扩展
- Naming and discovering
- 负载均衡
- 滚动更新
- 资源监控
- 日志访问
- 调度应用该程序
- 提供认证和授权
-
为什么使用Kubernetes?
- 使用Kubernetes最直接的感受就是我们可以轻装上阵的开发复杂的系统了;其次Kubernetes是在全面拥抱微服务架构(微服务的核心就是讲一个巨大的单体应用拆分成很多小的互相连接的微服务,一个微服务后面可能是多个实例副本在支撑,副本数量可以随着系统负荷变化而动态调整);最后Kubernetes系统架构具备超强的横向扩展能力。
1.1.2 Kubernetes快速入门
-
环境准备:
建议在执行 yum install -y etcd kubernetes 命令之前,先执行yum update命令,将yum更新至最新。 在安装过程中会把docker也跟着装上;
启动完成etcd后可以输入命令:systemctl status etcd命令查看是否启动成功:
如果docker启动失败,则参考是否为此原因,若需要重启,需要重启完毕后关闭防火墙: -
配置:
-
Tomcat配置:
执行配置时,我们需要在一个指定的目录中创建2个配置文件,将名称和内容按上面操作填充即可:
文件创建完成后不要忘了另外2个命令执行: -
问题解决
-
浏览测试
-
1.2 Kubernetes基本架构与常用术语
-
Kubernetes集群包含有节点代理kubelet和Master组件(APIS,scheduler,etc),一切都基于分布式的存储系统。下面这张图是Kubernetes的架构图:
在这张系统架构图中,我们把服务分为运行在工作节点上的服务和组成集群级别控制板的服务。
-
Kubernets节点有运行容器必备的服务,而这些都是受Master的控制
-
每个节点上都要运行Docker,Docker来负责所有具体的映像下载和容器运行。
-
KUbernetes主要由以下几个核心组件组成:
- etcd保存了整个集群的状态
- apiserver提供了资源操作的唯一入口,并提供认证,授权,访问控制,API注册和发现等机制
- controller manager负责维护集群的状态,比如故障检测,自动扩展,滚动更新等。
- scheduler负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;
- kubelet负责维护容器的生命周期,同时也负责Volume(CV)和网络(CNI)的管理;
- Container runtime负责镜像管理以及Pod和容器的真正运行(CRI);
- kube-proxy负责为service提供cluster内部的服务发现和负载均衡
-
除了核心组件,还有一些推荐的Add-ons:
- kube-dns负责为整个集群提供DNS服务
- Ingress Controller为服务提供外网入口
- Heapster提供资源监控
- Dashboard提供GUI
- Federation提供跨可用区的集群
- Fluentd-elasticsearch提供集群日志采集、存储与查询
-
Kubernetes设计理念和功能其实就是一个类似Linux的分层架构
- 核心层:Kubernetes最核心的功能,对外提供API构建高层的应用,对内提供插件式应用执行环境
- 应用层:部署(无状态应用、有状态应用、批处理任务、集群应用等)和路由(服务发现、DNS解析等)
- 管理层:系统度量(如基础设施、容器和网络的度量),自动化(如自动扩展、动态Provision等)以及策略管理(RBAC、Quota、PSP、NetworkPolicy等)
- 接口层:kubectl命令行工具、客户端SDK以及集群联邦
- 生态系统:在接口层之上的庞大容器集群管理调度的生态系统,可以划分为两个范畴:
- Kubernetes外部:日志、监控、配置管理、CI、CD、Workflow、FaaS、OTS应用、ChatOps等
- Kubernetes内部:CRI、CNI、CVI、镜像仓库、Cloud Provider、集群自身的配置和管理等;
-
Cluster:
- Cluster是计算、存储和网络资源的集合,Kubernetes利用这些资源运行各种基于容器的应用。
- Kubernetes Cluster由Master和Node组成,节点上运行着若干Kubernetes服务。
-
Master:
- 主要职责是调度,即决定将应用放在哪运行。Master运行Linux系统,可以是物理机或虚拟机。Master是Kubernetes Cluster的大脑,运行着的Daemon服务包括kube-apiserver、kube-scheduler、kuber-controller-manager、etcd和pod网络
- Api Server(kube-apiserver)
- Api Server提供 HTTP/HTTPS RESTful API,即Kubernetes API.是Kubernetes里所有资源的CRUD等操作的唯一入口,也是集群控制的入口进程。
- Scheduler(kube-scheduler)
- Scheduler负责资源调度的里程,简单说,它决定将Pod放在哪个Node上运行。
- Controller Manager(kube-controller-manager)
所有资源对象的自动化控制中心。Controller Manager负责管理Cluster各种资源,保证资源处于预期的状态。Controller Manager有多种,如replication controller、endpoints controller、namespace controller、serviceaccounts controller等。
- Api Server(kube-apiserver)
- 主要职责是调度,即决定将应用放在哪运行。Master运行Linux系统,可以是物理机或虚拟机。Master是Kubernetes Cluster的大脑,运行着的Daemon服务包括kube-apiserver、kube-scheduler、kuber-controller-manager、etcd和pod网络
-
Node:
- 除了Master,kubernets集群中的其他机器被称为Node节点。Node职责是运行容器应用,Node由Master管理,Node负责监控并汇报容器的状态,同时根据Master的要求管理容器的生命周期。Node也运行在Linux系统,可以是物理机或虚拟机。
- 每个Node节点上都运行着以下一组关键进程:
- Kubelet: 负责Pod对应的容器的创建、启动等任务,同时与Master节点密切协作,实现集群管理的基本功能。
- Kube-proxy: 实现Kubernetes Service的通信与负载均衡机制的重要组件。
- Docker Enginer: Docker引擎,负责本机的容器创建和管理工作。
-
Pod
- Pod是Kubernetes的最小单元,也是最重要和最基本的概念。每一个Pod包含一个或多个容器,Pod的容器会作为一个整体被Master调度到一个Node上运行。Kubernetes为每个Pod都分配了一个唯一的Ip地址,称为PodIP,一个Pod里的多个容器共享PodIP地址。在Kubernetes里,一个Pod里的容器与另外主机上的Pod容器能够直接通信。
它作为一个最小单元存在。一个Service可以由一个或多个Pod组成。
-
Service
- Kubernetes Service定义了外界访问一组特定Pod的方式,Service有自己的Ip和端口,Service为Pod提供了负载均衡。它也是Kubernetes最核心的资源对象之一,每个Service其实就是我们经常提起的微服务架构中的一个"微服务"。
-
Replication Controller
- Replication Controller(简称RC)是Kubernetes系统中的核心概念之一,它其实是定义了一个期望的场景,即声明某种Pod的副本数量在任意时刻都符合某个预期值,所以RC的定义包括如下几个部分:
- Pod期待的副本数(replicas)
- 用于筛选目标Pod的Label Selector
- Pod的副本数量小于预期数量时,用于创建新Pod的Pod模板(template)
- 以下是总结的RC的一些特性与作用:
- 在大多数情况下,我们通过定义一个RC实现Pod的创建过程及副本数量的自动控制。
- RC里包括完整的Pod定义模板
- RC通过Label Selector机制实现对Pod副本的自动控制
- 通过改变RC里的Pod副本数量,可以实现Pod的扩容或缩容功能
- 通过改变RC里Pod模板中镜像版本,可以实现Pod的滚动升级功能。
- Replication Controller(简称RC)是Kubernetes系统中的核心概念之一,它其实是定义了一个期望的场景,即声明某种Pod的副本数量在任意时刻都符合某个预期值,所以RC的定义包括如下几个部分:
二. Kubernetes集群
2.1 环境准备与规划
- Kubernetes用于协调高度可用的计算机集群,这些计算机集群被连接作为单个单元工作。Kubernetes在一个集群上以更有效的方式自动分发和调度容器应用程序。Kubernetes集群由两种类型的资源组成:
- Master是集群的调度节点
- Nodes是应用程序实际运行的工作节点
- 接下来为大家讲解一下如何快速部署一套Kubernetes集群,K8s集群部署有几种方式:kubeadm、minikube和二进制包。前两者属于自动部署,简化部署操作,我们这里强烈推荐初学者使用二进制包部署,因为自动部署屏蔽了很多细节,使得各个模块感知很少,非常不利于学习。
- 环境准备与规划:
- 推荐2核2G Docker version 17.05.0-ce
- 安装前的一些准备:
- 查看默认防火墙状态(关闭显示not running,开启后显示 running)
firewall-cmd --state
- 关闭防火墙
systemctl stop firewalld.service
- 禁止firewall开机启动
systemctl disable firewalld.service
- 获取Kubernetes二进制包
- 查看默认防火墙状态(关闭显示not running,开启后显示 running)
2.2 Docker安装
2.2.1 设置yum源
- 编辑命令:
vi /etc/yum.repos.d/docker.repo
- 内容:
[dockerrepo] name=Docker Repository baseurl= https://yum.dockerproject.org/repo/main/centos/$releasever/ enabled=1 gpgcheck=1 gpgkey=https://yum.dockerproject.org/gpg
2.2.2 安装docker
yum install docker-engine
2.2.3 安装后查看docker版本
docker -v
2.3 etcd服务
- etcd作为Kubernetes集群的主要服务,在安装Kubernetes各服务前需要首先安装和启动。
- 步骤:
- 下载etcd二进制文件:
https://github.com/etcd-io/etcd/releases
- 上传到master:
可以使用lrzsz,如果没有安装,可以通过yum进行安装yum install lrzsz
也可以用xftp将文件上传
-
将etcd和etcdctl文件复制到/usr/bin目录:
上传上去的文件需要先解压,然后取解压后的文件夹内的指定这2个进行移动。
-
配置systemd服务文件 /usr/lib/systemd/system/etcd.service,配置内容如下:
操作如图:
-
成功后再进行启动与测试etcd服务:
测试内容如下:
- 下载etcd二进制文件:
2.4 kube-apiserver服务
-
解压后将kube-apiserver、kube-controller-manager、kube-scheduler以及管理要使用的kubectl二进制命令文件放到/usr/bin目录,即完成这几个服务的安装。
cp kube-apiserver kube-controller-manager kube-scheduler kubectl /usr/bin/
-
下面是对kube-apiserver服务进行配置,编辑systemd服务文件 vi /usr/lib/systemd/system/kube-apiserver.service
-
最后做配置文件:
-
实战操作:
-
上传kubernetes-server-linux-amd64.tar.gz
-
解压:
tar -zxvf kubernetes-server-linux-amd64.tar.gz
-
进入server/bin目录
cd server/bin
-
将里面指定的者三个文件复制到/usr/bin中:
-
对kube-apiservier.service进行配置,这个配置文件本身不存在,需要我们自己手动建:
使用vi命令进行编辑,保存时若不存在此文件则默认新建此文件。
-
写入如图所示的内容,然后保存退出:
-
保存后,在etc/kubernetes下创建目录,并在下面创建apiserver文件:
-
将内容写入并保存:
-
2.5 kube-controller-manager服务
- kube-controller-manager服务依赖于kube-apiserver服务
- 配置systemd服务文件: vi /usr/lib/systemd/kube-controller-manager.service
- 配置如图:
- 配置文件: vi /etc/kubernetes/controller-manager
注意ip地址,跟随自己Master主机的设置的机器来变化。
2.6 kube-scheduler服务
- kube-scheduler服务也依赖于kube-apiserver服务
- 配置systemd服务文件: vi /usr/lib/systemd/system/kube-scheduler.service
- 配置内容:
- 配置文件: vi etc/kubernetes/scheduler
这里的ip也要换成master的主机地址。
2.6 启动
-
完成以上配置后,按顺序启动服务:
-
实战操作:
- 重新加载:
systemctl daemon-reload
- 启动etcd并查看是否启动:
systemctl enable etcd
systemctl start etcd
systemctl status etcd
- 启动docker服务并查看状态:
systemctl enable docker
systemctl start docker
systemctl status docker
- 启动kube-apiserver
systemctl enable kube-apiserver
systemctl start kube-apiserver
systemctl status kube-apiserver
- 启动kube-controller-manager
systemctl enable kube-controller-manager
systemctl start kube-controller-manager
systemctl status kube-controller-manager
- 启动systemctl enable kube-scheduler
systemctl enable kube-scheduler
systemctl start kube-scheduler
systemctl status kube-scheduler
- Master节点已经安装完毕,这个时候,我们应该将防火墙关闭,否则等会Node节点连接时若没有关闭防火墙,可能会出血一些连接问题。
systemctl stop firewalld
- 重新加载:
2.3 Node 1安装
- 在Node节点上,以同样的方式把压缩包中解压出的二进制文件kubelet-kube-proxy放到usr/bin目录中,在Node节点上需要预先安装docker,请参考Master上的Docker的安装,并启动Docker.
- 上传并解压:
- 进入目录: kubernetes/server/bin 目录下,然后拷贝其中2个文件至指定目录:
- 安装docker等,然后执行如下命令:
yum install docker-engine -y
2.3.1 kubelet服务
-
配置systemd服务文件:vi /usr/lib/systemd/system/kubelet.service:
-
创建kubelet配置文件:
-
若在etc/下没有kubernetes目录,我们就先新建一个此目录:mkdir /etc/kubernetes,如图所示: 创建两个文件夹,然后创建一个配置文件:
-
配置文件中填写内容:
-
编辑kubeconfig,并完善内容:
这里的额140服务器要改为我们实际的Master的ip地址;注意格式与缩进,内容如图所示:
2.3.2 kube-proxy服务
-
kubu-proxy服务依赖于network服务,所以一定要保证network服务正常,如果network服务启动失败,常见解决方案有以下几种:
-
安装步骤:
注意master的ip地址和自己的ip地址;
2.3.3 启动
- 接下来,我们就把我们的服务都启动一下:
systemctl daemon-reload
systemctl enable kubelet
systemctl start kubelet
systemctl status kubelet
systemctl enable kube-proxy
systemctl start kube-proxy
systemctl status kube-proxy
- 实战步骤如下:
- 检查并启动docker:
- 启动kubelet:
- 启动kube-proxy:
- 检查并启动docker:
2.4 Node 2安装
- Node2的节点根Node1 的步骤是一样的,只是本机的ip需要改变一下;
- 具体的安装步骤可参考上面的安装Node节点1步骤
2.5 健康检查与示例测试一
-
测试命令:
kubectl get nodes
-
如果发现结果为: “未找到命令”,则进入kubernetes中修改:
- 进入目录:
- 将kubectl 拷贝到 usr/bin下面:
- 再次执行命令:
kubectl get nodes
,若发现有2台设备则说明成功:
- 如果发现还是没有成功,可看下是否为下图中的问题:
- 进入目录:
-
获取集群的状态:
kubectl get cs
返回如图的ok时表示健康:
-
创建nginx-rc.yaml:
文件中描述的是:我们创建了一个Nginx,创建了3个副本,暴露的端口是80端口
-
创建nginx-svc.yml:在k8s目录中
-
根据nginx进行创建:
都是在k8s下执行。它的路径为:/usr/local/k8s
2.6 健康检查与测试二
- 搭建私有仓库的方法:
- 实战步骤:
- 拉去镜像:
- 运行镜像:
- vim 编辑daemon.json文件:
- 修改内容如下,ip改为自己的ip:
- 重启:
systemctl restart docker
- 拉去镜像:
2.7 K8S架构和组件
-
Master:
- Kubernetes Api Server: 作为Kubernetes系统的入口,其封装了核心对象的增删改查操作,以Restful API接口方式提供给外部客户和内部组件调用。维护的REST对象持久化到Etcd中存储。
- Kubernetes Scheduler: 为新建立的Pod进行节点(node)选择(即分配机器),负责集群的资源调度。组件抽离,可以方便替换成其他调度器
- Kubernetes Controller:负责执行各种控制器,目前已经提供了许多控制器来保证Kubernetes的正常运行
- Replication Controller: 关联Replication Controller 和Pod,保证Replication Controller定义的副本数量与实际运行Pod数量一致。
-
Node:
- Kubelet:负责管控容器,Kubelet会从Kubernetes Api Server接收Pod的创建请求,启动和停止容器,监控容器运行状态并汇报给Kubernetes API Server
- Kubernetes Proxy: 负责为Pod创建代理服务,Kubernetes Proxy会从Kubernetes API Server获取所有的Server信息,并根据Service的信息创建代理服务,实现Service到Pod的请求路由和转发,从而实现Kubernetes层级的虚拟转发网络。
- Docker:Node上需要运行容器服务。
-
常见问题及解决方案:
- 问题1:
- 问题2:
- 问题1:
2.8 Kubernetes 常用命令
- 获取当前命名空间下的容器:
kubectl get pods
- 获取所有容器列表
kubectl get all
- 创建容器
kubectl create -f kubernate-pvc.yaml
- 删除容器
kubectl delete pods/test-pd 或者 kubectl delete -f rc-nginx.yaml
- 查看指定pod跑在哪个node上
kubectl get pod /test-pd -o wide
- 查看容器日志
kubectl logs nginx-8586cf59-mwwtc
- 进入容器终端命令:
kubectl exec -it nginx-8586cf59-mwwtc /bin/bash
- 一个Pod里含有多个容器 用–container or -c 参数。
例如:假如这里有个Pod名为my-pod,这个pod有两个容器,分别名为main-app 和helper-app,下面的命令将打开到main-app的shell的容器里。
kubectl exec -it my-pod --container main-app -- /bin/bash
- 容器详情列表
kubectl describe pod/mysql0 m8rbl
三. 容器化进阶Kubernetes 核心技术
3.1 Pod详解
-
Pod是Kubernetes的重要概念,每一个Pod都有一个特殊的呗称为“根容器”的Pause容器。Pause容器对象的镜像属于Kubernetes平台的一部分,除了Pause容器,每个Pod还包含一个或多个紧密相关的用户业务容器。
-
Pod在K8s集群中的图:
-
Pod的区别:
-
下面是yaml文件定义的pod完整内容:
-
Pod的基本用法
- 在Kubernetes中对运行容器的要求为:容器的主程序需要一直在前台运行,而不是后台运行。应用需要改造成前台运行方式。如果我们创建的Docker镜像的启动命令是后台执行程序,则在kubelet创建包含这个容器的pod之后运行该命令,即认为Pod已经结束,将立刻销毁该Pod。如果为该Pod定义了RC,则创建、销毁会陷入一个无线循环的过程中。
- Pod可以由一个或多个容器组成
- 由一个容器组成的Pod示例:
- 由两个为紧耦合的容器组成的Pod示例:
- 创建
kubectl create -f xxx.yaml
- 查看
kubectl get pod/po <Pod_name> kubectl get pod/po <Pod_name> -o wide kubectl describe pod/po <Pod_name>
- 删除
kubectl delete -f pod pod_name.yaml
kubectl delete pod --all/[pod_name]
-
Pod 的分类:
- 普通Pod:普通Pod一旦被创建,就会被放入到etcd中存储,随后会被Kubernetes Master调度到某个具体的Node上并进行绑定,随后该Pod对应的Node上的kubelet进程实例化成一组相关的Docker容器并启动起来。在默认情况下,当Pod里某个容器停止时,Kubernetes会自动检测到这个问题并且重新启动这个Pod里所有容器,如果Pod所在的Node宕机,则会将这个Node上的所有Pod重新调度到其他节点上。
- 静态Pod:静态Pod是由kubelet进行管理的仅存在于特定Node上的Pod,它们不能通过API Server进行管理,无法与ReplicationCOntroller、Deployment或DaemonSet进行关联,并且kubelet也无法对它们进行健康检查。
静态的很少用。
-
Pod生命周期和重启策略:
-
Pod的状态:
说明 ing ing leted own -
Pod重启策略:
- Pod的重启策略包括Always、Onfailure和Never,默认是Always;
重启策略|说明
--------|--------
Always|当容器失效时,由Kubelet自动重启该容器
Onfailure| 当容器终止运行且退出码不为0时,由kubelet自动重启该容器
Never | 不论容器运行状态如何,kubelet都不会重启该容器
- Pod的重启策略包括Always、Onfailure和Never,默认是Always;
-
常见状态转换
含的容器数 Pod当前的状态 发生事件 Pod的结果状态 estartPolicy=Always RestartPolicy=OnFailure RestartPolicy=Never 容器 Running 容器成功退出 Running 容器 Running 容器失败退出 Running 容器 Running 1个容器失败退出 Running 容器 Running 容器被OOM杀掉 Running -
Pod资源配置:
- 每个Pod都可以对其能使用的服务器上的计算资源设置限额,Kubernetes中可以设置限额的计算资源有CPU与Memory两种,其中CPU的资源单位为CPU数量,是一个绝对值而非相对值。Memory配额也是一个绝对值,它的单位是内存字节数。
- Kubernetes里,一个计算资源进行配额限定需要设定以下两个参数:
- Requests:该资源最小申请数量,系统必须满足要求;
- Limits该资源最大允许使用的量,不能突破,当容器试图使用超过这个量的资源时,可能会被Kubernetes Kill并重启:
上述代码表明MySQL容器申请最少0.25个CPU以及64MiB内存,在运行过程中容器所能使用的资源配额为0.5个CPU以及128MiB内存。
-
3.2 Label详解
-
Label是Kubernetes系统中另一个核心概念。一个Label是一个key=value的键值对,其中key与value由用户自己指定。Label可以附加到各种资源上, 如Node、Pod、Service、RC,一个资源对象可以定义任意数量的Label,同一个Label也可以被添加到任意数量的资源上,Label通常在资源对象定义时确定,也可以在对象创建后动态添加或删除。
-
Label的最常见的用法是使用metadata.labels字段,来为对象添加Label,通过spec.selector来引用对象;
-
Label附加到Kubernetes集群的各种资源对象上,目的就是对这些资源对象进行分组管理,而分组管理的核心就是Label Selector。Label与Label Selector都是不能单独定义,必须附加在一些资源对象的定义文件上,一般附加在RC和Service的资源定义文件中。
3.3 Replication Controller详解
- Replication Controller(RC)是Kubernetes系统中核心概念之一,当我们定义了一个RC并提交到Kubernetes集群中以后,Master节点上的Controller Manager组件就得到通知,定期检查系统中存活的Pod,并确保目标Pod实例的数量刚好等于RC的预期值,如果有过多或过少的Pod运行,系统就会停掉或创建一些Pod,此外我们也可以通过修改RC的副本数量,来实现Pod的动态缩放功能。
kubectl scale rc nginx --replicas=5
- 由于Replication Controller与Kubernetes代码中的模块Replication Controller同名,所以在Kubernetes v1.2时,它就升级成了另外一个新的概念Replica Sets,官方解释为下一代的RC,它与RC的区别是:Replica Sets支援基于集合的Label selector,而RC只支持基于等式的Label Selector。我们很少单独使用Replica Set,它主要被Deployment这个更高层面的资源对象所使用,从而形成一整套Pod创建、删除、更新的编排机制。最好不要越过RC直接创建Pod,因为Replication Controller会通过RC管理Pod副本,实现自动创建、补足、替换、删除Pod副本,这样就能提高应用的容灾能力,减少由于节点崩溃等意外状况造成的损失。即使应用程序只有一个Pod副本,也强烈建议使用RC来定义Pod。
3.4 Replica Set详解
- ReplicaSet根ReplicationCOntroller没有本质的不同,只是名字不一样,并且ReplicaSet支持集合式的selector(ReplicationController仅支持等式)。由于ReplicaSet是ReplicationController的代替物,因此用法基本相同,唯一的区别在于ReplicaSet支持集合式的selector.
3.5 Deployment详解
- Deployment是Kuberntes v1.2 引入的一个概念,引入的目的是为了更好的解决Pod的编排问题,Deployment内部使用了Replica Set来实现。Deployment的定义与Replica Set的定义很类似,除了API声明与Kind类型有所区别:
3.6 Horizontal Pod Autoscaler
-
Horizontal Pod Autoscal(Pod 横向扩容 简称HPA)与RC、Deployment一样,也属于一种Kubernetes资源对象。通过追踪分析RC控制的所有目标Pod的负载变化情况,来确定是否需要针对性地调整目标Pod的副本数,这是HPA的实现原理。
-
Kubernetes对Pod扩容与缩容提供了手动和自动两种模式,手动模式通过kubectl scale命令对一个Deployment/RC进行Pod副本数量的设置。自动模式则需要用户根据某个性能指标或者自定义业务指标,并制定Pod副本数量的范围,系统将自动在这个范围内根据性能指标的变化进行调整。
-
手动扩容和缩容:
kubectl scale deployment frontend --replicas 1
-
自动扩容和缩容:
- HPA控制器基本Master的kube-controller-manager 服务启动参数 --horizontal-pod-autoscaler-sync-period定义的时长(默认值为30s),周期性地检测Pod的CPU使用率,并在满足条件时对RC或Deployment中的Pod副本数量进行调整,以符合用户定义的平均Pod CPU使用率。
- HPA控制器基本Master的kube-controller-manager 服务启动参数 --horizontal-pod-autoscaler-sync-period定义的时长(默认值为30s),周期性地检测Pod的CPU使用率,并在满足条件时对RC或Deployment中的Pod副本数量进行调整,以符合用户定义的平均Pod CPU使用率。
3.7 Volume详解
-
Volume是Pod中能够被多个容器访问的共享目录。Kubernetes的Volume定义在Pod上,它被一个Pod中的多个容器挂载到具体的文件目录下。Volume中的数据也不会丢失。要使用volume,pod需要指定Volume的类型和内容(spec.volumes)字段和映射到容器的位置(spec.containers.volumeMounts字段)
-
Kubernetes支持多种类型的Volume,包括:emptyDir、hostPath、gcePersistentDisk、awsElasticBlockStore、nfs、iscsi、flocker、glusterfs、rbd、cephfs、gitRepo、secret、persistentVolumeClaim、downwardAPI、azureFileVolume、azureDisk、vsphereVolume、Quobyte、PortworxVolume、ScaleO.
-
emptyDir
- EmptyDir类型的volume创建于Pod被调度到某个宿主机上的时候,而同一个pod内的容器都能读写EmptyDir中的同一个文件。一旦这个pod离开了这个宿主机,EmptyDir中的数据就会被永久删除。所以目前EmptyDir类型的volume主要用做临时空间,比如Web服务器写日志或者tmp文件需要的临时目录。yaml示例如下:
- EmptyDir类型的volume创建于Pod被调度到某个宿主机上的时候,而同一个pod内的容器都能读写EmptyDir中的同一个文件。一旦这个pod离开了这个宿主机,EmptyDir中的数据就会被永久删除。所以目前EmptyDir类型的volume主要用做临时空间,比如Web服务器写日志或者tmp文件需要的临时目录。yaml示例如下:
-
hostPath
- HostPath属性的volume使得对应的容器能够访问当前宿主机上的指定目录。例如,需要运行一个访问Docker系统目录的容器,那么就使用/var/lib/docker目录作为一个HostDir类型的volume;或者要在一个容器内部运行CAvisor,那么就使用/dev/cgroups目录作为一个HostDir类型的volume。一旦这个pod离开了这个宿主机,HostDir中的数据虽然不会被永久删除,但数据也不会随pod迁移到其他宿主机上。因此,需要注意的是,由于各个宿主机上的文件系统结构并不一定完全相同,所以相同pod的HostDir可能会在不同的宿主机上表现出不同和的行为。yaml示例如下:
- HostPath属性的volume使得对应的容器能够访问当前宿主机上的指定目录。例如,需要运行一个访问Docker系统目录的容器,那么就使用/var/lib/docker目录作为一个HostDir类型的volume;或者要在一个容器内部运行CAvisor,那么就使用/dev/cgroups目录作为一个HostDir类型的volume。一旦这个pod离开了这个宿主机,HostDir中的数据虽然不会被永久删除,但数据也不会随pod迁移到其他宿主机上。因此,需要注意的是,由于各个宿主机上的文件系统结构并不一定完全相同,所以相同pod的HostDir可能会在不同的宿主机上表现出不同和的行为。yaml示例如下:
-
nfs:
- NFS类型的volume. 允许一块现有的网络硬盘在同一个Pod内的容器间共享。yaml示例如下:
- NFS类型的volume. 允许一块现有的网络硬盘在同一个Pod内的容器间共享。yaml示例如下:
-
Namespace详解
- Namespace在很多情况下用于实现多用户的资源隔离,通过将集群内部的资源对象分配到不同的Namespace中形成逻辑上的分组,便于不同的分组在共享使用整个集群的资源同时还能被分别管理。Kubernetes集群在启动后,会创建一个名为"default"的Namespace,如果不特别指明Namespace,则用户创建的Pod,RC,Service都将被系统创建到这个默认的名为default的Namespace中。
- Namespace创建:
- Namespace查看
kubectl get pods --namespace=development
3.9 Service详解
-
Service是Kubernetes最核心概念,通过创建Service,可以为一组具有相同功能的容器应用提供一个统一的入口地址,并且将请求负载分发到后端的各个容器应用上。
-
service的定义(yaml格式的定义文件:完整的yaml文件):
-
每个字段代表的意义:
-
Service的基本用法:
-
一般来说,对外提供服务的应用程序需要通过某种机制来实现,对于容器应用最简便的方式就是通过TCP/IP机制及监听IP和端口号来实现。创建一个基本功能的Service:
-
我们可以通过kubectl get pods -l app=mywebapp -o yaml | grep podIP来获取Pod的Ip地址和端口号来访问Tomcat服务,但是直接通过Pod的Ip地址和端口号访问应用服务是不可靠的,因为当Pod所在的Node发生故障时,Pod将被Kubernetes重新调度到另一台Node,Pod的地址会发生改变。我们可以通过配置文件来定义Service,再通过Kubectl create来创建,这样可以通过Service地址来访问后端的Pod.
-
多端口Service
有时一个容器应用也可能需要提供多个端口的服务,那么在Service的定义中也可以相应地设置为将多个端口对应到多个应用服务。
-
外部服务Service:
在某些特殊环境中,应用系统需要将一个外部数据库作为后端服务进行连接,或将另一个集群或NameSpace中的服务作为服务的后端,这时可以通过创建一个无Label Selector的Service来实现。
-