一、资源需求与限制
  在Kubernetes上,可由容器或Pod请求或消费的"计算资源"是指CPU和内存(RAM),这也是目前仅有的受支持的两种类型。相比较来说,CPU属于可压缩(compressible)型资源,即资源的使用额度可按需收缩,而内存(当前)则是不可压缩性资源,对其执行收缩操作可能会导致某种程度的问题。
  目前来说,资源隔离尚且属于容器级别的,CPU和内存资源的配置需要在Pod中的容器上进行,每种资源均可由"requests"属性定义其请求的确保可用值,即容器运行可能用不到这些额度的资源,但是用到时必须要确保有如此多的资源可用,而"limits"属性则用于限制资源可用的最大值,即硬限制。不过,为了表述方便,人们通常仍然把资源配置称作Pod资源的请求和限制,只不过它是指Pod内所有容器上某种类型资源的请求和限制的总和。

  在Kubernetes系统上,1个单位的CPU相当于虚拟机上的1颗虚拟CPU(vCPU)或物理机上的一个超线程(Hyperthread,或称为一个逻辑CPU),它支持分数计量方式,一个核心(1 core)相当于1000个微核心(millicores),因此500m相当于0.5个核心,即二分之一个核心。内存的计量方式与日常使用方式相同,默认的单位是字节,也可以使用E、P、T、G、M和K作为单位后缀,或Ei、Pi、Ti、Gi、Mi和Ki形式的单位后缀。
  对于压缩性的资源来说,未定义其请求量以确保其最小可用资源时,它可能会被其他的Pod资源压缩至极低的水平,甚至会达到Pod不能够被调度运行的境地。而对于非压缩型资源来说,内存资源在任何原因导致的紧缺情形下都有可能导致相关进程被杀死。因此,在Kubernetes系统上运行关键性业务相关的Pod时必须使用requests属性为容器定义资源确保可用量。
  集群中的每个节点都拥有定量的CPU和内存资源,调度Pod时,仅那些被请求资源的余量可容纳当前被调度的Pod的请求量的节点才可作为目标节点。也就是说,Kubernetes的调度器会根据容器的requests属性中定义的资源需求量来判定仅哪些节点可接收运行相关的Pod资源,而对于一个节点的资源来说,每运行一个Pod对象,其requests中定义的请求量都要被预留,直到被所有Pod对象瓜分完毕为止。
  容器的资源需求仅能达到为其保证可用的最少资源量的目的,它并不会限制容器的可用资源上限,因此对应用程序自身存在Bug等多种原因而导致的系统资源被长时间占用的情况则无计可施,这就需要通过limits属性为容器定义资源的最大可用量。资源分配时,可压缩型资源CPU的控制阈值可自由调节,容器进程无法获得超出其CPU配额的可用时间。不过,如果进程申请分配超出其limits属性定义的硬限制的内存资源时,它将被OOM killer杀死,不过随后可能会被其控制进程所重启,例如,容器进程的Pod对象会被杀死并重启(重启策略为Always或OnFailure时),或者是容器进程的子进程被父进程所重启。

二、资源限制实验

1)编写创建Pod与定义资源限制的yaml文件

]# cat resource_limits.yaml
apiVersion: v1
kind: Pod
metadata:name: memleaklabels:app: memleak
spec:containers:- name: simmemleakimage: saadali/simmemleakimagePullPolicy: IfNotPresentresources:requests:memory: "64Mi"cpu: "1"limits:memory: "64Mi"cpu: "1"]# kubectl apply -f resource_limits.yaml
pod/memleak created

