Can we run an application that is configured to run on multi-node AWS EC2 K8s cluster using kops into local kubernetes cluster (using kubeadm)? - amazon-web-services

Can we run an application that is configured to run on multi-node AWS EC2 K8s cluster using kops (project link) into local Kubernetes cluster (setup using kubeadm)?
My thinking is that if the application runs in k8s cluster based on AWS EC2 instances, it should also run in local k8s cluster as well. I am trying it locally for testing purposes.
Heres what I have tried so far but it is not working.
First I set up my local 2-node cluster using kubeadm
Then I modified the installation script of the project (link given above) by removing all the references to EC2 (as I am using local machines) and kops (particularly in their create_cluster.py script) state.
I have modified their application yaml files (app requirements) to meet my localsetup (2-node)
Unfortunately, although most of the application pods are created and in running state, some other application pods are unable to create and therefore, I am not being able to run the whole application on my local cluster.
I appreciate your help.

It is the beauty of Docker and Kubernetes. It helps to keep your development environment to match production. For simple applications, written without custom resources, you can deploy the same workload to any cluster running on any cloud provider.
However, the ability to deploy the same workload to different clusters depends on some factors, like,
How you manage authorization and authentication in your cluster? for example, IAM, IRSA..
Are you using any cloud native custom resources - ex, AWS ALBs used as LoadBalancer Services
Are you using any cloud native storage - ex, your pods rely on EFS/EBS volumes
Is your application cloud agonistic - ex using native technologies like Neptune
Can you mock cloud technologies in your local - ex. Using local stack to mock Kinesis, Dynamo
How you resolve DNS routes - ex, Say you are using RDS n AWS. You can access it using a route53 entry. In local you might be running a mysql instance and you need a DNS mechanism to discover that instance.
I did a google search and looked at the documentation of kOps. I could not find any info about how to deploy to local, and it only supports public cloud providers.
IMO, you need to figure out a way to set up your local EKS cluster, and if there are any usage of cloud native technologies, you need to figure out an alternative way about doing the same in your local.

