参考资料
 
1. Docker 的简介  
开发和运维的环境与配置不同,相同的代码可能跑不起来。 或者说之前开发交给运维的是代码,现在开发交给运维的是代码及其相关的环境配置数据等全家桶。
镜像(image)即应用:运行文档,配置环境,运行环境,运行依赖包,内核,操作系统 容器(container):每个容器内运行一个应用, 仓库(repository):每个仓库存放某一类镜像
虚拟机:模拟一个完整的操作系统,启动慢,资源占用多 Linux容器(LXC): 只需要软件工作所需的库资源和设置,按需取设置
虚拟机需要虚拟出一套硬件,进而运行一个完整的操作系统,进而运行进程 
容器的应用进程直接运行于宿主的内核,没有自己的内核,也没有硬件虚拟 
每个容器之间相互隔离,且每个容器有自己的文件系统,容器之间进程互相不会影响 
 
 
 
2. Docker 安装 2.1 虚拟机安装: 
虚拟机使用NAT网络配置
centos7.0
镜像(image): 就是一个只读的模板,镜像可以用来创建Docker容器,一个镜像可以创建多个容器。是一个模板,类似java的类。 容器(container): 是镜像的一个实例,类似java的实例。一个镜像可以生成多个容器。 容器是用镜像创建的运行实例,可以被启动、开始、停止、删除,相互之间独立。可以认为容器是一个简易版的Linux环境和运行在其中的应用程序。容器的定义和镜像基本一样,区别是容器的最上面一层是可读可写。 仓库(Repository)是集中存放镜像文件的场所。仓库(Repository)与仓库注册服务器(Registry)是不同的。仓库注册服务器上存放多个仓库,每个仓库存放多个镜像,每个镜像有不同的标签(tag)(版本号)。国内的仓库主要是阿里云和网易云等。
image文件生成的容器实例。image本身也是一个文件,称为镜像文件 一个容器运行一个服务。可以通过docker客户端创建一个对应的运行实例,即容器
如无特殊说明,假设本章的命令都是root权限运行 。
2.2 Docker 安装 
 
测试hello-world:docker_host就是本地的主机,hello-world是docker-hub中自带的一个镜像,从 Registry 中获取 hello-world 镜像到本地,并在本地运行一个容器实例
安装docker后每次运行都输入sudo :
1 2 3 4 5 6 7 8 9 10 $sudo  groupadd docker    $sudo  gpasswd -a $USER  docker    $newgrp  docker    sudo service docker restart 当前用户退出重新登录 sudo chown  "$USER " :"$USER "  /home/"$USER " /.docker -R sudo chmod  g+rwx "/home/$USER /.docker"  -R 
 
配置阿里云加速 镜像加速器
https://cr.console.aliyun.com/cn-hangzhou/instances/repositories 
可以使用 docker info 命令,查看 registry Mirrors 是否是注册的镜像
1 2 3 4 docker info Registry Mirrors:   https://uignadd2.mirror.aliyuncs.com/ 
 
docker 命令 docker run 1 2 3 4 5 6 docker build docker pull docker run docker images docker ps 
 
docker 客户端 run (容器)之后,依次从 docker 主机(docker 主线程 Docker_daemon) 的本地镜像(images)、registry寻找对应的镜像
 
docker常用命令 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 systemctl restart docker.service  docker info docker run hello-world service docker restart ps -ef | grep docker docker version docker --help  docker images  docker search tomcat docker pull tomcat docker pull tomcat:latest docker rmi tomcat docker save image > /root/image.tar  docker load -i /root/image.tar  docker run centos  docker run -it centos  docker run -it centos /bin/bash  docker run -d centos  docker ps  docker ps -n 2 exit  / ctrl+P+Q docker start 容器ID或者容器名  docker restart 容器ID或者容器名 docker stop 容器ID或者容器名  docker kill  容器ID或者容器名  docker rm  [-f] 容器ID或者容器名  docker rm  -f $(docker ps -q) docker logs -f -t -tail  容器ID  docker run -d centos /bin/bash -c "while true;do echo hello world;sleep 2;done"  docker top 容器ID  docker inspect 容器ID或者镜像名  docker attach 容器ID  docker exec  -t 容器ID /bin/bash  docker exec  -t 容器ID ls   docker cp  容器ID:容器内路径 目的主机路径  
 
