Skip to content

1. 安装docker

1.1 在线安装

本示例来自docker官网centos的安装方式

1. 在线安装

bash
yum install -y yum-utils
yum-config-manager \
    --add-repo \
    https://download.docker.com/linux/centos/docker-ce.repo
    
yum install -y docker-ce docker-ce-cli containerd.io

2. 镜像加速(我使用aliyun)

创建/etc/docker/daemon.json文件并增加内容,重启docker服务

bash
vi /etc/docker/daemon.json

{
  "registry-mirrors": ["https://0oiclv7w.mirror.aliyuncs.com"]
}

systemctl daemon-reload
systemctl restart docker

{
  "registry-mirrors": ["https://docker.mirrors.ustc.edu.cn/"]
}

3. 启动docker

bash
systemctl start docker

4. 开机启动

bash
systemctl enable docker

5. 卸载docker

bash
yum remove docker \
           docker-client \
           docker-client-latest \
           docker-common \
           docker-latest \
           docker-latest-logrotate \
           docker-logrotate \
           docker-engine

2. 基础命令

2.1 docker服务命令

命令作用
systemctl start docker启动docker
systemctl stop docker停止docker
systemctl restart docker重启docker
systemctl status docker查看docker状态
systemctl enable docker开机启动
docker info查看docker概要信息
docker --help查看docker总体帮助文档
docker command --help查看docker命令帮助文档

2.2 docker镜像命令

2.2.1 docker images

列出镜像列表

bash
docker images 
REPOSITORY                         TAG           IMAGE ID       CREATED        SIZE
guacamole/guacd                    latest        ee0b218233ff   9 days ago     271MB
golang                             1.16-alpine   7e352955f83c   5 weeks ago    302MB
alpine                             latest        c059bfaa849c   7 weeks ago    5.59MB

列出的镜像列说明:

  • **REPOSITORY:**表示镜像的仓库源
  • **TAG:**镜像的标签,同一仓库源可以有多个 TAG,代表这个仓库源的不同个版本
  • **IMAGE ID:**镜像ID
  • **CREATED:**镜像创建时间,不是我们pull的时间
  • **SIZE:**镜像大小

搜索需要的镜像:docker search 镜像名字

--limit : 只列出N个镜像,默认25个 docker search --limit 5 redis

2.2.3 docker pull

拉取指定镜像:docker pull 镜像名字[:TAG] 没有TAG就是最新版,docker pull 镜像名字:latest

2.2.4 docker rmi

删除镜像:

  • 单个:docker rmi -f 镜像ID
  • 多个:docker rmi -f 镜像名1:TAG 镜像名2:TAG
  • 全部:docker rmi -f $(docker images -qa)

删除所有未打 dangling 标签的镜像:docker rmi $(docker images -q -f dangling=true)

2.2.5 docker system df

查看镜像/容器/数据卷所占的空间

bash
docker system df
TYPE            TOTAL     ACTIVE    SIZE      RECLAIMABLE
Images          7         4         3.915GB   374.5MB (9%)
Containers      4         4         2.392MB   0B (0%)
Local Volumes   2         1         0B        0B
Build Cache     0         0         0B        0B

有的时间我们会看见有些镜像的名称是none,TAG也是none,这种情况我们一般称之为虚悬镜像,遇到虚悬镜像,一般处理方式是直接删除,一般是我们自己制作镜像的时候发生

2.3 docker容器命令

2.3.1 docker run

由于这个命令比较复杂,下面将以具体的步骤进行演示,首先我们要知道docker run运行的流程

用户执行docker run来启动容器的时候,docker服务端会先检查本地有没有run的镜像,如果有,那么docker直接使用这个镜像

格式:docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

OPTIONS说明(常用):单词用两个-- 简写用一个-

  • --name="容器新名字" 为容器指定一个名称;
  • -d: 后台运行容器并返回容器ID,也即启动守护式容器(后台运行);
  • -i:以交互模式运行容器,通常与 -t 同时使用;
  • -t:为容器重新分配一个伪输入终端,通常与 -i 同时使用;也即启动交互式容器(前台有伪终端,等待交互);
  • -P: 随机端口映射,大写P,一般不使用
  • -p: 指定端口映射,小写p ,常用
  • -v:挂载容器卷,做数据持久化,默认是读写权限rw,如果只读只需要在结尾加上 :ro即可

-v /宿主机绝对路径目录:/容器内目录 [:ro]

  • --volumes-from 父类:继承其他容器挂载容器卷,父容器即便被删除,子容器的挂载不会有变化

  • --privileged=true:如果是CentOS7安全模块会比之前系统版本加强,不安全的会先禁止,所以目录挂载的情况被默认为不安全的行为,在SELinux里面挂载目录被禁止掉了额,如果要开启,我们一般使用--privileged=true命令,扩大容器的权限解决挂载目录没有权限的问题,使用该参数,container内的root拥有真正的root权限,否则,container内的root只是外部的一个普通用户权限。

