K8S控制器介绍与使用

K8S逻辑架构图

Kubernetes主要由以下几个核心组件组成:

  • etcd保存了整个集群的状态;

  • apiserver提供了资源操作的唯一入口,并提供认证、授权、访问控制、API注册和发现等机制;

  • controller manager负责维护集群的状态,比如故障检测、自动扩展、滚动更新等;

  • scheduler负责资源的调度,按照预定的调度策略将Pod调度到相应的机器上;

  • kubelet负责维护容器的生命周期,同时也负责Volume(CVI)和网络(CNI)的管理;

  • Container runtime负责镜像管理以及Pod和容器的真正运行(CRI);

  • kube-proxy负责为Service提供cluster内部的服务发现和负载均衡;
    除了核心组件,还有一些推荐的Add-ons:

  • kube-dns负责为整个集群提供DNS服务

  • Ingress Controller为服务提供外网入口

  • Heapster提供资源监控

  • Dashboard提供GUI

  • Federation提供跨可用区的集群

  • Fluentd-elasticsearch提供集群日志采集、存储与查询

CNI( 容器网络接口,提供网络资源)

CNI是Container Network Interface的是一个标准的,通用的接口。 CNI用于连接容器管理系统和网络插件。CNI的工作是从容器管理系统处获取运行时信息,包括network namespace的路径,容器ID以及network interface name,再从容器网络的配置文件中加载网络配置信息,再将这些信息传递给对应的插件,由插件进行具体的网络配置工作,并将配置的结果再返回到容器管理系统中。

CNI插件是可执行文件,由被kubelet调用。启动kubelet --network-plugin=cni,–cni-conf-dir 指定networkconfig配置,默认路径是:/etc/cni/net.d,并且,–cni-bin-dir 指定plugin可执行文件路径,默认路径是:/opt/cni/bin;

CNI plugin 只需要通过 CNI 库实现两类方法, 一类事创建容器时调用, 一类是删除容器时调用.

CNI的接口中包括以下几个方法:type CNI interface {AddNetworkList(net *NetworkConfigList, rt *RuntimeConf) (types.Result, error)DelNetworkList(net *NetworkConfigList, rt *RuntimeConf) errorAddNetwork(net *NetworkConfig, rt *RuntimeConf) (types.Result, error)DelNetwork(net *NetworkConfig, rt *RuntimeConf) error
}
该接口只有四个方法,添加网络、删除网络、添加网络列表、删除网络列表。

Overlay 模式

Overlay指的是一种传统网络架构上叠加的虚拟化技术,底层有(NVGRE和VXLAN等技术),在的典型特征是容器独立于主机的 IP 段,这个 IP 段进行跨主机网络通信时是通过在主机之间创建隧道的方式,将整个容器网段的包全都封装成底层的物理网络中主机之间的包。该方式的好处在于它不依赖于底层网络;

扩展资料:http://www.h3c.com/cn/d_201501/852551_30008_0.htm

路由模式

中主机和容器也分属不同的网段,它与 Overlay 模式的主要区别在于它的跨主机通信是通过路由打通,无需在不同主机之间做一个隧道封包。但路由打通就需要部分依赖于底层网络,比如说要求底层网络有二层可达的一个能力;

Underlay

模式中容器和宿主机位于同一层网络,两者拥有相同的地位。容器之间网络的打通主要依靠于底层网络。因此该模式是强依赖于底层能力的。

k8s网络之Flannel网络 k8s网络之Calico网络 https://www.cnblogs.com/goldsunshine/p/10740928.html

原文链接:https://blog.csdn.net/valada/article/details/104786619

参考地址:https://blog.csdn.net/zhonglinzhang/article/details/82697524

https://zhuanlan.zhihu.com/p/33390023

https://blog.csdn.net/valada/article/details/104786619

CRI (容器运行时接口,提供计算资源)

容器运行时接口(Container Runtime Interface),用于解除K8S和容器的耦合性;

CRI中定义了容器镜像的服务的接口

  • RuntimeService:容器和Sandbox运行时管理
  • ImageService:提供了从镜像仓库拉取、查看、和移除镜像的RPC。
cri-o:同时兼容OCI和CRI的容器运行时
cri-containerd:基于Containerd的Kubernetes CNI实现
rkt:由于CoreOS主推的用来跟docker抗衡的容器运行时
frakti:基于hypervisor的CRI
docker:kuberentes最初就开始支持的容器运行时,目前还没完全从kubelet中解耦,docker公司同时推广了OCI标准
clear-containers:由Intel推出的同时兼容OCI和CRI的容器运行时
kata-containers:符合OCI规范同时兼容CRI