The true answer, as Rajan Panneer Selvam said in his response, is that it depends, but I'd like to expand somewhat on his answer by saying that your application should run on any K8S cluster given that it provides the services that the application consumes. What you're doing is considered good practice to ensure that your application is portable, which is always a factor in non-trivial applications where simply upgrading a downstream service could be considered a change of environment/platform requiring portability (platform-independence).
To help you achieve this, you should be developing a 12-Factor Application (12-FA) or one of its more up-to-date derivatives (12-FA is getting a little dated now and many variations have been suggested, but mostly they're all good).
For example, if your application uses a database then it should use DB independent SQL or no-sql so that you can switch it out. In production, you may run on Oracle, but in your local environment you may use MySQL: your application should not care. The credentials and connection string should be passed to the application via the usual K8S techniques of secrets and config-maps to help you achieve this. And all logging should be sent to stdout (and stderr) so that you can use a log-shipping agent to send the logs somewhere more useful than a local filesystem.
If you run your app locally then you have to provide a surrogate for every 'platform' service that is provided in production, and this may mean switching out major components of what you consider to be your application but this is ok, it is meant to happen. You provide a platform that provides services to your application-layer. Switching from EC2 to local may mean reconfiguring the ingress controller to work without the ELB, or it may mean configuring kubernetes secrets to use local-storage for dev creds rather than AWS KMS. It may mean reconfiguring your persistent volume classes to use local storage rather than EBS. All of this is expected and right.
What you should not have to do is start editing microservices to work in the new environment. If you find yourself doing that then the application has made a factoring and layering error. Platform services should be provided to a set of microservices that use them, the microservices should not be aware of the implementation details of these services.
Of course, it is possible that you have some non-portable code in your system, for example, you may be using some Oracle-specific PL/SQL that can't be run elsewhere. This code should be extracted to config files and equivalents provided for each database you wish to run on. This isn't always possible, in which case you should abstract as much as possible into isolated services and you'll have to reimplement only those services on each new platform, which could still be time-consuming, but ultimately worth the effort for most non-trival systems.

Related

Microservices same as cloud services or webservices?

Firstly, I apologize for the rather basic question. I am just beginning to learn about Microservices Architecture and would like to get my basics right.
I was wondering if topics such as AWS cloud services/web services imply the Microservices architecture. For instance, if someone is working on an AWS project does that mean that he is using a microservice architecture? I do understand AWS, Docker etc is more of a platform. Are they exclusively for Microservices?
I would really appreciate a short clarification
Microservices, cloud infrastructure like Amazon Web Services, and container infrastructure like Docker are three separate things; you can use any of these independently of the others.
"Microservices" refers to a style of building a large application out of independently-deployable parts that communicate over the network. A well-designed microservice architecture shouldn't depend on sharing files between components, and could reasonably run distributed across several systems. Individual services could run on bare-metal hosts and outside containers. This is often in contrast to a "monolithic" application, a single large deployable where all parts have to be deployed together, but where components can communicate with ordinary function calls.
Docker provides a way of packaging and running applications that are isolated from their host system. If you have an application that depends on a specific version of Python with specific C library dependencies, those can be bundled into a Docker image, and you can just run it without needing to separately install them on the host.
Public-cloud services like AWS fundamentally let you rent someone else's computer by the hour. An AWS Elastic Compute Cloud (EC2) instance literally is just a computer that you can ssh into and run things. AWS, like most other public-cloud providers offers a couple of tiers of services on top of this; a cloud-specific networking and security layer, various pre-packaged open-source tools as services (you can rent a MySQL or PostgreSQL database by the hour using AWS RDS, for example), and then various proprietary cloud-specific offerings (Amazon's DynamoDB database, analytics and machine-learning services). This usually gives you "somewhere to run it" more than any particular design features, unless you're opting to use a cloud's proprietary offerings.
Now, these things can go together neatly:
You design your application to run as microservices; you build and unit-test them locally, without any cloud or container infrastructure.
You package each microservice to run in a Docker container, and do local integration testing using Docker Compose, without any cloud infrastructure.
You further set up your combined application to deploy in Kubernetes, using Docker Desktop or Minikube to test it locally, again without any cloud infrastructure.
You get a public-cloud Kubernetes cluster (AWS EKS, Google GKE, Azure AKS, ...) and deploy the same application there, using the cloud's DNS and load balancing capabilities.
Again, all of these steps are basically independent of each other. You could deploy a monolithic application in containers; you could deploy microservices directly on cloud compute instances; you could run containers in an on-premises environment or directly on cloud instances, instead of using a container orchestrator.
No, using a cloud provider does not imply using a microservice architecture.
AWS can be (and is often) used to spin up a monolithic service, e.g. just a single EC2 server which uses a single RDS database.
Utilizing Docker and a container orchestrator like ECS or EKS, also does not mean on its own that one has a microservice architecture. If you split your backend and frontend into two Docker containers that get run on ECS, that's really not a microservice architecture. Even if you'd horizontally scale them, so you'd have multiple identical containers running for both the backend and frontend service, they still wouldn't be thought of as microservices.

Can we migrate on-prem standalone apps to Runtime Fabric with Self-managed kubernetes on AWS?

