导图社区 Docker-完整详细学习笔记
涵盖Docker的基础概念、安装及卸载流程、常用命令、Dockerfile编写、Docker网络、springboot服务部署等完整知识
编辑于2023-01-10 11:54:42 河北省Docker
Docker概念
Docker为什么会出现
一款产品: 开发–上线 两套环境!应用环境,应用配置! 开发环境Windows,最后发布到Linux! 问题: ①开发 — 运维。 问题:我在我的电脑上可以允许!版本更新,导致服务不可用!对于运维来说考验十分大? ②环境配置是十分的麻烦,每一个及其都要部署环境(集群Redis、ES、Hadoop…) !费事费力。 ③在服务器配置一个应用的环境 Redis MySQL JDK ES Hadoop 配置超麻烦了,不能够跨平台。 传统:开发打出jar包 ---> 后面由运维来做! 现在:开发打包部署上线,一套流程做完! 发布一个项目( jar + (Redis MySQL JDK ES) ),项目能不能带上环境安装打包! Docker给以上的问题,提出了解决方案!  安卓流程: java — apk —发布(应用商店)一 张三使用apk一安装即可用! docker流程:java — jar+环境 — 打包项目帯上环境(镜像) — ( Docker仓库:商店)-----
Docker官网
Docker官网
文档
仓库
Docker的历史
出现 —> 开源
出现: 2010年,几个IT年轻人,就在美国成立了一家公司 dotcloud 做一些pass的云计算服务!LXC(Linux Container容器)有关的容器技术! Linux Container容器是一种内核虚拟化技术,可以提供轻量级的虚拟化,以便隔离进程和资源。 他们将自己的技术(容器化技术)命名就是 Docker Docker刚刚延生的时候,没有引起行业的注意!dotCloud,就活不下去! 开源: 2013年,Docker开源! 越来越多的人发现docker的优点!火了。Docker每个月都会更新一个版本! 2014年4月9日,Docker1.0发布! docker为什么这么火?十分的轻巧! 在容器技术出来之前,我们都是使用虚拟机技术! 虚拟机:在window中装一个VMware,通过这个软件我们可以虚拟出来一台或者多台电脑!笨重! 虚拟机也属于虚拟化技术,Docker容器技术,也是一种虚拟化技术!
Docker是基于Go语言开发的
Docker能干嘛
虚拟机技术 与 容器技术
虚拟机技术

1、 资源占用十分多
2、 冗余步骤多
3、 启动很慢!
容器技术
容器化技术不是模拟一个完整的操作系统 
两者的不同
传统虚拟机,虚拟出一条硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件
容器内的应用直接运行在宿主机的内容,容器是没有自己的内核的,也没有虚拟我们的硬件,所以就很轻便
每个容器间是互相隔离,每个容器内都有一个属于自己的文件系统,互不影响
DevOps(开发、运维)
更快速的交付与部署
传统:一堆帮助文档
Docker:打包镜像、发布测试、一键运行
更便捷的升级和扩缩容
升级
原来我们的环境为:SpringBoot 1.5 Mysql5 tomcat5 现在需要升级tomcat为8 传统: 需要升级tomcat后,运维还需要联调SpringBoot、Mysql与tomcat Docker: 开发直接打包(jar + 升级后的整体环境),直接简化了运维
扩缩容
问题: 想要扩容一个服务器! 方法:项目整体直接打包为一个镜像,从服务器A到服务器B 直接一键运行
更简单的系统运维
在容器化之后,我们的开发和测试的环境都是高度一致的
更高效的计算机资源利用
Docker是内核级别的虚拟化,可以在一个物理机上运行很多的容器实例,使得服务器的性能可以被压榨到极致
Docker安装
Docker的基本组成

镜像(image)
Docker镜像就好比是一个模板,可以通过这个模板来创建容器服务,通过这个镜像可以创建多个容器 镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件 例如: tomcat镜像—>run—>tomcat01(容器)
容器(container)
Docker利用容器技术,独立运行一个或一组应用,通过镜像来创建 容器可以:启动、停止、删除...
仓库(repository)
仓库就是存放镜像的地方! 仓库分为:公有镜像、私有镜像 Docker Hub(默认国外) 阿里云、华为云...都有容器服务器(配置镜像加速!)
Docker安装
安装环境
[root@iz2zeak7sgj6i7hrb2g862z ~]# uname -r 3.10.0-514.26.2.el7.x86_64 # 要求3.0以上 [root@iz2zeak7sgj6i7hrb2g862z ~]# cat /etc/os-release NAME="CentOS Linux" VERSION="7 (Core)" ID="centos" ID_LIKE="rhel fedora" VERSION_ID="7" PRETTY_NAME="CentOS Linux 7 (Core)" ANSI_COLOR="0;31" CPE_NAME="cpe:/o:centos:centos:7" HOME_URL="https://www.centos.org/" BUG_REPORT_URL="https://bugs.centos.org/" CENTOS_MANTISBT_PROJECT="CentOS-7" CENTOS_MANTISBT_PROJECT_VERSION="7" REDHAT_SUPPORT_PRODUCT="centos" REDHAT_SUPPORT_PRODUCT_VERSION="7"
1、Linux内核要求3.0以上
2、CentOs7以上
命令安装
#1.卸载旧版本 yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine #2.需要的安装包 yum install -y yum-utils #3.设置镜像的仓库 yum-config-manager \ --add-repo \ https://download.docker.com/linux/centos/docker-ce.repo #上述方法默认是从国外的,不推荐 #推荐使用国内的 yum-config-manager \ --add-repo \ https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo #更新yum软件包索引 yum makecache fast #4.安装docker相关的 docker-ce 社区版 而ee是企业版 yum install docker-ce docker-ce-cli containerd.io # 这里我们使用社区版即可 #5.启动docker systemctl start docker #6. 使用docker version查看是否按照成功 docker version #7. 测试 docker run hello-world
测试hello-world

卸载
#1. 卸载依赖 yum remove docker-ce docker-ce-cli containerd.io #2. 删除资源 rm -rf /var/lib/docker # /var/lib/docker 是docker的默认工作路径!
Docker run流程图

Docker常用命令

帮助命令
docker 命令 --help
docker version
docker info
docker stats:查看CPU使用率
镜像命令
docker images:查看本地主机所有
docker search 镜像名:搜索镜像
 可选项:--filter=STARS=5000 #过滤,搜索出来的镜像收藏STARS数量大于5000的 
docker pull 镜像名: 下载镜像
# 下载镜像 docker pull 镜像名[:tag] [root@iz2zeak7sgj6i7hrb2g862z ~]# docker pull tomcat:8 8: Pulling from library/tomcat #如果不写tag,默认就是latest(最新的) 90fe46dd8199: Already exists #分层下载: docker image 的核心 联合文件系统 35a4f1977689: Already exists bbc37f14aded: Already exists 74e27dc593d4: Already exists 93a01fbfad7f: Already exists 1478df405869: Pull complete 64f0dd11682b: Pull complete 68ff4e050d11: Pull complete f576086003cf: Pull complete 3b72593ce10e: Pull complete Digest: sha256:0c6234e7ec9d10ab32c06423ab829b32e3183ba5bf2620ee66de866df # 签名防伪 Status: Downloaded newer image for tomcat:8 docker.io/library/tomcat:8 #真实地址 #等价于 docker pull tomcat:8 docker pull docker.io/library/tomcat:8 
docker rmi 镜像id:删除镜像
docker rmi -f 镜像id #删除指定id的镜像 [root@iz2zeak7sgj6i7hrb2g862z ~]# docker rmi -f f19c56ce92a8 docker rmi -f $(docker images -aq) #删除全部的镜像 [root@iz2zeak7sgj6i7hrb2g862z ~]# docker stop $(docker ps -a -q)
docker tag 镜像id [新镜像名]:[标签]
容器命令
docker run [可选参数] image:启动容器
# 测试、启动并进入容器 [root@iz2zeak7sgj6i7hrb2g [root@iz2zeak7sgj6i7hrb2g862z ~]docker run -it centos /bin/bash [root@241b5abce65e /]# ls bin dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var [root@241b5abce65e /]exit #从容器退回主机 exit
当运行tomcat镜像时,容器中的tomcat并没有运行起来,需要运行bin下的startup.sh脚本。同时webapps目录下没有东西 需要拷贝webapps.dist目录下的内容
--name="Name" 容器名字
-d:后台方式运行
-it:使用交互方式运行,进入容器查看内容
-p:指定容器的端口
-p 主机端口:容器端口
-p 容器端口
容器端口
-P:随机指定端口
docker ps:列出当前运行中的容器
docker ps 命令 #列出当前正在运行的容器 -a, --all #列出当前正在运行的容器 + 带出历史运行过的容器 -n=?, --last int #列出最近创建的?个容器 ?为1则只列出最近创建的一个容器,为2则列出2个 -q, --quiet #只列出容器的编号
docker rm 容器id:删除容器,不能删除正在运行的容器
docker rm 容器id #删除指定的容器,不能删除正在运行的容器,如果要强制删除 rm -rf docker rm -f $(docker ps -aq) #删除所有的容器 docker ps -a -q|xargs docker rm #删除所有的容器
退出容器
exit #容器直接退出 ctrl +P +Q #容器不停止退出 ---注意:这个很有用的操作
启动和停止容器
docker start 容器id #启动容器 docker restart 容器id #重启容器 docker stop 容器id #停止当前正在运行的容器 docker kill 容器id #强制停止当前容器
常用其他命令
docker run -d 镜像名:后台启动命令
# 命令 docker run -d 镜像名 [root@iz2zeak7sgj6i7hrb2g862z ~]docker run -d centos a8f922c255859622ac45ce3a535b7a0e8253329be4756ed6e32265d2dd2fac6c [root@iz2zeak7sgj6i7hrb2g862z ~]docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES # 问题docker ps.发现centos停止了 # 常见的坑,docker容器使用后台运行,就必须要有要一个前台进程,docker发现没有应用,就会自动停止 # nginx,容器启动后,发现自己没有提供服务,就会立刻停止,就是没有程序了
docker logs:查看日志
docker logs --help 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:37) or relative (e.g. 42m for 42 minutes) --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:37) or relative (e.g. 42m for 42 minutes) ~ docker run -d centos /bin/sh -c "while true;do echo 6666;sleep 1;done" #模拟日志 #显示日志 -tf #显示日志信息(一直更新) --tail number #需要显示日志条数 docker logs -t --tail n 容器id #查看n行日志 docker logs -ft 容器id #跟着日志
docker top 容器id:查看容器内部的进程信息

