Docker入门—— Dockerfile,仓库

1. Dockerfile

  • Dockerfile
    Dockerfile是一个文本格式的配置文件,用户可以使用Dockerfile快速创建自定义的镜像。
    Dockerfile由一行行命令语句组成,基本一行命令就代表镜像封装中的一层,其中每一条指令都创建镜像的一层。
    Dockerfile一般分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。
  • 其指令的具体信息如下:
    • FROM
      格式为FROM < image > 或FROM< image >:< tag >。
      第一条指令必须为FROM指令。并且,如果在同一个Dockerfile中创建多个镜像时,可以使用多个FROM指令(每个镜像一一次)。
    • MAINTAINER
      格式为MAINTAINER < name >, 指定维护者信息。
    • RUN
      格式为RUN < command > 或RUN [ “executable”, “param1”, “param2”]。
      前者将在shell终端中运行命令,即/bin/sh -C ;后者则使用exec执行。指定使用其他终端可以通过第二种方式实现,例如RUN[“/bin/bash”,”-C”,”echohello”]。每条RUN指令将在当前镜像基础上执行指定命令,并提交为新的镜像。当命令较长时可以使用\来换行。
    • CMD
      支持三种格式:
      CMD [“executable”, “param1”, “param2”]使用exec执行,推荐方式。
      CMD command param1 param2 在/bin/sh中执行,提供给需要交互的应用。
      CMD [“param1”, “param2”]提供给ENTRYPOINT的默认参数。
      指定启动容器时执行的命令,每个Dockerfile只能有一-条CMD命令。如果指定了多条
      命令,只有最后一条会被执行。
      如果用户启动容器时候指定了运行的命令,则会覆盖掉CMD指定的命令。
    • EXPOSE
      格式为EXPOSE < port > [< port >…]。
      例如:EXPOSE 22 80 8443
      告诉Docker服务端容器暴露的端口号,供互联系统使用。在启动容器时需要通过-P,Docker主机会自动分配一个端口转发到指定的端口;使用-P,则可以具体指定哪个本地端口映射过来。
    • COPY
      格式为COPY < src > < dest >。
      复制本地主机的< src > (为Dockerfile所在目录的相对路径,文件或目录)为容器中的< dest >。目标路径不存在时,会自动创建。
      当使用本地目录为源目录时,推荐使用COPY。
    • ENTRYPOINT
      有两种格式:
      ENTRYPOINT [ “executable”, “param1”, “param2”]
      ENTRYPOINT command param1 param2 ( shell中执行)。
      配置容器启动后执行的命令,并且不可被docker run 提供的参数覆盖。
      每个Dockerfile中只能有一个ENTRYPOINT,当指定多个ENTRYPOINT时,只有最后一个生效。
    • VOLUME
      格式为VOLUME [“/data”]。
      创建-一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等。

1. 简单的dockerfile示例,建立一个封装httpd服务的镜像

進行httpd 服務的鏡像封裝:

編輯Dockerfile:
 vim Dockerfile

 FROM rhel7   # 父镜像
 ENV HOSTNAME test1
 MAINTAINER root@localhost
 EXPOSE 80    # 服务端口号
 COPY yum.repo /etc/yum.repos.d/yum.repo   # yum 源文件,需要进行指定
 RUN rpm --rebuilddb && yum install -y httpd && yum clean all 
 VOLUME ["/var/www/html"]
              # run 命令,进行httpd服务的安装
 CMD ["/usr/sbin/httpd","-D","FOREGROUND"]
              # 用镜像创建实例后,最终执行的命令

可能会遇到以下问题:
rpm数据库损坏需要重建。因此需要在 “yum install …” 前使用 “rpm –rebuilddb” 重建数据库。比如:
RUN rpm –rebuilddb && yum install -y sudo …
在我的环境中发现有时候如果有多条 “RUN yum install -y …” 指令,需要在每条之前都加上 “rpm –rebuilddb”。

创建镜像

编写完成Dockerfile之后,可以通过docker build 命令来创建镜像。

基本的格式为docker build[ 选项]路径,该命令将读取指定路径下(包括子目录)的 Dockefile,并将该路径下所有内容发送给Docker服务端,由服务端来创建镜像。因此一般建议 放置Dockerfile 的目录为空目录。

执行如下:

 docker built -t rhel7:httpd /tmp/docker/Dockerfile/httpd

2. 一个镜像封装多个服务

