Docker学习指引
目录Docker概述虚拟机技术容器化技术基本组成镜像容器仓库开始Docker安装通信模型Docker为什么比VM快Docker常用命令帮助命令镜像命令容器命令常用其他命令常见部署部署Nginx部署Tomcat部署ES + Kibana可视化工具portainerDocker镜像UnionFS联合文件系统Docker镜像加速的原理分层原理commit镜像容器数据卷概念使用数据卷数据卷容器Mac上进入
目录
Docker概述
- 发布一个项目,能不能带上环境安装打包
# 发布一个安卓app
java --> apk --> 发布(应用商店) --> 张三使用apk --> 安装即可用
# 同理,发布一个jar包,利用docker
java --> jar(环境) -->打包项目带上环境(镜像) --> (Docker仓库: 类比商店) --> 下载我们发布的镜像 --> 直接运行即可
- 隔离:Docker核心思想,打包装箱,每个箱子是互相隔离的
- 虚拟机:在window中装一个VMware,通过这个软件,我们可以虚拟化出来一台或者多台电脑,硬件也虚拟出来,比较笨重,属于虚拟化技术
- Docker容器技术也是一种虚拟化技术
VM: Linux centos原生镜像(相当与一台电脑),互相隔离,需要开启多个虚拟机,大小几个G
Docker: 隔离,镜像(最核心的环境 4M),十分小巧,运行镜像就可以了,几个M
Docker是基于Golang开发的
文档地址:https://docs.docker.com/
仓库地址:https://hub.docker.com/
虚拟机技术
- 资源占用十分多
- 冗余步骤多
- 启动很慢
- 虚拟化一些硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件
容器化技术
- 容器化技术不是模拟一个完整的操作系统
- 容器内的应用直接运行在宿主机的内核中,容器是没有自己的内核的,也没有虚拟我们的硬件,所以轻便了
- 每个容器内是相互隔离的,每个容器内都有一个属于自己的文件系统,互不影响
基本组成
镜像
-
image好比一个模版,可以通过这个模版来创建容器服务
-
tomcat镜像 --> run --> tomcat 容器
-
通过这个镜像可以创建多个容器,最终服务运行或者项目运行就是在容器中
容器
-
container:Docker容器技术,独立运行一个或者一个组应用,通过镜像来创建
-
启动、停止、删除、基本命令
-
目前就可以把这个容器理解为一个简易的Linux系统
仓库
-
仓库是存放镜像的地方
-
仓库分为共有仓库和私有仓库
-
Docker Hub默认是国外的
开始
Docker安装
-
官方安装文档
https://docs.docker.com/engine/install/centos/
-
测试
hello-world
jiangsiyong: ~ $ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
93288797bd35: Pull complete
Digest: sha256:393b81f0ea5a98a7335d7ad44be96fe76ca8eb2eaa76950eb8c989ebf2b78ec0
Status: Downloaded newer image for hello-world:latest
Hello from Docker!
This message shows that your installation appears to be working correctly.
- 查看下载的镜像
jiangsiyong: ~ $ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest 18e5af790473 37 hours ago 9.14kB
centos latest 300e315adb2f 9 months ago 209MB
docker run hello-world
流程- 开始,Docker会在本机寻找镜像
- 判断本机是否有这个镜像
- 如果本机有这个镜像,就直接使用这个镜像运行
- 否则,去
Docker Hub
下载 - 判断
Docker Hub
是否有这个镜像 - 如果有,下载这个镜像到本地,转向流程3
- 否则,返回找不到镜像的错误
通信模型
Docker是一个Client-Server结构的系统,Docker的守护进程运行在本机上,客户端通过Socker来访问Docker
Docker Server接收到Client发来的指令,就会执行这个指令
Docker为什么比VM快
- Docker有着比虚拟机更少的抽象层
- Docker利用的是宿主机的内核,VM需要的是Guest OS
- Docker不需要像虚拟机一样重新加载一个操作系统的内核,避免引导
Docker常用命令
帮助命令
docker version #显示docker的版本信息
docker info #显示docker更加详细的系统信息,包括镜像和容器的数量
docker 命令 --help #帮助命令
官方命令文档:https://docs.docker.com/reference/
镜像命令
-
查看所有本地主机的镜像
docker images [OPTIONS] [REPOSITORY[:TAG]]
jiangsiyong: ~ $ docker images REPOSITORY TAG IMAGE ID CREATED SIZE hello-world latest 18e5af790473 38 hours ago 9.14kB centos latest 300e315adb2f 9 months ago 209MB #解释 REPOSITORY 镜像的仓库源 TAG 镜像的标签 IMAGE ID 镜像的ID CREATED 镜像的创建时间 SIZE 镜像的大小 #可选项 --all, -a 列出所有的镜像 --quiet, -q 只显示镜像的id
-
搜索镜像
docker search [OPTIONS] TERM
jiangsiyong: ~ $ docker search mysql NAME DESCRIPTION STARS OFFICIAL AUTOMATED mysql MySQL is a widely used, open-source relation… 11470 [OK] mariadb MariaDB Server is a high performing open sou… 4354 [OK] mysql/mysql-server Optimized MySQL Server Docker images. Create… 848 [OK] #可选项 --filter=STARS=3000 搜出星级在3000以上的
-
拉取下载镜像
docker pull [OPTIONS] NAME[:TAG|@DIGEST]
jiangsiyong: ~ $ docker pull redis Using default tag: latest #如果不写,默认是最新的 latest: Pulling from library/redis d10c227306ce: Pull complete #分层下载,docker image的核心,联合文件系统 71f6c833430f: Pull complete f6169272c13d: Pull complete 17db4d790ed8: Pull complete c5b59ebbf80e: Pull complete 177c4d24fee3: Pull complete Digest: sha256:e595e79c05c7690f50ef0136acc9d932d65d8b2ce7915d26a68ca3fb41a7db61 Status: Downloaded newer image for redis:latest docker.io/library/redis:latest #真实地址
-
删除镜像
docker rmi [OPTIONS] IMAGE [IMAGE...]
jiangsiyong: ~ $ docker rmi redis #删除指定的镜像 Untagged: redis:latest Untagged: redis@sha256:e595e79c05c7690f50ef0136acc9d932d65d8b2ce7915d26a68ca3fb41a7db61 Deleted: sha256:33945ca6b5bfb35714f54f172737353a3e493c0866c238eb5e9034bdfe3ff798 Deleted: sha256:d11fdd6b15b07a0a1374773038f4f95881cde45357b8f028b63f147152f84821 Deleted: sha256:4ed432f18c5944c2c8eaa846424cdcbecf77ca65a49b9c27c2407c14c45dc24f Deleted: sha256:fe4801e23a4ce9410c27576d7432e6e0d277593c71461f82cad1458f26fb8527 Deleted: sha256:a339fc4111fd6563276f4f8b994062480416c25f2beb5c01281942ad94b00184 Deleted: sha256:a2bbab4dc2e346ff93626bd68c14d2f182a9d719521a6987c0f8b3b64c9b9d43 Deleted: sha256:5f140fe6ea259f8caec3cb6a4f230fe761c8efa223579bf3c5f9af9e5883e986
容器命令
我们有了镜像,才可以创建容器
-
新建容器并启动
docker run [OPTIONS] IMAGE [COMMAND] [ARG...]
#参数说明 --name="Name" 容器名字 tomcat01 tomcat02用来区分容器 -d 后台方式运行 -it 使用交互方式运行,进入容器查看内容 -p 指定容器端口 -p 8080:8080 -p ip:主机端口:容器端口 -p 主机端口:容器端口(常用) -p 容器端口 -P 指定随机端口 #测试 #启动并进入容器 jiangsiyong: ~ $ docker run -it centos /bin/bash [root@4d5a31acfaa7 /]# ls #进入容器内部 bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var [root@4d5a31acfaa7 /]# exit #从容器中退出主机 exit
-
列出当前正在运行的容器
docker ps [OPTIONS]
jiangsiyong: ~ $ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 4d5a31acfaa7 centos "/bin/bash" 3 minutes ago Exited (0) About a minute ago dreamy_leakey 578f57807749 hello-world "/hello" 23 hours ago Exited (0) 23 hours ago vibrant_cartwright #参数 --all, -a 显示当前正在运行的容器+带出历史运行过的容器 -n=? 显示最近创建的容器 -q 只列出容器的编号
-
退出容器
exit #直接容器停止并退出 Ctrl + P + Q #容器不停止退出
-
删除容器
docker rm 容器id #删除指定的容器,不能删除正在运行的容器,如果要强制删除,要用rm -rf 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 镜像名 jiangsiyong: ~ $ docker run -d centos #问题docker ps发现centos停止了 #常见问题:docker容器使用后台运行,就必须要有一个前台进程,docker发现没有应用,就会自动停止
-
查看容器的日志
jiangsiyong: ~ $ docker logs --help Usage: docker logs [OPTIONS] CONTAINER Fetch the logs of a container Options: --details Show extra details provided to logs -f, --follow Follow log output --since string Show logs since timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes) -n, --tail string Number of lines to show from the end of the logs (default "all") -t, --timestamps Show timestamps --until string Show logs before a timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes) #显示日志 -tf 显示日志,带上时间戳 --tail number 要显示的日志条数
-
显示容器内部的进程信息
docker top 容器id jiangsiyong: ~ $ docker top d1c UID PID PPID C STIME TTY TIME CMD root 2467 2441 0 14:38 ? 00:00:00 /usr/bin/qemu-x86_64 /bin/bash
-
查看容器的元数据
jiangsiyong: ~ $ docker inspect --help Usage: docker inspect [OPTIONS] NAME|ID [NAME|ID...] Return low-level information on Docker objects Options: -f, --format string Format the output using the given Go template -s, --size Display total file sizes if the type is container --type string Return JSON for specified type jiangsiyong: ~ $ docker inspect d1c [ { "Id": "d1c319b79b76e974fa4644c0cf154a0dd80bd68db012a6ba61cf8334de2fc0e4", "Created": "2021-09-26T14:38:10.65482422Z", "Path": "/bin/bash", "Args": [], "State": { "Status": "running", "Running": true, "Paused": false, "Restarting": false, "OOMKilled": false, "Dead": false, "Pid": 2467, "ExitCode": 0, "Error": "", "StartedAt": "2021-09-26T14:38:10.840967845Z", "FinishedAt": "0001-01-01T00:00:00Z" }, "Image": "sha256:300e315adb2f96afe5f0b2780b87f28ae95231fe3bdd1e16b9ba606307728f55", "ResolvConfPath": "/var/lib/docker/containers/d1c319b79b76e974fa4644c0cf154a0dd80bd68db012a6ba61cf8334de2fc0e4/resolv.conf", "HostnamePath": "/var/lib/docker/containers/d1c319b79b76e974fa4644c0cf154a0dd80bd68db012a6ba61cf8334de2fc0e4/hostname", "HostsPath": "/var/lib/docker/containers/d1c319b79b76e974fa4644c0cf154a0dd80bd68db012a6ba61cf8334de2fc0e4/hosts", "LogPath": "/var/lib/docker/containers/d1c319b79b76e974fa4644c0cf154a0dd80bd68db012a6ba61cf8334de2fc0e4/d1c319b79b76e974fa4644c0cf154a0dd80bd68db012a6ba61cf8334de2fc0e4-json.log", "Name": "/thirsty_kowalevski", "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/7facde6cefe6fb84fe71d61a08ab2b7d7bd16069c0e787e222d708ebd1dd9e02-init/diff:/var/lib/docker/overlay2/20d51d86652fa745c1f32efb2f77682f0a7ae3a0aa4f2d876ac8a85a2a269e98/diff", "MergedDir": "/var/lib/docker/overlay2/7facde6cefe6fb84fe71d61a08ab2b7d7bd16069c0e787e222d708ebd1dd9e02/merged", "UpperDir": "/var/lib/docker/overlay2/7facde6cefe6fb84fe71d61a08ab2b7d7bd16069c0e787e222d708ebd1dd9e02/diff", "WorkDir": "/var/lib/docker/overlay2/7facde6cefe6fb84fe71d61a08ab2b7d7bd16069c0e787e222d708ebd1dd9e02/work" }, "Name": "overlay2" }, "Mounts": [], "Config": { "Hostname": "d1c319b79b76", "Domainname": "", "User": "", "AttachStdin": true, "AttachStdout": true, "AttachStderr": true, "Tty": true, "OpenStdin": true, "StdinOnce": true, "Env": [ "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" ], "Cmd": [ "/bin/bash" ], "Image": "centos", "Volumes": null, "WorkingDir": "", "Entrypoint": null, "OnBuild": null, "Labels": { "org.label-schema.build-date": "20201204", "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": "7d0b3806ffe95fa22f8c1a6950b60fc1eb35f684031d37cc9e1e87c84ddb5728", "HairpinMode": false, "LinkLocalIPv6Address": "", "LinkLocalIPv6PrefixLen": 0, "Ports": {}, "SandboxKey": "/var/run/docker/netns/7d0b3806ffe9", "SecondaryIPAddresses": null, "SecondaryIPv6Addresses": null, "EndpointID": "c17a0ad271ea7b704292a6dd26cc02991543a3ade37dd4fbd0f413ad90dd474e", "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": "6a9b6e6db0fc67a93be97d23f7c086d6aa713a5b521a03e0f992553360109258", "EndpointID": "c17a0ad271ea7b704292a6dd26cc02991543a3ade37dd4fbd0f413ad90dd474e", "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 } } } } ]
-
进入当前正在运行的容器
#通常容器都是使用后台的方式运行的,需要进入容器修改一些配置 docker exec -it 容器id bashshell 进入容器后开启一个新的终端,可以在里面操作 docker attach 容器id 进入容器正在执行的终端,不会启动新的进程
-
从容器拷贝文件到主机上
docker cp 容器id:容器内的路径 目的的主机路径
常见部署
部署Nginx
#1 搜索镜像
#2 下载镜像
docker pull nginx
#3 运行容器 --name 给容器命名 -p 宿主机:容器内端口
docker run -d --name nginx -p 3344:80 nginx
#4 查看容器
docker ps
#5 本机自测
curl localhost:3344
#进入ngnix
jiangsiyong: ~ $ docker exec -it nginx /bin/bash
root@e2fc2bef14b4:/# ls
bin dev docker-entrypoint.sh home media opt root sbin sys usr
boot docker-entrypoint.d etc lib mnt proc run srv tmp var
部署Tomcat
#1 下载镜像
docker pull tomcat
#2 启动运行
docker run -d -p 3355:8080 --name tomcat tomcat
# 测试访问没有问题
# 进入tomcat
jiangsiyong: ~ $ docker exec -it tomcat /bin/bash
root@4ae869212724:/usr/local/tomcat# ls
BUILDING.txt LICENSE README.md RUNNING.txt conf logs temp webapps.dist
CONTRIBUTING.md NOTICE RELEASE-NOTES bin lib native-jni-lib webapps work
root@4ae869212724:/usr/local/tomcat# cp -r webapps.dist/* webapps
部署ES + Kibana
# es 暴露的端口很多
# es 十分耗内存
# es的数据一般需要放到安全目录
# --net somenetwork 网络配置
# 下载启动
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" elasticsearch:7.14.1
# 启动了,很卡: es十分耗内存
docker stats #查看cpu的状态
# 增加内存限制
docker run -d --name elasticsearch -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ES_JAVA_OPTS="-Xms64m -Xmx512m" elasticsearch:7.14.1
可视化工具portainer
Docker图形界面管理工具!提供一个后台面板供我们操作
docker run -d -p 8088:9000 -v /var/run/docker.sock:/var/run/docker.sock --restart=always --name prtainer portainer/portainer
访问测试:http://localhost:8088/
Docker镜像
- 从远程仓库下载
- 拷贝过来
- 通过DockerFile制作
UnionFS联合文件系统
- 下载的时候看到的一层层的就是这个
- 它是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下,联合文件系统是Docker镜像的基础,镜像可以通过分层来进行继承,基于基础镜像,可以制作各种具体的应用的镜像
- 特性:一次同时加载多个文件系统,但从外面看来,只看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
Docker镜像加速的原理
- Docker镜像实际上是由一层层的文件系统组成,这种层级叫联合文件系统
- bootfs主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动时候会加载bootfs文件系统,在Docker镜像最底层是bootfs。这一层与我们典型的Linux/Unix是一样的。包含了boot加速器和内核。当boot加载完成后整个内核就在内存中了,此时内存的使用权由bootfs转交给内核,此时系统会卸载bootfs
- rootfs:在bootfs之上,包含了典型的Linux系统的/dev、/proc、/bin、/etc等标准目录和文件。rootfs就是各种不同的操作系统的发行版。
- 对于一个精简的OS、rootfs可以很小、只需要包含基本的命令、工具和程序库就行。因为底层直接用Host的kernel,自己只需要提供rootfs就可以了,由此可见对于不同的linux发行版,rootfs会有差异,因此不同的发行版可以共用bootfs
分层原理
-
我们可以下载一个镜像,注意观察下载的日志输出,可以看到是一层一层下载的
-
采用分层结构,最大的好处是资源共享,比如有多个镜像都是从相同的Base镜像构建来的,那么宿主机只需要在磁盘中保留一份Base镜像就可以了,同时内存也只需要加载一份Base镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以共享。
-
查看镜像的分层的方式可以通过
docker image inspect
命令jiangsiyong: ~ $ docker image inspect nginx [ { "Id": "sha256:9fa3786cd6acd84e0c642aac376e374d55231e48546b1ec0611eb1d31f0a9f3d", "RepoTags": [ "nginx:latest" ], "RepoDigests": [ "nginx@sha256:853b221d3341add7aaadf5f81dd088ea943ab9c918766e295321294b035f3f3e" ], "Parent": "", "Comment": "", "Created": "2021-09-09T17:51:09.078592214Z", "Container": "e4a792602a7cb512b981296eccb2b50ae9e3ce77edc945db3bb8b0291c8655b3", "ContainerConfig": { "Hostname": "e4a792602a7c", "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.21.3", "NJS_VERSION=0.6.2", "PKG_RELEASE=1~buster" ], "Cmd": [ "/bin/sh", "-c", "#(nop) ", "CMD [\"nginx\" \"-g\" \"daemon off;\"]" ], "Image": "sha256:d06c4989171f08174a38d621f11f1adaa0668f9894f518a215624e957889767b", "Volumes": null, "WorkingDir": "", "Entrypoint": [ "/docker-entrypoint.sh" ], "OnBuild": null, "Labels": { "maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>" }, "StopSignal": "SIGQUIT" }, "DockerVersion": "20.10.7", "Author": "", "Config": { "Hostname": "", "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.21.3", "NJS_VERSION=0.6.2", "PKG_RELEASE=1~buster" ], "Cmd": [ "nginx", "-g", "daemon off;" ], "Image": "sha256:d06c4989171f08174a38d621f11f1adaa0668f9894f518a215624e957889767b", "Volumes": null, "WorkingDir": "", "Entrypoint": [ "/docker-entrypoint.sh" ], "OnBuild": null, "Labels": { "maintainer": "NGINX Docker Maintainers <docker-maint@nginx.com>" }, "StopSignal": "SIGQUIT" }, "Architecture": "arm64", "Variant": "v8", "Os": "linux", "Size": 125996525, "VirtualSize": 125996525, "GraphDriver": { "Data": { "LowerDir": "/var/lib/docker/overlay2/1e6c6e8e97a4062494f53ffffa2ff7b4272bf0c3789f97b9be177a98ff94f907/diff:/var/lib/docker/overlay2/60771f42be72e06623f7587b36e791927f0dac7a09c72972ff9ac80248d9c802/diff:/var/lib/docker/overlay2/e08ef36312b415cbb803829b9baed945d7d4eca637bf97ec6c94fe9038693635/diff:/var/lib/docker/overlay2/b38e18d2dabe4004fcb630d8f1e1450a409ca5b3373f019f08b1c61b9982f9ab/diff:/var/lib/docker/overlay2/74867c601bb2e4cf4fa04d40c3f91adc74f6dbc6749ef454cfaf55b7187e35c0/diff", "MergedDir": "/var/lib/docker/overlay2/6d855dc4415773ce4a4269df4441f2110c40b89ea2f048b249d18caa3c0d6ef1/merged", "UpperDir": "/var/lib/docker/overlay2/6d855dc4415773ce4a4269df4441f2110c40b89ea2f048b249d18caa3c0d6ef1/diff", "WorkDir": "/var/lib/docker/overlay2/6d855dc4415773ce4a4269df4441f2110c40b89ea2f048b249d18caa3c0d6ef1/work" }, "Name": "overlay2" }, "RootFS": { "Type": "layers", "Layers": [ "sha256:5f140fe6ea259f8caec3cb6a4f230fe761c8efa223579bf3c5f9af9e5883e986", "sha256:5ac2af1ad4fd920bb7e5cd04802bfda1b991c22a42d7bb1df773620553502d9a", "sha256:1fbe13821665fc8bd205e02dde22c5d72605c2170680c08401a6d3b8566c5dcb", "sha256:19d1177a9d832c9d7fb6f4285d74a5e35377fcc68242860abdf319293c4e2664", "sha256:a878019e90336fb68b6985982baf9f13b13d21f5230cbd1ce6c1d6b18f4ff6a3", "sha256:a97ebc9f68a9e9626354413ea31e221966d379567317a2bb59d0d15a89b230a4" ] }, "Metadata": { "LastTagTime": "0001-01-01T00:00:00Z" } } ]
-
所有的镜像都起始于一个基础的镜像层,当进行修改或者添加新的内容的时候,就会在当前镜像层上面创建新的镜像层,比如给予Ubuntu Linux 16.04创建一个新的镜像,这就是新的镜像的第一层,如果在该镜像中添加Python包,就会在基础的镜像层之上创建第二个镜像层,如果继续添加一个安全补丁,就会创建第三个镜像层。
-
Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部,这就是我们通常所说的容器层,容器层之下的叫镜像层。
commit镜像
docker commit 提交容器成为一个新的副本
#命令和git类似
docker commit -m "提交的描述信息" -a "作者" 容器id 目标镜像名:[TAG]
容器数据卷
概念
Docker的理念是将应用和环境打包成一个镜像,如果数据在容器中,那么我们将容器删除,数据就会丢失。
需要容器之间可以有一个数据共享的技术。在Docker容器中产生的数据,可以同步到本地,这就是卷技术
就是目录的挂载,将我们容器中的目录,挂载到Linux上面
容器间也是可以数据共享的
使用数据卷
- 方式一:直接使用命令来挂载
docker run -it -v 宿主机的目录:容器目录 容器 bash
jiangsiyong: ~ $ docker run -it -v ~/Downloads/testDocker:/home/test centos
[root@46d5de98a240 /]#
jiangsiyong: ~ $ docker inspect 46d5de98a240
…………
"Mounts": [
{
"Type": "bind",
"Source": "/Users/jiangsiyong/Downloads/testDocker",
"Destination": "/home/test",
"Mode": "",
"RW": true,
"Propagation": "rprivate"
}
]
…………
#假设将容器删除,挂载到本地的数据卷依旧没有消失
- 具名挂载和匿名挂载
#匿名挂载
-v 容器内路径
docker run -d -P --name ngnix01 -v /etc/nginx nginx
#查看所有卷volume的情况
docker volume ls
#发现
jiangsiyong: ~ $ docker volume ls
DRIVER VOLUME NAME
local 19580df3d818a1df43a2862e6c43437eba4c53b9c75da048015a215df1ff4b37
#具名挂载
docker run -d -P --name ngnix01 -v juming-nginx:/etc/nginx nginx
#发现
jiangsiyong: ~ $ docker volume ls
DRIVER VOLUME NAME
local 19580df3d818a1df43a2862e6c43437eba4c53b9c75da048015a215df1ff4b37
local juming-nginx
#查看卷的路径
docker volume inspect 卷名
jiangsiyong: ~ $ docker volume inspect 19580df3d818a1df43
[
{
"CreatedAt": "2021-09-28T13:57:20Z",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/19580df3d818a1df43a2862e6c43437eba4c53b9c75da048015a215df1ff4b37/_data",
"Name": "19580df3d818a1df43a2862e6c43437eba4c53b9c75da048015a215df1ff4b37",
"Options": null,
"Scope": "local"
}
]
#通过 -v 容器内路径:[ro:rw]来改变读写权限
#ro readonly 只读
#rw readwrite 可读可写
docker run -d -P --name ngnix01 -v juming-nginx:/etc/nginx:ro nginx
#一旦设置了容器权限,容器对我们挂载出来的内容就有限定了
#ro 只要看到ro,就说明这个路径只能通过宿主机来操作,容器内部是无法操作的
数据卷容器
#启动第一个容器
docker run -it --name docker01 centos
#第二个容器volumes-from docker01
docker run -it --name docker02 --volumes-from docker01 centos
#docker01容器创建的内容同步到docker02上
#启动docker03
docker run -it --name docker03 --volumes-from docker01 centos
#发现docker01、docker02和docker03之间的数据都是共享的
- 可以删除docker01,发现docker02和docker03的数据还是存在,是一种数据备份机制
- 多个mysql或者多个redis来实现数据共享
- 容器之间配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用
Mac上进入容器目录
对于Mac操作系统,无法看到/var/lib/docker目录,因为Mac上安装的Docker是将Docker安装在虚拟机上的。
我们需要用以下方式进入
jiangsiyong: ~ $ docker run -it --rm --privileged --pid=host justincormack/nsenter1
Unable to find image 'justincormack/nsenter1:latest' locally
latest: Pulling from justincormack/nsenter1
726619a9fa8c: Pull complete
Digest: sha256:e876f694a4cb6ff9e6861197ea3680fe2e3c5ab773a1e37ca1f13171f7f5798e
Status: Downloaded newer image for justincormack/nsenter1:latest
/ #
Dockerfile
Dockerfile是用来构建Docker的镜像构建文件,是命令脚本,通过这个脚本可以生成镜像,镜像是一层一层的,脚本一个一个的命令,每一个命令是一层镜像
- 创建一个Docker File文件:dockerfile1
FROM centos
VOLUME ["volume01","volume02"]
CMD echo "---end---"
CMD /bin/bash
-
构建一个镜像
docker build -f dockerfile1 -t hello/centos:1.0 .
-
执行
jiangsiyong: Docker $ docker build -f dockerfile1 -t hello/centos:1.0 .
[+] Building 1.3s (5/5) FINISHED
=> [internal] load build definition from dockerfile1 0.0s
=> => transferring dockerfile: 121B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/centos:latest 1.2s
=> [1/1] FROM docker.io/library/centos@sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177 0.0s
=> => resolve docker.io/library/centos@sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f432b177 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:0f3f2a3f60442405fcd2a2cb17113bd0c796ad26e470db3ff1a9c4bd9edbb114 0.0s
=> => naming to docker.io/hello/centos:1.0 0.0s
Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
基础
- 每个保留关键字都必须是大写字母
- 执行从上到下顺序执行
- #表示注释
- 每个执行都会创建一个新的镜像层,并提交
指令
FROM #基础镜像,一切从这里开始构建
MAINTAINER #镜像是谁写的,姓名+邮箱
RUN #镜像构建的时候需要运行的命令
ADD #步骤:tomcat镜像,这个tomcat的压缩包!添加内容
WORKDIR #镜像的工作目录
VOLUME #挂载的目录
EXPOSE #指定暴露的端口配置
#ls -a --> docker run -l
CMD #指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替换
ENTRYPOINT #指定这个容器启动的时候要运行的命令,可以追加命令
ONBUILD #当构建一个被继承的DockerFile的,这个时候就会运行ONBUILD指令,触发指令
COPY #将文件拷贝到镜像中,类似于ADD
ENV #构建的时候设置环境变量
构建自己的镜像
Docker Hub中99%的镜像都是从scratch过来的,然后配置需要的软件和配置进行构建的
- 创建一个自己的centos
My docker
#编写dockerfile镜像文件
jiangsiyong: Docker $ vim mydockerfile-centos
FROM centos
MAINTAINER helloworld<12345678@qq.com>
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 80
CMD echo $MYPATH
CMD echo "----end----"
CMD /bin/bash
#通过这个文件构建镜像
#通过docker build -f dockerfile 文件路径 -t 镜像名:[tag]
jiangsiyong: Docker $ docker build -f mydockerfile-centos -t mycentos:0.1 .
[+] Building 17.4s (8/8) FINISHED
=> [internal] load build definition from mydockerfile-centos 0.0s
=> => transferring dockerfile: 262B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/centos:latest 1.1s
=> CACHED [1/4] FROM docker.io/library/centos@sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f43 0.0s
=> [2/4] WORKDIR /usr/local 0.0s
=> [3/4] RUN yum -y install vim 14.2s
=> [4/4] RUN yum -y install net-tools 1.9s
=> exporting to image 0.2s
=> => exporting layers 0.2s
=> => writing image sha256:8ce98b373ff5f4fa14fa7c90c99e52ffbe61b5b103de2a1286dc19f7d46a3141 0.0s
=> => naming to docker.io/library/mycentos:0.1 0.0s
Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
- 查看当前镜像的构建过程
jiangsiyong: Docker $ docker history 8ce98b373ff5
IMAGE CREATED CREATED BY SIZE COMMENT
8ce98b373ff5 5 minutes ago CMD ["/bin/sh" "-c" "/bin/bash"] 0B buildkit.dockerfile.v0
<missing> 5 minutes ago CMD ["/bin/sh" "-c" "echo \"----end----\""] 0B buildkit.dockerfile.v0
<missing> 5 minutes ago CMD ["/bin/sh" "-c" "echo $MYPATH"] 0B buildkit.dockerfile.v0
<missing> 5 minutes ago EXPOSE map[80/tcp:{}] 0B buildkit.dockerfile.v0
<missing> 5 minutes ago RUN /bin/sh -c yum -y install net-tools # bu… 15.1MB buildkit.dockerfile.v0
<missing> 5 minutes ago RUN /bin/sh -c yum -y install vim # buildkit 66.6MB buildkit.dockerfile.v0
<missing> 5 minutes ago WORKDIR /usr/local 0B buildkit.dockerfile.v0
<missing> 5 minutes ago ENV MYPATH=/usr/local 0B buildkit.dockerfile.v0
<missing> 5 minutes ago MAINTAINER helloworld<12345678@qq.com> 0B buildkit.dockerfile.v0
<missing> 3 weeks ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 3 weeks ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B
<missing> 3 weeks ago /bin/sh -c #(nop) ADD file:420712a90b0934202… 272MB
- CMD和ENTRYPOINT的区别
CMD
#编写dockerfile命令
jiangsiyong: Docker $ vim dockerfile-cmd-test
jiangsiyong: Docker $ cat dockerfile-cmd-test
FROM centos
CMD ["ls","-a"]
#构建镜像
jiangsiyong: Docker $ docker build -f dockerfile-cmd-test -t cmdtest .
[+] Building 0.4s (5/5) FINISHED
=> [internal] load build definition from dockerfile-cmd-test 0.0s
=> => transferring dockerfile: 79B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/centos:latest 0.3s
=> CACHED [1/1] FROM docker.io/library/centos@sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f43 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:800ae6f76bf9bd620270ac45363d160888daaa2e8d4fd17c155f573761ddca66 0.0s
=> => naming to docker.io/library/cmdtest 0.0s
Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
#运行该镜像,发现ls -a生效
jiangsiyong: Docker $ docker run cmdtest
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
#想追加一个命令-l即ls -a -l
#cmd的情况下 -l会替换CMD ["ls","-a"]命令,而-l不是命令,所以报错
jiangsiyong: Docker $ docker run cmdtest -l
docker: Error response from daemon: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "-l": executable file not found in $PATH: unknown.
ERRO[0000] error waiting for container: context canceled
ENTRYPOINT
#编写dockerfile命令
jiangsiyong: Docker $ vim dockerfile-entrypoint-test
jiangsiyong: Docker $ cat dockerfile-entrypoint-test
FROM centos
ENTRYPOINT ["ls","-a"]
#构建镜像
jiangsiyong: Docker $ docker build -f dockerfile-entrypoint-test -t entrypoint-test .
[+] Building 0.4s (5/5) FINISHED
=> [internal] load build definition from dockerfile-entrypoint-test 0.0s
=> => transferring dockerfile: 93B 0.0s
=> [internal] load .dockerignore 0.0s
=> => transferring context: 2B 0.0s
=> [internal] load metadata for docker.io/library/centos:latest 0.3s
=> CACHED [1/1] FROM docker.io/library/centos@sha256:a27fd8080b517143cbbbab9dfb7c8571c40d67d534bbdee55bd6c473f43 0.0s
=> exporting to image 0.0s
=> => exporting layers 0.0s
=> => writing image sha256:9f1a36acb55321d87fe7400634a6d558f473f6905d4caf1c6734e627f2325abc 0.0s
=> => naming to docker.io/library/entrypoint-test 0.0s
Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
#效果跟cmd命令一样
jiangsiyong: Docker $ docker run entrypoint-test
.
..
.dockerenv
bin
dev
etc
home
lib
lib64
lost+found
media
mnt
opt
proc
root
run
sbin
srv
sys
tmp
usr
var
#不是替换cmd命令,而是追加的方式
jiangsiyong: Docker $ docker run entrypoint-test -l
total 56
drwxr-xr-x 1 root root 4096 Oct 9 13:37 .
drwxr-xr-x 1 root root 4096 Oct 9 13:37 ..
-rwxr-xr-x 1 root root 0 Oct 9 13:37 .dockerenv
lrwxrwxrwx 1 root root 7 Nov 3 2020 bin -> usr/bin
drwxr-xr-x 5 root root 340 Oct 9 13:37 dev
drwxr-xr-x 1 root root 4096 Oct 9 13:37 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 14:25 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 185 root root 0 Oct 9 13:37 proc
dr-xr-x--- 2 root root 4096 Sep 15 14:26 root
drwxr-xr-x 11 root root 4096 Sep 15 14:26 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 Oct 9 13:37 sys
drwxrwxrwt 7 root root 4096 Sep 15 14:26 tmp
drwxr-xr-x 12 root root 4096 Sep 15 14:25 usr
drwxr-xr-x 20 root root 4096 Sep 15 14:25 var
构建Tomcat镜像
- 准备镜像文件tomcat压缩包,jdk压缩包
- 编写dockerfile文件
jiangsiyong: Docker $ vim dockerfile-tomcat
jiangsiyong: Docker $
jiangsiyong: Docker $
jiangsiyong: Docker $ cat dockerfile-tomcat
FROM centos
MAINTAINER hello<12345678@qq.com>
COPY readme.txt /usr/local/readme.txt
ADD jdk-8u11-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.22.tar.gz /usr/local/
RUN yum -y -install vim
ENV MYPATH /usr/local
WORK $MYPATH
ENV JAVA_HOME /usr/local/jdk1.8.0_11
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tolls.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.22
ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.22
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
EXPOSE 8080
CMD /usr/local/apache-tomcat-9.0.22/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.22/bin/logs/catalina.out
jiangsiyong: Docker $
更多推荐
所有评论(0)