一、概要

1.1 为什么需要 Docker

在软件开发的世界里,环境一致性是个永恒的挑战。开发者在本地开发的应用,往往在部署到测试或生产环境时出现问题,这就是所谓的“在我的机器上可以运行”的困境。Docker 的出现,通过容器化技术,将应用及其依赖打包在一起,确保了在任何环境下的一致性,从而解决了这一问题。此外,Docker 还提供了资源隔离和快速部署的能力,使得开发和运维工作更加高效。

常规应用开发部署方式:自己在 Windows 上开发、测试 --> 到 Linux 服务器配置运行环境部署。

问题:我机器上跑都没问题,怎么到服务器就各种问题了

用 Docker 开发部署流程:自己在 Windows 上开发、测试 --> 打包为 Docker 镜像(可以理解为软件安装包) --> 各种服务器上只需要一个命令部署好

优点:确保了不同机器上跑都是一致的运行环境,不会出现我机器上跑正常,你机器跑就有问题的情况。

一个小时学会Docker(开源的应用容器引擎)_Dockerfile

1.2 什么是 Docker

Docker 是一个开源的应用容器引擎,它允许开发者将应用及其依赖打包到一个轻量级、可移植的容器中,然后发布到任何流行的 Linux 机器或 Windows 机器上,也可以实现虚拟化。容器是完全使用沙箱机制,相互之间不会有任何接口。

Docker 是一个应用打包、分发、部署的工具
你也可以把它理解为一个轻量的虚拟机,它只虚拟你软件需要的运行环境,多余的一点都不要,
而普通虚拟机则是一个完整而庞大的系统,包含各种不管你要不要的软件。

1.3 跟普通虚拟机的对比

虚拟机(VM)通过模拟硬件来运行完整的操作系统,而 Docker 容器则是直接运行在宿主机的操作系统上,共享宿主机的内核。因此,Docker 容器比虚拟机更轻量,启动更快,资源消耗更少。简单来说,如果你把虚拟机比作完整的旅行大巴,那么 Docker 容器就像是一辆轻便的自行车,都能带你到达目的地,但后者更加高效和便捷。

特性

普通虚拟机

Docker

跨平台

通常只能在桌面级系统运行,例如 Windows/Mac,无法在不带图形界面的服务器上运行

支持的系统非常多,各类 windows 和 Linux 都支持

性能

性能损耗大,内存占用高,因为是把整个完整系统都虚拟出来了

性能好,只虚拟软件所需运行环境,最大化减少没用的配置

自动化

需要手动安装所有东西

一个命令就可以自动部署好所需环境

稳定性

稳定性不高,不同系统差异大

稳定性好,不同系统都一样部署方式

1.4 Docker 的特点与优势

  • 轻量级:Docker 容器直接运行在宿主机的操作系统上,不需要额外的操作系统,因此比虚拟机更节省资源。
  • 快速部署:容器启动几乎是即时的,相比虚拟机的启动时间大大缩短。
  • 一致性:确保开发、测试和生产环境的一致性,减少“在我的机器上可以运行”的问题。
  • 可移植性:容器可以在任何安装了 Docker 的系统上运行,无论是开发、测试还是生产环境。
  • 隔离性:每个容器都是独立的,一个容器的故障不会影响其他容器。
  • 可扩展性:可以轻松地将应用扩展到多个容器,实现负载均衡和服务的高可用性。

1.5 Docker 通常用来做什么

Docker 被广泛应用于以下领域:

  • 开发与测试:提供一致的开发环境,简化测试流程。
  • 持续集成/持续部署(CI/CD):自动化应用的构建、测试和部署过程。
  • 微服务架构:支持微服务的部署和管理,使得服务更加模块化和易于维护。
  • 云计算和数据中心:容器化的应用更容易在云环境中部署和管理,提高了资源的利用率和应用的弹性。

