Go开发的应用程序的一个优势在于,可以从"零"开始构建应用的Docker镜像,镜像中仅需要包含Go应用程序编译后的二进制文件,不需要额外安装其他执行环境。这样一来Go应用镜像占用的空间确实很小(通常是几MB),而且也会更安全些。常用的alpine镜像(alpine是专门为容器设计的小型Linux发行版)中存在一个安全漏洞,该漏洞为大量生产容器留下了空的root用户密码,所以如果你的的Go应用程序在没有alpine(或任何其他操作系统)的容器中运行,黑客就不能利用操作系统的漏洞去攻击容器里的应用。

使用Docker的多阶段构建,从头开始构建映像非常简单,上一期的文章《线上Go项目的Docker镜像应该怎么构建?》已经介绍了怎么从"scratch"基础镜像,使用多阶段构建制作Go应用程序的镜像。今天接着上期的话题继续说一个从零构建的应用镜像的容器时区设置的问题。

如果你的应用程序在初始化函数init里有设置时区的操作,那么在启动应用容器时会遇到下面这个运行时panic

unknown time zone Asia/Shanghai

如果你在应用程序里不显示地设置时区,应用容器确实是能正常启动的,只不过这样time包里的函数统一用的是UTC时区,等你发现问题时再在程序里去显示设置时区仍然会遇到上面的运行时错误。

下面我们来做个试验,看看上面说的问题的现象。

首先写一个简单的Go应用程序

package mainimport ("fmt""time"
)func main() {// 输出当前的时区fmt.Print("Local time zone ")fmt.Println(time.Now().Zone())fmt.Println(time.Now().Format("2006-01-02 15:04:05"))
}

然后写一个用来构建应用镜像的Dockerfile,使用的就是之前介绍的多阶段构建。

FROM golang:alpine as build
RUN apk --no-cache add tzdata
WORKDIR /app
ADD . /app
RUN CGO_ENABLED=0 GOOS=linux go build -o myappFROM scratch as finalCOPY --from=build /app/myapp .
ENV TZ=Asia/ShanghaiCMD ["/myapp"]

Dockerfile里,我们用ENV指令设置了TZ这个环境变量。Go运行时会查找TZ这个环境变量来设置自己的时区,上面我们把TZ设置成了Asia/Shanghai,接下来我们看看在容器里应用是不是能如期运行,输出正确的时区和时间。

➜  docker build -t go_timezone .➜  docker run --rm go_timezone
Local time zone UTC 0
2020-07-17 04:47:37

根据运行结果发现时区的设置并没生效。

Linux系统下Go运行时会从多个来源读取时区信息,在$GOROOT/src/time/zoneinfo.unix文件里能够找到Go运行时是从哪些地方读取时区信息的。

// Many systems use /usr/share/zoneinfo, Solaris 2 has
// /usr/share/lib/zoneinfo, IRIX 6 has /usr/lib/locale/TZ.
var zoneSources = []string{"/usr/share/zoneinfo/","/usr/share/lib/zoneinfo/","/usr/lib/locale/TZ/",runtime.GOROOT() + "/lib/time/zoneinfo.zip",
}

于是我就进到刚才镜像的容器里看了看,上面列的几个目录都没有找到。到这里算是定位到问题了,scratch镜像里并不包含这些时区文件。那么解决办法就是从build阶段的镜像里拷贝时区文件到最终的应用镜像。

FROM golang:alpine as build
RUN apk --no-cache add tzdata
WORKDIR /app
ADD . /app
RUN CGO_ENABLED=0 GOOS=linux go build -o myappFROM scratch as finalCOPY --from=build /app/myapp .
### 下面这行是新加的
COPY --from=build /usr/share/zoneinfo /usr/share/zoneinfo
ENV TZ=Asia/ShanghaiCMD ["/myapp"]

重新构建镜像、运行容器后就能发现时区设置已经正常了,Go运行时按照环境变量TZ里指定的时区打印了当前时间。

➜  docker image rm go_timezone
➜  docker run --rm go_timezone
Local time zone CST 28800
2020-07-17 13:12:18.206 CST

线上Go项目的Docker镜像应该怎么构建?

容器和虚拟机到底有啥区别?

Go原子操作和互斥锁的区别

❤️爱心三连

1.看到这里了就点个在看支持下吧,你的「在看」是我创作的动力。

2.关注公众号网管叨bi叨,「每周为您分享原创技术文章」!

3.特殊阶段,带好口罩,做好个人防护。

“在看转发”是最大的支持

