这个问题与我以前的问题有关-但更具描述性。
我正在尝试构建自动生成和部署Docker容器的方法。 docker容器是使用packer创建的。
创建docker映像后,我正在使用packer的后期处理模块将其上传到AWS ECR:

{
    "type": "docker-push",
    "ecr_login": true,
    "aws_access_key": "<snip>",
    "aws_secret_key": "<snipe>",
    "login_server": "https://<snip>.dkr.ecr.eu-west-1.amazonaws.com/"
}


这很好用。泊坞窗图像已上传到我在ECR中的存储库中。
现在,下一步就是卡住了。
我想在AWS上运行启动容器。

我认为一个使用aws-cli命令的小脚本可能适用于此。
我不想使用Web ui-我确信这可以通过命令行完成,特别是当有人希望将其集成到某种形式的管道中时。

但是,我有几个问题,因为我我不确定我是否正确理解全局。我的docker映像可通过ECR获得。要运行它,我需要一些基本实例,对吗?根据前一个线程的回复,通过使用ECS或启动EC2实例,有多种方式运行docker容器。由于这与某些研究项目有关,在该项目中分析了docker和虚拟化,因此我想问哪种方法对我的案例来说是最佳选择。大概是EC2?重要的是,我可以使其自动化,这样就不需要用户交互。

我阅读了文档并检查了一些教程,但是我仍然不确定如何正确地按顺序正确完成所有操作。尤其是设置环境并启动映像的部分。

我知道我可以使用以下方式列出映像:

aws ecr list-images --repository-name prototypes



如果不清楚,请通知我,以便我尽可能详细地更新我的问题。

评论

我也有兴趣这样做,即在AWS上部署Docker容器。如果这仍然是一个带有示例部署的研究项目,那么也许会有一些GitHub的写作,以便可以直接进行代码贡献?您是否要部署一堆容器,即在部署之后,编排策略是什么?即也许您需要的是EKS?

@Peter我可能无法在github上发布代码,因为该研究项目在NDA之下。但是,当有人提供可以帮助我实现上述情况的答案时,我也许可以更新此线程。我仍然无法解决问题,希望有AWS经验的人能提供描述性的解释。

#1 楼

我将尝试尝试并举例说明所有必需的步骤。

如果解释不充分,请添加带有问题和改进建议的注释。

OP(原始海报)指awscli;在提供相应示例的同时,我还讨论了此方法的局限性,并给出了使用Python进行此操作的示例。

EC2部署

此答案的目的是证明正确假设OP,没有Web UI访问权限,也没有必须进行人工交互才能在AWS EC2实例上部署容器。

范围和限制

在此用例中,我们要出于演示/研究目的,仅手动启动一个容器,因此我们明确决定不进行任何编排。

因此,对于复杂且可能更现实的部署方案,此示例不可重用。出于相同的简单原因,我们将使用EC2服务并在那里创建单个虚拟机。

根据简短的文档研究,似乎没有预装Docker守护程序的正式AMI。因此,我们需要部署一些默认的EC2实例并在其中安装Docker守护程序,然后启动该守护程序。

使用私有注册表时,需要登录;为了简单起见,我还给出了一个示例,以从公共Docker Hub注册表中运行容器。

此外,我将不提供复制粘贴自动化脚本,而是可以轻松采用的单个步骤满足个人需求。无论如何,中间结果都需要解析和传递操作,这才是纯编程活动要考虑的问题。

可以通过使用awscli的bash或Python以及AWS的boto3 SDK来完成样板自动化。

Python是值得考虑的,因为您可以更好地处理从AWS获得的JSON响应。您还可以告诉Python在远程主机上执行SSH登录和bash命令。

执行计划


A.标识最近的Linux AMI(Amazon机器映像)ID
B。创建密钥对和实例(进一步,也称为VM)
C。连接到实例
D。安装和配置Docker守护程序
E。运行容器

