肝上面长了个人系列---------Docker
一、Docker背景:
以linux而言,linux操作系统会有一个主进程pid=1,派生出其他进程来控制不同服务例如: pid=2 --> python,pid=3–>java,pid4–>php ,三个服务可能会相互影响。
使用者期望将这三个不同的服务,跑在不同的运行时环境中实现相互不影响,同时不会增加服务器成本。
延伸出—>能否将这三种服务分别封装起来——>(vwM虚拟化技术,实现了一个操作系统模拟多个操作系统/不同的运行时环境。
随着技术发展—>虚拟化技术开销较大(例如:只要运行一个py脚本,想要使用虚拟化方式实现,还需要安装一个操作系统,并不方便/合理)
——>延伸出容器技术:
虚拟化层的抽象层(用户层)剥离,使用docker engine来替代(来宾操作系统去除),只要通过引擎就可以直接连接到宿主机操作系统中,极大减小了开销。

二、Docker概述
1、Docker概念:特殊的虚拟化
Docker是一个用于开发,交付和运行应用程序的开放平台。Docker使您能够将应用程序与基础架构分开,从而可以快速交付软件。
是一个开源的应用容器引擎,让开发者可以打包方式封装应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的Linux或者windows机器上,也可以实现虚拟化。
容器是完全使用沙箱机制(隔离机制),相互之间不会有任何接口。
沙箱(Sandbox):在计算机安全领域,沙箱是一种程序的隔离运行机制
Docker在2013年一炮而红,直到现在,已经成为容器技术的代名词。
Docker从一开始就以提供标准化的运行时环境为目标,真正做到"build once,run anywhere",可以将同一个构建版本用于开发、测试、预发布、生产等任何环境,并且做到了与底层操作系统的解耦(不吃操作系统)。在此基础上还进一步发展出了Caas(容器即服务)技术。
2、Docker特点:
- 服务彼此之间相互独立(服务之间的解耦)
- 服务可以灵活迁移(Docker引擎 docker-ce)
耦合是指两个或两个以上的体系或两种运动形式间通过相互作用而彼此影响以至联合起来的现象。
解耦就是用数学方法将两种运动分离开来处理问题,常用解耦方法就是忽略或简化对所研究问题影响较小的一种运动,只分析主要的运动。(便于管理,防止数据过多的积累在一个文件中)
小结:
Dcoker是基于容器技术的轻量级虚拟化解决方案;
docker是容器引擎,把linux的cgroup、namespaces等容器底层技术进行完美的封装、并抽象,为用户提供创建和管理容器的便捷界面(命令行cli、 api等)c/s;
cgroup :资源管理技术(LINUX—>cgroup )
2013年,发布了docker(面试话术)
是一种特殊的虚拟化:
①是一种轻量级的“虚拟机”,资源瓶颈受物理硬件资源限制;
②在Linux容器里运行应用的开源工具,有社区和企业版;
③类似于–集装箱(隔离),整个系统环境都丢在一个集装箱里。
程序可以在任何环境都会有一致的表现,这里程序运行的依赖也就是容器就好比集装箱,容器所处的操作系统环境
就好比货船或港口,程序的表现只和集装箱有关系(容器),和集装箱放在哪个货船或者哪个港口(操作系统)没有关
系。
docker的另一个好处就是快速部署,这是当前互联网公司最常见的一个应用场景,一个原因在于容器启动速度非
常快,另一个原因在于只要确保一个容器中的程序正确运行,那么你就能确信无论在生产环境部署多少都能正确运
行。
和宿主机共用内核。
3、Docker和虚拟即的区别:
- 容器提供实时配置和可伸缩性,但虚拟机提供缓慢的配置
- 与虚拟机相比,容器轻巧
- 与容器相比,VM的性能有限
- 与VM相比,容器具有更好的资源利用率

docker和vm ,解决了虚拟机的什么问题:
vm :
docker 解决了vm 的一个环境孤岛的问题–虚拟机没办法提前定义环境
docker 可以自定义传参(创建-创建镜像/容器、启动(基于镜像启动)之前)
4、Docker使用场景:
K8S底层里也是用image镜像+container容器的方式
war jar —>github gitlab 私有仓库(代码仓库)—>jenkins(测试)(应用程序封装/构建镜像)—>运维下载,使用容器技术进行运行/发布打包应用程序简单部署
可脱离底层硬件任意迁移(实现了应用的隔离,将应用拆分并进行解耦),例如:服务器从腾讯云迁移到阿里云持续集成和持续交付(cI/CD) :开发到测试发布
部署微服务
提供PAAS产品(平台即服务){OpenStack的云主机类似于阿里云的EcS,属于IAAS、Docker (KBS)属于PAAS}
运行时:一个程序在运行的依赖。
运行时环境:服务跑起来并持续运行所处的环境。
环境组成因素—>Linux平台、依赖环境c++,gcc、配置文件、其他相关配置/组件。
运行时仅指应用服务正常运行的状态。
①打包应用程序简化部署;
②可脱离底层硬件任意迁移
例:服务器从腾讯云迁移到阿里云
5、Docker引擎(Docker Engine)
Docker Engine是具有以下主要组件的C/s客户端-服务器应用程序:server端:服务器是一种长期运行的程序,称为守护程序进程( dockerd命令)。做事,等待指示
CLIENT端:REST API,它指定程序可以用来与守护程序进行通信并指示其操作的接口。命令行界面( CLI)客户端( docker命令)。
展示:
docker run
docker start
docker rm
6、如何实现应用A和应用B隔离:
应用和应用的隔离,如何进行判断:
以操作系统维度:
应用A与应用B隔离,在操作系统中,是通过namespaces (名称空间、命名空间)实现的,只要实现以下6个空间隔离,才能认为两个应用实现了完全/完整隔离。
docker把容器化技术做成了标准化平台cAAS (docker统一/指定了容器化技术的标准化平台)
7、名称空间
docker底层原理:
构成:cgroup和namespaces两者结合,控制管理了6个名称空间资源。
cgroups:Linux内核态中资源管理的模块,管理一些系统资源。
容器隔离了6个名称空间(namespace资源隔离-用容器化技术封装):
mount:文件系统,挂载点―—>一个文件系统内,不能重复挂载一个
指定目录,例如:/mnt。
user:操作进程的用户和用户组。
pid:进程编号。
uts:主机名和主机域。
ipc:信号量、消息队列,共享内存(理解,不同的应用调用内存资源的时候应该使用不同的内存空间)。
net:网络设备、网络协议栈、端口等。例如:IP相同
----->k8s可以选择某些隔离,某些不隔离。
该pid命名空间:进程隔离(PID:进程ID) 。
该net命名空间:管理网络接口(NET:网络)。
该ipc命名空间:管理访问IPC资源(IPC:进程间通信)。
该mnt命名空间:管理文件系统挂载点(MNT:mount) 。
该uts命名空间:隔离内核和版本标识符(UTs: Unix时间共享系统)。
docker引擎对内核版本有要求:3.8+
docker需要cgroups的资源管理功能;
最晚的一个名称空间定义,从内核版本3.8开始。
**控制组( control groups):**控制资源分配,实施约束
Linux上的Docker引擎还依赖于另一种称为控制组( cgroups)的技术。
cgroup将应用程序限制为一组特定的资源。控制组允许Docker Engine将可用的硬件资源共享给容器,并有选择地实施限制和约束。例如,您可以限制特定容器可用的内存。
8、### docker有什么意义:
docker把容器化技术做成了一个标准平台–CaaS–统一了容器化技术的标准化平台。
三个意义上的统一:
docker引擎统一了基础设施环境-docker环境―—>image—>封装一个简易的操作系统(3.0+G)
docker引擎统一了程序打包(装箱)方式-docker镜像—>images
docker引擎统一了程序部署(运行)方式-docker容器——>基于镜像->运行为容器(可运行的环境)实现了一次构建、多次、多处使用
要求:内核在3.8以上—>排除了centos6,centos7也就3.10
可以了解红帽版本
uname -r
docker 1.30版本迭代docker-ce docker-ee 1.7版本—>企业版和社区版
app 飞跃
不需要互联网、不需要电脑
小程序飞跃
只要安装微信即可
微信小程序,统一了平台,根据自己的平台发布所有需要的东西
一次调试,多处适用

9、### docker三要素:
镜像:模板,一组资源集合,包含了应用程序软件包、应用程序相关的依赖包、运行应用程序所需要的基础环境(泛指操作系统环境),可以理解为容器的模板。
容器:运行状态/运行时状态,基于镜像的一种运行时状态
仓库:存放镜像模板,存放image镜像,仓库大类:1、公共仓库—》docker hub 2、私有仓库 registry harbor。
即:
镜像是容器的基石,容器是在镜像的基础上创建的。一个镜像可以创建多个容器,仓库用来存放和分发镜像
10、### docker架构:( Docker architecture)
Docker使用客户端-服务器架构。
Docker 客户端与Docker守护进程进行对话,该守护进程完成了构建,运行和分发Docker容器的繁重工作。
Docker区别于传统的虚拟化,不需要虚拟硬件资源,直接使用容器引擎,所以速度快。
Docker Client:客户端/提供一个与用户交互,展示的平台+管理、控制docker服务端(功能)的工具docker。
Docker客户端(docker)是许多Docker用户与Docker交互的主要方式。
当您使用诸如之类的命令时docker run,客户端会将这些命令发送到dockerd,以执行这些命令。该docker命令使用Docker API。Docker客户端可以与多个守护程序通信。
Docker daemon:守护进程
Docker守护程序( dockerd)侦听Docker API请求并管理Docker对象,例如图像,容器,网络和卷。守护程序还可以与其他守护程序通信以管理pocker服务。
Docker images:镜像容器可以被打包成镜像
Decker container:容器
Docker registry:镜像仓库
yum install
docker pull nginx
11、仓库:
存储镜像的地方,默认在公共的Docker Hub上查找,可以搞个人仓库(registry、harbor)
yum仓库:rpm包
公共仓库:有一些东西官方不会做,例如LAMP、LNMP,很多是私人做的,安全性无法保证。
本地yum仓库
docker:镜像
docker hub公共仓库
docker-harbor 上传下载方便、安全
github: github——>404——>延迟
代码仓库:
gitlab:用的多
svn:用的多
码云
gitee
centos:依赖包、应用程序
三、容器部署:
1、环境配置:
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
2、安装依赖包:
yum -y install yum-utils device-mapper-persistent-data lvm2
//device 存储驱动 lvm2 资源控制工具
3、设置阿里云镜像源:
cd /etc/yum.repos.d/
yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
4、安装docker-ce社区版:
yum -y install docker-ce
5、开启docker:
systemctl start docker
systemctl enable docker
6、设置镜像加速:
tee /etc/docker/daemon.json << -'EOF'
{
"registry-mirrors": ["https://6z5b9t6z.mirror.aliyuncs.com"]
}
EOF
systemctl daemon-reload
systemctl restart docker
-------------镜像加速注册地址
https://help.aliyun.com/document_detail/60750.html
-------------查看地址
cd /etc/docker
cat daemon.json
7、网络优化:
vim /etc/sysctl.conf
net.ipv4.ip_forward=1
sysctl -p
systemctl restart network
systemctl restart docker
8、面试题:生产经验:docker-server端配置文件:daemon.json
"graph": "/data/ docker", 数据目录
"storage-driver": "overlay2", 存储引擎LxC -》overlay ——》overlay2--存储驱动,overlayfs文件系统
"insecure-registries": ["registry.access.redhat.com","quary.io"] 私有仓库
"registry-mirrors": [ "https://q" ] 镜像加速
"bip": "172.7.5.1/24", **docker网络
"exec-opts": [ "native.cgroupdriver=systemd" ], 启动时候的额外参数(驱动,k8s)
"live-restore": true 当docker容器引擎挂掉的时候,使用docker跑起来的容器还能运行(分离)}
以上是建议的配置项
docker容器网络生产经验
docker 的网络建议和宿主机的IP"对照”
比如宿主机 10.2.5.6容器的地址就可以修改为172.5.6.1,这样方便在故障发生时,更容易定位故障节点位置
systemctl daemon-reload
systemctl restart docker
9、docker镜像操作:
docker run hello-world
run:
①pull dockerhub---仓库有层级关系:项目/库/镜像
②start hello-world-image
1、docker client客户端连接到了服务端(服务端是以一个守护进程的形式跑在操作系统里面的)restful api典型的c/s架构
2、由docker服务端的守护进程从docker hub 上下载了镜像:
守护进程会先检测本地有无镜像
3、服务端创建了一个新的容器,然后从拉去的这个镜像启动了一个容器,容器执行了脚本/可执行程序让我们可以查看/使用( client)
4、docker服务端把这些信息流(传递)返回到客户端并展示出来(展示在终端上)
docker client 可以是多种形式,比如"docker"命令工具所在的终端
延伸:
yum仓库,如何开启缓存?软件包保存在哪?
PS:删除先删容器,再删镜像
面试题:docker的常规操作?进入容器方式的询问?attach和exec的区别?