1.6 Docker 中名词解释

  • 镜像(Image):Docker 镜像是容器的模板。镜像包含了文件系统和应用运行所需的所有内容。
  • 容器(Container):容器是镜像运行时的实例。容器可以创建、启动、停止、删除。
  • 仓库(Repository):仓库是集中存放镜像文件的地方。Docker Hub 是最著名的公共仓库。
  • Dockerfile:Dockerfile 是一种脚本,包含了从基础镜像开始,如何构建一个新的 Docker 镜像的指令。
  • 端口映射(Port Mapping):端口映射允许你将容器内部的端口映射到宿主机的端口,从而能够访问运行在容器内部的应用。
  • 卷(Volume):卷是 Docker 中用于数据持久化和共享的一种机制。它可以在容器之间共享和重用数据。
  • 打包:就是把你软件运行所需的依赖、第三方库、软件打包到一起,变成一个安装包
  • 分发:你可以把你打包好的“安装包”上传到一个镜像仓库,其他人可以非常方便的获取和安装
  • 部署:拿着“安装包”就可以一个命令运行起来你的应用,自动模拟出一摸一样的运行环境,不管是在 Windows/Mac/Linux。

1.7 Docker 学习资料

为了帮助您更好地学习和掌握 Docker,这里为您整理了一些重要的学习资源,包括官方网站、中文学习网站以及官方文档等。

  • Docker 官方网站
    官方网站是学习 Docker 的最佳起点,提供了最新的信息、教程和文档。您可以在这里找到从基础到高级的各种资源。
    Docker 官方网站
  • Docker 官方文档
    官方文档详细介绍了 Docker 的所有功能和使用方法,是深入学习 Docker 的重要资源。
    Docker 官方文档
  • Docker Hub
    Docker Hub 是 Docker 官方的镜像仓库,您可以在这里找到成千上万的预构建镜像,以及由社区维护的各种工具和应用。
    Docker Hub
  • Docker中文网
  • https://www.docker.org.cn/

通过这些资源的学习和实践,您将能够更快地掌握 Docker 的使用技巧,提高软件开发和部署的效率。记得在学习过程中多动手实践,这是掌握 Docker 最快的方式。

二、Docker安装

2.1、安装地址

桌面版:https://www.docker.com/products/docker-desktop服务器版:https://docs.docker.com/engine/install/#server

2.2、启动报错解决

报错截图

一个小时学会Docker(开源的应用容器引擎)_docker_02

解决方法:

控制面板->程序->启用或关闭 windows 功能,开启 Windows 虚拟化和 Linux 子系统(WSL2)

一个小时学会Docker(开源的应用容器引擎)_docker_03

命令行安装 Linux 内核
wsl.exe --install -d Ubuntu

你也可以打开微软商店 Microsoft Store 搜索 Linux 进行安装,选择一个最新版本的 Ubuntu 或者 Debian 都可以

上面命令很可能你安装不了,微软商店你也可能打不开,如果遇到这个问题,参考:

设置开机启动 Hypervisor
bcdedit /set hypervisorlaunchtype auto

注意要用管理员权限打开 PowerShell

设置默认使用版本2
wsl.exe --set-default-version 2

查看 WSL 是否安装正确

wsl.exe --list --verbose应该如下图,可以看到一个 Linux 系统,名字你的不一定跟我的一样,看你安装的是什么版本。

并且 VERSION 是 2

一个小时学会Docker(开源的应用容器引擎)_docker_04

确保 BIOS 已开启虚拟化,下图检查是否已开启好

如果是已禁用,请在开机时按 F2 进入 BIOS 开启一下,不会设置的可以网上搜索下自己主板的设置方法,Intel 和 AMD 的设置可能稍有不同

一个小时学会Docker(开源的应用容器引擎)_Docker_05

出现下图错误,点击链接安装最新版本的 WSL2

https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi

一个小时学会Docker(开源的应用容器引擎)_Docker_06