2)查看Pod资源信息

]# kubectl get pod -o wide
NAME      READY   STATUS             RESTARTS   AGE   IP            NODE     NOMINATED NODE   READINESS GATES
memleak   0/1     CrashLoopBackOff   1          10s   10.244.0.97   master   <none>           <none>]# kubectl describe pods memleak
Name:         memleak
Namespace:    default
Priority:     0
Node:         master/172.16.2.200
Start Time:   Fri, 18 Sep 2020 09:49:00 +0800
Labels:       app=memleak
Annotations:  Status:  Running
IP:           10.244.0.97
IPs:IP:  10.244.0.97
Containers:simmemleak:Container ID:   docker://4de663358d0ff68a11b81a31a6f39dd526135b8e5d825e4ca28f745e2b63ad24Image:          saadali/simmemleakImage ID:       docker-pullable://saadali/simmemleak@sha256:5cf58299a7698b0c9779acfed15c8e488314fcb80944550eab5992cdf3193054Port:           <none>Host Port:      <none>State:          WaitingReason:       CrashLoopBackOffLast State:     TerminatedReason:       OOMKilledExit Code:    137Started:      Fri, 18 Sep 2020 09:49:50 +0800Finished:     Fri, 18 Sep 2020 09:49:50 +0800Ready:          FalseRestart Count:  3Limits:cpu:     1memory:  64MiRequests:cpu:        1memory:     64MiEnvironment:  <none>Mounts:/var/run/secrets/kubernetes.io/serviceaccount from default-token-47pch (ro)
Conditions:Type              StatusInitialized       True Ready             False ContainersReady   False PodScheduled      True
Volumes:default-token-47pch:Type:        Secret (a volume populated by a Secret)SecretName:  default-token-47pchOptional:    false
QoS Class:       Guaranteed
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300snode.kubernetes.io/unreachable:NoExecute for 300s
Events:Type     Reason     Age                From               Message----     ------     ----               ----               -------Normal   Scheduled  <unknown>          default-scheduler  Successfully assigned default/memleak to masterNormal   Pulled     20s (x4 over 69s)  kubelet, master    Container image "saadali/simmemleak" already present on machineNormal   Created    20s (x4 over 69s)  kubelet, master    Created container simmemleakNormal   Started    20s (x4 over 69s)  kubelet, master    Started container simmemleakWarning  BackOff    5s (x6 over 67s)   kubelet, master    Back-off restarting failed container

.
  通过查看Pod的详细信息可以看到,OOMKilled表示容器因为内存耗尽而被终止了,因此,为limits属性中的memory设置一个合理的值至关重要。与resquests不同的是,limits并不会影响Pod的调度结果,也就是时,一个节点上的所有Pod对象的limits数量之和可以大于节点所拥有的资源量,即支持资源的过载使用(overcommitted)。不过,这么一来一旦资源被耗尽,尤其是内存资源耗尽,则必然会有容器因OOMKilled而终止。
  另外需要说明的是,Kubernetes仅会确保Pod能够获得它们的请求(requests)的CPU时间额度,它们是否获得额外的(throttled)的CPU时间,则取决于其他正在运行的作业对CPU资源的占用情况。例如,对于总数为1000m的CPU资源来说,容器A请求使用200m,容器B请求使用500m,在不超过它们各自的最大限额的前提下,余下的300m在双方都需要时会以2:5(200m:500m)的方式进行配置。
  还需要注意的是,于容器中运行top等命令观察资源可用量信息时,即便定义了requests和limits属性,虽然其可用资源受限于此两个属性中的定义,但容器中可见的资源量依然是节点级别的可用总量。

三、Pod的QoS服务质量
  Kubernetes允许节点资源对limits的过载使用,这意味着节点无法同时满足其上的所有Pod对象以资源满载的方式运行。Kubernetes需要借助于Pod对象的优先级来对Pod进行判定。根据Pod对象的requests和limits属性,Kubernetes将Pod对象归类到BestEffort、Burstable和Guaranteed三个服务质量(Quality of Servcie,QoS)类别下,具体说明如下:
  Guaranteed:每个容器都为CPU资源设置了具有相同值的requests和limits属性,以及每个容器都为内存资源设置了具有相同值的requests和limits属性的Pod资源会自动归属于此类别,这类Pod资源具有最高优先级。
  Burstable:至少有一个容器设置了CPU或者内存资源的requests属性,但不满足Guaranteed类别要求的Pod资源将自动归属于此类别,它们具有中等优先级。
  BestEffort:未为任何一个容器设置requests或limits属性的Pod资源将自动归属于此类别,它们的优先级为最低级别。

  当内存紧张时,BestEffort类别的容器将首当其冲地被终止,因为系统不为其提供任何级别的资源保证,但换来的好处是,它们能够在可用时做到尽可能多的占用资源。若已然不存在任何BestEffort类别的资源,则接下来是有着中等优先级的Burstable类别的Pod被终止。Guaranteed类别的容器拥有最高优先级,它们不会被杀死,除非其内存资源需求超限,或者OOM时没有其他更低优先级的Pod资源存在。

  每个运行状态容器都有其OOM得分,得分越高越会被优先杀死。OOM得分主要根据两个维度来计算:由QoS类别继承而来的默认分值和容器可用内存资源比例。
  同等级别优先级的Pod资源在OOM时,与自身的requests属性相比,其内存占用比例最大的Pod对象将会被首先杀死。
  OOM是内存耗尽时的处理机制,它们与可压缩型资源CPU无关,因此CPU资源的需求无法得到保障时,Pod仅仅是暂时获取不到相应的资源而已。

