zoukankan      html  css  js  c++  java
  • docker(三):docker镜像管理

    一、基本介绍

    1. docker镜像是容器启动的基础,镜像里面包含容器启动所需要的文件系统及其内容。docker镜像采用分层构建的机制,这种分层大致分为两部分,一部分是最底层的引导文件系统bootfs,类型有aufs,btffs或者overlay2等;另一部分真正让用户来构建用户空间并运行进程的容器称为rootfs。

      • bootfs:用于引导文件系统,包括BootLoader和kernel,容器启动完成后会被卸载以节约内存资源。(这里说的卸载,是从内存中移除而不是删除)

      • rootfs:位于bootfs之上,表现为docker的根文件系统,比如/dev、/bin之类。

        • 传统模式中,系统启动时,内核挂载rootfs时会先将其挂在为”只读“模式,自检完成后将其重新挂载为读写模式。
        • docker中,rootfs由内核挂载为”只读“模式,而后通过”联合挂载“技术额外挂载一个”可写“层。(我们在docker container中的操作就是可写层)
    2. 分层构建最底层的是基础镜像,位于上层的镜像称为父镜像(系统层),每添加一个镜像都是一个独立的层次。最上层为“可写层”。其它均为“只读”层。删除容器的时候,可写层会一并被删除

    3. 启动容器时,docker daemon会试图从本地获取相关镜像;本地不存在时,会从docker Registry(默认就是docker hub)中下载并保存到本地。
    1. docker registry用于保存docker镜像,包括镜像的层次结构和元数据,用户可以自建registry,也可以使用官方的docker hub。registry里面的镜像通常由开发人员制作,而后推送至registry上保存,以供用户使用。另外,为了安全起见,docker daemon要求docker registry必须是https的,如果不是就需要配置docker daemon。registry分类如下:

      • Sponsor registry:第三方的Registry,供客户和docker社区使用
      • Mirror registry:第三方的Registry,只让客户使用
      • Vendor registry:由发布docker镜像的供应商提供的registry。如Redhat自己的registry
      • private registry:通过设有防火墙和额外安全层的私有实体提供的registry。
    2. repository是由某个特定docker镜像的所有迭代版本所组成,一个registry可以存在多个repository。repository分为顶层仓库和用户仓库。

      • 顶层仓库是直接由仓库名命名的,一般用docker search搜索的第一个就是顶层仓库
      • 用户仓库名称格式为:用户名或者成为项目名/仓库名。一般除了docker search搜索的第一个,其它的都是用户仓库。
    3. 镜像的生成途径

      • 通过编写dockerfile
      • 基于容器制作:也就是把容器最上层的可写层提交成一个新的镜像。比如起了一个centos的容器,然后在上面搭建一个nginx,最后用docker container commit提交完就是一个nginx的镜像了。
      • docker hub automated builds:这个其实也是基于dockerfile构建的。首先在docker hub上面设置与GitHub的集成,然后本地写完dockerfile后推到GitHub上面,docker hub检测到GitHub的变化就会触发build,生成新的镜像。

    二、镜像制作

     1. 基于dockerfile制作镜像
     2. 基于容器制作镜像(第一种)

      a) 就以busybox镜像起一个容器,创建httpd启动所需要的文件

    [root@docker1 ~]# docker run --name busy01 -it busybox
    / # mkdir -p /data/html
    / # echo 'this is a test ' >/data/html/index.html
    / # ps
    PID   USER     TIME  COMMAND
        1 root      0:00 sh
        7 root      0:00 ps
    / # which httpd
    /bin/httpd
    

      b) 此时不要退出本窗口,另外开一个终端窗口进行镜像制作。

    上面使用ps命令可以看到,PID为1的进程是sh,容器中PID为1的进程就相当于我们宿主机的systemd进程,1进程是bash,它运行完就会结束的,PID为1的进程结束也就意味着容器就exit了。所以上面运行busybox容器的窗口是不可以关闭也不可以放在后台运行的。这里就顺便再提一下应用程序的运行:如果想让一个应用类的容器长久的运行下去,要么起一个类似busybox的容器,然后前台运行一个应用(比如httpd:httpd -f -h /data/html),这个窗口永远不能关闭;要么在把容器的CMD设置为前台运行应用的命令(也就是设置应用的PID为1)。

      c) 我们先看下busybox的CMD,可看到这个容器的CMD是sh。

    [root@docker1 ~]# docker inspect busy01 | grep Cmd -A1
                "Cmd": [
                    "sh"
    

      d) 基于busybox镜像重新commit一个CMD为httpd的镜像。

    [root@docker1 ~]# docker commit -c 'CMD ["/bin/httpd","-f","-h","/data/html"]' -p busy01 hamerle/httpd:v1
        # -c:以列表的形式修改dockerfile的指令。此例只修改CMD指令,使新容器CMD指令为httpd(也就是PID为1的进程是httpd),之前是sh。
        # -p:提交过程中暂停容器的运行,防止文件保存的不完整。
        # -p的后面跟的要操作容器的名字,最后是提交后生成新镜像的名字和tag。
    [root@docker1 ~]# docker images 
    REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
    hamerle/httpd            v1                  099c89327481        2 minutes ago       1.2MB
    busybox                  latest              64f5d945efcc        3 weeks ago         1.2MB
    

      e) 以这个新镜像创建一个httpd的容器,然后访问httpd服务

    [root@docker1 ~]# docker run --name httpd01 -d hamerle/httpd:v1
    [root@docker1 ~]# docker inspect httpd01 | grep Cmd -A4
                "Cmd": [
                    "/bin/httpd",
                    "-f",
                    "-h",
                    "/data/html"
    [root@docker1 ~]# docker inspect httpd01 | grep IPAddress
                "IPAddress": "172.17.0.3",
    [root@docker1 ~]# curl 172.17.0.3
    this is a test        # 访问成功
    

     3. 基于容器制作镜像(第二种)
      在公司使用openjdk做基础环境启动的java程序莫名其妙的有问题,所以就萌生想法自己手动制作一个jdk环境。

      a) 首先拉取centos镜像并启动容器

    [root@docker1 ~]# docker pull centos:centos7.4.1708
    [root@docker1 ~]# docker run --name jdk -itd centos:centos7.4.1708
    

      b) 上传jdk包到宿主机并解压,然后拷贝到容器内部

    [root@docker1 src]# pwd
    /usr/local/src
    [root@docker1 src]# tar xf jdk-8u201-linux-x64.tar.gz
    [root@docker1 src]# docker cp -a /usr/local/src/jdk1.8.0_201/ jdk:/usr/local
    

      c) 登入docker配置jdk

    [root@docker1 src]# docker exec -it jdk /bin/bash
    [root@cc8aaa0096bf /]# ln -s /usr/local/jdk1.8.0_201/bin/java /usr/bin/java
    [root@cc8aaa0096bf /]# echo -e 'export JAVA_HOME=/usr/local/jdk
    export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
    export PATH=$JAVA_HOME/bin:$PATH' >>/etc/profile
    [root@cc8aaa0096bf /]# source /etc/profile
    

      d) 然后以现在的docker容器commit一个jdk基础镜像出来。新的名字以仓库名的格式

    [root@docker1 src]# docker commit -m 'install jdk' -a 'hamerle' jdk hamerle/centos7.4:jdk
    [root@docker1 src]# docker images
    REPOSITORY          TAG                 IMAGE ID            CREATED              SIZE
    hamerle/centos7.4   jdk                 23a3a5d00138        About a minute ago   593MB
    

    三、镜像分享

    1. 镜像分享至docker hub

      • 注册hub.docker.com的账号
      • 点击"Repositories"菜单,然后点击"Create Repository +"来创建一个仓库,创建完成后浏览器的窗口不要关闭
    * 创建完仓库,就可以把上面制作的httpd镜像推上去了。当然,推之前需要先进行登录验证 ``` [root@docker1 ~]# docker login --help Usage: docker login [OPTIONS] [SERVER] # 从上面命令帮助可以看出,登录是要跟server地址的,但是默认登录就是docker hub,所以不用加server地址 [root@docker1 ~]# docker login -u hamerle Password: Login Succeeded # 验证成功,开始进行push操作。此处我加了tag,如果不加tag,就是将此镜像的所有版本都push上去。 [root@docker1 ~]# docker push hamerle/httpd:v1 ``` * push完成后,回到浏览器docker hub的窗口,刷新就可以看到tag的位置已经有push的镜像了
    2. 镜像分享至阿里云
    * 首先注册阿里云的账号
    * 点击"控制台"菜单,然后上面的搜索框搜索"容器镜像服务 控制台",首次使用需要同意开通容器镜像服务,然后点击"创建镜像仓库",使用命名空间(也就是你的用户名),创建过程还需要创建registry的密码,创建完成后浏览器窗口不要关闭。
    
    * 创建完成后,点击"管理"就可以看到操作指南了。首页也是登录验证,注意:阿里云的registry的密码和阿里云登录密码不是一个。 ``` [root@docker1 ~]# docker logout [root@docker1 ~]# docker login --username=hamerle registry.cn-shanghai.aliyuncs.com Password: Login Succeeded # 验证完成后,需要以阿里云的访问路径及仓库名称重新打一个tag才能进行后续的push操作。 [root@docker1 ~]# docker tag hamerle/httpd:v1 registry.cn-shanghai.aliyuncs.com/hamerle/httpd:v2 [root@docker1 ~]# docker images REPOSITORY TAG IMAGE ID CREATED SIZE hamerle/httpd v1 099c89327481 2 hours ago 1.2MB registry.cn-shanghai.aliyuncs.com/hamerle/httpd v2 099c89327481 2 hours ago 1.2MB busybox latest 64f5d945efcc 3 weeks ago 1.2MB [root@docker1 ~]# docker push registry.cn-shanghai.aliyuncs.com/hamerle/httpd:v2 ``` * push完成之后,还是在"管理"的界面,点击"镜像版本",就可以看到push上去的镜像信息。

    四、镜像导入导出

    # 这就以上面制作的hamerle/httpd:v1和v2为例,打包在一起导出供docker2使用
    [root@docker1 ~]# docker save -o httpd_images.gz hamerle/httpd:v1 registry.cn-shanghai.aliyuncs.com/hamerle/httpd:v2
        # -o:导出到某个文件。
    [root@docker1 ~]# ll httpd_images.gz 
    -rw------- 1 root root 1432576 Jun 10 13:42 httpd_images.gz
    # 将images拷贝到docker2上面,然后导入使用
    [root@docker1 ~]# scp httpd_images.gz 10.0.0.12:/root
    [root@docker2 ~]# ll httpd_images.gz 
    -rw------- 1 root root 1432576 Jun 10 13:52 httpd_images.gz
    [root@docker2 ~]# docker load -i httpd_images.gz
        # 从某个文件导入
    [root@docker2 ~]# docker images
    REPOSITORY                                        TAG                 IMAGE ID            CREATED             SIZE
    hamerle/httpd                                     v1                  099c89327481        4 days ago          1.2MB
    registry.cn-shanghai.aliyuncs.com/hamerle/httpd   v2                  099c89327481        4 days ago          1.2MB
    


    写作不易,转载请注明出处,谢谢~~

  • 相关阅读:
    java 应用使用jfr+sjk 生成应用火焰图
    使用btrace 分析java 应用
    vigil监控以及webhook使用
    honest-profiler+hprof2flamegraph 基础的扩展
    honest-profiler+hprof2flamegraph 查看java 应用火焰图信息
    Quark 基于electron 的跨平台应用开发ide
    nodejs 应用火焰图简单分析
    docker 中试用jfr
    使用foreman 管理基于Procfile 的应用
    xfs validation inode faild 问题解决
  • 原文地址:https://www.cnblogs.com/ccbloom/p/10979440.html
Copyright © 2011-2022 走看看