YAML如何操作Kubernetes核心对象

Pod

Kubernetes 最核心对象Pod

Pod 是对容器的“打包”,里面的容器多个容器)是一个整体,总是能够一起调度、一起运行,绝不会出现分离的情况,而且 Pod 属于 Kubernetes,可以在不触碰下层容器的情况下任意定制修改。

Kubernetes 让 Pod 去编排处理容器,然后把 Pod 作为应用调度部署的最小单位。

以 Pod 为中心的 Kubernetes 资源对象关系图:

在这里插入图片描述

如何使用 YAML 描述 Pod

下面这段 YAML 代码就描述了一个简单的 Pod,名字是“busy-pod”,再附加上一些标签:

apiVersion: v1
kind: Pod
metadata:
  name: busy-pod
  labels:
    owner: chrono
    env: demo
    region: north
    tier: back
spec:
  containers:
  - image: busybox:latest
    name: busy
    imagePullPolicy: IfNotPresent
    env:
      - name: os
        value: "ubuntu"
      - name: debug
        value: "on"
    command:
      - /bin/echo
    args:
      - "$(os), $(debug)"

“containers”是一个数组,里面的每一个元素又是一个 container 对象,也就是容器。

和 Pod 一样,container 对象也必须要有一个 name 表示名字,然后当然还要有一个 image 字段来说明它使用的镜像,这两个字段是必须要有的,否则 Kubernetes 会报告数据验证错误。

container 对象的其他字段

  • ports:列出容器对外暴露的端口,和 Docker 的 -p 参数有点像。
  • imagePullPolicy:指定镜像的拉取策略,可以是
  • Always/Never/IfNotPresent,一般默认是 IfNotPresent,也就是说只有本地不存在才会远程拉取镜像,可以减少网络消耗。
  • env:定义 Pod 的环境变量,和 Dockerfile 里的 ENV 指令有点类似,但它是运行时指定的,更加灵活可配置。
  • command:定义容器启动时要执行的命令,相当于 Dockerfile 里的 ENTRYPOINT 指令。
  • args:它是 command 运行时的参数,相当于 Dockerfile 里的 CMD 指令,这两个命令和 Docker 的含义不同,要特别注意。

如何使用 kubectl 操作 Pod

  • kubectl apply、kubectl delete 这两个命令,它们可以使用 -f 参数指定 YAML 文件创建或者删除 Pod,例如:
kubectl apply -f busy-pod.yml
kubectl delete -f busy-pod.yml
  • 如果在 YAML 里定义了“name”字段,也可以在删除的时候直接指定名字来删除:
kubectl delete pod busy-pod
  • 使用命令 kubectl get pod 可以查看 Pod 列表和运行状态:
kubectl get pod

Kubernetes 的 Pod 不会在前台运行,只能在后台(相当于默认使用了参数 -d),所以输出信息不能直接看到。

  • 可以用命令 kubectl logs,它会把 Pod 的标准输出流信息展示出来,在这里就会显示出预设的两个环境变量的值:
kubectl logs busy-pod

在这里插入图片描述
这个 Pod 运行有点不正常,状态是“CrashLoopBackOff

可以使用命令 kubectl describe 来检查它的详细状态,它在调试排错时很有用:

kubectl describe pod busy-pod

在这里插入图片描述
需要关注的是末尾的“Events”部分,它显示的是 Pod 运行过程中的一些关键节点事件。

对于这个 busy-pod,因为它只执行了一条 echo 命令就退出了,而 Kubernetes 默认会重启 Pod,所以就会进入一个反复停止 - 启动的循环错误状态。因为 Kubernetes 里运行的应用大部分都是不会主动退出的服务,所以我们可以把这个 busy-pod 删掉

在这里插入图片描述

kubectl 也提供与 docker 类似的 cp 和 exec 命令,kubectl cp 可以把本地文件拷贝进 Pod,kubectl exec 是进入 Pod 内部执行 Shell 命令,用法也差不多。

  • 启动一个之前的nginx pod试验一下
#启动nginx pod
kubectl apply -f ngx-pod.yml
#查看状态
kubectl get pod 
#查看日志
kubectl logs
  • 将一个“a.txt”文件,那么就可以使用 kubectl cp 拷贝进 Pod 的“/tmp”目录里
echo 'aaa' > a.txt
kubectl cp a.txt ngx-pod:/tmp