2.3、镜像加速源

镜像加速器

镜像加速器地址

Docker 中国官方镜像

https://registry.docker-cn.com

DaoCloud 镜像站

http://f1361db2.m.daocloud.io

Azure 中国镜像

https://dockerhub.azk8s.cn

科大镜像站

https://docker.mirrors.ustc.edu.cn

阿里云

https://ud6340vz.mirror.aliyuncs.com

七牛云

https://reg-mirror.qiniu.com

网易云

https://hub-mirror.c.163.com

腾讯云

https://mirror.ccs.tencentyun.com

"registry-mirrors": ["https://registry.docker-cn.com"]

一个小时学会Docker(开源的应用容器引擎)_Dockerfile_07

 三、Docker 快速安装软件

3.1、直接安装的缺点

  • 安装麻烦,可能有各种依赖,运行报错。例如:WordPress,ElasticSearch,Redis,ELK
  • 可能对 Windows 并不友好,运行有各种兼容问题,软件只支持 Linux 上跑
  • 不方便安装多版本软件,不能共存。
  • 电脑安装了一堆软件,拖慢电脑速度。
  • 不同系统和硬件,安装方式不一样

3.2、Docker 安装的优点

  • 一个命令就可以安装好,快速方便
  • 有大量的镜像,可直接使用
  • 没有系统兼容问题,Linux 专享软件也照样跑
  • 支持软件多版本共存
  • 用完就丢,不拖慢电脑速度
  • 不同系统和硬件,只要安装好 Docker 其他都一样了,一个命令搞定所有

3.3、演示 Docker 安装 Redis

Redis 官网:https://redis.io/

官网下载安装教程只有源码安装方式,没有 Windows 版本。想要自己安装 windows 版本需要去找别人编译好的安装包。

Docker 官方镜像仓库查找 Redis :https://hub.docker.com/

一个小时学会Docker(开源的应用容器引擎)_Docker_08

一个命令跑起来:docker run -d -p 6379:6379 --name redis redis:latest

docker run: 这是Docker命令行工具的基本命令之一,用于创建一个新的容器并运行一个镜像。

-d: 这个参数代表"detached",意味着容器将在后台运行。也就是说,一旦容器启动,命令行会立即返回,不会显示容器的输出。

-p 6379:6379: 这个参数用于端口映射。-p后面跟着的是两组数字,中间用冒号分隔。第一组数字是宿主机(也就是运行Docker的机器)上的端口,第二组数字是容器内部的端口。在这个例子中,宿主机的6379端口被映射到容器的6379端口上。这意味着,你可以通过访问宿主机的6379端口来与容器内的Redis服务进行通信。

--name redis: 这个参数用于给创建的容器指定一个名称。在这个例子中,容器的名称被设置为"redis"。这样做可以让你之后更方便地引用这个容器,而不需要记住容器的ID。

redis:latest: 这是要运行的Docker镜像的名称及标签。"redis"是镜像的名称,而"latest"是一个标签,代表要运行的是这个镜像的最新版本。Docker会自动从Docker Hub(一个公共的镜像仓库)拉取这个镜像,如果本地没有的话。

命令参考:https://docs.docker.com/engine/reference/commandline/run/

一个小时学会Docker(开源的应用容器引擎)_Docker_09

3.4、安装 Wordpress

docker-compose.yml

version: '3.1'

services:

  wordpress:
    image: wordpress
    restart: always
    ports:
      - 8080:80
    environment:
      WORDPRESS_DB_HOST: db
      WORDPRESS_DB_USER: exampleuser
      WORDPRESS_DB_PASSWORD: examplepass
      WORDPRESS_DB_NAME: exampledb
    volumes:
      - wordpress:/var/www/html

  db:
    image: mysql:5.7
    restart: always
    environment:
      MYSQL_DATABASE: exampledb
      MYSQL_USER: exampleuser
      MYSQL_PASSWORD: examplepass
      MYSQL_RANDOM_ROOT_PASSWORD: '1'
    volumes:
      - db:/var/lib/mysql

volumes:
  wordpress:
  db:

3.5、安装 ELK

docker run -p 5601:5601 -p 9200:9200 -p 5044:5044 -it --name elk sebp/elk

内存不够解决方法转到用户目录 cd ~,路径类似这个:C:\Users\<UserName>创建 .wslconfig 文件填入以下内容

[wsl2] memory=10GB # Limits VM memory in WSL 2 to 4 GB processors=2 # Makes the WSL 2 VM use two virtual processors

生效配置,命令行运行 wsl --shutdown

3.6、更多相关命令

docker ps 查看当前运行中的容器
docker images 查看镜像列表
docker rm container-id 删除指定 id 的容器
docker stop/start container-id 停止/启动指定 id 的容器
docker rmi image-id 删除指定 id 的镜像
docker volume ls 查看 volume 列表
docker network ls 查看网络列表

四、镜像制作

4.1、什么是dockerfile?

Dockerfile是一个包含用于组合映像的命令的文本文档。可以使用在命令行中调用任何命令。 Docker通过读取Dockerfile中的指令自动生成映像。

docker build命令用于从Dockerfile构建映像。可以在docker build命令中使用-f标志指向文件系统中任何位置的Dockerfile。

例:

docker build -f -t /path/to/a/Dockerfile registry:v1.0.1

4.2、Dockerfile的基本结构

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

4.3、Dockerfile文件说明

Docker以从上到下的顺序运行Dockerfile的指令。为了指定基本映像,第一条指令必须是FROM。一个声明以字符开头则被视为注释。可以在Docker文件中使用RUNCMDFROMEXPOSEENV等指令。

在这里列出了一些常用的指令。

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

格式:
  FROM 
  FROM :
  FROM @
示例:
  FROM mysql:5.6
注:
  tag或digest是可选的,如果不使用这两个值时,会使用latest版本的基础镜像

MAINTAINER: 维护者信息

格式:
    MAINTAINER 
示例:
    MAINTAINER zhangsan
    MAINTAINER tom@163.com
    MAINTAINER zhangsan <tom@163.com>

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

RUN用于在镜像容器中执行命令,其有以下两种命令执行方式:
shell执行
格式:
    RUN 
exec执行
格式:
    RUN ["executable", "param1", "param2"]
示例:
    RUN ["executable", "param1", "param2"]
    RUN apk update
    RUN ["/etc/execfile", "arg1", "arg1"]
注:
  RUN指令创建的中间镜像会被缓存,并会在下次构建中使用。如果不想使用这些缓存镜像,可以在构建时指定--no-cache参数,如:docker build --no-cache

ADD:将本地文件添加到容器中,tar类型文件会自动解压,可以访问网络资源,类似wget

格式:
    ADD ... 
    ADD ["",... ""] 用于支持包含空格的路径
示例:
    ADD hom* /mydir/          # 添加所有以"hom"开头的文件
    ADD hom?.txt /mydir/      # ? 替代一个单字符,例如:"home.txt"
    ADD test relativeDir/     # 添加 "test" 到 `WORKDIR`/relativeDir/
    ADD test /absoluteDir/    # 添加 "test" 到 /absoluteDir/

COPY:功能类似ADD,但是是不会自动解压文件,也不能访问网络资源

CMD:构建容器后调用,也就是在容器启动时才进行调用。

格式:
    CMD ["executable","param1","param2"] (执行可执行文件,优先)
    CMD ["param1","param2"] (设置了ENTRYPOINT,则直接调用ENTRYPOINT添加参数)
    CMD command param1 param2 (执行shell内部命令)
示例:
    CMD echo "This is a test." | wc -
    CMD ["/usr/bin/wc","--help"]
注:
   CMD不同于RUN,CMD用于指定在容器启动时所要执行的命令,而RUN用于指定镜像构建时所要执行的命令。

