Docker学习整理

概述

  • Docker 是一个开源的应用容器引擎,基于 Go 语言并遵从 Apache2.0 协议开源。

  • Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。

  • 容器是完全使用沙箱机制,相互之间不会有任何接口(类似 iPhone 的 app),更重要的是容器性能开销极低。

官方文档:https://docs.docker.com/

仓库地址:https://hub.docker.com/

历史

2010年,dotCloud公司成立,要提供基于PaaS的云计算技术服务。具体来说,是和LXC有关的容器技术。

后来,dotCloud公司将自己的容器技术进行了简化和标准化,并命名为——Docker,但是当时并没有引起很大的反响。

2013年,dotCloud 公司的PaaS业务不太景气,公司名字改为docker,并在同年3月份将docker开源。不开则已,一开惊人,越来越多的IT工程师发现了Docker的优点,然后蜂拥而至,加入Docker开源社区。

架构

Docker使用了C/S体系架构,Docker客户端与Docker守护进程通信,Docker守护进程负责构建,运行和分发Docker容器。Docker客户端和守护进程可以在同一个系统上运行,也可以将Docker客户端连接到远程Docker守护进程。Docker客户端和守护进程使用REST API通过UNIX套接字或网络接口进行通信。另一个 Docker 客户端是 Docker Compose,它允许您使用由一组容器组成的应用程序。

Docker daemon

Docker 守护进程 ( dockerd) 监听 Docker API 请求并管理 Docker 对象,例如图像、容器、网络和卷。守护进程还可以与其他守护进程通信以管理 Docker 服务。

Docker client

Docker 客户端 ( docker) 是许多 Docker 用户与 Docker 交互的主要方式。当您使用诸如 之类的命令时docker run,客户端会将这些命令发送到dockerd,从而执行它们。该docker命令使用 Docker API。Docker 客户端可以与多个守护进程通信。

Docker registries

