美文网首页
Docker 入门

Docker 入门

作者: 四相物联前端团队 | 来源:发表于2021-11-17 16:10 被阅读0次

    引言

    假如我们没有虚拟机,该怎么样让别人运行我们的项目,初学的时候,我们往往是打包代码,发给对方,然后让对方安装相应的环境,比如node、数据库,要是配置不同,项目很有可能无法运行,还会报错,如果多个人想要运行这份代码,那还得多次安装配置环境。

    当学习完虚拟机之后,我们可以直接发个链接给别人就可以查看,就得开始部署在服务器上。然后去买了服务器,学了linux,去服务器上搭建环境,下载node、mongogb,安装各种项目启动需要的东西,中途可能还安装不成功,然后XShell上传打包好的代码,然后解压运行,测试是否运行正常,ok,可以链接发给别人看了。

    但是总归是有些不方便吧,毕竟安装虚拟机配置环境,运行起来之后还特别吃内存,占用资源直接一半。

    直到学习docker之后,发现这些问题突然就可以得到解决了,那接下来让我们看看docker到底是什么,解决了什么样的问题,怎么操作吧


    1.环境配置的问题

    软件开发的时候,环境配置不同,很可能造成项目无法运行,每次其他人运行都需要配置相应的环境,

    从根本上解决问题:软件带环境安装,安装的时候把原始环境一模一样的复制过去

    解决方案:

    (1)虚拟机

    带环境安装的一种解决办法,可以在windows上运行linux系统,通过虚拟机可以还原软件原始环境

    优点:

    • 相当于真实系统,但是对于底层又是一个普通文件,可以随时删除,方便删除

    缺点:

    • 资源占用多:在物理服务器创建一台虚拟机时,便需要虚拟出一套硬件并在上面运行完整的操作系统

    • 冗余步骤多:必须有完整的操作过程,比如登录

    • 启动慢

    (2)Linux容器

    Linux 容器(Linux Containers,缩写为 LXC):Linux不是模拟的完整的操作系统,而是对进程进行隔离,在正常进程的外面套了一个保护层形成容器。对于容器里面的进程来说,它接触到的各种资源都是虚拟的,从而实现与底层系统的隔离

    优势【相对于虚拟机】:

    • 启动快

    • 用资源少

    • 体积小:只是一个进程,而不是完整的操作系统

    类似一个轻量级的虚拟机,但是对比于虚拟机,优点很多,虚拟机和linux都是带环境安装的解决办法,而Docker就是在linux容器的基础上发展的。

    2.Docker是什么

    Docker 基于Linux 容器的一种封装,提供简单易用的容器使用接口

    Docker 将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。就不用担心环境问题了,容器还可以进行版本管理、复制修改等。

    常常我们会觉得Docker是一个小型的虚拟机,但是其实本质不同,Docker不是在宿主机上虚拟出一套硬件后再虚拟出一个操作系统,而是让 Docker 容器里面的进程直接运行在宿主机上(Docker 会做文件、网络等的隔离),被隔离的进场也就是容器,可以完全独立于宿主机的进程

    (1)Docker优点

    (1)提供一次性的环境:本地测试他人软件,持续集成的时候提供单元测试和构建的环境

    (2)配置简化:将环境和配置放入代码然后部署,同样的Docker配置能够在各种环境中使用

    (3)快速部署:适用于持续集成和持续交付(CI/CD)

    (2)docker容器和虚拟机的对比

    对比 docker容器 虚拟机
    启动时间 秒级 分钟级
    系统支持量 上千个 一般只能几十个
    硬盘占用 KB-MB GB-TB
    隔离级别 进程级 操作系统级

    3.Docker组成

    (1)Docker架构

    Docker使用C/S架构

    客户端:Docker客户端与 Docker守护进程对话,,比如使用docker run等命令

    服务端:负责构建、运行和分发 Docker 容器的繁重工

    • Client:客户端是是Docker用户和Docker交互的方式,比如那些执行命令

    • DOCKER_HOST:用来监听客户端请求命令管理Docker对象

    • Registry:镜像仓库存储Docker镜像,类似代码仓库github,比如Docker Hub (官方的),本文后续使用Harbor(私有的)

      image-20211109145330004.png

    (2)Docker对象:

    Docker管理的对象包含镜像、容器、网络、数据卷,仅介绍镜像和容器,是在操作中常用的

    • Image(镜像):Docker 把应用程序及其依赖[提供运行项目的时候所需的程序,库,资源,配置等],打包在 image 文件里面。只有通过image,才能生成 Docker 容器。image 文件可以看作是容器的模板。Docker 根据 image 文件生成容器的实例。同一个 image 文件,可以生成多个同时运行的容器实例。

    • Container(容器):容器 = 镜像 (dockerfile每个命令生成一层,但是都是只读层) + 读写层(可读可写的最后一层包含容器),容器可以被创建、启动、停止、删除、暂停等。

    4.Docker的使用教程

    (1)安装Docker

    菜鸟教程中有各个平台安装Docker的方法,本文将在windows上进行安装操作

    windows docker安装【win10上安装需要查看电脑属性,需要符合64位的win10专业版,企业版,或者教育版构建在15063或者更高版本】

    安装之后报错:Docker. ApiServices. WSL2. WslKernelUpdateNotIns talledException的异常


    image-20211018143911623.png

    下载wsl路径及办法

    检查windows版本之后安装wsl,重启电脑之后报错消失

    cmd里面运行docker version或者docker info查看是否安装成功

    通常使用cli命令行来操作Docker,就像git一样

    // 打印docker版本
    docker version
    

    (2)运行Docker测试

    创建文件夹 hello-docker,创建index.html文件,随便写点儿什么

    再创建Dockerfile文件,复制以内容:

     # 基于哪个镜像
    FROM nginx
     # 将宿主机中的./index.html文件复制进容器里的/html/index.html
    COPY ./index.html html/index.html
     # 容器对外暴露80端口
    EXPOSE 80
    

    然后打包镜像:

    cd hello-docker/ // 进入刚刚的目录 以管理员身份打开PowerShell
    docker image build ./ -t hello-docker:1.0.0 // 打包镜像 基于路径./(当前路径)打包一个镜像,镜像的名字是hello-docker,版本号是1.0.0。该命令会自动寻找Dockerfile来打包出一个镜像
    

    然后查看本机已有镜像【基础命令可以在cmd里面执行,也可以直接打开安装好的docker desktop 直接查看镜像容器等情况】:

    docker images
    docker images ls
    

    删除本机已有的镜像:

    docker rmi [imageId] // 可删除
    

    运行容器:

    docker container create -p 5000:80 hello-docker:1.0.0 // 根据镜像创建一个容器并返回容器id 端口是本机暴露5000端口
    docker container start xxx // xxx 为上一条命令运行得到的结果 ## 启动一个创建好的容器
    

    查看容器:

    docker container ls//查看正在运行的容器
    docker ps //查看正在运行的容器
    docker ps -a // 查看所有的容器,包括停止运行的容器
    

    最后访问http://localhost:5000/就可以查看到index.html里面的内容

    更多创建容器的命令请查看官方文档https://docs.docker.com/engine/reference/commandline/create/

    (3)下拉官方镜像运行

    让我们继续进行Docker的使用

    我们可以直接使用Docker 的官方仓库里面的东西,比如一个hello world 案例,直接在某个文件夹中进行下面的操作

    docker image pull library/hello-world // 将 image 文件从仓库抓取到本地。
    docker image ls // 看到所有的image文件
    docker container run hello-world // 运行image生成的运行的容器实例
    docker container kill [containID] //终止容器 有的是可以自动终止的
    
    docker container rm [containerID] //  删除容器
    docker container ls --all //列出本机所有容器,包括终止运行的容器
    

    学习如上操作之后,Docker的基本操作都上手了一遍,从上面的简单例子中知道要image文件之后,需要生成image文件就需要Dockerfile 文件,是一个包含用于组合映像的命令的文本文档,用来配置image的。

    下面进行Dockerfile文件内容的编写和学习,学完之后就可以进行自己项目的镜像,提供给其他人使用了。

    (4)Dockerfile文件学习

    Docker 根据 该文件生成二进制的 image 文件。

    • 基本结构

    基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令,’#’ 为 Dockerfile 中的注释

    • 常用文件说明

    FROM:指定基础镜像,必须是第一个命令

    // FROM <image>:<tag>
    // FROM <image>@<digest>
    // FROM <image>
    FROM mysql:5.6
    // tag或digest是可选的,不使用这两个值时,会使用latest版本的基础镜像
    

    MAINTAINER:指定作者

     MAINTAINER <name>
     // MAINTAINER sorex@163.com
    

    RUN:构建镜像时执行的命令

    // RUN 《command》
    
    

    ADD:将本地文件添加到容器中

    // ADD 《src》 《destination》
    ADD test /absoluteDir/    # 添加 "test" 到 /absoluteDir/
    

    COPY:复制命令 类似ADD

    CMD:提供了容器默认的执行命令,构建容器后调用,也就是在容器启动时才进行调用。多个CMD就只会执行最后一个,

    CMD echo "This is a test." | wc -
    CMD ["/usr/bin/wc","--help"]
    // CMD ["executable","param1","param2"] (执行可执行文件,优先)
    // CMD ["param1","param2"] (设置了ENTRYPOINT,则直接调用ENTRYPOINT添加参数)
    // CMD command param1 param2 (执行shell内部命令)
    

    EXPOSE:指定容器在运行时监听的端口

    EXPOSE <port>;
    // EXPOSE 80;
    

    ENV:设置环境变量。它们使用键值对,增加运行程序的灵活性

    // ENV <key> <value>
    ENV LOG_LEVEL=debug
    ENV NODE_ENV=production
    

    USER:镜像正在运行时设置一个UID

    USER <uid>
    

    WORKDIR:相当于cd 进入文件夹

    // WORKDIR path
    WORKDIR /usr/local/hello
    

    (5)本地项目操作封装成docker

    本地项目使用主要技术如下

    1.Vue3.0+ts+element-plus构建前端页面
    2.koa+koa-router+ts构建后台服务
    

    新建忽略文件.dockerignore

    .git
    node_modules
    npm-debug.log
    

    由于docker是只能启动一个服务,所以把前后端合在一起,然后打包前端项目

    如果是单独的前端项目,则只需要直接进行打包之后新建一个文本文件 Dockerfile,按照上面的Dockerfile进行学习之后编写即可

    项目Dockerfile如下

    # Build environment 指定基础镜像
    FROM node:alpine
    
    # Copy packages 复制本地的代码
    COPY . .
    
    # run Monorepo 安装依赖
    RUN yarn install
    
    # run project 进入运行目录
    WORKDIR packages/back
    
    # 导出端口
    EXPOSE 3000
    
    # 运行命令
    CMD ["node","dist/index.js"]
    

    运行启动

    docker image build ./ -t filedemo:1.0.0
    docker container create -p 5000:3000 filedemo:1.0.0 //-p参数:容器的 3000 端口映射到本机的 5000 端口,访问时启动5000端口
    docker container start 容器id号
    

    直接访问ip:5000端口即可,现在在本机可以进行项目的自由访问了,但是如果别人需要使用,就需要上传仓库。

    5.Harbor镜像上传和下载操作

    虽然docker官方提供了公共的镜像仓库,但是出于安全和效率方面的考虑,将镜像上传私有仓库也是非常好的选择,比如Harbor

    下面将项目上传私有仓库

    (1)Harbor镜像上传

    账号登录

    // docker login ip地址
    docker login 192.168.0.7
    // 然后输入账号密码即可
    // or
    // docker login -u 账号名 -p 密码 仓库地址端口
    docker login -u xxx -p xxx 192.168.0.7
    // WARNING! Using --password via the CLI is insecure. Use --password-stdin.
    // Error response from daemon: Get "https://192.168.0.7/v2/": dial tcp 192.168.0.7:443: connect: connection refused
    
    // 如果登录失败,则是原因是因为仓库没有配置https 的问题
    // 去修改docker里面的daemon.json
      "insecure-registries": [
        "192.168.0.7"// 加上远程的仓库地址
      ],
    // 然后重启docker
    

    给项目打tag

    //查看image
    docker images
    
    // docker tag 本地镜像名字:标签名字 仓库tag名字
    docker tag filedemo:1.0.1 192.168.0.7/node/fileupload:v1.0.1
    

    上传仓库

    docker push 192.168.0.7/node/fileupload:v1.0.1
    

    (2)Harbor镜像下载操作

    依旧登录进去

    然后拉取镜像,和代码仓库命令类似

    docker pull 192.168.0.7/node/fileupload:v1.0.1
    

    拉取后docker images查看是否拉取到本地

    直接创建容器并运行

    docker container create -p 3002:3000 192.168.0.7/node/fileupload:v1.0.1 # 根据镜像创建一个容器并返回容器id
    docker container start 前一步返回的ID # 运行容器
    

    访问localhost:3002即可

    (3)portainer基础使用教程

    portainer是docker的图形化管理界面,可以把仓库里面的docker放在上面进行管理,就不需要使用命令进行启动这些操作,图形化界面操作会更简单容易。

    拉取私有仓库的images

    image-20211109164732320.png

    创建容器,选择侧边的containers->add container


    image-20211109165310926.png

    如上所示,就建好了容器管理了私有仓库的镜像,然后就可以根据根据自己设置的端口进行访问,别人也可以直接访问,可以形成和虚拟机一样的效果,但是操作更简单方便。

    (4)Docker容器的重启策略

    16347858307850.png

    Docker容器的重启策略是面向生产环境的启动策略,开发过程中可以忽略。

    never,默认策略,在容器退出时不重启容器 on-failure,在容器非正常退出时(退出状态非0),才会重启容器 on-failure:3,在容器非正常退出时重启容器,最多重启3次 always,在容器退出时总是重启容器 unless-stopped,在容器退出时总是重启容器,但是不考虑在Docker守护进程启动时就已经停止了的容器

    6.Docker镜像的优化

    由于构建镜像之后,发现镜像比较大,可能有几百MB或者有的上TB,那其实应该进行一个优化的,让这些镜像尽量占用少的空间,因为本来容器设计初衷就是为了快速和小巧独立,利于一次构建,多处运行

    (1)命令合在一起使用&&等操作符,减少层

    docker镜像是分层构建的,Dockerfile每条指令都会新建一层作为只读层,如果你新建容器,就会在最顶部添加读写层,每新增一层都会增加镜像的尺寸,所以可以减少命令的条数,把运行命令合在一起

     RUN cd /home/app && npm install --production
    

    (2)使用小的基础镜像

    可以使用Alpine作为基础镜像,一般基础镜像有Ubuntu、CentOs、Debian、Alpine,下面是一般的基础镜像的大小

    REPOSITORY  TAG       IMAGE ID             SIZE
    centos      7         49f7960eb7e4         200MB
    debian      latest    0af60a5c6dd0         101MB
    ubuntu      18.04     47b19964fb50         88.1MB
    ubuntu      latest    47b19964fb50         88.1MB
    alpine      3.8       3f53bb00af94         4.41MB
    

    一看alpine就小得多,可以减少大部分的体积

    (3)依赖的话需要打包的只需要安装到生产环境里面

    需要的运行时的依赖,放到生产环境中,开发时候的依赖,放到开发环境中,不必要放到生产环境中

    (4)善用.dockerignore文件

    .dockerignore文件,是用来声明不会被镜像包括的文件和目录。这有助于避免将不必要的大文件或敏感文件打包进去,并避免将它们添加到公共镜像。

    7.参考资料

    1.《Docker run reference》

    2.阮一峰Docker入门教程

    3.Linux容器

    4.Docker官网

    相关文章

      网友评论

          本文标题:Docker 入门

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