【云原生】K8s PSP 和 securityContext 介绍与使用

news2024/9/28 21:27:27

文章目录

    • 一、概述
    • 二、PodSecurityPolicy 的发展
      • 1)以前为什么需要 PodSecurityPolicy?
      • 2)现在为什么 PodSecurityPolicy 要消失?
    • 三、PSP 简单使用
      • 1)开启PSP
      • 2)示例演示
        • 1、没有PSP场景测试
        • 2、定义PSP
          • 【1】资源限制策略
          • 【2】资源允许策略
        • 3、角色定义(Cluster Role)
        • 4、角色绑定(Cluster Role Bindings)
        • 5、再测试验证
    • 四、PodSecurity admission
      • 1)podSecurity Standards
      • 2)podSecurity admission
      • 3)podSecurity standards 示例演示
        • 1、Baseline 策略
        • 2、Restricted 策略
      • 4)Pod Security admission 当前局限性
    • 五、默认的 securityContext 介绍和使用

一、概述

Pod Security Policies(Adminssion Controller)授予users和service accounts创建或更新pods使用资源的权限。这是一种集群级别的资源类型,用来限制pod对敏感资源的使用。它能够控制Pod的各个安全方面。

举例来说PSP可以做的事情:

  • 是否允许Pod使用宿主节点的PID,IPC,网络命名空间。
  • Pod是否允许绑定到宿主节点端口。
  • 容器运行时允许使用的用户ID。
  • 是否允许特权模式的POD。

【温馨提示】PodSecurityPolicy 在 Kubernetes v1.21 中被弃用, 在 Kubernetes v1.25 中被移除。

作为替代,你可以使用下面任一方式执行类似的限制,或者同时使用下面这两种方式。

  • PodSecurity admission
  • 自行部署并配置第三方插件

官方文档:https://kubernetes.io/zh/docs/concepts/policy/pod-security-policy/
关于 k8s RBAC的介绍,可以参考我这篇文章:Kubernetes(k8s)权限管理RBAC详解

在这里插入图片描述

二、PodSecurityPolicy 的发展

1)以前为什么需要 PodSecurityPolicy?

  • 在 Kubernetes 中,我们定义了 Deployment、StatefulSet 和 Service 等资源。 这些资源代表软件应用程序的构建块。Kubernetes 集群中的各种控制器根据这些资源做出反应, 创建更多的 Kubernetes 资源或配置一些软件或硬件来实现我们的目标。

  • 在大多数 Kubernetes 集群中,由 RBAC(基于角色的访问控制)规则 控制对这些资源的访问。 list、get、create、edit 和 delete 是 RBAC 关心的 API 操作类型, 但 RBAC 不考虑其所控制的资源中加入了哪些设置。例如, Pod 几乎可以是任何东西,例如简单的网络服务器,或者是特权命令提示(提供对底层服务器节点和所有数据的完全访问权限)。 这对 RBAC 来说都是一样的:Pod 就是 Pod 而已。

  • 要控制集群中定义的资源允许哪些类型的设置,除了 RBAC 之外,还需要访问控制。 从 Kubernetes 1.3 开始,内置 PodSecurityPolicy 一直被作为 Pod 安全相关字段的访问控制机制。 使用 PodSecurityPolicy,可以防止“创建 Pod”这个能力自动变成“每个集群节点上的 root 用户”, 并且无需部署额外的外部访问控制器。

2)现在为什么 PodSecurityPolicy 要消失?

  • 自从首次引入 PodSecurityPolicy 以来,我们已经意识到 PSP 存在一些严重的可用性问题, 只有做出断裂式的改变才能解决。

  • 实践证明,PSP 应用于 Pod 的方式让几乎所有尝试使用它们的人都感到困惑。 很容易意外授予比预期更广泛的权限,并且难以查看某种特定情况下应用了哪些 PSP。 “更改 Pod 默认值”功能很方便,但仅支持某些 Pod 设置,而且无法明确知道它们何时会或不会应用于的 Pod。 如果没有“试运行”或审计模式,将 PSP 安全地改造并应用到现有集群是不切实际的,并且永远都不可能默认启用 PSP。

三、PSP 简单使用

在这里插入图片描述

因为PSP在高版本中已经不再使用了,所以这里稍微了解即可。目前,如果我们想要使用PSP,需要手动配置启动。PSP控制pod的方面包容如下:

在这里插入图片描述

1)开启PSP