docker 底层原理 docker 是C-S结构的系统,Docker守护进程运行在主机上,然后通过Socket连接从客户端访问,守护进程从客户端接受命令并管理运行在主机上的容器,而容器是运行时环境,即集装箱。
Docker比VM快:不需要 Hypervisor实现硬件资源虚拟化,不需要重新加载操作系统
镜像是分层的,所以每个镜像都会涉及到其他的镜像,比如 pull tomcat 的时候,不仅仅会下载tomcat,也会下载其他好多的镜像。
docker 容器后台运行,就必须有一个前台进程。 容器运行的命令如果不是一直挂起的命令(top, tail),是会自动退出的。 或者可以理解成如果docker容器不执行任何操作,那么就会被自动退出。
Docker镜像 镜像简介 关键词:分层,UnionFS,共享资源
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件。
是 UnionFS (联合文件系统),支持对文件系统的修改作为一次提交来一层层的提交(不懂)。即Docker是一层层的文件系统组成。
镜像加载原理:bootfs(bootloader, kernal)—>rootfs 镜像的最底层是bootfs,开机加载bootfs,加载之后内核都在内存中,然后卸载bootfs 镜像的OS很小:所以对于镜像的OS,rootfs可以很小,只需要包括最基本的命令、工具等,并且底层直接使用Host的kernal tomcat比较大:因为从底层到高层分别是 kernal—centos—jdk8—tomcat
分层的优点:共享资源,简单来说,会有多个镜像基于同一个base镜像构建而来,只需要启动一个base镜像,就可以为所有容器服务,或者说多个镜像的共同部分也只需要启动一次,这是依赖于镜像的不可读性质,或者理解成相同依赖包只需要下载一次。这样就形成了镜像之间共享,容器之间独立的局面。
镜像commit docker commit 提交容器副本使之成为一个新的镜像
1 2 3 4 5 6 docker images docker images tomcat docker run -it -p 8080 :8080  tomcat  docker exec  -t 容器ID docker commit -a "zzyy"  -m "tomcat without docs"  容器ID atguigu/mytomcat:1.2  
 
Docker容器 数据卷 数据卷的目的:将容器产生的数据持久化
数据卷可以在容器之间共享或者重用数据 卷中的更改可以直接生效 数据卷中的更改不会包含在镜像的更新中 数据卷的生命周期一直持续到没有容器使用它为止
1 2 3 4 5 6 7 8 9 docker run -it -v /宿主机绝对路径:/容器内目录 镜像名 docker run -it -v /HostDataVolume:/dataVolume centos docker run -it -v /HostDataVolume:/dataVolume:ro centos 
 
Dockerfile 可以简单理解成镜像的源码或者配置文件或者描述文件 images—DokerFile     hello.java—hello.class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 mkdir  mydockercd  mydockervim Dockerfile FROM centos VOLUME ["/dataVolumeContainer1" ,"/dataVolumeContainer2" ] CMD echo  "finished"  CMD /bin/bash VOLUME["/dataVolumeContainer1" ,"/dataVolumeContainer2" ,"/dataVolumeContainer3" ]  docker run -it -v /host1:/dataVolumeContainer1 -v /host2:/dataVolumeContainer2 centos /bin/bash docker build -f /mydocker/Dockerfile -t zzyy/centos . Sending build context to Docker daemon  2.048kB Step 1/4 : FROM centos  ---> 0f3e07c0138f Step 2/4 : VOLUME ["/dataVolumeContainer1" ,"/dataVolumeContainer2" ]  ---> Running in  60eece724d99 Removing intermediate container 60eece724d99  ---> 6628dbbcafdc Step 3/4 : CMD echo  "finished"   ---> Running in  5942462d32f5 Removing intermediate container 5942462d32f5  ---> 12c8dd40b04e Step 4/4 : CMD /bin/bash  ---> Running in  4b4fc0fae3ee Removing intermediate container 4b4fc0fae3ee  ---> 6dccc6a1e127 Successfully built 6dccc6a1e127 Successfully tagged zzyy/centos:latest docker run -it zzyy/centos /bin/bash ls /dataVolumeContainer1 /dataVolumeContainer2 docker ps docker inspect container ID 
 
tips:Docker挂载主机目录 Docker 访问出现 cannot open directory:Permission denied 解决方法:在挂载目录后加 —privileged=true
1 docker run -it -v /HostDataVolume:/dataVolume centos --privileged=true  
 
Docker 数据卷容器 数据卷容器:实现容器间的传递共享
 
数据卷容器:命名的容器挂载数据卷,其他容器通过挂载这个(父容器)实现数据共享,挂载数据卷的容器,称之为数据卷容器。
以上一步建立的 zzyy/centos 为例,此时 zzyy/centos 已经自带容器 /dataVolumeContainer1 /dataVolumeContainer2,运行容器 dc01/dc02/dc03,目的是dc02 dc03中的数据来自dc01
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 docker run -it --name dc01 zzyy/centos ls dataVolumeContainer1 dataVolumeContainer2 cd  dataVolumeContainer2touch  dc01_add.txtctrl+P+Q  docker run -it --name dc02 --volumes-from dc01 zzyy/centos ls dataVolumeContainer1 dataVolumeContainer2 cd  dataVolumeContainer2ls dc01_add.txt touch  dc02_add.txtctrl+P+Q  docker ps docker run -it --name dc03 --volumes-from dc01 zzyy/centos cd  dataVolumeContainer2ls dc01_add.txt dc02_add.txt touch  dc03_add.txtctrl+P+Q  docker attach dc01 cd  dataVolumeContainer2ls dc01_add.txt dc02_add.txt dc03_add.txt docker inspect dc01 dcoker inspect dc02 docker rm  -f dc01 docker attach dc02 ls dc01_add.txt dc02_add.txt dc03_add.txt touch  dc02_update.txtctrl+P+Q docker attach dc03 ls dc01_add.txt dc02_add.txt dc03_add.txt dc02_update.txt 
 
Dockerfile 解析 构建三步骤: 手动编写 Dockerfile文件 docker build,获得镜像 docker run
Dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本。
Dockerfile 内容解析 规则: 每条保留字指令必须大写且必须跟随至少一个参数 指令从上到下顺序执行 # 表示注释 每条指令都会创建一个新的镜像层,并对镜像进行提交
执行过程: docker从基础镜像运行一个容器 执行一个指令并对容器进行修改 执行类似docker commit的操作提交一个新的镜像层 docker再基于刚刚提交的镜像运行一个新容器 再次执行下一个指令直到全部指令执行完成
Dockerfile面向开发,Docker镜像面向交互,Docker容器涉及部署与运维 Dockerfile—build—>Docker image—run—>Docker容器
 
Dockerfile体系结构 
关键字 
作用 
 
 
FROM 
基础镜像 
 
MAINTAINER 
镜像维护者的姓名和邮箱 
 
RUN 
容器构建时需要运行的命令 
 
EXPOSE 
当前容器对外暴露的端口 
 
WORKDIR 
指定当创建容器后,终端默认登录的进来工作目录 
 
ENV 
构建镜像过程中设置环境变量,可用于后续的RUN指令之类的 
 
ADD 
拷贝+解压:将宿主机目录下的文件拷贝到镜像并且自动处理URL和解压tar压缩包 
 
COPY 
拷贝文件和目录到镜像中 
 
COPY src dest 
COPY [“src”,”dest”] 
 
VOLUME 
容器数据卷,保存数据和持久化 
 
CMD 
指定容器启动时要运行的命令,Dockerfile可以执行多个CMD指令,但是只有最后一个生效,并且CMD指令会被docker run后面的参数替换 
 
ENTRYPOINT 
指定容器启动时允许的命令,多个都可以生效,并且docker run后面的命令会追加到ENTRYPOINT后 
 
ONBUILD 
当构建一个被继承的Dockerfile时运行命令,父镜像在被子继承后父镜像的onbuild被触发 
 
 
 