docker inspect 容器id:查看镜像的元数据
# 命令 docker inspect 容器id #测试 ➜ ~ docker inspect 55321bcae33d [ { "Id": "55321bcae33d15da8280bcac1d2bc1141d213bcc8f8e792edfd832ff61ae5066", "Created": "2020-05-15T05:22:05.515909071Z", "Path": "/bin/sh", "Args": [ "-c", "while true;do echo 6666;sleep 1;done" ], "State": { "Status": "running", "Running": true, "Paused": false, "Restarting": false, "OOMKilled": false, "Dead": false, "Pid": 22973, "ExitCode": 0, "Error": "", "StartedAt": "2020-05-15T05:22:06.165904633Z", "FinishedAt": "0001-01-01T00:00:00Z" }, "Image": "sha256:470671670cac686c7cf0081e0b37da2e9f4f768ddc5f6a26102ccd1c6954c1ee", "ResolvConfPath": "/var/lib/docker/containers/55321bcae33d15da8280bcac1d2bc1141d213bcc8f8e792edfd832ff61ae5066/resolv.conf", "HostnamePath": "/var/lib/docker/containers/55321bcae33d15da8280bcac1d2bc1141d213bcc8f8e792edfd832ff61ae5066/hostname", "HostsPath": "/var/lib/docker/containers/55321bcae33d15da8280bcac1d2bc1141d213bcc8f8e792edfd832ff61ae5066/hosts", "LogPath": "/var/lib/docker/containers/55321bcae33d15da8280bcac1d2bc1141d213bcc8f8e792edfd832ff61ae5066/55321bcae33d15da8280bcac1d2bc1141d213bcc8f8e792edfd832ff61ae5066-json.log", "Name": "/bold_bell", "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, "Capabilities": null, "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/1f347949ba49c4dbee70cea9ff3af39a14e602bc8fac8331c46347bf6708757a-init/diff:/var/lib/docker/overlay2/5afcd8220c51854a847a36f52775b4ed0acb16fe6cfaec3bd2e5df59863835ba/diff", "MergedDir": "/var/lib/docker/overlay2/1f347949ba49c4dbee70cea9ff3af39a14e602bc8fac8331c46347bf6708757a/merged", "UpperDir": "/var/lib/docker/overlay2/1f347949ba49c4dbee70cea9ff3af39a14e602bc8fac8331c46347bf6708757a/diff", "WorkDir": "/var/lib/docker/overlay2/1f347949ba49c4dbee70cea9ff3af39a14e602bc8fac8331c46347bf6708757a/work" }, "Name": "overlay2" }, "Mounts": [], "Config": { "Hostname": "55321bcae33d", "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 6666;sleep 1;done" ], "Image": "centos", "Volumes": null, "WorkingDir": "", "Entrypoint": null, "OnBuild": null, "Labels": { "org.label-schema.build-date": "20200114", "org.label-schema.license": "GPLv2", "org.label-schema.name": "CentOS Base Image", "org.label-schema.schema-version": "1.0", "org.label-schema.vendor": "CentOS", "org.opencontainers.image.created": "2020-01-14 00:00:00-08:00", "org.opencontainers.image.licenses": "GPL-2.0-only", "org.opencontainers.image.title": "CentOS Base Image", "org.opencontainers.image.vendor": "CentOS" } }, "NetworkSettings": { "Bridge": "", "SandboxID": "63ed0c837f35c12453bae9661859f37a08541a0749afb86e881869bf6fd9031b", "HairpinMode": false, "LinkLocalIPv6Address": "", "LinkLocalIPv6PrefixLen": 0, "Ports": {}, "SandboxKey": "/var/run/docker/netns/63ed0c837f35", "SecondaryIPAddresses": null, "SecondaryIPv6Addresses": null, "EndpointID": "b129d9a5a2cbb92722a2101244bd81a9e3d8af034e83f338c13790a1a94552a1", "Gateway": "172.17.0.1", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "IPAddress": "172.17.0.4", "IPPrefixLen": 16, "IPv6Gateway": "", "MacAddress": "02:42:ac:11:00:04", "Networks": { "bridge": { "IPAMConfig": null, "Links": null, "Aliases": null, "NetworkID": "ad5ada6a106f5ba3dda9ce4bc1475a4bb593bf5f7fbead72196e66515e8ac36a", "EndpointID": "b129d9a5a2cbb92722a2101244bd81a9e3d8af034e83f338c13790a1a94552a1", "Gateway": "172.17.0.1", "IPAddress": "172.17.0.4", "IPPrefixLen": 16, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "02:42:ac:11:00:04", "DriverOpts": null } } } } ]
docker exec/attach -it 容器id /bin/bash:进入一个容器
 docker exec # 进入容器后开启一个新的终端,可以在里面进行操作(常用) docker attach #进入容器正在执行的终端,不会启动新的进程
