Docker初学乍练之镜像相关

一、自定义docker image

镜像是创建容器的基础,镜像可以从官方的docker hub上下载,可以在一些第三方镜像仓库服务器上下载现成的,同时,也可以根据用户的需要自定义镜像;最常用的镜像生成途径有两种:基于容器制作和dockerfile。

1.1、基于容器制作镜像

现有容器做好修改后提交修改就创建了新的镜像,busybox可以看成是一个简易版的linux系统 ,内建了很多命令,我们可以基于busybox定制镜像

1.1.1、开启一个镜像

docker container run --name b1 -it busybox

1.1.2、改变镜像

/ # mkdir -p /data/html
/ # echo "<h1>hello docker</h1>" > /data/html/index.html

1.1.3、提交镜像

docker commit -p b1

1.1.4、为新镜像打标签(docker ps查看新镜像ID)

docker tag 87c118fcb55b jym/httpd:v0.1
docker tag jym/httpd:v0.1 jym/httpd:latest

Ps:新的镜像存在本地,未上传至仓库,新的镜像有两个标签,删除其中一个标签镜像依然存在,只是删除镜像的一个引用。

制作镜像时修改CMD

docker commit -a "eric <[email protected]>" -c 'CMD ["/bin/httpd","-f","-h","/data/html"]' -p b1 jym/httpd:v0.2

1.1.5、运行容器

docker container run  --name t1  jym/httpd:v0.2

1.1.6、访问httpd

[root@node ~]# docker container inspect t1  | grep "IPAddress"
            "SecondaryIPAddresses": null,
            "IPAddress": "172.17.0.3",
                    "IPAddress": "172.17.0.3",
[root@node ~]# curl 172.17.0.3
<h1>hello docker</h1>

1.2、基于Dockerfile制作镜像

Dockerfile 是一个文本格式的配置文件,用户可以使用dockerfile快速创建自定义的镜像
基本格式为docker build [options] dockerfile_path 该命令将读取指定路径下的Dockerfile,并将该路径下所有内容发送给Docker服务端,由服务端来创建镜像。因此一般建议放置Dockerfile的目录只存放Dockerfile文件。
示例:自定义一个nginx服务

1、下载nginx文件与dockerfile文件放在同一目录
[root@node1 docker-img]# ls
Dockerfile  nginx-1.15.12.tar.gz
2、编辑Dockerfile文件
#base image
FROM centos
#maintainer info
LABEL maintainer="eric <[email protected]>"
#mount a dir to container
VOLUME ["/data"]
#Download the source package from the url and put it in the directory of the container.
ADD nginx-1.15.12.tar.gz /usr/local/src/
#RUN is used to specify the program running during the docker build process, which can be any command
RUN yum install -y gcc gcc-c++ automake pcre pcre-devel zlip zlib-devel openssl openssl-devel  && groupadd -r nginx && useradd -r -g nginx nginx
#Change working directory
WORKDIR /usr/local/src/nginx-1.15.12
#Compile and install
RUN ./configure  --prefix=/usr/local/nginx    --user=nginx --group=nginx   --with-pcre && make && make install
#Add environment variables
ENV PATH /usr/local/nginx/sbin:$PATH
#Exposing port
EXPOSE 80/tcp 
#Specify a default run program for the container
ENTRYPOINT ["nginx"]
CMD ["-g","daemon off;"]

3、生成镜像
docker build -t myweb:v1.0 ./
4、运行镜像
docker run -d -p 8000:80 -v /home/jym/data:/data --name web1  myweb:v1.0

验证:访问主机的8000端口
Docker初学乍练之镜像相关

二、Dockerfile文件详解

基于Dockerfile文件生成镜像的示例中,有一行行命令语句组成,其中,注释行以#开头,Dockerfile 文件的非注释行的第一行要指定基于的基础镜像。Dockerfile 文件每一条命令都会创建一层image layer,所以Dockerfile文件尽量以最少的命令完成所有事。
常用命令语句:

2.1、FROM

FROM指令必须为dockerfile文件开篇的第一个非注释行,用于为镜像文件构建过程指定基准镜像,如果需要创建多个镜像时,可以使用多个FROM指令,后续指令运行于此基准镜像所提供的运行环境
实践中,基准镜像可以是任何可用镜像文件,默认情况下,docker build会在docker主机上查找指定的镜像文件,在其不存在时,则会从docker hub registry上拉取所需的镜像文件;如果还是没找到,docker build会返回一个错误信息。

