一、docker 介绍

Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。

三大核心:

Docker 技术的三大核心概念,分别是:镜像 Image、容器 Container、仓库 Repository。

  • Docker仓库(Registry): 保存镜像的仓库, 官方仓库 hub.docker.com 在国内已不能访问, 所幸国内的镜像仓库正在逐渐完善
  • Docker镜像(Images): 镜像是一个可执行包,也是一个静态的隔离的文件系统,其包含运行应用程序所需的代码、运行时、库、环境变量和配置文件;镜像可以用来创建、传输、拷贝等;镜像本身是静态的,不包含任何动态数据,其内容在构建之后也不会被改变;镜像必须通过实例化来创建和运行容器
  • Docker容器(Container): 容器是镜像运行后的一个环境,是一个进程,同一个镜像可以实例化并运行多个容器。

其他术语:

Docker主机(Host): 物理机或虚拟机, 用于运行 Docker 服务进程和容器, 也称之为宿主机, node 节点
Docker服务器端(Server): Docker 守护进程, 运行 Docker 容器
Docker客户端(Client): 客户端使用 docker 命令或其他工具调用 docker API

当我们请求 Docker 运行容器时,Docker 会在计算机上设置一个资源隔离的环境。然后将打包的应用程序和关联的文件复制到 Namespace 内的文件系统中,此时环境的配置就完成了。之后 Docker 会执行我们预先指定的命令,运行应用程序。

既然访问国外 docker 资源比较困难,下面的操作就重点以国内 docker 资源为例来进行学习了。

二、docker 管理

docker 安装包有两个命名形式, docker.io 和 docker-ce ,但他们的维护者、依赖管理和安装方式是不相同的,我们只能选择其中一个安装。‌

  • ‌维护者‌:docker-ce ‌是由 Docker 官方维护的;docker.io ‌则是由 Debian 团队维护的‌。
  • ‌依赖管理‌:‌docker-ce‌ 使用自己的方式管理依赖,能够自行管理所有依赖‌;‌docker.io‌ 则采用 apt 的方式管理依赖。
  • ‌安装方式‌:‌docker-ce‌ 需要通过特定的命令和仓库进行安装,例如使用 curl 命令添加 Docker 的官方 GPG 密钥和仓库地址,然后再进行安装;docker.io ‌可以通过 apt 命令直接安装

Debian 团队维护的 docker 版本一般会落后 docker-ce 版本很多,况且,得益于国内丰富的 docker-ce 镜像,我们就安装 docker-ce 吧。

1.安装 docker 引擎

国内很多大学的镜像源都有 docker 镜像,下面以[中科大docker-ce]](https://mirrors.ustc.edu.cn/help/docker-ce.html)为例来安装。

如果你过去安装过 docker,先删掉:

$ for pkg in docker.io docker-doc docker-compose podman-docker containerd runc; do apt-get remove $pkg; done

安装依赖(如果没有的话):

$ apt-get install ca-certificates curl gnupg

信任 Docker 的 GPG 公钥:

$ sudo install -m 0755 -d /etc/apt/keyrings
$ sudo curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/debian/gpg -o /etc/apt/keyrings/docker.asc  #或 wget -qO- https://mirrors.ustc.edu.cn/docker-ce/linux/debian/gpg | sudo tee /etc/apt/keyrings/docker.asc
$ sudo chmod a+r /etc/apt/keyrings/docker.asc   # 确保可读,其实默认应该可读

添加 docker 仓库:

$ echo  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://mirrors.ustc.edu.cn/docker-ce/linux/debian $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

安装 docker:

$ sudo apt update
$ sudo apt install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

2. docker 服务管理

$ systemctl < status | enable | start | stop | ... > docker

3. 查看 docker 版本信息

详细查看:

$ docker version
Client: Docker Engine - Community
 Version:           27.4.1
 API version:       1.47
 Go version:        go1.22.10
 Git commit:        b9d17ea
 Built:             Tue Dec 17 15:45:56 2024
 OS/Arch:           linux/amd64
 Context:           default
permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get "http://%2Fvar%2Frun%2Fdocker.sock/v1.47/version": dial unix /var/run/docker.sock: connect: permission denied

简单查看:

$ docker -v
Docker version 27.4.1, build b9d17ea

4. 查看 docker 状态

$ $ sudo docker info
Client: Docker Engine - Community
 Version:    27.4.1
 Context:    default
 Debug Mode: false
 Plugins:
  buildx: Docker Buildx (Docker Inc.)
    Version:  v0.19.3
    Path:     /usr/libexec/docker/cli-plugins/docker-buildx
  compose: Docker Compose (Docker Inc.)
    Version:  v2.32.1
    Path:     /usr/libexec/docker/cli-plugins/docker-compose

Server:
 Containers: 2
  Running: 0
  Paused: 0
  Stopped: 2
 Images: 0
 Server Version: 27.4.1
 ...省略输出...
 Insecure Registries:
  127.0.0.0/8
 Registry Mirrors:
  https://docker.1ms.run/
 Live Restore Enabled: false

二、docker 镜像

1. 修改 Docker 远程仓库镜像站

镜像需要下载/拉取到本地才能使用,而默认的官方镜像仓库目前又无法访问,只能找国内镜像仓库替代,可以通过修改(没有则新增) daemon 配置文件/etc/docker/daemon.json 来使用加速器:

$ sudo vim /etc/docker/daemon.json
{
    "registry-mirrors":["https://国内 docker 镜像仓库"]
}

修改完之后,重新加载 docker 服务:

$ sudo systemctl daemon-reload && sudo systemctl restart docker

常见的国内镜像仓库,常有关闭情况或者有访问限制,最近发现一个镜像较全且比较稳定的仓库是:https://docker.1ms.run

2. 查看本地 docker 镜像列表

执行: $ sudo docker images docker image ls

演示:

$ sudo docker images
REPOSITORY   TAG              IMAGE ID       CREATED        SIZE

如果没有拉取过镜像,这里将看不到镜像内容

3. 搜索 docker 远程仓库上的镜像列表

执行: $ sudo docker search 镜像名

docker search 默认是从 docker 官方镜像索引进行查找,即使我们设置了国内镜像仓库。解决搜索不到镜像的方法是在镜像前指定镜像仓库。

演示:

$ sudo docker search docker.1ms.run/httpd
NAME                     DESCRIPTION                                      STARS     OFFICIAL
httpd                    The Apache HTTP Server Project                   4820      [OK]
manageiq/httpd           Container with httpd, built on CentOS for Ma…   1         
paketobuildpacks/httpd                                                    0         
vulhub/httpd                                                              0         
jitesoft/httpd           Apache httpd on Alpine linux.                    0         
openquantumsafe/httpd    Demo of post-quantum cryptography in Apache …   15        
openeuler/httpd                                                           0         
...省略输出...     

常用选项

选项描述
--filter,-f条件过滤
-f STARS=3 表示查找 STARS 大于等于 3 的镜像,
is-official=ture 表示只查找官方镜像
--limit显示数量,--limit 5 只显示查找的前5个镜像
–no-trunc显示完整的描述信息(不截断成...)
–-format自定义打印格式
--format "{{.Name}}: {{.StarCount}}" 表示只显示镜像名和点赞数,中间用冒号隔开

也可以直接在浏览器中打开镜像仓库web站点,查询镜像,比如:https://1ms.run/ 可查询 docker.1ms.run 镜像仓库中的镜像

4.获取/下载docker远程仓库上的镜像

执行: sudo docker pull < 镜像名 | 镜像名:tag >

因为我们设置了国内镜像源,默认将首先从我们设置的镜像源拉取镜像,也可以直接指定镜像源

演示:

$ sudo docker pull httpd
Using default tag: latest
latest: Pulling from library/httpd
fd674058ff8f: Pull complete 
8c3081b233c7: Pull complete 
4f4fb700ef54: Pull complete 
172b239db5c2: Pull complete 
bbff13f6be42: Pull complete 
d7382fd3e491: Pull complete 
Digest: sha256:72f6e24600718dddef131de7cb5b31496b05c5af41e9db8707df371859a350bb
Status: Downloaded newer image for httpd:latest
docker.io/library/httpd:latest

注意:一个镜像名往往对应多个 tag(标签),而默认拉取的镜像 tag 通常是最近的一个也就是 latest,我们从上面语句的执行提示不难发现下载的就是 latest。如想要拉取指定的 tag,可以在浏览器中打开镜像对应的网站(如果有的话), 如:https://1ms.run/,可以搜索镜像名称: httpd,选择 httpd 镜像后,点击标签列表,就会发现有很多不同的 tag 了,然后执行 sudo docker pull 镜像名:tag名。要说明的是,不同的镜像网站,查询的方式可能有所不同。

可以执行 sudo docker images 看看是否存在刚刚下载的 httpd 镜像

$ sudo docker images
REPOSITORY   TAG       IMAGE ID       CREATED        SIZE
httpd        latest    4ce47c750a58   5 months ago   147MB

5. 查看镜像的详细信息

执行: sudo docker image inspect <镜像名 | 镜像名:tag | 镜像ID>

演示:

$ sudo docker image inspect httpd  
httpd 可以替换成 httpd:latest 或者 b260
因为本地只有一个tag 也就是 latest,所以可以省略
因为不同的镜像ID前四位很难相同,因此镜像ID一般可以只要输入前面4个字符即可。

6. 导出镜像

执行:sudo docker save 镜像名 > 需要导出的镜像包名

$ sudo docker save httpd >  httpd_latest.tar.gz

7. 删除镜像

执行: sudo docker rmi 镜像名

演示:

$ sudo docker rmi httpd
Untagged: httpd:latest
Untagged: httpd@sha256:f899e432292e4ee92772d35e43b2e3dcf30042b1c6385d33f00a9300c69ee729
Deleted: sha256:b260a49eebf92310bc8a6024591cb5c7846ca47ca30106a43d015c381bf87633
Deleted: sha256:9b953393e0c519b76cd335cc3268fc4822316b935c7dec1dbb89fd1228ec535a
Deleted: sha256:3b20e2e40731b3826de2ede5fa1ea9c6c028a94e469ade1ad78e552480df056a
Deleted: sha256:c53942b80e78b86a57720c746d131a7110449b850dec9135a4296acd10f240db
Deleted: sha256:3439b4fb9b4289be9427c14f2840d97e3573dc8d609584d9ceb2ad8bbd3ae9dc
Deleted: sha256:ad6562704f3759fb50f0d3de5f80a38f65a85e709b77fd24491253990f30b6be

$ sudo docker images     #查看镜像,没有找到httpd的镜像。
REPOSITORY   TAG              IMAGE ID       CREATED        SIZE
kmre2        v2.0-220415.10   3b9cc4a571e7   2 months ago   1.5GB

删除镜像前,必须先删除其所启动的所有容器,否则将会删除不成功。

8. 导入本地镜像

执行:sudo docker image load 需要导入的本地镜像包

演示:

$ sudo docker image load -i httpd_latest.tar.gz 
ad6562704f37: Loading layer [==================================================>]   83.9MB/83.9MB
4e2b986e3da3: Loading layer [==================================================>]  3.072kB/3.072kB
4a8d484c2011: Loading layer [==================================================>]  5.104MB/5.104MB
024f6c09059b: Loading layer [==================================================>]  60.44MB/60.44MB
d72eba6c41e7: Loading layer [==================================================>]  3.584kB/3.584kB
Loaded image: httpd:latest

$ sudo docker images
REPOSITORY   TAG              IMAGE ID       CREATED        SIZE
httpd        latest           b260a49eebf9   9 days ago     145MB
kmre2        v2.0-220415.10   3b9cc4a571e7   2 months ago   1.5GB

三、docker 容器

1.创建并启动(运行)容器

执行: sudo docker run [选项] 镜像名

常用选项描述
-i以交互模式运行容器,通常与 -t 同时使用;
-t分配一个伪输入终端,通常与 -i 同时使用;
-d后台运行容器,并返回容器ID;
-p指定端口映射,-p 宿主机端口:容器端口
-P随机端口映射,容器内部端口随机映射到主机的端口;
--name为容器指定一个容器名称,--name="容器名"
--network连接到一个网络,--network=my-network
--restart设置容器重启策略,--restart=always
-v挂载宿主机的目录或文件到容器中,-v path/on/host:path/on/container
-e设置环境变量,-e "ENV_VAR_NAME=value"
--rm退出容器时,自动删除该容器

演示: 以交互模式实例化 httpd 镜像并运行容器(指定容器名为 httpd),同时分配一个为输入终端 bash

$ $ sudo docker run -d --name "httpd" httpd
11d807cd2a78adfbdaa8f2ac640b47e100fa646e0167a62756a7dd24ddb42a3a
  • 每执行一次 docker run 命令都将创建和启动(运行)一个新的容器,并具有不同的容器ID和容器名。
  • 容器内至少需要有一个进程在该容器的前台运行(容器内必须有一个进程运行;该进程必须在前台运行),否则容器就会直接关闭。
  • 当执行 docker run 命令后容器无法正常运行时,一般是因为该容器没有开启进程。

2.查看系统中的容器列表

执行: sudo docker ps [选项]

选项:

-a    列出所有容器  
-l    列出最后一次运行的容器
-q    仅列出容器 ID

演示: 列出所有容器(包含未运行的容器)

$ sudo docker ps
CONTAINER ID   IMAGE     COMMAND              CREATED         STATUS         PORTS     NAMES
11d807cd2a78   httpd     "httpd-foreground"   6 seconds ago   Up 5 seconds   80/tcp    httpd

可以看出,刚才创建的 httpd 镜像并已经实例化为容器并在后台运行

3.查看容器信息

上面的实例,镜像经实例化并启动为 httpd 容器时,会分配好 ip 地址,我们只要在浏览器中输入容器的ip地址即可访问,可以通过查看容器信息来找到这个ip地址。

执行: sudo docker inspect <容器名 | 容器ID>

演示:

$ sudo docker inspect httpd

可以发现,容器的ip地址是172.17.0.2,我们在主机浏览器中输入这个 ip 地址就可以直接访问容器提供的 web 服务了。

4.关闭(停止运行)容器

执行: sudo docker stop <容器名 | 容器ID>

演示:

$ sudo docker stop httpd   # 关闭容器 httpd
httpd
$ sudo docker ps -a        # 查看容器,发现 httpd 于 3 秒前关闭
CONTAINER ID   IMAGE     COMMAND              CREATED          STATUS                     PORTS     NAMES
11d807cd2a78   httpd     "httpd-foreground"   18 minutes ago   Exited (0) 3 seconds ago             httpd

5.开启(运行)一个关闭(停止运行)的容器

执行: sudo docker start <容器名 | 容器ID>

演示:

$  sudo docker start httpd    # 开启容器 httpd
httpd
$ sudo docker ps -a           # 查看容器,发现 httpd 于 4 秒前开启
CONTAINER ID   IMAGE     COMMAND              CREATED          STATUS         PORTS     NAMES
11d807cd2a78   httpd     "httpd-foreground"   20 minutes ago   Up 4 seconds   80/tcp    httpd

6.登陆(进入)一个已经运行的容器

登陆(进入)一个已经运行的容器语法与创建运行容器的语法类似。不同的是,docker exec 的对象是容器,而 docker run 的对象是镜像。

执行: sudo docker exec [选项] < 容器名 | 容器ID >

演示:

$ sudo docker exec -it 11d807cd2a78 bash       #  登陆容器,-it 表示交互模式
root@11d807cd2a78:/usr/local/apache2# ls -al   #  查看容器内的文件 
total 56
drwxr-xr-x 1 www-data www-data 4096 Dec 24 22:18 .
drwxr-xr-x 1 root     root     4096 Dec 24 22:16 ..
drwxr-xr-x 2 root     root     4096 Dec 24 22:18 bin
drwxr-xr-x 2 root     root     4096 Dec 24 22:18 build
drwxr-xr-x 2 root     root     4096 Dec 24 22:18 cgi-bin
drwxr-xr-x 4 root     root     4096 Dec 24 22:18 conf
drwxr-xr-x 3 root     root     4096 Dec 24 22:18 error
drwxr-xr-x 2 root     root     4096 Dec 24 22:18 htdocs
drwxr-xr-x 3 root     root     4096 Dec 24 22:18 icons
drwxr-xr-x 2 root     root     4096 Dec 24 22:18 include
drwxr-xr-x 1 root     root     4096 Jan 17 01:37 logs
drwxr-xr-x 2 root     root     4096 Dec 24 22:18 modules

7.查看容器日志

执行: sudo docker logs [选项] < 容器名 | 容器ID >

演示:

$ sudo docker logs -f httpd    # -f 选项表示动态查看 httpd 容器的日志,需按 ctrl+c 退出查看

8.删除容器

$ sudo docker rm 容器ID
默认只能删除关闭(停止运行)的容器,如要强制删除需用 -f 选项

9.提交容器为镜像

执行:sudo docker commit <容器名 | 容器ID> 镜像名

自定义镜像名的常用命名规则:"用户账号/镜像名",如 "ymz316/httpd"

四、dockerfile 创建自定义镜像

(待更)