在Kubernetes1.9中的CRI接口在api.proto中定义

// Runtime service defines the public APIs for remote container runtimes
service RuntimeService {// Version returns the runtime name, runtime version, and runtime API version.rpc Version(VersionRequest) returns (VersionResponse) {}// RunPodSandbox creates and starts a pod-level sandbox. Runtimes must ensure// the sandbox is in the ready state on success.rpc RunPodSandbox(RunPodSandboxRequest) returns (RunPodSandboxResponse) {}// StopPodSandbox stops any running process that is part of the sandbox and// reclaims network resources (e.g., IP addresses) allocated to the sandbox.// If there are any running containers in the sandbox, they must be forcibly// terminated.// This call is idempotent, and must not return an error if all relevant// resources have already been reclaimed. kubelet will call StopPodSandbox// at least once before calling RemovePodSandbox. It will also attempt to// reclaim resources eagerly, as soon as a sandbox is not needed. Hence,// multiple StopPodSandbox calls are expected.rpc StopPodSandbox(StopPodSandboxRequest) returns (StopPodSandboxResponse) {}// RemovePodSandbox removes the sandbox. If there are any running containers// in the sandbox, they must be forcibly terminated and removed.// This call is idempotent, and must not return an error if the sandbox has// already been removed.rpc RemovePodSandbox(RemovePodSandboxRequest) returns (RemovePodSandboxResponse) {}// PodSandboxStatus returns the status of the PodSandbox. If the PodSandbox is not// present, returns an error.rpc PodSandboxStatus(PodSandboxStatusRequest) returns (PodSandboxStatusResponse) {}// ListPodSandbox returns a list of PodSandboxes.rpc ListPodSandbox(ListPodSandboxRequest) returns (ListPodSandboxResponse) {}// CreateContainer creates a new container in specified PodSandboxrpc CreateContainer(CreateContainerRequest) returns (CreateContainerResponse) {}// StartContainer starts the container.rpc StartContainer(StartContainerRequest) returns (StartContainerResponse) {}// StopContainer stops a running container with a grace period (i.e., timeout).// This call is idempotent, and must not return an error if the container has// already been stopped.// TODO: what must the runtime do after the grace period is reached?rpc StopContainer(StopContainerRequest) returns (StopContainerResponse) {}// RemoveContainer removes the container. If the container is running, the// container must be forcibly removed.// This call is idempotent, and must not return an error if the container has// already been removed.rpc RemoveContainer(RemoveContainerRequest) returns (RemoveContainerResponse) {}// ListContainers lists all containers by filters.rpc ListContainers(ListContainersRequest) returns (ListContainersResponse) {}// ContainerStatus returns status of the container. If the container is not// present, returns an error.rpc ContainerStatus(ContainerStatusRequest) returns (ContainerStatusResponse) {}// UpdateContainerResources updates ContainerConfig of the container.rpc UpdateContainerResources(UpdateContainerResourcesRequest) returns (UpdateContainerResourcesResponse) {}// ExecSync runs a command in a container synchronously.rpc ExecSync(ExecSyncRequest) returns (ExecSyncResponse) {}// Exec prepares a streaming endpoint to execute a command in the container.rpc Exec(ExecRequest) returns (ExecResponse) {}// Attach prepares a streaming endpoint to attach to a running container.rpc Attach(AttachRequest) returns (AttachResponse) {}// PortForward prepares a streaming endpoint to forward ports from a PodSandbox.rpc PortForward(PortForwardRequest) returns (PortForwardResponse) {}// ContainerStats returns stats of the container. If the container does not// exist, the call returns an error.rpc ContainerStats(ContainerStatsRequest) returns (ContainerStatsResponse) {}// ListContainerStats returns stats of all running containers.rpc ListContainerStats(ListContainerStatsRequest) returns (ListContainerStatsResponse) {}// UpdateRuntimeConfig updates the runtime configuration based on the given request.rpc UpdateRuntimeConfig(UpdateRuntimeConfigRequest) returns (UpdateRuntimeConfigResponse) {}// Status returns the status of the runtime.rpc Status(StatusRequest) returns (StatusResponse) {}
}// ImageService defines the public APIs for managing images.
service ImageService {// ListImages lists existing images.rpc ListImages(ListImagesRequest) returns (ListImagesResponse) {}// ImageStatus returns the status of the image. If the image is not// present, returns a response with ImageStatusResponse.Image set to// nil.rpc ImageStatus(ImageStatusRequest) returns (ImageStatusResponse) {}// PullImage pulls an image with authentication config.rpc PullImage(PullImageRequest) returns (PullImageResponse) {}// RemoveImage removes the image.// This call is idempotent, and must not return an error if the image has// already been removed.rpc RemoveImage(RemoveImageRequest) returns (RemoveImageResponse) {}// ImageFSInfo returns information of the filesystem that is used to store images.rpc ImageFsInfo(ImageFsInfoRequest) returns (ImageFsInfoResponse) {}

CSI:容器存储接口,提供存储资源 CSI 代表容器存储接口,CSI 试图建立一个行业标准接口的规范,借助 CSI 容器编排系统(CO)可以将任意存储系统暴露给自己的容器工作负载。

csi 卷类型是一种 in-tree(即跟其它存储插件在同一个代码路径下,随 Kubernetes 的代码同时编译的) 的 CSI 卷插件,用于 Pod 与在同一节点上运行的外部 CSI 卷驱动程序交互。部署 CSI 兼容卷驱动后,用户可以使用 csi 作为卷类型来挂载驱动提供的存储。

CSI 持久化卷支持是在 Kubernetes v1.9 中引入的,作为一个 alpha 特性,必须由集群管理员明确启用。换句话说,集群管理员需要在 apiserver、controller-manager 和 kubelet 组件的 “–feature-gates =” 标志中加上 “CSIPersistentVolume = true”。

CSI 持久化卷具有以下字段可供用户指定:

  • driver:一个字符串值,指定要使用的卷驱动程序的名称。必须少于 63 个字符,并以一个字符开头。驱动程序名称可以包含 “.”、“-”、“_” 或数字。

  • volumeHandle:一个字符串值,唯一标识从 CSI 卷插件的 CreateVolume 调用返回的卷名。随后在卷驱动程序的所有后续调用中使用卷句柄来引用该卷。

  • readOnly:一个可选的布尔值,指示卷是否被发布为只读。默认是 false。

对象管理与配置格式

K8S以对象的形式描述各种资源,多数对象都可以在 yaml 文件中作为一种 API 类型来配置

类别 名称
资源对象 Pod、ReplicaSet、ReplicationController、Deployment、StatefulSet、DaemonSet、Job、CronJob、HorizontalPodAutoscaling、Node、Namespace、Service、Ingress、Label、CustomResourceDefinition
存储对象 Volume、PersistentVolume、Secret、ConfigMap
策略对象 SecurityContext、ResourceQuota、LimitRange
身份对象 ServiceAccount、Role、ClusterRole

每个 Kubernetes 对象包含两个嵌套的对象字段,它们负责管理对象的配置:对象 spec 和 对象 status

  • spec 必须提供,它描述了对象的 期望状态—— 希望对象所具有的特征。
  • status 描述了对象的 实际状态,它是由 Kubernetes 系统提供和更新。

在任何时刻,Kubernetes 控制平面一直处于活跃状态,管理着对象的实际状态以与我们所期望的状态相匹配

必需字段

在想要创建的 Kubernetes 对象对应的 .yaml 文件中,需要配置如下的字段:

  • apiVersion - 创建该对象所使用的 Kubernetes API 的版本

  • kind - 想要创建的对象的类型

  • metadata - 帮助识别对象唯一性的数据,包括一个 name 字符串、UID 和可选的 namespace

示例

apiVersion: apps/v1beta1 #指定k8sapi版本
kind: Deployment 指定控制器
metadata:  #标识一下唯一性name: nginx-deployment
spec: #开始描述对象的期望数量replicas: 3 #期望的副本数量minReadySeconds: 0 #指定新的pod就绪多久后才认为这个pod正常运行了template: # 指定一下模板(PodTemplateSpec),k8s根据指定的模板创建podmetadata: #指定模板唯一标识labels:app: nginxspec: containers: #指定一下容器- name: nginx #指定名称image: nginx:1.7.9 指定镜像ports: #指定端口- containerPort: 80

YAML配置api参考地址:https://kubernetes.io/docs/reference/kubernetes-api/workload-resources/pod-v1/#PodSpec

ReplicationController 和 ReplicaSet

ReplicationController 用来确保容器应用的副本数始终保持在用户定义的副本数,即如果有容器异常退出,会自动创建新的 Pod 来替代;而如果异常多出来的容器也会自动回收。

在新版本的 Kubernetes 中建议使用 ReplicaSet 来取代 ReplicationController。ReplicaSet 跟 ReplicationController 没有本质的不同,只是名字不一样,并且 ReplicaSet 支持集合式的 selector。

虽然 ReplicaSet 可以独立使用,但一般还是建议使用 Deployment 来自动管理 ReplicaSet。

配置示例

apiVersion: extensions/v1beta1 #指定k8s版本
kind: ReplicaSet 指定对象
metadata:name: frontend 指定唯一标识labels:  #设定该对象的标签group: a0000number: a00001
spec: ##描述配置信息replicas: 3 #副本数量#标签选择器#ReplicaSet和ReplicationController的区别,只有ReplicaSet才有selector: #matchExpressions 的一个元素,其键字段为“key”,运算符为“In”,values 数组仅包含“value”matchLabels:group: a0000#matchExpressions 是标签选择器要求的列表,内部是and运算,可以写很多个matchExpressions:- {key: tier, operator: In, values: [frontend]}template: #指定模板metadata: #指定唯一标识labels:app: guestbooktier: frontendspec:containers: ##指定多个容器- name: php-redis #指定容器名称image: gcr.io/google_samples/gb-frontend:v3 #指定镜像resources:requests: #需求限制cpu: 100m #指定100毫核memory: 100Milimits: #最大限制,需要大于等于requests配置cpu: 100mmemory: 100Mienv:- name: GET_HOSTS_FROMvalue: dns# If your cluster config does not include a dns service, then to# instead access environment variables to find service host# info, comment out the 'value: dns' line above, and uncomment the# line below.# value: envports:- containerPort: 80

K8s的资源:

  • CPU

​ 2核2线程的CPU,可被系统识别为4个逻辑CPU,在K8s中对CPU的分配限制是对逻辑CPU做分片限制的。也就是说分配给容器一个CPU,实际是分配一个逻辑CPU。
而且1个逻辑CPU还可被单独划分子单位,即 1个逻辑CPU,还可被划分为1000个millicore(毫核)
豪核:可简单理解为将CPU的时间片做逻辑分割,每一段时间片就是一个豪核心。
所以:500m 就是500豪核心,即0.5个逻辑CPU.

  • 内存:
    K,M,G,T,P,E #通常这些单位是以1000为换算标准的。
    Ki, Mi, Gi, Ti, Pi, Ei #这些通常是以1024为换算标准的。

Deployment

Deployment 为 Pod 和 ReplicaSet 提供了一个声明式定义(declarative)方法,用来替代以前的 ReplicationController 来方便的管理应用。典型的应用场景包括:

  • 定义 Deployment 来创建 Pod 和 ReplicaSet

  • 滚动升级和回滚应用

  • 扩容和缩容

  • 暂停和继续 Deployment

注:Deployment是一种为无状态服务而设计

配置示例

apiVersion: extensions/v1beta1
kind: Deployment
metadata:name: nginx-deployment
spec:replicas: 3template:metadata:labels:app: nginxspec:containers:- name: nginximage: nginx:1.7.9ports:- containerPort: 80
  • 执行扩容:
#手动扩容
kubectl scale deployment nginx-deployment --replicas 10
#设置自动扩展
kubectl autoscale deployment nginx-deployment --min=10 --max=15 --cpu-percent=80
  • 更新镜像
kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
  • 回滚
kubectl rollout undo deployment/nginx-deployment

StatefulSet

StatefulSet 作为 Controller 为 Pod 提供唯一的标识。它可以保证部署和 scale 的顺序,是为了解决有状态服务的问题

StatefulSet 适用于有以下某个或多个需求的应用:

  • 稳定,唯一的网络标志。

  • 稳定,持久化存储。

  • 有序,优雅地部署和 scale。

  • 有序,优雅地删除和终止。

  • 有序,自动的滚动升级。

StatefulSet中每个Pod的DNS格式为

statefulSetName-{0…N-1}.serviceName.namespace.svc.cluster.local

其中

  • serviceName为Headless Service的名字

  • 0…N-1为Pod所在的序号,从0开始到N-1

  • statefulSetName为StatefulSet的名字

  • namespace为服务所在的namespace,Headless Servic和StatefulSet必须在相同的namespace

  • .cluster.local为Cluster Domain

什么是 DaemonSet?

DaemonSet 确保全部(或者一些)Node 上运行一个 Pod 的副本。当有 Node 加入集群时,也会为他们新增一个 Pod 。当有 Node 从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。

使用 DaemonSet 的一些典型用法:

  • 运行集群存储 daemon,例如在每个 Node 上运行 glusterd、ceph。

  • 在每个 Node 上运行日志收集 daemon,例如fluentd、logstash。

  • 在每个 Node 上运行监控 daemon,例如 Prometheus Node Exporter、collectd、Datadog 代理、New Relic 代理,或 Ganglia gmond。

一个简单的用法是,在所有的 Node 上都存在一个 DaemonSet,将被作为每种类型的 daemon 使用。 一个稍微复杂的用法可能是,对单独的每种类型的 daemon 使用多个 DaemonSet,但具有不同的标志,和/或对不同硬件类型具有不同的内存、CPU要求。

Job

Job负责批处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个Pod成功结束。

Job Spec格式

  • spec.template格式同Pod

  • RestartPolicy仅支持Never或OnFailure

  • 单个Pod时,默认Pod成功运行后Job即结束

  • .spec.completions标志Job结束需要成功运行的Pod个数,默认为1

  • .spec.parallelism标志并行运行的Pod的个数,默认为1

  • spec.activeDeadlineSeconds标志失败Pod的重试最大时间,超过这个时间不会继续重试

一个简单的例子:

apiVersion: batch/v1
kind: Job
metadata:name: pi
spec:template:metadata:name: pispec:containers:- name: piimage: perlcommand: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]restartPolicy: Never
$ kubectl create -f ./job.yaml
job "pi" created
$ pods=$(kubectl get pods --selector=job-name=pi --output=jsonpath={.items..metadata.name})
$ kubectl logs $pods -c pi
3.141592653589793238462643383279502...

