参考文章:
docker-compose.yml详解 http://www.imooc.com/article/278410
docker-compose官网 https://docs.docker.com/compose/compose-file/#command
我们在理解 docker 之前,我们首先要了解一下虚拟化技术.
百度百科定义:
在计算机中,虚拟化(英语:Virtualization)是一种资源管理技术,是将计算机的各种实体资源,如服务器、网络、内存及存储等,予以抽象、转换后呈现出来,打破实体结构间的不可切割的障碍,使用户可以比原本的组态更好的方式来应用这些资源。这些资源的新虚拟部分是不受现有资源的架设方式,地域或物理组态所限制。一般所指的虚拟化资源包括计算能力和资料存储。
在实际的生产环境中,虚拟化技术主要用来解决高性能的物理硬件产能过剩和老的旧的硬件产能过低的重组重用,透明化底层物理硬件,从而最大化的利用物理硬件。
虚拟化分类:
分为:硬件级虚拟化和操作系统级虚拟化.
1.硬件级虚拟化:
我们用的传统虚拟机就是在硬件级别进行的虚拟化.例如 VMware , VisualBox 之类的需要模拟整台机器包括硬件,每台虚拟机都需要有自己的操作系统,虚拟机一旦被开启,预分配给它的资源将全部被占用。每一台虚拟机包括应用,必要的二进制和库,以及一个完整的用户操作系统。
2.操作系统级虚拟化:
而容器技术是和我们的宿主机共享硬件资源及操作系统,可以实现资源的动态分配。容器包含应用和其所有的依赖包,但是与其他容器共享内核。容器在宿主机操作系统中,在用户空间以分离的进程运行。
容器技术是实现操作系统虚拟化的一种途径,可以让您在资源受到隔离的进程中运行应用程序及其依赖关系。通过使用容器,我们可以轻松打包应用程序的代码、配置和依赖关系,将其变成容易使用的构建块,从而实现环境一致性、运营效率、开发人员生产力和版本控制等诸多目标。容器可以帮助保证应用程序快速、可靠、一致地部署,其间不受部署环境的影响。容器还赋予我们对资源更多的精细化控制能力,让我们的基础设施效率更高。
而docker容器是 Linux 发展出了另一种虚拟化技术,简单来讲, docker容器不是模拟一个完整的操作系统,而是对进程进行隔离,相当于是在正常进程的外面套了一个保护层。对于容器里面的进程来说,它接触到的各种资源都是虚拟的,从而实现与底层系统的隔离。
Docker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了 Docker ,就不用担心环境问题。
Docker相比于传统虚拟化方式具有更多的优势:
docker的运行机制:
启动一个dockerClient -> 拉取docker镜像(images) -> 启动镜像得到一个容器(contain) -> 容器中就是我们的程序.
首先docker并不是一个容器,docker是一个容器管理引擎.
使用docker要在liunx上使用,当然docker也有win版本.但是win版本依然是使用的win10系统的hype-v虚拟的liunx系统.在其中运行docker.
安装docker
使用centos 7 1810 版本
yum install docker -y # 使用yum直接安装
docker -version # 验证安装,查看版本
启动docker
service docker start # 启动docker
service docker status # 查看docker运行状态
service docker stop # 停止docker
常用的命令
docker # 显示帮助信息
docker info # 查看docker信息
docker search tomcat # 搜索所有的镜像
docker pull redis # 拉去镜像 docker pull java:8 可以冒号指定标签(版本)
docker images # 查看所有的镜像
生成容器
docker run tomcat # 运行容器
docker run -d -p 8080:8080 tomcat # -d 后台运行 -p 指定端口映射
docker exec -it 容器id bash # 进入容器的内部查看
docker ps 查看所有的正在运行容器 -a 所有的 -q只显示容器id
docker stop 容器id
配置Tomcat外部文件挂载
将war包或是HTML页面放在宿主机固定的位置就可以在Tomcat中发布.而不用将其复制进入容器的内部.
tomcat默认位置在 : /usr/local/tomcat/webapps
tomcat外部文件挂载:
1.不要在home下创建共享(挂载目录),权限问题,会无法访问.
2.创建/usr/local/webapps/web1目录(web1是Tomcat的上下文根)
3.将main.html放在目录下.
4.启动docker: 将webapps下的内容挂载到容器中. (是文件夹下的内容,不包含当前文件夹!!!!!!!!)
--name 指定容器的名称
docker run -d -p 8090:8080 -v /usr/webapps:/usr/local/tomcat/webapps --name tomcat44 tomcat
命令解释 -d 后台运行 -p 指点端口 -v 进行文件夹挂载 [宿主机路径:容器内路径]
--name 为容器创建一个名字
最后一个tomcat是:启动的镜像
5.启动之后访问 .../web1/main.html即可
启动mysql并进行数据持久化
mysql配置文件路径: /etc/mysql/my.conf
mysql的数据存储位置: /var/lib/mysql
mysql的命令bin位置: /usr/bin
1.创建 /usr/local/mysql/conf/my.conf文件,将容器内的my.conf复制出来.
2.创建/usr/local/mysql/data ,用于没有mysql的数据存放
3.运行镜像
docker run -p 3306:3306
-v /usr/local/mysql/conf/my.conf:/etc/mysql/my.conf # 文件的映射
-v /usr/local/mysql/data:/var/lib/mysql # ,目录的映射
-e MYSQL_ROOT_PASSWORD=112233 # 配置环境
--name mysql22
--privileged=true #提升容器内root用户权限为真正的root权限
-d mysql
4.在mysql中创建一个数据库, 停止容器,并删除. 运行一个新的镜像(数据目录挂载相同文件夹).
可以看到数据库存在.
docker数据卷
数据卷就是docker目录的挂载的固定路径.
查看数据卷:docker volume ls
清理无用的数据卷: docker volume prune
查看数据卷的具体指向:docker volume inspect 数据卷名
docker cp命令
将宿主机的内容复制到容器中
docker cp /usr/local/main.txt 96f7f14e99ab:/usr/tmp
docker查看容器日志
docker logs -f -t --tail 200 dda7df088656
-f动态的查看 -t --tail 使用tail方式查看
Dockerfile中包括FROM、MAINTAINER、RUN、CMD、EXPOSE、ENV、ADD、COPY、ENTRYPOINT、VOLUME、USER、WORKDIR、ONBUILD等13个指令。下面一一讲解。
1.FROM
格式为FROM image或FROM image:tag,并且Dockerfile中第一条指令必须是FROM指令,且在同一个Dockerfile中创建多个镜像时,可以使用多个FROM指令。
2.MAINTAINER
格式为MAINTAINER user_name user_email,指定维护者信息
这个已经过期,推荐使用LABLE k=v来使用.
3.RUN
格式为RUN command或 RUN [“EXECUTABLE”,“PARAM1”,“PARAM2”…],前者在shell终端中运行命令,/bin/sh -c command,例如:/bin/sh -c “echo hello”;后者使用exec执行,指定其他运行终端使用RUN["/bin/bash","-c",“echo hello”]
每条RUN指令将当前的镜像基础上执行指令,并提交为新的镜像,命令较长的时候可以使用\来换行,同时可以使用&&并列执行,减少镜像的层数。
4.CMD
支持三种格式:
CMD [“executable”,“param1”,“param2”],使用exec执行,这是推荐的方式。
CMD command param1 param2 在/bin/sh中执行。
CMD [“param1”,“param2”] 提供给ENTERYPOINT的默认参数。
CMD用于指定容器启动时执行的命令,每个Dockerfile只能有一个CMD命令,多个CMD命令只执行最后一个。若容器启动时指定了运行的命令,则会覆盖掉CMD中指定的命令。
5.EXPOSE
格式为 EXPOSE port [port2,port3,…],例如EXPOSE 80这条指令告诉Docker服务器暴露80端口,供容器外部连接使用。
在启动容器的使用使用-P,Docker会自动分配一个端口和转发指定的端口,使用-p可以具体指定使用哪个本地的端口来映射对外开放的端口。
6.ENV
格式为:EVN key value 。用于指定环境变量,这些环境变量,后续可以被RUN指令使用,容器运行起来之后,也可以在容器中获取这些环境变量。
例如
ENV word hello
RUN echo $word
7.ADD
格式:ADD src dest
该命令将复制指定本地目录中的文件到容器中的dest中,src可以是是一个绝对路径,也可以是一个URL或一个tar文件,tar文件会自动解压为目录。
8.COPY
格式为:COPY src desc
复制本地主机src目录或文件到容器的desc目录,desc不存在时会自动创建。
9.ENTRYPOINT
格式有两种:
ENTRYPOINT [“executable”,“param1”,“param2”]
ENTRYPOINT command param1,param2 会在shell中执行。
用于配置容器启动后执行的命令,这些命令不能被docker run提供的参数覆盖。和CMD一样,每个Dockerfile中只能有一个ENTRYPOINT,当有多个时最后一个生效。
10.VOLUME
格式为 VOLUME ["/data"]
作用是创建在本地主机或其他容器可以挂载的数据卷,用来存放数据。
11.USER
格式为:USER username
指定容器运行时的用户名或UID,后续的RUN也会使用指定的用户。要临时使用管理员权限可以使用sudo。在USER命令之前可以使用RUN命令创建需要的用户。
例如:RUN groupadd -r docker && useradd -r -g docker docker
12.WORKDIR
格式: WORKDIR /path
为后续的RUN CMD ENTRYPOINT指定配置工作目录,可以使用多个WORKDIR指令,若后续指令用得是相对路径,则会基于之前的命令指定路径。
13.ONBUILD
格式ONBUILD [INSTRUCTION]
该配置指定当所创建的镜像作为其他新建镜像的基础镜像时所执行的指令。
例如下面的Dockerfile创建了镜像A:
ONBUILD ADD . /app
ONBUILD RUN python app.py
则基于镜像A创建新的镜像时,新的Dockerfile中使用from A 指定基镜像时,会自动执行ONBBUILD指令内容,等价于在新的要构建镜像的Dockerfile中增加了两条指令:
FROM A
ADD ./app
RUN python app.py
14.docker build
创建好Dockerfile之后,通过docker build命令来创建镜像,该命令首先会上传Dockerfile文件给Docker服务器端,服务器端将逐行执行Dockerfile中定义的指令。
通常建议放置Dockerfile的目录为空目录。另外可以在目录下创建.dockerignore文件,让Docker忽略路径下的文件和目录,这一点与Git中的配置很相似。
通过 -t 指定镜像的标签信息,例如:docker build -t regenzm/first_image . ##"."指定的是Dockerfile所在的路径
1.构建一个jdk镜像,并输出java -version
FROM centos
MAINTAINER gty
ADD ["jdk-8u221-linux-x64.tar.gz","/usr/local/apps/"]
ENV JAVA_HOME /usr/local/apps/jdk1.8.0_221/
ENV PATH $PATH:$JAVA_HOME/bin/
CMD ["java","-version"]
执行命令
末尾的点不能少.是指的寻找 .dockerignore
docker build -t one11:1.0 .
也可以显示的指定Dockerfile的路径
docker build -t two22:1.0 -f Dockerfile.two .
2.构建一个jdk镜像,并输出java -version,练习使用一些复杂的过程控制
FROM centos
MAINTAINER gty
WORKDIR /usr/local/
COPY ["jdk-8u221-linux-x64.tar.gz","soft/"]
RUN mkdir apps &&\
tar -xf soft/jdk-8u221-linux-x64.tar.gz -C apps &&\
ln -s /usr/local/apps/jdk1.8.0_221/ apps/jdk
ENV JAVA_HOME apps/jdk/
ENV PATH $PATH:$JAVA_HOME/bin/
CMD java -version
3.自定一个项目,将其打包为镜像
FROM java:8
MAINTAINER gty
COPY 18-docker-1.0.0.jar /usr/local
ARG one11=0 # 定义一个变量,进行赋值测试
RUN echo $one11
EXPOSE 8080
CMD java -jar /usr/local/18-docker-1.0.0.jar
docker-compose是编排容器的。例如,你有一个php镜像,一个mysql镜像,一个nginx镜像。如果没有docker-compose,那么每次启动的时候,你需要敲各个容器的启动参数,环境变量,容器命名,指定不同容器的链接参数等等一系列的操作,相当繁琐。而用了docker-composer之后,你就可以把这些命令一次性写在docker-composer.yml文件中,以后每次启动这一整个环境(含3个容器)的时候,你只要敲一个docker-composer up命令就ok了。就好像是docker容器的构建过程记录一样.
dockerfile的作用是从无到有的构建镜像。它包含安装运行所需的环境、程序代码等。这个创建过程就是使用 dockerfile 来完成的。Dockerfile - 为 docker build 命令准备的,用于建立一个独立的 image ,在 docker-compose 里也可以用来实时 build docker-compose.yml - 为 docker-compose 准备的脚本,可以同时管理多个 container ,包括他们之间的关系、用官方 image 还是自己 build 、各种网络端口定义、储存空间定义等.
这是docker compose的GitHub主页发行版
https://github.com/docker/compose/releases/
1.下载从GitHub
-L 指定的是链接
-o (这是路径,指定到文件,docker-componse是文件名)
curl -L "https://github.com/docker/compose/releases/download/1.25.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
2.给docker-componse权限
chmod +x /usr/local/bin/docker-compose
3.注册环境变量
或者向java_home似的那样注册也行
ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
4.验证
docker-compose -version
在docker-compose.yml中可以包含一个Dockerfile,进行直接镜像构建和启动.
先构建两个web服务的镜像.然后编排进入redis和mysql
1.第一个Dockerfile
# 第一个Dockerfile.web11
FROM java:8
COPY 18-docker-1.0.0.jar /usr/local
ARG oneparam=default
ARG twoparam=default
RUN echo "oneparam是:$oneparam" && echo "twoparam是:$twoparam"
EXPOSE 8080
CMD java -jar /usr/local/18-docker-1.0.0.jar
第二个Dockerfile
# 第二个Dockerfile.web22
FROM java:8
COPY 18-docker-1.0.0-web22.jar /usr/local
EXPOSE 8080
CMD java -jar /usr/local/18-docker-1.0.0-web22.jar
3.编写docker-compose.yml
注释都有用法,注意缩进
version: '3'
#在这里声明服务s
services:
# 第一个容器服务,名字是web11
web11: # 这是服务名
container_name: web11 # 指定容器名
image: "web11:1.0" # 指定dockerfile构建的镜像名
build:
context: ./ # dockerfile上下文, ./ 表示当前docker-compose.yml的文件位置
dockerfile: ./Dockerfile.web11 # 相对于上下文的位置
args:
- oneparam="false" # 参数如果是Boolean,必须用"Boolean"括起来才能识别,否则就是字符串
- twoparam=19 # 可以给Dockerfile中的ARG参数传值传值
links: # 将Redis11容器的IP配置进web11容器的hosts文件, 包括redis11中的环境变量
# 例如 192.168.25.25 redis11 在web11中可以ping redis11,可以使用redis11作为redis的IP
- "redis11"
# 同时可以指定别名,会同时添加web22以及otherwebservice
- "web22:otherwebservice"
ports:
- "8080:8080" # - 指定一个列表,进行端口映射
depends_on: # 指定web11的启动需要在redis11之后在启动.
- "redis11" # 其实就是指定启动的顺序.使用depends_on后web11一定在redis11之后启动
- "mysql44"
extra_hosts: # 在/etc/hosts中添加对应的hosts解析
- "somehost:162.242.195.82"
- "otherhost:50.31.209.229" # 启动之后就会有 50.31.209.229 otherhost
# 这是第二个容器
web22:
container_name: web22
image: "web22:1.0"
build:
context: .
dockerfile: ./Dockerfile.web22
links:
- "redis11"
- "mysql44"
ports:
- "8081:8080"
# 这是第三个容器
redis11:
image: "redis"
container_name: redis11
ports: #端口映射
- "6379:6379"
# 这是第四个容器
mysql44:
image: mysql
container_name: mysql44
ports:
- 3306:3306
volumes:
# - /usr/local/mysql/data:/var/lib/mysql # 使用固定的目录挂载mysql的容器的目录
- /usr/local/mysql/conf/my.conf:/etc/mysql/my.conf
# 使用docker的路径挂载容器目录docker volume ls和docker volume inspect 目录名查看具体位置
- mysql-data:/var/lib/mysql
privileged: true # 提升容器内用户权限为真正的root权限
environment: # 配置环境变量
- MYSQL_ROOT_PASSWORD=112233
# 配置数据卷,与service平级
volumes:
mysql-data:
4.启动docker-compose
docker-compose up -d # -d是后台启动
1.开启docker远程访问
vim /etc/sysconfig/docker
添加 -H unix://var/run/docker.sock -H tcp://0.0.0.0:2375
systemctl daemon-reload
systemctl start docker
查看端口2375的占用,并关闭防火墙
netstat -tulp
4.在maven中引入docker插件
com.spotify
docker-maven-plugin
1.0.0
build-image
package
build
gty/${project.artifactId}:1.0
gty
${project.basedir}/docker
http://192.168.25.25:2375
/
${project.build.directory}
${project.build.finalName}.jar
5.在项目根目录下创建/docker/Dockerfile
6.项目打包,同时开始了Dockerfile的构建
3.在启动项中添加
然后配置一下