I want to migrate Mule applications deployed on Mule standalone (on-Premise) to Anypoint Runtime Fabric (RTF) Self managed Kubernetes on AWS, but I could not find any document on this.
Any ideas or any document available on this please share it.
Thanks in advance
Mule applications run exactly the same on-prem, on CloudHub or in Anypoint Runtime Fabric. It is only if your applications make assumptions about their environment that you are going to need to make adjustments. For example any access to the filesystem (reading a file from some directory) or some network access that is not replicated to the Kubernetes cluster. A common mistake is when developers use Windows as the development environment and are not aware that the execution in a container environment will be different. You may not be aware of those assumptions. Just test the application and see if there are any issues. It is possible it will run fine.
The one exception is if the applications share configurations and/or libraries through domains. Since applications in Runtime Fabric are self isolated, domains are not supported. You need to include the configurations into each separate applications. For example you can not have an HTTP Listener config where several applications share the same TCP Port to listen to incoming requests. That should be replaced by using Runtime Fabric inbound configurations.
About the deployment, when you deploy to a new deployment model, it is considered a completely new application, with no relationship to the previous one. There is no "migration" of deployments. You can deploy using Runtime Manager or Maven. See the documentation. Note that the documentation states that to deploy with Maven you first must publish the application to Exchange.
Yes, you can.
In general, it is an easy exercise. However, things may go a little bit complicated when you have lots of dependencies on the persistent object store. It may require slight code refactoring in the worst case scenario. If you are running on-prem in cluster mode, then you are using HazelCast which is also available in RTF.
Choosing the Self-managed Kubernetes in EKS have some extra responsibilities. If you and your team have good expertise on Kubernetes and AWS then it is a great choice. Keep in mind that the Anypoint runtime console allows at most 8 replicas for each app. However, if you are using CI/CD pipeline, you should be able to scale it more.
There is no straightforward documentation as the majority of work is related to setup your EKS and associated network, ports, ingress, etc.

Spring boot/cloud microservices on AWS

I have created a Spring cloud microservices based application with netflix APIs (Eureka, config, zuul etc). can some one explain me how to deploy that on AWS? I am very new to AWS. I have to deploy development instance of my application.
Do I need to integrate docker before that or I can go ahead without docker as well.
As long as your application is self-contained and you have externalised your configurations, you should not have any issue.
Go through this link which discusses what it takes to deploy an App to Cloud Beyond 15 factor
Use AWS BeanStalk to deploy and Manage your application. Dockerizing your app is not a predicament inorder to deploy your app to AWS.
If you use an EC2 instance then it's configuration is no different to what you do on your local machine/server. It's just a virtual machine. No need to dockerize or anything like that. And if you're new to AWS, I'd rather suggest to to just that. Once you get your head around, you can explore other options.
For example, AWS Beanstalk seems like a popular option. It provides a very secure and reliable configuration out of the box with no effort on your part. And yes, it does use docker under the hood, but you won't need to deal with it directly unless you choose to. Well, at least in most common cases. It supports few different ways of deployment which amazon calls "Application Environments". See here for details. Just choose the one you like and follow instructions. I'd like to warn you though that whilst Beanstalk is usually easier then EC2 to setup and use when dealing with a typical web application, your mileage might vary depending on your application's actual needs.
Amazon Elastic container Service / Elastic Kubernetes Service is also a good option to look into.
These services depend on the Docker Images of your application. Auto Scaling, Availability cross region replication will be taken care by the Cloud provider.
Hope this helps.

Docker for AWS vs pure Docker deployment on EC2

