-
Docker是一个容器运行载体或称之为管理引擎。
-
可以看作是一个简易版的Linux环境。
-
容器虚拟化技术,取虚拟机的精华(相关内核。。)。
- 更轻量级:基于容器虚拟化,仅包含业务运行所需的runtime环境,CentOS/Ubuntu基础镜像仅仅有170M;宿主机可以部署100~1000个容器
- 更高效:误操作系统虚拟化开销
- 计算:轻量无额外开销
- 存储:系统盘aufs/dm/overlayfs;数据盘volume
- 网络:宿主网络,NS隔离
- 更敏捷、更灵活
- 分层的存储和包的管理,devops理念
- 支持多种网络配置
- 蓝色的大海就是宿主机系统
- 鲸鱼就是docker
- 集装箱就是容器实例,容器实例就来自镜像的模板
Docker利用容器(Container)独立运行一个或一组应用。
镜像(image)容器是用镜像创建的运行实例,镜像类似于类。
仓库(Repository)仓库是集中存放镜像文件的场所。每个**仓库注册服务器(Registry)**上一般存放着很多仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。
- 公开仓库(Public):存放了数量庞大的镜像供用户下载。
- 最大的公开仓库是Ducker Hub(速度慢。。。)
- 国内:
- 阿里云
- 网易云
- 私有仓库(Private)
安装
配置 阿里云镜像加速阿里云控制台操作文档。。。
-
配置/etc/docker/daemon.json
{ "registry-mirrors":["<此处需要从阿里云获取>"] } -
重新加载
systemctl daemon-reload
-
重启docker
systemctl restart docker
-
hello world
docker run hello-world #1.首先从本地查找有没有当前镜像 #2.从远程获取 # 2.1成功查找 # 2.1.1获取哈希码 # 2.1.2拉取镜像 # 2.2查找失败报错 #3.以该镜像为模板生产容器实例运行
CS结构(Client-Server),Docker守护进程运行在主机上,通过Socket链接从客户端访问,守护进程从客户端接受命令并管理运行在主机上的容器。(容器是一个运行时容器)
Docker 与虚拟机(VM)- docker比虚拟机有更少的抽象层。不需要Hypervisor(运行在基础物理服务器和操作系统之间的中间软件层)实现硬件资源虚拟化,运行在docker容器上的程序使用的都是实际物理机的硬件资源。
- Docker利用的是宿主机的内核,而不需要Guest OS。新建一个容器时,docker不需要和虚拟机一样重新加载一个操作系统内核。仍而避免引寻、加载操作系统内核返个比较费时费资源的过程,当新建一个虚拟机时,虚拟机软件需要加载Guest OS,返个新建过程是分钟级别的。而docker由于直接利用宿主机的操作系统,则省略了返个过程,因此新建一个docker容器只需要几秒钟。
| 操作系统 | 与宿主共享OS | 宿主OS上运行虚拟机OS |
| 存储大小 | 镜像小,便于存储与传输 | 镜像庞大(vmdk、vdi等) |
| 运行性能 | 几乎无额外性能损失 | 操作系统额外的CPU、内存消耗 |
| 移植性 | 轻便、灵活、适应与Linux | 笨重、与虚拟化技术耦合度高 |
| 硬件亲和性 | 面向软件开发者 | 面向硬件运维者 |
#docker版本 docker version #docker的具体信息,包括镜像的数量等 docker info #docker帮助命令 docker --help镜像命令
#列出本机上的镜像 docker images #从Docker Hub上查找该镜像 docker search [Option] 镜像名字 #下载镜像 docker pull [Option] 镜像名字:[tag] #删除单个或多个镜像 docker rmi [Option] 镜像名字、ID(可级联空格区分) #删除所有镜像 docker rmi [Option] $(docker images -qa) #提交容器副本使之成为一个新容器,运行时提交的被更改过后的容器成为一个新镜像。被提交的会被更改,而被提交的则不会更改,依旧是全新的容器。 docker commit [Option] 容器ID namespace/imagename:tag # 列出镜像变更历史,一般用于自定义的dockerfile构建后 docker history 镜像名字、ID容器命令 基础用法
#新建并启动容器 docker run [Option] 镜像名字(id) #查看启动的容器 docker ps [Option] #退出容器 exit #1.容器停止退出 ctrl+P+Q #2.容器不停止退出 #进入正在运行的容器并用命令行交互 docker attach 容器ID #在不进入容器的情况下操作容器(后面bashShell的值为/bin/bash可以新开终端,类似attach) docker exec [Option] 容器ID bashShell(bashShell:在容器中执行的命令) #启动容器 docker start 容器名字(id) #重启容器 docker restart 容器名字(id) #停止容器 docker stop 容器名字(id) #1.正常停止 docker kill 容器名字(id) #2.强制停止 #删除已停止的容器 docker rm 容器名字(id) #一次性删除多个容器 docker rm -f $(docker ps [Option]) docker ps [Option] | xargs docker rm重要用法
#Docker容器后台运行就必须有一个前台进程,如果不是一些挂起的命令(比如运行top,tail)就会自动退出 docker run -d 镜像名字(id) #指定端口 docker run -p 主机端口:docker容器端口 # 随机分配端口 docker run -P # 交互 docker run -i # 终端 docker run -t #继承数据卷 docker run --volumes-from 容器名字!(--name后面跟的这个名字) 镜像名字 #查看容器日志 docker logs -f -t --tail 数字 容器ID #-t是加入时间戳;-f跟随最新的日志打印;--tail数字 显示最后多少条 #查看容器内部的进程 docker top ConTAINER [ps OPTIONS] #查看容器内部细节 docker inspect ConTAINER #拷贝文件到主机 docker cp 容器ID:PATH 本机PATH
容器关闭后关闭前的文件依旧会停留在容器上。不删除容器,数据就不会丢失。如果要保留部分文件也可以使用挂载的方式。
Docker镜像 是什么?- UnionFS(联合文件系统)
- Docker镜像加载原理
- 分层镜像
- 层层嵌套每一部分都是一层【比如tomcat:(内——>外):kernel(linux内核)->centos->jdk8->tomcat】
- 使用这种分层的原因
https://www.jianshu.com/p/3ba255463047
特点-
Docker镜像都是只读的
-
当容器启动时一个新的科协曾被加载到镜像的顶部,这一层通常被称作“容器层”,“容器层”之下的都叫“镜像层”。
可以理解为一块移动硬盘,插在docker容器上。这个硬盘是否可以被读也会是主机说了算。
是什么?类似于redis中的aof和rdb,为了持久化docker产生的文件
能干嘛?- 容器的持久化
- 容器间继承+共享数据
特点:
- 数据卷可以在容器之间共享或重用数据
- 卷重的更改可以直接生效
- 数据卷中的更改不会包含在镜像的更新中
- 数据卷的生命周期一直持续到没有容器时用它为止
容器内添加数据卷
1.直接命令添加docker run -it -v /宿主机绝对路径目录:/容器内目录 镜像名
-
类似于直接将目录进行共享双方系统都可以进行读写操作。
-
在容器停止后,主机进行操作,操作会在容器再次启动时同步。
-
"Mounts": [ { "Type": "bind", "Source": "/home/advancer/mydataVolume", "Destination": "/dataVolumeContainer", "Mode": "", "RW": true, "Propagation": "rprivate" } ]
docker run -it -v /宿主机绝对路径目录:/容器内目录:ro 镜像名
(ps ro:read only)
-
不可以进行数据卷写的操作,仅仅可以进行读取。
-
"Mounts": [ { ... "Mode": "ro", "RW": false, ... } ]
报错:
Docker挂在主机目录Docker访问如果出现报错cannot open directory .: Permission denied
解决:在挂载目录后多加一个–privileged==true参数即可
docker run -it -v /宿主机绝对路径目录:/容器内目录 --privileged==true 镜像名2.DockerFile添加
使用这种方式可以添加多个数据卷(在镜像层面)。
DockerFile简述:是类似于Java中.class文件的,docker中源码级的描述。镜像模板的描述文件。
Form ... # 类似于java中的继承 ENV RUN # 可以运行一些linux命令 WORKDIR EXPOSE 【port】 # 暴露端口 CMD [CMD命令执行] ...
通过运行DockerFile后一个容器就被启动了,就像时运行了*.class后这些代码就被执行了。
-
dockerfile的构建
使用vim构建即可
FROM centos # 新建两个数据卷 VOLUME ["/dataVolumeContainer1", "/dataVolumeContainer2"] CMD echo "run---finish" CMD /bin/bash
-
build生成镜像
docker build -f dockerfile -t ljq/centos .
“.” :当前目录。。(maybe)
在dockerfile中并未指定主机挂载的目录,但是会由docker自动生成:通过命令docker inspect 容器ID查看。
数据卷容器 是什么就是挂载硬盘的同时再挂载硬盘,实现数据的传递、依赖。
总体介绍- 在父容器的基础上使用命令来进行创建子容器
- 子容器会和父容器共享数据卷,并不是剥夺
- 从父容器中获取了数据卷的地址以及绑定的主机地址。
docker run --volumes-from 容器名字!(--name后面跟的这个名字) 镜像名字
出于可移植和分享的考虑,用 ==-v 主机目录:容器目录 == 这种方法不能够直接在Dockerfile中实现。是由于宿主机目录是依赖于特定宿主机的,并不能够保证在所有的宿主机上都存在这样的特定目录。
结论:
容器之间配置信息的传递,数据卷的生命周期会一直持续到没有容器时用它为止。
DockerFile 定义用来构建Docker镜像文件,是由一系列命令和参数构成的脚本。
构建步骤- 编写DockerFile文件
- docker build 构建*
- docker run 运行编译生成的镜像
举例
Cent OS
FROM scratch #所有镜像文件的祖先类,类似于java中的Object MAINTAINER The CentOS Project构建过程 dockerfile基础# 作者加邮箱 ADD c68-docker.tar.xz / # LABEL name="CentOS base Image" vendor="CentOS" license="GPLv2" build-date="2016-06-02" #Default command CMD ["/bin/bash"] # 使用CMD命令运行"/bin/bash",就是在运行时不用特意使用/bin/bash来运行
- 每条保留字指令都必须为大写字母且后面要跟随至少一个参数
- 指令按照从上到下的顺序执行
- “#”表示注释
- 每条指令都会创建一个新的镜像层并对镜像进行提交
- docker从基础镜像运行一个容器
- 执行一条指令并对容器作出修改
- 执行类似于docker commit的操作提交一个新的镜像层
- docker再基于共提交的镜像运行一个新容器
- 执行dockerfile中的下一条指令直到所有指令都完成
- DockerFile是软件的原材料
- Docker镜像是软件的交付品
- Docker容器可以认为是软件的运行态
后面跟基础镜像,当前镜像是基于哪个镜像的
MAINTAINER后面跟镜像维护者的姓名和邮箱地址
RUN后面跟linux命令,容器构建时需要运行的命令
EXPOSE后面跟端口号,需要对外暴露的端口
WORKDIR后面跟目录,指定在容器创建后,终端默认登陆的进来工作目录。
ENV后面跟环境变量,用来在构建镜像过程中设置的环境变量
ADD将宿主机目录下的文件拷贝进镜像且ADD命令会自动处理URL和解压tar压缩包
COPY类似于ADD,拷贝文件和目录到镜像中。将构建上下文目录<源路径>的文件/目录复制到新的一层镜像内的<目标路径>的位置
- COPY src dest
- COPY json
容器数据卷,用于数据保存和持久化工作
CMD指定一个容器启动时要运行的命令。
Docker中可以有多个CMD命令,但是只有最后一个执行,CMD会被docker run后的参数替换
ENTRYPOINT指定一个容器启动时要运行的命令。
ENTRYPOINT的目的和CMD一样,都是在指定容器启动程序及参数。
onBUILD当构建一个被继承的Dockerfile时运行命令,父镜像在被子镜像继承后父镜像的ONBUILD被触发。
案例 案例①dockerfile1
FROM centos # 基础镜像为centos MAINTAINER ljq<504863638@qq.com> ENV MYPATH /user/local WORKDIR $MYPATH # 设置/user/local为 RUN yum -y install vim # 提前将没有的软件装入 RUN yum -y install net-tools EXPOSE 80 CMD echo $MYPATH CMD echo "------------success------------" CMD /bin/bash
(花卷、栈)
案例②dockerfile2
FROM centos RUN yum install -y curl CMD [ "curl", "-s", "http://ip.cn" ]
dockerfile3
FROM centos RUN yum install -y curl ENTRYPOINT [ "curl", "-s", "http://ip.cn" ]
两个文件的区别在于
docker run dockerfile2 -i # -i会直接替换CMD中的值 # 变成CMD -i导致报错 # 更为安全 docker run dockerfile3 -1 # -i会直接添加到curl后面作为这条命令的参数 # 变成 ENTRYPOINT [ "curl", "-s", -i "http://ip.cn" ] # 更为灵活案例⑤
dockerfile4
FROM centos RUN yum install -y curl ENTRYPOINT [ "curl", "-s", "http://ip.cn" ] onBUILD RUN echo "father onbuild"
dockerfile5
FROM dockerfile4 RUN yum install -y cur l ENTRYPOINT [ "curl", "-s", "http://ip.cn" ]
在构建dockerfile5时,会运行RUN echo "father onbuild",而当构建dockerfile4时不会运行该语句。
案例④创建一个较为完整的可以供web项目发布的环境。
-
创建一个合适的文件夹
mkdir - .../tomcat9
-
在新创建的目录中创建新的文件
touch c.txt
-
将需要的安装包拷贝进文件夹
apache-tomcat-9.0.54.tar.gz
jdk-8u311-linux-x64.tar.gz
-
在目录下创建新的DockerFile文件
dockerfile6
FROM centos MAINTAINER ljq<504863638@qq.com> #把java与tomcat添加到容器中 COPY c.txt /usr/local/o.txt ADD jdk-8u311-linux-x64.tar.gz /usr/local/ ADD apache-tomcat-9.0.54.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_311 ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar ENV CATALINA_HOME /usr/local/apache-tomcat-9.0.54 ENV CATALINA_base /usr/local/apache-tomcat-9.0.54 ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin #容器运行时监听的端口 EXPOSE 8080 #启动时运行tomcat # ENTRYPOINT ["/usrl/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.54/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.54/logs/catalina.out
如果文件命名为dockerfile时,在构建镜像时只要在对应的目录下,不需要添加-f来指定目标DickerFile文件。
(如果dockerfile错误会出现运行成功,但是docker ps 没有进程,该进程已经退出的情况) -
构建镜像
docker build -t mt9i .
-
运行镜像
docker run -d -p 9080:8080 --name tc9 -v /home/advancer/DockerFile/tomcat9/test:/usr/local/apache-tomcat-9.0.54/webapps/test -v /home/advancer/DockerFile/tomcat9/tomcat9logs/:/usr/local/apache-tomcat-9.0.54/logs --privileged=true tc9i
-
测试
-
拉取MySQL镜像
docker search mysql docker pull mysql:5.7
-
运行镜像
docker run -d -p 13306:3306 --name mysql -v /home/advancer/mysql/conf:/etc/mysql/conf.d -v /home/advancer/mysql/logs:logs -v /home/advancer/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.7
-
操作MySQL
docker exec -it mysql /bin/bash #进入docker中,即可操作 mysql -u root -p...
-
备份数据
docker exec (mysql容器ID) sh -c 'exec mysqldump --all-databases -uroot -p "123456"'>/home/advancer/all-databases.sql
-
拉取镜像
-
在主机文件夹添加配置文件(手动调添加!)
vim /home/advancer/redis/conf/redis.conf # 写入配置文件
-
运行镜像
docker run -p 16379:6379 --name redis -v /home/advancer/redis/conf:/etc/redis/redis.conf -v /home/advancer/redis/data:/data -d redis:6.2 redis-server /etc/redis/redis.conf --appendonly yes # 不挂载配置文件: docker run --name redis -p 6379:6379 -d --restart=always redis redis-server --appendonly yes --requirepass "这是密码"
-
(未验证是否真的是通过这个配置文件来运行的redis,可以通过设置密码实验。)
- 注册阿里云账号
- 右上角控制台,左边列表中找到容器镜像服务
- 创建实例/进入实例
$ docker login --username=advancer registry.cn-hangzhou.aliyuncs.com # 登录阿里云 $ docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/advancer/mytomcat:[镜像版本号] # 版本号对应关系处理 $ docker push registry.cn-hangzhou.aliyuncs.com/advancer/mytomcat:[镜像版本号] # push推送
————————————————————————
根据尚硅谷周洋老师Docker课程记录



