先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Linux运维全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上运维知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注运维)
img

正文

find /path/to/search -type f -exec grep -l “search_string” {} ;

 这将在`/path/to/search`目录及其子目录中查找包含`"search_string"`的文件,并列出它们的文件名。
3. **ack/ag命令**:如果安装了`ack`(又称为`ack-grep`)或`ag`(又称为`The Silver Searcher`),它们是更高级的文本搜索工具,支持更多选项和正则表达式。安装后,可以运行以下命令来搜索字符串:
	1. **使用`ack`**:
	```
	ack "search\_string" file_name_or_directory
	
	```
	2. **使用`ag`**:
	```
	ag "search\_string" file_name_or_directory
	
	```这些工具通常比`grep`更快速和强大。
4. **grep命令递归搜索目录**:如果要递归搜索目录中的文件,可以使用`grep`的`-r`或`-R`选项。例如:

grep -r “search_string” /path/to/search

 这将在指定目录及其子目录中搜索包含`"search_string"`的文件。


### 2.5 读取操作系统环境变量


一个二进制程序(比如说叫hello),在运行时,需要读取操作系统的环境变量“CONFIG\_PATH”,我们希望运行这个二进制程序,并且只对运行该程序的命令设置CONFIG\_PATH环境变量为/home。该命令应该是怎么样的?


回答:  
 可以使用`echo`命令来读取操作系统环境变量的值。操作系统环境变量是一些全局设置,用于存储与系统操作和配置相关的信息。以下是如何读取环境变量的示例:


1. 读取一个环境变量的值,使用`$`符号后跟环境变量的名称来读取其值。例如,要读取`PATH`环境变量的值,可以运行以下命令:

echo $PATH
#这将显示PATH环境变量的值,该变量包含了系统中可执行程序的搜索路径。

2. 读取多个环境变量的值,可以使用多个环境变量名称来一次性读取它们的值。例如:

echo $HOME $USER $SHELL
#这将显示HOME、USER和SHELL环境变量的值。

3. 查看所有环境变量,可以使用env命令。运行以下命令:

env
#这将列出当前所有环境变量及其对应的值。

4. 查看单个环境变量的值并将其传递给其他命令,要查看`HOME`环境变量的值并在`cd`命令中使用它来切换到家目录,可以执行以下操作:

cd $HOME
这可以进入当前用户的home目录。



### 2.6 添加环境变量


#### 2.6.1 系统环境相关,涉及全局的环境变量


如果你要为你的`shell`永久性的增加一个环境变量,比如`COOL_VARIABLE`,变量值为`/home`,你都会进行哪些操作?可以用`linux`命令辅以描述进行回答。


要在`Linux`系统上添加环境变量,需要编辑`shell`配置文件,以便在每次登录或启动新终端会话时设置这些变量。在`Linux`中,最常见的`shell`配置文件是`.bashrc(对于Bash shell)`和`.profile`。下面是添加环境变量的一般步骤:


1. 打开终端。
2. 使用文本编辑器`vim`打开`shell`配置文件。根据使用的`shell`和系统配置文件的不同,可以执行以下操作之一:
	* 对于`Bash shell`,打开`~/.bashrc`文件(如果不存在,可以创建它):
	```
	vim ~/.bashrc
	
	```
	* 对于`Bash shell`的全局配置,打开`/etc/environment`文件:
	```
	sudo vim /etc/environment
	
	```
	* 对于`Bash shell`的全局配置(仅适用于`Debian/Ubuntu`系统),可以编辑`/etc/profile`文件:
	```
	sudo vim /etc/profile
	
	```
	* 对于其他`shell`,例如`Zsh`,可以编辑其对应的配置文件,例如`~/.zshrc`。
3. 在打开的配置文件中,添加环境变量。例如,要添加一个名为`MY_VARIABLE`的环境变量,以及它的值,可以像这样添加行:

export MY_VARIABLE=“your_value_here”

 请确保将`your_value_here`替换为想要设置的实际值。
4. 保存文件并退出文本编辑器。
5. 在终端中重新加载配置文件,以使新的环境变量立即生效。可以运行以下命令之一:
	* 对于`.bashrc`或其他用户级配置文件:
	```
	source ~/.bashrc
	
	```
	* 对于全局配置文件(例如`/etc/environment`):
	```
	source /etc/environment
	
	```
	* 对于全局配置文件(例如/etc/profile):
	```
	source /etc/profile
	
	```


现在,已成功添加了一个环境变量。可以使用`echo $MY_VARIABLE`来验证它是否设置正确。请确保在配置文件中添加的环境变量的名称和值没有任何拼写错误。




---



> 
> 答:一、给单个用户添加:  
>  ①:vim ~/.bash\_profile  
>  ②:export COOL\_VARIABLE= /home  
>  二、给所有用户添加:  
>  ①:vim /etc/profile  
>  ②:export COOL\_VARIABLE= /home
> 
> 
> 


#### 2.6.2 应用程序相关,某些程序使用的环境变量


`/etc/profile.d/`目录下存放的则是一些应用程序所需的启动脚本,包括颜色、语言、`less`、`vim`及`which`等命令的一些附加设置。这些脚本文件之所以能够被自动执行,是因为`/etc/profile`中使用了`for`循环来调用这些脚本。因此,如果您在`/etc/profile.d/`路径下新建脚本,则必须遵循该脚本中定义的环境变量。


示例:



export GOROOT=/usr/local/go
export GOPATH=/opt/goprojects
export GO111MODULE=on
export GOPROXY=https://proxy.golang.com.cn,direct
export PATH= P A T H : PATH: PATH:GOROOT/bin:$GOPATH/bin

export PATH=/opt/bin/:$PATH

export DSMS_ENV=dev


#### 2.6.3 /etc/profile和/etc/profile.d/的区别


* `/etc/profile`文件与系统环境相关,涉及的是全局变量,修改后对所有用户生效。当一个用户登录或使用`su -命令`切换到另一个用户时,`Login shell`会运行`/etc/profile`脚本。一些重要的变量,如`PATH`、`USER`、`LOGNAME`等,都是在该脚本中设置的。需要注意的是,只有`Login shell`启动时才会调用`/etc/profile`脚本,而`Non-login shell`则不会调用它。此外,在`/home/user/.bashrc`文件中设置的变量只对当前用户有用。
* `/etc/profile.d/`目录下存放的则是一些应用程序所需的启动脚本,包括颜色、语言、`less`、`vim`及`which`等命令的一些附加设置。这些脚本文件之所以能够被自动执行,是因为`/etc/profile`中使用了`for`循环来调用这些脚本。因此,如果您在`/etc/profile.d/`路径下新建脚本,则必须遵循该脚本中定义的环境变量。


**除了以上内容,还需要注意以下几点**:


1. `/etc/profile`会优先执行`/etc/profile.d/`目录下的所有`*.sh`文件。
2. 如果要使环境变量生效,需要使用`source /etc/profile`或`./profile`命令执行`/etc/profile`文件,并且不能使用`sh /etc/profile`命令,因为`sh`会在子`shell`进程中执行,导致变量无法反应到当前环境中。
3. `export`相当于导出变量,使其在当前`shell`进程中可用。如果希望下载软件后不加入路径就能启动该程序,必须将可执行程序的路径加入`PATH`中。


### 2.7 Linux下普通文件和可执行文件有什么区别


`Linux`可执行文件既可以是二进制文件,也可以是普通的文本文件,`关键是要有执行权限`。执行权限可以简单的用命令:`chmod +x 文件名` 来添加执行权限。


在`Linux`系统中,普通文件和可执行文件是两种不同类型的文件,它们有以下区别:


1. **内容**:
	* **普通文件(Regular File)**:普通文件包含数据,可以是文本文件、二进制文件、图像文件、音频文件等。这些文件通常用于存储文本、程序代码、媒体内容等。
	* **可执行文件(Executable File)**:可执行文件包含可以被计算机执行的二进制代码。这些文件通常是程序、脚本或二进制可执行文件,可以被操作系统执行。
2. **权限**:
	* **普通文件**:普通文件可以有不同的权限,包括读取(r)、写入(w)和执行(x)权限,这些权限决定了用户对文件的操作权限。但普通文件通常不会被直接执行。
	* **可执行文件**:可执行文件通常具有可执行权限(执行权限),这意味着它们可以被直接运行。要运行可执行文件,用户必须拥有执行权限,并且该文件必须具有正确的文件格式和执行入口点。
3. **文件类型**:
	* **普通文件**:普通文件的文件类型标识通常是-(减号),在ls -l等命令的输出中,普通文件的行以减号开头,如-rw-r–r–。
	* **可执行文件**:可执行文件的文件类型标识通常是-(减号),但它们具有执行权限,允许它们在系统上执行。
4. **用途**:
	* **普通文件**:普通文件用于存储数据或信息,如文本、配置文件、数据文件等。它们不会被直接执行,而是由其他程序或工具处理。
	* **可执行文件**:可执行文件是可以直接运行的程序或脚本。它们包含了计算机能够理解和执行的指令,可以在终端或通过其他方式运行。


普通文件和可执行文件在`Linux`系统中有不同的用途和特性。普通文件用于存储数据,而可执行文件用于执行计算机程序。可执行文件通常需要执行权限,以便操作系统能够运行它们。普通文件可以包含各种类型的数据,而可执行文件包含二进制代码,可以在计算机上执行。


### 2.8 Linux下进程间通信有几种方式


在`Linux`系统中,有多种进程间通信(`Inter-Process Communication,IPC`)的方式,允许不同的进程之间进行数据交换和协作。以下是常见的`Linux IPC`方法:


1. **管道(Pipe)**:
	* **匿名管道**:通过使用|操作符,可以将一个进程的标准输出连接到另一个进程的标准输入。这种方式适用于有父子关系的进程或者同时由一个外壳控制的进程。
	* **命名管道(FIFO)**:通过创建命名管道文件,多个进程可以使用该文件来进行通信。它们不需要共享父进程或同一个终端。
2. **消息队列(Message Queue)**:
	* 进程可以通过消息队列发送和接收消息。消息队列通常用于进程之间的异步通信,允许进程按顺序处理消息。
3. **信号(Signal)**:
	* 信号是`Linux`中用于通知进程发生事件的一种机制。进程可以发送信号给其他进程,例如`SIGTERM`用于请求进程终止。信号可用于实现基本的进程间通信。
4. **共享内存(Shared Memory)**:
	* 进程可以创建一个共享内存区域,多个进程可以将其映射到它们的地址空间,并直接读取或写入共享内存。这是一种高效的IPC方法,但需要处理同步和互斥问题。
5. **信号量(Semaphore)**:
	* 信号量是用于同步进程的计数器。它们可以用来控制多个进程对共享资源的访问,以避免竞争条件。
6. **套接字(Socket)**:
	* 套接字通常用于不同主机上的进程间通信,但也可用于同一主机上的进程通信。它们通常与网络编程相关,可以在不同计算机之间或同一计算机上的不同进程之间传递数据。
7. **文件锁(File Locking)**:
	* 进程可以使用文件锁来协调对共享文件的访问。通过文件锁,进程可以锁定文件的某部分以防止其他进程同时修改。
8. **信号文件(Signal File)**:
	* 进程可以创建信号文件,当其他进程检测到该文件存在时,它们可以进行相应的操作。这是一种简单的IPC方法。


每种`IPC`方式都有其适用的场景和特点。选择正确的`IPC`方法取决于应用程序需求和设计。不同的`IPC`方式具有不同的复杂性和性能特点,因此需要谨慎选择以确保进程间的协作和数据交换得以顺利进行。


### 2.9 Linux下僵尸进程和孤儿进程是怎么产生的


在`Linux`下,僵尸进程和孤儿进程是由于进程的父子关系和进程的终止行为引起的。下面我将解释它们是如何产生的:


1. **僵尸进程(Zombie Processes)**:僵尸进程是指已经终止但其父进程尚未调用`wait()`或`waitpid()`等系统调用来获取子进程的退出状态信息的进程。当一个子进程终止时,它会向父进程发送一个终止信号(`SIGCHLD`),父进程通常应该使用`wait()`或`waitpid()`来等待子进程的终止状态。如果父进程没有处理子进程的终止状态,子进程就会变成僵尸进程。


**僵尸进程的产生过程:**


* 子进程创建并开始执行。
* 子进程在某个时刻终止,并向父进程发送终止信号。
* 父进程未及时调用`wait()`或`waitpid()`来处理子进程的终止状态。
* 子进程的终止状态信息保留在系统中,形成僵尸进程。


解决僵尸进程问题的方法是,父进程应该定期调用`wait()`或`waitpid()`来回收子进程的资源和终止状态。


2. **孤儿进程(Orphan Processes)**:孤儿进程是指父进程在子进程终止之前就终止了,导致子进程的父进程变为init进程(通常进程ID为1)。init进程会负责回收孤儿进程并释放它们占用的系统资源。


孤儿进程的产生过程:


* 父进程创建子进程。
* 父进程在子进程终止之前终止。
* 子进程继续运行,但其新的父进程变为init进程。


孤儿进程通常不会导致资源泄漏或问题,因为它们最终会被init进程回收。然而,这种情况可能需要注意,因为孤儿进程在终止之前可能会执行一些操作。


**总结:**  
 僵尸进程是由于父进程未能正确处理子进程的终止状态而产生的,而孤儿进程是由于父进程在子进程终止之前终止而产生的。在编写和管理进程的代码时,应注意处理这两种情况,以确保系统资源得到正确回收。




---


参考1:[Linux操作系统之孤儿进程和僵尸进程]( )


