文章

快速入门Docker

最简单的Docker应用实例

快速入门Docker

快速入门Docker

前言

最近在写Java,对方的环境是Java8 + Redis + MySQL

因为需要尽可能地快速分发测试环境,为了不去在每个人的电脑上折腾不同的Java版本留存问题 + 四个小时的MySQL导库 + 配置Redis

于是终于想起了轻量好用的Docker(究竟是什么原因让我2025年才开始用Docker呢…)

虚拟化 vs 容器化

省流:Docker使用容器化,比虚拟化的虚拟机启动更快,占用资源更少

几乎所有介绍都会说到的:

特性虚拟化容器化
操作系统每个虚拟机有自己的操作系统容器共享主机的操作系统
资源占用较高较低
启动速度较慢(分钟级别)快速(秒级别)
隔离级别强隔离(独立内核)操作系统级别隔离
管理工具传统虚拟化管理工具Docker、Kubernetes
典型场景多操作系统环境;运行完整应用程序微服务架构;轻量化应用部署

blablabla…

举个典型的例子:

Docker提供了许多官方镜像alt text

有Ubuntu,很眼熟,那么和我们虚拟机的Ubuntu有什么区别呢?

Docker 提供的 Ubuntu 镜像是一个轻量级的文件系统,包含 Ubuntu 的基本工具和库,但不包含操作系统内核或与硬件直接交互的组件

Docker提供的更像是一个依赖宿主机内核的精简版Ubuntu

而虚拟机的Ubuntu则是一整个系统

特性容器中的操作系统虚拟机中的操作系统
内核共享宿主机的内核独立的操作系统内核
文件系统仅包含最小依赖和工具包含完整的操作系统
硬件虚拟化无硬件虚拟化,直接使用宿主机硬件资源通过 Hypervisor 虚拟化硬件
资源占用极低较高
隔离操作系统级别隔离完整操作系统级别隔离
启动速度秒级分钟级

于是不难得出以下结论:

  • Docker镜像启动很快
  • 占用比虚拟机低很多
  • 依赖Linux内核,无法运行其他系统内核的操作系统

注:你所能看到的可以运行Windows NT的Docker镜像基本都使用了QEMU虚拟机

安装

不想赘述,Docker Doc比我能写的全面多了:Portal Here

注:Windows建议使用WSL2安装(Docker Desktop本身也是调用WSL2)

打包一个环境

要求:

  • 使用Debian
  • 安装并配置Redis, Java8
  • 从宿主机复制项目
  • 导出镜像,做到开箱即用

下载官方镜像

这里以 Debian 为例

1
docker pull debian:latest

等待进度条走完,我们就有了一个debian镜像

前置准备

  1. 创建一个文件夹用来存放接下来的文件
  2. 复制你需要的文件,这里我将编译好的jar文件、jdk、redis配置文件复制过来

alt text

创建 Dockerfile

使用Dockerfile来创建镜像,方便复现环境

  1. 创建一个文件,名称为Dockerfile
  2. 输入以下文本,关键词的注释已给出
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 使用debian为基础
FROM debian:latest

# 维护者名称,这里是你的昵称
LABEL maintainer="ShenNya"

# COPY 可以让你在主机和Docker之间复制文件,./jdk-8u202-linux-x64.tar.gz为刚刚准备的jdk安装包
COPY ./jdk-8u202-linux-x64.tar.gz /tmp/jdk-8u202-linux-x64.tar.gz
 
# RUN 可以在Docker中运行命令,这里运行命令安装java
RUN tar -xvzf /tmp/jdk-8u202-linux-x64.tar.gz -C /opt/ \
&& update-alternatives --install /usr/bin/java java /opt/jdk1.8.0_202/bin/java 1

# 更新源并安装redis
RUN apt update && apt install -y maven redis-server

# ENV 可以快速配置环境变量,这里对java进行设置
ENV JAVA_HOME=/opt/jdk1.8.0_202
ENV PATH="${JAVA_HOME}/bin:${PATH}"

# 测试java
RUN java -version

# 复制jar文件和redis配置
COPY ./basis.jar /server/basis.jar
COPY ./redis.conf /etc/redis/redis.conf

# 我的jar文件是一个开放在8084端口的服务器,所以要将Docker中的8084端口“暴露”出来
EXPOSE 8084

# 运行redis和服务器
CMD redis-server /etc/redis/redis.conf & java -jar /server/basis.jar

使用 Docker 构建我们的镜像

这里的 spring-server 是你想起的镜像名称

1
docker build -t spring-server .

alt text

运行之后它会根据你的 Dockerfile 构建你的镜像,在bash中可以看到进度

如图,没有任何报错之后就成功了

测试镜像,运行到容器

使用如下命令来启动你的镜像:

1
docker run -p 8084:8084 spring-server

-p 8084:8084 可以设置对应暴露的端口

spring-server 是你的镜像名称

alt text

没有任何问题,跑起来了

导出镜像,方便迁移

导出:

1
docker save -o my-image.tar spring-server

my-image.tar 是你要导出的文件名

spring-server 是你的镜像名称


导入:

1
docker load -i my-image.tar

之后在其他电脑上就可用了!

后期管理

1
docker run some-image

每次使用这条命令后,都会生成一个容器, 这个容器才是真正在运行的环境

日常需要对容器进行管理

查看容器

你可以输入这条命令查看当前的容器:

1
docker ps

看到的内容是这样的:

1
2
3
CONTAINER ID   IMAGE                                               COMMAND                  CREATED          STATUS          PORTS                    NAMES
2fe65426a0f8   mcr.microsoft.com/devcontainers/jekyll:2-bullseye   "/bin/sh -c 'echo Co…"   23 minutes ago   Up 23 minutes                            eloquent_kepler
fd3357f3f382   spring-server                                       "/bin/sh -c 'redis-s…"   35 minutes ago   Up 35 minutes   0.0.0.0:8084->8084/tcp   reverent_pasteur

2fe65426a0f8这样的是容器ID,可以通过它来控制容器的状态

停止容器

1
docker stop <container_id>

重启容器

1
docker restart <container_id>

删除不需要的容器

1
2
3
4
# 先关停
docker stop <container_id>
# 再删除
docker rm <container_id>

进入容器进行交互

1
docker exec -it <container_id> bash

这样会进入到容器中,可以像其他linux系统一样使用它

每次运行docker run都删除旧容器

添加--rm即可自动删除旧容器

1
docker run --rm -p 8084:8084 spring-server

问题和其他

localhost问题

在我的例子中,我的MySQL运行在主机,服务器运行在Docker

如果Docker中的服务器想要连接到MySQL,使用localhost无法连接

因为此时Docker中的 localhost 指向了容器内网

对此应当使用

1
host.docker.internal

这个地址会自动解析到主机的localhost,他是 Docker 的默认网桥网络

如果想学习更高级的做法,可以使用 Docker网络 ,本文不做说明

运行交互式容器

如果不想写Dockerfile,也可以直接运行一个Debian容器

docker run时使用-it即可直接进入容器

1
docker run -it --name my-debian-container debian:bookworm bash

docker run:运行一个新的容器

-it:交互模式,进入 Shell

--name my-debian-container:为容器起一个名字(可以换成你喜欢的名字)

debian:bookworm:使用 Debian 的 Bookworm 版本

bash:在容器中运行 Bash Shell


本文由作者按照 CC BY 4.0 进行授权