格式:
    FROM <repository>[:<tag>]:标签可省略,缺省为latest
    FROM <repository>@<digest>:指明镜像的哈希码,比镜像名更安全
示例:FROM centos

2.2、LABEL

用于让用户为镜像指定各类元数据
LABEL指令以key-value键值对形式定义

格式:
    LABEL <key>=<value> <key>=<value> <key>=<value> …
示例:LABEL maintainer="eric <[email protected]>"

2.3、COPY

复制本地主机的<src>(为Dockerfile所在目录的相对路径,文件或目录)为容器中的<dest>。目标路径不存在时,会自动创建。

格式:
    COPY <src> …<dest> 或 COPY ["<src>",…"<dest>"]
        <src>:要复制的源文件或目录,支持使用通配符
        <dest>:目标路径,即正在创建的image的文件系统路径;建议为<dest>使用绝对路径,否则,COPY指定则以WORKDIR为其起始路径;
    注意:在路径中有空白字符时,通常使用第二种格式

2.4、ADD

复制本地主机的<src>到容器中的<dest>。其中<src>可以是Dockerfile所在目录的一个相对路径(文件或目录);也可以是一个URL;还可以是一个tar文件(自动解压为目录)。

格式:
ADD <src> .<dest> 或 ADD ["<src>",. "<dest>"] 
示例:
ADD nginx-1.15.12.tar.gz /usr/local/src/

操作准则
• 同COPY指令
• 如果<src>为URL且<dest>不以/结尾,则<src>指定的文件将被下载并直接被 创建为<dest>;如果<dest>以/结尾,则文件名URL指定的文件将被直接下载 并保存为<dest>/<filename>
• 如果<src>是一个本地系统上的压缩格式的tar文件,它将被展开为一个目录 ,其行为类似于“tar -x”命令;然而,通过URL获取到的tar文件将不会自动 展开;
• 如果<src>有多个,或其间接或直接使用了通配符,则<dest>必须是一个以/结 尾的目录路径;如果<dest>不以/结尾,则其被视作一个普通文件,<src>的内 容将被直接写入到<dest>;

2.5、WORKDIR

为后续的RUN、CMD、ENTRYPOINT指令配置工作目录,可以使用多个WORKDIR指令。后续指令如果参数是相对路径,则会基于之前命令指定的路径

格式:WORKDIR /path/to/workdir
示例:WORKDIR /usr/local/src

注意:后续指令如果参数是相对路径,则会基于之前命令指定的路径

2.6、VOLUME

用于在image中创建一个挂载点目录,以挂载Docker host上的卷或其他容器上的卷

格式:
    VOLUME <mountpoint>或 VOLUME ["<mountpoint>"]
示例:VOLUME ["/data"]

注意:如果挂载点目录路径下存在文件,docker run命令会在卷挂载完成后将此前的所有文件复制到新挂载的卷中

2.7、EXPOSE

用于为容器打开指定要监听的端口以实现与外部通信

格式:
    EXPOSE <port>[/<protcol>] [<port>[/<protcol>] …]
    <protcol>用于指定传输层协议,可为tcp或udp二者之一,默认为TCP协议

示例:EXPOSE 80/tcp 443/tcp

注意:在启动容器时需要通过-P,Docker主机会自动分配一个端口转发到指定的端口;使用-p,则可以具体指定哪个本地端口映射过来

2.8、ENV

用于为镜像定义所需的环境变量,可被Dockerfile文件中位于其后的其它指令(如ENV,ADD,COPY等)所调用,并在容器运行时保持。

调用格式:$variable_name或${variable_name}
格式:
    ENV <key> <value>
    <key>之后的所有内容均会被视作其<value>的组成部分 ,因此,一次只能设置一个变量;
    ENV <key>=<value>…
可用一次设置多个变量,每个变量为一个"<key>=<value>"的 键值对,如果<value>中包含空格,可以反斜线(\)进行转义,也可通过 对<value>加引号进行标识;另外,反斜线也可用于续行;

注意:定义多个变量时,建议使用第二种方式,以便在同一层中完成所有功能;在创建镜像(build)时,可以通过-e,来传递变量

2.9、RUN

用于指定docker build过程中运行的程序,其可以是任何命令

