我正在尝试构建自动生成和部署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
。如果不清楚,请通知我,以便我尽可能详细地更新我的问题。
#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脚本中,您将使用仅
ssh
或scp
上传本地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
评论
我也有兴趣这样做,即在AWS上部署Docker容器。如果这仍然是一个带有示例部署的研究项目,那么也许会有一些GitHub的写作,以便可以直接进行代码贡献?您是否要部署一堆容器,即在部署之后,编排策略是什么?即也许您需要的是EKS?@Peter我可能无法在github上发布代码,因为该研究项目在NDA之下。但是,当有人提供可以帮助我实现上述情况的答案时,我也许可以更新此线程。我仍然无法解决问题,希望有AWS经验的人能提供描述性的解释。