当前位置: 首页 > article >正文

docker-操作实战

前言

C++镜像制作

因为我平常不用,所以不书写了

SpringBoot 微服务镜像制作

mkdir java
ca java
cp /data/maxhou/myapp/xxx.jar .
vi Dockerfile

FROM openjdk:8
COPY ./xxx.jar /app.jar
CMD ["java","-jar","/app.jar"]

COPY ./xxx.jar /app.jar就是把宿主机当前目录下的jar包拷贝到镜像目录里面,并改名
CMD就是在创建镜像的时候启动容器的默认命令
docker build -t springboot:v0.1 .
在这里插入图片描述
dokcer run -d --name myspringboot1 -p 8888:8080 springboot:v0.1
docker ps
docker logs -f myspringboot1

看的出来这个springboot程序占用的是8080端口,为什么会打印出这个呢
因为CMD命令启动了jar包,CMD就是在创建容器的时候发动的
在这里插入图片描述

CMD与EntryPoint实战

基础知识

ENTRYPOINT和CMD都是在docker image里执行一条命令, 但是他们有一些微妙的
区别.一般来说两个大部分功能是相似的都能满足。
比如执行运行一个没有调用ENTRYPOINT或者CMD的docker镜像, 返回错误,一般
的镜像最后都提供了CMD或者EntryPoint作为入口。
覆盖
在写Dockerfile 时, ENTRYPOINT或者CMD命令会自动覆盖之前的ENTRYPOINT
或者CMD命令.
在docker镜像运行时, 用户也可以在命令指定具体命令, 覆盖在Dockerfile里的命令.
如果你希望你的docker镜像只执行一个具体程序, 不希望用户在执行docker run的时
候随意覆盖默认程序. 建议用ENTRYPOINT.
就是写了很多个CMD和EntryPoint,只会执行最后一个,后面的会把前面的覆盖掉
docker run的时候指定命令的话,会覆盖CMD,而EntryPoint不会被覆盖,docker run的时候指定–entrypoint,就可以覆盖EntryPoint了

Shell 和 Exec模式

ENTRYPOINT和CMD指令支持2种不同的写法: shell表示法和exec表示法.
CMD命令语法
shell模式就是直接把命令放在后面,exec模式就是把命令用双引号用json数组的形式放在里面

Shell 
#EXEC 语法 
CMD ["executable","param1","param2"] (exec form, this is the 
preferred form) 
#用于给ENTRYPOINT 传入参数,推荐使用 
CMD ["param1","param2"] (as default parameters to ENTRYPOINT) 
#shell 语法 
CMD command param1 param2 (shell form) 

ENTRYPOINT语法

Shell 
 EXEC 语法 
ENTRYPOINT ["executable", "param1", "param2"] (exec form, 
preferred) 
 Shell 语法 
ENTRYPOINT command param1 param2 (shell form) 

当使用shell表示法时, 命令行程序作为sh程序的子程序运行, docker用/bin/sh -c的语
法调用. 如果我们用docker ps命令查看运行的docker, 就可以看出实际运行的是
/bin/sh -c 命令。这样运行的结果就是我们启动的程序的PID不是1,如果从外部发送
任何POSIX信号到docker容器, 由于/bin/sh命令不会转发消息给实际运行的命令, 则
比特就业课
不能安全得关闭docker容器。
EXEC语法没有启动/bin/sh命令, 而是直接运行提供的命令, 命令的PID是1. 无论你用
的是ENTRYPOINT还是CMD命令, 都强烈建议采用exec表示法。

CMD nginx -g “daemon off;”shell模式
执行的是 /bin/sh -c “nginx -g “daemon off;””-------》nginx的pid不是1,sh的pid才是1
如果docker stop的时候,并不会把指令转发给nginx,nginx最后也是强制结束,不是正常结束
CMD [“nginx”,“-g”, “daemon off;”]exec模式
nginx -g "daemon off;"这个就是这样运行的----》nginx的pid是1,docker stop会把停止信号发给nginx 进程,nginx进程就会优雅的结束
所以我们推荐使用exec模式

组合模式
组合使用ENTRYPOINT和CMD, ENTRYPOINT指定默认的运行命令, CMD指定默认
的运行参数.ENTRYPOINT和CMD同时存在时, docker把CMD的命令拼接到
ENTRYPOINT命令之后, 拼接后的命令才是最终执行的命令.
组合使用ENTRYPOINT和CMD,CMD会作为参数传递给ENTRYPOINT所有ENTRYPOINT单独负责可执行程序,CMD单独负责参数,推荐这个

实战-多次覆盖

mkdir cmd
cd cmd
vi Dockerfile