ENTRYPOINT:配置容器,使其可执行化。配合CMD可省去"application",只使用参数。

docker run
docker run

LABEL:用于为镜像添加元数据

格式:
    LABEL = = = ...
示例:
  LABEL version="1.0" description="这是一个Web服务器" by="IT笔录"
注:
  使用LABEL指定元数据时,一条LABEL指定可以指定一或多条元数据,指定多条元数据时不同元数据之间通过空格分隔。推荐将所有的元数据通过一条LABEL指令指定,以免生成过多的中间镜像。

ENV:设置环境变量

格式:
    ENV  
    ENV = ...
示例:
    ENV myName John Doe
    ENV myDog Rex The Dog
    ENV myCat fluffy

EXPOSE:指定于外界交互的端口

docker run
-P

VOLUME:用于指定持久化目录

格式:
    VOLUME ["/path/to/dir"]
示例:
    VOLUME ["/data"]
    VOLUME ["/var/www", "/var/log/apache2", "/etc/apache2"
注:
  一个卷可以存在于一个或多个容器的指定目录,该目录可以绕过联合文件系统,并具有以下功能:
1 卷可以容器间共享和重用
2 容器并不一定要和其它容器共享卷
3 修改卷后会立即生效
4 对卷的修改不会对镜像产生影响
5 卷会一直存在,直到没有任何容器在使用它

WORKDIR:工作目录,类似于cd命令

docker run

USER:指定运行容器时的用户名或 UID,后续的 RUN 也会使用指定用户。使用USER指定用户时,可以使用用户名、UID或GID,或是两者的组合。当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户

 格式:
  USER user
  USER user:group
  USER uid
  USER uid:gid
  USER user:gid
  USER uid:group

 示例:
  USER www

 注:

  使用USER指定用户后,Dockerfile中其后的命令RUN、CMD、ENTRYPOINT都将使用该用户。镜像构建完成后,通过docker run运行容器时,可以通过-u参数来覆盖所指定的用户。

ARG:用于指定传递给构建运行时的变量

格式:
    ARG [=]
示例:
    ARG site
    ARG build_user=www

ONBUILD:用于设置镜像触发器

格式:
  ONBUILD [INSTRUCTION]
示例:
  ONBUILD ADD . /app/src
  ONBUILD RUN /usr/local/bin/python-build --dir /app/src
注:
  当所构建的镜像被用做其它镜像的基础镜像,该镜像中的触发器将会被钥触发

 

以下是一个小例子:

# This my first nginx Dockerfile
# Version 1.0

# Base images 基础镜像
FROM centos

#MAINTAINER 维护者信息
MAINTAINER zhangsan 

#ENV 设置环境变量
ENV PATH /usr/local/nginx/sbin:$PATH

#ADD  文件放在当前目录下,拷过去会自动解压
ADD nginx-1.8.0.tar.gz /usr/local/  
ADD epel-release-latest-7.noarch.rpm /usr/local/  

#RUN 执行以下命令 
RUN rpm -ivh /usr/local/epel-release-latest-7.noarch.rpm
RUN yum install -y wget lftp gcc gcc-c++ make openssl-devel pcre-devel pcre && yum clean all
RUN useradd -s /sbin/nologin -M www

#WORKDIR 相当于cd
WORKDIR /usr/local/nginx-1.8.0 

RUN ./configure --prefix=/usr/local/nginx --user=www --group=www --with-http_ssl_module --with-pcre && make && make install

RUN echo "daemon off;" >> /etc/nginx.conf

#EXPOSE 映射端口
EXPOSE 80

#CMD 运行以下命令
CMD ["nginx"]

 

解释常用指令的意义

一个小时学会Docker(开源的应用容器引擎)_Docker_10

Dockerfile 文件中还是其它参数,参考:http://www.docker.org.cn/dockerppt/114.html