Argo CD is a continuous deployment tool for Kubernetes that follows the declarative GitOps philosophy. argo CD automatically synchronizes and deploys applications when Git repositories change.
Argo CD follows the GitOps model, using Git repositories as the true source for defining the required application state, and Argo CD supports multiple Kubernetes manifests.
- kustomize
- helm charts
- ksonnet applications
- jsonnet files
- Plain directory of YAML/json manifests
- Any custom config management tool configured as a config management plugin
Argo CD automatically deploys the required application state in a specified target environment, and application deployment can track updates to branches, tags, or fix to a specified version of the manifest at Git commit time.
Argo CD is implemented through a Kubernetes controller that continuously watches running applications and compares the current live state with the desired target state (specified in the Git repository). Deployed applications whose actual state differs from the target state are considered to be in OutOfSync
state, and the Argo CD reports showing these differences, while providing tools to automatically or manually synchronize the state to the desired target state. Any changes made to the desired target state in the Git repository can be automatically applied back to the specified target environment.
The following is a brief description of some of the main components in Argo CD.
API Service: The API Service is a gRPC/REST service that exposes the interfaces used by the Web UI, CLI and CI/CD system and has the following main functions.
- Application management and status reporting
- Execution of application operations (e.g., synchronization, rollback, user-defined operations)
- Storage repository and cluster credential management (stored as K8S Secrets objects)
- Authentication and authorization to external identity providers
- RBAC
- Listener/forwarder for Git webhook events
Repository Service: The Storage Repository Service is an internal service that maintains a local cache of Git repositories that hold application manifests. It is responsible for generating and returning Kubernetes manifests when the following inputs are provided.
- repository URL
- revision version (commit, tag, branch)
- application path
- Template configuration: parameters, ksonnet environment, helm values.yaml, etc.
Application Controller : The application controller is a Kubernetes controller that continuously watches the running application and compares the current live state with the desired target state (specified in the repo). It detects the OutOfSync
state of the application and takes some steps to synchronize the state, and it is responsible for invoking hooks for any user-defined lifecycle events (PreSync, Sync, PostSync).
Features
- Automatic deployment of applications to specified target environments
- Support for multiple configuration management/template tools (Kustomize, Helm, Ksonnet, Jsonnet, plain-YAML)
- Ability to manage and deploy to multiple clusters
- SSO integration (OIDC, OAuth2, LDAP, SAML 2.0, GitHub, GitLab, Microsoft, LinkedIn)
- Multi-tenancy and RBAC policies for authorization
- Rollback/anytime rollback to any application configuration committed in the Git repository
- Health analysis of application resources
- Automatic configuration detection and visualization
- Automatic or manual synchronization of applications to the desired state
- Web UI that provides a real-time view of application activity
- CLI for automation and CI integration
- Webhook integration (GitHub, BitBucket, GitLab)
- AccessTokens for automation
- PreSync, Sync, PostSync Hooks to support complex application deployments (e.g. blue/green and canary releases)
- Auditing of application events and API calls
- Prometheus monitoring metrics
- ksonnet/helm parameters for overriding Git
Core Concepts
- Application: an application, a set of Kubernetes resources defined by a resource manifest, which is a CRD resource object
- Application source type: the tool used to build the application
- Target state: the target state, the desired state of the application, represented by a file in the Git repository
- Live state: live state, the real state of the application, such as which Pods have been deployed
- Sync status: Sync status indicates whether the live state matches the target state, and whether the deployed application is the same as described by Git?
- Sync: Sync refers to the process of migrating an application to its target state, for example by applying changes to a Kubernetes cluster
- Sync operation status: Sync operation status refers to whether the sync was successful or not.
- Refresh: Refresh means comparing the latest code in Git to the live state and figuring out what the difference is.
- Health: the health of the application, is it running properly? Can it service requests?
- Tool: Tools are tools that create manifests from file directories, such as Kustomize or Ksonnet.
- Configuration management tool: Configuration management tool
- Configuration management plugin: Configuration management plugin
Install
Of course, the prerequisite is a kubectl-accessible Kubernetes cluster, which can be installed directly using the following command, here we install the latest stable version v2.4.9.
If you want to use it in a production environment, you can deploy a highly available version of HA using the following command.
This will create a new namespace argocd to which Argo CD’s services and application resources will be deployed.
|
|
If you’re not interested in features like UI, SSO, or multi-cluster management, and just want to sync application changes to the cluster, then you can disable authentication using the
-disable-auth
flag, which can be done with the commandkubectl patch deploy argocd-server -n argocd -p '[{"op": "add ", "path": "/spec/template/spec/containers/0/command/-", "value": "--disable-auth"}]' --type json
to achieve this.
We can then install the CLI tools locally for easy operation of the Argo CD. We can view the latest version of the Argo CD on the Argo CD Git repository release page or run the following command to get the version.
|
|
Replace VERSION
in the following command with the version of the Argo CD you want to download.
|
|
Give executable permissions to the argocd CLI.
|
|
Now we are ready to use the argocd
command. If you are a Mac, you can install it directly with brew install argocd
.
The Argo CD will run a gRPC service (used by the CLI) and an HTTP/HTTPS service (used by the UI), both protocols are exposed by the argocd-server
service on the following ports.
- 443 - gRPC/HTTPS
- 80 - HTTP (redirects to HTTPS)
We can expose the service to the public by configuring the Ingress. For other Ingress controller configurations, you can refer to the official documentation at https://argo-cd.readthedocs.io/en/stable/operator-manual/ingress/ for configuration.
Argo CD provides multiple protocols (gRPC/HTTPS) on the same port (443), so it is a bit tricky when we define individual nginx ingress objects and rules for the argocd service, because the nginx.ingress.kubernetes.io/backend -protocol
annotation annotation can only accept one backend protocol (e.g., HTTP, HTTPS, GRPC, GRPCS).
In order to expose the Argo CD APIServer with a single ingress rule and hostname, you must use the annotation nginx.ingress.kubernetes.io/ssl-passthrough
to pass a TLS connection and verify the TLS on the Argo CD APIServer on the Argo CD APIServer.
|
|
The above rule checks for TLS on the Argo CD APIServer, which detects the protocol being used and responds appropriately. Note that the nginx.ingress.kubernetes.io/ssl-passthrough
annotation requires the -enable-ssl-passthrough
flag to be added to the command line arguments of nginx-ingress-controller
.
Since each Ingress object for ingress-nginx
supports only one protocol, another approach is to define two Ingress objects. One for HTTP/HTTPS and the other for gRPC.
The Ingress object for HTTP/HTTPS is shown below.
|
|
The Ingress object corresponding to the gRPC protocol is shown below.
|
|
Then we need to run APIServer with TLS disabled. edit the deployment argocd-server to add the --insecure
flag to the argocd-server command, or simply set it in the argocd-cmd-params-cm
ConfigMap -server.insecure: "true"
and that’s it.
Once created, we can access the Argo CD service via argocd.k8s.local
, but note that the certificate we configured here is self-signed, so the first time you access it, you will be prompted that it is not secure, so force a jump.
By default, the initial password for the admin
account is automatically generated and stored in plaintext under the password
field of the Secret object named argocd-initial-admin-secret
in the namespace of the Argo CD installation, which we can get with the following command.
|
|
You can log in to Dashboard using the username admin
and the password output above.
We can also log in via the ArgoCD CLI command line tool.
|
|
Note that the login address here is the service address exposed by gRPC.
After a successful CLI login, the password can be changed using the command shown below.
|
|
Configuring Clusters
Since Argo CD supports deploying applications to multiple clusters, if you want to deploy your application to an external cluster, you need to register the authentication information of the external cluster to Argo CD first. If you are deploying internally (the same cluster running Argo CD, no configuration is required by default), you can directly use https://kubernetes.default.svc
as the K8S APIServer address of the application.
First list all cluster contexts currently in kubeconfig
.
|
|
Select a context name from the list and provide it to argocd cluster add CONTEXTNAME
, for example, for the kind-kind
context, run the following command.
|
|
Creating Applications
The Git repository at https://github.com/argoproj/argocd-example-apps.git is a sample repository containing a guestbook application that we can use to demonstrate how the Argo CD works.
Creating an application via the CLI
We can create an application with the argocd app create xxx
command.
|
|
Simply execute the command shown below.
Creating an app via UI
In addition to creating applications through the CLI tool, we can also create them through the UI interface by locating the argocd.k8s.local
page, logging in, and clicking the +New App
New App button, as shown below.
Name the application guestbook, use the default project, and set the sync policy to Manual
.
Then underneath, configure the Repository URL
to https://github.com/argoproj/argocd-example-apps.git
, for some reason we’re using a GitHub repository acceleration address here https://github.91chi.fun/https://github.com/cnych/argocd-example-apps.git
, set Revision to HEAD, and set the path to guestbook. Then in the Destination section below, set cluster to inCluster
and namespace to default.
After filling in the above information, click Create at the top of the page to create the guestbook application, and you can see that the current application is in the OutOfSync
state after the creation is complete.
By default, the Argo CD checks the Git repository every 3 minutes to determine if the actual state of the application matches the expected state declared in Git, and if it doesn’t, the state is converted to OutOfSync
. This does not trigger an update by default, unless you configure automatic synchronization via syncPolicy
.
Creating via CRD
In addition to the CLI and Dashboard, you can also create an application directly by declaring an Application
resource object, as follows.
|
|
Deploy the application
Since the sync policy we used above when creating the application is Manual
, the application is not automatically deployed after it is created, so we need to deploy the application manually. The same can be done with both CLI and UI interface.
Synchronization using CLI
Once the application is created, we can check its status with the following command.
|
|
The application state is the initial OutOfSync
state because the application has not been deployed and no Kubernetes resources have been created. To synchronize (deploy) the application, you can execute the command shown below.
|
|
This command retrieves the list of resources from the Git repository and executes kubectl apply
to deploy the application. After executing the above command, the guestbook application is now running in the cluster and we can now view its resource components, logs, events, and evaluate its health.
Synchronization via UI
Add the Sync
button directly to the application on the UI to start syncing.
You can see the status of our resources after the sync is complete.
It is even possible to view the log information of the application directly.
It is also possible to view our deployed resources via kubectl.
The status of the resources under the guestbook
directory is also synchronized with our synchronization from the Git repository, which proves that the synchronization was successful.
Tekton combined with Argo CD
Previously we used Tekton to complete the CI/CD process for our application, but the CD was done in Tekton’s task. Now we’re using GitOps to revamp our pipeline and use Argo CD for the CD part.
Here we have to review the previous Tekton practical part, the whole pipeline includes clone, test, build, docker, deploy, rollback several parts of the task, the last deploy and rollback belong to the CD part, we only need this part to use Argo CD to build can.
First, we extract the Helm Chart template from the project http://git.k8s.local/course/devops-demo.git
repository into a separate repository http://git.k8s.local/course/devops-demo-deploy
, so that it is easy to interface with the Argo CD, and only the Helm Chart templates for application deployment are available under the entire project.
If you have multiple teams, each maintaining a large number of applications, you need to use another concept of Argo CD: Projects. projects in Argo CD can be used to group applications, with different teams using different projects, thus enabling a multi-tenant environment. Projects also support more granular access control.
- Restrict deployment content (trusted Git repositories).
- Restricting the target deployment environment (target cluster and namespace).
- Restricting the types of resources deployed (e.g. RBAC, CRD, DaemonSets, NetworkPolicy, etc.).
- Define project roles that provide RBAC for the Application (e.g. OIDC group or JWT token binding).
For example, if we create a project named demo
here, creating the application under that project is as simple as creating an AppProject
object as shown below.
|
|
There are several core properties in this object.
sourceRepos
: repository references from which applications in the project can retrieve manifestsdestinations
: clusters and namespaces that applications in the project can deploy toroles
: roles defined for resource access within the project
Just create the object directly.
Then go to Argo CD to add the repository.
Note that the password here requires an AccessToken, which we can create by going to the GitLab page at http://git.k8s.local/-/profile/personal_access_tokens
.
After the project is created, an Application is created under the project, representing the application instance deployed in the environment.
|
|
Here we define an application named devops-demo
, the source of the application is from the helm path, using the my-values.yaml
file, in addition to the source.helm.parameters
to configure the parameters, the synchronization strategy we still choose to use the manual way, we can in Tekton We can trigger the synchronization manually in Tekton’s task. The application will be in the OutOfSync
state after the above resource object is created, because the application is not yet deployed in the cluster.
Now let’s go ahead and modify the previous Tekton pipeline. The previous Pipeline flowline is shown below.
|
|
Now we need to remove the deploy and rollback tasks at the end. When the Docker image build is done, we just need to modify the values file in the deployment code repository and then manually trigger ArgoCD to synchronize the state (you can skip this step if you have automatic synchronization turned on), and the rollback operation is done by manipulating the Git repository You don’t need to define a separate Task to do this.
Define a Taks task as follows.
|
|
Since we only need to modify the image.tag
parameter in the Helm Chart’s Values file, the best way is to modify the values.yaml
file in a Task and commit it to the Repo repository, but you can also configure the parameters directly on the application side of ArgoCD for simplicity, for example For example, you can use the argocd app set
command to configure parameters for the application, and then use the argocd app sync
command below to manually trigger the sync operation. .
Of course, in addition to configuring the parameters manually with argocd app set
, it may be better to modify the values in the Repo repository directly, so that there is a version record in the source code repository and we can create a new task to modify the values as shown below.
|
|
Now our pipeline becomes the list shown below.
|
|
Finally, create the Secret object to be used for ArgoCD login.
Finally, modify the Template in Tekton Triggers as shown below.
|
|
Now our entire pipeline is even more streamlined. Now let’s go to the application repository and modify the source code and commit it to trigger our pipeline.
Again, you can request the application to verify that the results are correct.
Now look at the applications in the Argo CD and you will see that they are all synchronized.
If you need to rollback, you can select the rollback version by clicking HISTORY AND ROLLBACK
install on the Argo CD page to see the deployment history.
You can view the status of the entire Tekton flow line.
|
|
Finally, a diagram to summarize the workflow of our GitOps implementation using Tekton in combination with Argo CD.
In addition to this, another very important thing to do in GitOps is to be secure. Stay tuned for a follow-up article on how to implement Secure GitOps.