Docker

142 阅读3分钟

什么是Docker

Docker 是一种容器化平台和工具,用于构建、部署和运行应用程序和服务。它的主要目标是简化应用程序的部署和管理,提供一种轻量级、可移植、可扩展的容器化解决方案

  • 可移植:能指定运行环境,如操作系统(windows/mac/linux),node版本等等。因此项目能方便的跨平台部署。
  • 隔离:docker中的镜像运行在docker的容器内,与宿主机几乎完全隔离,容器内的环境与运行时产生的报错不会影响宿主机。但并不是完全隔离,如容器占用cpu过高等,或容器占用磁盘空间较大等等也会影响宿主机。
  • 安全性: Docker 提供了一系列安全性功能,包括容器隔离、命名空间、安全策略等,以保护容器内的应用程序和数据。

docker中的一些基本概念

  1. 镜像(Image)

    • 镜像一般由Dockerfile定义,也可以从DockerHub或其他镜像仓库中获取。一般是与部署的代码相关的不可变的容器模版,包含了应用程序和其依赖的文件系统快照、运行时环境和启动命令。
    • 创建镜像命令行示例:进入到包含dockerfile文件的文件夹中,运行
    docker build --build-arg resourceDir=${RESOURCE_DIR} -t myApp:1.0 .
    

    上述命令意思是,以当前目录(最后的.)创建容器名为myApp:1.0的容器,并为dockerfile传入变量resourceDir。该变量可以在dockerfile中使用,如在dockerfile中输入COPY ${resourceDir} .

    • 如果要以远程仓库创建镜像,则运行,即讲最后的.替换成仓库地址
    docker build -t myapp:1.0 https://github.com/myuser/myapp.git/xxxx
    

    官方build指令文档

  2. 容器(container)

    • 是镜像的运行实例,可以理解可快速创建的虚拟机,与宿主机数据隔离,拥有自己的文件系统、网络和进程空间。
  3. Dockerfile

    • Dockerfile 是一个文本文件,包含了一系列指令,用于定义如何构建一个 Docker 镜像。
    • Dockerfile 包括基础镜像选择、应用程序代码复制、依赖安装、环境配置等。
    • 改文件的一些常用指令
      • ARGS 用于初始化一些命令,是唯一能写在FROM之前的指令,用法如:
          ARG NODE_VERSION=19.5.0
          FROM node:${NODE_VERSION}-alpine
        
      • FROM 用于确定镜像的基本环境,如node/python/nginx版本、操作系统等,也可以用于指定镜像。一个Dockerfile的开头只能是ARGS或者FROM。每一个FROM都意味着一个构建阶段,可以在一个文件里输入多个阶段
        FROM [--platform=<platform>] <image> [AS <name>]
          # 指定node版本
          FROM node:14-alpine as builder
          
          # 指定nginx版本
          FROM nginx:1.21-alpine
            
          # 使用自定义的基础镜像,该镜像包含了 Node.js 14 和 Nginx 1.21
          FROM my-custom-image:latest as builder
      
      • ENV 用于设置环境变量,比如常见的NODE_ENV:ENV NODE_ENV production。在前端项目的dockerfile中,ENV的变量与package.json中通过cross-env设置的变量的一样的。当然,只有同名时是一样的,因为Dockerfileenv本身是针对容器,cross-env是针对node程序。如:

        // package.json
        {
            "scripts":{
                "start":"cross-env MY_NAME=mgh webpack-dev-server"
             }
        }
        
        // Dockerfile
        ...
        ENV MY_NAME=mgh
        
      • RUN 通常用于执行一些在镜像构建期间必要的操作,比如安装软件包、执行配置命令、下载文件等。这些操作在镜像构建时只执行一次。例如前端中,打包一个dist一般是构建镜像的过程,可以在RUN中执行node模块安装等步骤 除此之外,RUN命令还提供了其他选项

        • -mount
        • -network
        • -security
      • CMDCMD在镜像构建时不执行任何操作,但在构建容器时执行。例如,前端中打包一个dist文件夹是一个构建镜像的过程,这段时间内的指令应该用RUN;构建dist后部署配置nginx类似于利用镜像生成容器的过程,配置nginx需要用CMD。另外,如果有多个CMD指令,只有最后一个会生效。

      • EXPOSE 用于指定镜像对外暴露的端口。

        • 可以指定端口与暴露的协议(TCP/UDP),默认是TCP

        • 下面例子中,容器暴露了端口3000,而宿主机通过端口1234访问容器内的内容。即在宿主机通过localhost:1234访问容器内部的localhost:3000

      // 这里的3000端口,其实就是npm依赖serve的默认端口
      ...
      EXPOSE 3000
      // EXPOSE 3000/tcp 与上面一样的效果
      ...
      # Start the app using serve command
      CMD [ "serve", "-s", "build" ]
      
      在通过镜像生成容器时,可以通过-p参数制定宿主机的访问接口
      docker run my-images -p 1234:3000

harbor与rancher

harbor

类似于dockerHub,是一个用于存储和管理镜像image的仓库。
部署项目的时候,可以将本地文件打包成镜像,然后将其push到私有的harbor(或者dockerHub中)

实际项目中,可以编写build_image.sh,用于生成镜像和推送镜像

目录结构如下

.
├── Dockerfile
└── build_image.sh

build_image.sh脚本

#!/usr/bin/env bash

set -e # 有错误就立即终止
HARBOR_REGISTRY='harbor-registry.xxxxx.com/tetris' # harbor仓库地址
service=editor-front
if [[ $# -lt 1 ]]; then
    mode=test
else
    mode=$1
fi

tag=`git rev-parse --short HEAD` # 拿git commitId
cur_dir=`dirname $0` # 当前目录
# 打印信息,即将构建的镜像名
echo building image ${HARBOR_REGISTRY}/${service}: "\x1b[31;42m${tag}\x1b[m" 
# 用指定的dockerfile生成镜像,并制定镜像名。
docker build --progress=plain -t ${HARBOR_REGISTRY}/${service}:${tag} -f ${cur_dir}/Dockerfile ${cur_dir}/.. --build-arg mode=${mode} 
# 推送镜像到harbor仓库
docker push ${HARBOR_REGISTRY}/${service}:${tag} 

Dockerfile内容,这里已经打包出了一个dist文件夹,dockerfile将这个dist文件夹内容打包成镜像,并通过http-server启动本地服务

# 注意这里的`--platform=linux/amd64`,在rancher部署时,发现苹果芯片打包出来会报错,因此额外指定了platform
FROM --platform=linux/amd64 node:16.20-alpine as run
RUN npm config set registry https://nexus3.xxxx.com/repository/npm-all/ \
    && npm install --global http-server

WORKDIR /
COPY /dist .
CMD ["http-server", "-d false", "-s"]

最终,能在本地获得一个镜像,并在远端harbor仓库看到该镜像

image.png

image.png

如果要在本地运行该镜像,可以执行命令

#这里的-p用于指定本地端口和容器端口映射。http-server启动的服务默认是8080端口
#这时本地访问localhost:5678就能访问部署的内容了
docker run -p 5678:8080 harbor-registry.xxxxx.com/tetris/editor-front:c8c6d62

image.png

rancher

Rancher是一个开源的容器管理平台,用于管理容器化的应用程序和基础设施
一般与harbor搭配使用,在新建的任务中,右下角的Image可以修改用于部署的镜像地址

image.png

未完待续...