亚马逊AWS官方博客

玩转 GPU 实例 – 我的 Linux 工具箱之二 – 基础设置  

前言

如果读过这个系列第一篇的朋友应该已经理解了如何简单快速的建立起来我们需要的GPU实例。我们应该已经可以通过ssh ubuntu@xxx.xxx.xxx.xxx 这样的方式连接到实例。 按照通常的习惯就要对我们新建的实例进行必要的设置,来满足我们使用上的需要。在AWS的官方文档“Amazon EC2用户指南”中已经包含了许多关于设置EC2实例的内容。不过考虑到目前EC2 实例的类别已经超过275种之多,而用户使用的操作系统版本也是千差万别,一份指南难以覆盖各个方面。我们还是有必要针对我们所选择的Ubuntu 18.04 这个版本下GPU 实例的设置来进行一些梳理。这一篇的内容围绕着实例的基础设置,涵盖了这样几个方面的内容:

 

1、安装设置AWS命令行工具(awscli)

2、设置系统时区(TimeZone)

3、设置NTP(网络时间协议)

4、设置 AmazonEC2 Instance Connect,这是一种简单安全的访问实例的方式

5、软件包安装的网络加速

 

设置AWSCLI的环境

AWS 命令行界面 (CLI) 是由AWS发布的用于管理 AWS 服务的统一工具。只通过一个工具进行下载和配置,使用者可以使用命令行控制AWS 服务并利用脚本来自动执行这些服务。在EC2实例中,awscli 工具并不是必须要安装的工具组件,但是如果我们需要在这台实例上进行针对AWS 服务进行操作的时候,尤其是以脚本化的方式来操作,你会发现这个工具会非常的强大而方便。事实上,我们创建EC2 实例使用的就是这个工具。以下内容即为安装、配置awscli的脚本。

 

#!/bin/bash

set-e

sudo apt-get install -y awscli

aws configure

if [ -f $HOME/.aws/config ];then

  cat <<'EOT' >> $HOME/.aws/config

s3 =

  max_concurrent_requests = 20

  max_queue_size = 10000

  multipart_threshold = 64MB

  multipart_chunksize = 16MB

  max_bandwidth = 50MB/s

  use_accelerate_endpoint = true

  addressing_style = path

EOT

fi

echo "Done."

其中,sudo apt-get install -y awscli 用于安装awscli 工具包。aws configure 用来进行交互式的配置awscli 所需要的几个重要参数。例如 :

$ aws configure

AWS Access Key ID [None]: XXXXXXXXXXX

AWS Secret Access Key [None]: XXXXXXXX

Default region name [None]: cn-northwest-1

Default output format [None]: text

 

关于这几个参数的,其具体的含义为 –

  • Aws_Access_key_ID – AWS用户凭据的AWS访问密钥部分
  • aws_Secret_Access_Key – AWS用户凭据的AWS秘密访问密钥部分
  • Default region name name – 缺省使用的AWS区域
  • Default output format – 缺省的输出格式 (textjsonyaml以及table 四种之一)

通常配置完成以后,用户凭据信息被保存在 ~/.aws/credentials 与文件中,而其它的设置项将保存在~/.aws/config 文件中。

 

至于脚本中s3 的配置部分则是用来优化s3 的性能,每一部分的具体的含义如下:

  • max_concurrent_requests – 并发请求的最大数量
  • max_queue_size – 任务队列中任务的最大数量
  • multipart_threshold – CLI用于单个文件的多部分传输的大小阈值
  • multipart_chunksize –在使用多部分传输时,这是CLI用于单个文件的多部分传输的块大小
  • max_bandwidth –用于向Amazon S3上传和下载数据的最大带宽

 

关于s3 的这几个参数,我们需要结合具体的使用场景与网络情况进行更精细的优化。

 

 

设置系统时区

 

对于许多与系统相关的任务和流程来说,使用正确的时区是非常重要的。例如,cron守护进程使用系统的时区执行cron作业,日志文件中的时间戳也要基于时区的设定。

在Ubuntu上,系统的时区是在安装过程中设置的,但是用户是可以进行更改的。检查当前系统时区的设置可以使用timedatectl 命令。

Ubuntu的系统时区是通过将/etc/localtime链接到/usr/share/zoneinfo目录中的二进制时区标识符来进行配置的。我们的设置只需要一条命令即可完成。

 

#!/bin/bash

set -e

TZ="Asia/Shanghai"

sudo timedatectl set-timezone ${TZ}

timedatectl

echo "Done."

 

至于为什么使用上海而不是北京作为中国时区的标志,在Wikipedia 中有这样的解释

 

“The territory of the People’s Republic of China is covered in the IANA time zone database by the following zones. The reason why Asia/Shanghai is used instead of Beijing is because Shanghai is the most populous location in the zone. Columns marked with * are from the file zone.”
                                                        

 

设置NTP(网络时间协议)

网络时间协议(Network Time Protocol,缩写:NTP)  是通过网络來同步时间的一种TCP/IP 协议,位于OSI模型的应用层。 自1985年出现以来,NTP是目前仍在使用的最古老的互联网协议之一。不同于Ubuntu 18.04 缺省的的NTP的设置,我们需要的是针对AWS EC2 作优化的NTP设置。这个设置的原因在于2017年11月,AWS 发布了 Amazon Time Sync服务。这是一项通过网络时间协议 (NTP) 提供的时间同步服务,在每个AWS区域使用冗余的卫星连接和原子钟来提供高精度的参考时钟。这项服务适用于AWS 区域中在 VPC 中运行的所有实例,且不会产生任何费用。除此以外,无论是同步的延迟还是可靠性都要远超过公共的NTP 服务器。

在配置NTP的时候,我们需要安装一个名为Chrony的工具。这是一个开源(GNU GPL v2 协议)的NTP实现,用来代替传统的ntpd。Chrony比使用 ntpd 的方式更快;它能够更快地同步系统时钟,并且准确度比我们熟悉的ntpd 更高。除非是非常特殊的原因,否则强烈建议使用Chrony。安装的脚本如下

#!/bin/bash
set -e

sudo apt-get install -y chrony

sudo sed -i 's|pool ntp.ubuntu.com        iburst maxsources 4|server 169.254.169.123 prefer iburst minpoll 4 maxpoll 4|g' /etc/chrony/chrony.conf

sudo service chronyd start
chronyc sources -v

echo "Done."

 

需要解释一下,每一个EC2 实例都可以通过169.254.169.123地址访问Amazon Time Sync 服务,所以就需要将chrony 配置文件(/etc/chrony/chrony.conf)中的NTP服务器项目作必要的替换,确保169.254.169.123 为配置中的第一个NTP 服务器。

时间处理是非常复杂的,对我们的许多应用而言也是重要的。关于时间服务的重要性,仅以“闰秒”的例子来加以说明。科学领域通常使用国际天体参照系 (ICRF) 来测量时间。而ICRF 则是使用远距离类星体的长基线干涉测量法、GPS卫星轨道和月球的激光测距计算得出的。地球的自转速度是不规则的,这会导致 UTC 相对于 ICRF 发生时间漂移。为了解决这一时钟漂移问题,国际地球自转和参考系 (IERS) 偶尔会在 UTC 中引入额外的秒数,使其与实时时间的时间差保持在 0.9 秒内。这就是所谓的“闰秒”。而闰秒的存在会导致计算机应用程序的错误,这可能是许多开发人员和系统管理员所关心的问题。 Amazon Time Sync Service服务的时钟会调整在一段时间后带来的闰秒问题 (通常称为“跳秒”),这使得应用程序不会因为时间不同步而出现问题。

 

设置 Amazon EC2 Instance Connect

以往,我们连接使用EC2 实例往往通过SSH来实现。对于EC2的实例来说,我们的选择不止这一种,我们还可以选择Amazon EC2 Instance Connect。具体说来,这是一种简单而安全连接到EC2实例的方法。借助 EC2 Instance Connect,我们可以使用 AWS Identity and Access Management (IAM) 策略以及使用 AWS CloudTrail 事件的审核连接请求,控制对实例的 SSH 访问。此外,我们还可以利用现有的 SSH 密钥,或者,通过每次授权用户连接时生成一次性 SSH 密钥,进一步增强连接的安全性。EC2 Instance Connect 可与任何 SSH 客户端协作,我们甚至可以通过 EC2 控制台中基于浏览器的方式连接到我们的实例。效果是这样的 –