在这里插入图片描述

  • kubectl exec 的命令格式与 Docker 有一点小差异,需要在 Pod 后面加上 --,把 kubectl 的命令与 Shell 命令分隔开,在用的时候需要小心一些:
kubectl exec -it ngx-pod -- sh

在这里插入图片描述

Job/CronJob

为什么要有 Job/CronJob

前面文章中运行了两个 Pod:Nginxbusybox,它们分别代表了 Kubernetes 里的两大类业务。

  • 一类是像 Nginx 这样长时间运行的“在线业务”,“在线业务”类型的应用有很多,比如 Nginx、Node.js、MySQL、Redis 等等,一旦运行起来基本上不会停,也就是永远在线。

  • 另一类是像 busybox 这样短时间运行的“离线业务”,离线业务”的特点是必定会退出,不会无期限地运行下去,所以它的调度策略也就与“在线业务”存在很大的不同,需要考虑运行超时、状态检查、失败重试、获取计算结果等管理事项。

  • “离线业务”也可以分为两种。一种是“临时任务”,跑完就完事了,下次有需求了说一声再重新安排;另一种是“定时任务”,可以按时按点周期运行,不需要过多干预。

  • 对应到 Kubernetes 里,“临时任务”就是 API 对象 Job,“定时任务”就是 API 对象 CronJob,使用这两个对象就能够在 Kubernetes 里调度管理任意的离线业务了。

如何使用 YAML 描述 Job

使用命令 kubectl explain job 来看它的字段说明。

kubectl explain job

在这里插入图片描述
注意

  • apiVersion 不是 v1,而是 batch/v1。
  • kind 是 Job,这个和对象的名字是一致的。
  • metadata 里仍然要有 name 标记名字,也可以用 labels 添加任意的标签。

生成 YAML 样板文件的话不能使用 kubectl run,因为 kubectl run 只能创建 Pod,要创建 Pod 以外的其他 API 对象,需要使用命令 kubectl create,再加上对象的类型名。

export out="--dry-run=client -o yaml"              # 定义Shell变量
kubectl create job echo-job --image=busybox $out

在这里插入图片描述

--生成到指定文件中
kubectl create job echo-job --image=busybox $out > echo-job.yml

在这里插入图片描述
在这里插入图片描述

稍微修改后的Job 对象:

apiVersion: batch/v1
kind: Job
metadata:
  name: echo-job

spec:
  template:
    spec:
      restartPolicy: OnFailure
      containers:
      - image: busybox
        name: echo-job
        imagePullPolicy: IfNotPresent
        command: ["/bin/echo"]
        args: ["hello", "world"]
  • Job 的描述与 Pod 很像,但又有些不一样,主要的区别就在“spec”字段里,多了一个 template 字段,然后又是一个“spec”,显得有点怪。

  • 它其实就是在 Job 对象里应用了组合模式,template 字段定义了一个“应用模板”,里面嵌入了一个 Pod,这样 Job 就可以从这个模板来创建出 Pod。

  • 而这个 Pod 因为受 Job 的管理控制,不直接和 apiserver 打交道,也就没必要重复 apiVersion 等“头字段”,只需要定义好关键的 spec,描述清楚容器相关的信息就可以了,可以说是一个“无头”的 Pod 对象。

在这里插入图片描述

  • 这里的 Pod 工作非常简单,在 containers 里写好名字和镜像,command 执行 /bin/echo,输出“hello world”。

  • 因为 Job 业务的特殊性,所以我们还要在 spec 里多加一个字段 restartPolicy,确定 Pod 运行失败时的策略,OnFailure 是失败原地重启容器,而 Never 则是不重启容器,让 Job 去重新调度生成一个新的 Pod。

如何在 Kubernetes 里操作 Job

创建 Job 对象,运行这个简单的离线作业

kubectl apply -f echo-job.yml

在这里插入图片描述
注意如果 job已经创建了,然后再执行 kubectl apply -f echo-job.yml,会报如下错误:
在这里插入图片描述
如过想要重新建立一个新job,需要删除现有的作业,并使用新的配置重新创建它

kubectl delete job echo-job 

这是因为在 Kubernetes 中,一旦资源(如 Pod 或 Job)被创建,其某些字段通常是不可变的,不能在更新时进行修改。因此,您需要确保在更新资源时不会修改这些不可变字段。

创建之后 Kubernetes 就会从 YAML 的模板定义中提取 Pod,在 Job 的控制下运行 Pod,你可以用 kubectl get job、kubectl get pod 来分别查看 Job 和 Pod 的状态:

