Docker实战

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
简介: Docker实战

         

968c3cf2e99b4e9b99da7f768958a4f7.png

一、FROM 语法

scratch -- 从头开始

尽量来使用官方提供的image


FROM 指定基础镜像,最好挑一些apline,slim之类的基础小镜像. scratch镜像是一个空镜像,常用于多阶段构建 如何确定我需要什么要的基础镜像? Java应用当然是java基础镜像(SpringBoot应用)或者Tomcat基础镜像(War应用) JS模块化应用一般用nodejs基础镜像 其他各种语言用自己的服务器或者基础环境镜像,如python、golang、java、php等e19acc465c7e4728bdc6115d90f2582b.png

编辑

二、label语法

meta信息,类似于代码的注释。

LABEL multi.label1="value1" multi.label2="value2" other="value3"
LABEL multi.label1="value1" \
multi.label2="value2" \
other="value3"

三、run语法

没run一次image上会有新的一层。因此有必要使用&&合并执行,避免layer 过多看起来很混乱。

编辑

四、workdir 语法

使用workdir不要使用run cd来替代

workdir尽量使用绝对路径。增强dockerfile的可移植性。

编辑

五、add 和copy 语法

  • 区别:add 还具有解压缩的功能,例如add test.tat.gz / 会直接将test.tar.gz解压出来

下面以reids源代码为例进行演示

Dockerfile如下

FROM alpine
ADD ./redis-7.0.8.tar.gz /redis/
RUN ls -l
RUN cd /redis && ls -l

结果

  • workdir 和add的结合
  • 添加远程文件/目录使用curl 或者 wget

编辑

copy文件夹时候的坑

https://www.jianshu.com/p/9b7da9aacd8a

六、ENV语法

定义常量,增加可维护性,和shell中定义变量一个意思。

编辑

七、volume 和expose 语法

八、run、cmd 和entrypoint

编辑2df0130c75be48cab5fb12251970f6e9.png例子:

shell 格式的docker file build的image

