初识kuberneters
一:kuberneters简介
kubernetes的本质是一组服务器集群,它可以在集群的每个节点上运行特定的程序,来对节点中的容器进行管理。目的是实现资源管理的自动化,主要提供了如下的主要功能:
自我修复:一旦某一个容器崩溃,能够在1秒中左右迅速启动新的容器
弹性伸缩:可以根据需要,自动对集群中正在运行的容器数量进行调整
服务发现:服务可以通过自动发现的形式找到它所依赖的服务
负载均衡:如果一个服务起动了多个容器,能够自动实现请求的负载均衡
版本回退:如果发现新发布的程序版本有问题,可以立即回退到原来的版本
存储编排:可以根据容器自身的需求自动创建存储卷
二:kuberneters组件介绍
kubernetes集群主要是由控制节点(master)、**工作节点(node)**构成,每个节点上都会安装不同的组件。
master:集群的控制平面,负责集群的决策 ( 管理 )
ApiServer : 资源操作的唯一入口,接收用户输入的命令,提供认证、授权、API注册和发现等机制
Scheduler : 负责集群资源调度,按照预定的调度策略将Pod调度到相应的node节点上
ControllerManager : 负责维护集群的状态,比如程序部署安排、故障检测、自动扩展、滚动更新等
Etcd :负责存储集群中各种资源对象的信息
node:集群的数据平面,负责为容器提供运行环境 ( 干活 )
Kubelet : 负责维护容器的生命周期,即通过控制docker,来创建、更新、销毁容器
KubeProxy : 负责提供集群内部的服务发现和负载均衡
Docker : 负责节点上容器的各种操作
三:kubernetes资源
Master:集群控制节点,每个集群需要至少一个master节点负责集群的管控
Node:工作负载节点,由master分配容器到这些node工作节点上,然后node节点上的docker负责容器的运行
Pod:kubernetes的最小控制单元,容器都是运行在pod中的,一个pod中可以有1个或者多个容器
Controller:控制器,通过它来实现对pod的管理,比如启动pod、停止pod、伸缩pod的数量等等
Service:pod对外服务的统一入口,下面可以维护者同一类的多个pod
Label:标签,用于对pod进行分类,同一类pod会拥有相同的标签
NameSpace:命名空间,用来隔离pod的运行环境
四:kubuternetes组件工作原理
部署一个nginx服务来说明kubernetes系统各个组件调用关系:
首先要明确,一旦kubernetes环境启动之后,master和node都会将自身的信息存储到etcd数据库中
一个nginx服务的安装请求会首先被发送到master节点的apiServer组件
apiServer组件会调用scheduler组件来决定到底应该把这个服务安装到哪个node节点上
在此时,它会从etcd中读取各个node节点的信息,然后按照一定的算法进行选择,并将结果告知apiServer
apiServer调用controller-manager去调度Node节点安装nginx服务
kubelet接收到指令后,会通知docker,然后由docker来启动一个nginx的pod
pod是kubernetes的最小操作单元,容器必须跑在pod中至此,
一个nginx服务就运行了,如果需要访问nginx,就需要通过kube-proxy来对pod产生访问的代理
这样,外界用户就可以访问集群中的nginx服务了
详解kuberneters
一:pod详解
每个Pod中都可以包含一个或者多个容器,这些容器可以分为两类:
用户程序所在的容器,数量可多可少
Pause容器,这是每个Pod都会有的一个根容器,它的作用有两个:
可以以它为依据,评估整个Pod的健康状态
可以在根容器上设置Ip地址,其它容器都此Ip(Pod IP),以实现Pod内部的网路通信
1.1pod资源清单-yaml 编写
apiVersion: v1
kind: Pod
metadata:
name: pod-resources
namespace: dev
spec: #pod的具体描述信息
containers:
- name: nginx
image: nginx:1.17.1
imagePullPolicy: Never # 镜像拉取策略
resources: # 资源配额
limits: # 限制资源(上限)
cpu: "2" # CPU限制,单位是core数
memory: "10Gi" # 内存限制
requests: # 请求资源(下限)
cpu: "1" # CPU限制,单位是core数
memory: "10Mi" # 内存限制
ports:
- containerPort: 80 # 容器开放的端口
protocol: TCP
env: # 环境变量列表
- name: username
value: "admin"
- name: password
value: "123456"
command: ["/bin/sh","-c","touch /tmp/hello.txt;while true;do /bin/echo $(date +%T) >> /tmp/hello.txt; sleep 3; done;"] #容器启动后执行的命令
#查看资源清单,查看每种资源的可配置项。
kubectl explain pod
1.2资源属性
在kubernetes中基本所有资源的一级属性都是一样的,主要包含5部分:
- apiVersion 版本,由kubernetes内部定义,版本号必须可以用 kubectl api-versions 查询到
- kind 类型,由kubernetes内部定义,版本号必须可以用 kubectl api-resources 查询到
- metadata 元数据,主要是资源标识和说明,常用的有name、namespace、labels等
- spec 描述,这是配置中最重要的一部分,里面是对各种资源配置的详细描述
- status 状态信息,里面的内容不需要定义,由kubernetes自动生成
1.3spec 描述
在上面的属性中,spec是接下来研究的重点,继续看下它的常见子属性:
- containers <[]Object> 容器列表,用于定义容器的详细信息
- nodeName 根据nodeName的值将pod调度到指定的Node节点上
- nodeSelector <map[]> 根据NodeSelector中定义的信息选择将该Pod调度到包含这些label的Node 上
- hostNetwork 是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络
- volumes <[]Object> 存储卷,用于定义Pod上面挂在的存储信息
- restartPolicy 重启策略,表示Pod在遇到故障的时候的处理策略
1.3.1 containers容器的详细信息
[root@k8s-master~]# kubectl explain pod.spec.containers
KIND: Pod
VERSION: v1
RESOURCE: containers <[]Object> # 数组,代表可以有多个容器
FIELDS:
name <string> # 容器名称
image <string> # 容器需要的镜像地址
imagePullPolicy <string> # 镜像拉取策略
command <[]string> # 容器的启动命令列表,如不指定,使用打包时使用的启动命令
args <[]string> # 容器的启动命令需要的参数列表
env <[]Object> # 容器环境变量的配置
ports <[]Object> # 容器需要暴露的端口号列表
1.3.2 imagePullPolicy镜像拉取策略
imagePullPolicy默认值说明:
如果镜像tag为具体版本号, 默认策略是:IfNotPresent
如果镜像tag为:latest(最终版本) ,默认策略是always
1.3.3 command容器启动后命令
command: ["/bin/sh","-c","while true;do /bin/echo $(date +%T);sleep 60; done;"]
1.3.4 env 环境变量
# 设置环境变量列表
- name: "username"
value: "admin"
- name: "password"
value: "123456"
1.3.5 port端口
- name <string> # 端口名称,如果指定,必须保证name在pod中是唯一的
- containerPort<integer> # 容器要监听的端口(0<x<65536)
- hostPort <integer> # 容器要在主机上公开的端口,如果设置,主机上只能运行容器的一个副本(一般省略)
- hostIP <string> # 要将外部端口绑定到的主机IP(一般省略)
- protocol <string> # 端口协议。必须是UDP、TCP或SCTP。默认为“TCP”。
1.3.6 restartPolicy资源配额
limits:用于限制运行时容器的最大占用资源,当容器占用资源超过limits时会被终止,并进行重启
requests :用于设置容器需要的最小资源,如果环境资源不够,容器将无法启动
#cpu:core数,可以为整数或小数
#memory: 内存大小,可以使用Gi、Mi、G、M等形式
1.3.7 pod生命周期
我们一般将pod对象从创建至终的这段时间范围称为pod的生命周期,它主要包含下面的过程:
pod创建过程
运行初始化容器(init container)过程
运行主容器(main container)
容器启动后钩子(post start)、容器终止前钩子(pre stop)
容器的存活性探测(liveness probe)、就绪性探测(readiness probe)
pod终止过程
整个生命周期中,Pod会出现5种状态(相位),分别如下:
- 挂起(Pending):apiserver已经创建了pod资源对象,但它尚未被调度完成或者仍处于下载镜像的过程中
- 运行中(Running):pod已经被调度至某节点,并且所有容器都已经被kubelet创建完成
- 成功(Succeeded):pod中的所有容器都已经成功终止并且不会被重启
- 失败(Failed):所有容器都已经终止,但至少有一个容器终止失败,即容器返回了非0值的退出状态
- 未知(Unknown):apiserver无法正常获取到pod对象的状态信息,通常由网络通信失败所导致
1.3.8 pod创建和终止
pod的创建过程
用户通过kubectl或其他api客户端提交需要创建的pod信息给apiServer
apiServer开始生成pod对象的信息,并将信息存入etcd,然后返回确认信息至客户端
apiServer开始反映etcd中的pod对象的变化,其它组件使用watch机制来跟踪检查apiServer上的变动
scheduler发现有新的pod对象要创建,开始为Pod分配主机并将结果信息更新至apiServer
node节点上的kubelet发现有pod调度过来,尝试调用docker启动容器,并将结果回送至apiServer
apiServer将接收到的pod状态信息存入etcd中
pod的终止过程
用户向apiServer发送删除pod对象的命令
apiServcer中的pod对象信息会随着时间的推移而更新,在宽限期内(默认30s),pod被视为dead
将pod标记为terminating状态
kubelet在监控到pod对象转为terminating状态的同时启动pod关闭过程
端点控制器监控到pod对象的关闭行为时将其从所有匹配到此端点的service资源的端点列表中移除
如果当前pod对象定义了preStop钩子处理器,则在其标记为terminating后即会以同步的方式启动执行
pod对象中的容器进程收到停止信号
宽限期结束后,若pod中还存在仍在运行的进程,那么pod对象会收到立即终止的信号
kubelet请求apiServer将此pod资源的宽限期设置为0从而完成删除操作,此时pod对于用户已不可见
1.3.9 初始化容器
初始化容器是在pod的主容器启动之前要运行的容器,主要是做一些主容器的前置工作,它具有两大特征:
初始化容器必须运行完成直至结束,若某初始化容器运行失败,那么kubernetes需要重启它直到成功完成
初始化容器必须按照定义的顺序执行,当且仅当前一个成功之后,后面的一个才能运行
初始化容器有很多的应用场景,下面列出的是最常见的几个:
提供主容器镜像中不具备的工具程序或自定义代码
初始化容器要先于应用容器串行启动并运行完成,因此可用于延后应用容器的启动直至其依赖的条件得到满足
# 创建pod
[root@k8s-master01 ~]# kubectl create -f pod-initcontainer.yaml
pod/pod-initcontainer created
# 查看pod状态
# 发现pod卡在启动第一个初始化容器过程中,后面的容器不会运行
root@k8s-master01 ~]# kubectl describe pod pod-initcontainer -n dev
........
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 49s default-scheduler Successfully assigned dev/pod-initcontainer to node1
Normal Pulled 48s kubelet, node1 Container image "busybox:1.30" already present on machine
Normal Created 48s kubelet, node1 Created container test-mysql
Normal Started 48s kubelet, node1 Started container test-mysql
# 动态查看pod
[root@k8s-master01 ~]# kubectl get pods pod-initcontainer -n dev -w
NAME READY STATUS RESTARTS AGE
pod-initcontainer 0/1 Init:0/2 0 15s
pod-initcontainer 0/1 Init:1/2 0 52s
pod-initcontainer 0/1 Init:1/2 0 53s
pod-initcontainer 0/1 PodInitializing 0 89s
pod-initcontainer 1/1 Running 0 90s
# 接下来新开一个shell,为当前服务器新增两个ip,观察pod的变化
[root@k8s-master01 ~]# ifconfig ens33:1 192.168.90.14 netmask 255.255.255.0 up
[root@k8s-master01 ~]# ifconfig ens33:2 192.168.90.15 netmask 255.255.255.0 up
1.3.10钩子函数
钩子函数能够感知自身生命周期中的事件,并在相应的时刻到来时运行用户指定的程序代码。
kubernetes在主容器的启动之后和停止之前提供了两个钩子函数:
post start:容器创建之后执行,如果失败了会重启容器
pre stop :容器终止之前执行,执行完成之后容器将成功终止,在其完成之前会阻塞删除容器的操作
钩子处理器支持使用下面三种方式定义动作:
Exec命令:在容器内执行一次命令
……
lifecycle:
postStart:
exec:
command:
- cat
- /tmp/healthy
……
TCPSocket:在当前容器尝试访问指定的socket
……
lifecycle:
postStart:
tcpSocket:
port: 8080
……
HTTPGet:在当前容器中向某url发起http请求
……
lifecycle:
postStart:
httpGet:
path: / #URI地址
port: 80 #端口号
host: 192.168.5.3 #主机地址
scheme: HTTP #支持的协议,http或者https
……
接下来,以exec方式为例,演示下钩子函数的使用,创建pod-hook-exec.yaml文件,内容如下
apiVersion: v1
kind: Pod
metadata:
name: pod-hook-exec
namespace: dev
spec:
containers:
- name: main-container
image: nginx:1.17.1
ports:
- name: nginx-port
containerPort: 80
lifecycle:
postStart:
exec: # 在容器启动的时候执行一个命令,修改掉nginx的默认首页内容
command: ["/bin/sh", "-c", "echo postStart... > /usr/share/nginx/html/index.html"]
preStop:
exec: # 在容器停止之前停止nginx服务
command: ["/usr/sbin/nginx","-s","quit"]
# 创建pod
[root@k8s-master01 ~]# kubectl create -f pod-hook-exec.yaml
pod/pod-hook-exec created
# 查看pod
[root@k8s-master01 ~]# kubectl get pods pod-hook-exec -n dev -o wide
NAME READY STATUS RESTARTS AGE IP NODE
pod-hook-exec 1/1 Running 0 29s 10.244.2.48 node2
# 访问pod
[root@k8s-master01 ~]# curl 10.244.2.48
postStart...
1.3.11 容器探测
容器探测用于检测容器中的应用实例是否正常工作,是保障业务可用性的一种传统机制。如果经过探测,实例的状态不符合预期,那么kubernetes就会把该问题实例" 摘除 ",不承担业务流量。kubernetes提供了两种探针来实现容器探测,分别是:
liveness probes:存活性探针,用于检测应用实例当前是否处于正常运行状态,如果不是,k8s会重启容器
readiness probes:就绪性探针,用于检测应用实例当前是否可以接收请求,如果不能,k8s不会转发流量livenessProbe 决定是否重启容器,readinessProbe 决定是否将请求转发给容器。
livenessProbe 决定是否重启容器,readinessProbe 决定是否将请求转发给容器。
1.3.12 重启策略
在上一节中,一旦容器探测出现了问题,kubernetes就会对容器所在的Pod进行重启,其实这是由pod的重启策略决定的,pod的重启策略有 3 种,分别如下:
Always :容器失效时,自动重启该容器,这也是默认值。
OnFailure : 容器终止运行且退出码不为0时重启
Never : 不论状态为何,都不重启该容器
重启策略适用于pod对象中的所有容器,首次需要重启的容器,将在其需要时立即进行重启,随后再次需要重启的操作将由kubelet延迟一段时间后进行,且反复的重启操作的延迟时长以此为10s、20s、40s、80s、160s和300s,300s是最大延迟时长。
1.3.12 pod 调度
在默认情况下,一个Pod在哪个Node节点上运行,是由Scheduler组件采用相应的算法计算出来的,这个过程是不受人工控制的。但是在实际使用中,这并不满足的需求,因为很多情况下,我们想控制某些Pod到达某些节点上,那么应该怎么做呢?这就要求了解kubernetes对Pod的调度规则,kubernetes提供了四大类调度方式:
- 自动调度:运行在哪个节点上完全由Scheduler经过一系列的算法计算得出
- 定向调度:NodeName、NodeSelector
- 亲和性调度:NodeAffinity、PodAffinity、PodAntiAffinity
- 污点(容忍)调度:Taints、Toleration
1.3.12 .1自动调度
运行在哪个节点上完全由Scheduler经过一系列的算法计算得出
1.3.12 .2定向调度
NodeName
NodeName用于强制约束将Pod调度到指定的Name的Node节点上。这种方式,其实是直接跳过Scheduler的调度逻辑,直接将Pod调度到指定名称的节点。
NodeSelector
NodeSelector用于将pod调度到添加了指定标签的node节点上。它是通过kubernetes的label-selector机制实现的,也就是说,在pod创建之前,会由scheduler使用MatchNodeSelector调度策略进行label匹配,找出目标node,然后将pod调度到目标节点,该匹配规则是强制约束。
1.3.12 .3亲和性调度
nodeAffinity(node亲和性): 以node为目标,解决pod可以调度到哪些node的问题
podAffinity(pod亲和性) : 以pod为目标,解决pod可以和哪些已存在的pod部署在同一个拓扑域中的问题
podAntiAffinity(pod反亲和性) : 以pod为目标,解决pod不能和哪些已存在pod部署在同一个拓扑域中的问题
关于亲和性(反亲和性)使用场景的说明:
亲和性:如果两个应用频繁交互,那就有必要利用亲和性让两个应用的尽可能的靠近,这样可以减少因网络通信而带来的性能损耗。
反亲和性:当应用的采用多副本部署时,有必要采用反亲和性让各个应用实例打散分布在各个node上,这样可以提高服务的高可用性。
1.3.12 .4 污点与容忍
污点(Taints) 给node 添加,pod就调度不到对应污点node上。
前面的调度方式都是站在Pod的角度上,通过在Pod上添加属性,来确定Pod是否要调度到指定的Node上,其实我们也可以站在Node的角度上,通过在Node上添加污点属性,来决定是否允许Pod调度过来。
Node被设置上污点之后就和Pod之间存在了一种相斥的关系,进而拒绝Pod调度进来,甚至可以将已经存在的Pod驱逐出去。
污点的格式为:key=value:effect, key和value是污点的标签,effect描述污点的作用,支持如下三个选项:
- PreferNoSchedule:kubernetes将尽量避免把Pod调度到具有该污点的Node上,除非没有其他节点可调度
- NoSchedule:kubernetes将不会把Pod调度到具有该污点的Node上,但不会影响当前Node上已存在的Pod
- NoExecute:kubernetes将不会把Pod调度到具有该污点的Node上,同时也会将Node上已存在的Pod驱离
# 设置污点
kubectl taint nodes node1 key=value:effect# 去除污点
kubectl taint nodes node1 key:effect-# 去除所有污点
kubectl taint nodes node1 key-
容忍 给pod 添加容忍,调度到node上。
tolerations: # 添加容忍
- key: "tag" # 要容忍的污点的key
operator: "Equal" # 操作符
value: "heima" # 容忍的污点的value
effect: "NoExecute" # 添加容忍的规则,这里必须和标记的污点规则相同
1.3.13.1 pod控制器详解
Pod是kubernetes的最小管理单元,在kubernetes中,按照pod的创建方式可以将其分为两类:
自主式pod:kubernetes直接创建出来的Pod,这种pod删除后就没有了,也不会重建.
什么是Pod控制器:
Pod控制器是管理pod的中间层,使用Pod控制器之后,只需要告诉Pod控制器,想要多少个什么样的Pod就可以了,它会创建出满足条件的Pod并确保每一个Pod资源处于用户期望的目标状态。如果Pod资源在运行中出现故障,它会基于指定策略重新编排Pod。
ReplicationController:比较原始的pod控制器,已经被废弃,由ReplicaSet替代
ReplicaSet:保证副本数量一直维持在期望值,并支持pod数量扩缩容,镜像版本升级
Deployment:通过控制ReplicaSet来控制Pod,并支持滚动升级、回退版本
Horizontal Pod Autoscaler:可以根据集群负载自动水平调整Pod的数量,实现削峰填谷
DaemonSet:在集群中的指定Node上运行且仅运行一个副本,一般用于守护进程类的任务
Job:它创建出来的pod只要完成任务就立即退出,不需要重启或重建,用于执行一次性任务
Cronjob:它创建的Pod负责周期性任务控制,不需要持续后台运行
StatefulSet:管理有状态应用
------------------------------------------------------------------------------------------------------
金丝雀发布Deployment
Deployment控制器支持控制更新过程中的控制,如“暂停(pause)”或“继续(resume)”更新操作。
比如有一批新的Pod资源创建完成后立即暂停更新过程,此时,仅存在一部分新版本的应用,主体部分还是旧的版本。然后,再筛选一小部分的用户请求路由到新版本的Pod应用,继续观察能否稳定地按期望的方式运行。确定没问题之后再继续完成余下的Pod资源滚动更新,否则立即回滚更新操作。这就是所谓的金丝雀发布。
二:service 详解
在kubernetes中,pod是应用程序的载体,我们可以通过pod的ip来访问应用程序,但是pod的ip地址不是固定的,这也就意味着不方便直接采用pod的ip对服务进行访问。
为了解决这个问题,kubernetes提供了Service资源,Service会对提供同一个服务的多个pod进行聚合,并且提供一个统一的入口地址。通过访问Service的入口地址就能访问到后面的pod服务。
1.1userspace模式
userspace模式下,kube-proxy会为每一个Service创建一个监听端口,发向Cluster IP的请求被Iptables规则重定向到kube-proxy监听的端口上,kube-proxy根据LB算法选择一个提供服务的Pod并和其建立链接,以将请求转发到Pod上。 该模式下,kube-proxy充当了一个四层负责均衡器的角色。由于kube-proxy运行在userspace中,在进行转发处理时会增加内核和用户空间之间的数据拷贝,虽然比较稳定,但是效率比较低。
1.2 iptables 模式
iptables模式下,kube-proxy为service后端的每个Pod创建对应的iptables规则,直接将发向Cluster IP的请求重定向到一个Pod IP。 该模式下kube-proxy不承担四层负责均衡器的角色,只负责创建iptables规则。该模式的优点是较userspace模式效率更高,但不能提供灵活的LB策略,当后端Pod不可用时也无法进行重试。
1.3 ipvs 模式
ipvs模式和iptables类似,kube-proxy监控Pod的变化并创建相应的ipvs规则。ipvs相对iptables转发效率更高。除此以外,ipvs支持更多的LB算法。
1.4Ingress介绍
在前面课程中已经提到,Service对集群之外暴露服务的主要方式有两种:NotePort和LoadBalancer,但是这两种方式,都有一定的缺点:
NodePort方式的缺点是会占用很多集群机器的端口,那么当集群服务变多的时候,这个缺点就愈发明显
LB方式的缺点是每个service需要一个LB,浪费、麻烦,并且需要kubernetes之外设备的支持
基于这种现状,kubernetes提供了Ingress资源对象,Ingress只需要一个NodePort或者一个LB就可以满足暴露多个Service的需求。工作机制大致如下图表示:
实际上,Ingress相当于一个7层的负载均衡器,是kubernetes对反向代理的一个抽象,它的工作原理类似于Nginx,可以理解成在Ingress里建立诸多映射规则,Ingress Controller通过监听这些配置规则并转化成Nginx的反向代理配置 , 然后对外部提供服务。在这里有两个核心概念:
ingress:kubernetes中的一个对象,作用是定义请求如何转发到service的规则
ingress controller:具体实现反向代理及负载均衡的程序,对ingress定义的规则进行解析,根据配置的规则来实现请求转发,实现方式有很多,比如Nginx, Contour, Haproxy等等
Ingress(以Nginx为例)的工作原理如下:
用户编写Ingress规则,说明哪个域名对应kubernetes集群中的哪个Service
Ingress控制器动态感知Ingress服务规则的变化,然后生成一段对应的Nginx反向代理配置
Ingress控制器会将生成的Nginx配置写入到一个运行着的Nginx服务中,并动态更新
到此为止,其实真正在工作的就是一个Nginx了,内部配置了用户定义的请求转发规则
三:数据存储
容器的生命周期可能很短,会被频繁地创建和销毁。那么容器在销毁时,保存在容器中的数据也会被清除。这种结果对用户来说,在某些情况下是不乐意看到的。为了持久化保存容器的数据,kubernetes引入了Volume的概念。
Volume是Pod中能够被多个容器访问的共享目录,它被定义在Pod上,然后被一个Pod里的多个容器挂载到具体的文件目录下,kubernetes通过Volume实现同一个Pod中不同容器之间的数据共享以及数据的持久化存储。Volume的生命容器不与Pod中单个容器的生命周期相关,当容器终止或者重启时,Volume中的数据也不会丢失。
kubernetes的Volume支持多种类型,比较常见的有下面几个:
简单存储:EmptyDir、HostPath、NFS
高级存储:PV、PVC
配置存储:ConfigMap、Secret
1.1 EmptyDir
EmptyDir是最基础的Volume类型,一个EmptyDir就是Host上的一个空目录。
EmptyDir是在Pod被分配到Node时创建的,它的初始内容为空,并且无须指定宿主机上对应的目录文件,因为kubernetes会自动分配一个目录,当Pod销毁时, EmptyDir中的数据也会被永久删除。 EmptyDir用途如下:
临时空间,例如用于某些应用程序运行时所需的临时目录,且无须永久保留
一个容器需要从另一个容器中获取数据的目录(多容器共享目录)
接下来,通过一个容器之间文件共享的案例来使用一下EmptyDir。
在一个Pod中准备两个容器nginx和busybox,然后声明一个Volume分别挂在到两个容器的目录中,然后nginx容器负责向Volume中写日志,busybox中通过命令将日志内容读到控制台。
1.2 HostPath
EmptyDir中数据不会被持久化,它会随着Pod的结束而销毁,如果想简单的将数据持久化到主机中,可以选择HostPath。
HostPath就是将Node主机中一个实际目录挂在到Pod中,以供容器使用,这样的设计就可以保证Pod销毁了,但是数据依据可以存在于Node主机上。
1.3NFS
HostPath可以解决数据持久化的问题,但是一旦Node节点故障了,Pod如果转移到了别的节点,又会出现问题了,此时需要准备单独的网络存储系统,比较常用的用NFS、CIFS。
NFS是一个网络文件存储系统,可以搭建一台NFS服务器,然后将Pod中的存储直接连接到NFS系统上,这样的话,无论Pod在节点上怎么转移,只要Node跟NFS的对接没问题,数据就可以成功访问。
2.高级存储
前面已经学习了使用NFS提供存储,此时就要求用户会搭建NFS系统,并且会在yaml配置nfs。由于kubernetes支持的存储系统有很多,要求客户全都掌握,显然不现实。为了能够屏蔽底层存储实现的细节,方便用户使用, kubernetes引入PV和PVC两种资源对象。
2.1 PV 持久化卷
PV(Persistent Volume)是持久化卷的意思,是对底层的共享存储的一种抽象。一般情况下PV由kubernetes管理员进行创建和配置,它与底层具体的共享存储技术有关,并通过插件完成与共享存储的对接。
2.2 PVC持久化声明
PVC(Persistent Volume Claim)是持久卷声明的意思,是用户对于存储需求的一种声明。换句话说,PVC其实就是用户向kubernetes系统发出的一种资源需求申请。
四. 安全认证
访问控制概述
Kubernetes作为一个分布式集群的管理工具,保证集群的安全性是其一个重要的任务。所谓的安全性其实就是保证对Kubernetes的各种客户端进行认证和鉴权操作。
客户端
在Kubernetes集群中,客户端通常有两类:
User Account:一般是独立于kubernetes之外的其他服务管理的用户账号。
Service Account:kubernetes管理的账号,用于为Pod中的服务进程在访问Kubernetes时提供身份标识。
认证、授权与准入控制
ApiServer是访问及管理资源对象的唯一入口。任何一个请求访问ApiServer,都要经过下面三个流程:
Authentication(认证):身份鉴别,只有正确的账号才能够通过认证
Authorization(授权): 判断用户是否有权限对访问的资源执行特定的动作
Admission Control(准入控制):用于补充授权机制以实现更加精细的访问控制功能
五.. DashBoard
在kubernetes中完成的所有操作都是通过命令行工具kubectl完成的。其实,为了提供更丰富的用户体验,kubernetes还开发了一个基于web的用户界面(Dashboard)。用户可以使用Dashboard部署容器化的应用,还可以监控应用的状态,执行故障排查以及管理kubernetes中各种资源。