`僵尸进程:`



> 
> 当一个进程调用 exit 命令结束自己的生命时,其实它并没有真正的被销毁,内核只是释放了该进程的所有资源,包括打开的文件、占用的内存等,但是留下一个称为僵尸进程的数据结构,这个结构保留了一定的信息(包括进程号 the process ID,退出状态,运行时间),这些信息直到父进程通过 wait()/waitpid() 才能释放。
> 
> 
> 



> 
> 但如果父进程没有这么做的话,此时,子进程虽然已经退出了,但是在系统进程表中还为它保留了一些退出状态的信息,如果父进程一直不取得这些退出信息的话,这系统进程表就将一直被占用,此时,这些占着茅坑不拉屎的子进程就成为“僵尸进程”。
> 
> 
> 


`孤儿进程:`



> 
> 父进程先于子进程结束,则子进程成为孤儿进程,子进程的父进程成为 init进程,称为 init 进程领养孤儿进程。
> 
> 
> 


### 2.10 Linux在使用TOP看CPU时负载和使用率有什么区别


参考1:[Linux中 cpu负载和cpu利用率的区别]( )


**CPU负载和CPU利用率的区别**  
 **CPU利用率**:显示的是程序在运行期间实时占用的CPU百分比。`top`命令中,`CPU`使用率由"us"(用户空间)和"sy"(系统内核空间)等字段表示,它们分别表示用户进程和系统内核的CPU使用率。


* "us"表示用户空间的CPU使用率,即由用户进程消耗的CPU时间。
* "sy"表示系统内核空间的CPU使用率,即由操作系统内核消耗的CPU时间。
* "ni"表示用户进程的低优先级CPU使用率。
* "id"表示CPU处于空闲状态的时间比例。
* "wa"表示CPU等待I/O操作完成的时间比例。
* "st"表示虚拟化环境中被虚拟机监控程序(hypervisor)"偷取"的时间比例。


高的`CPU`使用率可能表明系统的`CPU`资源正在被密集使用,这可能是由于运行大量计算密集型进程或`I/O`密集型操作。




---


**CPU负载**:显示的是一段时间内正在使用和等待使用`CPU`的平均任务数。通常以三个数字表示,分别对应于过去1分钟、5分钟和15分钟的时间段。负载的含义是等待运行的进程数,包括正在运行和等待`CPU`时间片的进程。负载的理想值取决于系统的核数,一般来说,负载应该低于系统的核数,以确保系统运行顺畅。


* 如果负载是1.0,表示系统上有一个进程正在运行,而其他进程正在等待。
* 如果负载是2.0,表示系统上有两个进程正在运行,而其他进程正在等待。
* 如果负载是0.5,表示系统上有一个进程正在运行,而另一个进程正在等待。


较高的负载可能表明系统过载,需要进一步分析,找出导致负载升高的原因。这可能包括CPU密集型任务、I/O等待等。


**总结:**  
 负载和`CPU`使用率是两个不同的性能指标,用于分别表示系统中等待运行的进程数量和`CPU`资源的利用情况。可以根据具体的性能问题来分析这两个指标,以了解系统的工作情况和性能瓶颈。


### 2.11 Linux查看网络带宽的命令


要在`Linux`中查看网络带宽使用情况,可以使用一些常见的命令工具来监视网络流量。以下是一些常用的命令:


1. **iftop**:`iftop`是一个交互式的实时流量监视器,它可以显示每个网络连接的带宽使用情况,以及流量的方向和速度。
	* **安装`iftop`(如果尚未安装)**:

sudo apt-get install iftop # 对于 Debian/Ubuntu
sudo yum install iftop # 对于 CentOS/RHEL


	* **运行`iftop`**:

sudo iftop

2. **nload**:`nload`是一个简单的命令行工具,用于显示网络流量的实时图形化视图。
	* **安装`nload`(如果尚未安装)**:

sudo apt-get install nload # 对于 Debian/Ubuntu
sudo yum install nload # 对于 CentOS/RHEL


	* **运行nload**:

nload

3. `iftop`和`nload`都是交互式的工具,可以在终端中实时查看网络带宽使用情况。要退出这些工具,通常可以按下 Ctrl+C。
4. **iperf**:`iperf`是一个网络性能测试工具,可以用来测量网络带宽和性能。可以在两台计算机之间运行服务器端和客户端,以测量它们之间的带宽。
	* **安装iperf(如果尚未安装)**:

sudo apt-get install iperf # 对于 Debian/Ubuntu
sudo yum install iperf # 对于 CentOS/RHEL


	* **运行iperf服务器端(在一台计算机上)**:

iperf -s


	* **运行iperf客户端(在另一台计算机上,替换<server\_ip>为服务器的 IP 地址)**:

iperf -c <server_ip>

5. **sar**:`sar`命令(`System Activity Reporter`)可以用于收集和报告系统的各种性能指标,包括网络带宽使用情况。
	* **安装sar(如果尚未安装)**:

sudo apt-get install sysstat # 对于 Debian/Ubuntu
sudo yum install sysstat # 对于 CentOS/RHEL


	* **运行sar来查看网络带宽使用情况**:

sar -n DEV 1

 上述命令中的`-n DEV`选项用于显示网络接口的统计信息,1表示每秒更新一次。


请根据需求选择适当的工具来监视网络带宽使用情况。这些工具可以帮助实时跟踪网络流量,了解网络性能并排查潜在的问题。


### 2.12 Linux软连接和硬连接的区别


在`Linux`系统中,有两种主要的文件链接类型:`软连接(Symbolic Link,也称为符号链接)`和`硬连接(Hard Link)`。它们都用于创建文件之间的关联,但它们之间存在一些关键差异。


* 软连接是一个独立的文件,指向另一个文件或目录的路径。它可以跨越文件系统和指向不存在的目标,但它更脆弱,因为目标被删除或移动后,它会变成坏链接。
* 硬链接是源文件的副本,与原始文件共享相同的`inode`。它只能在同一文件系统上创建,不可以指向目录,但当原始文件被删除后,硬链接仍然保留数据。


**软连接(Symbolic Link):**


1. **特点**:
	* 软连接是一个特殊的文件,它包含了指向另一个文件或目录的路径。
	* 它可以跨越不同的文件系统,甚至可以指向不存在的目标。
	* 软连接可以指向文件或目录。
2. **创建方式**:使用`ln -s`命令创建软连接。

ln -s /path/to/target /path/to/symlink

3. **修改源文件或目录**:如果原始文件或目录被删除或移动,软连接仍然存在,但它将变为`坏链接(dangling link)`。
4. **权限**:软连接有自己的权限和所有者,但实际上它是一个指向目标的路径,因此权限检查是针对目标而不是软连接本身的。
5. **示例**:

ln -s /usr/bin/python3 /usr/local/bin/python



**硬连接(Hard Link):**


1. **特点**:
	* 硬链接是目标文件或目录的一个副本,它与原始文件有相同的`inode`号。
	* 硬链接只能在同一个文件系统中创建,且不能指向目录。
	* 当删除原始文件时,硬链接仍然可以访问数据,因为它们共享相同的`inode`。
2. **创建方式**:使用`ln`命令创建硬链接。

ln /path/to/target /path/to/hardlink

3. **修改源文件**:所有硬链接都与源文件共享相同的数据和元数据,因此修改一个硬链接将影响其他硬链接以及源文件本身。
4. **权限**:硬链接不具有自己的权限和所有者。权限检查仍然是基于文件本身。
5. **示例**:

ln /etc/fstab /tmp/fstab-hardlink



### 2.13 Linux中TCP的配置参数有哪些


参考1:[linux下如何配置TCP参数设置详解]( )


1. **TCP最大连接数(net.core.somaxconn)**:
	* **描述**:这个参数定义了处于半连接状态(`SYN_RCVD`)的最大连接请求队列的大小。
	* **默认值**:128
2. **TCP最大挂起连接数(net.ipv4.tcp\_max\_syn\_backlog)**:
	* **描述**:定义了半连接状态(`SYN_RCVD`)的最大挂起连接数,即等待`accept()`的连接队列的大小。
	* **默认值**:1024
3. **TCP连接超时时间(net.ipv4.tcp\_synack\_retries)**:
	* **描述**:定义了`TCP`连接建立的最大尝试次数,通常在`SYN-ACK`重传方面使用。
	* **默认值**:5
4. **TCP最大窗口尺寸(net.ipv4.tcp\_window\_scaling)**:
	* **描述**:启用`TCP`窗口自动缩放,允许更大的`TCP`窗口尺寸,以提高网络性能。
	* **默认值**:1(开启)
5. **TCP最大接收窗口尺寸(net.core.rmem\_max)**:
	* **描述**:定义了`TCP`接收缓冲区的最大尺寸。
	* **默认值**:默认取决于系统版本和配置。
6. **TCP最大发送窗口尺寸(net.core.wmem\_max)**:
	* **描述**:定义了`TCP`发送缓冲区的最大尺寸。
	* **默认值**:默认取决于系统版本和配置。
7. **TCP延迟确认时间(net.ipv4.tcp\_delack\_min)**:
	* **描述**:定义了`TCP`延迟确认(`Delayed ACK`)的最小延迟时间。
	* **默认值**:40(毫秒)
8. **TCP最大连接数限制(net.core.netdev\_max\_backlog)**:
	* **描述**:定义了在接口上排队等待处理的入站数据包的最大数量。
	* **默认值**:1000
9. **TCP保持连接超时时间(net.ipv4.tcp\_keepalive\_time)**:
	* **描述**:定义了`TCP`连接保持活跃的时间间隔。
	* **默认值**:7200秒(2小时)
10. **TCP重传超时时间(net.ipv4.tcp\_retries2)**:
	* **描述**:定义了`TCP`连接中的重传尝试次数。
	* **默认值**:15


这些参数可以通过在`/etc/sysctl.conf`或相关的配置文件中进行设置,并通过`sysctl`工具来加载或重新加载。例如,要永久更改参数,可以编辑`/etc/sysctl.conf`文件,然后运行`sysctl -p`以应用新的配置。


注意,在调整这些参数时,需要谨慎,以避免对系统性能和稳定性产生不利影响。建议在调整参数之前详细了解它们的含义和影响,并在生产环境中小心测试。


### 2.14 Linux查看当前连接服务器的前10位Ip


要查看当前连接到服务器的前10位`IP`地址,可以使用以下命令结合一些其他命令来实现。这里使用`netstat`和`awk`命令来实现:



netstat -tn 2>/dev/null | awk ‘{print $5}’ | cut -d: -f1 | sort | uniq -c | sort -nr | head -n 10


命令的各个部分:


1. `netstat -tn 2>/dev/null`:这部分命令用于列出当前网络连接。`-t`选项表示只显示`TCP`连接,`-n`选项表示以数字形式显示`IP`地址和端口号,`2>/dev/null`用于将错误信息重定向到空设备,以避免显示不必要的错误信息。
2. `awk '{print $5}'`:这将提取`netstat`输出的第`5`列,即远程`IP`地址和端口。
3. `cut -d: -f1`:这将从`IP`地址和端口中提取`IP`地址部分,因为我们只关心`IP`地址。
4. `sort`:这将对`IP`地址进行排序。
5. `uniq -c`:这将统计每个`IP`地址的出现次数,并在前面显示出现次数。
6. `sort -nr`:这将按逆序(从最多到最少)对`IP`地址按出现次数排序。
7. `head -n 10`:最后,这将显示前10个`IP`地址,这些地址最频繁地连接到服务器。


执行这个命令后,将看到列出了前10个最频繁连接到服务器的`IP`地址。请注意,这些`IP`地址可能是服务器上不同的客户端或服务的地址。


### 2.15 Linux理论上最多能开多少个端口?


在`Linux`系统中,理论上最多可以打开的端口数是65535,这是因为`TCP`和`UDP`协议的端口号范围是0到65535(2^16 - 1)。这范围中的0到1023端口号通常被称为"系统端口",用于标准协议和服务(如HTTP的80端口、SSH的22端口等),而范围中的1024到65535端口号通常被称为"动态端口",用于应用程序和临时网络连接。


然而,实际上,不同的`Linux`系统可能会有一些限制,导致不能实际上打开这么多端口。这些限制包括:


1. **可用端口范围**:有些`Linux`系统可能限制了可以使用的端口范围,尤其是在低端口号上,以确保系统服务的正常运行。
2. **系统资源**:打开大量端口需要占用系统资源,如文件描述符(file descriptors),因此操作系统可能会限制每个进程可以打开的文件描述符数量。
3. **网络硬件和性能**:实际的网络硬件和性能也可能成为限制因素,因为大量并发的网络连接可能会影响网络性能。


通常情况下,不需要打开太多端口。如果需要处理大量并发连接,可以使用高级的网络编程技术,如使用多线程、多进程或事件驱动的服务器来有效地管理连接。此外,一些负载均衡和反向代理解决方案也可以帮助分散流量,减轻单一服务器上的连接负担。


### 2.16 假如服务器有瓶颈,你一般看哪些指标?你通过什么命令去看看哪些指标?


当服务器出现性能瓶颈时,通常需要监视各种系统性能指标,以帮助定位问题并找出潜在的瓶颈原因。以下是一些常见的性能指标和相应的`Linux`命令,用于查看这些指标:


1. **CPU利用率**:
	* 查看整体`CPU`利用率:`top` 或 `htop`
	* 查看每个`CPU`核心的利用率:`mpstat -P ALL 1` 或 `top` 中按1键