这里会用到supervisord

  • supervisord是一个进程管理工具,能对进程进行自动重启等操作。
    优点:
    • 可以将非后台运行程序后台运行
    • 自动监控,重启进程
      缺点:
    • 不能管理后台运行程序
    • 对多进程服务,不能使用kill关闭
编辑 supervisord 文件
  1 [surpervisord]
  2 nodaemon=true    
  3 
  4 [program:sshd]
  5 command=/usr/sbin/sshd -D   # 启动sshd服务
  6 
  7 [program:httpd]
  8 command=/usr/sbin/httpd     # 启动httpd服务

 Dockerifle
   1 FROM rhel7
   2 EXPOSE 80 22   # 一次暴露多个端口
   3 COPY yum.repo /etc/yum.repos.d/yum.repo
   4 RUN rpm --rebuilddb && yum install -y httpd && yum clean all && rpm --rebuil  ddb && yum install -y openssh-server openssh-clients supervisor && ssh-keygen -q -t rsa -f /etc/ssh/ssh_host_rsa_key -N "" && ssh-keygen -q -t ecdsa -f /etc/ssh/ssh_host_ecdsa_key -N "" && ssh-keygen -q -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N "" && echo root:redhat | chpasswd
   5 COPY supervisord.conf /etc/supervisord.conf
   6 CMD ["/usr/bin/supervisord"]  # 通过 supervisord 来进行

然后进行镜像生成

 docker build -t rhel7:mutil /tmp/docker/dockerfile/mutil

2. 仓库

  • 仓库(Repository)是集中存放镜像的地方。
    每个服务器上可以有多个仓库,而每个仓库下面有多个镜像。从这方面来说,仓库可以被认为是一个具体的项目或目录。例如对于仓库地址 dl.dockerpool.com/ubuntu 来说, dl.dockerpool.com 是注册服务器地址,,ubuntu 是仓库名。
    大部分时候,并不需要严格区分这两者的概念。
    目前 Docker 官方维护了一个公共仓库 Docker Hub (https://hub.docker.com/) ,其中已经包括了超过 15,000 的镜像。大部分需求,都可以通过在 Docker Hub 中直接下载镜像来实现。
    我这里着重强调进行用户私有仓库的创建
  • 使用registry镜像创建私有仓库
    安装Docker后,可以通过官方提供的registry镜像来简单搭建一套本地私有仓库环境:
    docker run -d -P 5000:5000 registry
    这将自动下载并启动一个registry容器,创建本地的私有仓库服务。
    默认情况下,会将仓库创建在容器的/tmp/registry目录下。可以通过-V参数来将镜像文件存放在本地的指定路径上。

示例如下:

1. 简单的本地免密仓库

 # 在本地启动一个私有仓库服务,监听端口为5000
 [root@foundation25 821]# docker run -d -p 5000:5000 -v /opt/registry:/var/lib/registry registry
 2d25eda8bc70f36ed240fb8f87009d18020b19ad9e94712fcf4758b38d0d0470
 [root@foundation25 821]# docker ps
 CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS                    NAMES
 2d25eda8bc70        registry            "docker-registry"   3 seconds  ago       Up 1 second         0.0.0.0:5000->5000/tcp   dreamy_noyce

 # 建立要推送到本地仓库的镜像
 [root@foundation25 821]# docker tag ubuntu localhost:5000/ubuntu 
 # 使用docer push 上传标记镜像
 [root@foundation25 821]# docker push localhost:5000/ubuntu
 The push refers to a repository [localhost:5000/ubuntu]
 5f70bf18a086: Image successfully pushed 
 11083b444c90: Image successfully pushed 
 9468150a390c: Image successfully pushed 
 56abdd66ba31: Image successfully pushed 
 Pushing tag for rev [07c86167cdc4] on {http://localhost:5000/v1/repositories/ubuntu/tags/latest}
 # 删除本地已有的ubuntu镜像
 [root@foundation25 821]# docker rmi -f localhost:5000/ubuntu ubuntu
 # 从本地仓库拉取上传过的镜像:localhost:5000/ubuntu
 [root@foundation25 821]# docker pull localhost:5000/ubuntu

以上是简单的本机仓库的搭建,但是除了本地用户外别的用户无法应用,这明显是很不方便的,我们可以搭建一个主机外用户可以访问的仓库,以适应生产需求

2. 配置用户免费HTTPS证书仓库

建立目录,进行证书的获取
 # 建立指定目录
 [root@foundation25 ~]# mkdir /etc/docker/certs
 [root@foundation25 ~]# cd /etc/docker/
 # 进入指定目录的上一级,并进行证书及密钥的获取
 [root@foundation25 docker]# openssl req -newkey rsa:4096 -nodes -sha256 -keyout certs/domain.key -x509 -days 365 -out certs/domain.crt
 Generating a 4096 bit RSA private key
 .................................................................................................................................................................................................++
 ......++
 writing new private key to 'certs/domain.key'
 -----
 You are about to be asked to enter information that will be incorporated
 into your certificate request.
 What you are about to enter is what is called a Distinguished Name or a DN.
 There are quite a few fields but you can leave some blank
 For some fields there will be a default value,
 If you enter '.', the field will be left blank.
 -----
 Country Name (2 letter code) [XX]:CN
 State or Province Name (full name) []:Shaanxi
 Locality Name (eg, city) [Default City]:Xi'an
 Organization Name (eg, company) [Default Company Ltd]:test
 Organizational Unit Name (eg, section) []:linux
 Common Name (eg, your name or your server's hostname) []:test.com
 Email Address []:root@localhost 
 # 获取成功
 [root@foundation25 docker]# ls certs/
 domain.crt  domain.key
 [root@foundation25 docker]# pwd
 /etc/docker
 # 将密钥移动到指定位置(/etc/docker/certs.d/'domain'/ca.crt)
 # 注意要添加好本地域名解析
 [root@foundation25 docker]# mkdir /etc/docker/certs.d/test.com -p
 [root@foundation25 docker]# cp /etc/docker/certs/domain.crt /etc/docker/certs.d/test.com/ca.crt
 [root@foundation25 docker]# ls /etc/docker/certs.d/test.com/ca.crt
 /etc/docker/certs.d/test.com/ca.crt
 # 启动一个registry容器
 [root@foundation25 docker]# docker run -d \
 > --restart=always \
 > --name registry \
 > -v `pwd`/certs:/certs \
 > -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
 > -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
 > -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
 > -p 443:443 \
 > registry
 9bcc3ee45b386014f1480e076fdc330a71a85849eb10ac2404c611ab057f9954
 [root@foundation25 docker]# docker ps
 CONTAINER ID        IMAGE               COMMAND               CREATED             STATUS              PORTS                             NAMES
 9bcc3ee45b38        registry            "docker-registry"   8 seconds ago       Up 7 seconds        0.0.0.0:443->443/tcp, 5000/tcp   registry

 然后进行本地镜像的上传:
 [root@foundation25 docker]# docker push test.com/rhel7

3. 配置加密仓库

清除上个实验的容器,但是保留建立的证书与密钥

 [root@foundation25 docker]# docker run -d --restart=always \
 > --name registry -v `pwd`/certs:/certs \ 
 > -e REGISTRY_HTTP_ADDR=0.0.0.0:443 \
 > -e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
 > -e REGISTRY_HTTP_TLS_KEY=/certs/domain.key -v `pwd`/auth:/auth \
 > -e "REGISTRY_AUTH=htpasswd" \
 > -e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" \
 > -e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd \
 > -p 443:443 \
 > 83139345d017    # 镜像 ID
 3539268d9f8af52b1f66ed443e518570674bb8ccb5c44866e6474ef469f01607
 # 启动仓库服务后,查看容器列表
 [root@foundation21 docker]# docker ps 
 CONTAINER ID        IMAGE               COMMAND                   CREATED             STATUS               PORTS                            NAMES
 3539268d9f8a        83139345d017        "/bin/registry /et..."   5  seconds ago       Up 4 seconds        0.0.0.0:443->443/tcp,  5000/tcp   registry
 进行镜像的上传,被拒绝,因为没有进行认证
 [root@foundation21 docker]# docker push test.com/nginx
 The push refers to a repository [test.com/nginx]
 18af9eb19b5f: Preparing 
 no basic auth credentials

登录仓库后,再进行上传

 # 进行用户登陆
 [root@foundation25 docker]# docker login -u test -p redhat test.com
 Login Succeeded
 # 上传镜像
 [root@foundation25 docker]# docker push test.com/nginx
 The push refers to a repository [test.com/nginx]
 18af9eb19b5f: Pushed 
 latest: digest: sha256:f1b19bc905965d1ff157c76b9ef6615c119aadad3cf4652bc881d3354ba3fdc4 size: 528
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值