Docker 仓库用来保存镜像,可以理解为代码控制中的代码仓库。Docker Hub(https://hub.docker.com) 提供了庞大的镜像集合供使用。

一个 Docker Registry 中可以包含多个仓库(Repository);每个仓库可以包含多个标签(Tag);每个标签对应一个镜像。通常,一个仓库会包含同一个软件不同版本的镜像,而标签就常用于对应该软件的各个版本。我们可以通过 <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。如果不给出标签,将以 latest 作为默认标签。

Images

一个镜像是用于创建一个docker容器指令的只读模板。通常,一个镜像基于另一个镜像,并带有一些额外的自定义。

可以创建自己的镜像,也可以仅使用其他人创建并在registries中发布的镜像。构建自己的镜像可以使用简单的语法创建一个Dockerfile,用于定义创建镜像和运行镜像所需的步骤。Dockerfile 中的每条指令都会在镜像中创建一个层。更改Dockerfile并重建镜像时,只会重建那些已更改的层。与其他虚拟化技术相比,这是使镜像如此轻巧、小巧和快速的部分原因。

Containers

容器是镜像的可运行实例。使用 Docker API 或 CLI 创建、启动、停止、移动或删除容器。您可以将容器连接到一个或多个网络,为其附加存储,甚至可以根据其当前状态创建新映像。

默认情况下,容器与其他容器及其主机相对隔离。可以控制容器的网络、存储或其他底层子系统与其他容器或主机之间的隔离程度。

容器由其映像以及在创建或启动它时提供给它的任何配置选项定义。当容器被移除时,未存储在持久存储中的对其状态的任何更改都会消失。

docker安装与卸载

以centos7示例:

  • 安装docker
# 环境 Linux version 3.10.0-693.el7.x86_64
# 1.卸载旧版本
sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine
# 2.安装yum-utils包(提供yum-config-manager 实用程序)并设置稳定存储库。
sudo yum install -y yum-utilssudo yum-config-manager \--add-repo \https://download.docker.com/linux/centos/docker-ce.repo
# 3.安装最新版本的 Docker Engine 和 containerd
sudo yum install docker-ce docker-ce-cli containerd.io
# 4.启动docker
sudo systemctl start docker
# 5.通过运行hello-world 映像验证 Docker Engine 是否已正确安装。
sudo docker run hello-world
  • 卸载docker
# 1.卸载 Docker Engine、CLI 和 Containerd 包:
sudo yum remove docker-ce docker-ce-cli containerd.io
# 2.主机上的映像、容器、卷或自定义配置文件不会自动删除。删除所有镜像、容器和卷:
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd

常用命令

帮助命令

# 查看docker版本信息
docker version
# 显示docker的系统信息,包括镜像和容器的数量
docker info
# 帮助命令
docker --help

镜像命令

# 显示本地所有镜像
docker images
# 搜索镜像
docker search 镜像名
# 拉取镜像
docker pull 镜像名
# 删除镜像
docer rmi 镜像名/镜像id
# 删除全部的镜像
docker rmi -f $(docker images -aq)

容器命令

  • 启动容器
docker start 容器id
  • 重启容器
docker restart 容器id
  • 停止容器
docker stop 容器id
  • kill容器
docker kill 容器id
  • 列出所有运行容器
docker ps
  • 删除容器
docker rm 容器名/容器id
  • 新建容器并启动
docker run 镜像id-d # 后台运行-i # 以交互模式运行,通常与-t一起使用-P # 随机端口映射,容器内部端口随机映射到主机的端口-p # 指定端口映射,格式为:主机(宿主)端口:容器端口-t # 为容器重新分配一个伪输入终端,通常与 -i 同时使用--name="nginx-lb"  #为容器指定一个名称-e # 设置环境变量--net="bridge" # 指定容器的网络连接类型,支持 bridge/host/none/container: 四种类型;--link=[] # 添加链接到另一个容器;--expose=[] # 开放一个端口或一组端口;--volume,-v # 挂载绑定一个卷
docker run -itd --name mysql_test -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -v /usr/docker_study/mysql/conf:/etc/mysql/conf.d 5c62e459e087

其他常用命令

docker logs -tf --tail 显示的日志条数 容器名/id  # 查看日志
docker top 容器名/id                 # 查看容器中的进程信息
docker inspect 容器名/id             # 查看镜像的元数据
docker exec -it 容器名/id /bin/bash  # 通常容器以后台方式运行,需要进入其中修改配置:进入容器后开启一个新终端
docker attach 容器名/id              # 进入容器正在执行的终端
docker cp 容器名/id:容器内路径 主机文件路径       # 从容器内拷贝文件到主机上
Exit                         # 从容器中退回主机
CTRL+Q+P                     # 容器不停止退出

镜像详解

镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于运行环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件。

UnionFS(联合文件系统)

Union文件系统是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下,Union文件系统是Dokcer镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的镜像。

特性:一次同时加载多个文件系统,但从外面看起来,只能看到一个文件系统,联合加载会把各层文件系统加载起来,这样最终的文件系统会包含所有的底层文件和目录。

镜像加载原理

docker的镜像实际上是由一层一层的文件系统构成,这种层级的文件系统UnionFS。主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是bootfs。这一层与我们典型的linux/unix系统是一样的,包含boot加载器内核。当boot加载完之后整个内核就都在内存中了,此时内存的使用权已经由bootfs交给内核了,此时系统也会卸载bootfs。

分层

docker pull的过程中是一层一层的下载。好处就是可以共享资源。

比如有多个镜像都从相同的base镜像构建而来,那么宿主机只需要在磁盘上保存一份base镜像,同时内存中也需要加载一份base镜像,就可以为所有服务器服务了。而且镜像的每一层都可以被共享。

创建镜像

docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[tag]  # 编辑容器后提交容器成为一个新镜像

创建自己的tomcat镜像示例:

# 1.搜索官方镜像
docker search tomcat
# 2.拉取官方镜像
docker pull tomcat:9.0
# 3.运行镜像
docker run -itd --name tomcat01 -p 8080:8080 tomcat:9.0
# 4.添加改变(官方镜像tomcat得webapps下无示例项目,需从webapps.list拷贝)
docker exec -it tomcat01 /bin/bash
cp -r webapps.dist/* webapps   #当前即可正常访问示例项目
# 5.提交镜像
docker commit -a="rzz" -m="add a webapp" 702580afdd48 mytomcat:1.0 #容器id换成自己的
# 6.查看
docker images

发布镜像到dockerhub

推送镜像的规范是docker push 注册用户名/镜像名。

# 1.登录
docker login -u 用户名
# 2.将镜像修改为规范的镜像
docker tag 镜像名:版本 用户名/镜像名:版本
# 3.推送
docker push 用户名/镜像名:版本
# 4.搜索自己的镜像
docker search mycentos

Docker数据卷与持久化

为了实现数据持久化,使容器之间可以共享数据。可以将容器内的目录,挂载到宿主机上或其他容器内,实现同步和共享的操作。即使将容器删除,挂载到本地的数据卷也不会丢失。

挂载方式

通过docker run 命令挂载

# -v设置挂载  ro代表容器内只读   rw代表容器内可写可读
# 具名挂载       -v 卷名:容器内路径:ro|rw(默认rw,可不填)
docker run -itd -P --name mounttomcat01 -v juming:/usr/local/tomcat/webapps tomcat:9.0
# 匿名挂载       -v 容器内路径
docker run -itd -P --name mounttomcat02 -v /usr/local/tomcat/webapps tomcat:9.0
# 指定路径挂载    -v 宿主机路径:容器内路径
docker run -itd -P --name mounttomcat03 -v /usr/tomcat/webapps:/usr/local/tomcat/webapps tomcat:9.0
# 显示所有卷
docker volume ls
# 显示某一卷详情
docker volume inspect 卷名

通过DockerFile挂载

上面介绍的通过docker run命令的-v标识创建的挂载点只能对创建的容器有效。通过dockerfile的 VOLUME 指令可以在镜像中创建挂载点,这样只要通过该镜像创建的容器都有了挂载点。还有一个区别是,通过 VOLUME 指令创建的挂载点,无法指定主机上对应的目录,是自动生成的。

FROM tomcat
MAINTAINER rzz<rzz1655@163.com>
VOLUME ["/data1","/data2"]

容器共享卷

创建另一个容器可以和mounttomcat03(已经创建好的容器)共享卷,来源可以是不同镜像。

# 使用--volumes-from 容器名/id
docker run -itd -P --name mounttomcat02 --volumes-from mounttomcat03 tomcat:9.0

Dockerfile

Docker可以通过读取Dockerfile中的指令自动构建镜像。Dockerfile是一个用来构建镜像的文本文件,文本内容包含了一条条构建镜像所需的指令和说明。

常用指令

FROM

该指令指定基础镜像,然后对镜像进行定制。

FROM [--platform=<platform>] <image> [AS <name>]
# 或
FROM [--platform=<platform>] <image>[:<tag>] [AS <name>]
# 或
FROM [--platform=<platform>] <image>[@<digest>] [AS <name>]
# 示例
FROM mysql:5.7

FROM指令初始化一个新的构建阶段并为后续指令设置基础镜像。因此,有效Dockerfile必须以FROM指令开头。

  • DockerfileARG是唯一一个优先于FROM的指令。
  • FROM可以在单个Dockerfile中多次出现创建多个镜像,或使用一个构建阶段作为另一个构建阶段的依赖项。只需记下每个新FROM指令之前提交输出的最后一个镜像ID 。每条FROM指令都会清除由先前指令创建的任何状态。
  • 可以选择通过添加AS nameFROM指令来为新的构建阶段命名。该名称可在后续FROMCOPY --from=<name>说明中用于引用此阶段构建的映像。
  • tagdigest值是可选的。省略则构建器会默认使用一个latest标签。如果找不到该tag值,构建器将返回错误。可以使用:docker images --digests展示digest。
  • 可以选择一个空镜像scratch作为基础镜像从0构建。

RUN

RUN 指令将在当前镜像基础上执行指定命令,并提交为新的镜像,构建时执行,区别于CMD,CMD在容器启动的时候运行。

RUN <command>                           # shell形式
RUN ["executable", "param1", "param2"]  # exec执行形式
# 示例
RUN /bin/bash -c 'source $HOME/.bashrc; echo $HOME'
RUN ["c:\\windows\\system32\\tasklist.exe"]

CMD

类似于 RUN 指令,用于运行程序,但二者运行的时间点不同,CMD在容器启动时运行。

CMD ["executable","param1","param2"]    #(exec形式,这是首选形式)
CMD ["param1","param2"]                 #(作为ENTRYPOINT 的默认参数)
CMD command param1 param2               #(外壳形式)
  • 在Dockerfile中只能有一个CMD指令。如果列出多个CMD,那么只有最后一个CMD生效。
  • CMD的主要目的是为正在执行的容器提供默认值。这些默认值可以包含可执行文件,也可以省略可执行文件,在这种情况下,您还必须指定一个ENTRYPOINT指令。
  • 如果CMD被用来为ENTRYPOINT指令提供默认参数,那么CMD和ENTRYPOINT指令都应该用JSON数组格式指定。

LABEL

LABEL 指令用来给镜像添加一些元数据(metadata),以键值对的形式。

LABEL <key>=<value> <key>=<value> <key>=<value> ...
#示例
LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
# 查看标签
docker image inspect --format='' myimage

MAINTAINER(废弃)

MAINTAINER指令设置生成镜像的作者属性。已废弃,建议使用LABEL指令

MAINTAINER <name>

EXPOSE

EXPOSE指令声明Docker容器在运行时监听指定的网络端口。

EXPOSE <port> [<port>/<protocol>...]
# 示例  可同时发布,同时包含以下两行即可
EXPOSE 80/tcp
EXPOSE 80/udp
  • 可以指定端口监听TCP还是UDP,如果不指定协议,默认为TCP。
  • EXPOSE指令实际上并不发布端口。帮助镜像使用者理解这个镜像服务的守护端口,以方便配置映射。要在运行容器时实际发布端口,请在docker run上使用-p来发布和映射一个或多个端口,或者使用-P发布所有暴露的端口并将它们映射到高阶端口。

ENV

设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。

ENV <key>=<value> ...
# 示例
ENV MY_NAME="John Doe"
ENV MY_DOG=Rex\ The\ Dog
ENV MY_CAT=fluffy
# 或
ENV MY_NAME="John Doe" MY_DOG=Rex\ The\ Dog \MY_CAT=fluffy

ADD

一个复制命令将本地文件复制到容器中,tar类型文件会自动解压。可以访问网络资源,类似wget。

# 两种形式,--chown不适用windows下,适用于linux下
ADD [--chown=<user>:<group>] <src>... <dest>
ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]
# 示例
ADD hom* /mydir/               # 添加所有以“hom”开头的文件:
ADD hom?.txt /mydir/           # ?被替换为任何单个字符,例如“home.txt”。
ADD test.txt relativeDir/      # 使用相对路径,并将“test.txt”添加到<WORKDIR>/relativeDir/
ADD test.txt /absoluteDir/     # 使用绝对路径,并将“test.txt”添加到 /absoluteDir/
ADD arr[[]0].txt /mydir/       # 特殊字符转义要添加名为 的文件arr[0].txt
ADD --chown=55:mygroup files* /somedir/     # UID/GID组合

COPY

复制指令,从上下文目录中复制文件或者目录到容器里指定路径。与ADD类似。但是不会自动解压文件,也不能访问网络资源。

COPY [--chown=<user>:<group>] <src>... <dest>
COPY [--chown=<user>:<group>] ["<src>",... "<dest>"]

ENTRYPOINT

类似于 CMD 指令,但其不会被 docker run 的命令行参数指定的指令所覆盖,而且这些命令行参数会被当作参数送给 ENTRYPOINT 指令指定的程序。

但是, 如果运行 docker run 时使用了 --entrypoint 选项,将覆盖 CMD 指令指定的程序。

# 两种形式
ENTRYPOINT ["executable", "param1", "param2"]
ENTRYPOINT command param1 param2
# 示例
ENTRYPOINT ["top", "-b"]
ENTRYPOINT top -b

VOLUME

VOLUME指令使用指定的名称创建一个挂载点,并将其标记为保存来自本机主机或其他容器的外部挂载的卷。

VOLUME ["/data"]
# 示例:此Dockerfil run后生成一个镜像,该镜像会创建新的挂载点/myvol并将greeting文件复制到新创建的卷中。
FROM centos
RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting
VOLUME /myvol

USER

指定运行容器时的用户名或UID,后续的 RUN 也会使用指定用户。使用USER指定用户时,可以使用用户名、UID或GID,或是两者的组合。

USER <user>[:<group>]
USER <UID>[:<GID>]

WORKDIR

指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。(WORKDIR 指定的工作目录,必须是提前创建好的)。

docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。

WORKDIR /path/to/workdir
# 示例
WORKDIR /a
WORKDIR b
WORKDIR c
RUN pwd #结果是:/a/b/c
# 或
ENV DIRPATH=/path
WORKDIR $DIRPATH/$DIRNAME
RUN pwd #结果是:/path/$DIRNAME

ARG

ARG指令定义了一个变量,用户可以在构建时docker build通过使用--build-arg <varname>=<value> 标志的命令将其传递给构建器。如果用户指定了未在 Dockerfile 中定义的构建参数,则构建会输出警告。

ARG <name>[=<default value>]
# 示例
FROM busybox
USER ${user:-some_user}
ARG SETTINGS
ARG user
USER $user
# 构建
docker build --build-arg user=what_user .
  • ARG定义的参数默认值,当build镜像时没有指定参数值,将会使用这个默认值
  • 一个 Dockerfile 可能包含一个或多个ARG指令。

ONBUILD

ONBUILD指令将一个触发指令添加到镜像中,以便稍后在该镜像用作另一个构建的基础时执行。

ONBUILD <INSTRUCTION>
# 示例
ONBUILD ADD . /app/src
ONBUILD RUN /usr/local/bin/python-build --dir /app/src
  • 该指令不影响当前镜像的构建
  • 在构建结束时,所有触发器的列表将存储在图像清单中的OnBuild键下。它们可以用docker inspect命令进行检查。
  • 触发器在执行后将从最终镜像中清除。换句话说,它们不是由“孙子辈”构建继承的。

STOPSIGNAL

STOPSIGNAL指令设置将发送到容器退出的系统调用信号。

该信号可以是与内核系统调用表中的位置匹配的有效无符号数,例如 9,或格式为 SIGNAME 的信号名称,例如 SIGKILL。

STOPSIGNAL signal
# 示例
STOPSIGNAL 9
STOPSIGNAL SIGKILL

HEALTHCHECK

HEALTHCHECK指令告诉 Docker 如何测试容器以检查它是否仍在工作。

HEALTHCHECK NONE                  #(禁用从基础镜像继承的任何健康检查)
HEALTHCHECK [OPTIONS] CMD command #(通过在容器内运行命令来检查容器健康状况)
# OPTIONS
--interval=DURATION       #(默认值:30s)
--timeout=DURATION        #(默认值:30s)
--start-period=DURATION   #(默认值:0s)
--retries=N               #(默认值:3)
  • 运行状况检查将在容器启动后首先运行interval秒,然后在每次之前的检查完成后再次运行interval秒。

  • 如果检查的单次运行时间超过timeout秒,则认为检查失败。

  • 它需要重试连续的健康检查失败才能考虑容器unhealthy

这可以检测诸如 Web 服务器陷入无限循环并且无法处理新连接的情况,即使服务器进程仍在运行。

当容器指定了健康检查时,除了其正常状态之外,它还具有健康状态。此状态最初为starting。每当健康检查通过时,它就会变成healthy(无论它之前处于什么状态)。连续失败一定次数后,变为unhealthy

命令的退出状态指示容器的健康状态。值为:

  • 0:成功 - 容器运行良好,可以使用
  • 1:不健康 - 容器不能正常工作
  • 2:reserved - 不要使用这个退出代码

检查流程:

  1. 运行状况检查将在容器启动后首先运行interval秒,然后在每次之前的检查完成后再次运行interval秒。
  2. 如果检查的单次运行时间超过timeout秒,则认为检查失败。
  3. 它需要重试连续的健康检查失败才能考虑容器unhealthy
# 例如,每五分钟左右检查一次网络服务器是否能够在三秒钟内为站点的主页提供服务
HEALTHCHECK --interval=5m --timeout=3s CMD curl -f http://localhost/ || exit 1

SHELL

SHELL指令允许覆盖用于shell形式的命令的默认shell 。

Linux上的默认shell是["/bin/sh", “-c”],而在Windows上[“cmd”, “/S”, “/C”]。

SHELL ["executable", "parameters"]
# 示例
SHELL ["powershell","-command"]

通过Dockerfile搭建centos

# 1.创建dockerfile文件并编辑
FROM centos
LABEL author="rzz" create_time="2021-06-27"
ENV MYPATH /usr/local
WORKDIR $MYPATH
RUN yum -y install vim
RUN yum -y install net-tools
EXPOSE 80
CMD echo $MYPATH
CMD echo "----------end-------"
CMD /bin/bash
# 2.构建镜像
docker build -f my_dockerfile_centos -t mycentos:1.0 .# 使用docker history查看镜像构建过程
docker history 镜像id

搭建redis集群

# 1.创建网卡
docker network create redis --subnet 172.38.0.0/16
# 2.编写配置脚本
for port in $(seq 1 6); \
do \
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat << EOF >/mydata/redis/node-${port}/conf/redis.conf
port 6379
bind 0.0.0.0
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 5000
cluster-announce-ip 172.38.0.1${port}
cluster-announce-port 6379
cluster-announce-bus-port 16379
protected-mode no
appendonly yes
EOF
done
# 3.创建节点
for port in $(seq 1 6); \
do \
docker run -p 637${port}:6379 -p 1637${port}:16379 --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.1${port} redis redis-server /etc/redis/redis.conf
done
# 4.进入容器
docker exec -it redis-1 /bin/bash
# 5.搭建集群
redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1
# 6.启动集群
redis-cli -c

docker安装kafka

# 1.下载zookeeper和kafka
docker pull wurstmeister/zookeeper
docker pull wurstmeister/kafka
# 2.启动zookeeper
docker run -itd --name zookeeper01 -p 2181:2181 wurstmeister/zookeeper
# 3.启动kafka
docker run  -itd --name kafka01 -p 9092:9092 -e KAFKA_BROKER_ID=0 -e KAFKA_ZOOKEEPER_CONNECT=139.196.204.230:2181 -e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://139.196.204.230:9092 -e KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092 -t wurstmeister/kafka
# 4.进入kafka容器
docker exec -it kafka01 /bin/bash
# 5.进入/opt/kafka_2.13-2.7.0/bin目录
cd /opt/kafka_2.13-2.7.0/bin
# 6.运行kafka生产者生产消息
./kafka-console-producer.sh --broker-list localhost:9092 --topic sun
# 7.发送消息
{"datas":[{"channel":"","metric":"temperature","producer":"ijinus","sn":"IJA0101-00002245","time":"1543207156000","value":"80"}],"ver":"1.0"}
# 8.重新进入容器运行消费者消费消息
./kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic sun --from-beginning

springboot整合docker

# 1.构建springboot项目
# 2.打包成jar
# 3.编写Dockerfile文件
FROM java:8
COPY *.jar /app.jar
CMD ["--server.port=8080"]
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/app.jar"]
# 4.jar和dockerfile上传到linux构建镜像(最后有一个点)
docker build -t 镜像名 .

Docker Compose

Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。借助 Compose,您可以使用 YAML 文件来配置应用程序的服务。然后,使用单个命令从配置中创建并启动所有服务。

Compose 使用的三个步骤:

  • 使用 Dockerfile 定义应用程序的环境。
  • 使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。
  • 最后,执行 docker-compose up 命令来启动并运行整个应用程序。

安装与卸载Compose

  • 安装
# 1.下载docker compose
sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# 2.添加可执行权限
sudo chmod +x /usr/local/bin/docker-compose
  • 卸载
sudo rm /usr/local/bin/docker-compose

入门示例

  1. 准备

    # 1.创建一个目录并进入
    mkdir composetest
    cd composetest
    # 2.创建app.py并编辑,redis是应用程序网络上的 redis 容器的主机名。
    import time
    import redis
    from flask import Flaskapp = Flask(__name__)
    cache = redis.Redis(host='redis', port=6379)def get_hit_count():retries = 5while True:try:return cache.incr('hits')except redis.exceptions.ConnectionError as exc:if retries == 0:raise excretries -= 1time.sleep(0.5)@app.route('/')
    def hello():count = get_hit_count()return 'Hello World! I have been seen {} times.\n'.format(count)
    # 3.创建requirements.txt并编辑
    flask
    redis
    
  2. 创建Dockerfile

    # 1.创建
    vim Dockerfile
    # 2.编辑
    # syntax=docker/dockerfile:1
    FROM python:3.7-alpine
    WORKDIR /code
    ENV FLASK_APP=app.py
    ENV FLASK_RUN_HOST=0.0.0.0
    RUN apk add --no-cache gcc musl-dev linux-headers
    COPY requirements.txt requirements.txt
    RUN pip install -r requirements.txt
    EXPOSE 5000
    COPY . .
    CMD ["flask", "run"]
    

    这告诉 Docker:

    • 从 Python 3.7 镜像开始构建镜像。
    • 将工作目录设置为/code.
    • 设置flask命令使用的环境变量。
    • 安装 gcc 和其他依赖项
    • 复制requirements.txt并安装 Python 依赖项。
    • 将元数据添加到图像以描述容器正在监听端口 5000
    • .项目中的当前目录复制到.镜像中的workdir 。
    • 将容器的默认命令设置为flask run.
  3. 在Compose文件中定义服务

    # 1.创建docker-compose.yml
    vim docker-compose.yml
    # 2.编辑,定义了两个服务:web和redis
    version: "3.3"
    services:web:build: .ports:- "5000:5000"redis:image: "redis:alpine"
    

    该 Compose 文件定义了两个服务:web 和 redis。

    • web:该 web 服务使用从 Dockerfile 当前目录中构建的镜像。然后,它将容器和主机绑定到暴露的端口 5000。此示例服务使用 Flask Web 服务器的默认端口 5000 。
    • redis:该 redis 服务使用 Docker Hub 的公共 Redis 映像。
  4. 使用Compose构建并运行

    # 在测试目录中,执行以下命令来启动应用程序
    docker-compose up -d
    # 访问
    curl localhost:5000
    
  5. 编辑Compose文件并挂载

    version: "3.3"
    services:web:build: .ports:- "5000:5000"volumes:- .:/codeenvironment:FLASK_ENV: developmentredis:image: "redis:alpine"
    

    volumes密钥将主机上的项目目录(当前目录)挂载到/code容器内部,允许即时修改代码,而无需重新构建镜像。该environment键设置 FLASK_ENV环境变量,它告诉flask run在开发模式下运行,并重新加载更改代码。这种模式应该只在开发中使用。

  6. 使用Compose文件重新构建运行

    docker-compose up
    
  7. 更新应用程序

    # 将最后一句改为
    return 'Hello Docker World! I have been seen {} times.\n'.format(count)
    
  8. 测试其他命令

    # 查看当前正在运行的内容
    docker-compose ps
    # docker-compose run命令允许您为您的服务运行一次性命令。例如,要查看web服务可用的环境变量 :
    docker-compose run web env
    # 查看其他可用命令
    docker-compose --help
    # 停止服务
    docker-compose stop
    # 可以使用以下down 命令关闭所有内容,完全删除容器。传递--volumes给 Redis 容器使用的数据卷:
    docker-compose down --volumes
    

docker-compose.yml核心

官方示例:

version: "3.3"
services:redis:image: redis:alpineports:- "6379"networks:- frontenddeploy:replicas: 2update_config:parallelism: 2delay: 10srestart_policy:condition: on-failuredb:image: postgres:9.4volumes:- db-data:/var/lib/postgresql/datanetworks:- backenddeploy:placement:max_replicas_per_node: 1constraints:- "node.role==manager"networks:frontend:backend:volumes:db-data:

version

指定 docker-compose.yml 文件的写法格式,格式有多个版本 - 1、2、2.x 和 3.x。

version: "3.3"

services

服务配置,Compose 文件是一个YAML文件,定义了 服务、网络和 卷。Compose 文件的默认路径是./docker-compose.yml.

build

指定为构建镜像上下文路径

#  webapp 服务,指定为从上下文路径 ./dir/Dockerfile 所构建的镜像:
version: "3.3"
services:webapp:build: ./dir

或者

version: "3.7"
services:webapp:build:context: ./dir      #上下文路径。dockerfile: Dockerfile-alternate   #指定构建镜像的 Dockerfile 文件名。args:               #添加构建参数,这是只能在构建过程中访问的环境变量。buildno: 1labels:             #设置构建镜像的标签。- "com.example.description=Accounting webapp"- "com.example.department=Finance"- "com.example.label-with-empty-value"target: prod        #多层构建,可以指定构建哪一层。shm_size: 10000000  #设置/dev/shm此构建容器的分区大小。network: host       #在构建期间为RUN指令设置连接到的网络容器。

cap_add, cap_drop

添加或删除容器拥有的宿主机的内核功能。

cap_add:- ALL # 开启全部权限cap_drop:- SYS_PTRACE # 关闭 ptrace权限

cgroup_parent

为容器指定父 cgroup 组,意味着将继承该组的资源限制。

cgroup_parent: m-executor-abcd

command

覆盖容器启动的默认命令。

command: bundle exec thin -p 3000
# 或
command: ["bundle", "exec", "thin", "-p", "3000"]

container_name

指定自定义容器名称,而不是生成的默认名称。

container_name: my-web-container

depends_on

设置依赖关系。

  • docker-compose up :以依赖性顺序启动服务。在以下示例中,先启动 db 和 redis ,才会启动 web。
  • docker-compose up SERVICE :自动包含 SERVICE 的依赖项。在以下示例中,docker-compose up web 还将创建并启动 db 和 redis。
  • docker-compose stop :按依赖关系顺序停止服务。在以下示例中,web 在 db 和 redis 之前停止。
version: "3.7"
services:web:build: .depends_on:- db- redisredis:image: redisdb:image: postgres

注意:web 服务不会等待 redis db 完全启动 之后才启动。

deploy

指定与服务的部署和运行有关的配置。只在 swarm 模式下才会有用。

devices

指定设备映射列表。

devices:- "/dev/ttyUSB0:/dev/ttyUSB0"

dns

自定义 DNS 服务器。可以是单个值或列表。

dns: 8.8.8.8
# 或
dns:- 8.8.8.8- 9.9.9.9

dns_search

自定义 DNS 搜索域。可以是单个值或列表。

dns_search: example.com
# 或
dns_search:- dc1.example.com- dc2.example.com

entrypoint

覆盖容器默认的 entrypoint。

entrypoint: /code/entrypoint.sh
# entrypoint也可以是一个列表
entrypoint: ["php", "-d", "memory_limit=-1", "vendor/bin/phpunit"]
# 或
entrypoint:- php- -d- zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20100525/xdebug.so- -d- memory_limit=-1- vendor/bin/phpunit

env_file

从文件添加环境变量。可以是单个值或列表的多个值。

env_file: .env

environment

添加环境变量。您可以使用数组或字典、任何布尔值(true、false、yes、no),布尔值需要用引号引起来,以确保 YML 解析器不会将其转换为 True 或 False。只有一个键的环境变量被解析为它们在运行 Compose 的机器上的值,这对于秘密或特定于主机的值很有帮助。

environment:RACK_ENV: developmentSHOW: 'true'SESSION_SECRET:
# 或
environment:- RACK_ENV=development- SHOW=true- SESSION_SECRET

expose

暴露端口,但不映射到宿主机,只被连接的服务访问。

仅可以指定内部端口为参数:

expose:- "3000"- "8000"

external_links

链接到在此之外docker-compose.yml甚至 Compose 之外启动的容器,尤其是对于提供共享或公共服务的容器。

external_links:- redis_1- project_db_1:mysql- project_db_1:postgresql

extra_hosts

添加主机名映射。类似 docker client --add-host。

extra_hosts:- "somehost:162.242.195.82"- "otherhost:50.31.209.229"

以上会在此服务的内部容器中 /etc/hosts 创建一个具有 ip 地址和主机名的映射关系:

162.242.195.82  somehost
50.31.209.229   otherhost

healthcheck

用于检测 docker 服务是否健康运行。

healthcheck:test: ["CMD", "curl", "-f", "http://localhost"] # 检测程序interval: 1m30s # 检测间隔timeout: 10s # 检测超时时间retries: 3 # 重试次数start_period: 40s # 启动后,多少秒开始启动检测程序# 禁止检查
healthcheck:disable: true

image

指定启动容器的镜像。可以是存储库/标签或部分图像 ID。如果镜像不存在,Compose 会尝试拉取它。

image: redis
image: ubuntu:18.04
image: tutum/influxdb
image: example-registry.com:4000/postgresql
image: a4bc65fd

labels

使用Docker 标签向容器添加元数据。您可以使用数组或字典。建议您使用反向 DNS 表示法,以防止您的标签与其他软件使用的标签发生冲突。

labels:com.example.description: "Accounting webapp"com.example.department: "Finance"com.example.label-with-empty-value: ""
# 或
labels:- "com.example.description=Accounting webapp"- "com.example.department=Finance"- "com.example.label-with-empty-value"

links

链接到另一个服务中的容器。指定服务名称和链接别名 ( "SERVICE:ALIAS"),或仅指定服务名称。

不建议使用links,使用networks替代。

web:links:- "db"- "redis"

logging

服务的日志记录配置。

driver:指定服务容器的日志记录驱动程序,默认值为json-file。有以下三个选项

driver: "json-file"
driver: "syslog"
driver: "none"

network_mode

网络模式。使用与 docker 客户端--network参数相同的值,加上特殊形式service:[service name]

network_mode: "bridge"
network_mode: "host"
network_mode: "none"
network_mode: "service:[service name]"
network_mode: "container:[container name/id]"

networks

要加入的网络,引用顶级networks键下的条目 。

services:some-service:networks:- some-network- other-network
networks:some-network:other-network:

volumes

将主机的数据卷或着文件挂载到容器里。

version: "3.7"
services:db:image: postgres:latestvolumes:- "/localhost/postgres.sock:/var/run/postgres/postgres.sock"- "/localhost/data:/var/lib/postgresql/data"

restart

no是默认的重启策略,在任何情况下都不会重启容器。当always指定时,容器总是重新启动。on-failure如果退出代码指示失败错误,则该策略会重新启动容器。unless-stopped总是重新启动容器,除非容器停止(手动或其他方式)。

restart: "no"
restart: always
restart: on-failure
restart: unless-stopped

networks

要加入的网络,引用顶级networks键下的条目 。

services:some-service:networks:- some-network- other-network
networks:some-network:other-network:

volumes

将主机的数据卷或着文件挂载到容器里。

version: "3.7"
services:db:image: postgres:latestvolumes:- "/localhost/postgres.sock:/var/run/postgres/postgres.sock"- "/localhost/data:/var/lib/postgresql/data"

restart

no是默认的重启策略,在任何情况下都不会重启容器。当always指定时,容器总是重新启动。on-failure如果退出代码指示失败错误,则该策略会重新启动容器。unless-stopped总是重新启动容器,除非容器停止(手动或其他方式)。

restart: "no"
restart: always
restart: on-failure
restart: unless-stopped

docker学习整理相关推荐

  1. Docker 学习资源整理

    Docker 是近年来非常火的容器技术,而且啊 Docke r不仅仅是红帽和Canonical等Linux巨头眼里的宠儿,微软等专有软件公司也在热烈拥抱 Docker,所以就知道 Docker 为啥这 ...

  2. 狂神 Docker学习笔记 从基础到进阶 一步到位

    Docker 学习笔记 感谢狂神的分享.附上B站视频链接. https://www.bilibili.com/video/BV1og4y1q7M4?from=search&seid=92256 ...

  3. Docker基础03--Dockerfile详解与镜像发布--(狂神说docker学习笔记)

    文章目录 1. Dockerfile介绍 2. Dockerfile指令说明 3. 制作Centos镜像 3.1 编写Dockerfile的文件 3.2 通过这个文件构建镜像(注意最后加个点!!!) ...

  4. docker学习笔记(初阶)

    笔记整理自狂神:Docker最新超详细版教程通俗易懂 Docker学习整体框架: Docker概述 Docker安装 Docker命令 镜像命令 容器命令 操作命令 Docker镜像! 容器数据卷! ...

  5. Docker:学习笔记(1)——基础概念

    Docker:学习笔记(1)--基础概念 Docker是什么 软件开发后,我们需要在测试电脑.客户电脑.服务器安装运行,用户计算机的环境各不相同,所以需要进行各自的环境配置,耗时耗力.为了解决这个问题 ...

  6. [转]Docker学习之四:使用docker安装mysql

    本文转自:https://blog.csdn.net/qq_19348391/article/details/82998391 Docker学习之一:注册Docker Hub账号 Docker学习之二 ...

  7. Java设计模式(学习整理)---命令模式

    设计模式之Command(学习整理) 1.Command定义 不少Command模式的代码都是针对图形界面的,它实际就是菜单命令,我们在一个下拉菜单选择一个命令时,然后会执行一些动作. 将这些命令封装 ...

  8. Docker学习之路 用commit命令创建镜像

    Docker学习之路 用commit命令创建镜像 docker 74k 次阅读 · 读完需要 7 分钟 假期快要结束了,干点正事,接着Docker的学习. 构建镜像 构建镜像的两种方法: 使用dock ...

  9. 2019.07.30 学习整理

    2019.07.30 学习整理 数据类型 1. 什么是数据类型 数据类型指的就是变量值的不同类型 2. 为何对数据分类? 变量的是用来反映状态以及状态变化的,毫无疑问针对不同的状态就应该用不同类型的数 ...

最新文章

  1. JAVA条件表达式的陷阱
  2. 点云数据向图像数据转换(附源码)
  3. python dict函数用法_如何将python中的dict作为参数传入c函数中用c做相关的处理?...
  4. 面试题:如何设计一个高并发系统?
  5. CF1131 G. Most Dangerous Shark (单调栈优化dp)
  6. 无法检索文件服务器,无服务器快速无法检索pdf文件(base64编码)
  7. ES6之let原理+回调函数等待队列——五个完全相同的按钮,点第i个按钮弹出i
  8. 前台性能和服务器性能是什么,前端性能优化指南[2]--什么是Web性能?
  9. hdu 1561 The more, The Better (依赖背包 树形dp)
  10. ubuntu使用VNC实现远程桌面
  11. 20.从0开始的微服务架构
  12. 河海大学文天学院计算机科学与技术,河海大学文天学院计算机科学与技术2010级软件工程试卷...
  13. 家里的无线网最近总是网速不稳定,一阵一阵的卡,是怎么回事?
  14. php 硬盘序号_关于取硬盘序列号
  15. webbrowser1 脚本报错_webbrowser脚本错误的解决办法
  16. 遗传算法调参 参数设置
  17. 【2020年高被引学者】 孙剑 旷视科技
  18. java工程license机制_使用truelicense实现用于JAVA工程license机制(包括license生成和验证)...
  19. 六、CSS 速览 —— 平面转换、3D转换、动画
  20. 涂鸦Wi-FiBLE SoC开发幻彩灯带(5)----烧录授权

热门文章

  1. 一次nginx代理前端报rewrite or internal redirection cycle while internally redirecting to “index.html“ 记录
  2. c通讯录 :动态申请内存版本
  3. PyCharm 2019
  4. android 计步器
  5. 程序员的财务自由之路(二)- 给自己树立一个目标
  6. python工程师职业规划书范文_AI工程师职业规划和学习路线完整版
  7. 关于机箱按键一键销毁或关机机箱内的多块VPX计算板卡的注意事项
  8. 优化.NET访问Active Directory的性能
  9. iOS 通过URL Scheme跳转到常用的App
  10. 【51NOD 1737】配对