kubernetes 简介

kubernetes 网上的资料良莠不均,刚开始表示完全不知道从何入手。最近在入门中,将一些资料做了整理,精简了大部分得出了这一篇文章。可以参照文末参考资料查看原文。当前最新版的k8s版本为:1.10.

一 什么是Kubernetes?

Kubernetes(k8s)是 google 开源的一套自动化容器管理平台,前身是 Borg,用于容器的部署、自动化调度和集群管理。

为什么使用容器?

传统的应用部署方式是通过插件或脚本来安装应用。这样做的缺点是应用的运行、配置、管理、所有生存周期将与当前操作系统绑定,这样做并不利于应用的升级更新/回滚等操作,当然也可以通过创建虚机的方式来实现某些功能,但是虚拟机非常重,并不利于可移植性。

新的方式是通过部署容器方式实现,每个容器之间互相隔离,每个容器有自己的文件系统 ,容器之间进程不会相互影响,能区分计算资源。相对于虚拟机,容器能快速部署,由于容器与底层设施、机器文件系统解耦的,所以它能在不同云、不同版本操作系统间进行迁移。

为什么使用容器

kubernetes能做什么?

Kubernetes能提供一个以“容器为中心的基础架构”,可以在物理或虚拟机的Kubernetes集群上运行容器化应用,满足在生产环境中运行应用的一些常见需求:负载均衡、服务发现、高可用、滚动升级、自动伸缩等。

kubernetes不能做什么?

  • Kubernetes不提供中间件(如message buses)、数据处理框架(如Spark)、数据库(如Mysql)或者集群存储系统(如Ceph)作为内置服务。但这些应用都可以运行在Kubernetes上面。
  • Kubernetes 不部署源码不编译应用。持续集成的 (CI)工作流方面,不同的用户有不同的需求和偏好的区域,因此,我们提供分层的 CI工作流,但并不定义它应该如何工作。
  • Kubernetes 允许用户选择自己的日志、监控和报警系统。
  • Kubernetes 不提供或授权一个全面的应用程序配置 语言/系统。
  • Kubernetes 不提供任何机器配置、维护、管理或者自修复系统。

Kubernetes是什么意思?

Kubernetes 实际上是一个希腊词κυβερνήτης, 意思是”船的舵手”。K8s是将中间8个字母“ubernete”替换为“8”的缩写。

二 Kubernetes 架构

一个K8s集群是由分布式存储(etcd)、服务节点(Node)和控制节点(Master)构成的。所有的集群状态都保存在etcd中,Master节点上则运行集群的管理控制模块。Node节点是真正运行应用容器的主机节点,在每个Minion节点上都会运行一个Kubelet代理,控制该节点上的容器、镜像和存储卷等。

Master 节点::

Master 是 Kubernetes Cluster 的大脑,运行着如下 Daemon 服务:

  • kube-apiserver

    Kubernetes Cluster 的前端接口,各种客户端工具(CLI 或 UI)以及 Kubernetes 其他组件可以通过它管理 Cluster 的各种资源。

  • kube-scheduler

    负责决定将 Pod 放在哪个 Node 上运行。Scheduler 在调度时会充分考虑 Cluster 的拓扑结构,当前各个节点的负载,以及应用对高可用、性能、数据亲和性的需求。

  • kube-controller-manager

    负责管理 Cluster 各种资源,保证资源处于预期的状态。

  • etcd

    负责保存 Kubernetes Cluster 的配置信息和各种资源的状态信息。当数据发生变化时,etcd 会快速地通知 Kubernetes 相关组件。

  • Pod 网络

    Pod 要能够相互通信,Kubernetes Cluster 必须部署 Pod 网络,flannel 是其中一个可选方案。

Node节点:

Node 是 Pod 运行的地方,Kubernetes 支持 Docker、rkt 等容器 Runtime。 Node上运行的 Kubernetes 组件有

  • kubelet

    kubelet 是 Node 的 agent,当 Scheduler 确定在某个 Node 上运行 Pod 后,会将 Pod 的具体配置信息(image、volume 等)发送给该节点的 kubelet,kubelet 根据这些信息创建和运行容器,并向 Master 报告运行状态。

  • kube-proxy

    service 在逻辑上代表了后端的多个 Pod,外界通过 service 访问 Pod。

    kube-proxy 就是负责将访问 service 的 TCP/UPD 数据流转发到后端的容器。如果有多个副本,kube-proxy 会实现负载均衡。

  • Pod 网络

K8s在实现上述架构时基于以下架构理念:

  • 只有API Server与存储通信,其他模块通过API Server访问集群状态。这样第一,是为了保证集群状态访问的安全。第二,是为了隔离集群状态访问的方式和后端存储实现的方式:API Server是状态访问的方式,不会因为后端存储技术etcd的改变而改变。加入以后将etcd更换成其他的存储方式,并不会影响依赖依赖API Server的其他K8s系统模块。
  • 一个工作节点被攻破不能导致整个K8s集群被攻破。这是所有分布式系统架构设计中都应该考虑的问题。
  • 考虑网络随时可能断开的情况,没有新配置声明时各模块按照之前的配置声明继续工作。在K8s集群中,所有的配置管理操作都声明式而非命令式的,因为声明式操作对于网络故障等分布式系统常见的故障情况更加稳定。
  • 各个模块在内存中缓存自己的相关状态以提高系统性能。
  • 需要监控某个系统状态来做下一步动作的时候,优先考虑观察通知模式,其次再考虑轮询模式,这也是为了提高系统的响应速度。

分层架构

Kubernetes设计理念和功能其实就是一个类似Linux的分层架构,如下图所示

img

  • 核心层:Kubernetes最核心的功能,对外提供API构建高层的应用,对内提供插件式应用执行环境
  • 应用层:部署(无状态应用、有状态应用、批处理任务、集群应用等)和路由(服务发现、DNS解析等)
  • 管理层:系统度量(如基础设施、容器和网络的度量),自动化(如自动扩展、动态Provision等)以及策略管理(RBAC、Quota、PSP、NetworkPolicy等)
  • 接口层:kubectl命令行工具、客户端SDK以及集群联邦
  • 生态系统:在接口层之上的庞大容器集群管理调度的生态系统,可以划分为两个范畴
    • Kubernetes外部:日志、监控、配置管理、CI、CD、Workflow、FaaS、OTS应用、ChatOps等
    • Kubernetes内部:CRI、CNI、CVI、镜像仓库、Cloud Provider、集群自身的配置和管理等

Kubernetes的核心技术概念

API对象是K8s集群中的管理操作单元。K8s集群系统每支持一项新功能,引入一项新技术,一定会新引入对应的API对象,支持对该功能的管理操作。

每个API对象都有3大类属性:

  • 元数据metadata,用来标识API对象,每个对象都至少有3个元数据:namespace,name和uid。

    除此以外还有各种各样的标签labels用来标识和匹配不同的对象,例如用户可以用标签env来标识区分不同的服务部署环境,分别用env=dev、env=testing、env=production来标识开发、测试、生产的不同服务。

  • 规范spec

    规范描述了用户期望K8s集群中的分布式系统达到的理想状态(Desired State),例如用户可以通过复制控制器Replication Controller设置期望的Pod副本数为3。

  • 状态status

    status描述了系统实际当前达到的状态(Status),例如系统当前实际的Pod副本数为2;那么复制控制器当前的程序逻辑就是自动启动新的Pod,争取达到副本数为3。

K8s中所有的配置都是通过API对象的spec去设置的,也就是用户通过配置系统的理想状态来改变系统,这是k8s重要设计理念之一,即所有的操作都是声明式(Declarative)的而不是命令式(Imperative)的。

声明式操作在分布式系统中的好处是稳定,不怕丢操作或运行多次,例如设置副本数为3的操作运行多次也还是一个结果,而给副本数加1的操作就不是声明式的,运行多次结果就错了。

概念

  1. Pod

    Pod是在K8s集群中运行部署应用或服务的最小单元,每个 Pod 包含一个或多个容器。Pod 中的容器会作为一个整体被 Master 调度到一个 Node 上运行。

  2. Controller

Kubernetes 通常不会直接创建 Pod,而是通过 Controller 来管理 Pod 的。Controller 中定义了 Pod 的部署特性,比如有几个副本,在什么样的 Node 上运行等。为了满足不同的业务场景,Kubernetes 提供了多种 Controller。

  • Deployment 管理 Pod 的多个副本,并确保 Pod 按照期望的状态运行。
  • ReplicaSet 实现了 Pod 的多副本管理。
  • DaemonSet 用于每个 Node 最多只运行一个 Pod 副本的场景。
  • StatefuleSet 保证 Pod 的每个副本在整个生命周期中名称是不变的。而其他 Controller 不提供这个功能,当某个 Pod 发生故障需要删除并重新启动时,Pod 的名称会发生变化。同时 StatefuleSet 会保证副本按照固定的顺序启动、更新或者删除。
  • Job :用于运行结束就删除的应用。而其他 Controller 中的 Pod 通常是长期持续运行。
  1. Service

    Deployment 可以部署多个副本,每个 Pod 都有自己的 IP,每次销毁重启时IP都会发生变化。

    而 Service 定义了外界访问一组特定 Pod 的方式。Service 有自己的 IP 和端口,Service 为 Pod 提供了负载均衡。

    Kubernetes 运行容器(Pod)与访问容器(Pod)这两项任务分别由 Controller 和 Service 执行。

  2. Namespace

    Namespace 为K8s集群提供虚拟的隔离作用。Namespace 可以将一个物理的 Cluster 逻辑上划分成多个虚拟 Cluster,每个 Cluster 就是一个 Namespace。不同 Namespace 里的资源是完全隔离的。

用 kubeadm 创建 Cluster

这里只做一些概念描述,具体步骤会再开一篇新文章描述。这部分摘自《部署 k8s Cluster(上)- 每天5分钟玩转 Docker 容器技术(118)》有删减。

  • kubelet 运行在 Cluster 所有节点上,负责启动 Pod 和容器。

  • kubeadm 用于初始化 Cluster。

  • kubectl 是 Kubernetes 命令行工具。

    通过 kubectl 可以部署和管理应用,查看各种资源,创建、删除和更新各种组件。

  1. 初始化master

    kubeadm init --apiserver-advertise-address 192.168.56.105 --pod-network-cidr=10.244.0.0/16
    
    --apiserver-advertise-address 指明用 Master 的哪个 interface 与 Cluster 的其他节点通信。如果 Master 有多个 interface,建议明确指定,如果不指定,kubeadm 会自动选择有默认网关的 interface。
    
    --pod-network-cidr 指定 Pod 网络的范围。Kubernetes 支持多种网络方案,而且不同网络方案对 --pod-network-cidr 有自己的要求,这里设置为 10.244.0.0/16 是因为我们将使用 flannel 网络方案,必须设置成这个 CIDR。在后面的实践中我们会切换到其他网络方案,比如 Canal。
    

    初始化做的事情有:

    ① kubeadm 执行初始化前的检查。

    ② 生成 token 和证书。

    ③ 生成 KubeConfig 文件,kubelet 需要这个文件与 Master 通信。

    ④ 安装 Master 组件,会从 goolge 的 Registry 下载组件的 Docker 镜像,这一步可能会花一些时间,主要取决于网络质量。

    ⑤ 安装附加组件 kube-proxy 和 kube-dns。

    ⑥ Kubernetes Master 初始化成功。

    ⑦ 提示如何配置 kubectl。

    ⑧ 提示如何安装 Pod 网络。

    ⑨ 提示如何注册其他节点到 Cluster。

  2. 配置 kubectl

  3. 安装 Pod 网络

    要让 Kubernetes Cluster 能够工作,必须安装 Pod 网络,否则 Pod 之间无法通信。

    Kubernetes 支持多种网络方案,例如 flannel 和 Canal。

  4. 注册其他节点到 Cluster

几乎所有的 Kubernetes 组件本身也运行在 Pod 里,kubelet 是唯一没有以容器形式运行的 Kubernetes 组件,它在 Ubuntu 中通过 Systemd 运行。

附录:

云计算与弹性伸缩

从云计算的定义出发,云计算系统一个基本特性就是计算能力的弹性和伸缩性。弹性和伸缩性的意思是能够根据实际的需要,随时增多或减少计算能力。弹性伸缩针对不同的处理对象,有不同的伸缩模式,如下图,分别处于X、Y、Z轴3个不同维度。

  1. 对于同一类事物的无状态服务,数据不需要持久化,处理结果不需要保存在信息系统中,可以通过X轴计算实例的水平复制进行伸缩,这就是Kubernetes系统中Replication Controller和ReplicaSet所完成的功能;举例说明,一个电子商务系统的下订单服务,本身只是做订单处理但不存储数据的无状态服务,这个微服务就可以用水平复制的模式来伸缩。

  2. 对于同一类事物的有状态服务,数据存储的内容各不相同,身份也各不相同,可以通过Z轴存储实例的数据分片进行伸缩,这就是Kuberenetes的PetSet或者StatefulSet所完成的功能;举例说明,下订单服务的订单数据存储在MySQL数据库中,要想增加订单数据存储的能力,就需要对针对订单数据库表进行数据分片。

    tips: 何为数据分片(segment,fragment, shard, partition),就是按照一定的规则,将数据集划分成相互独立、正交的数据子集,然后将数据子集分布到不同的节点上。注意,数据分片需要按照一定的规则,不同的分布式应用有不同的规则,但都遵循同样的原则:按照最主要、最频繁使用的访问方式来分片。)

  3. 对于不同类别事物的处理,则需要通过Y轴的功能分割来进行伸缩,Y轴的分割也称为垂直分割;举例说明,一个完整的电子商务系统,可以根据业务功能分割成用户管理、购物车管理、订单管理、产品目录管理、库存管理、支付管理、配送管理等多个独立的微服务。需要说明的是,功能分割(Y轴)是水平复制(X轴)和数据分片(Z轴)的前提,只有通过功能分割解耦将不同的事物分割出来,才能针对同一事物进行水平复制或数据分片。

4bd0da72f12b4c47834228a74a169ca219208981

容器与微服务架构

微服务架构的理念,是将一个完整的应用,按照业务拆分成彼此独立的模块以支撑服务的独立开发、部署和伸缩。

微服务分割也就是业务功能分割。微服务分割和传统软件模块分割的一大区别是,

微服务分割强调领域数据模型的分割,也就是数据存储服务的分割,以保证不同微服务之间没有持久化数据方面的依赖性,从而使得不同的微服务真正可以在运行时独立进行部署和伸缩。

传统的软件模块分割,比较多的是考虑代码的重用性和各模块开发的独立性,但因为并没有为超高用户压力的弹性要求做准备,比较少考虑数据持久化层面的伸缩性。

而如前所述,Y轴业务功能分割是Z轴数据分片的前提,因此要想真正应对超高用户压力的弹性计算要求,进行业务功能分割是第一步。

参考资料


后端开发者面试问题集锦 - github

原文: https://github.com/arialdomartini/Back-End-Developer-Interview-Questions

  1. 通用问题
  2. 开放式问题
  3. 设计模式相关问题
  4. 代码设计相关问题
  5. 语言相关问题
  6. Web相关问题
  7. 数据库相关问题
  8. 非关系型数据库相关问题
  9. 代码版本管理相关问题
  10. 并发问题
  11. 分布式系统相关问题
  12. 软件生命周期和团队管理相关问题
  13. 逻辑和算法相关问题
  14. 软件架构相关问题
  15. 面向服务架构(SOA)和微服务(Microservice)相关问题
  16. 安全相关问题
  17. 比尔盖茨式问题
  18. 代码示例问题