除了浏览器的方式以外,我们还可以用命令行的方式替代SSH来连接EC2实例,

$ mssh ubuntu@i-082a447c03166cff2

 

注意,这种连接方式使用的不同于传统的SSH 使用的目标计算机IP地址的方式。替代的方法是使用实例的ID。毋庸置疑,这种方式的安全性会较SSH为高。这里的mssh 是一个基于Python 的工具,我们需要用pip来进行安装

$ pip install ec2instanceconnectcli

回到我们目标的这台EC2,我们需要为其安装ec2-instance-connect。安装的脚本如下:

#!/bin/bash

sudo apt-get update
sudo apt-get install -y ec2-instance-connect
cat /lib/systemd/system/ssh.service.d/ec2-instance-connect.conf

echo "Done."
注意:目前AWS北京区域、AWS宁夏区域暂未提供EC2 Instance Connect。

 

 

软件包安装的网络加速

在AWS的北京区域以及AWS宁夏区域都已经提供了许多种类的EC2 GPU 实例。


不仅如此,使用cloudping.info 进行网络延迟测试的结果也让我非常满意,最高不超过37ms,最低可达10ms。这样的条件完全可以让我们充分发挥这些EC2实例的潜力,除了一件事情以外。这件让我们最为头疼的事情就是安装或者同步软件的时候那让人焦虑的速度。例如我们使用apt-get install 来安装软件的时候,ubuntu 为我们定向的http://cn-northwest-1a.clouds.archive.ubuntu.com 表现出来的速度完全不像我们生活在同一个区域。此外。当使用git clone 一个项目的时候,也会应为几K、十几K的网络速速而抓狂。在我的实践当中,解决问题的办法是这样的:

  • 使用一个SOCKS5 的代理
  • 将curl、git、apt、apt-gey等命令利用Linux 别名的机制强制使用SCOKS5 代理
  • 选择一个更快而稳定的Ubuntu 镜像仓库。目前我使用的镜像站点是http://ftp.jaist.ac.jp/pub/Linux/ubuntu/

 

具体的配置如下:

#!/bin/bash
set -e

PORT="1080"
PROXY="XXXX"

write_proxyrc() {
cat >> $HOME/.proxyrc <<EOT
alias apt-get='apt-get -o Acquire::http::proxy="socks5h://127.0.0.1:${PORT}/"'
alias apt='apt -o Acquire::http::proxy="socks5h://127.0.0.1:${PORT}/"'

#git
alias git="git config --global http.proxy socks5h://127.0.0.1:${PORT}"

#wget
export SOCKS_SERVER=127.0.0.1:${PORT}

#curl
alias curl="curl -x socks5h://127.0.0.1:${PORT}"
#libcurl
#env ALL_PROXY=socks5h://127.0.0.1:1080  PROGRAM [OPTION]...
#env http_proxy=socks5h://localhost:8001 HTTPS_PROXY=socks5h://localhost:8001 ALL_PROXY=socks5h://localhost:8001
EOT
}

if [ ! -f $HOME/.proxyrc ]; then
    touch $HOME/.proxyrc
    write_proxyrc
else
    source $HOME/.proxyrc
fi

killall -q ${PROXY}
nohup ${PROXY} &> /dev/null &

echo "Done."

 

不敢说这是一个最佳的方法,但至少解决了我安装、同步软件遇到的问题。如果你们有更好的方法,也希望能够分享给我你的经验。

到此,关于这台EC2实例的基础设置可以告一段落了。接下来,我们将深入到操作系统、网络、存储等系统优化的领域,希望这些方法对各位有所帮助。

 

本篇作者

费良宏

费良宏,AWS Principal Developer Advocate。在过去的20多年一直从事软件架构、程序开发以及技术推广等领域的工作。他经常在各类技术会议上发表演讲进行分享,他还是多个技术社区的热心参与者。他擅长Web领域应用、移动应用以及机器学习等的开发,也从事过多个大型软件项目的设计、开发与项目管理。目前他专注与云计算以及互联网等技术领域,致力于帮助中国的 开发者构建基于云计算的新一代的互联网应用。