kubectl get job
kubectl get pod

在这里插入图片描述

  • 因为 Pod 被 Job 管理,它就不会反复重启报错了,而是会显示为 Completed 表示任务完成,而 Job 里也会列出运行成功的作业数量,这里只有一个作业,所以就是 1/1。

  • 还可以看到,Pod 被自动关联了一个名字,用的是 Job 的名字(echo-job)再加上一个随机字符串(nkk7x),这当然也是 Job 管理的“功劳”,免去了我们手工定义的麻烦

控制离线作业的几个重要字段,其他更详细的信息可以参考 Job 文档:

  • activeDeadlineSeconds,设置 Pod 运行的超时时间。
  • backoffLimit,设置 Pod 的失败重试次数。
  • completions,Job 完成需要运行多少个 Pod,默认是 1 个。* parallelism,它与 completions 相关,表示允许并发运行的 Pod 数量,避免过多占用资源。

要注意这 4 个字段并不在 template 字段下,而是在 spec 字段下,所以它们是属于 Job 级别的,用来控制模板里的 Pod 对象。

下面再创建一个 Job 对象,名字叫“sleep-job”,它随机睡眠一段时间再退出,模拟运行时间较长的作业(比如 MapReduce)。Job 的参数设置成 15 秒超时,最多重试 2 次,总共需要运行完 4 个 Pod,但同一时刻最多并发 2 个 Pod:

apiVersion: batch/v1
kind: Job
metadata:
  name: sleep-job

spec:
  activeDeadlineSeconds: 15
  backoffLimit: 2
  completions: 4
  parallelism: 2

  template:
    spec:
      restartPolicy: OnFailure
      containers:
      - image: busybox
        name: echo-job
        imagePullPolicy: IfNotPresent
        command:
          - sh
          - -c
          - sleep $(($RANDOM % 10 + 1)) && echo done

使用 kubectl apply 创建 Job 之后,我们可以用 kubectl get pod -w 来实时观察 Pod 的状态,看到 Pod 不断被排队、创建、运行的过程:

kubectl apply -f sleep-job.yml 
kubectl get pod -w


在这里插入图片描述
到 4 个 Pod 都运行完毕,我们再用 kubectl get 来看看 Job 和 Pod 的状态:
在这里插入图片描述

如何使用 YAML 描述 CronJob

直接使用命令 kubectl create 来创建 CronJob 的样板

  • 因为 CronJob 的名字有点长,所以 Kubernetes 提供了简写 cj,这个简写也可以使用命令 kubectl api-resources 看到;

  • CronJob 需要定时运行,所以我们在命令行里还需要指定参数 --schedule。

export out="--dry-run=client -o yaml"              # 定义Shell变量
kubectl create cj echo-cj --image=busybox --schedule="" $out

$out的有效时间为当前会话窗口
在这里插入图片描述
编辑这个 YAML 样板,生成 CronJob 对象:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: echo-cj

spec:
  schedule: '*/1 * * * *'
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          containers:
          - image: busybox
            name: echo-cj
            imagePullPolicy: IfNotPresent
            command: ["/bin/echo"]
            args: ["hello", "world"]

重点关注它的 spec 字段,会发现它居然连续有三个 spec 嵌套层次:

  • 第一个 spec 是 CronJob 自己的对象规格声明
  • 第二个 spec 从属于“jobTemplate”,它定义了一个 Job 对象。
  • 第三个 spec 从属于“template”,它定义了 Job 里运行的 Pod。

CronJob 其实是又组合了 Job 而生成的新对象
在这里插入图片描述
除了定义 Job 对象的“jobTemplate”字段之外,CronJob 还有一个新字段就是“schedule”,用来定义任务周期运行的规则。

它使用的是标准的 Cron 语法,指定分钟、小时、天、月、周,和 Linux 上的 crontab 是一样的。像在这里我就指定每分钟运行一次,格式具体的含义你可以课后参考 Kubernetes 官网文档。

除了名字不同,CronJob 和 Job 的用法几乎是一样的,使用 kubectl apply 创建 CronJob,使用 kubectl get cj、kubectl get pod 来查看状态:

kubectl apply -f cronjob.yml
kubectl get cj
kubectl get pod

在这里插入图片描述
删除coreJob

kubectl delete -f schedule-job.yml 

