鲸鱼:docker
蓝色大海:宿主系统window10
鲸鱼的背上有集装箱
集装箱:容器实例 来自 镜像模板
Docker:解决了运行环境和配置问题的软件容器,方便做持续集成并有利于整体发布的容器虚拟化技术。
Docker出现的原因:代码在开发上没问题,但是到运维就有问题了。很可能的原因就是环境上的问题。Docker就应运而生,把开发下的代码、配置、系统、数据一起打包。
一次封装,到处运行
只需要一次配置好环境,换到别的机子上一件部署好,大大简化了操作
虚拟机(虚拟机连硬件都模拟,模拟的一个完整的操作系统)的缺点:
1、资源占用多
2、冗余步骤多
3、启动慢
Docker和传统虚拟化方式的不同之处:
Person p1=new Person();
Person p2=new Person();
Person p3=new Person();
镜像:模板Person 。
镜像是创建docker容器的基础,docker镜像类似于虚拟机镜像,可以将它理解为一个面向docker引擎的只读模块,包含文件系统。
容器:容器是用镜像创建的运行实例,mini版linux环境。p1、p2、p3
Docker容器类似一个轻量级的沙箱,Docker利用容器来运行和隔离应用。
仓库:仓库是存放docker镜像的地方。仓库和注册服务器(Registry)还是有区别的。注册服务器是存放仓库的地方,在其中存放了很多仓库,每个仓库存放一类镜像文件。 仓库分为公有仓库和私有仓库,DockerHub是目前最大的公有仓库。可以通过docker push/pull命令从仓库中上传和下载镜像,docker search命令来搜索镜像。
(我使用1-3没有安装成功)
(提供yum-config-manager 实用程序)并设置稳定repository。
sudo yum install -y yum-utils
sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
sudo yum install docker-ce docker-ce-cli containerd.io
Docker 已安装但未启动。该docker组被创建,但没有用户添加到组。
sudo systemctl start docker
通过运行hello-world 映像验证 Docker Engine 是否已正确安装。
sudo docker run hello-world
由于本地没有hello-word这个镜像,所以会下载一个hello-word镜像,并在容器内运行
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210612204648242.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzM4MTkwODIz,size_16,color_FFFFFF,t_70
(我使用了这种安装方法)
# 首先安装 Docker
yum -y install docker
# 然后启动 Docker 服务
service docker start
# 测试安装是否成功
docker -v
Docker是一个Client-Server结构的系统,Docker的守护进程运行在主街上,然后通过Socket连接从客户端访问,守护进程从客户端接受命令并管理运行在主机上的容器,容器是一个运行时的环境,就是集装箱。
docker version
docker -v
docker info
docker --help // 重要
# 列出本地镜像
docker images
# 列出本地所有镜像(含中间映像层)
docker images -a
# 只显示镜像ID
docker images -q
# 显示镜像的摘要信息DIGEST
docker images --digests
# 显示完整的镜像信息IMAGE ID
docker images --digests --no-trunc
REPOSITORY:镜像的仓库源
TAG:镜像标签
IMAGE ID:镜像ID
CREATED:镜像创建时间
SIZE:镜像大小
同一个仓库源可以有多个TAG,代表这个仓库源的不同版本,我们可以使用REPOSITORY:TAG来定义不同的镜像。如果不指定一个镜像的版本标签,docker将默认使用latest镜像。
docker search 某个镜像的名字
# 显示完整的镜像描述
docker search --no-trunc tomcat
# 列出收藏数不小于指定值的镜像
docker search -s 30 tomcat
# 下载最新镜像
docker pull 镜像名 = docker pull 镜像名:latest
docker rmi 镜像名称
# 强制删除正在运行的镜像
docker rmi -f 镜像名称
# 删除多个镜像
docker rmi -f 镜像名称1 镜像名称2
#删除全部镜像
docker rmi -f $(docker images -q)
有镜像才能创建容器,这是一个根本前提。
centos容器是用镜像创建的运行实例。安装的centos仅170M,因为docker拉取的仅仅是业务所需要的runtime环境。可以把这个centos容器看做简易版的Linux环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。
新建容器
docker pull centos
启动交互式容器
如果本地有的话就运行本地的,没有的话会先去hub上拉取
docker run [镜像名] image [command] [arg…]
–name=“容器新名字”
-d:后台运行容器,并返回容器ID,也就是启动守护式容器
-i:以交互模式运行容器,通常与-t同时使用
-t:为容器重新分配一个伪输入终端,通常与-i同时使用
-P:随机端口映射
-p:指定端口映射,有以下四种格式
ip:hostPort:containerPort
ip::containerPort
hostPort:containerPort
containerPort
docker run -it 300e315adb2f
docker ps
# 列出当前所有正在运行的容器+历史上运行过的
docker ps -a
# 显示最近创建的容器
docker ps -l
#显示最近创建的n个容器
docker ps -n 3
# 静默模式,只显示容器编号
docker ps -q
# 不揭短输出
docker ps --no-trunc
退出容器,下次需要重启,状态为Exited
暂时离开一下容器,下次不需要重启,状态为Up。只需要启动容器。
docker start 容器名或容器ID(CONTAINER ID)
docker restart 容器名或容器ID(CONTAINER ID)
慢慢的关掉容器
docker stop 容器名或容器ID(CONTAINER ID)
就像直接拔掉电源,断掉容器
docker kill 容器名或容器ID(CONTAINER ID)
docker rm 容器ID
# 删除多个容器
docker rm -f $(docker ps -a -q)
docker run -d 镜像名称(IMAGE ID)
以后台模式启动一个容器
问题:用docker ps -a 进行查看,我们会发现容器已经退出。
原因:
Docker容器后台运行,就必须要有一个前台进程,容器运行的命令如果不是那些一直挂起的命令(比如top、tail),就是会自动退出的。
这是Docker机制的问题,例如web容器,以nginx为例,正常情况下,我么配置启动服务只需要启动响应的service计科。例如service nginx start。
但是这样做,nginx会以后台进程的模式运行,就导致Docker前台没有运行的应用,这样的容器后台启动后,会立即自杀,因为它觉得它没事可做了。
解决方案:将要运行的程序以前台进程的形式运行。
要使以-d后台启动的容器不退出的话,那么必须要让前台做事情,可以每隔几秒打印日志。
# 使用镜像centos:latest以交互模式启动一个容器,在容器内执行/bin/bash命令
# /bin/bash的作用是因为docker后台必须运行一个进程,否则容器就会退出,在这里表示启动容器后启动bash。
docker run -it centos /bin/bash
docker run -d centos /bin/sh -c "while true;do echo hello zzzz;sleep 2;done"
# -f是跟随最新的日志打印,不停地打印到控制台页面
# -t是加入时间戳
# --tail数字显示最后多少条
docker logs -f -t --tail 容器ID
docker top 容器ID
docker容器是一层套一层的
docker inspect 容器ID
容器退出之后不停止运行,想要再进去。
直接进入容器启动命令的终端,不会启动新的进程
docker attach 容器ID
在容器中打开新的终端,并可以启动新的进程
docker exec -it 容器ID bashShell
# 可进入容器
docker exec -it 容器ID /bin/bash
docker cp 容器ID:容器上的文件 主机上的目录
docker镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。
# docker commit -a="作者名" -m="描述" 容器名 新容器名:版本
docker commit -a="lingling" -m="this is a new images" a38d89b5aa7e ling-centos:1.1
将运用与运行的环境打包形成容器运行,运行可以伴随容器,但是我们对数据的要求希望是持久化的。
容器之间希望有可能共享数据。
Docker容器产生的数据,如果不通过commit生成新的镜像,使得数据作为镜像的一部分保存下来,那么容器删除之后,数据也自然没有了。
为了能保存数据在docker中,我们使用卷。类似Redis里面的rdb和aof文件。
作用:
容器的持久化
容器间继承+共享数据
数据卷就是数据持久化的卷操作。
# -v会在容器和宿主机上对应的地方创建目录
docker run -it -v /宿主机绝对路径目录:/容器内目录 centos
docker run -it -v /myData:/myDataContainer centos
docker inspect 容器ID
在容器中可以创建并读写文件,可以在宿主机上看到。
注意:如果在容器中创建文件报错,那么就需要禁用宿主机上的selinux,将其关闭(setenforce 0)即可。
容器(exit)关闭后,在主机上新创建文件、修改文件,再启动容器,可以在容器上看到最新的。
# readonly只读
docker run -it -v /宿主机绝对路径目录:/容器内目录 centos
run -it -v /myData:/myDataContainer:ro centos
Java:Hello.java→Hello.class
Docker:images→DockerFile
根目录下新建mydocker文件夹并进入
mkdir /mydocker
cd mydocker/
处于可移植和分享的考虑,用-v主机目录:容器目录这种方法不能直接在DockerFile中实现。因为宿主机目录是依赖特定宿主机的,不能保证在所有宿主机上都存在这样的特定目录。
可在DockerFile中使用VOLUME指令来给镜像添加一个或多个数据卷。
VOLUME["/dataVolumeContainer1","/dataVolumeContainer2","/dataVolumeContainer3"]
创建DockerFile1文件
# volume test
FROM centos
VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2"]
CMD echo "finisher,-----------success1"
CMD /bin/bash
DockerFile1文件相当于以下命令:
docker run -it -v /host1:/dataVolumeContainer1 -v /host2:/dataVolumeContainer2 centos /bin/bash
# -f指定要编译的文件,-t容器名
# 在官方文档的示例里,PATH指明了.,然后在当前目录下的多有文件都被发送进了Docker的守护进程,PATH指定了构建镜像时上下文查找文件的路径。比如Dockerfile 里ADD指令的第一个参数可以从上下文也就是刚刚发送进Docker Daemon的文件中找到。
docker build -f /mydocker/DockerFile1 -t lingcentos .
docker run -it 677b0764a216
docker inspect 容器ID
如果Docker挂载主机目录Docker访问出现cannot open directory:Permission denied,解决办法加 --privileged=true:
docker run -it -v /myData:/myDataContainer --privileged=true centos
命名的容器挂载数据卷,其它容器通过挂载这个(父容器)实现数据共享,挂载数据卷的容器,称之为数据卷容器。
以上一步新建的镜像lingcentos为模板并运行容器dc01/dc02/dc03
它们已经有容器卷:dataVolumeContainer1、dataVolumeContainer2
docker run -it --name=dc01 lingcentos
touch dco1_add.txt
在dc02和dc03里分别创建dc02_add.txt和dc03_add.txt
docker run -it --name=dc02 --volumes-from dc01 lingcentos
docker run -it --name=dc03 --volumes-from dc01 lingcentos
dc01、dc02、dc03都可以看到dc01_add.txt dc02_add.txt dc03_add.txt三个文件
1、删除dc01
2、在dc02中添加dc02_updata.txt
3、进入dc02中,可以看到刚刚dc02添加的dc02_updata.txt
容器之间配置信息的传递,数据卷的声明周期一直持续到没有容器使用它为止。
是什么:DockerFile是用来构建Docker镜像的构建文件,是由一起列命令和参数构成的脚本。
构建三步骤:编写DockerFile文件,docker build、docker run
从应用软件的角度来看,DockerFile、Docker镜像、Docker容器分别代表软件的三个不同阶段
基础镜像,当前新镜像是基于哪个镜像的
镜像维护者的姓名和邮箱地址
容器狗剑士需要运行的命令
当前容器对外暴露的端口
用来构建在构建镜像过程中设置环境变量
拷贝+解压缩
将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理url和解压tar压缩包。
类似ADD,拷贝文件和目录到镜像中。
将从构建上下文目录中<源路径>的文件/目录复制到新的一层镜像内的<目标路径>位置
copy src dest
copy ["src","dest"]
容器数据卷,用于数据保持和持久化工作
指定一个容器启动时要运行的命令
DockerFile中可以有多个CMD命令,但只有最后一个生效,CMD会被docker run之后的参数替换
指定一个容器启动时要运行的命令
ENTRYPOINT的目的和CMD一样,都是在指定容器启动程序及参数,但是ENTRYPOINT会追加
当构建一个被继承的DockerFile时运行命令,父镜像在被子继承后,父镜像的onbuild被触发。
Docker Hub中99%的镜像都是通过在base镜像中安装和配置需要的软件构建出来的。
1、之前从hub上拖下来官方的centos
2、新建DockerFile2文件:
FROM centos
# 设置环境变量
ENV mypath /tmp
# 设置落脚点
WORKDIR $mypath
# 装上vim
RUN yum -y install vim
# 装上ifconfig
RUN yum -y install net-tools
# 端口80
EXPOSE 80
CMD /bin/bash
3、编译并运行
docker build -f /mydocker/DockerFile2 -t mycentos:1.1 .
docker run -it aeacd8de1cc1
4、可以看到落脚点为/tmp,vim和ifconfig命令都可以使用了。
5、查看运行历史
docker history 镜像ID
如果在DockerFile文件中有如下所示的命令
CMD 命令1
CMD 命令2
那么只会执行命令1不会执行命令2
命令1和命令2都会执行
mkdir mytomcat9
touch /mytomcat9/touch.txt
该段代码我没有运行成功。
FROM centos
MAINTAINER ll
# 把宿主机当前上下文的touch.txt文件拷贝到容器/usr/local路径下
COPY touch.txt /usr/local/cincontainer.txt
# 把jdk和Tomcat添加到容器中
ADD apache-tomcat-9.0.46.tar.gz /usr/local/
ADD jdk-8u291-linux-x64.tar.gz /usr/local/
# 安装vim编辑器
RUN yum -y install vim
# 设置工作访问时候的WORKDIR路径,登录落脚点
ENV mypath /user/local
WORKDIR $mypath
# 配置java和Tomcat的环境变量
ENV JAVA_HOME /user/local/jdk1.8.0_291
ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV CATALINA_HOME /user/local/apache-tomcat-9.0.46
ENV CATALINA_BASE /user/local/apache-tomcat-9.0.46
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
# 运行时监听的端口
EXPOSE 8080
#启动时运行Tomcat
# ENTRYPOINT ["/user/local/apache-tomcat-9.0.46/bin/startup.sh"]
# CMD ["/user/local/apache-tomcat-9.0.46/bin/catalina.sh","run"]
CMD /user/local/apache-tomcat-9.0.46/bin/startup.sh && tail -F /user/local/apache-tomcat-9.0.46/bin/logs/catalina.out
# -t默认读取当前目录下的DockerFile文件
docker build -t mytomcat9 .
# -d 后台运行
# --privileged=true
docker run -d -p 8080:8080 --name=myt9 -v /mytomcat9/test:/usr/local/apache-tomcat-9.0.46/webapps/test -v /mytomcat9/logs:/usr/local/apache-tomcat-9.0.46/logs mytomcat9
docker search tomcat
docker pull tomcat
docker run -it -p 8080:8080 tomcat
docker search mysql
docker pull mysql:5.6
docker run -p 3306:3306 --name=mysql -v /mysql/conf:/etc/mysql/conf.d -v /mysql/logs:/logs -v /mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.6
docker search redis
docker pull redis
# 后台启动redis,此时docker p该容器已经退出
# docker run -itd --name redis -p 6379:6379 redis
docker run -p 6379:6379 -v /data/redis/redis.conf:/etc/redis/redis.conf -v /data/redis/data:/data --name redis -d redis redis-server /etc/redis/redis.conf --appendonly yes
进入redis.conf文件,复制官网到redis.conf文件里。