• DockerFile与镜像(Image)仓库


    深入Docker 之 Image:

      当我们使用docker pull mysql 这个命令获取镜像的时候,到底他是怎么做的?我们登录官方提供的仓库看一下 https://github.com/docker-library.

      我们搜索mysql并且选择对应的版本,比如 5.7

      我们会看到改目录下只有两个文件,其中最重要的则是这个Dockerfile 文件了。然后 下面的 .sh 文件则是最后运行的脚本文件。我们看一下这个Dockerfile 文件里到底是定义了什么?

    FROM debian:stretch-slim
    
    # add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added
    RUN groupadd -r mysql && useradd -r -g mysql mysql
    
    RUN apt-get update && apt-get install -y --no-install-recommends gnupg dirmngr && rm -rf /var/lib/apt/lists/*
    
    # add gosu for easy step-down from root
    ENV GOSU_VERSION 1.7
    RUN set -x 
        && apt-get update && apt-get install -y --no-install-recommends ca-certificates wget && rm -rf /var/lib/apt/lists/* 
        && wget -O /usr/local/bin/gosu "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture)" 
        && wget -O /usr/local/bin/gosu.asc "https://github.com/tianon/gosu/releases/download/$GOSU_VERSION/gosu-$(dpkg --print-architecture).asc" 
        && export GNUPGHOME="$(mktemp -d)" 
        && gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys B42F6819007F00F88E364FD4036A9C25BF357DD4 
        && gpg --batch --verify /usr/local/bin/gosu.asc /usr/local/bin/gosu 
        && gpgconf --kill all 
        && rm -rf "$GNUPGHOME" /usr/local/bin/gosu.asc 
        && chmod +x /usr/local/bin/gosu 
        && gosu nobody true 
        && apt-get purge -y --auto-remove ca-certificates wget
    
    RUN mkdir /docker-entrypoint-initdb.d
    
    RUN apt-get update && apt-get install -y --no-install-recommends 
    # for MYSQL_RANDOM_ROOT_PASSWORD
            pwgen 
    # for mysql_ssl_rsa_setup
            openssl 
    # FATAL ERROR: please install the following Perl modules before executing /usr/local/mysql/scripts/mysql_install_db:
    # File::Basename
    # File::Copy
    # Sys::Hostname
    # Data::Dumper
            perl 
        && rm -rf /var/lib/apt/lists/*
    
    RUN set -ex; 
    # gpg: key 5072E1F5: public key "MySQL Release Engineering <mysql-build@oss.oracle.com>" imported
        key='A4A9406876FCBD3C456770C88C718D3B5072E1F5'; 
        export GNUPGHOME="$(mktemp -d)"; 
        gpg --batch --keyserver ha.pool.sks-keyservers.net --recv-keys "$key"; 
        gpg --batch --export "$key" > /etc/apt/trusted.gpg.d/mysql.gpg; 
        gpgconf --kill all; 
        rm -rf "$GNUPGHOME"; 
        apt-key list > /dev/null
    
    ENV MYSQL_MAJOR 5.7
    ENV MYSQL_VERSION 5.7.28-1debian9
    
    RUN echo "deb http://repo.mysql.com/apt/debian/ stretch mysql-${MYSQL_MAJOR}" > /etc/apt/sources.list.d/mysql.list
    
    # the "/var/lib/mysql" stuff here is because the mysql-server postinst doesn't have an explicit way to disable the mysql_install_db codepath besides having a database already "configured" (ie, stuff in /var/lib/mysql/mysql)
    # also, we set debconf keys to make APT a little quieter
    RUN { 
            echo mysql-community-server mysql-community-server/data-dir select ''; 
            echo mysql-community-server mysql-community-server/root-pass password ''; 
            echo mysql-community-server mysql-community-server/re-root-pass password ''; 
            echo mysql-community-server mysql-community-server/remove-test-db select false; 
        } | debconf-set-selections 
        && apt-get update && apt-get install -y mysql-server="${MYSQL_VERSION}" && rm -rf /var/lib/apt/lists/* 
        && rm -rf /var/lib/mysql && mkdir -p /var/lib/mysql /var/run/mysqld 
        && chown -R mysql:mysql /var/lib/mysql /var/run/mysqld 
    # ensure that /var/run/mysqld (used for socket and lock files) is writable regardless of the UID our mysqld instance ends up having at runtime
        && chmod 777 /var/run/mysqld 
    # comment out a few problematic configuration values
        && find /etc/mysql/ -name '*.cnf' -print0 
            | xargs -0 grep -lZE '^(bind-address|log)' 
            | xargs -rt -0 sed -Ei 's/^(bind-address|log)/#&/' 
    # don't reverse lookup hostnames, they are usually another container
        && echo '[mysqld]
    skip-host-cache
    skip-name-resolve' > /etc/mysql/conf.d/docker.cnf
    
    VOLUME /var/lib/mysql
    
    COPY docker-entrypoint.sh /usr/local/bin/
    RUN ln -s usr/local/bin/docker-entrypoint.sh /entrypoint.sh # backwards compat
    ENTRYPOINT ["docker-entrypoint.sh"]
    
    EXPOSE 3306 33060
    CMD ["mysqld"]

      FROM :指定基础镜像,比如 FROM ubuntu:14.04

      RUN :在镜像内部执行一些命令,比如安装软件,配置环境等,换行可以使用""

    RUN groupadd -r mysql && useradd -r -g mysql mysql

      ENV :设置变量的值,ENV MYSQL_MAJOR 5.7,可以通过docker run --e key=value修改,后面可以直接使 用${MYSQL_MAJOR}

    ENV MYSQL_MAJOR 5.7

      LABEL : 设置镜像标签 

    LABEL email="itcrazy2016@163.com"
    LABEL name="itcrazy2016"

      VOLUME : 指定数据的挂在目录

    VOLUME /var/lib/mysql

      COPY : 将主机的文件复制到镜像内,如果目录不存在,会自动创建所需要的目录,注意只是复制,不会提取和解压

    COPY docker-entrypoint.sh /usr/local/bin/

      ADD : 将主机的文件复制到镜像内,和COPY类似,只是ADD会对压缩文件提取和解压

    ADD application.yml /etc/itcrazy2016/

      WORKDIR : 指定镜像的工作目录,之后的命令都是基于此目录工作,若不存在则创建会在/usr/local/tomcat下创建test.txt文件会在/root/test下多出一个app.yml文件

    WORKDIR /usr/local
    WORKDIR tomcat
    RUN touch test.txt

      会在/usr/local/tomcat下创建test.txt文件

      CMD :容器启动的时候默认会执行的命令,若有多个CMD命令,则最后一个生效

    CMD ["mysqld"]
    或
    CMD mysqld

      ENTRYPOINT :和CMD的使用类似 .和CMD的不同 docker run执行时,会覆盖CMD的命令,而ENTRYPOINT不会

    ENTRYPOINT ["docker-entrypoint.sh"]

      EXPOSE : 指定镜像要暴露的端口,启动镜像时,可以使用-p将该端口映射给宿主机

    EXPOSE 3306

      实质上image就是由一层一层的layer组成的。先指定一个基础镜像,首先我们需要一个虚拟机的系统,然后由docker官方给我们提供基础的镜像,即运行这个镜像所需要的基础,比如运行一个jar包需要JDK的环境。拿mysql来说就好比如下图:

    Dockerfile实战Spring Boot项目:

    1.创建一个Spring Boot项目

    2.写一个controller

    @RestController
      public class DockerController {
        @GetMapping("/dockerfile")
        @ResponseBody
        String dockerfile() {
          return "hello docker" ;
       }
     }

    3.mvn clean package打成一个jar包 .在target下找到"dockerfile-demo-0.0.1-SNAPSHOT.jar"

    4.在安装了docker环境中新建一个目录"first-dockerfile"

    5.上传"dockerfile-demo-0.0.1-SNAPSHOT.jar"到该目录下,并且在此目录创建Dockerfile

    6.创建Dockerfile文件,编写内容

    FROM openjdk:8
    MAINTAINER itcrazy2016
    LABEL name="dockerfile-demo" version="1.0" author="itcrazy2016"
    COPY dockerfile-demo-0.0.1-SNAPSHOT.jar dockerfile-image.jar
    CMD ["java","-jar","dockerfile-image.jar"]

      如下图:

    7.基于Dockerfile构建镜像 docker build -t test-docker-image . 构建玩即可查看到我们生成的镜像。

    8.基于image创建container   docker run -d --name user01 -p 9981:8080 test-docker-image

    9.通过浏览器去访问 http://192.168.1.101:9981/dockerfile 出现如下说明创建容器成功:

    镜像仓库:

      官方仓库

      我们使用 docker pull  images 这个命令的时候,默认是去 hub.docker.com 拉去镜像的,那么就像我们刚刚自己制作的镜像想要推送到这个平台可以吗?当然是可以的。我们先要注册一个账号

     

    1.在docker机器上登录 docker login 。输入用户名和密码

    2.docker push wuzhenzhao/test-docker-image [注意镜像名称要和docker id一致(我这里就是wuzhenzhao),不然push不成功]

    3.给image重命名,并删除掉原来的

    docker tag test-docker-image wuzhenzhao/test-docker-image
    docker rmi -f test-docker-image

    4.再次推送,刷新hub.docker.com后台,发现成功 (由于是国外的网站,网速也有关系,这里不一定会成功)

    5.别人下载,并且运行

    docker pull wuzhenzhao/test-docker-image
    docker run -d --name user01 -p 9981:8080 wuzhenzhao/test-docker-image

      阿里云docker hub:

      使用官方的仓库会明显感受到网速以及传输的卡顿,所有我们这里还有另外一个方案,就是阿里云的镜像解决方案,也是一样我们需要注册阿里云的账号。

    1.创建一个命名空间:

    2.设置访问凭证,这里会告诉我们怎么连接:

    3.我们通过以上命令进行登录连接,输入密码显示登陆成功。

    4.制作阿里云镜像:sudo docker tag wuzhenzhao/test-docker-image registry.cn-hangzhou.aliyuncs.com/wuzz-docker/test-docker-image (:v1.0) 官方格式带上版本号

    5.阿里云镜像推送到阿里云镜像仓库:sudo docker push registry.cn-hangzhou.aliyuncs.com/wuzz-docker/test-docker-image (:v1.0)

     6.查看控制台:镜像推送成功

      如果需要拉取镜像使用:sudo docker pull registry.cn-hangzhou.aliyuncs.com/wuzz-docker/test-docker-image

    搭建自己的Docker Hub  (Harbor):

    1.访问github上的harbor项目 https://github.com/goharbor/harbor/releases下载版本,比如1.7.1

    2.harbor 需要依赖 docker-compose 环境,先安装 docker-compose:

    yum -y install epel-release 
    yum -y install python-pip
    pip install --upgrade pip
    pip install docker-compose 

    3.进入到harbor目录,修改harbor.cfg文件,主要是ip地址的修改成当前机器的ip地址。同时也可以看到Harbor的密码,默认是Harbor12345

    4.安装harbor,需要一些时间 sh install.sh

    5.浏览器访问,比如192.168.1.101,输入用户名和密码即可 默认密码 Harbor123456 ,可以在harbor.cfg 文件中配置

    这样子我们的镜像仓库就搭建好了,省下来的操作无非就是登录 推送镜像 拉去镜像等操作。

      如果出现登录报错:是因为未在docker启动文件中添加--insecure-registry信任关系!

      增加文件 /etc/docker/daemon.json ,写入内容:

    {
        "insecure-registries": [
            "172.33.16.1"    #harbor服务主机ip,如果不是80端口,一定要把端口同时添加进去
        ]
    }

      再次登录就没问题了。推送前需要打Tag。 docker tag 镜像名:标签 私服地址/仓库项目名/镜像名:标签

      然后推送 docker push 192.168.1.101/library/test-image 就可以了,然后通过页面可以看到已经在仓库里了

    Image 常用命令:

    docker images    查看本地image列表:
    docker pull         获取远端镜像:
    docker image rm imageid  删除镜像[注意此镜像如果正在使用,或者有关联的镜像,则需要先处理完]:
    docker rmi -f imageid
    docker rmi -f $(docker image ls)   删除所有镜像
    docker run image  运行镜像
    docker push    发布镜像
  • 相关阅读:
    Python基本数据类型
    DNS服务
    在浏览器地址栏输入百度网址之后的故事(面试必考)
    C++对象的赋值和复制
    C++区别于其他语言的知识点总结
    SQL连接查询(最全面)
    源码堆栈信息保存 到此一游
    linux 内核调试之关键函数名记要
    记几个命令 转
    JS 奇淫巧技 转
  • 原文地址:https://www.cnblogs.com/wuzhenzhao/p/11798039.html
Copyright © 2020-2023  润新知