刚刚开通了一个公众号,会分享一些技术博客和自己觉得比较好的项目,同时会更新一些自己使用的工具和图书资料,后面会整理一些面试资料进行分享,觉得有兴趣的可以关注一下。
文章目录
- 前言
- 打包镜像
- Dockerfile语法
- 项目使用
- 遇到的问题
- 后续继续更新
前言
公司最近切换架构,从PCF
切换到CAAS
,两者其实都是基于k8s
的平台,PCF
入手很快,使用很简单,直接有构建工具可以直接构建,但是可定制化的不够完全。
CAAS
基本就是k8s
那一套了,迁移最近也学习了一下k8s
,颇有收获。
打包镜像
CAAS
跟PCF
不一样的点,就是需要自己打包一下镜像,PCF
当然也可以,但是由于基本的构建工具,只需要提供一个jar
就能直接发布。但是CAAS
是需要打包的。我们肯定用的是私有云,这个就暂时不透露了,私有云都差不多。
打包镜像我们肯定是需要Dockerfile
的,因为后续是用在pipeline
上的,自动化构建。
Dockerfile语法
关键字 | 描述 | 语法 | 说明 |
---|---|---|---|
FROM | FROM <image>[:<tag> | @<digest>] [AS <name>] | 1.FROM指定一个基础镜像,且必须为Dockerfile文件开篇的每个非注释行,至于image则可以是任何合理存在的image镜像 2.FROM可以在一个Dockerfile中出现多次,以便于创建混合的images。如果没有指定tag,latest将会被指定为要使用的基础镜像版本。 3.AS name,可以给新的构建阶段赋予名称。该名称可用于后续FROM 和 COPY --from=<name | index>说明可以引用此阶段中构建的镜像 | |
LABEL | 为镜像生成元数据标签信息 | LABEL = \ <KEY>=“XXXX” | 多个标签写成一行,避免在镜像中额外增加layer |
MAINTAINER | 作者信息,写在FROM后 | MAINTAINER “auth <email>” | |
COPY | 当复制一个目录时,并不会复制目录本身,而是会递归复制其下子目录 至目标目录下. | COPY src dest | 文件复制准则: 1.必须是build上下言文中的路径,不能是其父目录中的文件。 2.如果src是目录,则其内部文件或子目录会被递归复制,但src目录自身不会被复制 3.如果指定了多个src,或在src中使用了通配符,则dest必须是一个目录,且必须以/结尾 4.如果dest事先不存在,它将会被自动创建,这包括其父目录路径。 |
ADD | ADD指令类似于COPY指令,ADD支持使用TAR文件和URL路径 | ADD <src>…<dest> ADD [“<src>”,…“<dest>”] | 1.如果<src>为URL且<dest>不以/结尾,则<src>指定的文件将被下载并直接被创建为<dest>;如果<dest>以/结尾,则文件名URL指定的文件将被直接下载并保存为<dest>/<filename> 2.如果<src>是一个本地文件系统上的压缩格式的tar文件,它将被展开为一个目录,其行为类似于"tar -x"命令;然而,通过URL获取到的tar文件将不会自动展开。 3.如果<src>有多个,或其间接或直接使用了通配符,则<dest>必须是一个以/结尾的目录路径;如果<dest>不以/结尾,则其被视作一个普通文件,<src>内容将被直接写入到<dest> 4.为了让镜像尽量小,最好不要使用 ADD 指令从远程 URL 获取包,而是使用 curl 和 wget。这样你可以在文件提取完之后删掉不再需要的文件来避免在镜像中额外添加一层。 |
WORKDIR | 用于为Dockerfile中所有RUN、CMD、ENTRYPOINT、COPY和ADD指令设定工作目录 | WORKDIR dir | 在Dockerfile文件中,WORKDIR指令可以出现多次,其路径也可以为相对路径,不过,其是相对此前一个WORKDIR指令指定的路径另外,WORKDIR也可调用由ENV指定定义的变量 |
RUN | 接受命令作为参数并用于创建镜像,在之前的commit层上形成新的层 | RUN (如同执行shell命令 /bin/sh -c) RUN [“executable”,“param1”,“param2”] | 1.RUN 指令将在当前image中执行任意合法命令并提交执行结果。命令执行提交后,就会自动执行Dockerfile中的下一个指令。 2.分层RUN指令和生成提交符合Docker的核心概念,其中提交很轻量,可以从image将用于Dockerfile中的下一步。 3.exec形式使得可以避免shell字符串变化,以及使用不包含指定的shell可执行文件的基本image来运行RUN命令。 4.在shell形式中,可以使用\(反斜杠)将单个RUN指令继续到下一行 |
CMD | 类似于RUN指令,CMD指令也可用于运行任何命令或应用程序 | CMD <command> //支持命令展开,但是不支持传递信号 CMD [“<executable>”,“<param1>”,“<param2>”] //相当于容器的第一个命令,可以接受信号 CMD [“param1”,“param2”] | CMD会在启动容器的时候执行,build时不执行,而RUN只是在构建镜像的时候执行,后续镜像构建完成之后,启动容器就与RUN无关了。这个命令就相当于在/etc/rc.d/rc.local中写命令.在Dockerfile中可以存在多个CMD指令,但仅最后一个生效 |
ENTRYPOINT | 类似CMD指令的功能,用于为容器指定默认运行程序,从而使得容器像是一具单独的可执行程序 与CMD不同的是,由ENTRYPOINT启动的程序不会被docker run命令行指定的参数所覆盖,而且,这些命令行参数会被当作参数传递给ENTRYPOINT指定的程序。不过,docker run 命令的–entrypoint 选项的参数可覆盖ENTRYPOINT指令指定的程序 | ENTRYPOINT <command> //这种方式能接受shell命令行展开 ENTRYPOINT [“<executable>”,“param1”] //展开不了,但能接收到信号 | docker run命令传入的命令参数会覆盖CMD指令的内容并且附加到ENTRYPOINT命令最后做为其参数使用。Dockerfile文件中也可以存在多个ENTRYPOINT指令,但仅有最后一个会生效 |
EXPOSE | 用来指定端口,使容器内的应用可以通过端口和外界交互 | 告诉Docker服务端容器对外映射的本地端口,需要在docker run 的时候使用-p 或者 -P 选项生效。 | |
ENV | ENV指令可以用于docker容器设置环境变量 | 指定一个环境变量,会被后续RUN指令使用,并在容器运行时保留。ENV设置的环境变量,可以使用 docker inspect 命令来查看。同时还可以使用 docker run --env <key>=<value>来修改环境变量 |
项目使用
Dockerfile使用如下:
FROM openjdk:11
LABEL app=app
WORKDIR "/home/app"
ENV \PARAMS="" \JAVA_OPTS=""
COPY ./build/libs/app.jar ./
RUN /bin/cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone
ENTRYPOINT ["sh", "-c", "java -Djava.security.egd=file:/dev/./urandom -Djava.io.tmpdir=/home/app/tmpdir ${JAVA_OPTS} -jar app.jar ${PARAMS}"]
EXPOSE 8080
FROM
可以忽略,这个涉及私有云,然后标签属性,设置工作目录,设置好环境变量,可以为不同的环境设置不同的启动参数。RUN
主要用来设置时区,因为默认时间不是中国时间。最后暴露端口8080。
遇到的问题
开始没有使用sh -c
,直接使用的java
命令,然后加入${PARAMS}
和${JAVA_OPTS}
完全不生效。后来才发现问题。
sudo
会给后面的 shell
命令授权, 但仅此而已. 如果后面还接有其他命令, 就会显示Permission denied
, 因为后面的命令并没有被授权
而 sh -c "command ..."
就是对后面的一整条命令整体授权, 所以多个命令需要使用 sh -c
如果不使用这个命令,设置的这两个参数就会完全不识别。