☰
Gophercloud 实战指南:使用 Go SDK 完成 OpenStack 认证与云资源编排
2026/9/28 3:40:50 网站建设 项目流程
  • 测试
  • 云原生
  • 质量保障

【免费下载链接】origin

Conformance test suite for OpenShift

项目地址:https://gitcode.com/gh_mirrors/or/origin
点击查看免费下载

本指南以 Gophercloud 官方 README 为核心,结合本仓库(OpenShift Conformance test suite 的origin镜像)中 vendored 的 Gophercloud 源码,系统讲解如何安装 SDK、准备 OpenStack 凭据、完成 Keystone 认证、创建服务客户端并编排云资源(如创建云服务器)。读完本文,你将掌握gophercloud与gophercloud/utils两种认证路径、ProviderClient与ServiceClient的底层工作方式,以及自动重认证、限流退避等高级行为的实现原理,可直接套用到自己的 Go 项目中。

什么是 Gophercloud

Gophercloud 是一个面向 OpenStack 的 Go SDK(官方定位为 "An OpenStack SDK for Go")。它把 OpenStack 各服务的 REST API 封装成 Go 类型与函数,让开发者可以用类型安全的 Go 代码完成认证、查询服务目录、创建/删除云资源等操作。

在当前仓库中,Gophercloud 以第三方依赖的形式被 vendored 在vendor/github.com/gophercloud/gophercloud/目录下,其顶层包包含认证选项(auth_options.go)、Provider 客户端(provider_client.go)、服务客户端(service_client.go)、端点搜索(endpoint_search.go)、分页(pagination/)等核心模块,openstack/子目录下则提供了各 OpenStack 服务(identity、compute、objectstorage 等)的实现。从 provider_client.go 中的DefaultUserAgent = "gophercloud/v1.14.1"可以看出,本仓库 vendored 的是 v1.14.1 版本。

如何安装

Gophercloud 与大多数 Go 库一样,通过标准 Go module 机制引入。在你的代码中引用任意 Gophercloud 包即可触发依赖解析:

import "github.com/gophercloud/gophercloud"

随后更新go.mod并拉取依赖:

go mod tidy

Gophercloud 的顶层包通常与其他包配合使用,常见组合是同时导入github.com/gophercloud/gophercloud/openstack(提供各服务客户端工厂函数)以及具体的服务资源包(如.../openstack/compute/v2/servers),具体用法见下文。

准备 OpenStack 凭据

因为要调用 OpenStack API,你首先需要获取自己的 OpenStack 凭据。官方推荐将凭据存放到clouds.yaml文件中,而不是写死在 Go 源码里——把凭据信息与源代码解耦后,你可以放心地把代码推送到版本控制系统而无需担心泄露。

需要准备的信息包括:

  • 一个有效的 Keystone identity URL(认证服务地址);
  • 凭据本身。可以是用户名/密码组合、一组 Application Credentials(应用凭据)、一个预生成的 token,或任何其他受支持的认证机制。

通过 Horizon 快速导出凭据

如果你部署了 OpenStack 仪表盘(Horizon),有一个快捷方式:访问project/api_access路径,点击右上角的 "Download OpenStack RC File" 按钮,即可下载两种格式的凭据文件:

  • clouds.yaml:结构化的 YAML 配置文件,包含全部访问细节。将其放到~/.config/openstack/clouds.yaml即可被 Gophercloud 生态的配置读取器识别;
  • openrc:一个 bash 脚本,执行source openrc会把所有访问细节导出为环境变量,随后会提示你输入密码。

需要说明的是:Gophercloud 核心库本身不直接解析clouds.yaml,该能力由配套库gophercloud/utils提供(见下文认证一节)。

认证:构建 ProviderClient

有了凭据之后,下一步是认证。Gophercloud 的认证由顶层 "Provider" 结构体——即ProviderClient——承担。ProviderClient是一个"顶级客户端",所有 OpenStack 服务客户端都由它派生而来,它内部保存了访问 API 所需的全部认证细节(如基础 URL 和 token ID)。

从 provider_client.go 的源码可以看到,ProviderClient的核心字段包括:

