娜尼的妮妮

导航

Docker 的创建

一  Docker 容器的创建。

       docker Image的创建一般有三种办法,以某个已经存在的docker image为base,在容器内部修改为自己的目标容器然后export保存;或者用docker file 创建docker image

       1 用已有容器做base 创建

  •       有时候用docker file创建一个docker image太麻烦了,可以用Ubuntu做一个base,相当于一个OS,命令为 docker pull Ubuntu:XXX  (xxx为ubuntu版本)

         

 

  •         然后在ubuntu docker image基础上创建一个自己想要的名字,这一步是从镜像创建容器

             docker run -p 8800:8000 -p 8822:22 -p 8880:80 -it --name myframework ubuntu:16.04 /bin/bash

             

 

  •       启动容器

                 docker start myframework

               

 

  •         进入容器    

                docker exec –it myframework /bin/bash

               

                 在容器中可以安装需要的包,修改配置,改成自己需要的目标Image

               

  •          导出并保存docker容器 

                 docker export -o myframework.tar containerID

 

  

 2 Dockerfile 创建docker Image

  

FROM privaterepo:5000/new_ubuntu //本例是从本地私有docker repo中拉取ubuntu image作为base,在上面定制android编译环境
# Takes values as builds arguments. 
ARG SSH_PRV_KEY // 此处为外部传入的参数,参数指定SSH KEY,在运行container的时候使用指定的ssh key 
ARG SSH_PUB_KEY
ARG GIT_CONFIG // 使用外部指定的git config 文件
ARG HDF_REVISION="refs/heads/dev" //默认的分支名
ENV HOME_JENKINS_PATH="/home/jenkins" 
ENV DEBIAN_FRONTEND=noninteractive
# ==================== Installs BASIC packges ====================
RUN apt-get update -y       && \
        apt-get upgrade -y  && \
    apt-get install -y   \
    wget    \
    sudo    \
        nano    \
    git     \
    git-core \
        iputils-ping    \
        net-tools   \
    curl    \
    libssl-dev openssl  \
    build-essential \
    zip unzip