2. **内存利用率**:
	* 查看内存使用情况:`free -m`
	* 查看内存详细信息:`top` 或 `htop`
3. **磁盘使用情况**:
	* 查看磁盘空间:`df -h`
	* 查看每个磁盘分区的I/O统计:`iostat -dx 1`
4. **网络状况**:
	* 查看网络接口的统计信息:`ifconfig` 或 `ip -s link`
	* 查看网络连接状态:`netstat -tuln` 或 `ss -tuln`
5. **进程和负载**:
	* 查看运行中的进程:`ps aux` 或 `top`
	* 查看系统负载:`uptime`
6. **日志文件**:
	* 查看系统日志:`cat /var/log/syslog 或 cat /var/log/messages`
	* 查看应用程序日志:根据应用程序的日志文件位置,通常在`/var/log`目录下。


通过监视这些指标,您可以获得关于服务器性能的详细信息,从而识别潜在的瓶颈。一般来说,高`CPU`利用率可能表示`CPU`瓶颈,高内存利用率可能表示内存瓶颈,高磁盘`I/O`可能表示磁盘瓶颈,高网络流量可能表示网络瓶颈。


针对特定问题,还可以使用其他专门的工具和命令来进行深入的性能分析,如`strace`、`vmstat`、`iotop`、`netstat`、`sar` 等。不同的性能问题可能需要不同的工具和方法来诊断和解决。


### 2.17 Linux下使用free查看内存,这个可用内存是怎么看的?真正可用的内存是有哪些?


在`Linux`系统中,`free`命令用于查看内存使用情况,其中的"可用内存"并不总是直观理解的,因为它会考虑操作系统的内存管理策略。可用内存不仅包括空闲的物理内存,还包括操作系统使用的内存中的可回收部分。  
 **free命令的输出通常如下所示:**



          total        used        free      shared  buff/cache   available

Mem: 16336232 4394884 5297220 618156 6642128 10956416
Swap: 0 0 0


其中,`"available"`行的数值表示当前系统的可用内存。  
 "可用内存"包括以下几个部分:


1. **“free”**:表示完全未使用的物理内存。
2. **“buff/cache”**:表示操作系统使用的内存中,可以被回收的部分,包括磁盘缓存(`buffer`)和页面缓存(`cache`)。这些内存可以在需要时迅速释放,以供应用程序使用。
3. **“used”**:表示操作系统当前使用的内存总量。
4. **“shared”**:表示被共享的内存,通常由共享库等共享资源使用。
5. **“available”**:表示可供应用程序使用的内存,包括未使用的内存、缓存和共享内存。这是当前系统中可以分配给新进程的内存数量。


在实际使用中,`"available"`行的数值更接近于实际可用内存。如果您需要获取精确的可用内存信息,可以使用`Linux`系统的 `/proc/meminfo`文件,或者借助其他工具如 `htop`、`top` 来查看更详细的内存使用情况。


**注意**:`Linux`内存管理是动态的,因此内存的可用性会根据系统的工作负载和内存管理策略而变化。在大多数情况下,`Linux`会尽力充分利用可用内存来提高性能,将不再需要的内存用于缓存,以减少磁盘I/O等。这种内存管理策略可以提高系统性能,但可能会导致"可用内存"的数值看似较低。


### 2.18 用没有用过Linux作为路由器使用?


在`Linux`系统上,可以将其配置为路由器以用于网络数据包转发和路由功能。以下是一些步骤来将`Linux`系统配置为路由器:


1. **启用IP转发**:首先,需要确保`Linux`系统上的IP转发功能已经启用。可以通过修改内核参数来实现:



sudo sysctl -w net.ipv4.ip_forward=1


这将启用`IPv4`数据包转发功能。如果需要`IPv6`支持,可以使用类似的命令来启用`IPv6`数据包转发。  
 2. **配置网络接口**:配置`Linux`系统上的网络接口,确保每个接口都有正确的IP地址和子网掩码。可以使用`ifconfig`或`ip`命令来配置网络接口。例如:



sudo ifconfig eth0 192.168.1.1 netmask 255.255.255.0


这将配置`eth0`接口的`IP`地址为`192.168.1.1`,子网掩码为`255.255.255.0`。可以根据网络拓扑和需求配置其他接口。  
 3. **配置静态路由或使用动态路由协议**:如果需要将数据包从一个网络转发到另一个网络,需要配置静态路由规则或使用动态路由协议(如BGP、OSPF、RIP)来管理路由表。可以使用`ip route`命令来配置静态路由。



sudo ip route add 10.0.0.0/24 via 192.168.1.2 dev eth0


这将添加一个静态路由,将数据包目的地为`10.0.0.0/24`的数据包发送到`192.168.1.2`的网关,通过`eth0`接口进行转发。  
 4. **配置NAT(Network Address Translation)**:如果要将内部网络连接到公共互联网,通常需要配置`NAT`,以便将内部`IP`地址映射到一个公共`IP`地址。可以使用`iptables`来配置NAT规则。



sudo iptables -t nat -A POSTROUTING -o eth1 -j MASQUERADE


这将配置`NAT`规则,允许数据包从`eth1`接口出口并将源`IP`地址替换为该接口的`IP`地址,以实现`Internet`访问。  
 5. **防火墙设置**:配置适当的防火墙规则以保护你的路由器和网络。使用`iptables`或其他防火墙工具来配置入站和出站规则,确保只有授权的流量可以通过。


这些步骤是将`Linux`系统配置为路由器的基本步骤。具体的配置可能会根据网络拓扑和需求而有所不同。确保在进行配置时谨慎操作,并考虑网络安全和性能方面的需求。


### 2.19 你对Linux系统的node指标的理解是怎么样的?比如负载。(待进一步验证)


负载的话,看三个指标吧,一个是这个CPU,然后还有就是内存,最后就是这个它的这个硬磁盘的使用情况,然后这三方面来看,然后还有的话,如果可能就是这个网络情况吧,是这样。


### 2.20 这个node的值它一般到多大是算高?需要介入排查呢?


### 2.21 系统指标采集,比如你需要你用go写一个agent,采集agent,那采集这些系统指标的一般的实现方法大概有哪些?(待进一步验证)


采集CPU、内存、硬盘、网络,然后还有程序的运行数量。


### 2.22 你怎么用go代码去拿这些数据呢?(待进一步验证)


go 的话它里面它有一个包是OS,它这个里面的话主要是与系统相关的,应该可以通过这个包里面的一些方法来获取到这个系统服务器上面的一些参数。


### 2.23 在linux服务器上的话一般是用什么命令要看日志?


1. **查看系统日志**:使用journalctl命令可以查看systemd日志。这个命令提供了很多选项,可以用于筛选和查找特定的日志信息。

journalctl

2. **查看特定日志文件**:使用cat、tail、less等命令可以查看特定日志文件的内容。例如,查看/var/log/syslog文件的最后几行:

tail /var/log/syslog

3. **查看实时日志**:使用tail命令的-f选项可以实时查看日志文件的新增内容,有助于实时监控系统状态。

tail -f /var/log/syslog

4. **查看指定服务的日志**:使用journalctl命令,结合-u选项可以查看特定服务的日志。例如,查看SSH服务的日志:

journalctl -u ssh

5. **查看错误日志**:使用dmesg命令可以查看内核环缓冲区的内容,显示系统启动过程中的消息和错误信息。

dmesg

6. **查看登录信息**:使用last命令可以查看登录历史记录,显示系统上的用户登录信息。

last

7. **查看用户活动日志**:使用w或who命令可以查看当前登录用户的活动。

w

8. **查看应用程序日志**:不同的应用程序可能会将日志存储在不同的位置。通常,应用程序的日志会存储在/var/log目录下,具体位置和命名可能会因发行版和应用程序而有所不同。


这些命令和工具提供了一些基本的日志查看和分析功能。在实际应用中,可以根据具体的需求使用其他工具和技术,如grep、awk、sed等,以及日志分析工具如 Logrotate、ELK Stack等。


### 2.24 每周定时备份一下MySQL的一个数据库,shell脚本该怎么写。



#!/bin/bash

MySQL 连接信息

DB_HOST=“localhost”
DB_USER=“your_username”
DB_PASS=“your_password”
DB_NAME=“your_database”

备份存储路径

BACKUP_DIR=“/path/to/backup”

当前日期作为备份文件名前缀

DATE_PREFIX=$(date +%Y%m%d)

创建备份目录

mkdir -p $BACKUP_DIR

完整备份文件名

BACKUP_FILE=“ B A C K U P _ D I R / BACKUP\_DIR/ BACKUP_DIR/DATE_PREFIX-$DB_NAME.sql”

使用 mysqldump 导出数据库

mysqldump -h $DB_HOST -u D B _ U S E R − p DB\_USER -p DB_USERpDB_PASS $DB_NAME > $BACKUP_FILE

检查备份是否成功

if [ $? -eq 0 ]; then
echo “MySQL backup completed successfully: $BACKUP_FILE”
else
echo “Error: MySQL backup failed!”
fi


脚本的说明:


1. 修改DB\_HOST、DB\_USER、DB\_PASS、DB\_NAME分别为你的MySQL主机、用户名、密码、以及要备份的数据库名称。
2. 修改BACKUP\_DIR为你希望存储备份文件的目录。
3. 使用date命令生成当前日期作为备份文件名的前缀。
4. 使用mysqldump命令导出MySQL数据库到指定的备份文件中。
5. 在脚本中使用条件语句检查导出过程是否成功,输出相应的信息。


请确保你在脚本中妥善处理数据库连接信息,以确保安全性。你可能需要设置脚本的执行权限,并使用cron作业调度工具来定期执行脚本。例如,将以下内容添加到你的 crontab文件中,以每周日的凌晨3点执行备份:



0 3 * * 0 /path/to/your/script.sh


这表示在每周日的凌晨 3 点执行指定的脚本。根据实际情况调整路径和时间。


## 3 Docker


`Docker`是一个用于开发、运输和运行容器化应用程序的平台。容器是轻量级、独立和可执行的软件包,包括运行一个软件所需的一切,包括代码、运行时、系统工具、库和设置。`Docker`因其简化创建、部署和管理应用程序的过程而在软件开发和部署领域广受欢迎。


### 3.1 Docker特点 / 优势


1. **轻量级容器**:`Docker`容器非常轻量,因此可以在几秒钟内启动和停止。与传统虚拟化相比,它们消耗更少的资源,因此可以在同一物理主机上运行多个容器。
2. **一致性**:`Docker`容器包含了应用程序及其所有依赖项,包括库、运行时和配置文件。这确保了在不同环境中容器的一致性,从而减少了“在我的机器上可以工作”的问题。
3. **可移植性**:`Docker`容器可以在不同的环境中运行,无论是开发、测试、生产服务器还是云计算平台,都可以保持一致。这使得应用程序更容易迁移到不同的部署环境。
4. **快速部署**:由于容器可以快速启动,因此应用程序可以更快地部署和扩展。这对于需要快速响应用户需求的情况非常有用。
5. **隔离性**:`Docker`容器提供了高度的隔离,使应用程序之间和与主机系统之间保持独立。这意味着一个容器的问题不会影响其他容器或主机系统。
6. **版本控制和镜像管理**:`Docker`允许创建和管理容器镜像,这些镜像可以与其他开发人员和团队共享。可以使用`Docker Hub`或自己的私有注册表来存储和分享镜像。
7. **易于扩展**:`Docker`容器可以根据需要水平扩展,以满足流量和资源需求的增加。容器编排工具如`Kubernetes`和`Docker Swarm`可以帮助自动化和管理扩展过程。
8. **生态系统**:`Docker`拥有庞大的生态系统,有丰富的第三方工具和服务,可以扩展`Docker`的功能,例如监控、日志记录、安全性、网络等方面。
9. **开源和社区支持**:`Docker`是一个开源项目,拥有活跃的社区支持。这意味着有大量的文档、教程和社区贡献的工具和插件可供使用。
10. **多平台支持**:`Docker`不仅限于`Docker`,还支持`Windows`和`macOS`等操作系统,因此可以在多个操作系统上使用相同的Docker容器。


总的来说,`Docker`的特点包括高度的可移植性、一致性、隔离性和快速部署,使其成为开发人员和运维团队的有力工具,用于构建、交付和管理现代应用程序。


### 3.2 Docker架构


`Docker`的架构是一个分层的体系结构,它包括多个组件,每个组件都有特定的功能。以下是Docker的主要架构组件:


1. **Docker守护程序(Docker Daemon)**:`Docker`守护程序是`Docker`的后台服务,负责管理Docker容器的生命周期。它接收来自`Docker`客户端的命令,并与容器运行时交互来创建、启动、停止和删除容器。`Docker`守护程序还管理镜像、网络、存储和卷等资源。
2. **Docker客户端**:`Docker`客户端是与用户交互的命令行工具或`API`客户端。用户可以使用`Docker`客户端通过命令行界面或`API`与`Docker`守护程序通信,以执行各种`Docker`操作。
3. **Docker镜像(Docker Images)**:`Docker`镜像是容器的只读模板,包含了运行容器所需的文件系统、应用程序代码、运行时、系统工具、库和配置。镜像可以被用来创建多个容器实例。`Docker`镜像采用分层存储,这意味着它们可以共享相同的基础层,从而节省存储空间。
4. **Docker容器(Docker Containers)**:`Docker`容器是`Docker`镜像的可运行实例。容器包括应用程序及其依赖项,并在隔离的环境中运行。容器是轻量级、可移植的,并且可以在不同的主机上运行,而不受主机操作系统的影响。
5. **Docker仓库(Docker Registry)**:`Docker`仓库是用于存储和分享`Docker`镜像的中央位置。`Docker Hub`是一个公共`Docker`仓库,开发人员可以在其中找到和分享镜像。还可以设置自己的私有`Docker`仓库。
6. **Docker Compose**:`Docker Compose`是一个用于定义和运行多容器`Docker`应用程序的工具。它使用`YAML`文件来描述应用程序的服务、网络、卷等配置,可以简化复杂应用程序堆栈的管理。
7. **Docker网络**:`Docker`提供多种网络模式,允许容器之间进行通信,以及容器与外部网络的连接。这包括桥接网络、主机网络、覆盖网络等。
8. **Docker存储**:`Docker`容器可以访问持久化存储,包括卷(`volumes`)和绑定挂载(`bind mounts`)。这允许容器在运行时持久化保存数据,并与主机文件系统交互。
9. **Docker编排工具**:`Docker`提供编排工具,如`Docker Swarm`和`Kubernetes`,用于自动化和管理多个容器的部署、伸缩和编排。


