美文网首页
Docker使用指南

Docker使用指南

作者: 吾等斩去红尘时 | 来源:发表于2022-05-07 14:04 被阅读0次

    开源应用容器引擎使用指南(Docker usage guide)

    概述

    Docker是一个用于开发、发布和运行应用程序的开放平台。Docker使您能够将应用程序与基础架构分离,以便您可以快速交付软件。使用Docker,您可以像管理应用程序一样管理基础架构。通过利用Docker的快速发布、测试和部署代码的方法,您可以显著减少编写代码和在生产环境中运行代码之间的延迟。

    官方网站

    名称 地址
    官方网站 https://www.docker.com/

    卸载程序

    如果你安装了旧版本的dockerdocker.iodocker-engine请先卸载它们

    sudo apt-get remove docker docker-engine docker.io containerd runc
    

    安装程序

    服务器上安装容器程序

    如果你是在ubuntu服务器上使用docker程序,请参照下面的步骤安装docker程序

    • 更新索引文件并安装相关依赖
    sudo apt-get update && sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common
    
    • 公开签名秘钥
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
    
    • 添加软件仓库
    echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
    
    • 更新索引文件并安装程序
    sudo apt-get update && sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
    

    验证容器程序是否安装成功

    如果你执行下面命令docker打印出客户端和服务端的版本信息说明docker已经安装成功

    sudo docker run version
    

    其它平台上安装容器程序

    如果你希望在windows或者macos下使用docker程序,请参照下面的链接安装docker程序

    系统 地址
    Windows https://docs.docker.com/desktop/windows/install/
    Mac https://docs.docker.com/desktop/mac/install/
    Linux https://docs.docker.com/engine/install/

    设置国内镜像加速源

    添加国内镜像加速源

    • 如果/etc/docker目录下daemon.json配置文件不存在,就创建一个daemon.json配置文件
    sudo nano /etc/docker/daemon.json
    

    /etc/docker/daemon.json

    {
      "registry-mirrors": ["https://registry.docker-cn.com"]
    }
    
    • 重启docker服务使其生效
    sudo systemctl restart docker.service
    

    验证国内镜像加速源是否添加成功

    如果在输出的信息中看到https://registry.docker-cn.com说明国内镜像加速源添加成功

    sudo docker info
    

    其它国内镜像加速源

    服务器 地址
    中国官方镜像 https://registry.docker-cn.com
    科大镜像 https://docker.mirrors.ustc.edu.cn
    网易镜像 https://hub-mirror.c.163.com
    腾讯镜像 https://mirror.ccs.tencentyun.com

    拉取多个镜像并在同一网络中通信运行容器

    通过拉取mongomongo-express镜像,并在创建的同一网络mongo-network中分别运行mongomongo-express容器,在下面步骤中实现了通过网页的形式来管理数据库

    拉取数据库镜像

    sudo docker pull mongo
    

    拉取数据库界面镜像

    sudo docker pull mongo-express
    

    为多个容器创建相互通信的网络

    sudo docker network create mongo-network
    

    运行数据库容器

    sudo docker run -d \
    -p 27017:27017 \
    --network mongo-network \
    --name mongo \
    -e MONGO_INITDB_ROOT_USERNAME=username \
    -e MONGO_INITDB_ROOT_PASSWORD=password \
    mongo
    

    运行数据库界面容器

    sudo docker run -d \
    -p 8081:8081 \
    --network mongo-network \
    --name mongo-express \
    -e ME_CONFIG_MONGODB_SERVER=mongo \
    -e ME_CONFIG_MONGODB_ADMINUSERNAME=username \
    -e ME_CONFIG_MONGODB_ADMINPASSWORD=password \
    mongo-express
    

    多容器部署 Docker-compose

    多容器部署docker-compose是以配置文件的形式来拉取多个镜像并在同一网络中通信运行容器,在下面步骤中同样实现了通过网页的形式来管理数据库,比上面直接拉取镜像再运行的方法更简单且更好管理

    安装软件

    sudo apt install -y docker-compose
    

    准备工作

    • 创建/home/mongo目录
    sudo mkdir -p /home/mongo
    
    • 进入/home/mongo目录
    cd /home/mongo
    

    编辑配置文件

    • /home/mongo目录中创建docker-compose.yaml配置文件
    sudo nano docker-compose.yaml
    

    /home/mongo/docker-compose.yaml

    # 版本信息
    version: '3'
    # 容器服务,包含多个容器
    services:
      # 容器一
      mongo:
        # 容器名称
        image: mongo
        # 端口[宿主机:容器]
        ports:
          - "27017:27017"
        # 环境变量
        environment:
          - MONGO_INITDB_ROOT_USERNAME=username
          - MONGO_INITDB_ROOT_PASSWORD=password
      # 容器二
      mongo-express:
        # 容器名称
        image: mongo-express
        # 端口[宿主机:容器]
        ports:
          - "8081:8081"
        # 环境变量
        environment:
          - ME_CONFIG_MONGODB_SERVER=mongo
          - ME_CONFIG_MONGODB_ADMINUSERNAME=username
          - ME_CONFIG_MONGODB_ADMINPASSWORD=password
    

    注意:在配置文件中我们并没有为mongomongo-express容器指定同一网络,它会自动创建默认的网络来进行容器间的通信和默认数据卷来持久化数据

    运行容器

    sudo docker-compose up -d
    

    停止容器

    sudo docker-compose down
    

    指令说明

    名称 地址
    官方指令说明 https://docs.docker.com/compose/compose-file/
    官方指令格式的版本说明 https://docs.docker.com/compose/compose-file/compose-versioning/
    指令 说明
    version 指定指令格式版本
    services 容器集合
    build 指定构建镜像的dockerfile配置文件
    image 指定镜像名称
    container_name 指定容器名称
    environment 设置环境变量
    env_file 通过配置文件设置环境变量
    ports 暴露端口给宿主机
    expose 暴露端口给连接服务且不暴露端口给宿主机
    labels 指定标签
    dns 自定义容器接口上的DNS服务器
    network_mode 设置容器的网络模式
    networks 指定网络名称
    volumes 指定数据卷挂载路径

    构建镜像 Dockerfile

    构建镜像dockerfile是以文本文件的形式来构建镜像,dockerfile文本文件中包含了构建镜像的指令和说明

    准备工作

    • 创建/home/helloworld目录
    sudo mkdir -p /home/helloworld
    
    • 进入/home/helloworld目录
    cd /home/helloworld
    

    编辑配置文件

    • /home/helloworld目录中创建helloworld.js程序文件
    sudo nano helloworld.js
    

    /home/helloworld/helloworld.js

    // 引入模块
    var http = require('http');
    // 网页服务
    http.createServer(function (request, response) {
      response.writeHead(200, {'Content-Type': 'text/plain'});
      response.end('HelloWorld\n');
    }).listen(3000);
    // 打印输出
    console.log('Server running at http://127.0.0.1:3000/');
    
    • /home/helloworld目录中创建dockerfile配置文件
    sudo nano dockerfile
    

    /home/helloworld/dockerfile

    # 基础镜像
    FROM node:17-alpine
    # 复制本地文件到镜像中
    ADD . /helloworld
    # 设置工作目录
    WORKDIR /helloworld
    # 运行命令,通常用于启动程序(只能有一条 CMD 指令)
    CMD [ "node","helloworld.js" ]
    

    构建镜像

    sudo docker build -t helloworld:latest .
    

    注意:每次修改dockerfile文件后就需要重新构建镜像

    运行容器

    sudo docker run -d -p 3000:3000 --name helloworld helloworld:latest
    

    进入容器的终端

    sudo docker exec -it helloworld /bin/sh
    

    退出容器的终端

    exit
    

    停止容器

    sudo docker stop helloworld
    

    指令说明

    名称 地址
    官方指令说明 https://docs.docker.com/engine/reference/builder
    指令 说明
    FROM 指定所创建镜像的基础镜像
    RUN 运行命令
    CMD 指定容器启动时默认执行的命令
    LABEL 指定生成镜像的元数据标签信息
    MAINTAINER 镜像维护者信息(弃用)
    EXPOSE 声明镜像内服务所监听的端口
    ENV 指定环境变量
    ADD 复制内容到镜像中并解压缩内容
    COPY 复制内容到镜像中(官方推荐)
    ENTRYPOINT 指定镜像的默认入口命令
    VOLUME 创建数据卷挂载点
    USER 设置容器启动的登录用户
    WORKDIR 设置工作目录
    ARG 指定镜像内使用的参数
    ONBUILD 创建子镜像时指定自动执行的操作指令
    STOPSIGNAL 容器退出的信号值
    HEALTHCHECK 设置所启动容器如何进行健康检查
    SHELL 指定默认 shell 类型

    推送镜像到远程仓库 Docker Hub

    创建远程仓库

    名称 地址
    容器官方镜像仓库 https://hub.docker.com/

    注意:要推送镜像到远程仓库需要提前在dokcer hub上注册帐号密码

    登录远程仓库

    sudo docker login
    

    注意:输入docker hub的帐号密码即可登录

    标记镜像

    sudo docker tag helloworld:latest dabolau/helloworld:latest
    

    推送镜像到远程仓库

    sudo docker push dabolau/helloworld:latest
    

    注意:如果修改了镜像需要重新构建镜像后再重复上面三个步骤

    注销远程仓库

    sudo docker logout
    

    注意:如果不更换其他私有仓库就不需要执行这一步

    构建镜像并多容器部署服务

    在这个过程中我们会构建镜像并多容器部署三个服务,了解数据卷和网络的相关配置

    准备工作

    • 创建/home/api目录
    sudo mkdir -p /home/api
    
    • 进入/home/api目录
    cd /home/api
    

    编辑配置文件

    • /home/api目录中创建api.js程序文件
    sudo nano api.js
    

    /home/api/api.js

    // 引入模块
    const Koa = require('koa');
    const Router = require('koa-router');
    const MongoClient = require('mongodb');
    // 实例化对象
    const app = new Koa();
    const router = new Router();
    // 获取当前机器的主机名
    function getHostName() {
        const os = require('os');
        return os.hostname()
    }
    // 获取当前机器的网络地址
    function getIpAddress() {
        const os = require('os');
        let ifaces = os.networkInterfaces()
        for (let dev in ifaces) {
            let iface = ifaces[dev]
            for (let i = 0; i < iface.length; i++) {
                let { family, address, internal } = iface[i]
                if (family === 'IPv4' && address !== '127.0.0.1' && !internal) {
                    return address
                }
            }
        }
    }
    // 判断是否为容器环境
    function isDocker() {
        const fs = require('fs');
        try {
            fs.accessSync('/.dockerenv');
            return true;
        } catch (error) {
            return false
        }
    }
    // 数据库连接地址
    let url = `mongodb://username:password@localhost:27017`;
    if (isDocker()) {
        // 获取环境变量
        let mongoAddress = process.env['MONGO_ADDRESS'];
        let mongoUsername = process.env['MONGO_USERNAME'];
        let mongoPassword = process.env['MONGO_PASSWORD'];
        if (mongoAddress && mongoUsername && mongoPassword) {
            url = `mongodb://${mongoUsername}:${mongoPassword}@${mongoAddress}`;
        } else {
            url = `mongodb://username:password@mongo:27017`;
        }
    }
    console.log("Mongo URL",url);
    // 初始化对象
    const mongoClient = new MongoClient.MongoClient(url);
    // 连接数据库
    mongoClient.connect(async (err) => {
        if (!err) {
            console.log(`Mongo connected successfully`);
            // 创建数据库
            await mongoClient.db("db").createCollection("users", (err) => {
                if (err) {
                    console.log('Collection already exists');
                    return;
                }
                console.log('Collection create successfully');
            });
            app.context.db = mongoClient.db("db");
        }
        else {
            console.log('Mongo connection failed:%s', err);
        }
    });
    // 首页
    router.all('/', (ctx) => {
        ctx.body = {
            "HostName": getHostName(),
            "IpAddress": getIpAddress(),
            "IsDocker": isDocker(),
        }
    });
    // 获取所有用户信息页
    router.all('/user', async (ctx) => {
        let user = await ctx.db.collection("users").find({});
        let datas = await user.toArray();
        if (user) {
            ctx.body = {
                "Datas": datas,
                "Message": "查询成功",
                "StatusCode": "200",
            };
        } else {
            ctx.body = {
                "Datas": [],
                "Message": "查询失败",
                "StatusCode": "403",
            };
        };
    });
    // 注册页
    router.all('/user/register', async (ctx) => {
        let usernameObj = { "username": ctx.query.username };
        let passwordObj = { "password": ctx.query.password };
        let user = await ctx.db.collection("users").updateOne(usernameObj, { '$set': passwordObj }, { upsert: true })
        if (user.upsertedId) {
            ctx.body = {
                "Message": "注册成功",
                "StatusCode": "200",
            };
        } else {
            ctx.body = {
                "Message": "注册失败",
                "StatusCode": "403",
            };
        };
    });
    // 登录页
    router.all('/user/login', async (ctx) => {
        let userObj = { "username": ctx.query.username, "password": ctx.query.password };
        let user = await ctx.db.collection("users").findOne(userObj);
        if (user) {
            ctx.body = {
                "Message": "登录成功",
                "StatusCode": "200",
            };
        } else {
            ctx.body = {
                "Message": "登录失败",
                "StatusCode": "403",
            };
        };
    });
    // 使用中间件
    app.use(router.routes());
    app.use(router.allowedMethods());
    // 监听端口
    app.listen(3000);
    // 打印输出
    console.log('Server running on http://0.0.0.0:3000/');
    
    • /home/api目录中创建package.json配置文件
    sudo nano package.json
    

    /home/api/package.json

    {
      "dependencies": {
        "koa": "^2.13.4",
        "koa-router": "^10.1.1",
        "mongodb": "^4.5.0"
      }
    }
    
    • /home/api目录中创建dockerfile配置文件
    sudo nano dockerfile
    

    /home/api/dockerfile

    # 基础镜像
    FROM node:16-alpine
    # 复制本地文件到镜像中
    ADD . /api
    # 设置工作目录
    WORKDIR /api
    # 运行命令,通常用于安装应用,安装依赖,配置系统信息(可以有多条 RUN 指令)
    RUN npm i --registry=https://registry.npm.taobao.org
    # 运行命令,通常用于启动程序(只能有一条 CMD 指令)
    CMD ["node","api.js"]
    

    构建镜像

    sudo docker build -t api:latest .
    

    注意:每次修改dockerfile文件后就需要重新构建镜像

    标记镜像

    sudo docker tag api:latest dabolau/api:latest
    

    推送镜像到远程仓库

    sudo docker push dabolau/api:latest
    

    注意:如果修改了镜像需要重新构建镜像后再重复上面三个步骤

    编辑配置文件

    • /home/api目录中创建docker-compose.yaml配置文件
    sudo nano docker-compose.yaml
    

    /home/api/docker-compose.yaml

    # 版本信息
    version: '3'
    # 容器服务,包含多个容器
    services:
      # 容器服务
      api:
        # 容器名称
        image: dabolau/api:latest
        # 端口[宿主机:容器]
        ports:
          - "3000:3000"
        # 容器网络
        networks:
          - mongo-network
        environment:
          - MONGO_ADDRESS=mongo:27017
          - MONGO_USERNAME=username
          - MONGO_PASSWORD=password
      # 容器服务
      mongo:
        # 容器名称
        image: mongo:latest
        # 端口[宿主机:容器]
        ports:
          - "27017:27017"
        # 容器网络
        networks:
          - mongo-network
        # 环境变量
        environment:
          - MONGO_INITDB_ROOT_USERNAME=username
          - MONGO_INITDB_ROOT_PASSWORD=password
        # 数据卷[宿主机:容器]
        volumes:
          - mongo-config:/data/configdb
          - mongo-data:/data/db
      # 容器服务
      mongo-express:
        # 容器名称
        image: mongo-express:latest
        # 端口[宿主机:容器]
        ports:
          - "8081:8081"
        # 容器网络
        networks:
          - mongo-network
        # 环境变量
        environment:
          - ME_CONFIG_MONGODB_SERVER=mongo
          - ME_CONFIG_MONGODB_ADMINUSERNAME=username
          - ME_CONFIG_MONGODB_ADMINPASSWORD=password
    # 数据卷
    volumes:
      # 命名数据卷名称与上面容器的宿主机数据卷名称一致
      mongo-config:
      mongo-data: # 容器网络
    networks:
      # 命名网络名称与上面容器的网络名称一致
      mongo-network:
    

    注意:当docker-compose.yaml运行时会自动创建网络mongo-network供三个容器网络通信,创建数据卷mongo-configmongo-data分别持久化存放数据库的配置文件和数据文件,持久化数据放在/var/lib/docker/volumes目录下

    运行容器

    sudo docker-compose up -d
    

    停止容器

    sudo docker-compose down
    

    容器数据持久化存储卷

    名称 地址
    官方数据卷说明 https://docs.docker.com/storage/

    常见容器中数据库数据卷的默认路径

    其它数据库的默认路径请在docker hub中查看帮助文档

    数据库名称 数据库容器中的路径
    mongo /data/db
    mysql /var/lib/mysql
    postgres /var/lib/postgresql/data

    在各平台下数据卷的默认路径

    数据卷在不同操作系统下路径不同,持久化存储的数据就存放在不同操作系统的对应目录中

    名称 路径
    windows c:\ProgramData\docker\volumes
    linux /var/lib/docker/volumes
    mac /var/lib/docker/volumes

    苹果系统下找不到数据卷路径的解决办法

    mac系统中找不到/var/lib/docker/volumes目录时需要先挂载数据卷运行ubuntu容器,挂载的数据就存放在这个ubuntu容器中的/var/lib/docker/volumes目录下

    docker run -v mongo-data:/data/db --name ubuntu -it ubuntu
    

    当再次查看数据卷内容时,需要重新启动ubuntu容器

    docker start ubuntu
    

    再进入终端查看/var/lib/docker/volumes目录下的数据

    docker exec -it ubuntu /bin/bash
    

    容器的基础网络

    名称 地址
    官方网络说明 https://docs.docker.com/network/

    容器网络简单说明

    网络名称 网络相关说明
    bridge 网桥网络,虚拟网络与宿主机通信,容器中默认的网络
    host 主机网络,与宿主机共用网络,需注意端口冲突
    none 没有网络,与外界完全隔离,用于安全性较高的场景

    相关文章

      网友评论

          本文标题:Docker使用指南

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