By Liu Sheng
To solve the common pain points of traditional applications involved with the cloud - such as slow upgrade cycles, bloated infrastructure, and difficulty to find faults - the concept of Cloud Native was born.
Cloud Native can improve the efficiency of application development, help to change the organizational structure of an enterprise, and even affect the overall decision-making of a company. Cloud Native applications are already becoming a fast moving torrent in cloud space today. In the world of containers, for example, Kubernetes has become the community standard for container orchestration and management operations because it provides a portable model that is also shared with Cloud Native applications where it can abstract application services into multiple resource types, such as deployment and device class. In this context, one new point of interest all across the community is how to make development process—which has traditionally involved DevOps—more efficient with the Cloud Native to achieve higher performance levels. The answer for many customers is switching to using the GitOps architecture with Cloud Native applications.
Compared with the more newish GitOps, you may be a bit more familiar with DevOps. At first, DevOps aimed to break the barriers between the development, testing, and operation departments with the hope of minimizing human error while also improving the iteration efficiency of application versions. These improvements were empowered by an extended use of automation coupled with programmed scripts. Now, container technology with its lightweight and standardized capabilities - in the era of Cloud Native - DevOps is now empowered more than ever to bring home better efficiency through automation. No matter how the technology is updated and iterated, the main core demand of DevOps remains unchanged, which of course is to increase the frequency and efficiency of application iteration and reduce costs. Well, GitOps simply is the logical extension of DevOps. At Its core, there is the goal is to release applications more efficiently and securely.
Before we go on to discuss anything else, let's first look at some of the pain points of users working with DevOps.
Of these pain points, the first is probably that users struggle with how to automatically promote the non-differential release of applications in the environment stack using DevOps. With DevOps, you usually have three environments: the test environment, the production environment, and the pre-release environment. For an application, the usual scenario is to deploy different branches to corresponding environments. For example, the master branch is usually deployed to the online environment, the last branch is deployed to the pre-release environment, and other development branches are deployed to the test environment. Currently, most of the practices are to create different jobs, pull different source code branches, and deploy them to different environments, or to use the same job, and add different build parameters to determine how to build and release. However, these practices are rather arduous both for beginning users and seasoned users alike, because these practices are not easy to manage. Just look at all the steps involved the following figure:
The second pain point of many users is that the releasing permission of the production environment generally needs to be strictly controlled, and usually only the application administrator or O&M administrator must have the production release permission. In communication with some customers, I learned that one implementation method used is to create different jobs in the same CICD environment, and then isolate these jobs based on the role access control policy, so that only personnel with the administrator permission can see the jobs used for the production release. However, a more direct, less convoluted method, which deals with less strict access control, is to create a CICD environment specifically for the production release. This method isn't perfect either, however, as it wastes resources and reduces the frequency of application iteration.
The third pain point is that users find it difficult to increase the frequency of application iterations and focus on the expansion of new or innovative businesses. One reason for this difficult is that developers see a gap in the synchronization and feedback processes between running applications or the results of tests on these applications. Adding to this, when online businesses encounter problems, they need to figure out a way to quickly locate, reproduce, and roll back the problems, which isn't that easy with this model either.
All of these three pain point are just a few of the pain points that I have learned about on communication with users. Now, let's revisit these pain points to see how the GitOps model is designed and how it can improve the overall development process.
Let me discuss some of the core demands when designing the GitOps release model. The first demand was version management. We hoped that the version number of each released application could be associated with the GIT Commit ID. This has the advantage that each change has a history which can be tracked, and faults as a result can be located and fixed more quickly and easily. The second demand is a better baseline management system. We will go into detail about two types of baseline management system later in this blog. The third demand is how to better implement secure releases—this including the releasing permission management and security approval processes. The last of these demands is how to better allow developers to quickly obtain feedback. Below is a quick summary of these demands:
To discuss the first point, the core idea of GitOps is to store the declarative infrastructure and applications of the application system in a Git repository. All operation changes to the application come from the updates of the Git repository, which is also the origin of the name, GitOps. This can help to simplify the overall structure. Actually, in the past, this was not possible with DevOps. We may store the scripts for building and deploying the application and the configuration files in the same repository as the application source code. This brings two problems: developers may need to maintain the deployment script or configuration file, so they cannot concentrate on product development. Next, the deployment script sometimes involves sensitive environment information and is not secure enough. Therefore, we had to separate the application source code repository from the build repository for management.
Next, let's take a look at the baseline management. The baseline management can be said to be divided into two types: one is the environment stack baseline. As shown in the figure, the setting is that only the code of the master branch can be deployed in the production environment, only the code of the latest branch can be deployed in the pre-release environment, and other development branches can be deployed in the preview environment. With this, the preview environment here also works as the test environment. However, at the same time, test environment is dynamically destroyed each time after the development branch passes testing and verification and is successfully merged into the latest branch. This can be easy to implement in the Kubernetes container cluster.
Naturally, however, different policies can be used in specific scenarios. In other words, baseline policies have a great level of flexibility. This baseline can be called a small baseline. It is used as a central way to manage the advancement of applications in the preview, pre-release, and production environments. The large baseline is for the management of online release versions, which can ensure that we can quickly roll back to the previous stable version when a fault occurs online. This is essential in the production release management. In GitOps, we can quickly locate faults to the exact "git commit." Consider the following figures to have a better visualization of these baselines:
Now, let's take a quick look at the systems of permission management and security approval of the application releasing process involved with GitOps. The permission management in GitOps can summarized as being implemented by controlling code merging processes. In this model, developers, or non-administrators, do not need to have special access permissions for CICD environments, such as for Jenkins. Rather, they only require the permission to view logs—this greatly simplifies things—if you remember the pain point we discusses of the convoluted structure of access management involved with DevOps. On the Git side, developers only have the permission to push code to the development branch, but can also apply the permissions needed for merging the code to the latest branch, specifically which are the permissions to submit MR/PR. After a developer creates a new MR/PR, the building will be triggered to deploy the application to the preview environment. The administrator determines whether to accept this MR/PR by checking whether the build and deployment of the new branch has passed a series of tests and verification. Only after the administrator accepts the merger of MR/PR, the latest branch code will be re-built and re-deployed to the pre-release environment, thus achieving the purpose of application release security approval through the acceptance and rejection of MR/PR. Check out this figured for an overall perspective of how this works:
Last, let's talk about how to get feedback quickly and realize the interaction between team members using GitOps. This includes two parts: one is that after pushing the source code, developers can obtain the build results in real time through things like email, DingTalk, and Slack, to develop and test their own applications more effectively and quickly. The other part is that developers can view the feedback of automated tests, application preview links, and comments from other team members on the MR/PR page. Below is this process visualized:
The following figure to come in this section is a diagram of the overall architecture and time sequence for managing the releasing of applications to different Kubernetes clusters using GitOps. First, the application source code is separated from the build source code. A dotted line can be seen at the top. The part above the dotted line is visible to common developers, and they have the permission to operate in this part. The remaining part is where administrators have the permission to operate. The green area is the pipeline task of Jenkins. A developer does not have the permission to create a job or build a job in the Jenkins environment, but only has permission to view the log to build a job. This common application is in the Git repository.
It has different branches and has a certain set relationship. Each build (such as preview-pipeline and prod-pipeline) will be done from another Git repository, where some information can be stored. Only the application administrator can see the information, and common developers have no permission to view it. Then, we need to set the application release environment stack. In this example, we have the settings for the preview environment, the pre-release environment, and the production environment. The release of applications in the pre-release environment and production environment requires the security approval of the administrator.
Finally, this is a time sequence diagram. The developer submits a new feature and creates an MR pointing to the latest branch. Then the action of creating the MR will trigger the build of preview-pipeline, and the build will pull the build repository of preview-pipeline. The build repository stores the build script, and the information of the environment to be deployed.
Then, an automated build process is executed. First, the application source code is pulled from the application source code repository for building, static code testing, and unit testing, and the test results is fed back to the MR. Then, the container image is packaged and pushed to the image repository. At last, the application is deployed to the Kubernetes cluster through the file, and a functional test will be conducted. The test results is also fed back to the MR. After deployment, relevant application information is collected and sent to the development group through DingTalk. After receiving the DingTalk notification, developers can click the link to view the application status. If a problem exists, they can re-develop and re-submit the application, and repeat the previous process. If no problem exists, they can request the administrator to approve and merge the code into the latest branch. When the latest branch and master branch are updated, a process similar to the previous build process will be triggered to push the application to the pre-release environment and the production environment.
Aliware - February 5, 2021
Alibaba Clouder - July 12, 2019
Alibaba Clouder - November 12, 2018
Alibaba Clouder - December 3, 2018
Alibaba Developer - September 16, 2020
Alibaba Cloud MaxCompute - September 18, 2019
Accelerate software development and delivery by integrating DevOps with the cloudLearn More
Alibaba Cloud Container Service for Kubernetes is a fully managed cloud container management service that supports native Kubernetes and integrates with other Alibaba Cloud products.Learn More
Accelerate and secure the development, deployment, and management of containerized applications cost-effectively.Learn More
A secure image hosting platform providing containerized image lifecycle managementLearn More
More Posts by Alibaba Container Service