Docker基础
Docker基础
容器和虚拟机的区别。
虚拟机:包含了完整的操作系统,对完整的硬件结构进行了模拟。
容器:容器内包含了运行程序所需的最小资源,并且容器是直接运行在宿主机上的。
配置篇
配置镜像加速
将Docker仓库地址配置为阿里云的Docker仓库地址来加速镜像下载。
流程如下:
- 登录阿里云
- 选择产品->容器->容器镜像服务
- 执行镜像工具->镜像加速器->操作文档中对应操作系统的命令
命令篇
基础命令
镜像管理
查询和删除
docker images
:列出本地所有镜像
docker search image_name
:根据镜像名称搜索镜像
docker pull image_name[:TAG]
:拉取镜像,如果忽略TAG,默认拉最新的
docker system df
:查看镜像、容器、数据卷所占用的空间
docker rmi image_id
:删除镜像id
docker rmi -f image_id
:强制删除镜像
docker rmi -f $(docker images -qa)
:删除全部镜像,$()
是一个表达式,从这里也可以看出docker支持参数的续传。
docker tag image_id registry_location/namespace/image_name:tag
:为目标镜像创建一个新的标签来引用目标镜像,一般用来构建镜像。
运行镜像
命令格式:
docker run [options] image_name[:TAG] [COMMAND]
options:
-i
:以交互方式运行,一般与-t
配合使用-t
:新开一个伪终端,一般与-i
配合使用,启动交互式容器示例docker run -it ubuntu /bin/bash
--name
:指定容器名称,docker run -it --name=myubuntu ubuntu
-p
:指定端口映射,格式:宿主机端口:容器端口
,docker run -p 8080:8080 ...
-P
:随机端口映射-d
:后台运行容器并返回容器id,也即启动守护式容器(后台运行)-v
:目录映射,格式-v /outer_path:/container_intra_path
-e
:添加环境变量--restart:type
:type可选值的详细信息见下文
数据卷:目录映射
在使用-v
进行目录映射时,如果映射的目录权限级别较高,则需要添加--privileged=true
参数,不然会报权限类型错误。
管理容器内映射文件夹权限
默认情况下,容器对映射文件夹具有读写权限,可通过type
修改默认值。
-v /outer_path:/container_intra_path:type
设置数据卷中type可取的值
ro
:仅读rw
:可读写
重启策略type可选值- no:不要自动重启容器
- on-failure[:max-retries]:如果容器因错误退出,设置重新启动的最大重试次数。当Docker进程重启时,容器不会重启
- always:如果容器停止,请始终重启容器。如果手动停止,则仅当Docker守护进程重启时,才会重启容器。
- unless-stopped:与always类似,唯一不同的是当Docker守护进程重启后,不会重启容器。
数据卷:继承目录映射
如果已经配置过一个docker容器,此时还想再运行一个容器,并且希望容器目录映射规则和之前的一致,此时可以使用volumes-from
参数(主要是需要指定父类名称)来继承之前的数据卷配置,包括目录映射规则和读写权限。格式如下:
docker run -it --privileged=true --volumes-from 父类名称 --name u2 ubuntu
构建镜像
docker commit -m='desc information' -a='author name' container_id commit_image_name:tag
:将容器构建为镜像
镜像仓库
有两种方式,一种是使用云服务提供商的服务,比如阿里云的镜像仓库服务,还有一种是自己搭建镜像仓库。
如果使用阿里云的镜像仓库服务,使用步骤如下:
- 进入镜像仓库服务页面,创建个人版实例
- 创建命名空间
- 创建镜像仓库,一个镜像仓库对应一个镜像
- 点击仓库名称,进入仓库详情页,在操作指南部分有具体的仓库使用方法,包括镜像推送和镜像拉取方法
利用docker创建私服仓库
docker run \
-e STORAGE=local \
-e STORAGE_PATH=/registry \
-p 5000:5000 \
-d \
--privileged=true \
-v /tmp/registry:/registry:rw \
registry
参数说明:
- storage_path:镜像仓库根目录
查看私服中的镜像仓库
通过docker安装的registry没有提供web管理页面,我们可以通过get命令来查看docker registry中包含哪些镜像仓库。
访问地址为:registry_location:5000/v2/_catalog
。如果在本地启动了registry,则访问地址为localhost:5000/v2/_catlog
。
镜像推送
可以使用如下命令将一个镜像推送到镜像仓库,如果私服没有设置密码,可以省略login这一步。
docker login --username=name registry_location
docker tag image_id registry_location/namespace/image_name:tag
docker push registry_location/namespace/image_name:tag
以上命令已在私服上测试,没有问题。
容器管理
列出
按要求列出容器
格式
docker ps [options]
options
-a
:列出所有容器,包含运行和退出的容器-l
:列出最近创建的容器
启动、重启、停止、强制停止、删除等
格式
docker [start|restart|stop|kill|rm] 容器id
关闭
以交互方式进入容器后,有两种方式退出容器,分别是:
- 输入
exit
,会导致容器停止。 - 使用快捷键
ctrl+p+q
,不会停止容器
查看容器资源占用情况
使用docker stats
命令
查看容器日志
使用命令docker logs 容器id
查看容器内进程运行情况
使用命令docker top 容器id
查看容器内部细节
docker inspect 容器id
重入容器
有两个命令可以重新进入容器中,但是它们有各自的特点,可按需要进行选择。
docker attach container_id
通过该命令进入容器,会复用之前的终端,如果在该终端输入exit
命令,将导致容器停止运行。
docker exec -it container_id /bin/bash
进入容器并新开一个伪终端,在新e开的伪终端中输入exit
不会导致容器停止。
注意:如果通过上面的方式进入终端失败,可以将bash
替换为sh
再试。
一般情况下,如果我们在启动容器时使用了-d
参数,那么就使用exec
进入容器。
文件传输
复制容器内文件到宿主主机
使用命令:docker cp container_id:/file_path /dir_path
导入导出容器
docker export container_id > name.tar
或docker export -o name.tar container_id
:导出容器docker import name.tar image_name:tag
或cat name.tar | docker import - image_name:tag
:导入容器
原理篇
UnionFS
联合文件系统(Union File System, UnionFs)它可以把不同物理位置的目录合并、挂载到同一个目录中,而实际上目录的物理位置是分开的。UnionFs 把文件系统的每一次修改作为一个个层进行叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。如果一次同时加载多个文件系统,UnionFs 会把各层文件叠加起来,最终文件系统会包含所有底层文件和目录,从外部视角看,就是一个完成的文件系统。所以说,联合文件系统实际上就是一个虚拟文件系统。
容器镜像设计中,为了解决各类依赖以及依赖共享,正是利用 UnionFs 实现了镜像分层,再结合 bootfs、rootfs,一层层继承、叠加。启动容器时把相关的层挂载到一个目录,作为容器的根文件系统,这就是容器镜像的原理。
- bootfs(boot file system):包含操作系统 bootloader 和 kernel。用户不能修改 bootfs,在内核启动后,bootfs 会被卸载。
- rootfs(root file system):包含系统常见的目录结构,如/dev 、/lib、/proc、/bin、/etc/、/bin 等
分层结构
Docker镜像的文件系统采用了UnionFS,最底层是bootfs和rootfs,在这之上可以是多个镜像层,启动该镜像后,会有一个容器层。只有容器层是可写的,其他层不可以进行修改。构建镜像的过程类似于面向对象编程中的单继承,我们可以基于某个镜像来构建自己的镜像,并且支持不断叠加。比如我们可以使用ubuntu镜像来构建自己的镜像。
镜像分层最大的好处就是共享资源,方便复制迁移,方便复用。比如说有多个镜像都是从同一份base镜像构建而来,那么Docker Host只需在磁盘上保存一份base镜像即可,同时内存中也只需加载一份base镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。
容器数据卷
卷就是目录或者文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统(UnionFS)。卷设计的目的就是数据的持久化,完全独立于容器的生命周期,因此Docker不会在容器被删除时,删除其挂载的数据卷。
特点
- 数据卷可在容器之间共享或重用数据
- 卷中的更改可以直接实时生效
- 数据卷中的更改不会包含在镜像的更新中
- 数据卷的生命周期一直持续到没有容器使用它为止
使用案例:
- redis数据持久化的目录可以放到宿主主机
- tomcat、nginx中,网站的静态数据需要随时修改,因此也可以放到宿主主机
常用容器篇
Tomcat
使用命令docker pull tomcat
来安装。
需要注意的是,新版的tomcat镜像默认情况下webapps
文件夹下是没有内容的,直接访问ip:8080/
会报404错误,tomcat默认资源在webapps-dist
文件夹下,可以通过mv webapps-dist webapps
来移动资源文件,移动后访问就可以看到那只猫了。
一般情况下,我们会将webapps文件夹通过-v
参数映射到宿主主机上。
MySQL
Mysql镜像的具体配置过程可以查看Docker Hub的官方页面,下面是一个示例。
docker run -d -p 3306:3306 \
--privileged=true \
-v /path/mysql/log:/var/log/mysql \
-v /path/mysql/data:/var/lib/mysql \
-v /path/mysql/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=123456 \
--name mysql \
mysql:5.7
上面的列子中,从上到下映射的数据卷内容有mysql日志、mysql数据文件夹、mysql配置文件夹,通过-e
参数指定了root密码。
MySQL集群部署方案可见:MySQL 中常见的几种高可用架构部署方案 - ZhanLi - 博客园 (cnblogs.com)