在这里插入图片描述

ConfigMap/Secret

应用程序有很多类别的配置信息,但从数据安全的角度来看可以分成两类:

  • 一类是明文配置,也就是不保密,可以任意查询修改,比如服务端口、运行参数、文件路径等等。
  • 另一类则是机密配置,由于涉及敏感信息需要保密,不能随便查看,比如密码、密钥、证书等等。

这两类配置信息本质上都是字符串,只是由于安全性的原因,在存放和使用方面有些差异,所以 Kubernetes 也就定义了两个 API 对象,ConfigMap 用来保存明文配置,Secret 用来保存秘密配置。

ConfigMap

用命令 kubectl create 来创建一个它的 YAML 样板。注意,它有简写名字“cm”,所以命令行里没必要写出它的全称:

export out="--dry-run=client -o yaml"        # 定义Shell变量
kubectl create cm info $out

在这里插入图片描述
样板文件:

apiVersion: v1
kind: ConfigMap
metadata:
  name: info

因为 ConfigMap 存储的是配置数据,是静态的字符串,并不是容器,所以它们就不需要用“spec”字段来说明运行时的“规格”。既然 ConfigMap 要存储数据,我们就需要用另一个含义更明确的字段“data”。

要生成带有“data”字段的 YAML 样板,你需要在 kubectl create 后面多加一个参数 --from-literal ,表示从字面值生成一些数据:

kubectl create cm info --from-literal=k=v $out

注意,因为在 ConfigMap 里的数据都是 Key-Value 结构,所以 --from-literal 参数需要使用 k=v 的形式。

在这里插入图片描述
把 YAML 样板文件修改一下,再多增添一些 Key-Value,就得到了一个比较完整的 ConfigMap 对象:

apiVersion: v1
kind: ConfigMap
metadata:
  name: info

data:
  count: '10'
  debug: 'on'
  path: '/etc/systemd'
  greeting: |
    say hello to kubernetes.

创建cm.yml文件,把上述配置cv到cm.yml中

touch cm.yml
vim cm.yml

在这里插入图片描述
使用 kubectl apply 把这个 YAML 交给 Kubernetes,让它创建 ConfigMap 对象了:

kubectl apply -f cm.yml

创建成功后,我们还是可以用 kubectl get、kubectl describe 来查看 ConfigMap 的状态:

kubectl get cm
kubectl describe cm info

在这里插入图片描述
可以看到,现在 ConfigMap 的 Key-Value 信息就已经存入了 etcd 数据库,后续就可以被其他 API 对象使用。

Secret

创建 YAML 样板的命令是 kubectl create secret generic ,同样,也要使用参数 --from-literal 给出 Key-Value 值:

kubectl create secret generic user --from-literal=name=root $out

在这里插入图片描述
Secret 对象:

apiVersion: v1
kind: Secret
metadata:
  name: user

data:
  name: cm9vdA==

“name”事做了 Base64 编码,根本算不上真正的加密,所以可以绕开 kubectl,可以用 Linux 小工具“base64”来对数据编码,然后写入 YAML 文件,比如:

echo -n "root" | base64
cm9vdA==

要注意这条命令里的 echo ,必须要加参数 -n 去掉字符串里隐含的换行符,否则 Base64 编码出来的字符串就是错误的

编辑 Secret 的 YAML,为它添加两个新的数据,方式可以是参数 --from-literal 自动编码,也可以是手动编码:

apiVersion: v1
kind: Secret
metadata:
  name: user

data:
  name: cm9vdA==  # root
  pwd: MTIzNDU2   # 123456
  db: bXlzcWw=    # mysql

创建和查看对象操作,使用 kubectl apply、kubectl get、kubectl describe:

kubectl apply  -f secret.yml
kubectl get secret
kubectl describe secret user

在这里插入图片描述
因为存储敏感信息的 Secret 对象是保密的,使用 kubectl describe 不能直接看到内容,只能看到数据的大小

Kubernetes使用ConfigMap/Secret

因为 ConfigMap 和 Secret 只是一些存储在 etcd 里的字符串,所以如果想要在运行时产生效果,就必须要以某种方式“注入”到 Pod 里,让应用去读取。

在这方面的处理上 Kubernetes 和 Docker 是一样的,也是两种途径:环境变量和加载文件。

环境变量方式使用 ConfigMap/Secret

Pod中描述容器的字段“containers”里有一个“env”,它定义了 Pod 里容器能够看到的环境变量。