COMMAND:

/bin/bash:放在镜像名后的是命令,这里我们希望有个交互式 Shell,因此用的是 /bin/bash。 要退出终端,直接输入 exit,保留运行容器需要使用ctrl+p+q

2.3.2 docker inspect

docker inspect 容器ID 查看容器详细信息,查看容器内部细节

2.3.3 docker logs

查看容器日志:docker logs 容器ID

2.3.4 docker cp

容器与主机文件拷贝 :docker cp 容器ID:容器内路径 目的主机路径

注意有两种情况

  1. 主机上文件拷贝到容器:docker cp 主机文件路径 容器ID:容器内路径
  2. 容器内文件拷贝到主机:docker cp 容器ID:容器内路径 目的主机路径
bash
#将主机上bin文件拷贝到容器
ls
bin  pkg
docker cp /root/go/bin 918822e6486b:/tmp/test 

# 容器
ls
1.txt  bin

2.3.5 docker exec

进入容器命令终端 :docker exec -it 容器ID bashShell

bash
# docker exec -it 327dcdc96475 sh
/ # 
/ # cd /tmp/test/
/tmp/test # ls
1.txt  bin

2.3.6 docker attach

进入容器启动命令终端 :docker attach 容器ID

bash
docker attach 327              
cd /tmp/test/
ls
1.txt  bin

attach 直接进入容器启动命令的终端,不会启动新的进程,用exit退出,会导致容器的停止。

exec 是在容器中打开新的终端,并且启动新的进程,用exit退出,不会导致容器的停止。

两者使用快捷键:ctrl+p+q 退出都不会停止容器

2.3.7 docker top

查看容器内运行的进程 : docker top 容器ID

2.3.8 dockre rm

**语法:**docker rm [OPTIONS] CONTAINER [CONTAINER...]

OPTIONS说明:

  • **-f 😗*通过 SIGKILL 信号强制删除一个运行中的容器。
  • **-l 😗*移除容器间的网络连接,而非容器本身。
  • **-v 😗*删除与容器关联的卷

删除所有容器:docker rm -f $(docker ps -a -q)

删除所有未运行的容器: docker container prune / docker rm $(docker ps -a -q)

删除未启动成功:docker rm $(docker ps -qf status=created)

删除退出状态: docker rm $(docker ps -qf status=exited)

2.3.9 docker kill

停止所有运行的容器 : docker kill $(docker ps -a -q)

2.4 容器的导入导出

为什么需要导出?

在某些情况下,我们需要将自己更新的容器导出称为镜像使用,比如在Ubuntu容器安装Java运行环境,我们可以将此初始化好的环境导出称为镜像,以后使用此镜像来创建容器,就自带了java的运行环境,而不用每次创建容器都进行环境的安装,类似虚拟机的模板文件

为什么需要导入?

在一个开发型的公司里面,一般研发开发好程序员以后,通过Dockerfile编译称镜像文件,运维需要将镜像文件导入到docker环境中run起来

应用场景:

主要用来制作基础镜像,比如从一个ubuntu镜像启动一个容器,然后安装一些软件和进行一些设置后,使用docker export保存为一个基础镜像。然后,把这个镜像分发给其他人使用,比如作为基础的开发环境。

2.4.1 容器导出

docker export 容器ID > 文件名.tar

bash
root@kali:~# docker export 9188 > myAlpine.tar.gz
root@kali:~# ls
myAlpine.tar.gz  thinclient_drives

2.4.2 容器导入

cat 文件名.tar | docker import - 镜像用户/镜像名:镜像版本号

bash
root@kali:~# cat myAlpine.tar.gz|docker import - moujun/my-alpine:0.0.1
sha256:0a79a0402e43234468b0896277bf342c385f73134ac21ecde0e012c946fa0318
root@kali:~# docker images                       
REPOSITORY                         TAG           IMAGE ID       CREATED         SIZE
moujun/my-alpine                   0.0.1         0a79a0402e43   7 seconds ago   5.59MB
alpine                             latest        c059bfaa849c   7 weeks ago     5.59MB
ubuntu                             latest        ba6acccedd29   3 months ago    72.8MB

root@kali:~#

注意,镜像名称必须要小写,否则报错

2.5 镜像推送

2.5.1 登录 docker login

2.5.2 修改标签 docker tag

docker tag moujun:0.0.1 moujunmore/umi:0.0.1

