zoukankan      html  css  js  c++  java
  • Docker

    一、Docker简介

    由于在项目部署的时候经常会出现在本机上运行是好使的,但是部署到服务器上时出现各种问题,而这种问题的原因经常是因为环境的问题,所以Docker出现了。
    
    Docker 是基于Go语言实现的开源项目。
    
    Docker是在Linux容器技术的基础上发展出来的。我们可以将应用运行在Docker容器上,而Docker容器在任何操作系统上都是一致的。
    
    Docker主要通过对应用组件的封装、分发、部署、运行等进行管理,来实现用户的app及其运行环境能够做到**一次封装,到处运行**。
    

    二、Docker的安装

    1、Ubuntu安装Docker

    $ sudo apt install docker.io
    
    $ sudo systemctl start docker
    $ sudo systemctl enable docker
    
    # 查看是否安装成功
    $ docker -v
    >> Docker version 17.12.1-ce, build 7390fc6
    

    2、配置阿里云镜像加速

    1)访问网址获取个人的加速器地址

    1533622722178

    2)按照下面的操作文档进行操作

    sudo mkdir -p /etc/docker
    sudo tee /etc/docker/daemon.json <<-'EOF'
    {
      "registry-mirrors": ["https://l7s5cnt9.mirror.aliyuncs.com"]
    }
    EOF
    sudo systemctl daemon-reload
    sudo systemctl restart docker
    

    3、hello,world

    # 非管理员用户要加sudo
    $ sudo docker run hello-world
    

    1533623675145

    4、Docker是怎么工作的

    Docker是一个CS结构的系统,Docker的守护进程运行在主机上,客户端通过socket连接与守护进程进行传输命令,守护进程接受命令并管理运行在主机上的容器。
    
    一个主机上可能有多个容器,每个中运行着镜像(tomcat、mysql...)的实例。
    

    img

    5、Docker为什么比虚拟机快

    详情请见

    虚拟机实现框架docker实现框架

    (1)由上图可以看出Docker比虚拟机少了抽象层Hypervisor,Docker不需要Hypervisor来实现硬件资源虚拟化,而是直接采用宿主的硬件资源。

    (2)而且Docker采用的是宿主机的内核,所以新建一个容器时不需要像虚拟机那样重新加载操作系统内核,从而避免引导、加载系统内核这个耗时的操作。

    三、常用命令

    1、帮助命令

    $ docker --help
    

    2、镜像命令

    1)查看本地主机中的所有镜像

    $ sudo docker images
    
    	Option:
    	  -a:列出本地所有镜像(包括中间映像层)**
    	  -q:只显示镜像id**
    	  --digests:显示镜像完整的描述信息
    	  --no-trunc:不截断输出
    

    1533634161051

    同一个仓库源可以有多个tag,代表这个仓库源的不同版本,所以我们使用REPOSITORY:TAG来定义不同的镜像。

    2)从hub上查找镜像

    $ sudo docker search 查找镜像名
    	
    	Option:
    	   --no-trunc:不截断输出
    	   -s 数字:列出星星不小于指定值的镜像
    	   --automated:列出自动构建类型的镜像
    

    1533633562964

    3)下载镜像

    # 版本号默认为lastest,最新版本
    $ sudo docker pull 下载的镜像名:[版本号]
    

    1533633948374

    4)删除镜像

    $ sudo docker rmi 某个镜像的id
    	
    	# 强制删除,当镜像被某个容器使用时,无法被删除
    	$ sudo docker rmi -f 某个镜像的id
    	# 删除多个镜像
    	$ sudo docker rmi 镜像id1 镜像id2...
    	# 删除全部镜像
    	$ sudo docker rmi -f $(docker images -qa)	# 查出本机所有镜像的id
    

    3、容器命令

    1)新建并启动容器

    $ sudo docker run 镜像id
    	
    	Option:
    		--name="想要给容器起的名字":设置容器名(可以不用写,会自动生成)
    		-d:在后台运行容器,也称守护式容器**
    		-i:以交互式运行容器,通常与-t同时使用**
    		-t:为容器分配一个伪终端,常与-i同时使用**
    		-P:随机端口映射
    		-p:指定端口映射,主要有以下4种格式
    			ip:hostPort:containerPort
    			ip::containerPort
    			hostPort:containerPort**
    			containerPort
    

    启动交互式容器

    1533627744155

    2)列出Docker中有哪些容器在运行

    $ sudo docker ps
    
    	Option:
    		-a:列出所有运行的容器(正在运行+历史运行)
    		-l:显示最近创建的容器
    		-n 数字:显示指定数字创建的容器
    		-q:静默模式,只显示容器编号**
    		--no-trunc:不截断输出
    

    1533628054077

    3)退出交互式容器

    # 容器停止退出
    exit
    # 容器不停止退出
    Ctrl+P+Q
    

    4)其他操作

    # 启动容器,将已经停止的容器启动
    $ sudo docker start 容器id
    
    # 重启容器
    $ sudo docker restart 容器id
    
    # 停止容器
    $ sudo docker stop 容器id
    
    # 强制停止容器
    $ sudo docker kill 容器id
    
    # 删除已经停止的容器
    $ sudo docker rm 容器id
    
    # 强制删除所有容器(不管是否停止)
    $ sudo docker rm -f $(docker ps -aq)
    $ sudo docker ps -aq | xargs docker rm
    

    5)守护式启动

    # 上面说过了,使用-d命令启动,下面介绍注意点
    $ sudo docker run -d 镜像id
    

    1533690548905

    由上图发现,我们运行的容器已经退出。

    这个是Docker机制的问题,由于我们启动的容器中没有前台进程,而是以后台进程的形式运行的,Docker就会以为它没事干,于是就将其杀死。

    解决方案:

    # 1.如果本地镜像只有一个版本,可以直接使用仓库源的名字
    # 2.这句命令的含义是:运行一个容器,使用/bin/sh执行后面的shell脚本
    $ sudo docker run -d centos /bin/sh -c "while true;do echo hello x5456;sleep 2;done"
    

    1533694197017

    6)查看容器日志

    查看容器内运行的进程

    $ sudo docker logs 容器编号
    
    	Option:
    		-t:加入时间戳
    		-f:跟随最新的日志打印
    		--tail 数字:显示指定数字内些条
    

    7)查看容器内部细节

    # 以json格式进行显示
    $ sudo docker inspect 容器id
    

    8)进入正在运行的容器并以命令行交互

    # 容器中启动新的终端并执行命令,返回
    # 如果不写后面的shell脚本,则会启动新的终端
    $ sudo docker exec -it 容器id shell脚本
    
    # 直接进入容器,不启动新的终端
    $ sudo docker attach 容器id
    

    1533691697043

    9)拷贝容器中的文件到本地

    $ sudo docker cp 容器id:容器中文件的位置 要copy到本地的位置
    

    四、Docker镜像

    镜像是一种轻量级、可执行的独立软件包,**用来打包软件运行环境和机基于运行环境开发的软件**,它包括某个软件所需要的所有内容(代码、库、环境变量、配置文件...)
    

    1、UnionFS联合文件系统

    联合文件系统是一种分层、轻量级、高性能的文件系统,它可以一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
    
    Docker的镜像基于UnionFS,也是由一层一层的文件系统组成。
    
    就像我们拉镜像的时候,实际上下载了多层。
    

    1533692670444

    为啥tomcat会辣么大??

    1533692774507

    采用这种分层结构的好处

    最大的一个好处就是--共享资源
    

    比如:有多个进行都是从相同的A镜像构建而来,那么宿主机只需要在磁盘上保存一份A镜像,内存中只需要加载一份A镜像,就可以为所有容器服务了。

    2、生成镜像Demo

    1.从Hub上下载tomcat镜像到本地并运行

    #                 对外暴露端口 内部使用端口
    $ sudo docker run -it -p 8888:8080 tomcat
    

    1533694709925

    2.故意删除tomcat容器的文档

    1533695118951

    1533695072321

    3.以当前运行的tomcat作为模板,提交生成新的镜像

    $ sudo docker commit -a="作者" -m="描述信息" 容器id 要创建的镜像名:[标签名]
    # eg.
    $ sudo docker commit -a="x5456" -m="del tomcat docs" 70c6fc38df47 x5456/tomcat:2.0
    

    4.启动我们生成的镜像

    1533695613314

    1533695579312

    五、Docker的数据管理

    部分参考于:这里

    生产环境中使用Docker的过程中,容器中会产生数据,如果不通过commit命令生成一个新的镜像,当容器删除后,其中数据就没有了,所以我们往往需要**对数据进行持久化**,或者需要在**多个容器之间进行数据共享**,这必然涉及容器的数据管理操作。
    

    容器中管理数据主要有两种方式:

    1. 数据卷(Data Volumes):容器内数据直接映射到本地主机环境;如何在容器内创建数据卷,并且把本地的目录或文件挂载到容器内的数据卷中。
    2. 数据卷容器(Data Volume Containers):使用特定容器维护数据卷。如何使用数据卷容器在容器和主机、容器和容器之间共享数据,并实现数据的备份和恢复。

    1、数据卷

    可以用于同步代码
    

    1)使用命令添加

    $ sudo docker run -v 宿主机绝对路径:容器内目录 镜像id/镜像名
    
    # 这样宿主机和容器中的这两个目录就联系起来了
    $ sudo docker run -v /myData:/ContainerData centos
    
    # 可以在目录后面加上:ro表示只读,这样有:ro的内个目录就只有read权限
    $ sudo docker run -v /myData:/ContainerData:ro centos
    

    2)采用DockerFile进行添加

    1.书写DockerFile文件dockerfile2

    FROM centos
    VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2"]
    CMD echo "finished,--------success1"
    CMD /bin/bash
    

    2.使用命令生成镜像

    $ sudo docker build -f dockerfile2 -t x5456/centos .
    

    1533706308408

    3.由于我们上面命令没有指定宿主机的位置,所以我们需要查看容器详细信息

    $ sudo docker inspect 724f7b7a9793
    

    1533706983968

    2、数据卷容器

    如果用户需要在**多个容器之间共享一些持续更新的数据**,最简单的方式是使用数据卷容器。数据卷容器也是一个容器,但是它的目的是专门用来提供数据卷供其他容器挂载。
    

    1.创建一个数据卷容器dbdata,并在其中创建一个数据卷挂载到/dbdata:

    $ docker run -it -v /dbdata --name dbdata centos
    root@3ed94f279b6f:/#
    

    2.查看/dbdata目录:

    root@3ed94f279b6f:/# ls
    
    bin  boot  **dbdata**  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run sbin  srv  sys  tmp  usr  var
    

    3.在其他容器中使用--volumes-from来挂载dbdata容器中的数据卷.

    例如创建db1和db2两个容器,并从dbdata容器挂载数据卷:

    $ docker run -it --volumes-from dbdata --name db1 ubuntu
    
    $ docker run -it --volumes-from dbdata --name db2 ubuntu
    

    此时,容器db1和db2都挂载同一个数据卷到相同的/dbdata目录。三个容器任何一方在该目录下的写入,其他容器都可以看到。

    例如,在dbdata容器中创建一个test文件,如下所示:

    root@3ed94f279b6f:/# cd /dbdata
    
    root@3ed94f279b6f:/dbdata# touch test
    
    root@3ed94f279b6f:/dbdata# ls
    
    test
    

    在db1容器内查看它:

    $ docker run -it --volumes-from dbdata --name db1  ubuntu
    
    root@4128d2d804b4:/# ls
    bin  boot  dbdata  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
    
    root@4128d2d804b4:/# ls dbdata/
    test
    

    4.数据卷的生命周期一直会持续到没有容器使用他时

    六、Dockerfile

    Dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本。

    1、Dockerfile基础知识:

    1)每条保留字指令都必须是大写字母且后面要跟随至少一个参数

    2)指令从上到下顺序执行

    3)#表示注释

    4)每条指令都会创建一个新的镜像层,并对镜像进行提交

    1533868028319

    2、Docker执行Dockerfile的流程

    1)Docker从基础镜像运行一个容器

    2)执行一条指令就对容器进行修改

    3)执行完一条指令就使用类似docker commit的操作提交一个新的镜像层

    4)docker再基于刚刚提交的镜像运行一个新容器

    由于镜像是由多个镜像层组成的,所以提交一个镜像层 <==> 生成了一个新镜像
    

    5)继续执行下一条指令,直到所有指令都执行完毕

    1533868603224

    从应用软件的角度上来看,Dockerfile、Docker镜像与Docker容器分别代表软件的三个不同阶段

    • Dockerfile:软件原材料,面向开发
    • Docker镜像:软件的交付品
    • Docker容器:软件运行状态

    1533869113643

    3、Dockerfile的保留字指令

    1)FROM

    基础镜像,当前镜像是基于哪个镜像的

    2)MAINTAINER

    镜像维护者的姓名和邮箱地址

    3)RUN

    容器构建时需要运行的命令

    1533869585666

    4)EXPOSE

    容器对外暴露的端口

    5)WORKDIR

    指定创建容器后,终端默认登陆进来的工作目录

    6)ENV

    在构建镜像过程中设置环境变量

    eg:

    # 声明一个环境变量,这个变量可以在后续的任何指令中使用
    ENV MY_PATH /usr/test
    # 比如设置工作目录
    WORKDIR	$MY_PATH
    

    7)ADD

    将宿主机目录下的文件copy进镜像,而且ADD命令会自动处理URL和解压压缩包

    8)COPY

    将文件copy到镜像中

    9)VOLUME

    容器数据卷,用于数据的保存和持久化工作

    10)CMD

    指定容器启动时要运行的命令

    • Dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换
      • 类似docker run /bin/sh xxx这种

    11)ENTRYPOINT

    指定容器启动时要运行的命令

    * ENTRYPOINT会==追加==docker run之后的参数
    

    12)ONBUILD

    当构建一个被继承的Dockerfile时运行的命令,父镜像在被子镜像继承后触发这个命令

    七、将镜像发布到阿里云上

    1.创建镜像仓库

    1533708554813

    1533708642369

    2.将镜像推送到阿里云上

    $ sudo docker login --username=1203901753@qq.com registry.cn-hangzhou.aliyuncs.com
    #                 本地镜像id                                        想要在阿里云上显示的版本号
    $ sudo docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/x5456/centos:[镜像版本号]
    $ sudo docker push registry.cn-hangzhou.aliyuncs.com/x5456/centos:[镜像版本号]
    

    1533709140661

    $ sudo docker login --username=1203901753@qq.com registry.cn-hangzhou.aliyuncs.com
    #                 本地镜像id                                        想要在阿里云上显示的版本号
    $ sudo docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/x5456/springboot:[镜像版本号]
    $ sudo docker push registry.cn-hangzhou.aliyuncs.com/x5456/springboot:[镜像版本号]
    

    3.在阿里云上查看

    1533709210050

    Docker安装Oracle

  • 相关阅读:
    java学习笔记3
    java学习笔记 2
    linux用户登录指定目录
    [Jenkins 新插件] 兼容阿里开发手册 (P3C) 的火线插件安装使用教程
    Color a Tree HDU
    网络流初步
    K度限制MST poj 1639
    曼哈顿距离MST
    ACM Amman Collegiate Programming Contest(7.22随机组队娱乐赛)
    HDU Distinct Values
  • 原文地址:https://www.cnblogs.com/x54256/p/9541124.html
Copyright © 2011-2022 走看看