一、概要
1.1 为什么需要 Docker
在软件开发的世界里,环境一致性是个永恒的挑战。开发者在本地开发的应用,往往在部署到测试或生产环境时出现问题,这就是所谓的“在我的机器上可以运行”的困境。Docker 的出现,通过容器化技术,将应用及其依赖打包在一起,确保了在任何环境下的一致性,从而解决了这一问题。此外,Docker 还提供了资源隔离和快速部署的能力,使得开发和运维工作更加高效。
常规应用开发部署方式:自己在 Windows 上开发、测试 --> 到 Linux 服务器配置运行环境部署。
问题:我机器上跑都没问题,怎么到服务器就各种问题了
用 Docker 开发部署流程:自己在 Windows 上开发、测试 --> 打包为 Docker 镜像(可以理解为软件安装包) --> 各种服务器上只需要一个命令部署好
优点:确保了不同机器上跑都是一致的运行环境,不会出现我机器上跑正常,你机器跑就有问题的情况。
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、启动报错解决
报错截图
解决方法:
控制面板->程序->启用或关闭 windows 功能,开启 Windows 虚拟化和 Linux 子系统(WSL2)
命令行安装 Linux 内核wsl.exe --install -d Ubuntu
你也可以打开微软商店 Microsoft Store 搜索 Linux 进行安装,选择一个最新版本的 Ubuntu 或者 Debian 都可以
上面命令很可能你安装不了,微软商店你也可能打不开,如果遇到这个问题,参考:
设置开机启动 Hypervisorbcdedit /set hypervisorlaunchtype auto
注意要用管理员权限打开 PowerShell
设置默认使用版本2wsl.exe --set-default-version 2
查看 WSL 是否安装正确
wsl.exe --list --verbose
应该如下图,可以看到一个 Linux 系统,名字你的不一定跟我的一样,看你安装的是什么版本。
并且 VERSION 是 2
确保 BIOS 已开启虚拟化,下图检查是否已开启好
如果是已禁用,请在开机时按 F2 进入 BIOS 开启一下,不会设置的可以网上搜索下自己主板的设置方法,Intel 和 AMD 的设置可能稍有不同
出现下图错误,点击链接安装最新版本的 WSL2
https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi
2.3、镜像加速源
镜像加速器 | 镜像加速器地址 |
Docker 中国官方镜像 | |
DaoCloud 镜像站 | |
Azure 中国镜像 | |
科大镜像站 | |
阿里云 | |
七牛云 | |
网易云 | |
腾讯云 |
"registry-mirrors": ["https://registry.docker-cn.com"]
三、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 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/
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文件中使用RUN
,CMD
,FROM
,EXPOSE
,ENV
等指令。
在这里列出了一些常用的指令。
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"]
解释常用指令的意义
Dockerfile 文件中还是其它参数,参考:http://www.docker.org.cn/dockerppt/114.html