四、LimitRange准入控制器
  经由认证插件和授权插件分别完成身份认证和权限检查之后,准入控制器将拦截那些创建、更新和删除相关的操作请求以强制实现控制器中定义的功能,包括执行对象的语义验证,设置缺失字段的默认值、限制所有容器使用的镜像文件必须来自某个特定的Registry、检查Pod对象的资源需求是否超出了指定的限制范围等等。
  虽然用户可以为容器指定资源需求及资源限制,但是未予指定资源限制属性的容器应用很有可能因故吞掉所在工作节点上的所有可用计算资源,因此妥当的做法是使用LimitRange资源在每个名称空间中为每个容器指定最小及最大计算资源用量限制,甚至是设置默认的计算资源需求和计算资源限制。在名称空间上定义了LimitRange对象之后,客户端提交创建或修改的资源对象将受到LimitRange控制器的检查,任何违反了LimitRange对象定义的资源最大量的请求将被直接拒绝。
  LimitRange资源支持限制容器、Pod和PersistentVolumeClaim三种资源对象的系统资源用量,其中Pod的容器主要用于定义可用的CPU和内存资源,而PersistenVolume-Claim则主要定义存储空间的限制范围。
  default:用于定义默认的资源限制。
  defaultRequest:定义默认的资源需求。
  min:定义最小的资源用。量
  max:最大的资源用量。
  maxLimitRequestRatio:设置为最小用量的倍数。
  
1)创建LimitRange资源对象

]# cat limitrange.yaml
apiVersion: v1
kind: LimitRange
metadata:name: cpu-limit-range
spec:limits:- default:cpu: 1000mdefaultRequest:cpu: 1000mmin: cpu: 500mmax:cpu: 2000mmaxLimitRequestRatio:cpu: 4 type: Container]# kubectl apply -f limitrange.yaml
limitrange/cpu-limit-range created

2)查看LimitRange资源对象详细信息

]# kubectl get limitrange
NAME              CREATED AT
cpu-limit-range   2020-09-19T01:37:55Z]# kubectl describe  limitrange cpu-limit-range
Name:       cpu-limit-range
Namespace:  default
Type        Resource  Min   Max  Default Request  Default Limit  Max Limit/Request Ratio
----        --------  ---   ---  ---------------  -------------  -----------------------
Container   cpu       500m  2    1                1              4

3)创建一个Pod资源测试

]# kubectl run limit-pod1 --image=ikubernetes/myapp:v1 --restart=Never
pod/limit-pod1 created]# kubectl get pods -o wide
NAME         READY   STATUS             RESTARTS   AGE   IP             NODE     NOMINATED NODE   READINESS GATES
limit-pod1   1/1     Running            0          16s   10.244.1.128   node1    <none>           <none>

4)查看Pod资源详细信息

]# kubectl describe pods limit-pod1
Name:         limit-pod1
Namespace:    default
Priority:     0
Node:         node1/172.16.2.101
Start Time:   Sun, 20 Sep 2020 09:38:27 +0800
Labels:       run=limit-pod1
Annotations:  kubernetes.io/limit-ranger: LimitRanger plugin set: cpu request for container limit-pod1; cpu limit for container limit-pod1
Status:       Running
IP:           10.244.1.128
IPs:IP:  10.244.1.128
Containers:limit-pod1:Container ID:   docker://2a19ed7f605fc474c3b511c492eccafdf84187e6400d1c32e87640db2976cb1dImage:          ikubernetes/myapp:v1Image ID:       docker-pullable://ikubernetes/myapp@sha256:9c3dc30b5219788b2b8a4b065f548b922a34479577befb54b03330999d30d513Port:           <none>Host Port:      <none>State:          RunningStarted:      Sun, 20 Sep 2020 09:38:28 +0800Ready:          TrueRestart Count:  0Limits:cpu:  1Requests:cpu:        1Environment:  <none>Mounts:/var/run/secrets/kubernetes.io/serviceaccount from default-token-47pch (ro)
Conditions:Type              StatusInitialized       True Ready             True ContainersReady   True PodScheduled      True
Volumes:default-token-47pch:Type:        Secret (a volume populated by a Secret)SecretName:  default-token-47pchOptional:    false
QoS Class:       Burstable
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300snode.kubernetes.io/unreachable:NoExecute for 300s
Events:Type    Reason     Age        From               Message----    ------     ----       ----               -------Normal  Scheduled  <unknown>  default-scheduler  Successfully assigned default/limit-pod1 to node1Normal  Pulled     <invalid>  kubelet, node1     Container image "ikubernetes/myapp:v1" already present on machineNormal  Created    <invalid>  kubelet, node1     Created container limit-pod1Normal  Started    <invalid>  kubelet, node1     Started container limit-pod1

