Minio(官方docker版)容器部署时区问题研究记录

文章目录

  • 感慨&概述
    • 补充:MINIO_REGION和容器时间的关系
  • 问题一:minio容器和本地容器时间不一致
    • 问题说明
    • 原因探究
    • 解决方法
    • 结果验证
  • 问题二:minio修改时间和本地查询结果不一致
    • 具体问题
    • 原因探究
    • 解决办法
    • 时间转化工具类
    • 调用测试和验证
    • 上传文件说明

感慨&概述

  • 在使用minio(容器部署方式)的过程中,由于使用容器时间和本地时间不同,然后寻求解决方法,花费了很多时间,然后才有以下的收获和整理。整个过程耗费不少时间。
  • 本文章对于bitnami/minio:latestminio/minio问题二:minio修改时间和本地查询结果不一致上均适用。在问题一:minio容器和本地容器时间不一致bitnami/minio:latest在部署时,使用TZ=Asia/Shanghai即可解决问题。

补充:MINIO_REGION和容器时间的关系

  • region描述的是服务器的物理位置,默认是us-east-1(美国东区1),也是亚马逊S3的默认区域。可以通过MINIO_REGION环境变量进行修改
  • 修改MINIO_REGION并不能解决,容器时间和本地时间问题,也不能解决文件最后修改时间在web控制台和java查询时间不一致的问题。这个可能是为了minio容器部署时,划分机器用的(如果错误,请大佬指导)
  • 当然,注意如果设置了MINIO_REGION请在java代码中配置同样的时区设置,否则导致代码运行失败,因为时区相差太大无法正常连接到minio
  • 当启动MinIO Docker容器时,可以通过设置环境变量MINIO_REGION来指定区域(如无需要,建议不要配置)
docker run -p 9000:9000 --name minio1 \-e "MINIO_ROOT_USER=minioadmin" \-e "MINIO_ROOT_PASSWORD=minioadmin" \-e "MINIO_REGION=cn-north-1" \-e "TZ=Asia/Shanghai" \minio/minio server /data
  • java minioclient配置
@Configuration
public class Config {//链式编程 构建MinioClient对象@Beanpublic MinioClient minioClient(){return MinioClient.builder().region("cn-north-1") //注意一致.endpoint("http://192.168.1.18:9000").credentials("minioadmin","minioadmin").build();}
}

问题一:minio容器和本地容器时间不一致

问题说明

  • 使用的Minio容器版本为1Panel中应用商店提供的minio官方镜像版本minio/minio:RELEASE.2024-04-06T05-26-02Z
  • minio容器内查看时间,刚好和本机相差八小时
    bash-5.1# date 
    Sat May  4 15:58:36 CST 2024
    bash-5.1# exit
    exit
    [root@yang ~]# date
    2024年 05月 04日 星期六 23:58:43 CST
    

原因探究

  • 这里不再详述探究的过程,简略地给出研究思路、方法。
  • 研究思路:查看容器中使用的时区,将其修改为东八区。
  • 研究过程和结果:在该版本容器内查看没有常见的linux时区设置的目录和文件,不过通过复制本地的文件到,minio容器中重新设置时区,可以成功解决容器时区和本地时区不一致的问题。

