# Kubernetes

Kubernetes是Google开源的容器集群管理系统，其提供应用部署、维护、 扩展机制等功能，利用Kubernetes能方便地管理跨机器运行容器化的应用：

* 使用Docker对应用程序包装(package)、实例化(instantiate)、运行(run)
* 以集群的方式运行、管理跨机器的容器
* 解决Docker跨机器容器之间的通讯问题
* Kubernetes的自我修复机制使得容器集群总是运行在用户期望的状态（比如用户想让apache一直运行，用户不需要关心怎么去做，Kubernetes会自动去监控，然后去重启，新建，总之，让apache一直提供服务）

在Kubenetes中，所有的容器均在Pod中运行,一个Pod可以承载一个或者多个相关的容器，同一个Pod中的容器会部署在同一个物理机器上并且能够共享资源。

> `pod`理解为一个物理主机上的一个逻辑子集，和物理服务器紧密绑定。

一个Pod也可以包含O个或者多个磁盘卷组（volumes）,这些卷组将会以目录的形式提供给一个容器，或者被所有Pod中的容器共享，对于用户创建的每个Pod,系统会自动选择那个健康并且有足够容量的机器，然后创建类似容器的容器,当容器创建失败的时候，容器会被node agent自动的重启,这个node agent叫kubelet,但是，如果是Pod失败或者机器，它不会自动的转移并且启动，除非用户定义了 replication controller。

> 单个pod占有的存储卷应该是本地存储;所有pod容器共享的存储卷是分布式存储（基于网络共享）
>
> pod失败（理解为物理服务器故障）默认不failover容器，需要定义复制（容器）控制器（replication controller）来进行故障迁移。

用户可以自己创建并管理Pod，Kubernetes将这些操作简化为两个操作：

* 基于相同的Pod配置文件部署多个Pod复制品
* 创建可替代的Pod

> 当一个Pod挂了或者机器挂了的时候，Kubernetes API中负责来重新启动，迁移等行为的部分叫做`replication controller`。
>
> 它根据一个模板生成了一个Pod,然后系统就根据用户的需求创建了许多冗余，这些冗余的Pod组成了一个整个应用，或者服务，或者服务中的一层。
>
> 一旦一个Pod被创建，系统就会不停的监控Pod的健康情况以及Pod所在主机的健康情况。如果这个Pod因为软件原因挂掉了或者所在的机器挂掉了，`replication controller`会自动在一个健康的机器上创建一个一摸一样的Pod,来维持原来的Pod冗余状态不变，一个应用的多个Pod可以共享一个机器。

**简单来说，只要应用无状态就可以采用`replication controller`在pod挂掉的时候在其他pod启动完全一致的pod。**

可以给Kubernetes Api中的任何对象贴上一组 `key:value`的标签，这样就通过标签来选择一组相关的`Kubernetes Api`对象，去执行一些特定的操作。每个资源额外拥有一组（很多） `keys` 和 `values`,然后外部的工具可以使用这些keys和vlues值进行对象的检索，这些`Map`叫做`annotations`（注释）。

> `key:value`标签理解为逻辑组

Kubernetes支持一种特殊的网络模型，Kubernetes创建了一个地址空间，并且不动态的分配端口，它可以允许用户选择任何想使用的端口，为了实现这个功能，它为每个Pod分配IP地址。

> 在物理服务器上创建的每个pod都分配一个IP地址，这样就可以对pod提供对外服务。

Kubernetes提供了**服务的抽象**，并提供了固定的IP地址和DNS名称，而这些与一系列Pod进行动态关联，这些都通过之前提到的标签进行关联。

可以关联任何Pod，当一个Pod中的容器访问这个地址的时候，这个请求会被转发到本地代理（`kube proxy`）,每台机器上均有一个本地代理，然后被转发到相应的后端容器。

Kubernetes通过一种轮训机制选择相应的后端容器，这些动态的Pod被替换的时候,Kube proxy时刻追踪着，所以，服务的 IP地址（dns名称），从来不变。

> pod和代理可以理解成：
>
> 对于物理服务器上的每个pod，每个pod都有一个对外IP，访问pod的服务是通过访问pod所在的IP和端口实现，而这个`IP+端口`是由kubernetes的一个对外代理服务器提供服务（这个代理服务可以是HAProxy也可以是Nginx balance，或者是LVS）。
>
> 代理服务会反向代理到后端pod中的容器所运行的真实服务器。并且反向代理有健康检测功能，可以自动剔除故障服务节点。
>
> 代理服务对外提供的IP和DNS名称始终保持不变，所以外部不需要了解pod中后端的容器中运行的服务是否正常，有多少容器服务等等，完全被这个对外的代理服务所包装了。

所有Kubernetes中的资源，比如Pod,都通过一个叫URI的东西来区分，这个URI有一个UID,URI的重要组成部分是：对象的类型（比如pod），对象的名字，对象的命名空间，对于特殊的对象类型，在同一个命名空间内，所有的名字都是不同的，在对象只提供名称，不提供命名空间的情况下，这种情况是假定是默认的命名空间。UID是时间和空间上的唯一。

## 个人理解

**以上注释部分是个人理解，不一定完全正确，并且随着对Kubernetes和Docker等技术的学习逐步进行完善和修正！**

> Kubernetes不是虚拟化也不是容器，而是将容器的计算资源进行抽象和标准化，以便能够大规模部署和管理。

Kubernetes对计算资源进行了更高层次的抽象，通过将容器进行细致的组合，将最终的应用服务交给用户。Kubernetes在模型建立之初就考虑了容器跨机连接的要求，支持多种网络解决方案，同时在Service层次构建集群范围的SDN网络。其目的是将服务发现和负载均衡放置到容器可达的范围，这种透明的方式便利了各个服务间的通信，并为微服务架构的实践提供了平台基础。而在Pod层次上，作为Kubernetes可操作的最小对象，其特征更是对微服务架构的原生支持。

## 参考

* [Kubernetes中文社区:Kubernetes概述](https://www.kubernetes.org.cn/k8s)
* [Kubernetes系统架构简介](http://www.infoq.com/cn/articles/Kubernetes-system-architecture-introduction)
* [Kubernetes权威指南：从Docker到Kubernetes实践全接触（第2版）](https://www.amazon.cn/Kubernetes%E6%9D%83%E5%A8%81%E6%8C%87%E5%8D%97-%E4%BB%8EDocker%E5%88%B0Kubernetes%E5%AE%9E%E8%B7%B5%E5%85%A8%E6%8E%A5%E8%A7%A6-%E9%BE%9A%E6%AD%A3/dp/B01LY9Q24C/ref=sr_1_2?ie=UTF8\&qid=1508816308\&sr=8-2\&keywords=Kubernetes%E6%9D%83%E5%A8%81%E6%8C%87%E5%8D%97%EF%BC%9A%E4%BB%8EDocker%E5%88%B0Kubernetes%E5%AE%9E%E8%B7%B5%E5%85%A8%E6%8E%A5%E8%A7%A6)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://huataihuang.gitbook.io/cloud-atlas-draft/iaas/kubernetes.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