面试题:如何批量删除容器、镜像、exit(指定)状态的容器?正则匹配
created状态

10、docker基本命令:
docker十条命令(运维相关):
镜像操作:
docker -v //查看docker版本
docker version //看客户端和服务端版本信息
docker info //看【版本、驱动、私有地址网段、镜像仓库地址、跑的镜像数量、状态】、资源管理器状态、运行时环境、分离情况,文件系统等
docker search 镜像关键字 //查找镜像
例如:docker search nginx/centos:7
docker pull 镜像名称 //下载镜像,默认从docker hub里面下
docker images/image ls //查看镜像列表
docker inspect 镜像ID //查看镜像信息
docker tag nginx:latest nginx:lamp //给镜像打标签---便于识别,使用私有仓库,推镜像必须打标签
docker rmi 镜像名称/镜像标签 //删除
docker save -o 文件名 镜像名 //导出镜像,例如:docker save -o centos_7 centos:7
docker load < centos:7 //导入镜像
容器操作:
docker ps -a //查询容器
docker ps -q //过滤容器ID,过滤所有+a
docker rm `docker ps -aq` //删除所有容器非up状态,docker rm -f `docker ps -aq`,强制删除
如何后台持续运行???
docker create -it nginx:latest /bin/bash //创建容器
-i:让容器的标准输入保持打开
-t:分配一个伪终端--->不然进不去,需要个入口
-d:后台守护进程的方式运行
docker start 容器ID(持续) //启动容器
docker run centos:latest /usr/bin/bash -c ls / //容器启动一次性执行,非持续,例如执行脚本,-c传递命令参数
docker stop 容器ID //停止容器,返回非0值,例如137,以主动退出方式停止容器
docker run -d centos:7 /usr/bin/bash -c "while ture;do echo hello;done" //后台持续运行
进入容器:
1、run:
docker run -it nginx:latest /bin/bash
docker run -itd --name centos centos:7 /bin/bash //指定容器名称创建
2、exec:(容器必须开启状态)
docker exec -it 容器ID /bin/bash
PS:
docker run -it会创建前台进程,但是会在输入exit后终止进程。
docker attach 会通过连接stdin,连接到容器内输入输出流,会在输入exit后终止进程.
docker exec -it 会连接到容器,可以像SSH一样进入容器内部,进行操作,可以通过exit退出容器,不影响容器运行。
ctrl+d也可以退出
PS:
容器内什么都没有,ifconfig等都用不了---->①下载②以不同环境运行
docker export 容器ID > 文件名 //容器导出
例如:docker export 容器ID > nginx_a
docker import 导出的文件名(容器) 指定镜像名称 //容器导入,生成镜像
例如:docker import nginx_a nginx:latest
cat 文件名(容器) | docker import - nginx:latest
docker rm 容器ID //删除容器
docker rm -f 容器ID //强制删除容器
docker ps -a | awk '{print "docker rm $1"}' | bash //批量删除容器
for i in `docker ps -a | grep -i exit | awk '{print $1}'`;do docker rm -f $i;done //批量删除exit状态的容器

11、制作镜像:
自己制作镜像,上传docker hub上。
优化—>减少镜像大小dockerfile,对企业而言,是加分项。
12、面试话术:
Linux发行版本:alpine centos redhat Debian(apt包管理,centos是rpm),生产环境可能会用。
---->知道/用过哪些Linux版本?
13、面试题:容器状态有哪些,分别是什么场景?
四、docker网络模式:
面试题:容器网络和网络模式:
1、docker中有几种网络模式,提供了哪些功能?

2、两个容器如何通信?**

3、暴露端口里,-p和-P区别?
-p 自定义端口(宿主机端口:容器内端口)
-P 随机端口(端口49153起始,为什么?)
docker端口范围49153–65535。
4、怎么把宿主机文件传入到容器内部?

docker inspect 看是否为特权容器
PS:docker网络原理:深层次–与k8s中网络查件flannel和calico相关:
Docker daemon—>通过api控制docker的网络,docker网络通过两部分组成,① CNM(设计规范)②libnetwork网络库(从docker daemon中拆分出来的)
①CNM:
定义的是构建容器的虚拟化网络的模型,有三个组件:沙盒+端点+具体网络技术(比如linux bridge 、VLAN等)
②libnetwork网络库(从docker daemon中拆分出来的)
是CNM设计规范的实现,实现的是CNM中的三个组件包含docker的核心网络代码,还可以实现服务发现,K8s里面ingress对容器的负载均衡也会使用这个网络库简单说是实现网络控制和管理
③驱动:实现数据管理,bridge 驱动、host 驱动、container驱动、overlay驱动(k8sflannel) . remote驱动、nuli驱动(就是实现几个网络模型的数据管理层)
1、容器网络图:
loopback:回环网卡、TCP/IP网卡是否生效。
docker0:容器的网关,绑定物理网卡,负责做NAT、地址转换、端口映射。
docker0本身也是一个容器。

virtual bridge:Linux
自身继承一个虚拟化功能(KVM),是原生架构的一个虚拟化平台,安装了一个虚拟化平台后系统就会自动安装虚拟网卡。

2、docker网络模式:四种

面试题:docker有几种网络模式,分别干嘛用的。
Host、Container、none、bridge四种。
Host:与宿主机共享网络名称空间/网络协议栈。
Container:多个容器之间共享一个network namespaces
none:自闭空间
bridge:默认模式,通过vth对连接容器与docker0网桥,网桥分配给容器IP,同时docker0作为“局域网”内容器的
网关,最后和宿主机网卡进行通讯。
①HOST模式:nat共享
host容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口;
如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。—只有net不隔离
使用host模式的容器可以直接使用宿主机的IP地址与外界通信,容器内部的服务端口也可以使用宿主机的端口,不需要进行NAT,host最大的优势就是网络性能比较好,但是dockerhost上已经使用的端口就不能再用了,网络的隔离性不好。

②container模式:不会创建自己的网卡,IP等,而是和一个指定的容器共享IP、端口范围
这个模式指定新创建的容器和已经存在的一个容器共享一个network namespace,而不是和宿主机共享,新创建
的容器不会创建自己的网卡,配置自己的IP,而是和一个指定地容器共享IP、端口范围等。
同样,两个容器除了网络方面,其他的如文件系统、进程列表还是隔离的。(★★***两个容器的进程可以通过lo0
网卡设备通信)

③none模式:该模式关闭了容器的网络功能:
可能测试,生产环境不会单独用;
这种网络模式下容器只有lo回环网口,没有其他的网卡。none模式可以在容器创建时通过-network=none参数指定;
这种类型的网络无法联网,但是封闭的网络能很好的保证容器的安全性。

④bridge模式:
此模式会为每一个容器分配、设置IP等,并将容器连接到一个docker虚拟网桥,通过docker0 网桥及iptables.的
nat表配置与宿主机通信。
当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟
网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。
从docker0子网中分配一个IP给容器使用,并设置dockero的IP地址为容器的默认网关。在主机上创建一对虚拟网
卡veth pair 设备,Docker 将veth pair 设备的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放
在主机中,以vethxxx,这样类似的名字命名,并将这个网络设备加入到docker0网桥中。可以通过brctl show命令
查看。
bridge模式是docker的默认网络模式,不写-net参数,就是bridge模式。使用docker run -p时, docker实际是在
iptables,做了DNAT规则,实现端口转发功能。可以使用iptables -t nat -vnl查看。

容器内部连接和对外暴露服务方式,IP,端口2个角度。

3、自定义网络:
docker network ls—>默认的中没有container这个模式,因为这个模式需要2个容器。
docker network ls //查看网络列表
docker inspect 容器ID //查看容器IP,配置,环境,网关,挂载,cmd等
PS:
docker run -itd --name test1 --network bridge --ip 172.17.0.10 centos:latest /bin/bash
(以上会报错)
docker network create --subnet=172.18.0.0/16 mynetwork //创建网段
docker run -itd --name test2 --net mynetwork --ip 172.18.0.100 nginx:latest /bin/bash
//自定义网络固定IP
docker run -itd -p 333:80 nginx /bin/bash //暴露端口---公网访问内部容器
docker run -itd -P nginx /bin/bash //暴露端口--随机
为什么run没有启动nginx啊?
docker exec -it 容器ID /bin/bash -c 'nginx' //在宿主机环境执行容器内命令
docker exec 容器ID/容器name 执行的命令
docker run -d -p 8808:80 nginx //这种方式直接可以创建容器并启动nginx