.
  在Pod对象limit-pod1的详细信息中可以看到,容器状态信息段中,CPU资源已经被设定为了默认值。

5)创建小于LimitRange所定义的资源对象

]# kubectl run limit-pod2 --image=ikubernetes/myapp:v1 --restart=Never --requests='cpu=400m'
Error from server (Forbidden): pods "limit-pod2" is forbidden: minimum cpu usage per Container is 500m, but request is 400m

.
  可以看到,若是Pod对象设定的系统资源需求量小于LimitRange中的最小用量限制,则会触发LimitRange准入控制器拒绝相关的请求。

6)创建大于LimitRange所定义的资源对象

]# kubectl run limit-pod2 --image=ikubernetes/myapp:v1 --restart=Never --requests='cpu=3000m'
The Pod "limit-pod2" is invalid: spec.containers[0].resources.requests: Invalid value: "3": must be less than or equal to cpu limit

.
  可以看到,若是Pod对象设定的系统资源限制量大于LimitRange中的最大用量限制,则一样会触发LimitRange准入控制器拒绝相关的请求。
  事实上,在LimitRange对象中设置的默认资源需求和资源限制,同最小资源用量及最大资源用量限制能够组合出多种不同的情形,不同的组合场景下真正生效的结果也会存在不小的差异。另外,内存资源及PVC资源限制的实现与CPU资源大同小异,各位可自行实验。

五、ResourceQuota资源与准入控制器
  尽管LimitRange资源能限制单个容器、Pod及PVC等相关资源或存储资源的用量,但是用户依然可以创建数量众多的此类资源对象进而侵占所以的系统资源。于是,Kubernetes提供了ResourceQuota资源用于定义名称空间的对象数量或系统资源配额,它支持限制每种资源类型的对象总数,以及所以对象所能消耗的计算资源及存储资源总量等。同名的ResourceQuota准入控制器负责观察传入的请求,并确保它没有违反相应名称空间中的ResourceQuota对象定义的任何约束。
  于是,管理员可为每个名称空间分别创建一个ResourceQuota对象,随后,用户在名称空间中创建资源对象,ResourceQuota准入控制器将跟踪使用情况以确保它不超过相应ResourceQuota对象中定义的系统资源限制。用户创建或更新资源的操作违反配额约束将导致请求失败,API Server以HTTP状态码"403 FORBIDDEN"作为响应,并显示一条消息以提示可能违反的约束。不过,在名称空间上启用了CPU和内存等系统资源的配额后,用户创建Pod对象时必须指定资源需求或资源限制,否则,会触发ResourceQuota准入控制器拒绝执行相应的操作。
  ResourceQuota对象可限制指定名称空间中非终止状态的所有Pod对象的计算资源需求及计算资源限制总量。
  cpu或requests.cpu:CPU资源需求的总量限额。
  memory或requests.memory:内存资源需求的总量限额。
  limits.cpu:CPU资源限制的总量限额。
  limits.memory:内存资源限制的总量限额。
  ResourceQuota对象支持限制特定名称空间中可以使用的PVC数量和这些PVC资源的空间大小总量,以及特定名称空间中可在指定StorageClass上使用的PVC数量和这些PVC资源的总数:
  requests.storage:所有PVC存储需求的存储空间总量限额。
  persistentvolumeclaims:可以创建的PVC总数,即PVC数量限额。
  <storage-class-name>.storageclass.storage.k8s.io/requests.storage:指定存储类上可使用的所有PVC存储需求的存储空间总量限额。
  <storage-class-name>.storageclass.storage.k8s.io/persistentvolumeclaims:指定存储类上可使用的PVC总数。
  requests.ephemeral-storage:所有Pod可用的本地临时存储需求的总量。
  limits.ephemeral-storage:所有Pod可用的本地临时存储限制的总量。
  在1.9版本之前,ResourceQuota支持在名称空间级别的有限的几种资源集上设定对象计算配额,如Pods、Services和ConfigMap等等,而自1.9版本起支持以"count/<resource>.group"的格式支持对所有资源类型对象的计数配额,如count/deployments.apps.count/deployments.extensions和count/services等等。