moujun:0.0.1:为原镜像名称

moujunmore/umi:0.0.1:为符合docker hub推送要求的镜像名称

2.5.3 docker push

sh
[root@more tmp]# docker push moujunmore/umi:0.0.1
The push refers to repository [docker.io/moujunmore/umi]
c569ef711d3f: Pushed 
46da2b1c58ba: Pushed 
2503893bd420: Pushed 
1686740e8bf1: Pushed 
98b38fd98eb3: Pushed 
0cf3d17b4494: Pushed 
392246cbae6c: Pushed 
f6e6b207d1f6: Pushed 
1d59199e80ce: Pushed 
5b95e425ec84: Pushed 
8d3ac3489996: Layer already exists 
0.0.1: digest: sha256:af14bfe72476acf8f4504186d04a68682b41cf5fb1a095a7a5aa6ecbf9bd006b size: 2627
[root@more tmp]# history

3. 认识镜像

镜像:是一种轻量级、可执行的独立软件包,它包含运行某个软件所需的所有内容,我们把应用程序和配置依赖打包好形成一个可交付的运行环境(包括代码、运行时需要的库、环境变量和配置文件等),这个打包好的运行环境就是image镜像文件。其实作用跟VM里面的ISO文件类似

3.1 UnionFS(联合文件系统)

UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。

特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录

3.2 镜像加载过程

通过观察pull,我们发现在下载docker的镜像过程中,镜像好像是在一层一层的在下载,这是为什么呢?

镜像分层最大的一个好处就是共享资源,方便复制迁移,就是为了复用。

比如说有多个镜像都从相同的 base 镜像构建而来,那么 Docker Host 只需在磁盘上保存一份 base 镜像; 同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。

3.3 Docker镜像加载原理:

docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。 bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是引导文件系统bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。

rootfs (root file system) ,在bootfs之上。包含的就是典型 Linux 系统中的 /dev, /proc, /bin, /etc 等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。

镜像分层

3.4 Docker仅容器层可写

所有启动的容器,都是再原来的镜像顶部加载一层,这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。并且任何写操作都不会影响到镜像层,镜像层不可用写入

3.5 docker commit

docker commit提交容器副本使之成为一个新的镜像,格式:

docker commit -m="提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:[标签名]

实验步骤:

  1. 创建一个容器:docker run -it alpine sh

  2. 修改容器:

    sh
    /home # ls
    /home # touch 1.txt
    /home # ls
    1.txt
    /home #
  3. 提交容器:docker commit -m="提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:[标签名]

    bash
    [root@VM-0-10-centos ~]# docker ps
    CONTAINER ID   IMAGE     COMMAND   CREATED         STATUS         PORTS     NAMES
    1894e6a5aaff   alpine    "sh"      5 minutes ago   Up 5 minutes             musing_dirac
    [root@VM-0-10-centos ~]# docker commit -m="提交测试" -a="moujun" 1894e6a5aaff moujun/alpine:1.0.0
    sha256:dc645a41ed81afc56d484f6d7d9a406192ff3176a3bc8e398bb7e4d489084828
    [root@VM-0-10-centos ~]# docker images
    REPOSITORY      TAG       IMAGE ID       CREATED         SIZE
    moujun/alpine   1.0.0     dc645a41ed81   4 seconds ago   5.59MB
    alpine          latest    c059bfaa849c   7 weeks ago     5.59MB
    [root@VM-0-10-centos ~]#
  4. 使用创建的镜像生产容器查看修改内容

    bash
    [root@VM-0-10-centos ~]# docker run -it moujun/alpine:1.0.0 sh
    / # cd /home/
    /home # ls
    1.txt
    /home #

4. Dockerfile

Dockerfile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需的指令和参数构成的脚本。

构建命令:docker build .

要在构建上下文中使用文件,Dockerfile指的是在指令中指定的文件,例如COPY指令。要提高构建的性能,请通过将.dockerignore文件添加到上下文目录来排除文件和目录。

4.1 Dockerfile指令

我们编写Dockerfile时,最重要的是理解其中的指令含义,由于常用指令不多,我们可以分别做说明

指令不区分大小写。但是,约定是大写的,以便更容易地将它们与参数区分开来。

4.1.1 FROM

FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]

FROM指令初始化一个新的构建阶段并为后续指令设置 基本映像。因此,有效Dockerfile必须以FROM指令开始。

4.1.2 RUN

RUN 有两种形式:

  • RUN <command>shell形式,命令在 shell 中运行
  • RUN ["executable", "param1", "param2"]执行形式)

RUN指令将在当前镜像之上的新层中执行任意命令并提交结果。生成的提交镜像将用于Dockerfile的下一步操作.

上次更新: