• 史上最全面的Docker容器引擎使用教程


    【本文版权归微信公众号"代码艺术"(ID:onblog)所有,若是转载请务必保留本段原创声明,违者必究。若是文章有不足之处,欢迎关注微信公众号私信与我进行交流!】

    Docker 是一个开源的应用容器引擎,基于 Go 语言] 并遵从Apache2.0协议开源。Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器上,也可以实现虚拟化。Docker 使用客户端-服务器 (C/S) 架构模式,使用远程API来管理和创建Docker容器。

    Docker有免费的CE社区版和收费的EE企业版,本文安装的是CE版本。

    1.Docker安装

    1.1 检查

    Docker 要求 CentOS 系统的内核版本高于 3.10 ,可以通过 uname -r 命令查看你当前的内核版本。

    如果CentOS版本是7以上并且为64位,那是完全没用问题的。

    1.2 安装

    安装一些必要系统工具:

    sudo yum install -y yum-utils device-mapper-persistent-data lvm2
    

    添加软件源信息:

    sudo yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    

    更新 yum 缓存:

    sudo yum makecache fast
    

    安装 Docker-ce:

    sudo yum -y install docker-ce
    

    启动 Docker 后台服务

    sudo systemctl start docker
    

    测试运行 hello-world

    docker run hello-world
    

    由于本地没有hello-world这个镜像,所以会下载一个hello-world的镜像,并在容器内运行。

    1.3 镜像加速

    例如在使用Maven时我们一般会配置阿里云国内镜像加速,在使用Docker时也是如此。我使用的是网易的镜像地址:http://hub-mirror.c.163.com

    新版的 Docker 使用 /etc/docker/daemon.json(Linux) 或者 %programdata%dockerconfigdaemon.json(Windows) 来配置 Daemon。

    请在该配置文件中加入(没有该文件的话,请先建一个):

    {
      "registry-mirrors": ["http://hub-mirror.c.163.com"]
    }
    

    一定要重启docker服务,如果重启docker后无法加速,可以重新启动OS。

    动作 指令
    概要 docker info
    启动 systemctl start docker
    停止 systemctl stop docker
    重启 systemctl restart docker
    查看状态 systemctl status docker
    开机启动 systemctl enable docker

    1.4 卸载Docker

    执行以下命令来删除 Docker CE:

    $ sudo yum remove docker-ce
    $ sudo rm -rf /var/lib/docker
    

    2.实战Nginx

    2.1 查找Docker Hub上的 nginx 镜像
    docker search nginx
    

    2.2 拉取官方镜像
    docker pull nginx
    
    2.3 拉取成功查看本地镜像
    docker images nginx
    

    2.4 启动Nginx服务器
    docker run -p 8080:80 -d nginx
    
    • -p 8080:80:将本机8080端口映射到Nginx容器的80端口
    • -d:后台启动
    2.5 查看Docker当前运行
    docker ps
    

    2.6 访问测试

    2.7 拷贝本地文件到容器内

    把当前目录下的index.html文件拷贝到容器内,替换Nginx的默认首页。

    docker cp index.html dbfc48660aeb://usr/share/nginx/html
    

    dbfc48660aeb是容器内Nginx运行的ID,/usr/share/nginx/html是容器内Nginx的首页默认路径。

    再次访问浏览器,可以看到首页已经更换为我们自定义的文件内容。

    2.8 停止Docker容器
    docker stop ID
    

    刷新浏览器,访问提示无法连接。

    2.9 保存容器内更改

    再次运行Nginx容器,访问首页,发现更改的首页又复原了。如图:

    这是因为在更改后没有提交保存导致的。也就是需要下面这句命令:

    docker commit -m 'fun' aaef9a68525a nginx-fun
    
    • -a ' author':作者名
    • -m 'fun':是说明文字;
    • aaef9a68525a:容器ID,通过ps命令获取;
    • nginx-fun:新生成的image镜像名称;

    然后查看现有镜像:

    发现新生成了一个nginx-fun镜像。

    2.10 删除容器

    虽然有些容器已经停止了,但是还存有信息,可以通过docker ps -a查看,再通过docker rm [CONTAINER ID]删除。

    3.Docker命令小结

    命令 用途
    docker pull 获取image
    docker build 创建image
    docker images 列出image
    docker run 运行container
    docker ps 列出container
    docker rm 删除container
    docker rmi 删除image
    docker cp 在host和container之间拷贝文件
    docker commit 保存改动为新的image

    4.DockerFile创建镜像

    创建文件Dockerfile文件,该文件名不可更改

    vi Dockerfile
    

    写入文本

    FROM alpine:latest
    MAINTAINER smilevt
    CMD echo "Hello Docker!"
    

    保存退出

    docker build命令用于使用 Dockerfile 创建镜像,

    docker build -t hello_docker .
    
    • -t : 镜像的名字及标签,通常 name:tag 或者 name
    • path : .点代表当前路径下的所有文件。

    运行结果:

    查看是否成功创建镜像并运行

    4.1 Dockerfile构建SpringBoot镜像

    将Spring Boot应用打包为Docker镜像是非常简单的,下面介绍一种比较原生的方式。

    1.比如我们有一个Spring Boot Web应用,我们将它在本地打包为Jar,并拷贝到一台装有Docker的机器上。

    2.在Jar包(docker-demo-0.0.1-SNAPSHOT.jar)所在目录下新建Dockerfile文件,文件内容为:

    FROM openjdk:8-jdk-alpine
    VOLUME /tmp
    ADD docker-demo-0.0.1-SNAPSHOT.jar app.jar
    ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]
    

    3.执行docker build命令打包为镜像

    docker build -t spring-boot-demo:tag .
    

    4.运行刚刚打包的镜像

    docker run -p 8080:8080 spring-boot-demo:tag
    

    5.访问你的应用,OK。

    延伸阅读:

    使用Maven插件构建Spring Boot应用程序镜像

    5.Dockerfile安装Nginx

    再次新建文件夹并新建Dockerfile文件,写入以下内容;

    FROM ubuntu
    MAINTAINER anthor
    RUN sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list
    RUN apt-get update
    RUN apt-get install -y nginx
    COPY index.html /var/www/html
    ENTRYPOINT ["usr/sbin/nginx", "-g", "daemon off;"]
    EXPOSE 80
    

    简单说一下文本含义:从(FROM)ubuntu容器中运行(RUN)3条命令,第一条是修改archive.ubuntu.com为mirrors.ustc.edu.cn国内镜像,第二、三条是安装nginx,然后复制(COPY)index.html到容器内,提供容器进入点(ENTRYPOINT),使nginx在前台运行,之所以使用数组是为了隔开命令,最后暴露80端口。

    接下来新建index.html文件,执行build命令创建镜像:

    docker build -t hello-nginx:tag .
    

    使用run命令启动该hello-nginx容器:

    docker run -p 8080:80 -d hello-nginx:tag
    

    测试访问host:8080端口如下:

    可以看到,Nginx成功启动,并输出自定义的index.html。

    6.Dockerfile命令小结

    指令 说明
    FROM 设置镜像使用的基础镜像
    MAINTAINER 设置镜像的作者
    RUN 编译镜像时运行的脚本
    CMD 设置容器的启动命令
    LABEL 设置镜像的标签
    EXPOSE 设置镜像暴露的端口
    ENV 设置容器的环境变量
    ADD 编译镜像时复制文件到镜像中
    COPY 编译镜像时复制文件到镜像中
    ENTRYPOINT 设置容器的入口程序
    VOLUME 设置容器的挂载卷
    USER 设置运行RUN CMD ENTRYPOINT的用户名
    WORKDIR 设置RUN CMD ENTRYPOINT COPY ADD指令的工作目录
    ARG 设置编译镜像时加入的参数
    ONBUILD 设置镜像的ONBUILD指令
    STOPSIGNAL 设置容器的退出信号量

    6.1 Dockerfile文件中的CMD和ENTRYPOINT指令差异对比

    CMD指令和ENTRYPOINT指令的作用都是为镜像指定容器启动后的命令,那么它们两者之间有什么各自的优点呢?为了更好地对比CMD指令和ENTRYPOINT指令的差异,我们这里再列一下这两个指令的说明,

    CMD

    支持三种格式

    CMD ["executable","param1","param2"] 使用 exec 执行,推荐方式; 
    
    CMD command param1 param2 在 /bin/sh 中执行,提供给需要交互的应用;
    
    CMD ["param1","param2"] 提供给 ENTRYPOINT 的默认参数;
    

    指定启动容器时执行的命令,每个 Dockerfile 只能有一条 CMD 命令。如果指定了多条命令,只有最后一条会被执行。

    如果用户启动容器时候指定了运行的命令,则会覆盖掉 CMD 指定的命令。

    ENTRYPOINT

    两种格式:

    ENTRYPOINT ["executable", "param1", "param2"]
    
    ENTRYPOINT command param1 param2(shell中执行)。
    

    配置容器启动后执行的命令,并且不可被 docker run 提供的参数覆盖。

    每个 Dockerfile 中只能有一个 ENTRYPOINT,当指定多个时,只有最后一个起效。

    从上面的说明,我们可以看到有两个共同点:

    1. 都可以指定shell或exec函数调用的方式执行命令;
    2. 当存在多个CMD指令或ENTRYPOINT指令时,只有最后一个生效;

    而它们有如下差异:
    差异1:CMD指令指定的容器启动时命令可以被docker run指定的命令覆盖,而ENTRYPOINT指令指定的命令不能被覆盖,而是将docker run指定的参数当做ENTRYPOINT指定命令的参数。

    差异2:CMD指令可以为ENTRYPOINT指令设置默认参数,而且可以被docker run指定的参数覆盖;

    详细参考:Dockerfile中ENTRYPOINT和CMD的区别

    7.镜像分层

    Dockerfile的每一行都会产生一个新层(新ID),比如:

    已经存在image里面的层是只读的,一旦镜像运行为容器之后,就会产生一个新层(RW读写),分层的好处就是多个image可以共享相同的层,减少存储大小。

    8.Volume

    我们知道,Docker容器中的改动是不会被保存的,为了能够保存(持久化)数据以及共享容器间的数据,Docker提出了Volume的概念。简单来说,Volume就是目录或者文件,它可以绕过默认的联合文件系统,而以正常的文件或者目录的形式存在于宿主机上。 比如在使用数据库时就可以使用Volume。

    9.Volume操作

    说白了,Volume只是-v参数而已。容器和宿主机目录挂载的三种方式:

    1.第一种方式

    运行Nginx容器,-d:后台运行,--name:指定名称nginx,-v /usr/share/nginx/html:运行容器内部用来访问网页的地址,最后的nginx是镜像名。

    docker run -d --name nginx -v /usr/share/nginx/html nginx
    

    获取容器/镜像的元数据

    docker inspect nginx
    

    可以看到宿主机目录Source和容器内目录Destination:

    继续查看宿本机目录:

    注意:如果是mac,则该路径不是mac上的实际路径,因为mac上运行docker是还有一层虚拟层,这是docker虚拟层中的路径,可以在docker中访问到

    2.第二种方式

    【本文版权归微信公众号"代码艺术"(ID:onblog)所有,若是转载请务必保留本段原创声明,违者必究。若是文章有不足之处,欢迎关注微信公众号私信与我进行交流!】

    在启动Nginx容器时使用-v参数挂载本地目录到容器目录

    docker run -p 8080:80 --name mynginx -v $PWD:/usr/share/nginx/html -d nginx
    

    这句命令使用PWD环境变量(该变量始终指向当前目录)将当前目录挂载到容器/usr/share/nginx/html目录。

    我们访问主机8080端口

    报错403,因为当前目录啥也没有,没有index.html文件。在当前目录新建该html文件,输入hello,访问网页

    3.第三种方式

    使用 docker create 创建一个新的容器但不启动它:

    docker create -v $PWD/data:/var/mydata --name data_container ubuntu
    
    • 宿主机目录:$PWD/data

    • docker目录:/var/mydata

    • 容器名:data_container

    • 基础镜像:ubuntu

    启动 ubuntu 容器镜像(默认ubuntu基础镜像没有服务):

    docker run -it --volumes-from data_container ubuntu /bin/bash
    
    • -it: 以交互模式运行容器,并为容器重新分配一个伪输入终端
    • --volumes-from data_container:以另外一个容器挂载
    • 最后在容器内执行/bin/bash命令

    进入到容器控制台后输入mount,查看挂载:

    我们在/var/mydata目录下新建whatever.txt文件后退出,进入data目录查看,可以看到刚刚新建的txt文件。

    10.Registry介绍

    Registry 是镜像仓库,我们可以从镜像仓库中拉取一些镜像到本地,也可以提交镜像到仓库。

    一些术语:

    ENGLISH 中文
    host 宿主机
    image 镜像
    container 容器
    registry 仓库
    daemon 守护程序
    client 客户端

    与registry仓库的交互:

    查找镜像

    docker search whalesay
    

    拖取镜像

    docker pull whalesay
    

    推送镜像

    docker push myname/whalesay
    

    国内的docker镜像仓库:

    daoclou

    时速云

    aliyun

    11.Registry实战

    1.查找镜像

    STARS可以理解为点赞数,默认是按照这个排序的。

    2.拉取镜像

    3.查看镜像

    可以看到,REPOSITORY是镜像名,TAG是默认的latest,正常情况是版本号,这两个比较重要。

    CREATED是创建时间,SIZE是占用空间的大小。

    4.运行镜像

    5.标记镜像

    使用docker tag命令标记本地镜像,将其归入某一仓库。

    docker tag docker/whalesay myhaleasy:tag
    

    6.上传镜像

    可以使用docker push命令上传本地镜像到仓库,但是需要注册登录。

    注册登录地址:https://hub.docker.com

    执行登录命令,输入用户名与密码即可。

    docker login
    

    上传镜像前还需要在Docker官网个人中心创建该镜像。

    docker push到私有仓库

    12.Compose多容器应用

    Compose 是一个用户定义和运行多个容器的 Docker 应用程序。在 Compose 中你可以使用 YAML 文件来配置你的应用服务。然后,只需要一个简单的命令,就可以创建并启动你配置的所有服务。

    docker-compose 安装

    1.Mac/Windows:

    ​ 安装docker的时候附带安装了。

    2.Linux:

    curl https://github.com/docker/compose
    

    Linux安装

    执行命令

    curl -L https://github.com/docker/compose/releases/download/1.9.0/docker-compose-$(uname -s)-$(uname -m) > /usr/local/bin/docker-compose
    

    该命令会下载文件到(>)/usr/local/bin/docker-compose,在下载地址中使用$(uname -s)是获取 unmae -s 命令的输出加到路径中。

    下载完成后,可以设置该目录的权限为777,意为所有人都可以读写该目录,最后使用 docker-compose --version 检查是否安装成功。

    13.Compose搭建博客网站

    接下来我们使用docker-compose搭建一个含nginx+ghost+db的博客网站。

    1.准备

    首先创建如下目录结构:

    ghost
      - ghost
        - Dockfile
        - config.js
      - nginx
          - nginx.conf
          - Dockfile
      - data
      - docker-compose.yml
    

    每个文件的具体内容有:

    • ghost/ghost/Dockfile

    过时的配置(不使用)

    FROM ghost
    COPY ./config.js /var/lib/ghost/config.js
    EXPOSE 2368
    CMD ["npm","start","--production"]
    

    最新版的官方镜像, 把配置文件改到/var/lib/ghost/content/ ,然后注释掉了 CMD["npm","start","--production"] 即可。

    FROM ghost
    COPY ./config.js /var/lib/ghost/content/ 
    EXPOSE 2368
    
    • ghost/ghost/config.js
    var path = require('path'),
        config;
    
    config = {
        production: {
            url: 'http://mytestblog.com',
            mail: {},
            database: {
                client: 'mysql',
                connection: {
                    host: 'db',
                    user: 'ghost',
                    password: 'ghost',
                    database: 'ghost',
                    port: '3306',
                    charset: 'utf8'
                },
                debug: false
            },
            paths: {
                contentPath: path.join(process.env.GHOST_CONTENT, '/')
            },
            server: {
                host: '0.0.0.0',
                port: '2368'
            }
        }
    };
    
    module.exports = config;
    
    • ghost/nginx/Dockerfile
    FROM nginx
    COPY nginx.conf /etc/nginx/nginx.conf
    EXPOSE 80
    
    • ghost/nginx/nginx.conf
    worker_processes 4;
    events {worker_connections 1024;}
    http {
        server {
            listen 80;
            location / {
                proxy_pass http://ghost-app:2368;
            }
        }
    }
    
    • ghost/docker-compose.yml
    version: '2'
    
    networks:
      ghost:
    services:
      ghost-app:
        build: ghost
        networks:
          - ghost
        depends_on:
          - db
        ports:
          - "2368:2368"
    
      nginx:
        build: nginx
        networks:
          - ghost
        depends_on:
          - ghost-app
        ports:
          - "80:80"
    
      db:
        image: "mysql:5.7.15"
        networks:
          - ghost
        environment:
          MYSQL_ROOT_PASSWORD: mysqlroot
          MYSQL_USER: ghost
          MYSQL_PASSWORD: ghost
        volumes:
          - $PWD/data:/var/lib/mysql
        ports:
          - "3306:3306"
    

    此处数据库相关的配置要和config.js中的配置(user、password)保持一致。

    一旦我们为一个服务指定了一个名字(db),它就可以被其它服务所解析。

    nginx 中proxy_pass 设置成 http://ghost-app:2368 也是因为在docker-compose.yml 指定了服务是ghost-app。

    2.启动

    将所有容器启动,并以daemon的方式后台运行。第一次不需要build,因为会自动创建镜像。

    docke-compose up -d
    

    3.查看应用

    docker-compose ps
    

    因为文件内容输入有误,导致启动未成功,修改文件后还需要停止、删除掉容器再重新构建才行。

    4.停止(+)

    停止所有容器

    docker-compose stop
    

    5.删除(+)

    删除时需要输入y手动确认

    docker-compose rm
    

    6.构建(+)

    非首次运行就需要手动创建镜像了

    docker-compose build
    

    最后,在ghost目录下再次启动!

    7.测试

    访问域名进入搭建的博客网站,可以注册账号发布博客。

    `

    关于ghost的使用这里不做过多介绍。

    14.docker-compose.yml常用命令

    命令 用途
    build 本地创建镜像
    command 覆盖缺省命令
    depends_on 连接容器
    ports 暴露端口
    volumes
    image pull镜像
    up 启动服务
    stop 停止服务
    rm 删除服务中的各个容器
    logs 观察各个容器的日志
    ps 列出服务相关的容器

    6.Docker资源链接

    Docker官方英文资源

    docker官网:http://www.docker.com

    Docker中文资源

    Docker中文网站:https://www.docker-cn.com/

    Docker安装手册:https://docs.docker-cn.com/engine/installation/

    Docker核心概念(镜像、容器、仓库)及基本操作

    Docker 国内镜像

    网易加速器:http://hub-mirror.c.163.com

    官方中国加速器:https://registry.docker-cn.com

    ustc的镜像:https://docker.mirrors.ustc.edu.cn

    daocloud:https://www.daocloud.io/mirror#accelerator-doc(注册后使用)

    版权声明

    【本文版权归微信公众号"代码艺术"(ID:onblog)所有,若是转载请务必保留本段原创声明,违者必究。若是文章有不足之处,欢迎关注微信公众号私信与我进行交流!】

  • 相关阅读:
    Java自学-I/O File类
    Java自学-异常处理 自定义异常
    Java自学-异常处理 Throwable
    Java自学-异常处理 异常分类
    Java自学-异常处理 处理
    Java自学-异常处理 Exception
    Java自学-日期 Calendar
    Java自学-日期 日期格式化
    Java自学-日期 Date
    Java自学-数字与字符串 MyStringBuffer
  • 原文地址:https://www.cnblogs.com/onblog/p/13036056.html
Copyright © 2020-2023  润新知