FROM busybox
CMD echo "hello world!"
CMD echo "hello bit!"

docker build -t cmd:v0.1 .
在这里插入图片描述
docker run -it --rm cmd:v0.1
在这里插入图片描述
说明后面的覆盖前面的了
cp Dockerfile Dockerfile2

vi Dockerfile2

FROM busybox
ENTRYPOINT echo "hello world!"
ENTRYPOINT echo "hello bit!"

ENTRYPOINT 也是这样的
docker build -t cmd:v0.2 -f Dockerfile2 .
docker run -it --rm cmd:v0.2
在这里插入图片描述

参数覆盖

docker run -it --rm cmd:v0.1 echo hello bit2!
在这里插入图片描述
说明docker run的指令会把CMD覆盖
docker run -it --rm cmd:v0.2 echo hello bit2!
在这里插入图片描述
我们发现ENTRYPOINT是不会被docker run的指令覆盖的,还是会执行ENTRYPOINT的
我们要覆盖entrypoint的话,就要指定–entrypoint
docker run -it --entrypoint “/bin/sh” --rm cmd:v0.2 -c “echo hello bit2!”
在这里插入图片描述
这个就是把"/bin/sh" 覆盖为 “echo hello bit2!”,-c是指定覆盖的内容
因为是shell模式,所以只能去覆盖/bin/sh,ENTRYPOINT的内容都是/bin/sh的参数
这样我们就覆盖ENTRYPOINT了
如果是exec格式的话,
cp Dockerfile2 Dockerfile3

vi Dockerfile3

FROM busybox
ENTRYPOINT echo "hello world!"
ENTRYPOINT ["echo","hello bit!"] 

docker build -t cmd:v0.3 -f Dockerfile3 .
docker run -it --rm cmd:v0.3 echo hello bit2!
在这里插入图片描述
我们可以发现变成了这个样子
因为这个相当于把echo hello bit2!这个命令全部作为参数全部喂给了ENTRYPOINT 中的echo命令
因为在shell格式中,echo hello bit2!无法作为参数赋给/bin/sh,所以没有什么用,
所以cmd,ENTRYPOINT 可以正常运行
但是exec格式,会把docker run里面的内容作为参数喂给ENTRYPOINT 中的命令

Shell VS Exec

vi Dockerfile4

FROM ubuntu:22.04 
RUN apt-get update -y && apt install -y iputils-ping 
CMD ping localhost 

docker build -t cmd:v0.4 -f Dockerfile4 .
docker run -it --rm cmd:v0.4
在这里插入图片描述
我们发现一直在ping本机
其实命令不是ping xxxx
而是 /bin/sh -c "ping xxx "
另一个shell
docker exec -it 容器id bash
ps -ef
在这里插入图片描述
这里可以看到pid为1的 不是ping
这个就是shell格式

FROM ubuntu:22.04 
RUN apt-get update -y && apt install -y iputils-ping 
CMD ["ping", "localhost"] 

docker build -t cmd:v0.5 -f Dockerfile4 .
docker run -it --rm cmd:v0.5
另一个shell
docker ps
在这里插入图片描述
docker exec -it 容器id bash
ps -ef
在这里插入图片描述
强烈推荐使用exec格式

组合

就是ENTYRPOINT存命令
CMD存参数
vi Dockerfile6

FROM ubuntu:22.04 
RUN apt-get update -y && apt install -y iputils-ping 
ENTRYPOINT ["ping","-c","3"]
CMD ["localhost"] 

参数就是[“localhost”]

docker build -t cmd:v0.6 -f Dockerfile6 .
docker run -it --rm cmd:v0.6

在这里插入图片描述
ping了三次就自动停止了,如果没有指定,就会一直ping

docker run -it --rm cmd:v0.6 www.baidu.com
在这里插入图片描述
这样也可以
因为www.baidu.com会替换CMD,作为ENTEYPOINT的参数

合理使用dockerignore

基础知识

Docker 是 C-S 架构,理论上Client和Server可以不在一台机器上。在构建docker镜
像的时候,需要把所需要的文件由Client发送给Server,这些要发送的文件叫做
build context。
回忆一下我们之前讲到的构建镜像的命令, 在命令的最后我们加了一个.表示当前目
录, 这个目录其实就代表了build context所指向的目录。
Shell
docker build -f -t <dockerfile_name> .
如果想忽略掉一些传送给Sever端的文件, 这就会用到.dockerignore文件。它会将记
录的所有文件都忽略掉, 不会传送给Server端, 有效的避免一些和容器内应用运行
无关的文件不会被复制到Server端, 即不会将无关的文件打入生成的镜像中

实战

mkdir ignore
cd ignore
vi Dockerfile