docker cp:容器和宿主机之间的复制
docker cp [OPTIONS] container:src_path dest_path docker cp [OPTIONS] dest_path container:src_path
持久化镜像/容器
①commit+save模式:保留了一个镜像的所有历史文件和元数据,它把容器的内容作为一个新的层覆盖在原有镜像之上,然后实现持久化。原有的镜像没有改变。 ②export模式:打扫干净屋子再请客。把之前镜像的层级删干净,只保留最新的快照文件。
Docker的特点
Docker镜像都是只读的,当容器启动时, 一个新的可写层被加载到镜像的顶部! 这一层就是我们通常说的容器层, 容器之下的都叫做镜像层

容器
export
export对当前的容器状态建立快照,并持久化为tar文件 原本的多个镜像层文件会直接打包变为一个镜像层
docker export -o 文件名.tar 容器id
docker import 文件名.tar 镜像名:TAG
commit
commit 把当前容器的内容新建一个层文件,覆盖在旧的镜像文件层之上,生成一个image镜像
docker commit -m="提交的描述信息" -a="作者" 容器id 目标镜像:[TAG]
docker commit -m="add webapps" -a="wzl" 685c6f4e449e tomcat02:1.0 
镜像
save
save 对当前的镜像进行持久化,形成tar文件
docker save -o 文件名.tar 镜像名:[TAG]
docker save -o nginx.tar nginx:latest
docker load -i 文件名.tar
容器数据卷
目录挂载 将应用和环境打包成一个镜像! 数据?如果数据都在容器中,那么我们容器删除,数据就会丢失!需求:数据可以持久化 MySQL,容器删了,删库跑路!需求:MySQL数据可以存储在本地! 容器之间可以有一个数据共享技术!Docker容器中产生的数据,同步到本地! 这就是卷技术,目录的挂载,将我们容器内的目录挂载到linux目录上面! 总结:容器的持久化和同步操作!容器间数据也是可以共享的! 所有的docker容器内的卷,没有指定目录的情况下都是挂载到宿主机的 /var/lib/docker/volumes/卷名/_data 下, 如果指定了目录,docker volume ls 是查不到的。
-v /宿主机路径:容器内路径:指定路径挂载
docker run -v 主机目录:容器目录 镜像[:TAG] /bin/bash
-v 容器内路径:匿名挂载
# 查看所有的volume(卷)的情况 $ docker volume ls DRIVER VOLUME NAME # 容器内的卷名(匿名卷挂载) local 21159a8518abd468728cdbe8594a75b204a10c26be6c36090cde1ee88965f0d0 local b17f52d38f528893dd5720899f555caf22b31bf50b0680e7c6d5431dbda2802c Hash值就是匿名挂载
例子:docker run -d -P --name nginx01 -v /etc/nginx nginx
-v 卷名:容器内路径:具名挂载
# 查看所有的volume(卷)的情况 $ docker volume ls DRIVER VOLUME NAME local 21159a8518abd468728cdbe8594a75b204a10c26be6c36090cde1ee88965f0d0 local b17f52d38f528893dd5720899f555caf22b31bf50b0680e7c6d5431dbda2802c local wzl #多了一个名字
例子:docker run -d -P --name nginx02 -v wzl:/etc/nginx nginx
wzl不是一个目录,只是一个名字
docker volume ls:查看所有卷
docker volume inspect wzl:查看wzl卷信息
所有的docker容器内的卷,没有指定目录的情况下都是挂载到宿主机的 /var/lib/docker/volumes/卷名/_data 下, 如果指定了目录,docker volume ls 是查不到的。
docker run -v 宿主机路径 : 容器内路径 : ro 镜像
ro readonly:只读 rw readwrite:可读可写 ro 只要看到ro就说明这个路径只能通过宿主机来操作,容器内部是无法操作!
容器之间同步数据(拷贝)
 可以用于容器之间的配置信息的传递,数据卷容器的生命周期一直持续到没有容器使用为止。 但是一旦你持久化到了本地,这个时候,本地的数据是不会删除的!
