石岩企业网站建设,企业网站建设费是无形资产吗,深圳网站优化排名公司,好的网站怎么设计师Docker
docker的工作原理
docker是一个client-server结构的系统#xff0c;docker守护进程运行在宿主机上#xff0c;守护进程从客户端接受命令并管理运行在主机上的容器#xff0c;容器是一个运行时环境#xff0c;这就是我们说的集装箱
docker组成部分
1、docker cli…Docker
docker的工作原理
docker是一个client-server结构的系统docker守护进程运行在宿主机上守护进程从客户端接受命令并管理运行在主机上的容器容器是一个运行时环境这就是我们说的集装箱
docker组成部分
1、docker client 客户端为用户提供一系列可执行命用户用这些命令实现跟docker daemon交互
2、docker daemon 守护进程在宿主机后台运行等待接收来自客户端的请求消息
3、docker image 镜像
4、docker container 容器 系统级别的服务
docker三大核心概念
1、镜像轻量级独立的安装包
2、容器基于镜像创建的一个实例化的镜像程序
3、镜像仓库用于存放镜像的地方
docker centos镜像小的原因
所有镜像容器都共享宿主机的kernel内核。
镜像分层结构以及为什么要使用镜像分层结构
新的镜像其实是从base镜像一层一层叠加生成的每安装一个软件dockerfile中使用RUM命令就会在现有镜像的基础上增加一层这样一层一层的叠加最后构成完整镜像。所以我们docker pull
拉取镜像的时候发现是一层一层拉取得。
分层的好处共享资源比如有多个镜像都从相同的base镜像构建而来那么docker host只需要在磁盘上保存一份base镜像同时内存中也只需要加载一份base镜像就可以为所有容器服务了。
而且镜像的每一层都可以被共享。
dockerfile的整个构建镜像的过程
1、创建一个目录用于存放应用程序以及构建过程中使用的各个文件
2、在这个目录下创建一个Dockerfile文件一般命名即为Dockerfile。
3、编写dockerfile编写指令。如使用FROM指令制定基础镜像COPY指令复制文件RUN指定运行的命令ENV设置环境变量EXPOSE指定容器要暴露的端口WORKDIR设置当前工作目录
CMD容器启动时命令。
4、Dockerfile编写完成就可以构建镜像了使用docker build -t 镜像名tag .命令来构建最后的.表示当前目录docker会默认寻找当前目录下dockerfile文件来构建如果不使用默认可以
使用-f来指定dockerfile文件如docker build -t 镜像名tag -f /xxx/xxx/xxx/Dockerfile
5、使用docke build命令构建后docker就会将当前目录下所有的文件发送给docker daemon顺序执行dockerfile文件里的指令在这个过程中会生成临时容器在临时容器里面安装RUN指定的命令
安装成功后docker底层会使用类似docker commit命令来将容器保存为镜像然后删除临时容器。以此类推一层层的构建镜像运行临时容器软件直到最后镜像构建成功。
dockerfile构建镜像出现异常排查
首先dockerfile是一层一层的构建镜像的期间会产生一个或多个临时容器构建过程中其实就是在临时容器里面安装应用如果临时容器安装应用出现异常会导致镜像构建失败这时容器虽然被清理掉
但是期间构建的中间镜像还在可以根据异常时上一层已经构建好的临时镜像将临时镜像运行为容器然后在容器里运行安装命令来具体定位。
dockerfile命令
FROM 指定基础镜像必须为第一个指令因为需要指定使用哪个基础镜像来构建镜像
MAINTAINER 设置镜像作者相关信息如作者名字日期邮件联系方式等
COPY 复制文件到镜像
ADD 复制文件到镜像ADD与COPY的区别在于ADD会自动解压tar、zip、tgz、xz等归档文件而COPY不会同时ADD指令还可以接一个url下载文件地址一般建议使用COPY复制文件即可文件在宿主机上
是什么样子复制到镜像里面就是什么样子这样比较好
ENV 设置环境变量
EXPOSE 暴露容器进程的端口仅仅是提示别人容器使用的哪个端口没有过多作用
VOLUME 数据卷持久化挂载一个目录
WORKDIR 设置工作目录如果目录不在则会自动创建目录
RUN 在容器中运行命令RUN指令会创建新的镜像层RUN指令经常被用于安装软件包
CMD 指定容器启动时默认运行哪些命令如果有多个CMD则只有最后一个生效另外CMD指令可以被docker run之后的参数替换
ENTRYOINT 指定容器启动时运行哪些命令如果有多个ENTRYOINT则只有最后一个生效另外如果Dockerfile中同时存在CMD和ENTRYOINT那么CMD或docker run之后的参数将被当做参数传递给ENTRYOINT
K8S
K8S组件
master和node两种节点master负责集群管理node节点是容器真正运行的地方。
master节点包括kube-api-server、kube-controller-manager、kube-scheduler、etcd。
nodekubelet、kube-proxy、container-runtime。
kubelet功能和作用
1、节点管理。kubelet启动时会向api-server进行注册然后会定时的向api-server汇报本节点信息状态资源使用状态等这样master就能够知道node节点的资源剩余节点是否失联等等相关的信息了。
master知道了整个集群所有节点的资源情况这对于 pod 的调度和正常运行至关重要。
2、pod管理。kubelet负责维护node节点上pod的生命周期当kubelet监听到master的下发到自己节点的任务时比如要创建、更新、删除一个podkubelet 就会通过CRI容器运行时接口插件来调用
不同的容器运行时来创建、更新、删除容器常见的容器运行时有docker、containerd、rkt等等这些容器运行时我们最熟悉的就是docker了但在新版本的k8s已经弃用docker了k8s1.24版本中已经
使用containerd作为容器运行时了。
3、容器健康检查
pod中可以定义启动探针、存活探针、就绪探针等3种我们最常用的就是存活探针、就绪探针kubelet 会定期调用容器中的探针来检测容器是否存活是否就绪如果是存活探针则会根据探测结果对
检查失败的容器进行相应的重启策略
4、Metrics server资源监控。在node节点上部署Metrics Server用于监控node节点、pod的CPU、内存、文件系统、网络使用等资源使用情况而kubelet则通过Metrics Server获取所在节点及容器的上的数据。
pod特点
1、每个pod就像一个独立的逻辑机器k8s会为每个pod分配一个集群内部唯一的IP地址所以每个pod都拥有自己的IP地址、主机名、进程等
2、一个pod可以包含1个或多个容器1个容器一般被设计成只运行1个进程1个pod只可能运行在单个节点上即不可能1个pod跨节点运行pod的生命周期是短暂也就是说pod可能随时被消亡如节点异常
pod异常等情况
3、每一个pod都有一个特殊的被称为根容器的pause容器也称info容器pause容器对应的镜像属于k8s平台的一部分除了pause容器每个pod还包含一个或多个跑业务相关组件的应用容器
4、一个pod中的容器共享network命名空间
5、一个pod里的多个容器共享pod IP这就意味着1个pod里面的多个容器的进程所占用的端口不能相同否则在这个pod里面就会产生端口冲突既然每个pod都有自己的IP和端口空间那么对不同的两个pod来
说就不可能存在端口冲突
6、应该将应用程序组织到多个pod中而每个pod只包含紧密相关的组件或进程
7、pod是k8s中扩容、缩容的基本单位也就是说k8s中扩容缩容是针对pod而言而非容器。
pause容器作用
每个pod里运行着一个特殊的被称之为pause的容器也称根容器而其他容器则称为业务容器创建pause容器主要是为了为业务容器提供 Linux命名空间共享基础包括 pid、icp、net 等以及启动
init 进程并收割僵尸进程这些业务容器共享pause容器的网络命名空间和volume挂载卷当pod被创建时pod首先会创建pause容器从而把其他业务容器加入pause容器从而让所有业务容器都在同
一个命名空间中这样可以就可以实现网络共享。pod还可以共享存储在pod级别引入数据卷volume业务容器都可以挂载这个数据卷从而实现持久化存储。
pod的重启策略
可以通过restartPolicy字段配置pod重启容器的策略
Always: 当容器终止退出后总是重启容器默认策略就是Always。
OnFailure: 当容器异常退出退出状态码非0时才重启容器。
Never: 当容器终止退出不管退出状态码是什么从不重启容器。
pod的镜像拉取策略
pod镜像拉取策略可以通过imagePullPolicy字段配置镜像拉取策略主要有3中镜像拉取策略
IfNotPresent: 默认值镜像在node节点宿主机上不存在时才拉取。
Always: 总是重新拉取即每次创建pod都会重新从镜像仓库拉取一次镜像。
Never: 永远不会主动拉取镜像仅使用本地镜像需要你手动拉取镜像到node节点如果node节点不存在镜像则pod启动失败。
pod的存活探针
kubernetes可以通过存活探针检查容器是否还在运行可以为pod中的每个容器单独定义存活探针kubernetes将定期执行探针如果探测失败将杀死容器并根据restartPolicy策略来决定是否重启容器
kubernetes提供了3种探测容器的存活探针
httpGet通过容器的IP、端口、路径发送http 请求返回200-400范围内的状态码表示成功。
exec在容器内执行shell命令根据命令退出状态码是否为0进行判断0表示健康非0表示不健康。
TCPSocket与容器的IP、端口建立TCP Socket链接能建立则说明探测成功不能建立则说明探测失败。
存活探针的属性参数
initialDelaySeconds表示在容器启动后延时多久秒才开始探测
periodSeconds表示执行探测的频率即间隔多少秒探测一次默认间隔周期是10秒最小1秒
timeoutSeconds表示探测超时时间默认1秒最小1秒表示容器必须在超时时间范围内做出响应否则视为本次探测失败
successThreshold表示最少连续探测成功多少次才被认定为成功默认是1对于liveness必须是1最小值是1
failureThreshold表示连续探测失败多少次才被认定为失败默认是3连续3次失败k8s 将根据pod重启策略对容器做出决定
注意定义存活探针时一定要设置initialDelaySeconds属性该属性为初始延时如果不设置默认容器启动时探针就开始探测了这样可能会存在
应用程序还未启动就绪就会导致探针检测失败k8s就会根据pod重启策略杀掉容器然后再重新创建容器的莫名其妙的问题。
在生产环境中一定要定义一个存活探针。
pod的就绪探针
httpGet通过容器的IP、容器的端口以及路径来发送http get请求返回200-400范围内的状态码表示请求成功。
exec在容器内执行shell命令它根据shell命令退出状态码是否为0进行判断0表示健康非0表示不健康。
TCPSocket通过容器的IP、端口建立TCP Socket链接能正常建立链接则说明探针成功不能正常建立链接则探针失败。
就绪探针的属性参数
initialDelaySeconds延时秒数即容器启动多少秒后才开始探测不写默认容器启动就探测
periodSeconds 执行探测的频率秒默认为10秒最低值为1
timeoutSeconds 超时时间表示探测时在超时时间内必须得到响应负责视为本次探测失败默认为1秒最小值为1
failureThreshold 连续探测失败的次数视为本次探测失败默认为3次最小值为1次
successThreshold 连续探测成功的次数视为本次探测成功默认为1次最小值为1次
pod创建过程
情况一、如果面试官问的是使用kubectl run命令创建的pod可以这样说
#注意kubectl run 在旧版本中创建的是deployment但在新的版本中创建的是pod则其创建过程不涉及deployment
如果是单独的创建一个pod则其创建过程是这样的
1、首先用户通过kubectl或其他api客户端工具提交需要创建的pod信息给apiserver
2、apiserver验证客户端的用户权限信息验证通过开始处理创建请求生成pod对象信息并将信息存入etcd然后返回确认信息给客户端
3、apiserver开始反馈etcd中pod对象的变化其他组件使用watch机制跟踪apiserver上的变动
4、scheduler发现有新的pod对象要创建开始调用内部算法机制为pod分配最佳的主机并将结果信息更新至apiserver
5、node节点上的kubelet通过watch机制跟踪apiserver发现有pod调度到本节点尝试调用docker启动容器并将结果反馈apiserver
6、apiserver将收到的pod状态信息存入etcd中。
至此整个pod创建完毕。
情况二、如果面试官说的是使用deployment来创建pod则可以这样回答
1、首先用户使用kubectl create命令或者kubectl apply命令提交了要创建一个deployment资源请求
2、api-server收到创建资源的请求后会对客户端操作进行身份认证在客户端的~/.kube文件夹下已经设置好了相关的用户认证信息
这样api-server会知道我是哪个用户并对此用户进行鉴权当api-server确定客户端的请求合法后就会接受本次操作并把相关
的信息保存到etcd中然后返回确认信息给客户端。
3、apiserver开始反馈etcd中过程创建的对象的变化其他组件使用watch机制跟踪apiserver上的变动。
4、controller-manager组件会监听api-server的信息controller-manager是有多个类型的比如Deployment Controller, 它的作用就
是负责监听Deployment此时Deployment Controller发现有新的deployment要创建那么它就会去创建一个ReplicaSet一个ReplicaSet
的产生又被另一个叫做ReplicaSet Controller监听到了紧接着它就会去分析ReplicaSet的语义它了解到是要依照ReplicaSet的template
去创建Pod, 它一看这个Pod并不存在那么就新建此Pod当Pod刚被创建时它的nodeName属性值为空代表着此Pod未被调度。
5、调度器Scheduler组件开始介入工作Scheduler也是通过watch机制跟踪apiserver上的变动发现有未调度的Pod则根据内部算法、
节点资源情况pod定义的亲和性反亲和性等等调度器会综合的选出一批候选节点在候选节点中选择一个最优的节点然后将pod绑定该该
节点将信息反馈给api-server。
6、kubelet组件布署于Node之上它也是通过watch机制跟踪apiserver上的变动监听到有一个Pod应该要被调度到自身所在Node上来
kubelet首先判断本地是否在此Pod如果不存在则会进入创建Pod流程创建Pod有分为几种情况第一种是容器不需要挂载外部存储
则相当于直接docker run把容器启动但不会直接挂载docker网络而是通过CNI调用网络插件配置容器网络如果需要挂载外部存储
则还要调用CSI来挂载存储。kubelet创建完pod将信息反馈给api-serverapi-servier将pod信息写入etcd。
7、Pod建立成功后ReplicaSet Controller会对其持续进行关注如果Pod因意外或被我们手动退出ReplicaSet Controller会知道
并创建新的Pod以保持replicas数量期望值。
pod的终止过程
1、用户向apiserver发送删除pod对象的命令
2、apiserver中的pod对象信息会随着时间的推移而更新在宽限期内默认30spod被视为dead
3、将pod标记为terminating状态
4、kubectl在监控到pod对象为terminating状态了就会启动pod关闭过程
5、endpoint控制器监控到pod对象的关闭行为时将其从所有匹配到此endpoint的server资源endpoint列表中删除
6、如果当前pod对象定义了preStop钩子处理器则在其被标记为terminating后会意同步的方式启动执行
7、pod对象中的容器进程收到停止信息
8、宽限期结束后若pod中还存在运行的进程那么pod对象会收到立即终止的信息
9、kubelet请求apiserver将此pod资源的宽限期设置为0从而完成删除操作此时pod对用户已不可见。
pod的生命周期有哪几种
Pending挂起API server已经创建pod但是该pod还有一个或多个容器的镜像没有创建包括正在下载镜像的过程
Running运行中Pod内所有的容器已经创建且至少有一个容器处于运行状态、正在启动括正在重启状态
Succeed成功Pod内所有容器均已退出且不会再重启
Failed失败Pod内所有容器均已退出且至少有一个容器为退出失败状态
Unknown未知某于某种原因apiserver无法获取该pod的状态可能由于网络通行问题导致