Kustomize Production Combat - Injection Monitoring APM Agent
This article was last updated on: July 24, 2024 am
Introduction to Kustomize
Kubernetes native configuration management toolIt customizes the use of out-of-the-box apps by introducing a template-free way to customize app configurations. Currently, inkubectl
Built in, passed apply -k
ready to use.
Kustomize traverses the Kubernetes manifest to add, remove, or update configuration options without forking. It can be used both as a standalone binary and askubectl
is used by native features.
Kustomize advantage
- 📢 Fully declarative approach to configuration customization
- 🍸 Build in natively
kubectl
middle - 🎶 Manage any number of uniquely customized Kubernetes configurations
- ☸ Supplied as a standalone binary for extension and integration into other services
- 📃 Each artifact used by customization is pure YAML and can be validated and processed
- 🔁 Kustomize supports fork/modify/rebase workflows
- 🔧 It is perfectly supported by GitOps tools such as ArgoCD
What Kustomize can do
📚️ Reference:
👉️URL: https://mp.weixin.qq.com/s/gmwkoqZpKbq1hM0B8XxQNw
In Kubernetes we use YAML files to declare how our application should be deployed to the underlying cluster, these YAML files contain application definitions, tags for governance needs, logs, security context definitions, resource dependencies, etc., when our application scales to hundreds or thousands of pods, managing these YAML files will become a nightmare.
Typically, there are many projects to manage, and at the same time there are multiple different deployment environments: development, test, UAT, and production. There may even be different public cloud Kubernetes distributions. Then each environment requires a variety of YAML files, but they directly differ only in some details. For example: image tag, service name, label, whether there is storage, etc.
If it’s all manual, the maintenance is huge and error-prone.
Compared with Helm, Kustomize is more suitable for solving the pain points of this scenario: there is a base template to manage all the basic YAML of a project, and more advanced requirements are overlayed through overlays.
Another typical scenario is fusing configuration data from different users (e.g. from devops/SRE and developers).
It can also be combined with helm for some more advanced configurations.
Let’s take a typical scenario today: production deployment is automatically injected into commercial (e.g. AppDynamics) or open source (SkyWalking/pinpoint) out-of-the-box Java Agent.
Hands-on - Monitor APM Agents via Kustomize injection
Background overview
In Java, for example, the APM Agent package here is an out-of-the-box Agent jar package provided by commercial (e.g., AppDynamics) or open source (SkyWalking/pinpoint) products.
In the Kubernetes scenario, there are several considerations:
- Separation from application images;
- Reuse
The Agent jar package is made into a general image, copied to the running application container through the init container, and automatically set the parameters by configuring environment variables.
✍️ Author’s Note:
In fact, commercial APM has the function of Helm or Operator to implement automatic installation and configuration, but the experience in actual use is not good, which is not suitable for our actual scenarios.
Monitor APM Agent steps through Kustomize injection
The steps are briefly described below: (using the AppDynamics Java Agent as an example)
- Get the original Deployment yaml file (pass
kubectl
andkubectl neat
plugins) - Pass each deployment via Kustomize
patches
Implement the following steps:- inject
initContainers
:appd-agent-attach-java
shouldinitContainers
Yes:volumeMounts
: Mount the Java Agent JAR package to the volume implementation share;
- In the Deployment -> application’s own container, add the following parameters:
volumeMounts
: Mount the Java Agent JAR package to the volume implementation share;- Add env information required by various AppD Java agents;
volumes
Sharing is achieved through tmpdir.
- inject
Kustomize directory structure
The directory structure is as follows:
1 |
|
Among them, the deployment of all subsequent applications that need to be injected into the APM Agent is placed base
directory.
base/kustomization.yaml
1 |
|
🐾Note:
Here’s a note, currently resources
File glob matching is not supported, and the specific issue can be found here:
But there is a temporary solution, which is by executing the command:kustomize edit add resource base/*.yml
After running, it will iterate through the file blob and add the results one by one kustomization.yaml
Middle.
The file after running might look like this:
1 |
|
overlays/prod/kustomization.yaml
1 |
|
🐾 Note:
It’s useless here patchesStrategicMerge
, but usedpatches
. The purpose is to batch patches. The above YAML means, willappd_agent.yaml
Applies to all Deployment manifests.
overlays/prod/appd_agent.yaml
The specific contents are as follows:
1 |
|
The above content will not be detailed, you can refer to this article to understand several ideas of APM Agent injection:
🐾 Note:
In practice, there are several points to note in the above content:
-
spec/template/spec/containers/name
Here is often the name of the app, such asfoo
Ifappd_agent.yaml
To patch correctly, you also need to write the same container name; This is not a problem for an application, but it is very inconvenient for batch automation/GitOps.- I wanted to use Kustomize before
nameReference
To achieve it, but I didn’t figure it out, there are those who know can teach me - ✔️20220706 11:00 update: Kustomize is strictly followed for security reasons
metadata.name
merged, so it can’t be solved by Kustomize; But it can passyq
(similar to jq, but for yaml) to solve, the example command is:i=foo yq -i '.spec.template.spec.containers[0].name="strenv(i)"' appd_agent.yaml
- I wanted to use Kustomize before
-
The previous environment variables, when deployed manually, are as follows:
1
2- name: APPDYNAMICS_AGENT_APPLICATION_NAME
value: fooWrite directly to death, which is not convenient for batch automation/GitOps. The solution is to take advantage of Kubernetes env
valueFrom
Ability. Change it to the following.1
2
3valueFrom:
fieldRef:
fieldPath: metadata.name -
appd_agent.yaml
The deployment name does not matter, because it will still be the name of the patch list; Other than thatappd_agent.yaml
Don’t bring it eithernamespace
, convenient batch automation/GitOps, can be adapted to all NameSpace.
Automation scripts
Finally, the automation script demo looks like this: (Assuming the script is located in /inject-appd-agent/scripts/
under the directory)
1 |
|
Run the above script to automatically inject AppD Java Agent into all deployments and Rollout takes effect.
🎉🎉🎉