kubernetes详解——从入门到入土(更新中~)
k8s简介
编排工具:系统层面ansible、saltstackdocker容器docker compose + docker swarm + docker machinedocker compose:实现单机容器编排docker swarm:实现多主机整合成为一个docker machine:初始化新主机mesos + marathonmesos IDC的操作系统,Apache研发的资源分配工具 marathon 面向容器编排的框架kubernetes补充:开发模式:瀑布式开发→迭代开发→敏捷开发→DevOps应用程序的架构:单体架构→分层架构→微服务 DevOps:需求→开发→测试→交付→部署应用模式的开发,把开发与运维整合起来,打破了两者直接的壁垒CI:持续集成:开发完合并代码到代码仓库然后自动构建部署测试,有问题打回给开发,无问题自动交付给运维方CD:持续交付:测试完之后自动打包好最终产品,并存放到可以被运维或客户拿到的地方CD:持续部署:交付完后自动拖出开发包并自动部署,运行时出现的bug自动反馈给开发常见部署方案:https://blog.csdn.net/hu1010037197/article/details/112670961 早期交付与部署环节因为各种不同系统不同版本的环境因素使其极其的困难,而容器的实现可以使其得以非常容易实现,可以真正的一次编写多次部署微服务:把每一个应用都拆解成一个微小的服务,只做一个功能,例如把一个单体应用程序拆解为数百个微服务,让其彼此间进行协作缺点:分发部署以及微服务互相之间的调用关系变得极其复杂,并且数以百计微服务难免其中的某些微服务会出现很问题,而单靠人工梳理和解决并不现实,容器与编排工具可以完美解决这些问题正是容器和编排工具的出现使得微服务和DevOps得以容易落地kubernetes特性:自动装箱自我修复水平扩展服务发现和负载均衡自动发布和回滚密钥和配置管理存储编排批量处理执行
K8S组成与架构
组成:整个kubernetes由master、node、附件组成四个核心附件:dnsHeapster/Metrics Server:用于收集和聚合集群和容器级别的资源使用情况和度量数据,以供监控和自动伸缩等用途。Kubernetes Dashboard:提供了一个基于 Web 的用户界面,用于可视化管理和监控 Kubernetes 集群。Ingress Controller:用于将外部网络流量路由到集群内部的服务。常见的 Ingress Controller 包括 Nginx Ingress Controller 和 Traefik。架构:kubernetes是一个有中心节点架构的集群系统master/node,一般会有一个或一组(三个master)节点作为主节点来做高可用,各node节点是用来贡献计算能力、存储能等相关资源(运行容器)的节点master三个核心组件(运行为三个守护进程):API Server:负责对外提供服务解析请求,并且需要存储整个集群中的个对象的状态信息,向客户端提供服务时使用https协议需要CA与证书scheduler(调度器):负责观测每个node之上的资源,并根据用户请求要创建容器所需要的资源量找到符合条件的node,然后根据调度算法中的最优算法选择最优node 控制器管理器:负责监控并确保每一个控制器的健康,并且在多个master之上做控制器管理器的冗余etcd共享存储:由于API Server需要存储整个集群中的对象的状态信息,存储量较大所以就需要etcd来实现;etcd是一个键值存储的数据库系统,而考虑到etcd的重要性,一般需要三个节点做高可用,默认是通过https进行通信,并且通过不同的两个接口分负责内外通信,其中内部通信需要一个点对点通信证书;向客户端提供服务是通过另一套证书实现node:理论上任何有计算能力可以装容器的机器都能作为node;核心组件:kubelet(集群代理):与master通信,接收master和调度过来的各种任务并试图让容器引擎(最流行的容器引擎为doker)来执行 docker:容器引擎,运行pod中的容器kube-proxy:每当pod增删和service需要改变规则需要依赖kube-proxy,每当pod增删时会有一个通知,通知到所有相关联的组件,service收到通知需要kube-proxy修改所有集群内所有节点的iptablespod控制器:又称之为工作负载(workload),负责监控所管理的每一个容器是否是健康的应用节点数是否符合,确保pod资源符合预期的状态,如果出现异常则向API server发送请求,由kubernetes重新创建启动容器、还可以滚动更新或回滚 控制器有多种类型:ReplicaSet: 代用户创建指定数量的pod副本数量,确保pod副本数量符合预期状态,并且支持滚动式自动扩容和缩容功能。ReplicaSet主要三个组件组成:(1)用户期望的pod副本数量(2)标签选择器,判断哪个pod归自己管理(3)当现存的pod数量不足,会根据pod资源模板进行新建帮助用户管理无状态的pod资源,精确反应用户定义的目标数量,但是RelicaSet不是直接使用的控制器,而是使用DeploymentDeployment:工作在ReplicaSet之上,用于管理无状态应用,目前来说最好的控制器。支持滚动更新和回滚功能;还提供声明式配置,可以随时重新进行声明,随时改变我们在API Server上定义的目标期望状态,只要那些资源支持动态运行时修改。 #更新和回滚功能:Deployment一般会控制两或多个个ReplicaSet,平时只激活运行一个,当更新时逐一停止激活状态的ReplicaSet上的容器并在另一个ReplicaSet上创建直到完成,回滚是相反的动作;可以控制更新方式和节奏:例如定义一次更新几个节点或者先临时加几个pod正常后在删除旧pod使能正常提供服务的pod个数保持一致等等HPA:二级控制器,负责监控资源,自动伸缩DaemonSet:用于确保集群中的每一个节点或符合标签选择器的节点上只运行特定的pod副本,通常用于实现系统级后台任务。比如ELK服务日志收集分析工具。只要新增节点就会自动添加此pod副本Deployment和DaemonSet所部署的服务特性:服务是无状态的服务必须是守护进程StatefulSet:管理有状态应用Job:只要完成就立即退出,不需要重启或重建;如果任务没完成异常退出才会重建Pod。适合一次性的任务Cronjob:周期性任务控制,不需要持续后台运行Statefulset:管理有状态应用,每一个Pod副本都是被单独管理pod:kubernetes中最小单元,是在容器上又封装一层模拟虚拟机,一个pod里可以有多个容器(一般为一个),其中这多个容器可以共享一个网络名称空间、共享存储卷 两类:自主式pod:如果node故障,其中的pod也就消失了pod控制器管理的pod label(标签):可以用打标签的方式给资源分组,所有对象都可打标签(pod是最重要的一类对象)格式:key=valueselector(标签选择器):根据标签过滤符合条件的资源对象的机制service[k8s的附加组件]:是一个四层调度器。实际是一个宿主机上的iptables dnat规则和宿主机的一个虚拟的地址负责反向代理后端容器服务,所以如果你创建一个service,service是会反应到整个集群的每一个节点之上的。他是可以被解析的地址也是固定的,但是并不附加在网卡之上;由于后端容器频繁的变更,不断伸缩、创建删除,他们的地址与容器主机名称是不固定的,所以后端容器每次变动,service通过标签选择器获取他们的标签区别并记录他们并同时记录对应的地址与容器名字,因此当服务请求进来后先到service,通过service找到对应的服务并且转发到其中的容器中,不过安装完K8S之后需要在集群中的dns中配置他的域名解析,如果手动修改service地址或名字,dns中的解析记录也会自动修改,如果后端一个服务有多个节点,service支持ipvs,会把规则写入ipvs中进行负载均衡service规则默认用的是ipvs,如果ipvsservicedns附件:service想要被发现需要dns服务,dns也是运行在pod之中监控:监控相关资源利用、访问量、是否故障示例:在K8S上创建一个NMT客户→LBaas→node接口→nginx_service→nginx容器→tomcat_service→tomcat→mysql_service→mysql如果使用的是阿里云,则在云上调用底层LBaas,因为node上可能没有网卡,所以用来负责把请求来的流量调度到node上的对外的接口上,然后通过控制器创建两个pod装载nginx,nginx之上创建一个servece负责接收node接口的流量,并把流量转发给nginx;继续通过控制器创建三个pod装载tomcat,之上在创建一个service,同理再创建两个mysql之上创建一个service
K8S网络与通信
K8S总共有三种网络:节点网络集群网络(service网络)pod网络通信:同一个pod之间通信:是通过lo通信不同pod之间通信:是通过“叠加网络”进行通信,把需要传递到pod的IP和端口报文外部再封装一个IP用于不同节点之间的传递,当节点接收到叠加网络报文时进行拆封,然后再根据内部的IP和端口找到对应的服务,当然pod是动态的随时会进行增删就需要通过service来找到具体目标podpod与service之间通信:因为service地址实际上只是宿主机上iptables规则地址,创建service后会反应到整个集群的所有节点和宿主机iptables之上,当pod需要与service通信时会把网关指向docker0乔的地址,另外宿主机也可以把docker0乔当作自己的一个网卡,所以宿主机之上pod可以直接与service通信,通过iptables规则表检查指向发送请求CNI插件体系:容器网络接口,负责接入外部插件网络解决方案,可以运行在pod之上作为集群的一个附加使用,需要共享宿主机的网络名称空间。目的:负责给pod、service提供ip地址负责网络策略功能:实现pod隔离,让不同的pod之间根据要求通过添加规则实现互通或隔离,防止托管在pod中的恶意服务截取或攻击其他pod中服务 常见插件:flannel(叠加网络):只支持网络配置calico(三层隧道网络):支持网络配置和网络策略canel:把前两者结合,用flannel配置网络,用calico配置网络策略...k8s名称空间:把一个集群根据每一类pod切割成多个名称空间,而切割的这个名称空间边界不是网络边界而是管理边界,例如创建一个项目,项目下可以有多个pod,可以批量管理这个项目中的pod,项目完成可以批量删除整个项目CA:K8S一般是需要5套CAetcd与etcd之间etcd与API Server之间API Server与用户之间API Server与kubetel之间API Server与kube-proxy之间
部署
常用部署方式:传统手动部署:所有组件运行为系统的守护进行,很繁琐包括做5个CAkubespray:kubespray是一个基于Ansible的部署方案,根据已经写好的ansible的剧本进行执行,也是把所有组件运行为系统的守护进行kubeadm(官方提供安装工具):容器化部署,更像是一套完整的脚本封装,比较快速简单实例:kubeadm安装至少两核cpu部署网络环境:节点网络:172.20.0.0service网络:10.96.0.0/12pod网络:10.244.0.0/16 (flannel插件默认)master+etcd:172.20.0.70node1:172.20.0.66node2:172.20.0.67安装步骤:(本人用的是:centos7.9docker-ce-20.10.8、docker-ce-cli-20.10.8kubelet-1.20.9、kubeadm-1.20.9、kubectl-1.20.9)1.所有主机安装docker+kubelet+kubeadm2.初始化master:kubeadm init(检查前置条件、并会把master三个组件和etcd运行为pod、CA等)3.初始化node:kubeadm join (检查前置条件、在pod中运行一个kube-proxy、dns、认证等)文档:官方文档:https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/安装参考文档:https://blog.csdn.net/qq_42475194/article/details/126356651注意:docker跟k8s需要特定版本,版本差距较大会出现不兼容问题。以下是一些常见的 k8s 和 Docker 版本对应关系:k8s 1.22.x 支持 Docker 20.10.xk8s 1.21.x 支持 Docker 20.10.xk8s 1.20.x 支持 Docker 19.03.xk8s 1.19.x 支持 Docker 19.03.xk8s 1.18.x 支持 Docker 19.03.x程序相关目录rpm -ql kubelet/etc/kubernetes/manifests ----清单目录/etc/sysconfig/kubelet ----配置文件/etc/systemd/system/kubelet.service/usr/bin/kubelet ----主程序kubeadm初始化准备(master)kubeadm initFlags:--apiserver-advertise-address string 设置apiserver监听地址(默认所有)--apiserver-bind-port int32 设置apiserver监听端口(default 6443)--cert-dir string 设置证书路径(default "/etc/kubernetes/pki") --config string 设置配置文件--ignore-preflight-errors strings 预检查时忽略掉出现的错误( Example: 'IsPrivilegedUser,Swap' )--kubernetes-version string 设置使用的kubernetes版本(default "stable-1")--pod-network-cidr string pod网络(flannel插件默认网络为 10.244.0.0/16 )--service-cidr string service网络(default "10.96.0.0/12")复制kubectl配置文件:需要有sudo权限的普通用户mkdir -p $HOME/.kubesudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/configsudo chown $(id -u):$(id -g) $HOME/.kube/config注释:admin.conf文件:kubeadm帮我们自动初始化好的一个被kubectl拿来做配置文件指定连接至K8s的API server并完成认证的配置文件
kubect命令
kubectl:是API Server的客户端程序,这个客户端程序是通过连接master节点上的API server这一个对应的应用程序,这也是整个K8S集群上唯一一个管理入口,kubectl就是这个管理入口的客户端管理工具
面向对象:kubectl仿照于面向对象的开发语言,所有k8s中的资源都可以看做对象类,类中有方法和属性。每当根据给定的参数创建pod时就相当于给类中的方法赋值,相当于实例化对象。
相关命令:kubectl version #获取版本信息cluster-info #获取集群信息api-versions #查看当前可支持api的版本-h #获取帮助describe #获取对象的详细描述信息包括所有可以作为对象的目标如:pod、service、node、deployment等object NodeName 示例:kubectl describe pod nginx-deploy get 获取信息cs #组件状态信息nodes #节点信息deployment #查看此控制器已创建的podns #获取名称空间 pods #获取当前正在运行的pod信息deployment #查看控制器信息(需要追加到对象之后)-w #持续监控-n #指定名称空间-o wide #显示扩展信息yaml #以yaml格式输出信息 --show-labels #(需要追加到对象之后)显示所有标签 -L #输出所有,但是只显示指定的标签的标签值,未指定的不显示示例:kubectl get pods -L app,run-l #标签过滤,只输出指定标签的资源格式(可指定多个):等值关系(只过滤KEY/等于/不等于):KEY_1,...KEY_N/KEY_1=VAL_1,.../KEY_1!=VAL_1,... 集合关系:KEY in (VAL_1,...VAL_N) 键的值只要是这集合中的一个就匹配KEY notin (VAL_1,...VAL_N)键的值不是是这集合中的一个就匹配KEY 有这个键的标签就匹配!KEY 无这个键的标签就匹配示例:kubectl get pods -l app,release --show-labels kubectl get pods -l release=conary,app=myapp --show-labels kubectl get pods -l "release in (canary,beta)" #过滤 release这个键的值包含canary,beta的pod kubectl get pods -l "release notin (canary,beta)" #过滤 release这个键的值不包含canary,beta的pod services/svc-n #指定名称空间# 指定名称空间为 kube-system 时可查看到集群dns服务的代理service IP,从而可以同过此IP解析集群中的其他service标签 run NAME #(控制器名称) 创建并启动--image='': #指定镜像--port='': #暴漏端口 --dry-run=true #模拟执行,非真正执行-- <cmd> <arg1> ... <argN> #指定运行命令和参数--restart=Never #pod异常后不自动创建-i-tExamples:kubectl run nginx-deploy --image=nginx:1.14-alpine --port=80 --dry-run=true测试:在集群中所有node节点都可以使用curl访问此nginx,但只能集群内部访问,想要外部访问需要特殊类型的service注:每个node会自动生成一个桥和接口,例如: cni0:inet 10.244.1.1 netmask 255.255.255.0 broadcast 10.244.1.255。此node上所有的pod都会在10.244.1.0 网段kubectl run client --image=busybox -it --restart=Never查看命令kubectl get pods -o widecreate #用于创建 Kubernetes 对象。如果对应的资源已经存在,则会返回错误,此时需要先删除原有的资源对象,然后再执行创建操作。如果资源对象不存在,则会自动创建对应的资源对象。适用于初始化资源对象的场景#Usage:kubectl create -f FILENAME [options]#FILENAME:资源配置yaml文件#[options]:namespace NAME deployment NAME --image=[]--dry-run='none/server/client'示例:kubectl create -f pod-demol.yamlkubectl create deployment nginx-deploy --image=nginx:1.14-alpine apply (-f FILENAME | -k DIRECTORY) [options] #用于声明式创建或更新一个 Kubernetes 对象并且可以声明多次。如果该资源对象已经存在,则会首先尝试更新对应的字段值和配置,如果不存在则会自动创建资源对象。适合更新和修改已有的资源对象,因为它会对比新的 YAML 配置文件和已有的资源对象配置,只更新需要更新的部分,而不会覆盖已有的全部配置。示例:kubectl create -f pod-demol.yamlpatch Usage:kubectl patch (-f FILENAME | TYPE NAME) -p PATCH [options]options:-p #打补丁示例:kubectl patch pod valid-pod -p '{"spec":{"containers":[{"name":"kubernetes-serve-hostname","image":"new image"}]}}'kubectl patch deployment myapp-deploy -p '{"spec":{"replicas":5}}'delete ([-f FILENAME] | [-k DIRECTORY] | TYPE [(NAME | -l label | --all)]) [options]示例:kubectl delete -f pod-demol.yamlexpose #暴漏服务端口,相当于创建一个service然后把pod服务中的端口映射固定在service上,创建完成后默认为ClusterIP类型所以集群外部依然不能访问,集群内部pod或node可以通过service进行访问服务。首先需要集群中dns找到service,然后service会生成一个iptables或ipvs规则把访问此service指定端口的请求都调度至它用标签选择器关联到的各pod后端(可以用 kubectl describe svc NAME 查看关联了哪些标签,可以用kubectl get pods --show-labels 显示pod有哪些标签 ) #解析的步骤:kubectl get svc/pod -n kube-system 查到dns的service代理IP为10.96.0.10;在pod中启动两个服务nginx-deploy并暴漏端口80映射为80,设置其service名字为nginx。因为集群中域名的默认后缀为default.svc.cluster.local,所以nginx域名为nginx.default.svc.cluster.local;解析测试:host -t A nginx.default.svc.cluster.local 10.96.0.10 解析地址为nginx地址expose Usage:kubectl expose (-f FILENAME | TYPE NAME) [--port=port] [--protocol=TCP|UDP|SCTP] [--target-port=number-or-name] [--name=name] [--external-ip=external-ip-of-service] [--type=type] [options]#注释:(-f FILENAME | TYPE NAME):指定需要与创建的service建立连接的pod的控制器的名字[--port=port]:service的端口[--target-port=number-or-name]: pod中的端口[--name=name]:service名称 [--type=type] : Type for this service: ClusterIP, NodePort, LoadBalancer, or ExternalName. Default is 'ClusterIPservice'.#service的4中主要类型合作用:1.ClusterIP 是默认的 Service 类型。它将创建一个虚拟的 IP 地址,用于连接客户端和 Pod。这个 IP 地址只能在集群内部使用,无法从集群外访问。这种类型通常用于后端服务,如数据库或缓存服务。访问路径:集群内部client → ClusterIP:ServicePort → PodIP:containerPort2.NodePort 允许从集群外部访问 Service,通过将提供的端口号映射到 Pod 的 IP 地址上,同时也会将该端口暴露到集群节点的 IP 地址上。这种类型通常用于开发和测试,不建议在生产环境中使用。访问路径:集群外部client → [负载均衡器]→NodeIP:NodePort→ClusterIP:ServicePort → PodIP:containerPort 3.LoadBalancer 可以在云环境中借助底层lbaas自动创建外部负载均衡器,并将客户端请求路由到 Pod。该类型的 Service 通常用于公共云或私有云环境中,可以将流量平衡到多个集群节点上,从而提高服务的可靠性和可用性。访问路径:集群外部client →负载均衡器(Lbaas)→ NodeIP:NodePort→ClusterIP:ServicePort → PodIP:containerPort4.ExternalName Service 允许 Service 对外暴露一个外部名称,这个名称可以被解析为外部服务的 DNS 名称。该类型的 Service 不会在集群中创建任何负载均衡器或 IP,而是将请求直接转发到指定的外部服务。一般是集群内pod作为客户端需要请求集群外服务时使用。 5.无头service,定义ClusterIP时设置为None。此时解析service域名时直接解析到后端Pod服务 Examples:kubectl expose deployment nginx-deploy --name=nginx --port=80 --target-port=80 --protocol=TCP容器中访问测试:wget -O - -q nginxwget -O - -q myapp/hostname.html #可查看调度到哪个pod(需要使用此镜像:--image=ikubernetes/myapp:v1)edit 修改对象信息,包括所有可以作为对象的目标如:pod、service、node、deployment等object NAME 注:可以直接改service类型,例如把ClusterIP改为 NodePort service的内部集群端口就会自动随机映射为外部端口,可以get查看端口,因此就可以通过外网使用集群中任何节点网络的IP:PORT 访问到此pod中的服务示例:kubectl edit svc nginxscale 伸缩控制器规模Usage:kubectl scale [--resource-version=version] [--current-replicas=count] --replicas=COUNT (-f FILENAME | TYPE NAME)注释:[--resource-version=version] [--current-replicas=count]:过滤条件Examples:kubectl scale --replicas=5 deployment myappset image 更新升级镜像Usage:kubectl set image (-f FILENAME | TYPE NAME) CONTAINER_NAME_1=CONTAINER_IMAGE_1 ... CONTAINER_NAME_N=CONTAINER_IMAGE_N#CONTAINER_NAME_1=CONTAINER_IMAGE_1:指明pod中的哪个容器和镜像,可以指定多个,可以用kubectl describe 查看pod内容器的名称,在Containers:下Examples:kubectl set image deployment myapp myapp=ikubernetes/myapp:v2rollout 管理一个或多个资源的上线Usage:kubectl rollout SUBCOMMAND [options]Commands:status Show the status of the rolloutExamples:kubectl rollout status deployment myapp undo 回滚,默认回滚到上一个版本Usage:kubectl rollout undo (TYPE NAME | TYPE/NAME) [flags] [options]history #查看滚动历史 示例:kubectl rollout history deployment myapp-deploypause #暂停resume #启动,与先暂停对应logs PodName -c containername (如果pod内有多个容器需要指定容器名称)示例:kubectl logs myapp-5d587c4d45-5t55gkubectl logs pod-demol -c myapplabes 配置标签#标签相当于附加到对象上的键值对#一个资源对象可以有多个标签,一个标签也可以被添加至多个资源对象之上;#标签可以在资源创建时指定,也可以在创建后通过命令管理#键值对有大小和字符规范限制Usage:kubectl label [--overwrite] (-f FILENAME | TYPE NAME) KEY_1=VAL_1 ... KEY_N=VAL_N [--resource-version=version]Examples:kubectl label pods foo unhealthy=true 添加标签kubectl label pods foo unhealthy=yes --overwrite 修改覆盖标签许多类型的资源都要基于标签选择器关联其他资源例如控制器、service。此时通常使用另外两个字段进行嵌套定义其使用的标签选择器: matchLabels 直接定义键值(service只支持这一种)matchExpressions 基于给定的表达式来定义使用标签选择器,格式{key:"KEY",operator:"OPERATOR",values:[VAL1,VAL2....]} #operator为判断条件,操作符如:In, NotIn,Exists, NotExists示例:kubectl explain pod.spec.nodeSelector:nodeSelector <map[string]string> #节点标签选择器,可以选择让pod运行在哪一类节点上 exec #容器外跳过边界执行容器内命令Usage:kubectl exec (POD | TYPE/NAME) [-c CONTAINER] [flags] -- COMMAND [args...] [options]#[-c CONTAINER]:pod中有多个容器需指定容器名示例: kubectl exec myapp-5d587c4d45-h4zxn datekubectl exec myapp-5d587c4d45-h4zxn -it -- /bin/shkubectl exec pod-demol -c myapp -it -- /bin/sh explain <type>.<fieldName>[.<fieldName>] #查看K8S内建的格式说明示例:kubectl explain podskubectl explain rskubectl explain pods.spec.containers
资源配置清单(一个yaml文件可以定义多个资源,需用—分隔开)
常用资源:对象分类:工作负载型资源对象:运行应用程序对外提供服务pod、各种pod控制器、服务发现及负载均衡service、ingress配置与存储volume、CSI、ConfigeMap(配置中心)、Secret(保存敏感数据)、 DownwordAPI(外部环境信息输出给容器)集群级资源namespace、node、role、clusterrole、rolebinding、clusterrolebingding元数据HPA、podtemplate、limitrange(资源限制)资源配置清单可分为以下五部分(配置清单中的一级字段): (apiserver仅接收json格式的资源定义:执行命令时会自动把你给的内容转换成json格式,而后再提交;查看yaml格式资源配置清单 实例: kubectl get pod myapp-848 -o yaml ) 1. apiVersion: 此对象属于K8S的哪一个API版本和群组,一般格式为 group/version 如果省略group则默认为核心组。例:控制器属于app组;pod属于核心组查看命令 :kubectl api-versions2. kind: 资源类别,用于初始化实例化成一个资源对象使用的3. metadata: 元数据 提供的信息有:name、namespace、labels、annotations(资源注解)selfLink:每个资源引用方式固定格式api/GROUP/VERSION/namespaces/NAMESPACE/TYPE/NAME示例:selfLink: /api/v1/namespaces/default/pods/myapp-848b5b879b-8fhgq4. spec: 用户期望的目标状态/规格,定义要创建的资源对象需要有怎样的特性或满足怎样的规范(例如它的容器应该有几个;容器应该用哪个镜像创建;容忍哪些污点)5. status: (只读)显示当前资源的当前的状态,如果当前状态与目标状态不一致,K8S就是为了目标状态定义完后当前状态无限向目标状态靠近或转移,以此来满足用户需要,注意本字段由K8S集群维护,用户不能定义此字段 资源配置清单中自主式Pod的配置([]表示列表):(可以用kubectl explain pod 查看描述文档)kubectl explain pods:metadata <Object>annotations <map[string]string>#资源注解,与label不同的地方在于,它不能用于挑选资源对象,仅用于为对象提供“元数据”,并且字符没有大小等规范限制 spec <Object>restartPolicy <string> #重启策略Always #Pod中的容器挂了就重启无论是否是正常终止,默认为Always。#重启逻辑:频繁重启会给服务器带来压力所以第一次会立即重启,每多一次重启就会增加等待时间,直到每5分钟重启一次OnFailure #只有状态错误时就重启Never #从不重启nodeSelector <map[string]string> #节点标签选择器,可以选择让pod运行在哪一类节点上 nodeName <string> #指定pod运行的节点hostNetwork <boolean> #设置pod直接使用主机的网络名称空间,此时可以使用主机ip:port直接访问pod,不需要暴露端口。常用在DaemonSet控制器中hostIPC <boolean> #共享主机IPhostPID <boolean> #共享主机PIDcontainers <[]Object>- name <string> -required-image <string>imagePullPolicy <string> #镜像获取途径的策略# <string>:Always:远程仓库拉取Never:要使用本地镜像,如果没有就等待,需要手动拉取镜像到本地IfNotPresent:如果本地有镜像优先使用默认用法:如果镜像标签是latest那么默认值就是Always除特定标签latest以外,其他标签默认镜像获取途径的策略为IfNotPresentCannot be updated:如果每个字段写上这段信息表示对象一旦被创建以后改变这个字段值是不被允许的ports <[]Object> #注释信息:标注要暴露的端口和端口信息,标注以后可以尝试引用这个名称- name <string>containerPort <integer> -required-protocol <string> command <[]string>#自定义容器要运行的程序相当于docker配置中的Entrypoint,但是所给定的代码不是运行在shell中,需要手动指定如果没有提供command,而docker镜像在制作时有ENTRYPOINT就会运行镜像中的ENTRYPOINT而如果指定了command,无论指没指定参数,docker镜像中的ENTRYPOINT和CMD都会被忽略示例:command:- "/bin/sh"- "-c"- "sleep 3600"h" args <[]string>#向Entrypoint传递的参数相当于docker配置中的CMD;如果指定args,则用args作为参数;如果没指定args且没指定command则用镜像中的CMD作为参数#$(VAR_NAME):在args中引用变量#$$$(VAR_NAME):进行逃逸,不使用引用的变量替换env <[]Object> #设置环境变量- name <string> -required-value <string> #如果引用别的变量格式:$(VAR_NAME)lifecycle <Object> #定义终止前和启动后钩子,用来定义启动后与终止前需要立即执行的操作 postStart <Object> #启动后钩子exec <Object>httpGet <Object>tcpSocket <Object>preStop <Object> #终止前钩子exec <Object>httpGet <Object>tcpSocket <Object> readinessProbe <Object> #就绪状态检测,与livenessProbe用法相同livenessProbe <Object> #存活状态检测exec <Object> #探测行为,执行自定义命令command <[]string> #如果返回值是成功说明是存活的,如果返回状态码表示存活探测失败httpGet <Object> #探测行为,向指定的TCP套接字发请求,通过http返回状态码判断host <string> #defaults to the pod IP.path <string>port <string> -required- #可以引用端口名称tcpSocket <Object> #探测行为,向对指定的http服务发请求 host <string> #defaults to the pod IP.port <string> -required-failureThreshold <integer> #探测几次都失败才认为失败,默认3次periodSeconds <integer> #每一次探测间隔时间默认10秒timeoutSeconds <integer> #超时时间,默认1秒initialDelaySeconds <integer> #第一次探测的时间,默认容器启动完就开始探测示例:(自主式Pod,不受控制器管理)vim pod-demal.yamlapiVersion: v1kind: Podmetadata:name: pod-demolnamespace: defaultlabels:app: myapp1tier: frontendspec:containers: - name: myappimage: ikubernetes/myapp:v1ports:-name: httpcontainerPort: 80readinessProbe:httpGet:port: httppath: /index.htmlinitialDelaySeconds: 1periodSeconds: 3 livenessProbe:httpGet:port: httppath: /index.htmlinitialDelaySeconds: 1periodSeconds: 3 - name: busyboximage: busybox:latestcommand:- "/bin/sh"- "-c"- "sleep 3600"- name: busybox-liveness-exec-containerimage: busybox:latestimagePullPolicy: IfNotPresentcommand: ["/bin/sh","-c","touch /tmp/healthy; sleep 60; rm -rf /tmp/healthy; sleep 3600"] livenessProbe:exec:command: ["test","-e","/tmp/healthy"]initialDelaySeconds: 1periodSeconds: 3 根据创建的配置清单文件创建容器:kubectl create -f pod-demol.yaml删除:kubectl deleted -f pod-demol.yamlkubectl deleted pods pod-demolPod的生命周期:从创建到结束的所有状态:Pending, Running, Failed, Succeeded, Unknown#Pending:挂起,请求创建pod时条件不能满足调度没完成。例如已经创建但没找到符合指定tag的节点#Unknown:未知状态,例如节点上的kubelet故障,API Server无法与之通信所以会出现未知状态Pod生命周期中的重要行为:主容器启动前:始化容器,主进程启动前先运行辅助容器init进行初始化容器,甚至和可以运行多个并串行执行,运行完之后退出启动主进程主容器启动时:执行启动后钩子主进程运行时:liveness:存活状态检测,判定主容器是否处于运行状态(runing),此时不一定能对外提供服务readiness:就绪状态检测,判定容器中的主进程是否已经准备就绪并可以对外提供服务(无论哪种探测都可以支持三种探测行为:执行自定义命令;向指定的TCP套接字发请求;向对指定的http服务发请求。并根据响应码判断其成功还是失败。即三种探针:ExecAction、TCPSocketAction、HTTPGetAction)主容器结束后:执行结束后钩子 创建Pod过程:用户创建Pod后把请求提交给API ServerAPI Server会把创建请求的目标状态保存到etcd中API Server会请求调度器进行调度,并把调度的结果、调度的那些节点资源保存到etcd中节点上的kubelet通过API Server当中的状态变化得知任务通知,并拿到用户此前提交的创建清单kubelet根据清单在当前节点上创建并启动podkubelet把当前pod状态发回给API Server删除Pod过程:防止删除Pod时数据丢失会向Pod内的每一个容器发送终止信号,让Pod中的容器正常进行终止,这个终止会给一个默认的宽限期默认30秒。如果过了宽限期还没终止就会重新发送kill信号资源配置清单中Pod控制器配置ReplicaSet控制器kubectl explain rs/ReplicaSet:kind <string>metadata <Object>spec <Object>replicas <integer> #副本数selector <Object> -required- #标签选择器template <Object> #模板,此模板嵌套的就是Pod的配置清单metadata <Object> #Pod的metadataspec <Object> #Pod的specmatchExpressions <[]Object>matchLabels <map[string]string>示例:(可以通过kubectl edit rs myapp 直接修改运行中控制器的yaml配置清单内容实现扩缩容和更新镜像等,但是更新镜像需要手动删除容器自动创建后才会是最新镜像)apiVersion: apps/v1kind: ReplicaSetmetadata:name: myappnamespace: defaultspec:replicas: 2selector:matchLabels:app: myapprelease: canarytemplate:metadata:name: myapp-podlabels:app: myapprelease: canaryenvironment: qaspec:containers:- name: myapp-containerimage: ikubernetes/myapp:v1ports:- name: httpcontainerPort: 80 deployment控制器(大部分配置与ReplicaSet相似) kubectl explain deploy/deployment: spec <Object>revisionHistoryLimit <integer> #保存多少个历史版本,默认是10个paused <boolean> #开始更新部署时先暂停strategy <Object> #更新策略type <string>#<string>:支持三类更新 Recreate:重建试更新,删一个创建一个RollingUpdate:滚动更新,为默认更新方法,更新策略需要配置在上级配置的RollingUpdate中 rollingUpdate <Object> #定义滚动更新策略,需要type配置为RollingUpdate才会生效 maxSurge <string> #设置可以超出期望的副本数几个,<string>可以是数字也可以是百分比,默认25%maxUnavailable <string> #设置最多有几个不可用,<string>可以是数字也可以是百分比,默认25%示例: apiVersion: apps/v1kind: Deploymentmetadata:name: myapp-deploynamespace: defaultspec:replicas: 3selector:matchLabels:app: myapprelease: canarytemplate:metadata:labels:app: myapprelease: canaryspec:containers:- name: myappimage: ikubernetes/myapp:v2ports:- name: httpcontainerPort: 80DaemonSet控制器(配置文件除了没有replicas,其他大部分与deployment控制器类似,也支持滚动更新策略)kubectl explain ds/DaemonSet:spec <Object>updateStrategy <Object>rollingUpdate <Object>maxUnavailable <string> #最多几个不可用,因为每个节点只能部署一个,没有maxSurge选项type <string> #Can be "RollingUpdate" or "OnDelete"(删除时更新). Default is RollingUpdate. 示例:apiVersion: apps/v1kind: DaemonSetmetadata:name: filebeat-dsnamespace: defaultspec:selector:matchLabels:app: filebeatrelease: stabletemplate:metadata:labels:app: filebeatrelease: stablespec:containers:- name: filebeatimage: ikubernetes/filebeat:5.6.5-alpineenv:- name: REDIS_HOSTvalue: redis.default.svc.cluster.local- name: REDIS_LOG_LEVELvalue: info 资源配置清单中service配置:kubectl explain svc/service:clusterIP <string> #<string> :service的IP,不需要指定因为在集群中会自动分配,如果要指定要确定不要导致ip冲突;也可以设置为None,没有集群IP又称为无头sevice。通过service域名直接解析到后端Pod上spec <Object>ports <[]Object>name <string>nodePort <integer> #指定节点上的端口,一般不用指定因为只有service类型时nodePort时节点端口才有用port <integer> -required- #指定对外提供服务的端口targetPort <string> #容器的端口protocol <string> #协议,默认为TCPselector <map[string]string>type <string> externalName <string> #type为ExternalName Service时才会有效,解析结果应该是A记录,用的比较少sessionAffinity <string> #会话粘性,默认情况是不做粘性的,如果设置为ClientIP则来自同一个客户端IP的请求始终调度到同一个后端Pod上去#<string>: "ClientIP" 或 "None"ingress Controlservice是一个四层调度器因此有个缺陷,它只是工作在TCP/IP协议栈或者OS模型的第四层。因此如果用户访问的是https请求,服务用service代理时CA证书、私钥无法配置,更无法调度https的这种七层协议,这种情我们只能在每个后端服务器配置https。因为https的特点是即贵且慢所以我们需要尽量在调度器上卸载所以需要七层调度器,使在外网时使用https,内网使用http。解决方案一: 设置一个独特的pod运行在七层用户空间正常的应用程序例如nginx,当用户试图访问某一服务时,我们不让它到达前端service而先到七层代理pod。pod与pod直接可以通过podIP同一网段直接通信完成反向代理访问路径:集群外部client进行https访问 →负载均衡器(Lbaas)→ NodeIP:NodePort→ClusterIP:ServicePort → PodIP:containerPort(七层代理服务卸载https并把http请求直接反向代理给后端)→PodIP:containerPort(真正提供服务的容器)弊端:多级调度导致性能低下方案二:ingress Control直接让七层代理pod共享节点的网络名称空间并监听宿主机地址端口。而且使用DaemonSet控制器启动此容器,并设置节点污点从而控制节点个数使这些节点只运行一个七层代理服务容器。这个代理pod在K8s上又被称为:ingress Control访问路径:集群外部client进行https访问→四层负载均衡器→NodeIP:NodePort(Pod中七层代理服务)→PodIP:containerPort(真正提供服务的容器)后端有多组web,每组提供不同功能的情况下:方案一:例如nginx代理可以用不同主机名或端口设置4个虚拟主机每个主机代理一组后端方案二:通过URL映射,每一个路径映射到一组后端服务七层代理服务:HAProxy:用的比较少nginx:默认Traefik:面向微服务的开发的,能监控自身配置文件变化并自动重载配置文件Envoy:servicemesh网络中比较倾向的,微服务用的比较多,也能监控自身配置文件变化并自动重载配置文件在七层代理服务器假如是nginx反代至后端时,因为后端时pod容器所以ip不固定,如何修改nginx上upsteam确认后端IP解决方案:在他们中间层设置一个service,但此service不做代理使用只是负责给后端资源分组K8S上有个ingress资源(注意与ingress Control区分),他可以读取每个service上所属的组包含的后端的IP定义成upsteam server并注入到nginx配置文件中并触发nginx重载配置文件资源配置清单中ingress配置:(创建ingress资源后,会根据配置自动注入到ingress Control中)kubectl explain ingress:apiVersion <string>kind <string>metadata <Object>annotations <map[string]string> #声明用哪种代理 spec <Object>backend <Object> #定义后端serviceName <string> #定义后端serviceservicePort <string> #后端service端口rules <[]Object> #定义调度规则host <string> #通过虚拟主机调度http <Object>paths <[]Object> -required- #通过url路径映射调度tls:定义https时定义ingress配置清单示例(https协议)1.用openssh生成一对自谦证书2.创建secret资源对象用来转换自签证书格式kubectl create secret tls tomcat-ingress-secret --cert=tls.crt --key=tls.key#tls:表示对象类型#tomcat-ingress-secret 自定义名字#--cert=tls.crt --key=tls.key :指明秘钥对文件3.创建ingress#tls为https协议,secretName为指定秘钥认证的secret,tomcat.magedu.com为后端名称虚拟主机,myapp为后端提供服务所属的service,80为后端所提供服务的端口号于service无关
安装和部署ingress-nginx Control(注意k8s不能低于1.19)kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.2/deploy/static/provider/cloud/deploy.yaml#ingress资源创建后会自动注入配置可以通过交互命令查看ingress-nginx中nginx配置信息
存储卷
补充:因为k8s是一个集群是由调度器调度所以类似于docker的单节点映射本地目录存储卷是行不通的,所以一般需要一个共享存储或者网络存储同一个pod中的多个容器可以共享一个存储卷:因为存储卷不是属于容器而是属于pod,同一个pod中的容器底层复制的同一个基础架构镜像:pause。
存储卷种类:非持久存储:emptyDir:作为容器中临时空目录使用,映射为宿主机目录或者内存,容器删除此目录中的数据也会被删除hostPath:宿主机目录做映射,pod变更重新创建时需要调度到同一个宿主机上才能实现持久存储gitRepo:类似与emptyDir,只不过是有内容的。在创建pod时会把指定的一个git仓库内容克隆下来并挂载。如果内容发生改变并不会自动进行推送或远程同步,要实现此功能需要一个辅助容器Sidecar持久存储:传统网络存储:SAN(iscsi)、NAS(NFS、CIFS)分部式存储(文件系统级别、块级别):glusterfs,rbd,cephfs云存储:ebs、Azure Disk资源配置清单中pod存储卷配置:kubectl explain pod.specvolumes <[]Object> #在pod中定义存储卷- nameemptyDir <Object> #emptyDir存储卷medium <string>sizeLimit <string>hostPath <Object> #hostPath存储卷path <string> -required- #指明宿主机上的路径type <string> #DirectoryOrCreate:挂载的宿主机上的目录如果不存在则创建#Directory:宿主机上必须存在此目录#FileOrCreate:挂载一个宿主机文件如果不存在则创建#File:宿主机必须存在此文件#Socket#CharDevice:字符类型设备文件#BlockDevice:块设备文件nfs <Object> #nfs存储卷,可以实现多个pod同时挂载同一个共享存储path <string> -required- #nfs共享路径readOnly <boolean>server <string> -required- #nfs服务器地址containersvolumeMounts <[]Object> #在容器中挂载存储卷- mountPath <string> -required-name <string> -required-readOnly <boolean>ubPathExpr <string>
示例1(emptyDir存储卷):定义一个pod中两个容器,并定义pod中存储卷并分别挂载到两个容器中,第二个容器输入内容到html并作为第一个nginx容器的主页显示。(可以通过curl 这个容器进行验证)
示例2(hostPath存储卷)
示例3(NFS共享存储)
需要各个节点都要安装nfs-utils
相关文章:
kubernetes详解——从入门到入土(更新中~)
k8s简介 编排工具:系统层面ansible、saltstackdocker容器docker compose docker swarm docker machinedocker compose:实现单机容器编排docker swarm:实现多主机整合成为一个docker machine:初始化新主机mesos marathonmesos …...
VScode异常处理 (因为在此系统上禁止运行脚本)
在使用 VScode 自带程序终端的时候会报出"系统禁止脚本运行的错误" 这是由于 Windows PowerShell执行策略导致的 解决办法 管理员身份运行 Windows PowerShell执行:get-ExecutionPolicy1,显示Restricted2执行:Set-ExecutionPoli…...
(5h)Unity3D快速入门之Roll-A-Ball游戏开发
DAY1:Unity3D安装 链接 DAY2:构建场景,编写代码 链接 内容:WASD前后左右移动、摄像机跟随 DAY3:待更新 DAY4:待更新 DAY5:待更新...
分享86个选项卡TABJS特效,总有一款适合您
分享86个选项卡TABJS特效,总有一款适合您 86个选项卡TABJS特效下载链接:https://pan.baidu.com/s/1NBtPP2tT5YQqi6c744tCqg?pwd6666 提取码:6666 Python采集代码下载链接:采集代码.zip - 蓝奏云 学习知识费力气࿰…...
【Linux】Linux基础
文章目录 学习目标操作系统不同应用领域的主流操作系统虚拟机 Linux系统的发展史Linux内核版和发行版 Linux系统下的文件和目录结构单用户操作系统vs多用户操作系统Windows和Linux文件系统区别 Linux终端命令格式终端命令格式查阅命令帮助信息 常用命令显示文件和目录切换工作目…...
动态规划求解 fibonacci 数列
动态规划: 动态规划的基本思想是:将原问题拆分为若干子问题,自底向上的求解。是自底向上的求解,即是先计算子问题的解,再得出原问题的解。 思路: 创建一个数组,大小为n1,用于存储斐波那契数列的值。数组的…...
js最大公约数的实现有哪些办法
在JavaScript中,有几种常见的方法可以实现最大公约数(GCD)的计算。以下是其中一些方法: 辗转相除法(欧几里德算法): 辗转相除法是一种基于递归的算法,用于计算两个数的最大公约数。它…...
盘后股价狂飙16% — GitLab的DevOps产品在AI时代展现强劲财务业绩
12月4日(周一)在美股收盘后,GitLab的股价狂飙16%!人工智能驱动的DevOps产品继续凸显其平台能力的优势。 GitLab 12 月 4 日股价图 GitLab报告第三季度收入同比增长32%!根据粗略统计,全球已经有接近1万家企…...
unity UI特效遮罩
using System.Collections; using System.Collections.Generic; using UnityEngine;/**UI特效遮罩 1.需要将ScrollRect 的遮罩Mask 换为 2D Mask2.将特效的Render里面的 Masking 设置为*/ public class UIParticleMaskControll : MonoBehaviour {// Start is called before …...
编程模拟支付宝能量产生过程--数据控制流
#模拟支付宝蚂蚁森林的能量产生过程 behavior_points { # 定义行为对应的积分"步行": 2,"生活缴费": 10,"线下支付": 5,"网络购票": 5,"共享单车": 10 }total_points 0 # 初始化总积分while True: # 开…...
SQL Sever 基础知识 - 数据筛选(1)
SQL Sever 基础知识 - 四、数据筛选 四、筛选数据第1节 DISTINCT - 去除重复值1.1 SELECT DISTINCT 子句简介1.2 SELECT DISTINCT 示例1.2.1 DISTINCT 一列示例1.2.2 DISTINCT 多列示例 1.2.3 DISTINCT 具有 null 值示例1.2.4 DISTINCT 与 GROUP BY 对比 第2节 WHERE - 过滤查询…...
2024 Move 中文开发者大会将于1月13–14日在上海举办
*以下文章来源于MoveFuns ,作者MoveFunsDAO 2024 Move 中文开发者大会将于1月13日-1月14日在上海举办。本届 Move 开发者大会以 “Move 生态关键的一年” 为主题。 由 MoveFuns 、OpenBuild 和 MoveBit 主办,Rooch、AptosGlobal、alcove、zkMove 和 Ti…...
基于PHP的在线日语学习平台
有需要请加文章底部Q哦 可远程调试 PHP在线日语学习平台 一 介绍 此日语学习平台基于原生PHP开发,数据库mysql。系统角色分为用户和管理员。(附带参考设计文档) 技术栈:phpmysqlphpstudyvscode 二 功能 学生 1 注册/登录/注销 2 个人中心 3 查看课程…...
解决element ui tree组件不产生横向滚动条
结果是这样的 需要在tree的外层,包一个父组件 <div class"tree"><el-tree :data"treeData" show-checkbox default-expand-all></el-tree></div> 在css里面这样写,样式穿透按自己使用的css编译器以及框架要求就好 &l…...
mysql的InnoDB存储引擎
详情请参考:https://dev.mysql.com/doc/refman/8.0/en/innodb-storage-engine.html InnoDB 是一个通用目的的存储引擎,它在高可用性、高性能方面做了平衡。MySQL 8.0,InnoDB 是默认的存储引擎。在创建表的时候,如果没有使用ENGIN…...
MCU 的 TOP 15 图形GUI库:选择最适合你的图形用户界面(二)
在嵌入式系统开发中,选择一个合适的图形用户界面(GUI)库是至关重要的。在屏幕上显示的时候,使用现成的图形库,这样开发人员就不需要弄清楚底层任务,例如如何绘制像素、线条、形状,如果再高级一点…...
软件工程 单选多选补充 复刻
原文 软件的主要特性:无形、高成本、包括程序和文档 软件工程三要素:方法、工具、过程 螺旋模型包含风险分析 软件工程的主要目标:风险分析 面向对象开发:Booch、UML、Coad、OMT 软件危机的主要表现:软件成本太高…...
微前端个人理解与简单总结
最近一段时间在学习微前端,一开始是看各种博客了解微前端含义、对比多种微前端框架优劣,最后选择了qiankun、micro-app、wujie这三种微前端框架进行深入研究、对比。 微前端框架 推出时间 官方文档易读性 社区讨论活跃度 配置难度 Qiankunÿ…...
PC端企业微信hook协议开发,获取要群发的客户群id
产品说明 一、 hook版本:企业微信hook接口是指将企业微信的功能封装成dll,并提供简易的接口给程序调用。通过hook技术,可以在不修改企业微信客户端源代码的情况下,实现对企业微信客户端的功能进行扩展和定制化。企业微信hook接口…...
RabbitMQ安装说明
注意: 本次安装以 CentOS 7为例 1、 准备软件 erlang 18.3 1.el7.centos.x86_64.rpm socat 1.7.3.2 5.el7.lux.x86_64.rpm rabbitmq server 3.6.5 1.noarch.rpm 2、安装Erlang rpm -ivh erlang-18.3-1.el7.centos.x86_64.rpm 3.、安装RabbitMQ 安装 rpm -ivh socat-1.7.3.2-…...
scrapy的建模及管道的使用
一、数据建模 通常在做项目的过程中,在items.py中进行数据建模 为什么建模 定义item即提前规划好哪些字段需要抓,防止手误,因为定义好之后,在运行过程中,系统会自动检查,配合注释一起可以清晰的知道要抓…...
Hadoop学习笔记(HDP)-Part.04 基础环境配置
目录 Part.01 关于HDP Part.02 核心组件原理 Part.03 资源规划 Part.04 基础环境配置 Part.05 Yum源配置 Part.06 安装OracleJDK Part.07 安装MySQL Part.08 部署Ambari集群 Part.09 安装OpenLDAP Part.10 创建集群 Part.11 安装Kerberos Part.12 安装HDFS Part.13 安装Ranger …...
【Linux】进程控制--进程创建/进程终止/进程等待/进程程序替换/简易shell实现
文章目录 一、进程创建1.fork函数2.fork函数返回值3.写时拷贝4.fork常规用法5.fork调用失败的原因 二、进程终止1.进程退出码2.进程退出场景3.进程常见退出方法 三、进程等待1.为什么要进行进程等待2.如何进行进程等待1.wait方法2.waitpid方法3.获取子进程status4.进程的阻塞等…...
用pip更新、安装python的包
查看pip的版本:python -m pip --version 例如,查看下pip的版本,在cmd下输入命令python -m pip --version,可以发现当前安装的pip的版本是23.2.1: 查看一个包的详情:python -m pip show 例如,…...
spring boot 事件机制
目录 概述实践监听spring boot ready事件代码 源码初始化流程调用流程 结束 概述 spring boot 版本为 2.7.17 。 整体看一下spring及spring boot 相关事件。 根据下文所给的源码关键处,打上断点,可以进行快速调试。降低源码阅读难度。 实践 spring…...
分布式版本管理系统---->Git(Linux---centos(保姆式)讲解1)
文章目录: 1:什么是Git以及作用 2.Git的基本操作过程(创建git仓库,配置仓库的配置) 3.git的工作区,暂存区,版本库的关系 4.将文件添加到版本库:git add 与git commit -m命令 5.git log查看日志的引入 6.查看.git文件中的内容 7.修改文件内容查…...
B树你需要了解一下
介绍B树的度数主要特点应用场景时间复杂度代码示例拓展 介绍 B树(B-tree)是一种自平衡的树,能够保持数据有序,常被用于数据库和文件系统的实现。 B树可以看作是一般化的二叉查找树,它允许拥有多于2个子节点。与自平衡…...
MFC设置状态栏文本导致崩溃的原因
文章目录 问题和原因解决办法1.消息机制2.定时器问题和原因 本人在类A使用多线程执行操作并且调用了类B的设置状态栏文本的函数,导致崩溃 类A void A::distribute_n_start_msg(){((B*)m_parent)->received_msg_n_start...
配置typroa上传图片到gitee
一、gitee相关配置 到gitee官网创建一个新的仓库并获取其token gitee配置时候一定要新建仓库之后初始化好仓库 比如:创建出README.md文档 出现master这个显示界面,刚开始未初始化的时候是会报错的 二、typora相关配置 在typora这个位置下载插件 在p…...
java并发-线程生命周期
文章目录 前言状态图状态变化说明补充说明 前言 线程的生命周期指的是线程从创建出来到最终消亡的整个过程,以及过程中的状态变化。 状态图 以下图用mermaid语法绘制: #mermaid-svg-32vKT6KmFdlYvCnr {font-family:"trebuchet ms",verdana,…...
煤矿建设工程质量监督总站网站/招代理最好的推广方式
纯属预告,不属广告:在windows server 2008这一块博客已经出了第一部“[为企业部署 Windows Server 2008 系列]”,总结如下:一、windows server 2008 部署条件:卍解[为企业部署Windows Server 2008系列一]二、完整安装模…...
地图类网站开发实战教程/快速排名seo
紫薯芝麻饼松软的手指食物。食材紫薯50克、面粉10克、芝麻酱1勺、鸡蛋1个、油2克标签手指食物、缓解便秘、加餐零食、不爱主食、各种饼类、中式面食、10m难度★★★标签推荐月龄仅针对展示的成品图,可根据宝宝月龄调整食材大小1. 紫薯提前蒸熟压成泥,鸡蛋…...
班级网站开发环境/网络营销案例范文
InnoDB事务相关概念 ● redo log MySQL在开启事务时,会将执行的SQL保存到指定的log文件,即redo log。当MySQL执行recovery时执行redo log里的SQL操作即可。redo log不会被立即写入磁盘,会先写入redo buffer;当客户端执行commit时…...
会展设计用什么软件/石家庄抖音seo
这里我们来谈论下函数式编程中另一个重要的概念,柯里化 首先,我们先通过下面的方式将上节代码中不纯的函数变成纯函数。就是将mini拿到函数内部去。 function checkAge (age) {let mini 18;return age > mini; }但是当我们把这个mini拿到函数内部的…...
网站掉排名/今日新闻快讯10条
首先,例如我们处于图形页面 如图: 我们想要切换到命令行模式,需要摁电脑的Ctrl键Alt键 及F2同时摁 如图进入页面: 输入root/用户名,输入密码回车进入成功 如果想要切换回来摁CtrlAltF1即可。 小伙伴们学废了么&am…...
网站访问量大/搜索引擎案例分析结论
在上一部分,我们完成了数据库的一部分安装,下面接着来安装。检查Oracle的环境变量,确保PATH中包括/u01/app/oracle/product/10.2.0/db_1/bin执行dbca命令,会弹出数据库配置助理界面。点击“Next”进入下一个界面。这里选择创建数据…...