Compare commits
5 Commits
c446012199
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
|
58ba4b2a2f
|
|||
|
009e86b553
|
|||
|
d1ec3a51d1
|
|||
|
dab866f13a
|
|||
| 94421168c6 |
@@ -15,6 +15,9 @@ trim_trailing_whitespace = true
|
|||||||
[project.json]
|
[project.json]
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|
||||||
|
[*.{yaml,yml}]
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
# C# and Visual Basic files
|
# C# and Visual Basic files
|
||||||
[*.{cs,vb}]
|
[*.{cs,vb}]
|
||||||
charset = utf-8-bom
|
charset = utf-8-bom
|
||||||
|
|||||||
@@ -1,33 +1,36 @@
|
|||||||
name: Build blog docker image
|
name: Build blog docker image
|
||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- master
|
||||||
jobs:
|
jobs:
|
||||||
Build-Blog-Image:
|
Build-Blog-Image:
|
||||||
runs-on: archlinux
|
runs-on: archlinux
|
||||||
steps:
|
steps:
|
||||||
- uses: https://mirrors.rrricardo.top/actions/checkout.git@v4
|
- name: Check out code.
|
||||||
name: Check out code
|
uses: https://mirrors.rrricardo.top/actions/checkout.git@v4
|
||||||
with:
|
with:
|
||||||
lfs: true
|
lfs: true
|
||||||
- name: Build project
|
- name: Build project.
|
||||||
run: |
|
run: |
|
||||||
cd YaeBlog
|
cd YaeBlog
|
||||||
dotnet publish
|
dotnet publish
|
||||||
- name: Build docker image
|
- name: Build docker image.
|
||||||
run: |
|
run: |
|
||||||
cd YaeBlog
|
proxy
|
||||||
podman build . -t registry.cn-beijing.aliyuncs.com/jackfiled/blog:latest --build-arg COMMIT_ID=$(git rev-parse --short=10 HEAD)
|
podman pull mcr.microsoft.com/dotnet/aspnet:9.0
|
||||||
- name: Workaround to make sure podman login succeed
|
unproxy
|
||||||
run: |
|
cd YaeBlog
|
||||||
mkdir /root/.docker
|
podman build . -t ccr.ccs.tencentyun.com/jackfiled/blog --build-arg COMMIT_ID=$(git rev-parse --short=10 HEAD)
|
||||||
- name: Login aliyun docker registry
|
- name: Workaround to make sure podman-login working.
|
||||||
uses: https://mirrors.rrricardo.top/actions/podman-login.git@v1
|
run: |
|
||||||
with:
|
mkdir /root/.docker
|
||||||
registry: registry.cn-beijing.aliyuncs.com
|
- name: Login tencent cloud docker registry.
|
||||||
username: 初冬的朝阳
|
uses: https://mirrors.rrricardo.top/actions/podman-login.git@v1
|
||||||
password: ${{ secrets.ALIYUN_PASSWORD }}
|
with:
|
||||||
auth_file_path: /etc/containers/auth.json
|
registry: ccr.ccs.tencentyun.com
|
||||||
- name: Push docker image
|
username: 100044380877
|
||||||
run: podman push registry.cn-beijing.aliyuncs.com/jackfiled/blog:latest
|
password: ${{ secrets.TENCENT_REGISTRY_PASSWORD }}
|
||||||
|
auth_file_path: /etc/containers/auth.json
|
||||||
|
- name: Push docker image.
|
||||||
|
run: podman push ccr.ccs.tencentyun.com/jackfiled/blog:latest
|
||||||
|
|||||||
@@ -39,6 +39,11 @@
|
|||||||
{
|
{
|
||||||
_page = Page ?? 1;
|
_page = Page ?? 1;
|
||||||
_pageCount = Contents.Count / EssaysPerPage + 1;
|
_pageCount = Contents.Count / EssaysPerPage + 1;
|
||||||
|
(_pageCount, int reminder) = int.DivRem(Contents.Count, EssaysPerPage);
|
||||||
|
if (reminder > 0)
|
||||||
|
{
|
||||||
|
_pageCount += 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (EssaysPerPage * _page > Contents.Count + EssaysPerPage)
|
if (EssaysPerPage * _page > Contents.Count + EssaysPerPage)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -16,11 +16,11 @@ public sealed class BlogHotReloadService(
|
|||||||
|
|
||||||
await rendererService.RenderAsync(true);
|
await rendererService.RenderAsync(true);
|
||||||
|
|
||||||
Task[] reloadTasks = [FileWatchTask(stoppingToken)];
|
Task[] reloadTasks = [WatchFileAsync(stoppingToken)];
|
||||||
await Task.WhenAll(reloadTasks);
|
await Task.WhenAll(reloadTasks);
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task FileWatchTask(CancellationToken token)
|
private async Task WatchFileAsync(CancellationToken token)
|
||||||
{
|
{
|
||||||
while (!token.IsCancellationRequested)
|
while (!token.IsCancellationRequested)
|
||||||
{
|
{
|
||||||
@@ -33,6 +33,15 @@ public sealed class BlogHotReloadService(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FileInfo changeFileInfo = new(changeFile);
|
||||||
|
|
||||||
|
if (changeFileInfo.Name.StartsWith('.'))
|
||||||
|
{
|
||||||
|
// Ignore dot-started file and directory.
|
||||||
|
logger.LogDebug("Ignore hidden file: {}.", changeFile);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
logger.LogInformation("{} changed, re-rendering.", changeFile);
|
logger.LogInformation("{} changed, re-rendering.", changeFile);
|
||||||
essayContentService.Clear();
|
essayContentService.Clear();
|
||||||
await rendererService.RenderAsync(true);
|
await rendererService.RenderAsync(true);
|
||||||
|
|||||||
@@ -109,6 +109,12 @@ public partial class EssayScanService : IEssayScanService
|
|||||||
{
|
{
|
||||||
foreach (BlogResult blog in fileContents)
|
foreach (BlogResult blog in fileContents)
|
||||||
{
|
{
|
||||||
|
if (blog.BlogContent.Length < 4)
|
||||||
|
{
|
||||||
|
// Even not contains a legal header.
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
int endPos = blog.BlogContent.IndexOf("---", 4, StringComparison.Ordinal);
|
int endPos = blog.BlogContent.IndexOf("---", 4, StringComparison.Ordinal);
|
||||||
if (!blog.BlogContent.StartsWith("---") || endPos is -1 or 0)
|
if (!blog.BlogContent.StartsWith("---") || endPos is -1 or 0)
|
||||||
{
|
{
|
||||||
@@ -121,14 +127,14 @@ public partial class EssayScanService : IEssayScanService
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
MarkdownMetadata metadata = _yamlDeserializer.Deserialize<MarkdownMetadata>(metadataString);
|
MarkdownMetadata metadata = _yamlDeserializer.Deserialize<MarkdownMetadata>(metadataString);
|
||||||
_logger.LogDebug("Scan metadata title: '{}' for {}.", metadata.Title, blog.BlogFile.Name);
|
_logger.LogDebug("Scan metadata title: '{title}' for {name}.", metadata.Title, blog.BlogFile.Name);
|
||||||
|
|
||||||
contents.Add(new BlogContent(blog.BlogFile, metadata, blog.BlogContent[(endPos + 3)..], isDraft,
|
contents.Add(new BlogContent(blog.BlogFile, metadata, blog.BlogContent[(endPos + 3)..], isDraft,
|
||||||
blog.Images, blog.NotFoundImages));
|
blog.Images, blog.NotFoundImages));
|
||||||
}
|
}
|
||||||
catch (YamlException e)
|
catch (YamlException e)
|
||||||
{
|
{
|
||||||
_logger.LogWarning("Failed to parser metadata from {} due to {}, skipping", blog.BlogFile.Name, e);
|
_logger.LogWarning("Failed to parser metadata from {name} due to {exception}, skipping", blog.BlogFile.Name, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
---
|
|
||||||
title: High Performance Computing 25 SP Quantum Computing
|
|
||||||
date: 2025-06-12T19:26:24.6668760+08:00
|
|
||||||
tags:
|
|
||||||
- 高性能计算
|
|
||||||
- 学习资料
|
|
||||||
---
|
|
||||||
|
|
||||||
|
|
||||||
<!--more-->
|
|
||||||
BIN
YaeBlog/source/drafts/hpc-2025-non-stored-program-computing/image-20250815093113115.png
(Stored with Git LFS)
BIN
YaeBlog/source/drafts/hpc-2025-non-stored-program-computing/image-20250815093113115.png
(Stored with Git LFS)
Binary file not shown.
BIN
YaeBlog/source/drafts/hpc-2025-non-stored-program-computing/image-20250817183832472.png
(Stored with Git LFS)
BIN
YaeBlog/source/drafts/hpc-2025-non-stored-program-computing/image-20250817183832472.png
(Stored with Git LFS)
Binary file not shown.
BIN
YaeBlog/source/drafts/hpc-2025-non-stored-program-computing/image-20250817184419856.png
(Stored with Git LFS)
BIN
YaeBlog/source/drafts/hpc-2025-non-stored-program-computing/image-20250817184419856.png
(Stored with Git LFS)
Binary file not shown.
BIN
YaeBlog/source/drafts/hpc-2025-non-stored-program-computing/image-20250817185111521.png
(Stored with Git LFS)
BIN
YaeBlog/source/drafts/hpc-2025-non-stored-program-computing/image-20250817185111521.png
(Stored with Git LFS)
Binary file not shown.
BIN
YaeBlog/source/drafts/hpc-2025-non-stored-program-computing/image-20250817185859510.png
(Stored with Git LFS)
BIN
YaeBlog/source/drafts/hpc-2025-non-stored-program-computing/image-20250817185859510.png
(Stored with Git LFS)
Binary file not shown.
BIN
YaeBlog/source/drafts/hpc-2025-non-stored-program-computing/image-20250817192006784.png
(Stored with Git LFS)
BIN
YaeBlog/source/drafts/hpc-2025-non-stored-program-computing/image-20250817192006784.png
(Stored with Git LFS)
Binary file not shown.
BIN
YaeBlog/source/drafts/hpc-2025-non-stored-program-computing/image-20250817194355228.png
(Stored with Git LFS)
BIN
YaeBlog/source/drafts/hpc-2025-non-stored-program-computing/image-20250817194355228.png
(Stored with Git LFS)
Binary file not shown.
BIN
YaeBlog/source/drafts/hpc-2025-non-stored-program-computing/image-20250817195139631.png
(Stored with Git LFS)
BIN
YaeBlog/source/drafts/hpc-2025-non-stored-program-computing/image-20250817195139631.png
(Stored with Git LFS)
Binary file not shown.
BIN
YaeBlog/source/drafts/hpc-2025-non-stored-program-computing/image-20250817195714935.png
(Stored with Git LFS)
BIN
YaeBlog/source/drafts/hpc-2025-non-stored-program-computing/image-20250817195714935.png
(Stored with Git LFS)
Binary file not shown.
BIN
YaeBlog/source/drafts/hpc-2025-non-stored-program-computing/image-20250817200350750.png
(Stored with Git LFS)
BIN
YaeBlog/source/drafts/hpc-2025-non-stored-program-computing/image-20250817200350750.png
(Stored with Git LFS)
Binary file not shown.
BIN
YaeBlog/source/drafts/hpc-2025-non-stored-program-computing/image-20250829210329225.png
(Stored with Git LFS)
BIN
YaeBlog/source/drafts/hpc-2025-non-stored-program-computing/image-20250829210329225.png
(Stored with Git LFS)
Binary file not shown.
@@ -1,12 +1,13 @@
|
|||||||
---
|
---
|
||||||
title: High Performance Computing 25 SP NVIDIA
|
title: High Performance Computing 25 SP NVIDIA
|
||||||
date: 2025-04-24T19:02:36.1077330+08:00
|
date: 2025-08-31T13:50:42.8639950+08:00
|
||||||
tags:
|
tags:
|
||||||
- 高性能计算
|
- 高性能计算
|
||||||
- 学习资料
|
- 学习资料
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Fxxk you, NVIDIA!
|
Fxxk you, NVIDIA!
|
||||||
|
|
||||||
<!--more-->
|
<!--more-->
|
||||||
@@ -1,11 +1,13 @@
|
|||||||
---
|
---
|
||||||
title: High Performance Computing 2025 SP Non Stored Program Computing
|
title: High Performance Computing 25 SP Non Stored Program Computing
|
||||||
date: 2025-05-29T18:29:28.6155560+08:00
|
date: 2025-08-31T13:51:17.5260660+08:00
|
||||||
tags:
|
tags:
|
||||||
- 高性能计算
|
- 高性能计算
|
||||||
- 学习资料
|
- 学习资料
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
No Von Neumann Machines.
|
No Von Neumann Machines.
|
||||||
|
|
||||||
<!--more-->
|
<!--more-->
|
||||||
@@ -60,7 +62,7 @@ There are two types of semi-custom ASICs:
|
|||||||
|
|
||||||
The Standard cell based ASICs is also called as **Cell-based ASIC(CBIC)**.
|
The Standard cell based ASICs is also called as **Cell-based ASIC(CBIC)**.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
> The *gate* is used a unit to measure the ability of semiconductor to store logical elements.
|
> The *gate* is used a unit to measure the ability of semiconductor to store logical elements.
|
||||||
|
|
||||||
@@ -84,7 +86,7 @@ Depending on the structure, the standard PLD can be divided into:
|
|||||||
- Programmable Logic Array(PLA): A programmable array of AND gates feeding a programmable of OR gates.
|
- Programmable Logic Array(PLA): A programmable array of AND gates feeding a programmable of OR gates.
|
||||||
- Complex Programmable Logic Device(CPLD) and Field Programmable Gate Array(FPGA): complex enough to be called as *architecture*.
|
- Complex Programmable Logic Device(CPLD) and Field Programmable Gate Array(FPGA): complex enough to be called as *architecture*.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -96,7 +98,7 @@ Depending on the structure, the standard PLD can be divided into:
|
|||||||
|
|
||||||
### FPGA Architecture
|
### FPGA Architecture
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
#### Configurable Logic Block(CLB) Architecture
|
#### Configurable Logic Block(CLB) Architecture
|
||||||
|
|
||||||
@@ -116,7 +118,7 @@ LUT is a ram with data width of 1 bit and the content is programmed at power up.
|
|||||||
|
|
||||||
The below figure shows LUT working:
|
The below figure shows LUT working:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
The configuration memory holds the output of truth table entries, so that when the FPGA is restarting it will run with the same *program*.
|
The configuration memory holds the output of truth table entries, so that when the FPGA is restarting it will run with the same *program*.
|
||||||
|
|
||||||
@@ -126,7 +128,7 @@ And as the truth table entries are just bits, the program of FPGA is called as *
|
|||||||
|
|
||||||
Let the input signal as address, the LUT will be configured as a RAM. Normally, LUT mode performs read operations, the address decoders can generate clock signal to latches for writing operation.
|
Let the input signal as address, the LUT will be configured as a RAM. Normally, LUT mode performs read operations, the address decoders can generate clock signal to latches for writing operation.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
#### Routing Architecture
|
#### Routing Architecture
|
||||||
|
|
||||||
@@ -134,7 +136,7 @@ The logic blocks are connected to each though programmable routing network. And
|
|||||||
|
|
||||||
Horizontal and vertical mesh or wire segments interconnection by programmable switches called programmable interconnect points(PIPs).
|
Horizontal and vertical mesh or wire segments interconnection by programmable switches called programmable interconnect points(PIPs).
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
These PIPs are implemented using a transmission gate controlled by a memory bits from the configuration memory.
|
These PIPs are implemented using a transmission gate controlled by a memory bits from the configuration memory.
|
||||||
|
|
||||||
@@ -146,7 +148,7 @@ Several types of PIPs are used in the FPGA:
|
|||||||
- Non-decoded MUX: n wire segments each with a configuration bit.
|
- Non-decoded MUX: n wire segments each with a configuration bit.
|
||||||
- Compound cross-point: 6 breakpoint PIPs and can isolate two isolated signal nets.
|
- Compound cross-point: 6 breakpoint PIPs and can isolate two isolated signal nets.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
#### Input/Output Architecture
|
#### Input/Output Architecture
|
||||||
|
|
||||||
@@ -158,7 +160,7 @@ The programmable Input/Output cells consists of three parts:
|
|||||||
- Routing resources.
|
- Routing resources.
|
||||||
- Programmable I/O voltage and current levels.
|
- Programmable I/O voltage and current levels.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
#### Fine-grained and Coarse-grained Architecture
|
#### Fine-grained and Coarse-grained Architecture
|
||||||
|
|
||||||
@@ -186,9 +188,9 @@ Three types of interconnected devices have been commonly used to connect there w
|
|||||||
|
|
||||||
### FPGA Design Flow
|
### FPGA Design Flow
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
The FPGA configuration techniques contains:
|
The FPGA configuration techniques contains:
|
||||||
|
|
||||||
@@ -222,7 +224,7 @@ The OpenCL is not an traditional hardare description language. And OpenCL needs
|
|||||||
|
|
||||||
The follow figure shows how the OpenCL-FPGA compiler turns an vector adding function into the circuit.
|
The follow figure shows how the OpenCL-FPGA compiler turns an vector adding function into the circuit.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
The compiler generates three stages for this function:
|
The compiler generates three stages for this function:
|
||||||
|
|
||||||
BIN
YaeBlog/source/posts/hpc-2025-non-stored-program-computing/image-20250815093113115.webp
(Stored with Git LFS)
Normal file
BIN
YaeBlog/source/posts/hpc-2025-non-stored-program-computing/image-20250815093113115.webp
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
YaeBlog/source/posts/hpc-2025-non-stored-program-computing/image-20250817183832472.webp
(Stored with Git LFS)
Normal file
BIN
YaeBlog/source/posts/hpc-2025-non-stored-program-computing/image-20250817183832472.webp
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
YaeBlog/source/posts/hpc-2025-non-stored-program-computing/image-20250817184419856.webp
(Stored with Git LFS)
Normal file
BIN
YaeBlog/source/posts/hpc-2025-non-stored-program-computing/image-20250817184419856.webp
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
YaeBlog/source/posts/hpc-2025-non-stored-program-computing/image-20250817185111521.webp
(Stored with Git LFS)
Normal file
BIN
YaeBlog/source/posts/hpc-2025-non-stored-program-computing/image-20250817185111521.webp
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
YaeBlog/source/posts/hpc-2025-non-stored-program-computing/image-20250817185859510.webp
(Stored with Git LFS)
Normal file
BIN
YaeBlog/source/posts/hpc-2025-non-stored-program-computing/image-20250817185859510.webp
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
YaeBlog/source/posts/hpc-2025-non-stored-program-computing/image-20250817192006784.webp
(Stored with Git LFS)
Normal file
BIN
YaeBlog/source/posts/hpc-2025-non-stored-program-computing/image-20250817192006784.webp
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
YaeBlog/source/posts/hpc-2025-non-stored-program-computing/image-20250817194355228.webp
(Stored with Git LFS)
Normal file
BIN
YaeBlog/source/posts/hpc-2025-non-stored-program-computing/image-20250817194355228.webp
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
YaeBlog/source/posts/hpc-2025-non-stored-program-computing/image-20250817195139631.webp
(Stored with Git LFS)
Normal file
BIN
YaeBlog/source/posts/hpc-2025-non-stored-program-computing/image-20250817195139631.webp
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
YaeBlog/source/posts/hpc-2025-non-stored-program-computing/image-20250817195714935.webp
(Stored with Git LFS)
Normal file
BIN
YaeBlog/source/posts/hpc-2025-non-stored-program-computing/image-20250817195714935.webp
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
YaeBlog/source/posts/hpc-2025-non-stored-program-computing/image-20250817200350750.webp
(Stored with Git LFS)
Normal file
BIN
YaeBlog/source/posts/hpc-2025-non-stored-program-computing/image-20250817200350750.webp
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
YaeBlog/source/posts/hpc-2025-non-stored-program-computing/image-20250829210329225.webp
(Stored with Git LFS)
Normal file
BIN
YaeBlog/source/posts/hpc-2025-non-stored-program-computing/image-20250829210329225.webp
(Stored with Git LFS)
Normal file
Binary file not shown.
@@ -1,11 +1,12 @@
|
|||||||
---
|
---
|
||||||
title: High Performance Computing 2025 SP OpenCL Programming
|
title: High Performance Computing 25 SP OpenCL Programming
|
||||||
date: 2025-05-29T18:29:14.8444660+08:00
|
date: 2025-08-31T13:51:02.0181970+08:00
|
||||||
tags:
|
tags:
|
||||||
- 高性能计算
|
- 高性能计算
|
||||||
- 学习资料
|
- 学习资料
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
Open Computing Language.
|
Open Computing Language.
|
||||||
|
|
||||||
<!--more-->
|
<!--more-->
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
---
|
---
|
||||||
title: High Performance Computing 25 SP Potpourri
|
title: High Performance Computing 25 SP Potpourri
|
||||||
date: 2025-06-12T18:45:49.2698190+08:00
|
date: 2025-08-31T13:51:29.8809980+08:00
|
||||||
tags:
|
tags:
|
||||||
- 高性能计算
|
- 高性能计算
|
||||||
- 学习资料
|
- 学习资料
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
Potpourri has a good taste.
|
Potpourri has a good taste.
|
||||||
|
|
||||||
<!--more-->
|
<!--more-->
|
||||||
@@ -1,11 +1,12 @@
|
|||||||
---
|
---
|
||||||
title: High Performance Computing 2025 SP Programming CUDA
|
title: High Performance Computing 25 SP Programming CUDA
|
||||||
date: 2025-05-15T19:13:48.8893010+08:00
|
date: 2025-08-31T13:50:53.6891520+08:00
|
||||||
tags:
|
tags:
|
||||||
- 高性能计算
|
- 高性能计算
|
||||||
- 学习资料
|
- 学习资料
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
||||||
Compute Unified Device Architecture
|
Compute Unified Device Architecture
|
||||||
|
|
||||||
<!--more-->
|
<!--more-->
|
||||||
130
YaeBlog/source/posts/podman-dns-failed.md
Normal file
130
YaeBlog/source/posts/podman-dns-failed.md
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
---
|
||||||
|
title: Podman容器中特定域名解析失败问题排查
|
||||||
|
date: 2025-10-22T17:42:07.7738936+08:00
|
||||||
|
tags:
|
||||||
|
- 技术笔记
|
||||||
|
- Bug Collections
|
||||||
|
---
|
||||||
|
|
||||||
|
最难以置信的一集。
|
||||||
|
|
||||||
|
<!--more-->
|
||||||
|
|
||||||
|
## 问题现象
|
||||||
|
|
||||||
|
在折腾我的Gitea CI/CD管线的时候我,我尝试进行一项重要的变更:在运行CI任务时,任务中的容器支持从Docker out of Docker(DoD)迁移到Podman inside Podman(PiP)。但是在执行该项迁移的过程中,我遇到了如下一个非常神秘的Bug。
|
||||||
|
|
||||||
|
在CI任务运行的过程中,我发现一些**特定的**、**稳定的**域名无法在任务容器中正常解析并请求。目前注意到的域名有如下两个:
|
||||||
|
|
||||||
|
- dot.net
|
||||||
|
- rcj.bupt-hpc.cn
|
||||||
|
|
||||||
|
在容器内使用`curl http://dot.net -vvvvi`时,日志中重复出现如下内容。
|
||||||
|
|
||||||
|
```
|
||||||
|
10:35:43.261007 [0-x] == Info: [MULTI] [INIT] added to multi, mid=1, running=1, total=2
|
||||||
|
10:35:43.261252 [0-x] == Info: [MULTI] [INIT] multi_wait(fds=1, timeout=0) tinternal=0
|
||||||
|
10:35:43.261533 [0-x] == Info: [MULTI] [INIT] -> [SETUP]
|
||||||
|
10:35:43.261690 [0-x] == Info: [MULTI] [SETUP] -> [CONNECT]
|
||||||
|
10:35:43.261838 [0-x] == Info: [READ] client_reset, clear readers
|
||||||
|
10:35:43.262042 [0-0] == Info: [MULTI] [CONNECT] [CPOOL] added connection 0. The cache now contains 1 members
|
||||||
|
10:35:43.262315 [0-0] == Info: [DNS] init threaded resolve of rcj.bupt-hpc.cn:9090
|
||||||
|
10:35:43.262597 [0-0] == Info: [DNS] resolve thread started for of rcj.bupt-hpc.cn:9090
|
||||||
|
10:35:43.262854 [0-0] == Info: [MULTI] [CONNECT] [TIMEOUT] set ASYNC_NAME to expire in 1000ns
|
||||||
|
10:35:43.263081 [0-0] == Info: [MULTI] [CONNECT] -> [RESOLVING]
|
||||||
|
10:35:43.263254 [0-0] == Info: [MULTI] [RESOLVING] multi_wait pollset[fd=4 IN], timeouts=1
|
||||||
|
10:35:43.263500 [0-0] == Info: [MULTI] [RESOLVING] [TIMEOUT] ASYNC_NAME expires in 355ns
|
||||||
|
10:35:43.263743 [0-0] == Info: [MULTI] [RESOLVING] multi_wait(fds=2, timeout=1) tinternal=1
|
||||||
|
10:35:43.265041 [0-0] == Info: [DNS] Curl_resolv_check() -> 0, missing
|
||||||
|
10:35:43.265218 [0-0] == Info: [MULTI] [RESOLVING] multi_wait pollset[fd=4 IN], timeouts=1
|
||||||
|
10:35:43.265497 [0-0] == Info: [MULTI] [RESOLVING] [TIMEOUT] ASYNC_NAME expires in 1545ns
|
||||||
|
10:35:43.265736 [0-0] == Info: [MULTI] [RESOLVING] multi_wait(fds=2, timeout=2) tinternal=2
|
||||||
|
10:35:43.268052 [0-0] == Info: [DNS] Curl_resolv_check() -> 0, missing
|
||||||
|
10:35:43.268236 [0-0] == Info: [MULTI] [RESOLVING] multi_wait pollset[fd=4 IN], timeouts=1
|
||||||
|
10:35:43.268471 [0-0] == Info: [MULTI] [RESOLVING] [TIMEOUT] ASYNC_NAME expires in 3582ns
|
||||||
|
10:35:43.268688 [0-0] == Info: [MULTI] [RESOLVING] multi_wait(fds=2, timeout=4) tinternal=4
|
||||||
|
```
|
||||||
|
|
||||||
|
## 初步假设与排除过程
|
||||||
|
|
||||||
|
这个问题非常奇怪,在问题排查初期,我进行了如下的操作。
|
||||||
|
|
||||||
|
1. 首先单独测试容器中的域名解析,使用`dig rcj.bupt-hpc.cn`进行解析测试,解析的结果符合预期,使用的DNS服务器是当前的容器的Podman网关地址10.17.14.1。
|
||||||
|
2. 独立启动容器,而不是使用CI管线启动的容器,使用`podman run --rm -it --privileged ccr.ccs.tencentyun.com/jackfiled/runner-base:latest bash -l`创建容器,对上述出现问题的两个域名上的服务进行请求,没有问题,排除镜像本身的问题。
|
||||||
|
|
||||||
|
此时已经束手无策了,遂尝试AI辅助进行排查。
|
||||||
|
|
||||||
|
## AI辅助下的问题排查
|
||||||
|
|
||||||
|
### dig工具和libc的解析机制之前存在差异
|
||||||
|
|
||||||
|
AI首先提到,上面测试的dig工具和其他应用使用的libc解析机制之间存在差异:
|
||||||
|
|
||||||
|
- `dig` 是直接使用 DNS 协议向 DNS 服务器发查询请求(绕过系统的解析器)。
|
||||||
|
- `curl`(以及大多数应用)依赖系统 C 库(如 glibc)的 `getaddrinfo()` 函数,它会读取 `/etc/nsswitch.conf` 和 `/etc/resolv.conf`,并可能使用 `systemd-resolved`、`nscd` 等服务。
|
||||||
|
|
||||||
|
于是需要使用`getent`工具测试libc库的DNS解析是否存在问题,测试发现解析结果正常。
|
||||||
|
|
||||||
|
### IPv6 优先导致超时或失败
|
||||||
|
|
||||||
|
AI还提到,如果系统尝试先用 IPv6 解析(AAAA 记录),但网络不支持 IPv6,可能导致 `curl` 卡住或失败,而 `dig` 默认查 A 记录。
|
||||||
|
|
||||||
|
于是在使用`curl`时手动指定使用的网络协议,的确当使用`curl -4 http://dot.net`时可以正常的完成请求。
|
||||||
|
|
||||||
|
虽然这一方法可以解决问题,但是其给出的理由似乎无法解释我遇到的问题,问题域名中的rcj.bupt-hpc.cn并没有任何的AAAA解析记录,执行 `getent ahosts rcj.bupt-hpc.cn` 仅返回 IPv4 地址,无 AAAA 记录,说明系统解析器未返回 IPv6 地址,`curl -4` 的成功不能用IPv6解释。
|
||||||
|
|
||||||
|
### DNS服务器
|
||||||
|
|
||||||
|
在尝试AI给出的几个建议之后,我也开始尝试修改容器内的DNS服务器,进行这个尝试是因为我发现,使用`podman run`启动容器时,容器内部使用的DNS服务器是10.3.9.4这一主机使用的DNS服务器,而在CI管线中启动的容器使用的DNS服务器是172.17.14.1这一容器网关。
|
||||||
|
|
||||||
|
于是在CI启动的容器中,我通过直接写入`/etc/resolv.conf`文件的方式修改DNS服务器为10.3.9.4,在修改之后,针对两个域名的网络请求就恢复了正常。
|
||||||
|
|
||||||
|
在将上述的新发现同步给AI之后,AI又给出了一些新的思路。
|
||||||
|
|
||||||
|
### c-ares 异步 DNS 解析器兼容性问题?
|
||||||
|
|
||||||
|
- 某些编译版本的 `curl`(尤其是 Alpine、某些容器镜像)会链接 `c-ares` 库,**绕过 glibc 的 `getaddrinfo`**,直接读取 `/etc/resolv.conf` 并发 DNS 请求。
|
||||||
|
- `c-ares` **不读取 `/etc/nsswitch.conf`**,也不支持 mDNS、systemd-resolved 等机制。
|
||||||
|
- 如果 `/etc/resolv.conf` 中的 nameserver(如 `172.17.14.1`)对 **某些域名响应异常**(如超时、截断、不响应 UDP 包),`c-ares` 会卡住。
|
||||||
|
|
||||||
|
但是按照AI提供的步骤进行排查:
|
||||||
|
|
||||||
|
- `curl --version` 输出中**未包含 `c-ares`**;
|
||||||
|
- curl 使用 glibc 的 `getaddrinfo()` 或 libcurl threaded resolver;
|
||||||
|
- **结论**:非 c-ares 导致。
|
||||||
|
|
||||||
|
### UDP DNS 响应截断(>512 字节)?
|
||||||
|
|
||||||
|
- `c-ares` 默认使用 **UDP** 查询 DNS。
|
||||||
|
- 如果 Podman 的内置 DNS 代理(通常是 `netavark` + `aardvark-dns` 或旧版 `dnsmasq`)在处理 **特定域名** 的 UDP 请求时:
|
||||||
|
- 响应过大导致 UDP 截断(TC=1),但 `c-ares` 未自动重试 TCP;
|
||||||
|
- 或代理本身 bug 导致丢包;
|
||||||
|
- 则 `c-ares` 会认为“无响应”,返回“missing”。
|
||||||
|
|
||||||
|
而 `dig` 默认使用 UDP,但**当 TC=1时会自动使用TCP重试**,所以成功,而你的域名 `rcj.bupt-hpc.cn` 可能有较多 CNAME 或 TXT 记录,导致 UDP 响应超 512 字节。
|
||||||
|
|
||||||
|
但是我清楚的知道域名 `rcj.bupt-hpc.cn` 仅有一条 A 记录,DNS 响应极小,`dig` 与 `getent` 均能快速返回结果。
|
||||||
|
|
||||||
|
## AI Conclusion:Podman 内置 DNS 代理(aardvark-dns)行为异常
|
||||||
|
|
||||||
|
Podman 4.5.2 默认使用 **aardvark-dns** 作为容器网络的 DNS 代理,监听于网关地址(如 `172.10.0.1`)。其职责包括:
|
||||||
|
|
||||||
|
- 解析容器名称(服务发现);
|
||||||
|
- 转发外部域名查询至上层 DNS。
|
||||||
|
|
||||||
|
可能的故障点包括:
|
||||||
|
|
||||||
|
1. aardvark-dns 对特定域名后缀(如 `.bupt-hpc.cn`)的转发逻辑存在缺陷;
|
||||||
|
2. 响应格式不符合 glibc 或 libcurl 的预期(如缺少 AA 标志、TTL 异常);
|
||||||
|
3. 首次查询存在延迟或丢包,而 libcurl threaded resolver 未充分重试;
|
||||||
|
4. 与宿主机 `/etc/resolv.conf` 中的 `search` 域交互异常,导致拼接错误查询。
|
||||||
|
|
||||||
|
尽管 `dig` 能获取结果,但 `dig` 具有更强的容错性和自动重试机制(如 TC=1 时切 TCP),而 libcurl 的 resolver 更严格。
|
||||||
|
|
||||||
|
> 对于AI的这个结果,说实话我表示怀疑,我感觉还是和IPv6有关系,这样才能同时解释`curl -4`和更换DNS都可以运行的现象。
|
||||||
|
|
||||||
|
## 临时缓解
|
||||||
|
|
||||||
|
最终,我在CI启动容器的配置选项中添加`--dns 10.3.9.4`,不使用Podman启动的DNS服务器,暂时绕过了这个问题。
|
||||||
|
|
||||||
|
不过这个问题并没有从本质上得到解决,甚至都还不知道背后的具体问题是什么,感觉会在后面攻击我,特此记录。
|
||||||
Reference in New Issue
Block a user