docker基础命令/dockerfile制作镜像/docker-compose编排容器

参考文章:
docker-compose.yml详解 http://www.imooc.com/article/278410
docker-compose官网 https://docs.docker.com/compose/compose-file/#command

什么是docker

我们在理解 docker 之前,我们首先要了解一下虚拟化技术.

百度百科定义:
在计算机中,虚拟化(英语:Virtualization)是一种资源管理技术,是将计算机的各种实体资源,如服务器、网络、内存及存储等,予以抽象、转换后呈现出来,打破实体结构间的不可切割的障碍,使用户可以比原本的组态更好的方式来应用这些资源。这些资源的新虚拟部分是不受现有资源的架设方式,地域或物理组态所限制。一般所指的虚拟化资源包括计算能力和资料存储。
在实际的生产环境中,虚拟化技术主要用来解决高性能的物理硬件产能过剩和老的旧的硬件产能过低的重组重用,透明化底层物理硬件,从而最大化的利用物理硬件。

虚拟化分类:
分为:硬件级虚拟化和操作系统级虚拟化.

1.硬件级虚拟化:
我们用的传统虚拟机就是在硬件级别进行的虚拟化.例如 VMware , VisualBox 之类的需要模拟整台机器包括硬件,每台虚拟机都需要有自己的操作系统,虚拟机一旦被开启,预分配给它的资源将全部被占用。每一台虚拟机包括应用,必要的二进制和库,以及一个完整的用户操作系统。

图解硬件级虚拟化:
在这里插入图片描述

2.操作系统级虚拟化:
而容器技术是和我们的宿主机共享硬件资源及操作系统,可以实现资源的动态分配。容器包含应用和其所有的依赖包,但是与其他容器共享内核。容器在宿主机操作系统中,在用户空间以分离的进程运行。

容器技术是实现操作系统虚拟化的一种途径,可以让您在资源受到隔离的进程中运行应用程序及其依赖关系。通过使用容器,我们可以轻松打包应用程序的代码、配置和依赖关系,将其变成容易使用的构建块,从而实现环境一致性、运营效率、开发人员生产力和版本控制等诸多目标。容器可以帮助保证应用程序快速、可靠、一致地部署,其间不受部署环境的影响。容器还赋予我们对资源更多的精细化控制能力,让我们的基础设施效率更高。

而docker容器是 Linux 发展出了另一种虚拟化技术,简单来讲, docker容器不是模拟一个完整的操作系统,而是对进程进行隔离,相当于是在正常进程的外面套了一个保护层。对于容器里面的进程来说,它接触到的各种资源都是虚拟的,从而实现与底层系统的隔离。

Docker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里运行,就好像在真实的物理机上运行一样。有了 Docker ,就不用担心环境问题。

图解操作系统级虚拟化
在这里插入图片描述

为什么使用docker

Docker相比于传统虚拟化方式具有更多的优势:

  • docker 启动快速属于秒级别。虚拟机通常需要几分钟去启动
  • docker 需要的资源更少, docker 在操作系统级别进行虚拟化, docker 容器和内核交互,几乎没有性能损耗,性能优于通过Hypervisor 层与内核层的虚拟化
  • docker 更轻量, docker 的架构可以共用一个内核与共享应用程序库,所占内存极小。同样的硬件环境, Docker运行的镜像数远多于虚拟机数量,对系统的利用率非常高
  • 与虚拟机相比, docker 隔离性更弱, docker 属于进程之间的隔离,虚拟机可实现系统级别隔离
  • 安全性: docker 的安全性也更弱。 Docker 的租户 root 和宿主机 root 等同,一旦容器内的用户从普通用户权限提升为root权限,它就直接具备了宿主机的root权限,进而可进行无限制的操作。虚拟机租户 root 权限和宿主机的 root 虚拟机权限是分离的,并且虚拟机利用如 Intel 的 VT-d 和 VT-x 的 ring-1 硬件隔离技术,这种隔离技术可以防止虚拟机突破和彼此交互,而容器至今还没有任何形式的硬件隔离,这使得容器容易受到攻击
  • 高可用和可恢复性: docker对业务的高可用支持是通过快速重新部署实现的。虚拟化具备负载均衡,高可用,容错,迁移和数据保护等经过生产实践检验的成熟保障机制, VMware 可承诺虚拟机 99.999% 高可用,保证业务连续性
  • 快速创建、删除:虚拟化创建是分钟级别的, Docker 容器创建是秒级别的, Docker的快速迭代性,决定了无论是开发、测试、部署都可以节约大量时间
  • 交付、部署:虚拟机可以通过镜像实现环境交付的一致性,但镜像分发无法体系化。 Docker 在 Dockerfile中记录了容器构建过程,可在集群中实现快速分发和快速部署

docker详解

docker的运行机制:
启动一个dockerClient -> 拉取docker镜像(images) -> 启动镜像得到一个容器(contain) -> 容器中就是我们的程序.
在这里插入图片描述

使用docker

首先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

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所在的路径

实例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

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

这是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

在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是后台启动

使用idea连接docker并发布镜像

1.开启docker远程访问

vim   /etc/sysconfig/docker

添加   -H unix://var/run/docker.sock -H tcp://0.0.0.0:2375

在这里插入图片描述重启docker

systemctl daemon-reload

systemctl start docker

查看端口2375的占用,并关闭防火墙

netstat -tulp

在这里插入图片描述

2.idea安装docker插件
在这里插入图片描述
3.配置docker访问
在这里插入图片描述

4.在maven中引入docker插件

			<!--使用docker-maven-plugin插件-->
            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>1.0.0</version>
                <!--将插件绑定在某个phase执行-->
                <executions>
                    <execution>
                        <id>build-image</id>
                        <!--将插件绑定在package这个phase上。也就是说,用户只需执行mvn package ,就会自动执行mvn docker:build-->
                        <!--这里我测试docker-compose的时候注释掉了.需要使用的时候记得打开-->
                        <phase>package</phase>
                        <goals>
                            <goal>build</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <!--指定生成的镜像名,镜像名中不能有下划线特殊符号,可以:指定标签-->
                    <imageName>gty/${project.artifactId}:1.0</imageName>
                    <!--指定标签可以用<imageTags>标签,但是也可以name:tag指定-->
                    <!--指定维护者-->
                    <maintainer>gty</maintainer>
                    <!-- 指定 Dockerfile 路径-->
                    <dockerDirectory>${project.basedir}/docker</dockerDirectory>
                    <!--指定远程 docker api地址-->
                    <dockerHost>http://192.168.25.25:2375</dockerHost>
                    <!-- 这里是复制 jar 包到 docker 容器指定目录配置 -->
                    <resources>
                        <resource>
                            <targetPath>/</targetPath>
                            <!--jar 包所在的路径  此处配置的 即对应 target 目录-->
                            <directory>${project.build.directory}</directory>
                            <!-- 需要包含的 jar包 ,这里对应的是 Dockerfile中添加的文件名 -->
                            <include>${project.build.finalName}.jar</include>
                        </resource>
                    </resources>
                </configuration>
            </plugin>

5.在项目根目录下创建/docker/Dockerfile
在这里插入图片描述
6.项目打包,同时开始了Dockerfile的构建
在这里插入图片描述
3.在启动项中添加
在这里插入图片描述然后配置一下
在这里插入图片描述

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值