解决方法

  1. 查看容器信息
    # 查看运行中minio容器的名称
    docker ps
    
    • 例如:运行中的MInio容器ID为 826ab07a0a42,名称为 minio
    [root@yang ~]# docker ps
    CONTAINER ID   IMAGE                                      COMMAND                   CREATED          STATUS          PORTS                                                                                  NAMES
    826ab07a0a42   minio/minio:RELEASE.2024-04-06T05-26-02Z   "/usr/bin/docker-ent…"   14 minutes ago   Up 14 minutes   0.0.0.0:9001->9000/tcp, :::9001->9000/tcp, 0.0.0.0:9000->9001/tcp, :::9000->9001/tcp   minio
    
  2. 进入容器创建时区文件目录
    # 进入容器 下面的两个命令任选其一即可
    # 命令一
    docker exec -it  docker_Minio_name bash # 上一步查询的信息 minio
    # 命令二
    docker exec -it  docker_Minio_ID bash # 上一步查询的信息 826ab07a0a42
    # 在容器内执行命令:创建时区文件目录
    mkdir -p  /usr/share/zoneinfo/Asia/
    # 推出容器命令
    exit
    
  3. 复制本地时区文件到容器
    # 复制本地的时区配置文件到容器中
    [root@localhost ~]# docker cp /usr/share/zoneinfo/Asia/Shanghai docker_Minio_name:/usr/share/zoneinfo/Asia/
    # 操作成功演示
    [root@yang ~]# docker cp /usr/share/zoneinfo/Asia/Shanghai minio:/usr/share/zoneinfo/Asia/
    Successfully copied 2.56kB to minio:/usr/share/zoneinfo/Asia/
    
  4. 再次进入容器内部,修改本地时间
    # 再次进入容器 下面的两个命令任选其一即可
    # 命令一
    docker exec -it  docker_Minio_name bash # 上一步查询的信息 minio
    # 命令二
    docker exec -it  docker_Minio_ID bash # 上一步查询的信息 826ab07a0a42# 定义本地的时区配置文件
    ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime  
    # 演示
    bash-5.1# ln -s /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
    

结果验证

  1. 使用命令查看容器和本机时间是否一致
    # 验证解决结果
    bash-5.1# date 
    Sat May  4 23:58:36 CST 2024
    bash-5.1# exit
    exit
    [root@yang ~]# date
    2024年 05月 04日 星期六 23:58:43 CST
    

  • Minio上传文件测试时间是否生效
  • 在观察页面显示正常,但是遗憾的是,如果使用java minio客户端查询还是显示相差八小时。(这是第二个问题)
    在这里插入图片描述

问题二:minio修改时间和本地查询结果不一致

具体问题

  • minio在web管理显示的文件最后修改时间和本地一致,然后使用java代码查询出来的时间和本地时间差八个小时
    在这里插入图片描述
  • 查询代码和结果
//查询代码
@Test
void testObjectExists() throws ServerException, InsufficientDataException, ErrorResponseException, IOException, NoSuchAlgorithmException, InvalidKeyException, InvalidResponseException, XmlParserException, InternalException {StatObjectResponse response = minioClient.statObject(StatObjectArgs.builder().bucket("test02").object("image.jpg").build());System.out.println(response);
}		
//查询结果
ObjectStat{bucket=test02, object=image.jpg, last-modified=2024-05-04T06:53:55Z, size=563102}

原因探究

  • MinIO存储文件的元数据时,通常会使用UTC(协调世界时间)来记录时间戳。这意味着无论实际的物理服务器位置如何,时间都会按照UTC来记录。但在Web管理界面中,MinIO会根据浏览器的时区设置自动调整显示时间,使其看起来与本地时间一致。
  • 当使用Java代码通过MinIO的API查询文件的最后修改时间时,如果没有正确处理时区,Java可能会默认将UTC时间作为本地时间(即不进行时区转换)来处理。导致看到的时间比实际的本地时间少8小时(中国大陆时间为UTC+8)。

解决办法

  • Java代码在处理时间时将UTC时间转换为本地时间(虽然麻烦,但只能这么解决问题)

时间转化工具类

  • 这里我给出一个已验证可用的工具类
