如何在 AWS elasticbeanstalk 中配置 sonarqube 7.1

How to configure sonarqube 7.1 in AWS elasticbeanstalk

我已经尝试了几种方法在我们的 AWS 环境中获取 sonarQube 运行ning,都成功了。但是,SonarQube 不稳定。每当 Elastic beanstalk 回收一个实例时,我的 SonarQube 环境就会被清除。

这是我尝试过的:

尝试 1: EC2 实例。我使用 bitnami ami imageId 创建 EC2 实例:ami-0f9cf81913a6dce27

这似乎是一个非常简单的过程。但我更喜欢弹性 beantalk 环境来管理我们的 sonarQube EC2 实例。

尝试 2: 使用单个 docker 实例创建 EB 环境,使用此 docker 文件:

{
  "AWSEBDockerrunVersion": "1",
  "Image": {
    "Name": "sonarqube:7.1"
  },
  "Ports": [{
    "ContainerPort": "9000"
  }]
}

这创建了 EB 环境。它创建一个 RDS 实例(使用 mySql 5.x)来存储扫描数据(在名为 ebdb 的数据库中)。 sonarQube 服务器在本地为其搜索数据托管一个内部 elasticsearch 实例。

然后我必须添加一些环境变量来支持 RDS 实例(jdbc 用户名、密码、url 端点等)。

然后我必须配置 sonarQube 安全端。

没有安装市场功能。所以我添加了 SonarJava、Groovy 和 SonarJS。

我添加了一个用于扫描的登录用户。一切顺利。

除此之外,Elastic Beanstalk 偶尔会出现运行状况问题并删除当前实例,然后重新创建一个新实例。

在这种情况下,一切都完好无损 - 安全:用户、密码等。除了市场功能已经消失。所以代码扫描将失败,直到我手动将它们添加回来。

单实例 docker 容器的架构非常稀疏,我没有看到任何进一步自定义 docker 文件的方法。

尝试 3: 使用多实例 docker 容器。架构更强大,也许我可以更明确地配置 sonarQube。例如可以传递环境变量,mysql设置等

我无法让它工作。我确实了解到我需要将内存设置为 2 GB 以上,以便 elasticsearch 启动。但是我无法启动 sonarQube 环境。

稍后我可能会重新访问它。

尝试 4: 在弹性 beantalk 中使用 AMI(使用 terraform aws 提供程序)

main.tf


resource "aws_elastic_beanstalk_application" "sonarqube" {
    name        = "SonarQube"
    description = "SonarQube for nano-services"
}

resource "aws_elastic_beanstalk_environment" "nonprod" {
    name                = "${var.application-name}"
    application         = "${aws_elastic_beanstalk_application.sonarqube.name}"
    solution_stack_name = "64bit Amazon Linux 2018.03 v2.10.0 running Docker 17.12.1-ce"
    wait_for_ready_timeout = "30m"

    setting {
        namespace = "aws:autoscaling:updatepolicy:rollingupdate"
        name      = "Timeout"
        value     = "PT1H"
      }

     setting {
        namespace = "aws:elasticbeanstalk:environment"
        name      = "ServiceRole"
        value     = "aws-elasticbeanstalk-service-role"
      }

      setting {
        namespace = "aws:elasticbeanstalk:command"
        name      = "DeploymentPolicy"
        value     = "Rolling"
      }

      setting {
        namespace = "aws:elasticbeanstalk:command"
        name      = "BatchSizeType"
        value     = "Fixed"
      }

      setting {
        namespace = "aws:elasticbeanstalk:command"
        name      = "BatchSize"
        value     = "1"
      }

      setting {
        namespace = "aws:elasticbeanstalk:command"
        name      = "IgnoreHealthCheck"
        value     = "true"
      }

      setting {
        namespace = "aws:autoscaling:launchconfiguration"
        name      = "EC2KeyName"
        value     = "web-aws-key"
      }

      setting {
        namespace = "aws:autoscaling:launchconfiguration"
        name      = "IamInstanceProfile"
        value     = "arn:aws:iam::<redacted>:instance-profile/aws-elasticbeanstalk-ec2-role"
      }

      setting {
        namespace = "aws:autoscaling:launchconfiguration"
        name      = "instanceType"
        value     = "t2.xlarge"
      }

      setting {
        namespace = "aws:elb:listener:443"
        name      = "ListenerProtocol"
        value     = "SSL"
      }

      setting {
        namespace = "aws:elb:listener:443"
        name      = "InstanceProtocol"
        value     = "SSL"
      } 

      setting {
        namespace = "aws:elb:listener:443"
        name      = "SSLCertificateId"
        value     = "arn:aws:acm:<redacted>"
      } 

      setting {
        namespace = "aws:elb:listener:443"
        name      = "ListenerEnabled"
        value     = "true"
      } 
}

