1.1、基本原理
Docker 是一个开源的应用容器引擎,基于 Go 语言 并遵从 Apache2.0 协议开源。
Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。
容器是完全使用沙箱机制,相互之间不会有任何接口。更重要的是容器性能开销极低。
Docker底层用的Linux的cgroup和namespace这两项技术来实现应用隔离,一个完整的Docker有以下几个部分组成:
- Docker Client:客户端。命令
- Docker Daemon:守护进程。
- Docker Image:镜像。
- Docker Container:容器。
- Docker Client:命令行工具,通过HTTP与dockerDamon 通信,执行指令
- Docker Damon 用来监听Docker API的请求和管理Docker对象,比如镜像、容器、网络和Volume。
组件
-
镜像(Image): docker镜像就相当于一个root 文件系统,比如官方镜像Ubuntu:16.08 就包含了完整的一套Ubuntu16.08 最小系统的root 文件系统。一个只读的模板,包含了运行应用程序所需要的所有文件、配置和依赖项。镜像可以被认为是容器的原型。镜像可以利用 Dockerfile 文件进行构建。
-
容器(Container):Docker 容器可以被看作是一个可运行的应用程序实例,是从 Docker 镜像生成的运行时环境。容器具有自己的根文件系统和资源隔离机制,并且可以通过端口映射来让它们之间互相通信。容器可以被创建,启动,停止,删除,暂停等。
创建过程
- 获取镜像,如docker pull centos
- 使用镜像创建容器
- 分配文件系统,挂载一个读写器,在读写层加载镜像。
- 分配网络、网桥接口,创建一个网络接口,让容器和宿主机通信
- 容器获取IP地址
- 执行容器命令,如 /bin/bash
- 反馈容器启动结果
- 仓库(Repository): 仓库可以看成一个代码控制中心,用来保存镜像。类型与github 可以用来拉取可用的各种镜像。
【其他】
- 文件系统:Docker 基于 AUFS(Advanced Multi-Layered Unification Filesystem) 实现了文件系统的隔离。AUFS 可将不同的文件系统挂载到同一个目录下,不同的容器之间共享相同的基础镜像。
- 网络 Docker 提供了多种网络模式来实现容器之间的通信,例如容器间通信、容器与主机之间通信,以及不同 Docker 主机之间的通信。Docker 还支持自定义网络,并可以为每个容器指定不同的网络配置
- 存储:Docker 的容器可以通过数据卷和挂载主机目录等方式实现数据的复制和持久化,从而保证数据的可靠性和持久性。
- Docker引擎:Docker的核心组件,是运行在宿主机的二进制文件。它主要由两个组件组成:Docker客户端和Docker服务端。客户端可以通过Docker命令与服务器端进行交互,服务端则负责管理容器和镜像等资源。
1.2、使用
1.2.1 docker 安装
- 使用命令行安装:sudo apt-get install docker
- 查看docker 运行状态 systemctl status docker
1.2.2、镜像
镜像的获取
- 利用镜像库获取镜像
//查看docker中的镜像
docker images (grep | **)
// 查询官方仓库的镜像
docker search 【imageName】
//拉取镜像
docker pull 【imageName】
- 通过外部导入镜像
//导入镜像包
docker load -i ***.tar
//导出镜像包
docker save -o ***.tar imageName:verison
- 镜像的删除
docker rmi imageID
镜像的制作
制作镜像的步骤
1️⃣建立DockerFile 文件 2️⃣编写DockerFile 内容 3️⃣执行生成镜像命令
DockerFile 文件格式介绍
FROM openeuler:22.03-light
MAINTAINER Xiaoxin<www.Xiaoxin.com>
COPY source /usr/local
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yum install g++ vim java autoconf automake gcc-c++ libstdc++ libtool unzip -y
ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.89
ENV CATALINA_BASH /usr/local/apache-tomcat-8.5.89
ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib:$CATALINA_HOME/bin
RUN cd /usr/local/apache-tomcat-8.5.89/logs \
&& touch catalina.out
EXPOSE 8080
CMD /usr/local/apache-tomcat-8.5.89/bin/startup.sh && tail -f /usr/local/apache-tomcat-8.5.89/logs/catalina.out
DockerFile 文件的组成部分
指令 | 描述 |
---|---|
FROM | 基础镜像,一切从这里开始构建 |
MAINTAINER | 镜像是谁写的,姓名+邮箱 |
RUN | 镜像构建的时候需要运行的命令 |
ADD | 添加内容: 比如加一个tomcat压缩包 |
WORKDIR | 镜像的工作目录 |
VOLUME | 镜像挂载的目录 |
EXPOSE | 保留暴露的端口 |
CMD | 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可以被代替 |
ENTRYPOINT | 指定这个容器启动的时候需要运行的命令,可以追加命令 |
ONBUILD | 当构建一个被继承DockerFile 的时候就会运行 ONBUILD 的指令。触发指令 |
COPY | 类似ADD ,将我们的文件拷贝到镜像中 |
ENV | 构建的时候设置环境变量 |
FROM
//有两种格式
FROM <IMAGE>
FROM <IMAGE>:<TAG>
MAINTAINER
MAINTAINER <NAME>
RUN
//方式1 shell 形式
RUN <command>
RUN yum install httpd && yum install ftp
//方式2 exec 形式
RUN ["executable","param1","param2"]
RUN ["/bin/bash","-c" "echo hello"]
ADD
ADD <src> <dest>
//<src>:可以是 Dockerfile 所在目录的一个相对路径(文件或目录);也可以是一个 URL;还可以是一个 tar 文件(自动解压为目录)
//<dest>:可以是镜像内绝对路径,或者相对于工作目录(WORKDIR)的相对路径
WORKDIR
WORKDIR /usr/local/app
WORKDIR指令为Dockerfile中的任何 RUN、CMD、ENTRYPOINT、COPY 和 ADD指令设置工作目录。如果WORKDIR不存在,即使在后续的Dockerfile指令中不使用它,也会创建它。WORKDIR指令可以在Dockerfile中多次使用。如果提供了一个相对路径,它将相对于前面的WORKDIR指令的路径。
VOLUME
VOLUME ["/data"]
EXPOSE
//使用这个指令的目的是告诉应用程序容器内应用程序会使用的端口。
EXPOSE <PORT>
//在运行时还需要使用-p参数指定映射端口。
docker run -p 80 -d dockertest/dockerfile_build nginx -g "daemon off"
CMD
//用于提供容器运行的默认命令,如果在`docker run`时指定了运行的命令,则CMD命令不会执行。如果有多个CMD指定,最后一个生效。CMD有三种模式:
CMD <command> (shell模式)//这个会当作/bin/sh -c "cmd"来执行
CMD [ "executable", "param1", "param2" ] (exec模式)
CMD [ 'param1', 'param2'] //这个时候CMD作为ENTRYPOINT的参数
【mark】如果需要替换,在运行时添加参数 docker run command
ENTRYPOINT
定义容器启动时需要执行的命令,作为容器的“入口”。能够起到与CMD类似的作用,在DockerFile 中CMD
与ENTRYPOINT
至少有一个。
两种格式 :
- ENTRYPOINT [“executable”, “param1”, “param2”] (exec 格式)
docker run image 后面跟的命令行参数将会添加到 ENTRYPOINT 所有参数的最后,且会覆盖掉所有 CMD 命令中的参数。这将允许运行时传递参数给 ENTRYPOINT 命令,例如 docker run image -d 会将 -d 参数传给 ENTRYPOINT 命令 。ENTRYPOINT 命令可以通过 docker run --entrypoint 参数来覆盖 。
- ENTRYPOINT command param1 param2 (shell 格式)
会忽略所有 CMD 命令的参数和 docker run 的命令行参数,ENTRYPOINT 要运行的命令会作为 /bin/sh -c 的子命令运行,而且 /bin/sh 不会传递信号,也就是说 ENTRYPOINT 要运行的命令不是 PID 为 1 的进程,且不会收到 Unix 信号,所以你要执行的命令不会收到 docker stop 发出的 SIGTERM 信号。
`ENTRYPOINT ["/bin/echo", "Hello"]`
`CMD ["world"] //表示默认参数,没提供参数,则使用此参数`
docker run -it [image] 输出:Hello world
docker run -it [image] 输出:Hello world
docker run -it [image] "hanke" 输出 Hello hanke ,不使用默认参数
docker run -it [image] "hanke" "hujing" 输出 Hello hankd hujing ,使用多个提供参数
FROM ubuntu
ENTRYPOINT["top","-b"]
CMD["-c"]
【mark】如果需要覆盖原始ENTRYPOINT 需要在运行时执行 docker run —entrypoint
COPY
COPY <源路径> ... <目标路径>
//其中 `<源路径>` 是相对于构建上下文的路径,可以是文件或目录的路径,甚至可以使用通配符。而 `<目标路径>` 是容器内的路径
ENV
ENV <key>=<value>
ENV MY_NAME="John Doe" //单个值
ENV MY_NAME="John Doe" MY_DOG=Rex MY_CAT=fluffy //d多值
- 构建并测试
//通过命令构建镜像 最后有个 `.`语法如下
docker build -f dockerfile 文件名 -t 镜像名:[tag] .
【镜像打包层级结构图】
镜像的运行
【概念】
- 容器的创建
docker create {imageid}
- 容器的启停:
docker start {container-id}
docker stop {container-id}
- 命令
docker run [imageid]
docker run imagename:tag
-d: 在后台运行容器,.并返回容器ID
-p: 用于容器端口映射
-v: 绑定一个卷,目录挂载
其他:-a(attach) -P( publish-all ):-i(interactive) rm -e:(env )
docker run == docker create + docker start
docker run -d -p 9090:8080 image:v1.1
- 容器的删除
docker rm {container-id}
- 容器访问
docker exec -it {container-id}(containerName) /bin/bash
docker exec -it {container-id}(containerName) sh
仓库的使用
- 登录docker Hub
docker login -u username -p passwd
- 镜像打tag `` docker tag localImage:tag henry598/image:tag
- 推送到仓库
docker push henry598/image:tag