[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# more Dockerfile 
FROM centos
ENV name Docker
ENTRYPOINT echo "hello $name"
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# docker build -t ninesun0318/centos-entrypoint-shell .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM centos
 ---> 0d120b6ccaa8
Step 2/3 : ENV name Docker
 ---> Running in 00b2f71e6d9f
Removing intermediate container 00b2f71e6d9f
 ---> 4be9a34323b3
Step 3/3 : ENTRYPOINT echo "hello $name"
 ---> Running in cfc67b613f7a
Removing intermediate container cfc67b613f7a
 ---> 865aaaacd1ee
Successfully built 865aaaacd1ee
Successfully tagged ninesun0318/centos-entrypoint-shell:latest
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# docker image ls
REPOSITORY                            TAG                 IMAGE ID            CREATED             SIZE
ninesun0318/centos-entrypoint-shell   latest              865aaaacd1ee        17 seconds ago      215MB
centos                                latest              0d120b6ccaa8        2 months ago        215MB
hello-world                           latest              bf756fb1ae65        10 months ago       13.3kB
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# docker run 865aaaacd1ee
hello Docker

很完美这个dockerfile没有问题。

exec格式的docker file build的image

[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# more Dockerfile 
FROM centos
ENV name Docker
ENTRYPOINT ["/bin/echo", "hello $name"]
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# docker build -t ninesun0318/centos-entrypoint-exec .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM centos
 ---> 0d120b6ccaa8
Step 2/3 : ENV name Docker
 ---> Using cache
 ---> 4be9a34323b3
Step 3/3 : ENTRYPOINT ["/bin/echo", "hello $name"]
 ---> Running in 61c84954936b
Removing intermediate container 61c84954936b
 ---> 2292313abbf0
Successfully built 2292313abbf0
Successfully tagged ninesun0318/centos-entrypoint-exec:latest
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# 
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# 
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# docker image ls
REPOSITORY                            TAG                 IMAGE ID            CREATED             SIZE
ninesun0318/centos-entrypoint-exec    latest              2292313abbf0        5 seconds ago       215MB
ninesun0318/centos-entrypoint-shell   latest              865aaaacd1ee        8 minutes ago       215MB
centos                                latest              0d120b6ccaa8        2 months ago        215MB
hello-world                           latest              bf756fb1ae65        10 months ago       13.3kB
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# docker run ninesun0318/centos-entrypoint-exec
hello $name
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# 

奇怪exec 并没有把name 这个ENV打印出来。为何?

只有shell 中才会执行name才会被解释为变量,exec 就是简单的执行。

如何修改呢?

[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# more Dockerfile 
FROM centos
ENV name Docker
ENTRYPOINT ["/bin/bash","-c","echo hello $name"]
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# 

重新build 然后run

[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# docker build -t ninesun0318/centos-entrypoint-exec-new .
Sending build context to Docker daemon  2.048kB
Step 1/3 : FROM centos
 ---> 0d120b6ccaa8
Step 2/3 : ENV name Docker
 ---> Using cache
 ---> 4be9a34323b3
Step 3/3 : ENTRYPOINT ["/bin/bash","-c","echo hello $name"]
 ---> Running in 5ee34add9195
Removing intermediate container 5ee34add9195
 ---> cf961663ddc1
Successfully built cf961663ddc1
Successfully tagged ninesun0318/centos-entrypoint-exec-new:latest
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# docker run ninesun0318/centos-entrypoint-exec-new
hello Docker
[root@iZ2vceej7yes1abpm7yec2Z dockerfile]# more Ddo
more: stat of Ddo failed: No such file or directory

这个问题得到了解决。

cmd推荐写法

6da701c7304a46da8a41c4abcaa70687.pngDockerfile 测试

CMD为ENTRYPOINT提供默认参数

FROM alpine
LABEL mantainer=ninesun
CMD ["testvm"]
CMD ["uuuidd"]
ENTRYPOINT ["echo"]
docker build -t demo:test -f Dockerfile3 .
docker run  --rm --name test demo:test
uuuidd
# 指定其他命令 
docker run  --rm --name test demo:test 22222
22222

9f10321e373b4064b73b7ae3188e9175.pngentrypoint推荐写法

例子说明:entrypoint 一定会被执行,cmd 会被覆盖。

Dockerfile列子

1. FROM alpine
2. LABEL mantainer=ninesun
3. CMD ["testvm"]
4. CMD ["uuuidd"]
5. ENTRYPOINT ["echo","hahhahah"]
# docker run指定参数 覆盖cmd,但是entrypoint一定被执行
docker run  --rm --name test demo:test 222
hahhahah 222
# docker run 不覆盖cmd,但是entrypoint一定被执行
docker run  --rm --name test demo:test
hahhahah uuuidd

CMD和ENTRYPOINT两者都可以作为容器的入口

Dockerfile中只能有一条CMD指令。 如果列出多个CMD,则只有最后一个CMD才会生效。

CMD的主要目的是为执行中的容器提供默认值。 这些默认值可以包含可执行文件,也可以省略可执行文件,在这种情况下,您还必须指定ENTRYPOINT指令。

ARG和ENV的区别

  • ARG 是构建时变量
  • ENV是运行时变量

1、ARG

ARG指令定义了一个变量,用户可以在构建时使用--build-arg = 传递,docker build命令会将其传递给构建器。--build-arg 指定参数会覆盖Dockerfile 中指定的同名参数

如果用户指定了 未在Dockerfile中定义的构建参数 ,则构建会输出 警告 。

ARG只在构建期有效,运行期无效

不建议使用构建时变量来传递诸如github密钥,用户凭据等机密。因为构建时变量值使用docker

history是可见的

ARG变量定义从Dockerfile中定义的行开始生效。

2、ENV

  • 在构建阶段中所有后续指令的环境中使用,并且在许多情况下也可以内联替换。
  • 引号和反斜杠可用于在值中包含空格。
  • ENV 可以使用key value的写法,但是这种不建议使用了,后续版本可能会删除
ENV MY_MSG hello
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
  • docker run --env 可以修改这些值
  • 容器运行时ENV值可以生效
  • ENV在image阶段就会被解析并持久化(docker inspect image查看),参照下面示例
FROM alpine
ENV arg=1111111
ENV runcmd=$arg
RUN echo$runcmd
CMD echo$runcmd  #ENV的固化问题: 改变arg,会不会改变 echo的值,会改变哪些值,如何修改这些值?

测试案例

FROM alpine
ARG arg1=22222
ENV arg2=1111111
ENV runcmd=$arg1
RUN echo$arg1$arg2$runcmd
CMD echo$arg1$arg2$runcmd

实战

java-springboot 镜像

# syntax=docker/dockerfile:1
FROM 10.50.10.185/qms/openjdk:8-jdk-alpine
LABEL maintainer="ninesun@126.com"
WORKDIR /opt/app
COPY target/*.jar ./
#Alpine Linux 下的包管理工具
#RUN apk   add mysql-client
# 设定时区UTC -> CST
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone && touch EDA_ETL-0.0.51-SNAPSHOT.jar
ENV JAVA_OPTS=""
ENV PARAMS=""
ENTRYPOINT [ "sh", "-c", "java -Djava.security.egd=file:/dev/./urandom $JAVA_OPTS -jar EDA_ETL-0.0.51-SNAPSHOT.jar $PARAMS" ]

python 程序镜像

FROM submitty/python:3.7
COPY ./redis_key_mig /app
WORKDIR /app
RUN /bin/bash -c 'pwd;ls -l /app'
#RUN  /usr/local/bin/python -m pip install --upgrade pip
RUN pip3 install redis==3.5.3
cmd ["python", "/app/redisMigrate.py"]
相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
29天前
|
SQL 关系型数据库 数据库
国产数据实战之docker部署MyWebSQL数据库管理工具
【10月更文挑战第23天】国产数据实战之docker部署MyWebSQL数据库管理工具
98 4
国产数据实战之docker部署MyWebSQL数据库管理工具
|
7天前
|
JavaScript Linux 持续交付
深入探索容器化技术——Docker 的实战应用
深入探索容器化技术——Docker 的实战应用
32 0
|
3月前
|
Docker 容器
Docker自建仓库之Harbor高可用部署实战篇
关于如何部署Harbor高可用性的实战教程,涵盖了从单机部署到镜像仓库同步的详细步骤。
151 15
Docker自建仓库之Harbor高可用部署实战篇
|
3月前
|
算法 Linux 调度
Docker的资源限制实战篇
本文详细介绍了如何利用Docker对容器的资源进行限制,包括内存和CPU的使用。文章首先概述了资源限制的重要性及其在Linux系统中的实现原理,并强调了不当设置可能导致的风险。接着,通过一系列实战案例展示了如何具体设置容器的内存限制,包括硬性限制、动态调整以及软限制等。最后,文章还提供了限制容器CPU访问的具体方法和示例,如指定容器使用的CPU核心数和基于`--cpu-shares`参数对CPU资源进行分配。通过这些实践,读者可以更好地理解和掌握Docker资源管理技巧。
267 14
Docker的资源限制实战篇
|
3月前
|
存储 数据管理 应用服务中间件
Docker的数据管理实战篇
关于Docker数据管理实战的教程,涵盖了Docker数据卷的使用、特点、场景以及数据卷容器的概念和应用。
67 13
Docker的数据管理实战篇
|
3月前
|
运维 Cloud Native Docker
云原生技术入门:Docker容器化实战
【9月更文挑战第20天】本文将引导你走进云原生技术的世界,通过Docker容器化技术的实战演练,深入理解其背后的原理和应用。我们将一起探索如何在云平台上利用Docker简化部署、扩展和管理应用程序的过程,并揭示这一技术如何改变现代软件的开发和运维模式。
|
3月前
|
Ubuntu Linux Docker
Ubuntu 18.04 安装Docker实战案例
关于如何在Ubuntu 18.04系统上安装Docker的实战案例,包括安装步骤、配置镜像加速以及下载和运行Docker镜像的过程。
370 3
Ubuntu 18.04 安装Docker实战案例
|
3月前
|
存储 Linux Docker
CentOS 7.6安装Docker实战案例及存储引擎和服务进程简介
关于如何在CentOS 7.6上安装Docker、介绍Docker存储引擎以及服务进程关系的实战案例。
152 3
CentOS 7.6安装Docker实战案例及存储引擎和服务进程简介
|
3月前
|
关系型数据库 Linux 虚拟化
Docker入门基础实战
Docker入门基础实战
|
2月前
|
Ubuntu Linux 应用服务中间件
Docker容器入门实战
Docker容器入门实战