制作Docker业务镜像

      随着容器云的迅猛发展,不断有业务需要Docker化。以下是笔者在制作Docker镜像中的一些浅见,希望能对大家有所帮助, 若有错误之处,欢迎大家指正与探讨。


基础镜像介绍

镜像仓库为大家提供了高效便捷的基础镜像,其中不仅包含安全所需的Onion Agent,还有发布平台、TGW等公司其他业务Agent, 减轻了大家制作业务镜像的负担。

1.tlinux2.2-gaia-with-onion:latest

服务列表 : 该基础镜像包含了安平的Onion Agent,制作业务镜像的时候无需再重新安装相应的组件,省去了不必要的重复性工作。完整镜像名称docker.oa.com:8080/library/tlinux2.2-gaia-with-onion:latest

  • onion agent

使用方法 :该镜像作为基础镜像,继承镜像需要先启动onion agent. 启动方式为:bash +x /usr/local/onion-start.sh

2、tlinux2.2-with-agent:latest

服务列表 : 当业务需要接入TGW、L5等,可以使用该镜像作为基础镜像。该基础镜像不仅包含必备的Onion组件,还包含了TGW、L5、发布平台等公司其他业务Agent。在制作业务镜像的时候只需专注业务逻辑,无需再关注各种Agent的安装。完整镜像名称docker.oa.com:8080/public/tlinux2.2-with-agent:latest

  • ssh
  • crontab
  • L5 agent
  • tnm2 agent
  • TSC Agent
  • publish platform agent
  • dns setting
  • onion agent

    开放端口

  • 8080
  • 80
  • 36000

    使用方法 :该镜像作为基础镜像,继承镜像需要先启动所有agent. 启动方式为:bash +x /usr/local/all-agent-start.sh

镜像制作示例

1、DockerFile 示例

    此处忽略DockerFile的各个指令介绍,Docker 官方网站有最全最详细的介绍文档。 ```

NAME Hello World Go With Onion Agent

Time 2017/5/11

VERSION 1.0.0

FROM docker.oa.com:8080/public/tlinux2.2-with-agent MAINTAINER elsanli [email protected] LABEL version="1.0" LABEL description="This Dockerfile is written for Hello World Go."

RUN yum -y update && \ yum install -y libstdc++.so.6 mariadb && \ yum clean all && \ rm -rf /tmp/ /var/tmp/ /data/tmp/* EXPOSE 36000 8080 80 WORKDIR /usr/local/

GO

COPY go1.6.3.linux-amd64.tar.gz ./ RUN tar zxvf go1.6.3.linux-amd64.tar.gz && mv go go1.6

ADD main.go /usr/local/go/ RUN cd go && chmod -v +x main.go

ADD run.sh ./ RUN chmod -v +x run.sh CMD ["/usr/local/run.sh"]

#### 2、Build
>       通常也可以将REPOSITORY设置为:业务名称/组件名称,方便管理。

docker build -t docker.oa.com:8080/public/hello-world-go:latest ./

#### 3、Push镜像到镜像仓库
>         可以将镜像Push到镜像仓库中进行保存。 Push镜像一分钟后,可以移步到 [GaiaStack体验环境](gaiastack.oa.com)  镜像仓库查看镜像,进行应用部署,并可以灵活绑定云硬盘,在线扩容等。若利用`GaiaStack`平台部署应用可以`略过步骤4-5`。
>    GaiaStack镜像仓库支持个人镜像、业务镜像、公有镜像。
    - 个人镜像:rtx名称/镜像名称:tag    `仅用户本人有权查看与部署`
    - 业务镜像:业务名称/镜像名称:tag (`其业务名称为:GaiaStack平台中业务组名称`) `仅同业务组人员有权查看与部署`
    - 公有镜像: public/镜像名称:tag    docker/镜像名称:tag    library/镜像名称:tag  `所有人有权查看与部署`

docker push docker.oa.com:8080/public/hello-world-go:latest

#### 4、启动容器

docker run -d docker.oa.com:8080/public/hello-world-go:latest


#### 5、登录容器

查看docker进程: docker ps

![Alt text](./1500463985616.png)

可以通过容器id登录容器: docker exec -it 645a767d59aa /bin/sh

##  精简镜像大小
>      由于Docker容器的文件系统采用了写入时拷贝技术,这项技术的作用是加快容器的启动时间,跟一般的虚拟机相比,容器的启动速度确实非常快。虽然该技术在很大程度上提升了docker容器的运行效率,但是也会增加磁盘读写方面的开销。 同时也为了避免大量时间都花费在等待镜像的回来传送上,精简镜像大小是非常有必要的。

#### 1、减少镜像Layer层数
      每次在Dockerfile中执行RUN命令的时候系统都会在镜像中新建一个层,每个镜像层都会占用一定的磁盘空间,因此为了尽量减少镜像的层数,最好把解压、删除等所有文件操作都写在同一行RUN命令下。可以看下下面的例子:

**错误示范**
```dockerfile
RUN tar zxvf go1.6.3.linux-amd64.tar.gz 
RUN mv go go1.6

      通过docker history查看,可以看到tar zxvf创建了一个大小为318.1MB的镜像层,而mv命令在它上面又创建了一个318.1MB的镜像层。 Alt text|1000*0