当时使用了简单的“value”,把环境变量的值写“死”在了 YAML 里,实际上它还可以使用另一个“valueFrom”字段,从 ConfigMap 或者 Secret 对象里获取值,这样就实现了把配置信息以环境变量的形式注入进 Pod,也就是配置与应用的解耦。

由于“valueFrom”字段在 YAML 里的嵌套层次比较深,初次使用最好看一下 kubectl explain 对它的说明:

kubectl explain pod.spec.containers.env.valueFrom

在这里插入图片描述
valueFrom”字段指定了环境变量值的来源,可以是“configMapKeyRef”或者“secretKeyRef”,然后再进一步指定应用的 ConfigMap/Secret 的“name”和它里面的“key”,要当心的是这个“name”字段是 API 对象的名字,而不是 Key-Value 的名字。

引用了 ConfigMap 和 Secret 对象的 Pod 如下,为了醒目,把“env”字段提到了前面:

apiVersion: v1
kind: Pod
metadata:
  name: env-pod

spec:
  containers:
  - env:
      - name: COUNT
        valueFrom:
          configMapKeyRef:
            name: info
            key: count
      - name: GREETING
        valueFrom:
          configMapKeyRef:
            name: info
            key: greeting
      - name: USERNAME
        valueFrom:
          secretKeyRef:
            name: user
            key: name
      - name: PASSWORD
        valueFrom:
          secretKeyRef:
            name: user
            key: pwd

    image: busybox
    name: busy
    imagePullPolicy: IfNotPresent
    command: ["/bin/sleep", "300"]

创建env-pod.yml
在这里插入图片描述

  • 这个 Pod 的名字是“env-pod”,镜像是“busybox”,执行命令 sleep 睡眠 300 秒,可以在这段时间里使用命令 kubectl exec 进入 Pod 观察环境变量。

  • 需要重点关注的是它的“env”字段,里面定义了 4 个环境变量,COUNT、GREETING、USERNAME、PASSWORD。

  • 对于明文配置数据, COUNT、GREETING 引用的是 ConfigMap 对象,所以使用字段“configMapKeyRef”,里面的“name”是 ConfigMap 对象的名字,也就是之前我们创建的“info”,而“key”字段分别是“info”对象里的 count 和 greeting。

  • 同样的对于机密配置数据, USERNAME、PASSWORD 引用的是 Secret 对象,要使用字段“secretKeyRef”,再用“name”指定 Secret 对象的名字 user,用“key”字段应用它里面的 name 和 pwd 。
    在这里插入图片描述

  • 从这张图你就应该能够比较清楚地看出 Pod 与 ConfigMap、Secret 的“松耦合”关系,它们不是直接嵌套包含,而是使用“KeyRef”字段间接引用对象,这样,同一段配置信息就可以在不同的对象之间共享。

弄清楚了环境变量的注入方式之后,让我们用 kubectl apply 创建 Pod,再用 kubectl exec 进入 Pod,验证环境变量是否生效:

kubectl apply -f env-pod.yml
kubectl exec -it env-pod -- sh

echo $COUNT
echo $GREETING
echo $USERNAME $PASSWORD

在这里插入图片描述

以 Volume 的方式使用 ConfigMap/Secret

Kubernetes 为 Pod 定义了一个“Volume”的概念,可以翻译成是“存储卷”。如果把 Pod 理解成是一个虚拟机,那么 Volume 就相当于是虚拟机里的磁盘。

可以为 Pod“挂载(mount)”多个 Volume,里面存放供 Pod 访问的数据,这种方式有点类似 docker run -v,虽然用法复杂了一些,但功能也相应强大一些。

在 Pod 里挂载 Volume 很容易,只需要在“spec”里增加一个“volumes”字段,然后再定义卷的名字和引用的 ConfigMap/Secret 就可以了。要注意的是 Volume 属于 Pod,不属于容器,所以它和字段“containers”是同级的,都属于“spec”。

下面定义两个 Volume,分别引用 ConfigMap 和 Secret,名字是 cm-vol 和 sec-vol:

spec:
  volumes:
  - name: cm-vol
    configMap:
      name: info
  - name: sec-vol
    secret:
      secretName: user