FROM centos:7
COPY ./* /

vi .dockerignore

*.txt

这个就是会忽略txt文件
echo "hello bit data " > ./test.data
echo “hello bit txt” > ./test.txt
docker build -t ignore:v0.1 .
docker run -it --rm ignore:v0.1 bash
ll
在这里插入图片描述
我们看到并没有test.txt

多阶段构建

基础知识

构建docker镜像可以有下面两种方式
• 将全部组件及其依赖库的编译、测试、打包等流程封装进一个docker镜像中。但
是这种方式存在一些问题, 比如 Dockefile 特别长,可维护性降低;镜像的层次多,
体积大,部署时间长等问题
• 将每个阶段分散到多个 Dockerfile。一个 Dockerfile 负责将项目及其依赖库
编译测试打包好后,然后将运行文件拷贝到运行环境中,这种方式需要我们编写多个
Dockerfile 以及一些自动化脚本才能将其两个阶段自动整合起来
• 为了解决以上的两个问题,Docker 17.05版本开始支持多镜像阶段构建。只需
要编写一个 Dockerfile即可解决上述问题。
在这里插入图片描述

实战

我们先拷贝之前c++写的Dockerfile
cp -r …/cpp/* .
在这里插入图片描述
docker build -t multi:v1.0 .
docker images multi
在这里插入图片描述
docker run --rm -it multi:v1.0
在这里插入图片描述
但是镜像很大
我们来修改Dockerfile

FROM centos:7 
# 设置版本 
ENV VERSION 1.0 
#设置国内源 
RUN  sed -e 's|^mirrorlist=|#mirrorlist=|g' \ 
         -e 
's|^#baseurl=http://mirror.centos.org/centos|baseurl=https://mirro
 rs.ustc.edu.cn/centos|g' \ 
         -i.bak \ 
         /etc/yum.repos.d/CentOS-Base.repo 
RUN yum makecache 
# 设置工作目录 
WORKDIR /src 
# 拷贝源文件 
COPY demo.c . 
# 安装gcc  
RUN yum install -y gcc && \ 
    gcc -v 
# 编译源文件 
RUN gcc demo.c -o demo && \ 
    rm -f demo.c && \ 
    yum erase -y gcc 
# 运行可执行文件 
CMD ["/src/demo"] 

修改后

FROM centos:7 as buildstage
# 设置版本 
ENV VERSION 1.0 
#设置国内源 
RUN  sed -e 's|^mirrorlist=|#mirrorlist=|g' \ 
         -e 
's|^#baseurl=http://mirror.centos.org/centos|baseurl=https://mirro
 rs.ustc.edu.cn/centos|g' \ 
         -i.bak \ 
         /etc/yum.repos.d/CentOS-Base.repo 
RUN yum makecache 
# 设置工作目录 
WORKDIR /src 
# 拷贝源文件 
COPY demo.c . 
# 安装gcc  
RUN yum install -y gcc && \ 
    gcc -v 
# 编译源文件 
RUN gcc demo.c -o demo && \ 
    rm -f demo.c && \ 
    yum erase -y gcc 
# 运行可执行文件 
CMD ["/src/demo"] 

FROM centos:7 
COPY --from=buildstage /src/demo /src/
CMD ["/src/demo"] 

docker build -t multi:v2.0 .
docker images multi
在这里插入图片描述

docker run --rm -it multi:v2.0
在这里插入图片描述
多级构建之后大小大大的减小了

FROM centos:7 as buildstage
# 设置版本 
ENV VERSION 1.0 
#设置国内源 
RUN  sed -e 's|^mirrorlist=|#mirrorlist=|g' \ 
         -e 
's|^#baseurl=http://mirror.centos.org/centos|baseurl=https://mirro
 rs.ustc.edu.cn/centos|g' \ 
         -i.bak \ 
         /etc/yum.repos.d/CentOS-Base.repo 
RUN yum makecache 
# 设置工作目录 
WORKDIR /src 
# 拷贝源文件 
COPY demo.c . 
# 安装gcc  
RUN yum install -y gcc && \ 
    gcc -v 
# 编译源文件 
RUN gcc demo.c -o demo && \ 
    rm -f demo.c && \ 
    yum erase -y gcc 
# 运行可执行文件 
CMD ["/src/demo"] 

FROM busybox 
COPY --from=buildstage /src/demo /src/
CMD ["/src/demo"] 

docker build -t multi:v3.0 .
docker images multi
docker run --rm -it multi:v2.0
在这里插入图片描述
构建docker镜像可以有下面两种方式
• 将全部组件及其依赖库的编译、测试、打包等流程封装进一个docker镜像中。但
是这种方式存在一些问题, 比如 Dockefile 特别长,可维护性降低;镜像的层次多,
体积大,部署时间长等问题
• 将每个阶段分散到多个 Dockerfile。一个 Dockerfile 负责将项目及其依赖库
编译测试打包好后,然后将运行文件拷贝到运行环境中,这种方式需要我们编写多个
Dockerfile 以及一些自动化脚本才能将其两个阶段自动整合起来
• 为了解决以上的两个问题,Docker 17.05版本开始支持多镜像阶段构建。只需
要编写一个 Dockerfile即可解决上述问题。

合理使用缓存

基础知识

• 在镜像的构建过程中,Docker 会根据 Dockerfile 指定的顺序执行每个指令。在执
行每条指令之前,Docker 都会在缓存中查找是否已经存在可重用的镜像,如果有就使
用现存的镜像,不会再重复创建。
• 在上边提到 Dockerfile中的每一条指令都会产生一层image layer。当某一个
layer 修改后,后面的所有layer我们都不能使用缓存, 这一点一定要注意。
• 如果不想在构建过程中使用缓存,你可以在 docker build 命令中使用 --no
cache=true 选项。但是我们建议最好合理使用缓存, 这样可以加快构建镜像的效率。

在这里插入图片描述
在这里插入图片描述
编译软件放在上面,那么每次修改代码都能使用安装编译软件的缓存了,不然使用不到它的缓存

实战

FROM centos:7 
# 设置版本 
ENV VERSION 1.0 
#设置国内源 
RUN  sed -e 's|^mirrorlist=|#mirrorlist=|g' \ 
         -e 
's|^#baseurl=http://mirror.centos.org/centos|baseurl=https://mirro
 rs.ustc.edu.cn/centos|g' \ 
         -i.bak \ 
         /etc/yum.repos.d/CentOS-Base.repo 
RUN yum makecache 
# 设置工作目录 
WORKDIR /src 
# 拷贝源文件 
COPY demo.c . 
# 安装gcc  
RUN yum install -y gcc && \ 
    gcc -v 
# 编译源文件 
RUN gcc demo.c -o demo && \ 
    rm -f demo.c && \ 
    yum erase -y gcc 
# 运行可执行文件 
CMD ["/src/demo"] 

docker build -t mucache:v1.0 .
因为有缓存,所以构建很快

vi demo.c
在这里插入图片描述
docker build -t mucache:v2.0 .
这次就很慢了

在这里插入图片描述
看的出来第一次构建用了0.1s
第二次用了20多s

FROM centos:7 
# 设置版本 
ENV VERSION 1.0 
#设置国内源 
RUN  sed -e 's|^mirrorlist=|#mirrorlist=|g' \ 
         -e 
's|^#baseurl=http://mirror.centos.org/centos|baseurl=https://mirro
 rs.ustc.edu.cn/centos|g' \ 
         -i.bak \ 
         /etc/yum.repos.d/CentOS-Base.repo 
RUN yum makecache 
# 设置工作目录 
WORKDIR /src 
# 安装gcc  
RUN yum install -y gcc && \ 
    gcc -v 
# 拷贝源文件 
COPY demo.c . 
# 编译源文件 
RUN gcc demo.c -o demo && \ 
    rm -f demo.c && \ 
    yum erase -y gcc 
# 运行可执行文件 
CMD ["/src/demo"] 

现在优化一下顺序

docker build -t mucache:v3.0 .

在这里插入图片描述
vi demo.c

docker build -t mucache:v4.0 .
在这里插入图片描述
这样就变快了

总结


http://www.kler.cn/a/611591.html

相关文章:

  • Visual Studio 使用 IntelliCode AI 辅助代码开发
  • 【CUDA】mnist_cuda
  • 模块学习篇#2:解析常用于YOLO等深度学习模型的注意力机制CBAM
  • Oracle常用分析诊断工具(9)——ADDM
  • Java单例设计模式详解
  • 深度学习篇---卷积网络结构
  • 【CodeReview】Jupiter(Eclipse插件)代码审查工具简介
  • Oracle补丁自动化安装步骤
  • 阶段一:Java基础语法
  • 运行前端项目报错解决方法
  • 游戏引擎学习第184天
  • MTK Android15 去掉设置中的顶部空白
  • 苹果与安卓,鸿蒙下跨设备,应用分享
  • 12届蓝桥杯—货物摆放
  • 【软件工程】简答题
  • 开源软件许可证冲突的原因和解决方法
  • ZW3D二次开发_非模板表单_控件_添加回调
  • Leetcode12-整数转罗马数字
  • 数据库基础知识点(系列七)
  • 【开题报告+论文+源码】基于SpringBoot的智能安全与急救知识科普系统设计与实现