通用问题:

  • 语言设计中空引用(null reference)的存在有什么问题?假设你想要将空引用的概念从你的首选语言中移除,可能导致什么结果?
  • 为什么函数式编程重要?什么时候适用函数式语言?
  • 设计(design)、架构(architecture)、功能(functionality)和美学(aesthetic)之间有什么区别?讨论一下。
  • 微软、谷歌、欧朋(opera)和火狐这类公司是如何从他们的浏览器中获利的?
  • 为什么打开TCP套接字有很大的开销?
  • 封装的重要性体现在哪儿?
  • 什么是实时系统?它与普通系统有什么区别?
  • 实时语言(real-time language)和堆内存分配(heap memory allocation)之间的关系是什么?
  • 不变性(Immutability)是指: (变量的)值只能在创建的时候被设置一次,之后就不能被改变。为什么不变性对写更加安全的代码有帮助?
  • 可变值(mutable values)和不可变值(immutable values)有哪些优缺点?
  • 什么是O/R阻抗失衡(Object-Relational impedence mismatch)?
  • 如果你需要使用缓存,你使用哪些原则来确定缓存的大小?
  • TCP和HTTP有什么区别?
  • 在客户端渲染(client-side rendering)和服务端渲染(server-side rendering)之间,你是如何权衡的?
  • 如何在一个不可靠的协议之上构建一个可靠的通信协议?

开放式问题:

  • 为什么人们会抵制变化?
  • 如何向你的祖母解释什么是线程?
  • 作为一个软件工程师,你想要既要有创新力,又要产出具有可预测性。采用什么策略才能使这两个目标可以共存呢?
  • 什么是好的代码?
  • 解释什么是流(Streaming)和如何实现一个流?
  • 假设你的公司给你一周的时间,用来改善你和同事的生活: 你将如何使用这一周?
  • 本周你学了什么?
  • 所有的设计中都会有美学元素(aesthetic element)的存在。问题是,你认为美学元素是你的朋友还是敌人?
  • 列出最近你读过的5本书。
  • 假设目前有个大型公司(非常有钱),他们的开发流程是瀑布式流程(Waterfall),如果需要你在他们公司引入持续交付(Continue Devivery),你会怎么做?
  • 我们来谈谈”重复造轮子”,”非我发明症”, “吃自己做出来的狗粮“的这些做法吧。

(注: 重复造轮子: Reinventing the wheel; 非我发明症:Not Invented Here Syndrome; 吃自己做出来的狗粮: Eating Your Own Dog Food)

  • 在你当前的工作流中,什么事情是你计划下一步需要自动化的?
  • 为什么写软件是困难的?是什么使软件的维护变得困难?
  • 你更喜欢在全新项目(Green Field Project)上工作还是在已有项目(Brown Field Project)基础上工作?为什么?
  • 当你在浏览器地址栏输入google.com回车之后都发生了什么?
  • 当操作系统CPU处于空闲的时候,它可能在处理哪些事情?
  • 如何向一个5岁的孩子解释什么是Unicode/数据库事务?
  • 如何维护单体架构(monolithic architecture)?
  • 一个”专业的开发者”意味着什么?
  • 软件开发是艺术、是技艺还是工程?你的观点是什么?
  • “喜欢这个的人也喜欢…“,如何在一个电子商务商店里实现这种功能?
  • 为什么在创新上,企业会比创业公司慢些?
  • 为什么说,你不应该尝试应用自己发明或者设计的密码学?

设计模式相关问题:

  • 请用一个例子表明,全局对象是邪恶的存在。
  • 假设你工作的系统不支持事务性,你会如何从头开始实现它?
  • 什么是好莱坞原则(Hollywood Principles)?
  • 关于迪米特法则(最少知识原则): 写一段代码违反它, 然后修复它。

(注: 迪米特法则:the Law of Demeter, 最少知识原则: the Principle of Least Knowledge)

  • Active-Record模式有什么限制和缺陷?
  • Data-Mapper模式和Active-Record模式有什么区别?
  • 空对象模式(Null Object Pattern)的目的是什么?
  • 为什么组合(Composition)比继承(Inheritance)更好?
  • 什么是反腐败层(Anti-corruption Layer)?
  • 你可以写一个线程安全的单例(Singleton)类吗?
  • 数据抽象(Data Abstraction)能力是指能改变实现而不影响客户端的这种能力。请构造一个一个例子,违反这个特性,并且尝试修复它。
  • 你是如何处理依赖关系地狱(Dependency Hell)的?
  • 为什么说goto语句是恶魔般的存在?
  • 健壮性是进行软件设计时的一个通用原则,它建议 “发送时要保守,接收时要开放”。这也经常被写成,“做一个有耐心的读者,做一个谨慎的作者”。你能解释一些这背后的逻辑吗?

译者注: “发送时要保守,接收时要开发”的原文是: “Be conservative in what you send, be liberal in what you accept”,有点类似于“严于律己,宽于待人”的意味。

代码设计相关问题:

  • 你在进行软件设计时会考虑软件测试吗?软件测试是如何影响软件设计的?
  • 内聚和耦合的区别是什么?
  • 重构在哪些场景下有用?
  • 代码中的注释有用吗?
  • 设计和架构有什么区别?
  • 为什么在测试驱动开发(TDD)中是先写测试,再写代码?
  • C++支持多继承,Java允许类实现多个接口。这些特性对正交性有什么影响?使用多继承和使用多接口有区别吗?[这个问题来自Andrew .Hunt 和 David Thomas写的《程序员修炼之道》]
  • 在存储过程(Stored Procedures)中写业务逻辑有什么优缺点?

