深入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 發布鏡像
