镜像(image):就好比是一个模板,可以通过这个模板来创建容器服务
容器(container):利用容器技术,独立运行一个或者一组应用,通过镜像来创建
仓库(repository):存放镜像的地方,分为公有仓库和私有仓库
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软件包索引
yum makecache fast
4. 安装docker
yum install docker-ce docker-ce-cli containerd.io
5. 启动docker
systemctl start docker
6. 测试是否安装成功
docker version
7. hello world
docker run hello-world
8. 查看下载的镜像
docker images
了解:卸载docker
1. 卸载依赖
yum remove docker-ce docker-ce-cli containerd.io
2. 删除资源
rm -rf /var/lib/docker #docker的默认工作路径
docker version
docker info
docker 命令 --help
docker images
-a:列出所有镜像
-q:只显示镜像的id
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest bf756fb1ae65 10 months ago 13.3kB
REPOSITORY:表示镜像的仓库源
TAG:镜像的标签
IMAGE ID:镜像ID
CREATED:镜像创建时间
SIZE:镜像大小
docker search 镜像名
--filter=stars=3000 #搜索出的镜像的STARS大于3000
--limit n #搜索结果条数
docker pull 镜像名[:tag] #如果不写tag,默认下载最新版本
docker rmi -f 容器id
docker rmi -f $(docker images -aq) #删除全部
有镜像才能创建容器,这是根本前提
docker pull centos
创建并启动容器
docker run [options] images [command][args]
--name="容器新名字": 为容器指定一个名称;
-d: 后台运行容器,并返回容器ID,也即启动守护式容器;
-i:以交互模式运行容器,通常与 -t 同时使用;
-t:为容器重新分配一个伪输入终端,通常与 -i 同时使用;
-P: 随机端口映射;
-p: 指定端口映射,有以下四种格式
ip:hostPort:containerPort
ip::containerPort
hostPort:containerPort
containerPort
列出所有当前正在运行的容器
docker ps [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 -aq) #删除所有容器
docker ps -a -q | xargs docker rm #删除所有的容器
启动守护式容器
docker run -d 容器名
查看容器日志
docker logs -tf --tail 10 容器id
-t 是加入时间戳
-f 跟随最新的日志打印
--tail 数字 显示最后多少条
查询容器运行进程
docker top 容器id
查询容器内部细节
docker inspect 容器id
进入正在进行的容器并以命令行交互
docker exec -it 容器ID /bin/bash
docker attach 容器ID
#两种方式的区别
attach 直接进入容器启动命令的终端,不会启动新的进程
exec 是在容器中打开新的终端,并且可以启动新的进程
docker exec -it 容器id ls -l / #直接在外面得到结果
从容器内拷贝文件到主机上
docker cp 容器ID:容器内的路径 主机目录
镜像是什么?
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件
UnionFS(联合文件系统)
一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是 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等等。
对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就可以了,因为底层直接用Host的kernel,自己只需要提供 rootfs 就行了。由此可见对于不同的linux发行版, bootfs基本是一致的, rootfs会有差别, 因此不同的发行版可以公用bootfs。
为什么docker镜像要采用这种分层结构呢?
最大的一个好处就是 - 共享资源
比如:有多个镜像都从相同的 base 镜像构建而来,那么宿主机只需在磁盘上保存一份base镜像,
同时内存中也只需加载一份 base 镜像,就可以为所有容器服务了。而且镜像的每一层都可以被共享。
镜像的特点
Docker镜像都是只读的
当容器启动时,一个新的可写的镜像被加载到镜像层的顶部。
这一层通常被叫做容器层,容器层之下的都叫镜像层
docker run -it -p 主机端口:docker容器端口 tomcat
docker run -it -P tomcat #随机分配端口
当镜像运行之后可以修改容器里面的内容,再提交成一个新的镜像
docker commit -a='作者' -m='镜像描述' 容器ID 新的镜像名/名称:版本
直接命令添加
命令:docker run -it -v /宿主机目录:/容器内目录 centos /bin/bash
查看容器卷是否挂载成功
docker inspect 容器id
容器和宿主机之间实现数据共享
容器停止退出后,主机修改数据后,数据能够同步到容器中
命令(带权限)
docker run -it -v /宿主机目录:/容器内目录:ro centos /bin/bash
容器中的数据只能读,不能写
DockerFile添加
1.在宿主机的根目录下创建mydocker文件夹并进入
2.在当前目录创建一个DockerFile的文件
3.编写DockerFile,添加以下内容
FROM centos
VOLUME ["/dataContainer1","/dataContainer2"]
CMD echo "finished,--------success1"
CMD /bin/bash
4.build生成一个新的镜像
docker build -f /mydocker/DockerFile -t binboy/centos . #注意后面有一个点
5.启动容器
docker run -it --name='mycentos' binboy/centos
6.宿主机查看信息
docker inspect 容器id #会自动在宿主机生成共享的目录
1.先启动一个父容器doc1
docker run -it --name "doc1" binboy/centos
2.doc2,doc3继承自doc1
docker run -it --name "doc2" --volumes-from doc1 binboy/centos
docker run -it --name "doc3" --volumes-from doc1 binboy/centos
在doc2,doc3中分别创建doc2.txt,doc3.txt
3.回到doc1可以看到doc2,doc3各自添加的都能共享
4.退出并停止doc1,在doc2中创建doc2_update.txt,在doc3中可以看到doc2_update.txt
5.退出并停止doc2,doc3还能访问数据
6.启动容器doc4继承doc3后,退出并停止doc3
docker run -it --name "doc4" --volumes-from doc3 binboy/centos
7.结论:容器之间配置信息的传递,数据卷的生命周期一直持续到没有容器使用它为止
1.Dockerfile是用来构建Docker镜像的构建文件,是由一系列的命令和参数构成的脚本
2.Dokcerfile的构建步骤
编写Dokcerfile文件
docker build 生成新的镜像
docker run 运行镜像
基础知识
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容器,容器是直接提供服务的。
FROM 基础镜像,当前新镜像是基于哪个镜像的
MAINTAINER 镜像维护者的姓名和邮箱地址
RUN 容器构建时需要运行的命令
EXPOSE 当前容器对外暴露的端口
WORKDIR 指定在创建容器后,终端默认登陆进来的工作目录
ENV 用来在构建镜像过程中设置环境变量
VOLUME 容器数据卷,用于数据保存和持久化工作
CMD 指定一个容器启动时要运行的命令格式
shell: CMD <命令>
exec CMD ['可执行文件',"参数1","参数2"]
DockerFile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换
ENTRYPOINT 指定一个容器启动时要运行的命令
ENTRYPOINT的目地和CMD一样,都是在指定容器启动程序及参数
ONBUILD 当构建一个被继承的Dockerfile时运行命令,父镜像在被子镜像继承后触发父镜像的onbuild
ADD 将宿主机目录下的文件拷贝进镜像并且ADD命令会自动处理URL和解压tar包
COPY 类似ADD,拷贝文件和目录到镜像中 ,语法COPY src dest COPY ["src","dest"]
Base镜像(scratch)
docker Hub上99%的镜像都是通过base镜像中安装和配置需要的软件构建出来的
自定义镜像mycentos
1. 编写DockerFile文件
cd /mydocker
touch Dockerfile
vim Dockerfile
向Dockerfile里面写入内容:
#继承父镜像
FROM centos
#作者和邮箱
MAINTAINER binboy<[email protected]>
#设置环境变量
ENV MYPATH /usr/local
WORKDIR $MYPATH
#安装vim 和网络工具
RUN yum -y install vim
RUN yum -y install net-tools
#对外暴露的端口[提示作用]
EXPOSE 80
#输出
CMD echo $MYPATH
CMD echo "success--------------ok"
CMD /bin/bash
2. 构建镜像
docker build -f /mydocker/DockerFile -t mycentos:1.2 .
3. 运行
docker run -it mycentos:1.2
4. 列出镜像的变更历史
docker history 镜像名:tag
CMD/ENTRYPOINT镜像案例
Dockerfile 中可以有多个CMD的命令,但只有最后一个生效,CMD会被docker run之后的参数替换掉
docker run -it -p 9999:8080 tomcat ls -lh
发现这个tomcat的容器启动之后就退出了
那是因为在启动容器的时候后面加了ls -lh那么会覆盖Dockerfile里面的 CMD ["catalina.sh", "run"]
使用ENTRYPOINT来运行命令,在run 运行的参数会追加到新的命令后面
自定义tomcat镜像
1. 准备工作
mkdir -p /mydocker/tomcat9
cd /mydocker/tomcat9
touch a.txt
#把下载好的tomcat和jdk放到/mydocker/tomcat9里面
2. 编写DockerFile
#基于centos镜像
FROM centos
MAINTAINER binboy<[email protected]>
#把宿主机当前上下文的README.txt拷贝到容器/usr/local/路径下
COPY README.txt /usr/local/README.txt
#把java与tomcat添加到容器中 使用ADD 会自动解压,使用COPY要自行手动解压
ADD jdk-8u181-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.19.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_181
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.19
ENV CATALINA_BASE /usr/local/apache-tomcat-9.0.19
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
#容器运行时监听的端口(提示作用)
EXPOSE 8080
#启动时运行tomcat
# ENTRYPOINT ["/usr/local/apache-tomcat-9.0.19/bin/startup.sh" ]
# CMD ["/usr/local/apache-tomcat-9.0.19/bin/catalina.sh","run"]
#启动tomcat并显示出logs/catalina.out下最后的日志
CMD /usr/local/apache-tomcat-9.0.19/bin/startup.sh && tail -F /usr/local/README.txt
3. 构建
docker build -t mytomcat9:1.0 .
4. 运行
docker run -d --name 'mytomcat9-1' -p 9999:8080 -v /mydocker/tomcat9/test:/usr/local/apache-tomcat-9.0.19/webapps/test --privilege=true mytomcat9:1.0
5. 验证
总体步骤
1.搜索镜像
2.拉取镜像
3.查看镜像
4.启动镜像
5.停止容器
6.移除容器
安装mysql
docker search mysql
docker pull mysql
docker images
docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql
使用win10来连接运行在docker上的mysql