语言相关问题:

  • 告诉我你的首选语言的三个最坏的缺陷。
  • 为什么现在函数式编程这么越来越受关注?
  • 闭包是什么?它有什么用途?闭包和类有什么共同点?
  • 泛型有什么用途?
  • 什么是高阶函数?有什么用途?用你的首选语言写个例子出来。
  • 讨论一下,如何写一个循环,然后把它转换成递归函数,要避免易变性。
  • 有些语言将函数视为第一公民,这是什么意思?
  • 用一个例子说明匿名函数是有用的。
  • 什么是动态方法调度(Dynamic Method Dispatch)?
  • 名字空间(Namespace)有什么用?有什么可以替代它的吗?
  • 谈谈Java和C#之间的互操作性(Interoperability) (任选其他两门语言都行)
  • 为什么很多软件工程师不喜欢Java?
  • 你认为好的语言好在哪里?差的语言差在哪里?
  • 写两个函数,一个是”引用透明的(Referentially Transparent)”,另一个是”引用不透明的(Referentially Opaque)”。讨论之。
  • 什么是栈?什么是堆?
  • 为什么一个语言中,”函数是第一公民”是很重要的?
  • 模式匹配(Pattern Matching)和Switch语句(Switch clauses)的区别在哪儿?
  • 为什么有些语言设计上没有异常机制?这有什么优缺点?
  • 如果Cat是一个Animal, 那么TaskCare<Cat>是一个TakeCare<Animal>吗?

web相关问题:

  • 为什么”第一方cookie(first-party cookie)”和”第三方cookie(third-party cookie)”被如此不同的对待?

数据库相关问题:

  • 如果要你将一个项目从MySQL迁移至PostgreSQL中,你会如何迁移?
  • 为什么SELECT * FROM table WHERE field = null不能匹配空的字段?
  • 什么是ACID(原子性,一致性,隔离性,持久性)原则?
  • 你是如何进行数据库模式(Database schema)迁移的?
  • 延迟加载(lazy loading)是如何实现的?什么场景下有用?他有什么缺陷?
  • 什么是N+1问题?
  • 如何找出应用中开销最大的查询?

非关系型数据库相关问题:

  • 什么是最终一致性(Eventual Consistency)?
  • 关于CAP理论,举一些CP、AP、CA系统的例子。
  • NoSQL是如何解决可伸缩性的挑战的?
  • 什么情况下你会使用类似于MongoDB的文档数据库而不是关系型数据库(如Mysql或者PostgreSQL)?

代码版本管理相关问题:

  • 为什么在Mercurial或者git中(管理)分支比SVN容易?
  • 分散式版本控制系统(比如git),相比集中式版本控制系统(如svn)有哪些优势和劣势?

(注:集中式版本控制系统: Centralized Version Control Systems;分散式版本控制系统: Distributed Version Control Systems)

  • 能描述一下什么是GitHubFlow和GitFlow工作流吗?
  • 什么是rebase?
  • 为什么合并操作(merge)在Mercurial和git中比在SVN和CVS中容易?

并发问题:

  • 为什么我们需要并发呢?解释一下。
  • 为什么测试多线程/并发代码这么困难?
  • 什么是竞争条件(Race Condition)?用任何一个语言写一个例子。
  • 什么是死锁?用代码解释一下。
  • 什么是饿死?
  • 什么是Wait-Free算法?

分布式系统相关问题:

  • 怎么测试一个分布式系统?
  • 什么场景下你会在两个系统中采用异步通信机制?
  • 远程过程调用的通用缺点是什么?
  • 如果你为了可扩展性和鲁棒性而构建一个分布式的系统,分别在封闭安全的网络环境情况下,和地理上的位置不同但是网络环境不是封闭和安全的情况下,你会考虑什么不同的事情?
  • 在Web应用中如何管理容错性?在桌面端呢?
  • 在分布式系统中,如何处理故障?
  • 让我们来谈谈网络分裂(network partitions)后有的几种恢复的手段吧。
  • 你认为分布式计算中有哪些谬论?
  • 你在什么时候会使用Request/Response模式,什么时候使用Publish/Subscribe模式?

软件生命周期和团队管理相关问题:

  • 什么是敏捷(Agility)?
  • 你是如何处理遗留代码(Legacy Code)的?
  • 假设我是你们公司的CEO,请向我解释什么是看板,并且说服我在它上面投资。
  • 敏捷(Agility)和瀑布(Waterfall)之间的最大区别是什么?
  • 作为团队管理者,你对会议太多这个问题是如何处理的?
  • 你会如何处理延期很长时间了的项目?
  • 个体与交互重于过程和工具“和”客户协作重于合同谈判“占了敏捷宣言(Agile Manifesto)的一半,谈论一下这两个观念。
  • 如果你是你们公司的CTO,你会采取什么样的决策?
  • 你觉得项目经理有用吗?
  • 如果要你组织一个弹性工作制的开发团队(即没有强制工作时间的要求),并且假期制度是”按需休假”,你会如何做?
  • 你会如何管理一个人员流动非常高的团队?如何在不加薪的条件下说服团队成员不要离开?
  • 除了代码之外,你最关注你的同事的哪3项素质?
  • 关于代码,你最希望非技术人员能知道的的三件事是什么?

