由于客户的IT系统大多都运行在Redhat或Centos系统下,所以我们在将应用做容器化时,也选择了基于Centos来做基础镜像。制作镜像时,为了方便后面运维管理,基础镜像中想添加基本的工具软件,以及中文的支持。
初试生成镜像
在第一版Dockerfile中,按照了glibc-common,设置了中文环境变量:
FROM centos:7
RUN yum update -y && \
yum reinstall -y glibc-common
ENV LANG=zh_CN.UTF-8 \
LANGUAGE=zh_CN:zh \
LC_ALL=zh_CN.UTF-8
....
原本在一般服务器上设置了环境变量就OK了,结果这次在登录进容器的时候,出现了如下警告:
bash: warning: setlocale: LC_ALL: cannot change locale (zh_CN.UTF-8)
同时,在使用locale -a命令时,会有如下提示:
locale: Cannot set LC_CTYPE to zh_CN.UTF-8: No such file or directory
locale: Cannot set LC_MESSAGES to zh_CN.UTF-8: No such file or directory
locale: Cannot set LC_COLLATE to zh_CN.UTF-8: No such file or directory
POSIX
C
看提示信息,应该是缺少相应支持的locale文件(网上也有很多说法,比如要安装chinese-support、Font、kde-l10n-Chinese等,这些在Centos7上都不好使)。
对locale的说明
这个要从系统locale的设定说起,locale直接翻译是地域的意思,它是根据计算机用户所使用的语言,所在的国家或地区,以及当地的文化传统所定义的一个软件运行时的语言环境。locale组成包括语言(Language), 地域 (Territory) 和字符集(Codeset),它的书写方式是“语言_地域.字符集”,例如:zh_CN.UTF-8,指语言为中文,地域为中华人民共和国,使用UTF-8字符集。
locale的定义文件放在/usr/share/i18n/locales目录下面,这些文件都是文本格式的,可以直接查看,比如,zh_CN文件的内容是这样的:
comment_char %
escape_char /
%
% Chinese language locale for the Peoples Republic of China
%
% This work is based on ISO PDTR 14652, Unicode 3.0, locale definition
% file for zh_CN revision 1.0 (hashao@china.com, 1999-04-28) and
% charmap file for GBK version 1.0 (sean.chen@turbolinux.com).
%
% The file is designed to work with multiple charsets. To ease the
% maintance and adding support for new charsets, all characters are
% in UCS notation and presented in Unicode order.
%
% Changelog:
% Tue Jul 25 2000 Yong Li <rigel863@hotmail.com>
% - first version for glibc 2.2
LC_IDENTIFICATION
title "Chinese locale for Peoples Republic of China"
source ""
address ""
contact ""
email "bug-glibc-locales@gnu.org"
tel ""
fax ""
language "Chinese"
territory "P.R. of China"
revision "0.1"
date "2000-07-25"
%
category "zh_CN:2000";LC_IDENTIFICATION
category "zh_CN:2000";LC_CTYPE
category "zh_CN:2000";LC_COLLATE
category "zh_CN:2000";LC_TIME
category "zh_CN:2000";LC_NUMERIC
category "zh_CN:2000";LC_MONETARY
这里面的文件对应的是locale定义中“.”之前的部分,也就是区域和语言,后半部分字符集映射信息位于/usr/share/i18n/charmaps目录中,也可以通过“locale -m”命令来查看。当然,这些并不是系统中能用的字符集,只能算是可用的字符集。由于Linux中包含的字符集和语言种类很多,而用户一般用到的很有限,没必要把所有的都集成到系统里。如果需要使用某种字符集和语言,需要使用/usr/share/i18n中的原始文件进行定义,类似于编译的过程,定义完的语言环境文件存放在/usr/lib/locale/locale-archive中。
定义语言环境可以使用localedef命令,比如定义zh_CN.UTF-8,则可以使用:
localedef -c -f UTF-8 -i zh_CN zh_CN.UTF-8
另外,localedef的完整帮助说明如下:
[root]# localedef --help
用法: localedef [选项...] 名称
或: localedef [选项...]
[--add-to-archive|--delete-from-archive] 文件...
或: localedef [选项...] --list-archive [文件]
编译区域规范
输入文件:
-f, --charmap=FILE Symbolic character names defined in FILE
-i, --inputfile=FILE 在 FILE 中找到源定义
-u, --repertoire-map=FILE FILE contains mapping from symbolic names to UCS4
values
输出控制:
-c, --force 即使出现警告消息也创建输出
--old-style 创建旧风格表格
--posix 严格遵循 POSIX
--prefix=PATH 可选的输出文件前缀
--quiet 关闭警告和信息消息
-v, --verbose 打印更多消息
归档控制:
--add-to-archive
将由参数命名的区域添加到归档文件中
-A, --alias-file=FILE 在制作归档文件时参考 locale.alias
文件
--delete-from-archive 从归档文件中删除由参数命名的区域
--list-archive 列出归档文件的内容
--no-archive 不要将新数据添加到归档文件中
--replace 替换现有的归档文件内容
-?, --help 给出该系统求助列表
--usage 给出简要的用法信息
-V, --version 打印程序版本号
长选项的强制或可选参数对对应的短选项也是强制或可选的。
System's directory for character maps : /usr/share/i18n/charmaps
repertoire maps: /usr/share/i18n/repertoiremaps
locale path : /usr/lib/locale:/usr/share/i18n
For bug reporting instructions, please see:
<http://www.gnu.org/software/libc/bugs.html>.
完整Dockerfile
至此,可以基于以上方法,制作一个支持中文环境的Centos7镜像,完成的Dockerfile如下:
FROM centos:7
ENV LANG=zh_CN.UTF-8 \
LANGUAGE=zh_CN:zh \
LC_ALL=zh_CN.UTF-8
# Install tools
RUN yum update -y && \
yum reinstall -y glibc-common && \
yum install -y telnet net-tools && \
yum clean all && \
rm -rf /tmp/* rm -rf /var/cache/yum/* && 、
localedef -c -f UTF-8 -i zh_CN zh_CN.UTF-8 && \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
# Define default command.
CMD ["bash"]