Volume 的定义之后,就可以在容器里挂载了,这要用到“volumeMounts”字段,正如它的字面含义,可以把定义好的 Volume 挂载到容器里的某个路径下,所以需要在里面用“mountPath”“name”明确地指定挂载路径和 Volume 的名字。

  containers:
  - volumeMounts:
    - mountPath: /tmp/cm-items
      name: cm-vol
    - mountPath: /tmp/sec-items
      name: sec-vol

引用关系如下:
在这里插入图片描述
挂载 Volume 的方式和环境变量又不太相同。环境变量是直接引用了 ConfigMap/Secret,而 Volume 又多加了一个环节,需要先用 Volume 引用 ConfigMap/Secret,然后在容器里挂载 Volume,有点“兜圈子”“弯弯绕”。

这种方式的好处在于:以 Volume 的概念统一抽象了所有的存储,不仅现在支持 ConfigMap/Secret,以后还能够支持临时卷、持久卷、动态卷、快照卷等许多形式的存储,扩展性非常好。

Pod 的完整 YAML 描述如下:

apiVersion: v1
kind: Pod
metadata:
  name: vol-pod

spec:
  volumes:
  - name: cm-vol
    configMap:
      name: info
  - name: sec-vol
    secret:
      secretName: user

  containers:
  - volumeMounts:
    - mountPath: /tmp/cm-items
      name: cm-vol
    - mountPath: /tmp/sec-items
      name: sec-vol

    image: busybox
    name: busy
    imagePullPolicy: IfNotPresent
    command: ["/bin/sleep", "300"]

在这里插入图片描述
执行如下命令:

kubectl apply -f vol-pod.yml
kubectl get pod
kubectl exec -it vol-pod -- sh

在这里插入图片描述
ConfigMap 和 Secret 都变成了目录的形式,而它们里面的 Key-Value 变成了一个个的文件,而文件名就是 Key。

因为这种形式上的差异,以 Volume 的方式来使用 ConfigMap/Secret,就和环境变量不太一样。环境变量用法简单,更适合存放简短的字符串,而 Volume 更适合存放大数据量的配置文件,在 Pod 里加载成文件后让应用直接读取使用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/595351.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

存储或读取时转换JSON数据

一、 数据库类型 二、使用Hutool工具 存储时将数据转换为JSON数据 获取时将JSON数据转换为对象 发现问题: 原本数据对象是Address 和 Firend但是转换完成后数据变成了JSONArray和JSONObject 三、自定义TypeHandler继承Mybatis的BaseTypeHandler处理器 package …

Feign 和 OpenFeign 的区别

Feign 和 OpenFeign 都是用来进行服务间调用的客户端库,它们旨在简化HTTP API客户端的编写过程,使得编写对外部服务的接口就像调用本地方法一样简单。尽管它们有相似之处,但也存在一些关键差异: 归属和演进: Feign 最初…

硬件设计计划与APQP

硬件设计的关键节点: 大的里程碑milestone分为: Kickoff->A Samples->做出第一批B样总成件->B Samples/OTS->C Samples->PPAP->SOP 具体到硬件,A/B/C sample阶段,又可细分为: 关键器件选型&硬件系统方案设计原理图绘制PCB LayoutA_BOM输出PCB制板…

3. 深度学习笔记--优化函数

深度学习——优化器算法Optimizer详解(BGD、SGD、MBGD、Momentum、Adagrad、Adadelta、RMSprop、Adam、Nadam、AdaMax、AdamW ) 0. GD (梯度下降) Gradient Descent(梯度下降)是一种迭代优化算法&#xf…

FreeRTOS内存管理(1-20)

FreeRTOS内存管理简介 在使用FreeRTOS创建任务,队列,信号量等对象时,一般都提供两种方法 1:动态创建任务(方法)自动地从FreeRTOS管理的内存堆中申请创建对象所需要的内存,并且在删除对象后可以…

九州金榜|孩子沉迷于网络:家庭教育的挑战与对策

随着时代的进步,科技的发展,网络现在成为了我们日常生活不可分割的一部分。然而,随着网络的普及也出现了一些列的问题,其中孩子沉迷于网络就是当前家长最为关心的问题,对于这种情况的发生,家庭教育就显得尤…

Linux主机重启后报错:[FAILED] Failed to start Switch Root.

一、问题描述 某次云主机因计费问题,导致批量重启,重启后发现某台云主机竟进入紧急救援模式(emergency模式),如下所示: 二、原因及处理 1)原因:加载根分区失败,导致无…

Libcity笔记:原子文件