逻辑和算法相关问题:

  • 只用LIFO栈如何构造一个FIFO队列?只用FIFO队列如何构造一个LIFO栈?
  • 写一段有栈溢出的代码。
  • 写一个尾递归版本的阶乘函数。
  • 使用任何一个语言,写一个REPL,功能是echo你输入的字符串。然后将它演化成一个逆波兰表达式的计算器。
  • 如果需要你设计一个文件系统磁盘碎片整理程序,你会如何设计?
  • 写一个生成随机迷宫的程序。
  • 写一段有内存泄漏的示例代码。
  • 随机生成一个的数字序列,里面每个数字都不同。
  • 写一个简单的垃圾回收系统。
  • 使用任何一门语言,写一个基本的消息代理。
  • 写一个基础的web服务器,然后画一张线路图,展示你将来还想要实现的功能。
  • 如何对一个10GB的文件进行排序?如果是10TB的数据,你会采用什么方法?
  • 请实现rnd()函数

软件架构相关问题:

  • 什么情况下缓存是没用的,甚至是危险的?
  • 为什么事件驱动的架构能提高可扩展性(scalability)?
  • 什么样的代码是可读性强的代码?
  • 紧急设计(Emergent Design)和演化架构(Evolutionary Architecture)之间的区别是什么?
  • 横向扩展(scale out) vs 纵向扩展(scale up): 有什么区别?分别在什么场景下使用?
  • 分布式系统中如何处理”故障切换(failover)”和”用户会话(user session)”?
  • 什么是CQRS(Command Query Responsibility Segregation)?他和最早的Command-Query Separation原则有什么区别?
  • 什么是三层架构?
  • 如何设计一个可扩展性高的系统?
  • 处理C10k问题的策略有哪些?
  • 如果让你来设计一个去中心化的P2P系统,你会如何设计?
  • 为什么CGI的扩展性不好?
  • 在设计系统时,你如何防止供应商依赖(Vendor Lock-in)?
  • 在可扩展性上,发布/订阅(Publish-Subscribe)模式有什么缺点?
  • 80年代以后,CPU有哪些变化?这些变化,对编程产生了什么影响?
  • 性能生命周期(performace lifecycle)中,你认为哪个部分是需要考虑进去的? 如何管理?
  • 除了恶意攻击造成的拒绝服务现象以外,哪些设计或者架构上的问题会导致拒绝服务?
  • 性能和可扩展性之间有什么关系?
  • 什么时候紧耦合是OK的?
  • 一个系统要有什么特征才能适配云计算环境(Cloud Ready)?
  • Does unity of design imply an aristocracy of architects?

面向服务架构(SOA)和微服务(Microservice)相关问题:

  • 在SOA中,为什么长期存活的事务(Long-lived transation)不被看好,而Saga却被看好?
  • SOA和MicroService之间有什么区别?
  • 我们来谈谈Web服务的版本管理、版本兼容性、重大变更管理这些事情吧.
  • 在saga中事务和补偿操作(compensation operation)之间的区别是什么?在SOA中呢?
  • 微服务不能做得太”微”,你认为什么时候微服务太”微”了?
  • MicroService架构的优劣是什么?

安全相关问题:

  • 什么是双因素认证(Two Factor Authentication)?在一个已有的Web应用中,你如何实现这种机制?

比尔盖茨式问题:

  • 如果你把一面镜子放在扫描仪上,会发生什么?
  • 假设有一个和你完全一样的克隆人,而他是你的上司,你愿意和他工作吗?
  • 现在请你面试一下我。
  • 为什么Quora上的回答会比Yahoo Answer上的回答好?
  • 对手是现代语言,你的任务是要为Cobol辩护,你会如何进行?
  • 10年后的你是什么样子?
  • 假设你是我老板,我被解雇了。你会如何通知我?
  • 我想要重构一个系统,而你想要从头重写。我们来争论一下该怎么弄吧。然后我们反转角色,再争论一下。
  • 老板要你对公司撒谎,你的反应是什么?
  • 如果你可以穿越到以前,你会给年轻时候的你什么建议?

代码示例问题:

  • 这段Javascript函数的输出是什么?
function hookupevents() {
  for (var i = 0; i < 3; i++) {
    document.getElementById("button" + i)
      .addEventListener("click", function() { 
        alert(i); 
      });
  }
}
  • 关于类型擦除(Type Erasure),这段Java代码的输出是什么?为什么?
ArrayList<Integer> li = new ArrayList<Integer>();
ArrayList<Float> lf = new ArrayList<Float>();
if (li.getClass() == lf.getClass()) // evaluates to true
  System.out.println("Equal");
  • 你能指出哪儿有内存泄漏吗?
public class Stack {
    private Object[] elements;
    private int size = 0;
    private static final int DEFAULT_INITIAL_CAPACITY = 16;

    public Stack() {
        elements = new Object[DEFAULT_INITIAL_CAPACITY];
    }

    public void push(Object e) {
        ensureCapacity();
        elements[size++] = e;
    }

    public Object pop() {
        if (size == 0)
            throw new EmptyStackException();
        return elements[--size];
    }

