docker容器访问宿主机的docker环境
一、问题描述 当我们使用docker容器的时候,有时候我们需要访问宿主机的docker环境,比如我们需要在容器中访问宿主机的docker服务,或者我们需要在容器中访问宿主机的docker网络。这时候我们就需要进行一些配置。 二、docker容器访问宿主机的docker环境 要想让docker容器访问宿主机器的docker环境,并可以在docker容器中使用docker命令,我们需要在docker容器中挂载宿主机的docker.sock文件和docker程序。docker.sock 文件是docker的socket文件,docker的api通过这个文件来进行通信。docker程序是docker的命令行程序,我们可以通过这个程序来操作docker,比如启动容器,停止容器等。在启动docker容器的时候,我们可以通过-v参数来挂载这两个文件,示例如下: docker run -d --name controller --privileged -v /usr/bin/docker:/usr/bin/docker # 挂载docker程序 -v /var/run/docker.sock:/var/run/docker.sock # 挂载docker socket文件 -t ubuntu:latest 注意,这里我们使用了--privileged参数,这个参数是为了让docker容器拥有更高的权限,这样我们才能在docker容器中使用docker命令。如果不加这个参数,我们在docker容器中使用docker命令的时候会报错,提示权限不够。 还需要注意的是,这里必须保证宿主机操作系统的glibc版本和容器运行的镜像的glibc版本相同,否则在容器中执行docker命令会出现glibc版本冲突的问题。因此容器和宿主机最好采用相同的linux发行版本。 三、在docker容器内部访问其他容器的网络命名空间 1. Linux网络命名空间 Linux 的网络命名空间(Network Namespace)是一种内核提供的资源隔离机制,它为系统中的网络资源提供了独立的上下文环境,网络命名空间允许在同一物理主机上创建多个相互隔离的网络环境。每个网络命名空间都有自己独立的网络设备(如网卡)、IP 地址、路由表、防火墙规则等网络资源。不同网络命名空间中的网络配置相互独立,互不影响。例如,在一个命名空间中配置的 IP 地址,在其他命名空间中不会冲突,也无法直接访问。这就像是在同一台主机上虚拟出了多台独立的网络设备,每个设备都有自己的网络栈。 通过刚刚的配置我们可以在容器内部使用docker network去配置容器的网络,但有时候我们需要更加复杂的网络配置,比如为两个容器创建veth pair。这就需要我们在容器内部访问其他容器的Linux 网络命名空间。 2. 配置方法 一般的容器,如何没有使用host网络模式,都会有自己的网络命名空间,但是docker服务并没有把他们挂载到/var/run/netns目录下,因此使用ip netns等命令是无法访问到这些网络命名空间的。我们通常使用docker inspect获取容器的进程号,然后通过/proc/$pid/ns/net文件来访问容器的网络命名空间,因此我们可以通过挂载/proc目录来访问容器的网络命名空间。示例如下: docker run -d --name controller --privileged -v /usr/bin/docker:/usr/bin/docker -v /var/run/docker.sock:/var/run/docker.sock -v /proc:/host_proc # 挂载宿主机的/proc -t ubuntu:latest 为了防止/proc与容器内部的/proc目录冲突,这里我将其挂载为/host_proc。之后我们在容器内部将其他容器的命名空间链接到/var/run/netns目录下,就可以使用容器的pid直接访问容器的命名空间,而不需要输入完整的路径。比如我有一个pid为123的容器,示例命令如下 ln -s /host_proc/123/ns/net /var/run/netns/123 3. host网络模式 通过上面的配置我们已经让容器可以访问其他容器的命令空间了。但是我们想要进行为两个容器创建veth pair或者使用linux bridge去连接容器,建议使用host网络模式。host网络模式是docker的一种网络模式,使用host网络模式的容器会和宿主机共享网络命名空间,这样容器就可以直接访问宿主机的网络设备,这样当我们使用ip link或者brctl等命令创建网络设备的时候,保证我们是在宿主机上创建的,而不是在容器内部创建的。 四、注意事项 容器和宿主机最好采用相同的linux发行版本,以避免glibc版本冲突的问题。 使用--privileged参数让docker容器拥有更高的权限,这样我们才能在docker容器中使用docker命令。 使用host网络模式,可以让容器和宿主机共享网络命名空间,这样容器就可以直接访问宿主机的网络设备。 如果想要创建veth pair或者使用linux bridge去连接容器,然后使用ping等命令测试网络连通性,记得需要在你的特权容器中进行如下配置,否则可能会出现网络连通性问题: sysctl -w net....
本地docker部署libretranslate翻译模型并采用CUDA加速
一、Libretanslate基本介绍 Libretanslate 是一个开源的,基于AI驱动的翻译软件,官方网站提供了在线的翻译功能,并且可以申请 api 密钥去调用 api 将翻译能力嵌入到我们自己的程序或者软件中。当然,官方的github有详细的本地部署教程,如果有能力建议根据官方的 README 部署,本文是对可能遇到的一些问题的补充。本文采用的是 docker 部署,当然官方提供了直接通过 pip 包部署,读者可以根据自己的需求选择。效果图如下: 二. docker 与 nvidia docker 支持的前置条件 首先需要保证你的本地系统已经安装的 docker 环境,建议采用国内的源安装,比如清华源、阿里源等。同时建议配置docker镜像源防止由于网络问题无法拉取镜像。这里不提供安装配置命令,建议读者自行搜索相关资料。 使用 nvidia 的 docker 加速,需要读者本地拥有 nvidia 的显卡,并安装了显卡驱动。如果没有 nvidia 的显卡支持,可以跳过这一部分,进行 cpu 版本的本地部署。 首先要在自己的电脑上安装 nvidia docker 支持,参考的官方地址。根据你的 linux 发行版复制粘贴命令就行了,debian 发行版的安装命令如下: # 添加 apt 源 curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | \ sudo gpg --dearmor -o /usr/share/keyrings/nvidia-container-toolkit-keyring.gpg && \ curl -s -L https://nvidia.github.io/libnvidia-container/stable/deb/nvidia-container-toolkit.list | \ sed 's#deb https://#deb [signed-by=/usr/share/keyrings/nvidia-container-toolkit-keyring.gpg] https://#g' | \ tee /etc/apt/sources....
Debian12中GoldenDict词典软件的使用
一、GoldenDict基本介绍 GoldenDict 是一款开源的词典软件,它具有高度的定制性,可以自定义软件界面,它支持导入词典数据、调用外部网站和自定义程序等功能,对于需要 在学习中阅读英文文献时非常方便使用。在 Debian12 中可以直接通过 apt 命令下载该软件 sudo apt update sudo apt install goldendict 下载完毕后,软件界面如下: 在上面工具栏的编辑 -> 首选项 -> 界面可以设置界面语言,并且可以配置内置的一些主题风格,本文不讨论如何自定义界面风格。在编辑 -> 首选项 -> 词典可以配置词典数据来源。GoldenDict 支持多种词典来源,包括本地的词典数据、远程词典服务器、调用搜索引擎和调用脚本程序等。本文会给出一些在网络上搜集的本地词典资源(感谢这些资源的提供者),并给出一个调用百度官方api进行翻译的 python 脚本。 二、词典资源配置 1.本地词典资源 打开编辑 -> 首选项 -> 词典 -> 词典来源 -> 文件,这里可以配置词典文件的路径,如果是文件夹路径需要勾上递归搜索,然后点击应用,这样 GoldenDict 会扫描所有指定的词典文件,并为其生成索引。如果词典数量比较多这个过程会比较漫长,这取决于你的电脑的性能。索引生成完毕后这些词典就可以使用了,索引文件会存储在本地磁盘中,下一次打开不需要重新生成了。我自己用的词典资源: 词典资源 提取码: bp47。示例效果如图所示: 2. 调用百度翻译接口 拥有这些本地词典后,GoldenDict 会帮助你从这些本地词典搜索你要查询的单词或者词语,只要你的词典中有对应的记录即可。但是GoldenDict并不支持句子翻译,即它不会把句子拆成一组单词分别去查询,除非你的词典中有这样一条句子的翻译记录。因此我考虑将百度翻译接入到 GoldenDict 中这样方便进行一些简短的句子翻译。 首先需要在百度翻译api注册账户,选择通用翻译服务,进行认证后高级版通用翻译服务每个月会有一定量的免费额度。然后在管理控制台获取你的APP ID和密钥,替换下面代码中的 APP ID 和密钥,并配置日志文件路径: import requests import random import re from hashlib import md5 import sys import time # 设置你自己的appid和appkey appid = 'xxxxxxxxxxxxxxxxxx' appkey = 'xxxxxxxxxxxxxxxxxx' EN_LIMIT = 800 # 每800个英文字符添加一个换行符 ZH_LIMIT = 300 # 每300个汉字添加一个换行符 EN_MIN_NUM = 8 ZH_MIN_NUM = 5 def hasZhChar(text): pattern = re....
C语言使用泰勒展开实现sinx并优化
一、sinx 泰勒展开的C实现 1.sinx 泰勒展开公式 sinx 的泰勒展开如下: $$ sinx = x - \frac{x^3}{3!} + \frac{x^5}{5!} - \frac{x^7}{7!} + … + \frac{(-1)^n}{(2n + 1)!}x^{2n+1} $$ 其中 n 从 0 开始计算,我采用的公式形态上是 $x=0$ 处的泰勒展开。实际上我们可以把 $x$ 写成 $x = x + x_0$ 来实现 $x=x_0$ 处的展开 2.C实现sinx泰勒展开 我们通过控制精度来控制展开项数,并且我们只考虑 $0-2\pi$ 的范围,归一化处理我们之后再详细考虑,通过泰勒展开公式我们的 C 程序如下: #include <math.h> #define degree 1e-2 float fun_sin(float x) { float res, term; int i; int factor; // 阶乘 term = x; // 每一项的结果 factor = 1; res = term; for (i = 1; fabs(term) > degree; i++) { factor *= (2 * i) * (2 * i + 1); term = pow(-1, i) * pow(x, 2 * i + 1) / factor; res += term; } return res; } 上面的代码基本是严格按照公式计算的,可惜的是它并不能正常工作,这涉及到计算阶乘时整数溢出的问题。当输入比较小,比如 0....