在Master上编辑/etc/kubernetes/manifests/kube-apiserver.yaml文件,然后我们需要在command下的enable-admission-plugins下添加PodSecurityPolicy

command:
   - --enable-admission-plugins=NodeRestriction,PodSecurityPolicy

在这里插入图片描述
重启kubelet

systemctl restart kubelet.service

【注意】开启PodSecurityPolicy功能后,即使没有使用任何安全策略,都会使得创建pods(包括调度任务重新创建pods)失败

2)示例演示

1、没有PSP场景测试

通过下面的deployment yaml文件测试在没有PSP策略的情况下是否可以创建pod:

cat >nginx-deployment.yaml<<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: default
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.15.4
EOF

使用下面的命令创建deployment资源:

kubectl apply -f nginx-deployment.yaml

使用下面的命令检查pod是否创建:

kubectl get pods,replicasets,deployments

在这里插入图片描述
通过上图可见deployments和relicaset正在运行,由于缺少PSP policy,集群并没有创建相应的pods。

2、定义PSP

这里定义两个不同权限的PSP策略:

【1】资源限制策略

下面是典型的限制资源使用的restrictive policy

cat >default-restrict-psp.yaml<<EOF
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: restrictive
spec:
  privileged: false
  hostNetwork: false
  allowPrivilegeEscalation: false
  defaultAllowPrivilegeEscalation: false
  hostPID: false
  hostIPC: false
  runAsUser:
    rule: RunAsAny
  fsGroup:
    rule: RunAsAny
  seLinux:
    rule: RunAsAny
  supplementalGroups:
    rule: RunAsAny
  volumes:
  - 'configMap'
  - 'downwardAPI'
  - 'emptyDir'
  - 'persistentVolumeClaim'
  - 'secret'
  - 'projected'
  allowedCapabilities:
  - '*'
EOF
【2】资源允许策略

下面是允许使用资源的permissive policy,多条permissive policy规则被用来设置相应user或者sevice account使用相关类型的资源。

cat >permissive-psp.yaml<<EOF
apiVersion: policy/v1beta1
kind: PodSecurityPolicy
metadata:
  name: permissive
spec:
  privileged: true
  hostNetwork: true
  hostIPC: true
  hostPID: true
  seLinux:
    rule: RunAsAny
  supplementalGroups:
    rule: RunAsAny
  runAsUser:
    rule: RunAsAny
  fsGroup:
    rule: RunAsAny
  hostPorts:
  - min: 0
    max: 65535
  volumes:
  - '*'
EOF

上面两种poicies可以使用下面的命令创建对应的PSP资源:

kubectl apply -f default-restrict-psp.yaml
kubectl apply -f permissive-psp.yaml

核对psp是否创建成功与否:

kubectl get psp

在这里插入图片描述
下面将通过cluster role和cluster role binding在集群中使用刚才定义的安全策略(Pod Security Policy)。

3、角色定义(Cluster Role)

关于restrictive policy的restrictive cluster role

cat >psp-restrictive-cluster-roleyaml<<EOF
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: psp-restrictive
rules:
- apiGroups:
  - extensions
  resources:
  - podsecuritypolicies
  resourceNames:
  - restrictive
  verbs:
  - use
EOF

关于permissive policy的permissive cluster role

cat >psp-permissive-cluster-roleyaml <<EOF
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: psp-permissive
rules:
- apiGroups:
  - extensions
  resources:
  - podsecuritypolicies
  resourceNames:
  - permissive
  verbs:
  - use
EOF

通过下面命令创建相应的cluster role资源:

kubectl apply -f psp-restrictive-cluster-roleyaml
kubectl apply -f psp-permissive-cluster-roleyaml

4、角色绑定(Cluster Role Bindings)

cat >psp-restrictive-cluster-role-binding.yaml<<EOF
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: psp-default
subjects:
- kind: Group
  name: system:serviceaccounts
  namespace: kube-system
roleRef:
  kind: ClusterRole
  name: psp-restrictive
  apiGroup: rbac.authorization.k8s.io
EOF

上面的role binding会将restrictive cluster role绑定到所有的system service account。

使用下面的命令生成role binding资源:

kubectl apply -f psp-restrictive-cluster-role-binding.yaml

5、再测试验证

kubectl delete deploy nginx-deployment
kubectl get po,rs,deploy

在这里插入图片描述
通过上图可知,可以正常调度pod,启动pod了。