docker run -it name docker02 --volumes-from docker01 centos:1.0
docker02 --volumes-from docker01 #docker02共享docker01数据卷 
Dockerfile
Dockerfile就是用来构建docker镜像的构建文件 (命令脚本:通过这个脚本可以生成镜像,镜像是一层一层的,脚本是一个个的命令,每个命令都是一层) 
Dockerfile指令
FROM # from:基础镜像,一切从这里开始构建 MAINTAINER # maintainer:镜像是谁写的, 姓名+邮箱 RUN # run:镜像构建的时候需要运行的命令 ADD # add:步骤,tomcat镜像,这个tomcat压缩包!添加内容 添加同目录 WORKDIR # workdir:镜像的工作目录 VOLUME # volume:挂载的目录 EXPOSE # expose:暴露端口配置 CMD # cmd:指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代 ENTRYPOINT # entrypoint:指定这个容器启动的时候要运行的命令,可以追加命令 ONBUILD # onbuild:当构建一个被继承DockerFile这个时候就会运行onbuild的指令,触发指令 COPY # copy:类似ADD,将我们文件拷贝到镜像中 ENV # env:构建的时候设置环境变量! 
大写
例子
# 1./home下新建dockerfile目录 $ mkdir dockerfile # 2. dockerfile目录下新建dockerfile2文件 $ vim mydockerfile-centos # 3.编写Dockerfile配置文件 FROM centos # 基础镜像是官方原生的centos MAINTAINER wzl1999<1572575970@qq.com> # 作者 ENV MYPATH /usr/local # 配置环境变量的目录 WORKDIR $MYPATH # 将工作目录设置为 MYPATH 工作目录(一进容器就进入的目录) RUN yum -y install vim # 给官方原生的centos 增加 vim指令 RUN yum -y install net-tools # 给官方原生的centos 增加 ifconfig命令 EXPOSE 80 # 暴露端口号为80 CMD echo $MYPATH # 输出下 MYPATH 路径 CMD echo "---------end---------" CMD /bin/bash # 启动后进入 /bin/bash # 4.通过这个文件(在当前目录下)构建镜像 # 命令: docker build -f 文件路径 -t 镜像名:[tag] . $ docker build -f dockerfile2 -t mycentos:1.0 . # 5.出现下图后则构建成功 
镜像构建步骤
1. 编写一个dockerfile文件
DockerFile:每个保留关键字(指令)都必须是大写字母
执行从上到下顺序
#表示注释
每一个指令都会创建提交一个新的镜像层并提交
2. docker build 构建成为一个镜像
3. docker run运行镜像
4. docker push发布镜像(DockerHub、阿里云仓库)
发布镜像
1、地址:https://hub.docker.com/
2、确定这个账号可以登录
3、登录
$ docker login --help Usage: docker login [OPTIONS] [SERVER] Log in to a Docker registry. If no server is specified, the default is defined by the daemon. Options: -p, --password string Password --password-stdin Take the password from stdin -u, --username string Username $ docker login -u 你的用户名 -p 你的密码
4、提交push镜像
 # 会发现push不上去,因为如果没有前缀的话默认是push到 官方的library # 解决方法: # 第一种 build的时候添加你的dockerhub用户名,然后在push就可以放到自己的仓库了 $ docker build -t kuangshen/mytomcat:0.1 . # 第二种 使用docker tag #然后再次push $ docker tag 容器id kuangshen/mytomcat:1.0 #然后再次push $ docker push kuangshen/mytomcat:1.0
docker history 镜像id:查看本地镜像的变更历史

例子
1.创建一个文件dockerfile1
2.编写dockerfile1
FROM centos VOLUME ["volume01","volume02"] #匿名挂载 CMD echo "------end-----" CMD /bin/bash
3.构建镜像:docker build -f dockerfile1 -t centos:1.0 .
-f #用哪个文件构建镜像 -t 镜像名:TAG #生成的镜像名 target
4.查看镜像:docker images
5.运行镜像:docker run -it centos:1.0 /bin/bash
6.刚刚设置的卷挂载是匿名的,通过docker inspect 容器id 查看

