- 云原生
- 操作系统
- 容器编排
【免费下载链接】talos
Talos Linux is a modern Linux distribution built for Kubernetes.
StaticHostConfig 是 Talos Linux 提供的配置文档(config document)类型,用于在节点的/etc/hosts中注入自定义的 IP 与主机名映射,例如把内部服务域名固定指向特定地址。本文基于 v1.15 参考文档并结合仓库源码,讲解该文档的 YAML 语法、字段校验规则、底层实现链路(从配置文档到network.StaticHost资源、再到进程内 DNS 与/etc/hosts渲染),帮助你准确、可复用地配置节点级静态主机解析。
StaticHostConfig 文档是什么
在 Talos Linux 中,机器配置既可以是传统的v1alpha1大文档,也可以拆分为多个独立的配置文档(config documents),每个文档拥有独立的apiVersion与kind,便于按功能模块单独维护。StaticHostConfig 参考文档 的开头明确说明:
StaticHostConfig is a config document to set /etc/hosts entries.
它的作用就是在节点的/etc/hosts中写入静态映射条目。其典型应用场景包括:
- 将集群内部服务名(如
my-server.example.org)固定解析到某个内网 IP,避免依赖外部 DNS; - 为没有 DNS 记录的裸机或边缘节点提供稳定的名称解析;
- 在 KubeSpan、SideroLink 等网络环境下,为主机名提供确定性的地址映射。
YAML 语法与字段说明
参考文档给出了完整的配置示例,一个最小的 StaticHostConfig 文档如下:
apiVersion: v1alpha1 kind: StaticHostConfig name: 10.5.0.2 # IP address (IPv4 or IPv6) to map the hostnames to. # List of hostnames to map to the IP address. hostnames: - my-server - my-server.example.org其中字段定义如下:
| Field | Type | Description | Value(s) |
|---|---|---|---|
name | string | IP address (IPv4 or IPv6) to map the hostnames to. | 任意合法的 IPv4 或 IPv6 地址 |
hostnames | []string | List of hostnames to map to the IP address. | 任意合法主机名列表,至少一个 |
文档结构与字段解析
在源码层,该文档由 static_host.go 中的StaticHostConfigV1Alpha1结构体定义,并通过init()注册进配置文档注册表(registry.Register(StaticHostKind, ...)),其中StaticHostKind = "StaticHostConfig":
type StaticHostConfigV1Alpha1 struct { meta.Meta `yaml:",inline"` // description: | // IP address (IPv4 or IPv6) to map the hostnames to. // schemaRequired: true MetaName string `yaml:"name"` // description: | // List of hostnames to map to the IP address. Hostnames []string `yaml:"hostnames"` }从结构体注释(schemaRequired: true)可以看出,name字段是必填的。同时该结构体实现了config.NamedDocument、config.Validator与config.NetworkStaticHostConfig三个接口,config.NetworkStaticHostConfig接口定义在 network.go 中,仅包含两个方法:
type NetworkStaticHostConfig interface { IP() string Aliases() []string }IP()返回MetaName(即文档的name),Aliases()返回Hostnames列表,这正是后续网络控制器读取该文档的唯一入口。
字段校验规则(Validate)
StaticHostConfigV1Alpha1实现了config.Validator接口,其Validate方法(见 static_host.go)会对文档做三项校验:
if s.MetaName == "" { errs = errors.Join(errs, errors.New("name is required")) } if _, err := netip.ParseAddr(s.MetaName); err != nil { errs = errors.Join(errs, errors.New("name must be a valid IP address")) } if len(s.Hostnames) == 0 { errs = errors.Join(errs, errors.New("at least one hostname is required")) }即:
name不能为空,否则报错name is required;name必须能通过netip.ParseAddr解析,即必须是合法的 IPv4 或 IPv6 地址(如10.5.0.2、fd00::1),否则报错name must be a valid IP address;hostnames至少包含一个条目,否则报错at least one hostname is required。
这些校验规则在单元测试 static_host_test.go 的TestHostConfigValidate中被逐一验证,包括 "empty"、"invalid ip"、"no hostnames"、"valid" 四个用例。测试还通过TestStaticHostMarshalStability保证了文档序列化输出的稳定性,期望输出与测试数据 testdata/statichostconfig.yaml 完全一致:
apiVersion: v1alpha1 kind: StaticHostConfig name: 10.5.0.2 hostnames: - example.org - example.com从配置文档到 /etc/hosts:底层实现链路
StaticHostConfig 并不是简单地被"写死"进/etc/hosts,而是通过 Talos 的 COSI(Controller Runtime)体系经历一条完整的处理链路,最终同时作用于进程内 DNS 服务与/etc/hosts 文件两个出口。
1. StaticHostController:配置到资源的翻译
internal/app/machined/pkg/controllers/network/static_host.go 中的StaticHostController负责将机器配置中的NetworkStaticHostConfig(即 StaticHostConfig 文档)以及节点自身的 hostname/FQDN 与地址,翻译成network.StaticHost资源:
- 输入(Inputs):监听活动机器配置(
config.MachineConfigType/ActiveID)、节点主机名状态(network.HostnameStatusType)和当前节点地址(network.NodeAddressCurrentID); - 输出(Outputs):独占产出
network.StaticHostType(StaticHosts.net.talos.dev)资源,资源 ID 即主机名(别名),spec 中保存该名字对应的地址列表。
在reconcile过程中,控制器遍历cfg.Config().NetworkStaticHostConfig(),对每个条目执行netip.ParseAddr(entry.IP())解析地址(解析失败会跳过该条目,注释说明 etcfile 渲染接受原始字符串,但 DNS 需要可解析的地址),并将每个别名(alias)与 IP 关联起来:
for _, entry := range cfg.Config().NetworkStaticHostConfig() { addr, parseErr := netip.ParseAddr(entry.IP()) if parseErr != nil { continue // 跳过非法条目 } for _, alias := range entry.Aliases() { name := normalizeHostName(alias) if name == "" { continue } hosts[name] = append(hosts[name], addr) } }normalizeHostName会将主机名转为小写并去除结尾的点号(.TrimRight(TrimSpace(name), ".")),因为 DNS 主机名不区分大小写,统一小写存储可以让 DNS handler 在查询时无需逐个归一化。
除此之外,控制器还会自动把节点自身的 hostname 与 FQDN 映射到当前节点地址:
if hostnameStatus != nil && nodeAddresses != nil { names := []string{ normalizeHostName(hostnameStatus.TypedSpec().Hostname), normalizeHostName(hostnameStatus.TypedSpec().FQDN()), } // ... 将 nodeAddresses 的 IP 追加到 hosts[name] }即除了你显式配置的映射外,节点的本机名解析也会被自动纳入静态主机表。最后通过dedupSortAddrs对地址去重排序后写入资源,并CleanupOutputs清理已删除的条目。
network.StaticHost资源本身定义在 pkg/machinery/resources/network/static_host.go,其 spec 仅包含Addresses []netip.Addr,并支持通过talosctl get statichosts查看(PrintColumns 输出Addresses列)。
2. 进程内 DNS:StaticHostHandler
internal/pkg/dns/static_host.go 中的StaticHostHandler是 CoreDNS 插件链中的一个 handler,它位于NodeHandler/Handler之前,保证静态配置的条目永远优先于上游解析(注释原文:statically configured entries always win against upstream resolution)。
其工作方式:收到 DNS 请求后,仅处理Qtype为 A 或 AAAA 的查询(q.Qtype == dns.TypeA || q.Qtype == dns.TypeAAAA),然后通过HostMapper.ResolveAddr在静态表中查找名字;命中则直接以dns.RcodeSuccess返回Authoritative = true的应答,未命中则转发给下一个 handler。
这意味着,只要配置了 StaticHostConfig,节点上通过 Talos 内置 DNS 解析该主机名时,会直接命中静态表,而不会再去询问上游 DNS 服务器。
3. /etc/hosts 渲染:EtcFileController
internal/app/machined/pkg/controllers/network/etcfile.go 负责将静态主机条目(连同系统默认的 localhost、ip6 等条目)渲染进files.EtcFileSpec的hosts文件,测试用例 etcfile_test.go 展示了其输出格式,例如:
127.0.0.1 localhost 33.11.22.44 foo.example.com foo ::1 localhost ip6-localhost ip6-loopback ff02::1 ip6-allnodes ff02::2 ip6-allrouters 10.0.0.1 a b 10.0.0.2 c d也就是说,你在 StaticHostConfig 中配置的每个hostnames条目,都会以IP hostname1 hostname2 ...的形式出现在/etc/hosts中,供所有依赖/etc/hosts的应用使用。
配置与使用建议
- 放置位置:StaticHostConfig 作为独立配置文档,可追加在 Talos 机器配置(machine config)的文档列表末尾,或与其它配置文档一起通过
talosctl apply-config/talosctl machineconfig patch提交。 - IPv6 支持:
name同时支持 IPv4 与 IPv6(源码通过netip.ParseAddr解析,天然兼容两种地址族),例如name: fd00::1同样合法。 - 多别名共享同一 IP:
hostnames是列表,允许为同一个 IP 配置多个名称(短名 + 完整域名),渲染时它们会出现在/etc/hosts的同一行。 - 覆盖优先级:静态条目在进程内 DNS 中优先级最高(
StaticHostHandler位于处理器链最前),因此适合用来"钉死"某些关键域名,避免被上游 DNS 干扰。 - 配置校验:提交前建议本地校验,
name必须是合法 IP、hostnames不能为空,否则talosctl会直接报出对应错误信息(与 static_host.go 中定义的错误文案一致)。
总结
StaticHostConfig 以最小化的 YAML 语法(name+hostnames两个字段)实现了节点级静态主机解析的声明式配置:从配置文档经StaticHostController翻译为network.StaticHost资源,再到进程内 DNS(StaticHostHandler)与/etc/hosts(EtcFileController)双路生效。借助源码中的强校验与自动化测试,它可以安全、稳定地用于需要固定名称解析的 Kubernetes 节点与边缘场景。
- 云原生
- 操作系统
- 容器编排
【免费下载链接】talos
Talos Linux is a modern Linux distribution built for Kubernetes.
相关推荐
Talos Linux EtcFileConfig 配置指南:通过机器配置管理 /etc 下的用户文件
Talos Linux EtcFileConfig 配置指南:通过机器配置管理 /etc 下的用户文件 EtcFileConfig 是 Talos Linux
云原生操作系统容器编排Talos Linux KubeletConfig 配置指南:使用多文档配置自定义 kubelet
Talos Linux KubeletConfig 配置指南:使用多文档配置自定义 kubelet 导读 KubeletConfig 是 Talos Linux
云原生操作系统容器编排Talos Linux SideroLinkConfig 配置指南:连接 SideroLink API 的机器配置文档详解
Talos Linux SideroLinkConfig 配置指南:连接 SideroLink API 的机器配置文档详解 SideroLinkConfig 是
云原生操作系统容器编排
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考