①面试题:
怎么把宿主机的文件传到容器内部?

五、docker数据卷:
面试:应用场景:
原理:将容器内部的配置文件目录挂载到宿主机指定目录下
作用:
1、修改配置文件,如nginx.conf /usr/local/nginx/conf/nginx.conf —> /container_data_nginx/conf/nginx.conf
2、容器内部产生的日志,如何收集?
将容器内部存放日志文件的目录挂载到宿主机指定目录下,/container_nginx/log/access_log/access_log
3、传入变量
挂载到宿主机,在宿主机添加变量内容,将变量放入共享目录,在容器中,/etc/profile直接加载
export xxdir=/ata/data1/xx
source

1、docker数据卷:


2、数据卷容器:
原理:让2个容器实现数据共享,配置、变量。
PHP和MySQL通讯,借助socket通讯文件。—>数据卷容器,mysql的socket和php组件对接,实现通讯。


容器互联:应用在
哨兵—>监控redis
哨兵和redis包括哨兵和哨兵间相互监控,用ping命令。
分担docker0压力。
六、dockerfile:
1、创建容器的几种方式:
①基于已有的模板文件进行创建;
容器导出、导入
②基于已有的镜像进行创建;
③dockerfile。
2、镜像分层简单版
镜像内容:

镜像分层示意图:

container 容器层
images 镜像层(应用的镜像层—>上层镜像层)
images 镜像层(依赖环境的镜像层—>下层)
base image 基础镜像层(Linux发行版本 操作系统 rootfs)
kernel 内核层(aufs+bootfs)
因为各linux发行版本公用一套bootfs引导、加载文件系统(是由宿主机内核提供的)
同时vm虚拟机的操作系统需要完整的模拟出来
所以容器的操作系统比vm虚拟机的操作系统更为轻量级
(区别在于容器是共享宿主机内核的)
简单一:
①最基础:FROM—>base image—>发行版本
②ADD run.sh—>依赖环境
③CMD/VOLUME—>执行/挂载执行启动脚本命令指令
----->
镜像:一组资源的集合,以分层的方式一层层累加,组成
完整的镜像。
最上层:work工作层—>整合展示。
每层都是一个小的镜像。
简单二:

