首页
About Me
推荐
weibo
github
Search
1
linuxea:gitlab-ci之docker镜像质量品质报告
49,197 阅读
2
linuxea:如何复现查看docker run参数命令
21,468 阅读
3
Graylog收集文件日志实例
18,257 阅读
4
git+jenkins发布和回滚示例
17,882 阅读
5
linuxea:jenkins+pipeline+gitlab+ansible快速安装配置(1)
17,778 阅读
ops
Openvpn
Sys Basics
rsync
Mail
NFS
Other
Network
HeartBeat
server 08
Code
Awk
Shell
Python
Golang
virtualization
KVM
Docker
openstack
Xen
kubernetes
kubernetes-cni
Service Mesh
Data
Mariadb
PostgreSQL
MongoDB
Redis
MQ
Ceph
TimescaleDB
kafka
surveillance system
zabbix
ELK Stack
Open-Falcon
Prometheus
victoriaMetrics
Web
apache
Tomcat
Nginx
自动化
Puppet
Ansible
saltstack
Proxy
HAproxy
Lvs
varnish
更多
互联咨询
最后的净土
软件交付
持续集成
gitops
devops
登录
Search
标签搜索
kubernetes
docker
zabbix
Golang
mariadb
持续集成工具
白话容器
linux基础
nginx
elk
dockerfile
Gitlab-ci/cd
最后的净土
基础命令
jenkins
docker-compose
gitops
haproxy
saltstack
Istio
marksugar
累计撰写
676
篇文章
累计收到
140
条评论
首页
栏目
ops
Openvpn
Sys Basics
rsync
Mail
NFS
Other
Network
HeartBeat
server 08
Code
Awk
Shell
Python
Golang
virtualization
KVM
Docker
openstack
Xen
kubernetes
kubernetes-cni
Service Mesh
Data
Mariadb
PostgreSQL
MongoDB
Redis
MQ
Ceph
TimescaleDB
kafka
surveillance system
zabbix
ELK Stack
Open-Falcon
Prometheus
victoriaMetrics
Web
apache
Tomcat
Nginx
自动化
Puppet
Ansible
saltstack
Proxy
HAproxy
Lvs
varnish
更多
互联咨询
最后的净土
软件交付
持续集成
gitops
devops
页面
About Me
推荐
weibo
github
搜索到
19
篇与
的结果
2019-03-08
linuxea:如何单单修改docker容器的系统时间
一般情况下,我们仅仅需要修改容器的时间与我们宿主机的实际实际一致即可,我们知道,默认情况下docker容器是不允许访问系统时钟,但是有一款开源的软件使这样的需求变成了可能。此lib拦截用于检索当前时间和日期的所有系统调用,完成了容器内时间的修改。阅读此篇文章,你将了解在容器内修改时间的方法。使用以alpine为例,我们进行编译安装,并挑选几个简单的使用方法来进行演示这个时间调整git clone https://github.com/wolfcw/libfaketime.git cd libfaketime/src make install他的使用非常简单,只需要设置环境变量即可,如下bash-4.4$ date Fri Mar 8 15:17:52 CST 2019修改天数bash-4.4$ LD_PRELOAD=/usr/local/lib/faketime/libfaketime.so.1 FAKETIME="-2d"bash-4.4$ date Wed Mar 6 15:28:03 CST 2019修改分钟bash-4.4$ LD_PRELOAD=/usr/local/lib/faketime/libfaketime.so.1 FAKETIME="-70m"bash-4.4$ date Fri Mar 8 14:18:45 CST 2019虚拟时间的默认规范是缓存的,时间为10秒钟FAKETIME_NO_CACHE =1是禁用缓存,但这可能带来性能影响嵌入docker基础镜像中使用此前的基础镜像。在启动脚本中添加TIME_OFFSET变量,顺便修改启动容器进程的id和用户名#!/bin/bash ######################################################################### # File Name: entrypoint.sh # Author: www.linuxea.com # Created Time: Tue 05 Mar 2019 03:59:05 PM CST ######################################################################### USER_ID=${USER_ID:-1101} USER_NAME=${USER_NAME:-www} TIME_OFFSET=${TIME_OFFSET:-FAKETIME_NO_CACHE=1 FAKETIME=""} echo "Starting with UID : $USER_ID And user $USER_NAME" addgroup --gid $USER_ID $USER_NAME adduser -u $USER_ID -S -H -s /bin/bash -g $USER_NAME -G $USER_NAME $USER_NAME -D # useradd --shell /bin/bash -u $USER_ID -o -c "" -m user export HOME=/home/$USER_NAME export LD_PRELOAD=/usr/local/lib/faketime/libfaketime.so.1 $TIME_OFFSET exec /usr/local/bin/gosu $USER_NAME "$@"这样以来,在下次启动的时候,传递环境变量就达到了修改容器时间的办法我将次镜像构建为marksugar/alpine:3.9-time-gosu,你可以下载进行使用[root@linuxea.com /opt/2019/djd/jj]# docker build -t marksugar/alpine:3.9-time-gosu .现在我们进行测试这个时间修改挂载/etc/localtime让容器时间与机器时间一致,而后在进行传递$TIME_OFFSET修改时间的偏移量docker run \ --rm \ -v /etc/localtime:/etc/localtime \ -e TIME_OFFSET=FAKETIME="-10m" \ -e USER_ID=1101 \ -e USER_NAME=linuxea.com \ -it marksugar/alpine:3.9-time-gosu \ date +%F" "%T我们先取出时间[root@linuxea.com ~]# date +%F" "%T 2019-03-08 15:54:11而后修改分钟,减去10分钟,-10m[root@linuxea.com ~]# docker run \ > --rm \ > -v /etc/localtime:/etc/localtime \ > -e TIME_OFFSET=FAKETIME="-10m" \ > -e USER_ID=1101 \ > -e USER_NAME=linuxea.com \ > -it marksugar/alpine:3.9-time-gosu \ > date +%F" "%T Starting with UID : 1101 And user linuxea.com 2019-03-08 15:44:16时间从2019-03-08 15:54:11变成2019-03-08 15:44:16修改天数,减去3天,-3d[root@linuxea.com ~]# docker run \ > --rm \ > -v /etc/localtime:/etc/localtime \ > -e TIME_OFFSET=FAKETIME="-3d" \ > -e USER_ID=1101 \ > -e USER_NAME=linuxea.com \ > -it marksugar/alpine:3.9-time-gosu \ > date +%F" "%T Starting with UID : 1101 And user linuxea.com 2019-03-05 15:57:43或者这样docker run \ --rm \ -v /etc/localtime:/etc/localtime \ -e TIME_OFFSET=FAKETIME="-10m" \ -e USER_ID=1101 \ -e USER_NAME=linuxea.com \ -it marksugar/alpine:3.9-time-gosu \ date +%F" "%TFAKETIME_NO_CACHE=1[root@DT_Node-172_17_0_1 ~]# date +%F" "%T 2019-03-08 16:03:18[root@DT_Node-172_17_0_1 ~]# docker run \ > --rm \ > -v /etc/localtime:/etc/localtime \ > -e TIME_OFFSET="FAKETIME_NO_CACHE=1 FAKETIME="-10m"" \ > -e USER_ID=1101 \ > -e USER_NAME=linuxea.com \ > -it marksugar/alpine:3.9-time-gosu \ > date +%F" "%T Starting with UID : 1101 And user linuxea.com 2019-03-08 15:53:18更多阅读linuxea:docker卷和文件系统权限linuxea:docker容器中程序不应该以root用户身份运行linuxea:变量实值与文件变量替换学习更多学习如何使用Docker CLI命令,Dockerfile命令,使用这些命令可以帮助你更有效地使用Docker应用程序。查看Docker文档和我的其他帖子以了解更多信息。docker目录白话容器docker-compose
2019年03月08日
5,817 阅读
0 评论
0 点赞
2019-03-07
linuxea:Docker多阶段构建与- target和--cache-from
在这篇文章中,我描述了在无法提供任何层缓存的无服务器主机上构建时,我如何提高容器的构建性能。我使用多阶段构建和远程存储库缓存的组合来避免重复性工作来提高性能。阅读本篇,你将了解--target的使用和--cache-from的使用,更好理解多阶段构建和缓存的利用。我将会在文章末尾放置多阶段构建使用的本站链接note使用--target来构建多级建立的特定阶段,并推动这些镜像传输到远程存储库。在后续构建中,拉出这些镜像并使用作为构建缓存--cache-from我们先来看,一个普通的构建脚本## 镜像版本号 DOCKER_IMAGE_VERSION=20190305_addpjp ## 构建镜像 docker build \ -t marksugar/test:$DOCKER_IMAGE_VERSION \ -t marksugar/test:latest \ -f "./Dockerfile" \ "." ## 推送到仓库 docker push marksugar/test:$DOCKER_IMAGE_VERSION docker push marksugar/test:latest 此bash脚本基于Dockerfile构建docker镜像,使用特定的版本号$DOCKER_IMAGE_VERSION和latest标记镜像tag,而后推送到仓库中,完成构建过程。事实上我们在实际生产中的构建脚本远比这要复杂的多。为此,学习利用--target和--cache-from能提高时间效益--target创建多阶段构建时候,可以为每个构建阶段提供名称,例如,我此刻命名的createfile和linuxea,分别在(准备阶段createfile和最终阶段linuxea):FROM marksugar/alpine:3.9-time-gosu as createfile MAINTAINER www.linuxea.com LABEL maintainer="www.linuxea.com" RUN mkdir /data/ && touch /hello.txt WORKDIR /data FROM marksugar/go:alpine-go1.12 as linuxea MAINTAINER www.linuxea.com LABEL maintainer="www.linuxea.com" COPY linuxea.go /data/linuxea.go WORKDIR /data CMD ["go","run","linuxea.go"] COPY --from=createfile /data/ .通过阶段的名称,可以在后续中引用,并且复制到最后的容器中。为了更好的解释这个,我们还是进行一次构建docker build -t test:1 .并运行[root@linuxea.com /opt/2019/djd/go/go2]# docker run -d -p:1818:8080 test:1 01e07ddc26daf94bc57ddc7d61d5cbe0f530c85792e045126dc501e67e047ac8运行正常,可以被访问[root@linuxea.com /opt/2019/djd/go/go2]# curl 127.0.0.1:8080 20190303 欢迎来到 www.linuxea.com但是,这仅仅只是多阶段构建。此刻,我只想构建其中一个阶段,--target就派上用途了。只构建某个阶段,如linuxea或者createfile,并不全部构建只构建linux的阶段[root@linuxea.com /opt/2019/djd/go/go2]# docker build --target linuxea -t test:linuxea -f "$PWD/Dockerfile" "." [root@linuxea.com /opt/2019/djd/go/go2]# docker run --rm -it test:1 bash Starting with UID : 1101 And user www bash-4.4$ ls linuxea.go bash-4.4$ 只构建createfile阶段[root@linuxea.com /opt/2019/djd/go/go2]# docker build --target createfile -t test:2 -f "$PWD/Dockerfile" "." [root@linuxea.com /opt/2019/djd/go/go2]# docker run --rm -it test:2 bash Starting with UID : 1101 And user www bash-4.4$ pwd /data bash-4.4$ ls /hello.txt /hello.txt如上所示中,两个阶段的构建结果仅限于Dockerfile中的多阶段构建的名称下的内容。我们在往下看。--cache-from默认情况下,在构建Docker镜像时,Docker使用它的构建缓存来检查它是否可以跳过Dockerfile中的任何步骤。该--cache-from参数告诉docker,可用缓存的镜像是什么。如果提供的镜像和当前版本具有相同的图层,则可以获得与在同一台计算机上构建镜像时以相同层构建出更快的速度。例如,简单地想象我们没有使用多阶段构建,因此推送到远程存储库的最终镜像包含所有构建层。不使用--cache-from我们的构建脚本总是必须执行Dockerfile中的每个命令,因为构建缓存将为空:docker build -t marksugar/test:01相反,我们可以--cache-from结合使用docker pull,大概如下:docker pull IMAGES1 || true docker build \ --cache-from IMAGES1 \ -t IMAGE2:Version \ -t IMAGE2:latest \ -f "PATH/Dockefile" \ "." docker push IMAGES2:latest docker push IMAGES2:Version为了更好的测试,我们手动进行build两个镜像做一个简单的测试第一个DockerfileFROM marksugar/alpine:3.9-time-gosu as createfile MAINTAINER www.linuxea.com LABEL maintainer="www.linuxea.com" RUN apk add nginx php RUN mkdir -p /data/wwwroot WORKDIR /data/wwwrootdocker build marksugar/test:01第二个Dockerfile在第二个dockerfile中,我们主要看两层,如下:RUN apk add nginx php RUN mkdir -p /data/wwwrootDockerfile。在dockerfile中的这两层与上一个dockerfile的层是相同的FROM marksugar/alpine:3.9-time-gosu MAINTAINER www.linuxea.com LABEL maintainer="www.linuxea.com" RUN apk add nginx php RUN mkdir -p /data/wwwroot RUN echo '\n\ server {\n\ listen 1080;\n \ root /data/wwwroot;\n \ index index.html;\n \ }\n'\ >> /etc/nginx/conf.d/default.conf \ && echo "hello www.linuxea.com" >> /data/wwwroot/index.html WORKDIR /data/wwwroot CMD ["nginx","-g","'daemon off;'"]builddocker build \ --cache-from marksugar/test:01 \ -t marksugar/test:02 \ -f "$PWD/Dockerfile" \ "."如下:[root@linuxea.com /opt/2019/djd/go/go3]# docker build --cache-from marksugar/test:01 -t marksugar/test:02 -f "$PWD/Dockerfile" "." Sending build context to Docker daemon 2.048kB Step 1/8 : FROM marksugar/alpine:3.9-time-gosu ---> 69cd7c6d7a86 Step 2/8 : MAINTAINER www.linuxea.com ---> Using cache ---> 45e40729aaae Step 3/8 : LABEL maintainer="www.linuxea.com" ---> Using cache ---> 5f10b4ec6e3e Step 4/8 : RUN apk add nginx php ---> Using cache ---> 0fd71721e8ff Step 5/8 : RUN mkdir -p /data/wwwroot ---> Using cache ---> 07066ac12068 Step 6/8 : RUN echo '\nserver {\n listen 1080;\n root /data/wwwroot;\n index index.html;\n }\n'>> /etc/nginx/conf.d/default.conf && echo "hello www.linuxea.com" >> /data/wwwroot/index.html ---> Running in 1aaa3449af16 Removing intermediate container 1aaa3449af16 ---> 434c3dee5d37 Step 7/8 : WORKDIR /data/wwwroot ---> Running in 2ed3ce787ab0 Removing intermediate container 2ed3ce787ab0 ---> 078644925acb Step 8/8 : CMD ["nginx","-g","'daemon off;'"] ---> Running in 065aa5b66fe8 Removing intermediate container 065aa5b66fe8 ---> 81adb261a754 Successfully built 81adb261a754 Successfully tagged marksugar/test:02我们在来对比一下层,你会发现这俩个镜像对于上述相同的RUN命令层,公用一个ID,这将减少我们的构建时间如果你的最终构建的镜像包含所有的docker构建层,这个简单的方法很有效。但在多阶段中可能会出现问题,我们可以使用--target和--cache-from一起使用--target And --cache-from倘若此时,在多构建的基础之上,我们需要重新构建准备阶段和最终的运行阶段我们可能使用这种方式,如下:DOCKER_IMAGE_VERSION=VERSION # 拉取最新的镜像 docker pull marksugar/base:1 || true # 使用最新拉取的镜像作为缓存层 docker build \ --target builder \ --cache-from marksugar/base:1 \ -t marksugar/base:1 \ -f "path/Dockerfile" \ "." # 在拉一个最终的镜像 docker pull marksugar/web:latest || true # 不指定target(构建整个Dockerfile) # 使用刚构建的构建器镜像和拉出的运行时候镜像作为缓存 docker build \ --cache-from marksugar/base:1 \ --cache-from marksuagr/Web:latest \ -t marksugar/web:$DOCKER_IMAGE_VERSION \ -t marksugar/Web:latest \ -f "path/Dockerfile" \ "." # 重新推送 docker push marksugar/Web:$DOCKER_IMAGE_VERSION docker push marskugar/Web:latest docker push marksugar/base:1延伸阅读linuxea:Distroless与多阶段构建linuxea:docker多阶段构建Multi-Stage与Builder对比总结学习更多学习如何使用Docker CLI命令,Dockerfile命令,使用这些命令可以帮助你更有效地使用Docker应用程序。查看Docker文档和我的其他帖子以了解更多信息。docker目录白话容器docker-compose
2019年03月07日
5,187 阅读
0 评论
0 点赞
2019-02-27
linuxea:缩减docker镜像大小的5个步骤
docker容器的应用程序易于部署管理是基于docker镜像,一个优良的docker镜像是非常有必要的。在多数情况下,我们处于无状态应用的快速部署,这个过程中,且不管你在dockerhub使用还是本地镜像仓库使用,合理的镜像的大小也是有必要的。除此之外,我们应该考虑那些?Docker镜像大小的重要性?网络带宽导致的空闲等待除了镜像大小外,我们还需要考虑更新迭代的问题,更大的基础镜像意味着需要更多的开发时间。这里必然少不了网络带宽的问题,上传下载的等待时间问题。磁盘空间问题当然,镜像大小不单单影响了上传下载操作人员等待的时间。如果你留意过磁盘的使用,你会发现磁盘空间也是一个非常吃紧的事情。安全问题事实上,磁盘并不会耗费太多的金钱。在内网来讲,带宽也不是一个特别大的问题。更多的需要注意的是容器的安全性的问题。太大的镜像往往意味着有更大的攻击面缩减镜像5个步骤在开始之前,我想复述一个重要的问题:你应该妥善考虑将要部署的应用的语言,框架,扩展,工具和第三方包。因为所有安装的内容都会增加镜像大小,docker镜像只需要运行应用所需的环境足以,其他的能少尽量的减少。安装适合的依赖工具包对于从0构建来说,生产的镜像仅仅配置有必要的程序以来包,对于一些不必要的包应该全部删除。如:curl,wget等等。更小的基础镜像假如你要从0开始构建,通常,常见的基础镜像是ubuntu和centos以及debian,除此之外,我们可以考虑使用alpine,alpine的大小仅仅只有5M。使用alpine减小了镜像的大小,但是alpine和centos,debian有一定的差别如果你之是运行一个python程序,或者php程序,你应该考虑使用官方的镜像,比如 : ptyhon:2.7-alpine3.8,这仅仅几十兆。你可以进行自己构建,假如你掌握了这些知识更少的层docker的层也决定了镜像的大小,我们应该尽可能的使用更少的层来构建。更少的层可能意味着更少的dockerfile命令,比如run命令,阅读dockerfile中的RUN指令对镜像大小的影响有助于你深入了解。同时,在很多时候,更少的层解决不了过于繁琐复杂的镜像构建,这时候就需要多阶段构建来解决。使用.dockerignore文件.dockerignore在构建的时候,控制构建的上下文中的内容,对一些内容进行忽略,从而达到想要的预期效果。对于一些特别不需要的文件这特别有用,你可以参考linuxea:docker不能忽视的.dockerignore用法深入了解压缩镜像docker-squash最后一个方式是压缩镜像,docker-squash是一个实用程序,用于将多个层压缩成一个,以便创建具有更少和更小层的镜像。它保留了Dockerfile命令,如PORT,ENV等。这样压扁镜像的工作方式与最初构建时相同。此外,后续图层中删除的文件实际上是在压缩时从镜像中清除的。延伸阅读linuxea:docker不能忽视的.dockerignore用法linuxea:docker多阶段构建Multi-Stage与Builder对比总结docker-squashlinuxea:dockerfile中的RUN指令对镜像大小的影响学习更多学习如何使用Docker CLI命令,Dockerfile命令,使用这些命令可以帮助你更有效地使用Docker应用程序。查看Docker文档和我的其他帖子以了解更多信息。docker目录白话容器docker-compose
2019年02月27日
3,369 阅读
0 评论
0 点赞
2019-02-26
linuxea:dockerfile中的RUN指令对镜像大小的影响
我们在github上,或者在一些应用官方提供的docker镜像的Dockerfile中,经常会看到很多难以琢磨的操作,这篇文章主要说明使用Dockerfile的RUN命令为什么要在后面使用&&链接,以及在实际镜像中的影响和区别。阅读本篇文章对Dockerfile的RUN命令和层有更深的认识,同时学会更好的缩减容器的镜像。为了更好的演示RUN命令与层带来的差异,我们分为几个步骤来做!1,测试多条命令的大小与差异2,减少多条命令的大小与差异多条RUN首先,我们进行多条命令RUN命令测试,如下:安装nginx,php,curl三个软件包[root@linuxea.com ~]# cat Dockerfile FROM alpine:3.9 as default MAINTAINER www.linuxea.com LABEL maintainer="www.linuxea.com" RUN apk add nginx RUN apk add php RUN apk add curl在Build的同时,依次进行[root@linuxea.com ~]# docker build -t linuxea:26 . Sending build context to Docker daemon 427kB Step 1/6 : FROM alpine:3.9 as default ---> caf27325b298 Step 2/6 : MAINTAINER www.linuxea.com ---> Using cache ---> 5ee27f5e579a Step 3/6 : LABEL maintainer="www.linuxea.com" ---> Using cache ---> a9b2f826f6c9 Step 4/6 : RUN apk add nginx ---> Running in c2b048d78656 fetch http://dl-cdn.alpinelinux.org/alpine/v3.9/main/x86_64/APKINDEX.tar.gz fetch http://dl-cdn.alpinelinux.org/alpine/v3.9/community/x86_64/APKINDEX.tar.gz (1/2) Installing pcre (8.42-r1) (2/2) Installing nginx (1.14.2-r0) Executing nginx-1.14.2-r0.pre-install Executing busybox-1.29.3-r10.trigger OK: 7 MiB in 16 packages Removing intermediate container c2b048d78656 ---> 116c307055ed Step 5/6 : RUN apk add php ---> Running in 29c651203043 (1/7) Installing php7-common (7.2.14-r0) (2/7) Installing ncurses-terminfo-base (6.1_p20190105-r0) (3/7) Installing ncurses-terminfo (6.1_p20190105-r0) (4/7) Installing ncurses-libs (6.1_p20190105-r0) (5/7) Installing libedit (20181209.3.1-r0) (6/7) Installing libxml2 (2.9.9-r1) (7/7) Installing php7 (7.2.14-r0) Executing busybox-1.29.3-r10.trigger OK: 21 MiB in 23 packages Removing intermediate container 29c651203043 ---> ec1cbef7f89e Step 6/6 : RUN apk add curl ---> Running in d96aef6e09f8 (1/5) Installing ca-certificates (20190108-r0) (2/5) Installing nghttp2-libs (1.35.1-r0) (3/5) Installing libssh2 (1.8.0-r4) (4/5) Installing libcurl (7.63.0-r0) (5/5) Installing curl (7.63.0-r0) Executing busybox-1.29.3-r10.trigger Executing ca-certificates-20190108-r0.trigger OK: 22 MiB in 28 packages Removing intermediate container d96aef6e09f8 ---> f4000a9883f1 Successfully built f4000a9883f1 Successfully tagged linuxea:26此时构建的镜像大小为18.8M[root@linuxea.com ~]# docker images linuxea:26 REPOSITORY TAG IMAGE ID CREATED SIZE linuxea 26 f4000a9883f1 12 seconds ago 18.8MB分为七层,每一条命令都分为一层,加起来的总大小是18.8M[root@linuxea.com ~]# docker history linuxea:26 IMAGE CREATED CREATED BY SIZE COMMENT f4000a9883f1 18 seconds ago /bin/sh -c apk add curl 1.68MB ec1cbef7f89e 21 seconds ago /bin/sh -c apk add php 8.89MB 116c307055ed 54 seconds ago /bin/sh -c apk add nginx 2.74MB a9b2f826f6c9 9 days ago /bin/sh -c #(nop) LABEL maintainer=www.linu… 0B 5ee27f5e579a 9 days ago /bin/sh -c #(nop) MAINTAINER www.linuxea.com 0B caf27325b298 3 weeks ago /bin/sh -c #(nop) CMD ["/bin/sh"] 0B <missing> 3 weeks ago /bin/sh -c #(nop) ADD file:2a1fc9351afe35698… 5.53MB 单条RUN此刻,我们尝试将安装的nginx,php,curl放在一条RUN,使用&&链接起来执行[root@linuxea.com ~]# cat Dockerfile FROM alpine:3.9 as default MAINTAINER www.linuxea.com LABEL maintainer="www.linuxea.com" RUN apk add nginx \ && apk add php \ && apk add curl [root@linuxea.com ~]# docker build -t linuxea:26-1 . Sending build context to Docker daemon 427kB Step 1/4 : FROM alpine:3.9 as default ---> caf27325b298 Step 2/4 : MAINTAINER www.linuxea.com ---> Using cache ---> 5ee27f5e579a Step 3/4 : LABEL maintainer="www.linuxea.com" ---> Using cache ---> a9b2f826f6c9 Step 4/4 : RUN apk add nginx && apk add php && apk add curl ---> Running in 19fb009c38d1 fetch http://dl-cdn.alpinelinux.org/alpine/v3.9/main/x86_64/APKINDEX.tar.gz fetch http://dl-cdn.alpinelinux.org/alpine/v3.9/community/x86_64/APKINDEX.tar.gz (1/2) Installing pcre (8.42-r1) (2/2) Installing nginx (1.14.2-r0) Executing nginx-1.14.2-r0.pre-install Executing busybox-1.29.3-r10.trigger OK: 7 MiB in 16 packages (1/7) Installing php7-common (7.2.14-r0) (2/7) Installing ncurses-terminfo-base (6.1_p20190105-r0) (3/7) Installing ncurses-terminfo (6.1_p20190105-r0) (4/7) Installing ncurses-libs (6.1_p20190105-r0) (5/7) Installing libedit (20181209.3.1-r0) (6/7) Installing libxml2 (2.9.9-r1) (7/7) Installing php7 (7.2.14-r0) Executing busybox-1.29.3-r10.trigger OK: 21 MiB in 23 packages (1/5) Installing ca-certificates (20190108-r0) (2/5) Installing nghttp2-libs (1.35.1-r0) (3/5) Installing libssh2 (1.8.0-r4) (4/5) Installing libcurl (7.63.0-r0) (5/5) Installing curl (7.63.0-r0) Executing busybox-1.29.3-r10.trigger Executing ca-certificates-20190108-r0.trigger OK: 22 MiB in 28 packages Removing intermediate container 19fb009c38d1 ---> 6d1be09ddac1 Successfully built 6d1be09ddac1 Successfully tagged linuxea:26-1得到的大小是18.7M[root@linuxea.com ~]# docker images linuxea:26-1 REPOSITORY TAG IMAGE ID CREATED SIZE linuxea 26-1 6d1be09ddac1 9 seconds ago 18.7MB而层也随机变少了,只有5层,18.7M[root@linuxea.com ~]# docker history linuxea:26-1 IMAGE CREATED CREATED BY SIZE COMMENT 6d1be09ddac1 23 seconds ago /bin/sh -c apk add nginx && apk add php &… 13.1MB a9b2f826f6c9 9 days ago /bin/sh -c #(nop) LABEL maintainer=www.linu… 0B 5ee27f5e579a 9 days ago /bin/sh -c #(nop) MAINTAINER www.linuxea.com 0B caf27325b298 3 weeks ago /bin/sh -c #(nop) CMD ["/bin/sh"] 0B <missing> 3 weeks ago /bin/sh -c #(nop) ADD file:2a1fc9351afe35698… 5.53MB 思考?现在我们经过对比,多条RUN似乎会导致多层,并且比一条RUN,也就是同一个层的镜像构建的要小一些。那现在肯定有人会迷惑,这说明了什么?现在,我们不妨在看看,我们换个方式。[root@linuxea.com ~]# cat Dockerfile FROM alpine:3.9 as default MAINTAINER www.linuxea.com LABEL maintainer="www.linuxea.com" RUN apk add nginx RUN apk add php RUN apk add curl RUN apk del nginx php curl如上,假设,我此刻在Dockerfile中已经使用了在这三个软件,在构建的最后步骤,我希望删掉->依赖安装最小化原则。而后我在进行build[root@linuxea.com ~]# docker build -t linuxea:26-2 . Sending build context to Docker daemon 427kB Step 1/7 : FROM alpine:3.9 as default ---> caf27325b298 Step 2/7 : AINTAINER www.linuxea.com ---> Using cache ---> 5ee27f5e579a Step 3/7 : LABEL maintainer="www.linuxea.com" ---> Using cache ---> a9b2f826f6c9 Step 4/7 : RUN apk add nginx ---> Using cache ---> 116c307055ed Step 5/7 : RUN apk add php ---> Using cache ---> ec1cbef7f89e Step 6/7 : RUN apk add curl ---> Using cache ---> f4000a9883f1 Step 7/7 : RUN apk del nginx php curl ---> Running in 124fea0865fb (1/14) Purging nginx (1.14.2-r0) (2/14) Purging php7 (7.2.14-r0) (3/14) Purging php7-common (7.2.14-r0) (4/14) Purging curl (7.63.0-r0) (5/14) Purging pcre (8.42-r1) (6/14) Purging libedit (20181209.3.1-r0) (7/14) Purging ncurses-libs (6.1_p20190105-r0) (8/14) Purging ncurses-terminfo (6.1_p20190105-r0) (9/14) Purging ncurses-terminfo-base (6.1_p20190105-r0) (10/14) Purging libxml2 (2.9.9-r1) (11/14) Purging libcurl (7.63.0-r0) (12/14) Purging ca-certificates (20190108-r0) Executing ca-certificates-20190108-r0.post-deinstall (13/14) Purging nghttp2-libs (1.35.1-r0) (14/14) Purging libssh2 (1.8.0-r4) Executing busybox-1.29.3-r10.trigger OK: 6 MiB in 14 packages Removing intermediate container 124fea0865fb ---> 3a74abf45025 Successfully built 3a74abf45025 Successfully tagged linuxea:26-2构建完成。镜像的大小仍然是18.9M。[root@linuxea.com ~]# docker images linuxea:26-2 REPOSITORY TAG IMAGE ID CREATED SIZE linuxea 26-2 3a74abf45025 16 seconds ago 18.9MB我们使用docker history命令查看镜像,可见我们的确执行了apk del nginx php curl命令[root@linuxea.com ~]# docker history linuxea:26-2 IMAGE CREATED CREATED BY SIZE COMMENT 3a74abf45025 28 seconds ago /bin/sh -c apk del nginx php curl 21.2kB f4000a9883f1 6 minutes ago /bin/sh -c apk add curl 1.68MB ec1cbef7f89e 6 minutes ago /bin/sh -c apk add php 8.89MB 116c307055ed 6 minutes ago /bin/sh -c apk add nginx 2.74MB a9b2f826f6c9 9 days ago /bin/sh -c #(nop) LABEL maintainer=www.linu… 0B 5ee27f5e579a 9 days ago /bin/sh -c #(nop) MAINTAINER www.linuxea.com 0B caf27325b298 3 weeks ago /bin/sh -c #(nop) CMD ["/bin/sh"] 0B <missing> 3 weeks ago /bin/sh -c #(nop) ADD file:2a1fc9351afe35698… 5.53MB 我们进入容器确认是否被卸载[root@linuxea.com ~]# docker run --rm -it linuxea:26-2 sh / # curl sh: curl: not found / # 发生了什么?为什么在Dockerfile删除的软件已经消失,而层的大小并没有因为删除而缩减?要回答这一点,我们要返回上面的docker history linuxea:26-2中查看。我们将SIZE用加法运算,得到的大小与docker image查看的几乎接近,如下[root@linuxea.com ~]# docker history linuxea:26-2|awk '{print $NF}'|grep -v "COMMENT" 21.2kB 1.68MB 8.89MB 2.74MB 0B 0B 0B 5.53MB这说明docker会将所有的层相加。尽管我们在删除了这三个包,但是在上一层中,这三个包仍然是存在的,因为从下到上叠加的层最终构成了镜像。所以,要从层中有效删除,就需要在一个层中有效的组织。这些层是否就没有了作用?当在测试环境中,编写Dockerfile的时候可以使用多层,也就是多条RUN的命令来缓存每一个层做测试或者调试,当相同的指令就会复用缓存中间层。这可以有效的缩减build时间,原因是利用了docker的构建缓存。而构建缓存在CI/CD中是很有用的。RUN正确的使用方式我们应该将命令使用RUN和&&链接起来,这样在中间的层就表现为一个层,这样的情况并不利于调试,如上所述。每次构建都会认为是一条指令,当发生一条命令的变化,就无法使用缓存加速构建。我们重新build,并且删除缓存FROM alpine:3.9 as default MAINTAINER www.linuxea.com LABEL maintainer="www.linuxea.com" RUN apk add nginx \ && apk add php \ && apk add curl \ && apk del nginx php curl \ && rm /var/cache/apk/*重新build后的大小仅为5.56M[root@linuxea.com ~]# docker images linuxea:26-3 REPOSITORY TAG IMAGE ID CREATED SIZE linuxea 26-3 f300b5797d81 33 seconds ago 5.56MB[root@linuxea.com ~]# docker history linuxea:26-3 IMAGE CREATED CREATED BY SIZE COMMENT f300b5797d81 2 seconds ago /bin/sh -c apk add nginx && apk add php &&… 26kB a9b2f826f6c9 10 days ago /bin/sh -c #(nop) LABEL maintainer=www.linu… 0B 5ee27f5e579a 10 days ago /bin/sh -c #(nop) MAINTAINER www.linuxea.com 0B caf27325b298 3 weeks ago /bin/sh -c #(nop) CMD ["/bin/sh"] 0B <missing> 3 weeks ago /bin/sh -c #(nop) ADD file:2a1fc9351afe35698… 5.53MB 其他的办法我们在使用RUN命令的时候,除了尽可能的减少层,我们还可以使用docker多阶段构建Multi-Stage。docker多阶段构建将"上一次的构建用在下一个Dockerfile中",这很实用FROM golang:1.7.3 as builder WORKDIR /go/src/github.com/alexellis/href-counter/ RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app . FROM alpine:latest WORKDIR /root/ COPY --from=builder /go/src/github.com/alexellis/href-counter/app .延伸阅读linuxea:如何利用docker构建缓存快速迭代?linuxea:docker多阶段构建Multi-Stage与Builder对比总结学习更多学习如何使用Docker CLI命令,Dockerfile命令,使用这些命令可以帮助你更有效地使用Docker应用程序。查看Docker文档和我的其他帖子以了解更多信息。docker目录白话容器docker-compose
2019年02月26日
5,075 阅读
0 评论
0 点赞
2019-02-25
linuxea:docker卷和文件系统权限
Docker容器是无状态的(不需要在运行时候做持久化数据)。一般来讲,一些有状态的,存储重要数据的应用需要一些持久存储。卷功能提供了一种支持此要求的方法,但它带有一些关于文件系统权限的问题。在大多数部署的设置中,将使用容器编排机制,并且持久存储由某些公共云产品提供,这些产品可能具有自己的配置权限的方式。但是,在本地开发或产品的早期迭代期间,最简单的方法是将主机目录公开为docker卷。简而言之,这些是将主机目录配置为卷时需要注意的事实:从主机和容器的角度来看,对卷中内容设置的文件权限是相同的。只有UID(用户ID)和GID(组ID)很重要。例如,用户和组的名称和密码不需要匹配,甚至不需要存在于主机和容器中根据自己的配置对在运行的容器,具有所有操作权限,如:强制执行文件权限。例如,如果用户A同时存在于主机和容器中,将用户A添加到主机上的组B,不允许用户A写入容器内的组B所拥有的目录,除非在容器内创建组B并且向其添加用户A.默认情况下,容器的命令以root身份运行(在基于unix的系统上)可以将文件/目录所有权设置为不属于任何实际组的GID如果你掌握上述事实,应该能够配置容器和卷而不会有太多意外事故。如果你不熟悉UNIX文件权限,我可以推荐本站的linuxea基础之权限管理一篇。权限我们可以方便地为本地开发配置内容,示例:将要用作卷的目录的组所有权设置为某些GID(在此示例中为1101)未在主机上的任何实际组上使用[root@linuxea.com ~]# mkdir /root/linuxea.com [root@linuxea.com ~]# chown :1101 /root/linuxea.com更改目录的权限以授予组成员完全访问权限(读取+写入+执行)[root@linuxea.com ~]# chmod 755 /root/linuxea.com确保文件夹中的所有之后内容都将继承组所有权[root@linuxea.com ~]# chmod g+s /root/linuxea.com/在Dockerfile中创建一个用户,该用户是1101组的成员看起来可以是这样FROM alpine:3.9 MAINTAINER www.linuxea.com LABEL maintainer="www.linuxea.com" RUN addgroup --gid 1101 www \ && adduser -u 1101 -S -H -s /bin/bash -g www -G www www -D(可选)将主机用户添加到组中,以便你方便地使用主机中的目录centos:useradd linuxea上面的示例是一个最小化设置,可确保你不以root身份运行容器命令,并且可以使用主机上附加卷的内容,而无需使用主机root用户(你必须确保你使用的非root用户启动容器。该设置在构建时执行硬编码配置,使你无法在运行时调整GID。如果需要,你必须将GID作为环境变量传递,并包含可以使用它的通用脚本。示例如下:entrypoint.sh#!/bin/bash # www.linuxea.com USER_ID=${LOCAL_USER_ID:-1101} USER_NAME=${LOCAL_USER_NAME:-www} echo "Starting with UID : $USER_ID And user $USER_NAME" addgroup --gid $USER_ID $USER_NAME adduser -u $USER_ID -S -H -s /bin/bash -g $USER_NAME -G $USER_NAME $USER_NAME -D # useradd --shell /bin/bash -u $USER_ID -o -c "" -m user export HOME=/home/$USER_NAME exec /usr/local/bin/gosu $USER_NAME "$@"我们在这里做的是从环境变量中获取UID和将要用到的名称,如果它不存在则默认为1101,NAME不存在则www,并且使用adduser/useradd设置UID时实际使用熟悉的命令创建用户“www” 。entrypoint创建最后我们用这个用户gosu来执行我们的流程"$@"。记住来自Dockerfile的CMD或来自docker CLI的命令作为命令行参数传递给entrypoint.sh脚本。我们在看DockerfileFROM alpine:3.9 MAINTAINER www.linuxea.com LABEL maintainer="www.linuxea.com" COPY entrypoint.sh /bin/entrypoint.sh RUN apk update \ && apk add bash \ && wget https://github.com/tianon/gosu/releases/download/1.11/gosu-amd64 -O /usr/local/bin/gosu \ && chmod +x /bin/entrypoint.sh /usr/local/bin/gosu \ && rm /var/cache/apk/* ENTRYPOINT ["entrypoint.sh"] CMD ["sleep","30000"]build[root@linuxea.com ~]# docker build -t marksugar/alpine:3.9 .run可以传递LOCAL_USER_ID和LOCAL_USER_NAME改变脚本参数,从而改变gid和name[root@linuxea.com ~]# docker run -d marksugar/alpine:3.9 00f7afb58a9ee069f1bca6fdd716131e48538bc161911e62bf4249328f98270b[root@linuxea.com ~]# docker exec -it 00f7 ps aux PID USER TIME COMMAND 1 www 0:00 sleep 30000 14 root 0:00 ps aux[root@linuxea.com ~]# ps aux|grep sleep 1101 27414 0.3 0.0 1520 4 ? Ss 21:56 0:00 sleep 30000现在你就可以下载marksugar/alpine:3.9镜像来作为基础镜像了。延伸阅读linuxea:了解uid和gid如何在docker容器中工作linuxea:docker容器中程序不应该以root用户身份运行学习更多学习如何使用Docker CLI命令,Dockerfile命令,使用Bash命令可以帮助你更有效地使用Docker应用程序。查看Docker文档和我的其他帖子以了解更多信息。docker目录白话容器docker-compose
2019年02月25日
2,731 阅读
0 评论
0 点赞
1
2
...
4