import java.lang.annotation.Retention;
import java.time.Instant;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;public class TimeConverter {// 使用自定义格式化模式private static final DateTimeFormatter isoFormatter = new DateTimeFormatterBuilder().append(DateTimeFormatter.ISO_LOCAL_DATE).appendLiteral('T').append(DateTimeFormatter.ISO_LOCAL_TIME).optionalStart().appendOffsetId().optionalEnd().toFormatter();private static final DateTimeFormatter customFormatter = new DateTimeFormatterBuilder().append(DateTimeFormatter.ISO_LOCAL_DATE).appendLiteral('T').append(DateTimeFormatter.ISO_LOCAL_TIME).appendLiteral('Z') // 添加字面值 'Z' 表示时区偏移量.toFormatter();/*** 将UTC时间转换为指定时区的时间,格式保持ISO-8601 默认时区为东八区* @param utcTimeString UTC时间字符串(ISO-8601格式)* @return 指定时区的时间字符串(ISO-8601格式)*/public static String convertUtcToLocal(String utcTimeString) {String zoneIdString="Asia/Shanghai";return convertUtcToLocal(utcTimeString,zoneIdString);}/*** 将UTC时间转换为指定时区的时间,格式保持ISO-8601* @param utcTimeString UTC时间字符串(ISO-8601格式)* @param zoneIdString 时区ID,如"Asia/Shanghai"* @return 指定时区的时间字符串(ISO-8601格式)*/public static String convertUtcToLocal(String utcTimeString, String zoneIdString) {Instant utcTime = Instant.parse(utcTimeString);ZonedDateTime localTime = utcTime.atZone(ZoneId.of(zoneIdString));DateTimeFormatter formatter = customFormatter.withZone(ZoneId.of(zoneIdString));return formatter.format(localTime);}/*** 将本地时间转换为UTC时间* @param localTimeString 本地时间字符串(ISO-8601格式)* @param zoneIdString 时区ID,如"Asia/Shanghai"* @return UTC时间字符串(ISO-8601格式)*/public static String convertLocalToUtc(String localTimeString) {String zoneIdString="Asia/Shanghai";return convertLocalToUtc(localTimeString,zoneIdString);}/*** 将本地时间转换为UTC时间* @param localTimeString 本地时间字符串(ISO-8601格式)* @param zoneIdString 时区ID,如"Asia/Shanghai"* @return UTC时间字符串(ISO-8601格式)*/public static String convertLocalToUtc(String localTimeString, String zoneIdString) {ZonedDateTime localTime = ZonedDateTime.parse(localTimeString, customFormatter.withZone(ZoneId.of(zoneIdString)));Instant utcTime = localTime.toInstant();return isoFormatter.format(utcTime.atZone(ZoneId.of("UTC")));}// 测试主方法public static void main(String[] args) {String utcTime = "2024-05-07T04:20:00Z";System.out.println("原UTC时间: " + utcTime);System.out.println("转换为北京时间: " + convertUtcToLocal(utcTime));String shanghaiTime = "2024-05-20T20:20:00Z";System.out.println("从北京时间转换回UTC时间: " + convertLocalToUtc(shanghaiTime));}
}
  • 测试结果
    UTC时间: 2024-05-07T04:20:00Z
    转换为北京时间: 2024-05-07T12:20:00Z
    从北京时间转换回UTC时间: 2024-05-20T12:20:00Z
    