容器化Go应用--基础镜像的未知时区问题相关推荐

  1. .NETCore 实现容器化Docker与私有镜像仓库管理

    一.Docker介绍 Docker是用Go语言编写基于Linux操作系统的一些特性开发的,其提供了操作系统级别的抽象,是一种容器管理技术,它隔离了应用程序对基础架构(操作系统等)的依赖.相较于虚拟机而 ...

  2. Docker容器化实战第二课 镜像、容器、仓库详解

    03 镜像使用:Docker 环境下如何配置你的镜像? 今天我将围绕 Docker 核心概念镜像展开,首先重点讲解一下镜像的基本操作,然后介绍一下镜像的实现原理.首先说明,咱们本课时的镜像均指 Doc ...

  3. Docker学习总结(36)——利用Google开源Java容器化工具Jib构建镜像

    一.前言 容器的出现让Java开发人员比以往任何时候都更接近"编写一次,到处运行"的工作流程,但要对Java应用程序进行容器化并非易事:你必须编写Dockerfile,以root身 ...

  4. JEECG容器化部署:Alpine镜像方式

    在前面的一篇文章中提到了JEECG的Alpine镜像使用时出现的问题,就是验证码需要使用到fontmanager,而环境中的OPENJDK的JRE中又没有提供,所以退而求其次使用官方的Dockerfi ...

  5. 阿里如何实现100%容器化镜像化?八年技术演进之路回顾

    八年时间,阿里集团实现了 100%内部容器化镜像化,经历了几代演进.本文将从最初的架构开始,向大家介绍下阿里内部的容器化演化过程. PouchContainer 现在服务于阿里巴巴集团和蚂蚁金服集团的 ...

  6. 阿里如何实现100%容器化镜像化?八年技术演进之路回顾 1

    八年时间,阿里集团实现了 100%内部容器化镜像化,经历了几代演进.本文将从最初的架构开始,向大家介绍下阿里内部的容器化演化过程. PouchContainer 现在服务于阿里巴巴集团和蚂蚁金服集团的 ...

  7. 阿里如何实现100%容器化镜像化?八年技术演进之路回顾(转)

    本文系转载.可以参考文中的以下内容: 阿里的容器框架的演进路线: 在大公司内部.跨多部门.并且已经有大量现有系统情况下的推广实施方案: 框架设计的方法论.设计图纸等. 八年时间,阿里集团实现了 100 ...

  8. 项目docker容器化部署步骤

    Docker在部署时的一些基本步骤(主要针对我公司的项目环境): 1.项目中存在不需要使用容器化的服务,所以请安装jdk7.redis.mq.zookeeper.dubbo控制台 2.镜像导入 #ca ...

  9. 容器化技术【Kubernetes】

    Kubernetes 主要内容 Kubernetes 架构 Kubernetes 集群搭建 Kubernetes 基础概念 Kubernetes 部署容器化应用 DashBoard 工具 Ingres ...

最新文章

  1. 青龙羊毛——闪电世界(合集篇)
  2. python怎么导入文件-Python文件如何引入?详解引入Python文件步骤
  3. .Net开源 Shuttle(飞梭)服务总线(ESB)入门
  4. c语言按行存储数据库,C语言实现按行读写文件
  5. vb设计一个由计算机,计算机VB程序的设计第一章.ppt
  6. 《复杂》读书笔记(part5)--复杂性度量
  7. 【Hbase】HBase分布式安装
  8. mysql主从同步 忽略库_主从复制中忽略库的参数
  9. RHCSA红帽认证考试题库--上午考试题
  10. 随机过程的概念以及统计特性(读书笔记)
  11. 阳春三月,再送32本书,快来快来!
  12. caniuse-lite is outdated. Please run next command `npm update`
  13. NS-3教程(2):NS-3简单介绍
  14. linux sqlplus 查询数据,Linux安装sqlplus及shell查询数据库
  15. 微信小程序自定义键盘|仿微信支付数字键盘
  16. hdu2191 买大米 多重背包 模板题
  17. Hadoop学习教程(MapReduce)(四)
  18. 2019年必看最新创意手机聊天界面设计
  19. 生源第一梯队来自清北,中科院这个研究所不简单
  20. C++ 获取时间戳:下周一、月初、月中、月末

热门文章

  1. Intel QuickAssist Technology and OpenSSL – Benchmarks and Setup Tips
  2. python开发学习记录
  3. 云场景实践研究第52期:畅游
  4. 一朵更好的云 MADE IN 青云QingCloud
  5. 2017年单多晶市场竞争核心分析
  6. 《C++编程惯用法——高级程序员常用方法和技巧》——2.7 Const
  7. scaleType属性设置!
  8. Json序列化空时间字段出异常
  9. Centos:Yum常用参数
  10. python库的学习系列之 13.2. ConfigParser — Configuration file parser