问题
I'd like to use docker containers without having to use elastic beanstalk or ec2 container service. I'd like to upload a .zip
file describing the container (like you do with elastic beanstalk) and have a generic ec2 instance run it using docker.
When looking into the user data
section of a beanstalk-created ec2 instance running a docker container, I see a cloud-init script that downloads a big shell script that does all the setup (Example). I assume that everything that elastic beanstalk does can also be achieved manually by using ec2 instances and a user data
script.
My question is: Could someone provide a minimal example for a user data
script that
- installs/configures docker
- downloads the .zip file
- runs my docker image
I'm familiar with auto scaling groups etc. and I'd like to get this setup running without using the beanstalk- or ec2 container service magic.
回答1:
Basically, you need to install Docker and nginx (as web proxy) in your EC2 instance. And then, download the web-app archive and deploy it. This is what Elastic Beanstalk does.
For the basic/minimal user-data in order to deploy a single docker container web application:
#!/bin/bash
IMG_LABEL=myapp
APP_INIT_URL=https://s3.amazonaws.com/your-bucket-app/myapp-init.tar.gz
function prepare_instance {
apt-get -y update
apt-get -y install nginx
curl -sSL https://get.docker.com/ | sh
mkdir /opt
curl -o /opt/deployer.sh http://169.254.169.254/latest/user-data
chmod 775 /opt/deployer.sh
}
function download_app {
curl -o /tmp/current.tar.gz $1
rm -rf /opt/app
mkdir -p /opt/app
tar zxvf /tmp/current.tar.gz -C /opt/app
rm /tmp/current.tar.gz
}
function build_image {
docker tag ${IMG_LABEL}:latest ${IMG_LABEL}:prev || echo "No built app"
docker build -t ${IMG_LABEL}:latest /opt/app
}
function run_container {
APP_CID=$(docker run -d ${IMG_LABEL}:latest)
APP_IP=$(docker inspect --format '{{ .NetworkSettings.IPAddress }}' ${APP_CID})
}
function setup_proxy {
rm /etc/nginx/sites-enabled/*
cat <<EOT > /etc/nginx/sites-enabled/app.conf
map \$http_upgrade \$connection_upgrade {
default upgrade;
'' close;
}
upstream app.local {
server ${APP_IP};
}
server {
listen 80;
location / {
proxy_pass http://app.local;
include /etc/nginx/proxy_params;
proxy_http_version 1.1;
proxy_set_header Upgrade \$http_upgrade;
proxy_set_header Connection \$connection_upgrade;
}
}
EOT
service nginx reload
}
function destroy_previous {
(docker ps -a --before="${APP_CID}" | awk '{ print $1,$2 }' | grep "${IMG_LABEL}" | awk '{print $1 }' | xargs -I {} docker stop {} | xargs -I {} docker rm {}) || echo "No previous container"
docker rmi ${IMG_LABEL}:prev || echo "No previous image"
}
if [ ! -f /opt/deployer.sh ];
then
prepare_instance
download_app ${APP_INIT_URL}
else
download_app $1
fi
build_image
run_container
setup_proxy
destroy_previous
In Elastic Beanstalk, there is an agent that listen to update request. But, to make it simple, we can call the above script to deploy a new web-app version via SSH:
ssh ubuntu@ec2-107-123-123-123.compute-1.amazonaws.com 'sudo /opt/deployer.sh https://s3.amazonaws.com/your-bucket-app/myapp-201510122341.tar.gz'
Note: I use EC2 instance with Ubuntu 14.04.
回答2:
The user data is basically just a bash script that is run when the instance boots up first time.
If you want to look into setting up an instance from scratch on instance creation I suggest you have a look at CloudInit and how to use it in CloudFormation. http://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-init.html
With CloudInit you can describe files to be placed, packages to be installed and services to be enabled for start at boot.
来源:https://stackoverflow.com/questions/33009731/howto-deploy-a-docker-container-on-aws-without-using-elastic-beanstalk-or-ec2-co