改进文件系统存储驱动以利用NFS功能¶
https://blueprints.launchpad.net/glance/+spec/improve-filesystem-driver
问题描述¶
Glance的文件系统后端可以将NFS共享挂载为本地文件系统,因此无需在Glance端存储任何特殊配置。Glance根本不关心NFS服务器地址或NFS共享路径,它只是假设每个镜像都存储在本地文件系统中。这种假设的缺点是Glance不知道NFS服务器是否已连接/可用,NFS共享是否已挂载,只是继续在本地文件系统目录上执行添加/删除操作,这可能会在NFS恢复在线时导致同步问题。
用例:在OpenStack Glance安装在OpenShift之上,并且NFS共享通过Volume/VolumeMount接口挂载的k8s环境中,如果NFS共享未准备好,Glance pod将无法启动。而如果NFS共享在Glance pod可用后不可用,则上传操作将失败并出现以下错误
sh-5.1$ openstack image create --container-format bare --disk-format raw --file /tmp/cirros-0.5.2-x86_64-disk.img cirros
ConflictException: 409: Client Error for url: https://glance-default-public-openstack.apps-crc.testing/v2/images/0ce1f894-5af7-44fa-987d-f4c47c77d0cf/file, Conflict
即使Glance Pod仍然处于运行状态,liveness和readiness探测开始失败,结果Glance Pod被标记为Unhealthy
Normal Started 12m kubelet Started container glance-api
Warning Unhealthy 5m24s (x2 over 9m24s) kubelet Liveness probe failed: Get "https://10.217.0.247:9292/healthcheck": net/http: request canceled (Client.Timeout exceeded while awaiting headers)
Warning Unhealthy 5m24s (x3 over 9m24s) kubelet Liveness probe failed: Get "https://10.217.0.247:9292/healthcheck": net/http: request canceled (Client.Timeout exceeded while awaiting headers)
Warning Unhealthy 5m24s kubelet Readiness probe failed: Get "https://10.217.0.247:9292/healthcheck": net/http: request canceled (Client.Timeout exceeded while awaiting headers)
Warning Unhealthy 4m54s (x2 over 9m24s) kubelet Readiness probe failed: Get "https://10.217.0.247:9292/healthcheck": net/http: request canceled (Client.Timeout exceeded while awaiting headers)
Warning Unhealthy 4m54s kubelet Readiness probe failed: Get "https://10.217.0.247:9292/healthcheck": net/http: request canceled (Client.Timeout exceeded while awaiting headers)
稍后,根据Pod设置的失败阈值,kubelet将Pod标记为Failed,我们可以看到失败,并且考虑到策略应该重新创建它
glance-default-single-0 0/3 CreateContainerError 4 (3m39s ago) 28m
$ oc describe pod glance-default-single-0 | tail
Normal Started 29m kubelet Started container glance-api
Warning Unhealthy 10m (x3 over 26m) kubelet Readiness probe failed: Get "https://10.217.0.247:9292/healthcheck": net/http: request canceled (Client.Timeout exceeded while awaiting headers)
Warning Unhealthy 10m kubelet Liveness probe failed: Get "https://10.217.0.247:9292/healthcheck": net/http: request canceled (Client.Timeout exceeded while awaiting headers)
Warning Unhealthy 10m kubelet Readiness probe failed: Get "https://10.217.0.247:9292/healthcheck": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
Warning Unhealthy 9m30s (x4 over 26m) kubelet Liveness probe failed: Get "https://10.217.0.247:9292/healthcheck": net/http: request canceled (Client.Timeout exceeded while awaiting headers)
Warning Unhealthy 9m30s (x5 over 26m) kubelet Liveness probe failed: Get "https://10.217.0.247:9292/healthcheck": net/http: request canceled (Client.Timeout exceeded while awaiting headers)
Warning Unhealthy 9m30s (x2 over 22m) kubelet Readiness probe failed: Get "https://10.217.0.247:9292/healthcheck": net/http: request canceled (Client.Timeout exceeded while awaiting headers)
Warning Unhealthy 9m30s (x3 over 22m) kubelet Readiness probe failed: Get "https://10.217.0.247:9292/healthcheck": net/http: request canceled (Client.Timeout exceeded while awaiting headers)
Warning Unhealthy 9m30s kubelet Liveness probe failed: Get "https://10.217.0.247:9292/healthcheck": context deadline exceeded (Client.Timeout exceeded while awaiting headers)
Warning Failed 4m47s (x2 over 6m48s) kubelet Error: context deadline exceeded
与其他部署(deployment != k8s)不同,即使NFS共享不可用,Glance服务仍会继续运行并从本地文件系统上传或删除数据。在这种情况下,我们可以肯定地说NFS共享不可用,Glance将无法在容器本地文件系统中上传任何镜像,并且Pod将被标记为失败并且无法重新创建。
提议的变更¶
我们计划在oslo.middleware中的healthcheckwsgi中间件中添加新的插件enable_by_files,该插件可用于所有OpenStack组件,如果所需的路径不存在,则报告503 <REASON>错误,如果一切正常则报告200 OK。
在Glance中,我们可以将此healthcheck中间件配置为glance-api-paste.ini中的应用程序
[app:healthcheck]
paste.app_factory = oslo_middleware:Healthcheck.app_factory
backends = enable_by_files (optional, default: empty)
# used by the 'enable_by_files' backend
enable_by_file_paths = /var/lib/glance/images/filename,/var/lib/glance/cache/filename (optional, default: empty)
# Use this composite for keystone auth with caching and cache management
[composite:glance-api-keystone+cachemanagement]
paste.composite_factory = glance.api:root_app_factory
/: api-keystone+cachemanagement
/healthcheck: healthcheck
如果一切正常,中间件将返回“200 OK”,否则将返回“503 <原因>”,并说明为什么不应该使用此 API。
“backends”将是“oslo.middleware.healthcheck”命名空间中的stevedore扩展的名称。
在Glance中,如果本地文件系统路径挂载在NFS共享上,我们建议在NFS共享中添加一个名为.glance的标记文件,然后使用该文件路径配置enable_by_fileshealthcheck中间件插件,如下所示
[app:healthcheck]
paste.app_factory = oslo_middleware:Healthcheck.app_factory
backends = enable_by_files
enable_by_file_paths = /var/lib/glance/images/.glance
如果NFS停止工作或以某种方式/healthcheck开始报告503 <REASON>,管理员可以采取适当的措施使NFS共享再次可用。
备选方案¶
为文件系统驱动程序引入一些配置选项,这将有助于检测NFS共享是否从Glance服务下方卸载。我们建议为同一目的引入以下新的配置选项
filesystem_is_nfs_configured - 布尔值,验证是否配置了NFS
filesystem_nfs_host - NFS服务器的IP地址
filesystem_nfs_share_path - 映射到本地文件系统的NFS挂载路径
filesystem_nfs_mount_options - 要传递给NFS客户端的挂载选项
rootwrap_config - 以root用户运行命令
如果设置了filesystem_is_nfs_configured,即如果配置了NFS,则部署者必须在glance-api.conf中指定filesystem_nfs_host和filesystem_nfs_share_path配置选项,否则相应的Glance存储将被禁用,并且不会用于任何操作。
我们计划使用现有的os-brick库(Glance_store的cinder驱动程序已经使用)来使用上述配置选项创建NFS客户端,并在服务初始化以及每次镜像上传/导入/删除操作之前检查NFS共享是否可用。如果在服务初始化期间NFS共享不可用,则将禁用添加和删除操作,但如果NFS之后停止工作,我们将向用户引发HTTP 410(HTTP GONE)响应。
Glance仍然没有能力在预先检查特定的NFS存储是否具有存储任何特定镜像的存储能力。它也没有能力验证在上传/导入操作期间是否发生网络故障。
数据模型影响¶
无
REST API 影响¶
无
安全影响¶
无
通知影响¶
无
其他最终用户影响¶
无
性能影响¶
无
其他部署者影响¶
需要为Glance配置healthcheck中间件。
开发人员影响¶
无
实现¶
负责人¶
- 主要负责人
abhishekk
- 其他贡献者
无
工作项¶
在oslo.middleware中添加enable_by_fileshealthcheck后端
记录如何配置enable_by_fileshealthcheck中间件
覆盖范围的单元/功能测试
依赖项¶
无
测试¶
单元测试
功能测试
Tempest 测试
文档影响¶
需要记录文件系统驱动程序的新行为,如果配置了NFS和healthcheck中间件。
参考资料¶
Oslo.Middleware 实现 - https://review.opendev.org/920055