CronJob

Cron Job 管理基于时间的 Job,即:

  • 在给定时间点只运行一次
  • 周期性地在给定时间点运行

一个 CronJob 对象类似于 crontab (cron table)文件中的一行。它根据指定的预定计划周期性地运行一个 Job,格式可以参考 Cron 。

CronJob Spec

  • .spec.schedule:调度,必需字段,指定任务运行周期,格式同 Cron

  • .spec.jobTemplate:Job 模板,必需字段,指定需要运行的任务,格式同 Job

  • .spec.startingDeadlineSeconds :启动 Job 的期限(秒级别),该字段是可选的。如果因为任何原因而错过了被调度的时间,那么错过执行时间的 Job 将被认为是失败的。如果没有指定,则没有期限

  • .spec.concurrencyPolicy:并发策略,该字段也是可选的。它指定了如何处理被 Cron Job 创建的 Job 的并发执行。只允许指定下面策略中的一种:注意,当前策略只能应用于同一个 Cron Job 创建的 Job。如果存在多个 Cron Job,它们创建的 Job 之间总是允许并发运行。

    • Allow(默认):允许并发运行 Job
    • Forbid:禁止并发运行,如果前一个还没有完成,则直接跳过下一个
    • Replace:取消当前正在运行的 Job,用一个新的来替换
  • .spec.suspend :挂起,该字段也是可选的。如果设置为 true,后续所有执行都会被挂起。它对已经开始执行的 Job 不起作用。默认值为 false。

  • .spec.successfulJobsHistoryLimit 和 .spec.failedJobsHistoryLimit :历史限制,是可选的字段。它们指定了可以保留多少完成和失败的 Job。默认情况下,它们分别设置为 3 和 1。设置限制的值为 0,相关类型的 Job 完成后将不会被保留。

