- 容器本身没有价值,有价值的是容器编排技术
- 容器(docker)其实是一种沙盒技术,一是可以将应用之间隔离开来,二是方便地将应用"搬来搬去"(快速装载,快速卸载)
- 容器其实是一种特殊的 进程,在容器外面观察它时(ps),它是普通的进程,在容器里面观察它时,外部的细节被屏蔽掉(namespace),使得它以为自己是独立存在的.容器本质上就是一个加了限定参数(namespace)的进程
- docker是没有上过历史课的进程
- 容器较轻量,虚拟机较重.容器底层依赖的仍然是宿主机的硬件/驱动,而虚拟机自己模拟了这些硬件/驱动.容器实现的仅是视图隔离
- cgroups 是Linux内核提供的一种可以限制单个进程或者多个进程所使用资源的机制,可以对 cpu,内存等资源实现精细化的控制,目前越来越火的轻量级容器 Docker 就使用了 cgroups 提供的资源限制能力来完成cpu,内存等部分的资源控制
- 虽然docker通过cgroups实现了容器的视图隔离,但是在容器内使用/proc下的命令,例如top/free等,看到的仍然是宿主机的信息,这是因为容器没有做到对/proc,/sys等文件系统的资源的视图隔离.可以通过lxcfs来解决这个问题
- cgroup只能对容器使用的资源上限做限定,但不能锁定下限,这很容易导致被其他容器抢占资源.k8s完善了这点
- rootfs : 根文件系统,挂载在容器的根目录上,用来为容器进程提供隔离后执行环境的文件系统.也就是所谓的"容器镜像" .包括的目录和文件有/bin , /etc , /proc等等.进入容器后执行的/bin/bash,就是这个目录下的/bin目录下的文件,与宿主机的/bin/bash不同
- docker容器使用了多个增量rootfs联合挂载一个完整rootfs的方案,也就是容器镜像中"层"的概念,包括可读写层,init层,只读层.只读层是共享层,我们使用docker commit提交本地修改后的docker镜像,实际上提交的是可读写层的内容,我们的修改都保存在读写层(分层复用).
- 上面的读写层通常也称为容器层,下面的只读层称为镜像层,所有的增删查改操作都只会作用在容器层,相同的文件上层会覆盖掉下层。知道这一点,就不难理解镜像文件的修改,比如修改一个文件的时候,首先会从上到下查找有没有这个文件,找到,就复制到容器层中,修改,修改的结果就会作用到下层的文件,这种方式也被称为copy-on-write。
- 一个进程,可以选择加入到某个进程已有的 Namespace 当中,从而达到“进入”这个进程所在容器的目的,这正是 docker exec 的实现原理
- 快速部署k8s的工具是kubeadm,它直接运行在宿主机上,然后k8s的其他组件以容器的方式被kubeadm调用(封装成pod)
- pod的定义文件是yaml.master等组件的yaml文件,在/etc/kubernetes.manifests路径下
- 快速部署k8s的工具:kops,ranche,minikube,katacoda提供的在线学习平台
- 创建pod的命令: kubectl apply -f [url] ,可以使用的文件包括
.yaml
/.yml
/.json
- rook:一个基于 Ceph 的 Kubernetes 存储插件
- 基于 Kubernetes 开展工作时,你一定要优先考虑这两个问题:我的工作是不是可以容器化?我的工作是不是可以借助 Kubernetes API 和可扩展机制来完成?
- 我们在yaml文件中定义API对象(pod),每一个API对象都有一个叫做Metadata的字段,即元数据,它是API对象的"标识",也是我们从k8s里找到这个对象的主要依据.这其中主要用到的字段是Labels,它是一组k-v格式的标签
- kubectl describe用于查看一个API对象的细节.在 Kubernetes 执行的过程中,对 API 对象的所有重要操作,都会被记录在这个对象的 Events 里,并且显示在 kubectl describe 指令返回的结果中.所以,这个部分正是我们将来进行 Debug 的重要依据。如果有异常发生,你一定要第一时间查看这些 Events,往往可以看到非常详细的错误信息。
- k8s鼓励开发者使用kubectl apply YAML文件这样的声明式API去替代docker run这种基于命令行的操作,因为这样可以以文件的形式记录下对k8s的操作,这样运维人员和开发人员可以通过yaml来进行交流沟通.
- 容器是单进程模型(并不是指容器里只能运行“一个”进程,而是指容器没有管理多个进程的能力)
- pod中可以有多个容器
- Pod 的实现需要使用一个中间容器Infra.在这个pod中,infra容器永远是第一个被创建的容器,而其他用户定义的容器,则通过 Join Network Namespace 的方式,与 Infra 容器关联在一起。Pod 的生命周期只跟 Infra 容器一致,而与容器 A 和 B 无关。
- 如果你能把 Pod 看成传统环境里的“机器”、把容器看作是运行在这个“机器”里的“用户程序”,那么很多关于 Pod 对象的设计就非常容易理解了