1)创建ResourceQuota资源对象

]# cat resourcequota.yaml
apiVersion: v1
kind: ResourceQuota
metadata:name: quota-example
spec:hard:pods: "5"requests.cpu: "1"requests.memory: 1Gilimits.cpu: "2"limits.memory: 2Gicount/deployment.apps: "1"count/deployment.extensions: "1"persistentvolumeclaims: "2"]# kubectl apply -f resourcequota.yaml
resourcequota/quota-example created

2)查看ResourceQuota资源对象详细信息

]# kubectl get quota -o wide
NAME            AGE   REQUEST                                                                                                                                              LIMIT
quota-example   12s   count/deployment.apps: 0/1, count/deployment.extensions: 0/1, persistentvolumeclaims: 0/2, pods: 2/5, requests.cpu: 2/1, requests.memory: 64Mi/1Gi   limits.cpu: 2/2, limits.memory: 64Mi/2Gi]# kubectl describe quota quota-example
Name:                        quota-example
Namespace:                   default
Resource                     Used  Hard
--------                     ----  ----
count/deployment.apps        0     1
count/deployment.extensions  0     1
limits.cpu                   0     2
limits.memory                0     2Gi
persistentvolumeclaims       0     2
pods                         0     5
requests.cpu                 0     1
requests.memory              0     1Gi

3)创建一个Pod资源

kubectl run myapp-deploy --image=ikubernetes/myapp:v1 --replicas=3 --requests='cpu=200m,memory=256Mi' --limits='cpu=500m,memory=256Mi'
pod/myapp-deploy created

4)再次查看ResourceQuota资源对象详细信息

]# kubectl describe quota quota-example
Name:                        quota-example
Namespace:                   default
Resource                     Used   Hard
--------                     ----   ----
count/deployment.apps        1      2
count/deployment.extensions  1      2
limits.cpu                   1200m  2
limits.memory                768Mi  2Gi
persistentvolumeclaims       0      2
pods                         3      5
requests.cpu                 500m   1
requests.memory              640Mi  1Gi

.
  从当前ResourceQuota的使用量可以看到系统资源已经被使用了一部分,此时,如果再扩展myapp-deploy的规模则会很快遇到某一项配额的限制而导致扩展受阻。由分析可知,将Pod副本数量扩展至5个就会达到limits.cpu的资源上限而导致第5个扩展失败。
  需要注意的是,资源配额仅对那些在ResourceQuota对象创建之后生成的对象有效,对已经存在的对象不会产生任何的限制。而且,一旦启用了计算资源需求和计算资源限制配额,那么创建的任何Pod对象都必须设置此两类属性,否则Pod对象的创建将会被相应的ResourceQuota对象所阻止。无须手动为每个Pod对象设置此两类属性时,可以使用LimitRange对象为其设置默认值。
  每个ResourceQuota对象上还支持定义一组适用范围(scope),用于定义其配额仅生效于这组适用范围交集内的对象,目前可用的适用范围包括Terminating、NotTerminating、BestEffort,具体的说明如下:
  Terminating:匹配.spec.activeDeadlineSeconds的属性值大于等于0的所有Pod对象。
  NotTerminating:匹配.spec.activeDeadlineSeconds的属性值为空的所有Pod对象。
  BestEffort:匹配所有位于BestEffort QoS类别的Pod对象。
  NotBestEffort:匹配所有非BestEffort QoS类别的Pod对象。
  另外,自Kubernetes 1.8版本起,管理员即可以设置不同的优先级类别(PriorityClass)来创建Pod对象,而自Kubernetes 1.11版本起,Kubernetes开始支持对每个PriorityClass对象分别设定资源限额,管理员可以使用scopeSelector字段,从而根据Pod对象的优先级控制Pod资源对系统资源的消耗。

