Salut! Have not written for a while since I joined new company back in this February! Here, in Azure we have so much awesome staff, so I could not really fine free time to keep running my blog with new ideas! With over dozen different options for microservice architecture, I fall in love with things like AKS, ACR, ACI etc.
If you are like me, enjoying to learn new staff and interested in containers around clouds, see what you can do with Azure Container Instances (ACI) and Azure Container Registry (aka ACR, or registry of you choice, like docker hub etc). There are multiple code samples of ACI (e.g. dockerized Wordpress, docker volume manager etc).
What is ACI?
Well, it is "serverless" container engine (of course it is serverfull, but as consumer of this service I don't have to worry about underlying computer facilities something like cluster or docker-machine). I can just use either Azure portal, CLI or Powershell to execute my container with image of my choice from any docker compatible registry. Sounds awesome, right? the pricing model is based on pay-as-you-execute (similar to runtime in Azure Functions with consumption model). The pricing page is here to help.
What is ACR?
If your journey with containers started from Docker Inc., you should be aware of it's hub. Great registry! However, let's imagine you need registry closer to your container's drivers or you need same code base available across the World for different developers. Also you may need your corporate identity integration as well (e.g. only authorized through AD users should be able to use your registries and objects within them). Finally, why do you need several places / portals for pretty the same set of tasks? Azure Container Registry allows you to store images for all types of container deployments including DC/OS, Docker Swarm, Kubernetes, and Azure services such as App Service, Batch, Service Fabric, and others. Your DevOps team can manage the configuration of apps isolated from the configuration of the hosting environment. And, last but not least, we are looking at the same docker CLI experience, so you do not have to relearn in order to use it. Just create registry, push your first image and enjoy.
What is jumpbox?
Jumpbox here is azure's compute resource with ssh server used for getting access to rest of other resources in the cloud. One of the option to do this is to run virtual machine with few ports (and may be inbound rules in NSG) opened for jumping in and then iterating with other VMs or services through internal (private) network. In this case we are running
ssh daemon with
shellinabox for accessing our resources through ssh through web browser. See below picture what exactly I mean.
- Azure command-line interface on your computer (obviously, you also need subscription, there is free tier available as well);
- Docker command-line interface;
Dockerfile for our jumpbox
The whole idea is based on Dockerize an SSH service with small modification. Let's create our image.
MAINTAINER ER @erudinsky.com
RUN apt-get update && apt-get install -y openssh-server shellinabox
RUN mkdir /var/run/sshd
RUN echo 'root:$SECRET' | chpasswd
RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
RUN sed -i 's#--no-beep#--no-beep --disable-ssl --service=/:SSH#g' /etc/default/shellinabox
# SSH login fix. Otherwise user is kicked off after login
RUN sed '[email protected]\s*required\s*[email protected] optional [email protected]' -i /etc/pam.d/sshd
ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile
#CMD ["/usr/sbin/sshd", "-D"]
CMD /usr/sbin/sshd -D
There are two small changes I made in this image:
shellinabox package to installer;
sed for modification in
/etc/default/shellinabox in order to disable ssl and inherit ssh settings (e.g. to allow root login etc).
For the sake of simplicity we don't create new user for ssh and we use default port (22).
Registry for images in Azure
Let's now push this to our personal container registry (as I said earlier there is ACR specifically for this).
Now, since we have Azure CLI in our computer, let's quickly do
az login and by following instructions get access to our portal (there will be link with random code to paste in it). Once done, you will see the output of all available subscriptions under this user. Now, let's create registry.
az acr create -n acr -g acr --sku basic|standard|premium
I went for basic sku for my registry, but you want to use better tiers (you can always switch this through portal or CLI).
Once, registry is ready, we can . setup service principal in order to authorize or we can always type username and password to access it. Let's use second option, since we want simplicity. As I said earlier your experience is absolutely the same as docker cli. To push you use this:
# Some variables
az group create -n $RG_NAME --location $REGION && \
docker build -t $ACI_NAME . && \
docker tag $ACI_NAME $IMAGE_NAME && \
docker push $IMAGE_NAME && \
az group command for new Azure Resource Group (RG). In Azure we keep all resources in RG, which is great way to structure your services and manipulate them (delete, move etc..). In environment variables we keep all names (you need to change them to yours).
If there were no errors (like in my case), we can continue to the main action, - creating container.
Launching jumpbox container
az container create \
-n $ACI_NAME \
-g $RG_NAME \
--image $IMAGE_NAME \
--ip-address public \
--dns-name-label $DNS_LABEL \
I've added one more variable with array of ports to pass them to my container instance. In this particular cli above we take image from registry and create new containers and exposing few ports in order to interact with them. Port 4200 is used by
shellinabox app by default (you can change this if you want, then you need to do some find_and_replace operations with default configuration of this app).
If everything is ok, you should be able to see json format 'ish output with IP. But we don't need IP since we ordered DNS label. So your container can be accessed through ssh by default port 22 or through regular http browser with port 4200 (
http://fqdn:4200). Default container's fqdn should be like this
dns_label.region.azurecontainer.io (where dns_label and region are your data from environment variables).
Once done, you can clean up by deleting your container through cli or portal. I put together
Dockerfile and shell script for building, pushing and creating on github.