数据专栏

智能大数据搬运工,你想要的我们都有

科技资讯:

科技学院:

科技百科:

科技书籍:

网站大全:

软件大全:

根据 Gartner 对全球 CIO 的调查结果显示,人工智能将成为 2019 年组织革命的颠覆性力量。对于人工智能来说,算力即正义,成本即能力,利用 Docker 和 Kubernetes 代表云原生技术为 AI 提供了一种新的工作模式,将 GPU 机器放到统一的资源池进行调度和管理,这避免了GPU 资源利用率低下和人工管理的成本。因此,全球主要的容器集群服务厂商 Kubernetes 都提供了 Nvidia GPU 容器集群调度能力,但是通常都是将一个 GPU 卡分配给一个容器。这虽然可以实现比较好的隔离性,确保使用 GPU 的应用不会被其他应用影响;对于深度学习模型训练的场景也非常适合,但是,针对模型开发和模型预测的场景还是会显得比较浪费。基于此,大家有了共享 GPU 的集群调度需求。
Kubernetes 共享 GPU 集群调度
共享 GPU 的集群调度就是能够让更多的模型开发和预测服务共享同一个 GPU 卡,进而提高集群中 Nvidia GPU 的利用率。而这就需要提供 GPU 资源的划分,而这里 GPU 资源划分的维度指的就是 GPU 显存和 Cuda Kernel 线程的划分。通常在集群级别谈支持共享 GPU 是以下两件事情:
1.调度
2.隔离,我们这里主要讨论的是调度,隔离的方案目前需要用户通过应用限制(比如使用 Tensorflow 的per_process_gpu_memory_fraction 来控制),未来会提供基于 Nvidia 的 MPS 的可选项, 也会考虑 GPU 的方案。
而对于细粒度的 GPU 卡调度,目前 Kubernetes 社区并没有很好的方案,这是由于 Kubernetes 对于 GPU 这类扩展资源的定义仅仅支持整数粒度的加加减减,无法支持复杂资源的分配。比如用户希望使用 Pod A 占用半张 GPU卡,这在目前 Kubernetes 的架构设计中无法实现资源分配的记录和调用。这里挑战是多卡 GPU 共享是实际矢量资源问题,而 Extened Resource 是标量资源的描述。
针对此问题,我们设计了一个 Out Of Tree 的共享 GPU 调度方案,该方案依赖于 Kubernetes 的现有的工作机制: Extended Resource 定义 Scheduler Extender 机制 Device Plugin 机制 Kubectl 的扩展机制
这个 GPU 共享调度扩展的好处是:利用 Kubernetes 的扩展和插件机制实现,对于 API Server,Scheduler,Controller Manager 以及 Kubelet 等核心组件没有侵入性。这就方便了使用者可以在不同 Kubernetes 版本上应用这个方案,无需 rebase 代码和重新构建 Kubernetes 二进制包。
用户场景 集群管理员:“我想提高集群的 GPU 使用率;在开发过程中,多个用户共享模型开发环境。” 应用开发人员:“我希望能够同时在 Volta GPU 上运行多个推理任务。”
[]( https://www.atatech.org/articles/132268#2) 目标 能够让使用者通过 API 描述对于一个可共享资源的申请, 并能实现该种资源的调度
[]( https://www.atatech.org/articles/132268#3) 非目标 不支持该共享资源的隔离 不支持超卖
[]( https://www.atatech.org/articles/132268#4) 设计原则 明确问题简化设计,第一步只负责调度和部署,后续再实现运行时显存管控。
有很多的客户明确的诉求是首先可以支持多AI应用可以调度到同一个 GPU 上,他们可以接受从应用级别控制显存的大小,利用类似 gpu_options.per_process_gpu_memory_fraction 控制应用的显存使用量。那我们要解决的问题就先简化到以显存为调度标尺,并且把显存使用的大小以参数的方式传递给容器内部。 不做侵入式修改
本设计中不会修改 Kubernetes 核心的 Extended Resource 的设计, Scheduler 的实现,Device Plugin 的机制以及 Kubelet 的相关设计。重用 Extended Resource 描述共享资源的申请 API。这样的好处在于提供一个可以移植的方案,用户可以在原生 Kubernetes 上使用这个方案。 按显存和按卡调度的方式可以在集群内并存,但是同一个节点内是互斥的,不支持二者并存;要么是按卡数目,要么是按显存分配。
详细设计
[]( https://www.atatech.org/articles/132268#6) 前提: 依旧延用 Kubernetes Extended Resource 定义,但是衡量维度最小单位从 1 个 GPU 卡变为 GPU 显存的 MiB。如果所节点使用的 GPU 为单卡 16GiB 显存,它对应的资源就是 16276MiB; 由于用户对于共享GPU的诉求在于模型开发和模型预测场景,在此场景下,用户申请的GPU资源上限不会超过一张卡,也就是申请的资源上限为单卡。
而我们的工作首先是定义了两个新的 Extended Resource: 第一个是 gpu-mem, 对应的是 GPU 显存;第二个是 gpu-count,对应的是 GPU 卡数。 通过两个标量资源描述矢量资源, 并且结合这一资源,提供支持共享 GPU 的工作机制。下面是基本的架构图:
[]( https://www.atatech.org/articles/132268#7) 核心功能模块: GPU Share Scheduler Extender : 利用 Kubernetes 的调度器扩展机制,负责在全局调度器 Filter 和 Bind 的时候判断节点上单个 GPU 卡是否能够提供足够的 GPU Mem,并且在 Bind 的时刻将 GPU 的分配结果通过 annotation 记录到 Pod Spec 以供后续 Filter 检查分配结果。 GPU Share Device Plugin : 利用 Device Plugin 机制,在节点上被 Kubelet 调用负责 GPU 卡的分配,依赖 scheduler Extender 分配结果执行。
[]( https://www.atatech.org/articles/132268#8) 具体流程: 资源上报
GPU Share Device Plugin 利用 nvml 库查询到 GPU 卡的数量和每张 GPU 卡的显存, 通过 ListAndWatch() 将节点的 GPU 总显存(数量 显存)作为另外 Extended Resource 汇报给 Kubelet; Kubelet 进一步汇报给 Kubernetes API Server。 举例说明,如果节点含有两块 GPU 卡,并且每块卡包含 16276MiB,从用户的角度来看:该节点的 GPU 资源为 16276 2 = 32552; 同时也会将节点上的 GPU 卡数量 2 作为另外一个 Extended Resource 上报。

2. 扩展调度
GPU Share Scheduler Extender 可以在分配 gpu-mem 给 Pod 的同时将分配信息以 annotation 的形式保留在 Pod spec 中,并且在过滤时刻根据此信息判断每张卡是否包含足够可用的 gpu-mem 分配。
2.1 Kubernetes 默认调度器在进行完所有过滤(filter)行为后会通过 http 方式调用 GPU Share Scheduler Extender的filter 方法, 这是由于默认调度器计算 Extended Resource 时,只能判断资源总量是否有满足需求的空闲资源,无法具体判断单张卡上是否满足需求;所以就需要由 GPU Share Scheduler Extender 检查单张卡上是否含有可用资源。

以下图为例, 在由 3 个包含两块 GPU 卡的节点组成的 Kubernetes 集群中,当用户申请 gpu-mem=8138 时,默认调度器会扫描所有节点,发现 N1 所剩的资源为 (16276 * 2 - 16276 -12207 = 4069 )不满足资源需求,N1 节点被过滤掉。

而 N2 和 N3 节点所剩资源都为 8138MiB,从整体调度的角度看,都符合默认调度器的条件;此时默认调度器会委托 GPU Share Scheduler Extender 进行二次过滤,在二次过滤中,GPU Share Scheduler Extender 需要判断单张卡是否满足调度需求,在查看 N2 节点时发现该节点虽然有 8138MiB 可用资源,但是落到每张卡上看,GPU0 和分别 GPU1 只有 4069MiB 的可用资源,无法满足单卡 8138MiB 的诉求。而 N3 节点虽然也是总共有 8138MiB 可用资源,但是这些可用资源都属于 GPU0,满足单卡可调度的需求。由此,通过 GPU Share Scheduler Extender 的筛选就可以实现精准的条件筛选。

2.2 当调度器找到满足条件的节点,就会委托 GPU Share Scheduler Extender 的 bind 方法进行节点和 Pod 的绑定,这里 Extender 需要做的是两件事情 以 binpack 的规则找到节点中最优选择的 GPU 卡 id,此处的最优含义是对于同一个节点不同的 GPU 卡,以 binpack 的原则作为判断条件,优先选择空闲资源满足条件但同时又是所剩资源最少的 GPU 卡,并且将其作为 ALIYUN_COM_GPU_MEM_IDX 保存到 Pod 的 annotation 中;同时也保存该 Pod 申请的 GPU Memory 作为 ALIYUN_COM_GPU_MEM_POD 和 ALIYUN_COM_GPU_MEM_ASSUME_TIME 保存至 Pod 的 annotation 中,并且在此时进行 Pod 和所选节点的绑定。 注意:这时还会保存 ALIYUN_COM_GPU_MEM_ASSIGNED 的 Pod annotation,它被初始化为“false”。它表示该 Pod 在调度时刻被指定到了某块 GPU 卡,但是并没有真正在节点上创建该 Pod。 ALIYUN_COM_GPU_MEM_ASSUME_TIME 代表了 指定 时间。
如果此时发现分配节点上没有 GPU 资源符合条件,此时不进行绑定,直接不报错退出,默认调度器会在 assume 超时后重新调度。 调用 Kubernetes API 执行节点和 Pod 的绑定
以下图为例,当 GPU Share Scheduler Extender 要把 gpu-mem:8138 的 Pod 和经过筛选出来的节点 N1 绑定,首先会比较不同 GPU 的可用资源,分别为 GPU0(12207),GPU1(8138),GPU2(4069),GPU3(16276),其中 GPU2 所剩资源不满足需求,被舍弃掉;而另外三个满足条件的 GPU 中, GPU1 恰恰是符合空闲资源满足条件但同时又是所剩资源最少的 GPU 卡,因此 GPU1 被选出。

3. 节点上运行
当 Pod 和节点绑定的事件被 Kubelet 接收到后,Kubelet 就会在节点上创建真正的 Pod 实体,在这个过程中, Kubelet 会调用 GPU Share Device Plugin 的 Allocate 方法, Allocate 方法的参数是 Pod 申请的 gpu-mem。而在 Allocate 方法中,会根据 GPU Share Scheduler Extender 的调度决策运行对应的 Pod 会列出该节点中所有状态为 Pending 并且 ALIYUN_COM_GPU_MEM_ASSIGNED 为 false 的 GPU Share Pod 选择出其中 Pod Annotation 的 ALIYUN_COM_GPU_MEM_POD 的数量与 Allocate 申请数量一致的 Pod。如果有多个符合这种条件的 Pod,就会选择其中 ALIYUN_COM_GPU_MEM_ASSUME_TIME 最早的 Pod。 将该 Pod 的 annotation ALIYUN_COM_GPU_MEM_ASSIGNED 设置为 true ,并且将 Pod annotation 中的 GPU 信息转化为环境变量返回给 Kubelet 用以真正的创建 Pod。
[]( https://www.atatech.org/articles/132268#9) 相关项目
目前项目已经开源到 github.com 上
gpushare-scheduler-extender
gpushare-device-plugin

部署
请参照 部署文档
[]( https://www.atatech.org/articles/132268#11) 测试样例 首先创建一个使用 aliyun.com/gpu-mem 的应用 apiVersion: apps/v1 kind: Deployment metadata: name: binpack-1 labels: app: binpack-1 spec: replicas: 1 selector: # define how the deployment finds the pods it manages matchLabels: app: binpack-1 template: # define the pods specifications metadata: labels: app: binpack-1 spec: containers: - name: binpack-1 image: cheyang/gpu-player:v2 resources: limits: # MiB aliyun.com/gpu-mem: 1024


使用
请参照 使用文档

构建
请参照 如何构建

视频 Demo

[]( https://www.atatech.org/articles/132268#15)Demo 1: 部署多个 GPU Share 的 Pod,发现他们以 binpack 的方式被放置到同一个 GPU 卡上
[]( https://www.atatech.org/articles/132268#16)Demo 2: 避免错误调度申请资源超过单个 GPU 可用资源的 Pod

Roadmap 在 Device Plugin 中提供 Nvidia MPS 的可选支持; 支持该方案可以在由 kubeadm 初始化的 Kubernetes 集群自动化部署; 提升 Scheduler Extener 的高可用性; 为 GPU, RDMA 和弹性网卡提供通用方案。
作者: jessie筱姜
原文链接
本文为云栖社区原创内容,未经允许不得转载。
云计算
2019-03-07 16:27:00
本文是Choerodon 的微服务系列推文第五篇,上一篇《 Choerodon 的微服务之路(四):深入理解微服务配置中心 》介绍了配置中心在微服务架构中的作用,本篇将介绍微服务监控的重要性和必要性。
▌文章的主要内容包括: 为什么要监控 开发者需要监控哪些 猪齿鱼的解决方案
在前面的几期的文章里,介绍了在 Choerodon 的微服务架构中,系统被拆分成多个有着独立部署能力的业务服务,每个服务可以使用不同的编程语言,不同的存储介质,来保持最低限度的集中式管理。
这样的架构决定了功能模块的部署是分布式的,不同的业务服务单独部署运行的,运行在独立的容器进程中,彼此之间通过网络进行服务调用交互。一次完整的业务流程会经过很多个微服务的处理和传递。
在这种情况下,如何监控服务的错误和异常,如何快速地定位和处理问题,以及如何在复杂的容器拓扑中筛选出用户所需要的指标,是 Choerodon 在监控中面临的首要问题。本文将会分享 Choerodon 在微服务下的监控思考,以及结合社区流行的 Spring Cloud、Kubernetes、Prometheus 等开源技术,打造的 Choerodon 的监控方案。
为什么要监控
在谈到 Choerodon 的监控之前,大家需要清楚为什么需要微服务下的监控。
传统的单体应用中,由于应用部署在具体的服务器上,开发者一般会从不同的层级对应用进行监控。比如猪齿鱼团队常用的方式是将监控分成基础设施、系统、应用、业务和用户端这几层,并对每一层分别进行监控。如下图所示。
而在微服务系统中,开发者对于监控的关心点是一样的,但是视角却发生了改变,从分层 + 机器的视角转化为以服务为中心的视角。在 Choerodon 中,传统的分层已经不太适用。服务是部署在 k8s 的 pod 中,而不是直接部署在服务器上。团队除了对服务器的监控之外,还需要考虑到 k8s 中容器的监控。同样,由于一个业务流程可能是通过一系列的业务服务而实现的,如何追踪业务流的处理也同样至关重要。
所以在微服务中,大家同样离不开监控,有效的监控能够帮开发者快速的定位故障,保护系统健康的运行。
平开发者需要监控哪些
在 Choerodon 中,将系统的使用人员分为应用的管理人员,开发人员,运维人员。而不同的人员在平台中所关心的问题则分别不同。 作为应用的管理人员,需要查看到系统中各个节点实例的运行状态以及实例中应用的状态。 作为开发人员,需要查看自己开发的服务在运行中的所有信息,也需要跟踪请求流的处理顺序和结果,并快速定位问题。 作为运维人员,需要查看系统集群中服务器的 CPU、内存、堆栈等信息。需要查看K8S集群的运行状态,同时也需要查看各个服务的运行日志。
除了这些以外,还需要监控到如下的一些信息: 服务的概览信息:服务的名称,相关的配置等基本信息。 服务的拓扑关系:服务之间的调用关系。 服务的调用链:服务之间的请求调用链。 服务的性能指标:服务的CPU,内存等。 接口的调用监控:接口的吞吐量,错误率,响应时间等。 服务的日志数据:服务运行中产生的日志异常。
简而概之,对于 Choerodon 而言,开发者将监控聚焦在指标监控,调用监控和日志监控。
猪齿鱼的解决方案
在开源社区中,有很多对监控的解决方案,比如指标监控有 Prometheus,链路监控有 zipkin、pinpoint,skywalking,日志则有 elk。
Choerodon 具有多集群多环境管理能力,Choerodon 为需要监控的集群配置监控组件,并与Choerodon 所在集群的监控组件互通以及过滤多余数据,可以最大限度地减少多集群非同一局域网的外网带宽需求。在多集群环境中仍然可以感知所管理应用的运行状态和配置预警信息。
▌指标监控
Spring Boot 的执行器包含一系列的度量指标(Metrics)接口。当你请求 metrics 端点,你可能会看到类似以下的响应: { "counter.status.200.root": 20, "counter.status.200.metrics": 3, "counter.status.200.star-star": 5, "counter.status.401.root": 4, "gauge.response.star-star": 6, "gauge.response.root": 2, "gauge.response.metrics": 3, "classes": 5808, "classes.loaded": 5808, "classes.unloaded": 0, "heap": 3728384, "heap.committed": 986624, "heap.init": 262144, "heap.used": 52765, "nonheap": 0, "nonheap.committed": 77568, "nonheap.init": 2496, "nonheap.used": 75826, "mem": 986624, "mem.free": 933858, "processors": 8, "threads": 15, "threads.daemon": 11, "threads.peak": 15, "threads.totalStarted": 42, "uptime": 494836, "instance.uptime": 489782, "datasource.primary.active": 5, "datasource.primary.usage": 0.25 }
这些系统指标具体含义如下: 系统内存总量(mem),单位:KB 空闲内存数量(mem.free),单位:KB 处理器数量(processors) 系统正常运行时间(uptime),单位:毫秒 应用上下文(应用实例)正常运行时间(instance.uptime),单位:毫秒 系统平均负载(systemload.average) 堆信息(heap,heap.committed,heap.init,heap.used),单位:KB 线程信息(threads,thread.peak,thead.daemon) 类加载信息(classes,classes.loaded,classes.unloaded) 垃圾收集信息(gc.xxx.count, gc.xxx.time)
有了这些指标,我们只需要做简单的修改,就可以使这些指标被 Prometheus 所监测到。Prometheus 是一套开源的系统监控报警框架。默认情况下 Prometheus 暴露的metrics endpoint为/prometheus。
在项目的pom.xml文件中添加依赖,该依赖包含了 micrometer 和 prometheus 的依赖,并对监控的指标做了扩充。 io.choerodon choerodon-starter-hitoa ${choerodon.starters.version}
Prometheus提供了4中不同的 Metrics 类型: Counter , Gauge , Histogram , Summary 。通过Gauge,Choerodon对程序的线程指标进行了扩充,添加了 NEW , RUNNABLE , BLOCKED , WAITING , TIMED_WAITING , TERMINATED 这几种类型,具体代码如下。 @Override public void bindTo(MeterRegistry registry) { Gauge.builder("jvm.thread.NEW.sum", threadStateBean, ThreadStateBean::getThreadStatusNEWCount) .tags(tags) .description("thread state NEW count") .register(registry); Gauge.builder("jvm.thread.RUNNABLE.sum", threadStateBean, ThreadStateBean::getThreadStatusRUNNABLECount) .tags(tags) .description("thread state RUNNABLE count") .register(registry); Gauge.builder("jvm.thread.BLOCKED.sum", threadStateBean, ThreadStateBean::getThreadStatusBLOCKEDCount) .tags(tags) .description("thread state BLOCKED count") .register(registry); Gauge.builder("jvm.thread.WAITING.sum", threadStateBean, ThreadStateBean::getThreadStatusWAITINGCount) .tags(tags) .description("thread state WAITING count") .register(registry); Gauge.builder("jvm.thread.TIMEDWAITING.sum", threadStateBean, ThreadStateBean::getThreadStatusTIMEDWAITINGCount) .tags(tags) .description("thread state TIMED_WAITING count") .register(registry); Gauge.builder("jvm.thread.TERMINATED.sum", threadStateBean, ThreadStateBean::getThreadStatusTERMINATEDCount) .tags(tags) .description("thread state TERMINATED count") .register(registry); }
▌调用监控
在微服务架构中,一个请求可能会涉及到多个服务,请求的路径则可能构成一个网状的调用链。而如果其中的某一个节点发生异常,则整个链条都可能受到影响。
针对这种情况,团队需要有一款调用链监控的工具,来支撑系统监控分布式的请求追踪。目前开源社区中有一些工具:Zipkin、Pinpoint、SkyWalking。Choerodon 使用的是 SkyWalking,它是一款国产的 APM 工具,包括了分布式追踪、性能指标分析、应用和服务依赖分析等。
Skywalking 包含 Agent 和 Collecter,具体的部署和原理在这里不在做具体的介绍,Choerodon 的服务在每个服务的 DockerFile 中,添加了对 Skywalking Agent 的支持。具体如下: FROM registry.cn-hangzhou.aliyuncs.com/choerodon-tools/javabase:0.7.1 COPY app.jar /iam-service.jar ENTRYPOINT exec java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap $JAVA_OPTS $SKYWALKING_OPTS -jar /iam-service.jar
部署时通过配置容器的环境变量 SKYWALKING_OPTS 来实现客户端的配置。
▌日志监控
日志是程序在运行中产生的遵循一定格式(通常包含时间戳)的文本数据,通常由Choerodon的服务生成,输出到不同的文件中,一般会有系统日志、应用日志、安全日志等等。这些日志分散地存储在不同的容器、机器中。当开发者在排查故障的时候,日志会帮助他们快速地定位到故障的原因。
Choerodon 采用了业界通用的日志数据管理解决方案,主要包括 elasticsearch 、 fluent-bit 、 fluentd 和 Kibana 。对于日志的采集分为如下几个步骤。
日志收集:通过 fluent-bit 读取 k8s 集群中 cluster 的日志,并进行收集。 日志过滤:通过 fluentd 将读取到的日志进行过滤,并进行缓存。 日志存储:将过滤后的日志存储至 elasticsearch 集群中。 日志展示:通过 kibana 查询 elasticsearch 中的日志数据,并用于展示。
通过端对端可视化的日志集中管理,给开发团队带来如下的一些好处: 故障查找:通过检索日志信息,定位相应的 bug ,找出解决方案。 服务分析:通过对日志信息进行统计、分析,了解服务器的负荷和服务运行状态。 数据分析:分析数据,对用户进行行为分析。
写在最后
回顾一下这篇文章,介绍了微服务监控的重要性和必要性,以及 Choerodon 是如何应对指标监控,调用监控和日志监控这三种监控的。微服务架构下的服务规模大,系统相对复杂,也使得众多开发者成为了微服务的受害者。如何做好微服务下的监控,保障系统健康地运行,我们仍有许多需要继续努力的。
更多关于微服务系列的文章,点击蓝字即可阅读 ▼ Choerodon的微服务之路(一):如何迈出关键的第一步 Choerodon的微服务之路(二):微服务网关 Choerodon 的微服务之路(三):服务注册与发现 Choerodon 的微服务之路(四):深入理解微服务配置中心
关于Choerodon猪齿鱼
Choerodon猪齿鱼 开源多云集成平台,基于开源技术Kubernetes,Istio,knative,Gitlab和Spring Cloud来实现本地和云端环境的集成,实现企业多云/混合云应用环境的一致性。平台通过提供精益敏捷、持续交付、容器环境、微服务、DevOps等能力来帮助组织团队来完成软件的生命周期管理,从而更快、更频繁地交付更稳定的软件。
大家也可以通过以下社区途径了解猪齿鱼的最新动态、产品特性,以及参与社区贡献: 官网: http://choerodon.io 论坛: http://forum.choerodon.io Github: https://github.com/choerodon 微信公众号:Choerodon猪齿鱼 微博:Choerodon猪齿鱼
欢迎加入Choerodon猪齿鱼社区,共同为企业数字化服务打造一个开放的生态平台。
云计算
2019-03-25 19:47:00
UCloud外网网关是为了承载外网IP、负载均衡等产品的外网出入向流量,当前基于Linux内核的OVS/GRE tunnel/netns/iptables等实现,很好地支撑了现有业务。同时,我们也在不断跟踪开源社区的新技术发展,并将之用于下一代外网网关的设计。这些新特性可将系统性能和管理能力再提上一档,满足未来几年的需求。在方案设计研发过程中发现,新特性存在不少缺陷和Bug,为此我们向开源社区回馈了10多个patch,并融入到kernel 5.0版本中,帮助完善kernel功能并提升稳定性。
当前业界的多租户外网网关很多都是基于OpenFlow的OpenvSwitch(OVS)方案,然而随着内核路由转发功能的不断完善,利用内核原生路由转发方式进行设计多租户外网网关系统成为一种可能。在这种方式下能有效的使用传统iproute2路由工具以及iptables、nftables等Firewall工具,并且随着SwitchDev技术的兴起,未来将网关系统迁移到Linux Switch上也成为一种可能。
现有kernel 3.x的不足
当前广泛使用的内核版本为3.x系列,例如CentOS 7全系列标准支持的内核为3.10版本,Fedora/Ubuntu等Linux发行版也有大量使用。在3.x系列内核下存在着IP tunnel管理复杂、租户隔离性能损耗等问题。
1. IP tunnel管理复杂
Linux内核创建IP tunnel设备来建立点对点的隧道连接,创建时需指定tunnel dst和 tunnel key。因为宿主机之间两两建立连接,面向宿主机的目的地址众多,这样就会导致网关节点上需要创建成千上万的tunnel设备,在大规模业务环境下,tunnel的管理将变得及其复杂。
2. 多租户隔离导致的性能下降
a. 公有云需要实现多租户隔离以确保用户间的安全和隐私。由于VPC网络下不同租户的内网地址可以重合,导致路由也有重合的可能性,此时需要通过大量的策略路由去隔离租户的路由规则,由于策略路由的链表属性,性能会随着链表长度的增加而急剧下降。
b. 由于Firewall和NAT的实现基于同样链式的iptables,性能损耗同样可观。
3. netns带来性能开销
通过netns实现租户路由和Firewall规则的隔离,但是netns会引入虚拟网卡和协议栈重入开销,使整体性能下降20%左右。
三项内核新技术
为了解决原有方案存在的困扰,我们调研了大量行业主流方案和内核上游的新动向,发现Lightweight tunneling(轻量级隧道,简称lwtunnel)、Virtual Routing Forwarding(虚拟路由转发,简称VRF)以及nftable & netfilter flow offload(流卸载)三项内核新技术的特性,可以帮助规避原方案存在的缺陷。
1. Lightweight tunneling
Linux内核在4.3版本中引入了轻量级隧道Lightweight tunneling,它提供了通过route方式设置tunnel属性的方法,这样可以避免管理大量的tunnel设备。
创建隧道设备时指定external模式,利用路由设置的轻量级隧道通过tun设备发送报文。
2. Virtual Routing Forwarding
Linux内核在4.3版本中引入了VRF的初步支持,并在4.8版本形成完备版本。Virtual Routing Forwarding虚拟路由转发,可以将一台Linux Box的物理路由器当多台虚拟路由器使用,能很好的解决租户路由隔离问题,避免直接使用策略路由。因此,可以将不同租户的网卡加入租户所属的虚拟路由器中来实现多租户的虚拟路由。
3. flow offload
Nftables是一种新的数据包分类框架,旨在替代现存的{ip,ip6,arp,eb}_tables。在nftables中,大部分工作是在用户态完成的,内核只知道一些基本指令(过滤是用伪状态机实现的)。nftables的一个高级特性就是映射,可以使用不同类型的数据并映射它们。例如,我们可以映射iif device到专用的规则集合(之前创建的存储在一个链中)。由于是hash映射的方式,可以完美的避免链式规则跳转的性能开销。
Linux内核在版本4.16引入了flow offload功能,它为IP forward提供了基于流的卸载功能。当一条新建连接完成首回合原方向和反方向的报文时,完成路由,Firewall和NAT工作后,在处理反方向首报文的forward hook,根据报文路由、NAT等信息创建可卸载flow到接收网卡ingress hook上。后续的报文可以在接收ingress hook上直接转发,不需要再进入IP stack处理。此外,将来flow offload还将支持hardware offload模式,这将极大提高系统转发性能。
方案设计与优化实践
通过对上述三项新技术的研究,我们发现可以尝试设计一套基于路由的方式,实现多租户overlay网络的外网网关。在方案设计过程中,我们也碰到了诸如lwtunnel和flow offload功能不足,以及VRF和flow offload不能一起有效的工作等问题。最终我们都设法解决了,并针对这些内核的不足提交patch给Linux开源社区。
1. lwtunnel发送报文tunnel_key丢失
**问题描述:**我们利用lwtunnel路由方式发送报文时,创建了一个external类型的gretap tunnel,我们将命令设置了id为1000,但是发送成功报文中没有tunnel_key字段。
**问题定位:**我们研究iproute2代码,发现由于TUNNEL_KEY flag并没有开放给用户态,所以iproute2工具并没有对lwtunnel路由设置TUNNEL_KEY,导致报文不会创建tunnel_key字段。
提交patch: 我们给内核和用户态iproute2分别提交patch来解决这一问题:
iptunnel: make TUNNEL_FLAGS available in uapi
https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git/commit/ ? id=1875a9ab01dfa96b06cb6649cb1ce56efa86c7cb
iproute: Set ip/ip6 lwtunnel flags
https://git.kernel.org/pub/scm/network/iproute2/iproute2.git/commit/?id=3d65cefbefc86a53877f1e6461a9461e5b8fd7b3 提交patch后,可以通过以下方式设置路由。
ip r r 2.2.2.11 via 1.1.1.11 dev tun encap ip id 1000 dst 172.168.0.1 key
2. lwtunnel对指定key的IP tunnel无效
**问题发现:**为了能有效隔离租户路由,我们给每个租户创建一个基于tunnel_key的gretap tunnel设备。如下图,创建一个tunnel_key 1000的gretap tunnel设备,把tunnel设备加入租户所属VRF,tunnel设备能有效地接收报文,但并不能发送报文。
问题定位:研究内核发现,IP tunnel在非external模式下即使指定了轻量级隧道路由,发送报文也没有使用它,导致报文路由错误被丢弃。
提交patch:
ip_tunnel: Make none-tunnel-dst tunnel port work with lwtunnel
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=d71b57532d70c03f4671dd04e84157ac6bf021b0 提交patch后,在未指定tunnel_dst的非external模式IP tunnel下,能使用轻量级隧道路由进行发送报文。
3. external IP tunnel ARP无法正常运行
**问题描述:**邻居IP tunnel进行了ARP请求,但是本端的ARP回应报文的隧道头中并没带tunnel_key字段。
**问题定位:**研究代码发现,tunnel收到了对端的ARP 请求,在发送报文ARP回复的时候会复制请求报文的tunnel信息,但是遗漏了所有tun_flags。
提交patch:
iptunnel: Set tun_flags in the iptunnel_metadata_reply from src
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=7bdca378b2301b1fc6a95c60d6d428408ae4e39e
4. Flow offload不能与DNAT有效工作
**问题描述:**Firewall创建规则从eth0收到目的地址2.2.2.11的报文,DNAT为10.0.0.7, flow offload无法工作。
**问题定位:**分析发现,客户端1.1.1.7 —> 2.2.2.7 DNAT到server 10.0.0.7,第一个reply反向报文(syc+ack)使用了错的目的地址获取反向路由
daddr = ct->tuplehash[!dir].tuple.dst.u3.ip 此时dir为反方向,所以daddr获取为原方向的目的地址,这个值是2.2.2.7, 但是由于被DNAT过,真正的路由不应该通过2.2.2.7去获取,而是应该根据10.0.0.7这个值去获取
addr = ct->tuplehash[dir].tuple.src.u3.ip
提交patch:
netfilter: nft_flow_offload: Fix reverse route lookup
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=a799aea0988ea0d1b1f263e996fdad2f6133c680 5. Flow offload不能与VRF有效工作
问题描述: 将网卡eth0和eth1加入VFR后,flow offload不起作用。
**问题定位:**查看代码发现,原方向和反方向首报文进入协议堆栈后skb->dev会设置为vrf device user1,创建flow offload规则的iif就是user1。但是offload规则下发在eth0和eth1的ingress hook上,所以后续报文在eth0和eth1的ingress hook上不能匹配flow规则。
提交patch:
netfilter: nft_flow_offload: fix interaction with vrf slave device
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=10f4e765879e514e1ce7f52ed26603047af196e2 最终,我们根据两个方向查找路由的结果,设置flow offload规则的iif和oif信息来解决此问题。
6. VRF PREROUTING hook重入问题
**问题描述:**配置网卡加入VRF,firewall ingress方向规则为接收目的地址2.2.2.11 、TCP 目的端口22的报文,egress方向规则为丢弃TCP 目的端口 22的报文。出现异常结果: 收到目的地址2.2.2.11 TCP 22目的端口的报文却被丢弃。
**问题定位:**研究发现网卡加入VRF后收到的报文会两次进入PREROUTING hook,因为在进入IP stack时会进第一次PREROUTING hook,然后被VRF设备接管后会再次进入PREROUTING hook。上述规则第一次在rule-1000-ingress chain中dst nat为10.0.0.7,第二次由于报文被DNAT后会错误的进入rule-1000-egress,导致报文被丢弃。
**提交patch:**我们给内核加了一个支持判断网卡类型的match项目,让用户态避免可知的第二次无效重入,内核态和用户态nftables分别提交了如下的patch:
netfilter: nft_meta: Add NFT_META_I/OIFKIND meta type
https://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next.git/commit/?id=0fb4d21956f4a9af225594a46857ccf29bd747bc meta: add iifkind and oifkind support
http://git.netfilter.org/nftables/commit/?id=512795a673f999fb04b84dbbbe41174e9c581430
使用方法:
nft add rule firewall rules-all meta iifkind "vrf" counter accept
原型验证
最终,我们成功地利用lwtunnel、VRF和flow offload实现多租户外网网关的原型验证。验证过程如下:
1. 首先创建原型环境。
a. netns cl模拟外网client, 地址为1.1.1.7,tunnel src 172.168.0.7,配置发送路由;
b. netns ns1模拟租户1,内网地址为10.0.0.7,外网地址为 2.2.2.11,tunnel src 172.168.0.11 tunnel_key 1000,配置发送路由;
c. netns ns2模拟租户2,内网地址为10.0.0.7,外网地址为 2.2.2.12,tunnel src 172.168.0.12 tunnel_key 2000,配置发送路由;
d. Host模拟外网网关,tunnel src 172.168.0.1,创建租户VRF user1和use2,创建租户IP tunnel tun1和tun2,配置转发路由。
原型环境图如下:
2. 创建firewall规则:
a. 租户1入向允许TCP目的端口22和ICMP访问,出向禁止访问外部TCP 22目的端口;
b. 租户2入向允许TCP端口23和ICMP访问,出向禁止访问外部TCP 23目的端口;
c. 在租户tun1和tun2设备上支持flow offload。
最终,client可以通过2.2.2.11成功访问user1 tcp 22端口服务,user1不能访问client tcp 22端口服务;client可以通过2.2.2.12成功访问user2 tcp 23端口服务,user1不能访问client tcp 23端口服务。
待后续hardware offload功能完善以及网卡厂商支持后,我们会做进一步的开发验证。
写在最后
以上是本项目涉及的部分核心问题,这些patch特性都可以在Linux kernel 5.0版本里获取。我们把这期间为Linux kernel社区贡献的patch整理成了一份列表,希望能为开发者提供帮助,读者可以点击 “阅读原文” 阅览完整patch list。
Linux作为成熟的开源套件,一直是云厂商使用的主流操作系统,但在技术的更新迭代过程中,一些新特性在实际应用上也会存在稳定性、兼容性等方面的问题。我们在研究使用上游技术的同时,也一直积极探索、丰富开源技术功能,帮助提高开源技术稳定性。并将产出持续回馈给社区,与社区共同构建一个繁荣的开源生态。
云计算
2019-03-25 17:57:00
MySql的镜像,默认情况下,MySql5.7中的sql_mode含有only_full_group_by,group by语句有时候会报错。通过手动修改sql_mode,那么如果删除容器或者新建容器,就会导致我们手动设置的sql_mode失效,所以自己制作一个基于mysql镜像的镜像,解决sql_mode含有only_full_group_by的问题。
运行容器
List-1 mjduan@mjduan:/opt % docker run -d -p 3306:3306 -e MYSQL_ALLOW_EMPTY_PASSWORD --name mysql1 mysql:5.7.9 5514c31a4e0bc524cee3cdcb962ac73b4fdeb1b5b32d70fa2840e9029b203a8c
进入容器安装vim
List-2 mjduan@mjduan:/opt % docker exec -ti mysql1 /bin/bash #在容器内执行如下命令 root@44504961189a:/opt % apt-get update ...... root@44504961189a:/opt % apt-get install vim ......
在容器内,/etc/mysql/conf.d/下,新建.cnf文件,将配置写入到里面,我们新建custom.cnf文件,写入如下内容:
List-3 root@44504961189a:/# more /etc/mysql/conf.d/custom.cnf [mysqld] sql_mode=STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
退出容器,用docker commit命令由容器制作镜像,
List-4 mjduan@mjduan:/opt % docker commit mysql1 mysql_custom:1.0
之后docker images就可以看到镜像mysql_custom:1.0了。
mysql_custom:1.0就是我们需要的,用它来启动容器,如下List-5
List-5 mjduan@mjduan:/opt % docker run -d -p 3306:3306 -e MYSQL_ROOT_PASSWORD=新密码 --name mysql_mjduan2 mysql_custom:1.0 44504961189a45442a6b33e5945778b73bc3dd058ab9e794c56b0bbfc3e603bf
之后进入容器mysql_mjduan2,用mysql命令进入mysql命令行时就会提示要root密码了。再次查看sql_mode,就会看到sql_mode没有only_full_group_by了。
注意,不要让别人拿到你的镜像,否则通过docker inspect命令就可以看到你设置的root密码。不过可以在创建容器的时候用MYSQL_ROOT_PASSWORD来设置新的root密码。
注:
也可以直接用Dockerfile基于mysql的镜像进行制作。
云计算
2019-03-24 20:48:00
RadosClient.h class librados::RadosClient : public Dispatcher //继承自Dispatcher(消息分发类) { public: using Dispatcher::cct; md_config_t *conf; //配置文件 private: enum { DISCONNECTED, CONNECTING, CONNECTED, } state; //网络连接状态 MonClient monclient; // monc Messenger *messenger; //网络消息接口 uint64_t instance_id; //相关消息分发 Dispatcher类的函数重写 bool _dispatch(Message *m); bool ms_dispatch(Message *m); bool ms_get_authorizer(int dest_type, AuthAuthorizer **authorizer, bool force_new); void ms_handle_connect(Connection *con); bool ms_handle_reset(Connection *con); void ms_handle_remote_reset(Connection *con); Objecter *objecter; // Osdc模块中的 用于发送封装好的OP消息 Mutex lock; Cond cond; SafeTimer timer; //定时器 int refcnt; version_t log_last_version; rados_log_callback_t log_cb; void *log_cb_arg; string log_watch; int wait_for_osdmap(); public: Finisher finisher; // 回调函数的类 explicit RadosClient(CephContext *cct_); ~RadosClient(); int ping_monitor(string mon_id, string *result); int connect(); // 连接 void shutdown(); int watch_flush(); int async_watch_flush(AioCompletionImpl *c); uint64_t get_instance_id(); int wait_for_latest_osdmap(); // 根据pool名字或id创建ioctx int create_ioctx(const char *name, IoCtxImpl **io); int create_ioctx(int64_t, IoCtxImpl **io); int get_fsid(std::string *s); // pool相关操作 int64_t lookup_pool(const char *name); bool pool_requires_alignment(int64_t pool_id); int pool_requires_alignment2(int64_t pool_id, bool *requires); uint64_t pool_required_alignment(int64_t pool_id); int pool_required_alignment2(int64_t pool_id, uint64_t *alignment); int pool_get_auid(uint64_t pool_id, unsigned long long *auid); int pool_get_name(uint64_t pool_id, std::string *auid); int pool_list(std::list >& ls); int get_pool_stats(std::list& ls, map& result); int get_fs_stats(ceph_statfs& result); /* -1 was set as the default value and monitor will pickup the right crush rule with below order: a) osd pool default crush replicated ruleset b) the first ruleset in crush ruleset c) error out if no value find */ // 同步创建pool 和 异步创建pool int pool_create(string& name, unsigned long long auid=0, int16_t crush_rule=-1); int pool_create_async(string& name, PoolAsyncCompletionImpl *c, unsigned long long auid=0, int16_t crush_rule=-1); int pool_get_base_tier(int64_t pool_id, int64_t* base_tier); //同步删除和异步删除 int pool_delete(const char *name); int pool_delete_async(const char *name, PoolAsyncCompletionImpl *c); int blacklist_add(const string& client_address, uint32_t expire_seconds); //Mon命令处理,调用monclient.start_mon_command 把命令发送给Mon处理 int mon_command(const vector& cmd, const bufferlist &inbl, bufferlist *outbl, string *outs); int mon_command(int rank, const vector& cmd, const bufferlist &inbl, bufferlist *outbl, string *outs); int mon_command(string name, const vector& cmd, const bufferlist &inbl, bufferlist *outbl, string *outs); //OSD命令处理,objector->osd_command 把命令发送给OSD处理 int osd_command(int osd, vector& cmd, const bufferlist& inbl, bufferlist *poutbl, string *prs); //PG命令处理,objector->pg_command 把命令发送给PG处理 int pg_command(pg_t pgid, vector& cmd, const bufferlist& inbl, bufferlist *poutbl, string *prs); void handle_log(MLog *m); int monitor_log(const string& level, rados_log_callback_t cb, void *arg); void get(); bool put(); void blacklist_self(bool set); };
connect() 连接 int librados::RadosClient::connect() { common_init_finish(cct); int err; // already connected? if (state == CONNECTING) return -EINPROGRESS; if (state == CONNECTED) return -EISCONN; state = CONNECTING; // get monmap err = monclient.build_initial_monmap(); //通过配置文件获取初始化的Monitor if (err < 0) goto out; err = -ENOMEM; messenger = Messenger::create_client_messenger(cct, "radosclient"); //创建通信模块 if (!messenger) goto out; // require OSDREPLYMUX feature. this means we will fail to talk to // old servers. this is necessary because otherwise we won't know // how to decompose the reply data into its consituent pieces. messenger->set_default_policy(Messenger::Policy::lossy_client(0, CEPH_FEATURE_OSDREPLYMUX)); ldout(cct, 1) << "starting msgr at " << messenger->get_myaddr() << dendl; ldout(cct, 1) << "starting objecter" << dendl; //创建objecter objecter = new (std::nothrow) Objecter(cct, messenger, &monclient, &finisher, cct->_conf->rados_mon_op_timeout, cct->_conf->rados_osd_op_timeout); if (!objecter) goto out; objecter->set_balanced_budget(); // mc添加 messenger monclient.set_messenger(messenger); // objecter 初始化 objecter->init(); // messenger添加 dispather messenger->add_dispatcher_tail(objecter); messenger->add_dispatcher_tail(this); // messenger启动 messenger->start(); ldout(cct, 1) << "setting wanted keys" << dendl; monclient.set_want_keys(CEPH_ENTITY_TYPE_MON | CEPH_ENTITY_TYPE_OSD); ldout(cct, 1) << "calling monclient init" << dendl; // mc 初始化 err = monclient.init(); if (err) { ldout(cct, 0) << conf->name << " initialization error " << cpp_strerror(-err) << dendl; shutdown(); goto out; } err = monclient.authenticate(conf->client_mount_timeout); if (err) { ldout(cct, 0) << conf->name << " authentication error " << cpp_strerror(-err) << dendl; shutdown(); goto out; } messenger->set_myname(entity_name_t::CLIENT(monclient.get_global_id())); objecter->set_client_incarnation(0); // objecter 启动 objecter->start(); lock.Lock(); // 定时器初始化 timer.init(); monclient.renew_subs(); //执行回调的完成类start finisher.start(); // 更新 状态为已连接 state = CONNECTED; instance_id = monclient.get_global_id(); ... }
create_ioctx 根据pool创建ioctx int librados::RadosClient::create_ioctx(const char *name, IoCtxImpl **io) { // 获取 poolid int64_t poolid = lookup_pool(name); ... // 创建 IoCtxImpl *io = new librados::IoCtxImpl(this, objecter, poolid, CEPH_NOSNAP); return 0; }
Mon OSD pg 命令操作 int librados::RadosClient::mon_command(const vector& cmd, const bufferlist &inbl, bufferlist *outbl, string *outs) { // mc start_mon_command 发送到monitor monclient.start_mon_command(cmd, inbl, outbl, outs, new C_SafeCond(&mylock, &cond, &done, &rval)); } int librados::RadosClient::osd_command(int osd, vector& cmd, const bufferlist& inbl, bufferlist *poutbl, string *prs) { // 发送到osd int r = objecter->osd_command(osd, cmd, inbl, &tid, poutbl, prs, new C_SafeCond(&mylock, &cond, &done, &ret)); } int librados::RadosClient::pg_command(pg_t pgid, vector& cmd, const bufferlist& inbl, bufferlist *poutbl, string *prs) { // 发送到pg int r = objecter->pg_command(pgid, cmd, inbl, &tid, poutbl, prs, new C_SafeCond(&mylock, &cond, &done, &ret)); }
Ioctximpl
librados::IoCtx的实现IoCtxImpl 把请求封装成ObjectOperation 类(osdc 中的) 把相关的pool信息添加到里面,封装成Objecter::Op对像 调用相应的函数 objecter- >op_submit 发送给相应的OSD 操作完成后,调用相应的回调函数。
如rados_write extern "C" int rados_write(rados_ioctx_t io, const char *o, const char *buf, size_t len, uint64_t off) { librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io; object_t oid(o); bufferlist bl; bl.append(buf, len); int retval = ctx->write(oid, bl, len, off); }
调用IoCtxImpl::write int librados::IoCtxImpl::write(const object_t& oid, bufferlist& bl, size_t len, uint64_t off) { ::ObjectOperation op; prepare_assert_ops(&op); // assert ops bufferlist mybl; mybl.substr_of(bl, 0, len); op.write(off, mybl); // 封装到op.write Objecter.h ObjectOperation write return operate(oid, &op, NULL); // IoCtxImpl::operate } int librados::IoCtxImpl::operate(const object_t& oid, ::ObjectOperation *o, ceph::real_time *pmtime, int flags) { int op = o->ops[0].op.op; Objecter::Op *objecter_op = objecter->prepare_mutate_op(oid, oloc, *o, snapc, ut, flags, NULL, oncommit, &ver); objecter->op_submit(objecter_op); }
AioCompletionImpl
OSDC
ObjectOperation struct ObjectOperation { vector ops; // ops集合 int flags; int priority; vector out_bl; // 输出bufferlist vector out_handler; // 回调函数 vector out_rval; // 返回码集合 size_t size() { // op个数 return ops.size(); } /** * This is a more limited form of C_Contexts, but that requires * a ceph_context which we don't have here. */ // 用户添加回调函数 class C_TwoContexts : public Context { Context *first; Context *second; }; /** * Add a callback to run when this operation completes, * after any other callbacks for it. */ // 添加回调函数 void add_handler(Context *extra) { size_t last = out_handler.size() - 1; Context *orig = out_handler[last]; if (orig) { Context *wrapper = new C_TwoContexts(orig, extra); out_handler[last] = wrapper; } else { out_handler[last] = extra; } } // 添加操作 OSDOp& add_op(int op) { int s = ops.size(); ops.resize(s+1); ops[s].op.op = op; out_bl.resize(s+1); out_bl[s] = NULL; out_handler.resize(s+1); out_handler[s] = NULL; out_rval.resize(s+1); out_rval[s] = NULL; return ops[s]; } // 添加data void add_data(int op, uint64_t off, uint64_t len, bufferlist& bl) { OSDOp& osd_op = add_op(op); osd_op.op.extent.offset = off; osd_op.op.extent.length = len; osd_op.indata.claim_append(bl); } void add_clone_range(int op, uint64_t off, uint64_t len, const object_t& srcoid, uint64_t srcoff, snapid_t srcsnapid) {} void add_xattr(int op, const char *name, const bufferlist& data) {} void add_xattr_cmp(int op, const char *name, uint8_t cmp_op, uint8_t cmp_mode, const bufferlist& data) {} // 添加call method void add_call(int op, const char *cname, const char *method, bufferlist &indata, bufferlist *outbl, Context *ctx, int *prval) { OSDOp& osd_op = add_op(op); unsigned p = ops.size() - 1; out_handler[p] = ctx; out_bl[p] = outbl; out_rval[p] = prval; osd_op.op.cls.class_len = strlen(cname); osd_op.op.cls.method_len = strlen(method); osd_op.op.cls.indata_len = indata.length(); osd_op.indata.append(cname, osd_op.op.cls.class_len); osd_op.indata.append(method, osd_op.op.cls.method_len); osd_op.indata.append(indata); } void add_pgls(int op, uint64_t count, collection_list_handle_t cookie, epoch_t start_epoch) {} void add_pgls_filter(int op, uint64_t count, const bufferlist& filter, collection_list_handle_t cookie, epoch_t start_epoch) {} void add_alloc_hint(int op, uint64_t expected_object_size, uint64_t expected_write_size) {} // ------ // pg 操作 void pg_ls(uint64_t count, bufferlist& filter, collection_list_handle_t cookie, epoch_t start_epoch) {} void pg_nls(uint64_t count, const bufferlist& filter, collection_list_handle_t cookie, epoch_t start_epoch) {} // 创建 操作 void create(bool excl) { OSDOp& o = add_op(CEPH_OSD_OP_CREATE); o.op.flags = (excl ? CEPH_OSD_OP_FLAG_EXCL : 0); } // 状态 struct C_ObjectOperation_stat : public Context { bufferlist bl; uint64_t *psize; ceph::real_time *pmtime; time_t *ptime; struct timespec *pts; int *prval; // 完成大小,时间等 void finish(int r) {} } }; // 查看状态,获取C_ObjectOperation_stat void stat(uint64_t *psize, ceph::real_time *pmtime, int *prval) {} void stat(uint64_t *psize, time_t *ptime, int *prval) {} void stat(uint64_t *psize, struct timespec *pts, int *prval) {} // object data // 读操作 void read(uint64_t off, uint64_t len, bufferlist *pbl, int *prval, Context* ctx) { bufferlist bl; add_data(CEPH_OSD_OP_READ, off, len, bl); unsigned p = ops.size() - 1; out_bl[p] = pbl; out_rval[p] = prval; out_handler[p] = ctx; } void sparse_read(uint64_t off, uint64_t len, std::map *m, bufferlist *data_bl, int *prval) {} // 写操作 void write(uint64_t off, bufferlist& bl, uint64_t truncate_size, uint32_t truncate_seq) { add_data(CEPH_OSD_OP_WRITE, off, bl.length(), bl); // 添加data, 将WRITE存入ops,将数据放在op中 OSDOp& o = *ops.rbegin(); o.op.extent.truncate_size = truncate_size; o.op.extent.truncate_seq = truncate_seq; } void write(uint64_t off, bufferlist& bl) {} void write_full(bufferlist& bl) {} void append(bufferlist& bl) {} void zero(uint64_t off, uint64_t len) {} void truncate(uint64_t off) {} void remove() {} void mapext(uint64_t off, uint64_t len) {} void sparse_read(uint64_t off, uint64_t len) {} void clone_range(const object_t& src_oid, uint64_t src_offset, uint64_t len, uint64_t dst_offset) {} // object attrs // 属性操作 void getxattr(const char *name, bufferlist *pbl, int *prval) {} void getxattrs(std::map *pattrs, int *prval) {} void setxattr(const char *name, const bufferlist& bl) {} void setxattr(const char *name, const string& s) {} void cmpxattr(const char *name, uint8_t cmp_op, uint8_t cmp_mode, const bufferlist& bl) {} void rmxattr(const char *name) {} void setxattrs(map& attrs) {} void resetxattrs(const char *prefix, map& attrs) {} // trivialmap void tmap_update(bufferlist& bl) {} void tmap_put(bufferlist& bl) {} void tmap_get(bufferlist *pbl, int *prval) {} void tmap_get() {} void tmap_to_omap(bool nullok=false) {} // objectmap void omap_get_keys(const string &start_after, uint64_t max_to_get, std::set *out_set, int *prval) { OSDOp &op = add_op(CEPH_OSD_OP_OMAPGETKEYS); bufferlist bl; ::encode(start_after, bl); ::encode(max_to_get, bl); op.op.extent.offset = 0; op.op.extent.length = bl.length(); op.indata.claim_append(bl); if (prval || out_set) { unsigned p = ops.size() - 1; C_ObjectOperation_decodekeys *h = new C_ObjectOperation_decodekeys(out_set, prval); out_handler[p] = h; out_bl[p] = &h->bl; out_rval[p] = prval; } } void omap_get_vals(const string &start_after, const string &filter_prefix, uint64_t max_to_get, std::map *out_set, int *prval) {} void omap_get_vals_by_keys(const std::set &to_get, std::map *out_set, int *prval) {} void omap_cmp(const std::map > &assertions, int *prval) {} void copy_get(object_copy_cursor_t *cursor, uint64_t max, uint64_t *out_size, ceph::real_time *out_mtime, std::map *out_attrs, bufferlist *out_data, bufferlist *out_omap_header, bufferlist *out_omap_data, vector *out_snaps, snapid_t *out_snap_seq, uint32_t *out_flags, uint32_t *out_data_digest, uint32_t *out_omap_digest, vector > *out_reqids, uint64_t *truncate_seq, uint64_t *truncate_size, int *prval) {} void undirty() {} struct C_ObjectOperation_isdirty : public Context {}; void is_dirty(bool *pisdirty, int *prval) {} void omap_get_header(bufferlist *bl, int *prval) {} void omap_set(const map &map) {} void omap_set_header(bufferlist &bl) {} void omap_clear() {} void omap_rm_keys(const std::set &to_remove) {} // object classes void call(const char *cname, const char *method, bufferlist &indata) {} void call(const char *cname, const char *method, bufferlist &indata, bufferlist *outdata, Context *ctx, int *prval) {} void rollback(uint64_t snapid) {} void copy_from(object_t src, snapid_t snapid, object_locator_t src_oloc, version_t src_version, unsigned flags, unsigned src_fadvise_flags) {} };
OSDOp osd_types.h struct OSDOp { ceph_osd_op op; // 操作 sobject_t soid; // oid bufferlist indata, outdata; // 输入输出data int32_t rval; // 返回码 };
Objecter class Objecter : public md_config_obs_t, public Dispatcher { public: Messenger *messenger; // 消息 MonClient *monc; // mc Finisher *finisher; private: OSDMap *osdmap; // osdmap public: using Dispatcher::cct; std::multimap crush_location; atomic_t initialized; private: atomic64_t last_tid; atomic_t inflight_ops; atomic_t client_inc; uint64_t max_linger_id; atomic_t num_unacked; atomic_t num_uncommitted; atomic_t global_op_flags; // flags which are applied to each IO op bool keep_balanced_budget; bool honor_osdmap_full; public: void maybe_request_map(); private: void _maybe_request_map(); version_t last_seen_osdmap_version; version_t last_seen_pgmap_version; mutable boost::shared_mutex rwlock; using lock_guard = std::unique_lock; using unique_lock = std::unique_lock; using shared_lock = boost::shared_lock; using shunique_lock = ceph::shunique_lock; ceph::timer timer; PerfCounters *logger; uint64_t tick_event; void start_tick(); void tick(); void update_crush_location(); public: /*** track pending operations ***/ // read public: struct OSDSession; struct op_target_t {} // 操作目标 struct Op : public RefCountedObject {}; // 操作 };
op_target_t
操作目标,封装pg信息,osd信息 struct op_target_t { int flags; object_t base_oid; object_locator_t base_oloc; object_t target_oid; // 目标oid object_locator_t target_oloc; // 位置 // 是否 base_pgid bool precalc_pgid; ///< true if we are directed at base_pgid, not base_oid // 直接的 pgid pg_t base_pgid; ///< explciti pg target, if any pg_t pgid; ///< last pg we mapped to unsigned pg_num; ///< last pg_num we mapped to unsigned pg_num_mask; ///< last pg_num_mask we mapped to // 启动的osd vector up; ///< set of up osds for last pg we mapped to // acting osd vector acting; ///< set of acting osds for last pg we mapped to // primary int up_primary; ///< primary for last pg we mapped to based on the up set int acting_primary; ///< primary for last pg we mapped to based on the /// acting set // pool 大小 int size; ///< the size of the pool when were were last mapped // pool 最小size int min_size; ///< the min size of the pool when were were last mapped // 是否按位排序 bool sort_bitwise; ///< whether the hobject_t sort order is bitwise // 是否副本 bool used_replica; bool paused; int osd; ///< the final target osd, or -1 };
操作 struct Op : public RefCountedObject { OSDSession *session; // session 连接 int incarnation; op_target_t target; // 操作目标 ConnectionRef con; // for rx buffer only uint64_t features; // explicitly specified op features vector ops; // 操作集合 snapid_t snapid; SnapContext snapc; ceph::real_time mtime; bufferlist *outbl; vector out_bl; vector out_handler; vector out_rval; int priority; Context *onack, *oncommit; uint64_t ontimeout; Context *oncommit_sync; // used internally by watch/notify ceph_tid_t tid; eversion_t replay_version; // for op replay int attempts; version_t *objver; epoch_t *reply_epoch; ceph::mono_time stamp; epoch_t map_dne_bound; bool budgeted; /// true if we should resend this message on failure bool should_resend; /// true if the throttle budget is get/put on a series of OPs, /// instead of per OP basis, when this flag is set, the budget is /// acquired before sending the very first OP of the series and /// released upon receiving the last OP reply. bool ctx_budgeted; int *data_offset; epoch_t last_force_resend; osd_reqid_t reqid; // explicitly setting reqid };
分片 Striper
扩展 ObjectExtent
记录分片信息 class ObjectExtent { public: object_t oid; // object id uint64_t objectno; // 序号 uint64_t offset; // in object object内偏移 uint64_t length; // in object 分片长度 uint64_t truncate_size; // in object object_locator_t oloc; // object locator (pool etc) pool位置 vector > buffer_extents; // off -> len. extents in buffer being mapped (may be fragmented bc of striping!) };
云计算
2019-03-23 18:45:00
本文作者:AIOps智能运维
干货概览

人生病了要去看医生,程序生病了看的就是运维工程师了。医生给病人看病要做很多检查,然后拿着结果单子分析病因。运维工程师分析系统故障也会查看采集的监控指标,然后判断根因是什么。

查看指标这事儿,说起来也不难。只要画出指标的趋势图(指标值随时间变化的曲线),有经验的工程师很容易就能看出有没有毛病,进而推断故障的原因。不过呢,都说脱离开剂量说食物的毒性是耍流氓,查看指标这事也差不多。如果只有几条指标需要查看,做个仪表盘就能一目了然,可是如果有成千上万的指标呢?人家查抄大老虎的时候点钞机都烧坏了好几台,如果人工查看这么多指标,脑子的下场估计也好不到哪儿去。所以说还是得靠“机器人”。

等等,“机器人”怎么能知道什么指标有毛病,什么指标没毛病呢?就算能知道,把有毛病的指标挑出来工程师凭啥就能知道根因呢?所以,我们的“机器人医生”必须能够识别出指标的异常,然后还需要能把识别出的异常整理成工程师容易理解的报告才行。

传统的办法

人工诊断故障的时候,工程师往往是根据脑子里的模块调用关系图(图 1)来排查系统。很多时候,故障都是因为在最上游的前端模块(图 1中的A)上看到了很多失败的请求发现的。这时,工程师就会沿着A往下查。因为A调用了B模块,所以需要查看B的指标,如果有指标异常那么就怀疑是B导致了故障。然后再检查B的直接下游模块C,以此类推。在这个过程中,怀疑通过模块的调用关系不断往下传递,直到传不下去为止。在图 1的例子中怀疑最后就停在了倒霉蛋G的头上,谁让它没有下游模块呢。

总的来说,这就是模块间把责任想办法往下游推的过程。当然,真实的场景要更加复杂一些。并不是只要下游有异常就可以推的,还需要考察异常的程度。比如,如果倒霉蛋G的异常程度比E的异常程度小很多,根因就更有可能在E里面。

找到了根因模块再去分析根因就容易多了,所以寻找根因模块是故障诊断中很重要的步骤。

上面的过程可以很直接地变成一个工具:
做一个页面展示模块调用关系图

工程师为每个指标配置黄金指标,以及黄金指标的阈值

在模块图中标出黄金指标有异常的模块以及它们到达前端模块的可能路径

这个工具通过配置黄金指标及阈值的方式解决了指标以及如何判断异常的问题,然后再通过模块调用关系图的方式呈现异常判断的结果,解决了异常判断和结果整理这两个核心问题。

不过,传统的办法在实际使用中还是会碰到很多问题:

1.活的系统一定是不断演化的,模块的调用关系也随之发生改变。为了保证工具里面的关系图不会过时,就需要不断从真实系统同步。干过系统梳理这种活的工程师都知道,这可不容易。如果整个系统使用统一的RPC中间件在模块中通讯,那就可以通过分析RPC trace log的方式挖掘出调用关系图来,不过“历史代码”通常会趴在路中间拦着你。

2.每个黄金指标通常只能覆盖一部分的故障类型,新的故障一出现,就需要增加黄金指标。这样一来配置工作——尤其是阈值的配置——就会不断出现。另外,指标多了,就很容易出现“全国山河一片红”的情况。大多数的模块都被标出来的时候,工具也就没啥用了。

3.大型的系统为了保证性能和可用性,常常需要在好几个机房中部署镜像系统。因为大多数的故障只发生在一个机房的系统中,所以工程师不但需要知道根因模块是谁,还需要知道在哪个机房。这样一来,每个机房都得有一个调用关系图,工程师得一个一个地看。

理想的效果

传统的方法作出来的诊断工具最多也就是半自动的,应用起来也受到很多的限制,所以我们就想做一个真正全自动、智能化的工具。

首先,我们希望新工具不要过于依赖于黄金指标,这样指标的配置工作就能减少。但是,这反过来说明全自动的工具必须能够扫描所有模块上的所有指标,这样才能做到没有遗漏。所以,异常判断不能再通过人工设置阈值的方式来进行,而必须是基本上无监督的(Unsupervised)。另外,不同指标的语意有很大差异,异常判断的算法也必须足够灵活,以适应不同指标的特点。

其次,我们希望工具不要太过依赖于调用关系图,这意味着我们需要寻找一种新的方式来整理和呈现结果。其实,调用关系图并不是必须的。在使用传统诊断方法时,我们就发现一部分工程师经常脱离调用关系图,直接按照黄金指标的异常程度从大到小检查模块。这是因为这部分工程师负责的系统黄金指标代表性强、容易理解,更重要的是不同模块黄金指标的异常程度可以比较。

所以说,我们完全可以做一个诊断工具来产出根因模块的推荐报告,报告的内容必须易于理解,推荐的顺序也必须足够准确。

实例指标的自动排查分析

我们以实例指标为例,介绍如何实现一个指标排查工具,达成理想的效果。

在第一步,所有被收集来的指标都会通过异常检测算法赋予它们一个异常分数。比较两个指标的异常分数就能够知道它们的异常程度谁大谁小了。这一步的核心是要寻找一个方法能够量化地衡量每个指标的异常,而且这个量化衡量出来的分数还可以在不同实例的不同指标之间比较。

第二步,我们把异常分数按照它们所属的实例分组,每组形成一个向量(vector)。这时,每个实例都会对应一个向量,向量中的每个元素就是一个指标的异常分数。然后,模式(pattern)差不多的向量就可以通过聚类(clustering)算法聚成若干个摘要(digest)。这样一来,工程师们就容易理解分析的结果了。

第三步,我们可以根据摘要中包含的实例以及指标的异常分数排序(ranking),形成推荐报告。

总结

本文介绍了一种在服务发生故障时自动排查监控指标的工具,第一步利用了概率统计的方式估算每个指标的异常分数,第二步用聚类的方式把异常模式相近的实例聚集在一起形成摘要,第三步用ranking的方式向工程师推荐最有可能是根因的摘要。

由于运维场景的特点是数据量大,但是标定很少,生成标定的代价高昂而且容易出错,接下来我们会详细介绍如何利用概率统计、非监督学习和监督学习的方法来解决这个问题,敬请期待吧~

原文链接地址: https://developer.baidu.com/topic/show/290066
云计算
2019-03-30 12:21:00
本文作者:AIOps智能运维
干货概览

AIOps(Artificial Intelligence for IT Operations ),即智能运维,是将人工智能的能力与运维相结合,通过机器学习的方法来提升运维效率。

在传统的自动化运维体系中,重复性运维工作的人力成本和效率问题得到了有效解决。但在复杂场景下的故障处理、变更管理、容量管理、服务资源过程中,仍需要人来掌控决策的过程,这阻碍了运维效率的进一步提升。而AI方法的引入,使得机器能够代替人来做出决策,从而让真正意义上的实现完全自动化成为了可能。

在AIOps的落地实施过程中,最关键的因素还是人,即AIOps的建设者们。

AIOps作为一个全新的技术发展和应用方向,并不是简单地说具备某一种技能或招募一两个大牛就可以完成的,它需要不同角色、多个团队的配合才可以达成。根据近几年来整个业界对AIOps的理解和实践,AIOps参与角色的划分也越来越清晰。在百度4年的AIOps实践中,我们总结得出了如下四种不可或缺的角色:
运维工程师

运维研发工程师

平台研发工程师

运维AI工程师

可以看到,除了运维AI工程师外,其他角色并不是AIOps产生之后才出现的,他们在传统运维中也发挥了重要作用。我们今天主要想和大家探讨一下,在AIOps时代,他们的职责究竟发生了哪些变化。为了方便大家理解,我们会基于百度AIOps的实践案例,来进行具体说明。

单机房故障自愈场景

单机房故障自愈是一个典型的AIOps落地项目。该方案主要解决的问题场景如下:某个业务由于网络、设备、变更、程序Bug、容量等原因造成故障,但故障范围仅局限在单个机房或单个Region内部。那么,我们可以基于流量调度等手段,将访问流量调度到非故障机房或Region,实现该类型故障的自动止损。

在这个过程中,需要AIOps四种角色分工明确、紧密配合,来完成整个AIOps解决方案的落地实现。

运维工程师

在单机房故障自愈项目中,运维工程师基于日常运维工作中所积累的场景、问题和经验,确定以单机房故障止损作为主要需求和突破口,通过定义单机房故障止损的问题域、解决思路以及风险点,明确AI可以发力的领域。

在完成问题域的定义后,运维工程师需要跟踪整个单机房故障自愈解决方案的落地,包括在策略设计前期提供数据标注支持,在中期进行效果的验收,在后期将单机房故障自愈方案实际部署运行到生产环境。

AIOps时代的职责和技能变化

运维工程师承担线上服务质量的责任,是服务质量的关键保证。在工作过程中,会与研发、产品、运营等各类角色、不同团队进行深度的沟通和协作。

传统运维中,运维工程师的主要职责分为三个方面:质量、成本、效率。

在AIOps落地实施中,运维工程师是处于中心的角色,也赋予了新的职责,他们是AIOps具体实施的需求提出者和成果验收者。具体职责包括:

在AIOps时代,运维工程师一方面需要熟悉运维领域的知识,了解运维的难题和解决思路;另一方面需要了解人工智能和机器学习的思路,能够理解哪些场景问题适合用机器学习方法解决,需要提供怎样的样本和数据,即成为AI在运维领域落地实施的解决方案专家。

运维AI工程师

在单机房故障自愈场景中,运维AI工程师将机器学习的算法与实际的故障处理业务场景相结合,针对单机房故障场景的风险点,进行策略研发与实验工作。如下图所示:

运维AI工程师分别设计了如下算法策略来满足整个复杂故障场景的自动决策:
异常检测算法:解决故障发现时指标异常判断问题,基于AI方法实现较高的准确率和召回率,作为整个故障自愈的数据基础。

策略编排算法:基于当前线上的实际流量和服务状态,设计损益计算模型,判断基于何种方式的操作组合或步骤,能够使整个自动止损带来收益最大,风险最小。

流量调度算法:基于线上服务容量与实时流量情况,进行精确流量比例计算,防御容量不足或不准风险,并实现流量调度收益最大化。

在完成策略设计与研发后,需要根据历史数据进行Case回溯,并进行仿真Case模拟,来验证策略效果,并进行逐步迭代调优,以达到线上运行的准确率和召回率要求。

AIOps时代的职责和技能变化

运维AI工程师是将AI引入运维的核心角色。他们针对运维数据、运维经验进行理解和梳理,使用机器学习的方法将海量运维数据进行汇总、归纳,使得数据中的价值显现出来。

运维AI工程师首先需要具备AI工程师的技能,需要对数学及机器学习方法有足够的掌握程度,并能应用实践。

如单机房故障自愈场景中的介绍,运维AI工程师需要具备机器学习知识并在运维领域落地的能力。

平台研发工程师

在单机房故障自愈场景中,平台研发工程师需要关注三类平台的建设。
基础运维平台:提供单机房故障自愈场景中的依赖平台,如:监控平台和流量调度平台。在日常运维中提供标准化运维数据获取和运维操作的基础,而在AIOps中,这部分接口需要能够同时支持人工和自动的数据获取和运维操作。

智能运维平台:提供对AI能力的支持,如:统一的数据服务(运维知识库)、运维开发框架,以及给AI策略实验和运行的运维策略框架等。

故障自愈机器人:针对单个业务场景进行平台化抽象,使之成为一个基础服务,基于AIOps平台研发和运行。

AIOps时代的职责和技能变化

平台研发工程师负责运维平台及基础组件的研发与建设。

在传统运维场景中,平台研发工程师负责平台、基础组件、类库和工具的研发工作。在针对运维的场景中,会覆盖运维相关的服务管理、监控、变更、流量调度等相关平台。

这部分平台是运维的基础,在AIOps时代仍然需要依赖于这些平台的建设。

同时在AIOps场景中,数据成为了中心,运维各种状态信息转换为大数据,机器学习则作用在大数据上进行分析。在百度AIOps的实践中,运维开发框架、运维知识库、运维策略框架共同组成了完整的智能运维平台,三大平台的建设和实施离不开大数据、机器学习架构的引入。这就要求平台研发工程师具备大数据、机器学习平台架构师的多重身份,具备流式计算、分布式存储、机器学习平台、算法策略平台等一系列大数据和机器学习平台架构能力。

运维研发工程师

基于多个业务线场景抽象出的单机房故障自愈解决方案,能够满足大部分场景需求,但并不意味着可以直接提供给各个业务线来使用。原因如下:
策略和参数需要进行调整

流量调度、容灾策略等策略,针对不同的业务线,配置并不相同。例如某些业务对响应时间敏感,跨地域的调度会带来较大的延迟,影响用户体验,这时就需要根据业务情况配置机房之间的跨机房流量调度延迟系数,来实现流量优先调度到延迟系数最低的机房。
通用框架无法满足所有需求

部分业务线需要对原有的策略进行部分重写才能够满足需求。例如,部分业务在流量调度时,需要联动服务降级来满足容量需求,这就需要额外增加服务降级联动的逻辑。

那么,就需要运维研发工程师出手来解决这个问题。根据业务线的实际情况,对策略和参数进行配置和调优,对通用框架无法满足的需求,进行定制化研发,使得单机房故障自愈方案能够实际应用在不同业务线上。

AIOps时代的职责和技能变化

运维研发工程师负责基于业务线特征的运维研发工作,在传统运维中,是运维自动化的实施者,实现了针对业务场景的自动化运维实施落地。

在AIOps时代,运维研发工程师承担了AIOps智能化运维解决方案在业务线实施落地的职责。他们是AIOps场景的实践者,将AIOps解决方案与业务架构特征相结合,实现AIOps在业务线的落地。

一方面,他们会与运维工程师紧密配合,对业务问题进行深度分析,理解业务的特点。另一方面,他们与平台研发工程师、AI工程师相配合,基于AIOps解决方案的策略和框架,进行定制化开发,使其适合自身业务线的特征。

总结

本文介绍了运维工程师、运维AI工程师、平台研发工程师、运维研发工程师四种角色在自动化运维时代和AIOps智能化运维时代,其职责和技能的拓展和变化。AIOps技术为运维技术的发展带来了更多的机遇,对于每个参与到AIOps实施的个人或团队也是如此。四种角色既有术业专攻,同时又紧密协作,共同将AI能力引入为运维赋能。那么,你的选择是什么呢?

原文链接地址: https://developer.baidu.com/topic/show/290065
云计算
2019-03-30 12:10:00
本文作者:AIOps智能运维
干货概览

在运小皮《百度自动化运维演讲》文章中提到,2014年以来,百度运维开始向智能化方向迈进。智能运维时代,如何提高智能运维效率,降低通用运维操作(典型如故障场景)开发难度和成本,成为首要难题。本文将向大家介绍面向感知、决策、执行的百度智能运维工程化解决方案。

背景介绍

故障处理和操作变更是运维两大主题。在过去,为维护系统稳定,各业务线都投入大量人力进行故障处理工作,除直接人肉运维外,各产品线深度定制的运维工具、系统被研发出来。随着业务规模扩张和形态变迁,传统运维模式受到极大挑战:
无统一的开发管理模式,运维服务开发及维护成本大,运维效率低。

横向扩展能力差,运维经验难以复用,各产品线”重复造轮子”。

智能运维开发框架,提供了一种以软件工程方式解决运维问题的解决方案。通过提供统一的开发模型和管理机制,支持不同产品线运维操作的设计、实现和管理。从而:
降低设计、开发难度与成本,使业务OP专注自身的业务逻辑,提高开发和迭代效率。

促进基于代码的跨产品线经验积累与分享,提升百度整体的业务运维能力。

充分运用和发挥自动控制、机器学习、人工智能等领域的技术成果,提高运维效率。

解决思路

智能运维开发框架以Noah(百度自动化运维管理平台)时代的运维经验为基础,通过对运维概念和操作的统一,整合当前运维系统,提供运维操作的统一入口;让更多的业务线OP加入到运维社区建设中,共享运维经验,满足业务日益多样化的需要。

具体解决思路如下:

1运维模式标准化
统一开发模式:提供统一的开发规范,社区化开发模式,业务线OP共同参与运维操作开发,沉淀运维经验。

统一运维对象:通过知识库,统一描述机器、实例、服务、应用等运维对象的属性,聚集分散的运维状态数据,达到公司内运维对象的统一。

统一运维操作:屏蔽具体平台操作实现,提供统一的运维对象操作接口。

2运维开发工程化
提供统一的运维开发框架:封装常用功能组件,提供高扩展的开发框架,使产品线专注于自身业务逻辑,开发”智能运维机器人”。

提供仿真系统:通过提供服务拓扑搭建及模拟故障的能力,完成机器人上线前功能验证,提高”机器人”可靠性。

提供托管平台:通过提供高可用的机器人托管环境,降低服务运维成本。

3运维操作智能化
智能感知:依赖监控系统提供的智能异常检测、多维度异常分析,感知满足时效性和准确度的异常事件。

智能决策:自定义算法实现决策机制,充分利用机器学习、人工智能成果,提供决策可靠性。并沉淀人对问题的决策经验,做到经验可迁移。

智能执行:提供丰富的执行策略,满足业务线通用运维操作的需求。

实现方案

整体解决方案如下:

以智能运维机器人为主体,深度整合公司内代码管理工具,持续交付平台,部署系统等devops工具链,帮助产品线同学快速完成源码构建、镜像打包、应用部署,提供开发、测试、运维整套解决方案,大幅提升开发效率。

智能运维开发框架自身提供的功能如下:

智能运维开发框架提供了高扩展、易使用的智能运维机器人开发框架,具备线上服务拓扑结构搭建和query级别异常模拟能力的仿真系统,具备单地域故障处理能力的高可用服务部署托管平台,完成开发至上线流程的全覆盖,用户只需要在智能运维开发框架基础上嵌入自己的业务代码,即可完成满足自身业务的运维操作。

总结

智能运维开发框架以变革运维模式为目标,提供了开发、验证、运维工程化解决方案。一经上线,便作为各类故障自愈、高可用架构项目的基础支撑,大幅提高了项目开发效率,减小了开发难度和成本,表现出了极强的稳定性。

相信在不久的将来,智能运维开发框架会成为百度运维操作的载体,不断达成智能运维的使命。

智能运维开发框架的具体实现和最佳实践将在后续文章中详细介绍,敬请期待!

原文链接地址: https://developer.baidu.com/topic/show/290064
云计算
2019-03-30 11:59:00
本文作者:AIOps智能运维
背景:为什么要做智能运维

百度云智能运维团队在运维工具和平台研发方向历史悠久,支撑了全百度数十万规模的服务器上的运维服务,所提供的服务包括服务管理、资源定位、监控、部署、分布式任务调度等等。最近几年,团队着力于发展智能化运维能力以及AIOps产品化建设。

众所周知,百度除了搜索业务之外,还有很多其他的业务线,有像地图、百科、知道、网盘这样的老牌业务,也有诸如像教育、医疗这样的新兴业务,每个业务在规模上、服务架构上都有很大差异。业务本身对稳定性的要求很高,需要保持99.995%的高可用,同时在业务上云的背景下,虚拟化、混合云等都给我们带来了新的挑战。

百度运维经历了从脚本&工具、基础运维平台、开放可定制运维平台到我们现在的智能运维平台,这样四个阶段的转变。过去运维的核心目标是提升效果,比如持续交付的速度、服务稳定性、运营成本等。经过这么多年的建设,整个运维行业已经非常成熟,而我们所支撑业务规模仍在不断增长,越来越多的运维场景和问题无法用传统方法来解决,而运维效率也难以继续支撑业务规模的快速扩张,所以我们更加关注怎么样解放运维自身的效率,以及解决传统运维方法(人工、自动化)所解决不了的问题。

这就好比从马车到汽车是为了提升运输效率,而到汽车已经接近饱和的时候,我们又希望用自动驾驶把驾驶员从开车这项体力劳动中解放出来,不仅可以增加运行效率,同时也可以减少交通事故率,这也是我们对智能运维的诉求。

发展:AIOps,从理念到落地

2016年Gartner报告中提出了AIOps概念,也就是Algorithmic IT Operations;基于算法的IT运维,主要指用大数据、机器学习驱动自动化、服务台、监控这些场景下的能力提升。

我们从2014年开始做智能运维方面的探索,最开始也是集中在监控指标分析、报警分析、故障根因分析、性能和成本分析这些方面,到2016年我们已经完成将AI应用于完整的运维平台研发的论证。在我们语义下的AIOps,目标是将人的知识和运维经验与大数据、机器学习技术相结合,开发成一系列的智能策略,融入到运维系统中。用这样的智能运维系统去完成运维任务,是我们所认为的AIOps,也就是Artificial Intelligence IT Operations。有意思的是,2017年之后的Gartner报告也将AIOps的概念改成了Artificial Intelligence IT Operations。

我们认为AIOps中有三部分不可或缺,一个是运维开发框架,这个是我们后续智能运维研发的骨架,第二个是运维知识库,这是让骨架能与我们真实线上环境关联起来的关键因素,起到了血肉的作用,让骨架能动起来。而最后一个则是运维策略库,这是运维的大脑,控制着运维平台的行为。

使用运维开发框架实现的运维程序,我们称其为运维机器人。运维机器人可以在多种不同的运维场景下提供多样的运维能力,服务不同类型的业务和用户。

框架:新的运维开发模式

运维开发框架基于这样一个抽象,就是如果我们把线上环境看做一个黑盒服务,那么我们对它的操作无非读写两类,所谓的写也就是操作控制流,是那种要对线上状态做一些改变的操作,我们常说的部署、执行命令,都属于这一类;另一类是读,指的是数据流,也就是要从线上获取状态数据,并进行一些聚合统计之类的处理,我们常说的指标汇聚、异常检测、报警都在这个里面。通过运维知识库,可以在这两种操作的基础上,封装出多种不同的运维机器人,对业务提供高效率、高质量以及高可用方面的能力。

根据操作流和数据流的不同,我们把框架分成了两部分,最基础的是运维执行框架,在这之上,加上分布式计算组件的支持,我们还建设了用于运维大数据计算的计算框架。

1工程化

运维开发框架给开发者提供一系列的开发套件,除了包含了一系列的基础能力,还包含了一个标准的运维工程研发流程。

在过去,运维研发采用简单的开发-使用方式,缺少必要的测试维护。而现在,在代码开发阶段,可以通过执行框架,用统一的操作接口库提升研发效率。在测试阶段,开发套件提供了单测和仿真系统,简化测试环境搭建。在上线后的阶段,通过状态服务和托管系统,可满足在各灾难场景下的运维机器人的自维护。

2组件化

运维开发框架通过三种不同的组件功能组合成运维机器人。分别是感知器、决策器和执行器。这三种组件针对各自使用场景,提供了多种架构能力。
感知器运维机器人的眼睛和耳朵感,就像人有两个眼睛和两个耳朵一样。运维机器人也可以挂载多个感知器来获取不同事件源的消息,比如监控的指标数据或者是报警事件,变更事件这些,甚至可以是一个定时器。这些消息可以以推拉两种方式被感知器获取到。这些消息也可以做一定的聚合,达到阈值再触发后续处理。

决策器是运维机器人的大脑,所以为了保证决策的唯一,机器人有且只能有一个决策器。决策器也是使用者主要要扩展实现的部分。除了常见的逻辑判断规则之外,未来我们还会加入决策树等模型,让运维机器人自主控制决策路径。

执行器是运维机器人的手脚,所以同样的,执行器可以并行的执行多个不同的任务。执行器将运维长流程抽象成状态机和工作流两种模式。这样框架就可以记住当前的执行状态,如果运维机器人发生了故障迁移,还可以按照已经执行的状态让长流程断点续起。

知识库:运维的知识图谱

知识库是智能运维架构中非常重要的一部分:所有要处理的数据都来自知识库,以及所有处理后的数据也都会再进入到知识库中。知识库由三部分组成,分别是元数据、状态数据和事件数据。持续的数据建设,是智能运维建设的关键。

考虑到未来需要对接不同的内部云平台和公有云平台,所以我们的运维数据也需要从底层的多种不同的运维平台中抽取,清洗和做数据的整合。并以尽可能高的时效性提供给平台用户使用。因此我们知识库建设遵照这四个能力指标进行,分别是全、准、新、稳。

由于知识库涉及的存储的内容篇幅太大,并且是相对独立的一块工作,所以这里就不再展开了。

实践:运维机器人

单机房故障自愈是2017年我们完成的重点项目,目标是将单机房范围的故障自愈水平普遍提升到L4级(整个处理过程,包括决策过程基本无人介入)。当然,另一部分原因是过去一两年发生的几次业界重大线上事故,我们希望可以防微杜渐,进一步提升MTTR水平。

相比较原有的单机房故障处理方式,在感知、决策、执行三个方面,L4级的单机房故障自愈系统效果显著:

1.感知方面,智能异常检测算法替代过去大量误报漏报的阈值检测方法;

2.决策方面,具备全局信息、自动决策的算法组件替代了过去“老中医会诊”的人工决策模式;

3.执行方面,状态机等执行长流程组件的加入,让执行过程可定位、可复用。

目前L4级的单机房故障自愈,已经覆盖百度大多数核心业务线,止损效率可做到分钟级,最快秒级止损,较人工止损效率提升60%-99%。

总结

随着AIOps逐渐走向成熟和产品化,必将有越来越多的运维场景被AIOps所变革,而我们,百度云智能运维团队,也希望秉承着这个方向,为行业贡献更多的创新理念、技术和产品,欢迎大家一起加入探讨。

最后,用一句话来总结下工程架构对于智能运维的意义:

框架在手,AI我有:智能时代,框架会越来越重要,从机器学习框架TensorFlow到自动驾驶框架Apollo,概莫能外。

原文链接地址: https://developer.baidu.com/topic/show/290063
云计算
2019-03-30 11:52:00
UK8S是UCloud推出的Kubernetes容器云产品,完全兼容原生API,为用户提供一站式云上Kubernetes服务。我们团队自研了CNI(Container Network Interface)网络插件,深度集成VPC,使UK8S容器应用拥有与云主机间等同的网络性能(目前最高可达10Gb/s, 100万pps),并打通容器和物理云/托管云的网络。过程中,我们解决了开源kubelet创建多余Sandbox容器导致Pod IP莫名消失的问题,确保CNI插件正常运行,并准备将修复后的kubelet源码提交给社区。
深度集成VPC的网络方案
按照我们的设想,开发者可以在UK8S上部署、管理、扩展容器化应用,无需关心Kubernetes集群自身的搭建及维护等运维类工作。UK8S完全兼容原生的Kubernetes API, 以UCloud 公有云资源为基础, 通过自研的插件整合打通了ULB、UDisk、EIP等公有云网络和存储产品,为用户提供一站式云上Kubernetes服务。
其中VPC既保障网络隔离,又提供灵活的IP地址定义等,是用户对网络的必备需求之一。UK8S研发团队经过考察后认为,UCloud基础网络平台具有原生、强大的底层网络控制能力,令我们能抛开Overlay方案,把VPC的能力上移到容器这一层,通过VPC的能力去实现控制和转发。 UK8S每创建一个Pod都为其申请一个VPC IP并通过VethPair配置到Pod上,再配置策略路由。 原理如下图所示。
此方案具有以下优势:
无Overlay,网络性能高。50台Node下的测试数据表明,容器与容器之间的网络性能,相对于云主机与云主机之间,只有轻微差异(小包场景下,pps 会有 3~5% 损耗),而且Pod网络性能各项指标(吞吐量,包量,延迟等)不会随着节点规模增大而削减。而Flannel UDP,VXLan模式和Calico IPIP的模式存在明显的性能消耗。 Pod能直通公有云和物理云。对于使用公有云和物理云的用户而言,业务上K8S少了一层障碍,多了一份便利。而Flannel的host gw模式下,容器无法访问公有云和物理云主机。 而CNI的工作流程如下所示。
创建Pod网络过程:
删除Pod网络过程:
Pod IP 消失问题的排查与解决
为了测试CNI插件的稳定性,测试同学在UK8S上部署了一个CronJob,每分钟运行一个Job任务,一天要运行1440个任务。该CronJob定义如下:
apiVersion: batch/v1beta1 kind: CronJob metadata: name: hello spec: schedule: "*/1 * * * *" jobTemplate: spec: template: spec: containers: - name: hello image: busybox args: - /bin/sh - -c - date; echo Hello from the Kubernetes cluster restartPolicy: OnFailure
每运行一次Job都要创建一个Pod, 每创建一个Pod,CNI插件需要申请一次VPC IP,当Pod被销毁时,CNI插件需要释放该VPC IP。 因此理论上,通过该CronJob每天需要进行1440次申请VPC IP和释放VPC IP操作。
然而,经过数天的测试统计,发现通过该CronJob,集群每天申请IP次数高达2500以上, 而释放的的IP次数也达到了1800。申请和释放次数都超过了1440,而且申请次数超过了释放次数,意味着,部分分配给Pod的VPC IP被无效占用而消失了。
CNI:待删除的IP去哪儿了?
仔细分析CNI插件的运行日志,很快发现,CNI在执行拆除SandBox网络动作(CNI_COMMAND=DEL)中,存在不少无法找到Pod IP的情况。由于UK8S 自研的CNI查找Pod IP依赖正确的Pod网络名称空间路径(格式:/proc/10001/net/ns),而kubelet传给CNI的NETNS环境变量参数为空字符串,因此,CNI无法获取待释放的VPC IP,这是造成IP泄露的直接原因,如下图所示。
问题转移到kubelet, 为什么kubelet会传入一个空的CNI_NETNS环境变量参数给CNI插件?
随后跟踪kubelet的运行日志,发现不少Job Pod创建和销毁的时候,生成了一个额外的Sandbox容器。Sandbox容器是k8s pod中的Infra容器,它是Pod中第一个创建出来的容器,用于创建Pod的网络名称空间和初始化Pod网络,例如调用CNI分配Pod IP,下发策略路由等。它执行一个名为pause的进程,这个进程绝大部分时间处于Sleep状态,对系统资源消耗极低。奇怪的是,当任务容器busybox运行结束后,kubelet为Pod又创建了一个新的Sandbox容器,创建过程中自然又进行了一次CNI ADD调用,再次申请了一次VPC IP。
回到UK8S CNI,我们再次分析重现案例日志。这一次有了更进一步的发现,所有kubelet传递给NETNS参数为空字符串的情形都发生在kubelet试图销毁Pod中第二个Sandbox的过程中。反之,kubelet试图销毁第二个Sandbox时,给CNI传入的NETNS参数也全部为空字符串。
到这里,思路似乎清晰了不少,所有泄露的VPC IP都是来自第二个Sandbox容器。因此,我们需要查清楚两个问题: 为什么会出现第二个Sandbox容器? 为什么kubelet在销毁第二个Sandbox容器时,给CNI传入了不正确的NETNS参数?
第二个Sandbox:我为何而生?
在了解的第二个Sandbox的前世今生之前,需要先交待一下kubelet运行的基本原理和流程。
kubelet是kubernetes集群中Node节点的工作进程。当一个Pod被kube-sheduler成功调度到Node节点上后, kubelet负责将这个Pod创建出来,并把它所定义的各个容器启动起来。kubelet也是按照控制器模式工作的,它的工作核心是一个控制循环,源码中称之为syncLoop,这个循环关注并处理以下事件:
Pod更新事件,源自API Server; Pod生命周期(PLEG)变化, 源自Pod本身容器状态变化, 例如容器的创建,开始运行,和结束运行; kubelet本身设置的周期同步(Sync)任务; Pod存活探测(LivenessProbe)失败事件; 定时的清理事件(HouseKeeping)。 在上文描述的CronJob任务中, 每次运行Job任务都会创建一个Pod。这个Pod的生命周期中,理想情况下,需要经历以下重要事件: Pod被成功调度到某个工作节点,节点上的Kubelet通过Watch APIServer感知到创建Pod事件,开始创建Pod流程; kubelet为Pod创建Sandbox容器,用于创建Pod网络名称空间和调用CNI插件初始化Pod网络,Sandbox容器启动后,会触发第一次kubelet PLEG(Pod Life Event Generator)事件。 主容器创建并启动,触发第二次PLEG事件。 主容器date命令运行结束,容器终止,触发第三次PLEG事件。 kubelet杀死Pod中残余的Sandbox容器。 Sandbox容器被杀死,触发第四次PLEG事件。
其中3和4由于时间间隔短暂,可能被归并到同一次PLEG事件(kubelet每隔1s进行一次PLEG事件更新)。
然而,在我们观察到的所有VPC IP泄露的情况中,过程6之后“意外地”创建了Pod的第二个Sandbox容器,如下图右下角所示。在我们对Kubernetes的认知中,这不应该发生。
对kubelet源码(1.13.1)抽丝剥茧
前文提到,syncLoop循环会监听PLEG事件变化并处理之。而PLEG事件,则来源kubelet内部的一个pleg relist定时任务。kubelet每隔一秒钟执行一次relist操作,及时获取容器的创建,启动,容器,删除事件。
relist的主要责任是通过CRI来获取Pod中所有容器的实时状态,这里的容器被区分成两大类:Sandbox容器和非Sandbox容器,kubelet通过给容器打不同的label来识别之。CRI是一个统一的容器操作gRPC接口,kubelet对容器的操作,都要通过CRI请求来完成,而Docker,Rkt等容器项目则负责实现各自的CRI实现,Docker的实现即为dockershim,dockershim负责将收到的CRI请求提取出来,翻译成Docker API发给Docker Daemon。
relist通过CRI请求更新到Pod中Sandbox容器和非Sandbox容器最新状态,然后将状态信息写入kubelet的缓存podCache中,如果有容器状态发生变化,则通过pleg channel通知到syncLoop循环。对于单个pod,podCache分配了两个数组,分别用于保存Sandbox容器和非Sandbox容器的最新状态。
syncLoop收到pleg channel传来事件后,进入相应的sync同步处理流程。对于PLEG事件来说,对应的处理函数是HandlePodSyncs。这个函数开启一个新的pod worker goroutine,获取pod最新的podCache信息,然后进入真正的同步操作:syncPod函数。
syncPod将podCache中的pod最新状态信息(podStatus)转化成Kubernetes API PodStatus结构。这里值得一提的是,syncPod会通过podCache里各个容器的状态,来计算出Pod的状态(getPhase函数),比如Running,Failed或者Completed。然后进入Pod容器运行时同步操作:SyncPod函数,即将当前的各个容器状态与Pod API定义的SPEC期望状态做同步。下面源码流程图可以总结上述流程。
SyncPod:我做错了什么?
SyncPod首先计算Pod中所有容器的当前状态与该Pod API期望状态做对比同步。这一对比同步分为两个部分:
检查podCache中的Sandbox容器的状态是否满足此条件:Pod中有且只有一个Sandbox容器,并且该容器处于运行状态,拥有IP。如不满足,则认为该Pod需要重建Sandbox容器。如果需要重建Sandbox容器,Pod内所有容器都需要销毁并重建。 检查podCache中非Sandbox容器的运行状态,保证这些容器处于Pod API Spec期望状态。例如,如果发现有容器主进程退出且返回码不为0,则根据Pod API Spec中的RestartPolicy来决定是否重建该容器。 回顾前面提到的关键线索:所有的VPC IP泄露事件,都源于一个意料之外的Sandbox容器,被泄露的IP即为此Sandbox容器的IP。刚才提到,SyncPod函数中会对Pod是否需要重建Sandbox容器进行判定,这个意外的第二个Sandbox容器是否和这次判定有关呢? 凭kubelet的运行日志无法证实该猜测,必须修改源码增加日志输出。重新编译kubelet后,发现第二个Sandbox容器确实来自SyncPod函数中的判定结果。进一步确认的是,该SyncPod调用是由第一个Sandbox容器被kubelet所杀而导致的PLEG触发的。
那为什么SyncPod在第一个Sandbox容器被销毁后认为Pod需要重建Sandbox容器呢?进入判定函数podSandboxChanged仔细分析。
podSandboxChanged获取了podCache中Sandbox容器结构体实例,发现第一个Sandbox已经被销毁,处于NOT READY状态,于是认为pod中已无可用的Sandbox容器,需要重建之,源码如下图所示。
注意本文前面我们定位的CronJob yaml配置, Job模板里的restartPolicy被设置成了OnFailure。SyncPod完成Sandbox容器状态检查判定后,认为该Pod需要重建Sandbox容器,再次检查Pod的restartPolicy为OnFailure后,决定重建Sandbox容器,对应源码如下。
可以看出kubelet在第一个Sandbox容器死亡后触发的SyncPod操作中,只是简单地发现唯一的Sandbox容器处于NOT READY状态,便认为Pod需要重建Sandbox,忽视了Job的主容器已经成功结束的事实。
事实上,在前面syncPod函数中通过podCache计算API PodStatus Phase的过程中,kubelet已经知道该Pod处于Completed状态并存入apiPodStatus变量中作为参数传递给SyncPod函数。如下图所示。
Job已经进入Completed状态,此时不应该重建Sandbox容器。而SyncPod函数在判定Sandbox是否需要重建时, 并没有参考调用者syncPod传入的apiPodStatus参数,甚至这个参数是被忽视的。
第二个Sandbox容器的来源已经水落石出,解决办法也非常简单,即kubelet不为已经Completed的Pod创建Sandbox,具体代码如下所示。
重新编译kubelet并更新后,VPC IP泄露的问题得到解决。
下图可以总结上面描述的第二个Sandbox容器诞生的原因。
事情离真相大白还有一段距离。还有一个问题需要回答:
为什么kubelet在删除第二个Sandbox容器的时候, 调用CNI拆除容器网络时,传入了不正确的NETNS环境变量参数?
失去的NETNS
还记得前面介绍kubelet工作核心循环syncLoop的时候,里面提到的定期清理事件(HouseKeeping)吗?HouseKeeping是一个每隔2s运行一次的定时任务,负责扫描清理孤儿Pod,删除其残余的Volume目录并停止该Pod所属的Pod worker goroutine。HouseKeeping发现Job Pod进入Completed状态后,会查找该Pod是否还有正在运行的残余容器,如有则请理之。由于第二个Sandbox容器依然在运行,因此HouseKeeping会将其清理,其中的一个步骤是清理该Pod所属的cgroup,杀死该group中的所有进程,这样第二个Sandbox容器里的pause进程被杀,容器退出。
已经死亡的第二个Sandbox容器会被kubelet里的垃圾回收循环接管,它将被彻底停止销毁。然而由于之前的Housekeeping操作已经销毁了该容器的cgroup, 网络名称空间不复存在,因此在调用CNI插件拆除Sandbox网络时,kubelet无法获得正确的NETNS参数传给CNI,只能传入空字符串。
到此,问题的原因已经确认。
问题解决
一切水落石出后,我们开始着手解决问题。为了能确保找到所删除的Pod对应的VPC IP,CNI需要在ADD操作成功后,将PodName,Sandbox容器ID,NameSpace,VPC IP等对应关联信息进行额外存储。这样当进入DEL操作后,只需要通过kubelet传入的PodName,Sandbox容器ID和NameSpace即可找到VPC IP,然后通过UCloud 公有云相关API删除之,无需依赖NETNS操作。
考虑到问题的根因是出现在kubelet源码中的SyncPod函数,UK8S团队也已修复kubelet相关源码并准备提交patch给Kubernetes社区。
写在最后
Kubernetes依然是一个高速迭代中的开源项目,生产环境中会不可用避免遇见一些异常现象。UK8S研发团队在学习理解Kubernetes各个组件运行原理的同时,积极根据现网异常现象深入源码逐步探索出问题根因,进一步保障UK8S服务的稳定性和可靠性,提升产品体验。
2019年内UK8S还将支持节点弹性伸缩(Cluster AutoScaler)、物理机资源、GPU资源、混合云和ServiceMesh等一系列特性,敬请期待。
欢迎扫描下方二维码,加入UCloud K8S技术交流群,和我们共同探讨Kubernetes前沿技术。
如显示群人数已加满,可添加群主微信zhaoqi628543,备注K8S即可邀请入群。
云计算
2019-04-12 16:53:00
行业内接入网络去堆叠已经逐步成为主流方向,在大型互联网公司也已经批量部署。但由于京东集团不同的业务需求及历史原因,没有条件完全复制目前主流的ARP转主机路由方式的去堆叠方案,这促使我们设计一种尽可能满足各类业务需求的方案。
近几年来云市场迅速发展,越来越多的用户把关键应用甚至全部应用部署到公有云上。云服务商在产品收入快速增长同时,也深刻体会到产品的高可用性对用户发展和用户留存的重要性。面向用户的产品SLA的实现效果取决于其依赖的各个环节,而基础网络是所有产品需要依赖的一个重要环节,因此,提升网络高可用SLA对整体提升产品整体SLA有着重要促进作用。今天我们要谈的异构去堆叠就是京东云在提高网络高可用SLA方面的新技术研究。用户自有网络其实也面临同样的问题,有提高网络可靠性需求的用户可以考虑在自有网络中使用类似方案。
网络高可用通用解决方案
首先,让我们先来看一下为了实现网络高可用,当下的四种服务器连接主流方案:
由上图可以看出,双网卡/交换机堆叠和双网卡/去交换机堆叠提供了更好的高可用保证。
通用堆叠方式 V.S 通用去堆叠方式
01 堆叠方案
优势 服务器双网卡捆绑,无需特别改造 交换机控制面统一,支持服务器BGP路由方式接入
劣势 多设备统一控制面,可靠性低 升级困难 横向连接浪费端口
02 去堆叠方案
常见的去堆叠方案有以下两种: 去堆叠方案- 路由方式
优势 交换机完全独立 支持异构 路由方式接入的服务器无需特别改造
劣势 2层方式接入的服务器需要进行改造 服务器除网卡IP外需配置单独业务IP 服务器多IP增加业务方运维复杂度 静态路由方式不适合VM或Docker漂移 动态路由方式要求全部服务器运行路由协议
2.去堆叠方案- ARP转主机路由方式
优势 交换机完全独立 服务器网卡捆绑方式不变,便于运维 服务器网卡捆绑方式不变,便于运维
劣势 一组交换机要求同厂商,不支持异构 需要修改服务器Linux内核ARP处理部分 不支持服务器BGP路由方式接入
通过以上对比,可以发现堆叠与去堆叠方式其实都可以实现网络的高可用,但各有利弊。针对这样的情况,京东云提出了一种理想的去堆叠方式,可以满足下图中的所有需求。
异构去堆叠方案
01 实现方法
交换机侧 IP配置/24掩码,两台交换机可配置相同IP或者不同IP; 启用ARP代理及转主机路由功能; 配置ARP超时时间为5s以便在服务器不响应ARP时快速撤回主机路由。
服务器侧 服务器双网卡配置相同IP地址(掩码/32); 采用onlink方式配置目的为交换机IP的静态路由指向对应网卡; 采用onlink方式配置缺省路由同时指向两块网卡; 需要运行Ifplugd进程监控物理连接,物理连接发生UP/DOWN时执行相应ARP Ping和路由修改操作。
02 冗余测试

从上图中的测试拓扑和结果中可以看出,不论是软件操作上的禁用还是硬件拔出,在设定的收敛时间内,服务器的网络一直保持高可用。
03 异构去堆叠方案小结 异构去堆叠方案优势 交换机完全独立 异构避免单一厂商风险 异构推动自研交换机快速上线 服务器侧支持2层方式或BGP路由方式 不修改Linux内核
注意事项 需要内核版本支持L4 HASH方式ECMP(Centos 7.4以上) 需要运行Ifplugd进程监控物理连接
总结
综上所述,异构去堆叠有助于实现苛刻的网络SLA和极致的用户体验。京东云在设计去堆叠方案时首先考虑了异构,一方面因为单一厂商对网络高可用SLA还是一个重要风险点,另一方面异构方式可以促进京东正在进行的自研交换机实现快速部署。众所周知,自研交换机在各大互联网公司都是重点项目,但软件和硬件的稳定性一直是批量部署的重大障碍。而异构去堆叠利用自研和商用交换机1+1的方式可以大大降低自研交换机稳定性的影响。
·END·
云计算
2019-04-11 11:36:00
今天, Google Cloud NEXT 2019大会召开,在这场规模三万人的盛会上,Google宣布推出Anthos作为多云服务新方案,提供跨云(目前仅支持AWS和Azure)管理Kubernetes集群。
Anthos(前身为Cloud Service Platform)让用户可以跨环境构建和管理现代混合应用程序,用户可以在Anthos之上交付和管理容器、Kubernetes、微服务架构和Service Mesh等。据Google CEO Sundar Pichai在大会发布时的介绍,Google自身作为公有云提供商,产品Anthos平台甚至可以支持部分竞争对手的云,如目前支持AWS和Azure,但除这二者之外的其他公有云如阿里云、Oracle、IBM等的云都尚不支持。
技术前瞻性和持续创新得到证明
Anthos的发布,对Rancher来说是一则十足的好消息。在Google Anthos中,我们看到了它与Rancher的愿景的完美契合。因为Rancher始终相信Kubernetes将成为所有公有云和私有云都会提供的、标准化的基础架构,企业Kubernetes平台必须提供多集群、多云管理的功能。
早在两年前,Rancher就预见到企业将需要跨不同的公有云和私有数据中心管理多个Kubernetes集群。正是怀着这种理念,我们构建了Rancher 2.0,它可以与所有Kubernetes集群协同工作,包括Google GKE、Amazon EKS、Azure AKS、华为云、阿里云、腾讯云等等,是业界第一个、也是目前唯一一个与所有主流公有云厂商完成官方合作及对接的Kubernetes平台。
在过去的12个月里,已有成千上万的具有前瞻性思维的企业在生产环境中应用了Rancher 2.0。但是在初期,当我们向用户阐释Rancher能够管理多Kubernetes服务(如GKE、AKS、EKS等)的这一功能的优势时,有用户虽然对这一创新特性兴奋与好奇,却仍忍不住问我们,“管理多Kubernetes集群与服务?Rancher是对的吗?”如今,Google正式推出Anthos足以强力地证明,Rancher对多集群多云Kubernetes的坚信和前瞻性,是对的。
Container和Kubernetes技术均正处于采用的早期阶段。我们相信创新的产品和服务是实现大规模采用的关键。我们喜欢Google Anthos和Google Cloud Run(同样是今天全新发布的)等新服务,同时也为Rancher团队开发的创新技术感到自豪。Rancher 2.0是业界第一个多集群、多云Kubernetes管理平台。除此之外,Rancher Labs的创新步伐从未放缓,如最近推出的轻量级Kubernetes发行版K3s、多Kubernetes集群网络框架Submariner、对单一应用程序跨多Kubernetes集群的部署与管理等等,都广受客户和用户称赞。
Anthos:竞争者?推动者?
那Google会成为Rancher的竞争对手吗?答案是否定的。首先,Rancher是一个开源的平台,而Anthos是一种云服务。我们甚至相信,Anthos的发布将毫无疑问加速Rancher被更大规模地采用。正如Google发布GKE而极大地帮助普及了Kubernetes技术一样,我们也相信Anthos将促进将多集群、多云Kubernetes管理带入更主流的阶段。
其次,作为一个完全开源的Kubernetes管理平台,Rancher自身并非公有云提供商,因而一如既往的是所有公有云提供商、包括他们提供的托管Kubernetes服务的合作伙伴而非竞争对手。Rancher也才更能中立地提供对其他厂商Kubernetes服务的最一流支持。因为公有云厂商之间天然的竞争关系,我们很难想象AWS乐意致力于把运行在EKS上的应用无缝迁移到Google GKE或者其他云服务商提供的Kubernetes服务上,反之亦然。
从世界范围内包含Google GKE、Amazon EKS、Azure AKS、华为云、阿里云、腾讯云以及正在加入Rancher合作伙伴列表的众多主流公有云与Rancher一直以来的紧密合作中可见,Rancher也始终是所有第三方公有云厂商普遍最为信任的统一管理平台。
宠物与牛的故事
听过那个云计算时代“宠物”与“牛”的故事吗?
传统的物理机时代,物理机(及它所代表的计算资源)被工程师称为“宠物”,它们价格高昂,需要精心维护和保养。而在云计算时代,工程师可以把服务器当成牛,一头牛倒下没关系,只要放牧人活着就行,服务器价格便宜,就像一次性工具,即时它们倒下,一台设备上的任务也能转移到另一台,对公司业务不会造成任何影响。
我们将公司及产品命名为“Rancher(放牧人)”,就是因为我们愿景中的未来里,企业可以自由选择并搭配着从他们喜欢的云提供商那里获得计算资源,而Rancher会开发一个软件平台来完美实现这种统一体验。随着Anthos的发布,我们相信整个行业又向实现这一愿景迈进了一步! 本文基于Rancher Labs联合创始人及CEO梁胜所写博客删改编辑而成: https://rancher.com/blog/2019/era-of-multi-cluster-multi-cloud-kubernetes-has-arrived/
云计算
2019-04-11 09:20:00
问题演变过程
时间点1:高防+WAF+SLB+2台ECS
时间点2:高防+WAF+SLB+4台ECS
问题描述
在时间点1时,没有发现明显的负载不均衡的情况。在时间点2时,出现大部分请求都打到了其中一台ECS上。需要定位问题原因
问题梳理 问题链路
是SLB后端的ECS出现负载不均衡的请求,那么直接影响这个转发算法的,是WAF以及SLB。那么和高防没有关系了。
配置情况 SLB:TCP监听,WRR转发算法,开启会话保持 WAF:无特殊配置,域名直接回源负载均衡IP
问题点1:轮询算法+会话保持
措施: 尝试修改轮询算法为WLC,会话保持时间调短。
然而这个优化措施效果并不明显,由于开启了会话保持,那原有负载不均衡的情况下,调整WRR算法到WLC的算法,没有实现预期的WLC。
但是从另外一个角度来说,如果源IP非常分散的场景下,即使有会话保持,理论上还是应该在经过一个较长的时间段之后,依然能够到达均衡。
这里由于是使用WAF的回源地址进行访问,所以对负载均衡来说,客户端的公网IP地址是固定的,一直是固定的几个;从而调整WLC+会话保持的调整收效甚微。
问题点2:会话保持模板刷新问题
措施: 尝试关闭会话保持。
稍有成效: 关闭会话保持后,经过一段时间的通信,4台ECS初步的开始均衡,但是到了一个固定值之后;没有继续均衡,一直保持着1:2的状态。
这里有 2个知识点 :
1、WLC算法的计数开始是从调整为这个算法的时间点开始的;那么如果历史开始就出现不均衡,那么开启后还是会不均衡的。
2、由于WAF的回源地址与SLB的通信一直在,没有断过所以历史的会话保持的效果依然存在,已经会话保持的IP,依然会发给对应负载均衡的RS,导致不均衡。
推荐的解法为: 使用负载均衡的权重功能,将连接数多的机器的权重调低,待4台机器的连接数基本均衡后,将RS的权重都调整为一致。
作者:枫凡
原文链接 ​
本文为云栖社区原创内容,未经允许不得转载。
云计算
2019-05-14 12:11:00


【ZStack学堂】第二季第5期报名开始啦!前几期的分享收获了很多小伙伴的好评,第5期课程将与大家一起分享ZStack GPU透传、IOMMU/ VT-d简介、典型场景:3D渲染等内容。欢迎扫描海报二维码报名参与, 转发海报或参与直播间互动还有机会获取ZStack精心准备的小礼品哦!

云计算
2019-05-14 09:19:00
作者:ZStack 社区 王彬

Iaas云服务的普及,让我们在使用服务器的时候享受了飞一般的感觉,新兴企业在构建自己的系统时,往往都会选择购买云厂商的云服务器(虚拟机)进行使用,使用这样的虚拟机企业不需要购置任何硬件,不需要考虑机房、网络、服务器维护相关的工作便可以获取到一个低成本、安全免维护、伸缩性强、可灵活迁移的云服务器。在这个云服务器上我们可以快速的构建企业的业务系统。

随着企业的不断发展,使用公有云服务在虚拟机的数量到达一个数量级的时候,成本会高于私有云,且虚拟机数量越大这个成本差就会越大,大多数互联网企业在创业初期都是使用主流的公有云服务,但是随着企业内部业务量不断上升虚拟机数量也不断上升,相关的成本也在一直增加。并且随着业务类型越来越多时,业务的安全需求也受到越来越多的挑战,此时就需要考虑自建机房、自建私有云,将公有云的服务迁移到私有云上降低成本并进行内部的安全控制。

关于私有云的构建,目前业界有很多的解决方案。我也有多方了解和比较。前段时间接触到了ZStack云平台,为了更好的理解和掌握ZStack的产品,特地前往ZStack进行参观学习。


ZStack(上海云轴)成立于2015年,是一家坚持自主创新、专注于产品化的云计算公司。

在本次学习过程中,我了解到 ZStack有一个极大的亮点——操作简单 。使用ZStack的时候你不需要考虑什么SSO、数据库、控制服务部署调试,也不需要考虑什么Nova、Swift、Glance、Keystone等等。你所要的在ZStack的镜像中已经完整的进行了配置。

下载ISO
ZStack-x86_64-DVD-3.3.0-c74.iso 安装ZStack系统,简单点说就是装个LINUX,和安装CentOS一样,系统装好后就完成了一个私有云云平台的安装。


2. 平台初始化
3.添加镜像

4.创建虚机



5.安装Windows系统虚拟机并加载驱动



通过以上的方式,我们可以快速的构建一个私有云环境并部署一个Windows2012的虚拟机,接着就可以运行业务了。

云计算平台承载用户核心业务,其系统架构设计必须稳定且高效。现阶段一些大的集群或者云平台扩容或上线的话需要特别大的资源占用和极高硬件成本。另外,在部署时需要购买更高级的一些License授权才可以使用。然而ZStack不需要很高配置的硬件和授权,也可以支持两千多个节点的部署。现在已经有很多客户在使用这个平台了,比如饿了么等一些数据量访问很大的公司。ZStack的扩容性、扩展性很强,可以在不停机的情况下实现在线的、无缝的升级和扩展一些其他的常用功能。

重启zstack平台不影响业务


云计算基础平台小到3~5服务器,大到数万台,资源管理平台必须有强的适配性。以订餐平台为例,基本上有两个业务高峰期,在这两业务高峰期的时候人员的访问会急剧增加,使用的普通服务器或者普通云平台的部署来支持的话,会造成大量的资源浪费,这时,ZStack的弹性伸缩功能就派上用场了。它可以设定一系列的计划,当某个时间段的时候,企业的虚拟云主机数量不够用,它可以按照弹性伸缩的计划自动扩展,包括添加一些可以支持高并发的访问操作等,在几分钟之内就可以出现几百台所需的虚拟云主机。

另外, ZStack具有良好的兼容性,不会有硬件捆绑情况,可将现有设备进行利旧统一成资源池。减轻企业采购压力,促进节能环保。

以上就是我在使用ZStack过程的心得体会。

根据IDC的数据,到2021年,中国IT市场,公有云占比约27%,私有云占比约26%,剩下的45.8%是没有云化的传统IT,中国私有云市场近几年的增速会超过公有云。Gartner明确说中国未来将是市场上最大的私有云市场之一。

因此,中国私有云的市场前景非常广阔,私有云市场与公有云市场将会产生非常大的交集,这就是混合云市场。

日后,我司将持续使用ZStack云管平台,完成客户从公有云到私有云部署的全过程。
云计算
2019-05-10 17:53:00
6月20日,北京,由Rancher Labs主办的【2019企业容器创新大会】限免报名已开启!全天18场演讲,特邀中国人寿、中国联通、平安科技、新东方、阿里云、百度云等著名企业的IT负责人,分享容器技术的企业级落地经验。 大会上,Rancher Labs研发经理还将现场Demo即将发布的Rancher 2.3中Istio、Windows容器的功能及使用!还有K3s、Rio等的现场交流。点击 http://hdxu.cn/hMsQ8 了解详情及在线报名啦~
2019年6月6日,Rancher Labs发布了Rancher全新版本2.2.4,该版本修复了近期发现的两个安全漏洞CVE-2019-12303 和 CVE-2019-12274,项目级别的监控功能也在此版本回归,还有一系列功能与优化。
CVE修复
2.2.4版本包含两个安全漏洞修复 CVE-2019-12303 和 CVE-2019-12274
第一个漏洞会影响v2.0.0到v2.2.3的版本,项目管理员可以在对接日志系统时,通过注入额外的Fluentd配置参数,来读取到Fluentd容器内的文件或执行任意命令,例如其他项目管理员配置的ElasticSearch。
具体链接:
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-12274
第二个漏洞会影响v1.6.0到v1.6.27(使用Cattle和Kubernetes的用户)以及v2.0.0到v2.2.3的版本。某些内嵌的主机驱动可以配置一个文件路径的参数。通过主机驱动创建主机时,创建者可以通过该漏洞获取Rancher Server内任意容器的内容,例如 /root/.kube/config 。这样,主机创建者可以获取Rancher管理平面的访问权限。
具体链接:
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2019-12303
功能与优化
项目级别监控回归

AKS集群新增多个区域的支持
RKE AWS集群新增了多个区域的支持
增强了全局DNS对CloudFlare的支持
内置监控新版本,该版本对性能和稳定性进行了增强。


解决了加载含有大规模Kubernetes资源的集群时,Rancher UI加载延迟很大的问题。
https://github.com/rancher/rancher/issues/18522
通过压缩Rancher服务器与Rancher Agent之前的通讯信息,从而优化了性能。
https://github.com/rancher/rancher/issues/19493
其他优化与增强
下面是2.2.4中修复的一些主要的问题,更多详情可以通过下面的链接查看。
https://github.com/rancher/rancher/milestone/160
增强了应用商店稳定性和性能
https://github.com/rancher/rancher/issues/19881
https://github.com/rancher/rancher/issues/19880
优化了Rancher性能
https://github.com/rancher/rancher/issues/18522
https://github.com/rancher/rancher/issues/16605
https://github.com/rancher/rancher/issues/19934
支持激活OTC主机驱动
普通用户可以创建全局DNS
OpenStack集成增强
https://github.com/rancher/rancher/issues/20456
https://github.com/rancher/rancher/issues/20562
etcd快照功能增强
https://github.com/rancher/rancher/issues/18807
https://github.com/rancher/rancher/issues/18793
https://github.com/rancher/rancher/issues/19639
修复了多集群应用模版删除后无法显示的问题
https://github.com/rancher/rancher/issues/20432
修复了HA模式下,Rancher从节点中无法更新应用模版的问题
https://github.com/rancher/rancher/issues/20299
云计算
2019-06-11 14:23:04
阿里妹导读:软件质量不是测出来的,但为什么又有这么多测试工程师为了质量而工作?测试是一个成本部门,测试创造的价值是什么?研发的模式在不断地变化,测试的定位如何不断去定义,未来的测试又会是什么形态?今天,阿里巴巴高级测试开发专家傲野总结了对未来测试形态的一些思考,希望对正在做测试的同学有所启发。
前言
从社会发展上来说,各领域的分工越来越细。但从技术部门的发展上来看,测试和开发的角色却是在不断融合,背后的原因是什么?是互联网迭代的速度越来越快促成的多角色融合,还是因为技术(特别是质量技术)先进生产力在逐渐取代落后的生产力?
在回答这些问题之前,我们先来回顾“测试工程师”作为一个职能或者个体在过去的发展历程:
10年前,最初级的测试产出工件是比较一次性的,比如项目中写的文本型测试用例,基本在项目发布后就废弃了。 那个时期测试工作的进阶是方法论,比如能够把测试用例的设计方法,项目流程管理讲得头头是道已经是高阶了。 有一些技术能力的测试同学,投身于自动化脚本的编写。自动化在“软件”测试时代和互联网初期,是真正的硬核能力。
但这样的测试模式和效率都是非常低的,显然无法支撑互联网无快不破的浪潮。2010年以后,在头部企业的测试团队发生了一系列的变革,快速地从上述的这些初级能力,扩大到以 CI/CD 为驱动的技术体系,并最终推动了测试技术产品化进程,形成一个较为清晰的测试平台发展脉络。
在这个将近十年的周期中,由于测试工具、平台的不断创新,测试团队得到了一个突破性的发展。但工具作为传统测试模式的辅助手段,仍然会遇到突破的瓶颈。比如,从全球来看质量也发生了一定的分支: 一种是不断坚持平台化的发展路径:项目质量是基础,不断孵化出各类的效能平台,解决的问题也从传统的质量领域本身,往研发各环节拓展。有些大型的企业也开始沉淀了通用的研发协同平台(研发流水线)。 一种是从内往外突破:比如 Google 的 SRE 团队,以纯技术的手段,打造一个内建且自洽的质量体系(传统以证伪为理论依据的是一个外建的质量体系)。[1]
这两者的方向和目标,是有一定的重合的,比如有些公司以测试负责线下,SRE 负责线上进行区分。但如果从质量这个大的目标来看,未来的成功画面应该是:“质量和效率的结合”和“外建与自洽的结合”。因为只有这样,才能打造一个真正完整的技术质量生态。
实时质量
也是基于上述的一些思考和实践,我们在2017年底提出了“实时质量”的概念。“它不是一个具体的测试技术产品,而是一种面向未来解决质量问题的方法和手段。”
它的主要特性是:运行含测试,实时可反馈。
为什么要往这个方向发展?
随着技术的不断创新和交付模式的不断改变,对于测试团队来说,需要尽快地从交付型质量往实时质量方向进行转移。传统的交付型质量,把测试作为一道道关卡,以任务的方式布防在开发提测、项目发布时。这种方式存在不同角色之间的过多交互,只能起到单点的质量保障。而实时质量的目标是:将质量手段以模块、组件乃至系统化的方式嵌入到业务型应用中,形成实时保障质量的能力。未来开发和测试人员之间的合作(或者就不区分开发测试了),不仅仅是人与人之间的协同,更多是双方分别为完成“业务特性服务的代码”和为完成”业务质量服务的代码“而相互配合,并形成系统级的依赖关系。在提供的这些质量系统上,我们希望公司内部的各种角色都能成为质量的操作者。只在做到这些,我们才可能将测试工作真正从面向过程到面向对象。
图示:理想的测试工作方式
实时质量的架构
要做到质量的实时反馈和面向对象测试,这意味着我们的测试方法和协同方式发生了较为根本性的变化。我们需要以一个合适的方式参与到业务应用中,与此同时我们还需要把测试的各种能力封装成一个个服务,而不是现在的工具。工具终究是需要人来操作的,而我们希望未来测试任务的主体是机器、算法。测试人员只构建测试服务,而不参与测试过程,这也是最符合测试开发 Test Development Engineer 的 job design 。
图示:实时质量架构
那测试到底还需不需要做功能测试?可能在很长一段时间内仍然是需要的,但那一定只是日常工作中很小一部分。
实时质量是基于现有测试能力改造
我们在推进一个新的方向时,尽量不要去推翻重来。如果要面向未来,实时质量必须是可以向下兼容的,因为只是这样才能继承现有的测试沉淀,也才能被团队中的测试人员所接受和支持。只有自己不断进化才符合自然规律。所以我们需要更多强调对现有测试能力的改造,而避免另起炉灶。以下用运营页面测试的实时质量改造作为一个案例。
案例:运营页面的实时质量改造
作为电商域的同学对于运营页面应该非常熟悉,在之前也非常痛恨。比如:
“CBU的一次大促,运营人员至少需要配置千级以上的活动页面,而每一个页面上又包含几百上千个商品等活动元素,平均一个页面需要5到10分钟的人肉检测,同时运营和测试人员需要不断就测试标准和 Bug 来回讨论、提交。一次大促下来,我们至少需要十几人/日的测试资源才能保证会场的正确性。”
这个过程很痛苦,运营人员需要不断去找对应的测试同学协同,幸福感很差。而测试人员来说,这些页面的测试更多是一个重复劳动,一个黑盒。能力也得不到什么成长。我们如何对它来进行实时质量的改造呢?
总共分两步: 我们对传统的测试体系进行了改造。把以往通过人工测试的各个测试点,通过自动化的方式来实现。比如基于 DOM 树制定一系列规则,例如403这些的错误都可以被很好地扫描出来。同时,针对于一些无法通过规则排查的问题,我们运用了算法能力。例如空坑检测,一致性检测等。 把以上测试组件,通过消息的方式跟运营页面发布系统对接。
它的系统依赖关系是如下的:
图示:运营页面检测系统依赖图【示意】
同时针对于不同的业务场景,我们开发了不同的页面检测能力,比如针对于 DOM 树的页面检查:
还有基于算法能力的识别能力:
通过上述的改造后,对于运营人员发布页面以及页面的测试就极简化为三步一站式的能力。从以往运营、测试、开发之间的来回交接,变成了运营跟系统之间的交互。不仅提升了运营人员的页面搭建体验,也极大地提升了测试的效率。
在某次运行中活动中实际的执行结果【示意图】:
以上的过程和结果数据,也充分体现了“运行含测试,实时可反馈”的价值。
数据和算法是实时质量的核心
测试出现以来,我们一直习惯于代码逻辑类的测试,但数据一直都是测试很重要的生产材料。因为人肉执行任务的局限性,我们发明了等价类和边界值等测试理论和方法来用尽可能少的成本来尽可能多的验证问题。但一方面算法的不断应用,每一个数据都可能存在个性化的业务表达,我们可能无法找到一个通用的预期结果较验(还是会有一些通用的预期结果的,比如非空判断和区间等,但这类的预期不能很好地做业务判断)。因此,我们也需要用数据和算法能力来武装自己。
在以数据驱动的业务发展进程中,我们的测试主体已经从简单的代码转变为数据+算法。或者说,业务对质量的核心述求,已经从简单的页面错误、代码 BUG 到数据的准确性、算法的有效性(我老板在每次大促前,都要再三叮嘱我数据不能错)。如何来感知质量风险,以及捕获各类的异常?那必须先把数据、流量、监控来做收口,同时提升测试工具在大数据分析上的能力。
基于这些思考,我们构建了全域实时数据校验能力,是一款通过实时获取线上 DB 中的海量业务数据,完成业务数据校验、质量风险感知的产品。
案例:Captain 全域实时数据校验
图示:数据对比框架【示意】
它具备的一些能力: 严格的安全策略。 实时获取线上数据:通过强大的数据支持能力,平台可以在无损线上数据库表的前提下,通过 SQL 查询获取线上 DB 中的真实业务数据,且做到了实时获取,通过数据可以进行完善健壮的数据校验,从根本上提高对于业务的把控。 多样的数据获取方式:目前平台支持多种数据获取方式:单库单表查询、单库多表联表查询、分库分表查询、跨库的多表的联表查询。 多种比对方式支持,比如跨库查询和联表查询等等。
最主要,它可以用一套脚本无损地支持测试环境、灰度、生产环境等。让线下测试的所有经验可以得到复用和沉淀。(我们内部调侃说,这才是带着测试的灵魂的,而其他的很多产品都只是一个面向开发的工具)
在前期解决数据一致性,对账等常用的基本需求上,我们可以依赖于这些数据和测试的服务,展开更多的业务形态。
实时质量需要不断突破测试的边界
测试的边界在哪里?
过去有人告诉我,不能去修改业务应用的代码,只能让在盒子外面或者调用的方式来测试。还有人说,我们只开发工具,不能接触任何的业务。现在这些都在逐渐模糊,大家努力一起,让测试的很多活动,从简单的功能测试,往研发工具和业务质量等或前或后地迁移。
在过去的一两年,我们团队也已经慢慢承接了更多的职责,有些甚至于是直接服务于客服、运营和产品人员的。我认为,一支强的团队一定是不断走在突破原来工作边界的道路上。没有什么是一成不变的。
但每个职能团队都是有自己的核心价值的,而至于哪些应该由测试来做,哪些由开发做。我们的标准是:判断这件事情是更为了“让技术更有品质”还是“让技术创造新商业”?(“让技术更有品质”是我们团队的使命,“让技术拓展业务边界”是开发团队的目标)
以下虽然是几年前的例子,但也很好的体现了我们在边界的突破,以及如何用实时质量的思想来开装自己,创造提交 BUG 以外更多的价值。
案例:Offer 360提升客服端实时质量能力
商品链路复杂,线上问题排查难度大,之前开发每天平均投入2-3个小时处理线上问题,但实际上大部分的问题都是正常业务逻辑,并且可以让客满或者技术支持自助查询的。因此,我们通过提供实时查询错误日志以及 debug 信息的服务,把用户反馈问题的排查,开放给客服。帮助他们第一时间解决用户的问题。
实时质量未来规划
实时质量是一种思想,我觉得它未来是可以跨越在当前两种不同的发展分支上的。
测试这么多年来一直被弱化,我也看到集团很多优秀的测试 leader 转型开发、产品。如果我们还不多些思考,多些探索。如果做测试都还没有梦想,那跟咸鱼有什么区别?
图示:测试未来的发展
后记
上周在内部的论坛上看到一个开发专家的留言,还是挺有感触的。我们一直以来都在强调测试能力不断演进,强调开发能力,但测试的初心不能丢。我们在工具、测试能力上不断改进,但是从人和组织的角度上来看,在追求最高效的同时,我们是需要一定的组织设计来形成岗位间的相互监督。这也是在测试1.0阶段开始,测试被赋予的一种职责。
作者: 傲野
原文链接 ​
本文为云栖社区原创内容,未经允许不得转载。
云计算
2019-06-11 12:18:00
阿里云对中国用户来说是最好的云计算服务厂商了,而它提供的优惠也多种多样,不管对玩主机的新手还是老手,面对各种各样的活动都会陷入眼花缭乱的困境,因此,我专门写一篇文章来给大家抽丝剥茧,详细描绘一下对不同的用户怎么购买主机才是最优惠的。
优惠活动图
本人是拥有十年程序猿开发经验,大学本科四年,工作6年,软件工程出身,所以我用我们程序猿特有的软件来绘制一个优惠活动图。
大概花了半个多小时绘制玩这张活动图 /(ㄒoㄒ)/~~
名词解释: 新用户:没注册过阿里云的用户或者注册且实名了但从未购买任何产品的用户 首购用户:表示已注册并实名认证后但从未购买该产品的用户 老用户:已实名并购买过该产品的用户
活动列表: 阿里云新用户2000元新手红包
阿里云Hi拼团活动
阿里云首购3折活动
优惠路线 新用户路线
领取2000元红包 —> 找老用户 开hi拼团活动 —> 2.4折优惠
领取2000元红包 —> 参加首购活动 —> 3折优惠 首购用户路线
找新用户 开hi拼团活动 —> 可以找到 —> 2.4折优惠
找新用户 开hi拼团活动 —> 没找到 —> 3折优惠
参加 首购活动 —> 3折优惠 老用户且非首购路线
找新用户 开hi拼团活动 —> 可以找到 —> 2.4折优惠
找新用户 开hi拼团活动 —> 没找到 —> 直接购买 —> 3折优惠
花了大概一个多小时认真写了这篇,也是想给自己刚上线的网站【 zhaozhuji.info 】做做推广,谢谢拜访!
其实做这个图也是得益于我的一个微信群"独立开发者"的,感谢小程序【魅力拍】作者徐玉丰,算也是给他做做推广,感谢他的启发!
云计算
2019-06-08 19:29:00
或许很多人可能认为资源消耗并非安全问题,但实际上不合理的资源消耗会让黑客有可乘之机,来攻击K8s的组件。本文将介绍如何处理资源消耗或noisy neighbor问题,包括如何管理Pods中的资源以及管理项目和资源配额等。
本文是关于Kubernetes安全系列三篇文章中的最后一篇。在第一篇文章中,我们分享了如何确保企业的Kubernetes集群免受外部攻击;第二篇文章介绍了三种保护Kubernetes免受内部威胁的方法。在本文中,我们将介绍如何处理资源消耗或noisy neighbor问题。
对于那些设置了多租户Kubernetes集群的集群管理员而言,他们十分关注和担心的一个问题是,如何防止共同租户成为“noisy neighbor”,即一个垄断了CPU、内存、存储和其他资源的人。Noisy neighbor会对共享基础设施的其他用户资源的性能产生极坏的影响。
如此一来,跟踪Kubernetes容器和Pod的资源使用情况,对集群管理而言非常重要,因为它不仅可以保持容器编排系统处于最佳运行状态,降低运维成本,还可以加强Kubernetes的整体安全状况。
一些运维团队可能不认为资源消耗是一种重要的安全问题,至少没有保护Kubernetes免受内部和外部网络攻击重要。但这种观点是不正确的。因为厉害的黑客会利用功能不良的基础设施,来找到攻击Kubernetes组件的方法。
“安全不仅仅是‘不要闯进我的房子’,而是‘我怎么能让我的房子一直保持良好的运行状态’,”Rancher Labs的高级解决方案架构师Adrian Goins表示。
运维团队需要最大限度地利用Kubernetes Pods(一组具有共享存储和网络资源的一个或多个容器)所消耗的资源,以确保每个用户都能拥有最佳性能,并且能监控成本分配的使用情况。“使用等于成本,”Goins说,“因为Kubernetes资源都是运行在AWS、谷歌云、阿里云等等云提供商的底层计算基础设施上,一切资源消耗都以为着金钱成本。即使集群是在数据中心的裸机上运行,过多的使用也会花费硬件、电力和其他资源。”
默认情况下,配置容器时,对其可以使用的资源量没有任何限制。如果容器不能高效运行,部署容器的组织必将支付超额费用。值得庆幸的是,Kubernetes具有帮助运维团队管理和优化Kubernetes资源利用能力的功能。
管理Pods中的资源
当管理员定义Pod时,他们可以选择指定每个容器需要多少CPU和内存(RAM)。当容器指定了资源请求时,调度程序可以更好地决定将Pod放在哪个节点上。根据Kubernetes的文档,当容器指定了限制时,可以按指定的方式处理节点上的资源争用。
默认情况下,Kubernetes集群中的所有资源都是在默认的命名空间中创建的。命名空间是一种逻辑地将集群资源进行分组的方法,包括用于指定资源配额的选项。
管理员可以在命名空间上设置资源限制或配额,为在命名空间中运行的工作负载或应用程序分配一定量的CPU、RAM或存储——Kubernetes集群中的三个资源。“如果在命名空间中启动另一个资源会超出预设的配额,那么任何新资源都无法启动,”Goins指出。
“当你应用了资源配额时,意味着你强制在该命名空间中运行的所有内容为其自身设置资源限制。限制有两种类型:预留,和最大限制,”Goins解释说。例如,通过预留,管理员可以让Kubernetes集群为WordPress站点分配128 MB的RAM。对于部署的每个WordPress Pod,服务器本身将保证128 MB的RAM。因此,如果管理员将资源请求与1GB的资源配额相结合,则用户只能在超过其限制之前运行八个WordPress Pod。在那之后,他们将无法再使用RAM了。
资源限制的第二部分是最大限度。管理员可以预留128 MB的资源请求和最多256 MB的RAM。“如果Pod超过256 MB的RAM使用量,Kubernetes会杀死它并重新启动它,”Goins说。“如此以来,用户可以免受失控过程和noisy neighbor的影响。”
项目和资源配额
像Rancher这样的平台,旨在通过提供直观的界面和集中管理任务(如全局层的角色描述)来简化Kubernetes的管理。
正如前一篇关于内部威胁防护的文章所述,Rancher包含一个有助于减轻集群管理负担的“项目(Project)”资源,来超越命名空间。在Rancher中,Project允许管理员将多个命名空间作为单个实体进行管理。因此,Rancher可以将资源配额应用于Projects。
在标准Kubernetes部署中,资源配额只能应用于单独的命名空间。但是,管理员无法通过单次操作,同时将配额应用于命名空间。资源配额必须经过多次操作。
然而在Rancher中,管理员可以将资源配额应用于Project,然后将配额传播到每个命名空间。然后,Kubernetes会使用本机版本的资源配额,来强制执行管理员限制。如果管理员希望更改特定命名空间的配额,则可以覆盖以前的配额。
强化和优化Kubernetes
毋庸置疑,Kubernetes已成为容器编排的标准,这也促使大多数云和虚拟化供应商将其作为标准基础架构来提供。但是,对与Kubernetes环境相关的安全问题的普遍缺乏认识,可能会使各种组件暴露于来自网络集群内外的攻击中。
本系列文章的上两篇中提供了一些可行的步骤,来告诉大家如何通过使用Kubernetes功能和容器管理解决方案(如Rancher),来加强Kubernetes对外部和内部网络威胁的防范。企业应通过基于角色的访问控制(RBAC)和强身份验证从外部保护Kubernetes API访问。对于内部人员保护,由于Kubernetes集群是多用户,因此组织需要通过RBAC、逻辑隔离和NetworkPolicies来保护交叉通信。
为了防止其他租户垄断CPU、内存、存储和其他资源从而拖累整个集群的性能,Kubernetes提供资源限制和配额等功能,以帮助运维团队管理和优化Kubernetes资源利用功能。最后,除了可用的默认设置之外,业界还有一些非常有效的工具可以帮助用户完成Kubernetes集群的管理和保护。例如像Rancher这样的平台就是一种高度优化的容器管理解决方案,专为将多个集群部署到生产环境中的组织而构建,企业用户可以更轻松地管理和运行各地的Kubernetes。它可以保护Kubernetes集群免受外部黑客威胁、内部隐患甚至noisy neighbor。
云计算
2019-07-03 10:50:00
元数据服务是 BeeGFS 中用来维护文件和目录关系及其属性配置的服务,其多线程epoll设计实现非常高效,主要流程如下: ConnAcceptor(PThread)类(一个线程)负责监听端口,并接受客户端连接,然后把;连接信息(包含接收的套接字)写入管道; StreamListenerV2(PThread)类(多个线程,可配置)从管道读取连接信息,使用epoll轮询接收数据,然后生成IncomingPreprocessedMsgWork(Work),写入MultiWorkQueue先进先出队列; Worker(PThread)类(多个线程,可配置)从MultiWorkQueue队列取出消息进行处理。
程序初始化
主函数 创建App对象,App对象是程序的主要载体: // fhgfs_meta\source\program\main.cpp #include "Program.h" int main(int argc, char** argv) { return Program::main(argc, argv); } // fhgfs_meta\source\program\Program.cpp #include #include "Program.h" #include App* Program::app = NULL; int Program::main(int argc, char** argv) { BuildTypeTk::checkDebugBuildTypes(); AbstractApp::runTimeInitsAndChecks(); // must be called before creating a new App app = new App(argc, argv); app->startInCurrentThread(); int appRes = app->getAppResult(); delete app; return appRes; }
创建ConnAcceptor 主程序中会初始化一个线程,监听服务端口,由ConnAcceptor类负责: // fhgfs_meta\source\app\App.cpp void App::initComponents(TargetConsistencyState initialConsistencyState) throw(ComponentInitException) { this->log->log(Log_DEBUG, "Initializing components..."); this->dgramListener = new DatagramListener( netFilter, localNicList, ackStore, cfg->getConnMetaPortUDP() ); if(cfg->getTuneListenerPrioShift() ) dgramListener->setPriorityShift(cfg->getTuneListenerPrioShift() ); streamListenersInit(); unsigned short listenPort = cfg->getConnMetaPortTCP(); this->connAcceptor = new ConnAcceptor(this, localNicList, listenPort); this->statsCollector = new StatsCollector(workQueue, STATSCOLLECTOR_COLLECT_INTERVAL_MS, STATSCOLLECTOR_HISTORY_LENGTH); this->buddyResyncer = new BuddyResyncer(); this->internodeSyncer = new InternodeSyncer(initialConsistencyState); this->timerQueue = new TimerQueue(1, 1); this->modificationEventFlusher = new ModificationEventFlusher(); workersInit(); commSlavesInit(); this->log->log(Log_DEBUG, "Components initialized."); }
创建StreamListener 根据配置创建多个StreamListener实例,每个实例对应线程,用于从ConnAcceptor接收新连接,已及从从连接读取数据,生成Work: // fhgfs_meta\source\app\App.cpp void App::streamListenersInit() throw(ComponentInitException) { this->numStreamListeners = cfg->getTuneNumStreamListeners(); for(unsigned i=0; i < numStreamListeners; i++) { StreamListenerV2* listener = new StreamListenerV2( std::string("StreamLis") + StringTk::uintToStr(i+1), this, workQueue); if(cfg->getTuneListenerPrioShift() ) listener->setPriorityShift(cfg->getTuneListenerPrioShift() ); if(cfg->getTuneUseAggressiveStreamPoll() ) listener->setUseAggressivePoll(); streamLisVec.push_back(listener); } }
创建WorkQueue 创建WorkQueue,用于保存StreamListener生成的Work: // fhgfs_meta\source\app\App.cpp /** * Init basic shared objects like work queues, node stores etc. */ void App::initDataObjects() throw(InvalidConfigException) { ... this->workQueue = new MultiWorkQueue(); this->commSlaveQueue = new MultiWorkQueue(); if(cfg->getTuneUsePerUserMsgQueues() ) workQueue->setIndirectWorkList(new UserWorkContainer() ); ... }
创建Worker 根据配置创建Worker线程,从WorkQueue读取Work并进行处理: // fhgfs_meta\source\app\App.cpp void App::workersInit() throw(ComponentInitException) { unsigned numWorkers = cfg->getTuneNumWorkers(); for(unsigned i=0; i < numWorkers; i++) { Worker* worker = new Worker( std::string("Worker") + StringTk::uintToStr(i+1), workQueue, QueueWorkType_INDIRECT); worker->setBufLens(cfg->getTuneWorkerBufSize(), cfg->getTuneWorkerBufSize() ); workerList.push_back(worker); } for(unsigned i=0; i < APP_WORKERS_DIRECT_NUM; i++) { Worker* worker = new Worker( std::string("DirectWorker") + StringTk::uintToStr(i+1), workQueue, QueueWorkType_DIRECT); worker->setBufLens(cfg->getTuneWorkerBufSize(), cfg->getTuneWorkerBufSize() ); workerList.push_back(worker); } }
连接监听
监听类ConnAcceptor ConnAcceptor类的定义: // fhgfs_common\source\common\components\streamlistenerv2\ConnAcceptor.h class ConnAcceptor : public PThread { public: ConnAcceptor(AbstractApp* app, NicAddressList& localNicList, unsigned short listenPort) throw(ComponentInitException); virtual ~ConnAcceptor(); private: AbstractApp* app; LogContext log; StandardSocket* tcpListenSock; StandardSocket* sdpListenSock; RDMASocket* rdmaListenSock; int epollFD; bool initSocks(unsigned short listenPort, NicListCapabilities* localNicCaps); virtual void run(); void listenLoop(); void onIncomingStandardConnection(StandardSocket* sock); void onIncomingRDMAConnection(RDMASocket* sock); void applySocketOptions(StandardSocket* sock); public: // getters & setters };
连接监听循环 使用epool来轮询监听端口,并建立新连接: // fhgfs_common\source\common\components\streamlistenerv2\ConnAcceptor.cpp void ConnAcceptor::run() { try { registerSignalHandler(); listenLoop(); log.log(Log_DEBUG, "Component stopped."); } catch(std::exception& e) { PThread::getCurrentThreadApp()->handleComponentException(e); } } void ConnAcceptor::listenLoop() { const int epollTimeoutMS = 3000; struct epoll_event epollEvents[EPOLL_EVENTS_NUM]; // (just to have these values on the stack...) const int epollFD = this->epollFD; RDMASocket* rdmaListenSock = this->rdmaListenSock; StandardSocket* sdpListenSock = this->sdpListenSock; StandardSocket* tcpListenSock = this->tcpListenSock; // wait for incoming events and handle them... while(!getSelfTerminate() ) { //log.log(Log_DEBUG, std::string("Before poll(). pollArrayLen: ") + // StringTk::uintToStr(pollArrayLen) ); int epollRes = epoll_wait(epollFD, epollEvents, EPOLL_EVENTS_NUM, epollTimeoutMS); if(unlikely(epollRes < 0) ) { // error occurred if(errno == EINTR) // ignore interruption, because the debugger causes this continue; log.logErr(std::string("Unrecoverable epoll_wait error: ") + System::getErrString() ); break; } // handle incoming connection attempts for(size_t i=0; i < (size_t)epollRes; i++) { struct epoll_event* currentEvent = &epollEvents[i]; Pollable* currentPollable = (Pollable*)currentEvent->data.ptr; //log.log(Log_DEBUG, std::string("Incoming data on FD: ") + // StringTk::intToStr(pollArray[i].fd) ); // debug in if(currentPollable == rdmaListenSock) onIncomingRDMAConnection(rdmaListenSock); else if(currentPollable == tcpListenSock) onIncomingStandardConnection(tcpListenSock); else if(currentPollable == sdpListenSock) onIncomingStandardConnection(sdpListenSock); else { // unknown connection => should never happen log.log(Log_WARNING, "Should never happen: Ignoring event for unknown connection. " "FD: " + StringTk::uintToStr(currentPollable->getFD() ) ); } } } }
套接字监听处理(派发给流) 把建立的套接字发送给指定的StreamListener: // fhgfs_common\source\common\components\streamlistenerv2\ConnAcceptor.cpp /** * Accept the incoming connection and add new socket to StreamListenerV2 queue. * * Note: This is for standard sockets like TCP and SDP. */ void ConnAcceptor::onIncomingStandardConnection(StandardSocket* sock) { try { struct sockaddr_in peerAddr; socklen_t peerAddrLen = sizeof(peerAddr); StandardSocket* acceptedSock = (StandardSocket*)sock->accept( (struct sockaddr*)&peerAddr, &peerAddrLen); // (note: level Log_DEBUG to avoid spamming the log until we have log topics) log.log(Log_DEBUG, std::string("Accepted new connection from " + Socket::endpointAddrToString(&peerAddr.sin_addr, ntohs(peerAddr.sin_port) ) ) + std::string(" [SockFD: ") + StringTk::intToStr(acceptedSock->getFD() ) + std::string("]") ); applySocketOptions(acceptedSock); // hand the socket over to a stream listener StreamListenerV2* listener = app->getStreamListenerByFD(acceptedSock->getFD() ); StreamListenerV2::SockReturnPipeInfo returnInfo( StreamListenerV2::SockPipeReturn_NEWCONN, acceptedSock); listener->getSockReturnFD()->write(&returnInfo, sizeof(returnInfo) ); } catch(SocketException& se) { log.logErr(std::string("Trying to continue after connection accept error: ") + se.what() ); } }
流处理的选择 选择StreamListener时,是根据fd的数值取模运算得来: // fhgfs_meta\source\app\App.h class App : public AbstractApp { public: /** * Get one of the available stream listeners based on the socket file descriptor number. * This is to load-balance the sockets over all available stream listeners and ensure that * sockets are not bouncing between different stream listeners. * * Note that IB connections eat two fd numbers, so 2 and multiples of 2 might not be a good * value for number of stream listeners. */ virtual StreamListenerV2* getStreamListenerByFD(int fd) { return streamLisVec[fd % numStreamListeners]; } }
数据包流处理
流处理类StreamListenerV2 StreamListener的定义: // fhgfs_common\source\common\components\streamlistenerv2\StreamListenerV2.h class StreamListenerV2 : public PThread { public: /** * This is what we will send over the socket return pipe */ struct SockReturnPipeInfo { /** * Standard constructor for creating/sending a returnInfo. */ SockReturnPipeInfo(SockPipeReturnType returnType, Socket* sock) : returnType(returnType), sock(sock) {} /** * For receiving only (no initialization of members). */ SockReturnPipeInfo() {} SockPipeReturnType returnType; Socket* sock; }; }
流处理循环 StreamListener使用epoll同时处理新连接以及数据接收: // fhgfs_common\source\common\components\streamlistenerv2\StreamListenerV2.cpp void StreamListenerV2::run() { try { registerSignalHandler(); listenLoop(); log.log(Log_DEBUG, "Component stopped."); } catch(std::exception& e) { PThread::getCurrentThreadApp()->handleComponentException(e); } } void StreamListenerV2::listenLoop() { const int epollTimeoutMS = useAggressivePoll ? 0 : 3000; struct epoll_event epollEvents[EPOLL_EVENTS_NUM]; // (just to have these values on the stack...) const int epollFD = this->epollFD; FileDescriptor* sockReturnPipeReadEnd = this->sockReturnPipe->getReadFD(); bool runRDMAConnIdleCheck = false; // true just means we call the method (not enforce the check) // wait for incoming events and handle them... while(!getSelfTerminate() ) { //log.log(Log_DEBUG, std::string("Before poll(). pollArrayLen: ") + // StringTk::uintToStr(pollArrayLen) ); int epollRes = epoll_wait(epollFD, epollEvents, EPOLL_EVENTS_NUM, epollTimeoutMS); if(unlikely(epollRes < 0) ) { // error occurred if(errno == EINTR) // ignore interruption, because the debugger causes this continue; log.logErr(std::string("Unrecoverable epoll_wait error: ") + System::getErrString() ); break; } else if(unlikely(!epollRes || (rdmaCheckForceCounter++ > RDMA_CHECK_FORCE_POLLLOOPS) ) ) { // epollRes==0 is nothing to worry about, just idle // note: we can't run idle check here directly because the check might modify the // poll set, which will be accessed in the loop below runRDMAConnIdleCheck = true; } // handle incoming data & connection attempts for(size_t i=0; i < (size_t)epollRes; i++) { struct epoll_event* currentEvent = &epollEvents[i]; Pollable* currentPollable = (Pollable*)currentEvent->data.ptr; if(currentPollable == sockReturnPipeReadEnd) onSockReturn(); else onIncomingData( (Socket*)currentPollable); } if(unlikely(runRDMAConnIdleCheck) ) { // note: whether check actually happens depends on elapsed time since last check runRDMAConnIdleCheck = false; rdmaConnIdleCheck(); } } }
新连接处理 如果是新连接,则加入epoll的fd中: // fhgfs_common\source\common\components\streamlistenerv2\StreamListenerV2.cpp /** * Receive pointer to returned socket through the sockReturnPipe and re-add it to the pollList. */ void StreamListenerV2::onSockReturn() { SockReturnPipeInfo returnInfos[SOCKRETURN_SOCKS_NUM]; // try to get multiple returnInfos at once (if available) ssize_t readRes = sockReturnPipe->getReadFD()->read(&returnInfos, sizeof(SockReturnPipeInfo) ); // loop: walk over each info and handle the contained socket for(size_t i=0; ; i++) { SockReturnPipeInfo& currentReturnInfo = returnInfos[i]; // make sure we have a complete SockReturnPipeInfo if(unlikely(readRes < (ssize_t)sizeof(SockReturnPipeInfo) ) ) { // only got a partial SockReturnPipeInfo => recv the rest char* currentReturnInfoChar = (char*)¤tReturnInfo; sockReturnPipe->getReadFD()->readExact( ¤tReturnInfoChar[readRes], sizeof(SockReturnPipeInfo)-readRes); readRes = sizeof(SockReturnPipeInfo); } // handle returnInfo depending on contained returnType... Socket* currentSock = currentReturnInfo.sock; SockPipeReturnType returnType = currentReturnInfo.returnType; switch(returnType) { case SockPipeReturn_MSGDONE_NOIMMEDIATE: { // most likely case: worker is done with a msg and now returns the sock to the epoll set struct epoll_event epollEvent; epollEvent.events = EPOLLIN | EPOLLONESHOT | EPOLLET; epollEvent.data.ptr = currentSock; int epollRes = epoll_ctl(epollFD, EPOLL_CTL_MOD, currentSock->getFD(), &epollEvent); if(likely(!epollRes) ) { // sock was successfully re-armed in epoll set pollList.add(currentSock); break; // break out of switch } else if(errno != ENOENT) { // error log.logErr("Unable to re-arm sock in epoll set. " "FD: " + StringTk::uintToStr(currentSock->getFD() ) + "; " "SockTypeNum: " + StringTk::uintToStr(currentSock->getSockType() ) + "; " "SysErr: " + System::getErrString() ); log.log(Log_NOTICE, "Disconnecting: " + currentSock->getPeername() ); delete(currentSock); break; // break out of switch } /* for ENOENT, we fall through to NEWCONN, because this socket appearently wasn't used with this stream listener yet, so we need to add it (instead of modify it) */ } // might fall through here on ENOENT case SockPipeReturn_NEWCONN: { // new conn from ConnAcceptor (or wasn't used with this stream listener yet) // add new socket file descriptor to epoll set struct epoll_event epollEvent; epollEvent.events = EPOLLIN | EPOLLONESHOT | EPOLLET; epollEvent.data.ptr = currentSock; int epollRes = epoll_ctl(epollFD, EPOLL_CTL_ADD, currentSock->getFD(), &epollEvent); if(likely(!epollRes) ) { // socket was successfully added to epoll set pollList.add(currentSock); } else { // adding to epoll set failed => unrecoverable error log.logErr("Unable to add sock to epoll set. " "FD: " + StringTk::uintToStr(currentSock->getFD() ) + " " "SockTypeNum: " + StringTk::uintToStr(currentSock->getSockType() ) + " " "SysErr: " + System::getErrString() ); log.log(Log_NOTICE, "Disconnecting: " + currentSock->getPeername() ); delete(currentSock); } } break; case SockPipeReturn_MSGDONE_WITHIMMEDIATE: { // special case: worker detected that immediate data is available after msg processing // data immediately available => recv header and so on onIncomingData(currentSock); } break; default: { // should never happen: unknown/unhandled returnType log.logErr("Should never happen: " "Unknown socket return type: " + StringTk::uintToStr(returnType) ); } break; } // end of switch(returnType) readRes -= sizeof(SockReturnPipeInfo); if(!readRes) break; // all received returnInfos have been processed } // end of "for each received SockReturnPipeInfo" loop }
数据包处理(生成工作) 生成Work(IncomingPreprocessedMsgWork),并放进队列(MultiWorkQueue): // fhgfs_common\source\common\components\streamlistenerv2\StreamListenerV2.cpp /** * Receive msg header and add the socket to the work queue. */ void StreamListenerV2::onIncomingData(Socket* sock) { // check whether this is just a false alarm from a RDMASocket if( (sock->getSockType() == NICADDRTYPE_RDMA) && isFalseAlarm( (RDMASocket*)sock) ) { return; } try { const int recvTimeoutMS = 5000; char msgHeaderBuf[NETMSG_HEADER_LENGTH]; NetMessageHeader msgHeader; // receive & deserialize message header sock->recvExactT(msgHeaderBuf, NETMSG_HEADER_LENGTH, 0, recvTimeoutMS); NetMessage::deserializeHeader(msgHeaderBuf, NETMSG_HEADER_LENGTH, &msgHeader); /* (note on header verification: we leave header verification work to the worker threads to save CPU cycles in the stream listener and instead just take what we need to know here, no matter whether the header is valid or not.) */ // create work and add it to queue //log.log(Log_DEBUG, "Creating new work for to the queue"); IncomingPreprocessedMsgWork* work = new IncomingPreprocessedMsgWork(app, sock, &msgHeader); int sockFD = sock->getFD(); /* note: we store this here for delayed pollList removal, because worker thread might disconnect, so the sock gets deleted by the worker and thus "sock->" pointer becomes invalid */ sock->setHasActivity(); // mark sock as active (for idle disconnect check) // (note: userID intToStr (not uint) because default userID (~0) looks better this way) LOG_DEBUG("StreamListenerV2::onIncomingData", Log_DEBUG, "Incoming message: " + NetMsgStrMapping().defineToStr(msgHeader.msgType) + "; " "from: " + sock->getPeername() + "; " "userID: " + StringTk::intToStr(msgHeader.msgUserID) + (msgHeader.msgTargetID ? "; targetID: " + StringTk::uintToStr(msgHeader.msgTargetID) : "") ); if (sock->getIsDirect()) getWorkQueue(msgHeader.msgTargetID)->addDirectWork(work, msgHeader.msgUserID); else getWorkQueue(msgHeader.msgTargetID)->addIndirectWork(work, msgHeader.msgUserID); /* notes on sock handling: *) no need to remove sock from epoll set, because we use edge-triggered mode with oneshot flag (which disables further events after first one has been reported). *) a sock that is closed by a worker is not a problem, because it will automatically be removed from the epoll set by the kernel. *) we just need to re-arm the epoll entry upon sock return. */ pollList.removeByFD(sockFD); return; } catch(SocketTimeoutException& e) { log.log(Log_NOTICE, "Connection timed out: " + sock->getPeername() ); } catch(SocketDisconnectException& e) { // (note: level Log_DEBUG here to avoid spamming the log until we have log topics) log.log(Log_DEBUG, std::string(e.what() ) ); } catch(SocketException& e) { log.log(Log_NOTICE, "Connection error: " + sock->getPeername() + ": " + std::string(e.what() ) ); } // socket exception occurred => cleanup pollList.removeByFD(sock->getFD() ); IncomingPreprocessedMsgWork::invalidateConnection(sock); // also includes delete(sock) }
工作处理
工人类(Worker) // fhgfs_common\source\common\components\streamlistenerv2\ConnAcceptor.cpp #define WORKER_BUFIN_SIZE (1024*1024*4) #define WORKER_BUFOUT_SIZE WORKER_BUFIN_SIZE class Worker : public PThread { public: Worker(std::string workerID, MultiWorkQueue* workQueue, QueueWorkType workType) throw(ComponentInitException); virtual ~Worker() { SAFE_FREE(bufIn); SAFE_FREE(bufOut); } private: LogContext log; bool terminateWithFullQueue; // allow self-termination when queue not empty (see setter nodes) size_t bufInLen; char* bufIn; size_t bufOutLen; char* bufOut; MultiWorkQueue* workQueue; QueueWorkType workType; HighResolutionStats stats; virtual void run(); void workLoopAnyWork(); void workLoopDirectWork(); void initBuffers(); // inliners bool maySelfTerminateNow() { if(terminateWithFullQueue || (!workQueue->getDirectWorkListSize() && !workQueue->getIndirectWorkListSize() ) ) return true; return false; } public: // setters & getters /** * Note: Do not use this after the run method of this component has been called! */ void setBufLens(size_t bufInLen, size_t bufOutLen) { this->bufInLen = bufInLen; this->bufOutLen = bufOutLen; } /** * WARNING: This will only work if there is only a single worker attached to a queue. * Otherwise the queue would need a getWorkAndDontWait() method that is used during the * termination phase of the worker, because the queue might become empty before the worker * calls waitForWork() after the maySelfTerminateNow check. */ void disableTerminationWithFullQueue() { this->terminateWithFullQueue = false; } };
工作类(Work) // fhgfs_common\source\common\components\worker\Work.h class Work { public: Work() { HighResolutionStatsTk::resetStats(&stats); } virtual ~Work() {} Work(const Work&) = delete; Work(Work&&) = delete; Work& operator=(const Work&) = delete; Work& operator=(Work&&) = delete; virtual void process(char* bufIn, unsigned bufInLen, char* bufOut, unsigned bufOutLen) = 0; protected: HighResolutionStats stats; public: HighResolutionStats* getHighResolutionStats() { return &stats; } #ifdef BEEGFS_DEBUG_PROFILING TimeFine* getAgeTime() { return &age; } private: TimeFine age; #endif }; // fhgfs_common\source\common\components\streamlistenerv2\IncomingPreprocessedMsgWork.h class IncomingPreprocessedMsgWork : public Work { public: /** * Note: Be aware that this class is only for stream connections that need to be returned * to a StreamListenerV2 after processing. * * @param msgHeader contents will be copied */ IncomingPreprocessedMsgWork(AbstractApp* app, Socket* sock, NetMessageHeader* msgHeader) { this->app = app; this->sock = sock; this->msgHeader = *msgHeader; } virtual void process(char* bufIn, unsigned bufInLen, char* bufOut, unsigned bufOutLen); static void releaseSocket(AbstractApp* app, Socket** sock, NetMessage* msg); static void invalidateConnection(Socket* sock); static bool checkRDMASocketImmediateData(AbstractApp* app, Socket* sock); private: AbstractApp* app; Socket* sock; NetMessageHeader msgHeader; };
工作循环 从WorkQueens获取Work并进行处理: // fhgfs_common\source\common\components\worker\Worker.cpp void Worker::workLoop(QueueWorkType workType) { LOG(DEBUG, "Ready", as("TID", System::getTID()), workType); workQueue->incNumWorkers(); // add this worker to queue stats while(!getSelfTerminate() || !maySelfTerminateNow() ) { Work* work = waitForWorkByType(stats, personalWorkQueue, workType); #ifdef BEEGFS_DEBUG_PROFILING TimeFine workStartTime; #endif HighResolutionStatsTk::resetStats(&stats); // prepare stats // process the work packet work->process(bufIn, bufInLen, bufOut, bufOutLen); // update stats stats.incVals.workRequests = 1; HighResolutionStatsTk::addHighResIncStats(*work->getHighResolutionStats(), stats); #ifdef BEEGFS_DEBUG_PROFILING TimeFine workEndTime; const auto workElapsedMS = workEndTime.elapsedSinceMS(&workStartTime); const auto workLatencyMS = workEndTime.elapsedSinceMS(work->getAgeTime()); if (workElapsedMS >= 10) { if (workLatencyMS >= 10) LOG_TOP(WORKQUEUES, DEBUG, "Work processed.", as("Elapsed ms", workElapsedMS), as("Total latency (ms)", workLatencyMS)); else LOG_TOP(WORKQUEUES, DEBUG, "Work processed.", as("Elapsed ms", workElapsedMS), as("Total latency (us)", workEndTime.elapsedSinceMicro(work->getAgeTime()))); } else { if (workLatencyMS >= 10) { LOG_TOP(WORKQUEUES, DEBUG, "Work processed.", as("Elapsed us", workEndTime.elapsedSinceMicro(&workStartTime)), as("Total latency (ms)", workEndTime.elapsedSinceMS(work->getAgeTime()))); } else { LOG_TOP(WORKQUEUES, DEBUG, "Work processed.", as("Elapsed us", workEndTime.elapsedSinceMicro(&workStartTime)), as("Total latency (us)", workEndTime.elapsedSinceMicro(work->getAgeTime()))); } } #endif // cleanup delete(work); } }
工作处理(消息生成和处理) 处理Work时,使用Work基类的processIncoming虚函数进行处理: // fhgfs_common\source\common\components\streamlistenerv2\IncomingPreprocessedMsgWork.cpp void IncomingPreprocessedMsgWork::process(char* bufIn, unsigned bufInLen, char* bufOut, unsigned bufOutLen) { const char* logContextStr = "Work (process incoming msg)"; const int recvTimeoutMS = 5000; unsigned numReceived = NETMSG_HEADER_LENGTH; // (header actually received by stream listener) NetMessage* msg = NULL; try { // attach stats to sock (stream listener already received the msg header) stats.incVals.netRecvBytes += NETMSG_HEADER_LENGTH; sock->setStats(&stats); // make sure msg length fits into our receive buffer unsigned msgLength = msgHeader.msgLength; unsigned msgPayloadLength = msgLength - numReceived; if(unlikely(msgPayloadLength > bufInLen) ) { // message too big LogContext(logContextStr).log(Log_NOTICE, std::string("Received a message that is too large. Disconnecting: ") + sock->getPeername() ); sock->unsetStats(); invalidateConnection(sock); return; } // receive the message payload if(msgPayloadLength) sock->recvExactT(bufIn, msgPayloadLength, 0, recvTimeoutMS); // we got the complete message buffer => create msg object AbstractApp* app = PThread::getCurrentThreadApp(); ICommonConfig* cfg = app->getCommonConfig(); AbstractNetMessageFactory* netMessageFactory = app->getNetMessageFactory(); msg = netMessageFactory->createFromPreprocessedBuf(&msgHeader, bufIn, msgPayloadLength); if(unlikely(msg->getMsgType() == NETMSGTYPE_Invalid) ) { // message invalid LogContext(logContextStr).log(Log_NOTICE, std::string("Received an invalid message. Disconnecting: ") + sock->getPeername() ); sock->unsetStats(); invalidateConnection(sock); delete(msg); return; } // process the received msg bool processRes = false; if(likely(!cfg->getConnAuthHash() || sock->getIsAuthenticated() || (msg->getMsgType() == NETMSGTYPE_AuthenticateChannel) ) ) { // auth disabled or channel is auth'ed or this is an auth msg => process NetMessage::ResponseContext rctx(NULL, sock, bufOut, bufOutLen, &stats); processRes = msg->processIncoming(rctx); } else LogContext(logContextStr).log(Log_NOTICE, std::string("Rejecting message from unauthenticated peer: ") + sock->getPeername() ); // processing completed => cleanup bool needSockRelease = msg->getReleaseSockAfterProcessing(); delete(msg); msg = NULL; if(!needSockRelease) return; // sock release was already done within msg->processIncoming() method if(unlikely(!processRes) ) { // processIncoming encountered messaging error => invalidate connection LogContext(logContextStr).log(Log_NOTICE, std::string("Problem encountered during processing of a message. Disconnecting: ") + sock->getPeername() ); invalidateConnection(sock); return; } releaseSocket(app, &sock, NULL); return; } catch(SocketTimeoutException& e) { LogContext(logContextStr).log(Log_NOTICE, std::string("Connection timed out: ") + sock->getPeername() ); } catch(SocketDisconnectException& e) { // (note: level Log_DEBUG here to avoid spamming the log until we have log topics) LogContext(logContextStr).log(Log_DEBUG, std::string(e.what() ) ); } catch(SocketException& e) { LogContext(logContextStr).log(Log_NOTICE, std::string("Connection error: ") + sock->getPeername() + std::string(": ") + std::string(e.what() ) ); } // socket exception occurred => cleanup if(msg && msg->getReleaseSockAfterProcessing() ) { sock->unsetStats(); invalidateConnection(sock); } SAFE_DELETE(msg); }
消息工厂
消息工厂类(NetMessageFactory) StreamListener收到数据时使用消息工厂类生成各种类型的消息: // fhgfs_meta\source\net\message\NetMessageFactory.h class NetMessageFactory : public AbstractNetMessageFactory { public: NetMessageFactory() {} protected: virtual NetMessage* createFromMsgType(unsigned short msgType); } ;
消息工厂初始化 // fhgfs_meta\source\app\App.cpp /** * Init basic networking data structures. * * Note: no RDMA is detected here, because this needs to be done later */ void App::initBasicNetwork() { // check if management host is defined if(!cfg->getSysMgmtdHost().length() ) throw InvalidConfigException("Management host undefined"); // prepare filter for outgoing packets/connections this->netFilter = new NetFilter(cfg->getConnNetFilterFile() ); this->tcpOnlyFilter = new NetFilter(cfg->getConnTcpOnlyFilterFile() ); // prepare filter for interfaces StringList allowedInterfaces; std::string interfacesList = cfg->getConnInterfacesList(); if(!interfacesList.empty() ) { log->log(Log_DEBUG, "Allowed interfaces: " + interfacesList); StringTk::explodeEx(interfacesList, ',', true, &allowedInterfaces); } // discover local NICs and filter them NetworkInterfaceCard::findAllInterfaces(allowedInterfaces, cfg->getConnUseSDP(), localNicList); if(localNicList.empty() ) throw InvalidConfigException("Couldn't find any usable NIC"); localNicList.sort(&NetworkInterfaceCard::nicAddrPreferenceComp); // prepare factory for incoming messages this->netMessageFactory = new NetMessageFactory(); }
生成消息 消息实例的生成均根据msgType来确定: // fhgfs_meta\source\net\message\NetMessageFactory.cpp /** * @return NetMessage that must be deleted by the caller * (msg->msgType is NETMSGTYPE_Invalid on error) */ NetMessage* NetMessageFactory::createFromMsgType(unsigned short msgType) { NetMessage* msg; switch(msgType) { // The following lines are grouped by "type of the message" and ordered alphabetically inside // the groups. There should always be one message per line to keep a clear layout (although // this might lead to lines that are longer than usual) // control messages case NETMSGTYPE_Ack: { msg = new AckMsgEx(); } break; case NETMSGTYPE_AuthenticateChannel: { msg = new AuthenticateChannelMsgEx(); } break; case NETMSGTYPE_GenericResponse: { msg = new GenericResponseMsg(); } break; case NETMSGTYPE_SetChannelDirect: { msg = new SetChannelDirectMsgEx(); } break; case NETMSGTYPE_PeerInfo: { msg = new PeerInfoMsgEx(); } break; // nodes messages case NETMSGTYPE_ChangeTargetConsistencyStatesResp: { msg = new ChangeTargetConsistencyStatesRespMsg(); } break; case NETMSGTYPE_GenericDebug: { msg = new GenericDebugMsgEx(); } break; case NETMSGTYPE_GetClientStats: { msg = new GetClientStatsMsgEx(); } break; case NETMSGTYPE_GetMirrorBuddyGroupsResp: { msg = new GetMirrorBuddyGroupsRespMsg(); } break; case NETMSGTYPE_GetNodeCapacityPools: { msg = new GetNodeCapacityPoolsMsgEx(); } break; case NETMSGTYPE_GetNodeCapacityPoolsResp: { msg = new GetNodeCapacityPoolsRespMsg(); } break; case NETMSGTYPE_GetNodes: { msg = new GetNodesMsgEx(); } break; case NETMSGTYPE_GetNodesResp: { msg = new GetNodesRespMsg(); } break; case NETMSGTYPE_GetStatesAndBuddyGroupsResp: { msg = new GetStatesAndBuddyGroupsRespMsg(); } break; case NETMSGTYPE_GetTargetMappings: { msg = new GetTargetMappingsMsgEx(); } break; case NETMSGTYPE_GetTargetMappingsResp: { msg = new GetTargetMappingsRespMsg(); } break; case NETMSGTYPE_GetTargetStatesResp: { msg = new GetTargetStatesRespMsg(); } break; case NETMSGTYPE_HeartbeatRequest: { msg = new HeartbeatRequestMsgEx(); } break; case NETMSGTYPE_Heartbeat: { msg = new HeartbeatMsgEx(); } break; case NETMSGTYPE_MapTargets: { msg = new MapTargetsMsgEx(); } break; case NETMSGTYPE_PublishCapacities: { msg = new PublishCapacitiesMsgEx(); } break; case NETMSGTYPE_RegisterNodeResp: { msg = new RegisterNodeRespMsg(); } break; case NETMSGTYPE_RemoveNode: { msg = new RemoveNodeMsgEx(); } break; case NETMSGTYPE_RemoveNodeResp: { msg = new RemoveNodeRespMsg(); } break; case NETMSGTYPE_RefreshCapacityPools: { msg = new RefreshCapacityPoolsMsgEx(); } break; case NETMSGTYPE_RefreshTargetStates: { msg = new RefreshTargetStatesMsgEx(); } break; case NETMSGTYPE_SetMirrorBuddyGroup: { msg = new SetMirrorBuddyGroupMsgEx(); } break; case NETMSGTYPE_SetRootNodeIDResp: { msg = new SetRootNodeIDRespMsg(); } break; case NETMSGTYPE_SetTargetConsistencyStates: { msg = new SetTargetConsistencyStatesMsgEx(); } break; case NETMSGTYPE_SetTargetConsistencyStatesResp: { msg = new SetTargetConsistencyStatesRespMsg(); } break; // storage messages case NETMSGTYPE_FindEntryname: { msg = new FindEntrynameMsgEx(); } break; case NETMSGTYPE_FindLinkOwner: { msg = new FindLinkOwnerMsgEx(); } break; case NETMSGTYPE_FindOwner: { msg = new FindOwnerMsgEx(); } break; case NETMSGTYPE_FindOwnerResp: { msg = new FindOwnerRespMsg(); } break; case NETMSGTYPE_GetChunkFileAttribsResp: { msg = new GetChunkFileAttribsRespMsg(); } break; case NETMSGTYPE_GetStorageTargetInfo: { msg = new GetStorageTargetInfoMsgEx(); } break; case NETMSGTYPE_GetEntryInfo: { msg = new GetEntryInfoMsgEx(); } break; case NETMSGTYPE_GetEntryInfoResp: { msg = new GetEntryInfoRespMsg(); } break; case NETMSGTYPE_GetHighResStats: { msg = new GetHighResStatsMsgEx(); } break; case NETMSGTYPE_GetMetaResyncStats: { msg = new GetMetaResyncStatsMsgEx(); } break; case NETMSGTYPE_RequestExceededQuotaResp: {msg = new RequestExceededQuotaRespMsg(); } break; case NETMSGTYPE_SetExceededQuota: {msg = new SetExceededQuotaMsgEx(); } break; case NETMSGTYPE_StorageResyncStarted: { msg = new StorageResyncStartedMsgEx(); } break; case NETMSGTYPE_StorageResyncStartedResp: { msg = new StorageResyncStartedRespMsg(); } break; case NETMSGTYPE_GetXAttr: { msg = new GetXAttrMsgEx(); } break; case NETMSGTYPE_Hardlink: { msg = new HardlinkMsgEx(); } break; case NETMSGTYPE_HardlinkResp: { msg = new HardlinkRespMsg(); } break; case NETMSGTYPE_ListDirFromOffset: { msg = new ListDirFromOffsetMsgEx(); } break; case NETMSGTYPE_ListDirFromOffsetResp: { msg = new ListDirFromOffsetRespMsg(); } break; case NETMSGTYPE_ListXAttr: { msg = new ListXAttrMsgEx(); } break; case NETMSGTYPE_LookupIntent: { msg = new LookupIntentMsgEx(); } break; case NETMSGTYPE_LookupIntentResp: { msg = new LookupIntentRespMsg(); } break; case NETMSGTYPE_MkDir: { msg = new MkDirMsgEx(); } break; case NETMSGTYPE_MkDirResp: { msg = new MkDirRespMsg(); } break; case NETMSGTYPE_MkFile: { msg = new MkFileMsgEx(); } break; case NETMSGTYPE_MkFileResp: { msg = new MkFileRespMsg(); } break; case NETMSGTYPE_MkFileWithPattern: { msg = new MkFileWithPatternMsgEx(); } break; case NETMSGTYPE_MkFileWithPatternResp: { msg = new MkFileWithPatternRespMsg(); } break; case NETMSGTYPE_MkLocalDir: { msg = new MkLocalDirMsgEx(); } break; case NETMSGTYPE_MkLocalDirResp: { msg = new MkLocalDirRespMsg(); } break; case NETMSGTYPE_MkLocalFileResp: { msg = new MkLocalFileRespMsg(); } break; case NETMSGTYPE_MovingDirInsert: { msg = new MovingDirInsertMsgEx(); } break; case NETMSGTYPE_MovingDirInsertResp: { msg = new MovingDirInsertRespMsg(); } break; case NETMSGTYPE_MovingFileInsert: { msg = new MovingFileInsertMsgEx(); } break; case NETMSGTYPE_MovingFileInsertResp: { msg = new MovingFileInsertRespMsg(); } break; case NETMSGTYPE_RefreshEntryInfo: { msg = new RefreshEntryInfoMsgEx(); } break; case NETMSGTYPE_RefreshEntryInfoResp: { msg = new RefreshEntryInfoRespMsg(); } break; case NETMSGTYPE_ResyncRawInodes: { msg = new ResyncRawInodesMsgEx(); } break; case NETMSGTYPE_ResyncRawInodesResp: { msg = new ResyncRawInodesRespMsg(); } break; case NETMSGTYPE_ResyncSessionStore: { msg = new ResyncSessionStoreMsgEx(); } break; case NETMSGTYPE_ResyncSessionStoreResp: { msg = new ResyncSessionStoreRespMsg(); } break; case NETMSGTYPE_RemoveXAttr: { msg = new RemoveXAttrMsgEx(); } break; case NETMSGTYPE_RemoveXAttrResp: { msg = new RemoveXAttrRespMsg(); } break; case NETMSGTYPE_Rename: { msg = new RenameV2MsgEx(); } break; case NETMSGTYPE_RenameResp: { msg = new RenameRespMsg(); } break; case NETMSGTYPE_RmChunkPathsResp: { msg = new RmChunkPathsRespMsg(); } break; case NETMSGTYPE_RmDirEntry: { msg = new RmDirEntryMsgEx(); } break; case NETMSGTYPE_RmDir: { msg = new RmDirMsgEx(); } break; case NETMSGTYPE_RmDirResp: { msg = new RmDirRespMsg(); } break; case NETMSGTYPE_RmLocalDir: { msg = new RmLocalDirMsgEx(); } break; case NETMSGTYPE_RmLocalDirResp: { msg = new RmLocalDirRespMsg(); } break; case NETMSGTYPE_SetAttr: { msg = new SetAttrMsgEx(); } break; case NETMSGTYPE_SetAttrResp: { msg = new SetAttrRespMsg(); } break; case NETMSGTYPE_SetDirPattern: { msg = new SetDirPatternMsgEx(); } break; case NETMSGTYPE_SetDirPatternResp: { msg = new SetDirPatternRespMsg(); } break; case NETMSGTYPE_SetLocalAttrResp: { msg = new SetLocalAttrRespMsg(); } break; case NETMSGTYPE_SetMetadataMirroring: { msg = new SetMetadataMirroringMsgEx(); } break; case NETMSGTYPE_SetStorageTargetInfoResp: { msg = new SetStorageTargetInfoRespMsg(); } break; case NETMSGTYPE_SetXAttr: { msg = new SetXAttrMsgEx(); } break; case NETMSGTYPE_SetXAttrResp: { msg = new SetXAttrRespMsg(); } break; case NETMSGTYPE_Stat: { msg = new StatMsgEx(); } break; case NETMSGTYPE_StatResp: { msg = new StatRespMsg(); } break; case NETMSGTYPE_StatStoragePath: { msg = new StatStoragePathMsgEx(); } break; case NETMSGTYPE_StatStoragePathResp: { msg = new StatStoragePathRespMsg(); } break; case NETMSGTYPE_TruncFile: { msg = new TruncFileMsgEx(); } break; case NETMSGTYPE_TruncFileResp: { msg = new TruncFileRespMsg(); } break; case NETMSGTYPE_TruncLocalFileResp: { msg = new TruncLocalFileRespMsg(); } break; case NETMSGTYPE_UnlinkFile: { msg = new UnlinkFileMsgEx(); } break; case NETMSGTYPE_UnlinkFileResp: { msg = new UnlinkFileRespMsg(); } break; case NETMSGTYPE_UnlinkLocalFileResp: { msg = new UnlinkLocalFileRespMsg(); } break; case NETMSGTYPE_UpdateBacklinkResp: { msg = new UpdateBacklinkRespMsg(); } break; case NETMSGTYPE_UpdateDirParent: { msg = new UpdateDirParentMsgEx(); } break; case NETMSGTYPE_UpdateDirParentResp: { msg = new UpdateDirParentRespMsg(); } break; // session messages case NETMSGTYPE_BumpFileVersion: { msg = new BumpFileVersionMsgEx(); } break; case NETMSGTYPE_BumpFileVersionResp: { msg = new BumpFileVersionRespMsg(); } break; case NETMSGTYPE_OpenFile: { msg = new OpenFileMsgEx(); } break; case NETMSGTYPE_OpenFileResp: { msg = new OpenFileRespMsg(); } break; case NETMSGTYPE_CloseFile: { msg = new CloseFileMsgEx(); } break; case NETMSGTYPE_CloseFileResp: { msg = new CloseFileRespMsg(); } break; case NETMSGTYPE_CloseChunkFileResp: { msg = new CloseChunkFileRespMsg(); } break; case NETMSGTYPE_WriteLocalFileResp: { msg = new WriteLocalFileRespMsg(); } break; case NETMSGTYPE_FSyncLocalFileResp: { msg = new FSyncLocalFileRespMsg(); } break; case NETMSGTYPE_FLockAppend: { msg = new FLockAppendMsgEx(); } break; case NETMSGTYPE_FLockEntry: { msg = new FLockEntryMsgEx(); } break; case NETMSGTYPE_FLockEntryResp: { msg = new FLockEntryRespMsg(); } break; case NETMSGTYPE_FLockRange: { msg = new FLockRangeMsgEx(); } break; case NETMSGTYPE_FLockRangeResp: { msg = new FLockRangeRespMsg(); } break; case NETMSGTYPE_GetFileVersion: { msg = new GetFileVersionMsgEx(); } break; case NETMSGTYPE_AckNotify: { msg = new AckNotifiyMsgEx(); } break; case NETMSGTYPE_AckNotifyResp: { msg = new AckNotifiyRespMsg(); } break; //admon messages case NETMSGTYPE_RequestMetaData: { msg = new RequestMetaDataMsgEx(); } break; case NETMSGTYPE_GetNodeInfo: { msg = new GetNodeInfoMsgEx(); } break; // fsck messages case NETMSGTYPE_RetrieveDirEntries: { msg = new RetrieveDirEntriesMsgEx(); } break; case NETMSGTYPE_RetrieveInodes: { msg = new RetrieveInodesMsgEx(); } break; case NETMSGTYPE_RetrieveFsIDs: { msg = new RetrieveFsIDsMsgEx(); } break; case NETMSGTYPE_DeleteDirEntries: { msg = new DeleteDirEntriesMsgEx(); } break; case NETMSGTYPE_CreateDefDirInodes: { msg = new CreateDefDirInodesMsgEx(); } break; case NETMSGTYPE_FixInodeOwners: { msg = new FixInodeOwnersMsgEx(); } break; case NETMSGTYPE_FixInodeOwnersInDentry: { msg = new FixInodeOwnersInDentryMsgEx(); } break; case NETMSGTYPE_LinkToLostAndFound: { msg = new LinkToLostAndFoundMsgEx(); } break; case NETMSGTYPE_CreateEmptyContDirs: { msg = new CreateEmptyContDirsMsgEx(); } break; case NETMSGTYPE_UpdateFileAttribs: { msg = new UpdateFileAttribsMsgEx(); } break; case NETMSGTYPE_UpdateDirAttribs: { msg = new UpdateDirAttribsMsgEx(); } break; case NETMSGTYPE_RemoveInodes: { msg = new RemoveInodesMsgEx(); } break; case NETMSGTYPE_RecreateFsIDs: { msg = new RecreateFsIDsMsgEx(); } break; case NETMSGTYPE_RecreateDentries: { msg = new RecreateDentriesMsgEx(); } break; case NETMSGTYPE_FsckSetEventLogging: { msg = new FsckSetEventLoggingMsgEx(); } break; case NETMSGTYPE_AdjustChunkPermissions: { msg = new AdjustChunkPermissionsMsgEx(); } break; default: { msg = new SimpleMsg(NETMSGTYPE_Invalid); } break; } return msg; }
云计算
2019-07-02 23:23:00
近日,Rancher Labs宣布在Rancher 2.3 Preview2版本上支持Istio,简化了Istio的安装和配置,让部署和管理Istio的旅程变得简单而快速。
近日,业界领先的容器管理软件提供商Rancher Labs(以下简称Rancher)宣布在Rancher 2.3 Preview 2版本上支持Istio,让部署和管理Istio的旅程变得简单而快速。
为什么选择Istio?
Istio,以及整个Service Mesh技术,是近一两年来Kubernetes生态系统中最亮眼的明星之一。Istio增加了容错、金丝雀部署、A/B测试、监控、跟踪和可观察性、身份认证和授权,开发人员无需再测试或编写特定代码,即可实现上述功能。如此一来,开发人员可以只专注于他们的业务逻辑,将剩下的工作交给Kubernetes和Istio。
上面这些说法其实并不新鲜。早在大约10年前,PaaS供应商们就提出了类似的说法,甚至在一定程度上兑现了这一要求。但问题在于,他们的产品需要特定的语言和框架,并且在大部分情况下只能用于非常简单的应用程序。用户的工作负载也会和供应商独特的方案关联在一起。这就意味着如果您希望应用程序使用PaaS服务,您可能会被锁定相当长的一段时间。
但如今,对于容器和Kubernetes而言,这些限制、这些被锁定的风险都不复存在。只要您将您的应用程序容器化,Kubernetes就可以为您运行它。
Istio在Rancher 2.3 Preview 2中如何工作
大量Rancher用户喜欢Rancher平台的原因,就是Rancher让管理和操作Kubernetes及相关的工具和技术变得极其简单,且用户们不必担心会被特定的云供应商锁定。而如今对于Istio,我们采取了同样的方法,致力于带给用户同样的体验。
在Rancher 2.3 Preview中,我们为用户提供了一个简单而友好的用户界面,在UI中使用工具菜单,即可启动Istio。系统提供了合理的默认配置,用户也可以根据需要进行修改:
为了监控流量,Istio需要注入Envoy sidecar。在Rancher 2.3 Preview当中,用户可以为每个空间名称注入自动sidecar。一旦您勾选了这个选项,Rancher会将sidecar容器注入到每个工作负载当中:
Rancher简化了Istio的安装和配置,内置了一个支持Kiali的仪表盘,用于流量和遥测的可视化,然后用Jaeger进行追踪,甚至还有自己的Prometheus和Grafana(与用于高级监控的实例不同)。
在启用自动sidecar注入的命名空间中部署工作负载后,您可以跳转到Istio菜单目录,观察微服务应用程序的流量:
点击Kiali、Jaeger、Prometheus或者Grafana,您将进入每个工具相应的用户界面,您可以在其中找到详细信息和选项:
正如前面所提到的,Istio的强大之处在于它能为您的服务带来诸如容错、断路、金丝雀部署等功能。要启用这些功能,您需要开发和应用适当的YAML文件。目前Windows工作负载还不支持Istio,因此不应在Windows集群中启用它。
结 语
Istio是当前Rancher及Kubernetes社区中最受关注的功能之一。但是,如何最达到Istio部署和管理的最佳实践,前路仍然漫长。在Rancher 2.3 Preview 2中,我们的目标是沿袭Rancher一如既往的理念,让部署和管理Istio的旅程变得简单而快速。
2019年6月20日,在Rancher于北京举办的千人容器技术盛典“2019企业容器创新大会”上,Rancher大中华区研发经理张浩在演讲中分享了Rancher 2.3 Preview的一系列新功能,包括正式支持Windows Kubernetes、镜像仓库、镜像扫描、服务网格、Google登陆、集群模版、集群安全扫描和集群自动扩缩容等等,并且demo了如何在Rancher中使用Istio进行金丝雀发布。您可在Rancher微信公众号(RancherLabs)后台回复“ECIC”获取大会完整PPT下载喔~
有关发行说明和安装步骤,请访问GitHub:
https://github.com/rancher/rancher/releases/tag/v2.3.0-alpha5
云计算
2019-07-02 10:01:00
Dev Ops源于Development和 Op eration s 的组合

常见的定义

DevOps是一种重视“软件开发人员(Dev)”和“IT运维技术人员(Ops)”之间沟通合作的文化、运动或惯例。透过自动化“软件交付”和“架构变更”的流程,来使得构建、测试、发布软件能够更加地快捷、频繁和可靠。

下面这个戴明环也是常见的表达形式:

点击此处添加图片说明文字




蓝鲸在深度实践DevOps后,结合对DevOps理解和经验总结,重新定义了DevOps。即下图这6个英文单词的首字母组成:
Do 、 Efficiency 、 Value 、 Open 、 Progress 、 Security 。

点击此处添加图片说明文字

结合这六个词、结合蓝鲸产品团队在今年6月蓝鲸DevOps活动上的分享以及个人理解,我们将从蓝鲸的视角展开来谈谈DevOps:

Do实践:以实践为基础推行DevOps

DevOps文化、理论体系的宣导者众多,各种大会也会去介绍各种“道、法、术”;大一些的企业基本都会有设立教练的角色,指导各个研发团队开展DevOps转型。但一些企业用户在听完各种“道、法、术”之后,要么是讲的听不懂,要么是懂也不会做、做也做不好。也有企业先找咨询公司做咨询,但咨询完后却不知道怎么落地。

蓝鲸DevOps认为DevOps的第一要素,就是实践,即所谓的“事上练”。没有实践过DevOps的经历就没有感悟,谈论再多的文化、理论,还不如贴近业务研发痛点,动手行动,用实践来验证想法和理论,点滴积累,绘成逐渐强大的DevOps体系。

Efficiency效能:效能是DevOps追求的目标

在我们开展实践之后,需要有目标。DevOps 根本的目标就是提升研发效能。

首先,效能体现在可以让大家可以“Focus On Your Job”。开发人员的职责是写代码和合并代码,合并代码完就去抽烟,其他的交给平台自动化执行;而不是去推动打包、申请资源、部署、测试、生产上线。

其次,效能体现在可以让大家在同一套平台中进行工作和协同,而不是在不同的工具中做不同的事情。一个企业IT部门有18套研发、测试、运维工具,这代表先进还是落后呢?很显然,这是一种落后的表现,因为这几乎将无法实现跨系统自动调度。蓝鲸DevOps平台可以将DevOps工具链进行整合,让不同的角色专注于其本职工作,达到提升效能的目标。

Value价值:DevOps必须输出价值

DevOps要为用户不断的输出价值,就要为DevOps体系中融入更多的提供价值的功能。例如: 在DevOps平台中加入质量红线,可以提供给用户来建立各种质量门禁,如:代码准入门禁、迭代验收门禁、发布控制门禁; 在DevOps平台中提供编译加速,帮助用户提升编译的性能; 在DevOps平台中提供构建资源池,在构建的时候可以自动调度构建资源,完成构建之后可以自动释放资源等等; 在DevOps平台中优化流水线的体验和原子,用户可以轻松组装出来各种复杂的业务场景……

价值也应该是可以复制的,企业通常有多个团队同时开展多个项目,我们对某个项目团队进行了大量DevOps方面的改进,并邀请工信部对项目进行了DevOps能力成熟度评级,我们团队达到了3级。但是,其他的项目或团队呢?他们能否达到3级标准?我们在DevOps方面做出的努力,是否可以平行复制到其他团队?

蓝鲸DevOps有一个理念是—— 价值应被平行复制到各个项目团队 。每一个价值点的输出,都可以让用户真正的感受到DevOps所能带来的改变,这样才能把用户凝聚在平台上,而不是总是考虑哪里用得不顺,自己建立一套平台。蓝鲸DevOps带来的体系完善、效能提升,不是针对某个团队,而是可以平行复制到所有的研发团队,这就是最大的价值。

Open开放:以开放的心态面对各种场景

不同的企业甚至同一家企业的不同团队,其DevOps落地的进程和对DevOps的要求都有差异的,我们必须用开放的心态接受这种差异。

例如:蓝鲸DevOps平台里面有敏捷协同模块,可以管理项目的需求、任务、缺陷、迭代计划等等,但是许多传统行业,基于企业的研发管控制度等原因,已经建立了适合自己的需求管理平台、研发任务管理平台等工具平台,我们的解决方案是不断给用户洗脑让用户放弃现有的协同和管理模式,还是以开放的心态来面对客户现有的管理体系呢?

蓝鲸的选择是以开放的体系面对不同团队的需求,提供尽可能灵活的架构和工具,通过工具开放的方式来兼容不同团队的模式。蓝鲸本身也是面向CI-CD-CO的研运一体化平台。

Progress演进:持续交付核心在于不断演进

DevOps的一个重要理念就在于持续改进。我们可以通过各个子系统的数据进行整体的度量,来发现哪个项目、哪些环节经常出现停滞、失败率比较高、耗时比较长,并且进行针对性的改进。

例如:如果研发效能瓶颈在测试环节,就需要深究导致测试耗时长的问题。如果是因为没有引入自动化的测试、手工测试耗时较长,就可以逐步补充自动化测试用例;如果研发效能瓶颈需要人工响应才能推进,就可以引入自动化的流水线和优化研发流程,减少人工参与和不必要的审核节点。

只有通过不断的改进,企业才能将原来的每月迭代和发布,缩短为每周迭代和发布,甚至逐步改进为每天迭代和发布,最终达到Google、FaceBook等企业达到的1天若干次发布的效果。

各个团队可以跟自己比,每一阶段都相比前一阶段有进步,就是团队的自我发展。而蓝鲸DevOps平台也是不断演进的成果。

Security安全:安全是基础

一个企业级的DevOps平台,安全是非常重要的。研发人员电脑、代码库、构建机、测试环境、制品库都可能导致代码及软件包的泄露,这也导致游戏行业大量私服的出现。而软件上线之后还要考虑漏洞被利用、跨站攻击、数据窃取等等问题。

不论DevOps平台本身,还是从平台流出的制品,一切要以安全为依归。DevOps平台本身应该提供监、管、控手段,可以进行细粒度的权限控制,避免非法访问和非法窃取数据、代码、软件包。DevOps平台也应该提供代码扫描、安全扫描、质量红线等安全工具,可以独立运行或者结合到流水线里面自动调用,保证交付的软件的可靠性,给平台使用者以及产出软件的用户一个安全保障。

作者:方勇
云计算
2019-07-23 18:15:00
本系列将利用阿里云容器服务,帮助您上手 Kubeflow Pipelines.
介绍
机器学习的工程复杂度,除了来自于常见的软件开发问题外,还和机器学习数据驱动的特点相关。而这就带来了其工作流程链路更长,数据版本失控,实验难以跟踪、结果难以重现,模型迭代成本巨大等一系列问题。为了解决这些机器学习固有的问题,很多企业构建了内部机器学习平台来管理机器学习生命周期,其中最有名的是 Google 的 Tensorflow Extended, Facebook 的 FBLearner Flow, Uber 的 Michelangelo,遗憾的是这些平台都需要绑定在公司内部的基础设施之上,无法彻底开源。而这些机器学习平台的骨架就是机器学习工作流系统,它可以让数据科学家灵活定义自己的机器学习流水线,重用已有的数据处理和模型训练能力,进而更好的管理机器学习生命周期。 谈到机器学习工作流平台,Google 的工程经验非常丰富,它的 TensorFlow Extended 机器学习平台支撑了 Google 的搜索,翻译,视频等核心业务;更重要的是其对机器学习领域工程效率问题的理解深刻,Google 的 Kubeflow 团队于 2018 年底开源了 Kubeflow Pipelines(KFP),  KFP 的设计与 Google 内部机器学习平台  TensorFlow Extended  一脉相承,唯一的区别是 KFP 运行在 Kubernetes 的平台上,TFX 是运行在 Borg 之上的。
什么是 Kubeflow Pipelines
Kubeflow Pipelines 平台包括: 能够运行和追踪实验的管理控制台 能够执行多个机器学习步骤的工作流引擎 (Argo) 用来自定义工作流的 SDK,目前只支持 Python
而 Kubeflow Pipelines 的目标在于: 端到端的任务编排 : 支持编排和组织复杂的机器学习工作流,该工作流可以被直接触发,定时触发,也可以由事件触发,甚至可以实现由数据的变化触发; 简单的实验管理 : 帮助数据科学家尝试众多的想法和框架,以及管理各种试验。并实现从实验到生产的轻松过渡; 通过组件化方便重用 : 通过重用 Pipelines 和组件快速创建端到端解决方案,无需每次从 0 开始的重新构建。
在阿里云上运行 Kubeflow Pipelines
看到 Kubeflow Piplines 的能力,大家是不是都摩拳擦掌,想一睹为快?但是目前国内想使用 Kubeflow Pipeline 有两个挑战: Pipelines 需要通过 Kubeflow 部署;而 Kubeflow 默认组件过多,同时通过 Ksonnet 部署 Kubeflow 也是很复杂的事情; Pipelines 本身和谷歌云平台有深度耦合,无法运行在其他云平台上或者裸金属服务器的环境。
为了方便国内的用户安装 Kubeflow Pipelines,阿里云容器服务团队提供了基于 Kustomize 的 Kubeflow Pipelines 部署方案。和普通的 Kubeflow 基础服务不同,Kubeflow Pipelines 需要依赖于 mysql 和 minio 这些有状态服务,也就需要考虑如何持久化和备份数据。在本例子中,我们借助阿里云 SSD 云盘作为数据持久化的方案,分别自动的为 mysql 和 minio 创建 SSD 云盘。
您可以在阿里云上尝试一下单独部署最新版本 Kubeflow Pipelines。
前提条件 您需要安装  kustomize
在 Linux 和 Mac OS 环境,可以执行 opsys=linux # or darwin, or windows curl -s https://api.github.com/repos/kubernetes-sigs/kustomize/releases/latest |\ grep browser_download |\ grep $opsys |\ cut -d '"' -f 4 |\ xargs curl -O -L mv kustomize_*_${opsys}_amd64 /usr/bin/kustomize chmod u+x /usr/bin/kustomize
在 Windows 环境,可以下载  kustomize_2.0.3_windows_amd64.exe 在阿里云容器服务创建 Kubernetes 集群, 可以参考  文档
部署过程 通过 ssh 访问 Kubernetes 集群,具体方式可以参考 文档 下载源代码 yum install -y git git clone --recursive https://github.com/aliyunContainerService/kubeflow-aliyun 安全配置
3.1 配置 TLS 证书。如果没有 TLS 证书,可以通过下列命令生成 yum install -y openssl domain="pipelines.kubeflow.org" openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout kubeflow-aliyun/overlays/ack-auto-clouddisk/tls.key -out kubeflow-aliyun/overlays/ack-auto-clouddisk/tls.crt -subj "/CN=$domain/O=$domain" 如果您有TLS证书,请分别将私钥和证书保存到 kubeflow-aliyun/overlays/ack-auto-clouddisk/tls.key 和 kubeflow-aliyun/overlays/ack-auto-clouddisk/tls.crt 下
3.2 配置 admin 的登录密码 yum install -y httpd-tools htpasswd -c kubeflow-aliyun/overlays/ack-auto-clouddisk/auth admin New password: Re-type new password: Adding password for user admin 首先利用 kustomize 生成部署 yaml cd kubeflow-aliyun/ kustomize build overlays/ack-auto-clouddisk > /tmp/ack-auto-clouddisk.yaml 查看所在的 Kubernetes 集群节点所在的地域和可用区,并且根据其所在节点替换可用区,假设您的集群所在可用区为  cn-hangzhou-g , 可以执行下列命令 sed -i.bak 's/regionid: cn-beijing/regionid: cn-hangzhou/g' \ /tmp/ack-auto-clouddisk.yaml sed -i.bak 's/zoneid: cn-beijing-e/zoneid: cn-hangzhou-g/g' \ /tmp/ack-auto-clouddisk.yaml 建议您检查一下 /tmp/ack-auto-clouddisk.yaml 修改是否已经设置 将容器镜像地址由  gcr.io  替换为  registry.aliyuncs.com sed -i.bak 's/gcr.io/registry.aliyuncs.com/g' \ /tmp/ack-auto-clouddisk.yaml 建议您检查一下 /tmp/ack-auto-clouddisk.yaml 修改是否已经设置 调整使用磁盘空间大小, 比如需要调整磁盘空间为 200G sed -i.bak 's/storage: 100Gi/storage: 200Gi/g' \ /tmp/ack-auto-clouddisk.yaml 验证 pipelines 的 yaml 文件 kubectl create --validate=true --dry-run=true -f /tmp/ack-auto-clouddisk.yaml 利用 kubectl 部署 pipelines kubectl create -f /tmp/ack-auto-clouddisk.yaml 查看访问 pipelines 的方式,我们通过 ingress 暴露 pipelines 服务,在本例子中,访问 IP 是 112.124.193.271。而 Pipelines 管理控制台的链接是:  https://112.124.193.271/pipeline/ kubectl get ing -n kubeflow NAME HOSTS ADDRESS PORTS AGE ml-pipeline-ui * 112.124.193.271 80, 443 11m 访问 pipelines 管理控制台
如果使用自签发证书,会提示此链接非私人链接,请点击显示详细信息, 并点击访问此网站。 请输入步骤 2.2 中的用户名 admin 和设定的密码。 这时就可以使用 pipelines 管理和运行训练任务了。
Q&A 为什么这里要使用阿里云的 SSD 云盘?
这是由于阿里云的 SSD 云盘可以设置定期的自动备份,保证 pipelines 中的元数据不会丢失。 如何进行云盘备份?
如果您想备份云盘的内容,可以为云盘  手动创建快照  或者  为硬盘设置自动快照策略  按时自动创建快照。 如何清理 Kubeflow Piplines 部署?
这里的清理工作分为两个部分: 删除 Kubeflow Pipelines 的组件 kubectl delete -f /tmp/ack-auto-clouddisk.yaml 通过 释放云盘 分别释放 mysql 和 minio 存储对应的两个云盘 如何使用现有云盘作为数据库存储,而避免自动创建云盘?
请参考 文档
总结
本文为您初步介绍了 Kubeflow Pipelines 的背景和其所要解决的问题,以及如何在阿里云上通过 Kustomize 快速构建一套服务于机器学习的 Kubeflow Pipelines, 后续我们会分享如何利用 Kubeflow Pipelines 开发一个完整的机器学习流程。
云计算
2019-07-23 17:53:00
本文作者:HelloDeveloper
在 7 月 2 号由百度开发者中心、百度开放云联合举办的第 64 期“百度开放云移动游戏和直播技术解读”沙龙上,来自百度的高级产品经理鲁玮,介绍了百度开放云在移动游戏方面的整体解决方案,并就相关实际案例给出具体讲解。

演讲者简介:

鲁玮,百度高级产品经理,2015 年加入百度云计算事业部,现作为百度开放云核心产品“计算与网络产品线”的产品负责人,领导、推动了云服务器、专属机、虚拟私有网络、VPN 服务、专线、弹性 IP 的产品化,实现了百度开放云相关产品从无到有,从有到优的明显提升。

一、移动游戏行业的发展现状

首先,鲁玮老师介绍了近年来中国移动游戏发展的现状,从 2008 年到 2015 年,大概 8 年的时间里,游戏收入从 185 亿增长到 1400 亿,从各个细分领域里的收入增速和发展趋势来看,排名前三的分别是手游、端游和页游。



近几年来,手游经过了爆发式的增长,2015 年的时候,手游的增长率达到 87.2%,手游已经变成了游戏行业里面最主要的而且是发展速度最快的方向。对于移动发行和移动应用来讲,游戏一直都是最主要的垂直模块,移动游戏也已变成了移动互联网里面变现最快的领域。

二、手游发展趋势-向中重度方向发展

手游发展到今天,从刚开始的休闲游戏到卡牌、MMO、MOBA 等,手游也在向中重度方向发展。归结原因,第一点是技术层面,移动处理器和 GPU 的快速发展会保证游戏跑得更加顺畅,重度游戏不会像原来那么卡顿;精细化的 3D 和情景式的游戏,对用户黏性很大,而且开发难度越来越低,这是手游往中重度发展的原因。另一个是运营层面,不能光靠游戏的长期下载量,要让用户沉浸在游戏里的时间更长,而最早出的游戏是偏休闲类的,比如斗地主、连连看,这种相对黏性较低,因为缺少互动模块,它会很容易流失掉用户,所以需要提高互动(帮会、聊天等模块)吸引用户,来产生更多的黏性。另外一个重要原因,这些玩家会付费购买道具来提升自己的级别,支付意愿较明显,所以中重度手游变现能力非常强。

三、移动游戏在部署和运行过程中遇到的痛点

游戏作为一个移动行业里面变现最快的行业,部署和运行过程中肯定会遇到很多问题。



首先手游生命周期短,购买物理资源浪费严重。手游对于其它 APP 来讲生命周期较短,很多游戏的厂商为了支撑游戏峰值业务,购买大量的硬件,而 90% 的情况下不能利用,导致成本和收益不成正比。

第二,流量峰值无法预测,已有 IT 资源无法支撑。很多时候要进行活动大推,或者由于社会热点(影视剧、网络小说)等因素导致游戏受到关注,从而引入大量玩家。这种情况下,原来的服务集群的计算性能无法支撑新涌入的玩家,所以搞活动、大推的时候,流量无法很好的预估。原来游戏部署在 IDC 时会选用物理机,但是物理机宕机恢复时间非常长,至少需要 30 分钟,这种游戏体验对玩家来讲很难接受,它会导致用户大量流失,而且这种传统的架构系统也是基于烟囱式的单点上面部署 OS、搭建应用服务,扩展性很差。

另外,中小游戏厂商使用 IDC,本身其防攻击能力很弱,所以会经常受到攻击,严重影响游戏收入。

四、百度开放云移动游戏解决方案介绍

下面我们从百度开放云游戏客户的实际案例中,分享不同游戏类型的架构解决方案。

卡牌类型手游



这个是卡牌类游戏的解决方案,通过百度开放云高性能的对象存储(BOS)和内容分发网络(CDN)把游戏安装包推送给玩家,玩家登录游戏时,经过云安全(BSS)的严格审查。另外游戏服运行在高性能云服务器(BCC)上,每个 BCC 配置一个单独的高性能数据库(RDS),这种方案大大提高了整个游戏系统的稳定性。通过支付服连接各个游戏渠道,保证了不同渠道引入的玩家购买道具等付费行为,支付数据库也记录了交易信息, 方便游戏 CP 和运营商对玩家的支付行为再进行二次分析。

社交类型手游



这个就是偏向于社交类游戏的解决方案,通过游戏加速服务系统将游戏安装包发送到手机端。玩家经过 BSS 的安全检测后,接入到登录服。因为游戏系统相对比较大,会有游戏服的资源管理、版本管理等模块。游戏大厅,类似于传统棋牌大厅的形式,每一个游戏服里有多个频道,每一个频道有多个房间。这类游戏的周边系统会把各个频道里边的聊天记录保存,同时因为大家在这里要排名,那排名也会有个专门的服务系统;通过跨区接入功能,也实现了玩家跨区的游戏 PK;另外为了增强游戏的流畅度,系统 DB 之前也会有缓存层。同时所有系统模块都会由智能云监控(BCM)来监测业务运行状况,包括通用运维指标、游戏程序等,游戏 CP 根据业务场景自定义设置报警规则,及时发现、处理宕机、业务性能压力过大的风险。

MOBA类型手游



这个是 MOBA 类型游戏的解决方案,MOBA 类型游戏对实时战斗的要求极强,但由于玩家位置不同、接入的运营商不同,导致南方和北方玩家访问质量不一致,游戏体验很差,所以百度开放云推荐此类游戏在南方和北方分别部署游戏集群。根据用户的不同位置,通过智能 DNS 接入最佳机房,实现用户更流畅的游戏体验;基于百度雄厚的基础网络资源,使用专线打通北京和广州区域机房,实现数据高速的同步和备份;另外游戏 CP 使用百度开放云业界领先的大数据服务,实现对玩家日志信息、玩家支付信息的精细分析,为游戏精细化运营提供宝贵数据。

五、移动游戏客户案例说明

沙巴克传奇,是今年盛大游戏重磅推出的 MMORPG 类型的手游,沙巴克传奇对服务器性能、网络安全的要求非常高。盛大游戏不仅需要高 PPS 转发的服务器、数据中心内网之间高速连通,还要求资源独享、灵活计费和完整的数据分析等能力。百度基于高性能的内核优化技术、自建的高质量 BGP 带宽、高性能的计算集群系统、超强的大数据服务,满足了盛大游戏对业务系统的严格要求。



在这个游戏里,不管前期测试、大推阶段还是后期运行管理,我们做了很多事情。沙巴克传奇封测阶段,我们给了很多支持与建议,包括定向内核优化、高可靠和弹性架构方案的推荐、结合上线节奏分配资源专区等。游戏大推阶段,我们提供超高性能的抗 D 服务、网络优化型云服务器、7*24 小时专人运维、游戏驻场支持、全国网络质量的实时监控和预测。后期运维阶段,我们也会定期的安全巡检,给出资源的生命周期管理的建议等。百度开放云提供了一整套完美的游戏解决方案,也帮助了沙巴克传奇实现了平稳的上线和火爆的大推,满足了沙巴克传奇游戏对性能、稳定性、安全等方面的高要求。
原文链接地址: https://developer.baidu.com/topic/show/290237
云计算
2019-07-23 17:24:00
本文作者:HelloDeveloper
在 1 月 16 日,由百度开发中心和 InfoQ 联合主办的“纵谈前端接入技术、SEO 和安全运维”主题沙龙活动中,来自百度开发者中心的资深运维工程师们热情洋溢的分享了百度在前端技术、搜索速度优化和全站使用 HTTPS 技术的进展及成果,以及百度在这些方面有哪些宝贵经验可供参考的。演讲嘉宾分别为百度 Golang 委员会成员陶春华、专注于网页搜索无线访问速度的工程师许霞,和处理网页搜索可达性、安全搜索等方向事务的主要技术负责人陈曦洋。
Go 语言在 Baidu Front-End 方面的应用实践
Go 语言的广泛流行取决于部署简单、并发性好、良好的语言设计,以及执行性能好。这也是在重写百度前端这一项目上为什么考虑选用 Go 语言的原因所在。陶春华老师介绍说,促使重写 Baidu Front-End 的诱因主要基于以下三点:一是修改成本高。事件驱动的编程模型本身的编码和调试难度都很大;C 语言本身的难度和开发效率有很多限制。二是配置管理方式落后。为单产品线设计,无法支持平台化要求;配置变更(修改、重载、验证)能力差。三是变更和稳定性的矛盾。例如程序出 core 也是比较头疼的事情。
在此前提之下,团队决定使用 Go 语言来重写前端,但是这里也遇到了一些问题,那就是 GC(Gabage Collection)本身难以避免的时间延迟。BFE 的需求是要在 1ms 以内,最大不超过 10ms,一旦超过这个平均值,那么用户体验将大打折扣。而 Go-BFE 实测 100 万连接,400ms GC延迟。这就需要不断的对 GC 进行优化。
在这里陶老师也介绍了两种优化思路,第一个常见的方法就是将扫描的小对象合并成大对象,利用 Array 来合并一组对象。第二种方法精算性更高一点,可以把消耗内存较多的内容放到 C 里面,因为 Go 语言有一个 CGO 接口,直接通过 Go 调到 C 可以解决这个问题,只不过代价比较大。但是,问题和方案永远是相生相伴的。用 Array 技术重写网络库,所有的 BFE 将永远用 Array 来写,理论上可行。这里的问题又来了,第一风险太大,第二如果 Go 语言升级了,还能不能继续使用下去。
陶老师在这里介绍的解决方法叫做车轮大战。即,在一组工作进程中,进程和服务是等价的,某一个进程跟服务运作到一定时间之后关闭GC,让它休息,第二个进程代替它服务,以此轮换,构成一个车轮大战的局面。如果在不能直接解决GC问题的时候直接关掉服务,然后绕过它。这基本的方案思路也就是关闭继承多进程的轮转战。(如上图)
搜索速度优化的前进之路
在整个百度接入服务里,百度搜索一直秉承提供最基础的三个保障,那就是安全、快速、可靠。许霞首先介绍说,在对速度进行度量之前,先要对数据检测、收集。对客户端数据监测的特点是:可以检测任何对象,成本高,并且监测的指标很固定。JS 埋点检测数据的特点是:可以检测任何指标,甚至可以检测每一条结果的速度。第三方数据检测的特点是:可以定制,并且有一定的海外监测能力,但成本高。
收集数据的意义在于可以很清晰的了解掌握用户的搜索习惯,这对 PV、UV 以及变现收入有很大影响。那么如何贴切搜索引擎的特点做搜索速度的优化?通过三个方面:接入质量提升、后端处理优化和前端渲染优化。接入质量提升主要有两个考察因素:延迟和带宽,对应的也就是优化 RTT 和传输效率。
后端优化其实就是整个搜索引擎的优化了,分为缓存优化和检索优化。缓存优化最基础的方式就是进入、淘汰机制等等,保证淘汰机制是最合理的。检索优化,则需要对硬件以及硬件方案的选择做一些深入考虑。在前端渲染优化方面,除了考虑节省时间之外还要考虑怎样让它定性化。
对优化做决定性决策只是其中的一种方法,还有更聪明的创新方法,那就是关于无线技术。这里面所涉及的内容包括手机终端、机站以及 IP 网络,传输速度当然是跟这三者有密不可分关系的。机站会根据自己能获得多少收益来处理用户的请求,尽量会缩小头部信息,进行一定程度的数据压缩。手机跟机站之间建立连接以维持这种连接关系。但电耗大是很关键的问题。百度搜索做了维持连接的一些机制,当用户页面空闲很长时间或者放在后台,就可以减少电量的消耗。(如上图)
全站 HTTPS 能否确保网站彻底安全?
2015 年 3 月,百度搜索成为国内首家完成全站 HTTPS 改造的大型站点;且目前来看,全站 HTTPS 已经成为百度产品的首要标准;同时,统一接入平台也大幅提升了 HTTPS 的接入效率和性能。陈曦洋老师在开讲前是这样介绍大背景的。全站 HTTPS 的原因是为了让用户保持良好的使用体验,解决反馈较多的劫持和隐私泄露等问题。这些问题的具体 case,包括页面被加上 URL 参数,不停刷新;页面被 DNS 劫持到其他网站;用户手机号码遭泄漏;白页,搜索功能异常等等。正是出于对用户数据的安全保密,维护网站正常运作的考量,百度专门成立了由百度搜索和运维部组成的 HTTPS-SUPPORT 团队,对 HTTPS 进行深入研究,提供完整的服务,保障用户正常访问百度原始产品。
陈曦洋老师在这里详细介绍了全站 HTTPS 改造的成本,这也是很多人都比较关心的焦点问题,这不仅涉及到证书的部署,还会涉及到激增的计算量,需要多次协商和握手,而用户端搜索的延迟将会给 HTTPS 改造需要解决的问题。除此以外,对于一个大型网站而言,架构如何解决多业务部署HTTPS的问题,巨大的页面和模板数量,以及如何解决实际部署中的各种问题,让用户无损 / 平滑的完成切换,其实是更具有挑战性的工作。
计算性能涉及到密钥(证书)的长度,1024 和 2048 位在性能有什么差别呢?原来使用 HTTP 协议的时候,假设 cps 可以达到 2w+,而转换成 HTTPS 之后,cps 只能达到 2-3 千;在访问速度方面,使用了 HTTPS 之后,不做任何优化,访问百度的速度可能会恶化 250-500ms, 一些设计比较差的页面可能会恶化 500-1200ms;在架构和产品成本方面,对于百度这样的综合性网站,牵一发而动全身,仅仅是在页面形式上就要改大量的模板,成本相当大。
那么有没有可选的优化方案呢?陈老师认为,性能优化上优先使用 ECC。这里使用 ECC 密钥长度大小要比 RSA 和 DH 密钥长度短。在硬件的优化上则可以使用硬件加速卡,可以做 TLS 的远程卸载 (小型站点在不面对大量的恶意请求时 完全可以通过纯软件卸载, 只需要保证连接复用率)。在访问速度上的优化上,通过复用连接和协议优化可以尽量减少握手次数,就可以让它接近于原始 HTTP 的性能。怎么去减少握手次数?比如 Session cache 和 Session ticket 可以极大的减少用户在一定时间内再次访问时的计算开销,而 HSTS 能在浏览器内部完成 HTTP 到 HTTPS 的跳转,不再经过一次网络传输和浏览器开销。另外还可以用 SPDY-HTTP2 方案,优点是基于单连接,能进一步提升连接复用比例,协议支持 header 压缩,在无线网络下有重要意义,这些都可以提高访问速度。
除了对协议层进行优化之外,也可以在应用层做些优化,预连接就是一个很好的优化方案。比如在网页端或者客户端,用户发起访问请求之前提前把这个握手过程完成,减少延迟,这一点也很重要。另外陈老师建议站点在发展到一定规模时一定要做整体的接入规划,控制域名数量,一些服务需要变成公共的,比如图片,静态资源的存储和访问。
在最后,陈老师也回答了大家普遍比较关心的问题,那就是使用 HTTPS 就代表着绝对安全吗?事实上并没有绝对地安全,代码是人写的,很多问题都是实际的实现上或者依赖的其他环境上出现了漏洞,OpenSSL HeartBlood 就是最典型的案例,甚至连随机数的生成和一些加密算法上也可能有人为埋下的漏洞,CDN 回源这样的路径很多情况下也是使用的 HTTP。百度使用 HTTPS 只能保护用户在浏览百度产品的时候的安全,但是很多手机号的泄露是第三方站点导致的 (它们会通过非法渠道购买识别用户手机号的服务),这个问题并不能通过百度的 HTTPS 解决。但是相对于 HTTP,HTTPS 的安全防范性能更高,增加了坏人的做恶难度。
原文链接地址: https://developer.baidu.com/topic/show/290236
云计算
2019-07-23 17:20:00
本文作者:y****n 自然语言处理(NLP)素有“人工智能皇冠上的明珠”盛誉,这也意味着语言与知识等认知层面的技术突破将进一步促进AI深入发展。 8月25日,以“掌握知识、理解语言、拥有智能” 为主题的百度大脑语言与知识技术峰会举行,百度CTO王海峰发表主旨演讲,解读百度语言与知识技术的发展历程与最新成果,与产学研各界分享技术及产业发展趋势和展望,百度集团副总裁吴甜和百度技术委员会主席吴华分别发布百度语言与知识技术系列产品和数据集共建计划,重磅推出5款产品 的新发布,全面加速AI技术大规模应用。这是一场凝聚了百度在语言与知识领域十年技术积累和产业实践的盛会,必将带来深远影响。
十年:
开拓者、深耕者、引领者 语言与知识技术是人工智能认知能力的核心。2010年,百度成立自然语言处理部,在前瞻技术与产业格局上不断引领、创新,十年间已成为中国NLP发展的一面旗帜。 峰会上,王海峰回顾,“在百度语言与知识技术的布局和发展中,我们始终在注意把握两个趋势,即技术发展趋势和产业发展趋势 ,并力争引领趋势。”纵览百度语言与知识技术发展历程, 从研究方法、研究对象、研究方向、产业应用 等各个层面,布局完整,不断打磨成熟,始终与应用的发展趋势、需求一脉相承,与产业接轨。 十年来,百度大脑语言与知识技术成果丰硕,获得包括国家科技进步奖在内的20多个奖项,30多项国际竞赛冠军,发表学术论文超过300篇,申请专利2000多项 。技术不断突破创新的同时,也在产品上创新探索,同时将领先的技术输出给开发者与合作伙伴,提升各行业智能化水平。
全面分享语言与知识技术成果 王海峰全面分享了百度语言与知识技术完整布局和最新成果。首先,知识图谱是机器认知世界的重要基础,百度打造了世界上最大规模知识图谱, 拥有超过50亿实体和5500亿事实 ,并在不断演进和更新。百度知识图谱应用于各行各业,每天的调用次数超过400亿次 。 其次,在融入知识的基础上,语言理解能力不断增强。2019年3月,百度提出知识增强的语义理解框架ERNIE,在深度学习的基础上融入知识,同时具备持续学习能力,曾一举登顶全球权威数据集GLUE榜单,首次突破90分大关,刷新榜单历史 。基于知识图谱和语义表示,突破了阅读理解、对话理解以及跨模态深度语义理解等技术。第三,语言生成是语言与知识技术中的重要组成部分。基于预训练技术的成功经验,百度提出基于多流机制的语言生成预训练技术,兼顾词、短语等不同粒度的语义信息,显著提升生成效果。百度也探索了多文档摘要生成,通过图结构语义表示引入篇章知识,在单文档和多文档摘要生成效果都有提升。 应用系统层面,对话系统和机器翻译等成绩卓著。 百度提出了知识图谱驱动的对话控制技术,以及首个基于隐空间的大规模开放域对话模型PLATO等 ,并推出智能对话定制和服务平台UNIT,帮助开发者高效构建智能对话系统,实现规模化应用。百度翻译支持200多种语言,每天响应超过千亿字符的翻译请求,支持超过40多万家第三方应用 ,技术上,提出了多智能体联合学习、基于语义单元的同传模型、稀缺语种分组混合训练算法等。 百度大脑语言与知识技术的持续探索和创新取得了令业界瞩目的成绩,同时这些技术以平台化的方式输出,赋能千行万业,持续提升产业智能化水平。
重磅推出5款产品的
新发布、2大计划 王海峰首次发布了百度大脑语言与知识产品全景图。百度集团副总裁吴甜接续发布语义理解技术与平台文心、智能文档分析平台TextMind和AI同传会议解决方案 3大新产品,同时发布了6项升级,包括智能创作平台的3个场景方案、以及智能对话定制与服务平台UNIT的3项全新升级。吴甜表示,“我们一直致力于将语言与知识技术凝聚成一系列技术平台和产品,在应用中产生大量价值,为广大开发者和产业实践者提供以语言与知识技术为核心驱动的系列产品。” 百度推出的 语义理解技术与平台文心 ,基于深度学习平台飞桨打造,依托领先的语义理解核心技术,集成优秀的预训练模型、全面的NLP算法集、端到端开发套件和平台,提供一站式NLP开发与服务,让开发者更简单、高效地定制企业级NLP模型。文心经过了大量真实应用场景的淬炼,具备优秀的工业级落地实力。 全新发布的智能文档分析平台TextMind ,基于OCR、NLP技术,以文档解析为核心能力,支持文档对比与文档审核,具备“多快好省”的核心优势,促进企业办公智能升级。 百度大脑智能创作平台针对媒体应用场景再升级,全新推出智能策划、智能采编、智能审校三大媒体场景方案,进一步助力媒体人更快、更好地创作,可谓切中媒体人的“痛点”。 智能对话定制与服务平台UNIT 升级3大特性:更智能的任务式对话理解、极致便捷的表格问答和融合通用的新对话引擎。此次UNIT全新升级的三大能力,将进一步降低任务式对话、智能问答的定制成本,并融合通用对话能力,提升交互体验。 全新发布的AI同传会议解决方案 ,覆盖会议全场景、全流程,旨在打造用户随身的“会议同传专家”。吴甜现场展示了如何只用一台电脑和一部手机快速搭建一套同传服务,只需点点鼠标、打几个字,就能快速获得专业的同传服务。 据匮乏、算力不足历来是语言与知识技术研发中面临的瓶颈。为突破瓶颈,百度联合中国计算机学会、中国中文信息学会发起中文自然语言处理数据共建计划——千言 ,解决数据稀缺问题。千言一期由来自国内11家高校和企业的数据资源研发者共同建设,已涵盖开放域对话、阅读理解等7大任务,20余个中文开源数据集。百度技术委员会主席吴华表示,“未来,我们希望有更多的数据集作者能够参与共建千言,共同推动中文信息处理技术的进步,建设世界范围的中文信息处理影响力。 我们计划在未来3年,面向20多个任务,收集和建设不少于100个中文自然语言处理数据集,覆盖语言与知识技术全部领域。” 吴华还发布了百度语言与知识技术算力共享计划,通过百度AI Studio平台提供算力支持,让广大开发者破除算力桎梏,专注于技术创新。 十年征程,百度语言与知识技术发展历程中培养、吸引了大量全球顶尖人才。会上,百度推出以王海峰为代表的百度NLP“十年十人”,十年坚守,不忘初心,秉持“技术信仰”,勇攀技术高峰,矢志不渝致力于让机器更好地理解世界、更好地服务于人。 正如王海峰所言,“我们致力于更好地与学术界、产业界携手,推动语言与知识技术发展,进而推动人工智能技术持续进步,为产业智能升级、社会经济高质量发展贡献力量。我们对未来充满信心,坚持研究和发展让机器掌握知识、理解语言、拥有智能,继续突破和创新,为技术和社会进步做出更大贡献。”
原文链接地址: https://developer.baidu.com/topic/show/291190
云计算
2020-08-26 10:22:00
本文作者:y****n
要说生活里最常见、最便民的AI应用技术,OCR(Optical Character Recognition,光学字符识别)当属其中之一。寻常到日常办理各种业务时的身份证识别,前沿到自动驾驶车辆的路牌识别,都少不了它的加持。作为一名开发者,各种OCR相关的需求自然也少不了:卡证识别、票据识别、汽车场景、教育场景文字识别……
OCR领域向来开源repo比较少,大部分核心算法用在了商业化产品。今年算是OCR开源领域的丰收年,chineseocr_lite,easyocr,以及百度飞桨推出的PaddleOCR先后横空出世。 确实喜大普奔 对于OCR方向开发者而言,开源repo最吸引人的莫过于: ① 高质量的预训练模型 ② 简单易上手的训练代码 ③ 好用无坑的部署能力 简单对比一下目前主流OCR方向开源repo的核心能力对于 语种方面 ,easyOCR的优势在于多语言支持,非常适合有小语种需求的开发者; 从预训练模型 来看,easyOCR目前暂无超轻量模型,chineseocr_lite最新的模型是10M左右,而PaddleOCR提供的8.6M是目前业界已知最轻量的 ; 对于部署方面 ,easyOCR模型较大不适合端侧部署,Chineseocr_lite和PaddleOCR都具备端侧部署能力; 对于自定义训练 ,实际业务场景中,预训练模型往往不能满足需求,对于自定义训练和模型Finetuning,目前只有PaddleOCR支持 ; PaddleOCR项目地址: https://github.com/PaddlePaddle/PaddleOCR PaddleOCR 8.6M超轻量模型,支持自定义训练、丰富的部署方式(覆盖服务器端、移动端/嵌入式端(apk/sdk)多场景需求)。提供的超级开源开发者大礼包,无疑让开发者大呼过瘾 ,看一下repo中提供的教程文档,真心全覆盖。高质量的内容也换来了开发者的广泛认可,GitHub Trending 第一,Star数量已经超过2.5k。 这仅仅是开始。。。 随着大量用户涌入,也实实在在提出了很多业务场景常见的问题,比如: 能否解决自然场景任意形状文本检测问题? 文字识别结果能否通过语义信息自动纠正? 既然开发者有需求,百度飞桨也是诚意满满!
百度自研SAST、SRN
两大SOTA算法开源啦!
核心信息先睹为快:

面向自然场景任意形状文字检测问题,开源ACM Multimedia 2019上发表的SAST(A Single-Shot Arbitrarily-Shaped Text Detector based on,Context Attended Multi-Task Learning)算法,在多个公开数据集(包括SCUT-CTW1500,Total-Text,ICDAR15 和 MLT),准确度取得了SOTA或可比的结果,速度上位列领先行列。

面向场景文本图像中兼顾视觉信息和语义信息的需求,开源CVPR2020中发表的SRN(Towards Accurate Scene Text Recognition with Semantic Reasoning Networks )算法,在包括ICDAR13、ICDAR15,IIIT5K,SVT,SVTP,CUTE80数据集,准确度取得了SOTA或可比的结果。
开源算法详细解读
01
单阶段任意形态文字检测器-SAST(ACM MM2019) 论文地址:https://arxiv.org/abs/1908.05498第一列为语义分割图,黄色框标记的为较长文字分割响应断裂的情况;第二列为SAST利用Pixel-to-Quad思想对实例分割的处理结果,相同颜色为同一个文字实例;第三列红色框为最终检测结果,蓝色为真值,青色为EAST算法检测结果。 目前业界解决任意形态文字检测问题的主流思路有两种: 一种基于Mask-RCNN思想的自顶向下的检测方法,例如LOMO、PMTD等; 另外一种是基于语义分割的自底向上的检测方法,例如TextField、TextMontain 等。 自顶而下的方法往往由于算法级联的模块比较多、特征抽取比较复杂导致实际使用效率没法得到很好保证;语义分割的方法由于缺乏实例(instance)的先验,在面临距离较近的文字条难以分割开、过长的文本条则容易出现响应不连续等问题。 SAST (“A Single-Shot Arbitrarily-Shaped Text Detector based on Context Attended Multi-Task Learning”) 收录于ACM Multimedia 2019,是百度研发的面向自然场景任意形状文字检测问题,兼顾效率和准确率的解决方案。 SAST使用多任务学习对文字中心线区域进行语分割的同时学习了文字实例的多种几何信息,进而实现文字的实例分割和多边形表达的重建。该方法的整体算法流程,如图1所示:



首先,通过多任务学习方法学习文字实例的多种几何信息,包括文字条中心线响应图 (Text Center Line, TCL),中心线像素与四角点偏移量 (Text Vertex Offset, TVO),中心线像素与文字中心点偏移量 (Text Center Offset, TCO) 和中心线到文字上下边界偏移量 (Text Border Offset, TBO);


其次,使用Pixel-to-Quad方法对TCL进行实例分割,该方法结合了高层检测信息和底层分割信息,具体过程如图2虚线框中所示。


最后,在实例分割的基础上,针对每个文字实例结合TBO信息,即可恢复出任意形状文字的几何表达。 论文中对SAST在多个公开数据集上进行了效果验证,包括SCUT-CTW1500,Total-Text,ICDAR15 和 MLT数据集,准确度上取得了SOTA或可比的结果,速度上位列领先行列。此次SAST开源工作中,通过对模型的Backbone和训练数据做了适当的升级和调整, 在icdar2015数据集上hmean达到87.33%,在弯曲文本数据集total-text上hmean达到84.03%。
02
利用语义推理网络强化的场景文字识别器-SRN(CVPR2020) 论文地址:https://arxiv.org/abs/2003.12294(a)是较难识别的场景文本图像,(b)是从(a)中图像里分离抽取出的字符图像,(c)是(a)中图像对应的语义内容。 场景文本图像包含两种层次的内容:视觉信息和语义信息。近年来致力于提高识别性能的工作,大多从提取鲁棒且有效的视觉特征的视角出发,例如升级模型Backbone,增加矫正模块,校准Attention机制等,往往忽视了改进语义特征。场景文字识别不单依赖视觉感知信息,也依赖高层次的语义信息的认知理解,例如图3所示 ,仅依靠视觉信息是很难准确识别分离抽取出的字符图像,尤其是(b)中红框标出的字符;相反地,结合整个单词完整语义信息进行推理的时候,我们是可以很容易识别出完整单词内容的。 为了解决如下主流Attention-based隐含式语义信息建模的方法缺陷: 1)仅仅感知了历史时刻的语义信息,而无法获取其他时刻的语义信息; 2)如果较早时刻解码出的错误字符,会为余下时刻的解码传递错误的语义信息,导致误差积累效应; 3)串行的解码模式是相对低效的(特别是在模型预测的环节) 百度在CVPR 2020录用工作SRN(Towards Accurate Scene Text Recognition with Semantic Reasoning Networks )中借鉴Transformer和NLP预训练模型思想提出了一种高效的全局并行语义推理模块GSRM,其信息传递方式采用如图 4(b)所示方式。 SRN是端到端可训练的场景文字识别网络,由四部分组成:基础网络Backbone、并行的视觉特诊提取模块(PVAM)、全局语义推理模块(GSRM) 和视觉语义融合的解码器(VSFD)。给定一张输入的文本图像,基于ResNet50 + Transformer unit的Backbone从中提取出视觉2D feature map V ;之后PVAM会针对每个目标字符获取其相应的视觉特征G ;GSRM会基于视觉特征G 获取全局语义信息,并转化为每个目标字符的语义特征S ;最后VSFD融合对齐的视觉特征和语义特征,预测出相应字符。在训练阶段和推断阶段,每个序列中各个字符之间是并行。 SRN在多个公开数据集上进行了效果验证,包括ICDAR13、ICDAR15,IIIT5K,SVT,SVTP,CUTE80数据集,在准确度上取得了SOTA或者可比的结果 。同时,也在中文长词数据集合TRW上与主流方法做了精度对比,证明了该方法对于中文的适用性。图 6中展示了语义推理模块的使用与否在中英文上的可视化对比效果。加了GSRM模块后,能将一些不符合语义逻辑的单字识别结果进行纠错。 参考DTRB文字识别训练和评估流程,使用MJSynth和SynthText两个文字识别数据集训练,在IIIT, SVT, IC03, IC13, IC15, SVTP, CUTE数据集上进行评估,算法效果如下:可以看到SRN检测算法指标明显优于其它算法,效果提升明显。而且值得一提的是,此次PaddleOCR开源SRN工作中,对训练方法做了适当的优化,采用一步到位端到端的训练方式,原始论文使用两阶段训练平均精度为89.74%,PaddleOCR中使用one-stage训练,平均精度为88.33%。精度虽然略有下降,但是训练效率和实用性明显增加。
开源数据集建设

除了开源自研算法,百度也一直致力于推动开源数据集的建设。ICDAR“Robust Reading Competitions”竞赛是评估自然场景/网络图片/复杂视频文本提取与智能识别新技术进展的权威国际赛事及评测标准,竞赛中涌现出诸多方法持续推动业界新技术的创新与应用。

作为ICDAR 2019 Robust Reading Competition竞赛主要组织者之一,百度联合学术界共同发布了两项极具挑战的竞赛任务, ICDAR 2019-LSVT ( L arge-scale S treet V iew T ext with Partial Labeling, 弱标注大规模街景文字识别竞赛)、 ICDAR 2019-ArT ( Ar bitrary-Shaped T ext, 任意形状场景文字识别竞赛)。 ICDAR 2019-LSVT竞赛数据聚焦探索大规模数据场景下深度学习文字识别能力极限,是业界最大的中文场景OCR集合。ICDAR2019-LSVT数据集源于百度真实应用场景,作为首个提出弱标注数据的场景文字数据集,包括精标注5万张街景图像,40万张弱标注图像,总计45万,数据量是现有公开数据集(ICDAR 2017、ICPR 2018等)的14倍以上。场景文字识别具有广泛应用场景,例如:拍照翻译、图像检索、街景地标识别、室外场景理解等。
ICDAR2019-ArT竞赛数据总计10176张,是业界最大的任意形状场景文字集合,聚焦推动自然场景下任意形状文字检测识别能力新突破。 PaddleOCR开源的超轻量和通用版中英文模型,训练数据组成中的中文真实数据集,主要就是上述开源的LSVT数据集,此外,本次SAST算法开源模型total-text指标超过论文指标约4%,主要原因也是由于加入了ArT数据集进行了优化。以上数据集也已经在PaddleOCR中开源了,欢迎使用: https://github.com/PaddlePaddle/PaddleOCR/blob/develop/doc/doc_ch/datasets.md
原文链接地址: https://developer.baidu.com/topic/show/291177
云计算
2020-08-25 09:20:00
本文作者:y****n
8月21日,百度在沧州开放Apollo Go自动驾驶出租车服务,沧州市民通过百度地图,即可一键呼叫免费搭乘体验,沧州由此成为中国第一个可以在主城区打到Robotaxi的城市。这也是继今年4月在长沙全面开放之后, Apollo在第二个城市上线常态化的打车服务,这意味着Apollo正在加速规模化部署,百度无人车服务Apollo Go迈入多地运营的全新阶段。
百度此次在沧州开启的Apollo Go Robotaxi服务,由Apollo和生态伙伴云图科技联合运营。 行车路线将覆盖高铁站、学校、星级酒店、博物馆、产业园等沧州核心区域。值得一提的是,Apollo 首次尝试将Robotaxi服务深入到高铁站、星级酒店等主城公共区域之间的网约车通行,“驶进”更多普通用户的主流生活场景。
沧州是京津冀城市群和京沪大通道上的重要节点城市,近几年,沧州大力发展智能网联技术,在自动驾驶落地应用方面,已经走在了国内城市的前列。沧州是中国北方第一个开展自动驾驶载人测试的城市,拥有全国第二大智能网联测试路网。 2019年9月,沧州与百度达成自动驾驶、智能交通战略合作。2019年11月,中国首个区级全域自动驾驶可载人测试路网在沧州开放,百度Apollo自动驾驶车队在当地的载人测试也随之开启,而此次Apollo Go Robotaxi在沧州主城区开放,更将加速沧州成为北方的智能网联创新高地。
百度Apollo是全球最大的自动驾驶开放平台,截止目前, 百度Apollo拥有自动驾驶路测牌照数总计超过150张、测试车队规模达到500辆级别、获得全球智能驾驶专利1800件、测试里程总计超过600万公里、实现安全载客超过10万人次。 2019年,百度Apollo与一汽红旗合作的前装量产的Robotaxi亮相长沙开启试运营,今年4月,百度Robotaxi向长沙市民全面开放试乘服务。目前,除了在长沙、沧州外,Apollo也已经在北京、重庆、阳泉等地开展自动驾驶载人测试。
Apollo Go Robotaxi在长沙、沧州多地开启载客试运营,是百度落地自动驾驶技术又一新的里程碑。 基于真实场景的载客运营,将加快自动驾驶的技术迭代和商业探索,加速Apollo实现惠及人人的简单、安全、美好的出行体验。
原文链接地址: https://developer.baidu.com/topic/show/291172
云计算
2020-08-24 16:00:00
作者 | 易立  阿里巴巴资深技术专家
导读 :WebAssembly 技术已经走出浏览器,让计算无处不在。本文利用 containerd 的扩展机制,可以为 WebAssembly 应用提供与其他容器应用一致的、抽象的、应用分发、交付和运维模型,可以在 Kubernetes 集群中进行统一调度和管理。
无处不在的 WebAssembly
如果评选 2019 年编程技术的“网红”,无论是前端圈还是后端圈,WebAssembly (WASM) 都绝对能够高票入选。然而,如果评选最被“低估”的技术,我觉得 WebAssembly 也可以轻松入围。
借用伏尔泰曾评价神圣罗马帝国的句式 “既不神圣,也不罗马,更非帝国”,我们也可以说WebAssembly “既不限于 Web,更不是 Assembly(汇编语言)”。
在 2019 年 12 月,万维网联盟 (World Wide Web Consortium  - W3C) 宣布  WebAssembly 核心规范正式成为 Web 标准 ,  这使得 WebAssembly 成为互联网上与 HTML, CSS, and JavaScript 并列的第四种官方语言,可以原生的运行在浏览器上。而更加重要的是,WebAssembly 作为一个安全的、可移植、高效率的虚拟机沙箱,可以在 Internet 的任何地方、任何平台(不同操作系统,不同 CPU 体系架构下)安全运行应用。WebAssembly 已得到了所有主流浏览器厂商的广泛支持(Google Chrome, Microsoft Edge, Apple Safari, Mozilla Firefox 等),然而它的影响已经远超 Web。
WebAssembly 的设计初衷之一是为了解决 JavaScript 的性能问题,使得 Web 网页应用有接近本机原生应用的性能。作为一个通用、开放、高效的底层虚拟机抽象,众多编程语言(如 C/C++, Rust 等)可以将现有应用编译成为 WASM 的目标代码,运行在浏览器中 。这让应用开发技术与运行时技术解耦,极大促进了代码复用。
Mozilla 在 2019 年 3 月推出了 WebAssembly System Interface(WASI),来标准化 WebAssembly 应用与系统资源的交互抽象,比如文件系统访问,内存管理,网络连接等,类似 POSIX 这样的标准 API。WASI 规范大大拓展了 WASM 应用的场景,可以让其可以超越浏览器环境,作为一个独立的虚拟机运行各种类型的应用。同时,平台开发商可以针对具体的操作系统和运行环境提供 WASI 接口不同的实现,可以在不同设备和操作系统上运行跨平台的 WebAssembly 应用。这可以让应用执行与具体平台环境实现解耦。这一切使得“Build Once, Run Anywhere”的理想逐渐形成现实。WASI 的示意图如下所示。2019 年 11 月,为了进一步推动模块化 WebAssembly 生态系统,Mozilla、Fastly、英特尔和红帽公司携手成立了字节码联盟( Bytecode Alliance ),共同领导 WASI 标准、 WebAssembly 运行时、语言工具等工作。
图片来源: https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/
WASM 与容器相爱相杀
WebAssembly 是否会取代容器?
正因为 WebAssembly 所具备的的安全、可移植、高效率,轻量化的特点,非常适于应用安全沙箱场景。WASM 得到了容器、函数计算、IoT / 边缘计算等社区的广泛关注。Docker 创始人 Solomon Hykes 在 WASI 发布之际的一句 Twitter,更是成为了去年容器和 WebAssembly 社区引用频率最高的一句话之一。
Fastly, Cloudflare 等 CDN 厂商基于 WebAssembly 技术实现了更加轻量化的应用安全沙箱,可以在一个进程内部运行多个独立的用户应用。阿里云 CDN 团队 EdgeRoutine 也实现了类似技术。与容器技术相比,WASM 可以实现毫秒级冷启动时间和极低的资源消耗。
原图: https://blog.cloudflare.com/cloud-computing-without-containers/
当然,世界上没有完美的技术。任何沙箱技术不可能同时满足执行效率、安全隔离性和通用性这三个维度的要求。WASM 在安全隔离和通用性等方面与 Docker Container 等存在差距。虽然如此,我们还是看到了 WebAssembly 技术巨大的潜力。
WebAssembly 容器
我的理解是 WebAssmebly 可以成为一种容器类型,类似 Linux Container 或者 Windows Container 一样。成为一个跨平台的标准应用分发方式和运行时环境。
应用分发
Docker 容器的一个重要贡献是其标准化了容器化应用打包规范 Docker Image,而且它已经成为开放容器计划 (Open Container Initiative - OCI) 的镜像格式标准。Docker 镜像提供了自包含、自描述的镜像格式。它可以将应用以及其依赖的环境信息打包在一起,从而实现应用与运行环境解耦,让容器应用可以轻松运行在从本地开发环境到云端生产环境的不同场景中。并且社区围绕 Docker 镜像构建了繁荣的工具链生态,如 Docker Hub 可以进行应用分发和 CI / CD 协同,Nortary / TUF 项目可以保障应用可信地分发、交付。
对与 WebAssembly,目前社区提供了类似 NPM 的包管理实现 WAPM ,可以较好地支持应用的分发。 为 WebAssembly 应用构建 Docker 镜像,可以实现双赢的局面。 WebAssembly 开发者可以完全复用 Docker/OCI 镜像规范和工具链,进一步简化应用分发和交付。比如,我们可以将 Nginx 的 WASM 镜像作为基础镜像,基于这个镜像可以构建包含不同 Web 内容的应用镜像;我们可以利用 tag 对应用版本进行追踪;利用 Docker Registry 进行应用分发;在这个过程我们还可以进一步利用数字签名来保障安全的软件供应链; Docker 镜像规范支持  Multi-Arch  镜像,可以简化不同 CPU 体系架构(如 x86, ARM, RISC-V 等)的应用镜像的构建与分发。而 WebAssembly 天生具备可移植性,大大简化了跨平台 Docker 应用镜像的构建和分发。参考: 利用 Docker 加速 ARM 容器应用开发和测试流程 。
我提供了一个技术原型 示例项目 ,大家可以参考其中的例子来构建 WASM 容器镜像。由于 WebAssembly 应用采用紧凑的二进制格式,而且没有任何操作系统依赖,WASM 应用可以构建出非常小的容器镜像。大家可以自行感受一下: $ sudo ctr image ls REF TYPE DIGEST SIZE PLATFORMS LABELS docker.io/denverdino/c-http-server-wasm:latest application/vnd.docker.distribution.manifest.v2+json sha256:2efa759f46f901cda2e6a9b4228c423b17a960c06e957964e72c21dc5b42408f 29.2 KiB linux/amd64 - docker.io/denverdino/hellowasm:latest application/vnd.docker.distribution.manifest.v2+json sha256:cadcc8b07eb82b18db2c8f500fa2b11e5ebf2e9054cfa687e4ffe44861860132 8.2 KiB linux/amd64 - docker.io/denverdino/nginxwasm:latest application/vnd.docker.distribution.manifest.v2+json sha256:8735c82524a463b842b7c79f2c1be8094ee1c57cfd34154f68752fbe79c25998 582.7 KiB linux/amd64 -
安全隔离
WebAssembly 的最初设计目标是让应用可以安全运行在浏览器中。WASM 虚拟机提供的 沙箱和内存隔离机制 ,可以有效减少安全攻击面。而当 WebAssembly 走出浏览器,面向更加通用的场景。WASM 也面对更加复杂的安全挑战。
WASI 提供了 基于能力的安全模型 。WASI 应用遵循最小权限原则,应用只能访问其执行所需的确切资源。传统上,如果应用需要打开文件,它会带路径名字符串调用系统操作 open。然后系统调用会检查应用是否具有访问该文件的相关权限,比如 Linux 实现了基于用户/组的权限模型。这样隐式的安全模型,依赖于正确的安全管理配置,比如一旦特权用户执行了一个恶意应用,它就可以访问系统中任意的资源。而对于 WASI 应用而言,如果它需要需要访问指定文件等系统资源,需要从外部显式传入加有权限的文件描述符引用,而不能访问任何其他未授权资源。这中依赖注入的方式可以避免传统安全模型的潜在风险。
一个示意图如下:
原图: https://hacks.mozilla.org/2019/03/standardizing-wasi-a-webassembly-system-interface/
我们可以看到 WASI 的安全模型与传统操作系统安全模型非常不同,而且还在持续演进中。比如字节码联盟提出了 nanoprocess 来解决应用模块间的安全协同和信任传递。
WebAssembly/WASI 的安全模型依然存在不足,比如: 资源隔离
对于内存资源,WebAssembly 实现了线性内存模型。WebAssembly 应用只能利用索引访问传入的一段逻辑线性内存。而 WASM 虚拟机负责确定内存的实际物理地址,WASM 应用无法获知内存的真实地址,也无法通过越界访问等方式发动攻击。所以理论上,可以对 WASM 应用进行资源容量限制。但是目前部分 WASM 虚拟机还无法对内存进行精确的隔离限制。
对于 CPU 资源,部分的 WASM 虚拟机实现可以对应用使用的 CPU 资源进行计量,但是大多无法实现精确的配额限制、优先级和抢占式调度。
I/O 资源,比如 IOPS 等,WASM 目前完全没有相关的隔离能力。 网络安全
WASI 的 Capability 模型对于文件系统访问相对比较容易保护。但是这个静态的安全模型无法适用于动态的网络应用场景。在微服务架构中,应用经常通过 Service Registry 进行服务发现,为服务的调用者和提供者实现动态的调用绑定。这个语义是无法用静态的 capability 模型描述和注入的。这也导致了 WASI 的网络部分 API 还处于讨论之中。现有的  WASI 网络安全模型 ,以及相关 讨论 。
Linux 操作系统和容器技术已经提供了非常完备的资源隔离和安全隔离实现。与 WebAssembly 结合在一起可以应对不同场景对不同隔离级别的需求。 共享进程资源 - 多个 WASM 应用模块运行在一个 WASM 虚拟机进程内部,依赖 WASM 运行时进行隔离。隔离级别低,控制粒度比较粗,资源开销极小。可以以较小代价保障系统安全。适合受限问题域的应用安全隔离; 独立进程资源 - 不同 WASM 应用模块运行在不同的 WASM 虚拟机进程中,可以复用操作系统的进程级隔离能力,比如 CGroup。此外,还可以利用类似 Kubernetes 中的 Network Policy (网络策略),或者服务网格(如Istio)等技术,对进程的网络访问进行细粒度的控制,甚至实现零信任网络。隔离级别比较高,控制粒度比较细,资源开销适中。可以应用于更加通用的场景。
注:当然利用安全沙箱如虚拟化等技术,结合 WebAssembly,可以进一步最小化安全攻击面,但是 ROI 不高。
调度与编排
在云时代,Kubernetes 已经成为分布式环境下资源调度和应用编排的事实标准。Kubernetes 可以屏蔽底层设施的差异性。可以在同一个 K8s 集群中包含 x86、ARM 等不同体系架构的节点,可以支持 Linux,Windows 等不同的操作系统。Kubernetes 和 WebAssembly 相结合可以进一步提升应用的可移植性。
微软的 Deis Labs 年初发布了一个 实验项目 ,来利用 Virtual Kubelet 类似的架构调度 WebAssembly 应用。但是这个方式有很多局限,无法借助容器方式进行应用分发,也无法利用 K8s 的语义进行资源编排。 
难得有一个春节假期可以宅在家里,在此期间我基于 Derek McGowan 去年的一个 实验性项目 ,完善了 containerd 的 WASM shim 实现。可以让 containerd 支持 WASM container,并且可以利用 Kubernetes 集群管理和调度 WASM container。
项目的代码实现: https://github.com/denverdino/containerd-wasm
注:这个项目更多是概念验证,进程管理、资源限制,性能优化等的细节并没未完整实现。
整个系统的架构设计如下,“container-shim-wasm-v1”作为 Containerd 的扩展,利用 wasmer 作为 WASM 应用运行时环境,可以实现与 runc 容器一致的用户体验。
我们还会将其注册为 K8s 的一个  RuntimeClass ,允许用户利用 K8s 来交付和运维 WASM 应用。
注:RuntimeClass 是 Kubernetes v1.12 引入的新概念,可以让 Kubernetes 支持多种不同的容器运行时,比如 runc 容器、或者 Kata Containers,gVisor 等安全沙箱容器。更多细节可以参考: containerd 与安全沙箱的 Kubernetes 初体验 。
Talk is Cheap, 放码过来
首先,我们将利用 Minikube 创建一个 K8s 测试环境,并将 Containerd 作为 Kubernetes 集群的容器运行时。
创建虚拟机测试环境
创建 Minikube K8s 集群,并将 Containerd 作为 Kubernetes 集群容器运行时。 minikube start --image-mirror-country cn \ --iso-url=https://kubernetes.oss-cn-hangzhou.aliyuncs.com/minikube/iso/minikube-v1.6.0.iso \ --registry-mirror=https://tgtsuwdg.mirror.aliyuncs.com \ --container-runtime=containerd
进入 Minikube 虚拟机: $ minikube ssh _ _ _ _ ( ) ( ) ___ ___ (_) ___ (_)| |/') _ _ | |_ __ /' _ ` _ `\| |/' _ `\| || , < ( ) ( )| '_`\ /'__`\ | ( ) ( ) || || ( ) || || |\`\ | (_) || |_) )( ___/ (_) (_) (_)(_)(_) (_)(_)(_) (_)`\___/'(_,__/'`\____)
配置环境所需依赖: wasmer 0.13; minikube 缺省安装了 container 1.2.x,需要升级 containerd 1.3.x; 我提供了一个预编译的 containerd-wasm-shim-v1,也可自己编译一个版本。 cd ~ # Install Wasmer 0.13.1 curl -L -O https://github.com/wasmerio/wasmer/releases/download/0.13.1/wasmer-linux-amd64.tar.gz gunzip wasmer-linux-amd64.tar.gz tar xvf wasmer-linux-amd64.tar sudo cp bin/* /usr/bin/ # Upgrade containerd to v1.3.2 curl -L -O https://github.com/containerd/containerd/releases/download/v1.3.2/containerd-1.3.2.linux-amd64.tar.gz gunzip containerd-1.3.2.linux-amd64.tar.gz tar xvf containerd-1.3.2.linux-amd64.tar sudo systemctl stop containerd sudo cp bin/* /usr/bin/ sudo systemctl restart containerd # Install containerd-wasm-shim wget http://kubernetes.oss-cn-hangzhou.aliyuncs.com/containerd-wasm/containerd-shim-wasm-v1 chmod +x containerd-shim-wasm-v1 sudo mv containerd-shim-wasm-v1 /usr/bin/
配置 containerd 支持 WASM shim
在 containerd 配置文件中添加 wasm shim 相关配置,并重启 containerd。 $ cat <测试 Hello World WASM 容器应用: $ sudo ctr image pull docker.io/denverdino/hellowasm:latest docker.io/denverdino/hellowasm:latest: resolved |++++++++++++++++++++++++++++++++++++++| manifest-sha256:cadcc8b07eb82b18db2c8f500fa2b11e5ebf2e9054cfa687e4ffe44861860132: done |++++++++++++++++++++++++++++++++++++++| layer-sha256:ecda28441283ecf01d35bca0361f2c1ef26a203454a06789ee5ce71ba1e32ca3: done |++++++++++++++++++++++++++++++++++++++| config-sha256:57974480d640c8d60d254a8b0fa4606b2c7107fe169bc3ddd455091277c3a5e4: done |++++++++++++++++++++++++++++++++++++++| elapsed: 3.0 s total: 0.0 B (0.0 B/s) unpacking linux/amd64 sha256:cadcc8b07eb82b18db2c8f500fa2b11e5ebf2e9054cfa687e4ffe44861860132... done $ sudo ctr run --rm --runtime io.containerd.wasm.v1 docker.io/denverdino/hellowasm:latest test1 Hello world
测试 Nginx 的 WASM 容器应用: $ sudo ctr image pull docker.io/denverdino/nginxwasm:latest docker.io/denverdino/nginxwasm:latest: resolved |++++++++++++++++++++++++++++++++++++++| manifest-sha256:8735c82524a463b842b7c79f2c1be8094ee1c57cfd34154f68752fbe79c25998: exists |++++++++++++++++++++++++++++++++++++++| layer-sha256:27f4d8ad067fbb709d18ea5acd7a5ddfb85851e5d9f030636e9da3d16cc4bd07: done |++++++++++++++++++++++++++++++++++++++| config-sha256:a55bd3bdb9d00fdac5ee2f64bfc1856e58e8bb90587943969ad3d8115f4ced70: done |++++++++++++++++++++++++++++++++++++++| elapsed: 3.0 s total: 0.0 B (0.0 B/s) unpacking linux/amd64 sha256:8735c82524a463b842b7c79f2c1be8094ee1c57cfd34154f68752fbe79c25998... done $ sudo ctr run --rm --runtime io.containerd.wasm.v1 docker.io/denverdino/nginxwasm:latest test2 2020/02/01 07:01:21 [notice] 30672#0: using the "select" event method 2020/02/01 07:01:21 [notice] 30672#0: nginx/1.15.3 2020/02/01 07:01:21 [notice] 30672#0: built by clang 6.0.1 (emscripten 1.38.11 : 1.38.11) 2020/02/01 07:01:21 [notice] 30672#0: OS: Linux 4.19.81 2020/02/01 07:01:21 [notice] 30672#0: getrlimit(RLIMIT_NOFILE): 1024:1024
在 Minikube 外部,可以用如下方式获得 nginx 应用的访问地址: $ echo http://$(minikube ip):8080 http://192.168.64.13:8080
利用浏览器打开上述地址,显示如下:
创建 WASM 容器的 RuntimeClass CRD
为了 WASM 容器可以被 Kubernetes 所调度,我们需要创建一个 RuntimeClass CRD。
下载示例文件: $ git clone https://github.com/denverdino/wasm-container-samples $ cd wasm-container-samples
注册 RuntimeClass “wasm”这个值: $ cat wasm-runtimeclass.yaml apiVersion: node.k8s.io/v1beta1 kind: RuntimeClass metadata: name: wasm handler: wasm $ kubectl apply -f wasm-runtimeclass.yaml runtimeclass.node.k8s.io/wasm created $ kubectl get runtimeclass kubectl get runtimeclass NAME CREATED AT wasm 2020-02-01T06:24:12Z
在 K8s 中运行 WASM 容器应用
在 K8s 应用的 yaml manifest 中,我们可以在 Pod Spec 上指明所需 runtimeClassName。下面我们就用 K8s 来部署一个 nginx 的 WASM 容器。 $ cat nginx-wasm.yaml apiVersion: v1 kind: Pod metadata: name: nginx-wasm spec: runtimeClassName: wasm containers: - name: nginx image: denverdino/nginxwasm ports: - containerPort: 8080 $ kubectl apply -f nginx-wasm.yaml pod/nginx-wasm created $ kubectl get pod NAME READY STATUS RESTARTS AGE nginx-wasm 1/1 Running 0 9s
新机遇、新希望
目前为止,WebAssembly 技术仍处于初期阶段,WASI 也有很多局限性。但是社区的进展非常快,SIMD 指令支持,多线程处理等规范也正在快速演进中。WebAssembly 已经打破次元壁,将高性能的计算能力带领到 Web 浏览器端,越来越多的计算密集型的游戏、AI 模型预测、和数据处理应用被移植到浏览器端,可以为应用提供更加优化的用户体验。
WebAssembly 更广阔的空间在云计算领域、区块链等分布式计算领域。WebAssembly 轻量、敏捷、安全的特性,可以有效降低 Serverless 应用启动速度和资源消耗。同时 WebAssembly 的可移植,可以让应用一致运行在从云端服务器到边缘 IoT 设备等不同平台环境中,让计算无处不在。
利用 containerd 的扩展机制,可以为 WebAssembly 应用提供与其他容器应用一致的、抽象的、应用分发、交付和运维模型,可以在 Kubernetes 集群中进行统一调度和管理。希望通过类似的探索可以简化基于 WebAssembly 的分布式应用管理和运维。
关于作者
易立,阿里云资深技术专家,阿里云容器服务的研发负责人。之前曾在 IBM 中国开发中心工作,担任资深技术专员;作为架构师和主要开发人员负责或参与了一系列在云计算、区块链、Web 2.0,SOA 领域的产品研发和创新。阿里云容器平台团队求贤若渴!社招技术专家 / 高级技术专家,base 杭州 / 北京 / 深圳。欢迎发简历到 jiaxu.ljx@alibaba-inc.com
“ 阿里巴巴云原生 关注微服务、Serverless、容器、Service Mesh 等技术领域、聚焦云原生流行技术趋势、云原生大规模的落地实践,做最懂云原生开发者的技术圈。”
云计算
2020-03-11 11:09:00
随着技术的发展,各种应用变得越来越复杂,开发的压力也与日俱增,速度与质量等等各种要求更是让企业的基础架构、IT 团队及工作流程压力山大。
假设一下,你正在使用笔记本电脑开发应用,并且开发环境有特定配置,其他开发人员的环境配置可能稍有不同。而你正在开发的应用不止依赖于你当前的配置,还需要某些特定的库、依赖项和文件。另一边,你的企业还有标准化的开发和生产环境、配置和支持文件等等,你希望尽可能多在本地模拟这些环境,而不产生额外的开销。这个时候你该如何确保应用能在这些环境中运行和通过质检,并在部署过程中没有让人头疼的问题,也不需要重新写代码和故障修复?
答案就是:使用容器。 容器可以确保你的应用有用必需的库、依赖项和文件,你可以在生产中自如迁移这些应用,无需担心出现任何负面影响。
容器这个词,字面释义代表的是“可容纳物料的器具”,简单来说就是“装”。那么在 IT 世界里,容器技术就是 Linux Container 的直译。没错,自从 Linux 提出以后,容器已经发展成为云平台上不可或缺的技术。Linux 可以帮助你跨多种环境,作为云原生中最基础的计算单元,其标准化、轻量级、易移植、安全等特点正在受到越来越多的企业欢迎。
除了 Linux,在当前,Docker 更是大家都在讨论的热点,几乎是容器的代名词。但在容器世界里,要想了解 Docker,得先搞清楚: 容器的基本构成是什么?容器的典型应用是怎么样的?有哪些使用容器的优秀案例值得参考?如何将容器应用到实际业务中提升效率?
六周玩转云原生 为了让开发者们在这个特殊的时期里可以学习到更多干货,京东智联云开发者特别策划 《六周玩转云原生》系列课程 ,让你迅速入门,持续充电。
3 月 12 日,第一节针对容器方向的公开课《容器入门,Docker、Pod初探》将隆重开讲!
本次公开课邀请到京东云与 AI 云产品研发部专家架构师 刘俊辉老师,从容器的基本构成出发,深入浅出地勾勒出容器的基本情况,包括容器的结构、基本使用方式等。不仅如此,还将引出 Docker 这一重要概念,为开发者们拨开容器应用的迷雾。此外,刘俊辉还会着重讲解 POD、了解 POD 的构成和基本应用,帮助开发者对容器有更深入的理解。
容器入门,Docker、Pod初探
主讲人:刘俊辉 (京东云与AI云产品研发部专家架构师)
课程大纲
课程时间
03月12日(周四)20:00-21:00
扫描下方二维码
立即报名
注意!!报名成功后,开课前会有短信/邮件提醒,所以报名时请填写正确的手机号码及邮箱地址哦!
添加小助手,回复: 玩转云原生 进入公开课交流群 👇👇👇

欢迎点击“ 京东云 ”了解更多精彩内容!
云计算
2020-03-10 23:08:00
本文作者:HelloDeveloper
“电子发票、食品溯源、数字身份、慈善信息上链……”这些名词在过去的一年中越来越多出现在大众眼前。区块链不再是某一数字货币的代名词,而是越来越多的作为一种技术呈现商业价值,其特有的去中心化、可追溯、不可篡改等特性逐渐被挖掘,与云计算、AI等一道成为新一代具有变革性的技术动力,牵引着千行百业创新发展。

技术在政策的驱动下日益高涨。

去年10月,在中央明确“把区块链作为核心技术自主创新的突破口,加快推动区块链技术和产业创新发展”后,以京沪穗为首的各省市地区陆续推出相关政策,11月区块链政策出台环比增长140%。对于科技企业来说,踏上时代与政策的红利是快速发展的好时机,但要想在竞争日益激烈的上升阶段占得先机,选择特定的行业深耕细作尤为重要。

由于行业的需求千差万别,我们从政策、市场需求、行业特性、技术成熟度等方面着重谈两个创新的行业,希望能够抛砖引玉,找到区块链与行业的结合点,共同挖掘区块链落地的商业价值。

政务:政策下迎来红利期

在讨论区块链在政务领域的发展可行性前,不妨先来看一组数据。

据公开资料统计,在2019年落地的846个项目中,涵盖12大应用领域共计100+应用场景。其中政务类项目214项,占比约25%,与金融行业一起占据绝对的领先地位。

从更细致的数据分析,2019年上半年,区块链政务应用的数量占区块链应用总量的20.3%,低于全年平均水平。从中可以看出,区块链在政务领域的应用不仅数量大,且在去年一直成上升趋势,这将极大提振投资者的信心,也能进一步推动技术的研发创新。

这样的上升趋势能否在2020年继续呢?这是肯定的,区块链在政务领域最大的刺激与决定性因素在于政策,而在去年10月份中央申明态度后,各地方政府对于区块链项目的鼓励政策可谓此起彼伏。

尤其在政务领域,我们看到很多由政府牵头的项目已经取得了阶段性的成果:
北京海淀区通过区块链技术,实现“不动产登记+用电过户”同步办理;南京建设证照链实现证照可信互认; 重庆应用区块链技术试点企业开办、工程项目审批两项业务;上海提出探索用区块链技术加速“市民云”建设; 广州市“智慧破产审理系统”系统上线,其包含全国首个破产审判区块链协同平台。

政策牵引下,科技巨头纷纷加码区块链政务。

以百度智能云为例,其通过三大平台(联盟链BaaS、可信计算平台、可信数字身份平台)及两个垂直行业专项解决方案,全面赋能各政务场景。

其中,联盟链BaaS平台与可信计算平台相互集合,降低了多个管理局之间数据协作的成本。让从前需要到各个机构获取证明的繁琐流程,现在可以一站式完成。而数字身份则不仅实现了政务的一网通办,也提升了各个行业涉及身份认证时的效率。由此可见,我国头部科技企业已经具备技术与经验上的实力,这为产业进一步的创新发展打下了良好的基础。

总的来说,目前区块链在政务领域的应用多落地于一线城市,而为政府项目提供技术支持的也多为头部科技公司,但市场远不止于此。

我国人口基数大,新增人口多,且未来二三线城市以至乡镇都将在政策带动下逐步数字化,市场需求长期存在。此外,考虑到政务类应用如数字身份、电子存证等涉及公民信息等敏感因素,对安全性等技术要求较高,市场进入门槛高。因此,具备优秀人才与技术资源的企业,在一段时间内依旧具有强大竞争力,无须考虑同质化的问题。

金融:全球在创新 需求在推动

无论是最早抓住人眼球的数字货币,还是现如今被大力开发的跨境支付、资金追溯、电子票据等应用,区块链与金融领域都有着密不可分的关系。有人会好奇,作为最早也是落地应用最多的领域之一,金融行业在2020年还会是区块链技术最肥沃的土壤吗?

我国中央政府在去年十月对区块链技术的肯定,无疑为2020年市场的蓬勃发展释放了利好信号,尤其是“金融创新”口号的日益响亮,也为区跨链在金融领域的发展提供了更多可能。

但与政务领域不同,金融业的发展与国际各个区域市场的关系紧密相连,那不妨就以此时间点为界,看看世界上主要国家对区块链在金融领域的态度。

纵观全球,绝大多数国家尤其是发达国家对区块链技术持鼓励态度,特拨科研经费、成立专项实验室等都是普通配置。美国、英国、俄罗斯国家和地区等都在探索区块链在金融体系建设方面的应用。以英国为例,去年11月,英国议会成立跨党派区块链小组全球专家委员会,该全球专家委员会共14人,将同委员会中28位英国议员共同推进区块链的发展。

此外,整理去年10月以来的公开信息发现,美国、英国、法国、新加坡等对加密行业的监管愈加严格,在税收、支付等领域严密管控,并呼吁制定全球性的监管框架。更有力的监管或许意味着,披着金融创新外套做投机生意的可能性越来越小,市场越来越规范,区块链的技术价值也将更多得到重视。

政策支持只是推动,市场有需求才是区块链在金融领域的火热的直接原因,而金融行业与区块链的特性则是两者结合基础。

金融行业涉及银行、保险、证券等多领域,所有这些都离不开交易,自然涉及交易的双方、时间、资产等数不清的交易信息,这就是金融业永远需要解决的问题,即交易信息记录的安全性和完备性。而区块链作为一种革命性的底层技术,也是一个分布式的总账本,最初的功能就是记账,解决的就是这样的问题。而因其具有的去中心化、不可篡改、可追溯等特点,还能解决账本的信用问题、公证问题、审计问题、确权问题等等,这意味着其不仅能改革金融基础建设,更是从监管、交易、征信、虚拟货币等场景起到增效作用。区块链技术的优越性十分明显,而金融行业本身数字化程度高的特点更进一步降低了使用门槛。

与政务领域一样,头部科技公司的推动力量不容小觑。它们紧随政策与资本,不断加大区块链技术在金融领域的创新实践,为区块链由技术真正转化为可落地的解决方案,繁荣行业发展,最终服务大众生活打下夯实基础。

以百度智能云为例,其在去年11月紧随国家政策,推出“链上可信金融”解决方案,构建了新型金融业务的核心技术基础设施与创新业务产品矩阵,包括百度金融联盟链平台、可信计算平台、分布式身份平台、数字积分平台,能够加速金融行业的业务协作和数据流通,更好地支持金融行业高效发展。

相信在头部科技企业的带动下,技术向纵深推进,必将带动金融行业整体效率的提升与进步,毫无疑问也会带动区块链在整个金融行业的发展。

综上所述,政务与金融行业受政策牵引、资本青睐、自身行业特性与技术创新等因素的影响,在2020年有望迎来高速发展阶段。从以上观察中可以看出,更多行业或者行业中的某一细分领域也正在积极和区块链相结合,只要选择了适合自身的发展路径,任何行业的企业都能享受到技术带来的红利。
原文链接地址: https://developer.baidu.com/topic/show/290686
云计算
2020-03-10 18:07:00
Serverless 计算将会成为云时代默认的计算范式,并取代 Serverful (传统云)计算模式,因此也就意味着服务器 -- 客户端模式的终结。 ------《简化云端编程:伯克利视角下的 Serverless计算》
前言
Serverless计算让开发者能够以更高的灵活性和更低的成本构建现代应用程序。开发者无需配置和管理服务器等基础设施,可将全部精力投入核心业务。
Serverless相比传统的serverful开发方式有着本质的区别: 计算和存储的解耦;它们独立扩展,独立定价; 代码的执行不再需要手动分配资源; 按使用量计费。
Serverless快速构建构建APP问卷调查
函数服务作为Serverless架构中的核心计算组件,可应用于各类Serverless架构,主要包括两大类:Web、移动、IoT、AI等无服务器后端和数据处理系统后端。
其中,Web、移动serverless后端的典型场景应用最为广泛,本文介绍如何使用函数服务+API网关分分钟在京东云APP中构建用户问卷调查。
构建APP问卷调查可由两个简单函数完成:获取问卷内容和提交答案。
Step1:创建存储
创建一个用于存储问卷题库及用户答案的数据库或对象存储bucket,本示例创建一个云缓存Redis实例(主从4GB)。
Step2:创建函数
在函数服务中创建并测试两个函数(运行时:Python2.7)
创建函数1
创建函数jcloud-app-survey-topic:请求用户PIN,问卷版本version,从数据库获取问卷内容,将入口文件index.py与依赖库redis SDK打包上传至函数服务。index.py代码如下: #coding=utf-8 import json import redis'''下载问卷''' def handler(event,context): if not bool(event): result = { 'statusCode': 200, 'headers': {}, 'body': "", } return result body = event['detail']['body'] body = json.loads(body) pin = body.get('pin', "") version = body.get('version', "") print(pin) print(version) r = redis.Redis(host='redis-v214pzrgiicq-proxy-nlb.jvessel-open-hb.jdcloud.com', port=6379, db=0) topic = r.hget('topic_' + version, version) data = {'pin': pin, 'version': version, 'topic': topic} data = json.dumps(data) result = { 'statusCode': 200, 'headers': {}, 'body': data, } return result
函数测试
创建函数2
创建函数2jcloud-app-survey-submit :请求用户PIN,问卷版本version,用户答案submit,上传至数据库,将入口文件index.py与依赖库redis SDK打包上传至函数服务。index.py代码如下。 #coding=utf-8 import json import redis''' 上传问卷结果''' def handler(event,context): if not bool(event): result = { 'statusCode': 200, 'headers': {}, 'body': "", } return result body = event['detail']['body'] body = json.loads(body) pin = body.get('pin', "") version = body.get('version', "") submit = body.get('submit', "") print(pin) print(version) print(submit) r = redis.Redis(host='*********.jdcloud.com', port=6379, db=0) old = r.hget('submit_' + version, pin) if old != None : data = {'code': 1, 'desc': 'user have submitted'} data = json.dumps(data) result = { 'statusCode': 200, 'headers': {}, 'body': data, } return result r.hset('submit_' + version, pin, submit) data = {'code': 0, 'desc': 'success'} data = json.dumps(data) result = { 'statusCode': 200, 'headers': {}, 'body': data, } return result
函数测试
Step 3:创建发布API
在API网关创建两个API,作为触发器绑定至对应函数,通过function响应API请求,并将API发布至测试环境。jcloud-app-survey-topic函数绑定API触发器如下:
jcloud-app-survey-submit函数绑定API触发器如下:

Step 4:验证上线
通过本地API接口测试工具验证API接口无误,即可与前端H5页面开发联调,测试完成后,可通过函数版本、别名功能管理线上函数迭代发布。
问卷提交页
以上,快速完成APP后端上线,只等活动上线

最终效果
最后,APP调查问卷效果如下:

点击“ 京东云 ”了解更多关于队列服务


云计算
2019-10-30 14:34:00
自从 云终端 出来以后对于它的吐槽就一直没有中断过的,有说它配置低性能差的,也有的说它兼容性差的,还有的说它显示效果差的,总之就是有各种各样吐槽的。虽然说对云终端的吐槽有很多也一直没有中断过,但是使用它的人数并没有因此而减少的,反而是一直在不断增加的。是什么原因让你明知道云终端有不少的缺点,但是却仍然使用它的。

首先性能并不差,我认为首先很重要的一个原因就是云终端虽然有一些小问题,但是它并不影响我们的正常办公使用,虽然说它本身的配置低,但是它更多的情况下是通过协议连接服务器使用的,它的性能其实并不低的,完全可以媲美i3/i5电脑性能的,对于office办公、教学应用和播放高清视频来说都是流畅无卡顿的。可以说出来一些大型的3D应用和特殊的外设无法兼容外,云终端的体验并不比传统PC差的。而大型的3D应用和特殊外设对于大多数用户来说使用的并不多的。

其次使用成本低,云终端配置是不高兼容性也没有传统PC那么好,但是它的使用成本低,即使是算上服务器的价格每个用户采购成本也可以比传统PC低10%-30%左右的,加上云终端本身的功耗低省电以及免维护的特点,和使用传统PC相比每年可以节省95%左右用电成本和维护成本,低的使用成本使得云终端虽然有一些缺点,但是还是有很多用户愿意使用它的。

第三数据安全高,随着社会的发展,人们对数据安全的意识越来越高的,传统的PC虽然性能强大,但是对于本地数据的管控却做的不是很好的,云终端性能是不强,但是它对于数据的管控却比传统PC要好,本地不存储重要数据,同时可以禁止云终端接入U盘等带存储拷贝功能的外设设备,通过后台服务器可以管控每一个用户使用桌面的情况,任何用户访问重要数据都需要授权,确保数据不被拷贝和任何形式传输泄露出去的。

云终端虽然有一些缺点和使用上的问题,但是同时它也具备传统PC所没有的优点,同时最主要的它的缺点对于很多人来说是可以忽略不计,并不影响正常的办公使用的,所以才会有这么多人坚持使用它的。
来源禹龙云
云计算
2019-10-30 14:22:00
ACP
说明:以下题目收集自网络和参与过考试的同学的分享,原内容有 765 道题,本人有一定阿里云实操经验,考试准备了一周时间,学习阿里云官方文档和网上找测试题,最终于 19-11 通过考试。题目整理得格式不好,有些答案的 ABCD 都缺失了,但答案是对的,只是需要自己对应下选项。ACP 考试本身更接近理论,但也是需要有一定实操经验的,可以使用阿里云按量计费的实例熟悉一下。希望这个能对大家有所帮助。
全部题库
★1/765、阿里云的云服务器ECS产品根据底层使用的硬件不同划分为不同的实例系列。对于实例系列I采用 lIntel Xeon CPU,实例系列采用 Haswell CPU。以下关于云服务器ECS产品的实例系列说法正确的是 。(正确 答案的数量:3个) A、实例系列Ⅱ的用户可以获得更大的实例规格 B、实例系列I相对于实例系列I增加了一些新的指令集,使整数和浮点运算的性能翻倍 C、ECS实例创建以后可以进行实例系列I与实例系列∏的变更 D、实例系列Ⅱ全部为O优化实例,配合SSD云盘使用可以获得更高的O性能 提示:排除法,实例系列I和实例系列Ⅱ直接是不同的处理器系列,创建之后不支持变更 答案:ABD
2★3/765、使用集群是解决高并发,海量数据的通常手段,对于这种类型的网站而言,不管多么强大的服务器都满 足不了持续增长的业务需求。这种情况下,需要增加服务器来分担原有系统的压力我们可以开通阿里云上哪个服 务来实现该请求的分发? A、ECS B、SLB C、RDS D、DRDS 提示:划重点:来实现该请求的分发,所以需要负载均衡SLB。 答案B
1★4/765、云计算是一种商业计算模型,它将计算任务分布在大量计算机组成的资源池上,使各种应用系统能够根 据需要获取计算力、存储空间和信息服务。以下哪些是按照云计算服务的部署方式分类的?(正确答案的数量:3 个) 、公共云 混合云 专有云 D、能源云 提示:能源云并不属于的云计算服务的部署方式。云计算的四种部署方式私有云、社区云、公有云(公共云)和混 合云。相关链接 答案:ABC
3★5/765、在阿里云的云盾态势感知中看到的所有安全威胁,阿里云的系统都会自动处理,不需要用户主动参与 只要知道就可以了。 A、正确 错误 提示: 答案B
1★6/765、通过阿里云“弹性伸缩”服务自动创建的ECS符合以下哪些特征?(正确答案的数量:3个) A、创建的ECS会配置相同的IP地址 、如果伸缩组里指定了RDS实例,系统会自动将ECS的P加入指定的RDS访问白名单当中 如果伸缩组里指定了SLB实例,系统会自动将ECS的加入到SLB组里 D、创建的ECS配置都是相同的 提示:弹性伸缩出来的机器配置和规格相同,但是不会出现相同I的情况 答案BCD
1★7/765、弹性伸缩一定要搭配负载均衡SLB、云监控才能使用。 A、对 错 提示:弹性伸缩无需搭载负载均衡SLB,云监控一起使用。 答案B
1★8/765、阿里云OSS图片处理服务,绑定域名名需要做线上验证,其中一步是下载验证文件并上传到您域名 的下,此步骤为验证您对绑定域名的所有权 A、有效率 B、根目录 C、顶级目录 D、子目录 提示:线上验证是将下载的验证文件放置于域名的根目录下来完成验证绑定域名的所有权。 答案B
3★9765、阿里云的负载均衡SLB支持同一地域( Region)跨可用区(Zone)容灾,结合DNS还可以支持跨地 域( Region)的容灾。 A、对 B、错 提示:多个不同地域的负载均衡SLB支持通过DNS轮询来实现跨域容灾,相关链接 答案A
1★10765、您在创建阿里云的云服务器ECS实例时必须要选择 来指定新建的云服务器ECS实例的系 统盘的配置? A、IP地址 、镜像 C、安全组 D、区域 提示:ECS的系统盘的配置需要通过镜像来新建完成。 答案B
2★11765、阿里云作为云计算服务的提供商,为用户提供的安全保障服务包括 (正确答案的数 量:2个) A、云计算底层硬件设施的安全运维 B、云服务器ECS中的应用维护 C、云计算租户之间的安全隔离 D、云数据库RDS的P白名单设置 提示:阿里云作为云计算服务的提供商为用户提供的安全保障会包括云计算底层硬件设施的安全运维、云计算 租户之间的安全隔离。但是云服务器ECS中的应用维护和云数据库RDS的IP白名单设置还是需要用户自己来 做 答案:AC
4★12765、阿里云对象存储OSS是阿里云对外提供的海量、安全、低成本、高可靠的云存储服务。与自建存 储对比,OSS在可靠性、安全、成本和数据处理能力等几个方面都具有优势。以下 不是OSS在数据处 理能力方面表现出来的优势。 提供大规模的数据分析能力 B、提供实时缩放图片的处理功能 C、提供实时的“文字水印”的图片处理功能 D、提供实时的“图片水印”的图片处理功能 提示:对象存储OSS并不具备大规模的数据分析能力。 答案:A
1★13/765、A公司管理员小牛近期发现公司的网站访问速度越来越慢,偶尔会出现无法打开的现象,从web 日志中发现了数据被恶意爬取的行为,且并发访问量较大,这种情况下可以使用阿里云的安全产品进 行防护。 A、安全管家 B、态势感知 、Web应用防火墙(WAF) D、云安全中心(安骑士) 提示:划重点:从web日志中发现了数据被恶意爬取的行为,且并发访问量较大。所以需要用到Web应用防火 墙(WAF)的防爬虫功能。 答案C
3★14765、如果用户只使用阿里云的云盾的DDoS基础防护功能,当攻击规模超过服务上限时,会触发黑洞规 则,之后用户的服务器仍可以对外提供服务,只是速度受到限制。 A、正确 B、错误 提示:当ECS或SLB实例的公网I遭到大量DDoS攻击,且DDoS攻击的流量超出对应的黑洞阈值后,该公网IP将 被黑洞,所有来自外部的流量都将被丢弃,导致相关的业务无法正常访问。相关链接 答案B
3★15/765、在使用阿里云的公网IP的负载均衡SLB实例的四层(TCP协议)转发时,后端云服务器池中的ECS 实例不能直接向该ECS实例所在的负载均衡SLB实例的公网发送请求 错 提示这和负载均衡TCP的实现机制有关。在四层TCP协议服务中,当前不支持后端云服务器的ECS既作为 Realserver,又作为客户端向所在的负载均衡实例发送请求。因为,返回的数据包只在云服务器内部转发,不 经过负载均衡,所以在负载均衡实例的后端ECS上去访问的负载均衡的服务地址是不通的。相关链接 答案:A
4*16/765、阿里云对象存储OSS是阿里云对外提供的海量、安全、低成本、高可靠的云存储服务。用OSS管理 的文件可以很方便地对外提供分享,分享前点击文件后面的“获取地址”文字链接即可得到当前文件的地址,这 个分享使用的是____应用层(七层)协议。 A、FTP B、HTTP C、TCP D、SMTP 提示:OSS的分享文件使用的是HTTP应用层(七层)的协议。 答案:B
4÷17/765、您已经创建好的阿里云的云服务器ECS实例上部署了服务A,当服务A不再需要提供服务时,可以 使用该云服务器部署服务B,如果服务A和B所需的操作系统不同,则需要更换该ECS实例的系统盘。在执行该 操作的过程中,以下说法正确的是?(正确答案的数量:5个) A、更换系统盘前云服务器ECS实例要处于已停止状态 B、更换系统盘时可以选择用户自定义镜像、阿里云为您提供的公共镜像 C、在有数据盘的情况下,如果是Windows系统更换至Linux系统,由于Linux默认无法识别NTFS格式,需要您 单独安装软件识别,例如ntfs-3G等 D、在有数据盘的情况下,如果是Linux系统更换至Windows系统,由于Windows系统默认无法识别ext3,ext4,xfs 等文件系统格式的磁盘,需要您单独安装软件识别,例如ext2read ext2fsd等 E、更换系统盘之后,您的长服务器ECS实例的IP地址会发生变化 F、更换系统盘之后,您现有系统盘的自动快照及其上的数据会丢失 提示:排除法,更换系统盘并不是导致网络层的IP地址会发生变化。 答案:ABCDF
2★18765、阿里云对象存储OSS提供了丰富的文件上传和下载接口,用户可以通过API方便地实现大容量存储 空间的管理。如果您想建立一个大型图片分享站点,该网站允许大量用户通过WEB方式进行图片的上传和分 享,可以使用阿里云的 产品与OSS配合实现。 A、负载均衡SLB B、云服务器ECS C、云数据RDS D、内容分发网络CDN 提示题目中要求允许大量用户通过WEB方式进行图片的上传和分享,所以需要云服务器ECS来提供WEB服务 支持。 答案B
3★19765、阿里云的负载均衡SLB实例和后端云服务器ECS实例之间是通过公网进行通信的,所以云服务器 ECS实例必须配置外网带宽。 A、对 B、错 提示:负载均衡SLB实例和后端云服务器ECS实例之间是通过内网通信的。 答案B
3★20765、某期货交易网站,使用阿里云负载均衡SLB服务。由于期货交易对于负载有高敏感性,高频的健康 检查有可能会对用户的正常访问带来影响。该网站可以通过以下方式减少健康检查对正常业务的影响:降低健 康检查的频率,增大健康检查间隔。 A、对 B、错 提示如果您的业务对负载敏感性高,高频率的健康检查探测可能会对正常业务访问造成影响。您可以结合业 务情况,通过降低健康检査频率、增大健康检査间隔、七层检査修改为四层检査等方式,来降低对业务的影 响。但为了保障业务的持续可用,不建议关闭健康检查。相关链接 答案:A
21/765、某保险公司的线上平台每天在线订单量超过20万笔,一年来频繁受到大流量攻击(超过10G),使 服务断断续续,严重影响了公司的品牌和业务量。如果该客户使用阿里云的 产品可以抵御这类攻 击,保证业务的高可用性。 A、DDoS基础防护 B、安全管家 C、态势感知 D、DDoS高防IP 提示DDoS基础防护只能防护5GB以下的DDoS攻击,超过5GB的DDoS攻击需要用到DDoS高防IP。 答案D
4★22765、您成功地创建了一台阿里云的云服务器ECS实例准备进行应用的部署。在部署应用之前如何保证 该云服务器ECS实例具备防御500M以内的DDoS攻击的能力? 、阿里云的云盾产品提供免费的基础DDoS防护服务,不需要单独购买 B、需要另行购买DDoS防护服务才可以具备防护功能 C、需要您自己架设防DDoS服务 D、其他都不对 提示:阿里云的云盾免费的DDoS基础防护提供最高5G的默认DDoS防护能力,所以5G以下可以选择云盾DDoS 基础防护,5G以上可以选择云盾的DDoS高防服务。 答案:A
3★23/765、某电子购物网站,为了方便用户,提供了购物车的功能,即在用户登录期间,可以添加自己喜欢 的商品到购物车,选择完成后一次性付款即可。上述网站搭建在阿里云上,选用了云服务器ECS实例和负载均 衡SLB实例,应用程序将会话信息和购物车信息都只保存在了应用程序的内存中,公测期间发现绝大部分测试 用户的购物车功能没有问题,但一小部分用户的购物车发生了最早添加的商品随机丢失的现象。试分析以下哪 些原因可能会造成这种情况?(正确答案的数量:3个 用户购物的时长超过了负载均衡SLB实例中定义的会话保持的超时时间 B、用户使用手机登录,一次购物的过程中,发生过网络的切换导致的重新链接 C、某台云服务器ECS实例状态不正常,导致这部分用户前期的购物篮记录被清空 D、负载均衡SLB实例未开启会话保持功能 E、负载均衡SLB实例进行上备可用区切换导致部分用户数据丟失 提示:商品的数据都保存在内存中,那既然出现了数据丢失,出现的问题要么是用户没有访问保存购物数据的 那台机器,要么是保存他那台数据的机器出问题了。 答案:ACE
1★24765、阿里云的负载均衡SLB提供对多台云服务器ECS实例进行流量分发的服务,可以通过流量分发扩展 应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。阿里云的负载均衡SLB可以支持 协议。(正确答案的数量:4个) 、UDP B、 Https C、 PPPOE 、TCP E、HTTP 提示 PPPOE是很老的拨号协议,阿里云负载均衡SLB不支持此协议。 答案:ABDE
3★25/765、小明是一个社交网站的架构师,创业初期用户量较少,每个注册客户上传的图片文件直接保存在 了一台阿里云的云服务器ECS实例上。最近用户量爆增,图片存储的空间达到了35T,WEB服务器由原来的1 合ECS实例扩展到了5合ECS实例,性能问题得到了解决,可是保存在ECS实例的图片无法在多台ECS之间共 享读写。阿里云的 产品非常适合解决这个问题。 、对象存储OSS B、负载均衡SLB C、归档存储( Archive Storage) D、内容分发网络CDN 提示:划重点:保存在ECS实例的图片无法在多台ECS之间共享读写,所以需要对象存储OSS提升图片存储的性 能已经共享读写图片。 答案:A
3★26/765、使用阿里云的负载均衡SLB实例时,合理的会话保持配置可以实现与某个连接( Session)相关的 所有应用请求能够由同一台后端云服务器ECS实例进行处理,维持业务的延续性。七层服务的会话保持是基于 实现的 A、源I B、负载均衡IP cookIe D、用户的UUID 提示四层服务的会话保持是基于源IP实现的,七层服务的会话保持是基于 Cookie实现的。 答案:C
2★27765、阿里云的云盾“DDoS基础防护”为阿里云用户提供最高5G的默认DDoS防护能力。用户如果加入安 全信誉防护联盟计划,云盾将基于安全信誉分进一步提升DDoS防护能力,用户最高可获得100G的免费DDos 防护资源。以下有关云盾“DDoS基础防护”的特点描述正确的是。(正确答案的数量:3个) A、BGP线路防护:受到DDoS攻击不会影响访问速度,带宽充足不会被其他用户连带影响,优质带宽保证业务 可用和稳定 精准防护:精准识别攻击,秒级开启防护,自研清洗设备和算法保证极低误杀 免安装免维护:无需采购昂贵清洗设备,自动为云上客户开通免安装,智能业务学习和配置防护规则 D、分布式:通过散列分布式的虚拟节点将业务分散部署,有效避免网络攻击的发生 提示具体的可以参考DDoS基础防护服务的产品简介:相关链接 答案:ABC
3★28/765、当您的云服务器ECS实例的镜像选择了 Aliyun linux,可以兼容以下操作系统 A、 CentoS B、 Windows server2008 C、 OpenSUSE D、 UBUNTU 提示 Aliyun Linux和 Centos都属于 Redhat一家的。兼容 Red hat。其中包括( Red Hat Enterprise linux, Fedora, Centos, Scientific Linux, Oracle linux),参考:相关链接 答案:A
3★29/765、阿里云弹性伸缩( Auto Scaling)中,当进行弹性收缩时,对于运行在需要移出伸缩组的ECS实例 上的应用,如果简单的中断服务,会影响到客户体验。如果需要确保在ECS实例上任务处理完成才释放该实 例,弹性伸缩提供了解决方案:在创建ECS实例使用的镜像中存放一个包含处理逻辑的脚本,并设置成在ECS 实例操作系统关机时自动执行该脚本。 对 B、错 提示:如您需要确保在ECS实例上任务处理完成才让弹性伸缩释放该实例,您需要在自定义镜像中存放执行脚 本,并设置命令在操作系统关机时自动执行该脚本。相关链接 答案:A
1★30765、对 ECS API接口调用是通过向 ECS API的服务端地址发送 Http Get请求,并按照接口说明在请求 中加入相应请求参数来完成的 对 B、错 提示:云服务器ECS的API是通过向 ECS API的服务端地址发送 Http Get请求来实现相关的业务请求。相关链 接 答案:A
1★31/765、用户如果想要在OSS中模拟实现文件夹的创建操作,需要使用的API是 A、 Multipart Upload B、 putobject C、 Get object D、 Copy object 提示OSS中文件夹的概念仅是一个逻辑概念,在通过 APISDK的方式设置文件夹的时候可以指定 object对应的 key值包括前面的目录即可实现该功能。相关链接 答案B
4★32765、您拥有香港地域可用区A、华北1(青岛)地域可用区B和华南1(深圳)可用区B的云服务器ECS 实例,现在希望通过购买新的块存储挂载到已有的云服务器ECS实例上进行磁盘空间的扩容,肯定不能购买 可用区的块存储。 华北1(青岛)地域可用区A B、华北1(青岛)地域可用区B C、香港地域可用区A D、华南1(深圳)地域可用区B 提示:根据题意,购买新的块存储意味创建新的数据盘,所以只能购买同一个可用区的云盘,所以只能选择: 香港地域可用区A,华北1(青岛)地域可用区B和华南1(深圳)可用区B 答案:A
2★33765、CDN节点系统关键组件有哪些?(正确答案的数量:3个) A、 origin 、LVS tengine D、 swift 提示:LVS做四层均衡负载; Tengine做七层负载均衡;Swit做HTP缓存。相关链接 答案:BCD
1★34765、云盾安骑上可以保防阿里云以外的服务器。 错 提示:云盾安骑士支持防护阿里云的ECS以及非阿里云的线下机房的实例。相关链接 答案:A
1★35765、云计算是一种商业计算模型,它将计算任务分布在大量计算机组成的资源池上,使各种应用系统 能够根据需要获取计算力、存储空间和信息服务。以下关于使用公共云计算相对于使用传统IC的优势,从云 计算的使用者角度来看,说法正确的有 ?(正确答案的数量:4个) 、云计算的使用者节约了建立基础设施的成本 B、云计算的使用者能快速搭建应用 C、云计算的使用者简化了管理和维护工作 D、云计算的使用者可以完全管理和控制底层基础设施 E、云计算的使用者拥有更大的灵活性和扩展性 提示:阿里云云计算的使用者是不可以管理和控制底层基础设施。 答案:ABCE
1★36/765、C公司基于阿里云对象存储OSS和云服务器ECS实例构建了一个网站,ECS实例与OSS之间有频繁 的文件上传和下载需求。系统管理员小赵最近通过阿里云管理控制台中的费用中心发现OSS的流量费用增长很 快,但是从ECS实例上部署的应用系统日志里没有发现网站访问量有明显增长。请您帮小赵判断一下有可能是 原因导致的。 A、系统架构中缺少云数据库RDS B、可能是ECS实例通过公网地址调用OSs的API C、ECS实例的系统配置不足,需要增加内存 D、系统架构中缺少负载均衡SLB 提示:题目中说:ECS和OSS之前有频繁的上传和下载的需求,但是ECS的访问量很小,但公网流量增长却很 快,所以可以判断是ECS辽过公网AP访问OSS导致的公网流量。 答案B
3★37765、阿里云负载均衡SLB是对多台云服务器ECS实例进行流量分发的服务。配置和管理一个负载均衡 SLB实例,主要涉及以下操作。(正确答案的数量:3个) 、负载均衡SLB实例的属性配置 B、负载均衡SLB实例的监听配置 负载均衡SLB实例的后端ECS实例配置 负载均衡SLB的公网IP E、负载均衡SLB的操作日志存储位置 提示:公网P是购买负载均衡SLB时候系统分配的,或者你单独购买EIP后单独给负载均衡SLB绑定。并不是在 你在负载均衡的配置和管理里面可以设定的。 答案:ABC
4★38765、阿里云对象存储OSS自动为每个 Bucket分配一个“外网地址”和“内网地址。正确使用OSS的内网地 址,可以节省OSS与云服务器ECS实例之间的流量费用,云服务器ECS实例通过内网访问OS能够有效的提升上传 和下载的质量。场景可以使用OSS的“内网地址”通信。(正确答案的数量:3个) A、 OSS Bucket在R1地域,用户有两台云服务器ECS实例分别在该地域的可用区A和可用区B,两台ECS实例上 的访问日志都要保存到OSS中 B、 OSS Bucket在R1地域,用户有1台云服务器ECS实例在R1地域的可用区A,此台ECS实例上的访问日志要保 存到OSS中 C、 oss Bucket在R2地域,用户在R1地域的可用区A有1台云服务器ECS实例,此台ECS实例上的访问日志要保 存到OSS中 D、 OSS Bucket在R1地域,在该地域的可用区B用户有1台云服务器ECS实例,此台ECS实例上的访问日志要保 存到OSS中 提示题目中问的是云服务器ECS实例通过内网访问OSS,所以要求云服务器CS和OSS需要处于同一个地 域," OSS Bucke在R2地域用户在R1地域的可用区A有1台云服务器ECS实例"明显不符合要求。 答案:ABD
3★39/765、阿里云的负载均衡SLB提供对多台云服务器ECS实例进行流量分发的服务,可以通过流量分发扩展 应用系统对外的服务能力,通过消除单点故障提升应用系统的可用性。阿里云的负载均衡SLB支持 层 网络协议的负载均衡服务。(正确答案的数量:2个) 、4层(传输层 B、7层(应用层 C、3层(网络层) D、2层(数据链路层) 提示:阿里云的负载均衡SLB目前仅支持4层和7层的负载均衡。 答案AB
3★40765、使用阿里云的负载均衡SLB时,为了实现跨地域( Region)的高可用性,可以在不同的地域 ( Region)创建多个负载均衡SLB实例,通过的方式对外提供服务。 A、DNS轮询 B、DNS最小连接数 C、DNS广播 D、DNS多播 提示:实现不同地域的多个负载均衡SLB的负载,需要通过DNS轮询来实现,相关链接 答案:A
1★41/765、在使用阿里云DDoS高防理P时, CNAME配置非常简单,只需要配一条DNS记录就可以启用。 、正确 B、错误 提示:CNAM接入模式更加方便,您只需要在域名解析服务商处(如万网云解析或者 DNSPod)修改一次解析 配置即可生效,实现零部署、零运维。相关链接 答案:A
4★42/765、SLB是将访问流量根据转发策略分发到后端多台云服务器(ECS实例)的流量分发控制服务。下列 关于SLB说法错误的是? SLB的服务能力与后端ECS的公网宽带规格无关 、同一组ECS不可以搭建多个网站并同时进行负载均衡 C、在使用SLB的过程中随时调整后端ECS的数目 D、不同操作系统的ECS可以同时做为SLB服务的后端服务器 提示:同一组ECS可以同时搭建多个网站并进行负载均衡 答案B
3★43765、用户可以通过控制台或AP配置监听的健康检查。下列属于SLB健康检查必选参数配置的有?(正 确答案的数量:3个 A、响应超时时间 B、健康检查间隔 C、不健康阀值 健康检査请求 提示:注意题目要求的是必选参数,考的是配置健康检査的实际操作能力,健康检査请求不是必须的配置参 数。相关链接 答案:ABC
1★44765、阿里云的云盾DDoS高防IP可以抵御数百G的DDoS攻击,阿里云及非阿里云主机都可以使用云盾 DDoS高防I服务。 错 提示:云盾DDoS高防I产品是针对解决互联网服务器(包括非阿里云主机)在遭受大流量的DDoS攻击后导致服 务不可用的情况 答案:A
★45/765、您已经在阿里云的一台经典网络类型的没有数据盘的云服务器ECS实例上运行所有的应用,现在出 于业务发展的需要,您希望将这台云服务器ECS实例迁移到相同地域的专有网络VPC中去,以下 操作 是可行的。 直接将云服务器ECS实例的类型转换为专有网络 B、将该云服务器ECS实例的安全组变更为专有网络类型 C、制作该云服务器ECS实例的镜像,基于该镜像制作专有网络类型的云服务器ECS实例,业务会短暂停顿 D、无法迁移 提示题目中需要将经典网络的云服务器ECS实例迁移到相同地域的专有网络VPC中去,虽然目前阿里云支持直 接迁移,但是从上云实践的规范中出发,因为云服务器或捆绑或者依赖其他多个附属的云产品(如:数据库 RDS等),所以运营一键辽多并不能完成其他附属云产品的转换。所以基于镜像来迁移至专用网络ⅤPC中去是 最稳妥的方法。
3★46/765、阿里云弹性伸缩( Auto Scaling)中的伸缩组是指部署了相同应用的云服务器ECS实例的集合,其 中的ECS实例既可以是包年包月的,也可以是按量付费的。对于业务量突变的场景,按量计费的ECS实例会在 满足业务需求的同时尽可能的节省成本;对于用户已有的包年包月的闲置的ECS实例,也可以手工添加到满足 一定条件的伸缩组,能充分利用闲置资源。 B、错 提示:弹性伸缩( Auto Scaling)中既支持自动伸缩,也支持手动添加闲置的ECS实例,手动添加的ECS的规格 配置不需要和伸缩配置中的配置相同。 答案:A
3★47765、阿里云对象存储OSS的存储费用在所有地域支持“按量付费”,在部分地域支持“包年包月”和“按量 付费两种方式。用户可以通过“包年包月”的付费方式可以获得资源包”,根据业务需求选择合适的资源包可 以节约使用OSS的成本。以下有关OSS包年包月收费方式的说法中是正确的。(正确答案的数 量:3个) 、费用一次性支付,立即生效 B、用户购买的“包年包月”资源包在有效期内,扣费方式为先扣除已购买的资源包内的额度,超出部分按量收 费 C、“包年包月”的资源包,采用按存储容量的阶梯计价,容量越大,单价越便宜 D、存储容量相同的“包年包月”的资源包,购买时长越短,单价越便宜 提示:排除法,存储容量相勹的“包年包月”的资源包,购买时长越短,单价越贵,购买时长越长,单价越便宜 答案:ABC
4★48/765、阿里云对象存储OSS中所有数据都保存在 Bucket中,当一个 oss bucket设置成 权限,意味 着该 oSS Bucket仅允许其他用户来访问( GET Object)属于该 Bucke下的 objecto A、公共读写 公共读 C、私有 D、私有读 提示:允许其他用户访问就代表允许公共访问此 Bucket,所以选择公共读 答案B
2★49/765、阿里云内容分发网络CDN建立并覆盖在承载网之上,由分布在不同区域的边缘节点服务器群组成 的分布式网络替代传统以 WEB Server为中心的数据传输模式。CDN加速特别适合在站点访问量大,且静态资 源被不同用户重复访问的比例高的场景中使用,重复访问率越高加速效果越明显。 A、对 B、错 提示:文档原话,阿里云CDN(内容分发网络)全称是 Alibaba Cloud Content Delivery Network,建立并覆盖在 承载网之上、由分布在不同区域的边缘节点服务器群组成的分布式网络,替代传统以 WEB Server为中心的数据 传输模式。 答案:A
4★50765、阿里云对象存储OSS是阿里云对外提供的海量、安全、低成本、高可靠的云存储服务。与自建存 储对比,OSS在可靠性、安全、成本和数据处理能力等几个方面都具有优势。以下是OSS在安全性方 面表现出来的优势。 A、流量清洗和黑洞设备需要另外购买,阿里云的云市场有多家优质的供应商可供选择 B、OSS提供灵活的开发接口,兼容市面上主流的安全防护设备和协议 、提供多种鉴权和授权机制,以及白名单、防盗链、主子账号功能 D、阿里云提供定制化的安全服务,可根据用户的需要一对一定制开发 提示:安全性主要表现在三方面:1.提供企业级多层次安全防护。2.多用户资源隔离机制,支持异地容灾机 制。3.提供多种鉴权和授权机制及白名单、防盜链、主子账号功能。相关链接 答案C
3★51765、开通阿里云对象存储OSS服务后,您首先需要使用OSS管理控制台或 OpenAPI创建存储空间 Bucket 以用来存储文件,以下有关 Bucket的说法 是正确的。 、 Bucket的名称要求全局唯一,且创建后不支持更改 B、 Bucket的名称要求全局唯一,创建后支持更改 C、 Bucket的名称只要求在本帐号内唯一,创建后支持更改 D、 Bucket的名称要求在本帐号内唯一,且创建后不支持更改 提示:每个 Bucket存储空间的名字全局唯一, Bucket存储空间一旦创建成功,名称和所处地域不能修改。 答案:A
3★52765、云服务器ECS系统资源监控 Dashboard页面内容有哪些?(正确答案的数量:3个) 、CPU使用率 磁盘IO C、网络带宽 D、TPS 提示 Dashboard不支持对TPS的监控 答案:ABC
3★53/765、阿里云的负载均衡SLB包含了几个主要的部分:来自外部的访问请求、 Listener、 LLoadBalancer、 Backendserver等,关于 Listener的说法中正确的是 主要包括用户定制的负载均衡策略和转发规则 B、提供对外服务的ECS实例集合 C、是指负载均衡SLB实例 D、通过配置监控规则,可以生成负载均衡SLB实例的监控指标 提示: Listener:用户定制的监听器,定义了负载均衡策略和转发规则。相关链接 答案A
3★54765、阿里云对象存储OSS是阿里云提供的海量、安全、低成本、高可靠的云存储服务。为了方便用户把 OSS服务集成到自己的网站或应用中,OSS提供了“自定义域名绑定”的功能,通过该功能用户可以实现通过自 己的域名来访问OSS中的文件(如: http://img.mydomain.net/xxxx )以下有关OSS绑定域名的相关说法 是正确的。(正确答案的数量:3个 、如果用户绑定的域名和OSS服务在同一个阿里云帐号中管理,在OSS管理控制台中可以选择自动添加或修 改域名的 CNAME记录 、不管域名是否在阿里云管理,绑定到OSS的域名必须在工信部备案 C、如果在OSS绑定域名时提示绑定的域名已经被其他用户绑定,此时用户无需额外操作即可进行强制绑定 绑定域名的时候可以选择“自动”或“手动"添加域名解析 提示:在OSS绑定域名时提ˉ绑定的域名已经被其他用户绑定,需要验证域名所有权后才可继续进行绑定操作。 相关链接 答案:ABD
3★55765、您需要将阿里云的专有网络vPC与传统数据中心组成一个按需定制的网络环境,实现应用的平滑 迁移上云。专有网络ⅤPC可以与 连接方式组合来实现该架构。(正确答案的数量:2个 A、 VRouter 专线 C、SDN VPN 提示根据题意,需要让专有网络ⅤPC与传统数据中心实现内网访问,所以专线和ⅤPN可以满足要求。 答案BD
3★56765、阿里云对象存储OSS里存储的文件可以进行分享和下载,当文件所在的 Bucket的读写权限为“私 有”时,OSS分享链接采用的安全机制是 A、在管理控制台中获取文件访问URL时设置分享链接的访问密码,访客下载文件时凭密码访问 B、“私有权限的文件对外享时,访客只能看到文件的一部分内容(前500K) C、在管理控制台中获取文件访间URL时设置分享链接有效的时间,超过设定时间就无法下载 D、“私有”权限的文件对外分享时,系统会检查文件的大小,超过2M的文件不允许分享 提示:出于安全考虑,目前控制台针对私有 bucketp的获取URL链接签名操作做了优化,使用的 AccessKey是临时 生成的密钥对,主账号用户最长有效时间是64800秒(18小时),RAM子账号用户以及sts用户最长有效时间是 3600秒(1小时),超时后链接就无法访问了。相关链接 答案:C
1★57/765、阿里云OSS与自建存储相比,有以下哪些优点?(正确答案的数量:4个) A、海量存储 低成本 C、安全 、多线BGP接入 E、支持数据备份 提示:自建的存储也是支持数据备份的,这个并不是OSS独有的优势。 答案:ABCD
1★58765、以下 安全事件是不能由阿里云态势感知集中管理的 A、发现主机有异常进程 B、发现主机成为肉鸡 C、机房断电 D、发现网站被DDoS攻击成功 提示机房断电是态势感知不能预测到的故障。 答案:C
4★59/765、阿里云对象存储OSS与云服务器ECS实例之间的内网通信免费,只要 OSS Bucke和ECS实例的所属 地域在中国大陆范围内,就可以使用内网地址免费通信 A、对 提示:只有ECS和OSS的 Bucket处于同一个地域( Region),才可以使用内网地址通信。 答案B
3★60765、用户开启SLB会话保持功能后,SLB会把来自同一客户端的访问请求分发到不同的后端ECS上进行 处理 A、对 提示:开启会话保持后,负载均衡监听会把来自同一客户端的访问请求分发到同一台后端服务器上。相关链接 答案B
1★61/765、阿里云内容分发网络CDN支持大文件下载加速、音视频点播加速,以及HTPS安全加速。 A、对 B、错 提示阿里云内容分发网络CDN支持各类网站静态内网的加速服务,支持 Https。相关链接 答案:A
1★62/765、A电商平台近几年业务增长很快,访问量持续保持每年提升300%,平台运营团队因此获得了公司 的年度特别奖励。在高兴之余运营团队发现平台系统带宽的支出是以每年500%的比例增长的,如果能有效降 低这块成本可以提升整体的运营质量。此时,该公司选择阿里云的 服务,效果会最明显。 A、支持多可用区的云数据库RDS 内容分发网络CDN C、对象存储OSS D、负载均衡SLB 提示:题目中说"系统带宽的支出是以每年500%的比例增长的",说明服务很占用带宽资源,可以通过内容分发 网络CDN来减少服务器的带宽输出。 答案B
5★63765、您部署在阿里云云服务器ECS上的服务,希望能够通过阿里云的产品来提升该服务的可用性,以下 哪种方案的可用性最高? 、在同一个地域的多个可用区的多台云服务器上部署应用,并挂载在同一个负载均衡实例后面 B、在同一个地域的同一个可用区的多台云服务器上部署应用,并挂载在同一个负载均衡实例后面 C、在不同地域的多个可用区的多台云服务器上部署应用,并挂载在同一个负载均衡实例后面 D、在不同地域的同一个可用区的多台云服务器上部署应用,并挂载在同一个负载均衡实例后面 提示:1、SLB不能跨地域,要想跨地域只能在多个地域单独配置不同的SLB再通过DNS轮询实现转发。2、同 个地域下,SLB通过在不同可用区配置ECS实现灾备。四个选项都是只有一个SLB,所以可用性最高的就是 多个可用部署应用 答案:A
3★64765、使用阿里云对象存储OSS保存云服务器ECS实例上的业务系统日志,可以有效降低存储成本。如果 ECS实例和OSS在同一地域,只能通过公网地址传输数据。 A、 对错 提示ECS实例和OSS在同一地域,是可以通过内网来传输数据的。 答案B
1★65/765、在使用阿里云弹性伸缩( Auto Scaling)创建伸缩组之后,除地域属性之外,还有以下哪些属性不可以 修改?(正确答案的数量:2个 A、伸缩组名称 、负载均衡实例 RDS数据库实例 D、移出策略 提示:伸缩组名称是可以修改成其他名称,移出策略是可以修改为其他策略。 答案BC
3★66765、在阿里云的负载均衡SLB的管理控制台中,可以根据一些监控的统计指标来设置报警信息,常见的 如流量、数据包、连接数等,设置报警阈值,一旦触发了报警条件,就会通过多种方式进行报警。目前还不支 持 的报警方式 电话报警 B、邮件报警 C、短信报瞀 D、旺旺报警 提示:阿里云的负载均衡SLB的监控报警目前还不支持电话报警。开通云监控服务后,您可以在云监控控制台配 置监控报警规则。云监控支持“短信”、“邮件”、‘旺旺”三种报警方式,暂不支持电话报警。相关链接 答案A
1★67/765、用户A是公司的系统管理员,经常去上海出差,每当他在上海远程登录服务器时系统就会发出报警 信息,提示“有人异地登录,请注意服务器安全”通过 方法可以快速、自助解决这个问题。 A、立即提交工单,咨询阿里云工程师 B、向公司领导请求帮助 C、登录阿里云管理控制台,在安骑土配置项里填加“常用登录地点” D、向朋友电话求助,他是业界有名的黑客高手 提示题目中说的是系统管理员每次在上海出差时候远程登录服务器就会发出异地的报警信息,所以需要通过 控制台的添加“常用登录地点”来解决这个报警信息的问题 答案C
3★68765、阿里云对象存储OSS的存储空间 Bucket支持删除操作,在删除 Bucke前必须先删除 Bucket中的所有 文件,包括未完成的分片文件。 错 提示:删除 Bucket前,碎片文件也必须要一起删除。相关链接 答案:A
1★69/765、您希望基于已有的磁盘快照在青岛可用区A的云服务器ECS实例创建一个新的块存储磁盘,您可以 使用 快照创建该磁盘。 A、以上都不行 B、青岛可用区A的某个ECS实例的系统盘快照1 C、北京可用区A的某个ECS实例的数据盘快照 D、香港可用区A的某个FCS实例的数据盘快照 提示题目中要求的是在ECS上面新挂载一块数据盘,所以可以使用和它同一个可用区的非系统盘快照来创建。 所以三个选项都是不符合要求的。系统盘快照,不能用来作为创建新的数据盘。 答案:A
3★70765、阿里云内容分发网络CDN建立并覆盖在承载网之上,由分布在不同区域的边缘节点服务器群组成 的分布式网络替代传统以 WEB Server为中心的数据传输模式。用户使用阿里云CDN时 步骤是必须 的。(正确答案的数量:2个) A、手动刷新缓存 B、添加“加速域名” CNAME域名解析 D、CDN使用资源监控 提示:CDN快速入门操作流程1开通CDN服务2添加加速域名3.配置 CNAME相关链接 答案BC
2★71765、BGP(边界网关协议)主要用于互联网AS(自治系统)之间的互联,BGP的最主要功能在于控制路由的 传播和选择最好的路由,BGP线路可有效避免不同运营商之间网络访问慢的问题。 正确 B、错误 提示:边界网关协议,简称BGP,主要用于互联网AS(自治系统)之间的互联。BGP协议的最主要功能在于控 制路由的传播和选择最好的路由。使用BGP髙防可以解决跨运营商访问慢、部分小运营商访问不稳定的情况。 这个是文档的原话。 答案:A
3★72/765、当一个阿里云的云服务器ECS实例无法加入指定的安全组时,可能是 原因造成的 A、该云服务器ECS实例的状态为运行中 B、云服务器ECS实例创建之后默认已经加入一个安全组,不能再加入其它安全组 、本云服务器ECS实例目前已经加入的安全组数量达到上限 D、该云服务器ECS实例没有开启公网带宽,所以无法加入安全组 提示:每个ECS实例最多可以加入5个安全组,当超过5个了以后就无法继续加入其他安全组 答案:C
2★73765、D公司在线视频业务全国排名前五,整个业务系统全部建设在阿里云之上,使用的云产品有云服务 器ECS、对象存储OSS、内容分发网络CDN。最近发现有黑客恶意下载公司的正版视频,在国外社区里分 发。假设你是D公司的系统管理员,从技术上可以如何解决这个问题? A、启用阿里云CDN的IP黑名单功能 启用阿里云CDN的URL鉴权功能 C、启用阿里云OSS的Reer黑名单功能 D、启用云服务顺的安全组功能 提示:划重点:公司使用了CDN,黑客恶意下载公司的正版视频。所以需要对CDN的访问进行保护,但是题目 中并不知道黑客的具体IP或者某一段IP,知道具体IP的话可以直接把具体IP或者这段加入黑名单,所以只能 需要采用CDN的URL鉴权能防止在社区在分发的问题。 答案B
3★74765、您发现某台阿里云的云服务器ECS实例的磁盘上的数据被误删除,需要回滚到之前某个时刻的数 据,可以通过对该磁盘进行回滚操作来实现。登录到阿里云的管理控制台进行回滚操作时,您发现不能进行该 操作,可能是 原因造成的。(正确答案的数量:3个) A、云服务器ECS实例的状态为“运行中” B、云服务器ECS实例的状态为启动中 云服务器ECS实例的状态为“已过期 D、云服务器ECS实例的状态为“已停止 提示:回滚磁盘必须要求云盘必须已经挂载到某台ECS实例上,而且已经停止实例。所以不会是“已停止”的状 态造成的。 答案:ABC
3★75/765、在删除阿里云弹性伸缩( Auto Scaling)的伸缩组时有两种模式:强制删除和非强制删除。在非强制 删除模式下,必须满足以下哪两个条件才可以删除?(正确答案的数量:2个) A、伸缩组没有任何伸缩活动正在执行 B、伸缩组当前的ECS实例数量为0 C、伸缩组没有对应的定时任务以及报警任务 D、伸缩组没有和负载均衡SLB、云数据库RDS配合使用 提示:如果 Forcedelete属性为 false,必须满足以下两个条件,才能删除伸缩组:1.伸缩组没有任何伸缩活动正 在执行。2伸缩组当前的ECS实例数量( Total Capacity)为0。 答案:AB
1★76/765、实现PC中ECS服务器切换迁移到同VPC下的其他交换机,包括以下几步,请选择正确的顺序 1打开云服务器管理控制台;2找到对应的需要切换迁移的云服务器;3.选择您所需的交换机,同 时指定新交换机下的IP;4.修改云服务器的私网地址; A、1,2,3,4 B、1,2,4,3 C、1,3,2,4 D、1,3,4,2 提示: 答案B
2★7765、阿里云的云盾的安骑士提供了服务器密码暴力破解防护,用户再也不用设置难记的复杂密码了。 A、正确 错误 提示:云盾的安骑士暴力破解防护,但是用户仍然需要做好密码的妥善保管工作。 答案B
4★78/765、阿里云弹性伸缩( Auto scaling)中的伸缩组,是指具有相同应用场景的ECS实例集合。当用户创建 个伸缩组时需要包含以下哪些内容?(正确答案的数量:3个) 、伸缩规则 、伸缩活动 伸缩配置 D、伸缩触发任务 提示:伸缩组包含伸缩配置、伸缩规则、伸缩活动。相关链接 答案:ABC
4★79765、您在阿里云的 Windows系统的云服务器ECS实例中不建议删除或者重命名 administrator账户,如果 进行以上操作可能会引起在阿里云的管理控制台上修改密码失效 对 B、错 提示:对 administrator账户做了操作,如禁用、删除和改名等操作确实会导致在控制台修改ECS实例密码不成 功。相关链接 答案:A
1★80765、在使用阿里云云产品时,可以通过以下哪些方式来提供数据库服务??(正确答案的数量:4个) A、 Linux的环境安装包安装数据库 单独购买RDS数据库 使用镜像市场免费配置环境的数据库 D、 Windows的环境安裝包安装数据库 提示四种方式都是支持提供数据库的服务的。 答案:ABCD
2★81765、阿里云的云盾先知计划的目的是帮助企业建立私有的 中心,以较低的成本发现企业自 身企业的安全风险,并得到解决方案。 A、私有数据中心 B、应急响应中心 C、病毒防护中心 D、远程备份中心 提示:先知计划是一个帮助企业建立私有应急响应中心的平台(帮助企业收集漏洞信息)。 答案B
2★82/765、在服务器上手动安装阿里云的云盾客户端安骑上时需要 权限。 A、系统管理员权限 B、系统普通用户权限 C、FTP服务权限 D、数据库权限 提示在服务器上手动安装安骑士时需要管理员权限。相关链接 答案:A
3★83/765、您可以根据业务的需要,选择采用手动或者镜像的方式进行阿里云的云服务器ECS实例的使用环境 的部署。针对这两种部署方式,以下说法中正确的包括 。(正确答案的数量:3个) Δ、阿里云的云市场提供了丰富的镜像资源,大部分镜像都集成了操作系统和应用程序 B、在创建ECS实例时,可以选择云市场的镜像来快速获得所需的应用程序,无需自行安装,如PHP、 MySQL 等 、如果您需要个性化定制的运行环境,可以使用手动部署 D、如果您使用镜像市场的镜像来重新初始化ECS实例,可以通过更换系统盘来完成操作,同时数据盘的数据 也会受到影响 提示:更改系统盘操作,只会影响系统盘的数据,数据盘的数据不会受到任何影响。 答案:ABC
1★84765、交换机,是组成VPC网络的基础网络设备。它可以连接不同的云产品实例。在VPC网络内创建 云产品实例的时候,必须指定云产品实例所在的交换机。下面关于交换机说法错误的是? A、VPC的交换机,是一个3层交换机,不支持2层广播和组播; B、只有当ⅤPC的状态为 Available时,才能创建新的交换机; C、交换机不支持并行创建,一个交换机创建成功之后,才能够创建下一个; D、交换机创建完成之后,无法修改 CIDRBlock; E、删除交换机时,该交换机所连接的云产品实例也一同删除; 提示删除交换机之前,必须先删除目标交换机所连接的云产品实例。 答案:E
2★85765、您在原有的数据中心已经部署了部分应用,现在需要构建新的应用,但本地的数据中心内的物理 资源不够用,也没有办法进行扩容,使用以下哪些方案可以用于解决该问题?(正确答案的数量:3个) A、在阿里云上申请专有网络VPC服务,并基于VPC申请新的云服务资源,与您原有的数据中心使用相同的内 网地址网段 、通过专线打通原有数据中心与阿里云上的VPC,实现已有数据中心向云上的平滑迁移 、通过VPN打通原有数据中心与阿里云上的VPC,实现已有数据中心向云上的平滑迁移 D、直接申请阿里云的云服务器无需任何操作就可以与原有的数据中心内网打通,实现已有数据中心向云上的 平滑迁移 提示:无需任何操作是不会打通的。 答案:ABC
1★86/765、若您的阿里云的云服务器ECS的实例希望能够和 internet直接连通,就一定要开启公网带宽或者绑 定EIP。 B、错 提示因为题目是说需要直接连通,所以只能通过公网带宽或者EIP来实现。 答案:A
1★87765、阿里云CDN不仅支持图片和cs文件加速,还支持视频流媒体加速。 B、错 提示:阿里云CDN广泛应用于网站与应用加速、音视频点播、文件等场景,通过高性能缓存机制,提高访问效 率和资源可用性。符合题目的描述。相关链接 答案:A
1★88/765、某社交网站的整个平台基于阿里云的负载均衡SLB、云服务器ECS和云数据库RDS构建,原来只提 供wEB纯动态的文字信息交流。最近网络直播很流行,运营团队为了增加会员活跃度,也准备开设网络直播 业务,实现全国20万会员随时随地快速观看直播,预计同步在线人数3000。需要再开通阿里云的 品来支撑这个业务。(正确答案的数量:4个) A、高性能计算HPC( AliCloud hPc) B、弹性伸缩( Auto Scaling) 对像存储OSS D、媒体转码( Media Transcoding 内容分发网络CDN 提示:题目中要求创建是計¢网站,需要支持直播,所以需要媒体转码( Media Transcoding)服务;同时支持全 国的会员随时随地快速观看,所以需要用到对象存储OSS来保存直播视频内容且配合内容分发网络CDN实现全 国地区的加速观看。 答案BCDE
4★89/765、某互联网金融公司为了实现业务快速上线,系统快速部署,基于阿里云搭建I基础架构。由于其 业务特性,不定期会有理财套餐的秒杀、促销活动,为了能够应对更大、更具偶发性的业务压力,需要全面考 虑应用、数据库等层面的扩展,以下说法正确的是:(正确答案的数量:3个) A、使用SLB实现应用层的弹性扩展 使用DRDS实现数据库层的弹性扩展 使用弹性伸缩使云服务器轻松应对秒杀场景扩容 D、应用之间采用紧耦合架构 E、将系统搭建在同一地域有利于系统的弹性扩展 提示:应用层的弹性通过SLB后增加机器实现,DRDS就是数据库集群,可以实现数据库的弹性扩展(),应用 间应该釆用松耦合的架均提高系统的可跨展性,紧耦合不利于维护。弹性扩展和部署在同一地域没有关系, 多个地域也可以每个地域单独实现弹性拓展。相关链接 答案:ABC
3★90765、某视频公司,使用负载均衡SLB将用户的访问请求分发到20合云服务器ECS实例上,由这些配置相 同的ECS实例来响应用户的请求。春节将至,根据经验预估,假期期间业务量会增加一倍。可以使用阿里云弹 性伸缩( Auto Scaling)来满足资源的弹性变化的需求,由于可以准确的预测业务量变化情况,因此可以选择 多种伸缩模式来实现。以下说法正确的是?(正确答案的数量:3个) A、定时任务:在假期开始当天,增加ECS实例个数到40台,假期过后减少至20台 B、云监控报瞀任务:通过监控CPU、负载等,在资源紧张时动态增加FCS实例,在资源空闲时,减少ECS实 C、固定数量模式:从假期开始当天,设置伸缩组的最小实例数为40台,假期过后将该参数调至20合 健康模式:保持伸缩组中当前的所有的ECS实例能正常工作,以满足用户访问请求的响应 提示:题目考察的是选择哪种伸缩模式实现比较合理,并不是说单独需要什么模式来实现。划重点:由于可 以准确预测业务量变化情况。所以不需要动态增加机器,所以报警任务不会选。 答案:ACD
3★91/765、阿里云的负载均衡SLB提供对多台云服务器ECS实例进行流量分发的服务,对于公网的负载均衡 SLB实例,支持 两种付费模式。(正确答案的数量:2个) 按使用流量计费 按固定带宽计费 C、按后端服务器台数计费 D、按照后端服务器的计算能力计费 提示:SLB支持按使用流量或者按照固定宽带付费。 答案:AB
1★92/765、在 OSS AP中通过 参数的操作可以实现设置 object头? A、 Multipart Upload B、 Get Object C、 Get bucket Copy Object 提示: Copy object接口可以发送一个Put请求给OSS,并在Put请求 Header中添加元素x- oSS-copy-Source来指定源 Object 答案D
1★93/765、无论伸缩组内是否有伸缩活动,都可以停用伸缩组。 A、对 错 提示伸缩组里面有伸缩活动正在执行的时候,不可以停用伸缩组。强制停用可能会导致伸缩组伸缩异常。 答案B
5★94/765、您在通过 Open AP制作阿里云的云服务器ECS实例的自定义镜像的时候失败了,有可能是 原因引起的。(正确答案的数量:3个) 选择数据盘快照制作 B、选择系统盘快照制作 、没有设置自定义镜像的名称 D、没有设置自定义镜像的描述 提示:云服务器ECS实例的自定义镜像的时候失败了,因为自定义镜像本身就是用系统盘快照来制作的,所以不 会是选择系统盘快照制作导致的,可能是选择数据盘快照制作导致的,同时制作镜像时,自定义镜像的名称和 自定义镜像的描述都是必须的不可为空。 答案:ACD
1★95/765、使用了阿里云CDN后,如果缓存命中率比较低,可能的原因是(正确答案的数量:4 个) 、缓存配置不合理,针对某些文件设置较短,导致CDN节点频繁回源 Http Header设置导致无法缓存,需要用户检査源站的 Cache- Control设置或者 Expires的设置 源站动态资源较多,多为不可缓存的内容,也会导致频繁回源拉取 网站访问量较低,文件热度不够,CDN收到请求较少无法有效命中缓存 提示题目考察的是缓存命中率比较低的原因,相关链接 答案:ABCD
1★96/765、阿里云专有网络ⅴPC内部存在虚拟交换机和虚拟路由器,可以像传统网络环境一样划分子网,每 个子网内的云服务器ECS实例之间使用同一个虚拟交换机互联,不同子网间的ECS实例之间使用虚拟路由器互 B、错 提示:不同专有网络之间通过隧道ID进行隔离。专有网络内部由于交换机和路由器的存在,所以可以像传统网 络环境一样划分子网,每一个子网内部的不同云服务器使用同一个交换机互联,不同子网间使用路由器互联。 相关链接 答案:A
297765、阿里云的云盾的先知计划,是调动众多网络安全专家的力量一起维护互联网平台和业务的安全,降 低客户的安全损失。适合使用先知计划的用户包括 。(正确答案的数量:3个) A、网站曾经被入侵,导致数据被泄露或者业务被篡改,造成公关风险,影响了公司形象和业务,正在寻求互联 网安全解决方案 网站漏洞多次被曝光,被竞争对手恶意炒作,正在寻求互联网安全解决方案 、买了很多安全产品和设备,但还是出现被攻击和入侵的情况,正在寻求互联网安全解决方案 D、用户的业务全部部署在自己的局域网,在公共互联网上无法访问,正在寻求内网安全的解决方案 提示排除法,用户的业务全部部署在自己的局域网,则在公网无法访问,所以无法适用于先知的使用场景。 答案:ABC
4★98765、您在阿里云的帐号A下基于云服务器ECS实例搭建好了Web应用服务,如果需要在另一个阿里云的帐 号B中快速创建包含相同应用的云服务器ECS实例,可以通过方式最高效的实现 A、在帐号A中创建该云服务器ECS实例的自定义镜像,并将该镜像共享给帐号B,帐号B基于该共享镜像进行新 的云服务器ECS实例的创建 B、直接在帐号B中申请云服务器ECS实例并进行相同的web应用的部署 C、在帐号A中进行该云服务器ECS实例的快照创建,并将该快照共享给帐号B,基于该快照进行新的ECS实例的 创建 D、其他方式都不可以完成 提示:共享镜像可用于跨账号部署ECS实例。创建自定义镜像后,您可以将镜像共享给其他阿里云账号使用。该 账号可使用您共享的自定y竟像,快速创建运行同一镜像环境的ECS实例。相关链接 答案:A
3★99765、使用阿里云的负载均衡SLB实例时,通过会话保持可以实现与某个连接( Session)相关的所有应用 请求能够由同一台后端云服务器ECS实例进行处理。为了在七层协议转发中,实现基于 cookie的会话保持,阿里 云的负载均衡SLB提供了处理方式。(正确答案的数量:2个) 植入 、 Cookie重写 C、 Cookie跟踪 D、 Cookie校验 提示HTTP/Https监听可使用植入cookie和重写cookie来进行会话保持。相关链接 答案:AB
3★100/765、某公司使用阿里云产品作为企业门户网站的解决方案,通过负载均衡SLB服务转发客户请求到后端 的云服务器ECS实例中去处理。目前他们要在网站中新增加一个库存查询的功能,需要访问云数据库RDS实例, 他们的方案是:把RDS实例挂到SLB实例的后端服务器池中,在现有的SLB实例上多配置一个监听( Listener) 专门负责监听库存查询的需求,然后把需求分发给RDS实例处理。 A、对 B、错 提示:负载均衡SLB只支持负载ECS,其他云产品都不支持负载。更不支持在SLB实例上多配置监听以及给RDS分 发请求。 答案B
5★101/765、您将业务部署在阿里云上时,可以通过将业务的模块进行拆分、采用多个低配置的云服务ECS实例 结合负载均衡SLB的方案,来提高业务的整体可用性。 对 B、错 提示:这个是上云实践中的描述,可以将业务拆分为多个模块,在多个低配置的云服务ECS实例结合负载均衡SLB 的方案,来实践业务的高可用。 答案:A
3★102765、阿里云弹性伸缩( Auto Scaling)中,伸缩组是一组部署了相同应用的云服务器ECS实例的集合。以下 关于伸缩组的说法中正确的是? 当伸缩组对应的伸缩规则的条件触发后,弹性伸缩会根据设定的伸缩规则添加或者减少伸缩组中的云服务器 ECS实例 B、伸缩组是云服务器ECS实例的资源池,当实际应用中需要添加计算资源时,会从伸缩组中获取可用的ECS实 例,添加到应用中去 C、伸缩组是云服务器ECS实例的资源池,弹性伸缩会预先创建一定数量的云服务器ECS实例放在伸缩组中 D、伸缩组是监控的目标,其中的云服务器ECS实例,必须是由阿里云弹性伸缩基于相同的镜像自动创建的 提示:阿里云弹性伸缩( Auto Scaling)的基础知识。服务器ECS实例可以是自己创建,也可以自动添加闲置的云 服务器ECS资源。 答案:A
3★103/765、阿里云对象存储OSS是阿里云提供的海量、安全、低成本、高可靠的云存储服务。在OSS里存储文 件前首先要创建一个存储空间 Bucket,之后才能在 Bucket中进行文件的上传和管理。以下有关 Bucket的描述中正 确的包括 (正确答案的数量:3个) 、同一个 Bucke内部的空间是扁平的,所有的对象都是直接隶属于其对应的 Bucket 、每个用户可以拥有多个 Bucket 、 Bucket的名称在OSS范围内必须是全局唯一的,一旦创建之后无法修改 D、 Bucket在创建时需要指定容量上限 提示 Bucke容量是没有上限的,所以无需在创建时指定。 答案ABC
3★104/765、当您发现无法将指定的阿里云的块存储挂载到某台的云服务器ECS实例上时,可能是 原因 造成的。(正确答案的数量:2个) 云服务器ECS实例已经挂载的数据盘数量达到上限 购买的块存储和云服务器ECS实例不在同一个可用区 C、云服务器ECS实例处于已停止状态 D、云服务器ECS实例没有公网PP 提示:题目中所说的是无法将数据盘挂载到ECS上面,请分析一下原因。分析一下挂载云盘的注意事项:,发现 台ECS实例最多能挂载16块云盘作数据盘用,且云盘只能挂载到同一地域下同一可用区内的实例上,不能跨可 用区挂载。相关链接 答案:AB
4★105/765、您需要在阿里云上创建云服务器ECS实例, 因素可能导致您创建的云服务器ECS实例的所 产生的费用不同。(正确答案的数量:4个) 云服务器ECS实例的地域 B、云服务器ECS实例的付费模式 、云服务器ECS实例的镜像类型 D、将要部署在云服务器ECS实例上的应用不同 、云服务器ECS实例的公网带宽不同 提示服务器ECS实例上的应用不同不会影响到ECS的定价 答案:ABCE
2★106/765、您通过阿里云的云监控服务为某台云服务器ECS实例的磁盘使用率设置了1条报瞀规则:统计周期 为5分钟,磁盘使用率平均值超过80%,连续探测5次超过阈值后就报警。如果您的磁盘平均使用率超过80%后, 至少需要几分钟后可以收到报警? A、0分钟 B、30分钟 C、40分钟 D、20分钟 提示连续五次超过阈值就报警,问的是最少的时间。所以可以假设刚启动云监控就开始第一次探测超过阈值。 所以后面一共只需要四个探测周期就可以报警了。所以时间为5分钟*次=20分钟。 答案D
3★107/765、某O20网站基于阿里云的云服务器ECS、负载均衡SLB以及弹性伸缩( Auto Scaling)搭建了线上 系统,其中ECS用来处理用户响应,SLB用来分发流量,弹性伸缩负责动态分配资源以满足突发的业务变化,三 个产品配合可以提供稳定、便捷、低成本的服务。现在想要增加云数据库RDS到该架构中来,用来保存用户访问 时产生的数据。以下说法中正确的是? A、如果在伸缩组中指定了RDS实例,则弹性伸缩会自动把伸缩组中的ECS实例的P地址添加到RDS的白名单中 去,无需手工设置 B、可以把RDS实例直接挂在SLB下,由SLB按照转发规则分配任务到RDS实例进行处理 C、可以把RDS实例手工添加到伸缩组,RDS实例可以保存用户访问的数据 D、对RDS实例所在的地域( Region)没有硬性规定,但是建议和弹性伸缩在同一个地域,可以减小网络传输的 延迟,提升响应速度 提示弹性伸缩( Auto scan.g)与SLB/RDS紧密集成,可以自动管理SLB后端服务器和RDS白名单,节省操作成 本。参考弹性伸缩产品优势链接:相关链接 答案:A
5★108/765、您在阿里云的云服务器ECS实例的使用中,要创建新的安全组规则时,不可以规定 类型的 授权。 A、IP授权 B、端口授权 C、MAC授权 D、安全组授权 提示:安全组规则是不支持MAC授权的。 答案C
3★109765、阿里云弹性伸缩( Auto Scaling)是根据用户的业务需求和策略,自动调整其弹性计算资源的管理服 务。为了在弹性伸缩创建的ECS实例中可以直接正常处理用户请求,无需任何额外的系统调度和配置,弹性伸缩 的云服务器ECS实例中部署的应用必须满足 A、无状态且可横向扩展的 B、有状态 C、无状态且符合幂等性的 D、所有数据保存在ECS实例磁盘上 提示:弹性伸缩主要是ECS的横向伸缩,同时也是服务的横向伸缩,弹性伸缩要求每台ECS是无状态的,否则不能 保证数据的统一。相关链接 答案A
4★110765、阿里云负载均衡SLB实例中的后端服务器ECS实例需要设置权重,可以给对外服务能力更强的ECS 实例设置更大的权重,这些ECS实例就会有机会处理更多的访问请求。在提供稳定服务的同时,充分的利用了已 有资源。如果将一台ECS实例的权重设置为0,以下说法正确的是。 A、该ECS实例不会再得到负载均衡SLB实例分发的外部访问请求 B、所有外部访问请求都被分发到这台ECS实例上 C、该ECS实例会被认为状态异常,负载均衡SLB会把它移出后端服务器池 D、负载均衡SLB会分发外部请求给这台ECS实例,分发量的大小等于总请求数除以后端服务器ECS实例个数 提示将负载均衡后端ECS的权重置零,新发起的业务请求是无法经负载均衡转发到该服务器的,健康检查相应 的会显示异常。所以该ECS实例不会再得到负载均衡SLB实例分发的外部访问请求。相关链接 答案:A
4★11/765、云产品的可用区指的是一套独立的基础设施,不同的可用区之间基础设施(网络,电力和空调等 相互独立,即一个可用区出现基础设施故障不影响另外一个可用区。下列关于阿里云ECS的可用区说法正确的 是 可用区是在用户购买时指定的,购买后不支持更改 B、可用区之间内网互通 C、可用区内网络延时最高不超过1s D、若要提高应用的容灾能力则可以将实例创建在同一可用区 提示:只有在同一个地域前提下,可用区之间的内网才是互通的。可用区是指在同一地域内,电力和网络互相独 立的物理区域。所以云产品一旦购买了,不支持更改可用区。 答案:A
1★112765、中国大陆范围内的网站都需要做CP备案,在架构设计时应该告诉客户提前就需要准备提 交备案? 网站上线前一天 B、网站上线当天 C、网站上线前一周 、网站上线前一个月 提示:为了保证网站能按时上线,需要在网站上线前一个月提交备案资料,保证留有充足的备案时间来完成备案 操作。 答案D
4★113/765、ECS服务器会对每个访问的请求进行身份验证,以下哪一个是用于标识访问者身份的? A、 Access Key Secret B、 RequestId Access Key Id D、 User name 提示注意不是 Access Key Secret, Access Key Secret是用来鉴权校验的, Access Key Id是用来区分用户的。阿里 云 access key ID和 access key secret是您访问阿里云AP的唯一凭证。 Access key D是类似身份的标识,而 access key secret的作用是签名您的访问参数,以防被篡改。 Access key secret类似您的登录密码,不要向任何人泄漏。 相关链接 答案:C
1★114765、如果用户需要创建SB实例,为了能够真正的实现应用的负载分担,那么要保证至少要有 个ECS实例? A、5个 B、2个 C、3个 D、1个 提示:因为题目中强调了需要真正实现负载的分担,所以至少需要两台ECS配合才能实现。 答案B
3★15765、云计算一个重要特点是弹性,阿里云的用户可以根据业务需求和策略实现计算资源的自动调整。在 业务量高峰时增加ECS实例来提升系统的处理能力,在业务量低谷时自动减少ECS实例以节约成本。针对此场 景,阿里云的 产品可以和云服务器ECS实例配合使用实现弹性计算。 A、云数据库RDS B、负载均衡SLB C、弹性伸缩 Auto Scaling D、专有网络ⅤPC 提示:题目中说需要自动根还有业务量来自动调节ECS实例的数目,所以需要选择弹性伸缩 Auto Scaling 答案:C
1★116765、以下哪些状态属于ECS生命周期中的稳定状态?(正确答案的数量:3个) 、运行中 B、已停止 、已过期 D、停止中 提示:稳定状态为已停止,运行中,停止中和创建中均为中间状态,特别注意运行中是稳定状态而非中间状态。 答案:ABC
1★117765、阿里云的负载均衡SLB中的证书( Certificate)用于 Https协议,在需要使用加密协议时,用户可 以将证书上传至负载均衡SLB实例中,在创建 Https协议监听时绑定证书,提供 Https服务。目前阿里云的负 载均衡SLB只支持 格式的证书。 、PEM B、P7B C、PFX D、DER 提示:负载均衡只支持PEM格式的证书。相关链接 答案:A
3★18765、使用阿里云弹性伸缩( Auto Scaling)来实现计算资源的弹性配置时,做了如下设置:伸缩组的属性中 设置 Min size=6, MaxSize=8,伸缩规则为“减少5台ECS”,伸缩配置也进行了正常的配置。该伸缩组当前的云服 务器ECS实例数为8台,通过设置定时任务来执行,执行一次后,会减少 云服务器ECS实例。 A、1 B、2台 C、0台 D、5 提示 Min size=6,8-6=2 答案B
1★119765、阿里云弹性伸缩( Auto Scaling)经常会和云服务器ECS、负载均衡SLB、云数据库RDS等产品配合 使用,以下说法中正确的是 Δ、弹性伸缩必须和云服务器ECS一起使用 B、弹性伸缩可以单独使用,不依赖于其他任何产品 C、弹性伸缩必须和云数据库RDS一起使用 D、弹性伸缩必须和负载均衡SLB一起使用 提示:此题有争议,之前的答案是可以单独使用,我上机测试,ECS最小为1,故修改答案必须和ECS一起使用 答案:A
3★120765、阿里云弹性伸缩( Auto scaling)的冷却时间是指在同一个伸缩组内,当有一个伸缩活动被成功执行后 的一段锁定时间内,该伸缩组不执行其他的伸缩活动。以下关于冷却时间的开始计时的时间点的说法正确的是? A、当伸缩组加入或移出多个ECS实例时,最后一个ECS实例加入或移出完成后,整个伸缩组冷却时间开始计时 B、当伸缩组加入或移出多个ECS实例时,第一个ECS实例加入或移出完成后,整个伸缩组冷却时间开始计时 C、伸缩活动结束后,冷却时间马上开始计时 D、伸缩活动开始后,冷却时间马上开始计时 提示:伸缩活动中,最后一个ECS实例加入或移出完成后,整个伸缩组冷却时间才开始计时 答案:A
3★121/765、阿里云对象存储OSS是阿里云对外提供的海量、安全、低成本,高可靠的云存储服务。除了基本的 存储功能外,OSS还提供了强大的图片处理能力,可根据实际业务需要对图片进行加工和转换。OSS的图片处理 能力包括 (正确答案的数量:3个 图片缩放、添加水印 图片格式转换(例如:由jpg转换成png 图片360度范围内旋转 D、OCR文字识别(将图片中的文字直接转成文本) 提示:OSS目前不具备OCR文字识别的处理能力。 答案:ABC
1★122/765、对安全组的操作调整,对用户的服务连续性没有影响 B、错 提示:对安全组的调整操作,对用户的服务连续性没有影响。这个是文档的原话,解释就是:用户操作了安全 组,可能会导致请求访问ECS失败,但是并不会影响到ECS上面服务的运行。 答案:A
2★123/765、阿里云内容分发网络CDN建立并覆盖在承载网之上,由分布在不同区域的边缘节点服务器群组成的 分布式网络替代传统以 WEB Server为中心的数据传输模式。如果用户在使用CDN的过程中发现CDN缓存的”命 中率“比较低,可能的原因是 。(正确答案的数量:4个) A、网站访问量较低,文件热度不够,CDN收到请求较少无法有效命中缓存 B、缓存配置不合理,针对某些文件设置较短,导致CDN节点频繁回源 Http Header设置导致无法缓存,需要用户检查源站的 Cache- Control设置或者 Expires的设置 D、源站动态资源较多,多为不可缓存的内容,也会导致频繁回源拉取 E、开通CDN时选择的带宽不足,服务能力已达到上限 提示:排除法,CDN是按照按每日带宽峰值计费,所以不存在带宽不足,服务能力达上限的问题 答案:ABCD
2★124/765、阿里云对象存储OSS的图片处理服务中,所有对图片的转换参数都会加在图片文件的URL后面,使 URL变得冗长,不方便管理与阅读。为了简化操作,OSS图片处理服务提供了 功能,可以将常见的转换 参数保存起来多次使用。 A、样式 B、方案 C、短网址 D、管道 提示:相关链接 答案:A
3★125/765、针对阿里云专有网络VPC内的云服务器ECS实例,可以通过安全组来进行ECS实例的访问控制配 置。以下说法中正确的是。 A、一个安全组中可以包含同一个可用区的不同ⅤPC里的云服务器ECS实例 B、一个安全组中可以包含同一个地域的不同VPC里的云服务器ECS实例 C、一个安全组中仅可以包含同一个可用区的同一个VPC内的云服务器ECS实例 D、一个安全组中可以包含同一个地域的同一个专有网络VPC内的云服务器ECS实例 提示:专有网络VPC里面的交换机支持部署在同一地域的不同可用区,专有网络ⅤPC类型的实例可以加入同一专 有网络(VPC)下的安全组 答案D
3★126/765、阿里云官网有很多阿里云内容分发网络CDN与其它云产品组合的方案与业务场景供用户参考。以 下选项中场景适合使用阿里云内容分发网络CDN。(正确答案的数量:3个 A、日访问次数低于100的BBS论坛 日访问次数大于10万次的阿里云虚拟主机纯静态站点 某中型电商类网站中的图片、html、css、js文件 D、新闻门户网站,日访问人数超过3000万次,用户遍布全国各地 提示:日均低于100的访问次数,不适合用CDN,因为热点不够,可能不足够形成CDN热点文件。同时从成本出发 也不适合使用。 答案BCD
3★127/765、阿里云的云盾态势感知用大数据分析技术,按攻击者的视角来建立安全防御体系,颠覆了传统单 的入侵和漏洞检测,让用户对安全可见、可控、可管”。以下关于态势感知功能的描述错误的是。 A、可以发现 webshell,恶意病毒攻击 B、利用大数据,可对高级攻击者使用的oday漏洞攻击进行防御 C、实时捕捉云服务器ECS实例中的网络连接,利用情报信息做异常识别,发现僵尸网络 D、是一个针对阿里云服务器ECS的托管服务 提示:态势感知是对云上资产的诊断服务,服务器安全托管服务才是对ECS的托管。相关链接 答案D
3★128765、某新媒体公司通过手机APP提供新闻资讯服务,采用阿里云弹性伸缩( Auto Scaling)来实现动态 添加或者减少云服务器ECS实例,来应对业务量的变化。该公司的业务人员和技术人员相互配合,估算出他们所 需要的资源为闲时10台ECS,但是有几个时间段业务量会比较多,基本上集中在7:30到9:00,18:30到20:00,随 着时间点的不同,所需的ECS实例在10到20个之间动态变化。他们在伸缩组中将最小实例个数设置为10,最大实 例个数设置为20。从容易部署以及节省成本的角度来考虑,他们还需要配置一个什么模式的任务? A、动态模式 B、定时模式 C、固定数量模式 D、lazy模式 提示题目中说了,ECS在这發时间内是动态变化的,以及要从节省成本的角度出发,定时任务一下子从10台增 加到20台,这样虽然满足业务要求但是成本增加了,所以选择动态任务既可以满足要求还可以根据需求适当扩展 ECS减少成本。 答案:A
1★129765、如果您不再需要某个阿里云的按量付费的云服务器ECS实例,可以将其释放。关于按量付费的实例 释放的操作中,错误的是 A、您可以再次设置自动释放的时间并覆盖前一次的设置 B、通过定时释放设置为您的按量付费实例安排释放计划,选择一个未来的时间释放资源 C、不可以随时释放按量付费的实例 D、可以立即释放该按量付费的实例 提示:自动释放时间可以多次设置,且随时可以取消之前的设置,实现随时释放按量付费的实例。 答案:C
3★130/765、阿里云的云监控( CloudMonitor)是一项针对云资源和互联网应用进行监控的服务。云监控服务 当前提供 功能。(正确答案的数量:4个) A、站点监控 、云服务监控 C、自定义监控 报警服务 E、自定义防火墙 提示:云监控包含了主机监控,自定义监控,站点监控,云服务监控,报瞀服务。相关链接 答案:ABCD
2★131/765、某大型购物商城新上了一套视频监控系统,在商城所在一个5层高的大楼里共安装了35个高清摄像 头,用于监控主要的出口通道。该系统的应用部署在一台阿里云的云服务器ECS实例上,该ECS实例上挂了4块 2T的数据盘来存储视频数据。上线后一周后发现视频数据的增速过快,预计8T硬盘不出1个月就会用完。您认 为使用阿里云的 产品可以最好地解决该客户的存储问题,同时在需要的时候快速读取到历史的视频数 据 A、归档存储( Archive Storage) B、多台云服务器ECS C、对象存储OSS D、内容分发网络CDN 提示:题目中要求需要解决类据增长过快的问题,需要可以通过将视频文件存储到OSS中来解决问题,因为OSS没 有空间上限,不需要担心曾长过快的问题,同时还可以满足快速读取的要求。(归档存储无法快速读取数据) 答案:C
3★132/765、阿里云的云盾的先知计划,是调动众多网络安全专家的力量一起维护互联网平台和业务的安全,降 低客户的安全损失。先知计划为企业提供的是 服务。 为企业收集情报(漏洞」 B、为企业保障服务器安全 C、为企业保障网络安全 D、用大数据的方式为企业进行安全分析 提示:先知(安全众测)是一个帮助企业建立私有应急响应中心的平台(帮助企业收集漏洞信息),尽早发现存 在的漏洞可以有效地减少企业可能的损失。相关链接 答案:A
1★133765、阿里云的云服务器ECS拥有与传统服务器和虚拟主机无法企及的优势。阿里云基于基于边界网管协 议( Border gateway Protocol,BGP)的最优路由算法提供多线接入。以下关于云服务器ECS的多线BGP接入说 法正确的是。(正确答案的数量:3个) A、阿里云在骨干机房有出口带宽大和云服务器独享的出口带宽的特点 B、多线接入与云服务的质量无关 通过BGP多线机房,实现全国访问流畅均衡 D、通过多线接入可以实现更高的云服务质量 提示:多线接入与云服务的质量是有关系的。 答案:ACD
★134/765、经典网络的内网网段不支持用户自定义,专有网络用户可自定义内网网段。 对 B、错 提示:经典网络的都是随系统分配,不支持用户自定义网段。ⅤPC网络可以支持用户自由定义网络,按需配置 网络,可自定义P地址范围与路由表等。 答案:A
3★135/765、在创建阿里云的云产品实例时,可以选择默认类型的专有网络VPC和交换机,这两项配置确定了专 有网络类型的云产品创建时在相应地域和可用区下唯一的默认网络位置,与非默认的专有网络和交换机之间的区 别主要在于默认类型的VPC和交换机只能由阿里云为您创建。下列关于默认交换机的描述错误的是 A、默认交换机只能创建在默认专有网络中 B、如果您有已经创建的专有网络vPC和交换机,在创建专有网络VPC类型的云产品实例时,云产品实例就不会 创建在默认交换机中 C、默认交换机与非默认交换机支持相同操作方式,且规格限制一致 D、默认交换机由阿里云为您创建,您自行创建的均为非默认交换机 提示默认专有网络与非默认专有网络的操作方式与规格限制一致。相关链接 答案B
3★136/765、您开通了阿里云的云服务器ECS实例之后,可以免费开通云盾的安全能力对您的云服务器 ECS实例的安全进行保护。(正确答案的数量:3个) 、DDoS基础防护 B、内容安全 、安骑士 D、服务器安全托管 提示服务器安全托管不属于云盾功能,而是属于安全管家的服务。 答案:ABC
3★137765、阿里云弹性伸缩( Auto Scaling)提供了“弹性自愈”功能,能保持伸缩组中的云服务器ECS实例都 处在正常状态,从而使业务始终保持正常的负载,提高系统的稳定性。关于“弹性自愈”,以下说法中正确的是? A、如果伸缩组中某台ECS实例状态不是运行中,则该ECS实例会被移出伸缩组,同时自动创建一台新的ECS实 例,添加到伸缩组中来 B、如果伸缩组中某台ECS实例的状态不是运行中,阿里云弹性伸缩会启动ECS实例的故障检查与修复进程,对 ECS实例进行自动修复 C、如果伸缩组中某台ECS实例状态不是运行中,阿里云弹性伸缩首先会自动重启该ECS,重启成功后继续保持 在伸缩组中,如果重启失败,则从伸缩组中移除,同时创建新的ECS实例键入到伸缩组中来 D、如果伸缩组中某台ECS实例状态不是运行中,阿里云弹性伸缩首先会自动重启该ECS,重启成功后继续保持 在伸缩组中,如果重启失败则会使用指定的镜像恢复该ECS实例到初始状态,继续保持在伸缩组中 提示弹性自愈即当检测某台ECS实例处于不健康状态时。弹性伸缩自动释放不健康ECS实例并创建新的ECS实 例,自动添加新ECS实例到负载均衡实例和RDS实例的访问白名单中。最后的介绍。相关链接 答案:A
3★138/765、某企业利用某公共云服务,租用了若干台虚拟机,并把这些虚拟机放在一个隔离的虚拟网络中,可 以完全掌控自己的虚拟网络,包括选择自有I地址范围、划分网段、配置路由表和网关等,这个虚拟网络在公 共云服务中通常称作 A、SDN服务 B、NFV服务 C、VPC服务 D、VPN服务 提示题目中说需要构建隔离的虚拟网络,所以需要用到阿里云专用网络VPC服务。 答案:C
3★139765、阿里云弹性伸缩( Auto scaling),是根据用户的业务需求和策略,自动调整其弹性计算资源的管理服 务。支持用户添加已有的云服务器ECS实例,但该云服务器ECS实例的状态必须为 运行中 B、已创建 C、已停止 D、准备中 提示弹性伸缩手动添加ECS,ECS的状态必须为运行中。 答案:A
1★140765、下列哪种 状态表示负载均衡SLB后端服务器的状态表示未开启SLB健康检查? 、 unavailable B、 available C、 abnormal D、 normal 提示:负载均衡SLB后端服务器的状态为 unavailable的时候表示其未开启健康检查,相关链接 答案:A
1★141/765、以下是ECS实例数据盘挂载点的是 ?(正确答案的数量:3个) 、/dev/xvdz B、/dev/xvdd C、/dev/xvda D、/dev/xvdb 提示:正常情况下用 fdisk-l命令,可以査看到新增的硬盘。/dev/xvda为系统盘,/ dev/]vdb dev/xdc./ dev/xvdz都是 数据盘。所以/ dev/avda为系统盘不会选择。 答案:ABD
3★14/765、阿里云对象存储OSS提供了海量的文件存储能力,对于文件管理除了支持简单上传、断点续传和大 文件分片上传功能外,还提供了多种删除文件的功能。如果需要删除的 Object数目很多,而且删除的 Object是有 定的规律,比如定期删除某些天之前的 Object,或者干脆是要清空整个 Bucket,特别适合使用哪个功能来完 成? A、管理控制台逐个删除 B、管理控制台批量删除 生命周期管理 D、通过 OpenAPI逐个删除 提示:题目中说需要比如定期删除某些天之前的 Object,所以可以通过生命周期管理来管理最合适。 答案:C
3★143/765、路由表是阿里云专有网络VPC路由器上管理路由条目的列表,路由条目定义了通向指定目标网段的 网络流量的下一跳地址。路由表支持通过方式进行配置。(正确答案的数量:2个) A、远程登录到路由器进行控制 B、专有网络PC的管理控制 C、进入机房直接对路由器进行控制 、阿里云VPC的 OpenAPI 提示:您可以通过专有网络VPC的管理控制台以及专有网络VPC的相关路由表接囗来管理配置路由表,相关链接 答案BD
1★144/765、当云服务器ECS实例选择了 Centos系统时,本地为 Windows操作系统,采用 方式无法正 确的登录该ECS实例 A、阿里云管理控制台 B、 SecurecrT C、 Putty D、 Windows自带的远程桌面客户端 提示: Windows自带的远程桌面客户端只能连接 Windows系统的远程界面,不能连接 Centos系统( Linux系统)。 答案D
★145/765、下列 参数代表的是负载均衡SLB实例的唯一标识? 、 LoadBalancerld B、 RegionId C、 Address D、 LoadBalancername 提示:负载均衡实例即 Loadbalancerld是来区分不同负载均衡SLB实例的唯一标识 答案:A
2★146/765、关于阿里云的云盾DDoS高防IP服务支持的“线路类型说法正确的是 A、仅支持BGP+电信 B、仅支持电信+联通 C、仅支持联通+BPG+电信 D、仅支持电信+联通+BGP+HK线路 提示: 答案D
5★147/765、您启动了一台新的阿里云的云服务器ECS实例,要求此实例只允许开放80端口的公网访问。可以通 过以下哪个操作来实现此要求而不影响其它实例? A、在该实例所在的默认安全组添加一条公网访问规则仅允许80端口的公网入流量 B、在该实例所在的默认安全组添加一条公网访问规则仅允许80端口的公网出访问,并添加一条公网访问规则不 允许所有的公网出流量 C、新建一个安全组,并新增一条安全组规则允许80端口的公网入流量,将该云服务器实例放入该安全组 D、新建一个安全组,并新增一条安全组规则允许80端口的公网入流量,将该云服务器实例放入该安全组,并从 原先的默认安全组挪出 提示题目中要求ECS实例只允许开放80端口的公网访问,所以需要新增安全组规则,允许80端口的公网入方向 访问,将实例加入该组为了不影响其他实例,并将其从原先的默认安全组移出。 答案D
4★148/765、对阿里云的云服务器ECS实例进行停止操作之后,ECS实例将停止工作,从而中断您的业务,需谨 慎执行。由于停止操作之后ECS实例处于停止状态,阿里云将不再对该ECS实例进行收费。 A、对 B、错 提示:停机不收费仅面向于按量付费的ECS,包年包月的ECS关机仍然继续收费,只有在ECS实例到期后才不继续 收费。 答案B
4★149765、关于阿里云的云服务器ECS实例是否支持安装虚拟化程序的说法正确的包括 。(正确答案 的数量:2个) A、云服务器巸CS实例是基于虚拟化平台运行的,不支持部署虚拟化程序 B、可以在云服务器ECS实例中部署虚拟化程序,阿里云提供相应的技术支持 C、如果在云服务器ECS实例中部署虚拟化程序,会导致服务器出现不可预测的问题 D、如果在云服务器ECS实例中部署虚拟化程序,服务器出现的问题是可以预测的 提示]如果在云服务器ECS实例中部署虚拟化程序,服务器出现的问题是不可预测的。阿里云强烈不建议在云服 务器ECS实例中部署虚拟化程序,这样会导致云服务器ECS出现不可预测的问题。 答案:AC
3★150765、阿里云OSS图片处理服务( Image Service,简称IMG),阿里云OSS图片处理服务有哪些性能? (正确答案的数量:3个) 、海量图片处理 B、无成本 C、通过简单的 RESTful接口对图片进行处理 、可靠性高 提示OSS的图片处理为收费服务。所以是需要成本的。相关链接 答案:ACD
1★151765、阿里云的负载均衡SLB可以把用户请求分发给后端的云服务器ECS实例,这些云服务器ECS实例的 规格配置必须相同。 A 对错 提示:负载均衡SLB后端的ECS实例的规格可以不同,用户只要确保后端ECS实例中的应用服务部署相同且数据一 致即可。相关链接 答案B
2★152/765、阿里云的云盾加密服务采用 机制来保证密钥的安全。 、符合国家密码管理局要求的算法 B、符合银监会对密钥强度的要求 C、防篡改硬件密码机 D、国际通用密码算法 提示:加密服务是云上的数据安全加密解决方案。服务底层使用经国家密码管理局检测认证的硬件密码机。密码 机的关键还是加密算法,题目主要问的是机制,所以选择国家密码管理局检测认证的加密算法。 答案:A
4★153765、以下 安全功能需要单独购买,不是在创建阿里云的云服务器ECS实例的同时可以免费获得 的 A、基础DDoS防护 B、木马查杀 C、防暴力破解 、DDoS高防IP 提示DDoS高防P是需要付费购买的功能。基础DDoS防护是可以免费开通的。 答案D
2★154/765、如果阿里云上的用户拥有多台云服务器ECS实例,且没有专业的运维团队或者不愿意在运维上花精 力,可以开通阿里云的云盾安骑上,提供专家人工安全体检、清除木马、系统加固、人工安全技术支持、托管服 务报告。 A、正确 B、错误 提示:安骑士不提供人工安全技术支持、托管服务报告的服务,需要人工安全技术支持、托管服务报告的服务需 要选用安全管家服务。 答案B
1★155/765、对于阿里云态势感知典型的功能点描述正确的是 A、恶意进程查杀 B、漏洞检测和修复 C、外部风险扫描:如AK泄露、账密泄露 D、全量安全日志,自动化入侵回溯 E、其它选项都正确 提示:文档原文:态势感知具备异常登录检测、网站后门査杀、网站后门査杀、进程异常行为、敏感文件篡改、 异常网络连接、Liux软件漏洞、 Windows系统漏洞、 Web-CMS漏洞、应急漏洞、web漏洞扫描、主机基线、 云产品基线、资产指纹、AK和账号密码泄露、数据大屏、日志检索、全量日志分析。相关链接 答案E
★156/765、PFX是使用二进制的格式保存的个人证书,一般出现在 Windows server中,现在想把该格式的证书 上传到阿里云的负载均衡SLB实例,以下说法正确的是 A、负载均衡SLB不支持PFX格式的证书,只能先将其转换成PEM格式,再上传 B、负载均衡SLB支持PFX格式的证书,可以将其直接上传 C、负载均衡SLB不支持PFX格式的证书,只能先将其转换成DBR格式,再上传 D、负载均衡SLB不支持PFX格式的证书,只能先将其转换成P7B格式,再上传 提示:负载均衡只支持PEM格式的证书。假如是PFX格式或其他部分格式,需要现将其转换成PEM格式再上传。 相关链接 答案:A
3★157/765、用户通过网络使用软件,无需购买软硬件、建设机房等,而改用向提供商租用基于web的软件,来 管理企业经营活动,且无需对软件进行维护,服务提供商会全权管理和维护软件。这种模式是云计算提供的 服务。 、SaS(软件即服务) B、PaS(平台即服务) C、IaS(基础设施即服务) D、DaS(数据即服务) 提示:题目中说了是基于web的软件,消费者只需要通过网络使用软件,不需要管理和维护软件,所以选择 SaS(软件即服务)。 答案:A
1★158/765、您的两台阿里云的云服务器ECS实例之间内网不能通信,一定不是由于 原因引起的。 A、两台云服务器实例在不同地域 B、其中一台云服务器ECS实例修改过私网P C、两台ECS实例在同一个账号下,同一个地域的不同可用区 D、两个云服务器ECS实例在不同的安全组 提示两台云服务器ECS实例之间内网不能通信,题目中问的一定不是什么原因导致的,所以在同一账号的同 地域是不会导致云服务器ECS实例之间内网不能通信的。 答案:C
1.当ECS或SLB实例遭到DDoS攻击,DDoS攻击的流量超过对应的黑洞阈值后,该公网ip将被黑洞,所有来自外部的流量都将被丢弃,导致相关的业务无法正常访问。
2.在四层TCp协议服务中,当前不支持后端云服务器的ECS既作为RealServer,又作为客户端所在的负载均衡实例发送请求。因为,返回的数据包只在云服务器内部转发,不经过负载均衡,所以在负载均衡实例的后端ECS上去访问的负载均衡的服务地址是不通的
3.OSS的分享文件使用的是HTTP应用层(7层)的协议。
4.负载均衡SLB实例和后端云服务器ECS实例之间是通过内网通信的。
5.DDoS基础防护只能防护5GB以下的DDOS攻击,超过5GB的DDoS攻击需要用到DDoS高防IP。
6.PPPoE是很老的拨号协议,阿里云负载均衡SLB不支持此协议
7.四层服务的会话保持是基于源IP实现的,七层服务的会话保持是基于Cookie实现的。
8.云盾DDoS基础防护服务具有以下功能优势: 优质的防护线路 受到DDoS攻击不会影响访问速度;带宽充足,不会被其他用户连带影响;优质带宽保证业务可用和稳定。 精准防护 精准识别攻击,秒级开启防护;自研清洗设备和算法,保证极低误杀;单点多点清洗不会相互影响。 免安装免维护 无需采购昂贵清洗设备;自动为云上客户开通,免安装;智能业务学习和配置防护规则。 免费 基础DDoS防护免费;阿里云用户免费加入安全信誉防护联盟。
9.如需要确保在ECs实例上任务处理完成才让弹性伸缩释放该实例,需要在自定义镜像中存放执行脚本,并设置命令在操作系统关机时自动执行该脚本。
10.OSS中文件夹的概念仅是一个逻辑概念,在通过API/SDK的方式设置文件夹的时候可以指定object对应的key值包前面的目录即可是想该功能。
11.CDN节点系统关键组件有: LVS做四层均衡负载,Tengine做7层负载均衡 Swift做Http缓存。
12.配置和管理一个负载均衡SLB实例主要涉及操作:属性配置、监听配置、后端ECS实例配置 公网IP是购买SLB时系统分配的 或者是单端购买EIP后单独给SLB绑定。
13.阿里云的负载均衡SLB目前仅支持4层和7层的负载均衡。
14.实现不同地区的多个负载均衡SB的负载,需要通过DNS轮训来实现。
15.弹性伸缩(Auto Scaling)中既支持自动伸缩,也支持手动添加闲置的ECS实例,手动添加的ECS的规格配置不需要和伸缩配置中的配置相同。
16.阿里云CDN(内容分发网络)全称是Alibaba Cloud Content Delivery Network,简历并覆盖在承载网智商、由分布在不同区域的边缘节点服务器群组成的分布式网络,替代传统以WEB Server为中心的数据传输模式。CDN加速特别适合在站点访问量大,且静态资源被不同用户重复访问的比例高的场景中使用,重复访问率越高 加速效果越明显。
17.OSS在安全性方面:1.提供且业绩多层次安全防护;2.多用户资源隔离机制,支持异地容灾机制;3.提供多种鉴权和授权机制 及白名单、防盗链、主子账号功能。
18.OSS对象存储服务 每个Bucket存储空间的名称全局唯一,Bucket存储空间一旦创建成功,名称和所处地域不能修改。
19.ECS系统资源监控DashBoard页面内容:CPU使用率,磁盘IO,网络带宽。
20.SLB包含:来自外部的访问请求、Listener、LoadBalancer、BackendServer。 Listener:用户定制的监听器,定义了负载均衡策略和转发规则。 LoadBalancer:负载均衡实例; BackendServer:后盾的一组ECS
21.出于安全考虑,目前控制台针对私有bucket的获取URL链接签名操作做了优化,使用的AccessKey是临时生成的秘钥对,主账号用户最长有效时间是18小时,RAM子账户用户及sts用户最长有效时间是1小时,超时后链接就无法访问了。
22.OSS与自建存储相比:海量存储;低成本;安全;多线BGP接入
23.阿里云弹性伸缩创建伸缩组之后地域属性、负载均衡实例、RDS数据库实例不可以修改。
24.OSS:删除Bucket之前, 碎片文件也必须要一起删除。
25.在ECS上新挂载一块数据盘,可以使用和它同一个可用区鹅非系统盘快照来创建。
26.CDN快速入门操作流程:1.开通CDN服务;2。添加加速域名。3。配置CNAME
27.边界网关协议,简称BGP(Border Gateway Protocol),主要用于互联网AS(自治系统)之间的互联。BGP协议的最主要功能在于控制路由的传播和选择最好的路由。使用BGP高防可以解决跨运营商访问慢、部分小运营商访问不稳定的情况。 阿里云在骨干机房有出口带宽大和云服务器独享的出口带宽的特点; 多线接入与云服务的质量是有关系的; 通过BGP多线机房,实现全国访问流畅均衡; 通过多线接入可以实现更高的云服务质量
28.每个ECS实例最多可以加入5个安全组,当超过5个以后就无法继续加入其它安全组。
29.伸缩组包括:伸缩配置、伸缩规则、伸缩活动。
30.云盾先知计划是一个帮助企业建立私有应急响应中心的 平台(帮助企业手机漏洞信息)。
31.在服务器上手动安装安骑士时需要管理员权限。
32.删除交换机之前,必须先删除目标交换机所连接的云产品实例。
33.ECS实例和internet直接连通,一定要开启公网带宽或者绑定EIP。
34.CDN广泛用于网站和应用加速、音视频点播、文件等场景,通过高性能缓存机制,提高访问效率和资源可用性。
35.SLB支持按使用流量或者按照固定带宽付费。
36.在OSS API中通过CopyObject参数的操作可以实现设置object头:Copy Object接口可以发送一个Put请求到OSS,并在Put请求Header中添加元素x-oss-copy-source来指定源Object。
37.伸缩组里面有伸缩活动正在执行的时候,不可以停用伸缩组。强制停用可能会导致伸缩组伸缩异常。
38.CDN缓存命中率下降的原因:刷新缓存,可能导致短时间内命中率下降;带宽突增,会导致CDN节点回源较多,命中率会表现下降趋势;CDN节点访问新内容,导致CDN节点回源较多;缓存规则调整
39.不同专有网络之间通过隧道ID进行隔离。专有网络内部由于交换机和路由器的存在,所以可以像传统网络环境一样划分子网,每一个子网内部的不同云服务器使用同一个交换机互联,不同子网间使用路由器互联。
40.HTTP、HTTPS监听可使用植入cookie和重写cookie来进行会话保持。
41.一台ECS实例最多能挂载16块云盘作数据盘用,且云盘只能挂载到同一地域下同一可用区内的实力上,不能跨可用区挂载。
42.弹性伸缩 与SLB、RDS紧密集成,可以自动管理SLB后端服务器和RDS白名单,节省操作成本。
43.弹性伸缩: 功能概述: 根据客户业务需求自动调整ECS实例数量; 自动向负载均衡的后端服务器组中添加或移除相应的ECS实例; 自动向RDS访问白名单中添加或移除ECS实例的IP 产品特点: 随需应变:根据需求“恰到好处”地分配资源,无需提前预测需求变化,实施应对需求突增; 自动化:无需人工干预,自动创建和释放ECS实例,自动配置负载均衡和RDS访问白名单; 伸缩模式丰富:多模式兼容,可同时配置定时、动态、自定义、固定、健康模式,可通过API对接外在监控系统; 智能:智能调度云计算资源,应对各种负载场景。
44.安全组规则是不支持MAC授权的。
45.弹性伸缩主要是ECS的横向伸缩,同事也是服务的横向伸缩,弹性伸缩要求每台ECS是无状态的,否则不能保证数据的统一。
46.将负载均衡后端ECS的权重置零,新发起的业务请求是无法经负载均衡转发到该服务器的,健康检查相应的会显示异常。所以该ECS实例不会再得到负载均衡SLB实例分发的外部访问请求。
47.为了保证网站能按时上线,需要在网站上线前一个月提交备案资料,保证留有重组的备案时间来完成备案操作。
48.ECS服务器会对每个访问的请求进行身份验证:Access Key Secret是用来鉴权校验的,AccessKeyId是用来区分用户的。阿里云accessKeyId和accessKeySecret是访问阿里云API的卫衣凭证。Id是类似身份的标识,而secret的作用是签名您的反问参数 以防被篡改。类似于您的登录密码。
49.负载均衡只支持PEM格式的证书,上传证书前,确保证书、证书链、私钥符合规格要求: Root CA机构颁发的证书 -----BEGIN CERTIFICATE-----,-----END CERTIFICATE----- 每行64个字符,最后一行长度可以不足64 证书内容不能包含空格 中级机构颁发的证书 服务器证书放第一位,中级证书放第二位,中间不能有空行 证书不能包含空格,每行64字节不能有空行 证书公钥: RSA1024 RSA2048 RSA4096 ECDSA(P-256/P-384/P-521)
50.OSS目前不具备OCR文字识别的处理能力
51.对安全组的调整操作,对用户的服务连续性没有影响。
52.CDN内容分发网络 是安装每日带宽峰值计费,所以不存在带宽不足,服务能力达上限的问题。
53.对图片进行处理后,所有的操作都会以参数形式加在图片的URL之后,导致图片URL变得冗长,不便于管理与阅读。OSS的图片处理服务允许您将常见的操作保存为一个别名,即样式(Style)。利用样式功能,只需一个很短的图片URL就能实现对图片的复杂操作。
54.专有网络VPC里面的交换机支持部署在同一地域的不同可用区,专有网络VPC类型的实力可以加入同一专有网络VPC下的安全组
55.云监控包括了:主机监控、自定义监控、站点监控、云服务监控、报警服务。
56.先知(安全众测)是一个帮助企业建立私有应急响应中心的平台(帮助企业收集漏洞信息),尽早发现存在的漏洞可以有效地减少企业可能的损失。
57.经典网络的IP都是随系统分配,不支持用户自定义网段。VPC网络可以支持用户字由定义网络,按需配置网络,可自定义IP地址范围与路由表等
58.默认专有网络和非默认装有网络的操作方式与规格显示一致
59.云盾的DDoS基础防护、内容安全、安骑士 的安全能力对云服务器ECS实例的安全进行保护 服务器安全托管不属于云盾功能,而是属于安全管家的服务。
60.弹性自愈即当检测到某台ECS实例出于不健康状态时,弹性伸缩自动释放不健康ECS实例并创建新的ECS实例,自动添加新ECS实例到负载均衡实例和RDS实例的访问白名单中。
61.弹性伸缩手动添加ECS,ECS的状态必须是运行中。
62.负载均衡SLB后端服务器的状态为unavailable的时候表示其未开启健康检查。
63.正常情况下用fdisk -l命令,可以查看到新增的阴干。 /dev/xvda为系统盘,/dev/xvdb /dev/xvdc .../dev/xvdz都是数据盘
64.可以通过专有网络VPC的管理控制台 以及 专有网络VPC的相关路由表接口来 管理配置路由表
65.负载均衡实例ID即LoadBalancerId是来区分不同负载均衡SLB实例的唯一标识。
66.如果在云服务器ECS实例中部署虚拟化程序,服务器出现的问题是不可预测的。阿里云强烈不建议在云服务器ECS实例中部署虚拟化程序,这样会导致云服务器ECS出现不可预测的问题。
67.安骑士不提供人工安全技术支持、托管服务报告的服务,需要 人工安全技术支持、托管服务报告的服务需要选用安全管家服务。
68.态势感知: 具备异常登陆检测、网站后门查杀、进程异常行为、敏感文件篡改、异常网络连接、linux软件漏洞、windows系统漏洞、Web-CMS漏洞、应急漏洞、Web漏洞扫描、主机基线、云产品基线、资产指纹、AK和账号密码泄露,数据大屏,日志检索、全量日志分析。 SaaS软件即服务 PaaS平台即服务 IaaS基础设施即服务 DaaS数据即服务
70.阿里云的专有网络VPC中用于连接VPC内的各个交换机的设备是 路由器和交换机 路由器(VRouter)是专有网络的枢纽,作为专有网络中重要的功能组件,它可以连接VPC内的各个交换机,同时也是连接VPC和其他网路的网关设备
71.互联网的一次标准的网络层会话可以用五个元素来唯一标识,通常称为“网络通信五元组”:源IP地址,源端口,目的IP地址,目的端口 和传输层协议
72.绿网(现:内容安全)
73.防WEB应用系统的密码破解不属于安骑士的功能,而是属于Web应用防火墙的功能。
74.弹性伸缩的伸缩规则定义了具体的扩展或收缩操作,例如加入或移除n个ecs实例
75.负载均衡SLB是对堕胎云服务器ECS实例进行流量分发的负载均衡服务,支持四层和七层的转发协议。其中四层服务主要是依据a、报文中的目标IP地址和端口;b、负载均衡SLB中设定的转发策略和规则把流量分发到对应的云服务器ECS实例上去。
76.oss中的文件夹其实就是一个大小为0kB的空文件(叫文件 Object 元素都可以)。
77.XSS 即为Cross Site Scripting 跨站脚本 时发生在目标用户的浏览器层面上的,当渲染DOM树的过程中发生了不在预期内执行的JS代码时,就发生了XSS攻击。
78.同一个安全组下的ECS实例默认是内网互通的,不同的安全组下ECS默认是内网不通的。 同一账号在同一地域的情况下,通过安全组实现内网互通,要么在同一个安全组下面,要么是两个安全组相互授权对方可以访问。
79.负载均衡SLB实例提供后端云服务器ECS视力健的数据自动同步功能,采用的是rsync的远程同步技术 在通过负载均衡SLB实例对外提供服务前,只需要确保SLB后端有一天ECS应用正常运行
80.用户只有通过URL签名 或者 匿名访问Object时,才会做防盗链验证。
81.阿里云的负载均衡SLB中的listener是服务监听,每个监听都对应了后端的一个应用服务。服务监听包含:监听端口 ;负载均衡策略;健康检查配置
82.DDoS(分布式拒绝服务)攻击,是指借助于客户端、服务器技术,将多个计算机联合起来作为攻击平台,对一个或者多个目标发动DDoS攻击,从而成倍得提高攻击的破坏力,使目标服务器无法提供正常服务,包括:ICMP Flood;UDP Flood;TCP flood;SYN Flood;ACK Flood等
83.数据分析需要借助Hadoop等软件配合硬件来实现,ECS不适合海量数据分析的工作,也不是ECS的经典应用场景。
84.TCP需要三次握手,UDP是面向非连接的协议
85.如果应用需要较高的容灾能力,建议将云服务器ECS实例部署在同一地域的不同可用区内; 是否将云服务器ECS实例放在同一个可用区内,主要取决于对容灾能力和网络延时的要求 如果应用在ECS实例之前需要飞航地的网络时延,讲义将ECS实例创建在相同的可用区内 同一可用区内的ECS实例之间的网络时延更小 在同一地域内不同可用区之间的内网互通,可用区之间能做到机房级别的故障隔离
86.站点监控可以对目标站点服务的可用性以及响应时间进行监控。系统已经默认预置了8种监控类型,包括http监控、ping监控、tcp监控、udp监控、DNS监控、pop监控、smtp监控、ftp监控。其中每种监控类型里面包含了两个监控项: 状态码status 和 响应时间responseTime
87.手动加入既有的ECS实例的步骤:1.判断伸缩组的健康状态、边界条件和ECS实例的状态、类型;2.分配ActivityId和执行伸缩活动;3.加入ECS实例;4.修改TotalCapacity;5.添加RDS白名单;6.挂载负载均衡,将权重设为当前伸缩组中已激活的伸缩配置上指定的“负载均衡权重”;7.伸缩活动完成,启动cooldown
88.云计算的特点:大规模;虚拟化;高可靠性;通用性;按需服务;高可伸缩性;廉价性。支持多租户
89.同一个负载均衡SLB只能挂载同一个地域的云服务器ECS,不支持跨地域部署。如果需要跨地域部署,可以考虑在多个地域部署负载均衡实例,通过DNS轮询来实现跨地域负载。
90.专有网络VPC可实现:网络的拓扑设计和私网IP地址段的划分。
91.OSS图片处理API Channel: 一个用户最多可以创建10个CHannel; 单个Object(即每张图片)允许的最大大小为20MB,但是每个Channle中存放的object的数量是没有限制的; IMG名称在整个图片处理服务中具有全局唯一性,且不能更改。
92.负载均衡集群采用 LVS和Tengine实现,其中4层监听(TCP、UDP)经过LVS后直接到达后端服务器,而7层监听(HTTP、HTTPS)经过LVS和Tengine最后到达后端服务器,7层性能没有4层性能好。 因为7层比4层多了一个处理环节,因此,7层性能没有4层性能好。
93.定时任务独立于伸缩组存在,不依赖伸缩组的生命周期管理,删除伸缩组不会删除定时任务;云监控报警任务独立于伸缩组存在,不依赖伸缩组的生命周期管理,删除伸缩组不会删除报警任务。
94.阿里云 内容分发网络 CDN支持以下防护配置:防盗链功能(Refer黑白名单),IP黑白名单,URL鉴权
95.多媒体转码服务MTS服务。
98.对象春初OSS的防盗链功能可以杜绝其他站点的下载
99.阿里云ECS的API为:ecs.aliyuncs.com
100.在VPC内选择一台云服务器ECS实例作为堡垒机,申请一个EIP绑定到该ECS实例,通过该堡垒机进行其他云服务器ECS实例的管理
101.OSS域名绑定(CNAME)功能目前仅支持OSS以散记域名访问方式进行绑定。即访问方式为:(BucketName).${region}.aliyuncs.com
102.添加的eCS需要和伸缩组出于同一个地域Region
103.阿里云CDN不支持直接对IP地址进行加速,使用内容分发CDN徐亚在控制台绑定域名。
104.闪电立方LightningCube(数据迁移 Data Transport)是阿里云为TB乃至PB级数据迁移提供的服务 云服务器ECS实例的数据盘上的大量非结构化的数据转存到其他的服务上去 使用OSSImport更方便
105.绿网支持API批量检测图片和识别的文字
106.CDN回源的地址可以是回源域名,也可以是回源IP,这时访问的是ECS的公网IP,不管是否在同一地域都会产生回源流量费
107.Bucket的权限:公共读写 公共读 私有
108.VPC下的云服务器ECS实例可以绑定EIP实现公网的访问,同时可以将其配置为公网网关,实现VPC内其他ECS实例的公网访问
109.敏感信息泄露属于Web应用防火墙的功能,是需要收费的服务。
110.实例创建快照时,实例必须处于运行中 或者 已停止状态
111.IaaS 基础设施即服务 (Infrastructure-as-a-service) IaaS公司会提供场外服务器,存储和网络硬件,也可以选择租用。节省了维护成本和办公场地,公司可以在任何时候利用这些硬件来运行其应用,比如阿里云的ECS 亚马逊的EC2 腾讯云的CVM都属于IaaS
112.SLB支持同一Region跨数据中心容灾,还可以通过与DNS结合支持跨Region容灾 SLB的服务能力与后端ECS的公网带宽规格无关
113.阿里云的云盾加密服务通过在阿里云上使用经国家密码管理局检测认证的硬件密码机,帮助用户满足数据安全方面的监管合规要求,保护云商业务数据的隐私性和机密性。管理云盾加密服务的密钥时,必须通过 身份卡(USB Key)方式认证。 所有的秘钥管理都必须依赖身份认证卡 若丢失 阿里云也无法恢复
114.阿里云的负载均衡SLB中的证书(certificate)用于HTTPS协议,当需要使用加密传输时,用户可以将证书上传至负载均衡SLB实例中,在创建HTTPS协议监听时绑定证书,提供HTTPS服务。用户可通过 负载均衡的管理控制台 以及 负载均衡的API上床HTTPS证书 方式上传证书。
115.先知计划 是有独立于阿里云的安全服务的 提供者“白帽子” 或 “安全公司”为企业提供众测服务。
116.专有网络VPC是一个免费的网络容器 交换机 路由器是免费的 弹性公网IP是收费服务
117.安骑士企业版可以检测并修复漏洞
118.RDS实例内外网切换会影响其他与RDS实例的链接
119.加速域名的源站可以放在阿里云的OSS上 源站域名不能与加速域名相同,否则会造成循环解析,无法回源。
120.当一个bucket(源bucket ,Source Bucket)开启访问日志记录功能够,OSS自动将访问的bucket中文件的请求访问记录 以小时为单位,按照设置的命名规则,生成一个Object写入用户指定的bucket(目标bucket,target Bucket) 日志每小时自动生成一次,通过对生成的日志文件进行分析,可以轻松定位到Oss Bucket上的所有操作。
121.SLB和ECS只需要在一个地域,创建伸缩配置时,ECS实例可以不选择公网带宽,但是为了方便管理ECS实例,建议购买至少1Mbps的ECS带宽
122.修改私网IP需要保证ECS处于已停止的状态
123.阿里云的负载均衡SLB目前只支持阿里云服务器ECS实例,不支持其他服务器
124.不同专有网络之间完全隔离,无法内网互通,当前可以通过公网建立VPN实现互通。
125.安装 安骑士客户端 后, 需要通过管理控制台的Key来完成和阿里云官网账号的关联。
126.弹性伸缩必须和ECS搭配使用,对其他云产品没有限制。
127.云服务器ECs实例与OSS之间的请求次数,部分内外网都会计费。走内网流量是不计费的,但是每次的请求次数还是收费的。
128.Internet使用TCP/IP洗衣实现了全球范围的计算机网络的互联
129.修改私网IP地址有两种方式:如果不需要更换交换机,则直接修改私网iP即可。如果需要更换交换机,则可以变更云服务器ECS实例所在的交换机,然后直接修改云服务器ECS实例的私网IP
130.MapReduce是一种编程模型,用于大规模数据及的并行运算,可以非常好的和云计算相结合以处理海量数据计算。MapReduce将自己的程序运行在分布式系统上,他的计算速度比较慢,计算出来的中间结果等等都会写到磁盘上,输出的结果也会到磁盘上,读写磁盘就意味着性能不能达到实时的要求,做历史数据的批处理比较好。 mapReduce的设计目标包括:易于编程、易于扩展、高容错性
131.EIP(弹性公网IP)可绑定到专有网络类型的ECS实例、专有网络类型的私网SLB实例和NAT网关上,不支持绑定到经典网络的ECS上。
132.使用阿里云负载均衡SLB将负载分发到多台云服务器ECS实例上去的时候,可获得发起请求的用户的真是IP:针对4层(TCP)负载均衡服务,可以直接获取用户IP,七层则需要通过请求头中的X-Forwarded-For获取 在负载均衡SLB中,可以通过X-Forwarded-For的方式获取访问者真实IP
133.安骑士提供的服务:端口检测、异地登录提醒、密码暴力破解、WebShell检测服务
134.通过VPN专线可以将该网络与传统数据中心组成一个按需定制的网络环境,实现应用的平滑迁移上云
135.阿里云的云监控服务是自动开通,不要单独开通
136.弹性公网IP(EIP)是可以独立购买和持有的公网IP地址资源,公网访问时支持全国所有地域的访问的。
137.在ECS中挂载磁盘的时候必须的请求参数: DiskId 和 InstanceId
138.在使用阿里云负载均衡SLB时后端服务器可以设置主备服务器组,当主机工作正常时,流量将直接走主机,当主机宕机时,流量将走到备机。主备服务器组是在监听维度上维护的,并且只支持四层监听。(TCP/UDP)协议
139.云盾数据风控产品具体可以防范 垃圾注册 营销作弊 盗卡支付 安全威胁。CC注册时Web应用防火墙的功能。
140.VPC基于隧道技术,实现数据链路层的隔离,为每个租户提供一张独立、隔离的安全网络。不同专有网络之间内部网络完全隔离,只能通过 对外映射的IP(弹性公网IP和NAT IP) 互联
141.CopyObject接口用于在存储空间(Bucket)内或 同地域的Bucket之间拷贝文件(Object),所以不需要使用带宽在此上传至OSS,可以节省OSS的网络带宽
142.在冷却时间内,伸缩组会拒绝由云监控报警人物出发的伸缩活动请求,但其他类型任务(手动执行任务、定时任务、健康模式)触发的伸缩活动可以立即执行,绕过冷却时间。
143.流量清洗的触发指标有公网IP每秒处理的报文数量(PPS) 和 公网IP每秒处理的流量值(bps)
144.实现OSS Object上传:简单上传指的是使用OSSAPI中的PutObject方法上传单个文件。简单上传适用于一次HTTP请求交互即可完成上传的场景,比如小文件(小于5GB)的上传,上传文件时支持设置ObjectMeta
145.OSS的成本优势: OSS服务基于多线BGP骨干网络构建,下行无带宽限制,上行流量免费 OSS最终用户不需要投入运维人员与托管费用,后天运维完全由阿里云负责 无需一次按峰值容量的存储硬件设备,按实际使用容量付费 ······OSS的下行带宽是没有限制的,上行(即上传)的流量是免费的。同事OSS的Bucket空间是灭有上限的,所以不存在扩容的情况,更不存在业务中断的情况。
146.默认专有网络VPC不占用阿里云为您分配的专有网络VPC配额 默认专有网络与非默认专有网络的操作方式和规格限制一致 每个地域的默认专有网络VPC唯一 默认专有网络VPC由阿里云为您创建,您自行穿件的均为非默认专有网络VPC
147.SLB LoadBalancer中 ModifyLoadBalancerInternetSpec 接口是用来修改SLB实例的计费方式的
148.SLB绑定证书是为了满足加密传输的HTTP协议要求
149.动静分离的网站是有利于通过CDN加速的,上云实践中用户可以通过利用OSS和CDN对网站进行架构优化,做到网站文件的动静分离的,提升用户访问体验,实现成本可控
150.在安全方面,OSS服务本身具备了防DDoS攻击和自动黑洞清洗的功能。
151.云盾DDoS防护功能可以保障ECS SLB WAF VPC EIP NAT云产品的DDoS网络安全
152.OSI Open System Interconnect 开放系统互联参考模型 第七层是指 应用层 七层协议:应用层 表示层 会话层 传输层 网络层 数据链路层 物理层
153.OSS中 单个Object的大小限制是48.8T
154.加速域名日志中记录的流量数据,使我们应用层日志统计出的流量,但是实际产生的网络流量却要比应用层统计到的额流量要高出 7%---15% 主要原因是:1.TCP/IP包头的消耗,2.TCP重传
155.安骑士不具备DDoS防护的功能特性
156.ECS磁盘在未创建快照的情况下 是不允许通过其他磁盘的快照进行回滚或数据恢复
157.每个ECS实例最多可以加入5个安全组,且ECS至少加入一个安全组
158.负载均衡的SLB中的公网或者私网访问的选择是由用户在购买时选择的,并不是系统自动选择
159.CDN控制台、OpenAPI都可以下载CDN访问日志
160.使用windows操作系统的时候,只有机器内存较低(低于2G)的时候,建议使用虚拟内存
161.七层服务可以关闭健康检查,四层服务无法关闭健康检查,只有HTTP和HTTPS监听支持关闭健康检查。UDP和TCP监听无法关闭健康检查。
163.BGP机房的服务器并不是都具备双机或者多机 冗错功能。 BGP机房的优点: 1.服务器只需要设置一个IP地址,最佳访问路由是由网络上的骨干路由器根据路由跳数与其他技术指标来确定的,不会占用服务器的任何系统资源。服务器的上行路由和下行路由都能选择最优的路径,所以能真正实现高速的单IP高速访问。 2.由于BGP协议本身具有冗余备份、消除环路的特点,所以当IDC服务商有多条BGP互联线路是可以实现路由的相互本分,在一条线路出现故障时路由会自动切换到其他线路。 3.使用BGP协议还可以使网络具有很强的扩展性,可以将IDC网络与其他运营商互联,轻松实现单IP多线路,做到所有互联运营商的用户访问都很快,这个是双IP双线无法比拟的。
165.目前一个SLB实例最多对应50个监听,每个监听可独立设定限定规则
166.CDN的全部缓存节点并没有采用BGP线路,BGP线路主要为OSS,和DDoS高防IP提供服务,实现不同运营商的网站都可以快速访问。CDN则是由充足的带宽和存储资源。
167.域名解析服务 和邮件服务 斌不是走UDP协议
168.更改云服务器ECS的MAC地址,可能会影响到服务器的网络通信服务
169.VPC只有配置中(Pending)和可用(Available)两种状态
170.阿里云的云盾DDoS基础防护功能在管理控制台可以配置针对云服务器的流量清洗的阈值,达到任意一个值即开始流量清洗。 触发清洗阈值:指的是触发流量清洗所需要的最低值,包括每秒流量每秒报文数量 每秒HTTP请求数三个触发清洗的阈值。用户云服务器上的流量超过三个钟的任意一个 都会触发清洗。
171.VPC支持VPN链接,但不是他提供的功能,VPN连接还是依赖于其他设备和网络的。
172.ECS中,无论每次接口调用请求是否成功,系统都会返回一个唯一识别码(返回参数)RequestId
173.虚拟化技术包括:全虚拟化、半虚拟化、硬件辅助虚拟化
174.快照保存在独立于自建的OSS空间内
175.如果弹性伸缩的ECS实例无法加入到RDS访问白名单中,自动创建的ECS会被回滚和释放,手动创建的ECS不会被回滚和释放
176.态势感知(云安全中心)的告警设置仅支持:短信、邮件、站内信 不支持钉钉旺旺
177.RDS是高度兼容Oracle
178.弹性伸缩的伸缩配置中支持配置的镜像包括:自定义镜像、公共镜像、共享镜像
179.当创建一个云产品实例时,如果没有可用的专有网络和交换机,您可以使用默认专有网络和交换机。在实例创建后,一个默认的专有网络和交换机也会随之创建好
180.四层是检查端口,七层是检查服务器端返回的状态码
181.NAS Network Attached Storage 文件存储 公共云计算中使用的存储并非是共享存储,而是分布式的私有存储
182.路由器是可以创建自定义路由表的
183.会话保持 默认关闭。启用后,负载均衡会把来自统一客户端的访问请求分发到同一台后盾云服务器ECS上进行处理。
184.ISV 独立软件开发商
185.如需要确保在ECS实例上任务处理完成后才让弹性伸缩释放该实例,需要在自定义镜像中存放执行脚本,并设置命令在操作系统关机时自动执行该脚本。
186
188.拒绝处理请求对应的状态码是 403
189.443端口即网页浏览端口,主要是用于HTTPS服务 .com域名一次性最多可以注册10年 .com域名查询whois里 Registrar是 域名所有者
190.负载均衡请求不均衡可能有以下几种原因:1.ECS实例请求连接数较少;2.不同ECS市里的性能不同导致请求不平衡;3.开启了会话保持功能;4.ECS健康检查异常;5.TCP Keepalive保持长连接
191.绿网(内容安全)的站点检测支持对网站的内容和图片进行检查,同事支持静态和动态的站点
192.阿里云官网给用户免费提供的安全验证手段:用户名密码校验 登录验证码或安全滑块 多因子(虚拟MFA)认证
193.复制镜像仅适用于自定义镜像。如果需要复制其他类型的镜像,可先使用镜像创建实例,在使用该实例创建自定义奖项,然后复制该自定义镜像
194.OSS服务本身不提供IP黑名单的功能,可以结合内容分发CDN来实现IP黑白名单的功能。
195.CDN系统能够实现内容加速的功能,需要智能DNS解析的支持 目前智能DNS解析不支持 页内容缓存的功能的
196.CDN支持对同名更新的实施更新,用户只要做相关配置后,在不主动提交请求的时候,CSN不会自动去刷新请求
197.SLB API ServerCertificate 目前使用UploadServerCertificate接口一次只能上传一份服务器证书和对应的私钥
198.负载均衡SLB下面的ECS必须开启健康检查,否则负载均衡SLB无法监听到后端ECS的状态则无法正常弹性伸缩
199.阿里云专有网络VPC和VPN是不同的概念。专有网络VPC是一个二层隔离的网络环境;VPN是一种远程访问技术,利用公网假设虚拟专用网络。 VPC使用的是二层的隔离技术,VPC中的交换机属于三层的交换机
200.CDN加速域名的停用 和删除 停用该加速域名后,该条加速域名信息仍保留,针对加速域名的请求系统将做自动回源处理。 删除该加速域名后,将删除该加速域名的全部相关记录,对于仅需要暂停使用该加速域名,推荐选择“停用”方式
201.ECS在容灾方面比传统虚拟主机拥有的优势:每份数据多份副本 单份数据孙华可在短时间内快速恢复 支持自动备份 ---传统虚拟主机也具备
202.当用户流量经过负载均衡某端口时,我们首先判断其是否能够匹配上某条转发规则,如果匹配,则将流量转发到该规则的后端服务器组上;若不匹配并且在该监听上设置了虚拟服务器组,那么将流量转发到该虚拟服务器组上;若用户没有在该监听上设置虚拟服务器组,即将流量转发到实例级别添加的各后端服务器中。
203.如果SLB实例已挂载了VPC类型的ECS实例,则不支持在该SLB下增加经典网络类型的ECS实例
204.云服务器ECS实例支持切换交换机,但是不支持切换路由器操作
205.ECS外部系统可以通过API在请求时传入参数来指定返回的数据格式,默认为XML格式
206.数据风控由阿里聚安全提供 是基于阿里大数据计算能力,通过业内领先的风险决策引擎,解决企业账号、活动、交易等关键业务环节的经济损失
207.阿里云多线BGP(中国电信、联通、移动、教育网等)接入,确保全国用户访问畅通,提升用户访问的质量。所以解决的是避免跨运营商的网络访问的速度瓶颈。
208.Google在2003年到2006年公布了关于GFS、MapReduce 和BigTable三篇技术论文
209.数据存储(OTS)保存客户海量用能数据,满足大数据分析的需求
210.数据风控目前只支持在Web中插入指定的JS代码,其他的暂时不支持
211.交换机创建完成后,无法修改CIDRBlock,且新建交换机所使用的的CIDRBlock不可以与已经存在的交换机的CIDRBlock重复。
212.阿里云使用隧道封装技术实现了不同专有网络VPC间二层网络隔离。在VPC内的云服务器ECS实例之间的三层网络访问控制 用 安全组 功能实现。
213.OSS 除了通过PUT Object接口上传文件到OSS以外,还可以 Multipart Upload
215.OSS支持的监控功能:存储空间的监控;对OSS服务请求的PV访问量(PUT、GET的请求数)的监控;对OSS服务请求的UV访问人次的监控
216.停用伸缩组以后,之前的冷却时间即失效。所以之后的伸缩活动不会受到冷却时间的影响
217.设置自动快照创建时间和重复日期时应尽量避开业务高峰,因为创建快照可能会轻微降低磁盘的性能,出现短暂瞬间变慢。
218.一个负载均衡实例对多支持添加50个监听,每个监听配置对应后端ECS实例上的一个应用,可以通过对后端ECS实例上的多个应用配置不同主机头的方式来满足这一需求。
219.云服务器Elastic Compute Service ECS :云服务器是BGP多线机房,全国访问流畅均衡,传统IDC是以单线和双线为主
220.路由器是删除VPC时自动删除的。
221.专有网络型的ECS实例只能在创建时指定,这类实例只可以属于单个虚拟交换机
222.源站服务器上获取“访客真实IP”: 1.“访客真实IP”保存在HTTp协议的X-Forwarded-For Header中,可以再Apache和Nginx的自定义LOG中直接获取到 2.在阿里云CDN的管理控制台中有一键开通”记录访客真实IP“功能,用户设置了这个开关后,可以再访问日志中直接看到访客真实IP
223.WEB服务不属于安骑士的功能点
224.弹性伸缩中的伸缩模式的任务:定时任务和报警任务 没有优先级之分,两个同时触发会随机执行。
225.由客户服务端调用风险识别服务API,获取风险评估结果。风险苹果结果,可作为其中一个因子参与到业务决策逻辑中,也可根据评估结果直接进行处置。
226.媒体转码 Media Transcoding MTS
227.阿里云弹性伸缩和负载均衡SLB一起使用时,两者必须处于同一地域
228.ECS的网络类型 对ECS性能没有影响。
229.linux系统的服务器不支持开启Selinux服务,如果开启了Selinux服务,会导致系统异常并无法启动
230.阿里云内容分发网络(Content Delivery Network CDN)是建立并覆盖在承载网之上,并分布在不同区域的边缘节点服务器群组成的分布式网络。阿里云CDN分担源站压力,避免网络拥塞,确保在不同区域、不同场景下加速网站内容的分发,提高资源访问速度
231.弹性伸缩支持数据盘的弹性伸缩。
232.同一组ECS实例可以待见多个网站,并可以同事对这些网站进行负载均衡; 负载均衡不提供CNAME地址,只提供IP地址; 后端服务器的权重之和是没有限制的; 后端服务池中的ECS可能由于异常导致机器不能正常运行,会出现非运行中的情况
233.SLB ECS Auto Scaling 配合使用: 三者必须在同一地域,才能配合使用 负载均衡SLB实例必须打开健康检查,否则无法和弹性伸缩配合使用 一个SLB实例可以绑定多个伸缩组 一个伸缩组可以同时支持多个SLB实例
234.BGP(边界网关协议)主要用于互联网AS(自治系统之间的互联,BGP的最主要功能在于控制路由的传播和选择最好的路由,阿里云的云服务器ECS产品支持的多线BGP接入,解决的主要问题是:笔迷跨运营商的网络访问的速度瓶颈:使用BGP协议还可以使网络具有很强的扩展性 可以将IDC网络与其他运营商互联,轻松实现单IP多线路,做到所有互联运营商的用户访问都很快。
235.一个负载均衡SLB实例可以绑定多个弹性伸缩的伸缩组,且这些伸缩组的伸缩配置可以不同,一个伸缩组可以对应多个负载均衡SLB实例,但是两只必须在同一个地域中。
236.弹性公网IP的限制有:ECS实例的网络类型必须是专有网络、ECS实例的地域必须和EIP的地域相同。
237.不能强行终止伸缩活动,否则可能会导致伸缩组伸缩异常,假如配置错误了以后可以自己手动修改伸缩配置来释放多创建的云服务器ECS
238.EIP解绑后,仍需要支付IP占有费,为避免不必要的计费,可以解绑后释放EIP
239.每个弹性公网IP只能绑定到同一地域的一个VPC网络的云产品实例上,不一定要求在同一个可用区
240.平台即服务:消费者不需要控制底层的设施,但是可以控制运行应用程序的托管环境配置,且平台包括 网络、服务器、操作系统、存储等。
241.云服务器ECS实例通过公网访问RDS实例的公网地址的时候,不会影响到其他经典网络通过公网访问此RDC实例;在VPC中的RDS,其他经典网络则无法访问该RDS实例。
242.HTTPDNS 是面向移动开发者推出的一款域名解析产品,具有域名防劫持、精准调度等特性,主要是用在客户端的时候请求URL防止域名挟持的情况
243.自动伸缩的话,实例的IP会自动增加到负载均衡SLB的白名单中
244.创建EIP后,云监控服务自动开启,无需手动开启即可对EIP进行监控
245.弹性伸缩目前只支持ECS及其数据哦按的弹性伸缩,不支持云数据库RDS、负载均衡等云产品的弹性伸缩
246.如果多个定时任务在相近的时间内触发执行同一个伸缩组的伸缩规则,则最早触发的定时任务会先执行伸缩活动。由于同一个伸缩组同一时刻内只能有一个伸缩活动,排在后面的定时任务会在LaunchExpirationTime内自动充实定时触发,如上一个伸缩活动完成之后,排在后面的定时任务还在LaunchExpirationTime内重试,贼执行该定时任务的伸缩规则并触发相应的伸缩活动。‘
247.一班情况下,默认路由在有外网情况下会先走外网网卡,如无外网则走内网网卡
248.打通VPC与传统数据中心,需要基于公网的VPN或者专线
249.OSS: 如果使用OSS自带域名,均限制在在浏览器中 以 “另存为”下载的方式打开文件,而不能直接浏览该文件。因此需要将自动以的域名访问绑定到属于自己的Bucket上面,即CNAME。域名绑定成功后,为了使用域名正常访问OSS,还需要添加CNAME记录指向存储空间对应的外网域名。
250.公网分发请求至SLB的正确方法: 购买公网IP的负载均衡SLB实例接收公网请求,或者创建VPC内的负载均衡SLB实例,然后再给这个SLB绑定EIP来接收公网请求 用跳板机接收外部请求不规范且冗余,既然有了公网IP,就没有必要使用跳板机来接收公网请求。
251.OSS针对VPC是有一套自己的内网地址,
252.OSS每小时结算一次调用OSS API的请求费用。目前支持支持按量付费,每万次请求的单价*美系哦啊哈斯实际请求次数/10000
253.负载均衡SLB再四层TCP转发是基于源IP的回话保持,四层回话保持的最长时间是3600秒
254.流量转发四层是通过LVS实现,七层是通过Tengine实现
255.阿里云的云监控产品的监控数据可以采用(只能查看报表,无法下载)方式下载:控制台中没有下载按钮,只能查看,API返回的JSON严格意义不算下载文件
256.在控制台里面,专用网络VPC下面的ECS,不管是否绑定了EIP,在设置安全组的时候,只可以设置内网规则,外网规则是不可以选的。因为对于其来说,内网规则等同于外网规则。
257.目前负载均衡SLB监听仅支持TCP、UDP四层 和HTTP、HTTPS七层这四种协议
258.提及到“子账号”,所以需要通过阿里云的RAM(Resource Access Management) 即用户身份管理与资源访问控制服务
259.本地的应用服务器制作镜像不支持上传到阿里云作为镜像提供服务
260.在阿里云专有网络VPC创建后,路由器也是随着VPC一起自动创建的,所以不需要手动创建了,这个时候需要继续创建交换机才能在交换机中创建其他云产品。
261.阿里云在LVS官方问题上进行了定制化: 新增转发模式FULLNAT,实现LVS-RealServer间跨vlan通讯; 新增synproxy等攻击TCP标志位DDOS攻击防御功能 采用LVS集群部署方式 优化keepaliwed性能
262.创建ECS镜像时,输入的自定义镜像名称 不能为空
263.滤网(内容安全)是以API的形式提供服务,不会占用云服务器ECS实例的CPU资源
264.OSS可靠性方面的优势: 服务可用性不低于99.9%,不受限于硬件可靠性 存储规模可自动扩展,OSS对外服务不中断 数据自动多重冗余备份
265.OSS的访问日志会自动保存,用户不需要手动保存访问日志记录。
266.CC攻击的DDos攻击是典型的拒绝服务攻击,服务器口令暴力破解只是破解了密码服务正常,网络后门植入式让服务端成为肉鸡,并不会去影响服务。
267.AccessKeySecret并不支持通过控制台直接查看,AccessKeySecret只能一次生成,后续不支持再次查看。如果忘记AccessKeySecret,只能在授权登录后在控制台重新生成。
268.对频繁连接的可疑IP进行屏蔽,需要通过IP白名单直接只允许指定的IP访问即可
269.云计算服务的三种类型(SaaS、Paas、IaaS)
270.如果在非阿里云的服务器上安装了云盾安骑士客户端,需要用在管理控制台生成的安装验证key与指定的阿里云官网账号关联 确保在管理控制台能查到此服务器的相关报告。
271.私网IP是可以用于SLB的负载均衡的, 同一地域内势力之间通过私网IP进行的通讯是不收取流量费的
272.OSS处理完的图片并不会保存到OSS,而是直接返回给请求的用户
273.在新建的LinuxECS实例中 启动OFBiz服务的时候 步骤如下: 进入OFBiz文件夹(cd ofbiz-release12.04) 给ant脚本赋予执行权限(chmod +x ant) 运行安装脚本(./ant run-install) 启动ant(./ant run)
274.伸缩配置有以下几种状态(LifecycleState): Active:生效状态,伸缩组会采用处于生效状态的伸缩配置自动创建ECS实例 Inactive:失效状态,该伸缩配置存在于伸缩组中,但伸缩组不会采用处于失效状态的伸缩配置自动创建ECS实例
275.希望实现两个VPC之间的私网通信,所以需要通过高速通道实现VPC之间的私网通信。
276.阿里云的与服务器ECS实例的快照是指某一时间点上某一块磁盘的数据拷贝。自动快照时保存在OSS里面,但是是保存在独立于用户自己的OSS Bucket里面,不是用户的BUcket里面。
277.Channel是OSS图片服务API的基本概念之一,是IMG上的命名空间,也是 计费、权限控制、日志记录等高级功能的管理实体
278.OSS分块上传: 支持断点上传;网络条件较差,经常连接断开,上传超过100MB的文件
279.阿里云的弹性伸缩中,创建完成伸缩组后,为了设置用于弹性伸缩的云服务器ECS实例的规格,需要定义 伸缩配置 在创建伸缩配置时,可以指定ECS实例的参数,例如实力规格,镜像类型,存储大小,登录实例用的秘钥对等。
280.阿里云负载均衡服务SLB提供性能保障型实例,该类型实例提供了可保障的性能指标,它的关键指标有: 最大连接数Max Connection 每秒新建连接数 Connection Per Second(CPS) 每秒查询数 Query Per Second
281.阿里云负载均衡服务SLB支持配置域名或者URL转发策略,将来自不同域名或者URL的请求转发给不同的ECS处理:关于域名或者URL转发策略支持的协议: 只有7层监听(HTTP、HTTPS协议) 支持配置URL转发策略
283.LVS做四层均衡负载;Tengine做七层负载均衡 Swift做HTTP缓存
284.公网IP是购买负载均衡SLB时系统分配的,或者是单独购买EIP后单独给负载均衡SLB绑定,并不是在负载均衡的配置和管理里面可以设定的。
285.阿里云的负载均衡SLB目前仅支持4层和7层的负载均衡。
286.阿里云SDN(内容分发网络 Alibaba Cloud Content Delivery network)建立并覆盖在承载网之上、由分布在不同区域的边缘节点服务器群组成的分布式网络,替代传统以WEB Server为中心的数据传输模式
287.OSS在安全性方面的表现: 提供企业级多层次安全防护; 多用户资源隔离机制,支持异地容灾机制 提供多种鉴权和授权机制 及白名单 防盗链 主子账号功能
288.阿里云的负载均衡SLB包含了几个主要部分:来自外部的访问请求、Listener/LoadBalancer/BackendServer等 Listener:用户定制的监听器,定义了负载均衡策略和转发规则
289.需要向阿里云的专有网络VPC与传统数据中心组成一个按需定制的网络环境,实现应用的平滑迁移上云。 专有网络VPC可以与 专线 和VPN 连接方式组合来实现该架构(需要让专有网络VPC与传统数据中心实现内网访问)
290.OSS分享链接采用的安全机制是: 在管理控制台中获取文件访问URL时设置分享链接有效时间,超过设定时间就无法下载
291.OSS与自建存储相比的优点: 海量存储、低成本、安全、多线BGP接入
292.对象是OSS存储数据的基本单元,也称为OSS的文件。对象由元信息ObjectMeta 用户数据Data 和文件名Key组成
293.VPC:使用了隧道技术,每个VPC都有一个独立的隧道号,一个隧道号对应着一张虚拟化网络,达到与传统VLAN方式类似的隔离效果。
294.使用阿里云的高速通道可以实现专有网络VPC之间的互联和私网通信。 高速通道(Espress Connect)是一款基于IPVPN的便捷高效的网络服务,用于在云商的不同网络环境间是想高速、稳定、安全的私网通信,包括跨地域、跨用户的VPC内网互通。专线接入等场景,有效的帮助提高网络拓扑的灵活性和跨网络通信的质量和安全性。 VPC中的ECS不可以和经典网络的ECS实现高效通道的通信。
295.NetworkManager服务来实现网络的配置和管理,Networkmanager服务启动以后可能会导致系统内部的网络配置出现紊乱
296.SLB支持的负载均衡的策略:轮询、加权轮询(WRR) 加权最小连接数(WLC)
297.在对阿里云的云服务器ECS实例进行续费操作时还可以做一些云服务器变配的操作, 修改配置操作完成后,必须通过管理控制台重启实例或使用RebootInstance接口重启实例,新配置才能生效。而非操作系统内重启。
298.WAF解释为WEB应用防护系统(也称 网络应用级入侵防御系统 Web Application Firewall,WAF) DDoS高防IP也是支持Web应用DDoS攻击防护,支持过滤多种flood,高频攻击等攻击,支持HTTP特征过滤、URI过滤、host过滤。
299.在阿里云上创建专有网络VPC时,VPC会自动为用户创建1条系统路由,这条路有的作用是:用于专有网络内的云产品实例访问专有网络外的云服务(该云服务支持VPC内的云产品实例直接访问) 以100.64.0.0/10为目标网段的路由条目,用于VPC内的云产品通信
300.不同部门使用的子系统应该根据不同子系统的应用配置不同的安全组,每个子系统的安全组分开配置,这样方便日后的维护管理。
301.OSS默认支持三份副本,通过校验保证三份副本一致,单副本损坏或丢失,会触发拷贝,保持三份
302.OSS支持的文件上传方法: 从OSS管理控制台直接上传 通过OpenAPI上传 通过SDK上传 通过云市场里的FTP工具上传
303.对象存储OSS的防盗链是基于HTTP或HTTPS 的header中包含Referer字段来实现的
304.CDN缓存是为了加速页面的访问,CDN提供的刷新缓存鹅方法:目录刷新、URL预热、URL刷新
305.SLB不需要购买设备,同事支持同城容灾。结合云盾提供免费的5G防DDoS攻击能力;负载均衡SLB的作用就是为了解决单台服务器单点问题,负载均衡后台多台ECS同事对外提供服务从而扩展了应用的服务能力,增强了应用的可用性,SLB实例的收费不仅有流量费 还有实例费、规格费
306.路由器是支持根据具体的路由条目的设置来转发网络流量。 VPC中的路由器都是随VPC的生命周期自动创建和删除的,用户不需要手动操作
307.阿里云多线BGP(中国电信、联通、移动、教育网等)接入,确保全国用户访问畅通,提升用户访问的质量。
308.操作系统级别监控指标包含 内存使用率、平均负载、磁盘IO读写、磁盘使用率 TCP连接数、进程总数等。
309.一个ECS实例最富哦能挂载16块云盘作数据盘用,并不支持无上限的增加数据盘
310.ECS升级CPU或内存等配置需要重启才可享受升级后的配置。
311.安骑士的功能点:防止密码破解
312.SSD云盘的顺序读写的IOPS都比普通云盘要高,以及访问延时很低
313.访问次数(VV):记录所有访客1天内访问了多少次您的网站,相同的访客有可能多次访问您的网站。 独立访客(UV):1天内相同访客多次访问网站,只计算为1个独立访客。 网站浏览量(PV):用户每打开一个页面便记录1次PV 独立IP(IP):同一IP无论访问了几个页面,独立IP数均为1
访问次数(VV) 名词:VV = Visit View(访问次数) 说明:从访客来到您网站到最终关闭网站的所有页面离开,计为1次访问。若访客连续30分钟没有新开和刷新页面,或者访客关闭了浏览器,则被计算为本次访问结束。
独立访客(UV) 名词:UV= Unique Visitor(独立访客数) 说明:1天内相同的访客多次访问您的网站只计算1个UV。以cookie为依据
网站浏览量(PV) 名词:PV=PageView (网站浏览量) 说明:指页面的浏览次数,用以衡量网站用户访问的网页数量。多次打开同一页面则浏览量累计;
独立IP(IP) 名词:IP=独立IP数 说明:指1天内使用不同IP地址的用户访问网站的数量。
314.黑洞是指服务器受攻击流量超过本机房黑洞阈值时,阿里云屏蔽服务器的外网访问。本服务器进入黑洞一段时间后,如果系统监控到攻击流量停止,黑洞会自动解封。
315.云盾反欺诈服务是阿里巴巴的数据风控服务能力开发的
316.SLB支持同一Region跨数据中心容灾,还可以通过与DNS服务结合支持跨Region容灾
317.手动修改ECS实例的公网IP后,该ECS实例的网络通信会受到影响。
318.SLB实例最多对应50ge监听,每个监听可独立设定限定规则
319.公共云计算中使用鹅存储并非是共享存储,而是分布式的私有存储。 阿里云的文件存储(Network Attached Atorage NAS)提供共享存储的服务: 多个云服务器实例可以同时访问同一个共享文件系统 适合跨多个云服务器实例部署的应用程序访问相同数据来源的应用场景 支持主流的应用程序及工作负载可无缝配合使用,无需任何修改即可读写数据
320.阿里云CDN不支持直接对IP地址进行加速,使用内容分发CDN需要在控制台绑定域名。
321.专有网络VPC是一个二层隔离的网络环境,VPN是一种远程访问技术,利用公网假设虚拟专用网络 VPC使用的是二层的隔离技术,VPC中的交换机属于三层的交换机。
322.云服务器ECS实例支持切换交换机,但是不支持切换路由器操作。
323.路由器和交换机的区别: 路由器可以为局域网自动分配IP和虚拟拨号、交换机只是用来分配网络数据的 路由器在网络层,根据IP地址寻址,路由器可以处理“TCP/IP”协议,交换机不行。交换机在中继层,根据“MAC”地址寻址; 路由器可以把一个IP分给多个主机使用,对外IP相同、交换机可以把很多主机连接起来,对外的IP不同; 路由器可以提供防火墙,交换机不能提供这个功能; 交换机是做扩大局域网接入点的,可以让局域网连进更多的电脑、路由器是用来做网间连接,也就是用来连接不同网络的;
324.弹性公网IP的限制有:ECS实例的网络类型必须是专有网络,ECS实例的地域必须和EIP的地域相同。
325.SLB四层流量走默认路由 SLB一般情况下,默认路由在有外网的情况下回先走外网网卡,如无外网则走内网网卡。
326.OSS目前只支持按量付费
327.负载均衡SLB不提供CNAME地址,只提供IP地址。
328.路由器是删除VPC时自动删除的
329.同一个VPC只能创建同一个地域不同可用区的交换机实现可用区容灾,不支持跨VPC创建交换机。
331.敏感信息泄露属于Web应用防火墙的功能,是需要收费的服务
332.在冷却时间内,伸缩组会拒绝由云监控报警任务处罚的伸缩活动请求,但其他类型任务(手动执行任务、定时任务)触发的伸缩活动可以立即执行,绕过冷却时间
333.自定义的监控项的数量的是没有数量限制的,且阿里云提供接口可以给开发者上报数据。
334.回滚磁盘必须要求云盘必须已经 挂载到某台ECS实例上,而且已经停止实例。
335.专有网络VPC里面的交换机支持部署在同一地域的不同可用区,专有网络VPC类型的是咧可以加入同一专有网络VPC下的安全组。
336.专有网络类型的ECS实例只能在创建时指定,这类实例只可以属于的单个虚拟交换机
337.专有网络VPC创建成功之后,CIRDBlock不可以进行修改,交换机创建成功之后,无法修改CIDRBlock,且新建交换机所使用的的CIDPBLock不可以与已经存在的交换机的CIDRBLock重复
338.ISV 独立软件开发商 :从安全的角度考虑 需要考虑 操作规范和角色账号的权限问题
339.CDN节点系统关键组件有: LVS做四层均衡负载;Tengine做七层负载均衡,Swift做Http缓存
340.伸缩组包括:伸缩配置 伸缩规则 伸缩活动
云计算
2019-10-30 13:47:00
2019年10月9日, Rancher 2.3正式发布 ,这是Rancher Labs迄今为止最重要的产品版本。Rancher 2.3是业界首个GA支持Windows容器的Kubernetes管理平台,并正式集成了Istio,还引入了创新的“集群模板”功能以增强企业集群的安全性。这些新功能无疑将极大助力企业充分利用Kubernetes变革性的力量,并为企业生产中落地Kubernetes提供更加便捷的途径,从而进一步实现了Rancher一直以来“Run Kubernetes Everywhere”的理念和战略。
   
在过去的20天里,Rancher Labs的研发及测试团队对Rancher 2.3的性能、稳定性、安全性以及功能性等进行了大量的测试和优化,今天上午8时,正式发布了Rancher 2.3.2版本,在这一版本中新增了Istio网关功能、GA了Kubernetes 1.16版本。这是Rancher 2.3.x第一个stable的版本,这意味着它是Rancher官方推荐所有用户可用于生产环境的稳定版本!
   
Rancher 2.3功能亮点
 
首个GA支持Windows容器的K8s管理平台
 
Rancher 2.3是市场上管理基于Windows Server容器的首批解决方案之一 ,通过把Kubernetes的所有优势引入Windows,Rancher 2.3极大降低了企业使用Windows容器的复杂性,并为基于Windows遗留应用程序的现代化提供快捷的途径——无论这些程序是在本地运行还是在多云环境中运行。此外,Rancher 2.3还可以将它们容器化并将其转换为高效、安全和可迁移的多云应用程序,从而省去重写应用程序的工作。
 
正式集成Istio
 
Istio,作为业界领先的服务网格,让开发人员无需编写特定代码,即可启用Kubernetes的关键功能,包括容错、金丝雀发布、A / B测试、监控和指标、追踪和可观察性以及身份验证和授权。Rancher 2.3正式完成了对Istio的集成,极大简化了Istio的安装和配置,Rancher中现已内置支持:
  用于流量和遥测可视化的Kiali仪表板 用于追踪的Jaeger 用于监控和可观察性的Prometheus和Grafana
 
通过“集群模板”功能增强Kubernetes安全性
 
Rancher 2.3引入了创新的“集群模板”这一功能。它可以让企业在整个基础架构中实施一致的集群配置,进而帮助企业降低安全风险。具体而言,通过使用集群模板:
  运维人员可以在其所有集群部署中创建、保存并放心使用经过良好测试的Kubernetes配置。 管理员可以启用配置强制实施,从而抑制配置漂移或不当的配置错误。如果创建更多的集群,这些配置不当可能会带来安全风险。
 
Rancher 2.3.2版本重点
 
Kubernetes 1.16 GA
 
Kubernetes 1.16现在已经GA,但是由于Kubernetes 1.16版本中弃用了之前版本的部分旧API,因此Kubernetes 1.16还不是不是默认版本。
 
增加Istio网关,虚拟服务和目标规则的UI
 
添加了通过UI添加Istio网关的功能,Istio的UI已经成为GA版本。默认情况下,可以通过Istio的UI使用虚拟服务和目标规则的功能。
 
修复了一些重要的Bug
  修复了使用TLS最为HTTPS终止时,HA升级由于在旧版本中生成错误的证书而导致HA升级失败的问题 [#23441] 修复了设置runAsNonRoot [#20884] 时无法启动监控的问题 修复了证书格式错误的项目无法再在UI中加载的问题 [#23285] 修复了readiness无法在Kubernetes 1.15和1.16版本的集群上 [#23430] 进行准备就绪探测的问题 修复了rancher/cli2:v2.3.0镜像无法正常工作的问题 [#23433]
 
升级与更新
 
更多关于Rancher 2.3.2中问题修复、升级与回滚,请参阅Github链接:
https://github.com/rancher/rancher/releases/tag/v2.3.2
 
Rancher企业级订阅客户如果对Rancher 2.3.2有任何疑问或希望对现有Rancher版本进行平滑升级,欢迎联系我们的Rancher Support技术团队。如果想咨询或购买企业级订阅支持,欢迎联系我们!
 
微信:rancher2
邮箱:yiyi@rancher.com
电话:0755-86966507 欢迎添加小助手(wx:rancher2),进官方技术群,了解更多Kubernetes使用攻略
云计算
2019-10-30 10:25:00
在对应用程序进行重构和更新的过程中,往往会出现一些挑战。更新应用程序的频率越高,复杂性就越是会增加。让应用程序在容器平台上运行,并且它们之间可以互相通信和连接,是通向模块化的、灵活的微服务架构的必经之路。但是微服务的这种灵活性也让其变得更加复杂。这时就轮到Service Mesh发挥作用了!
Service Mesh向企业提供了他们所需要的中心化控制面板,同时依然能够使用灵活的、基于云的应用程序开发方式。我们可以把Service Mesh看成是用于微服务API的专门的第7层网格,它提供身份验证、授权、安全和性能服务来优化服务之间的“east/west”流量。更重要的是,它能为你提供应用到这些策略的中心点,而不需要直接将所有这些编码到应用程序的业务逻辑中。
简单的Service Mesh类比
Service Mesh就像是城市的水管网络。你的团队控制着这些管道,根据需要连接它们并设置它们之间所有的流控制。无论是何种类型或用途,又或是Service Mesh所支持的应用程序的需求在不断变化,数据都可以通过你的系统进行传递。
这种流量控制可以在中心位置进行,也正是在中心位置构建规则,来管理那些相互连接的数据流。这就像是在天上的巨大控制室一样,你可以在农作物需要额外资源时,给加利福尼亚州的土地浇水,又或是迈阿密那边湿的太透了,你可以排干它们。最重要的一点是,这些操作都是可以自动执行并且动态调整的。
Service Mesh增强了可靠性和可视化能力
Service Mesh提供从网络或服务故障处自动恢复过来的智能流量路由功能,这样就可以追踪到整个堆栈的问题,甚至能追踪到服务间的中断。
如果服务器没有响应,你的服务网格将会把它从单个服务、或者是活跃的、负载均衡的服务池中剔除掉,转移到另一个池中,该池经常会检查是否可运行。当该服务器在合理的时间范围内开始响应时,它又会被自动push回活跃的负载均衡池中。
通过提供服务层系统各个方面的可视化,Service Mesh还可以用来debug和优化系统。这样微服务中的脏水问题(murky water)就解决了。随着时间推移,系统可以进行调整来扩展功能,满足性能和稳定性的需求。
Service Mesh保护服务间通信
当你的团队推出应用程序的新版本,或是要将应用程序托管的集群迁移到新的数据中心时,安全团队通常需要重新颁发证书并授权给系统中新的服务器。这会花费大量的时间和精力,是推动生产改进的阻碍。
有了服务网格,将服务间通信的安全性交给网格处理,这些关注点从应用程序本身抽象了出来,由服务网格处理所有这些限制,比如哪些服务可以相互通信、哪些系统可以访问哪些服务,以及哪些用户可以访问哪些服务。因此,升级网格中的应用程序不需要重新分配安全资源。
这样一来,还可以让围绕网络和服务间通信的安全问题能从任何内部开发的业务逻辑中独立出来。如果网络组建出现安全漏洞,服务网格会去处理围绕安全更新的更改,而不是重新架构每个应用程序。这就消除了在进行安全更改和更新相关工作时出现的大量停机时间。
研究大型微服务环境下的服务网格
不过服务网格有一个(巨大的)潜在的缺点。它添加了额外的容器,事实上,它让容器规模加倍了。大多数服务网格的实现使用了sidecar代理,将一个代理实例和每个容器绑定的微服务耦合在一起。这样一来,它所带来的好处大于运营成本,这也意味着服务网格对于小型环境来说通常过于庞大了。
但是,如果你正在管理数十个甚至数百个独立的微服务,不妨考虑服务网格。有了服务网格,你的团队可以更好的跟踪问题,确保服务的可用性,维护路由表的正确分布。对这些大型环境,无论是在公共云、在你的企业数据中心、还是在混合云的实现上,它们是云应用程序难题的最后一块拼图,也是将你的整个产业联系在一起的关键部分。
云计算
2018-12-28 13:00:00
DatwWorks终于升级2.0了,心情万分激动之余,又有一丝担忧。因为,没法再创建新的旧版工作流了。。。
新版抛弃了 “工作流” 这个概念,引入了 “业务流程” 和 “解决方案” 两个新的概念。于是,作为团队Leader,我花了很大的精力去钻研这两个概念到底该如何应用在我的实际业务中。
1.目的
能尽快应用DataWorks2.0的诸多给力新功能;
尽快解决掉由于无法新建旧版工作流引起的不便;
2.旧版工作流划分
任务节点一般分为以下几类: 源数据同步节点 单业务基础数据层统计节点 跨业务基础数据层统计节点 结果数据层统计节点 结果数据同步节点
2.1 划分维度
旧版本的工作流,主要包含以下几个维度:
2.1.1 源数据库 数据源是在哪个数据库中 包括:源数据同步节点
2.1.2 产品线 源数据属于哪个产品线 包括:源数据同步节点 + 单业务基础数据层统计节点
2.1.3 目标系统 结果数据是给哪个系统提供的(后台系统、BI、DataV、……) 包括:结果数据层统计节点 + 结果数据同步节点
2.1.4 业务模块 结果数据属于哪个业务模块(订单+投诉、订单+保险、商家+订单、……) 包括:跨业务基础数据层统计节点 + 结果数据层统计节点 + 结果数据同步节点
2.1.5 运行周期 每日、每周、每月运行 包括:所有节点
2.1.6 输入/统计/输出 包含的节点的类型,是属于“源数据迁入”、“统计任务”还是“结果数据迁出” 包括:所有节点
2.2 其他划分原则 尽量减少每个工作流所依赖的上游工作流的个数; 能用一句话给整个工作流起个名字; 每个工作流内的节点数量不超过30个;
3. 旧版工作流与新版业务流程的区别
3.1 运行周期 旧版工作流:
整个 工作流(包含多个内部节点),对应一个运行周期 新版业务流程:
每个 节点,对应一个运行周期
3.2 依赖关系 旧版工作流: 工作流依赖工作流; 内部节点依赖内部节点; 新版业务流程: 业务流程之间,无依赖关系; 节点依赖节点,可以跨业务流程依赖,可以不同运行周期的任务间依赖。
3.3 节点的分类 旧版工作流:
无分类 ,只能通过内部节点的命名来区分 新版业务流程:
可以自动 按节点类型 分类(SQL节点、数据同步节点、机器学习节点、……)
3.4 工作流(业务流程)的分类 旧版工作流:
无分类 ,只能通过工作流的命名来区分 新版业务流程:
可以通过“解决方案”功能来分类(类似于给每个业务流程 打标签 ),“业务流程”与“解决方案”是“多对多”的关系。
3.5 提交范围 旧版工作流:
整个 工作流(包含多个内部节点)一起提交 新版业务流程:
单个 任务节点提交。也支持业务流程中多个节点批量提交的方式。
3.6 重命名 旧版工作流: 工作流 不支持 重命名; 内部节点 不支持 重命名; 新版业务流程: 业务流程 支持 重命名; 节点 支持 重命名;
3.7 添加文件夹的位置 旧版工作流:
多级文件夹 →工作流→内部节点 新版业务流程:
业务流程→数据集成/数据开发→ 多级文件夹 →节点
4. 业务流程划分原则
最后,关于我的业务流程的划分原则,总结如下: 业务流程是完成一个最小业务的; 业务流程的数量可以稍微多一点儿,可以通过解决方案去查找; 每个业务流程里的节点最好不要太多,每个业务流程里能直观展示的就只有那么多;
希望大家也能早日用上DataWorks2.0的诸多给力功能!不用继续在旧版工作流中缝缝补补。
作者: neo.wang
原文链接
本文为云栖社区原创内容,未经允许不得转载。
云计算
2018-12-27 15:44:00
小文件背景知识
小文件定义
分布式文件系统按块Block存放,文件大小比块大小小的文件(默认块大小为64M),叫做小文件。
如何判断存在小文件数量多的问题
查看文件数量 desc extended + 表名
判断小文件数量多的标准
1、非分区表,表文件数达到1000个,文件平均大小小于64M
2、分区表: a) 单个分区文件数达到1000个,文件平均大小小于64M,
b) 整个非分区表分区数达到五万 (系统限制为6万)
产生小文件数量多的主要原因
1、表设计不合理导致:分区多导致文件多,比如按天按小时按业务单元(假如有6个业务单元BU)分区,那么一年下来,分区数将会达到365 24 6=52560。
2、在使用Tunnel、Datahub、Console等数据集成工具上传上传数据时,频繁Commit,写入表(表分区)使用不合理导致:每个分区存在多个文件,文件数达到几百上千,其中大多数是大小只有几 k 的小文件。
3、在使用insert into写入数据时过,几条数据就写入一次,并且频繁的写入。
4、Reduce过程中产生小文件过多。
5、Job执行过程中生成的各种临时文件、回收站保留的过期的文件过多。
注意:虽然在MaxCompute系统侧会自动做小文件合并的优化,但对于原因1、2、3需要客户采用合理的表分区设计和上传数据的方法才可以避免。
小文件数量过多产生的影响
MaxCompute处理单个大文件比处理多个小文件更有效率,小文件过多会影响整体的执行性能;小文件过多会给文件系统带来一定的压力,且影响空间的有效利用。MaxCompute对单个fuxi Instance可以处理的小文件数限制为120个,文件数过多影响fuxi instance数目,影响整体性能。
合并小文件命令 set odps.merge.max.filenumber.per.job=50000; --值默认为50000个;当分区数大于50000时需要调整,最大可到1000000万,大于1000000的提交多次merge ALTER TABLE 表名[partition] MERGE SMALLFILES;
如何合并小文件
分区表:
如果您的表已经是分区表,请检查您的分区字段是否是可收敛的,如果分区数过多同样会影响计算性能,建议用日期做分区。
1、定期执行合并小文件命令;
2、如果是按日期建的分区,可以每天对前一天的分区数据用insert overwrite重新覆盖写入。
例如: insert overwrite table tableA partition (ds='20181220') select * from tableA where ds='20181220';
非分区表:
如果您的表是非分区表,您可以定期执行合并小文件命令来优化小文件问题,但强烈建议您设计成分区表:
1、先创建一个新的分区表,建议按日期做分区,合理设置生命周期,以方便进行历史数据回收;
2、把原非分区表的数据导入新的分区表;(建议先暂停原非分区表的实时写入业务)
例如: create table sale_detail_patition like sale_detail; alter table sale_detail_insert add partition(sale_date='201812120', region='china'); insert overwrite table sale_detail_patition partition (sale_date='20181220', region='china') select * from sale_detail;
3、修改上下游业务:入库程序改成写入新分区表,查询作业改成从新分区表中查询;
4、新分区表完成数据迁移和验证后,删除原分区表。
注意:如果您使用insert overwrite重新写入全量数据合并小文件时,请注意一定不要同时存在insert overwrite和insert into同时存在的情况,否则有丢失数据的风险。
如何避免产生小文件
优化表设计
合理设计表分区,分区字段是尽量是可收敛或可管理的,如果分区数过多同样会影响计算性能,建议用日期做分区,并合理设置表的生命周期,以方便对历史数据回收,也可控制您的存储成本。
参考文章: 《MaxCompute 表(Table)设计规范》 、 《MaxCompute表设计最佳实践》
避免使用各种数据集成工具产生小文件
1、Tunnel->MaxCompute
使用Tunnel上传数据时避免频繁commit,尽量保证每次提交的DataSize大于64M,请参考 《离线批量数据通道Tunnel的最佳实践及常见问题》
2、Datahub->MaxCompute
如果用Datahub产生小文件,建议合理申请shard,可以根据topic的Throughput合理做shard合并,减少shard数量。可以根据topic的Throughput观察数据流量变化,适当调大数据写入的间隔时间。
申请Datahub shard数目的策略(申请过多的datahub shard将会产生小文件问题)
1)默认吞吐量单个shard是1MB/s,可以按照这个分配实际的shard数目(可以在此基础上多加几个);
2)同步MaxCompute的逻辑是每个shard有一个单独的task(满足5分钟或者64MB会commit一次),默认设置5分钟是为了尽快能在MaxCompute查到数据。如果是按照小时建partition,那个一个shard每个小时有12个文件。如果这个时候数据量很少,但是shard很多,在MaxCompute里面就会很多小文件(shard*12/hour)。所以不要过多的分配shard,按需分配。
参考建议:​​如果流量是5M/s,那么就申请5个shard,为预防流量峰值预留20%的Buffer,可以申请6个shard。
3、DataX->MaxCompute
因为datax也是封装了tunnel的SDK来写入MaxCompute的,因此,建议您在配置ODPSWriter的时候,把blockSizeInMB这个参数不要设置太小,最好是64M以上。
作者: 云花
原文链接
本文为云栖社区原创内容,未经允许不得转载。
云计算
2018-12-27 15:14:00
MaxCompute/DataWorks权限问题排查建议 __前提:__MaxCompute与DataWorks为两个产品,在权限体系上既有交集又要一定的差别。在权限问题之前需了解两个产品独特的权限体系。
MaxCompute:计算引擎
MaxCompute底层计算引擎有自己的安全权限体系,包括ACL、Policy授权体系。具体可以了解: https://help.aliyun.com/document_detail/27924.html
DataWorks:数据工场
DataWorks为MaxCompute上层的云数仓开发工具,拥有自身的权限模型外还支持底层MaxCompute底层数据授权体系。具体详见: https://help.aliyun.com/document_detail/92594.html
查看MaxCompute上的角色
通过MaxCompute Console命令list roles;可以看到角色体系,role_开头都为DataWorks基于MaxCompute封装的角色及权限体系。介绍如下:
rolename 对应产品及权限名称
admin MaxCompute底层引擎默认admin角色
role_project_admin DataWorks项目管理员
role_project_deploy DataWorks部署角色
role_project_dev DataWorks开发角色
role_project_guest DataWorks访客角色
role_project_pe DataWorks运维角色
role_project_scheduler
role_project_security
DataWorks生产代持账号
DataWorks安全管理员
__admin:__MaxCompute计算引擎的默认admin角色, 可以访问项目空间内的所有对象、对用户或角色进行管理、对用户或角色进行授权。与项目空间 Owner 相比, admin 角色不能将 admin 权限指派给用户 ,不能设定项目空间的安全配置,不能修改项目空间的鉴权模型,admin 角色所对应的权限不能被修改 。一般情况下,如未修改过权限,一般情况下admin角色用户只有一个为project owner账号。 odps@ clouder_bi>describe role admin; [users] ALIYUN$***@aliyun-test.com Authorization Type: Admin MaxCompute project owner可以将admin角色授予其他子账号,用于进行MaxCompute底层的权限模型管理。 role_开头的角色也可以通过describe role 方式查看其角色所具备的权限点及角色里的用户列表。以开发者角色为例: odps@ clouder_bi>describe role role_project_dev; [users] RAM$yangyi.pt@aliyun-test.com:yangyitest Authorization Type: Policy A projects/clouder_bi: * A projects/clouder_bi/instances/*: * A projects/clouder_bi/jobs/*: * A projects/clouder_bi/offlinemodels/*: * A projects/clouder_bi/packages/*: * A projects/clouder_bi/registration/functions/*: * A projects/clouder_bi/resources/*: * A projects/clouder_bi/tables/*: * A projects/clouder_bi/volumes/*: *
排查问题建议:
在普及完两个产品的权限体系之外,更多的用户会遇到各种权限的疑问或者问题。通常可以通过如下方式来排查: 首先,查看当前用户或指定用户所拥有的权限。 show grants; --查看当前用户自己的访问权限 show grants for ; --查看指定用户的访问权限,仅由ProjectOwner和Admin才能有执行权限 。 show grants for RAM$主帐号:子帐号;
可以看到用户所具有的角色及相关权限点。 查看指定对象的授权列表,一般获取表到人。 show acl for [on type ];--查看指定对象上的用户和角色授权列表 支持的objecTtype: PROJECT, TABLE, JOB, VOLUME, INSTANCE, RESOURCE, FUNCTION,PACKAGE,TOPOLOGY,MATRIX,XFLOW,OFFLINEMODEL,STREAMJOB
查看ACL是否生效(常常发生在授权之后返回OK,但是权限校验还是失败) show SecurityConfiguration;--查看项目空间的安全配置
除了通过命令行方式,也可以通过__ ++ DataWorks>项目管理>MaxCompute高级配置 ++ __里的ACL开关来确认是否打开。
Policy授权的查询
policy授权一般常见有两种,一个是项目级别的,一个是role级别的。 get policy;--获取项目级别的policy配置; get policy on role ;--获取指定的role policy设置。
作者: 祎休
原文链接
本文为云栖社区原创内容,未经允许不得转载。
云计算
2018-12-27 14:41:00
基本介绍
Aliplayer提供了缩略图的功能,让用户在拖动进度条之前知道视频的内容,用户能够得到很好的播放体验,缩略图是显示在Controlbar的上面,并且包含当前的时间,阿里云的媒体处理服务提供接口可以生成缩略图的功能, 先看一下基本的效果:
缩略图的格式
WebVTT介绍
缩略图采用了webvtt的文件格式去表示时间和显示图片的对应关系,WebVTT不仅可读性好,而且解析也比较容易,下面是一个27秒包含3个截图的WebVTT文件内容:
WEBVTT 00:00.000 --> 00:09.174 vM7nH0Kl-120.jpg?xywh=0,0,120,53 00:09.174 --> 00:18.348 vM7nH0Kl-120.jpg?xywh=120,0,120,53 00:18.348 --> 00:27.523 vM7nH0Kl-120.jpg?xywh=240,0,120,53
WebVTT是UTF-8编码格式的文本文件,主要如下: 第一行必需是WEBVTT,表明这是个WebVTT文件文件。 接着是一空行,后面就是时间范围和要显示的缩略图,时间格式是HH:MM:SS.sss,时:分:秒.毫秒, 开始时间 --> 结束时间,-->的两边各有一个空格,这两个时间必需写在同一行,并且时间都是相对于视频开始的时间间隔。 时间之后是缩略图的地址,时间和缩略图的地址之间不能有空行,缩略图的描述主要包含图片的地址,地址后面的xywh参数描述图片的显示位置和大小。
图片地址说明
缩略图可以是多张图片,也可以是雪碧图方式拼成的一张大图 ,雪碧图的优点是可以减少图片的请求数和减少图片显示的延迟时间等。
图片地址的基本格式:{imgUrl}?xywh=x,y,w,h, 参数说明:
名称 说明 x 水平位置,左上角是0,雪碧图时使用
y 垂直位置,左上角是0,雪碧图时使用
w
h
图片的显示宽度
图片的显示高度
独立图片的地址格式
每个地址都是不一样的, 参数只需要指定图片的显示宽度和高度,比如:
WEBVTT 00:00.000 --> 00:09.174 vM7nH0Kl-120.jpg?wh=120,53 00:09.174 --> 00:18.348 vM7nH0Kl-121.jpg?wh=120,53
雪碧图的地址格式
每个地址都使用同一个图片的地址,通过参数指定要显示的图片位置和大小,比如下面的雪碧图:
下面的描述对应的是第一张和第二张图的位置和大小
WEBVTT 00:00.000 --> 00:09.174 vM7nH0Kl-120.jpg?xywh=0,0,120,53 00:09.174 --> 00:18.348 vM7nH0Kl-120.jpg?xywh=120,0,120,53
Aliplayer的使用
Aliplayer可以独立的使用缩略图的功能,用户只需要指定WebVTT的地址,当然也可以和阿里云的媒体处理服务(MPS)结合使用,通过媒体处理服务生成缩略图,当通过videoId方式播放时,播放器会自动获取缩略图的地址,解析,然后显示。
如何生成缩略图
生成缩略图可以调用阿里云的媒体处理服务的截图功能,生成缩略图,仅支持HLS的视频格式,具体的接口地址: 如何设置截图
VideoId方式播放
媒体处理服务生成缩略图以后可以通过VideoId的方式播放,播放器会自动从云端获取缩略图地址、获取内容、解析、显示,代码如下:
let player = new Aliplayer({ id: 'J_prismPlayer', width: '100%', height: '100%', autoplay: true, vid : '1e067a2831b641db90d570b6480fbc40', accId: '', accSecret: '', stsToken: '', domainRegion: '', authInfo: '', });
媒体处理播放方式的详细文档参考: MPS播放说明
自己指定WebVTT地址
Aliplayer提供了thumbnailUrl属性用于指定WebVTT的地址,这种方式对于视频格式就没有要求了, 当用户由于特殊原因不能使用videoId的方式播放视频时,可以自己获取WebVTT的缩略图地址,通过thumbnailUrl属性指定,代码如下:
let player = new Aliplayer({ id: 'J_prismPlayer', width: '100%', height: '100%', autoplay: true, soruce:'https://player.alicdn.com/resource/player/qupai.mp4', thumbnailUrl:'http://100.69.163.12/vM7nH0Kl-120.vtt' });

作者: nahom
原文链接
本文为云栖社区原创内容,未经允许不得转载。
云计算
2019-01-09 16:19:00