字段作用
IdentityBase身份服务的基础 URL,用于发起认证请求,应指向身份服务的根资源而非某个特定版本
IdentityEndpoint身份端点,可能是特定版本的身份服务;若指定了版本,将直接使用该端点而非先查询版本
TokenID最近一次签发的有效 token 的 ID;应用不应直接读写该字段,而应使用Token()/SetTokenAndAuthResult()
EndpointLocator描述如何从服务目录中为各服务发现端点
HTTPClient允许用户注入自定义的 http/https 传输行为
UserAgent请求中的 User-Agent 头(默认gophercloud/v1.14.1,可通过UserAgent.Prepend()追加自定义前缀)
ReauthFunc请求返回 401 时用于重新认证的函数,因为不同版本的身份服务可能有不同的认证函数
RetryBackoffFunc/MaxBackoffRetries限流(429)时的退避重试函数与最大重试次数(默认 60 次)
RetryFunc通用失败请求处理函数,请求失败后总会调用;置空则遇到错误直接中止

方式一:使用 gophercloud/utils(推荐)

github.com/gophercloud/utils 库提供clientconfig包来简化认证,其中包含读取clouds.yaml文件等附加能力。使用clientconfig生成 Provider 客户端:

import ( "github.com/gophercloud/utils/openstack/clientconfig" ) // 也可以跳过配置,改在环境中设置 'OS_CLOUD' opts := new(clientconfig.ClientOpts) opts.Cloud = "devstack-admin" provider, err := clientconfig.AuthenticatedClient(opts)

注意:clientconfig属于独立的gophercloud/utils仓库,本仓库 vendored 的gophercloud核心库并未包含该包,使用前需要单独引入。

方式二:不使用 gophercloud/utils

Gophercloud 核心库不提供clouds.yaml文件支持,如果你不想依赖gophercloud/utils,需要自行实现这部分功能。此时有两种方式填充认证选项:

import ( "github.com/gophercloud/gophercloud" "github.com/gophercloud/gophercloud/openstack" ) // 方式 1:手动传入认证信息 opts := gophercloud.AuthOptions{ IdentityEndpoint: "https://openstack.example.com:5000/v2.0", Username: "{username}", Password: "{password}", } // 方式 2:用工具函数从环境变量读取 opts, err := openstack.AuthOptionsFromEnv()

拿到opts后,传入openstack.AuthenticatedClient(opts)即可获得一个ProviderClient:

provider, err := openstack.AuthenticatedClient(opts)
AuthOptions 字段详解

gophercloud.AuthOptions(定义于 auth_options.go)是所有身份实现与 provider 字段的并集,常用字段如下:

字段说明
IdentityEndpoint身份 API 的 HTTP 端点,即云运营商常说的 "auth_url" /OS_AUTH_URL
Username/UserIDIdentity V2 需要 Username;Identity V3 需要 UserID 或 Username + DomainID/DomainName
Password密码
PasscodeTOTP 认证方法使用的动态口令
DomainID/DomainName使用 Username 配合 Identity V3 时,两者最多提供一个;否则均可选
TenantID/TenantNameV2 API 中的租户;在 V3 中对应 project_id / project_name(这里统一叫 Tenant),部分 provider 允许用名称代替 ID
AllowReauth为 true 时允许 Gophercloud 在内存中缓存凭据并在 token 过期时自动重新认证(默认 false)。注意:若不加以限制,重认证可能无限重试,官方建议通过自定义 RoundTripper 记录失败次数来限制
TokenID允许用既有 token(可能是他人身份)完成认证
Scope认证请求的作用域(AuthScope含ProjectID、ProjectName、DomainID、DomainName、System)
ApplicationCredentialID/ApplicationCredentialName/ApplicationCredentialSecretApplication Credentials 认证所需信息

从ToTokenV3CreateMap()的实现可以看出,认证时支持password、token、application_credential、totp等 identity method,并对各类组合做了严格校验(如 Username 与 UserID 不能同时提供、使用 Username 时 DomainID/DomainName 必须提供其一、ApplicationCredential 必须提供 Secret 等)。注意CanReauth()对 TOTP 口令返回 false,即 TOTP 认证不支持自动重认证。

从环境变量读取:AuthOptionsFromEnv

openstack/auth_env.go 中的AuthOptionsFromEnv()会读取标准的OS_*环境变量并填充AuthOptions:

  • 必填:OS_AUTH_URL、OS_USERNAME(或OS_USERID)、OS_PASSWORD,缺失会返回对应的ErrMissingEnvironmentVariable;
  • 可选:OS_PROJECT_ID、OS_PROJECT_NAME(OS_TENANT_ID、OS_TENANT_NAME是二者的废弃形式)、OS_DOMAIN_ID、OS_DOMAIN_NAME、OS_APPLICATION_CREDENTIAL_ID/NAME/SECRET、OS_PASSCODE、OS_SYSTEM_SCOPE;
  • 若设置了OS_PROJECT_NAME,还需要设置OS_PROJECT_ID,以处理不在默认 domain 下的 project;
  • OS_SYSTEM_SCOPE=all时会把 Scope 设为系统级(System: true)。

