关注微信公众号
第一手干货与资讯
加入官方微信群
获取免费技术支持
In the first article in this series, we talked about making Kubernetes essential to your DevOps pipeline. We reviewed CI/CD and DevOps and why their relationship with Kubernetes is so powerful.
In this article, I’m going to dive into another term in the application development and management mix: GitOps. We’ll cover what GitOps is, how it affects an organization and how it aligns with Kubernetes.
GitOps is a process that leverages the Git developer toolset for operations and management of cloud-native applications. Git is the single source of truth when deploying applications to Kubernetes. When developers make changes to the application, Git automatically pushes them to Kubernetes for deployment. Further, if there are changes to the running state within Kubernetes that are inconsistent with the state within Git, they are reverted to the known state from within Git.
GitOps and CI/CD (continuous integration/continuous delivery or deployment) have an important working relationship. As a refresher, CI/CD lets developers continuously iterate, develop and deploy applications. Often the iteration is through a Git repository (although there can be other repositories) that flows through a toolset for pipelines. During the deployment/delivery phase, the built container-based application is “pushed” to Kubernetes for deployment. The operation of GitOps enhances the CI/CD model by using a “pull” method via Kubernetes, bringing the operational aspect into deployment/delivery.
But what happens if someone changes something running within the Kubernetes cluster? We’d use Git as the primary source of truth as a declarative deployment tool and leverage additional tools to alert us when there is divergence. By leveraging tools that can identify differences between running and declared state, Kubernetes remediates to the known/declared operating state.
Note: Continuous integration and continuous development are complementary but separate processes. In an optimal state, GitOps enables batch size as single-piece-flow, where work happens one unit at a time. However, since CI and CD processes occur in different groups, the process may vary from one organization to another.
Let’s look at this through the application lifecycle lens. During a typical lifecycle, an application goes through multiple states. These include:
With GitOps, we extend that list to include:
Under the GitOps operating model, when an application is released, Kubernetes ensures that it operates as intended. Kubernetes also manages the operation of the application by ensuring its stability and availability. If a developer changes the application via Git, Kubernetes takes the declaration and applies it as required.
In summary, here’s what GitOps is, and what it can do for you:
In closing, while there’s a lot more to operating in GitOps mode, there’s a clear synergy between GitOps, DevOps and existing CI/CD patterns. GitOps provides a model for delivering applications to a Kubernetes platform that ensures a single source of truth and leverages all of the operational features of Kubernetes. GitOps is not a tool replacement. Quite the opposite: GitOps augments your processes, increases maturity and helps teams deliver (and operate) applications by leveraging declarative processes and tools.
FluxCD (or Flux) is a great tool for integrating Kubernetes and Git. Flux is a Kubernetes Operator that you, as the administrator, install into Kubernetes to manage the integration between Git and native Kubernetes. Within Kubernetes, an Operator is an extension of the native Kubernetes platform as a pattern for custom resources that are used to manage applications and their components. This means that, with the aid of the Operator inside Kubernetes, the desired state – as represented within the running state – will continually check and adjust to align with what the Git repository declares. Flux can integrate with your existing CI/CD toolsets for additional workflow, permissions and auditing. Within Kubernetes, Flux monitors Git repositories that you declare (through configuration) for changes and will update Kubernetes to that desired running state, should changes occur locally on a Kubernetes pod that shouldn’t be changed. Remember, Git is the source of truth. The Flux Operator will detect this and change the running configuration back to the declared state from Git.
In the following demo, I’ll show you how to install and implement Flux.
Pre-Requisites: You Will Need
Steps
You can use the following configuration for testing/demonstration purposes. It includes the Docker file for the Flask application, as well as the Kubernetes deployment/configuration files. You will need these as part of the demonstration and can uploaded them to your nominated GIT repository.
Docker File
FROM python:3 RUN pip install flask RUN mkdir -p /corp/app WORKDIR /corp/app COPY main.py . ENV FLASK_APP=/corp/app/main.py ENV APP_NAME=CloudAcademy.DevOps ENV APP_VERSION=v1.0.0 CMD ["flask", "run", "--host=127.0.0.1"]
main.py Python Script File
import os from flask import Flask app = Flask(__name__) @app.route('/') def index(): appname = os.environ['APP_NAME'] appversion = os.environ['APP_VERSION'] response = "%s - %s.%s\n" %('Hello World', appname, appversion) return response
Kubernetes Deployment File
apiVersion: v1 kind: Namespace metadata: name: my-demo --- apiVersion: apps/v1 kind: Deployment metadata: name: fluxdemo namespace: my-demo annotations: flux.weave.works/tag.flask: glob:develop-v* flux.weave.works/automated: 'true' labels: role: fluxdemo env: demo app: flux spec: replicas: 1 selector: matchLabels: role: fluxdemo template: metadata: labels: role: fluxdemo spec: containers: - name: nginx image: nginx:1.16-perl imagePullPolicy: IfNotPresent ports: - name: http containerPort: 80 volumeMounts: - name: nginx-proxy-config mountPath: /etc/nginx/conf.d/default.conf subPath: nginx.conf - name: flask image: docker.io/<your docker repo>/flaskapp:develop-v1.8.0 imagePullPolicy: IfNotPresent ports: - name: http containerPort: 5000 env: - name: APP_NAME value: myfluxdemo.K8s.GitOps - name: APP_VERSION value: v1.0.5 volumes: - name: nginx-proxy-config configMap: name: nginx-conf --- apiVersion: v1 kind: ConfigMap metadata: name: nginx-conf namespace: my-demo data: nginx.conf: |- #CODE1.0: #add the nginx.conf configuration - this will be referenced within the deployment.yaml server { listen 80; server_name localhost; location / { proxy_pass http://localhost:5000/; proxy_set_header Host "localhost"; } }
Install Flux
Configure Flux for Repo * Create a Namespace
kubectl create ns <namespace> export FLUX_FORWARD_NAMESPACE= <namespace> fluxctl list-workloads
export GHUSER="" export REPO="gitops-demo" export NS="flux" fluxctl install \ --git-user=${GHUSER} \ --git-email=${GHUSER}@users.noreply.github.com \ --git-url=git@github.com: Image download failed. {REPO} \ --namespace=${NS} | kubectl apply -f -
Create SSH Key for Adding to Your GitHub Repository
Type the following in your terminal to obtain the key you will need for the next step.
Open GitHub, navigate to the Repository added when you installed Fluxcd, go to Setting > Deploy keys, click on Add deploy key, give it a title, check Allow write access, paste the public key and click Add key. **Update Deployment Manifest in Git Repo** * Open up your GitRepo that has the `deployment.yaml` file * Scroll down to the section as below and change the APP_VERSION number
env: - name: APP_NAME value: myfluxdemo.K8s.GitOps - name: APP_VERSION value: v1.0.5
```
Flux will (within 5 minutes) update your deployment
To test from a localhost, use the “Port-forward” command within Kubernetes:
kubectl get pods -n copy the pod name kubectl port-forward 8080:80 -n
Open another terminal:
curl -s -i http://localhost:8080
Update Container Image and Sync
Now let’s now make a modification to the Docker image and upload to our Docker hub repository. For this, we will modify the main.py file within the flaskapp directory.
main.py
flaskapp
Hello World
response = "%s - %s.%s\n" %('Flux World', appname, appversion)
Configuration Drift and Sync
Now let’s test what happens when there is a manual change to the running configuration
kubectl scale deployment/fluxdemo --replicas=4 -n
Now let’s watch the pods for a few minutes and see what happens. We will see the additional pods for a short period, but within 5 minutes, we will see the excess number of pods terminate. Therefore, Flux has brought the configuration back to the declared state of deployment currently held within Git.
kubectl get po -n --watch
Re-run the same command again and you can see that this view has now filtered down to the just one running pod.
Don’t forget to clean up and remove the deployment and Git connection (if you wish). Otherwise, start adding more repositories and keep on building.
Rancher makes it easier to operate and manage of multi-cluster, hybrid-cloud Kubernetes. It also has built-in tools for developers and other consumers of Kubernetes and computing power. New to Rancher? Learn how Rancher works in the technical architecture guide.