Docker 与容器基础

Docker 与容器基础学习笔记

什么是容器?

容器(Container)是一种轻量级的软件运行环境,可以把应用程序及其运行所需要的环境、依赖、配置等封装在一起,使应用能够在不同的服务器环境中保持相对一致的运行方式。

传统部署经常会遇到:

复制代码
开发环境可以运行
        ↓
换一台服务器
        ↓
软件版本不同
依赖库不同
配置不同
环境不同
        ↓
程序运行失败

容器的主要目的就是解决这类"环境不一致"的问题。

可以简单理解为:

容器 = 一个被隔离的应用运行环境。

例如一个 nginx 容器中会包含 nginx 程序以及运行所需要的相关文件。


容器和虚拟机的区别

容器和虚拟机都可以实现环境隔离,但是原理不同。

虚拟机

虚拟机通过 Hypervisor 创建完整的虚拟计算机。

结构:

复制代码
物理服务器
    ↓
VMware / KVM
    ↓
虚拟机
    ↓
完整操作系统
    ↓
应用程序

每台虚拟机通常都有独立的:

  • 操作系统

  • 内核

  • 文件系统

  • 进程

  • 网络环境

因此虚拟机比较重,启动时间通常也更长。


容器

容器不会为每个容器运行一个完整的 Linux 内核,而是共享宿主机的 Linux 内核。

结构:

复制代码
物理服务器
    ↓
Linux 内核
    ↓
Docker
    ↓
┌─────────┬─────────┬─────────┐
│ nginx   │ mysql   │ redis   │
│ 容器    │ 容器    │ 容器    │
└─────────┴─────────┴─────────┘

因此容器相比虚拟机:

  • 启动速度更快

  • 占用资源更少

  • 部署更加方便

  • 更适合微服务和持续交付


容器为什么能够实现隔离?

Linux 本身提供了容器所需要的很多基础能力,Docker 在这些能力之上实现容器运行。

其中最重要的是:

复制代码
Namespace
Cgroups
分层文件系统

Namespace

Namespace 用来实现资源隔离。

例如宿主机执行:

复制代码
ps aux

可以看到大量进程。

但是进入容器后:

复制代码
docker exec -it nginx bash
ps

容器内部看到的进程数量会明显不同。

这是因为容器拥有独立的进程视图。

可以简单理解为:

复制代码
宿主机:

进程1
进程2
进程3
进程4
进程5
...

        ↓ Namespace隔离

容器:

进程1
进程2

常见 Namespace 类型包括:

  • PID Namespace:进程隔离

  • NET Namespace:网络隔离

  • MNT Namespace:文件系统挂载隔离

  • UTS Namespace:主机名隔离

  • IPC Namespace:进程间通信隔离

  • User Namespace:用户和权限隔离


Cgroups

Cgroups(Control Groups)主要负责:

控制和限制容器能够使用的系统资源。

例如一台服务器:

复制代码
CPU:8核
内存:16GB

可以限制某个容器:

复制代码
CPU:最多使用1核
内存:最多使用512MB

例如:

复制代码
docker run -d \
  --name nginx \
  --cpus=1 \
  --memory=512m \
  nginx

这样可以避免某个容器占用过多资源,影响其他服务。


容器文件系统

容器看起来像一个独立的 Linux 文件系统:

复制代码
/bin
/etc
/home
/usr
/var

但是它并不是一台真正的虚拟机。

Docker 使用分层文件系统来构建镜像和容器。

一个镜像通常由多个 Layer 组成:

复制代码
Layer 1
Layer 2
Layer 3
Layer 4
Layer 5

不同镜像可以共享相同的基础 Layer。

例如:

复制代码
                Ubuntu基础层
                     │
          ┌──────────┼──────────┐
          ↓          ↓          ↓
        nginx      MySQL      Redis

这样可以减少存储空间,并提高镜像分发效率。


Docker 是什么?

Docker 是一个用于:

构建、运行、管理和分发容器的平台。

Docker 可以完成:

复制代码
构建镜像
    ↓
保存镜像
    ↓
上传镜像
    ↓
下载镜像
    ↓
创建容器
    ↓
运行容器
    ↓
管理容器

需要注意:

复制代码
容器 ≠ Docker

容器是一种技术和运行方式。

Docker 是实现和管理容器的一套平台。


Docker 最重要的三个概念

学习 Docker 时,最重要的是理解:

复制代码
Image
Container
Registry

即:

复制代码
镜像
容器
镜像仓库

三者关系:

复制代码
镜像 Image
    ↓ docker run
容器 Container

而镜像通常保存在:

复制代码
Registry

中。


什么是 Docker Image(镜像)?

镜像可以理解为:

创建容器的模板。

例如:

复制代码
nginx:latest
ubuntu:latest
redis:latest
mysql:latest

镜像里面包含应用程序运行所需要的文件和相关配置。

例如 nginx 镜像可以理解为:

复制代码
nginx镜像
├── nginx程序
├── 配置文件
├── 依赖文件
└── 基础文件系统

查看本地镜像:

复制代码
docker images

什么是 Container(容器)?

容器是:

镜像运行之后产生的实例。

关系:

复制代码
镜像
 ↓ docker run
容器

例如:

复制代码
docker run nginx

Docker 会根据 nginx 镜像创建一个 nginx 容器,并启动 nginx 服务。

同一个镜像可以创建多个容器:

复制代码
             nginx镜像
          ┌─────┼─────┐
          ↓     ↓     ↓
       容器1   容器2   容器3

什么是 Registry(镜像仓库)?

Registry 用于存放 Docker 镜像。

常见 Registry:

复制代码
Docker Hub
Harbor
Docker Registry

Docker Hub 是公共镜像仓库。

Harbor 是企业中常见的私有镜像仓库。

例如:

复制代码
Docker Hub
    │
    ├── nginx
    ├── redis
    ├── mysql
    └── ubuntu

企业内部则可以搭建:

复制代码
Harbor
reg.example.com
    │
    ├── library/nginx
    ├── project1/web
    └── project2/mysql

Docker 镜像名称

例如:

复制代码
reg.westos.org/library/nginx:latest

可以拆成:

复制代码
reg.westos.org
        ↓
镜像仓库地址

library
        ↓
项目名称

nginx
        ↓
镜像名称

latest
        ↓
标签 Tag

完整结构:

复制代码
Registry / Project / Image : Tag

docker pull

docker pull 用来从镜像仓库下载镜像。

例如:

复制代码
docker pull nginx

默认情况下:

复制代码
nginx

相当于:

复制代码
docker.io/library/nginx:latest

即默认从 Docker Hub 的 library 项目获取 nginx。

如果指定 Harbor:

复制代码
docker pull reg.westos.org/library/nginx:latest

则表示从:

复制代码
reg.westos.org

这个 Harbor 的:

复制代码
library

项目中获取:

复制代码
nginx:latest

docker run

docker run 用于根据镜像创建并运行容器。

例如:

复制代码
docker run nginx

后台运行:

复制代码
docker run -d nginx

指定容器名称:

复制代码
docker run -d --name web nginx

完整例子:

复制代码
docker run -d \
  --name web \
  -p 8080:80 \
  nginx

含义:

复制代码
-d
后台运行

--name web
容器名称为web

-p 8080:80
宿主机8080端口映射到容器80端口

nginx
使用nginx镜像

为什么容器会停止?

容器本质上是一个被隔离的进程环境。

如果容器中的主进程结束:

复制代码
主进程退出
    ↓
容器停止

例如:

复制代码
docker run ubuntu

可能启动后很快退出。

而 nginx:

复制代码
docker run -d nginx

由于 nginx 是一个持续运行的服务,因此容器可以持续运行。


docker ps

查看正在运行的容器:

复制代码
docker ps

查看所有容器:

复制代码
docker ps -a

例如:

复制代码
CONTAINER ID
IMAGE
COMMAND
STATUS
PORTS
NAMES

进入容器

可以使用:

复制代码
docker exec -it 容器名 bash

例如:

复制代码
docker exec -it web bash

进入以后可以执行:

复制代码
ls
ps
cat /etc/os-release

退出:

复制代码
exit

exit 只是退出容器终端,不会停止容器。


Docker 网络

Docker 默认会创建一个:

复制代码
docker0

网桥。

例如:

复制代码
宿主机
192.168.150.184
       │
     docker0
  172.17.0.1
       │
 ┌─────┴─────┐
 ↓           ↓
nginx       redis
172.17.0.2 172.17.0.3

容器通常拥有自己的网络空间和 IP 地址。


端口映射

容器内部的服务通常不能直接通过宿主机端口访问。

可以使用 -p 进行端口映射。

例如:

复制代码
docker run -d -p 8080:80 nginx

表示:

复制代码
宿主机8080
      ↓
容器80
      ↓
nginx

因此浏览器访问:

复制代码
http://服务器IP:8080

最终访问的是容器中的:

复制代码
80端口

Docker 数据存储

容器本身具有临时性。

如果重要数据直接放在容器内部,删除容器后可能导致数据丢失。

因此 Docker 提供 Volume。

创建 Volume:

复制代码
docker volume create mysql-data

使用:

复制代码
docker run -d \
  -v mysql-data:/var/lib/mysql \
  mysql

结构:

复制代码
Docker Volume
      ↓
容器
      ↓
/var/lib/mysql

即使删除容器:

复制代码
docker rm mysql

Volume 中的数据仍然可以保留。


Dockerfile

Dockerfile 是:

构建 Docker 镜像的配置文件。

例如:

复制代码
FROM nginx:latest

COPY index.html /usr/share/nginx/html/

EXPOSE 80

含义:

复制代码
FROM
指定基础镜像

COPY
复制文件到镜像

EXPOSE
声明应用使用的端口

构建镜像:

复制代码
docker build -t mynginx:1.0 .

查看:

复制代码
docker images

运行:

复制代码
docker run -d -p 8080:80 mynginx:1.0

Docker 镜像完整生命周期

Docker 的核心工作流程可以总结为:

复制代码
             Dockerfile
                  ↓
             docker build
                  ↓
               Image
                  ↓
          ┌───────┴───────┐
          ↓               ↓
     docker run       docker push
          ↓               ↓
      Container        Registry
                          │
                   ┌──────┴──────┐
                   ↓             ↓
               Docker Hub      Harbor
                                  │
                                  ↓
                             docker pull
                                  ↓
                              Container

企业实际部署流程

实际企业中,一个应用从开发到上线通常可以理解为:

复制代码
开发代码
   ↓
编写 Dockerfile
   ↓
docker build
   ↓
生成 Image
   ↓
docker tag
   ↓
docker push
   ↓
Harbor
   ↓
生产服务器 docker pull
   ↓
docker run / docker compose
   ↓
Container
   ↓
应用上线

如果使用 CI/CD,还可以进一步自动化:

复制代码
Git
 ↓
CI/CD
 ↓
Docker Build
 ↓
镜像
 ↓
Harbor
 ↓
服务器
 ↓
Docker Compose / Kubernetes
 ↓
应用运行

常用 Docker 命令总结

镜像相关

复制代码
docker images

查看镜像。

复制代码
docker pull nginx

下载镜像。

复制代码
docker rmi nginx

删除镜像。

复制代码
docker tag nginx:latest myrepo/nginx:latest

给镜像重新打标签。

复制代码
docker build -t myapp:1.0 .

构建镜像。

复制代码
docker push myrepo/nginx:latest

上传镜像。


容器相关

复制代码
docker run nginx

创建并运行容器。

复制代码
docker run -d nginx

后台运行。

复制代码
docker ps

查看运行中的容器。

复制代码
docker ps -a

查看所有容器。

复制代码
docker stop nginx

停止容器。

复制代码
docker start nginx

启动已有容器。

复制代码
docker restart nginx

重启容器。

复制代码
docker rm nginx

删除容器。

复制代码
docker exec -it nginx bash

进入容器。

复制代码
docker logs nginx

查看容器日志。


网络相关

复制代码
docker network ls

查看 Docker 网络。

复制代码
docker port nginx

查看容器端口映射。

复制代码
docker run -d -p 8080:80 nginx

进行端口映射。


Volume

复制代码
docker volume ls

查看 Volume。

复制代码
docker volume create data

创建 Volume。

复制代码
docker volume inspect data

查看 Volume 信息。


Compose

复制代码
docker compose up -d

启动所有服务。

复制代码
docker compose ps

查看服务状态。

复制代码
docker compose images

查看服务使用的镜像。

复制代码
docker compose logs

查看日志。

复制代码
docker compose down

停止并删除 Compose 创建的容器。


最终理解

学习 Docker 时,可以始终记住下面这条主线:

复制代码
Dockerfile
   ↓
docker build
   ↓
Image(镜像)
   ↓
Registry(仓库)
   ↓
docker pull
   ↓
docker run
   ↓
Container(容器)
   ↓
Application(应用)

而在企业环境中:

复制代码
开发
 ↓
构建镜像
 ↓
Harbor
 ↓
服务器
 ↓
Docker
 ↓
容器
 ↓
应用

最核心的概念可以记成:

复制代码
镜像 = 模板
容器 = 镜像运行后的实例
Registry = 存放镜像的仓库
Docker = 管理容器和镜像的平台
Harbor = 企业常用的私有镜像仓库
Docker Compose = 管理多个容器的工具
Dockerfile = 构建镜像的说明书
Volume = 持久化容器数据
Network = 负责容器之间以及容器与外部之间的通信
相关推荐
梦梦代码精6 小时前
《回收租赁系统技术选型避坑指南:业务闭环与二开自由度详解》
开发语言·低代码·docker·开源·代码规范
_itgo7 小时前
意图识别落地方案
运维·docker·容器
fangjianj7 小时前
LAMP 项目部署
linux
mengge.cloud7 小时前
0909华为云计算类综合服务小白实验教程
linux·运维·服务器·网络·华为云·云计算
fangjianj8 小时前
自有服务及软件包
linux
QYR-分析9 小时前
蓝海赛道高速扩容!全球小型观察ROV市场格局、细分场景与发展趋势分析
大数据·运维·云计算
陈皮糖..9 小时前
从零搭建一个简易 AI 运维问答机器人(RAG + LangChain + Streamlit)
运维·人工智能·ai·langchain·机器人
风哥2号10 小时前
数据库教程FGMT03‑生产环境Linux+Oracle19c+ASM安装配置与项目实战
linux·数据库
一木 之林10 小时前
七、一-AI 工程实践、插件化调试与软件交付
java·linux·c++