一、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 创建自定义镜像
(待更)
还好有Docker控制面板简化了好多流程,完全手工的话太麻烦了啊
要不是前段时间学习飞牛 OS 中用了一下 docker,都快要忘得差不多了,这次又重温了一遍。docker控制面板我没有装,可能我用得比较少吧,也就一两个而已,我怕用了控制面板会深陷其中。
使用劳动工具是进步啊,现在AI出来后写代码都容易了;只要不穿越回几十年前,手工操作用的也就不多
有道理,只要能达到目的,越简单越方便才是越好的,哈哈。