四、PodSecurity admission

在这里插入图片描述

Pod security admission 是 Kubernetes 内置的一种准入控制器,在 Kubernetes V1.23版本中这一特性门是默认开启的,在V1.22中需要通过 Kube-apiserver 参数--feature-gates="...,PodSecurity=true"开启。在低于V1.22的 Kuberntes 版本中也可以自行安装 Pod Security Admission Webhook。

  • PodSecurity admission 是通过执行内置的 Pod Security Standards 来限制集群中的 pod 的创建。
  • Pod 安全性标准定义了三种不同的 策略(Policy),以广泛覆盖安全应用场景。 这些策略是 叠加式的(Cumulative),安全级别从高度宽松至高度受限。 本指南概述了每个策略的要求。

1)podSecurity Standards

官方文档:https://kubernetes.io/zh-cn/docs/concepts/security/pod-security-standards/
为了广泛的覆盖安全应用场景, Pod Security Standards 渐进式的定义了三种不同的 Pod 安全标准策略:

策略描述
Privileged不受限制的策略,提供最大可能范围的权限许可。此策略允许已知的特权提升。
Baseline限制性最弱的策略,禁止已知的策略提升。允许使用默认的(规定最少)Pod 配置。
Restricted限制性非常强的策略,遵循当前的保护 Pod 的最佳实践。

2)podSecurity admission

官方文档:https://kubernetes.io/zh-cn/docs/concepts/security/pod-security-admission/

在 Kubernetes 集群中开启了 podSecurity admission 后,就可以通过给 namespace 设置 label 的方式来实施 Pod Security Standards。其中有三种设定模式可选用:

模式描述
enforce违反安全标准策略的 Pod 将被拒绝。
audit违反安全标准策略触发向审计日志中记录的事件添加审计注释,但其他行为被允许。
warn违反安全标准策略将触发面向用户的警告,但其他行为被允许。

label 设置模板解释:

# 设定模式及安全标准策略等级
# MODE必须是 `enforce`, `audit`或`warn`其中之一。
# LEVEL必须是`privileged`, `baseline`或 `restricted`其中之一
pod-security.kubernetes.io/<MODE>: <LEVEL>

# 此选项是非必填的,用来锁定使用哪个版本的的安全标准
# MODE必须是 `enforce`, `audit`或`warn`其中之一。
# VERSION必须是一个有效的kubernetes minor version(例如v1.23),或者 `latest`
pod-security.kubernetes.io/<MODE>-version: <VERSION>

通过准入控制器配置文件,可以为 Pod security admission 设置默认配置:

apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: PodSecurity
  configuration:
    apiVersion: pod-security.admission.config.k8s.io/v1beta1
    kind: PodSecurityConfiguration
    # Defaults applied when a mode label is not set.
    #
    # Level label values must be one of:
    # - "privileged" (default)
    # - "baseline"
    # - "restricted"
    #
    # Version label values must be one of:
    # - "latest" (default) 
    # - specific version like "v1.23"
    defaults:
      enforce: "privileged"
      enforce-version: "latest"
      audit: "privileged"
      audit-version: "latest"
      warn: "privileged"
      warn-version: "latest"
    exemptions:
      # Array of authenticated usernames to exempt.
      usernames: []
      # Array of runtime class names to exempt.
      runtimeClassNames: []
      # Array of namespaces to exempt.
      namespaces: []

podSecurity admission 可以从 username,runtimeClassName,namespace三个维度对 Pod 进行安全标准检查的豁免。

3)podSecurity standards 示例演示

1、Baseline 策略

Baseline 策略目标是应用于常见的容器化应用,禁止已知的特权提升,在官方的介绍中此策略针对的是应用运维人员和非关键性应用开发人员,在该策略中包括:

必须禁止共享宿主命名空间、禁止容器特权、 限制 Linux 能力、禁止 hostPath 卷、限制宿主机端口、设定 AppArmor、SElinux、Seccomp、Sysctls 等。

违反 Baseline 策略存在的风险:

  • 特权容器可以看到宿主机设备
  • 挂载 procfs 后可以看到宿主机进程,打破进程隔离
  • 可以打破网络隔离
  • 挂载运行时 socket 后可以不受限制的与运行时通信

【1】创建名为 my-baseline-namespace 的 namespace,并设定 enforce 和 warn 两种模式都对应 Baseline 等级的 Pod 安全标准策略:

apiVersion: v1
kind: Namespace
metadata:
  name: my-baseline-namespace
  labels:
    pod-security.kubernetes.io/enforce: baseline  
    pod-security.kubernetes.io/enforce-version: v1.23
    pod-security.kubernetes.io/warn: baseline
    pod-security.kubernetes.io/warn-version: v1.23

【2】创建一个违反 baseline 策略的 pod

apiVersion: v1
kind: Pod
metadata:
  name: hostnamespaces2
  namespace: my-baseline-namespace
spec:
  containers:
  - image: bitnami/prometheus:2.33.5
    name: prometheus
    securityContext:
      allowPrivilegeEscalation: true
      privileged: true
      capabilities:
        drop:
        - ALL
  hostPID: true
  securityContext:
    runAsNonRoot: true
    seccompProfile:
      type: RuntimeDefault

执行 apply 命令,显示不能设置 hostPID=truesecurityContext.privileged=true,Pod 创建被拒绝,特权容器的运行,并且开启 hostPID,容器进程没有与宿主机进程隔离,容易造成 Pod 容器逃逸:

【3】创建不违反 baseline 策略的 pod,设定 Pod 的 hostPID=falsesecurityContext.privileged=false

apiVersion: v1
kind: Pod
metadata:
  name: hostnamespaces2
  namespace: my-baseline-namespace
spec:
  containers:
  - image: bitnami/prometheus:2.33.5
    name: prometheus
    securityContext:
      allowPrivilegeEscalation: false
      privileged: false
      capabilities:
        drop:
        - ALL
  hostPID: false
  securityContext:
    runAsNonRoot: true
    seccompProfile:
      type: RuntimeDefault

执行 apply 命令,pod 被允许创建。

2、Restricted 策略

Restricted 策略目标是实施当前保护 Pod 的最佳实践,在官方介绍中此策略主要针对运维人员和安全性很重要的应用开发人员,以及不太被信任的用户。该策略包含所有的 baseline 策略的内容,额外增加:限制可以通过 PersistentVolumes 定义的非核心卷类型、禁止(通过 SetUID 或 SetGID 文件模式)获得特权提升、必须要求容器以非 root 用户运行、Containers 不可以将 runAsUser 设置为 0、 容器组必须弃用 ALL capabilities 并且只允许添加 NET_BIND_SERVICE 能力。

Restricted 策略进一步的限制在容器内获取 root 权限,linux 内核功能。例如针对 kubernetes 网络的中间人攻击需要拥有 Linux 系统的 CAP_NET_RAW 权限来发送 ARP 包。

【1】创建名为 my-restricted-namespace的namespace,并设定 enforce 和 warn 两种模式都对应 Restricted 等级的 Pod 安全标准策略:

apiVersion: v1
kind: Namespace
metadata:
name: my-restricted-namespace
labels:
 pod-security.kubernetes.io/enforce: restricted 
 pod-security.kubernetes.io/enforce-version: v1.23
 pod-security.kubernetes.io/warn: restricted
 pod-security.kubernetes.io/warn-version: v1.23

【2】创建一个违反 Restricted 策略的 pod

apiVersion: v1
kind: Pod
metadata:
  name: runasnonroot0
  namespace: my-restricted-namespace
spec:
  containers:
  - image: bitnami/prometheus:2.33.5
    name: prometheus
    securityContext:
      allowPrivilegeEscalation: false
  securityContext:
    seccompProfile:
      type: RuntimeDefault

执行 apply 命令,显示必须设置 securityContext.runAsNonRoot=true,securityContext.capabilities.drop=[“ALL”],Pod 创建被拒绝,容器以 root 用户运行时容器获取权限过大,结合没有 Drop linux 内核能力有 kubernetes 网络中间人攻击的风险。

【3】创建不违反 Restricted 策略的 pod,设定 Pod 的 securityContext.runAsNonRoot=true,Drop 所有 linux 能力。

apiVersion: v1
kind: Pod
metadata:
  name: runasnonroot0
  namespace: my-restricted-namespace
spec:
  containers:
  - image: bitnami/prometheus:2.33.5
    name: prometheus
    securityContext:
      allowPrivilegeEscalation: false
      capabilities:
        drop:
        - ALL
  securityContext:
    runAsNonRoot: true
    seccompProfile:
      type: RuntimeDefault

执行 apply 命令,pod 被允许创建。

4)Pod Security admission 当前局限性

