docker基础入门
Docker简介
什么是虚拟机?
通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的完整计算机系统。在计算机中创建虚拟机时,需要将实体机的部分硬盘和内存容量作为虚拟机的硬盘和内存容量。
什么是容器?
容器技术是和我们的宿主机共享硬件资源及操作系统,可以实现资源的动态分配。容器包含应用和其所有的依赖包,但是与其他容器共享内核。容器在宿主机操作系统中,在用户空间以分离的进程运行。
二者对比
Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口。它是目前最流行的 Linux
容器解决方案。
Docker架构
Docker有三个组件和三个基本元素。三个组件:
Docker Client
是用户界面,它支持用户与Docker Daemon
之间通信。Docker Daemon
运行于主机上,处理服务请求。Docker Index
是中央registry,支持拥有公有与私有访问权限的Docker容器镜像的备份。
三个基本要素分别是:
Docker Containers
负责应用程序的运行,包括操作系统、用户添加的文件以及元数据。Docker Images
是一个只读模板,用来运行Docker容器。DockerFile
是文件指令集,用来说明如何自动创建Docker镜像
我们常常与之打交道的是:镜像(Image)、容器(Container)和仓库(Repository)
安装docker
- 卸载本机自带docker
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine
- 安装依赖
yum install -y yum-utils
- 设置docker镜像仓库 (这里用的是阿里的,也可以用官方的
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
)
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
设置后需要更新下yum索引
yum makecache fast
- 安装docker
yum install docker-ce docker-ce-cli containerd.io
- 配置docker镜像加速
- 访问阿里云 https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors 镜像工具-镜像加速器
- 根据操作文档配置即可,以centos为例:
sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://vxxxxxaa.mirror.aliyuncs.com"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
当yum配置的是官当的地址时,安装出现报错,参考https://stackoverflow.com/questions/65878769/cannot-install-docker-in-a-rhel-server处理
-
查看docker版本
[root@localhost ~]# docker version Client: Docker Engine - Community Version: 20.10.5 API version: 1.41 Go version: go1.13.15 Git commit: 55c4c88 Built: Tue Mar 2 20:33:55 2021 OS/Arch: linux/amd64 Context: default Experimental: true Server: Docker Engine - Community Engine: Version: 20.10.5 API version: 1.41 (minimum version 1.12) Go version: go1.13.15 Git commit: 363e9a8 Built: Tue Mar 2 20:32:17 2021 OS/Arch: linux/amd64 Experimental: false containerd: Version: 1.4.4 GitCommit: 05f951a3781f4f2c1911b05e61c160e9c30eaa8e runc: Version: 1.0.0-rc93 GitCommit: 12644e614e25b05da6fd08a38ffa0cfe1903fdec docker-init: Version: 0.19.0 GitCommit: de40ad0 [root@localhost ~]#
-
Docker卸载
sudo yum remove docker-ce docker-ce-cli containerd.io
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd
Docker常用命令
先看几张网络流传的对于docker命令的介绍图解。
可以看到常用命令主要围绕着镜像、容器、仓库和Dockerfile这四个对象,下面我们逐一看一下相关的命令。
帮助命令
docker version # 查看docker版本
docker info # 显示docker系统信息,包括镜像和容器的数量
docker 命令 --help # 命令的帮助文档
镜像命令
docker images
[root@localhost ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
# 名词解释
REPOSITORY # 镜像仓库源
TAG # 镜像标签
IMAGE ID # 镜像id
CREATED # 镜像创建时间
SIZE # 镜像大小
Options:
-a, --all # 显示所有镜像
-q, --quiet # 只显示镜像的ID
-f, --filter # 显示符合过滤条件的镜像,例如 --filter=STARS=5000 显示STARTS数量大于5000的镜像
docker search image 镜像搜索
[root@localhost ~]# docker search nginx --filter=STARS=1000
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
nginx Official build of Nginx. 14692 [OK]
jwilder/nginx-proxy Automated Nginx reverse proxy for docker con… 2006 [OK]
[root@localhost ~]#
docker pull image 镜像下载
# docker pull 镜像[:tag] 不跟tag默认下载最新镜像latest
[root@localhost ~]#
[root@localhost ~]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
75646c2fb410: Pull complete
6128033c842f: Pull complete
71a81b5270eb: Pull complete
b5fc821c48a1: Pull complete
da3f514a6428: Pull complete
3be359fed358: Pull complete
Digest: sha256:1fefbe787475516735b828516f593412addcc9ad7a8e5b791647e58f094731d2
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
[root@localhost ~]#
docker rmi 镜像ID
docker rmi `docker images -aq` # 删除所有镜像
docker rmi 镜像id # 删除指定镜像
docker rmi 镜像id 镜像id # 删除指定镜像
镜像离线备份/恢复
docker save -o file.tar imageID # 保存镜像
docker load -i file.tar # 解压镜像
容器命令
有了镜像才能够创建容器,容器是镜像的一个运行实体。基于镜像的只读层,新建一个读写层,所有对容器进行的操作都会被写入到读写层。
容器运行
docker run [可选参数] image
# 参数说明
--name='NAME' 容器名字,nginx1 nginx2 来进行区分
-d 后台的方式启动
-t 以terminal终端的方式运行
-i 以input交互的模式启动镜像并运行
-p 指定端口运行
-p ip:主机端口:容器端口 对于多网卡的主机,可以指定使用哪块网卡的端口
-p 主机端口:容器端口 是指容器内的端口映射到主机的端口对外提供服务
-P 随机指定端口
--rm 启动后直接删除
> 以交互模式运行centos,启动并进入容器
[root@localhost ~]# docker run -it --name c1 centos bash
[root@137d0777f309 /]#
[root@137d0777f309 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
# exit退出容器,导致容器直接退出
[root@137d0777f309 /]# exit
exit
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
# 查看所有容器
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
137d0777f309 centos "bash" 14 seconds ago Exited (0) 3 seconds ago c1
[root@localhost ~]#
# 进入容器会报错,因为容器并未运行
[root@localhost ~]# docker exec -it 137d0777f309 sh
Error response from daemon: Container 137d0777f309a7931d837076af37a37d605209cec655fcf3b97d96f3d2171874 is not running
[root@localhost ~]#
# 通过start运行起来这个容器
[root@localhost ~]# docker start 137d0777f309
137d0777f309
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
137d0777f309 centos "bash" 3 minutes ago Up 4 seconds c1
[root@localhost ~]#
[root@localhost ~]# docker run -it --name c2 centos bash
[root@ecbb054ff06a /]#
# 进入容器后,使用Ctrl + p + q 退出容器而不退出
[root@ecbb054ff06a /]# [root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
ecbb054ff06a centos "bash" 11 seconds ago Up 11 seconds c2
137d0777f309 centos "bash" 5 minutes ago Up 2 minutes c1
[root@localhost ~]#
[root@localhost ~]#
查看所有容器
# docker ps [参数]
# 参数说明
-a 列出所有容器(含已停止的)
-n=? 显示最近创建的几个容器
-q 只显示容器的id
退出容器
exit # 直接退出容器并推出
Ctrl + p + q # 不停止容器退出
删除容器
# docker container rm [可选参数]
# 可选参数
Options:
-f, --force 强制删除
-l, --link Remove the specified link
-v, --volumes 删除容器和数据卷
启动和停止容器
docker star 容器id # 启动容器
docker restart 容器id # 重启容器
docker stop 容器id # 停止当前正在运行的容器
docker kill 容器id # 强制停止当前容器
容器启动常见新手坑
docker容器运行必须要有一个前台进程,docker服务发现如果一个容器未启动一个应用(未对外提供服务),就会直接结束这个容器。
# 下面演示一下后台运行 -d
# centos直接启动了但是未对外部提供服务
[root@localhost ~]# docker run --name c1 -d centos
643bfdc352fb5b058c6a59189d9cfa94ca4d9290895e9ad63d1309a858780cec
[root@localhost ~]#
# nginx启动是会对外提供服务的
[root@localhost ~]# docker run --name n1 -d nginx
c1facbaa3e30e8db44cc966f2b53ce194cbecb39b41e99e0572b0ec764ae6195
[root@localhost ~]#
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c1facbaa3e30 nginx "/docker-entrypoint.…" 3 seconds ago Up 2 seconds 80/tcp n1
[root@localhost ~]#
[root@localhost ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c1facbaa3e30 nginx "/docker-entrypoint.…" 6 seconds ago Up 5 seconds 80/tcp n1
643bfdc352fb centos "/bin/bash" 12 seconds ago Exited (0) 11 seconds ago c1
[root@localhost ~]#
常用其他命令
日志查看
# docker logs [可选参数] 容器id
# 可选参数:
-f, --follow 实时刷新日志
--since string 某时刻后 (例. 2013-01-02T13:23:37Z) 或时间段内 (例. 42m for 42 minutes)
-n, --tail string 尾部行数
-t, --timestamps Show timestamps
--until string 某时刻之前 (例. 2013-01-02T13:23:37Z) or 或时间段前 (e.g. 42m for 42 minutes)
# 日志查看
[root@localhost ~]#
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c1facbaa3e30 nginx "/docker-entrypoint.…" 10 hours ago Up 10 hours 80/tcp n1
[root@localhost ~]#
[root@localhost ~]# docker logs -tf --tail 30 c1facbaa3e30
2021-04-10T03:13:52.168667753Z /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
2021-04-10T03:13:52.168748946Z /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
2021-04-10T03:13:52.176780131Z /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
2021-04-10T03:13:52.196616259Z 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
2021-04-10T03:13:52.201315025Z 10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
2021-04-10T03:13:52.209915964Z /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
2021-04-10T03:13:52.214189363Z /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
2021-04-10T03:13:52.225238822Z /docker-entrypoint.sh: Configuration complete; ready for start up
^C
[root@localhost ~]#
查看容器内的进程信息
# docker ps 容器id
[root@localhost ~]#
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c1facbaa3e30 nginx "/docker-entrypoint.…" 10 hours ago Up 10 hours 80/tcp n1
[root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]# docker top c1facbaa3e30
UID PID PPID C STIME TTY TIME CMD
root 9072 9053 0 11:13 ? 00:00:00 nginx: master process nginx -g daemon off;
101 9130 9072 0 11:13 ? 00:00:00 nginx: worker process
[root@localhost ~]#
查看容器资源使用
# docker stats [容器ID]
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
# 名词解释
CONTAINER # 容器ID
NAME # 容器名称
CPU # CPU使用
MEM # 内存已用/最大/占比
NET # 网络吞吐
BLOCK # 磁盘读写
PIDS # 进程数
查看容器的元数据
# docker inspect 容器id
[root@localhost ~]#
[root@localhost ~]# docker inspect c1facbaa3e30
[
{
"Id": "c1facbaa3e30e8db44cc966f2b53ce194cbecb39b41e99e0572b0ec764ae6195",
"Created": "2021-04-10T03:13:51.657700582Z",
"Path": "/docker-entrypoint.sh",
"Args": [
"nginx",
"-g",
"daemon off;"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 9072,
"ExitCode": 0,
"Error": "",
"StartedAt": "2021-04-10T03:13:52.163838429Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:7ce4f91ef623b9672ec12302c4a710629cd542617c1ebc616a48d06e2a84656a",
"ResolvConfPath": "/var/lib/docker/containers/c1facbaa3e30e8db44cc966f2b53ce194cbecb39b41e99e0572b0ec764ae6195/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/c1facbaa3e30e8db44cc966f2b53ce194cbecb39b41e99e0572b0ec764ae6195/hostname",
"HostsPath": "/var/lib/docker/containers/c1facbaa3e30e8db44cc966f2b53ce194cbecb39b41e99e0572b0ec764ae6195/hosts",
"LogPath": "/var/lib/docker/containers/c1facbaa3e30e8db44cc966f2b53ce194cbecb39b41e99e0572b0ec764ae6195/c1facbaa3e30e8db44cc966f2b53ce194cbecb39b41e99e0572b0ec764ae6195-json.log",
"Name": "/n1",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "",
"ExecIDs": null,
"HostConfig": {
"Binds": null,
"ContainerIDFile": "",
"LogConfig": {
"Type": "json-file",
"Config": {}
},
"NetworkMode": "default",
"PortBindings": {},
"RestartPolicy": {
"Name": "no",
"MaximumRetryCount": 0
},
"AutoRemove": false,
"VolumeDriver": "",
"VolumesFrom": null,
"CapAdd": null,
"CapDrop": null,
"CgroupnsMode": "host",
"Dns": [],
"DnsOptions": [],
"DnsSearch": [],
"ExtraHosts": null,
"GroupAdd": null,
"IpcMode": "private",
"Cgroup": "",
"Links": null,
"OomScoreAdj": 0,
"PidMode": "",
"Privileged": false,
"PublishAllPorts": false,
"ReadonlyRootfs": false,
"SecurityOpt": null,
"UTSMode": "",
"UsernsMode": "",
"ShmSize": 67108864,
"Runtime": "runc",
"ConsoleSize": [
0,
0
],
"Isolation": "",
"CpuShares": 0,
"Memory": 0,
"NanoCpus": 0,
"CgroupParent": "",
"BlkioWeight": 0,
"BlkioWeightDevice": [],
"BlkioDeviceReadBps": null,
"BlkioDeviceWriteBps": null,
"BlkioDeviceReadIOps": null,
"BlkioDeviceWriteIOps": null,
"CpuPeriod": 0,
"CpuQuota": 0,
"CpuRealtimePeriod": 0,
"CpuRealtimeRuntime": 0,
"CpusetCpus": "",
"CpusetMems": "",
"Devices": [],
"DeviceCgroupRules": null,
"DeviceRequests": null,
"KernelMemory": 0,
"KernelMemoryTCP": 0,
"MemoryReservation": 0,
"MemorySwap": 0,
"MemorySwappiness": null,
"OomKillDisable": false,
"PidsLimit": null,
"Ulimits": null,
"CpuCount": 0,
"CpuPercent": 0,
"IOMaximumIOps": 0,
"IOMaximumBandwidth": 0,
"MaskedPaths": [
"/proc/asound",
"/proc/acpi",
"/proc/kcore",
"/proc/keys",
"/proc/latency_stats",
"/proc/timer_list",
"/proc/timer_stats",
"/proc/sched_debug",
"/proc/scsi",
"/sys/firmware"
],
"ReadonlyPaths": [
"/proc/bus",
"/proc/fs",
"/proc/irq",
"/proc/sys",
"/proc/sysrq-trigger"
]
},
"GraphDriver": {
"Data": {
"LowerDir": "/var/lib/docker/overlay2/e9ce2080590ff9df7aca2fe013e3f3f7c28bcfdc065c67b6f85cc3fb8a4a0bd3-init/diff:/var/lib/docker/overlay2/03ba41cbb98e51ac77550ebdaa45842f6ecbf8cfa5e46bbc11bcf69a65daffca/diff:/var/lib/docker/overlay2/0a33c5f1b1453c300ed2812ec8cad78e17bdce0b90e1cea3763e7ec7b34f6e1c/diff:/var/lib/docker/overlay2/0dc81292ba503f9ad3bbed6d8e1e0b7e71094f4fda08fcdab5f9d1ab465a3cd5/diff:/var/lib/docker/overlay2/f746f88696bc2be718cddbf9be61715eaef1afb412274f7e5525324ed208f220/diff:/var/lib/docker/overlay2/52d5cdf8a796baa2cc9a5cd5c539aa8c0cd3d3f8f9cf6372af1b5acc0c3a4a1f/diff:/var/lib/docker/overlay2/4bacbf47f498390759c41b25f9a0628383696e358b93c93650e3a47de00c002c/diff",
"MergedDir": "/var/lib/docker/overlay2/e9ce2080590ff9df7aca2fe013e3f3f7c28bcfdc065c67b6f85cc3fb8a4a0bd3/merged",
"UpperDir": "/var/lib/docker/overlay2/e9ce2080590ff9df7aca2fe013e3f3f7c28bcfdc065c67b6f85cc3fb8a4a0bd3/diff",
"WorkDir": "/var/lib/docker/overlay2/e9ce2080590ff9df7aca2fe013e3f3f7c28bcfdc065c67b6f85cc3fb8a4a0bd3/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "c1facbaa3e30",
"Domainname": "",
"User": "",
"AttachStdin": false,
"AttachStdout": false,
"AttachStderr": false,
"ExposedPorts": {
"80/tcp": {}
},
"Tty": false,
"OpenStdin": false,
"StdinOnce": false,
"Env": [
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
"NGINX_VERSION=1.19.9",
"NJS_VERSION=0.5.3",
"PKG_RELEASE=1~buster"
],
"Cmd": [
"nginx",
"-g",
"daemon off;"
],
"Image": "nginx",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": [
"/docker-entrypoint.sh"
],
"OnBuild": null,
"Labels": {
"maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>"
},
"StopSignal": "SIGQUIT"
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "215b083c80cd6163a5cecab41a0c9687d13ff1a1478fe3279687a49f52d09c25",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {
"80/tcp": null
},
"SandboxKey": "/var/run/docker/netns/215b083c80cd",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "0c087f336faab04c2700f88a4f0cf82e6e36155f468d4cd023d3431c6b15c075",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:02",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "ecfc352b4b0dada9e5b6ed430866782912063791dab093f328c1857341afdbdd",
"EndpointID": "0c087f336faab04c2700f88a4f0cf82e6e36155f468d4cd023d3431c6b15c075",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:02",
"DriverOpts": null
}
}
}
}
]
[root@localhost ~]#
进入当前正在运行的容器
# 方式一:docker exec -it 容器id 命令
[root@172 ~]#
[root@172 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
074cede752ab d0bd3a0d13e7 "/start.sh" 5 hours ago Up 5 hours 0.0.0.0:8000->80/tcp batch_log
[root@172 ~]#
# 一般使用 bash 或 /bin/bash
[root@172 ~]#
[root@172 ~]# docker exec -it batch_log bash
root@074cede752ab:/app# pwd
/app
root@074cede752ab:/app#
# 方式二:docker attach 容器id
[root@172 ~]# docker attach batch_log
[2021-06-21 15:08:25 +0800] [1] [INFO] Handling signal: winch
[2021-06-21 15:08:25 +0800] [1] [INFO] Handling signal: winch
# 比较
docker exec # 打开容器内的新的终端
docker attach # 进入容器正在执行的终端
容器内外文件复制
# docker cp 主机文件路径 容器id:路径
# docker cp 容器id:路径 主机路径
[root@localhost ~]#
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c1facbaa3e30 nginx "/docker-entrypoint.…" 10 hours ago Up 2 seconds 80/tcp n1
[root@localhost ~]#
[root@localhost ~]# ls
1000 anaconda-ks.cfg initial-setup-ks.cfg
[root@localhost ~]# touch abc.txt
[root@localhost ~]#
[root@localhost ~]# docker exec -it c1facbaa3e30 bash
root@c1facbaa3e30:/# ls
bin boot dev docker-entrypoint.d docker-entrypoint.sh etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
root@c1facbaa3e30:/# pwd
/
root@c1facbaa3e30:/#
root@c1facbaa3e30:/# touch sss.txt
root@c1facbaa3e30:/# exit
exit
[root@localhost ~]# docker cp abc.txt c1facbaa3e30:/
[root@localhost ~]# docker cp c1facbaa3e30:/sss.txt .
[root@localhost ~]# ls
1000 abc.txt anaconda-ks.cfg initial-setup-ks.cfg sss.txt
[root@localhost ~]#
[root@localhost ~]# docker exec -it c1facbaa3e30 bash
root@c1facbaa3e30:/# ls
abc.txt bin boot dev docker-entrypoint.d docker-entrypoint.sh etc home lib lib64 media mnt opt proc root run sbin srv sss.txt sys tmp usr var
root@c1facbaa3e30:/#
root@c1facbaa3e30:/#
查看容器的资源使用
# docker stats 列出所有容器的使用状态
[root@localhost ~]#
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b4e5f1c68098 tomcat "catalina.sh run" 11 minutes ago Up 11 minutes 0.0.0.0:8888->8080/tcp t2
675d785b758f tomcat "catalina.sh run" 18 hours ago Up About a minute 8080/tcp t1
c1facbaa3e30 nginx "/docker-entrypoint.…" 28 hours ago Up About a minute 80/tcp n1
[root@localhost ~]#
[root@localhost ~]#
[root@localhost ~]# docker stats
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O PIDS
b4e5f1c68098 t2 0.32% 125.7MiB / 1.795GiB 6.84% 10.8kB / 127kB 62.9MB / 0B 30
675d785b758f t1 0.11% 67.73MiB / 1.795GiB 3.69% 656B / 0B 8.09MB / 0B 29
c1facbaa3e30 n1 0.00% 2.633MiB / 1.795GiB 0.14% 656B / 0B 22.4MB / 0B 2
数据卷
Docker的镜像是由一系列的只读层组合而来,当启动一个容器的时候,Docker加载镜像的所有只读层,并在最上层加入一个读写层。这个设计使得Docker可以提高镜像构建、存储和分发的效率,节省了时间和存储空间,然而也存在如下问题。
(1)容器中的文件在宿主机上存在形式复杂,不能在宿主机上很方便的对容器中的文件进行访问
(2)多个容器之间的数据无法共享
(3)当删除容器时,容器产生的数据将丢失
为了解决这些问题,Docker引入了数据卷(volume)机制。volume是存在一个或多个容器中的特定文件或文件夹,这个目录能够独立于联合文件系统的形式在宿主机中存在,并为数据的共享与持久提供一下便利
(1)volume在容器创建时就初始化,在容器运行时就可以使用其中的文件
(2)volume能在不同的容器之间共享和重用
(3)对volume中的数据的操作会马上生效
(4)对volume中数据操作不会影响到镜像本身
(5)volume的生存周期独立于容器的生存周期,即使删除容器,volume仍然会存在,没有任何容器使用的volume也不会被Docker删除
数据卷使用
# 数据卷挂载
# docker run -v 数据卷:容器卷
匿名挂载
只指定容器中的挂载点,便于容器内部文件访问(一般不用)
docker run -itd -v /data/app 镜像ID
# docker volume COMMAND
# 可选参数:
create # 创建数据卷
inspect # 查看数据卷详情
ls # 列出所有数据卷
prune # 删除搜有未被使用的数据卷
rm # 删除一个或多个数据卷
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2ce37b1523e9 nginx "/docker-entrypoint.…" 3 minutes ago Up 3 minutes 0.0.0.0:83->80/tcp n3
854524b99b60 nginx "/docker-entrypoint.…" 4 minutes ago Up 4 minutes 0.0.0.0:82->80/tcp n2
e1ad3a34b432 portainer/portainer "/portainer" About an hour ago Up About an hour 0.0.0.0:9000->9000/tcp portainer
b4e5f1c68098 tomcat "catalina.sh run" About an hour ago Up About an hour 0.0.0.0:8888->8080/tcp t2
675d785b758f tomcat "catalina.sh run" 19 hours ago Up About an hour 8080/tcp t1
c1facbaa3e30 nginx "/docker-entrypoint.…" 30 hours ago Up About an hour 80/tcp n1
[root@localhost ~]#
[root@localhost ~]# docker volume ls
DRIVER VOLUME NAME
local a4bc07fe3366356230d5467998ddf2a243b660e0b3b765f64efc5e3dee11c3be
local nginx3
[root@localhost ~]#
[root@localhost ~]#
# 查看数据卷详情 docker volume inspect 具名
[root@localhost ~]# docker volume inspect nginx3
[
{
"CreatedAt": "2021-04-11T16:40:52+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/nginx3/_data",
"Name": "nginx3",
"Options": null,
"Scope": "local"
}
]
[root@localhost ~]#
-v 容器目录 # 匿名挂载,指定容器内部的挂载点。例如, -v /data/work
-v 卷名:容器目录 # 具名挂载,指定具名。例如, -v App:/app 直接声明了具名,一般默认主机的挂在路径为 `/data/docker/volumes/具名`
-v 卷名:容器目录:ro # 具名挂载,只读(rw读写),只能在主机操作,无法在容器内操作
-v /主机目录:容器目录 # 指定目录挂载
具名挂载
主机挂载
说明:
- 匿名挂载是为了确定容器的挂载点的位置,方便操作容器内部的文件
- 具名挂在是给对应的挂载起了一个名称,便于在主机查找被挂载点,可以使用 docker volumes ls 方便的查看到匿名和具名挂载信息,同时,具名挂载一般主机目录是在
- 主机文件挂载
数据卷共享
[root@localhost test_docker]# docker run -it --name c1 -v c1_volume bf536fcd39c8
[root@b262d2b6c690 /]#
[root@localhost test_docker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b262d2b6c690 bf536fcd39c8 "/bin/sh -c /bin/bash" 26 seconds ago Up 25 seconds c1
[root@localhost test_docker]#
[root@localhost test_docker]# docker inspect b262d2b6c690
# 启动一个容器挂载继承自上述c1
[root@localhost test_docker]# docker run -it --name c2 --volumes-from c1 bf536fcd39c8
[root@localhost test_docker]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c7ce81b0acd1 bf536fcd39c8 "/bin/sh -c /bin/bash" 10 seconds ago Up 9 seconds c2
b262d2b6c690 bf536fcd39c8 "/bin/sh -c /bin/bash" 3 minutes ago Up 3 minutes c1
[root@localhost test_docker]#
# 查看挂载信息
[root@localhost test_docker]# docker inspect c2
DockerFile
DockerFile实践
[root@it st_dockerfile1]# ll
总用量 249656
-rw-r--r-- 1 root root 1092 4月 15 16:01 application.properties
-rw-r--r-- 1 root root 2760 4月 15 16:01 application-test.properties
-rw-r--r-- 1 root root 104349690 4月 15 15:58 automated-testing-1.0.3-SNAPSHOT.jar
-rw-r--r-- 1 root root 7558560 4月 15 15:58 dist1.0.3.zip
-rw-r--r-- 1 root root 351 4月 16 17:29 dockerfile
drwxr-xr-x 8 10143 10143 273 12月 9 20:50 jdk1.8.0_281
-rw-r--r-- 1 root root 143722924 4月 16 13:49 jdk-8u281-linux-x64.tar.gz
[root@it st_dockerfile1]#
[root@it st_dockerfile1]# cat dockerfile
# 继承于哪个基础镜像
FROM centos
# 设置环境变量,用于下方引用
ENV work_dir /home/works
# 设置工作路径,一般在文件操作前指定工作路径(类似于cd)
WORKDIR $work_dir
# 吧当前主机下的文件拷贝到工作路径下
COPY jdk1.8.0_281 ./jdk1.8.0_281
# 设置环境变量
ENV JAVA_HOME $work_dir/jdk1.8.0_281
ENV CLASSPATH $JAVA_HOME/lib/
ENV PATH $PATH:$JAVA_HOME/bin
# 拷贝相关配置文件
COPY application.properties .
COPY application-test.properties .
COPY automated-testing-1.0.3-SNAPSHOT.jar .
# 执行命令
CMD java -jar automated-testing-1.0.3-SNAPSHOT.jar
[root@it st_dockerfile1]#
说明:
- 只有
ENV
中配置的变量才能在接下来的命令中引用(直接引用$WORKDIR是不行的)- jdk一定要搞清楚是32位还是64位
- COPY 路径尽量用绝对路径,不要用相对
打包镜像
# docker build [OPTIONS] PATH | URL | -
# 可选参数:
--add-host list Add a custom host-to-IP mapping (host:ip)
--build-arg list Set build-time variables
--cache-from strings Images to consider as cache sources
--cgroup-parent string Optional parent cgroup for the container
--compress Compress the build context using gzip
--cpu-period int Limit the CPU CFS (Completely Fair Scheduler) period
--cpu-quota int Limit the CPU CFS (Completely Fair Scheduler) quota
-c, --cpu-shares int CPU shares (relative weight)
--cpuset-cpus string CPUs in which to allow execution (0-3, 0,1)
--cpuset-mems string MEMs in which to allow execution (0-3, 0,1)
--disable-content-trust Skip image verification (default true)
-f, --file string Name of the Dockerfile (Default is 'PATH/Dockerfile')
--force-rm Always remove intermediate containers
--iidfile string Write the image ID to the file
--isolation string Container isolation technology
--label list Set metadata for an image
-m, --memory bytes Memory limit
--memory-swap bytes Swap limit equal to memory plus swap: '-1' to enable unlimited swap
--network string Set the networking mode for the RUN instructions during build (default "default")
--no-cache Do not use cache when building the image
--pull Always attempt to pull a newer version of the image
-q, --quiet Suppress the build output and print image ID on success
--rm Remove intermediate containers after a successful build (default true)
--security-opt strings Security options
--shm-size bytes Size of /dev/shm
-t, --tag list Name and optionally a tag in the 'name:tag' format
--target string Set the target build stage to build.
--ulimit ulimit Ulimit options (default [])
[root@localhost test_docker]#
使用上方dockerfile实践
# 使用dockerfile打包
[root@localhost test_docker]# docker build -f dockerfile -t mycentos:1.0.1 .
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM centos
---> 300e315adb2f
Step 2/4 : VOLUME ['volum1','data2']
---> Running in d652b383eac9
Removing intermediate container d652b383eac9
---> 8ec94a35e0bb
Step 3/4 : CMD echo '------end--------'
---> Running in 4ba29a74a0c0
Removing intermediate container 4ba29a74a0c0
---> 9ff8a0181629
Step 4/4 : CMD /bin/bash
---> Running in 91e6fccc2b2c
Removing intermediate container 91e6fccc2b2c
---> 1e4167a4374b
Successfully built 1e4167a4374b
Successfully tagged mycentos:1.0.1
[root@localhost test_docker]#
# 查看打包的镜像
[root@localhost test_docker]#
[root@localhost test_docker]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mycentos 1.0.1 1e4167a4374b 6 minutes ago 209MB
t2 1.0.1 bc3e82a80c49 About an hour ago 672MB
tomcat latest b72e45a11ad9 4 days ago 667MB
nginx latest 7ce4f91ef623 11 days ago 133MB
mysql 5.7 cd0f0b1e283d 11 days ago 449MB
portainer/portainer latest 580c0e4e98b0 3 weeks ago 79.1MB
centos latest 300e315adb2f 4 months ago 209MB
[root@localhost test_docker]#
DockerFile中的数据卷
# 通过dockerfile创建镜像,并添加volume
[root@localhost test_docker]# pwd
/home/test_docker
[root@localhost test_docker]# cat dockerfile
FROM centos
VOLUME ['volum1','data2']
CMD echo '------end--------'
CMD /bin/bash
[root@localhost test_docker]#
# FROM centos 指定基础镜像
# VOLUME ['volum1','data2'] 创建数据卷,此处如果使用单引号则只创建一个匿名卷,如果是双引号,则创建两个匿名卷,见下方图
# CMD echo '------end--------' 执行命令
# CMD /bin/bash 执行命令
双引号是两个卷
单引号是一个卷,被解析成描述字段
CMD和ENTRYPOINT的区别
CMD # 指定容器启动后执行的命令(只有最后一条cmd会生效),命令可被替代
ENTRYPOINT # 指定容器启动后执行的命令(只有最后一条cmd会生效),不会被替代,可被追加命令或参数
使用CMD
- 只执行最后一条
[root@it lwj]# cat Dockerfile
FROM centos
MAINTAINER wjlv4@iflytek.com
CMD ["pwd"]
CMD ["ls"]
# 打包镜像
[root@it lwj]# docker build -t t1:1.0 .
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM centos
---> 300e315adb2f
Step 2/4 : MAINTAINER wjlv4@iflytek.com
---> Running in 5343d5f910e2
Removing intermediate container 5343d5f910e2
---> 417eee370d63
Step 3/4 : CMD ["pwd"]
---> Running in 7bac8649856c
Removing intermediate container 7bac8649856c
---> 1db347fe84b4
Step 4/4 : CMD ["ls"]
---> Running in c333a126697f
Removing intermediate container c333a126697f
---> c565ada161ff
Successfully built c565ada161ff
Successfully tagged t1:1.0
# 执行
[root@it lwj]# docker run c56
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
[root@it lwj]#
- 命令会被覆盖
当输入pwd
或者w
时原始的命令被覆盖了
[root@it lwj]#
[root@it lwj]# docker run c56 pwd
/
[root@it lwj]#
[root@it lwj]# docker run c56 w
04:57:17 up 104 days, 24 min, 0 users, load average: 0.00, 0.01, 0.05
USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT
[root@it lwj]#
使用ENTRYPOINT
[root@it lwj]# cat Dockerfile
FROM centos
MAINTAINER wjlv4@iflytek.com
ENTRYPOINT ["w"]
ENTRYPOINT ["ls"]
# 镜像打包
[root@it lwj]# docker build -t t2:1.0 .
Sending build context to Docker daemon 2.048kB
Step 1/4 : FROM centos
---> 300e315adb2f
Step 2/4 : MAINTAINER wjlv4@iflytek.com
---> Running in 5278eed96b9f
Removing intermediate container 5278eed96b9f
---> cf401a10d8d8
Step 3/4 : ENTRYPOINT ["w"]
---> Running in c7c4b639e4e9
Removing intermediate container c7c4b639e4e9
---> 36b175abe2a1
Step 4/4 : ENTRYPOINT ["ls"]
---> Running in 97f320379f8b
Removing intermediate container 97f320379f8b
---> f7ec1769e374
Successfully built f7ec1769e374
Successfully tagged t2:1.0
[root@it lwj]#
- 仅执行最后一条
[root@it lwj]# docker run f7
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
[root@it lwj]#
- 命令不会被覆盖
[root@it lwj]# docker run f7 pwd
ls: cannot access 'pwd': No such file or directory
[root@it lwj]#
- 命令可被追加参数
[root@it home]# docker run f7 -lt
total 0
drwxr-xr-x 5 root root 340 Jul 12 05:14 dev
dr-xr-xr-x 237 root root 0 Jul 12 05:14 proc
drwxr-xr-x 1 root root 66 Jul 12 05:14 etc
dr-xr-xr-x 13 root root 0 Apr 16 09:28 sys
dr-xr-x--- 2 root root 162 Dec 4 2020 root
drwxr-xr-x 11 root root 163 Dec 4 2020 run
drwxrwxrwt 7 root root 145 Dec 4 2020 tmp
drwxr-xr-x 20 root root 262 Dec 4 2020 var
drwxr-xr-x 12 root root 144 Dec 4 2020 usr
drwx------ 2 root root 6 Dec 4 2020 lost+found
lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x 2 root root 6 Nov 3 2020 home
lrwxrwxrwx 1 root root 7 Nov 3 2020 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Nov 3 2020 lib64 -> usr/lib64
drwxr-xr-x 2 root root 6 Nov 3 2020 media
drwxr-xr-x 2 root root 6 Nov 3 2020 mnt
drwxr-xr-x 2 root root 6 Nov 3 2020 opt
lrwxrwxrwx 1 root root 8 Nov 3 2020 sbin -> usr/sbin
drwxr-xr-x 2 root root 6 Nov 3 2020 srv
[root@it home]#
- 可在命令的最后追加执行命令
[root@it home]# docker run f7 -lt && cd /home && pwd
total 0
drwxr-xr-x 5 root root 340 Jul 12 05:14 dev
dr-xr-xr-x 237 root root 0 Jul 12 05:14 proc
drwxr-xr-x 1 root root 66 Jul 12 05:14 etc
dr-xr-xr-x 13 root root 0 Apr 16 09:28 sys
dr-xr-x--- 2 root root 162 Dec 4 2020 root
drwxr-xr-x 11 root root 163 Dec 4 2020 run
drwxrwxrwt 7 root root 145 Dec 4 2020 tmp
drwxr-xr-x 20 root root 262 Dec 4 2020 var
drwxr-xr-x 12 root root 144 Dec 4 2020 usr
drwx------ 2 root root 6 Dec 4 2020 lost+found
lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x 2 root root 6 Nov 3 2020 home
lrwxrwxrwx 1 root root 7 Nov 3 2020 lib -> usr/lib
lrwxrwxrwx 1 root root 9 Nov 3 2020 lib64 -> usr/lib64
drwxr-xr-x 2 root root 6 Nov 3 2020 media
drwxr-xr-x 2 root root 6 Nov 3 2020 mnt
drwxr-xr-x 2 root root 6 Nov 3 2020 opt
lrwxrwxrwx 1 root root 8 Nov 3 2020 sbin -> usr/sbin
drwxr-xr-x 2 root root 6 Nov 3 2020 srv
/home
RUN命令
主要用于镜像构建时一些基础包安装、环境配置
[root@it lwj]# cat Dockerfile
FROM centos
MAINTAINER wjlv4@iflytek.com
RUN yum install -y which
CMD ["w"]
CMD ["which","ls"]
# 镜像打包
[root@it lwj]# docker build -t t1:1.0 .
Sending build context to Docker daemon 2.048kB
Step 1/5 : FROM centos
---> 300e315adb2f
Step 2/5 : MAINTAINER wjlv4@iflytek.com
---> Running in 52248af28db7
Removing intermediate container 52248af28db7
---> 1f4e6eab8176
Step 3/5 : RUN yum install -y which
---> Running in 35e94501bf45
CentOS Linux 8 - AppStream 841 kB/s | 8.1 MB 00:09
CentOS Linux 8 - BaseOS 986 kB/s | 3.6 MB 00:03
CentOS Linux 8 - Extras 13 kB/s | 9.8 kB 00:00
Dependencies resolved.
================================================================================
Package Architecture Version Repository Size
================================================================================
Installing:
which x86_64 2.21-12.el8 baseos 49 k
Transaction Summary
================================================================================
Install 1 Package
Total download size: 49 k
Installed size: 81 k
Downloading Packages:
which-2.21-12.el8.x86_64.rpm 770 kB/s | 49 kB 00:00
--------------------------------------------------------------------------------
Total 81 kB/s | 49 kB 00:00
warning: /var/cache/dnf/baseos-f6a80ba95cf937f2/packages/which-2.21-12.el8.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID 8483c65d: NOKEY
CentOS Linux 8 - BaseOS 1.6 MB/s | 1.6 kB 00:00
Importing GPG key 0x8483C65D:
Userid : "CentOS (CentOS Official Signing Key) <security@centos.org>"
Fingerprint: 99DB 70FA E1D7 CE22 7FB6 4882 05B5 55B3 8483 C65D
From : /etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial
Key imported successfully
Running transaction check
Transaction check succeeded.
Running transaction test
Transaction test succeeded.
Running transaction
Preparing : 1/1
Installing : which-2.21-12.el8.x86_64 1/1
Running scriptlet: which-2.21-12.el8.x86_64 1/1
Verifying : which-2.21-12.el8.x86_64 1/1
Installed:
which-2.21-12.el8.x86_64
Complete!
Removing intermediate container 35e94501bf45
---> 4bf8b8b4a058
Step 4/5 : CMD ["w"]
---> Running in 8ab9e716f85e
Removing intermediate container 8ab9e716f85e
---> 99500f570573
Step 5/5 : CMD ["which","ls"]
---> Running in c9a4c4164472
Removing intermediate container c9a4c4164472
---> f77a0f654e0c
Successfully built f77a0f654e0c
Successfully tagged t1:1.0
[root@it lwj]#
RUN
和
CMD和
ENTRYPOINT`区别?
RUN
在构建镜像的时候执行,而CMD
在容器运行的时候执行- 无论是
CMD
还是ENTRYPOINT
都只会运行最后一条CMD
的命令可以在容器运行时被替换掉(不支持追加参数)ENTRYPOINT
会把容器执行时的参数当作命令的追加参数(不会被替代)