Amazon ECS
ECS(弹性容器服务)是一个AWS集群协调平台。ECS允许你部署和运行容器化的Docker应用程序,使用ECS命令行界面(ecs cli),通过几个简单的cli命令对它们进行缩放,以创建微服务。你也可以使用AWS Web UI控制台来管理你的ECS集群,而无需使用CLI。
本文档将演示如何使用Fargate启动类型在ECS上设置SKIL集群。使用Fargate,不需要提供任何EC2实例,也不必担心在AWS中设置虚拟机的底层基础结构。
ECS 概念
任务定义
任务定义包含指定如何运行容器的所有元数据。你可以在这里了解更多关于任务定义的信息。你可以从任务定义创建任务,任务定义是运行容器的主要执行点。任务可以在其中运行多个容器。如果需要使用卷共享资源,或者需要使用“localhost”访问彼此,最好在单个任务定义中指定多个容器。
集群
群集包含应用程序设置中要具有的所有相关任务。它可以包含多个任务定义、多个用于缩放和维护任务日志的实例化任务。
先决条件
确保你已经处理了以下先决条件。
Docker
要安装Docker,请参阅以下Mac说明或以下Windows说明。对于Linux,可以使用以下命令安装Docker。
Shell
sudo yum -y update
sudo yum install -y docker
sudo systemctl start docker
sudo systemctl status docker
sudo systemctl enable docker
AWS CLI
AWS CLI将用于创建安全组、打开端口、创建IAM角色以及将角色策略附加到创建的角色。按照此链接在系统中安装AWS CLI。或者可以在Linux环境中执行以下命令
Shell
curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py" # Installing pip if necessary
sudo python get-pip.py
pip install awscli --upgrade --user
配置 AWS CLI
通过执行aws configure,你可以使用cli配置你的aws帐户。主要设置配置为:
- IAM Access Key
- IAM Secret Key
- Default region (us-east-1 推荐)
Shell
aws configure
ECS CLI
ECS CLI用于ECS集群配置、部署任务定义、在集群内运行任务、管理和查看任务内运行容器的状态和日志。
要安装ECS CLI,请访问此处
对于Linux系统,可以使用以下命令。
Shell
sudo curl -o /usr/local/bin/ecs-cli https://s3.amazonaws.com/amazon-ecs-cli/ecs-cli-linux-amd64-latest
sudo chmod +x /usr/local/bin/ecs-cli
ecs-cli --version
配置ECS CLI
Amazon ECS需要权限,这样你的Fargate任务就可以将日志存储在CloudWatch中。任务执行IAM角色包含此权限。
你需要在创建的IAM角色上附加AmazoneCastaskeExecutionRolePolicy策略。确保你拥有iam:CreateRole
权限,能够使用你的iam帐户创建角色。
使用ECS CLI使用你的凭据登录(分别用iam访问密钥和密钥替换
Shell
ecs-cli configure profile --profile-name my-ecs-profile --access-key --secret-key # Provide with your ACCESS_KEY and SECRET_KEY
创建一个名为“execution-assume-role.json”的文件,并将以下内容放入其中。
JSON
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "ecs-tasks.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
保存文件并以“ecseExecutionRole”的名称创建任务执行角色,将AmazonECSTaskExecutionRolePolicy
附加到该文件。
Shell
aws iam --region us-east-1 create-role --role-name ecsExecutionRole --assume-role-policy-document file://execution-assume-role.json
aws iam --region us-east-1 attach-role-policy --role-name ecsExecutionRole --policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
集群设置
部署模式使用两个任务定义,一个指定zookeeper和mysql实例的配置,SKIL实例将连接到该配置,另一个任务定义具有SKIL实例的配置。这种分离的原因是可以轻松地缩放集群中的SKIL实例。如果我们在同一个任务定义中定义了所有容器实例,那么我们将不得不按比例缩放所有容器。但是对于SKIL集群的设置,我们只需要扩展SKIL实例,所有实例都将连接到同一个zookeeper和mysql任务。
按如下方式配置集群名称、区域并指定集群配置的名称:
Shell
ecs-cli configure --cluster --region --default-launch-type FARGATE --config-name
ecs-cli up # Starting the cluster using the cluster configuration
VPC 与子网配置
由于SKIL实例需要连接到同一个专用网络,因此需要在同一个虚拟专用云中配置所有任务,并在任务定义中指定子网。
可以在这里创建专有网络,并在这里为专有网络配置子网。确保在该区域中创建它们作为ECS集群。
创建安全组和端口配置
你需要打开入站流量所需的端口(2181、3306、8080、9008),以便稍后在任务运行时从远程Web浏览器访问SKIL UI。
Shell
aws ec2 create-security-group --group-name "" --description "Security group for ECS (Shams)" --vpc-id ""
# You'll get the security group id after successfully executing the above command
aws ec2 authorize-security-group-ingress --group-id "" --protocol tcp --port 2181 --cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress --group-id "" --protocol tcp --port 3306 --cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress --group-id "" --protocol tcp --port 9008 --cidr 0.0.0.0/0
aws ec2 authorize-security-group-ingress --group-id "" --protocol tcp --port 8080 --cidr 0.0.0.0/0
为任务定义编写文件和ECS配置
容器在 docker-compose文件中定义,而ECS配置则在另一个文件中指定。ECS配置将包含任务执行角色名称、网络配置、网络模式、CPU和内存资源配置。
将以下内容放入文件名docker-compose.yml中,用于zookeeper和mysql:
YAML
version: '2'
services:
zookeeper:
image: zookeeper
cpu_shares: 2048
mem_limit: 4194304000
ports:
- "2181:2181"
logging:
driver: awslogs
options:
awslogs-group: tutorial-zookeeper
awslogs-region: us-east-1
awslogs-stream-prefix: zookeeper
mysql:
image: mysql:5.5
cpu_shares: 2048
mem_limit: 4194304000
ports:
- "3306:3306"
environment:
- MYSQL_ALLOW_EMPTY_PASSWORD=true
- MYSQL_DATABASE=skil_migrations
logging:
driver: awslogs
options:
awslogs-group: tutorial-mysql
awslogs-region: us-east-1
awslogs-stream-prefix: mysql
对于ECS配置,将以下脚本放在ecs-params.yml中。将
YAML
version: 1
task_definition:
task_execution_role: ecsExecutionRole
ecs_network_mode: awsvpc
task_size:
mem_limit: 8GB
cpu_limit: 4096
run_params:
network_configuration:
awsvpc_configuration:
subnets:
- ""
security_groups:
- ""
assign_public_ip: ENABLED
首先运行zookeeper和mysql服务,并注意正在运行的任务的私有IP地址。可以在这里找到ECS集群详细信息。
Shell
ecs-cli compose --project-name zksql-td service up --create-log-groups
注意私有IP地址,如下图所示:
任务的专有IP地址
对于SKIL配置,你需要首先对Docker Hub上可用的skil-ce镜像进行一些修改。为此,请将以下内容粘贴到start-skil.sh中。
Shell
#!/usr/bin/env bash
export SKIL_HOME=/opt/skil
#export SKIL_CLASS_PATH=/opt/skil/lib/*:/opt/skil/native/*:/opt/skil/jackson-2.5.1/*
export SKIL_LOG_DIR=/var/log/skil
export SKIL_PID_FILE=/run/skil/skil.pid
export SKIL_BACKEND=cpu
export SKIL_LICENSE_PATH=/etc/skil/license.txt
export SKIL_PUBLIC_KEY_PATH=/etc/skil/publickey.txt
bash /opt/skil/sbin/pre-start.sh
bash /opt/skil/sbin/start-skil-daemon
echo "Waiting for all SKIL Services to start..."
while [ $(jps | wc -l) != 5 ]
do
sleep 1s
done
until [ "grep join /var/log/skil/zeppelin-*.log" ]
do
sleep 1s
done
echo "SKIL Ready"
tail -f /var/log/skil/*.log
bash /opt/skil/sbin/stop-skil-daemon
现在,用下面的脚本创建一个“Dockerfile”。
Text
FROM skymind/skil
USER root
ADD start-skil.sh /start-skil.sh
RUN cat /start-skil.sh
RUN chmod 755 /start-skil.sh
RUN yum install -y mysql-connector-java && ln -s /usr/share/java/mysql-connector-java.jar /opt/skil/lib/mysql-connector-java.jar
# PLD
EXPOSE 9008
# File Server
EXPOSE 9508
# Zeppelin
EXPOSE 8080
# DL4J UI first port
EXPOSE 9002
# ModelHistoryServer port
EXPOSE 9100
CMD ["/start-skil.sh"]
现在你需要构建一个Docker镜像并将其上传到ECR仓库。确保你拥有ecr:DescribeRepositories
权限来管理你在ECS上的ecr仓库。
你可以在此处创建ECR仓库时获取仓库服务器的URI。为仓库命名为skymind/skil。
创建ECR仓库
创建仓库后,执行以下命令来构建和推送修改后的SKIL镜像。
Shell
sudo `aws ecr get-login --no-include-email --region ` # 运行从执行backticks中的命令返回的命令
sudo docker build -t skymind/skil:jdbc .
sudo docker tag skymind/skil:jdbc /skymind/skil:jdbc
sudo docker push /skymind/skil:jdbc
现在,通过将下面的脚本粘贴到“skil-ce.yml”中,为SKIL实例创建另一个任务定义。用包含zookeeper和mysql实例的任务的私有IP地址替换`
YAML
version: '2'
services:
skil:
image: /skymind/skil:jdbc
cpu_shares: 4096
mem_limit: 8388608000
ports:
- "9008:9008"
- "8080:8080"
environment:
- SKIL_USE_EMBEDDED_DB=false
- SKIL_DB_NAME=skil_migrations
- SKIL_DB_DRIVER=com.mysql.jdbc.Driver
- SKIL_DB_URL=jdbc:mysql://:3306/skil_migrations
- SKIL_DB_USER=root
- MODEL_HISTORY_SERVER_LAUNCH_DEFAULT=false
- ZEPPELIN_LAUNCH_DEFAULT=false
- ZOOKEEPER_HOST=
- ZOOKEEPER_PORT=2181
- ZOOKEEPER_EMBEDDED=false
logging:
driver: awslogs
options:
awslogs-group: tutorial-skil
awslogs-region: us-east-1
awslogs-stream-prefix: skil
现在,你可以运行SKIL服务并通过执行以下操作将它们连接到zookeeper和mysql进程:
Shell
ecs-cli compose --project-name skil-td --file skil-ce.yml service up --create-log-groups
通过指定任务定义的名称,可以看到正在运行的容器进程:
Shell
ecs-cli compose --project-name zksql-td service ps
ecs-cli compose --project-name skil-td service ps
你可以使用下面的ecs-cli命令查看任务ID日志:
Shell
ecs-cli logs --task-id --follow
使用scale子命令增加所需任务的数量,并指定要从刚才定义的skil-td
任务定义创建的SKIL实例的数量。
Shell
ecs-cli compose --project-name skil-td service scale 2
ecs-cli compose --project-name skil-td service ps
要删除你创建的正在运行的服务,请执行以下操作。
Shell
ecs-cli compose --project-name zksql-td service down
ecs-cli compose --project-name skil-td service down
ecs-cli down --force