Dockerfile 案例-自定义镜像mycentos base镜像:scratch
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 docker run -it centos /bin/bash pwd / [root@68e65a06005a /] bash: ifconfig: command  not found [root@68e65a06005a /] bash: vim: command  not found touch  DockerfileFROM centos ENV MYPATH /tmp 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 /mydocker/Dockerfile2 -t mycentos:1.3 . docker run -it mycentos:1.3 pwd vim abc ifconfig docker history  mycentos:1.3 
 
docker案例-CMD命令和ENTRYPOINT命令 1 2 3 4 5 docker run -it -p 8080:8080 tomcat docker run -it -p 8080:8080 tomcat ls   
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 touch  Dockerfile3FROM centos RUN yum install -y curl CMD ["curl" , "-s" , "http://www.baidu.com" ] docker run -it mybaidu  docker run -it mybaidu -i  touch  Dockerfile4FROM centos RUN yum install -y curl ENTRYPOINT ["curl" , "-s" , "http://www.baidu.com" ] docker run -it mybaidu  docker run -it mybaidu -i  
 
docker案例-ONBUILD命令案例 ONBUILD: 当构建一个被继承的Dockerfile时运行命令,父镜像在被子继承后父镜像的onbuild被触发
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 touch  Dockerfile5vi Dockerfile4 FROM centos RUN yum -y install curl ENTRYPOINT ["curl" , "-s" , "http://www.baidu.com"  ] ONBUILD RUN echo  "I am the father"  docker build -f /mydocker/Dockerfile5 -t mybaidu_father . touch  Dockerfile6FROM mybaidu_father RUN yum -y install curl ENTRYPOINT ["curl" , "-s" , "http://www.baidu.com"  ] docker build -f /mydocker/Dockerfile6 -t mybaidu_son . Step 1/3 : FROM mybaidu_father  ---> Running in  28b9a68efde1 I am the father Removing intermediate container 28b9a68efde1  ---> d35c7f097a70 
 
docker案例-自定义tomcat9 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 mkdir  -p /root/mydockerfile/tomcat9cd  /root/mydockerfile/tomcat9touch  c.txtapache-tomcat-9.0.8.tar.gz, jdk-8u171-linux-x64.tar.gz 下载链接见下面 ls apache-tomcat-9.0.8.tar.gz  c.txt  jdk-8u171-linux-x64.tar.gz FROM centos MAINTAINER tjj<tianjiajie1881090@163.com> COPY c.txt /usr/local/cincontainer.txt ADD jdk-8u171-linux-x64.tar.gz /usr/local ADD apache-tomcat-9.0.8.tar.gz /usr/local RUN yum -y install vim ENV MYPATH /usr/local WORKDIR $MYPATH  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 CMD /usr/local/apache-tomcat-9.0.8/bin/startup.sh && tail  -F /usr/local/apache-tomcat-9.0.8/bin/catalina.out docker build -f Dockerfile -t zzyytomcat9 . docker build -t zzyytomcat9 . docker run -d -p 9090:8080 --name mytom9 -v /root/mydockerfile/tomcat9/test:/usr/local/apache-tomcat-9.0.8/webapps/test -v /root/mydockerfile/tomcat9/tomcat9logs:/usr/local/apache-tomcat-9.0.8/logs --privileged=true  zzyytomcat9 localhost:9090 docker exec  myt9 ls  -l apache-tomcat-9.0.8 bin cincontainer.txt  etc games include jdk1.8.0_171 lib lib64 libexec sbin share src cd  /root/mydockerfile/tomcat9/testmkdir  WEB-INFcd  WEB-INFvim web.xml <?xml version="1.0"  encoding="UTF-8" ?> <web-app xmins:xsi="http://www.w3.org/2001/XMLSchema-instance"   xmins="http://java.sun.com/xml/ns/javaee"   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"   id ="WebApp_ID"  version="2.5" >  <display-name>test </display-name>  </web-app> cd  ..vim a.jsp <%@ page language="java"  contentType="text/html; charset=UTF-8"  pageEncoding="UTF-8" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"  "http://www.w3.org/TR/html4/loose.dtd" > <html>   <head >    <meta http-equiv="Content-Type"  content="text/html; charset=UTF-8" >    <title>Insert title here</title>   </head>   <body>    ----------welcome---------    <%="I am in docker tomcat self" %>    <br>    <br>    <% System.out.println("===========docker tomcat self" );%>   </body> </html> [root@localhost test ] a.jsp  WEB-INF [root@localhost test ] total 4 drwxr-xr-x. 2 root root  21 Dec  4 07:48 WEB-INF -rw-r--r--. 1 root root 496 Dec  4 07:57 a.jsp docker restart mytom9 vim a.jsp <%@ page language="java"  contentType="text/html; charset=UTF-8"  pageEncoding="UTF-8" %> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"  "http://www.w3.org/TR/html4/loose.dtd" > <html>   <head >    <meta http-equiv="Content-Type"  content="text/html; charset=UTF-8" >    <title>Insert title here</title>   </head>   <body>    ----------welcome---------<br>    <br>    <%="I am in docker tomcat self 3333333" %>    <br>    <br>    <% System.out.println("===========docker tomcat self" );%>   </body> </html> cd  /root/mydockerfile/tomcat9cd  ./tomcat9/logscat  catalina.out
 