A。根据官方文档确定最近的Linux AMI映像ID

搜索最新的最新Amazon Linux映像:

$ aws ec2 describe-images --owners amazon --filters 'Name=name,Values=amzn2-ami-hvm-2.0.????????.?-x86_64-gp2' 'Name=state,Values=available' --query 'reverse(sort_by(Images, &CreationDate))[:1].ImageId' --output text
ami-01f14919ba412de34


B 。创建密钥对和VM

使用awscli,您可能会说:

$ aws ec2 create-key-pair --key-name ec2-docker-test


但是,API向您发送包裹在JSON中的公共密钥数据信息。因此,使用Python可以更轻松地将此数据消息处理为.pem文件:

import boto3
ec2 = boto3.resource('ec2')

# create a file to store the key locally
outfile = open('ec2-keypair.pem','w')

# call the boto ec2 function to create a key pair
key_pair = ec2.create_key_pair(KeyName='ec2-docker-test')

# capture the key and store it in a file
KeyPairOut = str(key_pair.key_material)
print(KeyPairOut)
outfile.write(KeyPairOut)


使用以前获得的AMI ID,我们现在可以创建VM :

instances = self.ec2r.create_instances(
                 ImageId=AMI_ID,  
                 MinCount=1,
                 MaxCount=1,
                 InstanceType=instance_type,
                 KeyName='ec2-docker-test'
             )


AWS API还允许查找实例状态和IP。只需再添加一些Python / boto3节,就可以获取此数据,以了解何时可以继续。

注意:防火墙注意事项

要配置防火墙访问权限,请创建一个安全组并将其链接到计算机的VPC。出于可读性原因,不包含示例。

C。测试SSH连接

实例启动并运行后,您就可以通过远程命令执行来完成您喜欢的一切。

在Bash脚本中,您将使用仅sshscp上传本地bash脚本并远程运行。

 ssh -t <REMOTE_IP> -i <KEY_FILE> <COMMAND>


使用Python,您可以使用paramiko等其他模块建立SSH连接并远程运行命令。

client = paramiko.SSHClient()
client.connect(ip, username=username, key_filename=key_filename, port=port,
                           timeout=timeout,
                           auth_timeout=timeout)

stdin, stdout, stderr = ssh.exec_command("whoami")


出于可读性考虑,我列出了其他未包装的命令。在脚本中,您可能想使用基本帮助程序子例程来调用ssh_call(command)之类的调用。

D。如上所述安装和配置Docker守护程序

,这里的其他所有操作都在运行远程命令。

也就是说,总结步骤是按照官方文档中的示例进行的;进行过程与您在本地进行的过程相同,但是需要将其包装在脚本中,并根据需要传递中间结果:


安装并配置Docker守护程序
登录到您的Docker注册表(如果需要)
拉镜像
运行Docker容器

    sudo yum update -y
    sudo amazon-linux-extras install docker
    sudo service docker start
    sudo usermod -a -G docker ec2-user
    # relogin or continue with sudo, which you shouldn't
    aws ecr get-login --no-include-email --region region




E。运行容器

拉自定义图像并从AWS的私有注册表中运行容器。

    docker pull aws_account_id.REGISTRY.ecr.REGION.amazonaws.com/REPOSITORY/IMAGE:TAG
    docker run --name MYSERVICENAME -d -p PORT_HOST:PORT_CONTAINER IMAGE:TAG



拉出正式的公共图像并运行另一个容器侦听只需一步即可在端口8001上进行操作:

    docker run --name nginx -d -p 8001:80 nginx:latest




ECS的替代方案

如此处的这些Python / boto3示例所述在这里,可以使用AWS ECS服务定义计算机集群并在其中运行容器。

请注意,ECS集群为您提供了来自AWS EC2或AWS Fargate的抽象以交付实际的虚拟机。