Kubernetes学习之资源限额相关推荐

  1. 【云原生】kubernetes学习之资源(对象)控制器概述---概念和实战(五)

    一,kubernetes内的资源(或者称之为对象) 首先,应该是思考一个问题,为什么kubernetes里要引入资源(对象)这个概念? Kubernetes 中的所有内容都被抽象为"资源&q ...

  2. Kubernetes学习笔记

    Kubernetes学习笔记 1.简介 用于自动部署.扩缩和管理容器化应用程序的开源系统,支持自动化部署.大规模可伸缩. 2.架构 2.1.Control Plane 对集群做出全局决策 Contro ...

  3. Kubernetes学习笔记二:Namespace,Cgroups 的隔离与应用

    Kubernetes学习系列文章:Kubernetes-博客专栏 今天在学习极客时间专栏:<深入剖析Kubernetes> 第五讲05 | 白话容器基础(一):从进程说开去和第六讲06 | ...

  4. Kubernetes学习笔记(一)

    2019独角兽企业重金招聘Python工程师标准>>> Kubernetes学习笔记(一) 博客分类: Kubernetes 导语 2015年4月,传闻已久的Borg论文伴随Kube ...

  5. kubernetes学习笔记 (二):k8s初体验

    本文采用本地k8s v1.10.3版本开发,如果还没有搭建可参照 kubernetes学习笔记 (一):搭建本地k8s开发环境进行搭建 搭建本地Docker镜像仓库 docker pull docke ...

  6. Kubernetes学习笔记之Calico CNI Plugin源码解析(一)

    女主宣言 今天小编为大家分享Kubernets Calico CNI Plugin的源码学习笔记,希望对正在学习k8s相关部分的同学有所帮助: PS:丰富的一线技术.多元化的表现形式,尽在" ...

  7. Kubernetes 学习总结(19)—— Kubernetes 集群管理平台如何选择?Rancher vs KubeSphere

    前言 Kubernetes(K8s)集群管理平台都是基于 Kubernetes 提供功能,可以说他们是在 K8s 的基础上封装了一层更为友好的操作方式.他们都是为了降低 k8s 集群运维复杂度,降低运 ...

  8. Kubernetes学习总结(16)—— Kubernetes 实战之部署 Redis 集群

    一.问题分析 本质上来说在 k8s 上部署一个 redis 集群和部署一个普通应用没有什么太大的区别,但需要注意下面几个问题: Redis 是一个有状态应用:这是部署 redis 集群时我们最需要注意 ...

  9. Kubernetes学习之路目录

    Kubernetes基础篇 环境说明 版本说明 系统环境 Centos 7.2 Kubernetes版本 v1.11.2 Docker版本 v18.09 Kubernetes学习之路(一)之概念和架构 ...

最新文章

  1. 【译】Spring 官方教程:Spring Security 架构
  2. python调用gitlab api自动合并分支_Python3 如何使用 GitLab API 进行批量的合并分支
  3. 《精通正则表达式》读书笔记(1)
  4. 国内大公司的开源项目( 阿里 腾讯 百度 新浪 搜狐 豆瓣 大众点评)
  5. 北斗导航 | 卫星信号的跟踪与解调
  6. 用最小二乘法拟合任意次函数曲线(C#)
  7. 使用jOOQ的MockDataProvider破解简单的JDBC ResultSet缓存
  8. python编写代码_用 Python 编写干净、可测试、高质量的代码
  9. salesforce php,具有自动登录功能的Salesforce php REST API
  10. 使用live555制作rtsp客户端,捕获h264等解码
  11. HTML5新控件 - 日期和时间选择输入
  12. python——问题解决:读取excel文件字符串,写入txt时乱码
  13. 无人机倾斜摄影三维建模过程及方案
  14. 指针(一)(基本概念)
  15. C语言 与 或 非
  16. matlab 曲线 标注,请问关于Matlab曲线标注问题
  17. cocoscreator 模拟点击
  18. Axure 8.0 授权码
  19. Allegro(17.2)——常用菜单栏(3)
  20. 将文件夹下所有子文件夹中的sdf转mol2

热门文章

  1. OpenHD改造实现廉价高清数字图传(树莓派+PC )—(三)OpenVG和libshapes在PC上的移植
  2. 电气防火限流保护器ASCP 40A 汽车充电桩保护装置
  3. IDEA下运行Web项目 页面出现中文乱码
  4. git下载uniapp+vk-unicloud前端项目后如何下载vk-unicloud插件
  5. android datepicker 监听,DatePicker及其监听
  6. 数电5_4——触发器总结
  7. 美国“新蛋”成都孵化新公司
  8. GigE Vision,GenICam,以及相机的POE供电
  9. Picasso图片下载缓存库的使用心得
  10. 移动支付平台间接口报文解析技术及平台交易处理项目