以一个典型示例来说明docker的工作原理,然后详细介绍docker镜像管理的基础语法(增删改查)。
示例:使用docker切换操作系统
一个Linux操作系统一般由两部分组成
Linux内核,负责和机器硬件交互
centos7、ubuntu等发行版,提供软件功能
#查看发行版信息
[root@centos ~]$ cat /etc/redhat-release
CentOS Linux release 7.9.2009 (Core)
#查看Linux内核信息
[root@centos ~]$ uname -r
3.10.0-1160.71.1.el7.x86_64
- 利用docker获取不同的发行版镜像,例如 centos7.8.2003
#通过docker pull 镜像名:版本号 获取特定版本的镜像
#默认的版本号标签为 latest
[root@centos ~]$ docker pull centos:7.8.2003
[root@centos ~]$ docker pull ubuntu
- 运行 centos7.8.2003 发行版
#查看docker镜像的id
[root@centos ~]$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
redis latest ec466c2297ad 3 days ago 117MB
nginx latest 9eee96112def 3 days ago 142MB
ubuntu latest 58db3edaf2be 12 days ago 77.8MB
centos 7.8.2003 afb6fca791e0 2 years ago 203MB
#运行centos7.8.2003,并进入到容器内
# -i 交互式命令操作,-t 开启一个终端,bash进入容器后执行的命令
[root@centos ~]$ docker run -it afb6fca791e0 bash
#查看容器内的发行版
[root@ae5faf534a85 /]$ cat /etc/redhat-release
CentOS Linux release 7.8.2003 (Core)
#查看Linux内核,可以发现和宿主机的Linux内核信息是一致的
[root@ae5faf534a85 /]$ uname -r
3.10.0-1160.71.1.el7.x86_64
- 运行ubuntu发行版
[root@centos ~]$ docker run -it 58db3edaf2be bash
#查看容器内的发行版
root@e8061ad60163:/# cat /etc/os-release
PRETTY_NAME="Ubuntu 22.04.1 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.1 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy
#查看Linux内核,依旧是一样的
root@e8061ad60163:/# uname -r
3.10.0-1160.71.1.el7.x86_64
Tips:docker采用的是基于 Union FS 的分层存储架构,因此宿主机的centos7.9.2009、docker1的centos7.8.2003和docker2的ubuntu系统共用了底层的Linux 3.10.0的内核。能够最大限度地节省空间。
docker容器的优点
docker镜像可以自由地选择发行版,解决了软件安装过程中的兼容性问题;
安装环境干净,所有内容均保存在容器内部,不影响宿主机
docker镜像管理
下载docker镜像
#从docker镜像托管仓库(https://hub.docker.com/)查看并下载相关镜像
docker search 镜像名:tag
docker pull 镜像名:tag
#查看本地的镜像列表
docker images
或者 docker image ls
#查看镜像的存储路径
[root@centos ~]$ docker info|grep Root
Docker Root Dir: /var/lib/docker
[root@centos ~]$ ls /var/lib/docker/image/overlay2/imagedb/content/sha256/ -l
总用量 24
-rw------- 1 root root 2299 2月 8 09:58 58db3edaf2be6e80f628796355b1bdeaf8bea1692b402f48b7e7b8d1ff100b02
-rw------- 1 root root 7658 2月 7 22:12 9eee96112defa9d7b1880f18e76e174537491bcec6e31ad9a474cdea40f5abab
-rw------- 1 root root 2794 2月 8 09:52 afb6fca791e071c66276202f8efca5ce3d3dc4fb218bcddff1bc565d981ddd1e
-rw------- 1 root root 7700 2月 8 09:33 ec466c2297ad10fa11bd9cdee28465ba096f416a2d528c0feb9b1a75918fae41
#查看上述配置文件,描述了镜像和容器之间的配置关系
[root@centos ~]# cat /var/lib/docker/image/overlay2/imagedb/content/sha256/58db3edaf2be6e80f628796355b1bdeaf8bea1692b402f48b7e7b8d1ff100b02
{
"architecture": "amd64",
"config":
{
"Hostname": "",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],
"Cmd": ["/bin/bash"],
"Image": "sha256:269190441c1f8398e85a287ba6ac5568574f55bfcae7fb99bd253afad8cd8e69",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels":
{
"org.opencontainers.image.ref.name": "ubuntu",
"org.opencontainers.image.version": "22.04"
}
},
"container": "6be7983e643200aa82c27e883bf03ae871243571f93a39f39d11dd3c79c96611",
"container_config":
{
"Hostname": "6be7983e6432",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": ["PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"],
"Cmd": ["/bin/sh", "-c", "#(nop) ",
"CMD [\"/bin/bash\"]"],
"Image": "sha256:269190441c1f8398e85a287ba6ac5568574f55bfcae7fb99bd253afad8cd8e69",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels":
{
"org.opencontainers.image.ref.name": "ubuntu",
"org.opencontainers.image.version": "22.04"
}
},
"created": "2023-01-26T04:58:02.385638665Z",
"docker_version": "20.10.12",
"history": [
{
"created": "2023-01-26T04:57:59.893830181Z",
"created_by": "/bin/sh -c #(nop) ARG RELEASE",
"empty_layer": true
},
{
"created": "2023-01-26T04:57:59.959936538Z",
"created_by": "/bin/sh -c #(nop) ARG LAUNCHPAD_BUILD_ARCH",
"empty_layer": true
}],
"os": "linux",
"rootfs": {"type": "layers", "diff_ids": ["sha256:c5ff2d88f67954bdcf1cfdd46fe3d683858d69c2cadd6660812edfc83726c654"]}}
使用docker镜像创建容器
#--rm 表示容器退出时删除删除该容器
docker run [参数列表] 镜像名:版本号(或者镜像id) 运行命令
例如 docker run -it --rm centos bash
查看镜像
#查看本地镜像信息
docker images 或者 docker image ls
#查看具体的镜像
docker images 镜像名
#可以制定具体tag
docker images 镜像名:tag
#只列出镜像的id -q 或者 --quiet参数
docker images -q
#格式化显示镜像
docker images --format "{{.ID}}--{{.Repository}}"
ec466c2297ad--redis
9eee96112def--nginx
58db3edaf2be--ubuntu
afb6fca791e0--centos
#以表格形式展示
docker images --format "table {{.ID}}\t{{.Repository}}\t{{.Tag}}"
IMAGE ID REPOSITORY TAG
ec466c2297ad redis latest
9eee96112def nginx latest
58db3edaf2be ubuntu latest
afb6fca791e0 centos 7.8.2003
#搜索镜像
docker search 镜像名
#查看镜像的详细信息
docker image inspect 镜像id
删除镜像
#为了演示方便,下载一个小体积的docker镜像 hello-world
docker pull hello-world
#运行hello-world
[root@centos ~]$ docker run hello-world
Hello from Docker!
This message shows that your installation appears to be working correctly.
To generate this message, Docker took the following steps:
1. The Docker client contacted the Docker daemon.
2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
(amd64)
3. The Docker daemon created a new container from that image which runs the
executable that produces the output you are currently reading.
4. The Docker daemon streamed that output to the Docker client, which sent it
to your terminal.
To try something more ambitious, you can run an Ubuntu container with:
$ docker run -it ubuntu bash
Share images, automate workflows, and more with a free Docker ID:
https://hub.docker.com/
For more examples and ideas, visit:
https://docs.docker.com/get-started/
#删除hello-world镜像,发现hello-world镜像被容器占用
[root@centos ~]$ docker rmi hello-world:latest
Error response from daemon: conflict: unable to remove repository reference "hello-world:latest" (must force) - container 4db9380857b3 is using its referenced image feb5d9fea6a5
#查看容器运行信息
[root@centos ~]$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4db9380857b3 hello-world "/hello" About a minute ago Exited (0) About a minute ago frosty_merkle
e8061ad60163 ubuntu "bash" 9 hours ago Exited (0) 9 hours ago naughty_shamir
ae5faf534a85 afb6fca791e0 "bash" 9 hours ago Exited (0) 9 hours ago friendly_stonebraker
#删除容器记录
[root@centos ~]$ docker rm 4db9380857b3
#删除hello-world镜像
docker rmi 镜像名(或者镜像id)
[root@centos ~]$ docker rmi hello-world:latest
Untagged: hello-world:latest
Untagged: hello-world@sha256:aa0cc8055b82dc2509bed2e19b275c8f463506616377219d9642221ab53cf9fe
Deleted: sha256:feb5d9fea6a5e9606aa995e879d862b825965ba48de054caab5ef356dc6b3412
Deleted: sha256:e07ee1baac5fae6a26f30cabfe54a36d3402f96afda318fe0a96cec4ca393359
批量删除镜像
#运用命令行下的反引号
[root@centos ~]$ echo `docker images -aq`
ec466c2297ad 9eee96112def 58db3edaf2be afb6fca791e0
#批量删除镜像
docker rmi `docker images -aq`
#批量删除容器
docker rm `docker ps -aq`
修改镜像
#为centos:7.8.2003发行版安装vim
[root@centos ~]$ docker run -it centos:7.8.2003 bash
[root@f514378374a1 /]$ vim
bash: vim: command not found
[root@f514378374a1 /]$ yum install vim -y
#提交vim下载的docker记录
docker commit --author "EishinNi" --message "Add vim" f514378374a1 centos_vim:latest
#导出新的centos:7.8.2003镜像,则新镜像包含vim软件
docker image save centos_vim > /opt/centos_vim.tgz
#删除原有的centos:7.8.2003镜像
docker rmi centos_vim
#导入镜像
docker image load -i /opt/centos_vim.tgz
Tips: docker commit + docker save可以能够保存镜像所有的元数据,可以快速回滚到之前的版本。但是这类操作会修改大量的额外文件,导致最终的镜像体积臃肿。还是推荐使用dockerfile进行镜像的构建
[root@centos ~]$ docker images|grep centos REPOSITORY TAG IMAGE ID CREATED SIZE centos_vim latest 66a5241671c2 13 minutes ago 457MB centos 7.8.2003 afb6fca791e0 2 years ago 203MB