本笔记是个人收集整理的,后面的实操内容是看B站狂神老师的Docker教程做到笔记,【狂神说Java】Docker最新超详细版教程通俗易懂,对于入门的小白来说,看完确实是可以快速上手,不过有一些概念原理说的不是很清楚,我会在笔记整理docker相关的概念和技术原理,从而对Docker会有一个更深入的了解。
Docker 是一个开源的应用容器引擎,而一个容器containers其实是一个虚拟化的独立的环境,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。
Docker 的局限性之一,它只能用在 64 位的操作系统上。
Docker是一个虚拟环境容器,可以将你的开发环境、代码、配置文件等一并打包到这个容器中,并发布和应用到任意平台中。 原理: docker底层使用了LXC来实现,LXC将linux进程沙盒化,使得进程之间相互隔离,并且能够协调各进程的资源分配。 LXC: LXC为Linux Container的简写。可以提供轻量级的虚拟化,以便隔离进程和资源,而且不需要提供指令解释机制以及全虚拟化的其他复杂性。
Docker容器 | LXC | VM | |
---|---|---|---|
虚拟机类型 | OS虚拟化 | OS虚拟化 | 硬件虚拟化 |
性能 | =物理机性能 | =物理机性能 | 5%-20%损耗 |
隔离性 | NS隔离 | NS隔离 | 强 |
QoS | Cgroup弱 | Cgroup弱 | 强 |
安全性 | 中 | 差 | 强 |
GuestOS | 全部 | 只支持Linux | 全部 |
$ sudo apt-get remove docker docker-engine docker.io containerd runc
apt-get
如果报告没有安装这些软件包,那也没关系。在新主机上首次安装 Docker Engine 之前,您需要设置 Docker 存储库。之后,您可以从存储库安装和更新 Docker。
$ sudo apt-get update
$ sudo apt-get install \
ca-certificates \
curl \
gnupg \
lsb-release
$ sudo mkdir -p /etc/apt/keyrings
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
$ echo \
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin
$ apt-cache madison docker-ce
docker-ce | 5:20.10.17~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
docker-ce | 5:20.10.16~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
docker-ce | 5:20.10.15~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
docker-ce | 5:20.10.14~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
docker-ce | 5:20.10.13~3-0~ubuntu-focal | https://download.docker.com/linux/ubuntu focal/stable amd64 Packages
使用第二列中的版本字符串安装特定版本,例如5:20.10.17~3-0~ubuntu-focal
$ sudo apt-get install docker-ce= docker-ce-cli= containerd.io docker-compose-plugin
# 安装5:20.10.17~3-0~ubuntu-focal
$ sudo apt-get install docker-ce=5:20.10.17~3-0~ubuntu-focal docker-ce-cli=5:20.10.17~3-0~ubuntu-focal containerd.io docker-compose-plugin
hello-world
通过运行映像来验证 Docker 引擎是否已正确安装。$ sudo docker run hello-world
结果如下:
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete
Digest: sha256:80f31da1ac7b312ba29d65080fddf797dd76acfb870e677f390d5acba9741b17
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
$ sudo apt-get purge docker-ce docker-ce-cli containerd.io docker-compose-plugin
$ sudo rm -rf /var/lib/docker
$ sudo rm -rf /var/lib/containerd
您必须手动删除任何已编辑的配置文件。
sudo
运行docker命令$ sudo groupadd docker
$ sudo gpasswd -a ${USER} docker
sudo
了。$ docker version # 显示docker的版本信息
$ docker info # 显示docker系统信息,包括镜像和容器的数量
$ docker 命令 --help # 帮助命令
docker images
查看所有本地主机上的镜像,docker images命令$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
new_dingbot_msg latest cde233707f86 14 hours ago 437MB
dingmsg_service latest 269caf0cc7eb 21 hours ago 437MB
ubuntu 20.04 20fffa419e3a 3 days ago 72.8MB
httpd latest 98f93cd0ec3b 13 days ago 144MB
hello-world latest feb5d9fea6a5 8 months ago 13.3kB
# 解释
REPOSITORY 镜像的仓库源
TAG 镜像的标签
IMAGE ID 镜像的id
CREATED 镜像的创建时间
SIZE 镜像的大小
# 可选项
-a, --all # 显示所有镜像
-q, --quiet # 显示镜像的id
docker search
搜索镜像,docker search$ docker search mysql
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 12708 [OK]
mariadb MariaDB Server is a high performing open sou… 4878 [OK]
percona Percona Server is a fork of the MySQL relati… 579 [OK]
phpmyadmin phpMyAdmin - A web interface for MySQL and M… 553 [OK]
bitnami/mysql Bitnami MySQL Docker Image 71 [OK]
# 可选项,通过搜索来过滤
--filter , -f=STARS=3000 #搜索镜像的STARS大于3000的
$ docker search mysql -f=stars=3000
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 12708 [OK]
mariadb MariaDB Server is a high performing open sou… 4878 [OK]
docker pull
下载镜像,docker pull# 下载镜像 docker pull 镜像名[:tag]
$ docker pull mysql
Using default tag: latest # 如果不写tag,默认的是latest
latest: Pulling from library/mysql
c1ad9731b2c7: Pull complete # 分层下载 docker image 的核心 联合文件系统
54f6eb0ee84d: Pull complete
cffcf8691bc5: Pull complete
89a783b5ac8a: Pull complete
6a8393c7be5f: Pull complete
af768d0b181e: Pull complete
810d6aaaf54a: Pull complete
2e014a8ae4c9: Pull complete
a821425a3341: Pull complete
3a10c2652132: Pull complete
4419638feac4: Pull complete
681aeed97dfe: Pull complete
Digest: sha256:548da4c67fd8a71908f17c308b8ddb098acf5191d3d7694e56801c6a8b2072cc # 签名信息
Status: Downloaded newer image for mysql:latest
docker.io/library/mysql:latest # 真实地址
# 等价于
$ docke pull mysql
$ docke pull docker.io/library/mysql:latest
# 指定版本下载
$ docker pull mysql:5.7
5.7: Pulling from library/mysql
c1ad9731b2c7: Already exists # 之前下载过的镜像是可以共用的,大大节省内存 联合文件系统最高明之处
54f6eb0ee84d: Already exists
cffcf8691bc5: Already exists
89a783b5ac8a: Already exists
6a8393c7be5f: Already exists
af768d0b181e: Already exists
810d6aaaf54a: Already exists
81fe6daf2395: Pull complete
5ccf426818fd: Pull complete
68b838b06054: Pull complete
1b606c4f93df: Pull complete
Digest: sha256:7e99b2b8d5bca914ef31059858210f57b009c40375d647f0d4d65ecd01d6b1d5
Status: Downloaded newer image for mysql:5.7
docker.io/library/mysql:5.7
# 查看镜像
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mysql 5.7 2a0961b7de03 13 days ago 462MB
mysql latest 65b636d5542b 13 days ago 524MB
docker rmi
删除镜像,docker rmi$ docker rmi -f 容器id # 删除指定的容器
$ docker rmi -f 容器id 容器id 容器id 容器id 容器id # 删除多个容器
$ docker rmi -f $(docker images -aq) # 删除全部容器
$ docker pull centos
$ docker run [可选参数] image
# 参数选项
--name "Name" # 容器名字 centos1 centos2 用于区分容器
-d # 后台运行方式
-it # 使用交互方式执行,进入容器查看内容
-p # 指定容器端口 -p 8080:80
-p ip:主机端口:容器端口
-p 主机端口:容器端口(常用)
-p 容器端口
容器端口
-p # 随机指定端口3
# 测试,启动进入容器
$ docker run -it centos /bin/bash
[root@f766035e7769 /]# ls
bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var
# 从容器退回主机
$ [root@f766035e7769 /]# exit
exit
docker ps
列出所有运行的容器$ docker ps 命令
# 列出当前真在运行的的容器
-a # 列出当前正在运行的容器+历史运行的容器
-n=? # 显示最近创建的容器
-q # 显示容器的编号
# 列出当前真在运行的的容器
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7e61c738bcf4 dingmsg_service "python3 app/lemumsg…" 22 hours ago Up 22 hours 0.0.0.0:6655->6655/tcp, :::6655->6655/tcp dingbot-test
986f882220ef httpd "httpd-foreground" 40 hours ago Up 17 hours 0.0.0.0:8877->80/tcp, :::8877->80/tcp apache-test
# 列出当前正在运行的容器+历史运行的容器
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f766035e7769 centos "/bin/bash" 20 minutes ago Exited (0) 5 minutes ago beautiful_proskuriakova
7e61c738bcf4 dingmsg_service "python3 app/lemumsg…" 22 hours ago Up 22 hours 0.0.0.0:6655->6655/tcp, :::6655->6655/tcp dingbot-test
286484b695e4 20fffa419e3a "/bin/sh -c 'apt-get…" 25 hours ago Exited (127) 25 hours ago nervous_kilby
# 显示最近创建的容器
$ docker ps -n=1
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f766035e7769 centos "/bin/bash" 18 minutes ago Exited (0) 3 minutes ago beautiful_proskuriakova
# 显示容器的编号
$ docker ps -aq
f766035e7769
7e61c738bcf4
286484b695e4
$ exit # 直接容器停止并退出
$ Ctrl + P + Q # 容器不停止推出
$ docker rm 容器id # 删除制定的容器,不能删除正在运行的容器,如果要强制删除需要使用 rm -f
$ docker rm -f $(docker ps -aq) # 删除所有容器
$ docker ps -a -q | xargs docker rm # 删除所有的容器
$ docker start 容器id # 启动容器
$ docker restart 容器id # 重启容器
$ docker stop 容器id # 停止当前正在运行的的容器
$ docker kill 容器id # 强制停止当前容器
# 命令:docker run -d 镜像名
$ docker run -d centos
# 问题docker ps ,发现centos停止了
# 常见的坑:docker 容器使用后台运行,就必须要有一个前台进程,docker发现没有应用就会自动停止
# apache ,容器启动后,发现自己没有提供服务,就会停止,就没有程序了。
$ docker logs -tf --tail 10 容器id 没有日志
# 如果docker镜像启动本来就没有日志,可以编写一个脚本进行测试
$ docker run -d centos /bin/sh -c "while true;do echo hello docker;sleep 1;done"
8095f554dbd16c29ef61182a12813756458a0a24d09bdbe761142dac1c971e7c
# 查看运行docker
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
be72714b0e60 centos "/bin/sh -c 'while t…" 16 seconds ago Up 15 seconds jovial_zhukovsky
# 显示日志
-tf # 显示时间和日志
--tail num # 显示日志条数
# 显示10行的be72714b0e60的日志
$ docker logs -tf --tail 10 be72714b0e60
2022-06-10T12:52:09.983041830Z hello docker
2022-06-10T12:52:10.984397462Z hello docker
2022-06-10T12:52:11.985690607Z hello docker
2022-06-10T12:52:12.986983999Z hello docker
2022-06-10T12:52:13.988244570Z hello docker
2022-06-10T12:52:14.989404639Z hello docker
2022-06-10T12:52:15.990945974Z hello docker
2022-06-10T12:52:16.992115773Z hello docker
2022-06-10T12:52:17.993503637Z hello docker
2022-06-10T12:52:18.995010360Z hello docker
$ docker top 容器id # 查看指定容器的进程信息
$ $ docker top be72714b0e60
UID PID PPID C STIME TTY TIME CMD
root 650475 650452 0 20:50 ? 00:00:00 /bin/sh -c while true;do echo hello docker;sleep 1;done
root 682489 650475 0 21:17 ? 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1
# 命令
$ docker inspect 容器id
# 查看centos 容器的元数据
$ docker inspect be72714b0e60
[
{
"Id": "be72714b0e60f4911bc807bbb4597e139f6eaa829c9ac117b76e2f13b87c1bf2",
"Created": "2022-06-10T12:50:51.582969979Z",
"Path": "/bin/sh",
"Args": [
"-c",
"while true;do echo hello docker;sleep 1;done"
],
"State": {
"Status": "running",
"Running": true,
"Paused": false,
"Restarting": false,
"OOMKilled": false,
"Dead": false,
"Pid": 650475,
"ExitCode": 0,
"Error": "",
"StartedAt": "2022-06-10T12:50:51.87753439Z",
"FinishedAt": "0001-01-01T00:00:00Z"
},
"Image": "sha256:5d0da3dc976460b72c77d94c8a1ad043720b0416bfc16c52c45d4847e53fadb6",
"ResolvConfPath": "/var/lib/docker/containers/be72714b0e60f4911bc807bbb4597e139f6eaa829c9ac117b76e2f13b87c1bf2/resolv.conf",
"HostnamePath": "/var/lib/docker/containers/be72714b0e60f4911bc807bbb4597e139f6eaa829c9ac117b76e2f13b87c1bf2/hostname",
"HostsPath": "/var/lib/docker/containers/be72714b0e60f4911bc807bbb4597e139f6eaa829c9ac117b76e2f13b87c1bf2/hosts",
"LogPath": "/var/lib/docker/containers/be72714b0e60f4911bc807bbb4597e139f6eaa829c9ac117b76e2f13b87c1bf2/be72714b0e60f4911bc807bbb4597e139f6eaa829c9ac117b76e2f13b87c1bf2-json.log",
"Name": "/jovial_zhukovsky",
"RestartCount": 0,
"Driver": "overlay2",
"Platform": "linux",
"MountLabel": "",
"ProcessLabel": "",
"AppArmorProfile": "docker-default",
"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/0fc9cdacc3b9f7bb1a6445173c604dafba45749458ba4c8500dad1a8aac09b3a-init/diff:/var/lib/docker/overlay2/643b7419a5e24b28b4b201c15accae5d5b1a0caf84229d9cff1d8c068f18ac8e/diff",
"MergedDir": "/var/lib/docker/overlay2/0fc9cdacc3b9f7bb1a6445173c604dafba45749458ba4c8500dad1a8aac09b3a/merged",
"UpperDir": "/var/lib/docker/overlay2/0fc9cdacc3b9f7bb1a6445173c604dafba45749458ba4c8500dad1a8aac09b3a/diff",
"WorkDir": "/var/lib/docker/overlay2/0fc9cdacc3b9f7bb1a6445173c604dafba45749458ba4c8500dad1a8aac09b3a/work"
},
"Name": "overlay2"
},
"Mounts": [],
"Config": {
"Hostname": "be72714b0e60",
"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",
"while true;do echo hello docker;sleep 1;done"
],
"Image": "centos",
"Volumes": null,
"WorkingDir": "",
"Entrypoint": null,
"OnBuild": null,
"Labels": {
"org.label-schema.build-date": "20210915",
"org.label-schema.license": "GPLv2",
"org.label-schema.name": "CentOS Base Image",
"org.label-schema.schema-version": "1.0",
"org.label-schema.vendor": "CentOS"
}
},
"NetworkSettings": {
"Bridge": "",
"SandboxID": "2e1d253296845eb7e8e5dc418d9a2b9fa7a39b38e470f632270f3bb3612db632",
"HairpinMode": false,
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"Ports": {},
"SandboxKey": "/var/run/docker/netns/2e1d25329684",
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"EndpointID": "98e8d239576f58070b4898d4ef16dc89a9afdb7f07d96f9980b52efeb028f2af",
"Gateway": "172.17.0.1",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.6",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"MacAddress": "02:42:ac:11:00:06",
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "d64c7bbc42f591f3d4e7ce51fdbf9a93ac1bcf29459995c66db327dfce79003b",
"EndpointID": "98e8d239576f58070b4898d4ef16dc89a9afdb7f07d96f9980b52efeb028f2af",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.6",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:06",
"DriverOpts": null
}
}
}
}
]
# 我们通常容器都是使用后台方式运行的,需要进入容器,修改一些配置
# 命令
$ docker exec -it 容器id bashshell
# 测试
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
be72714b0e60 centos "/bin/sh -c 'while t…" 51 minutes ago Up 51 minutes jovial_zhukovsky
lemu-devops@lemudevops:~$ docker exec -it be72714b0e60 /bin/bash
[root@be72714b0e60 /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 12:50 ? 00:00:00 /bin/sh -c while true;do echo hello docker;sleep 1;done
root 3133 0 0 13:43 pts/0 00:00:00 /bin/bash
root 3153 1 0 13:43 ? 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 1
root 3154 3133 0 13:43 pts/0 00:00:00 ps -ef
# 方式二
$ docker attach 容器id
# 测试
$ docker attach be72714b0e60
正在执行当前的代码..
# docker exec # 进入容器开始一个新的终端,可以在里面操作(常用)
# docker attach # 进入容器正在执行的终端,不会启动新的进程!
$ docker cp 容器id:容器内路径 目的主机路径
# 测试
# 查看当前主机目录的文件
root@lemudevops:/home/lemu-devops/docker_test# ls
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
24f8d1099201 centos "/bin/bash" 5 seconds ago Up 4 seconds
```$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
24f8d1099201 centos "/bin/bash" 5 seconds ago Up 4 seconds
35 [OK]
# 进入容器内部
$ docker exec -it 24f8d1099201 /bin/bash
[root@24f8d1099201 /]# cd /home/
# 在容器内部创建一个文件
[root@24f8d1099201 home]# touch kizai.py
[root@24f8d1099201 home]# exit
exit
# 将文件拷贝到主机上
docker cp 24f8d1099201:/home/kizai.py /home/lemu-devops/docker_test
root@lemudevops:/home/lemu-devops/docker_test# ls
kizai.py
# 后面使用数据卷的技术才能把数据打通
命令 | 解释 | 中文解释 |
---|---|---|
attach | Attach to a running container | # 当前she11下attach连接指定运行镜像 |
build | Build an image from a Dockerfile | # 通过Dockerfile定制镜像 |
commit | Create a new image from a container changes | # 提交当前容器为新的镜像 |
cp | Copy files/folders from the containers filesystem to the host path | # 从容器中拷贝指定文件或者目 录到宿主机中 |
create | Create a new container | # 创建一个新的容器,同run,但不启动容器 |
diff | Inspect changes on a container’s filesystem | # 查看docker容器变化 |
events | Get real time events from the server | # 从docker服务获取容器实时事件 |
exec | Run a command in.an existing container | # 在已存在的容器上运行命令 |
export | Stream the contents of a container as a tar archive | # 导出容器的内容流作为一个tar归档文件[对应 |
import | history Show the history of an image | # 展示一个镜像形成历史 |
images | List images | # 列出系统当前镜像 |
import | Create a new filesystem image from the contents of a tarbal1 | # 从tar包中的内容创建一个新的文件系统映像[对应export] |
info | Display system-wide information | # 显示系统相关信息 |
inspect | Return low-level information on a container | # 查看容器详细信息 |
kill | Kill a running container | # kill指定docker容器 |
load | Load an image from a tar archive | # 从一个tar包中加载一个镜像[对应save] |
login | Register or Login to the docker registry server | # 注册或者登陆一个docker源服务器 |
logout | Log out from a Docker registry server | # 从当前Docker registry退出 |
logs | Fetch the logs of a container | # 输出当前容器日志信息 |
port | Lookup the public-facing port which is NAT-ed to PRIVATE_PORT | # 查看映射端口对应的容器内部源端 |
pause | Pause all processes within a container | # 暂停容器 |
ps | List containers | # 列出容器列表 |
pull | Pull an image or a repository from the docker registry server | # 从docker镜像源服务器拉取指定镜像或者库镜像 |
push | Push an image or a repository to the docker registry server | # 推送指定镜像或者库镜像至docker源服务器 |
restart | Restart a running container | # 重启运行的容器 |
rm | Remove one or more containers | # 移除一个或者多个容器 |
rmi | Remove one or more images | # 移除一个或多个镜像[无容器使用该镜像才可删除,否则需删除相关容器才可继续或 -f 强制删除] |
run | Run a command in a.new container | # 创建一个新的容器并运行一个命令 |
save | Save an image to a tar archive | # 保存一个镜像为一个tar包[对应load] |
search | Search for an image on the Docker Hub | # 在docker hub中搜索镜像 |
start | Start a stopped containers | # 启动容器 |
stop | Stop a running containers | # 停止容器 |
tag | Tag an image into a repository | # 拾源中镜像打标签 |
top | Lookup the running processes of a container | # 查看容器中运行的进程信息 |
unpause | Unpause a paused container | # 取消暂停容器 |
version | Show the docker version information | # 查看docker版本号 |
wait | Block until a container stops,then print its exit code | # 截取容器停止时的退出状态值 |
UnionFS(联合文件系统)
Dockerk镜像加载原理
平时我们安装进虚拟机的CentOS都是好几个G,为什么Docker这里才200M?
下载redis镜像看看
docker image inspect
命令$ docker image inspect redis:latest
.....
"RootFS": {
"Type": "layers",
"Layers": [
"sha256:ad6562704f3759fb50f0d3de5f80a38f65a85e709b77fd24491253990f30b6be",
"sha256:49cba0f0997b2bb3a24bcfe71c7cbd6e9f6968ef7934e3ad56b0f1f9361b6b91",
"sha256:309498e524b3e2da1f036d00cd5155e0b74cf9e1d964a3636c8ed63ca4a00d43",
"sha256:86efad1273f723462d374c3c3191637ae6598e715312f8f1ec5929c3b70aee35",
"sha256:9a2bd1816e9a1abda14f1acf07ca32ce4d43c52127836704a36d8fd1a1198ff2",
"sha256:a7b30871a925a85530ee4bf40b5b875cc7ab0b452d9d571eb841cf92156083d8"
]
},
.....
理解:
在添加额外的镜像层的同时,镜像始终保持是当前所有镜像的组合,理解这一点非常重要。下图中举了一个简单的例子,每个镜像层包含3个文件,而镜像包含了来自两个镜像层的6个文件。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6LfUIXAp-1655391103197)(https://s2.loli.net/2022/06/11/abmtjKfYWshe4lv.png)]
commit 镜像
$ docker commit 提交容器成为一个新的副本
# 命令跟git原理类似
$ docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像名:[TAG]
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
new_dingbot_msg latest cde233707f86 2 days ago 437MB
dingmsg_service latest 269caf0cc7eb 3 days ago 437MB
redis latest dd8125f93b94 3 days ago 117MB
ubuntu 20.04 20fffa419e3a 5 days ago 72.8MB
mysql latest 65b636d5542b 2 weeks ago 524MB
httpd latest 98f93cd0ec3b 2 weeks ago 144MB
hello-world latest feb5d9fea6a5 8 months ago 13.3kB
centos latest 5d0da3dc9764 8 months ago 231MB
# 启动httpd服务
$ docker run -it -p 8088:80 --name apache-tt -d httpd
d0f5368beceec8596197b734ff6be012b26eee32b3dae20df2a07ef17525e9a1
# 查看启动状态
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d0f5368becee httpd "httpd-foreground" 33 seconds ago Up 31 seconds 0.0.0.0:8088->80/tcp, :::8088->80/tcp apache-tt
$ docker exec -it d0f5368becee /bin/bash
root@d0f5368becee:/usr/local/apache2# ls
bin build cgi-bin conf error htdocs icons include logs modules
root@d0f5368becee:/usr/local/apache2# cd htdocs/
root@d0f5368becee:/usr/local/apache2/htdocs# ls
index.html
root@d0f5368becee:/usr/local/apache2/htdocs# cat index.html
<html><body><h1>It works!</h1></body></html>
# 注意httpd默认是没有安装vim的,需要更新一下源再安装
root@d0f5368becee:/usr/local/apache2/htdocs# apt-get update
....
root@d0f5368becee:/usr/local/apache2/htdocs# apt-get install vim
....
# 修改index.html的内容
root@d0f5368becee:/usr/local/apache2/htdocs# vim index.html
<html><body><h1>httpd run in docker!It works!</h1></body></html>
# 保存退出docker终端
# 查看修改httpd后的内容
$ wget 127.0.0.1:8088
--2022-06-12 18:07:58-- http://127.0.0.1:8088/
Connecting to 127.0.0.1:8088... connected.
HTTP request sent, awaiting response... 200 OK
Length: 65 [text/html]
Saving to: ‘index.html’
index.html 100%[=======================================================================================================================================================================================>] 65 --.-KB/s in 0s
2022-06-12 18:07:58 (17.0 MB/s) - ‘index.html’ saved [65/65]
$ cat index.html
<html><body><h1>httpd run in docker!It works!</h1></body></html>
# 提交修改后的镜像
$ docker commit -a="kizai" -m="change the content of a index.html" d0f5368becee httpd-test:0.0.1
sha256:5ef56fce7bbbf2ad631214cc6e78ae497ce466b8fac50ec1b0b1550535f96f5e
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
httpd-test 0.0.1 5ef56fce7bbb 25 seconds ago 199MB
$ docker pull httpd
$ docker images httpd
REPOSITORY TAG IMAGE ID CREATED SIZE
httpd latest 98f93cd0ec3b 11 days ago 144MB
$ docker run -it -p 8877:80 --name apache-test -d httpd
986f882220ef2e78874d20e6ea7e6dbd2d62877e2026b1e2bbc489482e3291ae
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
986f882220ef httpd "httpd-foreground" 33 seconds ago Up 32 seconds 0.0.0.0:8877->80/tcp, :::8877->80/tcp apache-test
docker logs apache-test
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 172.17.0.2. Set the 'ServerName' directive globally to suppress this message
[Wed Jun 08 15:09:22.925340 2022] [mpm_event:notice] [pid 1:tid 139932608978240] AH00489: Apache/2.4.53 (Unix) configured -- resuming normal operations
[Wed Jun 08 15:09:22.925448 2022] [core:notice] [pid 1:tid 139932608978240] AH00094: Command line: 'httpd -D FOREGROUND'
172.17.0.1 - - [08/Jun/2022:15:10:33 +0000] "GET / HTTP/1.1" 200 45
172.17.0.1 - - [08/Jun/2022:15:10:34 +0000] "GET /favicon.ico HTTP/1.1" 404 196
127.0.0.0:8877
就可以看到docker的httpd服务了。内置命令 | 作用 |
---|---|
FROM | 指明基础镜像的名称和版本。必填项 |
MAINTAINER | 可用于提供作者、版本及其其他信息。可选项 |
RUN | 用于执行后面的指令。当RUN执行完毕后,将产生一个新的文件层。可选项 |
CMD | 指定此镜像启动默认执行的命令。可选项 |
LABEL | 用于在镜像中添加元数据。例如版本号、构建日期等。可选项 |
EXPOSE | 用于指定需要暴露的网络端口号。可选项 |
ENV | 用于在镜像添加环境变量。可选项 |
ADD | 向镜像添加新文件或者新目录。可选项 |
COPY | 从主句向镜像复制文件。可选项 |
ENTRYPOINT | 在镜像中设定默认执行的二进制程序。可选项 |
VOLUME | 向镜像中挂载一个卷组。可选项 |
USER | 在镜像构建过程中,生成或者切换到另外一个用户。可选项 |
WORKDIR | 设定此镜像后续操作默认的工作目录。可选项 |
ONBUILD | 配置构建触发指令集。可选项 |
$ cd ~
$ mkdir -p Docker_Project/Query_DingBot/app
# 此时的文件结构如下:
.
├── app
│ ├── config.ini
│ └── lemumsg_run.py
└── Dockerfile
1 directory, 3 files
Query_DingBot
创建Dockerfile文件$ vim Dockerfile
# 添加以下内容
# 基于哪个镜像
FROM ubuntu:20.04
# 维护者信息
LABEL maintainer="[email protected]"
# 设置工作空间,后续命令会在此目录下执行
WORKDIR /app
# 添加文件到容器中
ADD . /app/
# 安装运行环境
RUN apt-get update && apt-get install -y python3 && apt-get install -y python3-pip && pip install DingtalkChatbot==1.5.3 && pip install flask==2.1.2 && pip install flask_json==0.3.4
# 开放6655端口
EXPOSE 6655
# 配置容器启动后执行的命令
ENTRYPOINT ["python3"]
CMD ["app/lemumsg_run.py"]
FROM
指令指定初始镜像。Dockerfile
一定要有FROM
指令作为第一个非注释指令。shell
命令,是将要在镜像里执行的。$ docker build -t dingmsg_service .
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
dingmsg_service latest cd4570fa31e6 2 minutes ago 437MB
dingmsg_service
镜像$ docker run -it --restart=always -p 6655:6655 --name dingbot-test -d dingmsg_service
# Docker 容器的重启策略如下:
--restart具体参数值详细信息:
no // 默认策略,容器退出时不重启容器;
on-failure // 在容器非正常退出时(退出状态非0)才重新启动容器;
on-failure:3 // 在容器非正常退出时重启容器,最多重启3次;
always // 无论退出状态是如何,都重启容器;
unless-stopped // 在容器退出时总是重启容器,但是不考虑在 Docker 守护进程启动时就已经停止了的容器
$ docker logs dingbot-test
* Serving Flask app 'lemumsg_run' (lazy loading)
* Environment: production
WARNING: This is a development server. Do not use it in a production deployment.
Use a production WSGI server instead.
* Debug mode: on
* Running on all addresses (0.0.0.0)
WARNING: This is a development server. Do not use it in a production deployment.
* Running on http://127.0.0.1:6655
* Running on http://172.17.0.2:6655 (Press CTRL+C to quit)
* Restarting with stat
* Debugger is active!
* Debugger PIN: 915-478-794
10.0.0.1 - - [09/Jun/2022 09:35:07] "POST /api/v1/text HTTP/1.0" 200 -
INFO:werkzeug:10.0.0.1 - - [09/Jun/2022 09:35:07] "POST /api/v1/text HTTP/1.0" 200 -
10.0.0.1 - - [09/Jun/2022 09:35:28] "POST /api/v1/text HTTP/1.0" 200 -
INFO:werkzeug:10.0.0.1 - - [09/Jun/2022 09:35:28] "POST /api/v1/text HTTP/1.0" 200 -
Docker的日志一般保存在/var/lib/docker/.
每个容器都有一个特定于其 ID 的日志(完整 ID,而不是通常显示的缩短的 ID),您可以像这样访问它:
/var/lib/docker/containers/ID/ID-json.log
$ docker exec -i -t dingbot-test /bin/bash
root@7e61c738bcf4:/app# ls
Dockerfile app
root@7e61c738bcf4:/app# cd app/
root@7e61c738bcf4:/app/app# ls
config.ini lemumsg_run.py
进到dingbot-test进程服务终端,其实可以发现里面的文件架构跟创建镜像时的是一样的。
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
7e61c738bcf4 dingmsg_service "python3 app/lemumsg…" 7 hours ago Up 6 hours 0.0.0.0:6655->6655/tcp, :::6655->6655/tcp dingbot-test
986f882220ef httpd "httpd-foreground" 25 hours ago Up About an hour 0.0.0.0:8877->80/tcp, :::8877->80/tcp apache-test
# 创建文件夹来保存镜像文件
$ mkdir -p ~/Docker_Project/images
# 导出镜像
$ docker export 7e61c738bcf4 > ~/Docker_Project/images/dingbot_msg_01.tar
# 导出成功不会有提示,可以查看该文件夹是否tar的镜像包
$ ls
dingbot_msg_01.tar
上面命令执行后,可以看到文件已经保存到当前的~/Docker_Project/images
终端目录下。
3. 使用 docker import
命令则可将这个镜像文件导入进来。
$ docker import - new_dingbot_msg < dingbot_msg_01.tar
sha256:cde233707f864c1578cb521d4ba88eee38f185b6435cc3478e49ec8e7aa07705
docker images ls
命令可以看到镜像确实已经导入进来了。$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
new_dingbot_msg latest cde233707f86 59 seconds ago 437MB
dingmsg_service latest 269caf0cc7eb 7 hours ago 437MB
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
new_dingbot_msg latest cde233707f86 15 minutes ago 437MB
dingmsg_service latest 269caf0cc7eb 7 hours ago 437MB
ubuntu 20.04 20fffa419e3a 2 days ago 72.8MB
httpd latest 98f93cd0ec3b 12 days ago 144MB
hello-world latest feb5d9fea6a5 8 months ago 13.3kB
docker save
命令根据 ID 将镜像保存成一个文件。$ docker save 269caf0cc7eb > dingbot_msg_02.tar
docker load
命令则可将这个镜像文件载入进来。docker load < dingbot_msg_02.tar
特别注意:两种方法不可混用。
import
导入 save
产生的文件,虽然导入不提示错误,但是启动容器时会提示失败,会出现类似docker: Error response from daemon: Container command not found or does not exist
的错误。docker import
可以为镜像指定新名称docker load
不能对载入的镜像重命名docker export
不支持docker save
支持docker-compose.yml
编排的多个镜像组合,但我们要部署的客户服务器并不能连外网。这时就可以使用 docker save 将用到的镜像打个包,然后拷贝到客户服务器上使用 docker load 载入。数据卷是一个可供一个或多个容器使用的特殊目录,它绕过UFS
(联合文件系统[Union File System],把其他文件系统联合到一个联合挂载点的文件系统服务),可以提供很多有用的特性:
docker的理念回顾
数据?如果数据都在容器中,那么我们容器删除,数据就会丢失!需求:数据可以持久化
MySQL,容器删了,删库跑路!需求:MySQL数据可以存储在本地!
容器之间可以有一个数据共享的技术!Docker容器中产生的数据,同步到本地!
这就是卷技术!目录的挂载,将我们容器内的目录,挂载到Liux上面!
$ docker run -it -v 主机目录:容器目录 -p
# 在本机创建一个映射文件夹
$ mkdir -p /home/lemu-devops/Docker_Project/share
# 运行并挂载
$ docker run -it -v /home/lemu-devops/Docker_Project/share/centos:/home centos /bin/bash
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
b7d2b3ee3d32 centos "/bin/bash" About a minute ago Up About a minute thirsty_napier
# 启动起来之后可以通过docker inspect查看容器的数据
$ docker inspect b7d2b3ee3d32
...
"Mounts": [
{
"Type": "bind",
"Source": "/home/lemu-devops/Docker_Project/share/centos",
"Destination": "/home",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
],
...
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Cn9yyN7x-1655391103199)(https://s2.loli.net/2022/06/12/1gthMQw3YodbuOm.png)]
好处:以后修改只需要在本都修改即可,容器内会自动同步。
# 获取镜像
$ docker pull mysql:5.7
# 运行容器,需要做数据挂载! 安装启动mysql,需要配置密码
# 官方测试配置:$ docker run --name some-mysql -v /my/custom:/etc/mysql/conf.d -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:tag
# 启动mysql
-d 后台运行
-p 端口映射
-v 卷挂载
-e 环境配置
$ docker run -d -p 3310:3306 -v /home/lemu-devops/Docker_Project/share/mysql/conf:/etc/mysql/conf.d -v /home/lemu-devops/Docker_Project/share/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
# 启动成功之后使用,mysql插件来测试一下
# mysql插件链接到服务器的3310 --- 3310和容器内的3306映射,这个时候就可以连上了
# 匿名挂载
-v 容器内路径
$ docker run -d -P --name httpd02 -v /usr/local/apache2 httpd
# 查看所有volume 的情况
$ docker volume ls
DRIVER VOLUME NAME
local 3baac0bfac36eca270cb3935e83f95db4140e3a2c85bf00d848ec12817b0f7c4 (匿名卷)
local 79de0d956d465f57a3731395041ff2c566d15c2b8a837c2f992c1d15f1cdaef0 (匿名卷)
# 这里发现,这种就是匿名挂载,我们在-v 只写了容器内的路径,没有写容器外的路径
# 具名挂载
$ docker run -d -P --name htppd03 -v juming-apache:/usr/local/apache2 httpd
b484b2f53946b46ce3320ef070af0fa9f935e2da5c13f571a46e58a35752d603
$ docker volume ls
DRIVER VOLUME NAME
local 3baac0bfac36eca270cb3935e83f95db4140e3a2c85bf00d848ec12817b0f7c4
local 79de0d956d465f57a3731395041ff2c566d15c2b8a837c2f992c1d15f1cdaef0
local juming-apache
# 通过 -v 卷名:容器内路径
# 查看一下这个卷
$ docker volume inspect juming-apache
[
{
"CreatedAt": "2022-06-12T23:00:39+08:00",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/juming-apache/_data",
"Name": "juming-apache",
"Options": null,
"Scope": "local"
}
]
$ cd /var/lib/docker/
root@lemudevops:/var/lib/docker# ls
buildkit containers image network overlay2 plugins runtimes swarm tmp trust volumes
root@lemudevops:/var/lib/docker# cd volumes/
root@lemudevops:/var/lib/docker/volumes# ls
3baac0bfac36eca270cb3935e83f95db4140e3a2c85bf00d848ec12817b0f7c4 backingFsBlockDev metadata.db
79de0d956d465f57a3731395041ff2c566d15c2b8a837c2f992c1d15f1cdaef0 juming-apache
root@lemudevops:/var/lib/docker/volumes# cd juming-apache/
root@lemudevops:/var/lib/docker/volumes/juming-apache# ls
_data
root@lemudevops:/var/lib/docker/volumes/juming-apache# cd _data/
root@lemudevops:/var/lib/docker/volumes/juming-apache/_data# ls
bin build cgi-bin conf error htdocs icons include logs modules
/var/lib/docker/volumes/xxx/_data
路径下具名挂载
。# 如何确定是具名挂载还是匿名挂载,还是指定路径挂载
-v 容器内路径 # 匿名挂载
-v 卷名:容器内路径 # 具名挂载
-v /宿主机路径:/容器内路径 # 指定路径挂载
ro readonly # 只读
rw readwrite # 可读可写
# 一旦设置了容器权限,容器对我们挂载出来的内容就有限定了
$ docker run -d -P --name htppd04 -v juming-apache:/usr/local/apache2:ro httpd
$ docker run -d -P --name htppd04 -v juming-apache:/usr/local/apache2:rw httpd
# ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作的!!!
# 创建一个dockerfile文件,名字可以随机,建议使用Dockerfile
# 文件内容指令(大写) 参数
$ mkdri -p /home/lemu-devops/Docker_Project/docker-test-volume
$ cd Docker_Project/docker-test-volume/
$ vim dockerfile1
# 写入dockerfile 命令,这里的每个命令都是镜像的一层
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "----end----"
CMD /bin/bash
# 保存退出
# 构建镜像
$ docker build -f dockerfile1 -t kizai/centos .
# 启动3个容器,通过自己写的镜像启动
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4SDSL7D6-1655391103200)(https://s2.loli.net/2022/06/13/AULRn3jqYSD9crv.png)]
$ docker run -it b0248e10a05e /bin/bash
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OY3yT1Ek-1655391103201)(https://s2.loli.net/2022/06/13/lmyktKOe92VG8pu.png)]
假设构建镜像时没有挂载卷,要手动镜像挂载 -v 卷名:容器内路径
启动第docker02数据卷继承于docker01,在这里docker01就叫做数据卷容器。
$ docker run -it --name docker02 --volumes-from docker01 b0248e10a05e
# 启动mysql01
$ docker run -d -p 3310:3306 -v /etc/mysql/conf.d -v /var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 --name mysql01 mysql:5.7
# 启动mysql02
$ docker run -d -p 3310:3306 -e MYSQL_ROOT_PASSWORD=123456 --name mysql02 --volumes-from mysql01 mysql:5.7
# 这个时候就可以实现两个容器数据同步
容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。
但是一旦持久化到本地,这个时候,本地是数据是不会删除的。
dockerfile 是用来构建docker镜像的文件,命令参数脚本!
构建步骤:
1. 编写一个dockerfile文件
2. docker build
构建成为一个镜像
3. docker run
运行镜像
4. docker push
发布到(DockerHub、私有DockerHub服务)
查看一下官方是怎么做到?
很多官方的镜像都是基础包,很多功能没有,我们通常会自己搭建自己的镜像。
#
表示注释dockerfile是面向开发的,以后要发布项目做镜像,就需要编写dockerfile文件,这个文件比较简单!
Docker镜像逐渐成为企业交互的标准!
FROM # 基础镜像
MAINTAINER # 镜像谁写的,姓名+邮箱
RUN # 镜像构建的时候需要运行的命令
ADD # 步骤:centos镜像,centos压缩包!添加内容
WORKDIR # 镜像的工作目录
VOLUME # 挂载的目录
EXPOSE # 暴露端口配置
CMD # 指定这个容器启动的时候运行的命令,只有最后一个会生效,可以被替代
ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD # 当构建一个被继承 DockerFile 这个时候就会运行 ONBUILD 的指令。触发指令
COPY # 类似ADD,将我们文件拷贝到镜像中
ENV # 构建的时候设置环境变量
Docker Hub中99%镜像都是从这个基础镜像过来的FROM scratch
,然后配置需要的软件和配置来进行构建。
# 1.编写dockerfile文件
$ vim dockerfile-centos
FROM centos:latest
MAINTAINER kizai
ENV MYPATH /usr/local
WORKDIR $MYPATH
EXPOSE 80
CMD echo $MYPATH
CMD echo "-----end-----"
CMD /bin/bash
# 2.通过这个文件构建镜像
# 命令: docker build -f dockerfile文件路径 -t 镜像名:[tag]
Successfully built 602aa38c9a1a
Successfully tagged mycentos:0.1
# 测试运行
CMD # 指定这个容器启动的时候运行的命令,只有最后一个会生效,可以被替代
ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令
测试CDM
# 编写dockerfile文件
$ vim dockerfile-cmd-test
FROM centos
CMD ["ls","-a"]
# 构建镜像
$ docker build -f dockerfile-cmd-test -t cmdtest .
# run运行,发现我们的ls -a命令生效了
$ docker run 933abee7baa1
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
# 想追加一个命令-l ls -al
$ docker run 933abee7baa1 -l
docker: Error response from daemon: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: exec: "-l": executable file not found in $PATH: unknown.
# cmd的命令下 -l 替换了CMD ["ls","-a"] 命令,-l 不是命令所以报错!
测试ENTRYPOINT
$ vim dockerfile-cmd-entrypoint
FROM centos
CMD ["ls","-a"]
# 构建镜像
$ docker build -f dockerfile-cmd-entrypoint -t entrypoint-test .
Sending build context to Docker daemon 4.608kB
Step 1/2 : FROM centos
---> 5d0da3dc9764
Step 2/2 : ENTRYPOINT ["ls","-a"]
---> Running in 6ee8bc2055a2
Removing intermediate container 6ee8bc2055a2
---> e2414dc3a0c9
Successfully built e2414dc3a0c9
Successfully tagged entrypoint-test:latest
# 查看镜像
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
entrypoint-test latest e2414dc3a0c9 9 seconds ago 231MB
cmdtest latest 933abee7baa1 11 minutes ago 231MB
mycentos 0.1 0f0d9b408fbd About an hour ago 231MB
kizai/centos latest b0248e10a05e 9 hours ago 231MB
httpd-test 0.0.1 5ef56fce7bbb 29 hours ago 199MB
new_dingbot_msg latest cde233707f86 3 days ago 437MB
dingmsg_service latest 269caf0cc7eb 4 days ago 437MB
redis latest dd8125f93b94 4 days ago 117MB
ubuntu 20.04 20fffa419e3a 6 days ago 72.8MB
mysql 5.7 2a0961b7de03 2 weeks ago 462MB
mysql latest 65b636d5542b 2 weeks ago 524MB
httpd latest 98f93cd0ec3b 2 weeks ago 144MB
hello-world latest feb5d9fea6a5 8 months ago 13.3kB
centos latest 5d0da3dc9764 9 months ago 231MB
# 运行镜像
$ docker run e2414dc3a0c9
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
# 追加命令运行镜像,是直接拼接我们的 ENTRYOINT 命令后面
$ docker run e2414dc3a0c9 -l
total 56
drwxr-xr-x 1 root root 4096 Jun 13 15:12 .
drwxr-xr-x 1 root root 4096 Jun 13 15:12 ..
-rwxr-xr-x 1 root root 0 Jun 13 15:12 .dockerenv
lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x 5 root root 340 Jun 13 15:12 dev
drwxr-xr-x 1 root root 4096 Jun 13 15:12 etc
drwxr-xr-x 2 root root 4096 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
drwx------ 2 root root 4096 Sep 15 2021 lost+found
drwxr-xr-x 2 root root 4096 Nov 3 2020 media
drwxr-xr-x 2 root root 4096 Nov 3 2020 mnt
drwxr-xr-x 2 root root 4096 Nov 3 2020 opt
dr-xr-xr-x 643 root root 0 Jun 13 15:12 proc
dr-xr-x--- 2 root root 4096 Sep 15 2021 root
drwxr-xr-x 11 root root 4096 Sep 15 2021 run
lrwxrwxrwx 1 root root 8 Nov 3 2020 sbin -> usr/sbin
drwxr-xr-x 2 root root 4096 Nov 3 2020 srv
dr-xr-xr-x 13 root root 0 Jun 13 15:12 sys
drwxrwxrwt 7 root root 4096 Sep 15 2021 tmp
drwxr-xr-x 12 root root 4096 Sep 15 2021 usr
drwxr-xr-x 20 root root 4096 Sep 15 2021 var
Dockerfile中很多命令都十分相似,我们需要了解他们的区别,最后的方法就是做对比测试。
清空所有的容器和镜像
# 删除所有容器
$ docker rm -f $(docker ps -aq)
# 删除所有镜像
$ docker image rm -f $(docker image -aq)
en
仅仅就是 ethernet
的意思,就像eth
用于对应 eth0
一样。 p
是以太网卡的总线编号,s
是插槽编号。 所以enp1s0
告诉我们很多我们正在使用的硬件的信息。 # BROADCAST 该接口支持广播
# MULTICAST 该接口支持多播
# UP 网络接口已启用
# LOWER_UP 网络电缆已插入,设备已连接至网络
# DOWN 网络接口已关闭
# UNKNOWN 暂不知道网络接口的状态
mtu 1500 最大传输单位(数据包大小)为1,500字节
qdisc pfifo_fast 用于数据包排队
state UP 网络接口已启用
group default 接口组
qlen 1000 传输队列长度
link/ether d8:bb:c1:17:ae:68 接口的 MAC(硬件)地址
brd ff:ff:ff:ff:ff:ff 广播地址
inet 10.0.0.131/23 IPv4 地址
brd 10.0.1.255 广播地址
scope global 全局有效
dynamic enp1s0 地址是动态分配的
valid_lft 75239sec IPv4 地址的有效使用期限
preferred_lft 75239sec IPv4 地址的首选生存期
inet6 fd5c:a4db:ced8:0:681:9546:4ec:c846/64 IPv6 地址
scope link 仅在此设备上有效
valid_lft forever IPv6 地址的有效使用期限
preferred_lft forever IPv6 地址的首选生存期
# 运行命令:
$ docker run -i -t -d --name dockername --restart=always imageId
# --restart的参数
no - container #不重启
on-failure - container # 退出状态非0时重启
on-failure:n # 在容器非正常退出时重启容器,并且指定重启次数。n 为正整数。如果不指定次数,则会一直重启。
always # 始终重启
unless-stopped # 在容器退出时总是重启容器,但是 Docker 守护进程启动之前就已经停止运行的容器不算在内。
--restart=always
如何补救
update
命令$ docker container update --restart=always 容器id
# vim /var/lib/docker/containers/容器ID/hostconfig.json,找到关键字 RestartPolicy,将 no 改为 always修改前:
"RestartPolicy:{"Name":"no","MaximumRetryCount":0}
# 修改后:
"RestartPolicy:{"Name":"always","MaximumRetryCount":0}
# 重启容器即可。如果无法修改容器的配置,可先将容器停止,修改配置文件后再启动。
AUFS 是联合文件系统,意味着它在主机上使用多层目录存储,每一个目录在 AUFS 中都叫作分支,而在 Docker 中则称之为层(layer),但最终呈现给用户的则是一个普通单层的
文件系统,我们把多层以单一层的方式呈现出来的过程叫作联合挂载。
如上图,每一个镜像层和容器层都是 /var/lib/docker 下的一个子目录,镜像层和容器层都在 aufs/diff 目录下,每一层的目录名称是镜像或容器的 ID 值,联合挂载点在 aufs/mnt 目录下,mnt 目录是真正的容器工作目录。
下面我们针对 aufs 文件夹下的各目录结构,在创建容器前后的变化做详细讲述。
在LINUX系统中有一个重要的概念:一切都是文件。 其实这是UNIX哲学的一个体现,而Linux是重写UNIX而来,所以这个概念也就传承了下来。在UNIX系统中,把一切资源都看作是文件,包括硬件设备。UNIX系统把每个硬件都看成是一个文件,通常称为设备文件,这样用户就可以用读写文件的方式实现对硬件的访问。这样带来优势也是显而易见的:
这一关键设计原则提供了一个统一的范式,用于访问各种输入输出资源:文档、目录、磁盘驱动器、CD-ROM、调制解调器、键盘、打印机、显示器、终端,甚至是一些进程间通信和网络通信。所有这些资源拥有一个通用的抽象,UNIX 之父将其称为“文件”。因为每个“文件”都通过相同的 API 暴露出来,所以你可以使用同一组基本命令来读取和写入磁盘、键盘、文档或网络设备。
Linux文件系统的层次
由上图可以知道,整个文件系统体系分为了三个层面,用户层,内核层,硬件层,用户层是通过API通过系统调用调用的方式访问虚拟文件系统。在内核层,我们可以看到虚拟文件系统下连接了各种类型的文件系统,其是对不同的文件系统的抽象,为上层应用提供了统一的 API 接口;上图内核层还有一层是各个文件系统之下的一层,这一层的作用是隐藏了不同硬件设备之间的细节,为内核提供了统一的 IO 操作接口。下面我们对整个文件系统从下到上对各个层的作用进行一个阐述:
Device Driver(硬盘驱动):常见的硬盘类型有PATA,SATA,在Linux中,对于硬盘提供的驱动模块一般都存放在内核目录树drivers/ata中,而对于一般通用的硬盘驱动,可能会直接被编译到内核中。
通用块设备层(General Block Device Layer):不同的硬盘,会提供不同的 IO 接口,对于内核来讲,这种杂乱的接口是不利于管理的,因此就把这些接口进行了抽象,形成了一个统一的对外接口,这样就不管你是什么存储设备,操作他们的IO接口并没有什么区别。
文件系统层:目前大多数Linux使用的是ex4,与此同时,btrfs也呼之欲出
虚拟文件系统:正如不同的存储设备具有不同的 IO 接口,那么不同的文件系统也具有不用的 API,内核想实现的是不管是什么文件系统,都采用的是相同的 API 进行操作,所以 VFS 就做了一个抽象,提供了统一的 API 接口,使之可以对不同的文件系统采用同样的操作。
Linux广义文件分类
# 使用以下命令查看
$ journalctl -u docker.service
三个网络
# 问题:docker 是如何处理处理容器网络访问的?
$ docker run -d -P --name centos-test centos
# 查看容器的内部网络地址: ip addr