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]\nskip-host-cache\nskip-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    發布鏡像


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM