参考资料
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,依赖于宿主机的驱动版本。