如果你的集群中已经配置 PodSecurityPolicy,考虑把它们迁移到 podSecurity admission 是需要一定的工作量的。
首先需要考虑当前的 podSecurity admission 是否适合你的集群,目前它旨在满足开箱即用的最常见的安全需求,与 PSP 相比它存在以下差异:

  • podSecurity admission 只是对 pod 进行安全标准的检查,不支持对 pod 进行修改,不能为 pod 设置默认的安全配置。
  • podSecurity admission 只支持官方定义的三种安全标准策略,不支持灵活的自定义安全标准策略。这使得不能完全将PSP规则迁移到 podSecurity admission,需要进行具体的安全规则考量。
  • podSecurity admission 不像 PSP 一样可以与具体的用户进行绑定,只支持豁免特定的用户或者 RuntimeClass 及 namespace。

五、默认的 securityContext 介绍和使用

官方文档:https://kubernetes.io/zh-cn/docs/reference/kubernetes-api/workload-resources/pod-v1/#security-context

SecurityContext 包含 Pod 级别的安全属性和常见的容器设置。 可选:默认为空。每个字段的默认值见类型描述。

【温馨提示】PodSecurityContext 包含 Pod 级别的安全属性和常用容器设置。 一些字段也存在于 container.securityContext 中。container.securityContext 中的字段值优先PodSecurityContext 的字段值。

  • securityContext.runAsUser——运行容器进程入口点(Entrypoint)的 UID。如果未指定,则默认为镜像元数据中指定的用户。 也可以在 SecurityContext 中设置。 如果同时在 SecurityContextPodSecurityContext 中设置,则在对应容器中所设置的 SecurityContext 值优先。 注意,spec.os.name 为 “windows” 时不能设置此字段。
  • securityContext.runAsGroup——运行容器进程入口点(Entrypoint)的 GID。如果未设置,则使用运行时的默认值。 也可以在 SecurityContext 中设置。如果同时在 SecurityContextPodSecurityContext 中设置, 则在对应容器中设置的 SecurityContext 值优先。 注意,spec.os.name 为 “windows” 时不能设置该字段。
  • securityContext.privileged——以特权模式运行容器。特权容器中的进程本质上等同于主机上的 root。默认为 false。 默认情况下,容器是不可以访问宿主上的任何设备的,不过一个“privileged(特权的)” 容器则被授权访问宿主上所有设备。 这种容器几乎享有宿主上运行的进程的所有访问权限。 【注意】这个参数不能在 PodSecurityContext 中设置。 注意,spec.os.name 为 “windows” 时不能设置此字段。
  • securityContext.fsGroup——应用到 Pod 中所有容器的特殊补充组。某些卷类型允许 kubelet 将该卷的所有权更改为由 Pod 拥有:
    • 文件系统的属主 GID 将是 fsGroup 字段值
    • setgid 位已设置(在卷中创建的新文件将归 fsGroup 所有)
    • 权限位将与 rw-rw---- 进行按位或操作
  • securityContext.fsGroupChangePolicy——fsGroupChangePolicy 定义了在卷被在 Pod 中暴露之前更改其属主和权限的行为。 此字段仅适用于支持基于 fsGroup 的属主权(和权限)的卷类型。它不会影响临时卷类型, 例如:secret、configmap 和 emptydir。 有效值为 “OnRootMismatch” 和 “Always”。如果未设置,则使用 “Always”。 注意,spec.os.name 为 “windows” 时不能设置此字段。

上面只是列出了几个常用的参数,更多参数,可以参考官方文档。对应的字段如下:

  • spec.securityContext.runAsUser
  • spec.securityContext.runAsGroup
  • spec.containers[*].securityContext.privileged
  • spec.containers[*].securityContext.runAsUser
  • spec.containers[*].securityContext.runAsGroup
  • spec.securityContext.fsGroup
  • spec.securityContext.fsGroupChangePolicy

【示例1】PodSecurityContext

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: default
  labels:
    app: nginx
spec:
  replicas: 1
  
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      securityContext:
        runAsUser: 10000
        runAsGroup: 10000
      containers:
      - name: nginx
        image: nginx:1.15.4

【示例2】container.securityContext

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  namespace: default
  labels:
    app: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      securityContext:
        runAsUser: 10000
        runAsGroup: 10000
      containers:
      - name: nginx
        image: nginx:1.15.4
        securityContext:
          runAsUser: 10000
          runAsGroup: 10000
          privileged: true
          fsGroup: 2000

如上这个配置,可以看到 Pod 中所有容器内的进程都是已用户 uid=10000 和主组 gid=10000来运行的,而创建的任何文件的属组都是 groups=2000。通过这样的方法,可以达到让用户的进程不使用默认的 Root (uid=0,gid=0)权限的目的。

【温馨提示】镜像中必须存储10000 UID 和 10000 GUI ,如果同时设置了,container.securityContext优先级更高。

K8s PSP 和 securityContext 介绍与简单使用就先到这里,有任何疑问欢迎给我留言,后续会持续更新【云原生+大数据】相关的文章。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

C++中的多态(原理篇)

多态的原理 虚函数表 下面这一串代码 class A { public:virtual void func(){cout << "func1()" << endl;} private:int _a; };我们看到了a对象的大小是8bit大小&#xff0c;但是a对象里面不应该只是一个_a吗&#xff1f;当我们打开监视窗口发现 a对象…

C++STL-list的简易实现

文章目录1. list的介绍2. 迭代器的分类3. list的构造4. list的实现4.1 list的基本结构4.2 list的push_back函数4.2 list的迭代器4.2.1 operator- >4.2.2 const迭代器4.3 insert函数4.4 earse函数4.5 迭代器失效问题4.6 析构函数4.7 构造函数4.8 拷贝构造1. 传统写法2. 现代写…

【C++升级之路】第四篇:类和对象(下)

&#x1f31f;hello&#xff0c;各位读者大大们你们好呀&#x1f31f; &#x1f36d;&#x1f36d;系列专栏&#xff1a;【C学习与应用】 ✒️✒️本篇内容&#xff1a;类与对象知识汇总&#xff0c;包括初始化列表的基本概念和使用的注意事项、explicit关键字、C/C中的static成…

Python【方法和返回值(Union)联合类型】注解

什么是类型注解&#xff1a;供调用者在使用函数&#xff08;方法&#xff09;时&#xff0c;如果没有完善的文档作为参考&#xff0c;开发者不知道要给定义的【变量、方法中的函数、】传入什么数据类型&#xff0c;以免减少编译错误。有了类型注解可以让 IDE 知道了数据类型后&…

C++语法2——for、while、do-while的语法及区别

C语言语法1详情请看这两篇博客&#xff1a;&#xff08;此号为本人小号&#xff09; 四则运算及基本语法 数据类型 接下来要讲得是循环语句 for循环 基本语法&#xff1a; for(表达式1&#xff1b;表达式2&#xff1b;表达式3) {内嵌语句&#xff1b; }执行顺序&#xff1a;…

js如何计算年龄?如何创建Javascript 年龄计算器?

