容器化技术

容器化技术

  1. 什么是容器化技术?优势是什么?
  • 定义:容器化技术是一种操作系统级虚拟化技术,通过将应用程序及其依赖(如库、配置文件)打包成一个独立的 “容器”,实现应用在不同环境(开发、测试、生产)中的一致性运行。容器共享宿主机内核,无需模拟硬件或安装完整操作系统,因此轻量且高效。
  • 核心优势
    • 轻量便捷
    • 环境一致
    • 资源高效
    • 快速扩展
  1. 容器与镜像?
维度 镜像(Image) 容器(Container)
本质 只读的文件系统模板 镜像的运行时实例,可读写
状态 静态(存储在磁盘) 动态(运行在内存,有进程、网络等)
关系 镜像 → 容器(通过docker run创建) 容器停止后,可提交为新镜像(docker commit
示例 nginx:latest(存储在本地仓库) 运行中的 Nginx 容器(对外提供 80 端口服务)

通俗理解

  • 镜像类似 “安装包”,容器类似 “正在运行的软件”。
  • 一个镜像可启动多个容器(如用nginx:latest启动 10 个 Nginx 实例,负载均衡流量)。
  1. 容器与虚拟机的区别?
维度 容器(Container) 虚拟机(VM)
架构 共享宿主机内核(无 Guest OS) 每个 VM 包含完整 Guest OS(如 Ubuntu、Windows Server)
资源占用 极低(MB 级内存,秒级启动) 高(GB 级内存,分钟级启动)
隔离性 进程级隔离(通过命名空间 / Cgroups) 硬件级隔离(更彻底,但开销大)
性能 接近宿主机原生性能(损耗 5-10%) 性能损耗 20-30%(因模拟硬件)
适用场景 微服务、CI/CD、快速迭代 传统应用、多租户隔离、需 Guest OS 的场景

典型场景对比

  • 容器:开发环境快速测试(如用 Docker 启动 MySQL 测试数据)、Kubernetes 集群部署微服务。
  • 虚拟机:运行老旧系统(如 Windows XP)、需硬件虚拟化的场景(如运行 Docker inside VM)。
  1. 容器的底层技术是什么?
  • 容器依赖Linux 内核的三大核心技术,实现隔离与资源限制:
    • 命名空间(Namespaces)
    • 控制组(Cgroups)
    • 联合文件系统(UnionFS)

Docker简介

容器化技术:一种操作系统级虚拟化技术;简单理解为“微型的虚拟机”;

  1. 实现应用间隔离运行;
  2. 实现应用的一键“打包”,将应用服务、依赖环境打包成镜像;
  3. 让应用可以在不同的系统环境中拥有一致的运行环境;
  4. 对容器进行资源限制;
  5. 一键运行容器;

Docker

  • 使用go语言开发的容器管理工具,容器运行时(Container Run Time);
  • 同类应用:RUNC、Podman、Containerd、LXc、rkt、CRI-0
  • Docker 诞生于 2013年初,最初是 dotcloud 公司内部的
    一个业余项目。

容器和镜像

  • 容器:一个运行中的镜像,类似与一个进程;
  • 镜像:容器的模板,是静态文件,类似一个安装包;

镜像仓库:存放各种镜像的下载站点;官方docker hub;公司内部可以搭建私有仓库;

容器和虚拟机的区别:

虚拟机
image

  • 优点:
    • 应用程序运行环境强隔离
    • 虚拟机操作系统与底层操作系统无关化
    • 虚拟机内部操作不会影响到物理机
  • 缺点:
    • 拥有操作系统会占用部署资源及存储
    • 网络传输效率低
    • 当应用程序需要调用硬件响应用户访问时间延迟大

容器
image

  • 优点:
    • 可以实现应用程序的隔离
    • 直接使用物理机的操作系统可以快速响应用户请求
    • 不占用部署时间
    • 占用少量磁盘空间

Docker的底层技术:

  • Namespaces:Linux内核中提供命名空间功能,隔离进程、网络、文件系统;
  • Cgroups:资源限制,cpu、内存;
  • OverlayFS:镜像文件分层系统;

Docker可以做什么:

  • 快速部署应用服务;

  • 可以统一开发、测试、生成环境,避免由于环境问题导致的服务运行异常;

  • Docker的特点:

    • 容器化
    • 轻量级
    • 可移植性
    • 版本控制和组件复用
    • 隔离性
    • 易于扩展
  • Docker 的核心组件:

    1. Docker 引擎(Docker Engine):负责创建和管理 Docker 容器的核心组件。
    2. Docker 镜像(Docker Image):包含了应用运行所需的所有内容,如代码、运行时、库、环境变量和配置文件等。
    3. Docker 容器(Docker Container):Docker 镜像的运行实例,可以启动、停止、移动和删除。
    4. Docker 仓库(Docker Registry):用于存储和分发 Docker 镜像,最常见的公共仓库是 Docker Hub。
    5. Docker Compose:一个工具,允许开发者通过 YAML 文件定义和运行多容器 Docker 应用。
    6. Docker Swarm:Docker 自带的本地集群管理工具,支持多节点容器编排。

安装Docker

#卸载残留Docker软件包
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done
#更新软件包
sudo apt update
#升级已安装软件包(可选)
#sudo apt upgrade

#安装Docker依赖
apt-get -y install ca-certificates curl gnupg lsb-release
#添加Docker国内GPG密钥
# 最终回显OK表示运行命令正确
curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
#添加Docker软件源
# 需要管理员交互式按一下回车键
sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
#安装Docker
apt-get -y install docker-ce docker-ce-cli containerd.io

#验证 Docker 是否安装成功
sudo docker --version
sudo docker run hello-world  # 运行测试容器,显示 "Hello from Docker!" 即正常
  • 配置Docker镜像加速
#置docker配置文件,默认没有
# registry-mirrors设置国内镜像站,加速下载镜像
vim /etc/docker/daemon.json

{
 "registry-mirrors": [
    "https://0c105db5188026850f80c001def654a0.mirror.swr.myhuaweicloud.com",
    "https://5tqw56kt.mirror.aliyuncs.com",
    "https://docker.1panel.live",
    "http://mirrors.ustc.edu.cn",
    "http://mirror.azure.cn",
    "https://hub.rat.dev",
    "https://docker.chenby.cn",
    "https://docker.hpcloud.cloud",
    "https://docker.m.daocloud.io",
    "https://docker.unsee.tech",
    "https://dockerpull.org",
    "https://dockerhub.icu",
    "https://proxy.1panel.live",
    "https://docker.1panel.top",
    "https://docker.1ms.run",
    "https://docker.ketches.cn"
  ],
  "insecure-registries": [
    "http://192.168.57.200:8099"
   ]
}

#重载docker服务、重启docker生效配置
systemctl daemon-reload
systemctl restart docker

Docker常用命令

镜像常用命令:

 #查找镜像
docker search ubuntu            

#下载镜像
docker pull 镜像:版本           

#查看本地的镜像
docker images

#命令获取所有镜像的 ID
docker images -aq

#删除所有镜像
docker rmi $(docker images -aq)

#批量导入所有镜像
for img in 'ls *.tar';do docker load -i $img;done

#将镜像保存为压缩文件
docker save 镜像:版本 -o 镜像.tar    

#删除镜像
docker rmi 镜像名                   

#加载压缩的镜像文件到本地镜像仓库
docker load -i 镜像.tar            

#查看镜像的详细信息
docker inspect 镜像:版本    
  

容器管理命令:

#查看正在运行的容器
docker ps

#查看运行与曾经运行过的容器
docker ps -a

#使用镜像运行容器
docker yun
#参数
--name  		   #指定容器名称
-i      		   #交互式启动
-t      		   #分配终端
-d      		   #后台执行容器
-v = --volume      #目录映射 真机路径:容器路径
-p 				   #指定端口映射 真机端口:容器端口
-P                 #随机端口
-e                 #设置容器中的环境变量
--network          #指定网络模式
--rm               #容器停止时,自动删除容器和容器中的数据
-u                 #以什么用户身份创建容器
-h                 #指定容器的主机名,默认容器ID号的前N位
-m                 #设置容器内存的最大值
#使用格式
docker run --name nginx-01 -itd -p80:80 nginx:1.26

#进入容器,执行命令与操作
docker exec -it nginx-01 /bin/bash

#将修改好内容的容器导出成镜像文件
docker export -o mynginx.tar nginx-01

#将镜像容器生成的文件导入本地镜像仓库
docker import mynginx.tar mynginx:1.0

#直接将容器生成镜像到本地仓库
docker commit nginx-01 mynginx:2.0

#停止容器
docker stop nginx-01

#删除容器
docker rm nginx-01

#docker cp 复制

#将主机/data目录拷贝到容器96f7f14e99ab中,目录重命名为/www
docker cp /data 96f7f14e99ab:/www
# 将容器96f7f14e99ab的/www目录拷贝到主机的/tmp目录中
docker cp  96f7f14e99ab:/www /tmp/

仓库管理命令:

#登陆仓库
docker login http://192.168.57.200
账号:admin
密码:root123

#修改镜像标签名
docker tag h5-game:1.0 192.168.57.200/yun11/h5-game:1.0

#将镜像上传到私有镜像站
docker push 192.168.57.200:8099/yun11/h5-game:1.0
#下载 MySQL最新版本
docker pull mysql:latest
#运行MySQL容器
mkdir -p /data/mysql/data
docker run -itd --name mysql-test \
           -p 3306:3306 \
           -e MYSQL_ROOT_PASSWORD=123456 \
           -v /data/mysql/data:/var/lib/mysql \
           --restart=always \
           mysql
#启动后台容器(端口映射)
docker run -d -p 80:80 --name mynginx nginx
#查看运行容器
docker ps
#进入容器 bash
docker exec -it mynginx /bin/bash
#查看容器日志
docker logs -f mynginx
#停止
docker stop mynginx
#启动已停止的容器
docker start [容器名/ID]
#重启容器
docker restart [容器名/ID]
#删除已停止的容器
docker rm [容器名/ID]
#清理无用资源
docker system prune -a
#查看本地所有镜像
docker images
#删除本地镜像
docker rmi [镜像名/ID]
#查看容器的IP地址
docker inspect mysql-master | grep "IPAddress"

#docker限制容器CPU
#创建容器mycentos1,分配1024的cpu权值,并进入容器
docker run --name mycentos1 --cpu-shares 1024 -it centos /bin/bash
#查看容器分配的CPU权值
[root@87476ea8bd94 /]# cat /sys/fs/cgroup/cpu/cpu.shares
1024

#创建mycentos1容器,cpu权值1024,只允许在宿主机的cpu1和cpu0上运行
docker run -it --name mycentos1 
--cpu-shares 1024 
-v /etc/yum.repos.d:/etc/yum.repos.d 
--cpuset-cpus 0,1 
centos /bin/bash

#docker限制容器内存
#创建一个只允许容器内存最多使用128M
docker run --name mycentos3 -it -m 128M centos /bin/bash
#查看容器的内存限制 
cat /sys/fs/cgroup/memory/memory.limit_in_bytes

Docker实战

Docker单机安装部署MySQL一主二从集群

#拉取MySQL镜像
docker pull mysql:8.0.20

#Master主库安装
docker run -p 3306:3306 --name mysql-master \
-v /mydata/mysql-master/log:/var/log/mysql \
-v /mydata/mysql-master/data:/var/lib/mysql \
-v /mydata/mysql-master/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=123456 -d mysql

#slave1从库安装
docker run -p 3307:3306 --name mysql-slave1 \
-v /mydata/mysql-slave1/log:/var/log/mysql \
-v /mydata/mysql-slave1/data:/var/lib/mysql \
-v /mydata/mysql-slave1/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=123456 -d mysql

#slave2从库安装
docker run -p 3308:3306 --name mysql-slave2 \
-v /mydata/mysql-slave2/log:/var/log/mysql \
-v /mydata/mysql-slave2/data:/var/lib/mysql \
-v /mydata/mysql-slave2/conf:/etc/mysql/conf.d \
-e MYSQL_ROOT_PASSWORD=123456 -d mysql

#检测容器是否运行成功
docker ps

#创建主库配置文件
vim /mydata/mysql-master/conf/my.cnf

[mysql]
default-character-set=utf8mb4
[mysqld]
#设置server_id,同一局域网中需要唯一
server_id=20
#指定不需要同步的数据库名称 binlog-do-db 为需要同步的数据库
binlog-ignore-db=mysql
#开启二进制日志功能
log-bin=micro-mysql-bin
## 设置二进制日志使用内存大小(事务)
binlog_cache_size=1M
## 设置使用的二进制日志格式(mixed,statement,row)
binlog_format=mixed
## 二进制日志过期清理时间。默认值为0,表示不自动清理。
binlog_expire_logs_seconds=604800

-----------------------
#使用指令重启容器使用配置生效 
docker restart mysql-master

#进入主MySQL的容器
docker exec -it mysql-master /bin/bash

#进入数据库
mysql -u root -p123456

#创建名slave为用户供从库连接
CREATE USER 'slave'@'%' IDENTIFIED BY '123456';
#授权表示可以从任意ip使用此用户名和密码连接到主数据库
GRANT REPLICATION SLAVE ON *.* to 'slave'@'%';
#刷新配置
FLUSH PRIVILEGES;
#退出MySQL和主容器
exit

#设置从库mysql-slave1配置文件
vim /mydata/mysql-slave1/conf/my.cnf

[mysql]
default-character-set=utf8mb4
[mysqld]
#设置server_id
server_id=17
#指定不需要同步的数据库名称
binlog-ignore-db=mysql 
#开启二进制日志功能,以备Slave作为其它数据库实例的Master时使用
log-bin=micro-mysql-slave-bin 
#设置二进制日志使用内存大小(事务)
binlog_cache_size=1M 
#设置使用的二进制日志格式(mixed,statement,row)
binlog_format=mixed 
#二进制日志过期清理时间。默认值为0,表示不自动清理。
binlog_expire_logs_seconds=604800 
#relay_log配置中继日志
relay_log=micro-relay-log-bin
#log_slave_updates表示slave将复制事件写进自己的二进制日志
log_slave_updates=1 
#slave设置为只读(具有super权限的用户除外)
read_only=1

----------------------------------------

#设置从库mysql-slave2配置文件
vim /mydata/mysql-slave2/conf/my.cnf

[mysql]
default-character-set=utf8mb4
[mysqld]
#设置server_id
server_id=18
#指定不需要同步的数据库名称
binlog-ignore-db=mysql 
#开启二进制日志功能,以备Slave作为其它数据库实例的Master时使用
log-bin=micro-mysql-slave-bin 
#设置二进制日志使用内存大小(事务)
binlog_cache_size=1M 
#设置使用的二进制日志格式(mixed,statement,row)
binlog_format=mixed 
#二进制日志过期清理时间。默认值为0,表示不自动清理。
binlog_expire_logs_seconds=604800 
#relay_log配置中继日志
relay_log=micro-relay-log-bin
#log_slave_updates表示slave将复制事件写进自己的二进制日志
log_slave_updates=1 
#slave设置为只读(具有super权限的用户除外)
read_only=1

--------------------------------------------------

#使用指令重启容器使用配置生效 
docker restart mysql-slave1
docker restart mysql-slave2

#启动Slave从库复制

#进入主MySQL的容器
docker exec -it mysql-master /bin/bash
#进入数据库
mysql -u root -p123456
#获取binlog日志名称
SHOW BINARY LOG STATUS;
#退出
exit

#查看主库容器的IP地址
docker inspect mysql-master | grep "IPAddress"

#进入对应从库,配置主从
#进入从MySQL-slave1的容器
docker exec -it mysql-slave1 /bin/bash
#进入数据库
mysql -u root -p123456
#编辑主从
CHANGE REPLICATION SOURCE TO
SOURCE_HOST='172.17.0.2',
SOURCE_USER='slave',
SOURCE_PASSWORD='123456',
SOURCE_LOG_FILE='micro-mysql-bin.000003',
SOURCE_LOG_POS=859,
SOURCE_CONNECT_RETRY=30,
SOURCE_PORT=3306,
GET_SOURCE_PUBLIC_KEY=1;
#启动主从复制
START REPLICA;
#查看主从是否成功
SHOW REPLICA STATUS\G

#进入从MySQL-slave2的容器
docker exec -it mysql-slave2 /bin/bash
#进入数据库
mysql -u root -p123456
#编辑主从
CHANGE REPLICATION SOURCE TO
SOURCE_HOST='172.17.0.2',
SOURCE_USER='slave',
SOURCE_PASSWORD='123456',
SOURCE_LOG_FILE='micro-mysql-bin.000003',
SOURCE_LOG_POS=859,
SOURCE_CONNECT_RETRY=30,
SOURCE_PORT=3306,
GET_SOURCE_PUBLIC_KEY=1;
#启动主从复制
START REPLICA;
#查看主从是否成功
SHOW REPLICA STATUS\G

#测试验证
#主库新建test
#进入主MySQL的容器
docker exec -it mysql-master /bin/bash
#进入数据库
mysql -u root -p123456

#创建test库
create database test;
#进入test库
use test;
#创建表
CREATE TABLE `student` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT 'ID',
  `name` varchar(50) NOT NULL COMMENT '姓名',
  `gender` varchar(10) NOT NULL COMMENT '性别',
  `birthday` date NOT NULL COMMENT '生日',
  `address` varchar(100) NOT NULL COMMENT '地址',
  `phone` varchar(20) NOT NULL COMMENT '电话',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='学生表';
#插入数据
INSERT INTO `student` (`id`, `name`, `gender`, `birthday`, `address`, `phone`) 
VALUES (1, '张三', '男', '2023-06-16', '北京市朝阳区', '13700137000');

INSERT INTO `student` (`id`, `name`, `gender`, `birthday`, `address`, `phone`) 
VALUES (2, '李四', '女', '2023-06-16', '上海市浦东新区', '13800126000');
#查看表数据
SELECT * FROM `student`;

#去验证Slave1从库和Slave2从库是否已经完成复制
#进入从MySQL-slave1的容器
docker exec -it mysql-slave1 /bin/bash
#进入数据库
mysql -u root -p123456
#选择数据库
use test;
#查询表信息
SELECT * FROM `student`;

#进入从MySQL-slave2的容器
docker exec -it mysql-slave2 /bin/bash
#进入数据库
mysql -u root -p123456
#选择数据库
use test;
#查询表信息
SELECT * FROM `student`;

Docker安装项目:Blog、电商、游戏、网盘、视频网站

#部署 简单文件视频服务器
# 创建视频存放目录
sudo mkdir -p /home/videos

# 设置权限(确保Docker可以访问)
sudo chmod 777 /home/videos

#启动视频服务器容器
docker run -d \
  --name video-server \
  -p 8080:80 \
  -v /home/videos:/usr/share/nginx/html \
  --restart unless-stopped \
  nginx:alpine
  
# 创建一个测试页面
echo "<h1>我的视频服务器</h1><p>将视频文件放入 /home/videos 目录即可在线播放</p>" > /home/videos/index.html

# 或者下载一个测试视频(可选)
cd /home/videos
# wget 一个测试视频文件(如果有网络的话)

#访问与使用
打开网页:浏览器访问 http://192.168.25.55:8080  
  • 通过Docker命令创建一个自己的镜像

Docker网络

c
docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
3d6931b616e5   bridge    bridge    local
b8476dbfc093   host      host      local
b50c7fe1d3c6   none      null      local

#bridge 桥接模式(默认模式),创建docker0网卡,每个容器都有一个自动分配对的IP地址,建立虚拟局域网,容器间IP+port通信,外部访问容器通过宿主机的IP+port,端口映射;

#host 主机模式,让容器直接使用主机的网络(IP地址和端口),优点:网络效率最高;缺点:会占用主机端口

#none 无网络模式,不联网,没用IP

#Overlay Network 层叠网络,跨主机通讯,vxlan(隧道技术),容器的集群部署中使用该模式

#查看当前的docker网络
docker network ls
#创建docker虚拟网络 桥接模式
docker network create test-network -d bridge
#使用docker网络,启动容器时,指定--network=参数 
docker run -itd --network=test-network --name mynginx nginx:1.26
#将容器添加到网络中
docker network connect test-network 容器名称/ID
#当docker网络不被使用时可以删除,先把使用该网络的容器停止删除后删除网络
docker network rm test-network

Docker存储

docker 数据卷(Data Volume)是一个可供容器使用的特殊目录,它将主机操作系统目录直接映射进容器,类似于 Linux 的 mount 操作。

数据卷创建、挂载、删除、数据共享

  • docker volume create 数据卷名称

    • 默认会存放在目录:/var/lib/docker/volumes/数据卷名称/
  • 直接使用系统目录作为数据卷

    • -v 系统目录:容器目录
#查看所有数据卷
docker volume ls
#创建数据卷 test_l1
docker volume create test_l1

#目录挂载:(以主机文件为主)
-v /app/nghtml:/usr/share/nginx/html
#卷映射:(以容器内文件为主)
-v ngconf:/etc/nginx

#在运行容器时直接挂载数据卷
docker run --name mynginx-01 -v test_l1:/etc/nginx -p 8080:80 nginx:1.26
#两个容器共享一个数据卷
docker run --name mynginx-02 -v test_l1:/etc/nginx -p 9090:80 nginx:1.26
#查看数据卷详情
docker volume inspect 数据卷名称
#删除数据卷 需确保没有任何容器正在使用该数据卷
docker volume rm 数据卷名称

DockerFile

一键创建镜像

通过编写Dockerfile,可以将环境配置、应用程序代码、依赖关系等打包成一个镜像,便于快速创建容器

image

Dockerfile常用指令
指令 功能
FROM 指定基础镜像(父镜像)
LABEL 添加新建镜像的元数据(作者、邮箱、简介)
RUN 在容器中执行linux命令
ENV 在容器中设置环境变量
ADD 复制本地文件自动解压缩,支持URL下载
COPY 只有复制功能
VOLUME 指定持久化目录
CMD 容器启动时执行的命令,会被运行的命令覆盖
ENTRYPOINT 容器启动时执行的命令,不会被运行的命令覆盖
WORKDIR 工作目录,等价于执行cd命令
EXPOSE 指定对外暴露的端口
2.1 FROM:指定基础镜像
#指定构建新镜像时使用的基础镜像,通常必须是Dockerfile的第一个有效指令
# 格式
FROM <image:[版本标签]>

# 指定基础镜像
FROM centos:7
FROM ubuntu:22.04

# 说明:如果不指定版本标签,默认使用latest
------------------------------------------------------------------------------------------------------------------
2.2 LABEL:添加镜像的元数据
#LABEL一般使用键值对方式。

# 格式
LABEL <key>=<value> <key>=<value>....

# 为镜像添加元数据
LABEL version="2.0" description="业务系统第二个版本"

# 说明:一条LABEL可以指定多条元数据,尽量不要写多个LABEL
------------------------------------------------------------------------------------------------------------------
2.3 RUN:构建镜像时执行的命令
#有两种执行方式
方式一:shell执行

# 格式
RUN <command>

# 示例
RUN yum update -y

# 说明:RUN 指令创建的中间镜像会被缓存,并在下次构建中使用。可以在构建时使用--no-cache取消缓存:
docker build --no-cache
方式二:exec执行

# 格式:
RUN ["executable", "参数1", "参数2"]

# 示例
RUN ["/bin/bash", "-c", "echo hello"]
------------------------------------------------------------------------------------------------------------------
2.4 ENV:在容器内部设置环境变量
# 格式
ENV <key> <value>

# 示例
ENV MYPATH /usr/local
------------------------------------------------------------------------------------------------------------------
2.5 ADD:将本地文件添加到镜像中
#相当于scp。只是scp 需要将用户名和密码的权限验证,而ADD 不用。
#tar 类型文件会自动解压,可以访问网络资源,类似 wget

# 语法
ADD <src> <dest>
ADD ["src", "dest"]

# 示例
ADD nginx.tar /opt

# 说明:路径可以是相对路径或绝对路径,建议使用绝对路径。
# 尽量不要把<src> 写成一个文件夹,如果<src> 是一个文件夹,复制整个目录的内容
------------------------------------------------------------------------------------------------------------------
2.6 COPY:将文件或目录复制到镜像中。
#功能类似 ADD,但不会自动解压文件,也不能访问网络资源

# 语法
COPY <src> <dest>
COPY ["<src>", "<dest>"]
#与 ADD 区别,COPY 的只能是本地文件,其他用法一致
------------------------------------------------------------------------------------------------------------------
2.7 VOLUME:指定持久化目录
#VOLUME 指令用于在镜像中创建一个挂载点(mount point),并且声明该挂载点应该被 Docker 主机或其他容器共享的卷(volume)覆盖。
#VOLUME 指令的主要目的是为了在多个容器之间共享数据,或者为了持久化数据(即使容器被删除,数据仍然保留在宿主机上)。

# 格式
VOLUME ["/path/to/dir"]
或者
VOLUME /path/to/dir

# 示例
VOLUME ["/data"]
VOLUME ["/data/log", "/data/config"]
# 一个卷可以存在于一个或多个容器的指定目录,该目录可以绕过联合文件系统
# /data 是容器内的一个目录路径,Docker 会在这个路径上创建一个挂载点。
----------------------------------------------------------------------------------------------------------------
2.8 CMD:容器启动时运行的命令(不常用)
# 语法
CMD ["executable","param1","param2"]
CMD command param1 param2

# 示例
CMD echo $LANG
----------------------------------------------------------------------------------------------------------------
2.9 ENTRYPOINT:容器启动时运行的命令(常用)
# 语法
ENTRYPOINT ["executable", "param1", "param2"] 
ENTRYPOINT command param1 param2

# 示例
ENTRYPOINT java -jar /data/config.jar

#ENTRYPOINT和CMD的异同点:
#相同点:

(1)只能写一条,如果写了多条,那么只有最后一条生效

(2)容器启动时才运行,运行时机相同

#不同点:

(1)ENTRYPOINT不会被运行的command覆盖,而CMD则会被覆盖

(2)如果我们在Dockerfile种同时写了ENTRYPOINT和CMD,并且CMD指令不是一个完整的可执行命令,那么CMD指定的内容将会作为ENTRYPOINT的参数
----------------------------------------------------------------------------------------------------------------
2.10 EXPOSE:暴露容器运行时的监听端口给外部
# 格式:
EXPOSE <port> [<port>...]

# 示例:
EXPOSE 8080
EXPOSE 443/tcp 80/tcp
#注意:
#EXPOSE 并不会让容器的端口访问到主机。在运行时使用随机端口映射时,也就是 docker run -P 时,会自动随机映射 EXPOSE 的端口
#如果没有暴露端口,后期也可以通过docker run -p 8080:8080 方式映射端口,但不能通过 -P 形式映射
----------------------------------------------------------------------------------------------------------------
2.11 WORKDIR:工作目录
#功能类似cd命令。后续指令将在该目录中执行。若WORKDIR指定的目录不存在,则Docker会自动创建。
----------------------------------------------------------------------------------------------------------------

使用Dockerfile制作MySQL镜像
#创建一个dockerfile文件
vim dockerfile
#在文件里编辑内容
FROM ubuntu:22.04
RUN apt update 
RUN apt install -y vim
RUN apt install mysql-server -y

ENV MYSQL_ROOT_PASSWORD=root123
COPY ./my.cnf /etc/mysql/conf.d/custom-my.cnf
ENTRYPOINT service mysql start
EXPOSE 3306
---------------------------------------------------------
#编辑自定义MySQL配置
vim my.cnf

[mysqld]
# 字符集:支持emoji,彻底解决中文乱码
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
init_connect='SET NAMES utf8mb4'

# 连接优化:适配中小型应用并发
max_connections=1000
wait_timeout=600
interactive_timeout=600
connect_timeout=10

# 日志:便于排查慢查询(可选,按需开启)
slow_query_log=1
slow_query_log_file=/var/lib/mysql/slow.log
long_query_time=5  # 执行超5秒的查询记录到慢日志

# 存储引擎:默认InnoDB(支持事务)
default-storage-engine=InnoDB
innodb_buffer_pool_size=256M  # 缓存池大小(根据服务器内存调整)

[mysql]
# 客户端默认字符集
default-character-set=utf8mb4
---------------------------------------------------------

#制作镜像
docker build -t my-mysql .

#等待编译完成可以使用镜像
docker 各种搭建

#Docker搭建复古中文 DOS 游戏
docker run -d --name dosgame -p 262:262 oldiy/dosgame-web-docker:latest
#访问http://ip:262即可
------------------------------------------------------------------------------------------------------------------
#Docker搭建一款开源的个人在线音乐平台
sudo docker pull foamzou/melody
sudo docker run -d -p 5566:5566  -v ~/melody-profile:/app/backend/.profile foamzou/melody:latest
#访问http://ip:5566即可
------------------------------------------------------------------------------------------------------------------
#Docker搭建网页版VScode
sudo docker pull codercom/code-server
sudo docker run -d -p 8080:8080 -e PASSWORD=123456 codercom/code-server
#访问http://ip:8080即可
------------------------------------------------------------------------------------------------------------------
#Docker搭建可视化管理面板dpanel
docker run -it -d --name dpanel --restart=always \
 -p 80:80 -p 443:443 -p 8807:8080 \
 -v /var/run/docker.sock:/var/run/docker.sock \
 -v dpanel:/dpanel -e APP_NAME=dpanel dpanel/dpanel:latest
#访问http://ip:8080即可
------------------------------------------------------------------------------------------------------------------
#Docker搭建一款轻量级&好用的个人云盘

mkdir -p /data/jmalcloud  && cd /data/jmalcloud

docker run \
--restart=always \
--name jmalcloud \
-p 9070:80 \
-p 9071:8080 \
-p 9072:8088 \
-p 27017:27017 \
-v /data/jmalcloud/files/:/jmalcloud/files/ \
-v /data/jmalcloud/db/:/data/db/ \
-d registry.cn-guangzhou.aliyuncs.com/jmalcloud/jmalcloud:2.2.35
---------------------------------------------------------
#Docker-compose创建服务
version: '3'
services:
  jmalcloud:
    image: registry.cn-guangzhou.aliyuncs.com/jmalcloud/jmalcloud:2.2.35
    restart: always
    ports:
      - 9070:80
      - 9071:8080
      - 9072:8088
      - 27017:27017
    volumes:
      - /data/jmalcloud/files/:/jmalcloud/files/
      - /data/jmalcloud/db/:/data/db/

#启动项目
docker-compose up -d
#访问http://ip:9即可

DockerCompose

单机容器编排,一键批量管理多个容器

使用yaml格式 Docker-compose.yml

version: '3.8'

# 定义服务(Nginx + MySQL)
services:
  # 1. Nginx 服务
  nginx:
    image: nginx:1.26
    container_name: my-nginx
    ports:
      - "80:80"  # 宿主机80端口映射到容器80
    volumes:
      # 挂载自定义网页目录(宿主机 ./nginx/html → 容器 /usr/share/nginx/html)
      - ./nginx/html:/usr/share/nginx/html
      # 挂载自定义配置文件(覆盖容器默认配置)
      - ./nginx/conf/default.conf:/etc/nginx/conf.d/default.conf
      # 挂载日志卷(全局定义的 nginx-logs)
      - nginx-logs:/var/log/nginx
    restart: always  # 容器退出自动重启
    depends_on:
      - mysql  # 依赖 mysql 服务,mysql 启动后再启动 nginx
    networks:
      - my-network  # 加入自定义网络

  # 2. MySQL 服务
  mysql:
    image: mysql:8.0
    container_name: my-mysql
    ports:
      - "3306:3306"
    volumes:
      # 挂载数据卷(全局定义的 mysql-data,实现数据持久化)
      - mysql-data:/var/lib/mysql
      # 挂载初始化脚本(容器启动时自动执行 SQL)
      - ./mysql/init:/docker-entrypoint-initdb.d
    environment:
      # 环境变量:设置 root 密码、默认数据库
      MYSQL_ROOT_PASSWORD: root123
      MYSQL_DATABASE: my_app_db
    restart: always
    networks:
      - my-network  # 与 nginx 同网络,可通过服务名 `mysql` 通信

# 全局数据卷(供服务复用)
volumes:
  nginx-logs:  # Nginx 日志卷
  mysql-data:  # MySQL 数据卷(删除容器后数据不丢失)

# 自定义网络(服务间通信)
networks:
  my-network:
    driver: bridge
docker compose 常用命令
命令 说明
docker-compose up 启动所有服务(加 -d 后台运行:docker-compose up -d
docker-compose down 停止并删除所有服务、网络(加 -v 同时删除数据卷:docker-compose down -v
docker-compose ps 查看所有服务状态
docker-compose logs 查看服务日志(加服务名:docker-compose logs nginx 查看指定服务)
docker-compose build 构建 services 中用 build 定义的自定义镜像

Docker私有镜像站-Harbor

私有镜像站,方便管理,下载部署内部的镜像

搭建私有镜像站 harbor
cd /opt
#下载harbor安装压缩包
wget http://192.168.57.200/Software/harbor-offline-installer-v2.14.0.tgz
#解压
tar -xvf harbor-offline-installer-v2.14.0.tgz
#进去解压出来的harbor目录
cd harbo
#复制一份.yml文件
cp harbor.yml.tmpl harbor.yml
#编辑.yml文件 对需要的内容进行修改
vim harbor.yml

hostname   #改成自己的IP
passwrod
ssl

#编辑/etc/docker/daemon.json 文件 添加上当前IP地址
vim /etc/docker/daemon.json
"insecure-registries": [
  "http://192.168.57.200:8099",
  "http://192.168.25.55"
]
#重新加载配置文件并重启docker
systemctl daemon-reload
systemctl restart docker

# 生成 Harbor 配置文件
./prepare
# 安装并启动 Harbor
./install.sh

#通过compose启动所有服务
docker compose up -d
harbor镜像站的推送命令
#Docker 推送命令

#给要推送的镜像改标签
docker tag 镜像名:版本号 192.168.25.55/library/镜像名:版本号

#推送镜像到当前harbor镜像站仓库:
docker push 192.168.25.55/library/镜像名:版本号

Docker-Swarm

多主机容器集群管理:统一管理多台服务器上的Docker容器;

master节点:统一管理node节点和所有node节点上的容器;

搭建docker-swarm
  • 准备机器
    • 192.168.25.51 Master
    • 192.168.25.52 Node1
    • 192.168.25.53 Node1
#安装docker(所有节点操作)

#卸载残留Docker软件包
for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done
#更新软件包
sudo apt update
#升级已安装软件包(可选)
#sudo apt upgrade

#安装Docker依赖
apt-get -y install ca-certificates curl gnupg lsb-release
#添加Docker国内GPG密钥
# 最终回显OK表示运行命令正确
curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
#添加Docker软件源
# 需要管理员交互式按一下回车键
sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
#安装Docker
apt-get -y install docker-ce docker-ce-cli containerd.io

#验证 Docker 是否安装成功
sudo docker --version
sudo docker run hello-world  # 运行测试容器,显示 "Hello from Docker!" 即正常
----------------------------------------------------------------------------------------------------------------
#添加镜像加速(所有节点操作)
vim /etc/docker/daemon.json

{
 "registry-mirrors": [
    "https://0c105db5188026850f80c001def654a0.mirror.swr.myhuaweicloud.com",
    "https://5tqw56kt.mirror.aliyuncs.com",
    "https://docker.1panel.live",
    "http://mirrors.ustc.edu.cn",
    "http://mirror.azure.cn",
    "https://hub.rat.dev",
    "https://docker.chenby.cn",
    "https://docker.hpcloud.cloud",
    "https://docker.m.daocloud.io",
    "https://docker.unsee.tech",
    "https://dockerpull.org",
    "https://dockerhub.icu",
    "https://proxy.1panel.live",
    "https://docker.1panel.top",
    "https://docker.1ms.run",
    "https://docker.ketches.cn"
  ],
  "insecure-registries": [
    "http://192.168.57.200:8099"
   ]
}

#重载docker服务、重启docker生效配置
systemctl daemon-reload
systemctl restart docker
----------------------------------------------------------------------------------------------------------------
# 设置 hosts 解析(所有节点操作)
cat >> /etc/hosts << EOF
192.168.25.51 server01
192.168.25.52 server02
192.168.25.53 server03
EOF
----------------------------------------------------------------------------------------------------------------
# 1.Manager节点初始化集群-init(master节点-51)
docker swarm init --advertise-addr 192.168.25.51

## 保存下列命令与token令牌,用于添加工作节点(会自动生成新的内容替换下面内容)
docker swarm join --token SWMTKN-1-4p5a3zjok9jfkrwep2i3hjsklmujwzfm2v84w3u64vq698bgxj-ehxrjlxcq523pkm0hfn6ogy3p 192.168.25.51:2377

----------------------------------------------------------------------------------------------------------------
#2.添加worker(node工作节点)到swarm(所有node节点操作52/53)
# 复制你自己上一步中输出的完整命令到工作节点中
docker swarm join --token SWMTKN-1-4p5a3zjok9jfkrwep2i3hjsklmujwzfm2v84w3u64vq698bgxj-ehxrjlxcq523pkm0hfn6ogy3p 192.168.25.51:2377

#验证集群加入情况
docker node ls
----------------------------------------------------------------------------------------------------------------
在Swarm中部署服务(nginx为例)
# 创建网络在部署服务
# 创建overlay网络
docker network create -d overlay nginx_net

#在主节点部署服务(master节点 51)
docker service create --replicas 3 --network nginx_net --name my_nginx -p 80:80 nginx:1.26    
# 就创建了一个具有3个副本(--replicas 3 )的nginx服务,使用镜像nginx(副本数量看需求添加)

#查看正在运行服务的列表
docker service ls
#查询Swarm中服务的信息 --pretty 使命令输出格式化为可读的格式,不加 --pretty 可以输出更详细的信息
docker service inspect --pretty my_nginx

# 查询到哪个节点正在运行该服务
docker service ps my_nginx

#swarm部署的集群自带负载均衡功能,可以修改每个节点副本容器里的网页内容来验证负载均衡的效果(所有节点)
docker exec -it my_nginx.1 /bin/bash
#修改网页内容(所有节点)
echo 51 > /usr/share/nginx/html/index.html
#多次搜索任意集群内IP验证负载均衡
curl 192.168.25.51
扩容、缩容
#将上面的 my_nginx 容器动态扩展到 6 个
docker service scale my_nginx=6
#将上面的 my_nginx 容器动态缩容到 2 个
docker service scale my_nginx=2
容器版本升级、回滚
#将nginx的版本升级或回滚
docker service update --image nginx:new my_nginx
#查看nginx版本(任意集群的IP都可以)
curl -i 192.168.25.51
posted @ 2025-10-31 11:11  落无一  阅读(12)  评论(0)    收藏  举报