    /**
     * Ensure space for at least one more element, roughly
     * doubling the capacity each time the array needs to grow.
     */
    private void ensureCapacity() {
        if (elements.length == size)
            elements = Arrays.copyOf(elements, 2 * size + 1);
    }
}
  • if语句,或者更加通用点,条件表达式通常是过程式编程/命令式编程的形式。你能去掉这段代码中的switch语句,用面向对象的方式来修改这段代码吗?
public class Formatter {

    private Service service;

    public Formatter(Service service) {
        this.service = service;
    }

    public String doTheJob(String theInput) {
        String response = service.askForPermission();
        switch (response) {
        case "FAIL":
            return "error";
        case "OK":
            return String.format("%s%s", theInput, theInput);
        default:
            return null;
        }
    }
}
  • 你能去掉这里的if语句,将它改成更加面向对象吗?
public class TheService {
    private final FileHandler fileHandler;
    private final FooRepository fooRepository;

    public TheService(FileHandler fileHandler, FooRepository fooRepository) {
        this.fileHandler = fileHandler;
        this.fooRepository = fooRepository;
    }

    public String Execute(final String file) {

        final String rewrittenUrl = fileHandler.getXmlFileFromFileName(file);
        final String executionId = fileHandler.getExecutionIdFromFileName(file);

        if ((executionId == "") || (rewrittenUrl == "")) {
            return "";
        }

        Foo knownFoo = fooRepository.getFooByXmlFileName(rewrittenUrl);

        if (knownFoo == null) {
            return "";
        }

        return knownFoo.DoThat(file);
    }
}
  • 如何重构这段代码?
function()
{
    HRESULT error = S_OK;

    if(SUCCEEDED(Operation1()))
    {
        if(SUCCEEDED(Operation2()))
        {
            if(SUCCEEDED(Operation3()))
            {
                if(SUCCEEDED(Operation4()))
                {
                }
                else
                {
                    error = OPERATION4FAILED;
                }
            }
            else
            {
                error = OPERATION3FAILED;
            }
        }
        else
        {
            error = OPERATION2FAILED;
        }
    }
    else
    {
        error = OPERATION1FAILED;
    }

    return error;
}

参考资料


网络线路知识

中国

骨干网

  • 中国公用计算机互联网(CHINANET)

    邮电部经营管理的基于Internet网络技术的电子信息网,1995年初与国际互联网连通,邮电部撤销后改由中国电信经营。

  • 中国金桥信息网(CHINAGBN)

    由中国信息产业部(原电子工业部)负责管理的公用计算机信息网。金桥信息网于1994年开始建设,1996年9月正式开通。

  • 中国教育和科研计算机网(CERNET)

    始建于1994年,由中国教育部投资并管理,是中国最大的公益性、学术性计算机互联网络。有连接美国的国际专线。网络总控中心设在清华大学。

  • 中国科技网 (CSTNET)

    由中国科学院主持,联合清华、北大共同建设。1994年4月与美国NSFNET直接互联,目前由中国科学院管理的。

以上为四大骨干网。下面的是其它专有网络或相对较小的网络:

  • 中国联通计算机互联网(UNINET)

  • 中国电信下一代承载网(ChinaNet Next Carrying Network,简称CN2)

  • 中国网通公用互联网(CNCNET)

  • 中国移动互联网(CMNET)

    于2000年1月组建。

  • 中国长城互联网(CGWNET)

    非经营性,军队专用,不设国际出口带宽。

  • 中国国际经济贸易互联网(CIETNET)

    全国外贸系统企事业单位专用,由中国国际电子商务中心负责组建、运行和维护,不设国际出口带宽。

三大运营商

中国电信拥有2张全国骨干网:中国公用计算机互联网(CHINANET / CHINA163)和中国电信下一代承载网(ChinaNet Next Carrying Network,简称CN2)。

有4个IPT产品,包括163骨干网、美洲电信AS36678、电信CN2 GT和电信CN2 GIA。

  • CHINANET/163,也就是AS4134接入的带宽,中国电信骨干网,常见的202.97开头的路由,就是这个网。邮电部撤消后,由中国电信经营管理。这个网络负责了90%的电信业务负载。

  • 美洲电信AS36678,是中国电信美洲分公司的ASN号码,实际上就比4134多一跳。质量和4134一个级别。 6678用美洲分公司直接运营,不需要经过电信集团公司审批。

  • 中国电信CN2 GT,是电信CN2产品线中的Global Transit的产品,CN2 GT到中国国际出口有自己的单独线路,但是进入国内还是使用的163出口。

    省级/出国节点为202.97开头,国际骨干节点有2~4个59.43开头的CN2节点。

  • 中国电信CN2 GIA,属于CN2中的Global Internet Access产品,等级最高,省级/出国/国际骨干节点都以59.43开头,全程没有202.97开头的节点。CN2 GIA拥有独立的回国链路,属于轻度负载,保证访问质量。这种带宽的质量是电信网络里最好的。

中国联通拥有1张全国骨干网:中国网通互联网(CHINA169)。

原中国金桥信息网(CHINAGBN)由吉通公司负责建设、运营和管理,2002年5月16日,吉通公司并入中国网通,2009年中国网通与中国联通合并。2009年工信部同意原中国网通互联网骨干网(CHINA169)和原中国联通互联网骨干网(UNINET)实施网络融合,并将 UNINET 作为下级网络接入 CHINA169。

  • 联通的 cn2 (精品网),as9929 的联通骨干网,联通 /网通合并前的联通的骨干网。用户基数少,网络负荷小。出国的网络质量一般要比 4837 要好。
  • as4837 ,一般用户都是这个或者其子网