`Docker`的架构允许开发人员和运维人员轻松创建、交付和运行容器化应用程序,实现了应用程序的一致性、可移植性和隔离性。容器技术已经成为现代软件开发和部署的重要组成部分,为应用程序开发和部署带来了更高的效率和可靠性。  
 ![在这里插入图片描述](https://img-blog.csdnimg.cn/72a95ca75e1840b18c52a92f0ffb0dfd.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA6KW_5pyoUWk=,size_20,color_FFFFFF,t_70,g_se,x_16)


### 3.3 Docker底层原理


`Docker`的底层原理涉及多个关键技术和组件,包括`Linux`容器、`cgroups`、命名空间、联合文件系统以及`Docker`自身的架构。以下是`Docker`底层原理的关键要点:


1. **Linux容器(Linux Containers,LXC)**:`Docker`基于`Linux`容器技术,这是`Linux`内核提供的一种虚拟化技术。容器允许将一个应用程序及其依赖项隔离到一个独立的用户空间中,但与宿主操作系统共享内核资源。这种隔离性使容器可以在不同的环境中运行,同时具有较低的资源开销。
2. **命名空间(Namespaces)**:命名空间是`Linux`内核提供的一种机制,用于隔离不同进程之间的资源。`Docker`使用不同类型的命名空间来隔离进程的文件系统、网络、进程、用户等方面的视图,从而实现容器的隔离。
3. **cgroups(Control Groups)**:`cgroups`是`Linux`内核的特性,用于限制和管理资源的使用,如`CPU`、内存、磁盘`I/O`等。`Docker`使用`cgroups`来确保容器不会耗尽主机的资源,并允许对容器资源分配进行精细化控制。
4. **联合文件系统(Union File System)**:联合文件系统是一种文件系统层叠技术,允许将多个文件系统层合并为一个单一的文件系统视图。`Docker`使用联合文件系统来构建镜像,其中包含基础镜像和一系列文件系统层,使镜像变得轻量且易于共享和管理。
5. **Docker镜像**:`Docker`镜像是只读的、多层的文件系统,它包含了应用程序代码、运行时、系统工具、库和配置。每一层都可以被重新使用,这使得镜像变得高效且易于构建。容器实例基于这些镜像运行,并添加一个可写层用于容器特定的修改。
6. **Docker守护程序和客户端**:`Docker`的架构包括一个守护程序(`Docker Daemon`)和一个客户端(`Docker Client`)。守护程序负责管理容器的生命周期和资源,而客户端允许用户与守护程序交互,以执行各种`Docker`操作。
7. **Docker网络**:`Docker`提供了不同类型的网络模式,如桥接网络、主机网络和覆盖网络,以便容器之间通信以及与外部网络连接。这些网络模式使用`Linux`内核的网络命名空间来实现隔离。
8. **Docker存储**:`Docker`容器可以使用持久化存储,包括卷(`volumes`)和绑定挂载(`bind mounts`),以便在容器之间或与主机文件系统之间共享数据。


总结:  
 `Docker`的底层原理涉及了多个`Linux`内核功能的协同工作,以实现容器的隔离、资源管理和文件系统层叠。这些技术共同构成了`Docker`的核心,使其成为一种强大的容器化解决方案,可用于构建、交付和管理应用程序。理解这些原理有助于更深入地使用和调优`Docker`容器。


### 3.4 Docker镜像分层


参考1:<https://zhuanlan.zhihu.com/p/139653646>



> 
> docker中的镜像是按照分层的结构一层一层网上叠加的。每层代表Dockerfile中的一条指令。
> 
> 
> 



以下面Dockerfile为例:
FROM ubuntu:18.04
COPY . /app
RUN make /app
CMD python /app/app.py



> 
> 采用镜像分层的方式最好的就是共享资源,假设有多个镜像都是从相同的底层镜像构建来的,那么docker 只需要在磁盘上保持一份底层镜像,同时内存只用加载一份底层镜像,这样一来这一份镜像就可以为其他的镜像服务了。
> 
> 
> 


容器和镜像区别:



> 
> 对于容器和镜像(container和image)的主要区别就是顶部的可写层(the top writable layer),在容器中添加数据或者修改现有数据的所有读写操作都会存储在此可写层中。删除容器后,可写层也会被删除,而基础镜像则保持不变。  
>  每个容器都会有自己的可写层,所有的改变都存储在该容器层中。多个容器可以共享对同一基础镜像的访问,但可以拥有自己的数据状态。
> 
> 
> 




---


`Docker`镜像采用分层存储(`Layered File System`)的方式来构建,这个特性是`Docker`镜像的核心概念之一。镜像的分层结构使得镜像的创建、共享和管理变得高效。下面是有关`Docker`镜像分层的关键信息:


1. **分层文件系统**:`Docker`镜像使用分层文件系统来构建。每个镜像可以由多个文件系统层组成,每一层都是只读的,并且包含了文件和目录。这些层以一种特殊的方式叠加在一起,形成了一个完整的镜像。
2. **基础镜像(Base Image)**:镜像的最底层通常是一个基础镜像,它包含了操作系统的根文件系统和一些最基本的工具。基础镜像通常是一个标准的`Linux`发行版,如`Ubuntu`、`Alpine`或`CentOS`。
3. **镜像层**:在基础镜像之上,每个`Docker`镜像可以包含一个或多个镜像层。每个镜像层都添加了一些文件、目录或配置。这些镜像层可以在不同的镜像之间共享,从而节省存储空间。
4. **只读和可写层**:镜像的所有层都是只读的,这意味着它们不可更改。当容器运行时,`Docker`会在顶部添加一个可写的层,用于存储容器运行时的修改。这个可写层通常被称为"容器层"或"容器文件系统",并且是唯一可写的部分。
5. **分层的好处**:镜像的分层结构具有以下好处:
	* **高效存储和传输**:因为镜像层可以在不同的镜像之间共享,所以它们不会被多次存储或传输,节省了存储空间和带宽。
	* **可复用性**:通过分层,镜像可以重复使用基础层,从而降低了创建新镜像的成本。
	* **版本控制**:每个镜像层都有一个唯一的哈希值,这使得镜像版本的管理更容易,以确保镜像的一致性和可重复性。
6. **Docker镜像命令**: 使用`Docker`镜像命令(如`docker pull`、`docker build`和`docker push`)可以方便地获取、构建和共享镜像。当构建或拉取一个镜像时,`Docker`会下载或创建所需的镜像层,并按顺序叠加它们以构建完整的镜像。


**总结:**  
 `Docker`镜像分层是一种高效的方式来管理和共享容器化应用程序的组件。它使得镜像的创建、更新和传输变得更加高效和可维护。通过共享基础层和分层结构,`Docker`镜像允许在不同环境中实现一致性和可移植性。


### 3.5 Docker Dockfile


`Dockerfile`(中文称为“`Docker`文件”)是一个文本文件,用于定义构建`Docker`容器镜像的一组指令。`Docker`容器是轻量、可移植且隔离的环境,可以在不同系统上一致地运行应用程序和服务。`Dockerfile`是`Docker`生态系统的基本组成部分,因为它们提供了创建定制容器镜像的方式,以满足特定需求。


**`Dockerfile`结构的概述以及每个部分的作用:**


1. **基础镜像**:`Dockerfile`中的第一行指定了用于构建自定义镜像的基础镜像。可以将基础镜像视为应用程序的起点。例如,可以使用官方的`Linux`发行版镜像,如`Ubuntu`、轻量的`Alpine Linux`镜像,或针对特定编程语言或框架定制的镜像。

FROM ubuntu:20.04

2. **环境设置**:在定义基础镜像之后,可以设置应用程序的环境。这包括安装依赖项、设置环境变量和根据需要配置系统。

RUN apt-get update &&
apt-get install -y python3

3. **复制文件**:可以将本地计算机上的文件复制到容器镜像中。这通常用于添加应用程序代码、配置文件和其他资源。

COPY ./app /app

4. **工作目录**:设置容器内的工作目录,后续命令将在其中执行。这有助于组织应用程序的文件结构。

WORKDIR /app

5. **暴露端口**:如果应用程序监听特定网络端口,可以在`Dockerfile`中暴露这些端口。

EXPOSE 80

6. **命令**:最后,指定容器启动时应执行的命令。这可以是简单的`shell`命令、脚本或应用程序入口点。

CMD [“python3”, “app.py”]



构建了`Dockerfile`之后,可以使用`docker build`命令来从中构建镜像。例如:



docker build -t my-custom-image:1.0 .


这个命令告诉`Docker`使用当前目录中的 `Dockerfile`(.)来构建一个镜像,并将其标记为`my-custom-image`,版本为`1.0`。


构建镜像后,可以使用`docker run`来创建和运行基于该镜像的容器:



docker run -p 8080:80 my-custom-image:1.0


这将从`my-custom-image:1.0` 镜像创建一个容器,并将容器内部的端口80映射到主机系统上的端口8080。


`Dockerfile`允许以版本控制的方式定义应用程序的环境和依赖关系,从而更容易在不同环境和平台上共享和部署应用程序。


#### 3.5.1 Docker Dockfile完整示例



使用官方的 Golang 镜像作为基础镜像,选择需要的 Go 版本

FROM golang:1.17

设置容器内的工作目录

WORKDIR /app

将本地的 Go 源代码复制到容器中

COPY . .

构建 Go 应用程序

RUN go build -o myapp

暴露容器内的端口,此示例服务使用 8080 端口

EXPOSE 8080

定义容器启动时执行的命令

CMD [“./myapp”]


这个示例`Dockerfile`基于官方`Golang`镜像构建了一个容器镜像,执行以下操作:


1. 设置工作目录为`/app`,这将是容器内部的工作目录。
2. 使用`COPY`指令将本地的`Go`源代码复制到容器中。确保`Dockerfile`位于`Go`项目根目录下,以便将整个项目复制到容器。
3. 使用`RUN`指令运行`go build`命令来构建`Go`应用程序。这将生成一个名为`myapp`的可执行文件。
4. 使用`EXPOSE`指令暴露容器内的端口`8080`,以便外部可以访问该端口。
5. 使用`CMD`指令定义容器启动时要执行的命令,这里是运行`myapp`可执行文件。


可以将上述`Dockerfile`保存为文件,然后使用`docker build`命令来构建容器镜像,假设`Go`项目位于当前目录下:



docker build -t my-golang-app:1.0 .


接下来,可以使用`docker run`命令来创建和运行基于该镜像的容器:



docker run -p 8080:8080 my-golang-app:1.0


将创建一个运行`Go`服务的容器,并将容器内部的端口`8080`映射到主机上的端口`8080`,以便通过主机访问该服务。请确保 `Go`应用程序监听端口`8080`,以使其正常工作。


### 3.6 Docker Compose


参考1:[Docker Compose和Docker Swarm简析与区别]( )  
 `Compose`:是用于定义和运行多容器`Docker`应用程序的工具【即容器编排】。通过`Compose`,可以使用`YML`文件来配置应用程序需要的所有服务,包括容器、网络、卷等。然后,使用一个命令,就可以根据`YML`文件启动和管理整个应用程序堆栈。


**Compose 使用的三个步骤:**


* 使用`Dockerfile`定义应用程序的环境。
* 使用`docker-compose.yml`定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。
* 最后,执行`docker-compose up`命令来启动并运行整个应用程序。
* 执行`docker-compose down`命令停止程序。


以下是使用`docker-compose`的基本概念和用法:


1. **Docker Compose文件**:`Docker Compose`使用一个名为`docker-compose.yml`(或`docker-compose.yaml`)的文件来定义应用程序的配置。这个文件包含了应用程序中各个服务的描述,以及它们之间的关系和依赖。
2. **服务(Services)**:一个服务通常对应一个容器,它定义了应用程序的一个组件,例如一个 Web 服务器、数据库、消息队列等。在`docker-compose.yml`文件中,可以指定服务的镜像、端口映射、环境变量、卷挂载等配置。
3. **堆栈(Stacks)**:使用`docker-compose`启动一组服务时,这组服务被称为一个堆栈。堆栈是一种逻辑上的组织方式,允许将相关的服务一起管理。
4. **启动应用程序**:使用`docker-compose up`命令可以启动整个应用程序堆栈。`Docker Compose`会读取`docker-compose.yml`文件,并按照文件中的配置启动服务。可以通过添加`-d`标志来以守护进程模式运行应用程序。
5. **关闭应用程序**:使用`docker-compose down`命令可以停止和删除整个应用程序堆栈的容器、网络和卷。这会清理堆栈中的资源。
6. **构建镜像**:如果需要,可以使用`docker-compose build`命令来构建自定义的镜像,然后在`docker-compose.yml`文件中引用这些镜像。
7. **扩展和伸缩**:使用`docker-compose`,可以轻松扩展应用程序的服务数量,以满足不同的负载需求。例如,可以使用`docker-compose scale`命令伸缩特定服务的容器数量。
8. **环境变量和秘密**:在`docker-compose.yml`文件中,可以定义环境变量或引用`Docker Swarm`的秘密来配置服务,以便在容器中访问敏感信息。
9. **覆盖文件**:可以使用覆盖文件来在不修改原始`docker-compose.yml`文件的情况下,更改服务的配置或添加额外的配置。这对于不同环境(例如开发、测试和生产)中的不同配置非常有用。


`Docker Compose`是一个强大的工具,特别适用于开发人员和运维团队,用于本地开发、测试和快速部署多容器应用程序。它简化了多容器应用程序的管理,同时提供了一种一致性的部署方式,以确保应用程序在不同环境中的行为一致。


#### 3.6.1 Docker Compose常用命令


#### 3.6.2 Docker Compose构建golang服务和MySQL数据库的示例


要使用`Docker Compose`构建一个包含`Go`服务和`MySQL`数据库的多容器应用,可以按照以下步骤进行操作:


1. 创建一个新的目录,用于存放的`Go`项目文件、`Docker Compose`配置文件和`MySQL`初始化脚本。
2. 在该目录中创建一个`Go Web`服务的源代码文件,例如`main.go`,以及一个`Dockerfile`来构建`Go`服务的`Docker`镜像。以下是一个示例`Go Web`服务的`main.go`文件,它将连接到`MySQL`数据库:



package main

import (
“database/sql”
“fmt”
“log”
“net/http”

\_ "github.com/go-sql-driver/mysql"

)

func handler(w http.ResponseWriter, r *http.Request) {
// 连接到 MySQL 数据库
db, err := sql.Open(“mysql”, “root:password@tcp(database:3306)/mydb”)
if err != nil {
log.Fatal(err)
}
defer db.Close()

// 执行查询
rows, err := db.Query("SELECT message FROM messages")
if err != nil {
	log.Fatal(err)
}
defer rows.Close()

// 处理查询结果
var message string
for rows.Next() {
	if err := rows.Scan(&message); err != nil {
		log.Fatal(err)
	}
	fmt.Fprintf(w, "Message from MySQL: %s\n", message)
}

}

func main() {
http.HandleFunc(“/”, handler)
http.ListenAndServe(“:8080”, nil)
}


3. 创建一个`Dockerfile`文件,用于构建`Go`服务的`Docker`镜像。以下是一个示例`Dockerfile`文件:



使用官方的 Golang 镜像作为基础镜像

FROM golang:1.17

设置容器内的工作目录

WORKDIR /app

复制 Go 源代码到容器中

COPY . .

构建 Go 服务

RUN go build -o myapp

暴露容器内的端口,此示例服务使用 8080 端口

EXPOSE 8080

定义容器启动时执行的命令

CMD [“./myapp”]


4. 创建一个`docker-compose.yml`配置文件,定义`Go`服务和`MySQL`服务。以下是一个示例`docker-compose.yml`文件:



version: ‘3’
services:
webapp:
build:
context: .
dockerfile: Dockerfile
ports:
- “8080:8080”
depends_on:
- database
database:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: password
MYSQL_DATABASE: mydb


在这个示例中,我们定义了两个服务:`webapp`和`database`。


* **webapp**:服务使用构建上下文 (`context`) 为当前目录,指定了`Dockerfile`来构建`Go`服务的镜像。它还将容器内部的端口`8080`映射到主机上的端口8080,以便通过浏览器访问`Web`应用。`depends_on`选项确保`webapp`服务在`database`服务之后启动,以便数据库服务准备好后才启动`Web`服务。
* **database**:服务使用官方的`MySQL`镜像,并设置了环境变量来配置`MySQL`数据库的根密码和数据库名称。


5. 在同一目录中创建一个`MySQL`初始化脚本,用于在容器启动时初始化数据库。创建一个名为`init.sql`的文件,内容如下:



CREATE TABLE messages (
id INT AUTO_INCREMENT PRIMARY KEY,
message VARCHAR(255) NOT NULL
);

INSERT INTO messages (message) VALUES (‘Hello, Docker Compose and MySQL!’);


6. 打开终端,导航到包含以上文件的目录,然后运行以下命令,使用`Docker Compose`启动多容器应用:



docker-compose up


`Docker Compose`将会根据配置文件创建并启动两个容器,分别运行`Go Web`服务和`MySQL`数据库。`Go Web`服务将连接到`MySQL`数据库并查询数据。  
 7. 在浏览器中访问:`http://localhost:8080`,应该能够看到来自`MySQL`数据库的消息。  
 8. 若要停止并删除容器,可以在终端中按下`Ctrl+C`停止正在运行的`Docker Compose`进程,然后运行以下命令:



docker-compose down


这个示例演示了如何使用`Docker Compose`构建和管理一个包含`Go`服务和`MySQL`数据库的多容器应用程序。根据项目需求,可以进一步扩展和自定义`docker-compose.yml`文件以满足需要。


### 3.7 Docker Swarm


`Docker Swarm`是`Docker`的集群和编排工具,用于管理和编排多个`Docker`容器在多个主机上的部署。它允许创建一个`Docker`集群,将多个`Docker`主机组合在一起,以便更轻松地管理和扩展容器化应用程序。`Docker Swarm`提供了以下关键功能:


1. **容器编排**:`Docker Swarm`允许定义容器化应用程序的服务和任务,并确保它们在整个集群中运行,从而轻松进行横向扩展和负载均衡。
2. **高可用性**:`Docker Swarm`提供高可用性特性,可以在集群中保证服务的可用性。它会自动重新调度容器任务到其他可用节点上,以应对容器或节点的故障。
3. **服务发现**:`Swarm`提供内置的服务发现功能,允许容器在集群中相互通信,而无需手动配置网络设置。
4. **负载均衡**:`Swarm`集成了内置的负载均衡功能,可自动将请求分配给运行相同服务的不同容器实例,从而提供更好的性能和容错性。
5. **安全性**:`Swarm`提供了安全性特性,包括节点身份验证、访问控制列表 (ACL) 和加密,以保护容器化应用程序和集群中的数据。
6. **内置日志和监控**:`Docker Swarm`集成了日志记录和监控工具,能够轻松地监视和诊断容器化应用程序。


使用`Docker Swarm`,可以轻松地创建和管理一个容器编排集群,部署容器化应用程序,并实现高可用性和自动扩展。`Swarm`的配置文件通常称为`docker-compose.yml`,与`Docker Compose`兼容,因此可以无缝地将应用程序从本地开发环境迁移到`Swarm`集群中。


#### 3.7.1 Docker Swarm常用命令


1. 初始化一个`Docker Swarm`集群:



docker swarm init


2. 将其他`Docker`主机加入`Swarm`集群:



docker swarm join --token :2377


3. 部署一个服务(例如,Nginx):



docker service create --name my-nginx -p 80:80 nginx


4. 列出当前`Swarm`集群的服务:



docker service ls


5. 扩展服务的副本数:



docker service scale my-nginx=5


6. 删除一个服务:



docker service rm my-nginx


`Docker Swarm`是一个强大的容器编排工具,适用于搭建生产环境中的容器化应用程序,使应用程序更易于管理、部署和扩展。它提供了一种容器编排解决方案,使得容器集群的管理变得更加简单和可靠。


#### 3.7.2 Docker Swarm构建golang服务和MySQL数据库的示例


下面是一个示例,演示如何使用`Docker Swarm`构建一个包含`Go`服务和`MySQL`数据库的分布式应用程序。在这个示例中,我们将创建一个`Docker Swarm`集群,并在该集群上部署一个简单的`Go Web`服务和一个`MySQL`数据库。


1. **创建一个`Docker Swarm`集群**:  
 首先,初始化一个`Docker Swarm`集群,可以选择一个节点作为`Swarm`管理节点(`manager`),其他节点将加入到这个集群中。  
 在管理节点上运行以下命令:



docker swarm init


这将返回一个命令,可以在其他节点上运行以加入集群。例如:



docker swarm join --token :2377


在其他节点上运行上述命令以加入`Swarm`集群。


2. **创建一个`docker-compose.yml`文件**:  
 在任何一个节点上创建一个名为`docker-compose.yml`的文件,用于定义服务。以下是一个示例`docker-compose.yml`文件:



version: ‘3.8’

services:
webapp:
image: my-golang-app:1.0
ports:
- “8080:8080”
deploy:
replicas: 3
networks:
- mynetwork
depends_on:
- database
environment:
- DATABASE_URL=mysql://myuser:mypassword@database:3306/mydb

database:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: mypassword
MYSQL_DATABASE: mydb
networks:
- mynetwork

networks:
mynetwork:


此配置文件定义了两个服务:`webapp`和`database`。`webapp`服务是一个简单的`Go Web`服务,它运行在端口`8080`上,并依赖于`database`服务。`database`服务是一个`MySQL`数据库。


3. **构建和推送`Go`服务镜像**:  
 在包含`Go`服务代码的节点上,使用以下命令构建和推送`Go`服务镜像到`Docker`镜像仓库(如果有的话):



docker build -t my-golang-app:1.0 .


4. **部署服务到`Swarm`集群**:  
 在包含`docker-compose.yml`文件的节点上,运行以下命令来部署服务:



docker stack deploy -c docker-compose.yml myapp


这将创建一个名为`myapp`的服务堆栈,并在`Swarm`集群中部署`webapp`和`database`服务。


5. **查看服务状态**:  
 可以使用以下命令查看服务状态:



docker stack ps myapp


这将显示服务的运行状态,包括哪个节点上运行每个服务的副本。


6. **测试应用程序**:  
 使用浏览器或其他工具访问`Swarm`集群上的任何节点的`http://<node-ip>:8080`,应该能够访问`Go Web`服务。该服务将连接到`MySQL`数据库,执行查询并返回结果。
7. **扩展和管理服务**:  
 可以使用`Docker Swarm`的命令来扩展服务、更新服务、管理节点等。例如,要扩展`webapp`服务的副本数,可以运行:



docker service scale myapp_webapp=5


这会将`webapp`服务的副本数扩展到5个。


### 3.8 Docker Stack


`Docker Stack`是一个用于在`Docker Swarm`集群中部署分布式应用程序的命令行工具。它建立在`Docker Compose`文件的基础上,允许定义和部署多个服务,这些服务可以在多个`Swarm`节点上运行,以实现高可用性和容器编排。


**以下是`Docker Stack`的主要特点和用途:**


1. **应用部署**:`Docker Stack`允许使用一个`docker-compose.yml`文件来定义整个应用程序的多个服务、网络、卷和配置。这个文件可以包含应用程序的所有组件和设置。
2. **多容器编排**:通过`Docker Stack`,可以轻松地在`Docker Swarm`集群中部署和编排多个容器。它提供了服务发现、负载均衡、容器间通信等功能。
3. **高可用性**:`Docker Stack`支持高可用性配置,可以确保服务在整个`Swarm`集群中保持可用。如果某个节点失败,`Swarm`会自动重新调度任务到其他可用节点上。
4. **自动负载均衡**:`Docker Stack`集成了内置的负载均衡功能,可以自动将请求分发给运行相同服务的不同容器实例,从而提供更好的性能和容错性。
5. **服务扩展**:使用`Docker Stack`,可以轻松地扩展服务的副本数量,以满足流量和性能需求。这可以通过命令行或更新`docker-compose.yml`文件来实现。
6. **栈管理**:可以使用`Docker Stack`来创建、列出、更新和删除服务堆栈。这使得应用程序的生命周期管理更加容易。
7. **多环境支持**:`Docker Stack`支持不同的环境(例如开发、测试和生产),并可以使用不同的`docker-compose.yml`文件进行部署。


#### 3.8.1 Docker Stack常用命令


1. **创建一个服务堆栈**:



docker stack deploy -c docker-compose.yml myapp


2. **列出正在运行的服务堆栈**:



docker stack ls


3. **查看服务堆栈的详细信息**:



docker stack ps myapp


4. **扩展服务的副本数量**:



docker service scale myapp_web=5


5. **删除服务堆栈**:



docker stack rm myapp


`Docker Stack`是一个有力的工具,用于管理`Docker Swarm`集群中的容器化应用程序。它允许开发人员和运维团队轻松地定义、部署和管理复杂的分布式应用程序,并确保它们在多个节点上运行,并具备高可用性和容器编排的功能。这使得容器化应用程序在生产环境中更容易管理和维护。


#### 3.8.2 Docker Stack构建golang服务和MySQL数据库的示例


以下是一个示例`Docker Stack`配置,演示如何使用`Docker Stack`在`Docker Swarm`集群中构建一个包含`Go`服务和`MySQL`数据库的分布式应用程序。在这个示例中,我们将使用一个简单的`Go Web`服务连接到`MySQL`数据库。


1. **创建一个`Docker Swarm`集群**:  
 在初始化之前,确保已经创建了一个`Docker Swarm`集群。可以在其中一个节点上运行以下命令来初始化集群:



docker swarm init


然后,使用输出中提供的`docker swarm join`命令将其他节点加入到`Swarm`集群中。


2. **创建一个目录并进入**:  
 创建一个新的目录,用于存放应用程序代码和`Docker Stack`配置文件,并进入该目录。



mkdir my-golang-app
cd my-golang-app


3. **创建一个`Go Web`服务的源代码文件**:  
 在目录中创建一个名为`main.go`的`Go`服务源代码文件。以下是一个示例`main.go`文件,它将连接到`MySQL`数据库并显示数据库中的消息:



package main

import (
“database/sql”
“fmt”
“log”
“net/http”

\_ "github.com/go-sql-driver/mysql"

)

func handler(w http.ResponseWriter, r *http.Request) {
db, err := sql.Open(“mysql”, “myuser:mypassword@tcp(database:3306)/mydb”)
if err != nil {
log.Fatal(err)
}
defer db.Close()

rows, err := db.Query("SELECT message FROM messages")
if err != nil {
    log.Fatal(err)
}
defer rows.Close()

var message string
for rows.Next() {
    if err := rows.Scan(&message); err != nil {
        log.Fatal(err)
    }
    fmt.Fprintf(w, "Message from MySQL: %s\n", message)
}

}

func main() {
http.HandleFunc(“/”, handler)
http.ListenAndServe(“:8080”, nil)
}


4. **创建一个`Dockerfile`文件**:  
 在同一目录中创建一个名为`Dockerfile`的文件,用于构建`Go`服务的`Docker`镜像。以下是一个示例`Dockerfile`文件:



使用官方的 Golang 镜像作为基础镜像

FROM golang:1.17

设置容器内的工作目录

WORKDIR /app

复制 Go 源代码到容器中

COPY . .

构建 Go 服务

RUN go build -o myapp

暴露容器内的端口,此示例服务使用 8080 端口

EXPOSE 8080

定义容器启动时执行的命令

CMD [“./myapp”]


5. **创建一个`docker-compose.yml`文件**:  
 在同一目录中创建一个名为`docker-compose.yml`的`Docker Stack`配置文件。以下是一个示例`docker-compose.yml`文件:



version: ‘3.8’

services:
webapp:
build:
context: .
dockerfile: Dockerfile
ports:
- “8080:8080”
deploy:
replicas: 3
networks:
- mynetwork
depends_on:
- database
environment:
- DATABASE_URL=mysql://myuser:mypassword@database:3306/mydb

database:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: mypassword
MYSQL_DATABASE: mydb
networks:
- mynetwork

networks:
mynetwork:


这个配置文件定义了两个服务:`webapp`和`database`,与之前的示例相似。


6. **构建`Go`服务的镜像**:  
 在包含`Go`服务代码的目录中,运行以下命令构建`Go`服务的`Docker`镜像:



docker build -t my-golang-app:1.0 .


7. **使用`Docker Stack`部署服务**:  
 在包含`docker-compose.yml`文件的目录中,使用以下命令来部署服务到`Swarm`集群:



docker stack deploy -c docker-compose.yml myapp


8. **查看服务状态**:  
 可以使用以下命令查看服务状态:



docker stack ps myapp


9. **测试应用程序**:  
 使用浏览器或其他工具访问`Swarm`集群中的任何节点的`http://<node-ip>:8080`,应该能够访问`Go Web`服务。该服务将连接到`MySQL`数据库并执行查询并返回结果。
10. **扩展和管理服务**:  
 可以使用`Docker Stack`的命令来扩展服务、更新服务、管理节点等。例如,要扩展`webapp`服务的副本数,可以运行:



docker service scale myapp_webapp=5


这个示例演示了如何使用`Docker Stack`构建和管理一个包含`Go`服务和`MySQL`数据库的分布式应用程序。根据需求,可以进一步扩展和定制服务以满足复杂应用程序的需求。


### 3.9 Dockfile 、Compose、Swarm、Stack区别


1. **Dockerfile**:
	* **用途**:`Dockerfile`用于定义和创建容器镜像。它是一个文本文件,包含一系列指令,指导`Docker`引擎如何构建镜像。
	* **功能**:`Dockerfile`包括镜像的基础配置、构建步骤、环境变量、依赖项安装等信息。
	* **示例**:`Dockerfile`通常用于构建单个容器镜像,例如一个包含`Web`服务器的容器镜像。
2. **Docker Compose**:
	* **用途**:`Docker Compose`用于定义和管理多个`Docker`容器的编排和配置。它通过一个声明性的配置文件来定义应用程序的多个服务、网络、卷以及它们之间的关系。
	* **功能**:`Docker Compose`简化了多容器应用程序的部署和管理,可以定义多个容器的组合和交互,并一键启动整个应用程序栈。
	* **示例**:`Docker Compose`适用于部署多容器应用程序,如微服务架构,以及将应用程序的不同部分分为多个容器。
3. **Docker Swarm**:
	* **用途**:`Docker Swarm`用于创建和管理`Docker`容器的集群。它提供容器编排、高可用性、负载均衡和服务发现等功能,使多个 Docker 主机协同工作。
	* **功能**:`Docker Swarm`允许容器在多个节点上运行,并提供服务发现、负载均衡、自动恢复和高可用性功能。
	* **示例**:`Docker Swarm`适用于部署容器化应用程序到生产环境,以实现容器编排和高可用性。
4. **Docker Stack**:
	* **用途**:`Docker Stack`是`Docker Swarm`集群中部署分布式应用程序的命令行工具。它建立在`Docker Compose`文件的基础上,用于定义和部署多个服务,这些服务可以在多个`Swarm`节点上运行。
	* **功能**:`Docker Stack`可以使用`Docker Compose`配置文件来部署多容器应用程序,并提供高可用性、负载均衡和容器编排功能。
	* **示例**:`Docker Stack`适用于在`Docker Swarm`集群中部署和管理多容器应用程序,支持多节点部署和容器编排。


**总结:**  
 `Docker Dockfile`用于构建容器镜像,`Docker Compose`用于编排多容器应用程序的开发环境,`Docker Swarm`用于管理`Docker`集群和部署容器化应用程序,而`Docker Stack`是`Docker Swarm`中的一个工具,用于在集群中部署分布式应用程序。这些工具共同构成了`Docker`生态系统中的不同层次的解决方案,用于容器化应用程序的开发、测试和部署。


### 3.10 Docker的隔离机制


`Docker`通过多种隔离机制来确保容器之间和容器与主机之间的资源隔离。这些隔离机制有助于保护应用程序的安全性、稳定性和性能。以下是`Docker`的主要隔离机制:


1. **命名空间(Namespaces)**: `Docker`使用Linux命名空间来隔离容器的视图,以便它们能够在一个单独的用户空间内运行,而不会干扰其他容器或主机系统。以下是一些常见的命名空间类型:
	* **PID命名空间**:用于隔离进程`ID(PID)`,每个容器都有自己独立的进程空间。
	* **网络命名空间**:用于隔离网络接口和`IP`地址,每个容器都有自己的网络命名空间。
	* **挂载命名空间**:用于隔离文件系统挂载点,每个容器都有自己的文件系统视图。
	* **UTS命名空间**:用于隔离主机名和域名信息。
	* **IPC命名空间**:用于隔离进程间通信资源,如共享内存、信号量等。
2. **控制组(cgroups)**: `Docker`使用`cgroups`来限制和管理容器的资源使用,包括`CPU`、内存、磁盘`I/O`等。每个容器可以被分配一定的资源配额,以确保它不会过度消耗主机资源。
3. **联合文件系统(Union File System)**: `Docker`镜像使用分层联合文件系统,允许多个镜像层以只读方式堆叠在一起。这允许容器共享相同的基础层,从而减少存储空间的占用和提高效率。
4. **容器文件系统**: 每个容器都有一个可写层,用于容器运行时的修改。这个层是容器唯一可以写入的部分,其他层都是只读的,以确保文件系统的隔离。
5. **用户和组**: `Docker`容器通常在一个单独的用户空间内运行,每个容器可以有自己的用户和组。这有助于隔离容器内的进程和文件访问权限。
6. **Seccomp(安全计算)**: `Docker`支持`Seccomp`来限制容器中的系统调用。通过`Seccomp`配置,可以减少容器对主机内核的敏感系统调用,从而提高安全性。
7. **AppArmor和SELinux**: `Docker`可以与`Linux`的强制访问控制(`MAC`)机制,如`AppArmor`和`SELinux`集成,以进一步加强容器的隔离。这些工具可以限制容器对主机资源和文件的访问。
8. **容器网络隔离**: `Docker`提供不同类型的网络隔离,包括桥接网络、主机网络、覆盖网络等,以确保容器之间的通信隔离。这些网络隔离方式使用不同的网络命名空间。


这些隔离机制共同工作,确保容器可以在相对独立和安全的环境中运行,而不会干扰其他容器或主机系统。这使得`Docker`成为一个强大的容器化平台,适用于各种应用程序和工作负载的隔离需求。但需要注意,虽然`Docker`提供了许多隔离机制,但仍然需要谨慎配置和管理容器以确保安全性。


### 3.11 Docker的网络模式


`Docker`提供了多种网络模式,允许容器之间进行通信以及容器与外部网络连接。选择适当的网络模式取决于应用程序需求和安全性要求。以下是`Docker`的一些常见网络模式:


1. **桥接网络(Bridge Network)**:这是`Docker`的默认网络模式。在这种模式下,每个容器连接到一个本地虚拟网络桥接,容器可以相互通信,同时也可以通过主机的网络连接到外部网络。这种模式适用于多个容器需要在同一主机上互相通信的情况。
2. **主机网络(Host Network)**:在这种模式下,容器与主机共享网络命名空间,容器可以直接使用主机的网络接口。这使得容器与主机之间的网络性能非常高,但也会导致容器与主机之间的网络隔离降低。这种模式适用于需要最大化网络性能的情况。
3. **覆盖网络(Overlay Network)**:覆盖网络允许不同`Docker`主机上的容器相互通信。这对于分布式应用程序和容器编排平台(如`Docker Swarm`和`Kubernetes`)非常有用,因为它允许容器跨主机进行通信。覆盖网络使用`VXLAN`等技术在不同主机之间建立虚拟网络。
4. **MACVLAN网络(MACVLAN Network)**:这种模式允许容器分配具有唯一`MAC`地址的虚拟网络接口。每个容器在网络上看起来像是物理主机的一部分,这对于需要容器与外部网络直接交互的应用程序非常有用。
5. **无桥接网络(None Network)**:在这种模式下,容器不会连接到任何网络,这意味着容器无法直接与外部网络通信。这种模式通常用于特定安全需求或测试目的。
6. **自定义网络(Custom Networks)**: 可以创建自定义网络,根据应用程序的需要配置网络模式、子网、网关等属性。这种方式允许更精细地控制容器之间的通信和网络配置。


选择适当的网络模式取决于应用程序需求和安全性要求。通常情况下,使用桥接网络是最常见的,因为它提供了良好的隔离性和通信能力,但在某些情况下,可能需要使用其他网络模式来满足特定的需求。 `Docker`的网络模式灵活,可以根据不同的应用场景进行配置和调整。


### 3.12 Docker命令


#### 3.12.1 Docker常用命令


1. **容器生命周期管理**:
	* `docker run <options> <image> <command>`:运行一个新的容器。
	* `docker start <container>`:启动已停止的容器。
	* `docker stop <container>`:停止运行中的容器。
	* `docker restart <container>`:重启容器。
	* `docker pause <container>`:暂停容器的进程。
	* `docker unpause <container>`:恢复暂停的容器。
	* `docker kill <container>`:强制停止容器。
	* `docker rm <container>`:删除一个或多个容器。
	* `docker ps`:列出运行中的容器。
	* `docker ps -a`:列出所有容器,包括已停止的。
	* `docker logs <container>`:查看容器的日志。
	* `docker exec -it <container> <command>`:在运行的容器中执行命令。
2. **镜像管理**:
	* `docker pull <image>`:拉取镜像。
	* `docker push <image>`:推送镜像到仓库。
	* `docker build <options> <path>`:构建自定义镜像。
	* `docker images`:列出本地镜像。
	* `docker rmi <image>`:删除本地镜像。
3. **容器网络管理**:
	* `docker network ls`:列出所有网络。
	* `docker network inspect <network>`:查看网络的详细信息。
	* `docker network create <network>`:创建自定义网络。
	* `docker network connect <network> <container>`:将容器连接到网络。
	* `docker network disconnect <network> <container>`:将容器从网络断开。
4. **容器数据管理**:
	* `docker volume ls`:列出所有卷。
	* `docker volume create <volume>`:创建卷。
	* `docker volume inspect <volume>`:查看卷的详细信息。
	* `docker volume rm <volume>`:删除卷。
	* `docker cp <container>:<source_path> <destination_path>`:从容器复制文件到主机。
	* `docker cp <source_path> <container>:<destination_path>`:从主机复制文件到容器。
5. **其他常用命令**:
	* `docker info`:查看`Docker`系统信息。
	* `docker version`:查看`Docker`版本信息。
	* `docker login`:登录到`Docker Hub`或其他`Docker`仓库。
	* `docker logout`:退出登录。
	* `docker search <term>`:搜索`Docker Hub`上的镜像。
	* `docker-compose <command>`:使用`Docker Compose`管理多容器应用程序。


#### 3.12.2 Docker挂载文件的命令


`Docker`允许将主机文件系统上的文件或目录挂载到容器内部,以便容器可以访问这些文件。这是通过`-v`或`--volume`选项来实现的。以下是挂载文件的`Docker`命令示例:


1. **将主机文件挂载到容器内部**:



docker run -v /host/path:/container/path


* `/host/path`:是主机上的文件或目录路径。
* `/container/path`:是容器内部的挂载点路径。
* `<image>`:是要运行的`Docker`镜像。  
 例如,要将主机上的`/app/data`目录挂载到容器内的`/data`目录,可以运行以下命令:



docker run -v /app/data:/data myapp_image


2. **将主机当前目录挂载到容器内部**:



docker run -v $(pwd):/container/path


这个命令将主机的当前工作目录挂载到容器内的指定路径。


3. **挂载具有读写权限的卷**:



docker run -v /host/path:/container/path:rw


通过添加`:rw`选项,可以将卷以读写模式挂载到容器内。


4. **挂载匿名卷**:



docker run -v /container/path


如果省略主机路径,则`Docker`将创建一个匿名卷,并将其挂载到容器内的指定路径。匿名卷可以用于临时数据存储。


请注意,挂载文件或目录可以在容器和主机之间进行双向数据传输,因此容器对这些文件的更改将反映在主机上,反之亦然。挂载是非常有用的,因为它允许容器访问主机上的配置文件、数据或其他资源,同时也提供了一种简单的方式来在主机和容器之间共享数据。


#### 3.12.3 Docker中查看Pod日志的命令


在`Docker`中,容器是最小的可部署单元,而`Pod`通常是`Kubernetes`中用于组织容器的概念。如果要查看容器的日志,可以使用`Docker`命令,但如果正在使用`Kubernetes`或其他容器编排工具来管理容器,通常需要使用相应的工具来查看`Pod`日志。


**在`Docker`中查看容器日志的命令:**


1. **使用docker logs命令查看容器日志**:



docker logs <container_id>


其中`<container_id>`是要查看日志的容器的ID或名称。这将显示容器的标准输出和标准错误日志。如果容器已经停止,仍然可以使用这个命令来查看容器的最后一次运行时的日志。


2. **使用docker logs命令实时查看容器日志**:



docker logs -f <container_id>


添加`-f`标志,可以实时跟踪容器的日志输出,这对于查看容器当前正在发生的事情非常有用。


**请注意,这些命令用于查看单个容器的日志。如果正在使用`Kubernetes`或其他容器编排工具,通常需要使用该工具提供的命令来查看`Pod`日志,因为`Pod`可以包含多个容器。**


**在`Kubernetes`中,可以使用以下命令来查看`Pod`的日志:**


1. **使用kubectl logs命令查看`Pod`日志**:



kubectl logs <pod_name> -c <container_name>


* `<pod_name>`:是`Pod`的名称。
* `<container_name>`:是要查看日志的容器的名称。如果`Pod`中只有一个容器,可以省略`-c`选项。


2. **实时查看`Pod`日志**:



kubectl logs -f <pod_name> -c <container_name>


添加`-f`标志,可以实时跟踪日志输出。


这些命令适用于`Kubernetes`中的`Pod`,用于查看每个容器的日志。如果使用的是其他容器编排工具,具体的命令可能会有所不同,但一般原理是类似的:首先选择`Pod`,然后选择容器,最后使用相关命令查看日志。


#### 3.12.4 Docker崩溃后自动重启的命令


假设你有一个`docker`镜像叫做coolimage:v1,如何运行该镜像?需要保证即使容器内部的程序崩溃了,该容器依然能自动恢复;同时需要保证当主机重启之后,该容器能够自动运行起来。



> 
> 答:①运行镜像的命令:docker run coolimage --restart always
> 
> 
> 




---


`Docker`本身不提供自动重启容器的功能。然而,可以使用一些外部工具和策略来实现在`Docker`容器崩溃或停止后自动重启容器的目标。以下是一些方法:


1. **使用Docker Compose**: 如果使用`Docker Compose`来管理容器,可以在`docker-compose.yml`文件中为每个服务定义重启策略。例如,可以将`restart`字段设置为`"always"`,以指定容器应该始终自动重启:



services:
my-service:
image: my-image
restart: always


2. **使用Docker Swarm**: 如果使用`Docker Swarm`来编排容器,可以使用`--restart`标志来设置容器的重启策略。例如,以下命令将创建一个服务并设置它在崩溃或停止时自动重启:



docker service create --name my-service --restart-condition any my-image


3. **使用容器编排工具**: 如果使用`Kubernetes`或其他容器编排工具,这些工具通常提供了管理容器重启策略的功能,可以在`Pod`或`Deployment`配置中定义重启策略。
4. **使用监控和自动恢复工具**: 还可以考虑使用监控和自动恢复工具,如`Docker`的`Healthcheck`、`Supervisor`、`Systemd`等。这些工具可以监测容器的健康状态,当容器崩溃时触发自动重启。
5. **使用第三方工具**: 有一些第三方工具,如`Docker`自动重启脚本或监控工具,可以监测`Docker`容器并在容器崩溃时自动重启。这些工具可以根据需求进行定制。


**注意:**  
 自动重启容器可能会在某些情况下隐藏问题,因此在实施自动重启策略之前,建议仔细考虑容器的稳定性和问题排查。确保了解为什么容器会崩溃,并采取适当的措施来解决根本问题,以确保应用程序的稳定性。


#### 3.12.5 Docker打包镜像的操作【golang项目】


参考1:<https://www.jianshu.com/p/f1c34772f058>


完整的Dockerfile:



编译镜像

FROM golang:1.16-alpine AS build

WORKDIR /project/
COPY ./project /project
RUN go env -w GOPROXY=https://goproxy.io,direct
RUN go build -o /project/work/server main.go

运行镜像

FROM alpine
ENV TZ Asia/Shanghai
COPY --from=build /project/work/ /work/

定义工作目录为work

WORKDIR /work

开放http 80端口

EXPOSE 80

启动http服务

ENTRYPOINT [“./server”]


构建并推送镜像:



在Dockerfile所在文件夹运行

docker build -t xxxx/xxxx:v1 .

构建成功后,运行测试一下

docker run -d xxxx/xxxx:v1

docker ps查看一下运行情况

docker ps

查看一下容器对应的pid

docker inspect 554c4578242e|grep -i pid

查看对应的IP配置

nsenter -t 256418 -n ip a


#### 3.12.6 Docker构建镜像的命令


在`Docker`中,可以使用`docker build`命令来构建自定义的镜像。要构建镜像,需要创建一个名为`Dockerfile`的文件,其中包含有关如何构建镜像的指令。然后,使用以下命令构建镜像:



docker build -t <image_name>: <path_to_Dockerfile_directory>


**以下是各个部分的解释:**


* `<image_name>`:要创建的镜像的名称。
* `<tag>`:要分配给镜像的标签(可选),通常用于版本控制。如果不指定标签,默认为`latest`。
* `<path_to_Dockerfile_directory>`:包含`Dockerfile`的目录的路径。`Docker`将在该目录中查找`Dockerfile`并使用它来构建镜像。


以下是一个示例,演示如何构建一个名为`myapp`的镜像,标签为`v1.0`,`Dockerfile`位于当前目录下:



docker build -t myapp:v1.0 .


`Docker`将会读取`Dockerfile`并执行其中的指令,这些指令包括基础镜像选择、安装软件包、拷贝文件等。在构建过程中,`Docker`将创建一系列的镜像层,这些层包含了构建过程中的每个步骤,以便后续的重用和版本控制。


一旦构建完成,可以使用以下命令来列出新构建的镜像:



docker images


这会显示创建的镜像以及它们的标签和其他信息。


请确保在构建镜像之前正确编写和测试`Dockerfile`,以确保镜像包含期望的应用程序和配置。构建的镜像可以用于启动容器,以便在各种环境中运行应用程序。


### 3.13 `Docker Compose`部署的服务,如果有一个挂了,它是怎么重新发送到正常服务里的,怎么实现的?


`Docker Compose`本身并不提供高可用性(`High Availability, HA`)功能。`Docker Compose`用于定义和运行多个`Docker`容器的应用程序堆栈,通常在单个主机上运行。要实现`Docker`应用的高可用性,通常需要考虑以下几个方面:


1. **使用编排工具**: `Docker Compose`适用于本地开发和测试,它通常不用于生产环境的高可用性。对于生产环境,可以考虑使用编排工具,如`Docker Swarm`、`Kubernetes`或其他容器编排工具,以实现容器应用的高可用性。
2. **容器编排**: 使用容器编排工具,可以将容器部署到多个主机上,并配置容器的副本以确保服务的冗余和高可用性。这些工具还提供故障恢复和自动扩展功能。
3. **数据存储高可用**: 对于需要数据持久性的应用程序,确保数据库和存储解决方案具有高可用性配置。这可能涉及到复制、分区、备份等机制,以确保数据不会因单点故障而丢失。
4. **负载均衡**: 高可用的应用程序通常使用负载均衡器来将流量分发到多个容器实例。这有助于确保即使其中一个容器实例出现问题,流量仍然可以被正确路由到其他正常工作的实例。
5. **监控和自动恢复**: 使用监控工具来检测容器或主机的故障,以及应用程序的性能问题。配置自动恢复机制,以便在故障发生时能够快速恢复服务。
6. **容器注册中心**: 使用容器编排工具通常需要一个容器注册中心,如`Consul`或`etcd`,以存储和管理容器和服务的状态信息。这有助于实现服务发现、故障恢复和负载均衡。
7. **存储卷和数据管理**: 确保应用程序在容器重启或重新部署时不会丢失重要数据。使用`Docker`卷或外部存储解决方案,以确保数据的持久性和高可用性。
8. **多区域部署**: 如果应用程序需要更高级别的高可用性,考虑在多个数据中心或云区域中部署,并设置跨区域的负载均衡和故障恢复策略。


**总结**:`Docker Compose`适用于本地开发和测试,但对于生产环境中的高可用性,需要使用适当的容器编排工具,并采取适当的措施来确保容器应用的冗余、故障恢复和性能。具体的配置和实施取决于应用程序和基础架构需求。


### 3.14 Docker与虚拟机的区别


`Docker`和虚拟机(`VM`)是两种不同的虚拟化技术,它们在多个方面有着明显的区别。以下是`Docker`和虚拟机之间的主要区别:


1. **架构差异**:
	* **`Docker`**:`Docker`是一种容器化技术,它利用操作系统的容器化功能来隔离应用程序和其依赖项。每个`Docker`容器共享主机操作系统的内核,但拥有自己的用户空间。这使得`Docker`容器轻量且启动迅速。
	* **虚拟机**:虚拟机是一种基于`Hypervisor`的虚拟化技术,它模拟了完整的硬件层,每个虚拟机都运行一个完整的操作系统,包括内核。这导致虚拟机相对较重,并且启动速度较慢。
2. **资源利用效率**:
	* **`Docker`**:由于`Docker`容器共享主机操作系统的内核,因此它们更加轻量,需要更少的资源。多个容器可以在同一主机上运行而不会显著增加资源消耗。
	* **虚拟机**:虚拟机需要模拟整个操作系统,因此每个虚拟机通常需要较多的资源,包括内存和磁盘空间。这限制了在同一主机上运行的虚拟机数量。
3. **启动时间**:
	* **`Docker`**:`Docker`容器的启动时间通常非常快,几乎可以瞬间启动。这使得`Docker`容器非常适合快速扩展和缩减。
	* **虚拟机**:虚拟机的启动时间相对较长,通常需要几分钟来启动,因为它们必须启动整个操作系统。
4. **隔离性和安全性**:
	* **`Docker`**:`Docker`容器提供了良好的进程隔离,但容器共享主机操作系统的内核,因此容器之间有一定的安全风险。 `Docker`引入了一些安全性功能,如命名空间和`Seccomp`,以提高容器的安全性。
	* **虚拟机**:虚拟机提供更高级别的隔离,每个虚拟机都有独立的内核。这增加了虚拟机之间的隔离程度,使其更适合多租户环境和安全性要求严格的工作负载。
5. **镜像管理**:
	* **`Docker`**:`Docker`使用分层文件系统和`Docker`镜像来轻松创建、分享和管理容器。镜像可以非常高效地共享和复用。
	* **虚拟机**:虚拟机镜像通常较大,复制和传输的成本更高,镜像管理相对较为复杂。


**总结:**  
 `Docker`更适合轻量级应用程序容器化和快速部署,而虚拟机通常更适合要求更严格的隔离和安全性的工作负载。选择使用哪种虚拟化技术取决于特定需求和应用场景。在某些情况下,`Docker`和虚拟机可以结合使用,以充分利用它们各自的优势。


### 3.15 Docker容器有几种状态


1. **运行中(Running)**:容器正在正常运行,其内部的应用程序或服务正在执行。
2. **停止(Exited)**:容器已经停止,其内部的应用程序或服务已经退出或被停止。这可能是因为容器的主进程已完成或手动停止了容器。
3. **暂停(Paused)**:容器的所有进程都被暂停,但容器的状态保持不变。容器可以被恢复以恢复正常运行。
4. **创建中(Creating)**:容器正在创建,`Docker`正在初始化容器的资源和环境。
5. **终止中(Terminating)**:容器正在被停止或删除。这个状态表示容器正在进行清理操作。
6. **重启中(Restarting)**:如果使用了重启策略(如`--restart`选项),容器在崩溃或退出后会尝试重新启动。这个状态表示容器正在重新启动。


这些状态反映了容器的当前状态,可以使用`docker ps -a`命令来查看容器的状态以及其他相关信息。容器状态的管理和监控对于运维容器化应用程序非常重要,以确保容器的稳定性和可用性。


### 3.16 DockerFile中的命令COPY和ADD命令有什么区别


在`Dockerfile`中,`COPY`和`ADD`命令都用于将文件或目录从主机系统复制到容器内部,但它们有一些重要的区别:


1. **COPY命令**:
	* `COPY`命令用于将本地文件或目录复制到容器内部。它的语法如下:

COPY
# 是主机上的源文件或目录的路径。
# 是容器内部的目标路径。


	* `COPY`命令只复制本地文件系统上的文件或目录到容器,不执行额外的解压缩或处理操作。这使得它更加可预测和透明。
	* `COPY`命令通常用于将应用程序代码、配置文件等静态文件复制到容器中。
2. **ADD命令**:
	* `ADD`命令也用于将本地文件或目录复制到容器内部。它的语法如下:

ADD
# 是主机上的源文件或目录的路径。
# 是容器内部的目标路径。


	* 与`COPY`不同,`ADD`命令具有附加功能,它可以处理网络上的`URL`、压缩文件(如`.tar`和`.zip`)以及自动解压缩文件。这使得`ADD`命令更灵活,但也更复杂。
	* 使用`ADD`命令时要小心,因为它可能导致意外行为。例如,如果`<src>`是一个`URL`,容器构建可能会因为网络问题而失败,或者可能会导致每次构建时都重新下载文件。


总的来说,`COPY`命令更加简单和可预测,适用于复制本地文件或目录到容器。而`ADD`命令具有更多的功能,但需要小心使用,以避免意外行为。通常情况下,如果只需要复制文件或目录,建议使用`COPY`命令,而在需要处理特殊情况时再考虑使用`ADD`命令。


### 3.17 如何批量清理临时镜像文件


要批量清理`Docker`中的临时镜像文件,可以使用`Docker`提供的`docker system prune`命令。此命令可用于删除不再使用的镜像、容器、卷和网络资源,以释放磁盘空间。


以下是如何使用`docker system prune`命令进行批量清理的步骤:


1. 打开终端,并确保以`Docker`管理员或拥有足够权限的用户身份登录。
2. 运行以下命令以清理不再使用的临时镜像文件:`docker system prune`,这将会列出要删除的临时镜像文件以及将删除的总数量。程序会要求确认操作。
3. 如果需要自动确认并删除,可以使用`-f`或`--force`选项:`docker system prune -f`,这将跳过确认提示,立即删除不再使用的资源。
4. 如果只想清理特定类型的资源,可以使用子命令,例如清理未被使用的容器、卷、网络或镜像:
	* 清理未被使用的容器:`docker container prune`
	* 清理未被使用的卷:`docker volume prune`
	* 清理未被使用的网络:`docker network prune`
	* 清理未被使用的镜像:`docker image prune`


请注意,清理操作是不可逆的,一旦删除,无法恢复。因此,在执行清理操作之前,请确保了解要删除的资源,以免意外删除重要数据。


另外,如果需要定期清理`Docker`资源,可以设置定时任务或脚本来自动运行`docker system prune -f`或其他适当的清理命令。这有助于保持磁盘空间的干净和可用。


### 3.18 如何查看镜像支持的环境变量


查看`Docker`镜像支持的环境变量,可以使用以下步骤:


1. **运行容器**:首先,需要运行该镜像的一个容器实例。可以使用`docker run -it <image_name_or_id> /bin/bash`命令启动一个容器,并将进入其`Shell`,请将`<image_name_or_id>`替换为要查看的镜像的名称或`ID`。这会启动一个交互式容器。
2. **查看环境变量**:一旦进入容器的`Shell`,可以使用`env`命令查看环境变量,这将显示容器内部的所有环境变量及其值。可以滚动查看列表以查找感兴趣的特定环境变量。
3. **退出容器**:当查看完环境变量后,可以使用`exit`命令退出容器并返回到主机系统的终端。


请注意,这种方法只能查看镜像在运行时设置的环境变量。如果镜像的环境变量是在`Dockerfile`中设置的,那么可以查看`Dockerfile`以了解它们的定义。此外,一些应用程序可能会动态加载环境变量,这些变量可能不会在容器启动时立即可见,而是在应用程序运行时设置。


### 3.19 本地的镜像文件都存放在哪里


本地的`Docker`镜像文件存储在`Docker`守护程序的数据目录中。`Docker`数据目录的位置因操作系统而异:


1. **Linux**:在大多数`Linux`发行版中,`Docker`数据目录通常位于`/var/lib/docker`。镜像文件和其他`Docker`相关数据存储在这个目录中。
2. **Windows**:在`Windows`上,`Docker`数据目录通常位于`C:\ProgramData\Docker`。这个目录包含了`Docker`镜像和容器数据。
3. **macOS**:在`macOS`上,`Docker`数据目录通常位于`/var/lib/docker`,与`Linux`类似。请注意,在`macOS`上,`Docker`使用的是`HyperKit`虚拟化技术。


`Docker`镜像文件存储在数据目录的子目录中,其中包括镜像的层(`layers`)、容器的元数据和其他相关数据。具体的存储路径和目录结构可能会因`Docker`版本和配置而异,但通常情况下,不需要手动操作这些文件,`Docker`会负责管理它们。


如果想要查看`Docker`数据目录的位置,可以运行以下命令来查看`Docker`的配置信息:



docker info


在输出中,查找名为`"Data Root"`的项,它将显示`Docker`数据目录的路径。


请注意,如果不是管理员或没有足够的权限,可能无法访问`Docker`数据目录中的文件。对`Docker`数据目录进行直接操作通常是不推荐的,而应该使用`Docker`命令和API来管理容器和镜像。


### 3.20 容器退出后,通过docker ps命令查看不到,数据会丢失么


当容器退出后,通过`docker ps`命令查看不到容器的时候,容器的元数据会被清除,但容器内的数据通常不会立即丢失:


1. **容器元数据**:`Docker`容器在运行时会有一个相应的元数据记录,包括容器的名称、`ID`、状态等信息。当容器退出(例如,正常停止或发生错误导致退出)时,这些元数据记录会被清除,所以通过`docker ps`命令查看不到已经退出的容器。
2. **容器数据**:容器的数据(文件系统等)通常不会立即删除。`Docker`会保留容器的数据,以便可以随时重新创建容器并访问先前运行的容器内部的数据。

 如果想要重新启动已经退出的容器,可以使用容器的名称或`ID`来重新创建它,例如:`docker start <container_name_or_id>`,这将重新启动容器,并且可以通过`docker ps`查看到运行中的容器。

 但是,请注意以下几点:


	* 如果在容器退出之前没有使用`docker commit`命令将其保存为新的镜像,容器内所做的更改将不会被保留。
	* 如果手动删除了容器(使用`docker rm`命令),那么容器的数据将被删除,除非在删除容器时使用了`-v`选项来保留卷数据。
	* 数据的保留时间也受到`Docker`存储驱动程序的影响,不同的存储驱动程序可能会有不同的行为。


如果希望容器的数据永久保存,通常的做法是将数据卷挂载到容器中,这样即使容器退出,数据卷中的数据仍然会被保留。


### 3.21 如何停止所有正在运行的容器


要停止所有正在运行的`Docker`容器,可以使用以下命令:



docker stop $(docker ps -q)


这个命令执行了以下两个步骤:


1. `docker ps -q`:这个命令将列出当前正在运行的容器的`ID`,每个`ID`占据一行。 `-q`标志表示仅输出容器的`ID`,而不包括其他信息。
2. `docker stop`:然后,使用`docker stop`命令来停止列出的所有容器。`$(docker ps -q)` 将上一步中列出的容器`ID`作为参数传递给`docker stop`命令。


![](https://img-blog.csdnimg.cn/img_convert/9a8cb5f8c0ec69e6499adead0da6e95b.png)



最全的Linux教程,Linux从入门到精通

======================

1.  **linux从入门到精通(第2版)**

2.  **Linux系统移植**

3.  **Linux驱动开发入门与实战**

4.  **LINUX 系统移植 第2版**

5.  **Linux开源网络全栈详解 从DPDK到OpenFlow**



![华为18级工程师呕心沥血撰写3000页Linux学习笔记教程](https://img-blog.csdnimg.cn/img_convert/59742364bb1338737fe2d315a9e2ec54.png)



第一份《Linux从入门到精通》466页

====================

内容简介

====

本书是获得了很多读者好评的Linux经典畅销书**《Linux从入门到精通》的第2版**。本书第1版出版后曾经多次印刷,并被51CTO读书频道评为“最受读者喜爱的原创IT技术图书奖”。本书第﹖版以最新的Ubuntu 12.04为版本,循序渐进地向读者介绍了Linux 的基础应用、系统管理、网络应用、娱乐和办公、程序开发、服务器配置、系统安全等。本书附带1张光盘,内容为本书配套多媒体教学视频。另外,本书还为读者提供了大量的Linux学习资料和Ubuntu安装镜像文件,供读者免费下载。



![华为18级工程师呕心沥血撰写3000页Linux学习笔记教程](https://img-blog.csdnimg.cn/img_convert/9d4aefb6a92edea27b825e59aa1f2c54.png)



**本书适合广大Linux初中级用户、开源软件爱好者和大专院校的学生阅读,同时也非常适合准备从事Linux平台开发的各类人员。**

> 需要《Linux入门到精通》、《linux系统移植》、《Linux驱动开发入门实战》、《Linux开源网络全栈》电子书籍及教程的工程师朋友们劳烦您转发+评论




**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注运维)**
![img](https://img-blog.csdnimg.cn/img_convert/50810edae0e4a154d3692c29605ee8d8.jpeg)

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
没有足够的权限,可能无法访问`Docker`数据目录中的文件。对`Docker`数据目录进行直接操作通常是不推荐的,而应该使用`Docker`命令和API来管理容器和镜像。


### 3.20 容器退出后,通过docker ps命令查看不到,数据会丢失么


当容器退出后,通过`docker ps`命令查看不到容器的时候,容器的元数据会被清除,但容器内的数据通常不会立即丢失:


1. **容器元数据**:`Docker`容器在运行时会有一个相应的元数据记录,包括容器的名称、`ID`、状态等信息。当容器退出(例如,正常停止或发生错误导致退出)时,这些元数据记录会被清除,所以通过`docker ps`命令查看不到已经退出的容器。
2. **容器数据**:容器的数据(文件系统等)通常不会立即删除。`Docker`会保留容器的数据,以便可以随时重新创建容器并访问先前运行的容器内部的数据。

 如果想要重新启动已经退出的容器,可以使用容器的名称或`ID`来重新创建它,例如:`docker start <container_name_or_id>`,这将重新启动容器,并且可以通过`docker ps`查看到运行中的容器。

 但是,请注意以下几点:


	* 如果在容器退出之前没有使用`docker commit`命令将其保存为新的镜像,容器内所做的更改将不会被保留。
	* 如果手动删除了容器(使用`docker rm`命令),那么容器的数据将被删除,除非在删除容器时使用了`-v`选项来保留卷数据。
	* 数据的保留时间也受到`Docker`存储驱动程序的影响,不同的存储驱动程序可能会有不同的行为。


如果希望容器的数据永久保存,通常的做法是将数据卷挂载到容器中,这样即使容器退出,数据卷中的数据仍然会被保留。


### 3.21 如何停止所有正在运行的容器


要停止所有正在运行的`Docker`容器,可以使用以下命令:



docker stop $(docker ps -q)


这个命令执行了以下两个步骤:


1. `docker ps -q`:这个命令将列出当前正在运行的容器的`ID`,每个`ID`占据一行。 `-q`标志表示仅输出容器的`ID`,而不包括其他信息。
2. `docker stop`:然后,使用`docker stop`命令来停止列出的所有容器。`$(docker ps -q)` 将上一步中列出的容器`ID`作为参数传递给`docker stop`命令。


![](https://img-blog.csdnimg.cn/img_convert/9a8cb5f8c0ec69e6499adead0da6e95b.png)



最全的Linux教程,Linux从入门到精通

======================

1.  **linux从入门到精通(第2版)**

2.  **Linux系统移植**

3.  **Linux驱动开发入门与实战**

4.  **LINUX 系统移植 第2版**

5.  **Linux开源网络全栈详解 从DPDK到OpenFlow**



![华为18级工程师呕心沥血撰写3000页Linux学习笔记教程](https://img-blog.csdnimg.cn/img_convert/59742364bb1338737fe2d315a9e2ec54.png)



第一份《Linux从入门到精通》466页

====================

内容简介

====

本书是获得了很多读者好评的Linux经典畅销书**《Linux从入门到精通》的第2版**。本书第1版出版后曾经多次印刷,并被51CTO读书频道评为“最受读者喜爱的原创IT技术图书奖”。本书第﹖版以最新的Ubuntu 12.04为版本,循序渐进地向读者介绍了Linux 的基础应用、系统管理、网络应用、娱乐和办公、程序开发、服务器配置、系统安全等。本书附带1张光盘,内容为本书配套多媒体教学视频。另外,本书还为读者提供了大量的Linux学习资料和Ubuntu安装镜像文件,供读者免费下载。



![华为18级工程师呕心沥血撰写3000页Linux学习笔记教程](https://img-blog.csdnimg.cn/img_convert/9d4aefb6a92edea27b825e59aa1f2c54.png)



**本书适合广大Linux初中级用户、开源软件爱好者和大专院校的学生阅读,同时也非常适合准备从事Linux平台开发的各类人员。**

> 需要《Linux入门到精通》、《linux系统移植》、《Linux驱动开发入门实战》、《Linux开源网络全栈》电子书籍及教程的工程师朋友们劳烦您转发+评论




**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**

**需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注运维)**
[外链图片转存中...(img-SJg4gN25-1713148654777)]

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