Docker 基础篇
Docker 基础篇
镜像加速器配置
使用阿里云官网的容器镜像服务提供的镜像加速器提高docker
下载速度。
修改/etc/docker/daemon.json
来使用加速器。
帮助启动类命令
systemctl
类似于任务管理器
systemctl start docker # 启动 docker 服务
systemctl status docker # 查看 docker 服务的状态
systemctl stop docker # 停止 docker
systemctl restart docker # 重启 docker
systemctl enable docker # 开机后自动启动 docker 服务
docker info # 查看 docker 概括信息
docker --help # 查看 docker 相关命令
docker 具体命令 --help # 查看具体命令用法
镜像命令
docker images -[aq] # 列出本地仓库镜像
#-a 列出本地所有镜像(包括历史映像层)
#-q 只显示镜像ID
docker search 镜像名称 # 查看远程仓库该镜像信息
docker pull 镜像名称[:版本号] # 从远程仓库拉去镜像
docker system df # 查看镜像/容器/数据卷所占空间
docker rmi [-f] 镜像名称/ID # 删除镜像
# -f 强制删除
docker rmi -f $(docker images -qa) # 删除所有镜像
容器命令
# 新建/启动容器
docker run [OPTIONS] IMAGE [COMMAND]
OPTIONS说明:
--name="容器名称"
-d 后台运行容器并返回容器ID,即守护进程
-i 以交互模式运行,通常与 -t 一起使用
-t 为容器重新分配一个伪输入终端,通常与 -i 一起使用
-p port(宿主机端口):port(容器端口)
# 列出容器
docker ps [OPTIONS]
OPTIONS说明:
-a 所有容器(包括运行的和停止的)
-l 最近运行的容器
-n cnt 最近运行的cnt个容器
-q 只显示容器ID
# 退出容器
exit # run 进去容器后,执行exit退出,容器停止
ctrl+p+q # run 进去容器后,ctrl+p+q退出,容器不会停止
# 启动已停止的容器
docker start ID/NAME
#重启容器
docker restart ID/NAME
# 停止容器
docker stop ID/NAME
# 强制停止容器
docker kill ID/NAME
# 删除容器
docker rm [-f] ID
# 查看容器日志
docker logs ID
# 查看容器内运行的进程
docker top ID
# 查看容器内部细节
docker inspect ID
docker run -it 命令示例
docker run -it centos /bin/bash
-it
启动交互模式,在进入交互模式后应有个交互式shell
,其中 /bin/bash
命令指定这个shell
是bash
,输入exit
退出终端并且容器停止,输入ctrl+p+q
退出终端但容器不会停止
从容器拷贝文件到主机
docker cp ID:/tmp/a.txt /usr/data/b.txt
将容器内路径文件拷贝到宿主机对应路径
后台守护进程启动容器
在大部分场景下,我们希望 docker 服务以守护进程模式运行(比如 redis),可以通过 -d 指定后台运行。
进入前台交互容器
docker exec -it ID /bin/bash
docker attach ID
两者区别:attach
直接进入容器启动命令的终端,不会启动新的进程,用exit
退出,会导致容器停止,而exec
在容器中打开新的终端,并且可以启动新的进程,用exit
退出,不会导致容器的停止。
推荐使用exec
命令
docker run 与 docker run -d 区别
执行docker run redis
后容器以前台模式运行,当前终端即为容器终端,一旦退出当前终端则redis
容器停止运行,而执行redis run -d redis
后redis
容器以后台守护模式运行,仍然可以以前台交互模式进入该容器,且退出终端后容器不会停止。
在一些情况下这两者并没有区别,比如运行ubuntu
容器时就都是后台守护模式
导入/导出容器
导出容器
docker export ID > 文件名.tar
导入容器镜像
cat 文件名.tar | docker import - 镜像用户/镜像名:镜像版本号
示例:
docker run exec -it ubuntu bash
docker export ID > abc.tar
cat abc.tar | docker import - horizon:1.0
至此本地镜像多了一个REPOSITORY
为horizon
,TAG
为1.0的ubuntu
镜像
注意:启动export与import命令导出导入的镜像必须加/bin/bash或者其他/bin/sh,否则会报错docker: Error response from daemon: No command specified.
docker 虚悬镜像
仓库名和标签都是<none>
的镜像
镜像的分层概念
联合文件系统
联合文件系统是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。联合文件系统是 docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(类似Object),可以制作各种具体的应用镜像。
特性:一次用时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终文件系统会包含所有底层的文件和目录。
docker
镜像实际上就是一层一层的文件系统组成,例如拉取tomcat
镜像时可以看出它是有层次地下载。
镜像分层最大的一个好处就是共享资源,方便复制迁移,可以复用。
比如说多个镜像都从相同的base
镜像构建而来,那么Docker Host
只需在磁盘上保存一份base
镜像,同时内存中也只需要加载一份base
镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。
- Docker 镜像层都是只读的,容器层是可写的
当容器启动时,一个新的可写层被加载到镜像的顶部。这一层通常被称作“容器层”,“容器层”之下是镜像层“”
commit 镜像加强命令
普通的ubuntu
容器是没有vim
命令的,但可以通过提交容器副本使之成为一个新的镜像,在这个新的镜像中安装有vim
命令。
格式:docker commit -m="描述信息" -a="作者" ID 镜像名:TAG
步骤如下:
-
进入
ubuntu
容器 -
apt-get update
更新源 -
apt-get -y install vim
安装vim
-
退出容器,执行
docker commit -m="add vim cmd" -a="horizon" 83f6a3466748 myubuntu:1.0
至此镜像仓库就多了一个装有vim
的myubuntu
镜像,也是由原本镜像加了一层形成的。
本地镜像发布到阿里云
首先在阿里云的容器镜像服务中创建命名空间,然后在该命名空间下创建镜像仓库,代码源选择本地仓库,然后根据页面提供的命令操作即可。
容器数据卷
卷就是目录或文件,存在与一个或多个容器中,由docker
挂载到容器。将容器目录与主机目录做一个映射,完成数据持久化到本地机目录与备份。容器内文件的更改会立即映射到宿主机对应文件中,宿主机的更改也会同步到容器中。
docker run -it --privileged=true -v /宿主机绝对路径目录:/容器内目录 镜像名
注意:容器本身就类似于一个Linux,--privileged=true使容器拥有root权限,否则只有普通用户权限
实例
-
docker run -it --privileged=true -v /tmp/host_data:/tmp/docker_data --name=u1 ubuntu bash
创建容器 -
在容器内执行
cd /tmp/docker_data
,touch dockerin.txt
,此时在宿主机的/tmp/host_data
下就存在dockerin.txt
文件 -
在宿主机中
/tmp/host_data
下执行echo 'hello docker' > a.txt
,在容器映射目录下也存在a.txt
文件 -
通过
docker inspect ID
命令,在Mounts
中可以看到容器的目录挂载情况 -
在停止容器后,在宿主机的文件修改依旧可以同步到容器的对于挂载目录
限制容器挂载目录文件为只读
docker run ... /宿主机目录:/容器目录:ro ...
默认是rw
权限
容器卷的继承
-
docker run -it --privileged=true -v /tmp/host_data:/tmp/docker_data --name=u1 ubuntu bash
创建宿主机和容器1之间的映射 -
docker run -it --privileged=true --volumes-from u1 --name=u2 ubuntu bash
创建容器2,卷继承自容器1 -
即使容器1挂了,容器2和宿主机的映射关机依旧存在
tomcat 使用
docker pull tomcat
拉取镜像
docker run -d -p 8080:8080 tomcat
运行容器
此时访问localhost:8080
会出现404
,这可能是防火墙没设置,另外就是因为新版tomcat
容器内部的webapp
文件夹为空,需要删除这个空文件夹然后将webapp.dist
文件夹改名为webapp
,这时就能正常访问
mysql 使用
docker pull mysql:5.7
拉取镜像
docker run -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123 -d mysql:5.7
运行容器,然后进入容器内部mysql -u root -p 123
启动mysql
即可正常使用
数据卷备份
docker run -d -p 3306:3306 --privileged=true \
-v /mysql/log:/var/log/mysql \
-v /mysql/data:/var/lib/mysql \
-v /mysql/conf:/etc/mysql/conf \
-e MYSQL_ROOT_PASSWORD=123 \
--name=mysql mysql:5.7
在容器被删除后,由于宿主机保留有对应的数据文件,所以重新执行以上命令,新的容器内依旧存在原来的数据
中文乱码问题
show variables like 'character%';
可以看到编码是latin1
这时进入主机/mysql/conf
目录下新建配置文件my.cnf
,编辑如下:
[client]
default_character_set=utf8
[mysqld]
collation_server=utf8_general_ci
character_set_server=utf8
然后docker restart mysql
重启容器,进入查看发现编码为utf8
至此中文乱码解决
redis 使用
将正常的redis.conf
文件复制到宿主机/redis
下,将其中的daemonize yes
注释掉或者改成no
,否则会与docker run
中-d
冲突,会导致容器一直启动失败。注释掉bind 127.0.0.1
,运行redis
外地连接。
docker run -d -p 6379:6379 --privileged=true \
-v /usr/local/redis/etc/redis.conf:/etc/redis/redis.conf \
-v /usr/local/redis/data:/data \
redis:6.0.8 redis-server /etc/redis/redis.conf \
--requirepass "123"
使用指定的配置文件启动redis
。注意使用配置文件启动要将配置文件中的 daemonize
设为 no,否则无法启动。