典型用法是先source openrc导出环境变量,再调用:

opts, err := openstack.AuthOptionsFromEnv() provider, err := openstack.AuthenticatedClient(opts)

ProviderClient 的认证流程

调用openstack.AuthenticatedClient(options)时(见 openstack/client.go),实际执行两步:

  1. NewClient(options.IdentityEndpoint):创建未认证的ProviderClient,规范化 URL 并填充IdentityBase/IdentityEndpoint,同时调用UseTokenLock()初始化并发安全的 token 锁;
  2. Authenticate(client, options):向端点发起认证请求,根据端点支持的版本自动选择 Keystone v2(优先级 20)或 v3(优先级 30,优先选择 v3),成功后将 token 与 service catalog 写入客户端。

认证成功后,ProviderClient会:

  • 记录 token,并通过AuthenticatedHeaders()在后续请求中自动附带X-Auth-Token头;
  • 设置EndpointLocator,后续各服务客户端依据服务目录(catalog)定位端点;
  • 若设置了AllowReauth,会构造一个"一次性客户端"(throw-away client,token 与 reauth 函数被清零),注册ReauthFunc——当某个请求收到 401 时,provider_client.go 中的Request()会自动调用Reauthenticate()重新认证并重放请求(同一请求只重认证一次,避免无限循环)。

创建服务客户端

有了基础 Provider 之后,将其作为依赖注入到各个 OpenStack 服务中。例如,要使用 Compute API,需要创建一个 Compute 服务客户端。使用clientconfig的方式:

client, err := clientconfig.NewServiceClient("compute", opts)

使用核心库的方式,通过openstack包的工厂函数创建:

client, err := openstack.NewComputeV2(provider, gophercloud.EndpointOpts{ Region: os.Getenv("OS_REGION_NAME"), })

openstack包为各服务提供了对应的工厂函数(均定义于 openstack/client.go),例如:

函数服务类型
NewComputeV2compute(Nova)
NewNetworkV2network(Neutron,端点后附加v2.0/)
NewObjectStorageV1object-store(Swift)
NewBlockStorageV1/V2/V3volume / volumev2 / volumev3(Cinder)
NewImageServiceV2image(Glance,附加v2/)
NewLoadBalancerV2load-balancer(Octavia)
NewDNSV2dns(Designate)
NewIdentityV2/V3identity(Keystone)
NewBareMetalV1/NewBareMetalIntrospectionV1baremetal / baremetal-introspection(Ironic)
NewSharedFileSystemV2sharev2(Manila)
NewKeyManagerV1key-manager(Barbican)
NewWorkflowV2、NewPlacementV1、NewCDNV1、NewDBV1、NewOrchestrationV1、NewClusteringV1、NewMessagingV2、NewContainerV1、NewContainerInfraV1等对应各类服务

EndpointOpts 与端点定位

工厂函数接收的gophercloud.EndpointOpts(定义于 endpoint_search.go)用于在服务目录中唯一确定一个端点:

字段必填说明
Type是服务类型(如 "compute"、"object-store"),一般由服务客户端函数自动填充
Name否服务名称(如 "nova")。服务可能同 Type 不同 Name,因此有时两者都需要
Region视情况端点所在的地理区域,仅对跨区域的服务必需
Availability否端点可见性:AvailabilityPublic(默认)/AvailabilityInternal/AvailabilityAdmin,对应 v2 的 publicURL/internalURL/adminURL 与 v3 的 Interface

ServiceClient 的使用

ServiceClient(service_client.go)封装了具体服务的基础 URL 与资源路径,提供Get、Post、Put、Patch、Delete、Head方法,最终都转发到ProviderClient.Request()。它还支持:

  • Microversion:设置服务微版本,请求时会自动附带对应的版本头(如 Nova 的X-OpenStack-Nova-API-Version)与通用的OpenStack-API-Version头;
  • MoreHeaders:为服务的所有请求统一附加 HTTP 头;
  • ServiceURL(parts...):按资源片段拼接完整 URL。

实战:创建一台云服务器(Provision a server)

使用上面创建的 Compute 服务客户端,即可执行任意 Compute API 操作。以创建新服务器为例,调用Create方法并传入 flavor ID(硬件规格)与 image ID(操作系统镜像):

import "github.com/gophercloud/gophercloud/openstack/compute/v2/servers" server, err := servers.Create(client, servers.CreateOpts{ Name: "My new server!", FlavorRef: "flavor_id", ImageRef: "image_id", }).Extract()