实战安装Tomcat镜像
1.准备tomcat和jdk到当前目录

2.编写DockerFile
$ vim DockerFile FROM centos # 基础镜像centos MAINTAINER cao<1572575970@qq.com> # 作者 COPY README /usr/local/README # 复制README文件 ADD jdk-8u231-linux-x64.tar.gz /usr/local/ # 添加jdk,ADD 命令会自动解压 ADD apache-tomcat-9.0.35.tar.gz /usr/local/ # 添加tomcat,ADD 命令会自动解压 RUN yum -y install vim # 安装 vim 命令 ENV MYPATH /usr/local # 环境变量设置 工作目录 WORKDIR $MYPATH ENV JAVA_HOME /usr/local/jdk1.8.0_231 # 环境变量: JAVA_HOME环境变量 ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.35 # 环境变量: tomcat环境变量 ENV CATALINA_BASH /usr/local/apache-tomcat-9.0.35 # 设置环境变量 分隔符是: ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin EXPOSE 8080 # 设置暴露的端口 CMD /usr/local/apache-tomcat-9.0.35/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.35/logs/catalina.out # 设置默认命令
3.构建镜像
# 因为DockerFile命名使用默认命名 因此不用使用-f 指定文件 $ docker build -t mytomcat:0.1 .
4.启动容器
# -d:后台运行 -p:暴露端口 --name:别名 -v:绑定路径 $ docker run -d -p 8080:8080 --name tomcat01 -v /home/wzl1999/build/tomcat/test:/usr/local/apache-tomcat-9.0.35/webapps/test -v /home/wzl1999/build/tomcat/tomcatlogs/:/usr/local/apache-tomcat-9.0.35/logs mytomcat:0.1
5.访问测试
$ docker exec -it 自定义容器的id /bin/bash $ curl localhost:8080
Docker网络

原理
1、运行tomcat镜像前,ip addr

2、我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要安装了docker,就会有一个网卡docker0 桥接模式,使用的技术是veth-pair
3、运行tomcat镜像后,ip addr,会发现多了一对网卡
 # 我们发现这个容器带来网卡,都是一对对的 # veth-pair 就是一对的虚拟设备接口,他们都是成对出现的,一端连着协议,一端彼此相连 # 正因为有这个特性 veth-pair 充当一个桥梁,连接各种虚拟网络设备的 # OpenStac,Docker容器之间的连接,OVS的连接,都是使用veth-pair技术
4、容器和容器之间是可以互相ping通的
 结论:tomcat01和tomcat02公用一个路由器,docker0。 所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用ip。
自定义网络
# docker0,特点:默认,域名不能访问。 --link可以打通连接,但是很麻烦! # 我们可以 自定义一个网络 $ docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
1、查看Docker所有网络:docker network ls

--net bridge
# 我们直接启动的命令 --net bridge,而这个就是我们的docker0 # bridge就是docker0 $ docker run -d -P --name tomcat01 tomcat => docker run -d -P --name tomcat01 --net bridge tomcat
自定义网络

--driver bridge
--subnet 192.168.0.0/16:子网
--gateway 192.168.0.1:网关
查看自定义的网络

--net 自定义网络名字:使用自定义网络
 
测试容器之间(都使用自定义网络)是否可以ping通

网络连通
两种网段的容器之间是不能互通的,我们现在打通它们 (例如:容器tomcat-01连接到mynet)  
docker network connect 网络名 容器名

网络模式
bridge:桥接模式 docker默认
自定义一般使用桥接模式
host:和宿主机共享网络
none:不配置网络
SpringBoot微服务打包Docker镜像
1、构建SpringBoot项目
2、打包
3、编写Dockerfile
FROM java:8 COPY *.jar /app.jar CMD ["--server.port=8080"] EXPOSE 8080 ENTRYPOINT ["java","-jar","app.jar"]
4、构建镜像
# 1.复制jar和DockerFIle到服务器 # 2.构建镜像 $ docker build -t xxxxx:xx .
5、发布运行