美文网首页
Docker基础

Docker基础

作者: 烦远远 | 来源:发表于2021-07-30 17:01 被阅读0次

    1 docker简介

            在项目开发中,为了部署我们的项⽬,需要配置各种各样的依赖环境,容易出错,不易管理,还要搞⼀堆各式各样的配置,⼀个地⽅不对,项⽬就有可能瘫痪。

    Docker 属于 Linux 容器的⼀种封装,提供简单易⽤的容器使⽤接⼝。

    Docker 将应用程序与该程序的依赖,打包在⼀个⽂件⾥⾯。运⾏这个文件,就会⽣成⼀个虚拟容器。程序在这个虚拟容器⾥运行,就好像在真实的物理机上运行⼀样。有了 Docker,就不⽤担心环境问题。

    Doker可以隔离应用级别:⽐如我写了两个应⽤(网站),这两个应⽤部署在同⼀台服务器上,如果⼀个应⽤出现了问

    题,导致CPU占100%,那另⼀个应⽤也会受到关联。而dockr在应用隔离的时候将他的资源已经分配好了,应用之间解耦,不会相互影响。

    docker应用隔离

    2 docker安装(linux)

            centos7安装docker: yum install docker

            centos7启动docker: systemctl start(stop) docker

            (开机启动):systemctl enable docker

            查看docker版本: docker version

    3 docker的重要概念

            docker中主要有这么三个东西:Images(镜像)、Containers(容器)、Repository(仓库)。

    3.1 Images(镜像)

            image其实就是⼀个⽂件系统,它的存储是一层一层往上叠起来的。它与宿主机的内核⼀起为程序提供⼀个虚拟的linux环境。它类似于虚拟机中使⽤到的镜像,由于任何应⽤程序都需要有它⾃⼰的运⾏环境,Image就是⽤来提供所需运⾏环境的⼀个模板。Image本身是只读的,可以通过Dockerfifile定义,也可以到Repository中取拉取。

    3.2 Container(容器)

            Container是Docker提供的⼀个抽象层,它就像⼀个轻量级的沙盒,其中包含了⼀个极简的Linux系统环境与运⾏在其中的应⽤程序。Container是Image的运⾏实例(类似Java的类和对象)。(Image本身是只读的,Container启动时,Docker会在Image的上层创建⼀个可写层,任何在Container中的修改都不会影响到Image,如果想要在Image保存Container中的修改,Docker采⽤了基于Container⽣成新的Image层的策略),Docker引擎利⽤Container来操作并隔离每个应⽤(也就是说,每个容器中的应⽤都是互相独⽴的)。也就是运⾏Images的地⽅。

    3.3 Repository(仓库)

            Repository:存放Images的仓库。 

            官⽅仓库: https://hub.docker.com/ https://hub.docker.com/search?image_fifilter=offiffifficial&type=image 

            举个例子,小明写了⼀个erp系统,该系统的技术栈⾮常⼴,需要依赖于各种开源库和 中间件。如果按照纯⼿动的部署⽅式,⼩明需要安装各种开源软件,还需要写好每个开源软件的配置⽂件。如果只是部署⼀次,这点时间开销还是可以接受的,但如果⼩明每隔⼏天就需要 换个服务器去部署他的程序,那么这些繁琐的重复⼯作⽆疑是会令⼈发狂的。这时候, Docker的⽤处就派上场了,小明只需要根据应⽤程序的部署步骤编写⼀份Dockerfifile⽂件(将 安装、配置等操作交由Docker⾃动化处理),然后构建并发布他的镜像,这样不管在什么机器上小明都只需要拉取他需要的镜像,然后就可以直接部署运行了。

    4 Image

    4.1 操作镜像的基本命令

    下载镜像 :docker pull hello-world(镜像名是hello-world)。

    下载镜像

    运行镜像:docker run hello-word (运行镜像是在Container中运行的)。

    运行镜像

    查看镜像:docker image ls 

    查看镜像

        #REPOSITORY image名称

        #TAG 版本号

        #IMAGE ID image的id

        #CREATED 创建时间

        #SIZE image的大小

    删除镜像:docker rmi -f  镜像id

        #删除镜像 -f 强制删除

    删除镜像

    4.2 创建自定义镜像

    创建一个hello-docker目录

    在⾥⾯创建⼀个hello.c⽂件

    编译hello.c (需要安装依赖gcc 和glibc-static)会⽣成⼀个hello执⾏⽂件

    gcc -static hello.c -o hello

    应⽤Dockerfifile将可执⾏⽂件hello 打包成⼀个image

    现在在hello-docker⽂件夹外⾯新建⼀个Dockerfile并编写

    目录结构

    Dockerfile编写

    dockerFile

    打包镜像:docker build -t maguoq/hello .

    maguoq为Docker Hub的账号ID,没有的可以注册⼀下https://hub.docker.com/

    hello为image的名字,全名由账号和image名字购成。

    .表示Dockerfifile所在的⽬录(根据⾃⼰情况填写eg:/data/)

    构建镜像 带有版本的镜像

    查看并运行镜像

    运行镜像 运行带有版本的镜像

    5 container

            想要运⾏⼀个Image,就必须有⼀个container,image就好⽐jave中的类,container就像java中image类所创建出的对象。container通过image创建(复制的过程);然后再image基础上再加⼀层,可读可写成(image是只读的)。最终运⾏的是container。

    Container

    5.1 container操作

    #列出本地正在运⾏的container

    docker container ls

    #列出所有的container 包括运⾏完退出的

    docker container ls -a

    docker container ls -aq (所有container的ID)

    docker container ls -f "status=exited" -q (所有退出的container ID)

    #构建运⾏容器

    doucker run 名称:版本号(⽆默认最新版);

    docker run 会构建container然后执⾏Dockerfifile中的命令

    docker run -it [镜像名字] (交互式运⾏,可以进⼊container的读写层,然后操作)

    docker run -d [镜像名字] (后台运⾏)

    #按照ID删除container

    docker container rm CONTAINERID

    docker container rm $(docker container ls -aq ) #删所有

    docker container rm $(docker container ls -f "status=exited" -q) #删退出的

    #杀掉运⾏中的container

    docker container kill CONTAINERID

    #将⼀个container 改动后变成⼀个新的image

    docker container commit [container的名字] [(docker HupID号)/新的名字:版本号]

    将一个container构建成一个新的manage

    docker history [imageID] (查看⼀个image的构建历史)

    5.2 通过dockerfile构建出一个新的image

    删除原来的 dockerfile,新建一个docker,引用之前的镜像。编写新的dockerfile增加一些操作。

    如果引用的镜像没有下载下来的话,在build的时候会去自动下载镜像。然后构建出我们的新的镜像。

    引用centos 的镜像的新的镜像

    构建镜像:docker build -t 镜像名称 . (.指的是dockerfile的位置 当前文件夹)

    构建镜像 新的镜像

    交互运行镜像:docker run -it maguoq/centos-new 

    我们可以进入镜像的container 的可读可写层。

    运行镜像

    退出container

    退出container

    6 Dockerfile构建镜像实践

    6.1 dockerfile 语法

    FROM:从那个image基础上构建我们的image,空则为scratch

    eg:FROM centos:7.4(版本号)

    备注:尽量使⽤官⽅的image作为base,⾮官⽅的image为(id号/名称)

    LABEL:注释说明, 指令会添加元数据到镜像。

    LABEL <key>=<value> <key>=<value> <key>=<value> ...

    编写dockerfile添加LABEL 

    添加LABEL

    构建镜像:docker build -t maguoq/centos-new .

    查看镜像:docker inspect

    VOLUME:数据持久化地址RUN: 执⾏命名,多条命令⽤ && 连接,如果⼀⾏放不下⽤ \ 换⾏

    eg: RUN yum update && yum install redis \

    && yum install -y vim

    WORKDIR:指定当前⼯作⽬录

    eg: WORKDIR /test #没有回⾃动创建

    WORKDIR zyz #进⼊ /test/zyz

    ADD:将本地⽂件添加到image,ADD 命令会⾃动解压缩⽂件,解压你导⼊的.gz包

    eg: ADD hello / #添加到根⽬录

    WORKDIR /test

    ADD hello zyz/ #添加到/test/zyz下⾯

    COPY:通ADD功能差不多,不能⾃动解压⽂件,优先级低于ADD

    ENV:定义常量

    eg:ENV NAME ZYZ

    RUM echo ${NAME}

    6.2 RUN、CMD 和 ENTRYPOINT

    1. RUN 执行命令并创建新的镜像层,RUN 经常用于安装软件包。(还记得我们在centos中安装了⼀个Redis嘛?在原有的基础上加了⼀层Redis)。

    2. CMD 设置容器启动后默认执行的命令及其参数,但 CMD 能够被 docker run 后面跟的命令行参数替换。 基于此,CMD往往被设置为默认执⾏的命令。

    3. ENTRYPOINT 配置容器启动时运行的命令,一定都会被执行。

    6.3 Dockerfile的 Shell 和 Exec 格式

    Shell 格式

    <instruction> <command>

    例如:

    ENV NAME python

    RUN apt-get install python3

    CMD echo "Hello $NAME "

    ENTRYPOINT echo "Hello world"

    Exec 格式

    <instruction> ["executable", "param1", "param2", ...]

    例如:

    RUN ["apt-get ", "install", "python3"]

    CMD ["/bin/echo", "Hello world"]

    ENTRYPOINT ["/bin/echo", "Hello world"]

    ENV NAME python

    ENTRYPOINT echo "Hello $NAME" #name并没有被替换成python

    ENTRYPOINT ["/bin/sh", "-c", "echo Hello, $NAME"] #name被替换成python

    6.4 RUM CMD ENTRYPOINT区别

    RUN:RUN 指令通常用于安装应用和软件包。

    RUN 在当前镜像的顶部执行命令,并通过创建新的镜像层。Dockerfile 中常常包含多个RUN 指令。

    RUN 有两种格式:

        1.Shell 格式:RUN

        2.exec 格式:RUN ["executable", "param1", "param2"]

    CMD:指令允许⽤户指定容器的默认执⾏的命令。

    此命令会在容器启动且 docker run 没有指定其他命令时运⾏。

    如果 docker run 指定了其他命令,CMD 指定的默认命令将被忽略。

    如果 Dockerfile 中有多个 CMD 指令,只有最后一个 CMD 有效。

    CMD 有三种格式:

        1.Exec 格式:CMD ["executable","param1","param2"]

        2.CMD ["param1","param2"] 为 ENTRYPOINT 提供额外的参数,此时 ENTRYPOINT必须使用 Exec 格式。

        3.Shell 格式:CMD command param1 param2

    例子:

    CMD echo "Hello world"

    docker run -it [image]

    输出Hello world

    docker run -it [image] /bin/bash

    CMD被忽略掉,执⾏bash命令

    ENTRYPOINT 指令可让容器以应⽤程序或者服务的形式运⾏。

    ENTRYPOINT 看上去与 CMD 很像,它们都可以指定要执⾏的命令及其参数。不同的地⽅在于 ENTRYPOINT 不会被忽略,⼀定会被执⾏,即使运⾏ docker run 时指定了其他命令。

    ENTRYPOINT 有两种格式:

        1.Exec 格式:ENTRYPOINT ["executable", "param1", "param2"] 这是 ENTRYPOINT的推荐格式。

        2.Shell 格式:ENTRYPOINT command param1 param2eg: ENTRYPOINT ["/bin/echo", "Hello"]

    CMD ["world"]

    docker run -it [image] #输出Hello world

    docker run -it [image] /bin/bash #CMD忽略 ENTRYPOINT 执⾏

    docker run -it [image] docker #输出 Hello docker

    eg:ENTRYPOINT ["java","-jar","hello-1.0-SNAPSHOT.jar"]

    CMD []

    最佳实践

    1. 使用 RUN 指令安装应用和软件包,构建镜像。

    2. 如果 Docker 镜像的用途是运行应用程序或服务,比如运行一个 MySQL,应该优先使用 Exec 格式的 ENTRYPOINT 指令。CMD 可为 ENTRYPOINT 提供额外的默认参数,同时可利用 docker run 命令行替换默认参数。

    3.如果想为容器设置默认的启动命令,可使用 CMD 指令。用户可在 docker run 命令行中替换此默认命令。

    7 镜像发布

    将自己的image发布到docker hub,可共他人下载使用,首先要注册docker hup账户。

    https://hub.docker.com/

    注意:⾃⼰创建的image 名称必须是 【dockerHupId/image名】

    1#登录docker

     docker login

     2#输入用户名和密码

     3#docker push [image名称:版本号]

     docker push maguoq/hello:latest

     #可以使用tag为镜像更名

    docker tag 名称 某个ID/名称

    8 更换docker的repository

    Docker Hup官网速度很慢,下载image速度很慢,这是候我们需要把docker的repository切换到国内的镜像仓库。

    登录阿⾥云在产品中⼼搜索【容器镜像服务】开启服务。按照提示操作即可。

    配置容器镜像

    将上面富文本编辑器里面的命令复制下来运行就配置完成了。然后用 docker info 查看镜像地址。

    docker info

    9 阿里云创建私有的镜像仓库

    1.登录阿里云控制台界面。搜索容器镜像服务,然后点击创建个人版实例。

    创建镜像

    操作镜像

    阿里云操作演示:

    #登录阿里云的镜像

    登录

    #推送镜像

    $ docker push registry.cn-hangzhou.aliyuncs.com/maguoq/test:[镜像版本号]

    相关文章

      网友评论

          本文标题:Docker基础

          本文链接:https://www.haomeiwen.com/subject/gwhgultx.html