我想过一个非常有意思的东西:在docker里面运行docker,然后在docker里运行的docker中再运行一个docker,接着在docker里运行的docker里运行的docker中再开一个docker…接着迭代100次会发生什么
结合这篇文章:https://jpetazzo.github.io/2015/09/03/do-not-use-docker-in-docker-for-ci/
以及自己的经验与实践总结出下文.
“If you want the short solution without the details, just scroll to the bottom of this article. ☺”
##Bad
如果你在docker中运行了docker,会导致一下问题:
1.当你使用-privileged的时候会导致一个在内部docker与外部docker之间的安全配置无法合并的冲突,是关于LSM (Linux Security Modules)的
2.外部docker运行在正常的文件系统中,但内部docker运行在写时拷贝的文件系统,会直接导致无法运行或者因为命名空间的问题影响其他container
##Solution
其实基本上来说是不存在需要在docker中跑docker这种需求的,你想要的只是在docker中启动一个docker的container来运行你的程序,并不关心这个container在哪个docker进程中.下面提供一种方式可以让你在docker内部调用这个docker程序开启新的container帮助你完成工作:
1 docker run -v /var/run/docker.sock:/var/run/docker.sock ...
这样你程序所在的container中已经有权限访问docker的socket,因此可以用docker run启动同胞兄弟而不是子容器
1 2 3 4 5 6 7 8 9 / # docker ps ➜ ~ docker run -v /var/run/docker.sock:/var/run/docker.sock -ti docker CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8c84704e890e docker "docker-entrypoint..." 2 seconds ago Up 1 second brave_lichterman / # docker run -v /var/run/docker.sock:/var/run/docker.sock -ti docker / # docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 34dcf16326c2 docker "docker-entrypoint..." 3 seconds ago Up 2 seconds inspiring_mcnulty 8c84704e890e docker "docker-entrypoint..." 37 seconds ago Up 36 seconds brave_lichterman
##Practice
使用上述Solution打包一个docker镜像
###构建打包镜像的环境
网上实在没有找到包含docker+aws+packer的ubuntu docker镜像,以下是dockerfile
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 FROM ubuntu:14.04 # install docker RUN apt-get update \ && apt-get -y install ca-certificates \ curl \ openssl \ unzip ENV DOCKER_BUCKET get.docker.com ENV DOCKER_VERSION 1.13.0 ENV DOCKER_SHA256 fc194bb95640b1396283e5b23b5ff9d1b69a5e418b5b3d774f303a7642162ad6 RUN set -x \ && curl -fSL "https://${DOCKER_BUCKET}/builds/Linux/x86_64/docker-${DOCKER_VERSION}.tgz" -o docker.tgz \ && echo "${DOCKER_SHA256} *docker.tgz" | sha256sum -c - \ && tar -xzvf docker.tgz \ && mv docker/* /usr/local/bin/ \ && rmdir docker \ && rm docker.tgz \ && docker -v # install aws RUN apt-get install -y python-pip groff-base RUN pip install awscli # install packer RUN curl -OL#\ https://releases.hashicorp.com/packer/0.12.2/packer_0.12.2_linux_amd64.zip &&\ unzip packer_0.12.2_linux_amd64.zip -d /usr/local/bin/ # copy file WORKDIR /build COPY infrastructure infrastructure COPY pipeline/test/env_packet/packet4testEnv.sh /usr/local/bin ENTRYPOINT ["packet4testEnv.sh"]
然后添加打包脚本
1 2 3 4 5 6 7 8 echo "----------------------------------build packet environment" docker build -t packer_aws_env -f ./pipeline/test/env_packet/Dockerfile . echo "----------------------------------tag image" docker tag packer_aws_env $ECR_REPOSITORY:sf-test-packet echo "----------------------------------aws login" aws ecr get-login | bash echo "----------------------------------push to ecr" docker push $ECR_REPOSITORY:sf-test-packet
###结合packer与ecr构建并上传镜像
外层docker环境
1 2 3 4 5 6 7 8 9 10 11 12 echo "----------------------------------pull docker image from ecr" aws ecr get-login | bash docker pull $ECR_REPOSITORY:sf-test-packet echo "----------------------------------run packer in docker and packet for test environment" docker run --rm \ -e AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID \ -e AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY \ -e AWS_DEFAULT_REGION=$AWS_DEFAULT_REGION \ -e ECR_LOGIN_SERVER=$ECR_LOGIN_SERVER \ -e ECR_REPOSITORY=$ECR_REPOSITORY \ $ECR_REPOSITORY:sf-test-packet
内层docker环境
1 "run_command": ["-d", "-i", "-t", "-v", "/var/run/docker.sock:/var/run/docker.sock", "{{.Image}}", "/bin/bash"]
号外号外
最近在总结一些针对Java 面试相关的知识点,感兴趣的朋友可以一起维护~
地址:https://github.com/xbox1994/2018-Java-Interview