apache-tomcat-9.0.8.tar.gz jdk-8u171-linux-x64.tar.gz jdk-8u171-linux-x64.tar.gz 华为云 
总结:
 
Docker 常用安装 1 2 3 4 5 6 docker search docker pull docker images docker run docker kill  docker rm  
 
Docker mysql 在Docker中安装mysql,用外部的机器(宿主机(centos),主机(windows))进行控制,并且docker操作mysql进行数据备份
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 docker search mysql docker pull mysql:5.6 docker images docker run -p 3306:3306 --name mysql -v /root/mysql/conf:/etc/mysql/conf.d -v /root/mysql/logs:/logs -v /root/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=123456 -d mysql:5.6 docker exec  -it mysql /bin/bash mysql -uroot -p mysql> show databases; +--------------------+ | Database           | +--------------------+ | information_schema | | mysql              | | performance_schema | +--------------------+ 3 rows in  set  (0.00 sec) create database db01; use db01; Database changed mysql> create table t_book(id  int not null primary key, bookName varchar(20)); mysql> show tables; mysql> insert into t_book values(1, 'java' ); mysql> select * from t_book; +----+----------+ | id  | bookName | +----+----------+ |  1 | java     | +----+----------+ mysql> select * from t_book; +----+----------+ | id  | bookName | +----+----------+ |  1 | java     | |  2 | oracle   | +----+----------+ 2 rows in  set  (0.00 sec) docker exec  mysql sh -c 'exec mysqldump --all-databases -uroot -p"123456" '  > /root/test1/all-databases.sql 
 
docker Redis 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 docker search redis docker pull redis:3.2 docker run -p 6379:6379 -v /root/myredis/data:/data -v /root/myredis/conf/redis.conf:/usr/local/etc/redis/redis.conf -d --name myredis redis:3.2 redis-server /usr/local/etc/redis/redis.conf --appendonly yes  vim /root/myredis/conf/redis.conf/redis.conf [root@localhost ~] 127.0.0.1:6379> set  k1 v1 OK 127.0.0.1:6379> set  k2 v2 OK 127.0.0.1:6379> set  k3 v3 OK 127.0.0.1:6379> SHUTDOWN cd  /root/myredis/datacat  appendonly.aof
 
本地镜像发布到阿里云 阿里云镜像服务控制台 
 
 
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 docker run -it mycentos:1.3 ctrl+P+Q docker commit -a zzyy -m "new mycentos with vim and ifconfig"  容器ID mycentos:1.4 docker images $ sudo docker login --username=15652211016 registry.cn-hangzhou.aliyuncs.com sudo docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/tianjiajie/mycentos:1.4.1 sudo docker push registry.cn-hangzhou.aliyuncs.com/tianjiajie/mycentos:1.4.1 docker rmi -f registry.cn-hangzhou.aliyuncs.com/tianjiajie/mycentos:1.4.1 docker pull registry.cn-hangzhou.aliyuncs.com/tianjiajie/mycentos:1.4.1 
 
docker-GPU 需要使用 nvidia-docker 
1 2 root@zbp-PowerEdge-T630:~ 
 
docker运行pytorch,依赖于宿主机的驱动版本。