-
一:🔥 虚拟化 & 容器化🦋 什么是虚拟化、容器化物理机:实际的服务器或者计算机。相对于虚拟机而言的对实体计算机的称呼。物理机提供给虚拟机以硬件环境,有时也称为“寄主”或“宿主”。虚拟化:是指通过虚拟化技术将一台计算机虚拟为多台逻辑计算机。在一台计算机上同时运行多个逻辑计算机,每个逻辑计算机可运行不同的操作系统,并且应用程序都可以在相互独立的空间内运行而互不影响,从而显著提高计算机的工作效率。容器化:容器化是一种虚拟化技术,又称操作系统层虚拟化(Operating system levelvirtualization),这种技术将操作系统内核虚拟化,可以允许用户空间软件实例(instances)被分割成几个独立的单元,在内核中运行,而不是只有一个单一实例运行。这个软件实例,也被称为是一个容器(containers)。对每个实例的拥有者与用户来说,他们使用的服务器程序,看起来就像是自己专用的。容器技术是虚拟化的一种,而 docker是现今容器技术的事实标准类比理解物理机就像一个庄园,独立占用了一块土地,花园都是自己的,其他人无法共享使用。虚拟机相当于开发商的一个楼盘,一栋楼一套房子一户人家,共享一块宅基地,共享小区的花园,共享小区的游乐设施容器相当于几个人一起合租一套房,共享这套房子的卫生间、共享厨房、共享 WiFì,只有衣服、电脑等私人物品是你自己的。🦋 为什么要虚拟化、容器化?我们从上面的历史发展来看,虚拟化和容器化的最主要目的就是资源隔离,随着资源隔离的实现逐渐也带来了更大的收益。资源利用率高:将利用率较低的服务器资源进行整合,用更少硬件资源运行更多业务,降低 IT 支出和运维管理成本。比如上图中我们的土地直接复用,使用这块土地的人多了,但是成本还是庄园那块地环境标准化:一次构建,随处执行。实现执行环境的标准化发布,部署和运维。开发过程中一个常见的问题是 环境一致性问题。由于开发环境、测试环境、生产环境不一致,导致有些bug 并未在开发过程中被发现。而 Docker 的镜像提供了除内核外完整的运行时环境确保了应用运行环境一致性,从而不会再出现 「这段代码在我机器上没问题啊」 这类问题。资源弹性收缩:根据业务情况,动态调整计算、存储、网络等硬件及软件资源。比如遇到双 11 了,把服务扩容 100 个,双 11 过去了, 把扩容的 100 个收回去。差异化环境提供:同时提供多套差异化的执行环境,限制环境使用资源。比如我的服务一个以来 Ubuntu 操作系统,一个服务依赖 CentOS 操作系统,但是没有预算购买两个物理机,这个时候容器化就能很好的提供多种不同的环境。沙箱安全:为避免不安全或不稳定软件对系统安全性、稳定性造成影响,可使用虚拟化技术构建虚拟执行环境。比如我在容器里面执行 rm -f/* 不会把整个服务器搞死,也不影响其他人部署的程序使用。容器对比虚拟机更轻量,启动更快:传统的虚拟机技术启动应用服务往往需要数分钟,而 Docker 容器应用,由于直接运行于宿主内核,无需启动完整的操作系统,因此可以做到秒级、甚至毫秒级的启动时间。大大的节约了开发、测试、部署的时间。docker不需要虚拟内核,所以启动可以更快,相当于 windows 的开机时间省去了。维护和扩展容易:Docker 使用的分层存储以及镜像的技术,使得应用重复部分的复用更为容易,也使得应用的维护更新更加简单,基于基础镜像进一步扩展镜像也变得非常简单。此外,Docker 团队同各个开源项目团队一起维护了一大批高质量的 官方镜像,既可以直接在生产环境使用,又可以作为基础进一步定制,大大的降低了应用服务的镜像制作成本。比如 docker hub 提供了很多镜像,各个系统的一个命令就可以拿到了,研发也可以自己定制镜像分享给各个产品。🦋 虚拟化常见类别虚拟机:存在于硬件层和操作系统层间的虚拟化技术。虚拟机通过“伪造”一个硬件抽象接口将一个操作系统以及操作系统层以上的层嫁接到硬件上,实现和真实物理机几乎一样的功能。比如我们在一台 Windows 系统的电脑上使用 Android 虚拟机,就能够用这台电脑打开 Android 系统上的应用。容器:存在于操作系统层和函数库层之间的虚拟化技术。容器通过“伪造”操作系统的接口将函数库层以上的功能置于操作系统上。以 Docker 为例,其就是一个基于 Linux 操作系统的 Namespace 和 Cgroup 功能实现的隔离容器,可以模拟操作系统的功能。简单来说,如果虚拟机是把整个操作系统封装隔离,从而实现跨平台应用的话,那么容器则是把一个个应用单独封装隔离,从而实现跨平台应用。所以 容器体积比虚拟机小很多,理论上占用资源更少M。容器化就是应用程序级别的虚拟化技术。容器提供了将应用程序的代码、运行时、系统工具、系统库和配置打包到一个实例中的标准方法。容器共享一个内核(操作系统),它安装在硬件上。JVM 之类的虚拟机:存在于函数库层和应用程序之间的虚拟化技术。Java 虚拟机同样具有跨平台特性,所谓跨平台特性实际上也就是虚拟化的功劳。因为 Java 语言是 调用操作系统函数库 的,JVM 就是在应用层与函数库层之间建立一个 抽象层,对下通过不同的版本适应不同的操作系统函数库,对上提供统一的运行环境交给程序和开发者,使开发者能够调用不同操作系统的函数库。补充:应用程序执行环境分层 硬件层:提供硬件抽象,包括指令集架构、硬件设备及硬件访问接口操作系统层:提供系统调用接口,管理硬件资源程序库层:提供数据结构定义及函数调用接口二:🔥 常见虚拟化实现方式🦋 主机虚拟化(虚拟机)实现主机虚拟化的原理是通过在物理服务器上安装一个 虚拟化层 来实现。这个虚拟化层可以在物理服务器和客户操作系统之间建立虚拟机,使得它们可以独立运行。从软件框架的角度上,根据虚拟化层是直接位于硬件之上还是在一个宿主操作系统之上,将虚拟化划分为 Type1 和 Type2 Type1 类的 Hypervisor:是一种系统软件,它充当计算机硬件和虚拟机之间的中介,负责有效地分配和利用由各个虚拟机使用的硬件资源,这些虚拟机在物理主机上单独工作,因此,Hypervisor 也称为 虚拟机管理器特点:直接运行在硬件之上,没有宿主机操作系统,Hypervisor 直接控制硬件资源和客户机典型框架为Xen、VmwareESXType2 类的 Hypervisor:运行在一个宿主机操作系统之上(Vmware Workstation) 或者 系统里面,Hypervisor 作为宿主机操作系统中的一个应用程序,客户机就是在宿主机操作系统上的一个进程。🦋 容器虚拟化实现容器虚拟化,有别于主机虚拟化,是操作系统层的虚拟化。基本原理:通过 namespace 进行各程序的隔离,加上 cgroups 进行资源的控制,以此来进行虚拟化。🎀 Namespace(命名空间)定义:namespace 是 Linux 内核用来隔离内核资源的方式。作用:实现进程、文件系统、用户等资源的隔离。具体实现:通过将一个或多个进程指定在同一个namespace中,使得这些进程只能看到与自己相关的资源。注意:Linux namespaces 是对全局系统资源的一种封装隔离,使得处于不同 namespace 的进程拥有独立的全局系统资源,改变一个 namespace 中的系统资源只会影响当前namespace 里的进程,对其他 namespace 中的进程没有影响。Namespace 系统调用参数 隔离的全局系统资源 内核版本UTS CLONE_NEWUTS 主机名和域名 2.6.19IPC CLONE_NEWIPC 信号量、消息队列和共享内存 – 进程间通信 2.6.19PID CLONE_NEWPID 进程编号 2.6.24Network CLONE_NEWNET 网络设备、网络栈、端口等 2.6.29Mount CLONE_NEWNS 文件系统挂载点 2.4.19User CLONE_NEWUSER 用户和用户组 3.8以上命名空间在容器环境下的隔离效果如下:UTS:每个容器能看到自己的 hostname,拥有独立的主机名和域名。IPC:同一个 IPC namespace 的进程之间能互相通讯,不同的IPC namespace 之间不能通信。PID:每个 PID namespace 中的进程可以有其独立的 PID,每个容器可以有其 PID 为进程。1 的 rootNetwork:每个容器用有其独立的网络设备,IP地址,IP路由表,/proc/net目录,端口号。Mount:每个容器能看到不同的文件系统层次结构。User:每个 container 可以有不同的 user 和 group id.想想以下如果我们要隔离两个进程需要怎么办?首先容器进程与进程之间需要隔离,所以需要 PID 隔离首先 容器 A 进程 不能读取 容器 B进程 通讯内容需要、隔离信号量等,所以需要 IPC 隔离首先 **容器 A 进程 **不能读取 容器 B进程 的文件,所以需要 Mount 隔离首先 **容器 A 进程 **不能读取 容器 B进程 的 socket,所以需要 网络隔离、主机隔离Docker 允许用户在主机和容器间共享文件夹,同时不需要限制容器的访问权限这就容易让容器突破资源限制。需要借助用户空间来完成用户之间的隔离。命令详解命令 功能 用途dd 复制文件并转换数据 创建镜像、测试性能、备份磁盘mkfs 创建文件系统 格式化新分区df 查看磁盘空间 查看挂载点使用情况mount 挂载文件系统 挂载 ISO、U盘、设备等unshare 创建隔离命名空间 容器底层调试、实验性隔离环境① dd 命令:用于读取、转换并输出数据,可以从标准输入或文件中读取数据,根据指定的格式转换数据,再输出到文件、设备或标准输出语法:dd OPTION ,参数如下:参数 描述if=文件名 输入文件名,默认为标准输入。即指定源文件。of=文件名 输出文件名,默认为标准输出。即指定目的文件。bs=bytes 同时设置读入/输出的块大小为 bytes 个字节,如果是ibs设置单次读入块大小, obs 设置单次输出块大小, cbs 设置转换块大小skip/seek=blocks 从 输入/输出 文件开头跳过 blocks 个块后再开始复制count=blocks 仅拷贝 blocks 个块,块大小等于 ibs 指定的字节数。conv=<关键字>,关键字有如下类型:conversion:用指定的参数转换文件ascii:转换 ebcdic 为 asciiebcdic:转换 asccii 为 ebcdicibm:转换 ascii 为 alternate ebcdicblock/unblock:把每一行转换为长度为 cbs,不足部分用空格lcase/ucase:交换输入的每对字节noerror:出错时不停止notrunc:不截断输出文件sync:将每个输入块填充到 ibs 个字节,不足部分用空(NULL)字符补齐案例# 生成镜像文件dd if=/dev/zero of=test.txt bs=8k count=1014# 大写转小写dd if=in.txt of=out.txt conv=ucase# 测试磁盘写入速度dd if=/dev/zero of=testfile bs=1G count=1 oflag=direct② mkfs 命令:在设备上创建指定类型的文件系统,即 “格式化”语法:mkfs [-V] [-t fstype] [fs-options] filesys [blocks] ,参数如下:参数 描述-t fstype 指定要建立何种文件系统;如 ext3,ext4。filesys 指定要创建的文件系统对应的设备文件名。blocks 指定文件系统的磁盘块数。-V 详细显示模式。fs-options 传递给具体文件系统的参数。案例# 格式化分区为 ext4 文件系统mkfs -t ext4 test.txtmke2fs 1.46.5 (30-Dec-2021)Discarding device blocks: done Creating filesystem with 20480 4k blocks and 20480 inodesAllocating group tables: done Writing inode tables: done Creating journal (1024 blocks): doneWriting superblocks and filesystem accounting information: done③ df 命令:用于显示目前在 Linux 系统上的文件系统磁盘使用情况统计。语法:dd OPTION ,参数如下:参数 描述-a, --all 包含所有的具有 0 Blocks 的文件系统。-h, --human-readable 使用人类可读的格式。-H, --si 很像 -h,但是用 1000 为单位而不是用 1024。-t, --type=TYPE 限制列出文件系统的类型。-T, --print-type 显示文件系统的形式。案例:lighthouse@VM-8-10-ubuntu:~$ df -hFilesystem Size Used Avail Use% Mounted ontmpfs 340M 1020K 339M 1% /run/dev/vda2 69G 22G 45G 33% /tmpfs 1.7G 24K 1.7G 1% /dev/shmtmpfs 5.0M 0 5.0M 0% /run/locktmpfs 340M 4.0K 340M 1% /run/user/1002tmpfs 340M 4.0K 340M 1% /run/user/1001④ mount 命令:用于加载文件系统到指定的加载点语法:mount [-l] mount [-t vfstype] [-o options] device dir常见参数如下:参数 描述-l 显示已加载的文件系统列表。-t vfstype 指定加载文件系统类型,支持常见的 ext3, ext4, iso9660, tmpfs, xfs 等。-o options 主要用来描述设备或档案的挂接方式。loop 用来把一个文件当成硬盘分区挂接上系统。ro 采用只读方式挂接设备。rw 采用读写方式挂接设备。device 要挂接(mount)的设备。dir 挂载点的目录。案例lighthouse@VM-8-10-ubuntu:test$ sudo mkdir /mymountlighthouse@VM-8-10-ubuntu:test$ sudo mount test.txt /mymountlighthouse@VM-8-10-ubuntu:test$ ll /mymount/total 24drwxr-xr-x 3 root root 4096 Jul 9 20:51 ./drwxr-xr-x 21 root root 4096 Jul 9 20:51 ../drwx------ 2 root root 16384 Jul 9 20:47 lost+found/lighthouse@VM-8-10-ubuntu:test$ df -t ext4Filesystem 1K-blocks Used Available Use% Mounted on/dev/vda2 72127952 22751700 46319384 33% //dev/loop4 72652 24 66896 1% /mymount# 取消挂载lighthouse@VM-8-10-ubuntu:test$ sudo umount /mymountlighthouse@VM-8-10-ubuntu:test$ df -t ext4Filesystem 1K-blocks Used Available Use% Mounted on/dev/vda2 72127952 22751804 46319280 33% /⑤ unshare 命令:语法:dd OPTION ,参数如下:参数 描述-i, --ipc 不共享 IPC 空间。-m, --mount 不共享 Mount 空间。-n, --net 不共享 Net 空间。-p, --pid 不共享 PID 空间。-u, --uts 不共享 UTS 空间。-U, --user 不共享用户。-V, --version 版本查看。--fork 执行 unshare 的进程 fork 一个新的子进程,在子进程中执行 unshare 传入的参数。--mount-proc 执行子进程前,将 proc 优先挂载过去。案例:lighthouse@VM-8-10-ubuntu:test$ sudo unshare -u /bin/bashroot@VM-8-10-ubuntu:/home/lighthouse/code/test# hostname test1root@VM-8-10-ubuntu:/home/lighthouse/code/test# hostnametest1# 查看进程root@VM-8-10-ubuntu:/home/lighthouse/code/test# ps -ajx | grep bash1877172 1877180 1877180 1877180 pts/2 1886346 Ss 1001 0:00 -bash1877180 1886346 1886346 1877180 pts/2 1886346 S+ 0 0:00 sudo unshare -u /bin/bash1886346 1886347 1886347 1886347 pts/1 1886575 Ss 0 0:00 sudo unshare -u /bin/bash1886347 1886348 1886348 1886347 pts/1 1886575 S 0 0:00 /bin/bash1886348 1886576 1886575 1886347 pts/1 1886575 S+ 0 0:00 grep --color=auto bash# exit 退出进程, 发现之前的没有持久设置root@VM-8-10-ubuntu:/home/lighthouse/code/test# exitexitlighthouse@VM-8-10-ubuntu:test$ hostnameVM-8-10-ubuntu⚠️ 注意:unshare 是一个运行时命令,执行后会启动一个新的 shell 进程,该进程处于独立的命名空间中,但不会持久化 ,退出即失效。空间隔离实战① 进程隔离:unshare命令专门提供了一个参数--mount-proc,在新的namespace挂载一个独立的/proc目录,方便进行进程的监控。lighthouse@VM-8-10-ubuntu:test$ sudo unshare --fork --pid --mount-proc /bin/bashroot@VM-8-10-ubuntu:/home/lighthouse/code/test# ps -auxUSER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMANDroot 1 0.0 0.1 7636 4272 pts/1 S 21:00 0:00 /bin/bashroot 7 0.0 0.1 10336 3752 pts/1 R+ 21:00 0:00 ps -aux可以看到,创建了新的 namespace后,ps -aux只能查到两个进程,一个是bash,一个是grep。这就将namespace内部的进程与宿主机的进程隔离开了。② 文件隔离 🎀 CGroup定义:cgroups(Control Groups) 是 linux 内核提供的一种机制,这种机制可以根据需求把系列系统任务及其子任务整合(或分隔)到按资源划分等级的不同组内,从而为系统资源管理提供一个统一的框架。作用:限制CPU、内存、网络等所使用的物理资源。具体实现:本质上来说,cgroups 是内核附加在程序上的一系列钩子(hook),通过程序运行时对资源的调度触发相应的钩子以达到资源追踪和限制的目的。用途如下:Resource limitation:限制资源使用,例:内存使用上限/cpu 的使用限制Prioritization:优先级控制,例:CPU 利用/磁盘 IO 吞吐Accounting:一些审计或一些统计Control:挂起进程/恢复执行进程相关命令① pidstat:用于检测一个进程的 CPU、内存、IO、线程等资源的占用情况。sudo apt install sysstat # 安装pidstat [option] [时间间隔] [次数] # 语法一键获取完整项目代码bash12选项:-u:检测 CPU 使用情况(默认)-r:检测内存使用情况-d:检测 IO 使用情况-p:指定进程 PID,如果指定 ALL 则监视所有进程-C:检测通过指定命令启动的进程示例:默认输出:pidstat 会输出所有进程的 CPU 占用情况。指定进程:pidstat -p 1234 检测 PID 为 1234 的进程。指定命令:pidstat -C bash 检测通过 bash 命令启动的进程。检测内存:pidstat -r 检测内存占用情况。指定检测次数与频率:pidstat 1 3 每隔一秒检测一次,共检测三次。简单测试:lighthouse@VM-8-10-ubuntu:test$ pidstat -C bashLinux 5.15.0-126-generic (VM-8-10-ubuntu) 07/09/2025 _x86_64_ (2 CPU)09:19:13 PM UID PID %usr %system %guest %wait %CPU CPU Command09:19:13 PM 1001 1877180 0.00 0.00 0.00 0.00 0.00 0 bashlighthouse@VM-8-10-ubuntu:test$ pidstat -rLinux 5.15.0-126-generic (VM-8-10-ubuntu) 07/09/2025 _x86_64_ (2 CPU)09:19:20 PM UID PID minflt/s majflt/s VSZ RSS %MEM Command09:19:20 PM 0 1 0.09 0.00 184012 10948 0.31 systemd09:19:20 PM 0 366 0.00 0.83 179024 81516 2.34 systemd-journal09:19:20 PM 0 410 0.00 0.00 289312 27096 0.78 multipathd09:19:20 PM 0 412 0.00 0.00 12120 5012 0.14 systemd-udevd09:19:20 PM 101 828 0.00 0.00 16128 1608 0.05 systemd-network09:19:20 PM 0 843 0.00 0.00 2816 1104 0.03 acpid09:19:20 PM 103 848 0.00 0.00 8876 4008 0.12 dbus-daemon09:19:20 PM 0 864 0.00 0.00 234504 4472 0.13 polkitd② stress:一个压力测试工具,可以对 CPU、内存、IO 等进行压力测试。sudo apt install stress # 安装stress [option] # 语法 参数:-c --cpu N:产生 N 个进程,每个进程都循环调用 sqrt 函数产生 CPU 压力。-m --vm N:产生 N 个进程,每个进程都循环调用 malloc 和 free 函数,产生内存压力。示例:stress -c 1 创建一个进程进行 CPU 压力测试。 左侧使用stress创建了一个进程进行CPU压力输出右侧检测stress产生的压力结果一个进程占满了100%的CPU资源资源控制实战① 信息查看cgroups 版本查看lighthouse@VM-8-10-ubuntu:~$ cat /etc/*release* # 查看当前系统版本DISTRIB_ID=UbuntuDISTRIB_RELEASE=22.04DISTRIB_CODENAME=jammyDISTRIB_DESCRIPTION="Ubuntu 22.04 LTS"PRETTY_NAME="Ubuntu 22.04 LTS"NAME="Ubuntu"VERSION_ID="22.04"VERSION="22.04 (Jammy Jellyfish)"VERSION_CODENAME=jammyID=ubuntuID_LIKE=debianHOME_URL="https://www.ubuntu.com/"SUPPORT_URL="https://help.ubuntu.com/"BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"UBUNTU_CODENAME=jammylighthouse@VM-8-10-ubuntu:~$ cat /proc/filesystems |grep cgnodev cgroupnodev cgroup2 # 可以支持两个版本 cgroupcgroups 子系统查看lighthouse@VM-8-10-ubuntu:test$ cat /proc/cgroups#subsys_name hierarchy num_cgroups enabledcpuset 0 109 1cpu 0 109 1cpuacct 0 109 1blkio 0 109 1memory 0 109 1devices 0 109 1freezer 0 109 1net_cls 0 109 1perf_event 0 109 1net_prio 0 109 1hugetlb 0 109 1pids 0 109 1rdma 0 109 1misc 0 109 1查看挂载信息:这里是每一个资源的控制目录,比如在 /sys/fs/cgroup/cpu 目录下,就是控制CPU资源的配置文件lighthouse@VM-8-10-ubuntu:~$ mount | grep cgroupcgroup2 on /sys/fs/cgroup type cgroup2 (rw,nosuid,nodev,noexec,relatime,nsdelegate,memory_recursiveprot)查看一个进程上的 cgroup 限制lighthouse@VM-8-10-ubuntu:~$ cat /proc/$$/cgroup0::/user.slice/user-1001.slice/session-83590.scope # 层级编号:挂载的子系统:路径② 内存控制创建内存控制组cd /sys/fs/cgroup/memorymkdir test_memory设置最大内存echo "20971520" > test_memory/memory.limit_in_bytes将进程加入控制组stress -m 1 --vm-bytes 50m # 每个进程占用 50Mpidstat -recho "15070" > test_memory/tasks3③ CPU 控制创建 CPU 控制组cd /sys/fs/cgroup/cpumkdir test_cpu设置 CPU 占用率echo "5000" > test_cpu/cpu.cfs_period_usecho "2000" > test_cpu/cpu.cfs_quota_us一键获取完整项目代码bash12将进程加入控制组stress -c 1pidstat -uecho "60769" > test_cpu/tasks一键获取完整项目代码bash123三:🔥 容器虚拟化基础之 LXC🦋 LXC 是什么?LXC(LinuX Containers)是一种操作系统层虚拟化技术,为 Linux 内核容器功能的一个用户空间接口。它将应用软件系统打包成一个软件容器(Container),内含应用软件本身的代码,以及所需要的操作系统核心和库。透过统一的名字空间和共享 API 来分配不同软件容器的可用硬件资源,创造出应用程序的独立沙箱运行环境,使得 Linux 用户可以容易地创建和管理系统或应用容器。尽管 LXC 极大地简化了容器技术的使用,但比起直接通过内核调用来使用容器技术,其复杂程度其实并没有多大降低,因为我们必须要学会 LXC 的一组命令工具,且由于内核的创建都是通过命令来实现的,通过批量命令实现数据迁移并不容易。其隔离性也没有虚拟机那么强大。后来就出现了 Docker,所以从一定程度上来说,Docker 就是 LXC 的增强版。🦋 LXC 容器操作Ubuntu 上安装 LXC,如下:检查及卸载(如需)systemctl status lxclxc-stop -n xxx # 停止所有运行的容器lxc-destroy -n xxx # 删除所有容器apt-get purge --auto-remove lxc lxc-templatessystemctl status lxc # 确保服务已卸载安装 LXCsudo apt install lxc lxc-templates bridge-utils -ysystemctl status lxc # 检查服务是否正常一键获取完整项目代码bash123LXC的常用命令说明如下:① 检查系统支持性:lxc-checkconfig② 创建指定模板容器:lxc-create -n NAME -t TEMPLATE_NAME [--template-options]③ 启动容器:lxc-start -n NAME -d④ 列出容器:lxc-ls -f(-f 参数显示容器得详细信息)⑤ 查看容器信息:lxc-info -n NAME⑥ 进入容器:lxc-attach --name=NAME [--COMMAND]⑦ 停止容器:lxc-stop -n NAME⑧ 删除容器:lxc-destroy -n NAME实战如下:# 1. 检查运行状态root@VM-8-10-ubuntu:~$ systemctl status lxc● lxc.service - LXC Container Initialization and Autoboot Code Loaded: loaded (/lib/systemd/system/lxc.service; enabled; vendor preset: enabled) Active: active (exited) since Fri 2025-07-11 15:28:38 CST; 3min 34s ago Docs: man:lxc-autostart man:lxc Process: 2423230 ExecStartPre=/usr/lib/x86_64-linux-gnu/lxc/lxc-apparmor-load (code=exited, status=0/SUCCESS) Process: 2423235 ExecStart=/usr/lib/x86_64-linux-gnu/lxc/lxc-containers start (code=exited, status=0/SUCCESS) Main PID: 2423235 (code=exited, status=0/SUCCESS) CPU: 24ms# 2. 查看可用模板root@VM-8-10-ubuntu:/home/lighthouse# ls /usr/share/lxc/templates/lxc-alpine lxc-centos lxc-fedora lxc-oci lxc-plamo lxc-sparclinux lxc-voidlinuxlxc-altlinux lxc-cirros lxc-fedora-legacy lxc-openmandriva lxc-pld lxc-sshdlxc-archlinux lxc-debian lxc-gentoo lxc-opensuse lxc-sabayon lxc-ubuntulxc-busybox lxc-download lxc-local lxc-oracle lxc-slackware lxc-ubuntu-cloud# 3. 创建容器 -n 容器的名称 -t 模版 -r release版本 -a cpu架构lxc-create -n lxchost1 -t ubuntu -- -r xenial -a amd64 # Ubuntu上创建Ubuntu容器lxc-create -n centos7 --template=download -- --dist=centos --release=7 --arch=amd64 # Ubuntu上创建CentOS容器# 4. 查看创建结果root@VM-8-10-ubuntu:/home/lighthouse# lxc-ls -fNAME STATE AUTOSTART GROUPS IPV4 IPV6 UNPRIVILEGED lxchost1 STOPPED 0 - - - false # 5. 启动容器root@VM-8-10-ubuntu:/home/lighthouse# lxc-start -n lxchost1 -droot@VM-8-10-ubuntu:/home/lighthouse# lxc-info -n lxchost1Name: lxchost1State: RUNNINGPID: 2455869Link: vethNx0mnE TX bytes: 726 bytes RX bytes: 1.41 KiB Total bytes: 2.12 KiB# 6. 使用 ssh 进入容器root@VM-8-10-ubuntu:/home/lighthouse# ssh ubuntu@ipAre you sure you want to continue connecting (yes/no/[fingerprint])? yesubuntu@1.12.51.69's password: # 密码是当前 系统密码# 7. 在容器中执行常用命令ip addr # 查看网络信息df -h # 查看磁盘挂载情况ps -ef # 查看进程信息ubuntu@VM-8-10-ubuntu:~$ df -hFilesystem Size Used Avail Use% Mounted ontmpfs 340M 1.1M 339M 1% /run/dev/vda2 69G 23G 44G 35% /tmpfs 1.7G 24K 1.7G 1% /dev/shmtmpfs 5.0M 0 5.0M 0% /run/locktmpfs 340M 4.0K 340M 1% /run/user/1002tmpfs 340M 4.0K 340M 1% /run/user/1001tmpfs 1.7G 0 1.7G 0% /run/qemutmpfs 340M 4.0K 340M 1% /run/user/1000# 8. 从宿主机向容器中发送命令root@VM-8-10-ubuntu:/home/lighthouse# lxc-attach -n lxchost1 --clear-env -- echo "Hello LXC"Hello LXC# 9. 停止 & 删除容器root@VM-8-10-ubuntu:/home/lighthouse# lxc-stop -n lxchost1 root@VM-8-10-ubuntu:/home/lighthouse# lxc-destroy -n lxchost1通过LXC学习容器的创建与管理,体会容器化技术的基本原理。了解Docker不是唯一的容器实现方式,Docker在0.9版本起引入了自家的 libcontainer,而如今大部分Docker使用的都是libcontainer而非LXC。四:🔥 共勉😋 以上就是我对 【Docker#2】容器化虚拟化 的理解, 觉得这篇博客对你有帮助的,可以点赞收藏关注支持一波~ 😉————————————————版权声明:本文为CSDN博主「Zfox_」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/weixin_50776420/article/details/157184498
-
一、什么是 Docker Registry镜像仓库 (Docker Registry) 负责存储、管理和分发镜像,并且提供了登录认证能力,建立了仓库的索引。镜像仓库管理多个 Repository, Repository 通过命名来区分。每个 Repository 包含一个或多个镜像,镜像通过镜像名称和标签 (Tag)来区分。 1.镜像仓库(Registry):要从哪一个镜像仓库拉取镜像,通常通过 DNS 或 IP 地址来确定一个镜像仓库如 hub.docker.com;一个 Registry 中可以存在多个Repository·Repository可分为“顶层仓库”和“用户仓库”;·用户仓库名称格式为“用户名/仓库名”·每个仓库可以包含多个 Tag(标签),每个标签对应一个镜像2.Repository: ·由某特定的 docker 镜像的所有迭代版本组成的镜像仓库3.镜像名称(name)+标签(tag):如 nginx:latest4.认证能力:提供用户注册,登录、登出能力5.索引:提供镜像的索引信息,方便检索一个容器镜像包含了两个部分,一个是元数据,其实就是由 dockerfile 构建出来的描述文件,这个描述文件会说这个容器镜像有多少层,每一层里面有什么内容,它的checksum 这些信息都会记录下来,还有最终的可执行文件在哪就是在存储数据里面,就是在一个一个的 blob 里面,真正占有空间的就是这些 blob。镜像仓库生活案例大家可以类比超市,一个 Repository 就是一个货架,白象就是组织者,货架上放的产品打的不同标签就是对应的 tag 二、镜像仓库分类按是否对外开放划分,也是研发人员常说的:(1)公有仓库:像阿里云、dockerhub 等放到公有网络上,不用登录就可以下载镜像,供大家访问使用(2)私有仓库:不对外开放,往往位于私有网络,只有公司内部人员可以使用。按供应商和面向群体划分:(1)sponsor(赞助) registry:第三方的 registry,供客户和 docker 社区版使用(2)mirror(镜像) registry:第三方的 registry,只让客户使用,例如阿里云必须注册才能使用(3)vendor(供应商) registry:由发布 docker 镜像的供应商提供的 registry,例如像Google 和 Redhat 提供了镜像仓库服务(4)private registry:通过没有防火墙和额外的安全层的私有实体提供的 registry,仅供内部使用三、镜像仓库工作机制1. 镜像仓库使用流程(1)通过 docker login 登录仓库(2)Docker pull 拉取需要的镜像(3)通过 dockerfile 或者 commit 等方式制作完镜像通过 docker push 上传到仓库2. 实际研发中镜像仓库如何使用Docker Registry 中的镜像通常由开发人员制作,而后推送至“公共”或“私有”Registry 上保存,供其他人员使用,例如“部署”到生产环境;名词解释:开发环境:开发人员使用的一套环境测试环境:需求开发完成后,发布到供测试人员进行测试的环境预发布环境:版本测试完成后,发布到和生产类似的环境,提前模拟生产发布生产环境:真正面向客户的环境3. 镜像仓库的拉取机制启动容器时,docker daemon 会试图从本地获取相关的镜像;本地镜像不存在时,其将从 Registry 中下载该镜像并保存到本地;四、常用的镜像仓库1.DockerHubDocker Hub 是什么?Docker Hub 是 Docker 提供的托管存储库服务,用于查找容器映像并与您的团队共享。具有以下功能:(1)个人可以注册私有仓库,能够发布自己的镜像(2)提供镜像检索能力(3)提供海量官方和认证组织的镜像(4)从 GitHub 和 Bitbucket 自动构建容器镜像并将它们推送到 Docker Hub(5)支持 webhook(webhook 是一种基于 HTTP 的回调函数,发生指定的事件时,服务器会自动将相关的有效负载发送到客户端的 webhook URL。 )Docker Hub 功能浏览:镜像 tag 查找:版本拉取命令、镜像对应版本:2. 国内镜像源国内从 Docker Hub 拉取镜像有时会遇到困难,此时可以配置镜像加速器。国内很多云服务商都提供了国内镜像加速器服务,例如阿里云加速器(点击管理控制台 -> 登录账号(淘宝账号) -> 右侧镜像工具 -> 镜像加速器-> 复制加速器地址)网易云加速器地址 https://hub-mirror.c.163.com百度云加速器地址 https://mirror.baidubce.com可以在 /etc/docker/daemon.json 中写入如下内容(如果文件不存在请新建该文件):{# 注意如果最外层以及你给有了配置,不要直接覆盖,而是将下面的内容添加,然后确保 json 的格式正确 "registry-mirrors": [ "https://hub-mirror.c.163.com", "https://mirror.baidubce.com" ]}添加完成后需要重新加载配置,重启 Docker:# 加载配置sudo systemctl daemon-reload # 重启 dockersudo systemctl restart docker #查看 docker 状态sudo systemctl status docker3. 私有仓库私有镜像仓库则是指部署在公司或组织内部,用于自身应用 Docker 镜像存储、分发的镜像仓库。在构建公司内部使用的自动化发布系统的过程中,从安全的角度出发,应用的打包镜像一般情况下只会被存储在私有镜像仓库中,CI/CD 流程的衔接点也是通过向私有镜像仓库上传镜像和拉取镜像的操作来完成的。常见的私有仓库工具:1.Harbor:Harbor 是 VMware 公司最近开源的企业级 Docker Registry 项目,其目标是帮助用户迅速搭建一个企业级的 Docker registry 服务。它以 Docker 公司开源的registry为基础,提供了管理 UI, 基于角色的访问控制(Role Based Access Control),AD/LDAP集成、以及审计日志(Audit logging) 等企业用户需求的功能,同时还原生支持中文。Harbor 的每个组件都是以 Docker容器的形式构建的,使用 Docker Compose 来对它进行部署。 .2. Nexus:Nexus 是 Sonatype公司发布的一款仓库(Repository)管理软件,目前常被用来作为 Maven 私服、Docker 私服。(3.) Docker registry:由 docker 官方提供的私服,类似于 docker hub。用于保存公司内部上传的 Docker 镜像。五、镜像仓库命令1.docker login功能:登陆到一个 Docker 镜像仓库,如果未指定镜像仓库地址,默认为官方仓库 Docker Hub。语法:docker login [OPTIONS] [SERVER]AI写代码powershell1关键参数-u :登陆的用户名-p :登陆的密码样例:docker login -u 用户名 -p 密码AI写代码powershell12.docker pull(1).功能从镜像仓库中拉取或者更新指定镜像(2).语法docker pull [OPTIONS] NAME[:TAG|@DIGEST]AI写代码powershell1(3).别名docker image pullAI写代码powershell1(4).关键参数-a :拉取所有 tagged 镜像–disable-content-trust :忽略镜像的校验,默认开启(5).样例docker pull nginx:1.23.3AI写代码powershell13. docker push(1)功能将本地的镜像上传到镜像仓库,要先登陆到镜像仓库(2)语法docker push [OPTIONS] NAME[:TAG]AI写代码powershell1(3)别名docker image pushAI写代码powershell1(4)关键参数-a :推送所有 tagged 镜像–disable-content-trust :忽略镜像的校验,默认开启docker push myapache:v1AI写代码powershell14.docker search(1)功能从 Docker Hub 查找镜像,因 docker 网站被封,该命令暂时国内无法实操,需要国外网络联系。(2)语法docker search [OPTIONS] TERMAI写代码powershell1(3)关键参数–no-trunc :显示完整的镜像描述;-f <过滤条件>:列出收藏数不小于指定值的镜像(4)样例#从 Docker Hub 查找所有镜像名包含 nginx,并且 star 数大于 10 的镜像docker search -f stars=10 nginxAI写代码powershell125.docker logout(1)功能登出一个 Docker 镜像仓库,如果未指定镜像仓库地址,默认为官方仓库 Docker Hub,(2)语法docker logout [SERVER]AI写代码powershell1(3)样例docker logoutAI写代码powershell1六、镜像命令学习仓库前我们需要提前了解一部分的镜像命令1.docker images(1)功能列出本地镜像。(2)语法docker images [OPTIONS] [REPOSITORY[:TAG]](3)别名docker image ls, docker image listAI写代码powershell1(4)关键参数○ -a :列出本地所有的镜像(含中间映像层,默认情况下,过滤掉中间映像层);○ --digests :显示镜像的摘要信息;○ -f :显示满足条件的镜像;○ --format :指定返回值的模板文件;○ --no-trunc :显示完整的镜像信息;○ -q :只显示镜像 ID。(5) 样例#列出本地全部镜像docker images#列出本地镜像中 REPOSITORY 为 ubuntu 的镜像列表。docker images ubuntu`在这里插入代码片`2. docker image inspect(1) 功能查看镜像详细信息(2) 语法docker image inspect [OPTIONS] IMAGE [IMAGE...]AI写代码powershell1• 样例docker images inspect nginx:1.23.3AI写代码powershell13. docker tag(1) 功能标记本地镜像,将其归入某一仓库。(2)语法docker tag SOURCE_IMAGE[:TAG] TARGET_IMAGE[:TAG]AI写代码powershell1(3) 别名docker image tagAI写代码powershell1(4) 样例docker tag ubuntu:22.04 myregistry.com/myubuntu:22.04七、容器命令学习仓库前我们需要提前了解一部分的容器命令1.docker run(1) 功能创建一个新的容器并运行一个命令(2)语法docker run [OPTIONS] IMAGE [COMMAND] [ARG...](3) 别名docker container run(4)关键参数○ -d: 后台运行容器,并返回容器 ID;○ -i: 以交互模式运行容器,通常与 -t 同时使用;○ -P: 随机端口映射,容器内部端口随机映射到主机的端口○ -p: 指定端口映射,格式为:主机(宿主)端口:容器端口○ -t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;○ --name=“nginx-lb”: 为容器指定一个名称;○ -h “mars”: 指定容器的 hostname;○ -e username=“ritchie”: 设置环境变量;○ --cpuset-cpus=“0-2” or --cpuset-cpus=“0,1,2”: 绑定容器到指定 CPU 运行;○ -m :设置容器使用内存最大值;○ --network=“bridge”: 指定容器的网络连接类型;○ --link=[]: 添加链接到另一个容器;○ --volume , -v: 绑定一个卷○ --rm :shell 退出的时候自动删除容器(5)样例#使用 docker 镜像 nginx:latest 以后台模式启动一个容器,并将容器命名为mynginx。docker run --name mynginx -d nginx:latest#使用镜像 nginx:latest,以后台模式启动一个容器,将容器的 80 端口映射到主机的 80 端口,主机的目录 /data 映射到容器的 /data。docker run -p 80:80 -v /data:/data -d nginx:latest2. docker ps(1) 功能列出容器(2) 语法docker ps [OPTIONS]AI写代码powershell1(3)别名docker container ls, docker container list, docker container psAI写代码powershell1(4)关键参数○ -a :显示所有的容器,包括未运行的。○ -f :根据条件过滤显示的内容。○ --format :指定返回值的模板文件。如 json 或者 table○ -l :显示 latest 的容器。○ -n :列出最近创建的 n 个容器。○ --no-trunc :不截断输出。○ -q :静默模式,只显示容器编号。○ -s :显示总的文件大小。(5) 样例docker ps -aAI写代码powershell1总结以上就是本文全部内容,主要介绍了docker中的镜像仓库,还介绍了镜像仓库,镜像和容器相关基础的命令。感谢各位能够看到最后,如有问题,欢迎各位大佬在评论区指正,希望大家可以有所收获!创作不易,希望大家多多支持!————————————————版权声明:本文为CSDN博主「努力也学不会Java.」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/2403_87459748/article/details/155466679
-
数据丢失的核心原因是 数据卷挂载配置错误(路径不对、权限不足、挂载类型误用),Docker 环境下 PostgreSQL 的数据持久化完全依赖正确的卷挂载 ——PostgreSQL 容器的默认数据存储目录是 /var/lib/postgresql/data,如果挂载时路径不匹配、宿主机目录无写入权限,数据会默认存到容器的 “临时存储层”,容器重启后就会丢失。一、先排查:你的数据卷挂载到底错在哪?1. 最常见错误:挂载路径不匹配(没对准容器内默认数据目录)PostgreSQL 容器的 数据必须存储在 /var/lib/postgresql/data 目录下(这是官方镜像的固定路径,改不了)。如果你的启动命令里挂载路径写错了(比如多写一层目录、少写路径),数据根本没写到宿主机卷里。常见小错误(路径错误): # 错误1:挂载到 /var/lib/postgresql(少了 /data 后缀)docker run -d -v pgdata:/var/lib/postgresql postgres:15# 错误2:自定义容器内路径(比如 /data),但PostgreSQL不往这写docker run -d -v /宿主机路径:/data postgres:15# 错误3:绑定挂载时宿主机路径拼写错误(比如 /home/user/pgdata 写成 /home/user/pgdat)docker run -d -v /home/user/pgdat:/var/lib/postgresql/data postgres:15 正确示例(路径必须对准 /var/lib/postgresql/data): # 命名卷(推荐,Docker自动管理路径和权限)docker run -d -v pgdata:/var/lib/postgresql/data postgres:15# 绑定挂载(宿主机路径自定义,需确保权限)docker run -d -v /home/user/pgdata:/var/lib/postgresql/data postgres:15 2. 第二常见:宿主机目录权限不足(容器内用户写不进去)PostgreSQL 容器内默认使用 postgres 用户(UID=999,GID=999)运行,如果是 绑定挂载(直接挂载宿主机目录),宿主机目录的属主 / 权限不对,postgres 用户无法写入数据,会自动降级为 “临时存储”(重启丢失)。错误场景:宿主机创建了 /home/user/pgdata 目录,但默认属主是 root,权限是 755(只有 root 能写),容器内 postgres 用户没权限写入,只能用临时存储。修复方法(绑定挂载时): # 1. 先给宿主机目录设置正确权限(让 UID=999 能写入)sudo chown -R 999:999 /home/user/pgdatasudo chmod -R 700 /home/user/pgdata # PostgreSQL要求数据目录权限为700(仅所有者可读写)# 2. 再启动容器(路径正确+权限正确)docker run -d -v /home/user/pgdata:/var/lib/postgresql/data postgres:15 3. 其他的小错误:误用 “匿名卷” 或 “临时存储”匿名卷:启动命令里只写 -v /var/lib/postgresql/data(没指定宿主机路径或卷名),Docker 会创建随机命名的匿名卷,容器删除后匿名卷可能被清理(重启容器不删,但手动删容器时容易丢);临时存储:如果启动时没加任何 -v 挂载,数据直接存在容器的 “可写层”,容器重启 / 重建后 100% 丢失。二、Docker 部署 PostgreSQL 的正确流程(确保数据不丢)推荐用 命名卷(Docker 自动管理路径、权限,避免手动配置错误)1. 提前创建命名卷(也可启动时自动创建) # 创建名为 pgdata 的命名卷(Docker会把数据存在 /var/lib/docker/volumes/pgdata 下)docker volume create pgdata 2. 启动容器(核心:正确的去挂载卷 + 设置必要环境变量)docker run -d \ --name postgres-db \ -p 5432:5432 \ # 端口映射(宿主机:容器) -v pgdata:/var/lib/postgresql/data \ # 命名卷挂载(关键) -e POSTGRES_USER=myuser \ # 自定义数据库用户(避免用默认postgres) -e POSTGRES_PASSWORD=mypassword \ # 自定义密码(必须设置,否则容器启动失败) -e POSTGRES_DB=mydb \ # 初始化时创建的数据库(可选) -e PGDATA=/var/lib/postgresql/data/pgdata \ # 可选:指定数据子目录(避免和配置文件混放) --restart=always \ # 容器异常退出时自动重启 postgres:15 # 指定具体版本(不要用latest,避免版本迭代问题) 3. 验证数据持久化(确保重启后不丢) # 1. 进入容器,创建测试数据docker exec -it postgres-db psql -U myuser -d mydb# 执行SQL创建表并插入数据CREATE TABLE test (id int);INSERT INTO test VALUES (1);SELECT * FROM test; # 确认能查到数据,退出容器(ctrl+d)# 2. 重启容器docker restart postgres-db# 3. 再次进入容器,验证数据是否存在docker exec -it postgres-db psql -U myuser -d mydbSELECT * FROM test; # 能查到 (1) 说明持久化成功 三、Docker 环境使用 PostgreSQL 的关键注意事项1. 数据卷相关(重中之重)优先用 命名卷:避免绑定挂载的权限、路径问题,Docker 会自动维护卷的生命周期(容器删除后卷不会删,数据保留);绑定挂载需注意:宿主机目录必须提前创建并设置 999:999 属主(容器内 postgres 用户的 UID/GID),权限设为 700(PostgreSQL 安全要求,禁止其他用户访问数据目录);不要修改容器内默认数据目录:官方镜像的 /var/lib/postgresql/data 是固定路径,修改 PGDATA 环境变量时需确保挂载路径同步(比如 PGDATA=/var/lib/postgresql/data/pgdata,挂载路径仍为 /var/lib/postgresql/data)。2. 配置与权限必须设置密码:PostgreSQL 官方镜像从 10 版本后,必须通过 POSTGRES_PASSWORD 环境变量设置密码,否则容器启动失败;避免硬编码密码:生产环境不要直接在命令行写密码,可用 --env-file 加载环境变量文件(比如 docker run --env-file .env ...,.env 文件里写 POSTGRES_PASSWORD=mypassword);挂载配置文件:如果需要修改 postgresql.conf(比如调整内存、连接数),可将宿主机的配置文件挂载到 /var/lib/postgresql/data/postgresql.conf(命名卷中会自动生成默认配置,可先拷贝出来修改再挂载): # 先拷贝容器内默认配置到宿主机docker cp postgres-db:/var/lib/postgresql/data/postgresql.conf /home/user/pgconf/# 修改后重新挂载配置文件docker run -d -v pgdata:/var/lib/postgresql/data -v /home/user/pgconf/postgresql.conf:/var/lib/postgresql/data/postgresql.conf ... 3. 容器管理禁止用 docker rm -v 删除容器:-v 参数会同时删除挂载的卷(包括命名卷),导致数据丢失;定期备份数据卷:即使挂载了卷,也要定期备份(比如用 docker run --rm -v pgdata:/source -v /宿主机备份路径:/dest alpine tar -czf /dest/pgbackup.tar.gz -C /source .);指定具体镜像版本:不要用 postgres:latest,避免容器重建时自动升级版本(可能出现兼容性问题),比如固定 postgres:15.6。4. 网络与端口避免暴露 5432 端口到公网:默认 -p 5432:5432 会把端口暴露到公网,容易被暴力破解,生产环境可改为内网访问(比如 -p 127.0.0.1:5432:5432,仅允许宿主机访问),或用 Docker 自定义网络隔离;容器间通信:如果其他容器需要访问 PostgreSQL,建议创建 Docker 网络(docker network create pg-network),启动时加入网络(--network pg-network),通过容器名(比如 postgres-db)访问,无需暴露端口。5. 资源限制限制 CPU / 内存:避免 PostgreSQL 容器占用过多宿主机资源,可通过 --cpus 和 --memory 限制(比如 --cpus 2 --memory 4g,限制 2 核 CPU、4G 内存);磁盘空间监控:命名卷默认存在 /var/lib/docker/volumes/ 下,需监控宿主机磁盘空间,避免数据量增长导致磁盘满。四、如果数据已经丢失,怎么去救救数据呢?如果容器还没删除,可尝试从容器的 “临时存储层” 抢救数据: # 1. 查看容器是否还存在(即使已停止)docker ps -a | grep postgres-db# 2. 用新容器挂载原容器的存储层,拷贝数据docker run --rm -v /宿主机临时路径:/backup alpine \ cp -r /var/lib/docker/containers/[原容器ID]/mounts/secrets/ /backup/# (注:如果原容器已删除,临时存储层会被清理,无法恢复,只能依赖之前的备份) 总结一下下数据丢失的核心是 挂载路径不对 或 权限不足,记住:PostgreSQL 容器必须挂载 /var/lib/postgresql/data 目录;推荐用 命名卷 部署,避免手动配置权限和路径的麻烦;生产环境务必做好 定期备份 和 权限隔离,不要暴露端口到公网,指定固定镜像版本。
-
概念简述核心定义 Docker Compose 是一个用于定义和运行多容器 Docker 应用程序的工具。它允许您使用一个单独的配置文件(通常是 .yml 格式)来配置应用程序的所有服务、网络和卷,然后通过一条简单的命令就能创建和启动所有服务。可以把它想象成一个自动化脚本或编排工具,专门用于在单台主机上部署由多个容器组成的应用。 为什么要使用 Docker Compose?解决什么问题? 在理解 Compose 之前,先想想如果不用它,会多麻烦:假设应用由以下服务组成:Web 应用、Redis 缓存服务、MySQL 数据库服务,如果没有 Docker Compose,你需要手动完成以下步骤: 创建一个 Docker 网络让容器可以通信。单独启动 MySQL 容器,并指定网络、卷、环境变量等。单独启动 Redis 容器,并指定网络、环境变量等。构建你的 Web 应用的镜像。启动 Web 应用容器,并链接到之前创建的网络,设置环境变量指向 Redis 和 PostgreSQL 的容器名。你需要记住并输入一大堆 docker run 命令,这个过程非常繁琐且容易出错。 Docker Compose 解决了这个问题: 简化流程:用一个文件(docker-compose.yml)描述整个应用栈的架构。一键操作:通过一条命令(docker compose up)就能同时创建、启动所有服务,并处理好它们之间的依赖关系。配置即代码:将你的应用基础设施(服务、网络、存储)用配置文件管理起来,可以纳入版本控制系统,方便协作和追溯。核心概念与工作流程 定义 docker-compose.yml 文件:这是 Docker Compose 的核心。你在这个 YAML 文件中定义你的应用所需的服务、网络和卷。 服务:对应一个容器。你可以指定使用哪个镜像、暴露哪些端口、挂载哪些卷、设置哪些环境变量、依赖哪些其他服务等。网络:定义容器之间通信的网络。卷:定义持久化数据存储的位置。执行 docker compose up 命令:在包含 docker-compose.yml 文件的目录下运行此命令。Compose 会: 自动构建或拉取所需的镜像。按依赖顺序创建并启动所有定义的服务。将所有服务的日志输出聚合到一个流中,方便查看。执行 docker compose down 命令:当你想要停止并清理整个应用时,运行此命令。它会停止所有容器,并删除创建的容器和网络(默认情况下不删除卷)。 总结:Docker Compose 的优点 隔离环境:整个应用栈与主机环境完全隔离。极简配置:一个命令替代了大量复杂的 docker run 命令。快速部署:极大地简化了多容器应用的部署和测试流程,是开发、测试和 CI/CD 环境的理想选择。服务发现:自动在服务之间创建网络,并通过服务名进行DNS解析,使容器间通信变得非常简单。注意:Docker Compose 通常用于开发、测试和单机部署。对于生产环境中跨多台主机的集群管理和编排,更强大的工具如 Kubernetes 或 Docker Swarm 更为合适。不过,Compose 文件可以作为学习这些更复杂工具的基础。 配置文件格式version:指定Docker Compose文件的版本格式,不同版本支持的功能和语法有所不同,高版本兼容低版本services: 服务,可以存在多个 servicename: 服务名字,它也是内部bridge网络可以使用的DNS name,如果不是集群模式相当于docker run的时候指定的一个名称,集群(Swarm)模式是多个容器的逻辑抽象 image: 镜像的名字(必选) command: 如果设置,则会覆盖默认镜像里的CMD命令 environment: 等价于docker container run里的–env选项,设置环境变量 volumes: 等价于docker container run里的-v选项,绑定数据卷 networks: 等价于docker container run里的–network选项,指定网络 ports: 等价于docker container run里的-p选项,指定端口映射 expose: 可选,指定容器暴露的端口 build: 构建目录 depends_on: 服务依赖配置 env_file: 环境变量文件 servicename2: image: command: networks: ports: servicename3:#…volumes: # 可选,等价于 docker volume createnetworks: # 可选,等价于 docker network create 参数详解准备这样一个目录结构: mycompose/├── prj1│ └── docker-compose.yml├── prj2│ └── docker-compose.yml└── prj3 └── docker-compose.yml...... image功能:指定容器镜像示例: 创建prj1目录:mkdir prj1在prj1中创建文件docker-compose.ymlcd prj1touch docker-compose.yml编辑docker-compose文件vim docker-compose.yml services: web: image: nginx:1.24.0 启动配置docker compose up清除容器docker compose down 接下来就不再详细展示每个步骤,重点讲解第3步文件的配置。command功能:覆盖容器启动的默认指令格式: command: ["bundle", "exec", "thin", "-p", "3000"]//或command: bundle exec thin -p 3000 示例: serveices: web: image: nginx:1.24.0 command: bundle exec thin -p 3000 这些内容都写在配置文件docker-compose.yml里面 entrypoint功能:覆盖容器默认的 entrypoint。格式: entrypoint: /code/entrypoint.sh 也可以是列表格式: entrypoint: - php - -d - zend_extension=/usr/local/lib/php/extensions/no-debug-non-zts-20100525/xdebug.so - -d - memory_limit=-1 - vendor/bin/phpunit 示例: services: web: image: nginx:1.24.0 entrypoint: - tail - -f - /etc/os-release environmentenvironment功能: 添加环境变量。您可以使用数组或字典、任何布尔值,布尔值需要用引号引起来,以确保 YML 解析器不会将其转换为 True 或 False。格式: # map 格式environment: RACK_ENV: development SHOW: "true" USER_INPUT: # 数组格式environment: - RACK_ENV=development - SHOW=true - USER_INPUT= 示例: services: web: image: nginx:1.24.0 environment: TEST: 1 networks功能:配置容器网络示例: services: web: image: nginx:1.24.0 networks: - web1 - web2 networks: web1: web2: volume功能:配置容器的存储卷 #短语法volumes: - "/localhost/postgres.sock:/var/run/postgres/postgres.sock" - "/localhost/data:/var/lib/postgresql/data"#完整语法volumes:#命名卷 - type: volume source: db-data target: /data volume: nocopy: true#绑定卷 - type: bind source: /var/run/postgres/postgres.sock target: /var/run/postgres/postgres.sock 示例: services: web: image: nginx:1.24.0 volumes: - /home/qsy/gitDocker/data/myvolumes:/usr/share/nginx/html/ ports功能:配置容器的端口映射 #完整语法ports: - target: 80 host_ip: 127.0.0.1 published: 8080 protocol: tcp mode: host - target: 80 host_ip: 127.0.0.1#短语法ports: - "3000" - "3000-3005" - "8000:8000" - "9090-9091:8080-8081" - "49100:22" - "127.0.0.1:8001:8001" - "127.0.0.1:5000-5010:5000-5010" - "6060:6060/udp" 示例: services: web: image: nginx:1.24.0 ports: - 7070:80 expose功能:暴露端口,但不映射到宿主机,只被连接的服务访问。仅可以指定内部端口为参数.格式/示例: expose: - "3000" - "8000" depends_on功能:设置依赖关系 docker compose up:以依赖性顺序启动服务。在以下示例中,先启动 db 和 redis,才会启动 web。docker compose up SERVICE:自动包含 SERVICE 的依赖项。在以下示例中,docker compose up web 还将创建并启动 db 和 redis。docker compose stop:按依赖关系顺序停止服务。在以下示例中,web 在 db 和 redis 之前停止。version: "3.7"services: web: build: . depends_on: - db - redis redis: image: redis db: image: postgres env_file从文件添加环境变量。可以是单个值或列表的多个值。 env_file: xxx.env 也可以是列表格式: env_file: - ./.env - ./apps/web.env - /opt/secrets.env docker compose指令docker compose 指令与容器操作相似,只不过把容器改成了服务命令格式:docker-compose 命令的基本的使用格式为 docker compose [OPTIONS] COMMAND [ARGS...] 命令清单: docker compose build - 构建服务docker compose config - 以规范格式显示服务配置docker compose cp - 在本地系统和服务容器之间拷贝文件docker compose create - 创建服务的容器docker compose down - 停止所有容器并删除容器docker compose events - 从服务器获取实时事件docker compose exec - 在容器中执行命令docker compose images - 列出所有容器使用的镜像docker compose kill - 强制停止服务的容器docker compose logs - 显示容器日志docker compose ls - 显示所有项目docker compose pause - 暂停服务docker compose port - 列出所有的端口映射docker compose ps - 列出项目中目前的所有容器docker compose pull - 拉取服务镜像docker compose push - 推送服务镜像docker compose restart - 重启服务docker compose rm - 删除已停止的服务容器docker compose run - 在指定服务容器上执行命令docker compose start - 启动当前停止的容器docker compose stop - 停止当前运行的容器docker compose top - 显示运行的进程docker compose unpause - 恢复服务docker compose up - 构建、创建、启动和链接服务相关的容器(支持 --no-recreate 参数避免重新创建,-d 后台运行)docker compose version - 查看版本信息用法和功能与容器的相关指令类似,只是docker compose的操作对象是服务而已。参考文章:Docker容器核心指令关键命令选项up功能: 该命令的作用十分强大,它会尝试自动完成包括构建镜像、(重新)创建服务、启动服务并关联服务相关容器的一系列操作,可以直接通过该命令来启动一个项目。语法: docker compose up [options] [service...]运行本项目bash1选项说明: -d 在后台运行服务器,推荐在生产环境下使用该选项--force-recreate 强制重新创建容器,不能与 --no-recreate 同时使用--no-recreate 如果容器已经存在了,则不重新创建,不能与 --force-recreate 同时使用down功能:停止所有容器,并删除容器和网络。语法: docker compose down [options] [SERVICE...] 选项说明: -v, --volumes:删除容器同时删除目录映射。run功能:该命令可以在指定服务器上执行相关的命令语法: # 例如:启动一个 ubuntu 服务容器,并执行 ping docker.com 命令# docker compose run ubuntu ping docker.comdocker compose run [options] SERVICE [COMMAND] [ARGS...] 与docker run的区别,该指令是用服务启动容器,而不是镜像选项说明: -d 后台运行容器--name NAME 为容器指定一个名字--entrypoint CMD 覆盖默认的容器启动指令-e KEY=VAL 设置环境变量值,可多次使用选项来设置多个环境变量-u, --user="" 指定运行容器的用户名或者 uid--rm 运行命令后自动删除容器-p, --publish=[] 映射容器端口到本地主机示例: 综合案例docker-compose.yml配置 启动,会先启动依赖的服务。 清理,与启动相反,先清理主要的服务,然后清理依赖的服务。 ———————————————— 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 原文链接:https://blog.csdn.net/2302_80105876/article/details/151714145
-
一.容器实操测试基本操作与状态迁移基本操作:运行对应镜像(本地不存在就去远端拉取):启动实时日志监测:下面接着创建对应的容器,先不让他跑,然后看下状态变化:可以看到从create 和 stop 状态不同,且都能被start变成运行状态。下面测试下restart状态: 它的状态是从stop再次变成运行状态。测试下暂停状态:状态迁移:容器过滤与查询命令:根据名称过滤得到容器编号命令:docker container ls -qf name=xxx作用:通过名称筛选,仅返回匹配容器的 ID。根据状态过滤容器信息命令:docker container ls --filter status=running作用:只展示状态为 “running(运行中)” 的容器信息。静默获取全部容器 ID命令:docker container ls -aq作用:返回所有容器(包括运行和停止)的 ID,输出简洁无额外信息。过滤镜像名为 xxx 的容器信息命令:docker container ls --filter ancestor=xxx作用:依据镜像名称,筛选出使用该镜像的所有容器信息。过滤镜像 ID 为 xxx 的容器信息命令:docker container ls --filter ancestor=xxx作用:按照镜像 ID,找出基于该镜像创建的容器信息。命令参数解释:-a:列出所有容器(含已停止和正在运行的)。-q:仅返回容器的 ID,不显示其他详细信息。-f:基于指定条件过滤容器,等价于 --filter 选项,用于精准筛选目标容器。如下: 基于多命令组合执行:下面以start所有停止容器为例(~下面的符号): 可以发现所有stop的容器全部起来(除了被kill强制杀死的容器)。容器交互模式attach与detach模式attached 模式命令示例:docker container run -p 80:80 nginx,将宿主机 80 端口映射到容器 80 端口。端口映射说明:第一个 80 是宿主机端口,第二个 80 是容器端口。特点:容器在前台运行,访问时实时打印日志;在 Linux 服务器按 Ctrl+C 可能误停服务;仅适用于容器和程序的调试阶段。detached 模式启动方式:在 docker container run -p 80:80 nginx 命令后加 -d 或 --detach 选项。特点:容器在后台运行,启动时仅显示容器 ID,可继续输入其他命令;关闭窗口容器仍运行,停止或删除需用 shell 命令,减少误操作;比 attached 模式更推荐使用。 默认attach启动,前台被占用。下面试试退出后会怎么样? 发现容器就跟着挂了。下面用detach模式后台运行下(-d): 发现恢复了,无论是否ctrl c后,后台detach模式的容器都不受影响。下面测试下如果对应的网络断开,离线模式等情况会不会影响容器运行: 仍在运行。因此,总结下:默认就是attach模式,也就是前台运行,如果前台受到影响,自然容器就挂了,而如果detach模式,放在后台运行,无论前台咋样,即使离线,只要服务器没挂,容器正常运行不受影响;如果测试环境就用attach,前台运行,而生生产环境就用detach模式,后台运行。interactive模式用途:创建容器后,要在容器内获取信息或执行命令(如Ubuntu容器输Shell命令交互),需进交互模式。创建运行容器并进交互模式:参数:-i 保持容器运行,常与 -t 一起用,搭配 -it 容器创建后自动进入,退出则关闭;-t 为容器分配伪输入终端,常和 -i 配合。前台模式: 前台都需要手动启动nginx命令来开启这个访问,而后台默认自动启动。 发现正常启动。 无论如何ctrl c 都无法关闭,就类似一个bash终端一样。输入exit退出当前环境: 成功退出。测试后台模式: 后台程序,只要不bash,默认自动启动nginx指令。下面进行bash交互并退出: 这里退出只是退出当前容器里的执行bash的这个环境,退出的是这个bash,也就是退了这个在容器中执行命令的这个环境,然后并没退出nginx容器这个环境。总结下:前台运行容器,需要手动启动,而后台只要不启动bash后台就是自动启动nginx,然后前台以bash来运行接收exit退出容器的命令,如果无论是前台还是后台不是以bash运行,而是exec进入容器执行bash命令,此时exit就无法退出容器。也就是说exit是退出当前环境,而容器以bash运行(当前容器环境)和在容器中执行bash命令(exec对应的bash命令这个环境)不是同一个环境。二.宿主机与容器之间进行文件拷贝拿test2做测试:文件拷贝到宿主机:进行vim修改:图片访问原链接查看拷贝回去(覆盖性拷贝):图片访问原链接查看 进行重新访问:图片访问原链接查看 符合预期。不支持容器之间拷贝。三. 容器的自动删除与自动重启自动删除(run的时候带–rm)发现自动删除了,后台程序也是一样(注意是stop不是pause)。自动重启:docker run --restart=no [容器名]:默认值,不自动重启容器。docker run --restart=on-failure:3 [容器名]:仅在容器退出状态非0时自动重启,可指定重启次数(此处为3次),超过次数则放弃重启。docker run --restart=always [容器名]:容器退出时总是自动重启。docker run --restart=unless-stopped [容器名]:容器退出时总是自动重启,但不考虑Docker守护进程启动时就已经停止的容器。若容器启动时未设置--restart参数,可通过docker update --restart=always [容器名]命令更新重启策略。这里默认就是no(查看容器信息): 下面拿always模式测试下(这里需要进入容器,执行容器内设置的退出指令): 但是如果在容器外部被宿主机被stop了呢? 说明stop后不能被重启。四.容器环境变量设置与容器信息查看及借助容器执行特殊任务环境变量设置-e 参数(运行时设置)命令:docker run -e 变量名=值 镜像名特点:仅对当前运行容器有效,适合临时注入少量配置,如密码等敏感信息。–env-file 参数(运行时从文件加载)命令:docker run --env-file 文件路径 镜像名特点:从文件批量加载多个环境变量到当前运行容器,适合管理多个配置项。测试下:-e: 符合预期。--env-file :按照文件给它输进去: 符合预期。容器详情信息查看这里其实就是docker ps 与docker container inspect 容器名字 这两命令;前者是后者的简单提取,后者是更详细的: 宿主机靠容器执行单行命令我们可以直接借助 docker 的容器环境执行一些命令,比如容器中有某个命令而宿主机上没有这个时候借助容器可以完成某些任务。假设宿主机没有ping与ifconfig这个命令(借助busybox): 这里看到的都是容器的,以容器的视角执行的命令(一般测试容器命令的时候可以这样,测试的都是对外通用的命令)。———————————————— 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 原文链接:https://blog.csdn.net/2401_82648291/article/details/150776761
-
1、前言采用离线安装的方式。关于离线安装的方式官网有介绍,但是说的很简单,网址:Binaries | Docker Docs官网介绍的有几种主流linux系统的安装方式,但是没有kylin的,所以在此记录一下。在安装过程中也遇到了些问题,走了些弯路。在此记录的只是某一种能正常安装的方式,也许也有其它方式能够安装成功,欢迎一起交流。2、kylin系统信息官网上有关于系统要求的: 系统版本信息 查看Linux内核 查看iptables版本 查看处理器架构 3、下载官网下载对应版本:Index of linux/static/stable/ 麒麟系统是arm架构的,下载aarch64版本,下载的是当时最新版 4、安装将下载文件拷贝到kylin电脑目录下,解压: 将解压后的文件移动或拷贝到/usr/bin/目录下,注意使用sudo,后面的命令都要使用sudo。mv docker/* /usr/bin/AI写代码bash此时就可以查看docker版本 5、配置docker服务先创建两个系统文件(后面的操作都需要sudo)docker.servicevim /etc/systemd/system/docker.serviceAI写代码bash输入以下内容[Unit]Description=Docker Application Container EngineDocumentation=https://docs.docker.comAfter=network-online.target firewalld.serviceWants=network-online.targetRequires=docker.socket [Service]Type=notifyExecStart=/usr/bin/dockerdExecReload=/bin/kill -s HUP $MAINPIDTimeoutStartSec=0Restart=on-failureStartLimitBurst=3StartLimitInterval=60sLimitNOFILE=infinityLimitNPROC=infinityDelegate=yesKillMode=process [Install]WantedBy=multi-user.targetAI写代码bashdocker.socketvim /etc/systemd/system/docker.socketAI写代码bash输入以下内容[Unit]Description=Docker Socket for the APIPartOf=docker.service [Socket]ListenStream=/var/run/docker.sockSocketMode=0660SocketUser=rootSocketGroup=docker [Install]WantedBy=sockets.targetAI写代码bash为docker.service添加执行权限chmod +x docker.serviceAI写代码bash编辑daemon.json,没有就创建vim /etc/docker/daemon.jsonAI写代码bash输入以下内容{ "registry-mirrors":["https://mirrors.ustc.edu.cn"], "exec-opts":["native.cgroupdriver=systemd"]}AI写代码bash所有的配置文件编辑并保存后,执行systemctl daemon-reloadAI写代码bash6、启动docker服务systemctl start docker.serviceAI写代码bash如果想开机自动启动,输入以下指令:systemctl enable docker.serviceAI写代码bash7、验证docker是否安装成功执行 docker info 命令能显示如下信息: 或者输入 docker version(注意:没有 - ) 8、Hello world熟悉的 hello world……执行 docker run hello-world 命令报错:docker: Error response from daemon: Get "https://registry-1.docker.io/v2/": net/http: request canceled while waiting for connection (Client.Timeout exceeded while awaiting headers) 这种是镜像仓库路径配置的有问题,按照如下修改daemon.json:{ "registry-mirrors":["https://mirrors.ustc.edu.cn","https://docker-cf.registry.cyou","https://dockercf.jsdelivr.fyi","https://docker.jsdelivr.fyi","https://dockertest.jsdelivr.fyi","https://mirror.aliyuncs.com","https://dockerproxy.com","https://mirror.baidubce.com","https://docker.m.daocloud.io","https://docker.nju.edu.cn","https://docker.mirrors.sjtug.sjtu.edu.cn","https://docker.mirrors.ustc.edu.cn","https://mirror.iscas.ac.cn","https://docker.rainbond.cc" ], "exec-opts":["native.cgroupdriver=systemd"]}AI写代码bash保存退出,执行下面的命令:systemctl daemon-reloadsystemctl restart docker.servicedocket run hello-worldAI写代码bash出现以上信息应该就说明docker安装的没问题了。———————————————— 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 原文链接:https://blog.csdn.net/bailang_zhizun/article/details/147770700
-
华为云Docker教程在解决系统特异性问题(如依赖冲突、配置校验)上提供了实用方案,但需用户具备一定Linux排错能力。其与SWR镜像服务的深度整合,是构建稳定容器化管道的关键利器 💪。
-
我想本地部署deepseek,借助modelarts平台昇腾算力,在要拉取镜像时发现,modelarts的管理员权限不开放,导致我无法下载docker,卡在这里,我想在这里求助一下,还有其他下载docker的方法吗?
-
教程非常适合新手,学到了不少东西
-
【案例共创】ESC基于RAGFlow和DeepSeek构建本地问答知识库一、案例介绍在人工智能技术飞速发展的当下,企业知识库智能化正成为提升运营效率的核心路径。DeepSeek 几乎家喻户晓,而 RAGFlow 是一个基于深入文档理解的开源RAG(检索增强生成)引擎。当与LLMs集成时,它能够提供真实的问题回答功能,并由来自各种复杂格式数据的有理有据的引用支持。本次我们基于ESC使用 Docker 部署RAGFlow,并使用 ollama 部署 DeepSeek R1 模型和 bge-m3 嵌入模型,体验 RAGFlow 的知识库、对话、Agent等功能,通过RAGFlow的智能文档解析与DeepSeek大语言模型的精准推理能力,构建具备多源异构数据处理、语义深度理解及动态知识更新特征的问答知识库、Agent。二、案例用时本案例总时长预计120分钟。三、案例流程 说明:通过ECS中安装dokcer部署ragflow通过ECS中docker部署ollama来运行deepseek通过配置ragflow来调用deepseek-r1模型能力用过通过公网ip访问ECS从而体验ragflow+deepseek四、资源总览云资源消耗/时时长ECS(含公网IP、磁盘等)0.9885120min合计:1.977元五、实践步骤0. 购买ECS配置如下:bash计费模式: 按需计费区域: 西南-贵阳一可用区: 随机分配CPU架构:x86计算实例规格:通用计算增强型 | x1e.4u.16g | 4vCPUs | 16GiB镜像: 公共镜像-Ubuntu 24.04 server 64bit(10GiB)磁盘: 通用型SSD 50G弹性公网IP:现在购买-全动态BGP-按带宽计算-5Mbit/s-随实例释放云服务器名称:ecs-ragflow密码:RagFlow@123使用时长:设定删除时间为 8 小时之后购买数量: 1清单链接:https://www.huaweicloud.com/pricing/calculator.html?shareListId=267c3c60fc6411efa933bd915e6892f51、安装 RAGFlow1.1 安装 Docker CE 和 Docker Compose打开终端,新建 install-docker.sh:bash# 查看系统uname -alsb_release -a# 准备安装 dockercd ~pwdmkdir RAGFlowcd RAGFlowvi install-docker.sh写入以下脚本到 install-docker.shbash#!/bin/bash# 定义日志文件路径LOGFILE="/var/docker-install.log"# 将标准输出和错误输出重定向到日志文件,同时显示到终端exec > >(tee -a "$LOGFILE") 2>&1# 设置DEBUG模式下的时间戳输出格式trap '{ set +x; } 2>/dev/null; echo -n "[$(date -Is)] "; set -x' DEBUG# 下载并安装 docker CE 和 docker composeecho "开始安装 Docker CE 和 Docker Compose..."# 添加Docker官方GPG密钥curl -fsSL https://mirrors.huaweicloud.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -echo "已添加 Docker GPG 密钥"# 添加Docker软件源echo "" | sudo add-apt-repository "deb [arch=amd64] https://mirrors.huaweicloud.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"echo "已添加 Docker 软件源"# 更新软件包列表echo "正在更新软件包列表..."echo "y" | sudo apt-get update# 安装Docker CE和Docker Composeecho "正在安装 Docker CE 和 Docker Compose..."echo "y" | sudo apt-get install docker-ce docker-composeecho "Docker 安装完成"# 配置docker镜像仓库为华为云镜像echo "正在配置华为云镜像源..."sudo echo '{"registry-mirrors": ["https://b4a1f63a156e435f9aeb797bdf515250.mirror.swr.myhuaweicloud.com"]}' >/etc/docker/daemon.json# 重启docker服务使配置生效echo "正在重启 Docker 服务..."sudo systemctl restart dockerecho "Docker 配置完成"接着运行 docker 安装脚本:bashsudo bash ./install-docker.sh我们查看版本发现 docker-compse 版本有点低,可能会影响后续的安装,因此尝试升级 docker-composebashdocker -vdocker-compse -v升级 docker-compose:bash# 先看看 docker-compose 的路径whereis docker-compose# 备份一下sudo mv /usr/bin/docker-compose /usr/bin/docker-compose.bak# 下载对应系统的 docker-composewget https://github.com/docker/compose/releases/download/v2.33.1/docker-compose-linux-x86_64 -O docker-compose# 如果速度慢可以尝试使用加速源,如 https://hub.gitmirror.com/、https://github.moeyy.xyz/、https://ghfast.top/# wget https://hub.gitmirror.com/https://github.com/docker/compose/releases/download/v2.33.1/docker-compose-linux-x86_64 -O docker-compose# 也可以自行去 github 下载: https://github.com/docker/compose/releases# 替换 docker-composesudo cp ./docker-compose /usr/bin/docker-compose# 加权限sudo chmod +x /usr/bin/docker-compose# 验证docker-compose -v1.2 安装 RAGFlow先设置一下最大虚拟内存。vm.max_map_count该值设置进程可能拥有的内存映射区域的最大数量。它的默认值是65530。虽然大多数应用程序需要的映射少于一千个,但减小此值可能会导致异常行为,并且当进程达到限制时,系统将抛出内存不足错误。RAGFlow v0.17.0使用Elasticsearch或Infinity进行多次调用。正确设置vm.max_map_count的值对于Elasticsearch组件的正常运行至关重要。bash# 检查vm.max_map_count的值sysctl vm.max_map_count# 如果小于 262144 则至少设置为 262144sudo sysctl -w vm.max_map_count=262144接着安装 RAGFlowbash# 下载源码git clone https://github.com/infiniflow/ragflow.git# 如果下载比较慢请尝试使用镜像加速,如:# git clone https://ghfast.top/https://github.com/infiniflow/ragflow.gitcd ragflow/docker# 切换最新稳定分支 (截止 20205-03-08 为 0.17.0)git checkout -f v0.17.0git branch我们可以修改 .env 启用全量版本(非必须,可无须修改直接使用 slim 版本),并设置 docker 镜像源:bashsudo echo '{"registry-mirrors": ["https://b4a1f63a156e435f9aeb797bdf515250.mirror.swr.myhuaweicloud.com"]}' >/etc/docker/daemon.jsonRAGFlow镜像标签镜像大小(GB)是否包含嵌入模型和Python包是否稳定v0.17.0≈9✔️稳定版本v0.17.0-slim≈2❌稳定版本nightly≈9✔️nightly 构建不稳定nightly-slim≈2❌nightly 构建不稳定接着通过 docker-compose 启动 RAGFlow,全量的镜像约 9G,安装稍微慢些,需要耐心等待大约10分钟bash# 拉取镜像并启动(默认不包含 embedding 模型, 可以修改 .env 配置,选为华为云镜像v0.17.0 )# vi .env 找到对应位置进行修改docker-compose -f docker-compose.yml up -d# 如果minio拉取不顺,请尝试切换镜像源,需修改 docker-compose-base.yml 的:quay.io 为 quay.m.daocloud.io# 查看日志docker-compose logs -f ragflow-server# 查看端口情况netstat -nptl2. 访问本地 RAGFlow并配置模型RAGFlow是一个RAG引擎,需要与大模型服务一起搭配使用,实现本地、无幻觉的问答功能。RAGFlow支持大多数主流LLMs。2.1 访问本地RAGFlow 并注册账号登录如本次案例中 ecs-ragflow 的 ip 为1.95.184.111 则访问: http://1.95.184.111/login ,注册账号即可使用 RAGFlow。登录之后的主界面如下:⚠️本地模型为选配,同样可以使用其他大模型API服务,比如 Mass、硅基流动等2.2 通过 Docker 安装 ollama首先我们设置docker镜像源,重启docker之后,通过docker拉取ollama镜像并运行bash# 设置 docker 镜像源sudo echo '{"registry-mirrors": ["https://b4a1f63a156e435f9aeb797bdf515250.mirror.swr.myhuaweicloud.com"]}' >/etc/docker/daemon.jsonsudo systemctl restart dockersudo docker run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama2.3 安装 DeepSeek-R1 模型和 bge-m3 鉴于网络下载速度比较慢,我们拉取相对较小的 deepseek-r1:1.5b 和嵌入模型 bge-m3 (预计25分钟,具体看网络状况)bash# 拉取 deepseek-r1:1.5bsudo docker exec ollama ollama pull deepseek-r1:1.5b# 拉取 bge-m3sudo docker exec ollama ollama pull bge-m32.4 配置模型虽然RAGFlow和Ollama都是跑在同一台机器上,但由于分别使用了docker-compose和docker来部署,可能会导致网络不通的情况,那我们可以通过暴露 11434 ollama的端口来提高大模型服务。于是,我们在模型提供商选择Ollam之后分别配置了嵌入模型 bge-m3 和聊天模型deepseek-r1:1.5b。接着并在设置--系统模型设置中配置好聊天模型和嵌入模型。3. 简单使用接下来,我们简单体验一下RAGFlow 提供的功能,分别是知识库、聊天、搜索、Agent。3.1 知识库功能体验点击知识库,我们创建了一个名为ModelArts助手的知识库,传入了几个pdf文件作为本地知识库。在RAGFlow中知识库被称为数据集,我们可以上次多个文件作为数据集,并通过不通的解析方法将文档进行处理如切片、Q/A等。解析成功的文档可以在后续功能中作为知识库引入。3.2 聊天功能体验我们创建了ModelArts助手的助理,可以对助理进行配置如基本信息、关键词分析、模型参数设置等,并选取知识库作为回答语料。我们一个“如何快速入门”的简单问题开始,AI助理根据挂载的知识给了相关的回答。3.3 搜索功能体验在RAGFlow中,还有搜索功能,类似于传统的搜索引擎给出结果并添加了智能回答和思维导图。3.4 Agent功能体验最后我们来体验Agent功能,这里我们使用的是预置的 text2sql。Agent 会提供一个工作流编排界面,并提供运行测试功能,我们发现Agent也是可以作为单独的页面嵌入到其他网站,简单地要Agent给出“用户转化率”,它基于 deepseek-r1 模型,因此也有思考能力,最终它生成了一段完整的 SQL 语句。至此,案例实践就结束了,记得释放资源哦!记得释放资源哦!记得释放资源哦!我正在参加【案例共创】第2期 构建开发场景最佳实践/体验评测,创作案例文章cid:link_0
-
1.Docker应用部署(Mysql、tomcat、Redis、redis)https://bbs.huaweicloud.com/forum/thread-0251176000289103057-1-1.html 2. 鸿蒙NEXT开发案例:随机数生成https://bbs.huaweicloud.com/forum/thread-0226175856046738051-1-1.html3.ExaGear for Server on Ubuntuhttps://bbs.huaweicloud.com/forum/thread-02127175583262901024-1-1.html4.惊叹数据结构之美,品味排序算法之妙:对快排的详细介绍 -转载https://bbs.huaweicloud.com/forum/thread-0210175572143077031-1-1.html5.修改 Docker 容器的 http_proxy 和 https_proxy -转载https://bbs.huaweicloud.com/forum/thread-02127175572007355023-1-1.html6.【Linux】gdb_进程概念-转载https://bbs.huaweicloud.com/forum/thread-0257175571963347026-1-1.html7.详解Redis之事务-转载https://bbs.huaweicloud.com/forum/thread-0251175571892832022-1-1.html8.Python中的对象关系映射SQLAlchemy ORM在Web开发中的实践 -转载https://bbs.huaweicloud.com/forum/thread-0218175571849778026-1-1.html9.鸿蒙NEXT开发案例:颜文字搜索器https://bbs.huaweicloud.com/forum/thread-0225175848016900053-1-1.html10.鸿蒙NEXT开发案例:经纬度距离计算https://bbs.huaweicloud.com/forum/thread-02127175847897096052-1-1.html11.鸿蒙NEXT开发案例:世界时间表https://bbs.huaweicloud.com/forum/thread-0220175848120824046-1-1.html12.鸿蒙NEXT开发案例:保质期计算https://bbs.huaweicloud.com/forum/thread-0257175848211239048-1-1.html13.鸿蒙NEXT开发案例:九宫格随机https://bbs.huaweicloud.com/forum/thread-0257175848540835049-1-1.html14.Python中的对象关系映射SQLAlchemy ORM在Web开发中的实践 -转载https://bbs.huaweicloud.com/forum/thread-0218175571849778026-1-1.html15.【MySQL】 表的操作-转载https://bbs.huaweicloud.com/forum/thread-0220174982575490008-1-1.html
-
Docker 是一种开源的容器化技术,它可以帮助开发人员和运维人员以更高效、更轻松的方式管理应用程序和服务。通过容器技术,我们可以将应用与其所有的依赖包一起打包,使得应用可以在任何环境中快速、可靠地运行。本文将展示如何在 Docker 容器中部署 MySQL、Tomcat 和 Redis 服务,帮助你快速构建一个多服务的应用环境。1. 准备工作在开始 Docker 部署之前,请确保已经安装了 Docker。可以通过以下命令检查 Docker 是否安装成功:bashCopy Codedocker --version如果没有安装 Docker,可以参考官方文档进行安装:Docker 官方安装文档2. 部署 MySQL 服务2.1. 拉取 MySQL 镜像首先,我们需要拉取 MySQL 镜像。使用 Docker Hub 提供的官方 MySQL 镜像:bashCopy Codedocker pull mysql:latest2.2. 启动 MySQL 容器接下来,通过以下命令启动一个 MySQL 容器:bashCopy Codedocker run --name mysql-container -e MYSQL_ROOT_PASSWORD=root -d mysql:latest--name mysql-container:指定容器名称为 mysql-container。-e MYSQL_ROOT_PASSWORD=root:设置 MySQL 的 root 用户密码为 root。-d:以后台模式运行容器。mysql:latest:使用 mysql 的最新版本镜像。2.3. 连接到 MySQL 容器要进入 MySQL 容器,可以使用以下命令:bashCopy Codedocker exec -it mysql-container mysql -uroot -p输入密码 root 即可进入 MySQL 命令行。2.4. 设置数据库在 MySQL 中创建一个数据库和一个用户(可选):sqlCopy CodeCREATE DATABASE mydb; CREATE USER 'myuser'@'%' IDENTIFIED BY 'password'; GRANT ALL PRIVILEGES ON mydb.* TO 'myuser'@'%'; FLUSH PRIVILEGES;3. 部署 Tomcat 服务3.1. 拉取 Tomcat 镜像我们可以使用官方的 Tomcat 镜像:bashCopy Codedocker pull tomcat:latest3.2. 启动 Tomcat 容器启动 Tomcat 容器,指定要暴露的端口:bashCopy Codedocker run --name tomcat-container -d -p 8080:8080 tomcat:latest--name tomcat-container:指定容器名称为 tomcat-container。-d:后台运行容器。-p 8080:8080:将容器内的 8080 端口映射到主机的 8080 端口。Tomcat 启动后,可以通过浏览器访问 http://localhost:8080 来查看 Tomcat 默认的欢迎页面。3.3. 部署 Web 应用将自己的 WAR 文件部署到 Tomcat 中的 webapps 目录中,方法如下:bashCopy Codedocker cp your-app.war tomcat-container:/usr/local/tomcat/webapps/将 your-app.war 替换为你自己的应用包。重新启动 Tomcat 容器以加载新部署的应用:bashCopy Codedocker restart tomcat-container此时,你的应用可以通过 http://localhost:8080/your-app 来访问。4. 部署 Redis 服务4.1. 拉取 Redis 镜像我们可以使用官方的 Redis 镜像:bashCopy Codedocker pull redis:latest4.2. 启动 Redis 容器启动 Redis 容器并将端口映射到主机:bashCopy Codedocker run --name redis-container -d -p 6379:6379 redis:latest--name redis-container:指定容器名称为 redis-container。-d:后台运行容器。-p 6379:6379:将容器内的 6379 端口映射到主机的 6379 端口。4.3. 连接到 Redis 容器要连接到 Redis 容器,可以使用以下命令:bashCopy Codedocker exec -it redis-container redis-cli5. 测试应用是否正常运行测试 MySQL:可以通过以下命令测试 MySQL 服务是否正常运行:bashCopy Codedocker exec -it mysql-container mysql -uroot -p -e "SHOW DATABASES;" 这会列出当前 MySQL 实例中的所有数据库。测试 Tomcat:通过访问 http://localhost:8080,可以检查 Tomcat 是否成功启动。测试 Redis:可以通过以下命令测试 Redis 是否正常运行:bashCopy Codedocker exec -it redis-container redis-cli ping如果返回 PONG,则表示 Redis 正常运行。6. 总结通过 Docker 容器化技术,我们能够轻松地部署 MySQL、Tomcat 和 Redis 服务。Docker 提供了简单的命令来启动、配置和管理这些服务,使得开发和部署过程更加高效和便捷。通过容器化的方式,你可以确保应用在任何环境中都能保持一致性和可移植性。这种方法对于开发、测试以及生产环境的部署都非常有用,并且可以通过 Docker Compose 进一步简化多个服务的管理。希望这篇文章能帮助你更好地理解如何使用 Docker 部署和管理 MySQL、Tomcat 和 Redis 服务。
-
修改 Docker 容器的 http_proxy 和 https_proxy 可以通过几种方式实现。以下是一些常用的方法:在运行容器时设置环境变量:当你启动一个新的容器时,可以使用 -e 选项设置这些环境变量:docker run -e HTTP_PROXY=http://proxy.example.com:8080 -e HTTPS_PROXY=http://proxy.example.com:8080 your_image1对于已经运行的容器:a. 使用 docker exec 命令:docker exec -it your_container_name /bin/bashexport HTTP_PROXY=http://proxy.example.com:8080export HTTPS_PROXY=http://proxy.example.com:8080123注意,这种方法只在当前会话中有效,容器重启后就会失效。b. 修改容器的 /etc/environment 文件:docker exec -it your_container_name /bin/bashecho "HTTP_PROXY=http://proxy.example.com:8080" >> /etc/environmentecho "HTTPS_PROXY=http://proxy.example.com:8080" >> /etc/environment123这种方法在容器重启后仍然有效。在 Dockerfile 中设置:如果你正在构建自己的镜像,可以在 Dockerfile 中设置这些环境变量:ENV HTTP_PROXY http://proxy.example.com:8080ENV HTTPS_PROXY http://proxy.example.com:808012使用 Docker Compose:如果你使用 Docker Compose,可以在 docker-compose.yml 文件中设置环境变量:version: '3'services: your_service: image: your_image environment: - HTTP_PROXY=http://proxy.example.com:8080 - HTTPS_PROXY=http://proxy.example.com:8080修改 Docker 守护进程的配置:你可以为 Docker 守护进程设置全局代理,这会影响所有容器。编辑 /etc/systemd/system/docker.service.d/http-proxy.conf 文件(如果不存在就创建它):[Service]Environment="HTTP_PROXY=http://proxy.example.com:8080"Environment="HTTPS_PROXY=http://proxy.example.com:8080"123然后重启 Docker 服务:sudo systemctl daemon-reloadsudo systemctl restart docker12注意事项:确保使用正确的代理地址和端口。某些应用程序可能使用小写的环境变量名(http_proxy, https_proxy),你可能需要同时设置大写和小写版本。如果你的代理需要认证,格式应该是:http://username:password@proxy.example.com:8080———————————————— 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 原文链接:https://blog.csdn.net/jsyzliuyu/article/details/142873507
-
entrypoint.sh 文件通常用于 Docker 容器中,作为容器启动时执行的默认脚本。这个文件定义了容器启动时需要执行的一系列命令或操作。通过自定义 entrypoint.sh,开发者可以控制容器如何初始化、启动应用程序、设置环境变量等。下面是一些关于 entrypoint.sh 的关键点和用法示例:关键点启动应用程序:entrypoint.sh 中通常会包含启动容器中主要应用程序的命令。环境配置:可以在脚本中设置环境变量,确保应用程序在正确的环境中运行。权限管理:根据需要,脚本中可能包含更改文件或目录权限的命令。前置/后置操作:在启动应用程序之前或之后,可以执行一些前置或后置操作,比如数据库迁移、静态资源编译等。错误处理:添加错误处理逻辑,确保在出现问题时能够正确记录日志或进行其他处理。示例以下是一个简单的 entrypoint.sh 示例,它展示了如何设置环境变量、执行一个前置操作(如数据库迁移),然后启动应用程序:#!/bin/sh # 设置环境变量 export DATABASE_URL="postgres://user:password@db/dbname" # 前置操作:数据库迁移 echo "Running database migrations..." ./manage.py migrate # 启动应用程序 echo "Starting application..." exec gunicorn myapp.wsgi:application --bind 0.0.0.0:8000使用方法创建 entrypoint.sh 文件:在你的项目根目录或 Docker 上下文中创建一个名为 entrypoint.sh 的文件,并将上述脚本内容粘贴进去。修改权限:确保 entrypoint.sh 文件具有可执行权限。你可以使用 chmod +x entrypoint.sh 命令来设置。在 Dockerfile 中引用:在你的 Dockerfile 中,使用 COPY 命令将 entrypoint.sh 文件复制到镜像中,并使用 ENTRYPOINT 指令指定它为容器启动时执行的命令。例如:# ... 其他 Dockerfile 指令 ... COPY entrypoint.sh /entrypoint.sh RUN chmod +x /entrypoint.sh ENTRYPOINT ["/entrypoint.sh"] 构建和运行容器:使用 docker build 命令构建镜像,然后使用 docker run 命令启动容器。此时,容器将按照 entrypoint.sh 中定义的逻辑启动和运行。通过自定义 entrypoint.sh,你可以灵活控制 Docker 容器的启动过程,确保应用程序在最佳状态下运行。
-
开发者空间的ubuntu系统如何安装docker?试了好几种网上的方案,都报错
推荐直播
-
HDC深度解读系列 - Serverless与MCP融合创新,构建AI应用全新智能中枢2025/08/20 周三 16:30-18:00
张昆鹏 HCDG北京核心组代表
HDC2025期间,华为云展示了Serverless与MCP融合创新的解决方案,本期访谈直播,由华为云开发者专家(HCDE)兼华为云开发者社区组织HCDG北京核心组代表张鹏先生主持,华为云PaaS服务产品部 Serverless总监Ewen为大家深度解读华为云Serverless与MCP如何融合构建AI应用全新智能中枢
回顾中 -
关于RISC-V生态发展的思考2025/09/02 周二 17:00-18:00
中国科学院计算技术研究所副所长包云岗教授
中科院包云岗老师将在本次直播中,探讨处理器生态的关键要素及其联系,分享过去几年推动RISC-V生态建设实践过程中的经验与教训。
回顾中 -
一键搞定华为云万级资源,3步轻松管理企业成本2025/09/09 周二 15:00-16:00
阿言 华为云交易产品经理
本直播重点介绍如何一键续费万级资源,3步轻松管理成本,帮助提升日常管理效率!
回顾中
热门标签