『Kubernetes(K8S) 入门进阶实战』实战入门 - Pod 详解
『Kubernetes(K8S) 入门进阶实战』实战入门 - Pod 详解
Pod 结构
- 每个 Pod 中都可以包含一个或者多个容器,这些容器可以分为两类
- 用户程序所在的容器,数量可多可少
- Pause 容器,这是每个 Pod 都会有的一个根容器,它的作用有两个
- 可以以它为依据,评估整个 Pod 的健康状态
- 可以在根容器上设置 IP 地址,其它容器都此 IP(Pod IP),以实现 Pod 内部的网路通信
Pod 定义
- Pod 的资源清单
apiVersion: v1 #必选,版本号,例如v1
kind: Pod #必选,资源类型,例如 Pod
metadata: #必选,元数据name: string #必选,Pod名称namespace: string #Pod所属的命名空间,默认为"default"labels: #自定义标签列表- name: string
spec: #必选,Pod中容器的详细定义containers: #必选,Pod中容器列表- name: string #必选,容器名称image: string #必选,容器的镜像名称imagePullPolicy: [ Always|Never|IfNotPresent ] #获取镜像的策略 command: [string] #容器的启动命令列表,如不指定,使用打包时使用的启动命令args: [string] #容器的启动命令参数列表workingDir: string #容器的工作目录volumeMounts: #挂载到容器内部的存储卷配置- name: string #引用pod定义的共享存储卷的名称,需用volumes[]部分定义的的卷名mountPath: string #存储卷在容器内mount的绝对路径,应少于512字符readOnly: boolean #是否为只读模式ports: #需要暴露的端口库号列表- name: string #端口的名称containerPort: int #容器需要监听的端口号hostPort: int #容器所在主机需要监听的端口号,默认与Container相同protocol: string #端口协议,支持TCP和UDP,默认TCPenv: #容器运行前需设置的环境变量列表- name: string #环境变量名称value: string #环境变量的值resources: #资源限制和请求的设置limits: #资源限制的设置cpu: string #Cpu的限制,单位为core数,将用于docker run --cpu-shares参数memory: string #内存限制,单位可以为Mib/Gib,将用于docker run --memory参数requests: #资源请求的设置cpu: string #Cpu请求,容器启动的初始可用数量memory: string #内存请求,容器启动的初始可用数量lifecycle: #生命周期钩子postStart: #容器启动后立即执行此钩子,如果执行失败,会根据重启策略进行重启preStop: #容器终止前执行此钩子,无论结果如何,容器都会终止livenessProbe: #对Pod内各容器健康检查的设置,当探测无响应几次后将自动重启该容器exec: #对Pod容器内检查方式设置为exec方式command: [string] #exec方式需要制定的命令或脚本httpGet: #对Pod内个容器健康检查方法设置为HttpGet,需要制定Path、portpath: stringport: numberhost: stringscheme: stringHttpHeaders:- name: stringvalue: stringtcpSocket: #对Pod内个容器健康检查方式设置为tcpSocket方式port: numberinitialDelaySeconds: 0 #容器启动完成后首次探测的时间,单位为秒timeoutSeconds: 0 #对容器健康检查探测等待响应的超时时间,单位秒,默认1秒periodSeconds: 0 #对容器监控检查的定期探测时间设置,单位秒,默认10秒一次successThreshold: 0failureThreshold: 0securityContext:privileged: falserestartPolicy: [Always | Never | OnFailure] #Pod的重启策略nodeName: <string> #设置NodeName表示将该Pod调度到指定到名称的node节点上nodeSelector: obeject #设置NodeSelector表示将该Pod调度到包含这个label的node上imagePullSecrets: #Pull镜像时使用的secret名称,以key:secretkey格式指定- name: stringhostNetwork: false #是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络volumes: #在该pod上定义共享存储卷列表- name: string #共享存储卷名称 (volumes类型有很多种)emptyDir: {} #类型为emtyDir的存储卷,与Pod同生命周期的一个临时目录。为空值hostPath: string #类型为hostPath的存储卷,表示挂载Pod所在宿主机的目录path: string #Pod所在宿主机的目录,将被用于同期中mount的目录secret: #类型为secret的存储卷,挂载集群与定义的secret对象到容器内部scretname: string items: - key: stringpath: stringconfigMap: #类型为configMap的存储卷,挂载预定义的configMap对象到容器内部name: stringitems:- key: stringpath: string
- 在这里,可通过一个命令来查看每种资源的可配置项,反而不需要去记
# kubectl explain 资源类型 查看某种资源可以配置的一级属性
# kubectl explain 资源类型.属性 查看属性的子属性
[root@k8s-master01 ~]# kubectl explain pod
KIND: Pod
VERSION: v1
FIELDS:apiVersion <string>kind <string>metadata <Object>spec <Object>status <Object># 查看下一个层级
[root@k8s-master01 ~]# kubectl explain pod.metadata
KIND: Pod
VERSION: v1
RESOURCE: metadata <Object>
FIELDS:annotations <map[string]string>clusterName <string>creationTimestamp <string>deletionGracePeriodSeconds <integer>deletionTimestamp <string>finalizers <[]string>generateName <string>generation <integer>labels <map[string]string>managedFields <[]Object>name <string>namespace <string>ownerReferences <[]Object>resourceVersion <string>selfLink <string>uid <string>
- 在 kubernetes 中基本所有资源的一级属性都是一样的,主要包含 5 部分
- apiVersion 版本:由 kubernetes 内部定义,版本号必须可以用
kubectl api-versions
查询到 - kind 类型:由 kubernetes 内部定义,版本号必须可以用
kubectl api-resources
查询到 - metadata 元数据:主要是资源标识和说明,常用的有 name、namespace、labels 等
- spec 描述:这是配置中最重要的一部分,里面是对各种资源配置的详细描述
- status 状态信息:里面的内容不需要定义,由 kubernetes 自动生成
- 在上面的属性中,spec 是接下来研究的重点,继续看下它的常见子属性:
- containers <[]Object> 容器列表:用于定义容器的详细信息
- nodeName:根据 nodeName 的值将 pod 调度到指定的 Node 节点上
- nodeSelector <map[]> :根据 NodeSelector 中定义的信息选择将该 Pod 调度到包含这些 label 的 Node 上
- hostNetwork:是否使用主机网络模式,默认为 false,如果设置为 true,表示使用宿主机网络
- volumes <[]Object> 存储卷:用于定义 Pod 上面挂在的存储信息
- restartPolicy 重启策略:表示 Pod 在遇到故障的时候的处理策略
Pod 配置
pod.spec.containers
属性,是 pod 配置中最为关键的一项配置
[root@k8s-master01 ~]# 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> # 容器需要暴露的端口号列表resources <Object> # 资源限制和资源请求的设置
- 创建 pod-base.yaml 文件,内容如下
apiVersion: v1
kind: Pod
metadata:name: pod-basenamespace: devlabels:user: heima
spec:containers:- name: nginximage: nginx:1.17.1- name: busyboximage: busybox:1.30
- 上面定义了一个比较简单 Pod 的配置,里面有两个容器
- nginx:用 1.17.1 版本的 nginx 镜像创建,(nginx 是一个轻量级 web 容器)
- busybox:用 1.30 版本的 busybox 镜像创建,(busybox 是一个小巧的 linux 命令集合)
# 创建Pod
[root@k8s-master01 pod]# kubectl apply -f pod-base.yaml
pod/pod-base created# 查看 Pod 状况
# READY 1/2:表示当前 Pod 中有 2 个容器,其中 1 个准备就绪,1 个未就绪
# RESTARTS:重启次数,因为有 1 个容器故障了,Pod 一直在重启试图恢复它
[root@k8s-master01 pod]# kubectl get pod -n dev
NAME READY STATUS RESTARTS AGE
pod-base 1/2 Running 4 95s# 可以通过describe查看内部的详情
# 此时已经运行起来了一个基本的 Pod,虽然它暂时有问题
[root@k8s-master01 pod]# kubectl describe pod pod-base -n dev
Pod 镜像拉取(imagePullPolicy)
- 创建 pod-imagepullpolicy.yaml 文件,内容如下
apiVersion: v1
kind: Pod
metadata:name: pod-imagepullpolicynamespace: dev
spec:containers:- name: nginximage: nginx:1.17.1imagePullPolicy: Never # 用于设置镜像拉取策略- name: busyboximage: busybox:1.30
imagePullPolicy
:用于设置镜像拉取策略,kubernetes 支持配置三种拉取策略
- Always:总是从远程仓库拉取镜像(一直远程下载)
- IfNotPresent:本地有则使用本地镜像,本地没有则从远程仓库拉取镜像(本地有就本地 本地没远程下载)
- Never:只使用本地镜像,从不去远程仓库拉取,本地没有就报错 (一直使用本地)
- 默认值说明:
- 如果镜像 tag 为具体版本号, 默认策略是:IfNotPresent
- 如果镜像 tag 为:latest(最终版本) ,默认策略是 always
# 创建Pod
[root@k8s-master01 pod]# kubectl create -f pod-imagepullpolicy.yaml
pod/pod-imagepullpolicy created# 查看Pod详情
# 此时明显可以看到nginx镜像有一步Pulling image "nginx:1.17.1"的过程
[root@k8s-master01 pod]# kubectl describe pod pod-imagepullpolicy -n dev
......
Events:Type Reason Age From Message---- ------ ---- ---- -------Normal Scheduled <unknown> default-scheduler Successfully assigned dev/pod-imagePullPolicy to node1Normal Pulling 32s kubelet, node1 Pulling image "nginx:1.17.1"Normal Pulled 26s kubelet, node1 Successfully pulled image "nginx:1.17.1"Normal Created 26s kubelet, node1 Created container nginxNormal Started 25s kubelet, node1 Started container nginxNormal Pulled 7s (x3 over 25s) kubelet, node1 Container image "busybox:1.30" already present on machineNormal Created 7s (x3 over 25s) kubelet, node1 Created container busyboxNormal Started 7s (x3 over 25s) kubelet, node1 Started container busybox
启动命令(command)
- 在前面的案例中,一直有一个问题没有解决,就是的 busybox 容器一直没有成功运行
- 原来 busybox 并不是一个程序,而是类似于一个工具类的集合,kubernetes 集群启动管理后,它会自动关闭。解决方法就是让其一直在运行,这就用到了 command 配置
- 创建 pod-command.yaml 文件,内容如下
apiVersion: v1
kind: Pod
metadata:name: pod-commandnamespace: dev
spec:containers:- name: nginximage: nginx:1.17.1- name: busyboximage: busybox:1.30command: ["/bin/sh","-c","touch /tmp/hello.txt;while true;do /bin/echo $(date +%T) >> /tmp/hello.txt; sleep 3; done;"]
- command:用于在 pod 中的容器初始化完毕之后运行一个命令
# 稍微解释下上面命令的意思"/bin/sh","-c", # 使用sh执行命令touch /tmp/hello.txt; # 创建一个/tmp/hello.txt 文件while true;do /bin/echo $(date +%T) >> /tmp/hello.txt; sleep 3; done; # 每隔3秒向文件中写入当前时间
- 查看容器内的执行
# 创建Pod
[root@k8s-master01 pod]# kubectl create -f pod-command.yaml
pod/pod-command created# 查看Pod状态
# 此时发现两个pod都正常运行了
[root@k8s-master01 pod]# kubectl get pods pod-command -n dev
NAME READY STATUS RESTARTS AGE
pod-command 2/2 Runing 0 2s# 进入 pod 中的busybox容器,查看文件内容
# 补充一个命令: kubectl exec pod名称 -n 命名空间 -it -c 容器名称 /bin/sh 在容器内部执行命令
# 使用这个命令就可以进入某个容器的内部,然后进行相关操作了
# 比如,可以查看txt文件的内容
[root@k8s-master01 pod]# kubectl exec pod-command -n dev -it -c busybox /bin/sh
/ # tail -f /tmp/hello.txt
14:44:19
14:44:22
14:44:25
- 特别说明(command+args>command>args=ENTRYPOINT>Dockerfile配置)
- 通过上面发现 command 已经可以完成启动命令和传递参数的功能,为什么这里还要提供一个 args 选项,用于传递参数呢?这其实跟 docker 有点关系,kubernetes 中的command、args 两项其实是实现覆盖 Dockerfile 中 ENTRYPOINT 的功能
- 如果 command 和 args 均没有写,那么用 Dockerfile 的配置
- 如果 command 写了,但 args 没有写,那么 Dockerfile 默认的配置会被忽略,执行输入的 command
- 如果 command 没写,但 args 写了,那么 Dockerfile 中配置的 ENTRYPOINT 的命令会被执行,使用当前 args 的参数
- 如果 command 和 args 都写了,那么 Dockerfile 的配置被忽略,执行 command 并追加上 args 参数
- 所谓的 args 在这里
环境变量
- 创建 pod-env.yaml 文件,内容如下
apiVersion: v1
kind: Pod
metadata:name: pod-envnamespace: dev
spec:containers:- name: busyboximage: busybox:1.30command: ["/bin/sh","-c","while true;do /bin/echo $(date +%T);sleep 60; done;"]env: # 设置环境变量列表- name: "username"value: "admin"- name: "password"value: "123456"
env
:环境变量,用于在 pod 中的容器设置环境变量
# 创建Pod
[root@k8s-master01 ~]# kubectl create -f pod-env.yaml
pod/pod-env created# 进入容器,输出环境变量
[root@k8s-master01 ~]# kubectl exec pod-env -n dev -c busybox -it /bin/sh
/ # echo $username
admin
/ # echo $password
123456
端口设置
- 容器的端口设置,也就是 containers 的 ports 选项。首先看下 ports 支持的子选项
[root@k8s-master01 ~]# kubectl explain pod.spec.containers.ports
KIND: Pod
VERSION: v1
RESOURCE: ports <[]Object>
FIELDS:name <string> # 端口名称,如果指定,必须保证name在pod中是唯一的 containerPort<integer> # 容器要监听的端口(0<x<65536)hostPort <integer> # 容器要在主机上公开的端口,如果设置,主机上只能运行容器的一个副本(一般省略) hostIP <string> # 要将外部端口绑定到的主机IP(一般省略)protocol <string> # 端口协议。必须是UDP、TCP或SCTP。默认为“TCP”。
- containerPort 与 hostPort 的区别
- 创建 pod-ports.yaml
apiVersion: v1
kind: Pod
metadata:name: pod-portsnamespace: dev
spec:containers:- name: nginximage: nginx:1.17.1ports: # 设置容器暴露的端口列表- name: nginx-portcontainerPort: 80protocol: TCP
- 执行脚本
- 访问容器中的程序需要使用的是 Podip:containerPort
# 创建Pod
[root@k8s-master01 ~]# kubectl create -f pod-ports.yaml
pod/pod-ports created# 查看pod
# 在下面可以明显看到配置信息
[root@k8s-master01 ~]# kubectl get pod pod-ports -n dev -o yaml
......
spec:containers:- image: nginx:1.17.1imagePullPolicy: IfNotPresentname: nginxports:- containerPort: 80name: nginx-portprotocol: TCP
......
资源配额
- 容器中的程序要运行,肯定是要占用一定资源的,比如 cpu 和内存等,如果不对某个容器的资源做限制,那么它就可能吃掉大量资源,导致其它容器无法运行。针对这种情况, kubernetes 提供了对内存和 cpu 的资源进行配额的机制,这种机制主要通过 resources 选项实现,他有两个子选项
limits
:用于限制运行时容器的最大占用资源,当容器占用资源超过 limits 时会被终止,并进行重启requests
:用于设置容器需要的最小资源,如果环境资源不够,容器将无法启动
- 创建 pod-resources.yaml
apiVersion: v1
kind: Pod
metadata:name: pod-resourcesnamespace: dev
spec:containers:- name: nginximage: nginx:1.17.1resources: # 资源配额limits: # 限制资源(上限)cpu: "2" # CPU限制,单位是core数memory: "10Gi" # 内存限制requests: # 请求资源(下限)cpu: "1" # CPU限制,单位是core数memory: "10Mi" # 内存限制
- 在这对 cpu 和 memory 的单位做一个说明
- cpu:core数,可以为整数或小数
- memory:内存大小,可以使用 Gi、Mi、G、M 等形式
# 运行Pod
[root@k8s-master01 ~]# kubectl create -f pod-resources.yaml
pod/pod-resources created# 查看发现pod运行正常
[root@k8s-master01 ~]# kubectl get pod pod-resources -n dev
NAME READY STATUS RESTARTS AGE
pod-resources 1/1 Running 0 39s # 接下来,停止Pod
[root@k8s-master01 ~]# kubectl delete -f pod-resources.yaml
pod "pod-resources" deleted# 编辑pod,修改resources.requests.memory的值为10Gi
[root@k8s-master01 ~]# vim pod-resources.yaml# 再次启动pod
[root@k8s-master01 ~]# kubectl create -f pod-resources.yaml
pod/pod-resources created# 查看Pod状态,发现Pod启动失败
[root@k8s-master01 ~]# kubectl get pod pod-resources -n dev -o wide
NAME READY STATUS RESTARTS AGE
pod-resources 0/1 Pending 0 20s # 查看pod详情会发现,如下提示
[root@k8s-master01 ~]# kubectl describe pod pod-resources -n dev
......
Warning FailedScheduling 35s default-scheduler 0/3 nodes are available: 1 node(s) had taint {node-role.kubernetes.io/master: }, that the pod didn't tolerate, 2 Insufficient memory.(内存不足)
Pod 生命周期
- 一般将 pod 对象从创建至终的这段时间范围称为 pod 的生命周期,它主要包含下面的过程
- pod 创建过程
- 运行初始化容器(init container)过程
- 运行主容器(main container)
- 容器启动后钩子(post start)、容器终止前钩子(pre stop)
- 容器的存活性探测(liveness probe)、就绪性探测(readiness probe)
- 在整个生命周期中,Pod 会出现 5 种状态(相位)
- 挂起(Pending):apiserver 已经创建了 pod 资源对象,但它尚未被调度完成或者仍处于下载镜像的过程中
- 运行中(Running):pod 已经被调度至某节点,并且所有容器都已经被 kubelet 创建完成
- 成功(Succeeded):pod 中的所有容器都已经成功终止并且不会被重启
- 失败(Failed):所有容器都已经终止,但至少有一个容器终止失败,即容器返回了非 0 值的退出状态
- 未知(Unknown):apiserver 无法正常获取到 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 对于用户已不可见
初始化容器
- 初始化容器是在 pod 的主容器启动之前要运行的容器,主要是做一些主容器的前置工作,它具有两大特征
- 初始化容器必须运行完成直至结束,若某初始化容器运行失败,那么 kubernetes 需要重启它直到成功完成
- 初始化容器必须按照定义的顺序执行,当且仅当前一个成功之后,后面的一个才能运行
- 初始化容器有很多的应用场景,下面列出的是最常见的几个
- 提供主容器镜像中不具备的工具程序或自定义代码
- 初始化容器要先于应用容器串行启动并运行完成,因此可用于延后应用容器的启动直至其依赖的条件得到满足
- 测试案例,创建 pod-initcontainer.yaml
- 假设要以主容器来运行 nginx,但是要求在运行 nginx 之前先要能够连接上 mysql 和 redis 所在服务器
apiVersion: v1
kind: Pod
metadata:name: pod-initcontainernamespace: dev
spec:containers:- name: main-containerimage: nginx:1.17.1ports: - name: nginx-portcontainerPort: 80initContainers:- name: test-mysqlimage: busybox:1.30command: ['sh', '-c', 'until ping 192.168.124.87 -c 1 ; do echo waiting for mysql...; sleep 2; done;']- name: test-redisimage: busybox:1.30command: ['sh', '-c', 'until ping 192.168.124.88 -c 1 ; do echo waiting for reids...; sleep 2; done;']
# 创建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 node1Normal Pulled 48s kubelet, node1 Container image "busybox:1.30" already present on machineNormal Created 48s kubelet, node1 Created container test-mysqlNormal 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
钩子函数
- 钩子函数能够感知自身生命周期中的事件,并在相应的时刻到来时运行用户指定的程序代码
- 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-execnamespace: dev
spec:containers:- name: main-containerimage: nginx:1.17.1ports:- name: nginx-portcontainerPort: 80lifecycle: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...
容器探测
- 容器探测用于检测容器中的应用实例是否正常工作,是保障业务可用性的一种传统机制。如果经过探测,实例的状态不符合预期,那么kubernetes就会把该问题实例" 摘除 ",不承担业务流量。kubernetes 提供了两种探针来实现容器探测,分别是:
- liveness probes:存活性探针,用于检测应用实例当前是否处于正常运行状态,如果不是, k8s 会重启容器
- readiness probes:就绪性探针,用于检测应用实例当前是否可以接收请求,如果不能,k8s 不会转发流量
- 总结:livenessProbe 决定是否重启容器,readinessProbe 决定是否将请求转发给容器
- 上面两种探针目前均支持三种探测方式
- Exec:在容器内执行一次命令,如果命令执行的退出码为 0,则认为程序正常,否则不正常
……lifecycle:postStart: exec:command:- cat- /tmp/healthy
……
- TCPSocket:将会尝试访问一个用户容器的端口,如果能够建立这条连接,则认为程序正常,否则不正常
…… lifecycle:postStart:tcpSocket:port: 8080
……
- HTTPGet:调用容器内 Web 应用的 URL,如果返回的状态码在 200 和 399 之间,则认为程序正常,否则不正常
……lifecycle:postStart:httpGet:path: / #URI地址port: 80 #端口号host: 192.168.5.3 #主机地址scheme: HTTP #支持的协议,http或者https
……
- 测试 Exec 探测
- 创建 pod-liveness-exec.yaml
apiVersion: v1
kind: Pod
metadata:name: pod-liveness-execnamespace: dev
spec:containers:- name: nginximage: nginx:1.17.1ports: - name: nginx-portcontainerPort: 80livenessProbe:exec:command: ["/bin/cat","/tmp/hello.txt"] # 执行一个查看文件的命令
- 创建 pod,观察效果
# 创建Pod
[root@k8s-master01 ~]# kubectl create -f pod-liveness-exec.yaml
pod/pod-liveness-exec created# 查看Pod详情
[root@k8s-master01 ~]# kubectl describe pods pod-liveness-exec -n dev
......Normal Created 20s (x2 over 50s) kubelet, node1 Created container nginxNormal Started 20s (x2 over 50s) kubelet, node1 Started container nginxNormal Killing 20s kubelet, node1 Container nginx failed liveness probe, will be restartedWarning Unhealthy 0s (x5 over 40s) kubelet, node1 Liveness probe failed: cat: can't open '/tmp/hello11.txt': No such file or directory# 观察上面的信息就会发现nginx容器启动之后就进行了健康检查
# 检查失败之后,容器被kill掉,然后尝试进行重启(这是重启策略的作用,后面讲解)
# 稍等一会之后,再观察pod信息,就可以看到RESTARTS不再是0,而是一直增长
[root@k8s-master01 ~]# kubectl get pods pod-liveness-exec -n dev
NAME READY STATUS RESTARTS AGE
pod-liveness-exec 0/1 CrashLoopBackOff 2 3m19s# 当然接下来,可以修改成一个存在的文件,比如/tmp/hello.txt,再试,结果就正常了......
- 测试 TCPSocket 探测
- 创建 pod-liveness-tcpsocket.yaml
apiVersion: v1
kind: Pod
metadata:name: pod-liveness-tcpsocketnamespace: dev
spec:containers:- name: nginximage: nginx:1.17.1ports: - name: nginx-portcontainerPort: 80livenessProbe:tcpSocket:port: 8080 # 尝试访问8080端口
- 创建 pod,观察效果
# 创建Pod
[root@k8s-master01 ~]# kubectl create -f pod-liveness-tcpsocket.yaml
pod/pod-liveness-tcpsocket created# 查看Pod详情
[root@k8s-master01 ~]# kubectl describe pods pod-liveness-tcpsocket -n dev
......Normal Scheduled 31s default-scheduler Successfully assigned dev/pod-liveness-tcpsocket to node2Normal Pulled <invalid> kubelet, node2 Container image "nginx:1.17.1" already present on machineNormal Created <invalid> kubelet, node2 Created container nginxNormal Started <invalid> kubelet, node2 Started container nginxWarning Unhealthy <invalid> (x2 over <invalid>) kubelet, node2 Liveness probe failed: dial tcp 10.244.2.44:8080: connect: connection refused# 观察上面的信息,发现尝试访问8080端口,但是失败了
# 稍等一会之后,再观察pod信息,就可以看到RESTARTS不再是0,而是一直增长
[root@k8s-master01 ~]# kubectl get pods pod-liveness-tcpsocket -n dev
NAME READY STATUS RESTARTS AGE
pod-liveness-tcpsocket 0/1 CrashLoopBackOff 2 3m19s# 当然接下来,可以修改成一个可以访问的端口,比如80,再试,结果就正常了......
- 测试 HTTPGet 探测
- 创建 pod-liveness-httpget.yaml
apiVersion: v1
kind: Pod
metadata:name: pod-liveness-httpgetnamespace: dev
spec:containers:- name: nginximage: nginx:1.17.1ports:- name: nginx-portcontainerPort: 80livenessProbe:httpGet: # 其实就是访问http://127.0.0.1:80/hello scheme: HTTP #支持的协议,http或者httpsport: 80 #端口号path: /hello #URI地址
- 创建 pod,观察效果
# 创建Pod
[root@k8s-master01 ~]# kubectl create -f pod-liveness-httpget.yaml
pod/pod-liveness-httpget created# 查看Pod详情
[root@k8s-master01 ~]# kubectl describe pod pod-liveness-httpget -n dev
.......Normal Pulled 6s (x3 over 64s) kubelet, node1 Container image "nginx:1.17.1" already present on machineNormal Created 6s (x3 over 64s) kubelet, node1 Created container nginxNormal Started 6s (x3 over 63s) kubelet, node1 Started container nginxWarning Unhealthy 6s (x6 over 56s) kubelet, node1 Liveness probe failed: HTTP probe failed with statuscode: 404Normal Killing 6s (x2 over 36s) kubelet, node1 Container nginx failed liveness probe, will be restarted# 观察上面信息,尝试访问路径,但是未找到,出现404错误
# 稍等一会之后,再观察pod信息,就可以看到RESTARTS不再是0,而是一直增长
[root@k8s-master01 ~]# kubectl get pod pod-liveness-httpget -n dev
NAME READY STATUS RESTARTS AGE
pod-liveness-httpget 1/1 Running 5 3m17s# 当然接下来,可以修改成一个可以访问的路径path,比如/,再试,结果就正常了......
- 至此,已经使用 liveness Probe 演示了三种探测方式,但是查看 livenessProbe 的子属性,会发现除了这三种方式,还有一些其他的配置,在这里一并解释下:
[root@k8s-master01 ~]# kubectl explain pod.spec.containers.livenessProbe
FIELDS:exec <Object> tcpSocket <Object>httpGet <Object>initialDelaySeconds <integer> # 容器启动后等待多少秒执行第一次探测timeoutSeconds <integer> # 探测超时时间。默认1秒,最小1秒periodSeconds <integer> # 执行探测的频率。默认是10秒,最小1秒failureThreshold <integer> # 连续探测失败多少次才被认定为失败。默认是3。最小值是1successThreshold <integer> # 连续探测成功多少次才被认定为成功。默认是1
- 可以增加配置 2 个进行测试
apiVersion: v1
kind: Pod
metadata:name: pod-liveness-httpgetnamespace: dev
spec:containers:- name: nginximage: nginx:1.17.1ports:- name: nginx-portcontainerPort: 80livenessProbe:httpGet:scheme: HTTPport: 80 path: /initialDelaySeconds: 30 # 容器启动后30s开始探测timeoutSeconds: 5 # 探测超时时间为5s
重启策略
- 一旦容器探测出现了问题,kubernetes 就会对容器所在的 Pod 进行重启,其实这是由 pod 的重启策略决定的,pod 的重启策略有 3 种:
- Always:容器失效时,自动重启该容器,这也是默认值
- OnFailure: 容器终止运行且退出码不为 0 时重启
- Never: 不论状态为何,都不重启该容器
- 重启策略适用于 pod 对象中的所有容器,首次需要重启的容器,将在其需要时立即进行重启,随后再次需要重启的操作将由 kubelet 延迟一段时间后进行,且反复的重启操作的延迟时长以此为 10s、20s、40s、80s、160s 和 300s,300s 是最大延迟时长
- 创建 pod-restartpolicy.yaml
apiVersion: v1
kind: Pod
metadata:name: pod-restartpolicynamespace: dev
spec:containers:- name: nginximage: nginx:1.17.1ports:- name: nginx-portcontainerPort: 80livenessProbe:httpGet:scheme: HTTPport: 80path: /hellorestartPolicy: Never # 设置重启策略为 Never
- 运行 Pod 测试
# 创建Pod
[root@k8s-master01 ~]# kubectl create -f pod-restartpolicy.yaml
pod/pod-restartpolicy created# 查看Pod详情,发现nginx容器失败
[root@k8s-master01 ~]# kubectl describe pods pod-restartpolicy -n dev
......Warning Unhealthy 15s (x3 over 35s) kubelet, node1 Liveness probe failed: HTTP probe failed with statuscode: 404Normal Killing 15s kubelet, node1 Container nginx failed liveness probe# 多等一会,再观察pod的重启次数,发现一直是0,并未重启。会发现状态是 Completed
[root@k8s-master01 ~]# kubectl get pods pod-restartpolicy -n dev
NAME READY STATUS RESTARTS AGE
pod-restartpolicy 0/1 Completed 0 35s
Pod 调度
- 在默认情况下,一个 Pod 在哪个 Node 节点上运行,是由 Scheduler 组件采用相应的算法计算出来的,这个过程是不受人工控制的。但是在实际使用中,这并不满足的需求,因为很多情况下,我们想控制某些 Pod 到达某些节点上。因此 kubernetes 提供了四大类调度方式:
- 自动调度:运行在哪个节点上完全由 Scheduler 经过一系列的算法计算得出
- 定向调度:NodeName、NodeSelector
- 亲和性调度:NodeAffinity、PodAffinity、PodAntiAffinity
- 污点(容忍)调度:Taints、Toleration
相关文章:
『Kubernetes(K8S) 入门进阶实战』实战入门 - Pod 详解
『Kubernetes(K8S) 入门进阶实战』实战入门 - Pod 详解 Pod 结构 每个 Pod 中都可以包含一个或者多个容器,这些容器可以分为两类 用户程序所在的容器,数量可多可少Pause 容器,这是每个 Pod 都会有的一个根容器,它的作用有两个 可…...
【React框架】什么是 Vite?如何使用vite自动生成react的目录?
什么是 Vite? Vite 是一个基于原生 ES Modules 开发的前端构建工具,由 Evan You(Vue 的作者)开发。它最大的特点包括: 极速冷启动:因为利用了浏览器原生的 ES Modules,所以在开发时无需等待整…...
JS实现文件点击或者拖拽上传
B站看到了渡一大师课的切片,自己实现了一下,做下记录 效果展示 分为上传前、上传中和上传后 实现 分为两步 界面交互网络请求 源码如下 upload.html <!DOCTYPE html> <html lang"zh-CN"><head><meta charset&q…...
【Vue #3】指令补充样式绑定
一、指令修饰符 Vue 的指令修饰符(Directive Modifiers)是 Vue 模板语法中的重要特性,它们以半角句号 . 开头,用于对指令的绑定行为进行特殊处理 修饰符作用如下: 简化事件处理(如阻止默认行为、停止冒泡…...
Vue.js组件安全工程化演进:从防御体系构建到安全性能融合
——百万级流量场景下的安全组件架构与源码级解决方案 文章目录 总起:安全工程化的组件革命 分论: 一、现存组件架构的七宗罪与安全改造路径 1.1 组件生态安全赤字现状 1.2 架构级安全缺陷深度剖析 1.3 性能与安全的死亡螺旋 二、百万级…...
LINUX基础 [二] - Linux常见指令
目录 💻前言 💻指令 🎮ls指令 🎮pwd指令 🎮whoami指令 🎮cd指令 🎮clear指令 🎮touch指令 🎮mkdir指令 🎮rmdir指令 🎮rm指令 &#…...
Linux进阶命令
目录 一、touch 1. 基本语法 2. 常用选项 二、which 1. 基本语法 2. 主要功能 3. 常用选项 三、find 1. 基本语法 2. 常用选项和表达式 四、more 1. 基本语法 2. 常用操作 3. 对比 more 和 less 五、grep 1. 基本语法 2. 常用选项 六、wc 1. 基本语法 2. 常…...
【Spring Boot 过滤器】
文章目录 前言一、什么是过滤器 Filter?二、Spring Boot 中使用 Filter 的方式1. 使用 Component 注解2. 使用 FilterRegistrationBean 显式注册 三、自定义过滤器示例1. 引入必要依赖2. 创建一个自定义 Filter3. 使用 FilterRegistrationBean 显式注册 四、多个 Fi…...
SPI通讯的软硬件NSS SSM SSI
学习自记: 1. NSS(Slave Select,从设备选择) 功能: NSS是SPI通信中用于选择从设备的信号线。主设备通过拉低NSS信号选中某个从设备,使其参与通信。通信结束后,主设备释放NSS&#…...
Java基础:集合List、Map、Set(超详细版)
集合体系概述 Collection常用方法 补充:addAll() Collection的遍历方式 迭代器 增强for(空集合可以,null不可以) lambda 集合对象存储对象原理 遍历方式的区别 List集合 特点、特有方法 遍历方式 (同上)…...
vue+leaflet 区域划分_反向遮罩层
leaflet 区域划分_遮罩层 geojson在线生成器网址:(https://datav.aliyun.com/portal/school/atlas/area_selector) 点击前往阿里云geojson生成器 效果图: 实现下面效果,只需要把addSateLayer函数的调用取消掉就好了. //添加遮罩层代码function addMask() {var latlngs;var fe…...
聊一聊原子操作和弱内存序
1、原子操作概念 在并发编程中,原子操作(Atomic Operation)是实现线程安全的基础机制之一。从宏观上看,原子操作是“不可中断”的单元,但若深入微观层面,其本质是由底层处理器提供的一组特殊指令来保证其原…...
免费送源码:Java+ssm+MySQL 校园二手书销售平台设计与实现 计算机毕业设计原创定制
摘 要 信息化社会内需要与之针对性的信息获取途径,但是途径的扩展基本上为人们所努力的方向,由于站在的角度存在偏差,人们经常能够获得不同类型信息,这也是技术最为难以攻克的课题。针对校园二手书销售平台等问题,对校…...
DAPP实战篇:使用ethersjs连接智能合约并输入地址查询该地址余额
本系列目录 专栏:区块链入门到放弃查看目录-CSDN博客文章浏览阅读400次。为了方便查看将本专栏的所有内容列出目录,按照顺序查看即可。后续也会在此规划一下后续内容,因此如果遇到不能点击的,代表还没有更新。声明:文中所出观点大多数源于笔者多年开发经验所总结,如果你…...
14.【.NET 8 实战--孢子记账--从单体到微服务--转向微服务】--微服务基础工具与技术--CAP
CAP 是一款专为 .NET 生态设计的开源框架,其核心目标是解决微服务中跨服务数据一致性问题。在分布式系统中,传统事务无法跨服务保证数据一致性,CAP 通过本地事务与消息记录绑定,再利用消息中间件(如 RabbitMQ、Kafka 等…...
智能资源管理机制-重传机制
一、发送端资源管理的核心机制 1. 滑动窗口(Sliding Window) 这是TCP协议的核心优化设计: 窗口动态滑动:发送端不需要保留所有已发送的分组,只需维护一个"发送窗口"窗口大小:由接收方通告的接…...
【Linux网络与网络编程】08.传输层协议 UDP
传输层协议负责将数据从发送端传输到接收端。 一、再谈端口号 端口号标识了一个主机上进行通信的不同的应用程序。在 TCP/IP 协议中,用 "源IP","源端口号","目的 IP","目的端口号"&…...
局域网下ESP32-S3 LED灯的UDP控制
在局域网下通过IP地址控制ESP32-S3上的LED,可以使用UDP或TCP协议。以下是一个基于UDP协议的完整示例,包括ESP32-S3的服务器代码和一个简单的Python客户端代码。 ESP32-S3 服务器代码 import socket import time import network import machineled Non…...
call、bind、apply
call、bind、apply它们三个都是函数的方法,都可以用于改变this的指向问题。 var person "liangxiao" let obj {name:"张三",say:function() {console.log(this.name);} }obj.say(); setTimeout(function() {obj.say(); },1000) obj.say()打…...
Redis 哨兵模式 搭建
1 . 哨兵模式拓扑 与 简介 本文介绍如何搭建 单主双从 多哨兵模式的搭建 哨兵有12个作用 。通过发送命令,让Redis服务器返回监控其运行状态,包括主服务器和从服务器。 当哨兵监测到master宕机,会自动将slave切换成master,然后通过…...
客户端负载均衡与服务器端负载均衡详解
客户端负载均衡与服务器端负载均衡详解 1. 客户端负载均衡(Client-Side Load Balancing) 核心概念 定义:负载均衡逻辑在客户端实现,客户端主动选择目标服务实例。典型场景:微服务内部调用(如Spring Cloud…...
Ningx负载均衡
Ningx负载均衡 upstream(上游)配置负载均衡1、weight(加权轮询)2、ip_hash(负载均衡)3、url hash负载均衡4、least_conn(最小连接负载均衡) upstream(上游)配置负载均衡 Nginx负载均衡 参考: nginx从安装…...
头歌软件工程导论UML画图题(基于starUML)
一.结构化分析方法-数据流图 本关卡需要画图的一共有5关,直接将此图画好每关提交一次即可,以下的所有图均以此方法提交 二.面向对象分析之用例图 三.面向对象分析之类图 注意此处创建Class之后,双击Class出现以下选项 点击相应的选项创建属性…...
智能车摄像头开源—9 动态权、模糊PID、速度决策、路径优化
目录 一、前言 二、动态权 1.概述 2.偏差值加动态权 三、模糊PID 四、速度决策 1.曲率计算 2.速度拟合 3.速度控制 五、路径 六、国赛视频 一、前言 在前中期通过识别直道、弯道等元素可进行加减速操作实现速度的控制,可进一步缩减一圈的运行速度ÿ…...
java基础 this和super的介绍
this和super this关键字的用法super关键字的用法this与super的区别和注意事项 this关键字的用法 this是自身的一个对象,代表对象本身,可以理解为:指向对象本身的一个指针 class Person{private String name;private int age;public String …...
《Python星球日记》第25天:Pandas 数据分析
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 订阅专栏:《Python星球日记》 目录 一、引言二、数据分组与聚合1. 分组操…...
C++在Linux上生成动态库并调用接口测试
加减乘除demo代码 项目结构 CPP/ ├── calculator.cpp ├── calculator.h ├── main.cpp 头文件 #ifndef CALCULATOR_H #define CALCULATOR_H#ifdef __cplusplus extern "C" {#endifdouble add(double a, double b);double subtract(double a, double b…...
Cesium.js(6):Cesium相机系统
Camera表示观察场景的视角。通过操作摄像机,可以控制视图的位置、方向和角度。 帮助文档:Camera - Cesium Documentation 1 setView setView 方法允许你指定相机的目标位置和姿态。你可以通过 Cartesian3 对象来指定目标位置,并通过 orien…...
机器学习中的数学(PartⅡ)——线性代数:概述
首先引入代数和线性代数的概念: 在将一些直观的、基于经验或直觉的概念转化为严格的数学或逻辑定义时,一种常用方法是构建一组对象和一组操作这些对象的规则,这就是代数。线性代数是研究向量和某些操作向量的规则。 其次从更广泛的意义上定…...
基于双闭环PID控制器的永磁同步电机控制系统匝间故障Simulink仿真
欢迎微♥关注“电击小子程高兴的MATLAB小屋”获取巨额优惠 1.模型简介 本仿真模型基于MATLAB/Simulink(版本MATLAB 2013Rb)软件。建议采用matlab2013 Rb及以上版本打开。(若需要其他版本可联系代为转换,高于该版本的matlab均可正…...
在51单片机上实现平滑呼吸灯:50us定时器PWM实战指南
在51单片机上实现平滑呼吸灯:50us定时器PWM实战指南 引言 本文将详细介绍如何在51单片机平台上,通过精确的50us定时器中断实现无闪烁的呼吸灯效果。相比常见的125us实现方案,50us定时器能提供更高的PWM频率和更细腻的亮度控制。 硬件设计 基本电路配置 主控芯片:SC92F8…...
asm汇编源代码之CPU型号检测
提供1个子程序: 1. CPU型号检测 CPUTYPE 无输入参数,返回值AX指示CPU类型(报歉,当时最新CPU型号只有80486) 函数的返回值详细描述如下 CPUTYPE PROC FAR ;OUT: AX01, 8086; AX02, 80286; AX03, 80386; AX04, 80486 UP; ; more source code at http://www.ahj…...
提高课:数据结构之树状数组
1,楼兰图腾 #include<iostream> #include<cstring> #include<cstdio> #include<algorithm>using namespace std;typedef long long LL;const int N 200010;int n; int a[N]; int tr[N]; int Greater[N], lower[N];int lowbit(int x) {ret…...
python可变对象与不可变对象
文章目录 Python 中的可变对象与不可变对象不可变对象(Immutable Objects)可变对象(Mutable Objects)重要区别 Python 中的可变对象与不可变对象 在 Python 中,对象可以分为可变对象(mutable)和不可变对象(immutable),这是 Python 中非常重要的概念&…...
C++学习之金融类安全传输平台项目git
目录 1.知识点概述 2.版本控制工具作用 3.git和SVN 4.git介绍 5.git安装 6.工作区 暂存区 版本库概念 7.本地文件添加到暂存区和提交到版本库 8.文件的修改和还原 9.查看提交的历史版本信息 10.版本差异比较 11.删除文件 12.本地版本管理设置忽略目录 13.远程git仓…...
果篮问题 Python
# 给你两个长度为 n 的整数数组,fruits 和 baskets,其中 fruits[i] 表示第 i 种水果的 数量,baskets[j] 表示第 j 个篮子的 容量。 # 你需要对 fruits 数组从左到右按照以下规则放置水果: # 每种水果必须放入第一个 容量大于等于 …...
Spring 是如何解决循环依赖的?
在使用 Spring 框架进行开发时,循环依赖是一个常见而棘手的问题。循环依赖指的是两个或多个 bean 之间的相互依赖,导致 Spring 容器无法正常创建这些 bean。下面将深入探讨 Spring 如何解决循环依赖问题,并提供一些最佳实践。 什么是循环依赖…...
部署NFS版StorageClass(存储类)
部署NFS版StorageClass存储类 NFS版PV动态供给StorageClass(存储类)基于NFS实现动态供应下载NFS存储类资源清单部署NFS服务器为StorageClass(存储类)创建所需的RBAC部署nfs-client-provisioner的deployment创建StorageClass使用存储类创建PVC NFS版PV动态供给StorageClass(存储…...
深入理解 PyTorch 的 nn.Embedding:词向量映射及变量 weight 的更新机制
文章目录 前言一、直接使用 nn.Embedding 获得变量1、典型场景2、示例代码:3、特点 二、使用 iou_token nn.Embedding(1, transformer_dim) 并访问 iou_token.weight1、典型场景2、示例代码:3、特点 三、第一种方法在模型更新中会更新其值吗?…...
go语言内存泄漏的常见形式
go语言内存泄漏 子字符串导致的内存泄漏 使用自动垃圾回收的语言进行编程时,通常我们无需担心内存泄漏的问题,因为运行时会定期回收未使用的内存。但是如果你以为这样就完事大吉了,哪里就大错特措了。 因为,虽然go中并未对字符串…...
操作系统
操作系统 操作系统(OperatingSystem,OS)是指控制和管理整个计算机系统的硬件和软件资源,并合理地组织调度计算机的工作和资源的分配;以提供给用户和其他软件方便的接口和环境;它是计算机系统中最基本的系统…...
《JVM考古现场(十八):造化玉碟·用字节码重写因果律的九种方法》
"鸿蒙初判!当前因果链突破十一维屏障——全体码农修士注意,《JVM考古现场(十八)》即将渡劫飞升!" 目录 上卷阴阳交缠 第一章:混沌初开——JVM因果律的量子纠缠 第二章:诛仙剑阵改—…...
【2】k8s集群管理系列--包应用管理器之helm(Chart语法深入应用)
一、Chart模板:函数与管道 常用函数: • quote:将值转换为字符串,即加双引号 • default:设置默认值,如果获取的值为空则为默认值 • indent和nindent:缩进字符串 • toYaml:引用一…...
汇编获取二进制
mov_.S mov %r8d,0 nop执行命令: gcc -c mov_.S 会输出 mov_.o 文件:objdump -D mov_.o : mov_.o: 文件格式 elf64-x86-64Disassembly of section .text:0000000000000000 <.text>:0: 44 89 04 25 00 00 00 mov %r8d,0x0…...
《嵌套调用与链式访问:C语言中的函数调用技巧》
🚀个人主页:BabyZZの秘密日记 📖收入专栏:C语言 🌍文章目入 一、嵌套调用(一)定义(二)实现方式(三)优点(四)缺点 二、链式…...
txt、Csv、Excel、JSON、SQL文件读取(Python)
txt、Csv、Excel、JSON、SQL文件读取(Python) txt文件读写 创建一个txt文件 fopen(rtext.txt,r,encodingutf-8) sf.read() f.close() print(s)open( )是打开文件的方法 text.txt’文件名 在同一个文件夹下所以可以省略路径 如果不在同一个文件夹下 ‘…...
前端工程化之新晋打包工具
新晋打包工具 新晋打包工具前端模块工具的发展历程分类初版构建工具grunt使用场景 gulp采用管道机制任务化配置与api简洁 现代打包构建工具基石--webpack基于webpack改进的构建工具rollup 推荐举例说明package.jsonrollup.config.mjsmy-extract-css-rollup-plugin.mjssrc/index…...
Python语言介绍
Python 是一种高级、通用、解释型的编程语言,由 Guido van Rossum 于 1991 年首次发布。其设计哲学强调代码的可读性和简洁性。 Python通过简洁的语法和强大的生态系统,成为当今最受欢迎的编程语言之一。 一、核心特点 Python 是一种解释型、面向对象、…...
关于 Spring Boot 部署到 Docker 容器的详细说明,涵盖核心概念、配置步骤及关键命令,并附上表格总结
以下是关于 Spring Boot 部署到 Docker 容器的详细说明,涵盖核心概念、配置步骤及关键命令,并附上表格总结: 1. Docker 核心概念 概念描述关系镜像(Image)预定义的只读模板,包含运行环境和配置(…...
Tomcat 服务频繁崩溃的排查方法
# Tomcat 服务频繁崩溃排查方法 当Tomcat服务频繁崩溃时,可以按照以下步骤进行系统化排查: ## 1. 检查日志文件 **关键日志位置**: - catalina.out (标准输出和错误) - catalina.log (主日志) - localhost.log (应用相关日志) - host-mana…...