如何创建年龄计算器? 要构建这个项目,我们需要HTML,CSS和Javascript。 让我们来看看这个项目是如何工作的。项目由输入日期组成。用户必须单击它并选择他们的出生日期或任何所需的日期。在此之后,用户必须单击计算按钮。用户单击计算按钮后,我们会根据他们输入的日期(…

深入理解ConcurrentLinkedQueue源码

1. 概述 在我们的日常开发中&#xff0c;经常会使用队列这种数据结构&#xff0c;需要它的队尾进、队头出的特点。于是&#xff0c;Doug Lea大师设计了一个线程安全的队列ConcurrentLinkedQueue&#xff0c;它是采用链表的形式构成的。我们接下来尝试通过代码去了解其中的设计…

S7-200SMART通过表格指令实现模拟量信号滑动平均值滤波的具体方法

S7-200SMART通过表格指令实现模拟量信号滑动平均值滤波的具体方法 当现场的模拟量信号波动太大,而通过硬件的方式尚无法实现平稳的信号输入时,可采用软件上的滤波进行信号处理, 本次和大家分享的即通过取多个信号值的平均值的方式实现模拟量滤波的具体方法示例,仅供大家参考…

DataNode节点下线速度优化

目录 一、节点掉线或退役 1.1区分节点掉线和节点退役的区别 1.2 如何处理节点掉线出现的各种风暴 1.2.1 Datanode的block复制 1.2.2 控制节点掉线RPC风暴的参数 二、如何快速节点下线 一、节点掉线或退役 背景&#xff1a;5台数据节点&#xff0c;存储40T数据 block数112…

高等数学(上) —— 一元积分学

文章目录Ch4.不定积分原函数F(x)F(x)F(x)原函数存在定理不定积分∫f(x)dx\int f(x)dx∫f(x)dx不定积分公式不定积分 ⇦⇨ 变上限积分&#xff1a;∫f(x)dx∫0xf(t)dt\int f(x){\rm d}x\int_0^xf(t){\rm d}t∫f(x)dx∫0x​f(t)dtCh5.定积分1.定积分定义定积分的几何意义2.定积分…

ESP32的python开发环境搭建:Thonny+MicroPython

1 Thonny安装 Thonny —— 一个面向初学者的 Python IDE。Thonny良好的支持Microbit、ESP32和树莓派等的开发. 安装下载地址&#xff1a; https://thonny.org/ 2 Micropython安装 MicroPython 是 Python 3 语言的精简实现 &#xff0c;包括Python标准库的一小部分&#xff0…

Vector - VT System - 板卡_VT8006/VT8012

由于最近不幸变为了小*人&#xff0c;因此断更了一周&#xff0c;今天稍有好转&#xff0c;就新加一块大家应该会比较感兴趣的VT板卡硬件介绍吧&#xff0c;也预示着新的开始&#xff0c;马上也要到了元旦&#xff0c;新的一年即将开始&#xff0c;提前在这里祝福大家在新的一年…

JavaPub面试宝典【第22版】

JavaPub面试宝典【第22版】 直接上干货&#xff0c;几百篇原创笔记都在这。 文章列表 &#x1f4da;最少必要面试题 Java基础Java并发入门Java容器JavaWebJVMMySQLMyBatisSpringSpringBootRedisElasticSearchKafkaZookeeperDocker缓存 &#x1f4d6;知识点总结 下面是原创…

linux 下命令

linux 下命令 Linux 是一套免费使用和自 由传播的类 Unix 操作系统&#xff0c; 是一个基于 POSIX 和 UNIX 的多用户、 多任务、 支持多线程和多 CPU 的操作系统。 它能运行主要的 UNIX 工具软件、 应用程序和网络协议。 它支持 32 位和 64 位硬件。 Linux 继承了 Unix 以网络为…

uniCloud云开发----4、uniCloud云开发进阶使用方法

uniCloud云开发进阶使用方法前言1、云对象的importObject的创建和使用(1&#xff09;创建云对象&#xff08;2&#xff09;编辑云对象&#xff08;3&#xff09;在.vue文件中调用云对象&#xff08;4&#xff09;在.vue文件中调用方法2、客户端直接连接数据库(1)直接在客户端引…

设计模式-牛刀小试02

前言 本文为datawhale2022年12月组队学习《大话设计模式》最后一次打卡任务&#xff0c;本次完成homework2。 【教程地址】https://github.com/datawhalechina/sweetalk-design-pattern 一、任务描述 1.1 背景 小李已经是一个工作一年的初级工程师了&#xff0c;他所在的公…

sqlite wal 分析

动手点关注干货不迷路sqlite 提供了一种 redo log 型事务实现&#xff0c;支持读写的并发&#xff0c;见 write-ahead log&#xff08;https://sqlite.org/wal.html&#xff09;。本文将介绍 wal 原理&#xff0c;并源码剖析 checkpoint 过程&#xff0c;同时讨论下 wal 使用中…

知行之桥EDI系统如何通过ZIP端口压缩文件?

在EDI项目当中&#xff0c;对于IT技术不够成熟或设备不够完善的用户来说&#xff0c;EXCEL方案是较为适中的选择。收到合作伙伴发来的850订单之后&#xff0c;将订单数据转换为EXCEL&#xff0c;再将EXCEL发送至用户指定的邮箱。若每条订单单独发送至邮箱&#xff0c;当订单量大…

#榜样的力量#《新冠战“疫”——2022中国数据智能产业最具社会责任感企业》榜正式发布...

‍数据猿出品数据猿此次推出的#榜样的力量#《新冠战“疫”——2022中国数据智能产业最具社会责任感企业》榜单/奖项为公益主题策划活动。旨在为正能量助威&#xff0c;为中国数据智能产业中具有社会责任感的典型性企业发声。数据智能产业创新服务媒体——聚焦数智 改变商业新冠…

66、【链表】leetcode——142. 环形链表 II(C++、Python版本)

题目描述 方法一&#xff1a;哈希表 C版本 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode(int x) : val(x), next(NULL) {}* };*/ class Solution { public:ListNode *detectCycle(ListNode *head) {unord…