apiVersion: batch/v1beta1
kind: CronJob
metadata:name: hello
spec:schedule: "*/1 * * * *"jobTemplate:spec:template:spec:containers:- name: helloimage: busyboxargs:- /bin/sh- -c- date; echo Hello from the Kubernetes clusterrestartPolicy: OnFailure

启动删除

kubectl run hello --schedule="*/1 * * * *" --restart=OnFailure --image=busybox -- /bin/sh -c "date; echo Hello from the Kubernetes cluster"
kubectl delete cronjob hello

K8S控制器介绍与使用相关推荐

  1. k8s控制器模式介绍

    k8s控制器模式介绍

  2. 学习笔记之-Kubernetes(K8S)介绍,集群环境搭建,Pod详解,Pod控制器详解,Service详解,数据存储,安全认证,DashBoard

    笔记来源于观看黑马程序员Kubernetes(K8S)教程 第一章 kubernetes介绍 应用部署方式演变 在部署应用程序的方式上,主要经历了三个时代: 传统部署:互联网早期,会直接将应用程序部署 ...

  3. k8s 基础介绍及概念

    k8s 的介绍 k8s 的介绍 容器化相对于传统虚拟化优势 选择docker容器部署要使用k8s的原因 k8s Master节点和Node节点各个节点组件间的关系 ​Master节点组件介绍 Node ...

  4. K8S组件介绍及安装

    K8S组件介绍以及安装 一.K8S组件 1. 组件作用 1.1 master组件 1.2 node组件 1.3 插件组件 1.3.1 kubeDNS 1.3.2 Dashboard(Web界面) 1. ...

  5. Go微服务架构实战-中篇 1. k8s架构介绍

    Go微服务架构实战-公粽号:[堆栈future] 本系列文章主要是针对云原生领域微服务架构的实战,包括网关,k8s,etcd以及grpc等相关技术的应用,同时也会把服务发现与注册,熔断,降级,限流以及 ...

  6. (20)Zynq FPGA Quad-SPI闪存控制器介绍

    1.1 Zynq FPGA Quad-SPI闪存控制器介绍 1.1.1 本节目录 1)本节目录: 2)本节引言: 3)FPGA简介: 4)Zynq FPGA Quad-SPI闪存控制器介绍: 5)结束 ...

  7. (16)Zynq FPGA SD控制器介绍

    1.1 Zynq FPGA SD控制器介绍 1.1.1 本节目录 1)本节目录: 2)本节引言: 3)FPGA简介: 4)Zynq FPGA SD控制器介绍: 5)结束语. 1.1.2 本节引言 &q ...

  8. (13)Zynq DDR控制器介绍

    1.1 Zynq DDR控制器介绍 1.1.1 本节目录 1)本节目录: 2)本节引言: 3)FPGA简介: 4)Zynq DDR控制器介绍: 5)结束语. 1.1.2 本节引言 "不积跬步 ...

  9. (12)Zynq CAN控制器介绍

    1.1 Zynq CAN控制器介绍 1.1.1 本节目录 1)本节目录: 2)本节引言: 3)FPGA简介: 4)Zynq CAN控制器介绍: 5)结束语. 1.1.2 本节引言 "不积跬步 ...

