快速入门
容器 Container
- 早期的软件项目中软件更新,发布低效,开发测试发布周期很长,很难敏捷。有了容器技术,就可以利用其标准化的特点,大幅提高生产效率
- 容器技术提高了硬件资源利用率、方便了企业的业务快速横向扩容(可以达到秒级快速扩容)、实现了业务宕机自愈功能(配合K8s可以实现,但OpenStack无此功能)
=
使用容器技术的意义
-
统一基础设施环境(docker环境)、统一程序打包的方式(docker镜像)、统一程序部署的方式(docker容器)
-
每个虚拟机都有自己的OS。。。而所有容器与宿主共用OS内核,还能实现相互之间的隔离
namespace
内核通过6种namespace
实现容器运行空间的相互隔离
cgroups (Control groups)
-
内核通过
cgroups
对各个容器能访问的资源上限进行控制、同时还能设置进程优先级 -
namespace、cgroups
只实现了基础的容器运行环境,还需要容器管理工具’进行更加细致的管理’(比如docker)
docker
-
容器管理工具之一
-
是一个可以将应用程序及其依赖库打包成容器的工具,打包后的容器几乎可以在任何服务器上运行
-
Docker相当于增强版的LXC
LXC
已经淘汰的容器管理工具,可以提供轻量级的虚拟化功能
Podman(Pod Manager tool)
-
Podman是一个为 Kubernetes 而生的开源的容器管理工具
-
是一种无守护程序的容器引擎,用于在Linux系统上开发、管理和运行任何符合OCI 标准’的容器和容器镜像
-
Podman 里面87%的指令都和 Docker CLI 相同
容器技术规范(OCI 标准)
OpenContainer Initiative(OCI)
-
容器技术除了docker之外,还有coreOS的rkt,还有阿里的Pouch,为了保证容器生态的标准性和健康可持续发展,包括Linux 基金会、Docker、微软、红帽、谷歌和IBM等公司在2015年6月共同成立了一个叫Open Container Initiative(OCI)的组织,其目的就是制定开放的标准的容器规范
-
目前OCI一共发布了两个规范:
1.runtime spec
# 要求各种runtime技术相互兼容
2.image format spec
# 要求各种镜像格式相互兼容 -
有了这两个规范,不同的容器公司开发的容器只要兼容这两个规范,就可以保证容器的可移植性和相互可操作性
runtime
- runtime是真正运行容器的地方,是’容器的工作环境
- runtime分为许多类型,runc 是其中之一
runc
-
是 runtime 的一种
-
是目前Docker默认的runtime !!!
-
runc 遵守OCI规范
镜像 image
-
Docker启动一个容器需要一个外部模板,称为镜像
-
含有启动容器所需要的文件系统及所需要的内容。。。主要用于方便和快速地创建并启动容器
1.一个镜像可以被启动为多个容器
2.可以在旧镜像基础之上做自定义配置并将其提交为一个新镜像
3.docker的镜像可以保存在一个公共的地方(仓库)共享使用,只要把镜像下载下来就可以使用
仓库 Registry
统一保存多个不同镜像版本的地方,叫做镜像仓库
-
Docker hub:
docker官方的【公共仓库】,已经保存了大量的常用镜像,可以方便大家直接使用 -
阿里云,网易云:
第三方镜像的【公共仓库】 -
Image registry:
docker官方提供的【私有仓库部署工具】,无web管理界面,目前使用较少 -
Harbor:
vmware 提供的自带web界面、自带认证功能的【镜像私有仓库】
为什么要编排
1、当多个容器在多个主机运行的时候,单独管理容器是相当复杂的,而且很容易出错
2、无法实现某一台主机宕机后容器自动迁移到其他主机从而实现高可用的目的
3、无法实现动态伸缩的功能
'因此需要有一种工具可以实现统一管理、动态伸缩、故障自愈、批量执行等功能,这就是【容器编排引擎】
=
Docker compose
docker 官方实现【单机的】容器编排工具
Kubernetes
-
google领导开发的容器编排引擎
-
能同时支持 docker 和CoreOS,当前已成为容器编排工具 事实上的标准!!!!
CoreOS
-
CoreOS是一个基于Linux 内核的轻量级操作系统,为了计算机集群的基础设施建设而生,专注于自动化,轻松部署,安全,可靠,规模化
-
作为一个操作系统,CoreOS 提供了在应用容器内部署应用所需要的基础功能环境以及一系列用于服务发现和配置共享的内建工具。
一个典型的 Linux文件系统由 bootfs
和 rootfs
两部分组成
bootfs
- 主要包含bootloader和kernel
- bootloader主要用于引导加载 kernel,Linux刚启动时会加载bootfs文件系统,当boot加载完成后,kernel被加载到内存中后接管系统的控制权,然后bootfs就被卸载(unmount)
rootfs
-
包含的就是典型 Linux 系统中的
/dev、/proc、/bin、/etc
等标准目录和文件 -
不同的 linux 发行版( 如 ubuntu 和 CentOS ) 主要在 rootfs这一层会有所区别
镜像如何虚拟完整的OS环境
镜像含里面是一层层的文件系统,叫做’Union FS 联合文件系统’,可以将几层目录挂载到一起,形成一个’虚拟文件系统’
虚拟文件系统的目录结构就像普通 linux 的目录结构一样
'镜像通过虚拟文件系统(提供rootfs)再加上宿主机的内核(提供bootfs)共同提供了一个 linux 的虚拟环境。。。
从镜像加载启动为一个容器后,会生成一个可写层,其写入的数据会复制到宿主机上对应容器的目录,但是容器内的数据在删除容器后也会被随之删除
原理疑问
1.容器镜像打标签有何意义
# 在提交镜像的时候标记TAG号,生产当中常用,后期可以根据TAG标记创建不同版本的镜像以及创建不同版本的容器
2.Dockerfile中指定匿名卷VOLUMN有何作用
# 按照最佳实践的要求,不应该在容器存储层内进行数据写入操作,所有写入应该使用卷。如果定制镜像的时候,就可以确定某些目录会发生频繁大量的读写操作,那么为了避免在运行时由于用户疏忽而忘记指定卷,导致容器发生存储层写入的问题,就可以在 Dockerfile 中使用 VOLUME 来指定某些目录为匿名卷。这样即使用户忘记了指定卷,也不会产生不良的后果。
3.删除容器不会删除其对应的匿名卷
`docker rm` # 不会删除其对应的匿名卷
`docker rm -v` # 可以删除对应匿名卷
'但若使用命名卷或者挂载绝对路径,无论是否 -v 都不能删除对应的数据。。。
4.容器内时间、容器内时区是由什么决定的? 如何修改?
# 结论:
# 容器内时间默认使用UTC时间
[root@ubuntu1804 ~]# docker run -it centos bash
[root@b13888d228f3 /]#
[root@b13888d228f3 /]# ls -l /etc/localtime
lrwxrwxrwx 1 root root 25 Aug 9 21:40 /etc/localtime -> ../usr/share/zoneinfo/UTC
'由上可知:docker容器默认使用 UTC 时间
# 由软链接/etc/localtime 决定
# 两种修改方式:
【方法一】可在启动容器的时候直接 -v /etc/localtime:/etc/localtime
# 演示:
[root@ubuntu1804 ~]# docker run -it -v /etc/localtime:/etc/localtime alpine sh
/ # date
Fri Nov 20 21:40:34 CST 2020 '已经是CST时间
/ # ls -l /etc/localtime
-rw-r--r-- 1 root root 554 Sep 20 2019 /etc/localtime '挂载关系,因此不是软链接
/ #
【方法二】也可在进入容器之后修改/etc/localtime软链接指向
# 演示:
# 修改为上海时间:
# 先删除此软链接,再将其重新指向
[root@b13888d228f3 /]# rm -f /etc/localtime
[root@b13888d228f3 /]# ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
[root@b13888d228f3 /]# ls -l /etc/localtime
lrwxrwxrwx 1 root root 33 Nov 20 10:49 /etc/localtime -> /usr/share/zoneinfo/Asia/Shanghai
命令与配置疑问
1.docker ps -f 'status=up' 为什么执行失败
# 正确写法: docker ps -f 'status=running'
2.docker inspect --format="{{.Mounts}}" n1 中的 "{{.Mounts}}" 是什么语法
# 注意:docker inspect 可查看镜像。。也可查看容器。。
# 是Go语言模板。。。
3.docker volume rm `docker volume ls -q` 不能删除正在使用的卷?
# 是的。。。
# stop停止容器都不行。。。必须删除该卷对应的容器,才能删除卷
4.使用 'docker rm <容器ID>' 删除容器时,不会删除对应的匿名卷,因此会产生垃圾文件。。。
# 可使用 docker rm -v <容器ID> 实现 删除容器同时删除对应匿名卷
5. /etc/docker/daemon.json 文件中的 "hosts": ["tcp://0.0.0.0:2375", "fd://"] 什么意义???
# docker本身默认只提供单机连接使用
# 添加此项并重启服务,可实现远程主机连接本机docker管理容器
6.在 service 文件中指定 --bip 之后,如何复原成 172.17 ???
【方法一】重新指定 bip
【方法二】删掉文件中的 --bip ,重启主机。。。(注意重启docker不会复原)