The purpose is production-level deployment of a 8-container application, using swarm.
It seems (ECS aside) we are faced with 2 options:
Use the so called docker-for-aws that does (swarm) provisioning via a cloudformation template.
Set up our VPC as usual, install docker engines, bootstrap the swarm (via init/join etc) and deploy our application in normal EC2 instances.
Is the only difference between these two approaches the swarm bootstrap performed by docker-for-aws?
Any other benefits of docker-for-aws compared to a normal AWS VPC provisioning?
Thx
If you need to provide a portability across different cloud providers - go with AWS CloudFormation template provided by Docker team. If you only need to run on AWS - ECS should be fine. But you will need to spend a bit of time on figuring out how service discovery works there. Benefit of Swarm is that they made it fairly simple, just access your services via their service name like they were DNS names with built-in load-balancing.
It's fairly easy to automate new environment creation with it and if you need to go let's say Azure or Google Cloud later - you simply use template for them to get your docker cluster ready.
Docker team has put quite a few things into that template and you really don't want to re-create them yourself unless you really have to. For instance if you don't use static IPs for your infra (fairly typical scenario) and one of the managers dies - you can't just restart it. You will need to manually re-join it to the cluster. Docker for AWS handles that through IPs sync via DynamoDB and uses other provider specific techniques to make failover / recovery work smoothly. Another example is logging - they push your logs automatically into CloudWatch, which is very handy.
A few tips on automating your environment provisioning if you go with Swarm template:
Use some infra automation tool to create VPC per environment. Use some template provided by that tool so you don't write too much yourself. Using a separate VPC makes all environment very isolated and easier to work with, less chance to screw something up. Also, you're likely to add more elements into those environments later, such as RDS. If you control your VPC creation it's easier to do that and keep all related resources under the same one. Let's say DEV1 environment's DB is in DEV1 VPC
Hook up running AWS Cloud Formation template provided by docker to provision a Swarm cluster within this VPC (they have a separate template for that)
My preference for automation is Terraform. It lets me to describe a desired state of infrastructure rather than on how to achieve it.
I would say no, there are basically no other benefits.
However, if you want to achieve all/several of the things that the docker-for-aws template provides I believe your second bullet point should contain a bit more.
E.g.
Logging to CloudWatch
Setting up EFS for persistence/sharing
Creating subnets and route tables
Creating and configuring elastic load balancers
Basic auto scaling for your nodes
and probably more that I do not recall right now.
The template also ingests a bunch of information about related resources to your EC2 instances to make it readily available for all Docker services.
I have been using the docker-for-aws template at work and have grown to appreciate a lot of what it automates. And what I do not appreciate I change, with the official template as a base.
I would go with ECS over a roll your own solution. Unless your organization has the effort available to re-engineer the services and integrations AWS offers as part of the offerings; you would be artificially painting yourself into a corner for future changes. Do not re-invent the wheel comes to mind here.
Basically what #Jonatan states. Building the solutions to integrate what is already available is...a trial of pain when you could be working on other parts of your business / application.

Choosing the right AWS Services and software tools

I'm developing a prototype IoT application which does the following
Receive/Store data from sensors.
Web application with a web-based IDE for users to deploy simple JavaScript/Python scripts which gets executed in Docker Containers.
Data from the sensors gets streamed to these containers.
User programs can use this data to do analytics, monitoring etc.
The logs of these programs are outputted to the user on the webapp
Current Architecture and Services
Using one AWS EC2 instance. I chose EC2 because I was trying to figure out the architecture.
Stack is Node.js, RabbitMQ, Express, MySQl, MongoDB and Docker
I'm not interested in using AWS IoT services like AWS IoT and Greengrass
I've ruled out Heroku since I'm using other AWS services.
Questions and Concerns
My goal is prototype development for a Beta release to a set of 50 users
(hopefully someone else will help/work on a production release)
As far as possible, I don't want to spend a lot of time migrating between services since developing the product is key. Should I stick with EC2 or move to Beanstalk?
If I stick with EC2, what is the best way to handle small-medium traffic? Use one large EC2 machine or many small micro instances?
What is a good way to manage containers? Is it worth it use swarm and do container management? What if I have to use multiple instances?
I also have small scripts which have status of information of sensors which are needed by web app and other services. If I move to multiple instances, how can I make these scripts available to multiple machines?
The above question also holds good for servers, message buses, databases etc.
My goal is certainly not production release. I want to complete the product, show I have users who are interested and of course, show that the product works!
Any help in this regard will be really appreciated!
If you want to manage docker containers with least hassle in AWS, you can use Amazon ECS service to deploy your containers or else go with Beanstalk. Also you don't need to use Swarm in AWS, ECS will work for you.
Its always better to scale out rather scale up, using small to medium size EC2 instances. However the challenge you will face here is managing and scaling underlying EC2's as well as your docker containers. This leads you to use Large EC2 instances to keep EC2 scaling aside and focus on docker scaling(Which will add additional costs for you)
Another alternative you can use for the Web Application part is to use, AWS Lambda and API Gateway stack with Serverless Framework, which needs least operational overhead and comes with DevOps tools.
You may keep your web app on Heroku and run your IoT server in AWS EC2 or AWS Lambda. Heroku is on AWS itself, so this split setup will not affect performance. You may heal that inconvenience of "sitting on two chairs" by writing a Terraform script which provisions both EC2 instance and Heroku app and ties them together.
Alternatively, you can use Dockhero add-on to run your IoT server in a Docker container alongside your Heroku app.
ps: I'm a Dockhero maintainer