还在用Nexus么,何不尝试使用AWS CodeArtifact?

715 阅读6分钟

以往我们习惯使用Nexus来自建Maven、Gradle依赖包;Nexus功能很全面,它既可以管理Java Maven/Gradle依赖也可以管理python pip依赖和nodejs npm依赖,但是它在云时代有一些弱点就是在大型公司使用时需要人力去维护服务,比如频繁的软件更新和安全修复,提前购置好服务器和磁盘空间等;超过实际需要的计算资源会造成成本浪费,低于峰值需求的计算资源会严重影响正常开发;频繁的维护也消耗了不少的运维资源,所以在综合成本的角度上看,对基础工具类服务而言,云服务商的按需付费模式更加划算。

AWS CodeArtifact是AWS推出的原生版软件依赖管理服务,能够完全取代Nexus,它完全不需要进行软硬件的维护,没有预付费,没有最低消费,你用多少就算多少钱(大部分公司基本没有什么费用),全部的硬件资源的按需预置和软件的安全补丁都由AWS来负责,你只需要使用即可。

前面我们讲道CodeArtifact可以管理Maven,Gradle,pip,npm依赖,那么我们就逐步的拆解不同包管理下的最佳实践。首先CodeArtifact是完全兼任这些包管理器的规范的,运维管理员需要创建好云端的包管理仓库,软件开发者需要在自己本地开发电脑上配置好临时口令。对软件开发者而言值得注意的是口令是临时的不是永久的,口令的最长的有效期是12小时,而且不是普通的账户和秘密对;这样做的出发点是安全方面的考虑,避免长期的口令泄漏导致的公司软件仓库的安全事故。

关于管理员设置CodeArtifact仓库,我们可以看codeartifact user guide

关于开发人员为自己的开发环境设置CodeArtifact密钥,请继续往下看。

开发环境设置密钥的前提是电脑上有安装了AWS Cli2并配置好AWS IAM口令.如果没有请看几种高效管理AWS的方式以及AWS开发环境配置 ; 上述条件具备后,一般情况下的通用做法是我们可以用aws cli命令登陆CodeArtifact并获取临时口令,然后将口令保存到环境变量或者配置文件中,这样后续的包管理器和CodeArtifact交互的时候可以正确的读取到临时口令。

不同语言的包管理配置请看:

相比Nexus,CodeArtifact强制的临时口令(最大12小时)虽然安全但是如果我们开发人员每次或在每一段时间刷新手动刷新口令的话,就非常的麻烦,影响了开发的速度。那么有没有一种自动化的方式,来帮我们做到口令在过期前的自动刷新呢?答案是有的。

全自动刷新口令

Gradle自动刷新口令

gradle有不错的脚本执行能力,我们可以在build.gradle定义好变量,用这个变量保存脚本执行后返回的临时口令的值,然后这个值被build.gradle里面的其他的地方所引用。由于每次我们打开项目或者执行构建的时候,build.gradle都会被解析,那么这个临时口令是可以被实时的触发更新的,完全不需要你做任何的口令更新操作,是全自动的。推荐Java开发者使用Gradle替换Maven,Gradle构建速度更快,build.gradle相比POM文件更加简洁清晰而且能执行一些自定义的前置/后置脚本,功能更强大。

比如我非常简单的就设置好了自己的java依赖仓库

依赖下载设置

// 从AWS CodeArtifact下载依赖
// 每次build.gradle被解析的时候,自动执行下面的命令,从AWS CodeArtifact获取临时口令
def codeartifactToken = "aws codeartifact get-authorization-token --domain omoz --domain-owner 843XXX41269 --query authorizationToken --output text --profile default".execute().text
repositories {
    // 优先使用本地仓库
    mavenLocal()
    // 第二优先使用优先使用AWS CodeArtifact私有仓库
    maven {
        url 'https://omoz-843XXX41269.d.codeartifact.us-east-1.amazonaws.com/maven/omoz-mvn/'
        credentials {
            username "aws"
            // 引用临时口令
            password codeartifactToken
        }
    }
    // 最后使用maven中央仓库和Spring仓库
    mavenCentral()
    maven { url 'https://repo.spring.io/release' }
}

依赖上传设置

    // 发布到AWS CodeArtifact私有库
    publishing {
        publications {
            mavenJava(MavenPublication) {
                // 包含打包出的jar包
                from components.java
                // 包含源代码
                artifact sourceJar
                pom {
                    name = rootProject.name
                    description = 'xxxx 后端服务.'
                    url = 'https://github.com/xxxx/xxx/xxxx'
                    licenses {
                        license {
                            name = 'The Apache License, Version 2.0'
                            url = 'https://www.apache.org/licenses/LICENSE-2.0.txt'
                        }
                    }
                }
            }
        }

        repositories {
            maven {
                url 'https://omoz-843XXX41269.d.codeartifact.us-east-1.amazonaws.com/maven/omoz-mvn/'
                credentials {
                    username "aws"
                    // 引用临时口令
                    password codeartifactToken
                }
                // 禁用使用非安全协议通信(比如http)
                allowInsecureProtocol false
            }
        }
    }

类似这样

image

定时刷新口令

除了gradle,一些其他的包管理器在运行的时候,基本没有执行脚本的能力,这时我们有2种方案

  1. 将获取/更新CodeArtifact临时口令的脚本和环境变量写到bash文件里面然后设置开机自启动,这样每次系统启动时会进行一次脚本的更新。这种方式在服务器或者开发机长期不重启的情况下不适用,比如开发者的电脑超过12小时连续运行的情况。
  2. 使用cron定时(比如每2小时)执行获取/更新CodeArtifact临时口令的脚本,cron设置开机启动,这样我们的电脑会在后台定时自动刷新,推荐这种方式。

cron使用方式参考:

我们先写好各种包管理器的登陆脚本:

管理器命令
pipaws codeartifact login --tool pip --repository omoz-pip --domain omoz --domain-owner 843XXX41269 --region us-east-1
twineaws codeartifact login --tool twine --repository omoz-pip --domain omoz --domain-owner 843XXX41269 --region us-east-1
npmaws codeartifact login --tool npm --repository omoz-npm --domain omoz --domain-owner 843XXX41269 --region us-east-1

我们计划每2小时刷新一次临时口令,那么cron表达式为* */2 * * *

见设置cron服务自启动,并编辑cron任务

thinktik@thinkstation:~$ sudo systemctl enable cron
[sudo] password for thinktik: 
Synchronizing state of cron.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable cron
thinktik@thinkstation:~$ sudo systemctl start cron
thinktik@thinkstation:~$ 
thinktik@thinkstation:~$ crontab -e

image

填入cron命令

# pip
* */2 * * * aws codeartifact login --tool pip --repository omoz-pip --domain omoz --domain-owner 843XXX41269 --region us-east-1
# twine
* */2 * * * aws codeartifact login --tool twine --repository omoz-pip --domain omoz --domain-owner 843XXX41269 --region us-east-1
# npm
* */2 * * * aws codeartifact login --tool npm --repository omoz-npm --domain omoz --domain-owner 843XXX41269 --region us-east-1

image

当我们设置好了后,cron表达式会自动的定期刷新。