最初我包含了 sonarQube AMI:

  setting {
    namespace = "aws:autoscaling:launchconfiguration"
    name      = "imageId"
    value     = "ami-0f9cf81913a6dce27"
  }

这确实创造了一切。但是EC2实例响应太慢,EB进入灰色状态。即使 SonarQube 启动并且 运行ning,EB 也不知道它。所以我注释掉了这一点,并一次性手动修改了图片id。

wait_for_ready_timeout 确实有助于此,因为这只是防止 terraform 超时。例如它在 22.5 分钟内完成,而不是在 20 分钟时硬停。

在这种情况下,它会使用本地 mysql 数据库(无 RDS 实例)创建 SonarQube,其中 elasticsearch 也是本地的。

SonarQube 的市场功能也包括在内,Groovy 除外。我添加的。

但是,和以前一样的问题。当 EB 删除一个实例并重新创建它时,sonarQube 环境将被清除。这一次,凭据、市场功能和一切。

有人 运行 解决了这个问题吗?

我使用 ECS (Fargate) 而不是 Elastic Beanstalk 容器解决了这个问题。

步骤:

  1. 在 AWS 中为声纳创建一个 RDS mysql 实例

  2. 为本实例开一个mysqlshell,配置sonar,见:Sonar setup with MySql

  3. 使用您关心的插件创建一个 docker 文件,例如:

    FROM sonarqube:latest
    
    ENV SONARQUBE_JDBC_USERNAME=[YOUR-USERNAME] \   
        SONARQUBE_JDBC_PASSWORD=[YOUR-PASSWORD] \    
        SONARQUBE_JDBC_URL=jdbc:mysql://[YOUR-RDS-ENDPOINT]:3306/sonar?useSSL=false&useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance
    
    RUN wget "https://sonarsource.bintray.com/Distribution/sonar-java-plugin/sonar-java-plugin-5.7.0.15470.jar" \
        && wget "https://sonarsource.bintray.com/Distribution/sonar-javascript-plugin/sonar-javascript-plugin-4.2.1.6529.jar" \
        && wget "https://sonarsource.bintray.com/Distribution/sonar-groovy-plugin/sonar-groovy-plugin-1.4.jar" \
        && mv *.jar $SONARQUBE_HOME/extensions/plugins \
        && ls -lah $SONARQUBE_HOME/extensions/plugins
    
    EXPOSE 9000
    
    EXPOSE 9092

我公开了 9092 以防我想注释掉 mysql 连接,并在某个时候使用内部 h2 数据库在本地进行测试。

  1. 验证 docker 图像在本地运行

eval $(docker-machine env)

docker build -t sonar .

docker run -it -d --rm --name sonar -p 9000:9000 -p 9092:9092 sonar:latest

echo $DOCKER_HOST

打开浏览器到这个ip地址,端口9000。例如http://192.x.x.x:9000

  1. 创建一个名为 sonar 的新 ECS 存储库来存储 docker 图像。

    AWS 接口实际上告诉你如何发布你的 docker 图像,所以这应该是不言而喻的。

  2. 标记 docker 文件并将其推送到声纳存储库

$(aws ecr get-login --no-include-email --region [YOUR-AWS-REGION])

docker tag sonar:latest [YOUR-ECS-DOCKER-IMAGE-URI]/sonar:latest

docker push [YOUR-ECS-DOCKER-IMAGE-URI]/sonar:latest

  1. 创建一个新的 fargate 集群,名为 sonar

  2. 创建新的任务定义。

    对于您的容器,请使用 ECS docker 图像 URI。我给了我 6 GB 内存和 2 cpus,有 1024 cpu 个单元。这里我暴露了9000和9092端口。我在这里的Dockerfile中也添加了环境变量。

  3. 创建 ECS 服务,并包含任务。 运行 它,验证日志 cloudwatch。然后点击端口 9000 上的 public 端点,完成。

我很大程度上借鉴了这个:https://www.infralovers.com/en/articles/2018/05/04/sonarqube-on-aws-fargate/

我希望这对其他人有帮助。