如果我们要使用EC2,则再次需要获取最近的机器映像,但这需要针对ECS优化的机器。简而言之,这些机器将具有ECS代理;通过其配置,我们将计算机分配给目标集群。

还有一点好处是ECS计算机已经预安装了Docker守护进程。

因此,我们创建一个ECS集群并向其中添加虚拟机。

ecs_client.create_cluster(clusterName=cluster_name)

ec2_client.run_instances(
        ImageId=AMI_ID,
        MinCount=1,
        MaxCount=1,
        InstanceType="t2.micro",
        IamInstanceProfile={
            "Name": "ecsInstanceRole"
        },
        UserData="#!/bin/bash \n echo ECS_CLUSTER=" + cluster_name + " >> /etc/ecs/ecs.config"
    )



在集群中,我们可以创建服务的任务定义,它们都是容器概念的抽象。

ecs_client.register_task_definition(
        containerDefinitions=[
        {
          "name": "<MY_SERVICE>",
          "image": "<MY_IMAGE>",
          "portMappings": [
            {
              "containerPort": 80,
              "hostPort": 80
            }
          ]
        }
        ],
        family="hello_world"
    )


现在,您可能会问自己,实例上的Docker守护程序如何知道您的私有注册表以提取指定的映像?为此,机器的ECS代理需要其他配置。

现在,您可以启动该服务,该服务将使用先前定义的任务告诉先前授权的Docker守护进程从ECR中提取先前构建和发布的映像,并在数据中包含在ECS集群中的机器上运行容器Jeff建造的中心房。

ecs_client.create_service(
        cluster=cluster_name,
        serviceName=service_name,
        taskDefinition=task_name,
        desiredCount=1,
        clientToken='request_identifier_string',
        deploymentConfiguration={
            'maximumPercent': 200,
            'minimumHealthyPercent': 50
        }
    )


ECS上下文中安全组的配置已在StackOverlow上突出显示。简而言之,这些是对与安全组管理相关的API部分的进一步调用。

结论

Bash和Python实现选项都有其优点和缺点。

从长远来看,Python是具有大型社区的通用编程语言,它允许从云API或系统进程进行复杂的字符串操作和抽象。

而无需了解其真正的目标。部署,上述步骤的端到端可能不值得,因为对于部署一组更典型的方案的相关容器而言,其他方法可能更实用。

在进入技术实施之前,最好是针对业务目标和预算做出精心设计的决策和选择:


自动化需要运行多少次,从头到尾在哪个时间段内实施它?
评估您是否仅需要EC2或带EC2的ECS或Fargate来执行无状态任务,或者您是否需要Kubernetes?

进一步阅读:“托管Kubernetes与Amazon ECS的好处”(截至2019年8月,云顾问博客的简短论点)。


2018年CNCF调查引用了83 %的组织使用Kubernetes作为其容器编排解决方案,而ECS则为24%。


评论


借助boto3,您可以将ECS客户端对象(在其中定义集群和服务)与ECR客户端(在此处获得存储库部署令牌)连接起来。我在此找到了一个不错的GitHub小示例,请告诉我是否要按照这些方式添加答案部分。 github.com/AlexIoannides/py-docker-aws-example-project/blob/…

– Peter Muryshkin
20年1月4日在20:40



将在几个小时内完成。

– Peter Muryshkin
20 Jan 5 '20 at 7:32

做完了请查阅。

– Peter Muryshkin
20年1月6日在14:28

是的,您需要向ECS客户端提供它可以带给ECR的角色。快速查看:请检查docs.aws.amazon.com/AmazonECS/latest/developerguide/…并与boto3 iam规格进行比较,并告诉我它是否有帮助。

– Peter Muryshkin
20年1月6日在21:02



可能您需要进行一些调试:SSH到ec2实例,检查容器日志,打开容器的终端并验证正在发生的事情。也许发布一个新问题:-)

– Peter Muryshkin
20年1月7日在6:37