最新文章

  1. win10 修改win登录logo_技巧:分享自己使用Win10过程中,一些实用小技巧
  2. Win8Metro(C#)数字图像处理--2.14Prewitt 边缘检测
  3. linux tracepoint例子,tracepoint介绍
  4. MySQL ceil()函数
  5. 利用 VMware vRealize - 构建和优化云管理
  6. 【Git】Git-常用命令备忘录(二)
  7. Tomcat安装与环境变量的配置-Linux+windows
  8. kotlin 泛型约束
  9. 洗头 Wet Hair
  10. python基础教程doc_python基础教程之Word Cloud (词云) - Python|python基础教程|python入门|python教程...
  11. CV | Max Flow / Min Cut 最大流最小割算法学习
  12. 魔点人脸识别智慧工地实名制考勤管理系统
  13. 效率低?响应慢?报表工具痛点及其解决方案
  14. 局域网内两台电脑无法共享文件问题
  15. 安卓桌面软件哪个好_每日提醒软件哪个好?电脑上有什么好用的可以每天提醒的桌面便签软件...
  16. 测试手机运行速度的软件,你的手机合格了吗 两款手机性能测试软件横评
  17. 离职,我应该做什么?
  18. 信息论——JS散度(Jensen-Shannon)
  19. 一款APP从设计稿到切图过程全方位揭秘 Mark
  20. Vue单页面中进行业务数据的上报

热门文章

  1. 居家健康管理小能手——智能体脂秤
  2. LOL代练检测——2019腾讯游戏安全技术竞赛初赛记录
  3. ERROR o.s.d.redis.listener.RedisMessageListenerContainer
  4. ros中关于ros::Rate 和ros::spin()等的理解
  5. 家用路由器电源适配器9v和12v可以通用吗?
  6. python web开发--web前端开发介绍
  7. 朴素贝叶斯分类、半朴素贝叶斯分类算法
  8. - 并查集详解(第二节)
  9. RTOS内功修炼记(九)—— 任务入口函数执行完毕之后去哪里?
  10. 7个项目管理强力工具介绍