1 介绍 Libcity中的数据以原子文件的形式存在 2 原子文件类别 对于不同的交通预测任务,可能用到不同的原子文件,同一个数据集不一定包含全部六种原子文件 网格数据需要按照先行后列的顺序遍历OD数据需要按照先起点后终点的顺序遍历 2.1 geo 存储地理…

Netty 实现dubbo rpc

一、RPC 的基本介绍 RPC (Remote Procedure Call) 远程过程调用,是一个计算机通信协议。该协议允许运行于一台计算机的程序调用另一台计算机的子程序,而程序员无需额外的为这个交互编程。也就是说可以达到两个或者多个应用程序部署在不同的服务器上&…

OpenCV 入门(七)—— 身份证识别

OpenCV 入门系列: OpenCV 入门(一)—— OpenCV 基础 OpenCV 入门(二)—— 车牌定位 OpenCV 入门(三)—— 车牌筛选 OpenCV 入门(四)—— 车牌号识别 OpenCV 入门&#xf…

德国韦纳WENAROLL滚压刀,液压缸,滚光刀,挤压刀,滚轧刀

德国韦纳WENAROLL滚压刀,液压缸,滚光刀,挤压刀,滚轧刀(百度一下,西安尚融) 德国韦纳(WENAROLL)的滚压刀、液压缸、滚光刀、挤压刀和滚轧刀在工业领域享有很高的声誉,这些产品因其高…

SM618卡件SM480模块和利时

SM618卡件❗电:183-6998-1851❗SM480模块和利时。自动化程度的提高,I/O点数大幅增 加,传统单一配线的方式已经无法满足发展的需 要SM618卡件SM480模块和利时。.对简单、可靠的配线方式的需求日益强烈. 传统接线 - 以并联方式连 接…

C# WinForm —— 12 ListBox绑定数据

ListBox加载大量数据时,避免窗体闪烁的方法: 在加载语句的前后分别加上 BeginUpdate()方法 和 EndUpdate()方法 指定一个集合为绑定的数据源 1. 首先,右键项目,添加类 2. 在新建的类文件中添加属性值信息 3. 构建初始化的对象…

访问学者在外访学期间,是否可以中途回国?

在全球化的今天,访问学者制度已成为促进国际学术交流与合作的重要桥梁。然而,对于许多国外访问学者来说,一个常见的问题是:在访学期间,我是否可以中途回国?这个问题涉及到多个方面,包括政策法规…

7步教程从零开始搭建跨境电商平台开发

跨境电商平台开发一直是创业者们追逐的热门领域之一。本文将为您提供一个7步教程,帮助您从零开始搭建跨境电商平台,让您在这个充满机遇的领域中抢占先机。 步骤一:市场调研和定位 在开始搭建跨境电商平台之前,第一步是进行充分的…

大数据与会计专业主要学什么课程

大数据与会计专业是一个结合了传统会计知识与现代大数据技术的交叉学科,旨在培养既懂会计又熟悉大数据分析的复合型人才。该专业的学生将会学习以下主要课程内容: 会计基础课程:包括基础会计、财务会计、成本会计、管理会计等,这些…

我独自升级崛起下载教程 我独自升级崛起怎么一键下载

定于5月8日全球盛大发布的动作RPG力作《我独自升级崛起》,基于备受追捧的同名动画及网络漫画,誓为热情洋溢的游戏爱好者们呈献一场深度与广度兼具的冒险盛宴。这款游戏巧妙融合网络武侠元素,其创意十足的设计框架下,核心叙述聚焦于…

OSPF综合实验(超详细易懂)(HCIP)

1、拓扑信息 2、需求分析 3、IP规划 4、配置 5、测试 1、拓扑信息 2、需求分析 R4为ISP,其上只能配置I地址; R4与其他所有直连设备间均使用公有IP 公网中使用的是点到…

外贸大客户开发的三大困境

外贸大客户开发的三大困境,第一个是进不来,什么叫进不来呢?就是客户,大客户他不仅能够为企业带来大额的业绩,而且利润也高,那么也对于这种品牌也有一定的关联,还能为企业带来更多的一些资源&…

Python测试框架Pytest的参数化详解

上篇博文介绍过,Pytest是目前比较成熟功能齐全的测试框架,使用率肯定也不断攀升。 在实际工作中,许多测试用例都是类似的重复,一个个写最后代码会显得很冗余。这里,我们来了解一下pytest.mark.parametrize装饰器&…