# ==================== Installs Java 8 ====================
RUN apt-get install -y openjdk-8-jdk && \
        apt-get install -y ant && \
        apt-get clean && \
        rm -rf /var/lib/apt/lists/* && \
        rm -rf /var/cache/oracle-jdk8-installer && \
    curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash && \
    sudo apt-get install git-lfs
RUN apt-get update && \
        apt-get install -y ca-certificates-java && \
        apt-get clean && \
        update-ca-certificates -f && \
        rm -rf /var/lib/apt/lists/* && \
        rm -rf /var/cache/oracle-jdk8-installer;

# Setup JAVA_HOME, this is useful for docker commandline
ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64/
RUN export JAVA_HOME
# ==================== Installs Python3 ====================
RUN apt-get update && \
    apt-get upgrade -y  && \
    apt-get install -y software-properties-common && \
    apt-get install -y python3 python3-dev python3-pip python3-venv && \
    python3 -m pip install pip==20.3.3 --upgrade

# ==================== Installs Python2 ====================
RUN apt-get update && \
    apt-get upgrade -y  && \
    apt-get install -y python python-dev  && \
    curl https://bootstrap.pypa.io/2.7/get-pip.py -o get-pip.py && \
    python get-pip.py && \
    python -m pip install pip==20.3.3 --upgrade


# ==================== Installs repo tool ==================== 
RUN curl https://storage.googleapis.com/git-repo-downloads/repo-1 > /opt/repo    && \
    chmod a+xr /opt/repo

# symbolic link from /opt/repo to /usr/local/bin/repo
RUN ln -s /opt/repo /usr/local/bin/repo

# ==================== Creates Jenkins user ====================
# We add uid = 1005 as a default value, this id will be changed 
## 创建用户jenkins ,创建Jenkins home 目录
# according to the final node destination
RUN useradd -u 1005 -s /bin/bash -m -d "${HOME_JENKINS_PATH}" -G sudo jenkins && \
    echo "jenkins:jenkins@docker" | chpasswd
USER jenkins
# ---------- Creates Working structure ----------
RUN mkdir "${HOME_JENKINS_PATH}"/workspace/  && \
    chmod 775 -R "${HOME_JENKINS_PATH}"/workspace/

# ---------- Create the SSH structure ----------
RUN mkdir -p "${HOME_JENKINS_PATH}"/.ssh/ && \
    chmod -R 0700 "${HOME_JENKINS_PATH}"/.ssh/

# ---------- Add the keys passed on build command and set permissions ----------
RUN echo "$SSH_PRV_KEY" > "${HOME_JENKINS_PATH}"/.ssh/id_rsa && \
    echo "$SSH_PUB_KEY" > "${HOME_JENKINS_PATH}"/.ssh/id_rsa.pub && \
    echo "$GIT_CONFIG" > "${HOME_JENKINS_PATH}"/.gitconfig && \
    chmod 600 "${HOME_JENKINS_PATH}"/.ssh/id_rsa     && \
    chmod 600 "${HOME_JENKINS_PATH}"/.ssh/id_rsa.pub && \
    chmod 600 "${HOME_JENKINS_PATH}"/.gitconfig

# Skip Host verification for git
RUN echo "Host * \n \tStrictHostKeyChecking no"  > "${HOME_JENKINS_PATH}"/.ssh/config && \
    chmod 600 "${HOME_JENKINS_PATH}"/.ssh/config

# Changes to root user, to install dependencies
USER root
RUN cd framework && \
    pip install -r requirements.txt && \
    python setup.py develop

# Other Pip dependecies
RUN pip install \
    Mako==1.0.3 && \
    pip3 install Cryptography==2.8

# ==================== Metadata ====================
# Default user
USER root
# Change the root password
RUN echo "root:jen@123" | chpasswd
# Default path
WORKDIR ${HOME_JENKINS_PATH}/workspace

# Save the timespan of the Image
RUN date "+%H:%M:%S   %d/%m/%y" > "image_timespam_base_harman_image.txt"

  

  Dockerfile 有固定的语法,具体的语法参见https://www.runoob.com/docker/docker-dockerfile.html

  对应的docker build command 如下

docker image build -f base.dockerfile -t  privaterepo:5000/base:16.04 --build-arg SSH_PRV_KEY="$(cat ~/.ssh/id_rsa)" --build-arg SSH_PUB_KEY="$(cat ~/.ssh/id_rsa.pub)" --build-arg 
GIT_CONFIG="$(cat shared_files/.gitconfig)" .

  注意最后有一个"." 表示docker build 的context 是当前目录 ,很容易忽略这个点导致image 编译错误。build context 是dockers build 的环境,在这个环境里可以存放docker file中用到的文件,docker context中的

文件会在docker build的时候一起被发送到docker daemon 端,所以一定要注意这个路径(一般是存放dockerfile的同级路径)不要有不必要的文件。我之前在一个android的编译环境下build docker image, 最后编译log 显示发送
的context 有100多个G ,就是这个问题导致的。如果context目录中有不需要上传的文件,可以添加.dockerignore文件,把需要忽略的文件加进去,原理和.gitignore 差不多。

docker run的命令如下
docker run -it --network host --user jenkins -v /home/jenkins/workspace/mirrors:/home/jenkins/workspace/mirrors:rw,z base_image

 --network 参数表示网络端口沿用Host主机的端口,不用另外-p指定端口. 一般在容器需要处理大量的端口的情况下采用这种方法。并且host模式仅支持inux,在windows/Mac下不支持。-v 表示container在host上的挂载点。--mount和--volume的区别是,--mount相比volume 是把mount具体命令拆开来写,volume是合在一起。 且volume只有三个参数.volume第一个参数是主机的实体路径挂载点,第二个参数是container内的目录,要被挂载的路径,第三个是volume的权限,默认是ro, readyonly.所以在使用-v 的时候如果container内部改变的内容要保存在主机上,需要加上参数rw. 还有一个z 参数表示挂载点的内容在多container 之间是可以共享的。

  

 

posted on 2021-07-28 14:37  娜尼的妮妮  阅读(501)  评论(0编辑  收藏  举报