Before going into this article, I sat for a long time, smoking a lot of cigarettes, just to think about whether a developer in 2019 needs to know what the hell is called container-native . After all, I came to the conclusion: even though I don’t know how to smoke (and I don’t smoke either), a modern developer needs to know this concept.
So what is container-native but I have to work so hard? Does it help the world peace? Will it help the great technology revolution 4.0 go up a new ladder? Or help Vietnam to stand shoulder to shoulder with world powers in the world or not?
Answer is possible). And all of that is due in large part to your academic accomplishments. People who are sitting in front of a computer screen read this article.
First things first
I’m Monmen, and today I’m going to work with you to explore a very new concept but contain very old things that are container-native . This article will talk about what it is (in our naïve way), what effect it has in software development and better than some of the practices I’ve accumulated when implementing it.
To be able to follow this article, I recommend that you should have some background knowledge first:
- What is a container, what is a docker container.
- Environment variables
- Manage application state, stateless / stateful application.
For the time being, let’s go into the details.
What is container-native?
Still searching …
It is strange that I cannot find an official definition of this concept. People talk about it, people work with it, people talk about it, … it’s all based on a vague notion of what ‘container-native’ means. Fortunately, the techcrunch doctor gave a pretty close definition of the concept of container-native :
- Software that treats the container as the first-class unit of infrastructure (as opposed to, for example, treating the physical machine or the virtual machine as the first-class unit)
- Software that does not just “happen to work” in, on or around containers, but rather is purposefully designed for containers
Basically this definition says that you 1 must consider the container as the thing that will deploy your application, not a VM or physical server. The second is that you orientate container-native to be done from the beginning when creating the application, rather than just coding … Once you have one, bring it into the container and run.
It sounds true, but it’s too vague, it’s not clear what you will have to do to reach that container-native realm, right?
Characteristics of container-native application
Here are some of the features I have summarized (and also the requirements) for your app to be called container-native :
- All in containers: Everything you need to run your code is in the container.
- Stateless container: The container does not contain anything related to the state , ie the container will not contain database, session, uploaded file, etc.
- One image – multiple environments: The image to create a container can be run on multiple environments. To do this, the image will not contain a configuration related to interacting with the environment outside the container.
- Graceful start and shutdown: The start and stop applications must be handled smoothly, leaving no resource waste (such as connection, temp)
The above are just 4 basic points only. There is a lot more to do to get you to a container-native level like architecture dealing with concurrency, security, monitoring, etc. Farmers themselves just start with these.
Now let’s go deeper into each feature.
Everything is in the container
This is the first step that needs to be taken. A container similar to a black box is used to run your code. Now people just need to input it as config, the output is the result, and in that black box how to run the code, that’s our dev’s job. Here is the checklist for you to make:
-  Full system OS and system dependencies for build and run. If you need a
nodeto run code, install the node into a container. If you need
npmto manage dependencies, install
npminto a container,
npmmakes your application independent of any
globalcomponents of the external system (which is easy to conflict with each other). . Eg: 2 projects require 2 different PHP versions, …
-  Manage application dependencies with package managers like composer, npm, gem, … and install it when building the image. There is a lock dependencies mechanism to ensure the desired version when building. This helps you avoid having a nice day the author of the other package updates the code and … boom , your million dollar system goes away.
-  The most important part here: Your code . Many of you use containers like a pure virtual machine to simulate the environment and
mount code từ ngoài. However we should not do so. Building the code into a executable file, or even not building it, should be done entirely in the container and packed into the image.
These heads are easy. No need to fix too many of your archaic applications. The following characteristics make you refactor that headache.
Next is the equally important feature, which is designing a stateless container . Imagine that the cost of running a container is much lower than the cost of running a virtual machine. (The comparison is a little lame, but it’s easy to understand.) Therefore, the container deployment model will be to take advantage of the power of distribution, run multiple containers in parallel, rather than running 1-2 giant virtual machines. And so what happens?
State . Everything related to the state will be a weakness of the container deployment model. State is basically the data generated at runtime , contained in the database , files , ram , etc. that has an impact on the entire application. If you create a session file on container 1, then container 2 also needs to know the existence of that session file. Because of this, the state will not be stored in the container but pushed out. Here are some basic things that will be used outside of the app container:
-  Database (this is easy)
-  User-generated content (uploaded file is saved to s3, central file is stored, session is stored on external memory cache like redis, …)
-  Say no to Runtime static assets (like Yii2 asset), replace it with On-build static assets , which is the asset created during the build process.
-  Log (log out stdout of container)
One image – multiple environments
This feature contrasts with the Everything in the container above. It helps keep your code running environment homogeneous. But how can an image containing code can be run both locally, on dev, staging, production, …? By turning your container into a giant function, there are all necessary parameters in the input, rather than a hard fix in the function. This means that anything that belongs to the configuration , such as app parameters , DB connection information , thirt-party url , etc., will be transmitted from outside the container.
This is done by:
-  Push out all the things related to the outside – become parameters
-  Read these parameters in an external environment variable or config file
You simply configure your app so that everything can be changed through an environment variable. There are many libraries reading environment variables on languages like
dotenv , …. that you can easily use.
Tips: The most difficult application to implement this feature is SPA applications. However you can in an extremely farmer way but equally effective is to use the
envsubstcommand when the start container is described in this article.
Graceful start and shutdown
You need to manage the Application Life Cycle – the application’s life cycle. You have to know when you start the application, what will it do, when will it be ready, … And when you turn off, how will you close the connection, how to recover resources, …
This is hard to do. However, some languages you will not need to pay much attention to this problem when the web server / framework has handled it for you. However, I recommend that you should study carefully and intervene if you do not want your application to update every time an error occurs. It is simply:
-  There is a way to check when your application is ready (successfully launched) such as health check, ready check, …
-  Resolve errors that occur when the runtime cannot recover (such as loss of DB connection, …) and shut down the application intentionally.
-  Handling signals sent from the environment when the container or process is stopped (SIGTERM, SIGKILL, …)
The architecture of a simple native container application
So the bottom line is that you have to know what this container-native is for? Only your application can deploy using containers ? =)))
Sounds like salad? Containers are hot keywords of technology circles. What crime without trend trend?
However, in addition to giving it a yoke , it is also what makes your application:
- Avoid bugs: local is good but production is dead, or one day the production will be dead
- Scale is
- Suitable for cloud platforms
- Suitable for micro-service architecture and distributed model
Sounds stimulating? Are you ready to embark on container-native application right away or are you waiting?