是什么
docker理念
Docker镜像的设计,使得Docker得以打破过去「程序即应用」的观念。透过镜像(images)将作业系统核心除外,运作应用程式所需要的系统环境,由下而上打包,达到应用程式跨平台间的无缝接轨运作。
解决了运行环境和配置问题软件容器,方便做持续集成并有助于整体发布的容器虚拟化技术。
能干嘛
之前的虚拟机技术虚拟机(virtual machine)就是带环境安装的一种解决方案。
它可以在一种操作系统里面运行另一种操作系统,比如在Windows 系统里面运行Linux 系统。应用程序对此毫无感知,因为虚拟机看上去跟真实系统一模一样,而对于底层系统来说,虚拟机就是一个普通文件,不需要了就删掉,对其他部分毫无影响。这类虚拟机完美的运行了另一套系统,能够使应用程序,操作系统和硬件三者之间的逻辑不变。Linux 容器(Linux Containers,缩写为 LXC)。
Linux 容器不是模拟一个完整的操作系统,而是对进程进行隔离。有了容器,就可以将软件运行所需的所有资源打包到一个隔离的容器中。容器与虚拟机不同,不需要捆绑一整套操作系统,只需要软件工作所需的库资源和设置。系统因此而变得高效轻量并保证部署在任何环境中的软件都能始终如一地运行。比较了 Docker 和传统虚拟化方式的不同之处:
*传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;
*而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。
* 每个容器之间互相隔离,每个容器有自己的文件系统 ,容器之间进程不会相互影响,能区分计算资源。
开发/运维(DevOps)一次构建、随处运行
更快速的应用交付和部署传统的应用开发完成后,需要提供一堆安装程序和配置说明文档,安装部署后需根据配置文档进行繁杂的配置才能正常运行。Docker化之后只需要交付少量容器镜像文件,在正式生产环境加载镜像并运行即可,应用安装配置在镜像里已经内置好,大大节省部署配置和测试验证时间。
更便捷的升级和扩缩容随着微服务架构和Docker的发展,大量的应用会通过微服务方式架构,应用的开发构建将变成搭乐高积木一样,每个Docker容器将变成一块“积木”,应用的升级将变得非常容易。当现有的容器不足以支撑业务处理时,可通过镜像运行新的容器进行快速扩容,使应用系统的扩容从原先的天级变成分钟级甚至秒级。
更简单的系统运维
应用容器化运行后,生产环境运行的应用可与开发、测试环境的应用高度一致,容器会将应用程序相关的环境和状态完全封装起来,不会因为底层基础架构和操作系统的不一致性给应用带来影响,产生新的BUG。当出现程序异常时,也可以通过测试环境的相同容器进行快速定位和修复。
更高效的计算资源利用Docker是内核级虚拟化,其不像传统的虚拟化技术一样需要额外的Hypervisor支持,所以在一台物理机上可以运行很多个容器实例,可大大提升物理服务器的CPU和内存的利用率。
官网
docker官网:http://www.docker.com
docker中文网站:https://www.docker-cn.com/
仓库
Docker Hub官网: https://hub.docker.com/
前提说明
CentOS Docker 安装
Docker支持以下的CentOS版本:
CentOS 7 (64-bit)
CentOS 6.5 (64-bit) 或更高的版本
前提条件
目前,CentOS 仅发行版本中的内核支持 Docker。
Docker 运行在 CentOS 7 上,要求系统为64位、系统内核版本为 3.10 以上。
Docker 运行在 CentOS-6.5 或更高的版本的 CentOS 上,要求系统为64位、系统内核版本为 2.6.32-431 或者更高版本。
查看自己的内核
uname命令用于打印当前系统相关信息(内核版本号、硬件架构、主机名称和操作系统类型等)。[root@yangdong ~]# uname -r 3.10.0-1062.el7.x86_64
查看已安装的CentOS版本信息(CentOS6.8有,CentOS7无该命令)[root@yangdong ~]# cat /etc/redhat-release CentOS Linux release 7.7.1908 (Core)
Docker的基本组成
镜像(image)Docker 镜像(Image)就是一个只读的模板。镜像可以用来创建 Docker 容器,一个镜像可以创建很多容器。
Docker 利用容器(Container)独立运行的一个或一组应用。容器是用镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。可以把容器看做是一个简易版的 Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。容器的定义和镜像几乎一模一样,也是一堆层的统一视角,唯一区别在于容器的最上面那一层是可读可写的。
仓库(repository)仓库(Repository)是集中存放镜像文件的场所。仓库(Repository)和仓库注册服务器(Registry)是有区别的。仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。仓库分为公开仓库(Public)和私有仓库(Private)两种形式。最大的公开仓库是 Docker Hub(https://hub.docker.com/),存放了数量庞大的镜像供用户下载。国内的公开仓库包括阿里云 、网易云 等
小总结需要正确的理解仓储/镜像/容器这几个概念:
Docker 本身是一个容器运行载体或称之为管理引擎。我们把应用程序和配置依赖打包好形成一个可交付的运行环境,这个打包好的运行环境就似乎 image镜像文件。只有通过这个镜像文件才能生成 Docker 容器。image 文件可以看作是容器的模板。Docker 根据 image 文件生成容器的实例。同一个 image 文件,可以生成多个同时运行的容器实例。
* image 文件生成的容器实例,本身也是一个文件,称为镜像文件。
* 一个容器运行一种服务,当我们需要的时候,就可以通过docker客户端创建一个对应的运行实例,也就是我们的容器
* 至于仓储,就是放了一堆镜像的地方,我们可以把镜像发布到仓储中,需要的时候从仓储中拉下来就可以了。
安装步骤CentOS6.8安装Docker
yum install -y epel-release
yum install -y docker-io
安装后的配置文件:/etc/sysconfig/docker
启动Docker后台服务:service docker start
docker version验证
CentOS7安装Docker
https://docs.docker.com/install/linux/docker-ce/centos/
安装步骤
官网中文安装参考手册
https://docs.docker-cn.com/engine/installation/linux/docker-ce/centos/#prerequisites
确定你是CentOS7及以上版本
cat /etc/redhat-release
yum安装gcc相关
yum -y install gcc yum -y install gcc-c++
卸载旧版本yum -y remove docker docker-common docker-selinux docker-engine
或者
yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine
2018.3官网版本安装需要的软件包yum install -y yum-utils device-mapper-persistent-data lvm2
设置stable镜像仓库
推荐yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
更新yum软件包索引yum makecache fast
安装DOCKER CEyum -y install docker-ce
或者
yum install docker-ce docker-ce-cli containerd.io
启动dockersystemctl start docker
测试
docker version docker run hello-world
配置镜像加速
mkdir -p /etc/docker tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://nxezw98y.mirror.aliyuncs.com"] } EOF systemctl daemon-reload systemctl restart docker
开机启动docker
systemctl enable docker
卸载
systemctl stop docker yum -y remove docker-ce rm -rf /var/lib/docker
永远的HelloWorld
阿里云镜像加速
是什么
https://dev.aliyun.com/search.html
获取加速器地址鉴于国内网络问题,后续拉取 Docker 镜像十分缓慢,我们可以需要配置加速器来解决,
我使用的是阿里云的本人自己账号的镜像地址(需要自己注册有一个属于你自己的): https://xxxx.mirror.aliyuncs.com将获得的自己账户下的阿里云加速地址配置进other_args="--registry-mirror=https://你自己的账号加速信息.mirror.aliyuncs.com"
mkdir -p /etc/docker tee /etc/docker/daemon.json <<-'EOF' { "registry-mirrors": ["https://nxezw98y.mirror.aliyuncs.com"] } EOF systemctl daemon-reload systemctl restart docker
或者
vim /etc/docker/daemon.json { "registry-mirrors": ["https://nxezw98y.mirror.aliyuncs.com"] }
systemctl daemon-reload systemctl restart docker
重新启动Docker后台服务:service docker restart
网易云加速
基本同上述阿里云
启动Docker后台容器(测试运行 hello-world)
[root@yangdong docker]# docker run hello-world Unable to find image 'hello-world:latest' locally latest: Pulling from library/hello-world 0e03bdcc26d7: Pull complete Digest: sha256:6a65f928fb91fcfbc963f7aa6d57c8eeb426ad9a20c7ee045538ef34847f44f1 Status: Downloaded newer image for hello-world:latest Hello from Docker! This message shows that your installation appears to be working correctly. To generate this message, Docker took the following steps: 1. The Docker client contacted the Docker daemon. 2. The Docker daemon pulled the "hello-world" image from the Docker Hub. (amd64) 3. The Docker daemon created a new container from that image which runs the executable that produces the output you are currently reading. 4. The Docker daemon streamed that output to the Docker client, which sent it to your terminal. To try something more ambitious, you can run an Ubuntu container with: $ docker run -it ubuntu bash Share images, automate workflows, and more with a free Docker ID: https://hub.docker.com/ For more examples and ideas, visit: https://docs.docker.com/get-started/
run干了什么
底层原理Docker是怎么工作的
Docker是一个Client-Server结构的系统,Docker守护进程运行在主机上, 然后通过Socket连接从客户端访问,守护进程从客户端接受命令并管理运行在主机上的容器。 容器,是一个运行时环境,就是我们前面说到的集装箱。
为什么Docker比较比VM快(1)docker有着比虚拟机更少的抽象层。由亍docker不需要Hypervisor实现硬件资源虚拟化,运行在docker容器上的程序直接使用的都是实际物理机的硬件资源。因此在CPU、内存利用率上docker将会在效率上有明显优势。
(2)docker利用的是宿主机的内核,而不需要Guest OS。因此,当新建一个容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。仍而避免引寻、加载操作系统内核返个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载Guest OS,返个新建过程是分钟级别的。而docker由于直接利用宿主机的操作系统,则省略了返个过程,因此新建一个docker容器只需要几秒钟。
见解:docker镜像就是docker从dockerhub中pull过来的,类似于java的类,一个镜像可以创建多个容器,容器的存在不会依存于镜像,一旦容器创建,即使删除镜像,容器也可以运行。
查看镜像 docker images
查看容器 docker ps -a
创建容器 docker run
启动容器 docker start
删除镜像 docker rmi
删除容器 docker rm
帮助命令
docker version
docker info
docker --help
镜像命令
docker images
列出本地主机上的镜像
OPTIONS说明:
-a :列出本地所有的镜像(含中间映像层)
-q :只显示镜像ID。
--digests :显示镜像的摘要信息
--no-trunc :显示完整的镜像信息[root@yangdong docker]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE redis latest 4cdbec704e47 7 weeks ago 98.2MB mysql 5.7 413be204e9c3 7 weeks ago 456MB hello-world latest bf756fb1ae65 4 months ago
docker search 某个XXX镜像名字
网站
https://hub.docker.com
命令
docker search [OPTIONS] 镜像名字
OPTIONS说明:
--no-trunc : 显示完整的镜像描述
-s : 列出收藏数不小于指定值的镜像。
--automated : 只列出 automated build类型的镜像;
docker pull 某个XXX镜像名字 下载镜像 docker pull 镜像名字[:TAG]
docker rmi 某个XXX镜像名字ID 删除镜像删除单个docker rmi -f 镜像ID
[root@yangdong docker]# docker rmi -f hello-world:latest Untagged: hello-world:latest Untagged: hello-world@sha256:6a65f928fb91fcfbc963f7aa6d57c8eeb426ad9a20c7ee045538ef34847f44f1 Deleted: sha256:bf756fb1ae65adf866bd8c456593cd24beb6a0a061dedf42b26a993176745f6b
删除多个 docker rmi -f 镜像名1:TAG 镜像名2:TAG
删除全部 docker rmi -f $(docker images -qa)
思考
结合我们Git的学习心得,大家猜猜是否会有 docker commit /docker push??
容器命令
有镜像才能创建容器,这是根本前提(下载一个CentOS镜像演示)
docker pull centos
docker run [OPTIONS] IMAGE [COMMAND] [ARG...] 新建并启动容器
OPTIONS说明OPTIONS说明(常用):有些是一个减号,有些是两个减号
--name="容器新名字": 为容器指定一个名称;
-d: 后台运行容器,并返回容器ID,也即启动守护式容器;
-i:以交互模式运行容器,通常与 -t 同时使用;
-t:为容器重新分配一个伪输入终端,通常与 -i 同时使用;
-P: 随机端口映射;
-p: 指定端口映射,有以下四种格式
ip:hostPort:containerPort
ip::containerPort
hostPort:containerPort
containerPort--privileged=true
大约在0.6版,privileged被引入docker。
使用该参数,container内的root拥有真正的root权限。
否则,container内的root只是外部的一个普通用户权限。
privileged启动的容器,可以看到很多host上的设备,并且可以执行mount。
甚至允许你在docker容器中启动docker容器。
启动交互式容器
[root@yangdong docker]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE tomcat latest 1b6b1fe7261e 7 days ago 647MB redis latest 4cdbec704e47 7 weeks ago 98.2MB mysql 5.7 413be204e9c3 7 weeks ago 456MB centos latest 470671670cac 4 months ago 237MB [root@yangdong docker]# docker run -it centos [root@081b2df0acdf /]#
#使用镜像centos:latest以交互模式启动一个容器,在容器内执行/bin/bash命令。
docker run -it centos /bin/bash列出当前所有正在运行的容器 docker ps [OPTIONS]显示正在运行的容器
OPTIONS说明
-a :列出当前所有正在运行的容器+历史上运行过的
-l :显示最近创建的容器。
-n:显示最近n个创建的容器。
-q :静默模式,只显示容器编号。
--no-trunc :不截断输出。
exit容器停止退出
ctrl+P+Q 容器不停止退出docker start 容器ID或者容器名 启动容器
docker restart 容器ID或者容器名 重启容器
docker stop 容器ID或者容器名 停止容器
docker kill 容器ID或者容器名 强制停止容器
docker rm 容器ID 删除已停止的容器
docker rm -f $(docker ps -a -q)
docker ps -a -q | xargs docker rm 一次性删除多个容器
重要docker run -d 容器名 启动守护式容器
#使用镜像centos:latest以后台模式启动一个容器
docker run -d centos
问题:然后docker ps -a 进行查看, 会发现容器已经退出
很重要的要说明的一点: Docker容器后台运行,就必须有一个前台进程.
容器运行的命令如果不是那些一直挂起的命令(比如运行top,tail),就是会自动退出的。
这个是docker的机制问题,比如你的web容器,我们以nginx为例,正常情况下,我们配置启动服务只需要启动响应的service即可。例如
service nginx start
但是,这样做,nginx为后台进程模式运行,就导致docker前台没有运行的应用,
这样的容器后台启动后,会立即自杀因为他觉得他没事可做了.
所以,最佳的解决方案是,将你要运行的程序以前台进程的形式运行启动守护式容器后容器自动关闭
[root@yangdong ~]# docker run -d --name="centos1" centos e553833e14ee8ba5cbb01ca9c529833e36acff48fb53e0be1ba87987ab20fa6e [root@yangdong ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES [root@yangdong ~]# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e553833e14ee centos "/bin/bash" About a minute ago Exited (0) About a minute ago centos1 72604b72fef0 centos "/bin/bash" 28 minutes ago Exited (127) 26 minutes ago centos0 87e902723d74 centos "-it -name=centos0" 30 minutes ago Created sad_kalam 081b2df0acdf centos "/bin/bash" 54 minutes ago Exited (0) 45 seconds ago dazzling_carson
docker logs -f -t --tail 容器ID 查看容器日志
* -t 是加入时间戳
* -f 跟随最新的日志打印
* --tail 数字 显示最后多少条启动守护式容器并且每隔2秒打印一句话容器则不会自动退出docker run -d centos /bin/sh -c "while true;do echo hello zzyy;sleep 2;done"
[root@yangdong ~]# docker run -d --name="centos3" centos /bin/bash -c "while true;do echo hello zzyy;sleep 2;done" 6ecfce9a30e496ae57e79c6c88060ba1867e7de227ac420a698566b9942b53d3 [root@yangdong ~]# docker logs -tf --tail 10 centos3 2020-05-23T19:38:47.112419595Z hello zzyy 2020-05-23T19:38:49.116200945Z hello zzyy 2020-05-23T19:38:51.120568593Z hello zzyy 2020-05-23T19:38:53.124790406Z hello zzyy ^C [root@yangdong ~]# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 6ecfce9a30e4 centos "/bin/bash -c 'while…" 2 minutes ago Up 2 minutes centos3
docker top 容器ID 查看容器内运行的进程[root@yangdong ~]# docker top 6ecfce9a30e4 UID PID PPID C STIME TTY TIME CMD root 16749 16734 0 03:37 ? 00:00:00 /bin/bash -c while true;do echo hello zzyy;sleep 2;done root 17668 16749 0 03:54 ? 00:00:00 /usr/bin/coreutils --coreutils-prog-shebang=sleep /usr/bin/sleep 2
docker inspect 容器ID 查看容器内部细节
[root@yangdong ~]# docker inspect 6ecfce9a30e4 [ { "Id": "6ecfce9a30e496ae57e79c6c88060ba1867e7de227ac420a698566b9942b53d3", "Created": "2020-05-23T19:37:25.297639643Z", "Path": "/bin/bash", "Args": [ "-c", "while true;do echo hello zzyy;sleep 2;done" ], "State": { "Status": "running", "Running": true, "Paused": false, "Restarting": false, "OOMKilled": false, "Dead": false, "Pid": 16749, "ExitCode": 0, "Error": "", "StartedAt": "2020-05-23T19:37:26.829229586Z", "FinishedAt": "0001-01-01T00:00:00Z" }, "Image": "sha256:470671670cac686c7cf0081e0b37da2e9f4f768ddc5f6a26102ccd1c6954c1ee", "ResolvConfPath": "/var/lib/docker/containers/6ecfce9a30e496ae57e79c6c88060ba1867e7de227ac420a698566b9942b53d3/resolv.conf", "HostnamePath": "/var/lib/docker/containers/6ecfce9a30e496ae57e79c6c88060ba1867e7de227ac420a698566b9942b53d3/hostname", "HostsPath": "/var/lib/docker/containers/6ecfce9a30e496ae57e79c6c88060ba1867e7de227ac420a698566b9942b53d3/hosts", "LogPath": "/var/lib/docker/containers/6ecfce9a30e496ae57e79c6c88060ba1867e7de227ac420a698566b9942b53d3/6ecfce9a30e496ae57e79c6c88060ba1867e7de227ac420a698566b9942b53d3-json.log", "Name": "/centos3", "RestartCount": 0, "Driver": "overlay2", "Platform": "linux",
docker exec -it 容器ID bashShell 进入正在运行的容器并以命令行交互docker attach 容器ID 重新进入
上述两个区别
attach 直接进入容器启动命令的终端,不会启动新的进程
exec 是在容器中打开新的终端,并且可以启动新的进程,exec可以直接获取执行结果而不必进入系统[root@yangdong ~]# docker exec 6ecfce9a30e4 ls / bin dev etc home lib lib64 lost+found media mnt opt proc root
docker cp 容器ID:容器内路径 目的主机路径 从容器内拷贝文件到主机上
小总结
常用命令attach Attach to a running container # 当前 shell 下 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 tarball # 从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(联合文件系统)UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录
Docker镜像加载原理Docker镜像加载原理:
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。
bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
rootfs (root file system) ,在bootfs之上。包含的就是典型 Linux 系统中的 /dev, /proc, /bin, /etc 等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。
分层的镜像Docker镜像加载原理:
docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统UnionFS。
bootfs(boot file system)主要包含bootloader和kernel, bootloader主要是引导加载kernel, Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。
rootfs (root file system) ,在bootfs之上。包含的就是典型 Linux 系统中的 /dev, /proc, /bin, /etc 等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。平时我们安装进虚拟机的CentOS都是好几个G,为什么docker这里才200M??
对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供 rootfs 就行了。由此可见对于不同的linux发行版, bootfs基本是一致的, rootfs会有差别, 因此不同的发行版可以公用bootfs。
最大的一个好处就是 - 共享资源
比如:有多个镜像都从相同的 base 镜像构建而来,那么宿主机只需在磁盘上保存一份base镜像,
同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。
特点
Docker镜像都是只读的 当容器启动时,一个新的可写层被加载到镜像的顶部。 这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。
Docker镜像commit操作补充
docker commit提交容器副本使之成为一个新的镜像
docker commit -m=“提交的描述信息” -a=“作者” 容器ID 要创建的目标镜像名:[标签名]
案例演示
从Hub上下载tomcat镜像到本地并成功运行
docker run -it -p 8080:8080 tomcat
-p 主机端口:docker容器端口
-P 随机分配端口root@ccc42c3a5b3b:/usr/local/tomcat# ls BUILDING.txt CONTRIBUTING.md LICENSE NOTICE README.md RELEASE-NOTES RUNNING.txt bin conf lib logs native-jni-lib temp webapps webapps.dist work root@ccc42c3a5b3b:/usr/local/tomcat# cd webapps root@ccc42c3a5b3b:/usr/local/tomcat/webapps# ls
注意:启动tomcat后无法访问主页是因为webapps文件夹是空的,把webapps.dist文件夹中的文件复制一份到webapps中重启tomcat就可以访问主页了
i:交互
t:终端
故意删除上一步镜像生产tomcat容器的文档
也即当前的tomcat运行实例是一个没有文档内容的容器, 以它为模板commit一个没有doc的tomcat新镜像atguigu/tomcat02[root@yangdong ~]# docker commit -a="yangdong" -m="tomcat without docs" ccc42c3a5b3b yangdong/tomcat sha256:57357b86335b8a0eaf1c51c01ee75122aefe0089a0ebc3ee809e463016b1d7da [root@yangdong ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE yangdong/tomcat latest 57357b86335b 12 seconds ago 531MB tomcat 8 f19c56ce92a8 7 days ago 529MB redis latest 4cdbec704e47 7 weeks ago 98.2MB mysql 5.7 413be204e9c3 7 weeks ago 456MB centos latest 470671670cac 4 months ago 237MB
启动我们的新镜像并和原来的对比
启动atguigu/tomcat02,它没有docs
是什么
先来看看Docker的理念:
* 将运用与运行的环境打包形成容器运行 ,运行可以伴随着容器,但是我们对数据的要求希望是持久化的
* 容器之间希望有可能共享数据
Docker容器产生的数据,如果不通过docker commit生成新的镜像,使得数据做为镜像的一部分保存下来,
那么当容器删除后,数据自然也就没有了。
为了能保存数据在docker中我们使用卷
一句话:有点类似我们Redis里面的rdb和aof文件
能干嘛卷就是目录或文件,存在于一个或多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过Union File System提供一些用于持续存储或共享数据的特性:
卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷
特点:
1:数据卷可在容器之间共享或重用数据
2:卷中的更改可以直接生效
3:数据卷中的更改不会包含在镜像的更新中
4:数据卷的生命周期一直持续到没有容器使用它为止
容器的持久化
容器间继承+共享数据
数据卷容器内添加
1.直接命令添加
命令 docker run -it -v /宿主机绝对路径目录:/容器内目录 镜像名
查看数据卷是否挂载成功 docker inspect 容器ID
容器和宿主机之间数据共享
命令(带权限) docker run -it -v /宿主机绝对路径目录:/容器内目录:ro 镜像名 ,ro是readonly的缩写
2.DockerFile添加
根目录下新建mydocker文件夹并进入
可在Dockerfile中使用VOLUME指令来给镜像添加一个或多个数据卷VOLUME["/dataVolumeContainer","/dataVolumeContainer2","/dataVolumeContainer3"]
说明:出于可移植和分享的考虑,用-v 主机目录:容器目录这种方法不能够直接在Dockerfile中实现。
由于宿主机目录是依赖于特定宿主机的,并不能够保证在所有的宿主机上都存在这样的特定目录。
File构建# volume test FROM centos VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2"] CMD echo "finished,--------success1" CMD /bin/bash
build后生成镜像 获得一个新镜像zzyy/centos
通过上述步骤,容器内的卷目录地址已经知道 对应的主机目录地址哪??[root@yangdong /]# mkdir dockerfile [root@yangdong /]# cd /dockerfile/ [root@yangdong dockerfile]# vim dockerfile0 # volume test FROM centos VOLUME ["/datavolumecontainer","/datavolumecontainer1"] CMD echo "finished" CMD /bin/bash [root@yangdong dockerfile]# docker build -f /dockerfile/dockerfile0 -t ysangdong/centos . Successfully built a63a54be0ceb Successfully tagged ysangdong/centos:latest [root@yangdong dockerfile]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE ysangdong/centos latest a63a54be0ceb 10 seconds ago 237MB [root@yangdong dockerfile]# docker run -it a63a54be0ceb [root@60b59d8ba2c8 /]# ls bin datavolumecontainer datavolumecontainer1 dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var [root@yangdong dockerfile]# docker inspect 60b59d8ba2c8 "Mounts": [ { "Type": "volume", "Name": "f5bf2e065d80b88d7f3f75759fecfcd5dd8edc27e27ae59a3b376f8aa1259569", "Source": "/var/lib/docker/volumes/f5bf2e065d80b88d7f3f75759fecfcd5dd8edc27e27ae59a3b376f8aa1259569/_data", "Destination": "/datavolumecontainer", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" }, { "Type": "volume", "Name": "48c1e86795a9c3c5162b5edc4d0a9ce171caf4f39cd9abbde93ebd7993d826bb", "Source": "/var/lib/docker/volumes/48c1e86795a9c3c5162b5edc4d0a9ce171caf4f39cd9abbde93ebd7993d826bb/_data", "Destination": "/datavolumecontainer1", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" } ],
注意:编辑dockerfile的时候没有指定宿主机绑定的目录位置,docker会自动生成一个目录来绑定容器内的卷目录,docker inspect 60b59d8ba2c8命令生成的详细信息中mount数组就是docker在宿主机中自动生成的目录
备注
Docker挂载主机目录Docker访问出现cannot open directory .: Permission denied
解决办法:在挂载目录后多加一个--privileged=true参数即可,该参数可以提高权限VOLUME 和-v 映射的都只是目录
数据卷容器命名的容器挂载数据卷,其它容器通过挂载这个(父容器)实现数据共享,挂载数据卷的容器,称之为数据卷容器
以上一步新建的镜像zzyy/centos为模板并运行容器dc01/dc02/dc03
容器间传递共享(--volumes-from)
先启动一个父容器dc01 在dataVolumeContainer2新增内容
dc02/dc03继承自dc01 --volumes-from
命令 docker run -it --name dc02 --volumes-from dc01 zzyy/centosdc02/dc03分别在dataVolumeContainer2各自新增内容
同一个镜像创造出来的容器如果没有继承关系,他们不能共享数据,也就是说他们的宿主机映射目录不同[root@yangdong dockerfile]# docker run -it --name dc01 a63a54be0ceb [root@8948e1e79ff5 /]# ls bin datavolumecontainer datavolumecontainer1 dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var [root@8948e1e79ff5 /]# cd datavolumecontainer [root@8948e1e79ff5 datavolumecontainer]# touch dc01.txt [root@8948e1e79ff5 datavolumecontainer]# ls dc01.txt [root@yangdong ~]# docker run -it --name dc02 a63a54be0ceb [root@e15eafafe633 /]# ls bin datavolumecontainer datavolumecontainer1 dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var [root@e15eafafe633 /]# cd datavolumecontainer [root@e15eafafe633 datavolumecontainer]# touch dc02.txt [root@e15eafafe633 datavolumecontainer]# ls dc02.txt [root@yangdong ~]# docker inspect dc02 "Mounts": [ { "Type": "volume", "Name": "46cdee2235a22a84add27f31ff2eea429a66cb3c8a65f2cd857d95a253c7120c", "Source": "/var/lib/docker/volumes/46cdee2235a22a84add27f31ff2eea429a66cb3c8a65f2cd857d95a253c7120c/_data", "Destination": "/datavolumecontainer", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" }, { "Type": "volume", "Name": "eefb056d46657264592906401532f2a3d3b374bf79def26570995cdf0e937e52", "Source": "/var/lib/docker/volumes/eefb056d46657264592906401532f2a3d3b374bf79def26570995cdf0e937e52/_data", "Destination": "/datavolumecontainer1", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" } ] [root@yangdong ~]# docker inspect dc01 "Mounts": [ { "Type": "volume", "Name": "9dbe73b7adb0e83198e4d330ff005d273fafac7a2b34449511e94e3a74f18a7e", "Source": "/var/lib/docker/volumes/9dbe73b7adb0e83198e4d330ff005d273fafac7a2b34449511e94e3a74f18a7e/_data", "Destination": "/datavolumecontainer", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" }, { "Type": "volume", "Name": "b2d85da8731435517fcb3295eb0221028e523b8d8b9107a85bec69c8f9b1b005", "Source": "/var/lib/docker/volumes/b2d85da8731435517fcb3295eb0221028e523b8d8b9107a85bec69c8f9b1b005/_data", "Destination": "/datavolumecontainer1", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" } ],
如果 同一个镜像创造出来的容器有了继承关系 --volumes-from,他们就会有共同的宿主机映射目录
[root@yangdong ~]# docker run -it --name dc03 --volumes-from dc01 a63a54be0ceb [root@b17ed8efd19d /]# cd /datavolumecontainer [root@b17ed8efd19d datavolumecontainer]# ls dc01.txt [root@yangdong ~]# docker inspect dc03 "Mounts": [ { "Type": "volume", "Name": "b2d85da8731435517fcb3295eb0221028e523b8d8b9107a85bec69c8f9b1b005", "Source": "/var/lib/docker/volumes/b2d85da8731435517fcb3295eb0221028e523b8d8b9107a85bec69c8f9b1b005/_data", "Destination": "/datavolumecontainer1", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" }, { "Type": "volume", "Name": "9dbe73b7adb0e83198e4d330ff005d273fafac7a2b34449511e94e3a74f18a7e", "Source": "/var/lib/docker/volumes/9dbe73b7adb0e83198e4d330ff005d273fafac7a2b34449511e94e3a74f18a7e/_data", "Destination": "/datavolumecontainer", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" } ], [root@yangdong ~]# docker inspect dc01 "Mounts": [ { "Type": "volume", "Name": "9dbe73b7adb0e83198e4d330ff005d273fafac7a2b34449511e94e3a74f18a7e", "Source": "/var/lib/docker/volumes/9dbe73b7adb0e83198e4d330ff005d273fafac7a2b34449511e94e3a74f18a7e/_data", "Destination": "/datavolumecontainer", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" }, { "Type": "volume", "Name": "b2d85da8731435517fcb3295eb0221028e523b8d8b9107a85bec69c8f9b1b005", "Source": "/var/lib/docker/volumes/b2d85da8731435517fcb3295eb0221028e523b8d8b9107a85bec69c8f9b1b005/_data", "Destination": "/datavolumecontainer1", "Driver": "local", "Mode": "", "RW": true, "Propagation": "" } ],
结论:容器之间配置信息的传递,数据卷的生命周期一直持续到没有容器使用它为止
是什么
Dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本。
构建三步骤 编写Dockerfile文件 docker build docker run
DockerFile构建过程解析
Dockerfile内容基础知识
1:每条保留字指令都必须为大写字母且后面要跟随至少一个参数
2:指令按照从上到下,顺序执行
3:#表示注释
4:每条指令都会创建一个新的镜像层,并对镜像进行提交
Docker执行Dockerfile的大致流程
(1)docker从基础镜像运行一个容器
(2)执行一条指令并对容器作出修改
(3)执行类似docker commit的操作提交一个新的镜像层
(4)docker再基于刚提交的镜像运行一个新容器
(5)执行dockerfile中的下一条指令直到所有指令都执行完成
小总结从应用软件的角度来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段,
* Dockerfile是软件的原材料
* Docker镜像是软件的交付品
* Docker容器则可以认为是软件的运行态。
Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可,合力充当Docker体系的基石。1 Dockerfile,需要定义一个Dockerfile,Dockerfile定义了进程需要的一切东西。Dockerfile涉及的内容包括执行代码或者是文件、环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等;
2 Docker镜像,在用Dockerfile定义一个文件之后,docker build时会产生一个Docker镜像,当运行 Docker镜像时,会真正开始提供服务;
3 Docker容器,容器是直接提供服务的。
DockerFile体系结构(保留字指令)
FROM 基础镜像,当前新镜像是基于哪个镜像的
MAINTAINER 镜像维护者的姓名和邮箱地址
RUN 容器构建时需要运行的命令
EXPOSE 当前容器对外暴露出的端口
WORKDIR 指定在创建容器后,终端默认登陆的进来工作目录,一个落脚点
ENV 用来在构建镜像过程中设置环境变量 ENV MY_PATH /usr/mytest(key value)这个环境变量可以在后续的任何RUN指令中使用,这就如同在命令前面指定了环境变量前缀一样;也可以在其它指令中直接使用这些环境变量,比如:WORKDIR $MY_PATH
ADD 将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包
COPY 类似ADD,拷贝文件和目录到镜像中。 将从构建上下文目录中 <源路径> 的文件/目录复制到新的一层的镜像内的 <目标路径> 位置 COPY src dest COPY ["src", "dest"]
VOLUME 容器数据卷,用于数据保存和持久化工作
CMD 指定一个容器启动时要运行的命令 Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效,CMD 会被 docker run 之后的参数替换
ENTRYPOINT 指定一个容器启动时要运行的命令 ENTRYPOINT 的目的和 CMD 一样,都是在指定容器启动程序及参数
ONBUILD 当构建一个被继承的Dockerfile时运行命令,父镜像在被子继承后父镜像的onbuild被触发小总结
Base镜像(scratch)
Docker Hub 中 99% 的镜像都是通过在 base 镜像中安装和配置需要的软件构建出来的FROM scratch ADD centos-7-x86_64-docker.tar.xz / LABEL \ org.label-schema.schema-version="1.0" \ org.label-schema.name="CentOS Base Image" \ org.label-schema.vendor="CentOS" \ org.label-schema.license="GPLv2" \ org.label-schema.build-date="20200504" \ org.opencontainers.image.title="CentOS Base Image" \ org.opencontainers.image.vendor="CentOS" \ org.opencontainers.image.licenses="GPL-2.0-only" \ org.opencontainers.image.created="2020-05-04 00:00:00+01:00" CMD ["/bin/bash"]
scratch镜像就是源镜像
自定义镜像mycentos
编写
Hub默认CentOS镜像什么情况自定义mycentos目的使我们自己的镜像具备如下:
登陆后的默认路径
vim编辑器
查看网络配置ifconfig支持FROM centos MAINTAINER zzyy
ENV MYPATH /usr/local WORKDIR $MYPATH RUN yum -y install vim RUN yum -y install net-tools EXPOSE 80 CMD echo $MYPATH CMD echo "success--------------ok" CMD /bin/bash
构建
docker build -f dockerfile目录 -t 新镜像名字:TAG .会看到 docker build 命令最后有一个 . . 表示当前目录
运行
docker run -it 新镜像名字:TAG可以看到,我们自己的新镜像已经支持vim/ifconfig命令,扩展成功了。
列出镜像的变更历史
docker history 镜像名:是dockerfile的执行过程,从下往上执行[root@yangdong dockerfile]# docker history centos IMAGE CREATED CREATED BY SIZE COMMENT 470671670cac 4 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
4 months ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B 4 months ago /bin/sh -c #(nop) ADD file:aa54047c80ba30064… 237MB [root@yangdong dockerfile]# docker history yangdong/centos IMAGE CREATED CREATED BY SIZE COMMENT f145a9e2c004 6 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "/bin… 0B 242ef0c2c3cc 6 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B 3a56f0dd746d 6 minutes ago /bin/sh -c #(nop) CMD ["/bin/sh" "-c" "echo… 0B 6b77478e4feb 6 minutes ago /bin/sh -c #(nop) EXPOSE 80 0B 2c2b9c933999 6 minutes ago /bin/sh -c yum -y install net-tools 24.1MB 9165d9c50364 6 minutes ago /bin/sh -c yum -y install vim 59.8MB 124195da6063 6 minutes ago /bin/sh -c #(nop) WORKDIR /usr/local 0B 76be82733f0c 6 minutes ago /bin/sh -c #(nop) ENV MYPATH=/usr/local 0B c5d5aa177bb9 6 minutes ago /bin/sh -c #(nop) MAINTAINER zzyy 4 months ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B 4 months ago /bin/sh -c #(nop) ADD file:aa54047c80ba30064… 237MB
CMD/ENTRYPOINT 镜像案例
都是指定一个容器启动时要运行的命令
CMD Dockerfile 中可以有多个 CMD 指令,但只有最后一个生效,CMD 会被 docker run 之后的参数替换
ENTRYPOINT docker run 之后的参数会被当做参数传递给 ENTRYPOINT,之后形成新的命令组合
制作CMD版可以查询IP信息的容器 crul命令解释FROM centos RUN yum install -y curl CMD [ "curl", "-s", "http://ip.cn" ]
curl命令可以用来执行下载、发送各种HTTP请求,指定HTTP头部等操作。
如果系统没有curl可以使用yum install curl安装,也可以下载安装。
curl是将下载文件输出到stdout
使用命令:curl http://www.baidu.com
执行后,www.baidu.com的html就会显示在屏幕上了
如果我们希望显示 HTTP 头信息,就需要加上 -i 参数,制作ENTROYPOINT版查询IP信息的容器我们可以看到可执行文件找不到的报错,executable file not found。
之前我们说过,跟在镜像名后面的是 command,运行时会替换 CMD 的默认值。
因此这里的 -i 替换了原来的 CMD,而不是添加在原来的 curl -s http://ip.cn 后面。而 -i 根本不是命令,所以自然找不到。
那么如果我们希望加入 -i 这参数,我们就必须重新完整的输入这个命令:FROM centos RUN yum install -y curl ENTRYPOINT [ "curl", "-s", "http://ip.cn" ]
重新build
[root@yangdong dockerfile]# docker build -f /dockerfile/dockerfile2 -t curl2/centos .
添加参数执行
[root@yangdong dockerfile]# docker run curl2/centos -i HTTP/1.1 200 OK Accept-Ranges: bytes Cache-Control: private, no-cache, no-store, proxy-revalidate, no-transform Connection: keep-alive Content-Length: 2381 Content-Type: text/html Date: Thu, 28 May 2020 04:31:56 GMT Etag: "588604c8-94d" Last-Modified: Mon, 23 Jan 2017 13:27:36 GMT Pragma: no-cache Server: bfe/1.0.8.18
ONBUILD 当构建一个被继承的Dockerfile时运行命令,父镜像在被子继承后父镜像的onbuild被触发
FROM centos
RUN yum install -y curl
ENTRYPOINT [ "curl", "-s", "http://ip.cn" ]
ONBUILD RUN echo "father images onbuild---886"
重新build
[root@yangdong dockerfile]# docker build -f /dockerfile/dockerfile2 -t father/centos .
继承father镜像
FROM father/centos
RUN echo "child is build"
EXPOSE 8080
ENTRYPOINT ["curl","-s","http://www.qq.com"]
build chuild ,run child
[root@yangdong dockerfile]# docker build -f /dockerfile/dockerfile3 -t child/centos .
Sending build context to Docker daemon 5.12kB
Step 1/4 : FROM father/centos
# Executing 1 build trigger
---> Running in af095f736cee
father is onbuild--886
[root@yangdong dockerfile]# docker run child/centos
302 Found
302 Found
nginx
注意:每修改一次dockerfile就要重新build一次镜像,这样修改的dockerfile才会起作用,子镜像不会继承父镜像的CMD
和ENTRYPOINT
解决报错WARNING: IPv4 forwarding is disabled. Networking will not work.
[root@yangdong dockerfile]# docker run -it curl/centos WARNING: IPv4 forwarding is disabled. Networking will not work.
第一步:在宿主机上执行echo "net.ipv4.ip_forward=1" >>/usr/lib/sysctl.d/00-system.conf 或者使用vim命令在00-system.conf的最后一行添加net.ipv4.ip_forward=1,这行代码的作用是开启路由功能。
echo "net.ipv4.ip_forward=1" >>/usr/lib/sysctl.d/00-system.conf
第二步:重启network和docker服务
[root@localhost /]# systemctl restart network && systemctl restart docker
自定义镜像Tomcat9
1. mkdir -p /zzyyuse/mydockerfile/tomcat9
2. 在上述目录下touch c.txt
3. 将jdk和tomcat安装的压缩包拷贝进上一步目录
apache-tomcat-9.0.8.tar.gz
4. 在/zzyyuse/mydockerfile/tomcat9目录下新建Dockerfile文件 目录内容FROM centos MAINTAINER zzyy
#把宿主机当前上下文的c.txt拷贝到容器/usr/local/路径下 COPY c.txt /usr/local/cincontainer.txt #把java与tomcat添加到容器中 ADD jdk-8u171-linux-x64.tar.gz /usr/local/ ADD apache-tomcat-9.0.8.tar.gz /usr/local/ #安装vim编辑器 RUN yum -y install vim #设置工作访问时候的WORKDIR路径,登录落脚点 ENV MYPATH /usr/local WORKDIR $MYPATH #配置java与tomcat环境变量 ENV JAVA_HOME /usr/local/jdk1.8.0_171 ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.8 ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.8 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin #容器运行时监听的端口 EXPOSE 8080 #启动时运行tomcat # ENTRYPOINT ["/usr/local/apache-tomcat-9.0.8/bin/startup.sh" ] # CMD ["/usr/local/apache-tomcat-9.0.8/bin/catalina.sh","run"] CMD /usr/local/apache-tomcat-9.0.8/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.8/bin/logs/catalina.out 6.run 备注
web.xml
test
a.jsp<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
Insert title here -----------welcome------------ <%="i am in docker tomcat self "%>
<% System.out.println("=============docker tomcat self");%>测试
[root@yangdong tomcat]# cd test/ [root@yangdong test]# mkdir WEB-INF [root@yangdong test]# cd WEB-INF/ [root@yangdong WEB-INF]# vim web.xml [root@yangdong WEB-INF]# cd .. [root@yangdong test]# vim a.jsp [root@yangdong test]# docker restart myt9 myt9 [root@yangdong test]# ls a.jsp WEB-INF [root@yangdong test]# cd .. [root@yangdong tomcat]# ls apache-tomcat-8.5.55.tar.gz c.txt dockerfile3 jdk-8u11-linux-x64.tar.gz test tomcatlogs [root@yangdong tomcat]# cd tomcatlogs/ [root@yangdong tomcatlogs]# ls catalina.2020-05-29.log host-manager.2020-05-29.log localhost_access_log.2020-05-29.txt catalina.out localhost.2020-05-29.log manager.2020-05-29.log [root@yangdong tomcatlogs]# cat catalina.out 29-May-2020 12:25:51.685 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version name: Apache Tomcat/8.5.55........... 29-May-2020 12:44:27.819 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 943 ms =============docker tomcat self
docker run -d -p 9080:8080 --name myt9 -v /zzyyuse/mydockerfile/tomcat9/test:/usr/local/apache-tomcat-9.0.8/webapps/test -v /zzyyuse/mydockerfile/tomcat9/tomcat9logs/:/usr/local/apache-tomcat-9.0.8/logs --privileged=true zzyytomcat9
小总结
总体步骤
搜索镜像
拉取镜像
查看镜像
启动镜像
停止容器
移除容器
安装tomcat
docker hub上面查找tomcat镜像 docker search tomcat
从docker hub上拉取tomcat镜像到本地 docker pull tomcat
使用tomcat镜像创建容器(也叫运行镜像 docker run -it -p 8080:8080 tomcat -p 主机端口:docker容器端口 -P 随机分配端口 -i:交互 -t:终端(一般-i,-t结合使用)安装mysql
docker hub上面查找mysql镜像 从docker hub上(阿里云加速器)拉取mysql镜像到本地标签为5.6
使用mysql5.6镜像创建容器(也叫运行镜像) 使用mysql镜像docker run -p 12345:3306 --name mysql -v /zzyyuse/mysql/conf:/etc/mysql/conf.d -v /zzyyuse/mysql/logs:/logs -v /zzyyuse/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.6
命令说明:
-p 12345:3306:将主机的12345端口映射到docker容器的3306端口。
--name mysql:运行服务名字
-v /zzyyuse/mysql/conf:/etc/mysql/conf.d :将主机/zzyyuse/mysql/conf/ 挂载到容器的 /etc/mysql/conf.d
-v /zzyyuse/mysql/logs:/logs:将主机/zzyyuse/mysql/logs 目录挂载到容器的 /logs。
-v /zzyyuse/mysql/data:/var/lib/mysql :将主机/zzyyuse/mysql/data目录挂载到容器的 /var/lib/mysql
-e MYSQL_ROOT_PASSWORD=123456:初始化 root 用户的密码。
-d mysql:5.6 : 后台程序运行mysql5.6注意:-v 指令宿主机
docker exec -it MySQL运行成功后的容器ID /bin/bash
docker exec myql服务容器ID sh -c ' exec mysqldump --all-databases -uroot -p"123456" ' > /zzyyuse/all-databases.sql
安装redis从docker hub上(阿里云加速器)拉取redis镜像到本地标签为3.2
docker run -p 6379:6379 --name=redis -v /myredis/data:/data -v /myredis/conf:/usr/local/etc/redis -d redis redis-server /usr/local/etc/redis/redis.conf --appendonly yes
在主机/zzyyuse/myredis/conf/redis.conf目录下新建redis.conf文件vim /zzyyuse/myredis/conf/redis.conf/redis.conf
运行 redis docker exec -it redis redis-cli 开启 aof 持久化 vi /mydata/redis/conf/redis.conf # 添加如下内容 appendonly yes 重启 redis docker restart redis
-v只能映射目录,不能映射文件
测试redis-cli连接上来docker exec -it 运行着Rediis服务的容器ID redis-cli
本地镜像发布到阿里云流程
镜像的生成方法前面的DockerFile
从容器创建一个新的镜像 docker commit [OPTIONS] 容器ID [REPOSITORY[:TAG]]OPTIONS说明:
-a :提交的镜像作者;
-m :提交时的说明文字;
将本地镜像推送到阿里云
本地镜像素材原型
阿里云开发者平台 https://dev.aliyun.com/search.html
创建仓库镜像 命名空间 仓库名称
将阿里云上的镜像下载到本地 下载到本地