缓存复用,直到工作层,把所有缓存保存在工作层,并清空下面的缓存。—>减小镜像大小
如果有更新,work层抛弃原有持久化缓存,从新加载各层缓存。—>生成全新镜像
镜像2创建文件,镜像3删除。删除的是2的缓存,文件依旧存在2中。不会相互影响
AUFS:堆叠式文件系统,把多个文件内容合并一起,提供一个统一的视图展示。用与docker组织images。
堆叠/组合形式挂载+统一展示
3、docker镜像分层(基于AUFS构建):Docker镜像位于bootfs之上
每一层镜像的下一层成为父镜像
第一层镜像成为base image(操作系统环境镜像>容器层(可读可写),在最顶层(writable)
容器层以下都是readonly
即:
contaier读写层
images (只读)base image
bootfs + rootfs + aufs(kernel)

2、涉及技术:
①bootfs (boot file system)
主要包含bootloader和kernel
bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs
这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs
在linux操作系统中(不同版本的linux发行版本),linux加载bootfs时会将rootfs设置为read-only,系统自检后会将只读改为读写,让我们可以在操作系统中进行操作
②rootfs (root file system)
在bootfs之上 (base images,例如centos 、 ubuntu)
包含的就是典型 Linux系统中的/dev,/proc,/bin,/etc等标准目录和文件
rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等
小结:为什么docker的centos镜像只有200M多一点
bootfs+rootfs:作用是加载、阴道内核程序+挂载使用Linux操作系统等一些关键目录文件
对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供 rootfs就行了。由此可见对于不同的linux发行版,bootfs基本是一致的,rootfs会有差别,
因此不同的发行版可以公用bootfs

③AUFS 与overlay /overlay2 (docker 高版本)
AUFS是一种联合文件系统。它使用同一个Linux host上的多个目录,逐个堆叠起来,对外呈现出一个统一的文件系统。AUFS使用该特性,实现了Docker镜像的分层。
而docker 使用了overlay/overlay2存储驱动来支持分层结构:
OverlayFS将单个Linux主机上的两个目录合并成一个目录。这些目录被称为层,统一过程被称为联合挂载
overlay 结构:
overlayfs在linux主机上只有两层,一个目录在下层,用来保存镜像(docker),另外一个目录在上层,用来存储容器信息:
1、rootfs 基础镜像
2、lower 下层信息(为镜像层,容器)
3、upper 上层目录(容器信息,可写)
4、worker 运行的工作目录( copy-on-write写时复制–》准备容器环境)
5、mergod "视图层”(容器视图>
docker镜像层次结构小结:
1、base image :基础镜像
2、image:固化了一个标准运行环境,镜像本身的功能-封装一组功能性的文件,通过统一的方式,文件格式提供出来(只读)
3、container:容器层(读写)
4、docker-server端
5、呈现给docker-client(视图)
PS:小实验:联合挂载:
mkdir demo
cd demo/
mkdir lower
mkdir upper
ls
echo "lower.aaaa" > lower/aaaa
echo "lower.bbbb" > lower/bbbb
echo "upper.bbbb" > upper/bbbb
echo "upper.cccc" > upper/cccc
yum -y install tree
mkdir work
mkdir mergod //展示目录
tree -L 2
mount -t overlay overlay -o lowerdir=lower,upperdir=upper,workerdir=work mergod //挂载
df -hT
tree -L 2 //看下前后区别
4、dockerfile编写:
面试题:
CMD和entrypoint区别是什么???
ADD和COPY区别是什么???
copy=复制,将宿主机指定的文件复制到image层中;
add=可以复制,同时兼有解压功能,将压缩包复制进去的同时会对压缩包进行解压。
add复制对象可以是URL—>跨节点的数据。

PS:制作Nginx镜像:
mkdir nginx
cd nginx/
vim Dcokerfile
FROM centos:7
MAINTAINER THIS IS NGINX IMAGES
RUN yum -y install update
RUN yum -y install pcre-devel zlib-devel gcc gcc-c++ make
RUN useradd -M -s /sbin/nologin nginx
ADD nginx-1.12.0.tar.gz /usr/local/src
WORKDIR /usr/local/src/nginx-1.12.0
RUN ./ configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--with-http_stub_status_module && make && make install
ENV PATH /usr/local/nginx/sbin:$PATH
EXPOSE 80
RUN echo "daemon off;">>/usr/local/nginx/conf/nginx.conf
CMD nginx
基于dockerfile文件构建镜像:
docker build -t nginx:new
完整版:docker build -f dockerfile -t nginx:new .
docker build:基于dockerfile构建镜像的命令
-f:指定dockerfile文件—不写默认当前目录
-t:(tag)打标签—>nginx:new
.:专业说法,指的是构建镜像时的上下文环境,简单理解:值得当前目录环境中的文件,不指定会遍历目录。
3、优化DOCKERFILE
1、优化方式
减少RUN 指令的使用
RUN yum -y update
RUN yum install -y gcc gcc-c++
整合为yum install -y gcc gcc-c++ && yum -y update
将执行后的缓存/不用的输出丢入黑洞 (减少缓存)
yum install -y gcc gcc-c++ && yum -y update > /dev/null
多阶段构建
使用更小体积的linux发行版本
更加轻量级的centos的版本
4646

被折叠的 条评论
为什么被折叠?



