Docker基础

25

Docker基础

容器和虚拟机的区别。
虚拟机:包含了完整的操作系统,对完整的硬件结构进行了模拟。
容器:容器内包含了运行程序所需的最小资源,并且容器是直接运行在宿主机上的。

配置篇

配置镜像加速

将Docker仓库地址配置为阿里云的Docker仓库地址来加速镜像下载。
流程如下:

  1. 登录阿里云
  2. 选择产品->容器->容器镜像服务
  3. 执行镜像工具->镜像加速器->操作文档中对应操作系统的命令

命令篇

基础命令

镜像管理

查询和删除

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:将容器构建为镜像

镜像仓库

有两种方式,一种是使用云服务提供商的服务,比如阿里云的镜像仓库服务,还有一种是自己搭建镜像仓库。
如果使用阿里云的镜像仓库服务,使用步骤如下:

  1. 进入镜像仓库服务页面,创建个人版实例
  2. 创建命名空间
  3. 创建镜像仓库,一个镜像仓库对应一个镜像
  4. 点击仓库名称,进入仓库详情页,在操作指南部分有具体的仓库使用方法,包括镜像推送和镜像拉取方法
    利用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

关闭

以交互方式进入容器后,有两种方式退出容器,分别是:

  1. 输入exit,会导致容器停止。
  2. 使用快捷键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.tardocker export -o name.tar container_id:导出容器
  • docker import name.tar image_name:tagcat 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不会在容器被删除时,删除其挂载的数据卷。
特点

  • 数据卷可在容器之间共享或重用数据
  • 卷中的更改可以直接实时生效
  • 数据卷中的更改不会包含在镜像的更新中
  • 数据卷的生命周期一直持续到没有容器使用它为止

使用案例:

  1. redis数据持久化的目录可以放到宿主主机
  2. 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)