Dockerfile文件常用命令,docker容器的隔离机制授权,及docker run命令运行与调试

Posted 阿啄debugIT

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Dockerfile文件常用命令,docker容器的隔离机制授权,及docker run命令运行与调试相关的知识,希望对你有一定的参考价值。

Dockerfile文件常用命令

FROM命令

FROM:获取基础镜像,FROM必须是第一个命令,如果需要多个镜像时,可以使用多个FROM指令(每个镜像一次),如果不加tag,默认是使用latest,如下所示:

# FROM <image name>
# FROM <image name>:<tag>
FROM ubuntu
FROM java:8

RUN命令

RUN:在构建镜像过程中执行特定的指令,并生成一个中间镜像

  • RUN <commond>:shell格式
  • RUN ["executable", "param1", "param2"]:exec格式

CMD命令

CMD:指定容器运行时的默认参数,如果出现多次以最后一次为准

  • CMD ["executable", "param1", "param2"]exec格式
  • CMD command param1 param2shell格式

LABEL命令

LABEL:给构建的镜像打标签,如果base image中也有标签,则继承,如果是同名标签,则覆盖。为了减少图层数量,尽量将标签写在一个LABEL指令中去

LABEL <key>=<value> <key>=<value> ...

# 实例
LABEL multi.lable1="value1" multi.lable2="value2" other="value3"

EXPOSE命令

EXPOSE:为构建的镜像设置监听端口,但是并不会让容器监听host的端口

EXPOSE <port> [<port>...]

#多个映射接口
EXPOSE 8080
EXPOSE 8090
EXPOSE 9090

ENV命令

ENV:在构建的镜像中设置环境变量

#可以设置多个环境变量,如果<value>中存在空格,需要转义用引号"括起来

ENV myName="John Doe" \\
myDog=Rex\\ The\\ Dog \\
myCat=fluffy

ADD命令

ADD:在构建镜像时,复制文件到镜像中

# <src>可以是文件、目录,也可以是文件URL,如果<src>是个目录,则复制的是目录下的所有内容,但不包括该目录
# <dest>可以是绝对路径,也可以是相对WORKDIR目录的相对路径
ADD <src>... <dest>
ADD ["<src>",... "<dest>"]

ENTRYPOINT命令

ENTRYPOINT:指定镜像的执行程序,只有最后一条ENTRYPOINT指令有效

#CMD和ENTRYPOINT至少得使用一个。ENTRYPOINT应该被当做docker的可执行程序,CMD应该被当做ENTRYPOINT的默认参数

ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

VOLUME命令

VOLUME:指定镜像内的目录为数据卷,使此目录具有持久化存储数据的功能,该目录可以被容器本身访问,也可以被其他容器访问

VOLUME ["/var/log"]
VOLUME /var/log /var/db

Dockerfile文件实际应用

下面是两个简单的构建镜像的Dockerfile文件,分别是后台的和前端的项目

后台SpringBoot项目:

#简单的Dockerfile
[root@localhost work_data]# vim dev/azserver/Dockerfile
FROM java:8
ADD nile-az-be-0.0.1.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

#复杂的Dockerfile
[root@localhost work_data]# vim dev/jmserver/Dockerfile

FROM openjdk:8
MAINTAINER azdebugIT
LABEL app="jmserver" version="0.0.1" by="azdebugIT"
COPY ./data-jmserver-0.0.1-SNAPSHOT.jar jmserver-data.jar
COPY ./config config
EXPOSE 9005
ENV JAVA_OPTS=""
CMD java $JAVA_OPTS -jar jmserver-data.jar
#install sshpass
#RUN apt-get update && apt-get -y install sshpass --assume-yes apt-utils
RUN DEBIAN_FRONTEND=noninteractive apt-get update && apt-get install sshpass --assume-yes

前端项目:

FROM nginx
RUN rm -rf /etc/nginx/nginx.conf
ADD mz-feature-mwc-customization /etc/nginx/html/mz-feature-mwc-customization
ADD nginx.conf /etc/nginx/nginx.conf

在docker容器中使用gdb调试

如何在docker容器中的centos,使用gdb调试?

ptrace: Operation not permitted
解决方法 参考:https://stackoverflow.com/questions/42029834/gdb-in-docker-container-returns-ptrace-operation-not-permitted

在docker run 命令中加上参数--cap-add=SYS_PTRACE

docker run --cap-add=SYS_PTRACE ......

更多cap可查看手册

还有不太优雅的做法不建议使用:通过–privileged解决 –privileged等效于–cap-add=ALL

进入容器之后执行修改容器时间

格式如下:

docker run  --cap-add=SYS_TIME --cap-add=SYS_PTRACE    ...

以普通方式运行docker容器

docker run -it --rm --name centos centos /bin/bash

参数说明:

-it: 表示启用一个伪终端,并以交互方式运行
--rm: 表示退出之后立马删除该容器
--name: 表示给容器起一个名字
centos: 表示镜像名称
/bin/bash: 表示运行于bash程序

此时进入容器之后执行修改容器时间的指令

date +%T -s "15:03:00"

会给出date: cannot set date: Operation not permitted的错误

那么如何才能修改容器的时间呢? 主要是,因为有时候需要测试一些定时任务的场景

退出之前的容器, 以如下方式重新进入容器:

docker run -it --cap-add SYS_TIME --rm --name centos centos /bin/bash

进入容器再使用指令

date +%T -s "15:03:00"

修改时间, 此时就可以修改成功了.

这个和之前的方式有什么区别呢?多了--cap-add SYS_TIME参数

docker容器的隔离机制

由于docker容器的隔离是基于Linux的Capability机制实现的, Linux的Capability机制允许你将超级用户相关的高级权限划分成为不同的小单元. 目前Docker容器默认只用到了以下的Capability.

CHOWN, 
DAC_OVERRIDE, 
FSETID, 
FOWNER, 
MKNOD, 
NET_RAW, 
SETGID,  
SETUID, 
SETFCAP, 
SETPCAP, 
NET_BIND_SERVICE, 
SYS_CHROOT, 
KILL, 
AUDIT_WRITE

而要修改系统时间,需要有SYS_TIME权限.
使用 --cap-add, --cap-drop 可以添加禁用特定的权限.
--privileged参数也可以达到开放权限的作用, 与--cap-add的区别就是, --privileged是将所有权限给容器.
docker使用--privileged, --cap-add, --cap-drop 来对容器本身的能力进行开放或限制.

成功案例

[root@localhost work_data]# vim dev/jmserver/start.sh

#!/bin/sh
group=work_data
appname=jmserver
version=1.0.0
appport=28762
docker build -t $group/$appname:$version .
docker run --restart=always --name $group-$appname -e TZ="Asia/Shanghai" \\
-m 5120m \\
-e JAVA_OPTS='-Xmx4096m' \\
--cpus=2 \\
--cap-add=SYS_PTRACE \\
-v $PWD/config:/config \\
-p $appport:8762 \\
--add-host jmserver.eureka:172.16.8.11 \\
-d $group/$appname:$version

 

以上是关于Dockerfile文件常用命令,docker容器的隔离机制授权,及docker run命令运行与调试的主要内容,如果未能解决你的问题,请参考以下文章

docker常用命令镜像命令容器命令数据卷,使用dockerFile创建镜像,dockefile的语法规则。

docker 常用命令

学Docker(超详细)

docker之容器管理常用命令

docker常用技巧

Docker命令-docker run