浅谈Docker & k8s
Docker
轻量级虚拟环境(相对于VM来说)。
Linux Containers
Linux 容器 (LXC) 不是模拟一个完整的操作系统,而是对进程进行隔离。或者说,在正常进程的外面套了一个保护层。对于容器里面的进程来说,它接触到的各种资源都是虚拟的,从而实现与底层系统的隔离。
Docker概念
Docker相当于为LXC封装了一个好用的API。
image = 小的虚拟环境。可以叠加。like OS + App1 + App2…
Docker用处
问Docker的用处,实际上就是问“轻量级虚拟环境”的用处。
Why do we need containers after all?
https://kubernetes.io/zh/docs/concepts/overview/what-is-kubernetes/
如果app之间没有隔离:
- 资源分配问题。一个App可能占用大部分资源。
- 安全问题。
- 不够灵活。
Docker 的主要用途,目前有三大类。
(1)提供一次性的环境。比如,本地测试他人的软件、持续集成的时候提供单元测试和构建的环境。
(2)提供弹性的云服务。因为 Docker 容器可以随开随关,很适合动态扩容和缩容。
(3)组建微服务架构。通过多个容器,一台机器可以跑多个服务,因此在本机就可以模拟出微服务架构。
Docker的意思
Docker = 码头工,所以应该就是一个把那些container移来移去的app。
Kubernetes
用来管理容器。这个“管理”包含了很多方面:
-
服务发现和负载均衡
Kubernetes 可以使用 DNS 名称或自己的 IP 地址公开容器,如果进入容器的流量很大, Kubernetes 可以负载均衡并分配网络流量,从而使部署稳定。
-
存储编排
Kubernetes 允许你自动挂载你选择的存储系统,例如本地存储、公共云提供商等。
-
自动部署和回滚
你可以使用 Kubernetes 描述已部署容器的所需状态,它可以以受控的速率将实际状态 更改为期望状态。例如,你可以自动化 Kubernetes 来为你的部署创建新容器, 删除现有容器并将它们的所有资源用于新容器。
-
自动完成装箱计算
Kubernetes 允许你指定每个容器所需 CPU 和内存(RAM)。 当容器指定了资源请求时,Kubernetes 可以做出更好的决策来管理容器的资源。
-
自我修复
Kubernetes 重新启动失败的容器、替换容器、杀死不响应用户定义的 运行状况检查的容器,并且在准备好服务之前不将其通告给客户端。
-
密钥与配置管理
Kubernetes 允许你存储和管理敏感信息,例如密码、OAuth 令牌和 ssh 密钥。 你可以在不重建容器镜像的情况下部署和更新密钥和应用程序配置,也无需在堆栈配置中暴露密钥。
架构
重要名词
Kubelet: Worker(或者说Node)机器上的Kubernetes代理。它负责与Control Plane交互。
Pod: Kubernetes管理的最小单位,我翻译为“小组”。它可以包含一个或多个container(image).
注意:Kubernetes不直接管理container。
Pod 为特定于应用程序的“逻辑主机”建模,并且可以包含相对紧耦合的不同应用容器。例如,Pod 可能既包含带有 Node.js 应用的容器,也包含另一个不同的容器,用于提供 Node.js 网络服务器要发布的数据。Pod 中的容器共享 IP 地址和端口(以及存储Volume),始终位于同一位置并且共同调度,并在同一工作节点上的共享上下文中运行。
Pod是 Kubernetes 平台上的原子单元。 当我们在 Kubernetes 上创建 Deployment 时,该 Deployment 会在其中创建包含容器的 Pod (而不是直接创建容器)。
Appl.yaml: 配置文件,你可以在此指定系统的“Desired State”,而不必知道k8s是如何达到”Desired State”的。
图中,我们想要一个包含Image1&Image2的Pod,并且指定该Pod要有三个Replicas。
一个分配方案是让每个Worker运行一个Pod1实例。
当有Worker down的时候,k8s会自动把上面的任务分配到可用的机器上。
高级
Service
之前说过,每个Pod都有一个IP。但是提供同一应用的几个Pods可能会动态变化(比如某一台机器炸了),IP也会跟着变。有的时候我们不关心具体连到哪个Pod,只要能获得服务就可以了。
因此k8s在Pod之上又抽象了一个Service层,其包括一些Pods,并封装了对外的统一IP。还提供负载均衡功能。
在定义Service时,我们要指定该Service包含哪些Pods。这是通过选择器来实现的。每一个Pod上都有一些Label,比如name:syh。当我们选择name=syh时,就会选择到含有label name:syh
的Pods。
一个Service的endpoints
就是它所包含的每个Pod的IP。
Service默认只暴露给集群内部。可以设置成暴露给集群外部。
参见https://kubernetes.io/zh/docs/concepts/services-networking/service/#publishing-services-service-types