正确示范

RUN tar zxvf go1.6.3.linux-amd64.tar.gz && mv go go1.6

将tar zxvf操作与mv操作放在同一行RUN命令中,可以查看到, mv操作并没有再创建一个镜像层。 Alt text|1000*0

2、迁移数据

    不要把训练数据等直接COPY到镜像中,由于数据往往过于庞大,不仅占用存储空间,致使性能下降,更会导致敏感数据泄露。可以利用分布式文件系统、数据库等存储数据。比如将存储在 GaiaStack云平台的云硬盘(cephfs、ceph rbd)中,在部署应用的时候挂载该云硬盘,从而使用数据。

3、有效删除不必要文件

     在下载压缩包或者其他归档文件的时候,可以将其解压,以及立即删除归档文件。但前提是这几个操作还是要在同一个RUN命令下。

RUN yum -y update && \
    yum install -y libstdc++.so.6 mariadb && \
    yum clean all && \
    rm -rf /tmp/* /var/tmp/* /data/tmp/*

其他注意事项

1、当心latest标签

    不要误以为latest版本镜像是最新与最稳定的版本镜像,这可能是个惯例,但并不是出于任何严格的规定。与所有其他版本镜像一样,当有新的版本push到镜像仓库中,latest标签的镜像也不会自动更新。

2、不要在DockerFile中启动进程

    DockerFile的每个step都是在一个临时的container执行的,DockerFile里启动的进程并不会在之后的容器里启动。

3、当心/etc/resolv.conf

    直接将修改好的resolve.conf 文件在DockerFile中COPY到镜像里,当容器启动时候,会被宿主机resovle.conf覆盖。

4、tag充分体现版本变更

     若某个NODE节点上已经有了某个版本的镜像,若该版本镜像(latest除外)内容有所修改,虽然已经上传到镜像仓库中,在该节点上在利用该镜像启动容器,Docker是不会再从镜像仓库拉取新的镜像,所以tag要充分体现版本变更。

FAQ

1、 为何Docker容器内部无法解析域名

     有的基础镜像默认没有打开IP转发功能,可以通过查看proc文件系统,来确认IP转发功能状态。 如果文件中的值为0,则说明禁止IP转发,如果为1,这说明已经打开IP转发功能。 Alt text|1000*0

    如果IP转发被禁止,可以将net.ipv4.ip_forward参数修改为1 ,打开IP转发功能。

2、为何在 Docker容器中修改hosts文件,重启后无效

     容器中/etc/hosts文件不存在于镜像,而是存在宿主机中,在启动容器的时候,通过mount的形式将该文件挂载到容器内部。因此,如果在容器中修改这些文件的话,修改部分不会存在于容器的top layer,而是直接写入物理文件中。每次Docker在启动容器的时候,都会重新构建新的/etc/hosts文件,所以原先修改内容会被Docker自动给覆盖掉。      可以通过docker run命令的--add-host参数来为容器添加host与IP的映射关系。 Alt text|1000*0

3、Docker容器如何修改/proc/sys/kernel/shmmax等内核参数

    在容器中修改特定参数,结果提示this is a rad-only file。这是因为默认情况下,Docker的container是没有特权的,并未拥有真正的root权限,是不能修改系统参数的。可以通过--privileged选项,使容器获取额外的特权,从而修改系统参数。 Alt text|1000*0

4、在Build镜像时,指定了--shm-size大小,但是镜像启动之后发现没有生效

     因为Docker build 的shm参数是指定构建镜像过程中的container的shm大小,实际镜像运行的shm大小要通过docker run --shm-size来指定。但是要注意的是, --shm-size设定的数值要小于系统变量SHMMAX数值,否则会报错,可以通过sysctl -a|grep shmmax进行查看。 Alt text

results matching ""

    No results matching ""