上述代码创建了一台带指定参数的新服务器,并把新资源体现在server变量中(一个servers.Server结构体)。Gophercloud 的请求/响应模型是"XxxOpts构造请求 +XxxResult承载响应":servers.Create返回CreateResult,调用其Extract()方法把响应体解析为强类型结构体;若Extract()返回的err非 nil,则表示创建失败。CreateOpts还支持Networks、SecurityGroups、UserData、Metadata等更多字段,具体定义可查阅 servers/requests.go。

高级用法:请求定制与自动重试

Gophercloud 的ProviderClient.Request()支持通过RequestOpts(provider_client.go)精细控制每一次 HTTP 请求:

字段说明
JSONBody/RawBody请求体,二选一:前者会被 JSON 编码(默认 Content-Type 为 application/json),后者直接消费一个io.Reader
JSONResponse非 nil 时,响应体会被解析为 JSON 并填充到该变量
OkCodes视为成功的 HTTP 状态码列表;不设置时按 HTTP 方法取默认值(GET/HEAD → 200,POST/PUT → 201/202,PATCH → 200/202/204,DELETE → 202/204)
MoreHeaders/OmitHeaders追加 / 移除请求头(OmitHeaders 优先于 MoreHeaders)
ErrorContext自定义错误类型,可根据状态码返回更具体的资源错误
KeepResponseBody保留响应体以便后续使用(不能与JSONResponse同时使用)

Request()的完整处理链(见doRequest)包括:编码请求体 → 组装请求头(Content-Type、Accept、User-Agent、X-Auth-Token)→ 发送请求 → 校验状态码 → 按需处理错误。当收到 401 时自动触发重认证并重放请求;收到 429/498(限流)时调用RetryBackoffFunc退避重试,最大次数受MaxBackoffRetries限制(未设置时取DefaultMaxBackoffRetries = 60);其他错误码(400/403/404/405/408/409/500/502/503/504)则映射为对应的ErrDefaultXxx错误类型,若设置了RetryFunc还会把失败交给它决定是否重试。

此外,Gophercloud 的pagination包(vendor/github.com/gophercloud/gophercloud/pagination/)提供Pager、LinkedPage、MarkerPage、SinglePage等分页工具,处理 OpenStack API 的列表类资源;openstack/utils目录下还有版本协商等辅助逻辑。原 README 还提到一份 FAQ 用于定制 Gophercloud 行为的技巧,不过该文件并未包含在本仓库的 vendored 树中,可按需从上游获取。

向后兼容性保证

Gophercloud 的版本号遵循 semver(语义化版本):

  • 在v1.0.0之前没有任何兼容性保证;
  • 自 v1 起,同一个 major 版本内不会引入破坏性变更(no breaking changes within a major release)。

这意味着在你的go.mod中以v1.x引入 Gophercloud 后,可以放心在 minor/patch 升级中保持代码兼容。上游的版本发布流程说明见其RELEASE.md(同样未随 vendored 树携带,可从上源获取)。

结语与进一步阅读

Gophercloud 把 OpenStack 复杂的 REST API 世界收敛为一套清晰的 Go 类型系统:AuthOptions负责认证信息,ProviderClient持有会话与 token,ServiceClient代表具体服务,XxxOpts/XxxResult构成资源的请求与响应模型。无论你是用clouds.yaml+gophercloud/utils的声明式配置,还是用OS_*环境变量 +AuthOptionsFromEnv()的经典方式,都能在几分钟内完成认证并开始操作云资源。

想深入源码细节,可在本仓库中直接阅读以下文件:

  • provider_client.go:Provider 客户端、认证头、自动重认证与退避重试实现;
  • openstack/client.go:各服务客户端工厂函数与 v2/v3 认证流程;
  • auth_options.go:认证选项字段与认证请求体构建逻辑;
  • openstack/auth_env.go:OS_*环境变量解析与校验;
  • service_client.go:服务客户端与微版本请求头;
  • openstack/compute/v2/servers/requests.go:Compute 服务资源操作(含CreateOpts)示例。
  • 测试
  • 云原生
  • 质量保障

【免费下载链接】origin

Conformance test suite for OpenShift

项目地址:https://gitcode.com/gh_mirrors/or/origin
点击查看免费下载
上一篇:如何快速掌握Mi-Create:免费创建小米手表个性化表盘的终极指南
下一篇:如何将PowerShell脚本转换为EXE:3分钟完成专业级程序封装

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询