格式:
    RUN <command>
    第一种格式中,<comand>通常是一个shel命令,且以“/bin/sh -c”来运行它, 这意味着此进程在容器中的PID不为1,不能接收Unix信号,因此,当使用 docker stop <container>命令停止容器时,此进程接收不到SIGTERM信号;

    RUN ["<executable>","<param1>","<param2>"]
    第二种语法格式中的参数是一个JSON格式的数组,其中<excutable>为要运行的 命令,后面的<parmN>为传递给命令的选项或参数;然而,此种格式指定的命 令不会以“/bin/sh -c”来发起,因此常见的shel操作如变量替换以及通配符(?,* 等)替换将不会进行;不过,如果要运行的命令依赖于此shel特性的话,可以将 其替换为类似如下格式: RUN ["/bin/bash", -c", <excutable>", <parm1>"]

2.10、CMD

类似于RUN指令,CMD指令也可用于运行任何命令或应用程序, 不过,二者的运行时间点不同
• RUN指令运行于映像文件构建过程中,而CMD指令运行于基于Dockerfile构建出的新映像文件启动一个容器时
• CMD指令的首要目的在于为启动的容器指定默认要运行的程序,且其运行结束后,容器也将终止;不过,CMD指定的命令其可以被docker run的命令行选项所覆盖
• 在Dockerfile中可以存在多个CMD指令,但仅最后一个会生效
• RUN和CMD指令指定的命令必须是基础镜像中有的命令

格式:
    CMD <comand> 
    CMD [“<excutable>” , “<parm1>” , “<parm2>”] 
    CMD ["<parm1>",<parm2>"] 
    前两种语法格式的意义同RUN 
第三种则用于为ENTRYPOINT指令提供默认参数

2.11、ENTRYPOINT

类似CMD指令的功能,用于为容器指定默认运行程序,从而使得容器像是一个单独的可执行程序
与CMD不同的是,由ENTRYPOINT启动的程序不会被docker run命令行指定的参数所覆盖,而且,这些命令行参数会被当作参数传 递给ENTRYPOINT指定指定的程序
不过,docker run命令的-entrypoint选项的参数可覆盖ENTRYPOINT指令指定的程序

格式:
ENTRYPOINT <comand> 
ENTRYPOINT ["<excutable>", <parm1>", <parm2>"] 

docker run命令传入的命令参数会覆盖CMD指令的内容并且附加到 ENTRYPOINT命令最后做为其参数使用
Dockerfile文件中也可以存在多个ENTRYPOINT指令,但仅有最后一个会生效

2.12、USER

用于指定运行image时的或运行Dockerfile中任何RUN、CMD或 ENTRYPOINT指令指定的程序时的用户名或UID,默认情况下,container的运行身份为root用户

格式:
USER <UID>|<UserName>

注意:<UID>可以为任意数字,但实践中其必须为/etc/paswd中 某用户的有效UID,否则,docker un命令将运行失败

三、Docker Registry

将自定义镜像上传至docker hub

3.1、注册docker hub账号

https://cloud.docker.com

3.2、登陆docker hub

docker login -u 614949750 -p ***

3.3、将镜像推送到docker hub

按照要上传的注册服务器的要求打上标签
[root@node ~]# docker tag myweb:v1.0 614949750/mynginx:v1.0
上传镜像
[root@node ~]# docker push 614949750/mynginx:v1.0

四、Docker 私有 registry之harbor

4.1、harbor简介

Docker hub是docker官方的registry,是存放docker仓库的的具体服务器,允许用户注册,上传自己的镜像到docker hub上;对与服务器在国内的用户来说,将线上的镜像放在docker hub上限于网速,效率低下;对于使用阿里云vps环境的用户来说,将镜像放在阿里云的registry上到是个明智的选择;那么,对于未使用云服务器的用户来说,搭建私有仓库是非常好的选择。
Harbor就是一个开源的企业级docker registry服务器,其功能强大,社区活跃,版本稳定更新。下面是引自 harbor github:https://github.com/goharbor/harbor 上对于harbor的功能介绍:
• 基于角色的访问控制:用户和镜像仓库通过“项目”进行阻止,用户对一个项目下的多个镜像拥有不同的权限
• 基于策略的镜像复制:镜像可以在多个Registry实例中复制(同步)。尤其适合于负载均衡,高可用,混合云和多云的场景
• 漏洞扫描:Harbor定期扫描镜像并向用户告警
• LDAP / AD支持:Harbor与现有企业LDAP / AD集成以进行用户身份验证和管理,并支持将LDAP组导入Harbor并为其分配适当的项目角色。
• 镜像删除和垃圾收集:可以删除镜像,并可以回收它们的空间
• 公证制度:使用公证人制度确保镜像的真实性
• ui界面:提供ui界面使用户浏览,检索当前Docker镜像仓库,管理项目
• 审计:用户对镜像仓库的操作都被记录,便与审计
• RESTful API:适用于大多数管理操作的RESTful API,易于与外部系统集成
• 易安装:提供在线和离线安装程序。

4.2、安装前准备

4.2.1、安装docker-ce

Docker-ce repo文件下载:https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo
配置好yum源,直接yum安装docker-ce

4.2.2、安装docker-compose

Docker-compose收录在epel源
yum install epel-release.noarch 
yum install docker-compose

4.2.3、安装openssl

yum install openssl

4.3、安装

harbor下载地址:https://github.com/goharbor/harbor/releases

4.3.1、下载对应的安装包

在线和离线两种,本文下载的是离线
wget https://storage.googleapis.com/harbor-releases/release-1.7.0/harbor-offline-installer-v1.7.5.tgz

4.3.2、解压并修改配置文件

tar xzvf harbor-offline-installer-v1.7.5.tgz -C /usr/local/
cat  harbor.cfg |grep hostname
hostname = 192.168.143.130

4.3.3、启动docker

systemctl start docker.service 

4.3.4、安装harbor

./install.sh 
共有五步:
[Step 0]: checking installation environment …
[Step 1]: loading Harbor images ...
[Step 2]: preparing environment …
[Step 3]: checking existing instance of Harbor …
[Step 4]: starting Harbor ...

4.3.5、启动harbor容器

docker-compose start

4.3.6、访问ui

配置文件默认配置端口为80, ui用户名密码是admin/Harbor12345
Docker初学乍练之镜像相关
Docker初学乍练之镜像相关

项目:新增/删除项目,查看镜像仓库,给项目添加成员、查看操作日志、复制项目等
日志:仓库各个镜像create、push、pull等操作日志
系统管理
用户管理:新增/删除用户、设置管理员等
复制管理:新增/删除从库目标、新建/删除/启停复制规则等
配置管理:认证模式、复制、邮箱设置、系统设置等
其他设置
用户设置:修改用户名、邮箱、名称信息
修改密码:修改用户密码

4.3.7、修改docker配置文件

docker默认使用https方式连接镜像仓库服务器,而harbor默认使用http方式连接,所以配置docker使用http方式连接。

vim /etc/docker/daemon.json
添加一条配置 "insecure-registries":["192.168.143.130"]
重启docker服务
systemctl restart docker.service

4.3.8、登陆harbor

[root@node1 harbor]# docker login 192.168.143.130
Username: admin
Password: 

4.3.9、修改标签&上传镜像

目前已有一个公开项目library,我们可以向项目中推送镜像

[root@node1 harbor]# docker tag minio/minio 192.168.143.130/library/minio:latest
[root@node1 harbor]# docker push 192.168.143.130/library/minio:latest

Docker初学乍练之镜像相关

五、Docker 私有 registry之docker-distribution

5.1、安装

yum install docker-registry

5.2、配置文件

/etc/docker-distribution/registry/config.yml
version: 0.1
log:
  fields:
    service: registry
storage:
    cache:
        layerinfo: inmemory
    filesystem:
        rootdirectory: /var/lib/registry
http:
    addr: :5000

5.3、启动

systemctl start docker-distribution.service

5.4、修改docker配置文件

vim /etc/docker/daemon.json
{
    "insecure-registries":["192.168.143.130:5000"]
}
systemctl restart docker

5.5、修改标签&上传镜像

docker tag myweb:v1.0 192.168.143.130:5000/myweb:v1.0
docker push 192.168.143.130:5000/myweb:v1.0

参考文章:
马哥docker.pdf
docker docs:https://docs.docker.com/develop/develop-images/dockerfile_best-practices/
Harbor docs: https://goharbor.io/docs/
Harbor github: https://github.com/goharbor/harbor/blob/master/docs/installation_guide.md

猜你喜欢

转载自blog.51cto.com/jiayimeng/2383004