调用测试和验证

  • 测试类代码
    @SpringBootTest
    class MinioApplicationTests {@Resourceprivate MinioClient minioClient;/*** 判断文件是否存在*/@Testvoid testObjectExists() throws Exception {StatObjectResponse response = minioClient.statObject(StatObjectArgs.builder().bucket("test02").object("image.jpg").build());System.out.println("修改前文件信息:"+response);String localLastModifiedTime = TimeConverter.convertUtcToLocal(response.lastModified().toString());ZonedDateTime localLastModified = ZonedDateTime.parse(localLastModifiedTime);//通过反射 修改文件信息 不影响minio存储的文件信息try {Field lastModifiedField = response.getClass().getDeclaredField("lastModified");lastModifiedField.setAccessible(true);lastModifiedField.set(response, localLastModified);} catch (NoSuchFieldException | IllegalAccessException e) {e.printStackTrace();}System.out.println("修改后文件信息:"+response);}
    }
    
  • 测试结果
    修改前文件信息:ObjectStat{bucket=test02, object=image.jpg, last-modified=2024-05-04T06:53:55Z, size=563102}
    修改后文件信息:ObjectStat{bucket=test02, object=image.jpg, last-modified=2024-05-04T14:53:55Z, size=563102}
    

在这里插入图片描述

上传文件说明

  • 在查询文件信息时,需要将文件修改时间进行本地化转化,但是在上传文件的时候,我没找到直接设置文件修改时间的配置。所以,上传文件的时候,正常上传就行。
/*** 上传文件*/
@Test
void testObjectUpload() throws Exception {ObjectWriteResponse response = minioClient.uploadObject(UploadObjectArgs.builder().bucket("test02").object("image3.jpg").filename("src/main/resources/picture/image.jpg").build());System.out.println(response);
}
  • 上传成功后,在web控制台正常显示本地时间。查询时,使用工具类就可以了!
    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/685643.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

etcd单机部署和集群部署

1、etcd单实例部署 对于平常的学习,其实搭建一个单机节点是够了的。接下来就讲讲怎么搭建单机节点。 本次部署是在 centos7 系统,cpu 为amd64 上面进行的。 部署是直接使用官方编译好的二进制文件,大家也可以直接看 ectd-releases 界面选择…

有什么方便实用的黏土特效教程?6个软件教你快速进行特效制作

有什么方便实用的黏土特效教程?6个软件教你快速进行特效制作 作为时尚小达人,你自己是否想要制作出属于自己的黏土特效照片呢?比如下面几种。 看到这些黏土特效软件有没有心动,下面我也为大家详细的介绍一下可以制作出对应特效的…

邻域注意力Transformer

邻域注意力(NA),这是第一个高效且可扩展的视觉滑动窗口注意力机制,NA是一种逐像素操作,将自注意力(SA)定位到最近的相邻像素,因此与SA的二次复杂度相比,具有线性时间和空…

数据库被攻击后出现1044 - access denied for user ‘root‘@‘% ‘ to database table

MySQL数据库被攻击后,数据库全部被删除,并且加一个一个勒索的数据,向我索要btc, 出现这个问题就是我的数据库密码太简单了,弱密码,被破解了,并且把我权限也给修改了 导致我操作数据库时&#…

AI英语口语训练软件有哪些?这4款简单易用

AI英语口语训练软件有哪些?AI英语口语训练软件在现代语言学习中确实扮演着举足轻重的角色。它们凭借先进的智能算法,能够为我们量身定制学习方案,精准识别并纠正发音错误,模拟真实对话场景,使学习过程更加高效、有趣。…

【动态规划】子序列问题

最长上升子序列 题目描述: 解题思路: 核心思路: 用f[i]:表示以第i个数结尾的最大子序列,只需要找到比第i个小的最大子序列再加上1 即可; ----> f[i]max(f[j]1,f[i]); 定义 f[i] 表示以第 i 个元素结尾的最长上升子…

代码随想录算法训练营第36期DAY18

DAY18 二叉树的层序遍历 102二叉树的层序遍历 “队列先进先出,符合一层一层遍历的逻辑,而用栈先进后出适合模拟深度优先遍历也就是递归的逻辑。” 二叉树层序遍历模版: /** * Definition for a binary tree node. * struct TreeNode { *…

基于torch_dispatch机制生成Megatron-DeepSpeed调用关系图

基于torch_dispatch机制生成Megatron-DeepSpeed调用关系图 一.局部效果图二.运行训练过程,拦截算子,生成调用关系信息三.可视化,生成SVG图像 想知道Megatron-DeepSpeed训练过程中各模块之间的调用关系。torch_dispatch机制可以拦截算子,inspect又能获取到调用栈(文件,类名,函数…

《引爆流量获客技术》实操方法,手把手教你搭建盈利流量池

[1]-先导课.mp4 [2]-第1节:设计客户终身价值的方法和买客户思维.mp4 [3]-第2节:【渠道模型】解决谁是我的客户如何找到.mp4 [4]-第3节:【诱饵模型】解决 如何获得更多的客户.mp4 [5]-第4节:【钩子模型】解决让目标客户主动找你…

轮式机器人

迄今为止,轮子一般是移动机器人学和人造交通车辆中最流行的运动机构。它可达到很高的效率, 如图所示, 而且用比较简单的机械就可实现它的制作。 另外,在轮式机器人设计中,平衡通常不是一个研究问题。 因为在所有时间里,轮式机器人一般都被设计成在任何时间里所有轮子均与地接…

milvus元数据在etcd的存储解析

milvus元数据在etcd的存储解析 数据以key-value形式存在。 大致包含如下一些种类: databasecollectionfieldpartitionindexsegment-indexresource_groupsession database 创建一个数据库会产生2个key,但value是相同的。 key规则: 前缀/root-coord/database/db…

01.基本概念

操作系统 为什么要有操作系统? 计算机时一个十分复杂的系统,又cpu、内存、磁盘、IO设备、网络接口等等复杂的硬件组成,人的精力是有限的,不可能了解所有的硬件接口,但是程序可以。 所以我们在计算机上安装了一层软件&…