中国移动,拥有1张全国骨干网:中国移动互联网(CMNET),于2000年1月组建。

其实,中国的互联网原本是一张网,中国电信几乎垄断着全国的固话网络,新兴的宽带互联网自然也是由电信”独家”经营。但是,中国电信的南北分拆打破了这一局面。

2002年5月,国内电信业大重组,原中国电信北方10个省份正式划入中国网通集团,南方21个省份重组为新的中国电信。这次”大分家”把中国的互联网人为地一分为二。


有助于提高系统管理员团队工作效率的32个问题 - 51CTO

Limoncelli的测试:

【编辑推荐】

  1. 自动监控从MySQL同步的脚本
  2. Nagios远程监控软件的安装与配置详解
  3. Linux监控工具的展览馆

关于云计算超卖,你需要知道的都在这里了 - 知乎

目前也在做云平台相关的工作,找到了这篇关于云平台超售的文章,对于计算超售的过程还不是特别了解,转到小站方便研究。作者是 阿里云高级产品专家 realzyy,以下是原文https://zhuanlan.zhihu.com/p/24435587.:

2016年10月26日,IT之家的CEO发布了一则公告(参见《完成阿里云至百度云站点迁移工作》),其中抱怨阿里云ECS云服务器超卖严重且售后态度不积极的内容引发了整个云计算圈子激烈讨论。 随后的一天,袋鼠云的CTO在云栖社区上发声(参见《IT之家,这不是个案》),指出IT之家的技术架构落后,使用云计算的“姿势不对”是导致整个事件最主要的原因。

-—————————– 为了避免草率得出结论,我们先使用理论数据推演。首先定义超卖率(OverSaleRate):

假设一台物理主机有16个物理CPU+256GB内存,且其中内存是限定资源。另有假设平均的云服务器规格为2vCPU+4GB的内存,则CPU超卖率有如下推导:

这意味着,当内存售卖率(LimitedResourceSaleRate)为10%时CPU是不超卖的,当内存售卖率为60%时CPU超卖率是380%,当内存售卖率为80%时CPU超卖率则达到了540%。

-—————————– 在上述的假设条件下,云计算的CPU超卖程度显然是比较夸张的。那么实际情况是怎么样的呢?为了避免口水战,我们使用全球最大的云计算厂商AWS的官网数据来进行验证。 首先是根据EC2专用主机EC2实例的配置,推测EC2物理主机的配置:

  1. 通用型t2、m3、m4三个系列的内存/vCPU比例为0.5、1、2、4
  2. 计算优化型c3、c4两个系列的内存/vCPU比例为2
  3. 内存优化型r3、r4两个系列的内存/vCPU比例为8(x1系列比较特殊,略去)

相应的,我们从这个表里面能获取到的关键信息是什么呢?

  1. 假设只有c3和c4系列的EC2实例是对应分布在c3和c4类主机上的,则c3和c4主机不存在CPU超卖
  2. 假设只有r3和r4系列的EC2实例是对应分布在r3和r4类主机上的,则r3主机不存在CPU超卖,而r4主机存在少量CPU超卖
  3. 假设只有m3和m4系列的EC2实例是对应分布在m3和m4类主机上的,则m3主机不存在CPU超卖,而m4主机存在少量CPU超卖
  4. t2系列的EC2实例没有任何主机型号与之直接对应,而t2型的内存/CPU比例非常低(0.5-2),是造成CPU超卖的元凶

在此不妨做一个推测,AWS的EC2实例分配策略基于三条逻辑:

  1. c3、c4、r3、r4、m3、m4等EC2规格分布在对应类型的主机上
  2. t2系列中的2vCPU+8GB、4vCPU+16GB、8vCPU+32GB三个规格分布在m3、m4主机上
  3. t2系列中的1vCPU+0.5GB、1vCPU+1GB、1vCPU+2GB、2vCPU+4GB四个规格分布在CPU比较空闲的主机上,并会有定期的调度策略保证物理CPU最大程度上的平均利用

在这三条逻辑的保障下,AWS可以在t2实例数量较少的情况下将超卖比控制在非常低的水位上,让用户基本对CPU超卖没有感知。在t2实例数量特别多的情况下,超卖比则会迅速恶化至500%、1000%,甚至2000%。

那么是否可能专门为t2系列定制一款主机,保证超卖在理论上就不会发生?我想AWS应该是可以做到的,但是主机成本将会非常高昂,跟t2系列低价的卖点将会背道而驰。

-—————————–

回到最初的问题:

云计算的虚拟化是否就一定存在着资源超卖,因此不能满足大企业的稳定性需求?

答案已经非常明显了,请大家自行脑补吧。


删除 ssh known_hosts 中特定的主机

重装了系统,登陆的时候提示无法登陆。

以前的做法,都是直接把 known_hosts 删除了事。由于现在记录的太多了,删除掉会又问题。随意添加了几个反斜杠,就成功了:

ssh-keygen -f "/root/.ssh/known_hosts" -R \[103.71.xxx.xxx\]\:xxx

显示删除成功

Host [103.71.xxx.xxx]:xxx found: line 4 type ECDSA 
/root/.ssh/known_hosts updated. 
Original contents retained as /root/.ssh/known_hosts.old