一款产品从开发到上线,从操作系统,到运行环境,再到应用配置。作为开发+运维之间的协作需要关心很多西,这也是很多互联网公司都不得不面对的问题,特别是各种版本的迭代之后,不同版本环境的兼容,对运维人员都是考验。
Docker之所以发展如此迅速,也是因为它对此给出了一个标准化的解决方案。开发人员利用 Docker 可以消除协作编码时“在我的机器上可正常工作”的问题。透过镜像(images)将作业系统核心,运作应用程式所需要的系统环境,由下而上打包,达到应用程式跨平台间的无缝接轨运作。
Docker是基于Go语言实现的云开源项目。Docker的主要目标是“Build,Ship and Run Any App, Anywhere”。运行环境能够做到“一次封装,到处运行”。
虚拟机(virtual machine)就是带环境安装的一种解决方案,虚拟机的缺点:资源占用多、冗余步骤多 、启动慢。
Linux 容器不是模拟一个完整的操作系统,而是对进程进行隔离。有了容器,就可以将软件运行所需的所有资源打包到一个隔离的容器中。容器与虚拟机不同,**不需要捆绑一整套操作系统,只需要当前软件工作所需的库资源和设置。**系统因此而变得高效轻量并保证部署在任何环境中的软件都能始终如一地运行。
二者的不同之处:
传统虚拟机技术是虚拟出一套硬件后,在其上运行一个完整操作系统,在该系统上再运行所需应用进程;
而容器内的应用进程直接运行于宿主的内核,容器内没有自己的内核,而且也没有进行硬件虚拟。因此容器要比传统虚拟机更为轻便。每个容器之间互相隔离,每个容器有自己的文件系统 ,容器之间进程不会相互影响,能区分计算资源。
Docker有三个重要的概念:仓库、镜像和容器 ,它们是Docker的三大基础组件。
Docker本身是一个容器运行载体或称之为管理引擎。我们把应用程序和配置依赖打包好形成一个可交付的运行环境,这个打包好的运行环境就是image镜像文件。只有通过这个镜像文件才能生成Docker容器。image文件可以看作是容器的模板。Docker根据镜像文件生成容器的实例。同一个image文件,可以生成多个同时运行的容器实例。仓库(Repository)是集中存放镜像文件的场所。
安装以CentOS6.8为例
step1:安装EPEL包
yum install -y epel-release
step2:安装Docker
yum install -y docker-io
安装后的配置文件在:/etc/sysconfig/docker
step3:启动Docker
service docker start
docker version
step4:配置阿里云镜像加速
https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors
找到自己的加速器地址:https://xxxx.mirror.aliyuncs.com
vim /etc/sysconfig/docker
将获得的自己账户下的阿里云加速地址配置进:
other_args="--registry-mirror=https://自己的账号加速信息.mirror.aliyuncs.com"
重启Dockerservice docker restart
即可
step5:测试HelloWorld
docker run hello-world
Docker运行原理:
Docker是一个Client-Server结构的系统,Docker守护进程运行在主机上,然后通过Socket连接从客户端访问,守护进程从客户端接受命令并管理运行在主机上的容器。
当新建一个虚拟机时,虚拟机软件需要加载Guest OS,返个新建过程是分钟级别的。而Docker由于直接利用宿主机的操作系统,则省略了返个过程,因此新建一个Docker容器只需要几秒钟。
docker version
docker info
docker --help
docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
hello-world latest 9f5834b25059 14 months ago 1.84 kB
docker search
搜索某个镜像名称(从http://hub.docker.com)
>> docker search tomcat
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
tomcat Apache Tomcat is an open source implementa... 2659 [OK]
tomee Apache TomEE is an all-Apache Java EE cert... 75 [OK]
dordoka/tomcat Ubuntu 14.04, Oracle JDK 8 and Tomcat 8 ba... 53 [OK]
bitnami/tomcat Bitnami Tomcat Docker Image 31 [OK]
kubeguide/tomcat-app Tomcat image for Chapter 1 28 [OK]
docker pull 镜像名称[:TAG]
下载镜像
[root@hadoop1 /]# docker pull tomcat
latest: Pulling from tomcat
ed7bc7435c95: Pull complete
......
Digest: sha256:613e0884313f0da2e3b536c0c1c1850a9df405055e78320eb24b1559b708fa3c
Status: Downloaded newer image for tomcat:latest
docker rmi 镜像名称[:TAG]
删除镜像
有镜像才能创建容器
docker run [OPTION] IMAGE [COMMAND][ARG...]
新建并启动容器
ip:hostPort:containerPort
ip::containerPort
hostPort:containerPort
containerPort
>> docker run -it --mycentos 2f5f33207762
[root@hadoop1 桌面]# docker run -it efa3cf
[root@a596cb0250f4 /]# ll
docker ps [OPTIONS]
列出正在运行的容器
OPTIONS说明(常用):
[root@hadoop1 桌面]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a596cb0250f4 efa3cf "/bin/bash" 5 minutes ago Up 5 minutes desperate_turing
exit
容器停止并退出
Ctrl + P + Q
容器不停止退出
docker start 容器ID
启动容器
docker restart 容器ID
重启容器
docker stop 容器ID
停止容器
docker kill 容器ID
强制停止容器
docker rm 容器ID
删除已停止容器
docker run -d centos /bin/sh -c "while true;do echo hello zzyy;sleep 2;done"
上面命令是启动守护式容器,不显示终端,可以通过查日志了解运行情况
docker logs -f -t --tail 倒数几条 容器ID
查看容器内运行的进程:docker top 容器ID
查看容器内部细节:docker inspect 容器ID
进入正在运行的容器并以命令行交互:
直接进入容器启动命令的终端,不会启动新的进程
docker attach 容器ID
是在容器中打开新的终端,并且可以启动新的进程
docker exec -it 容器ID bashShell
从容器内拷贝文件到主机上:docker cp 容器ID:容器内路径 目标主机路径
镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。
UnionFS(联合文件系统):Union文件系统(UnionFS)是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录。
在下载的过程中我们可以看到docker的镜像好像是在一层一层的在下载。
为什么一个Tomcat镜像500Mb:因为它有很多层依赖
分层的原因:
分层最大的一个好处就是共享资源
有多个镜像都从相同的base镜像构建而来,那么宿主机只需在磁盘上保存一份base镜像;
同时内存中也只需加载一份base镜像,就可以为所有容器服务了,而且镜像的每一层都可以被共享。
Docker镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部,这一层通常被称为容器层,容器层之下的都叫镜像层。
docker cp 容器ID:容器内路径 目标``docker cp 容器ID:容器内路径 目标主机路径
docker commit
提交容器副本使之成为一个新的镜像。
docker commit -m="提交的描述信息" -a="作者" 容器ID 要创建的目标镜像名:[标签名]
以删除Tomcat中的docs目录并打包镜像为例:
docker run -it -p 8888:8080 tomcat:6.0
docker exec -it dd48eb572cfa /bin/bash
docker commit -a="tulong" -m="del tomcat docs" dd48eb572cfa tulong/mytomcat:1.2
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
tulong/mytomcat 1.2 5af170c2e5bd 5 seconds ago 354.7 MB
Docker容器产生的数据,如果不通过docker commit生成新的镜像,使得数据做为镜像的一部分保存下来,那么当容器删除后,数据自然也就没有了。为了能保存数据在docker中我们使用容器数据卷。
卷的设计目的就是数据的持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数卷,其特点为:
将容器与宿主机之间文件绑定:
docker run -it -v /宿主机目录:/容器内目录 centos /bin/bash
查看数据卷是否挂在成功:
docker inspect 容器ID
容器与宿主机之间数据共享:
容器停止退出后,主机修改后数据同步。
只读权限:docker run -it -v /宿主机绝对路径目录:/容器内目录 ro 镜像名
Dockerfile为Image的描述文件
可在Dockerfile中使用VOLUME指令来给镜像添加一个或多个数据卷:
# volume test
FROM centos
VOLUME ["/dataVolumeContainer1","/dataVolumeContainer2"]
CMD echo "finished,--------success1"
CMD /bin/bash
build后生成新镜像:
docker build -f /mydocker/dockerfile -t tulong/centos
run容器后自动挂载了两个目录/dataVolumeContainer1
和/dataVolumeContainer2
命名的容器挂载数据卷,其它容器通过挂载这个(父容器)实现数据共享,挂载数据卷的容器,称之为数据卷容器.
dc02继承自dc01:
docker run -it --name dc02 --volumes-from dc01 tulong/centos
dc03继承自dc02
在dc01、dc02、dc03任意一个添加文件其它两个都会存在。
结论:容器之间配置信息的传递,数据卷的生命周期一直持续到没有容器使用它为止
Dockerfile是用来构建Docker镜像的构建文件,是由一系列命令和参数构成的脚本。
构件步骤:
CentOS6.8 的 Dockerfile:
FROM scratch
MAINTAINER The CentOS Project
ADD c68-docker.tar.xz /
LABEL name="CentOS Base Image" \
vendor="CentOS" \
license="GPLv2" \
build-date="2016-06-02"
Dockerfile文件内容:
Docker执行Dockerfile的大致流程:
FROM:基础镜像,当前镜像是基于那个镜像的;
MAINTAINER:作者、邮箱;
RUN:容器构建时需要运行的命令;
EXPOSE:暴露端口号,启动容器的时候还需使用 –p 指定端口;
WORKDIR:指定在创建容器后,终端默认登录后进来的工作目录,一个落脚点,默认根目录,通常绝对路径,CMD ENTRYPOINT 都会在这个目录下执行;
ENV:构建镜像的过程中设置环境变量, 构建和运行时都有效可以使用$引用;
ADD:将宿主机目录下的文件拷贝到镜像且会自动处理URL和解压tar压缩包;
COPY:拷贝文件和目录到镜像中,将从构建上下文目录中<源路径>的文件/复制到新的一层镜像内<目标路径>的位置。语法:COPY src dest COPY [“src”, “desc”];
VOLUME:容器数据卷, 数据保存和持久化;
USER:指定该镜像由什么用户运行,不指定由root 运行;
CMD:指定容器启动时要运行默认的命令,Dockerfile中可以有多个cmd , 但只有最后一个生效;
ENTERPOINT:指定容器启动时要运行的命令。
自定义mycentos目的使镜像具备:登陆后的默认路径、vim编辑器、查看网络配置ifconfig支持。
FROM centos
MAINTAINER zzyy
ENV MYPATH /usr/local
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
step1: 首先创建文件夹存放jdk与tomcat的安装包
mkdir -p /tulong/mydockerfile/tomcat9
step2:将jdk和tomcat安装的压缩包拷贝进上一步目录
apache-tomcat-9.0.8.tar.gz
与jdk-8u171-linux-x64.tar.gz
step3:在/tulong/mydockerfile/tomcat9目录下新建Dockerfile文件
FROM centos
MAINTAINER zzyy
#把宿主机当前上下文的c.txt拷贝到容器/usr/local/路径下
COPY c.txt /usr/local/cincontainer.txt
#把java与tomcat添加到容器中
ADD jdk-8u171-linux-x64.tar.gz /usr/local/
ADD apache-tomcat-9.0.8.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_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
#启动时运行tomcat
# ENTRYPOINT ["/usr/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.8/bin/startup.sh && tail -F /usr/local/apache-tomcat-9.0.8/bin/logs/catalina.out
step4:构件镜像
docker build -t mytomcat
step5:运行容器
docker run -d -p 9080:8080 --name myt9
-v /zzyyuse/mydockerfile/tomcat9/test:/usr/local/apache-tomcat-9.0.8/webapps/test
-v /zzyyuse/mydockerfile/tomcat9/tomcat9logs/:/usr/local/apache-tomcat-9.0.8/logs
--privileged=true zzyytomcat9
注:test目录中加入war包可以挂载到容器内,容器中logs文件中产生的日志可以同步到主机上。
Docker全流程示意图: