python
资源
| 资源 | 组织 | 类型 |
|---|---|---|
| scientific python development | python | 文档 |
| Python Enhancement Proposals Index | python | 文档 |
| geeksforgeeks | python | docs |
| 可乐 python | docs | 文档 |
| pythonguide | pythonguide | docs |
| superfastpython | superfastpython | blog |
Docker 疑难问题
docker
安装
开发测试环境
1 | curl -fsSL https://get.docker.com | bash -s docker |
links:
更新
查看系统版本, 根据官方 文档 更新
1 | cat /etc/os-release |
QA: Error response from daemon: Unknown runtime specified docker-runc
当从不兼容的版本升级 docker 并且升级后无法启动 docker 容器时会出现这种情况,执行一下命令,然后重启 docker。
1 | grep -rl 'docker-runc' /var/lib/docker/containers/ | xargs sed -i 's/docker-runc/runc/g' |
dockerd
1 | ps -ef | grep dockerd |
/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock 是 Docker daemon 的启动命令,其中:
-
/usr/bin/dockerd 是 Docker daemon 的路径。
-
-H fd:// 是 Docker daemon 的监听地址,fd:// 是一个特殊的 Unix socket,用于 systemd socket activation。
-
–containerd=/run/containerd/containerd.sock 是指定 Docker daemon 使用的 containerd 的 socket 文件路径。
Docker daemon 使用 containerd 作为其默认的容器运行时,主要是因为 containerd 是一个轻量级的、高性能的开源容器运行时,它可以管理完整的容器生命周期,包括镜像管理、容器执行、任务管理、网络管理等。
除了 containerd,Docker 还支持其他的容器运行时,例如 runc、gVisor、Kata Containers 等。可以通过修改 Docker daemon 的配置文件来更改默认的容器运行时。
cgroup driver
Docker 的 cgroup driver 主要有两种类型:systemd 和 cgroupfs。
-
systemd: 当 Docker 使用 systemd 作为其 cgroup driver 时,它将会使用 systemd 来创建和管理 cgroup。这意味着 Docker 将会与系统的其他部分(也使用 systemd 的部分)共享同一套 cgroup,从而实现更好的资源管理。
-
cgroupfs: 当 Docker 使用 cgroupfs 作为其 cgroup driver 时,它将会直接与 cgroup 文件系统交互来创建和管理 cgroup。这意味着 Docker 将会有自己独立的一套 cgroup,与系统的其他部分(使用 systemd 的部分)分开。
总的来说,systemd 和 cgroupfs 的主要区别在于它们与系统的其他部分的交互方式不同。systemd 更倾向于与系统的其他部分共享资源,而 cgroupfs 则更倾向于独立管理资源。
要将 Docker 的 cgroup driver 从 cgroupfs 迁移到 systemd,需要在 Docker 的配置文件中进行更改。以下是步骤:
-
打开 Docker 的配置文件,通常位于 /etc/docker/daemon.json。如果文件不存在,需要创建它。
1 | nano /etc/docker/daemon.json |
-
在配置文件中添加或修改 "exec-opts",将其设置为 "native.cgroupdriver = systemd"。
1 | { |
-
保存并关闭文件,然后重启 Docker 服务。
1 | systemctl restart docker |
迁移到 systemd 的好处主要有:
-
更好的资源管理:systemd 可以与系统的其他部分共享 cgroup,从而实现更好的资源管理。
-
更好的兼容性:一些 Kubernetes 工具(如 kubeadm)要求 Docker 使用 systemd 作为其 cgroup driver,以确保与 Kubernetes 的兼容性。
-
更好的稳定性:systemd 作为 cgroup driver 的稳定性通常比 cgroupfs 更好。
links:
command
docker daemon service
1 | service docker start/stop/restart/status |
volume
1 | docker volume ls |
docker QA
以下为 Docker 中各种疑难问题及解答
Got permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Get http://%2Fvar%2Frun%2Fdocker.sock/v1.40/images/json: dial unix /var/run/docker.sock: connect: permission denied
docker daemon 配置
docker 运行配置主要通过文件 daemon.json 配置。所在路径在 /etc/docker/daemon.json。
1 | { |
links:
docker context
docker context 用于本地方便地访问远程主机的 docker 服务。在不需要手动通过 ssh 连接远程服务器时比较有帮助。
添加 context
1 | docker context create <context-name> --docker "host=ssh://format" |
这里 format 可使用一下格式:
-
username@host-ip[:port]
-
name,指在~/.ssh/config 中提供的 ssh 连接配置名称。
示例:
1 | $ cat ~/.ssh/config |
常用命令
下面列出了常用的 docker context 命令和示例。
1 | $ docker --context my-remote-docker-machine images -q |
1 | $ docker context use my-remote-docker-machine |
1 | $ docker context use default # back to default |
使用 docker 上下文可能有助于避免手动将 SSH 连接到远程服务器。但是,当涉及到在本地使用远程 docker 构建映像时,需要考虑将上载 / 下载多少 docker 上下文。
reference
docker run permission
–cap-add
通常用于开发用的镜像需要设置 cli 参数给予相应的容器权限。
-
–cap-add=NET_RAW: 允许容器进程使用原始套接字,直接访问网络层,一般进行网络嗅探等网络底层操作的容器进程需要。
-
–cap-add=SYS_PTRACE: 允许容器进程使用 ptrace 系统调用。 ptrace 允许一个进程监视和控制另一个进程的执行,包括读取和修改其内存和寄存器状态。这个选项通常用于需要进行调试或其他进程控制操作的容器。
-
–cap-add=NET_ADMIN: 允许容器进程使用网络管理功能。该选项需要对网络进行配置或管理的容器,例如配置网络接口、设置路由或进行网络诊断等操作。
–security-opt
-
–security-opt seccomp = unconfined: 允许设置容器的 seccomp 配置。seccomp 是一种 Linux 内核安全模块,它可以限制进程可以执行的系统调用。该选项禁用 seccomp 配置,从而允许容器进程执行所有系统调用,通常用于需要执行一些不受限制的系统调用的容器,但是这也会降低容器的安全性。
–privileged
-
它允许容器进程拥有主机上的所有特权。这个选项通常用于需要访问主机上的特权设备或执行一些需要特权的操作的容器。使用这个选项会增加容器的安全风险,因为容器进程可以访问主机
–gpus
允许访问主机 gpu 资源
-
[num]: gpu 数量
-
all: 所有 gpu
[!TIP]
如果需要支持 Nvidia Cuda,则需要额外安装支持的 Docker Runtime
1
2 apt update && apt install -y nvidia-docker2 \
&& nvidia-ctk runtime configure
验证 gpu 是否可用
1 | # https://catalog.ngc.nvidia.com/orgs/nvidia/teams/k8s/containers/cuda-sample |
QA
-
failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error running hook #0: error running hook: exit status 1, stdout: , stderr: nvidia-container-cli: requirement error: unsatisfied condition: cuda>=11.7: unknown.
镜像版本要求 cuda 需要大于 11.7:
-
升级驱动满足镜像要求
-
采用符合要求的镜像
容器中执行设置错误退出
1 | # set -e 配置遇到错误即退出,并设置退出错误码255 |
dockerignore
.dockerignore 主要用于在 docker 构建镜像时忽略不需要打包进去的过滤方式,类似于 .gitignore 文件。该文件位于构建上下文的根目录。
匹配规则如下:
| pattern | description |
|---|---|
| /temp | 匹配根路径下一级目录下所有以 temp 开头的文件或目录 |
| //temp* | 匹配根路径下两级目录下所有以 temp 开头的文件或目录 |
| temp? | 匹配根路径下以 temp 开头,任意一个字符结尾的文件或目录 |
| **/*.go | 匹配所有路径下以 .go 结尾的文件或目录,即递归搜索所有路径 |
| *.md !README.md |
匹配根路径下所有以 .md 结尾的文件或目录,但 README.md 除外 |
[!CAUTION]
如果存在冲突的行或重叠包含关系,那么以后面的匹配规则为准。
reference
dockerfile
links:
RUN
使用 EOF 避免使用冗余的换行符运行, dockerfile:1.4 声明版本, 或者直接指定版本 1
1 | # syntax=docker/dockerfile:1 |
links:
ADD & COPY
在编写 Dockerfile 时经常需要拷贝文件或文件夹的操作,这时就需要用到 ADD 和 COPY 指令。
-
拷贝单个文件到指定目录
1 | #拷贝当前目录下的test.jar到/usr/bin目录下 |
-
拷贝特定的多个文件到指定目录
ADD 指令支持通配符,常用的示例如下:
1 | #拷贝当前目录下的bin文件夹的所有sh文件到/usr/bin目录下 |
-
拷贝文件夹到指定的目录
ADD 宿主机文件夹的全路径 docker 容器下的文件夹路径 + 新文件夹名
1 | #拷贝当前目录下的config文件夹到/usr/bin目录下 |
SHELL
用于覆盖默认的 Shell
1 | # syntax=docker/dockerfile:1 |
links:
dockerfile 优化
选择基础镜像
优化指令顺序
把 WORKDIR/ENV 等命令放在前面,COPY/ADD 等命令放在后面 [^2]。
合并构建指令
清理中间缓存
用户数据缓存:
-
~/.cache 等用户缓存。
-
安装包临时缓存。
开发镜像和运行时镜像分离
runtime 镜像仅包含基本运行环境,开发镜像包含所有的开发依赖。开发镜像尽可能以 runtime 镜像为基础构建。
多阶段构建
使用 buildkit
1 | # 构建多平台镜像 |
使用构建缓存 RUN --mount
[!CAUTION]
buildkit 会使用 docker 构建缓存,也就是 Build Cache,需要定期清理。查看缓存:docker system df
清理方式:echo yes | docker builder prune -a
二进制工具安装
从现有镜像中安装二进制文件
1 | FROM golang:1.17 |
reference
docker inspect
docker inspect 输出可以通过--format,使用{{.}}检索某个字段结果
1 | # 输出原始数据, 这里`.`表示所有结果 |
log
Docker 默认将日志存储到一个日志文件中。要检查日志文件路径,请运行命令
1 | docker inspect --format='{{.LogPath}}' containername |
要查看实时日志,可以在以下命令中运行
1 | tail -f `docker inspect --format='{{.LogPath}}' containername` |
注意:
/var/lib/docker/containers/f844a7b45ca5a9589ffaa1a5bd8dea0f4e79f0e2ff639c1d010d96afb4b53334/f844a7b45ca5a9589ffaa1a5bd8dea0f4e79f0e2ff639c1d010d96afb4b53334-json.log仅当 docker 生成日志(如果没有日志)时,才会创建此日志文件,否则该文件将不存在。如果我们运行命令docker logs containername,它类似于某个时候,但什么也不返回。在这种情况下,该文件将不可用。
-
重定向
1 | docker logs -f <yourContainer> &> your.log & |
说明:
-
-f(即–follow):写入所有现有日志,并继续(跟随)记录接下来出现的所有内容。
-
&> 重定向标准输出和标准错误。
-
可能想在后台运行该方法,因此 &。
-
可以通过以下方式将输出和 stderr 分开:(> output.log 2> error.log 而不是使用 &>)。
docker port
porting 映射
默认情况下,宿主机是无法访问容器内部网络的,但是可以使用端口映射来解决这个问题。主要通过 docker run 跟 -P(大写) 或 -p(小写)参数来实现。docker run -P 会把容器中监听的端口随机绑定到宿主机的可用端口上:
1 | docker run -p <format> image |
<format>指定格式如下
-
ip:hostport:containerport #指定 ip、指定宿主机 port、指定容器 port
-
ip::containerport #指定 ip、未指定宿主机 port(随机)、指定容器 port
-
hostport:containerport #未指定 ip、指定宿主机 port、指定容器 port
容器互联
容器互联通过 --link 配置链接实现单独隔离容器的互联。
以下以 nginx + php-fpm 示例:
1 | # 这里分别有一个 php-fpm 和 nginx 镜像。 |
参考
dumb-init
这里介绍了一种容器初始化系统 dumb-init。
主要关注于解决两个问题。
-
作为
PID为 1 容器进程的信号处理。 -
孤儿僵尸进程回收。
flutter
Flutter
Google 开发的基于 Dart 跨平台桌面开发框架。
Resource
| 资源 | 类型 | 组织 |
|---|---|---|
| flutter | dev doc | flutter |
| flutter cn | dev doc | flutter |
| dartpad | dev tool | online flutter dev environment |
network
resource
| 资源 | 组织 | 类型 |
|---|---|---|
| devops-exercises | bregman-arie | 基础 |
ipv4
格式表示
IPv4 地址是 Internet Protocol Version 4 的缩写,它是一种在互联网上使用的网络地址。IPv4 地址由四个数字组成,每个数字在 0 到 255 之间,数字之间用点(.)分隔。例如,192.168.1.1 就是一个 IPv4 地址。
IPv4 地址的二进制表示是将每个数字转换为 8 位二进制数。例如,192.168.1.1 的二进制表示为:11000000.10101000.00000001.00000001
cpp 实践
开发社区
搜集的 C++ 问答社区
相关资源
C++ 比较庞杂,开源社区资源,整理如下:
| 资源 | 组织 | 类型 |
|---|---|---|
| ISO CPP | isocpp | 规范 |
| C++ Core Guidelines | isocpp | 规范 |
| C++ Note | TOMO-CAT | 基本语法 |
| C++ Tips | Abseil 及 Google | 规范 |
| Google C++ Style Guide | 规范 | |
| C++ Stories | Bartłomiej Filipek | 博客 |
| AwesomePerfCpp | fenbf | 博客 |
| awesome cpp cn | jobbole | 框架 |
| awesome cpp | fffaraz | 框架 |
| C++ Insights | cppinsights | 工具 |
| C++ Compiler Explorer | godbolt | 工具 |
| Computer simulator | cpulator | 工具 |
| sandbox | melpon | 工具 |
| Reshaper 激活码 | Reshaper | 插件 / 工具 |
| Visual Assist | Visual Assist | 插件 / 工具 |
| Performance Effect | johnnysswlab | blog |
| ISO/IEC C++ | ISO/IEC | 标准规范 |
| ISO/IEC C | ISO/IEC | 标准规范 |
| ISO/IEC POSIX | ISO/IEC | 标准规范 |
| cpp-best-practices | cpp-best-practices | Jason Turner |
| cppnext | Alex Dathskovsky blog | 博客 |
| moderncpp | Alan De Freitas | 博客 |
| cpp-resources | sandordargo | github 仓库 |
| c-cpp-notes | caiorss | 博客 |
Welcome to Hexo
Welcome to Hexo! This is your very first post. Check documentation for more info. If you get any problems when using Hexo, you can find the answer in troubleshooting or you can ask me on GitHub.








