├── .pre-commit-config.yaml ├── Dockerfile-app-serving ├── Dockerfile-jenkins-k8s ├── Jenkinsfile ├── README.md ├── ansible ├── deploy_jenkins │ ├── create_compute_instance.yaml │ └── deploy_jenkins.yaml ├── inventory └── secret_keys │ └── .gitignore ├── app ├── config.py ├── id2url.json ├── images │ ├── bikini.png │ └── woman_blazers.png ├── main.py ├── pinecone_utils.py ├── requirements.txt └── utils │ ├── __init__.py │ ├── data_processing.py │ └── images_response.py ├── client.py ├── gifs ├── add_webhook_out.gif ├── connect_github_out.gif ├── connect_gke_out.gif ├── connect_jenkins_ui_out.gif ├── connect_vm_out.gif ├── create_compute_instance.gif ├── create_svc_acc_out.gif ├── dockerhub_out.gif ├── get_pod_out.gif ├── install_plugin_out.gif ├── pinecone_apikey_out.gif ├── run_cicd_out.gif ├── ssh_key_out.gif └── test_api_out.gif ├── helm_charts ├── app │ ├── Chart.yaml │ └── templates │ │ ├── app_ingress.yaml │ │ ├── deployment.yaml │ │ └── service.yaml ├── grafana │ ├── Chart.yaml │ ├── README.md │ ├── templates │ │ ├── deployment.yaml │ │ ├── grafana-datasource-config.yaml │ │ └── service.yaml │ └── values.yaml ├── nginx_ingress │ ├── .helmignore │ ├── Chart.yaml │ ├── README.md │ ├── crds │ │ ├── appprotect.f5.com_aplogconfs.yaml │ │ ├── appprotect.f5.com_appolicies.yaml │ │ ├── appprotect.f5.com_apusersigs.yaml │ │ ├── appprotectdos.f5.com_apdoslogconfs.yaml │ │ ├── appprotectdos.f5.com_apdospolicy.yaml │ │ ├── appprotectdos.f5.com_dosprotectedresources.yaml │ │ ├── externaldns.nginx.org_dnsendpoints.yaml │ │ ├── k8s.nginx.org_globalconfigurations.yaml │ │ ├── k8s.nginx.org_policies.yaml │ │ ├── k8s.nginx.org_transportservers.yaml │ │ ├── k8s.nginx.org_virtualserverroutes.yaml │ │ └── k8s.nginx.org_virtualservers.yaml │ ├── templates │ │ ├── NOTES.txt │ │ ├── _helpers.tpl │ │ ├── controller-configmap.yaml │ │ ├── controller-daemonset.yaml │ │ ├── controller-deployment.yaml │ │ ├── controller-globalconfiguration.yaml │ │ ├── controller-hpa.yaml │ │ ├── controller-ingress-class.yaml │ │ ├── controller-leader-election-configmap.yaml │ │ ├── controller-pdb.yaml │ │ ├── controller-secret.yaml │ │ ├── controller-service.yaml │ │ ├── controller-serviceaccount.yaml │ │ ├── controller-servicemonitor.yaml │ │ ├── controller-wildcard-secret.yaml │ │ └── rbac.yaml │ ├── values-icp.yaml │ ├── values-nsm.yaml │ ├── values-plus.yaml │ ├── values.schema.json │ └── values.yaml ├── prometheus-operator-crds │ ├── .gitignore │ ├── .helmignore │ ├── Chart.yaml │ ├── README.md │ ├── charts │ │ └── crds │ │ │ ├── Chart.yaml │ │ │ └── templates │ │ │ ├── crd-alertmanagerconfigs.yaml │ │ │ ├── crd-alertmanagers.yaml │ │ │ ├── crd-podmonitors.yaml │ │ │ ├── crd-probes.yaml │ │ │ ├── crd-prometheusagents.yaml │ │ │ ├── crd-prometheuses.yaml │ │ │ ├── crd-prometheusrules.yaml │ │ │ ├── crd-scrapeconfigs.yaml │ │ │ ├── crd-servicemonitors.yaml │ │ │ └── crd-thanosrulers.yaml │ ├── hack │ │ └── update_crds.sh │ └── values.yaml └── prometheus │ ├── .helmignore │ ├── Chart.yaml │ ├── templates │ ├── alert-deployment.yaml │ ├── alert-service.yaml │ ├── clusterRole.yaml │ ├── config-map-alert.yaml │ ├── config-map.yaml │ ├── node_exporter.yaml │ ├── prometheus-deployment.yaml │ └── prometheus-service.yaml │ └── values.yaml ├── images ├── app_pod_metrics.png ├── architecture.png ├── connect_gke.png ├── deploy_successfully_2gke.png ├── gke_ui.png ├── grant_access.png ├── install_jenkins_vm.png ├── jenkins_cicd.png ├── k8s_jenkins.png ├── node_metrics.png └── pipeline.png └── terraform ├── .gitignore ├── main.tf ├── outputs.tf └── variables.tf /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | exclude: "^\ 2 | (third-party/.*)\ 3 | " 4 | 5 | repos: 6 | - repo: https://github.com/pre-commit/pre-commit-hooks 7 | rev: v4.1.0 8 | hooks: 9 | - id: detect-private-key 10 | - id: end-of-file-fixer 11 | - id: requirements-txt-fixer 12 | - id: trailing-whitespace 13 | 14 | # Format Python files 15 | - repo: https://github.com/psf/black 16 | rev: 23.7.0 17 | hooks: 18 | - id: black 19 | 20 | # Sort the order of importing libs 21 | - repo: https://github.com/PyCQA/isort 22 | rev: 5.12.0 23 | hooks: 24 | - id: isort 25 | args: [--profile=black] 26 | -------------------------------------------------------------------------------- /Dockerfile-app-serving: -------------------------------------------------------------------------------- 1 | FROM python:3.8 2 | 3 | ARG PINECONE_APIKEY 4 | 5 | WORKDIR /app 6 | 7 | ENV PINECONE_APIKEY=$PINECONE_APIKEY 8 | 9 | COPY /app /app/app 10 | 11 | WORKDIR /app/app 12 | 13 | RUN pip install -r requirements.txt --no-cache-dir 14 | RUN pip install git+https://github.com/openai/CLIP.git 15 | 16 | EXPOSE 30000 17 | 18 | CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "30000"] 19 | -------------------------------------------------------------------------------- /Dockerfile-jenkins-k8s: -------------------------------------------------------------------------------- 1 | # Ref: https://hackmamba.io/blog/2022/04/running-docker-in-a-jenkins-container/ 2 | FROM jenkins/jenkins:lts 3 | USER root 4 | RUN curl https://get.docker.com > dockerinstall && chmod 777 dockerinstall && ./dockerinstall && \ 5 | curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl && \ 6 | chmod +x ./kubectl && \ 7 | mv ./kubectl /usr/local/bin/kubectl && \ 8 | curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash 9 | USER jenkins -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | pipeline { 2 | agent any 3 | 4 | options{ 5 | // Max number of build logs to keep and days to keep 6 | buildDiscarder(logRotator(numToKeepStr: '5', daysToKeepStr: '5')) 7 | // Enable timestamp at each job in the pipeline 8 | timestamps() 9 | } 10 | 11 | environment{ 12 | registry = 'duong05102002/text-image-retrieval-serving' 13 | registryCredential = 'dockerhub' 14 | } 15 | 16 | stages { 17 | stage('Test') { 18 | steps { 19 | echo 'Testing model correctness..' 20 | echo 'Always pass all test unit :D' 21 | } 22 | } 23 | 24 | stage('Build image') { 25 | steps { 26 | script { 27 | echo 'Building image for deployment..' 28 | def imageName = "${registry}:v1.${BUILD_NUMBER}" 29 | def buildArgs = "--build-arg PINECONE_APIKEY=${PINECONE_APIKEY}" 30 | // PINECONE_APIKEY env is set up on Jenkins dashboard 31 | 32 | dockerImage = docker.build(imageName, "--file Dockerfile-app-serving ${buildArgs} .") 33 | echo 'Pushing image to dockerhub..' 34 | docker.withRegistry( '', registryCredential ) { 35 | dockerImage.push() 36 | } 37 | } 38 | } 39 | } 40 | 41 | stage('Deploy to Google Kubernetes Engine') { 42 | agent { 43 | kubernetes { 44 | containerTemplate { 45 | name 'helm' // Name of the container to be used for helm upgrade 46 | image 'duong05102002/jenkins-k8s:latest' // The image containing helm 47 | } 48 | } 49 | } 50 | steps { 51 | script { 52 | steps 53 | container('helm') { 54 | sh("helm upgrade --install app --set image.repository=${registry} \ 55 | --set image.tag=v1.${BUILD_NUMBER} ./helm_charts/app --namespace model-serving") 56 | } 57 | } 58 | } 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Continuous deployment [text image retrieval service](https://github.com/duongngyn0510/text-image-retrieval) to [Google Kubernetes Engine](https://console.cloud.google.com/kubernetes/list/overview?project=striking-decker-399102) using CI/CD 2 | ## System Architecture 3 | ![](images/architecture.png) 4 | # Table of Contents 5 | 6 | 1. [Create GKE Cluster](#1-create-gke-clusterCreate-GKE-Cluster) 7 | 2. [Deploy serving service manually](#2-deploy-serving-service-manually) 8 | 9 | 1. [Deploy nginx ingress controller](#21-deploy-nginx-ingress-controller) 10 | 11 | 2. [Deploy application](#22-deploy-application-to-gke-cluster-manually) 12 | 13 | 3. [Deploy monitoring service](#3-deploy-monitoring-service) 14 | 15 | 1. [Deploy Prometheus service](#31-deploy-prometheus-service) 16 | 17 | 2. [Deploy Grafana service](#32-deploy-grafana-service) 18 | 19 | 20 | 4. [Continuous deployment to GKE using Jenkins pipeline](#4-continuous-deployment-to-gke-using-jenkins-pipeline) 21 | 22 | 1. [Create Google Compute Engine](#41-spin-up-your-instance) 23 | 24 | 2. [Install Docker and Jenkins in GCE](#42-install-docker-and-jenkins) 25 | 26 | 3. [Connect to Jenkins UI in GCE](#43-connect-to-jenkins-ui-in-compute-engine) 27 | 28 | 4. [Setup Jenkins](#44-setup-jenkins) 29 | 30 | 5. [Continuous deployment](#45-continuous-deployment) 31 | ## 1. Create GKE Cluster 32 | ### How-to Guide 33 | 34 | #### 1.1. Create [Project](https://console.cloud.google.com/projectcreate) in GCP 35 | #### 1.2. Install gcloud CLI 36 | Gcloud CLI can be installed following this document https://cloud.google.com/sdk/docs/install#deb 37 | 38 | Initialize the gcloud CLI 39 | ```bash 40 | gcloud init 41 | Y 42 | ``` 43 | + A pop-up to select your Google account will appear, select the one you used to register GCP, and click the button Allow. 44 | 45 | + Go back to your terminal, in which you typed `gcloud init`, pick cloud project you using, and Enter. 46 | 47 | + Then type Y, type the ID number corresponding to **us-central1-f** (in my case), then Enter. 48 | 49 | #### 1.3. Install gke-cloud-auth-plugin 50 | ```bash 51 | sudo apt-get install google-cloud-cli-gke-gcloud-auth-plugin 52 | ``` 53 | 54 | #### 1.4. Create service account 55 | Create your [service account](https://console.cloud.google.com/iam-admin/serviceaccounts), and select `Kubernetes Engine Admin` role (Full management of Kubernetes Clusters and their Kubernetes API objects) for your service account. 56 | 57 | Create new key as json type for your service account. Download this json file and save it in `terraform` directory. Update `credentials` in `terraform/main.tf` with your json directory. 58 | 59 | #### 1.5. Add permission for Project 60 | Go to [IAM](https://console.cloud.google.com/iam-admin/iam), click on `GRANT ACCESS`, then add new principals, this principal is your service account created in step 1.3. Finally, select `Owner` role. 61 | ![](images/grant_access.png) 62 | 63 | #### 1.6. Using [terraform](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli) to create GKE cluster. 64 | Update your [project id](https://console.cloud.google.com/projectcreate) in `terraform/variables.tf` 65 | Run the following commands to create GKE cluster: 66 | ```bash 67 | gcloud auth application-default login 68 | ``` 69 | 70 | ```bash 71 | cd terraform 72 | terraform init 73 | terraform plan 74 | terraform apply 75 | ``` 76 | + GKE cluster is deployed at **us-central1-f** with its node machine type is: **n2-standard-2** (2 CPU, 8 GB RAM and costs 71$/1month). 77 | + Unable [Autopilot](https://cloud.google.com/kubernetes-engine/docs/concepts/autopilot-overview) for the GKE cluster. When using Autopilot cluster, certain features of Standard GKE are not available, such as scraping node metrics from Prometheus service. 78 | 79 | It can takes about 10 minutes for create successfully a GKE cluster. You can see that on [GKE UI](https://console.cloud.google.com/kubernetes/list) 80 | 81 | ![](images/gke_ui.png) 82 | #### 1.7. Connect to the GKE cluster. 83 | + Go back to the [GKE UI](https://console.cloud.google.com/kubernetes/list). 84 | + Click on vertical ellipsis icon and select **Connect**. 85 | You will see the popup Connect to the cluster as follows 86 | ![](images/connect_gke.png) 87 | + Copy the line `gcloud container clusters get-credentials ...` into your local terminal. 88 | 89 | After run this command, the GKE cluster can be connected from local. 90 | ```bash 91 | kubectx [YOUR_GKE_CLUSTER_ID] 92 | ``` 93 | ## 2. Deploy serving service manually 94 | Using [Helm chart](https://helm.sh/docs/topics/charts/) to deploy application on GKE cluster. 95 | 96 | ### How-to Guide 97 | 98 | #### 2.1. Deploy nginx ingress controller 99 | ```bash 100 | cd helm_charts/nginx_ingress 101 | kubectl create ns nginx-ingress 102 | kubens nginx-ingress 103 | helm upgrade --install nginx-ingress-controller . 104 | ``` 105 | After that, nginx ingress controller will be created in `nginx-ingress` namespace. 106 | 107 | #### 2.2. Deploy application to GKE cluster manually 108 | Text-image retrieval service will be deployed with `NodePort` type (nginx ingress will route the request to this service) and 2 replica pods that maintain by `Deployment`. 109 | 110 | Each pod contains the container running the [text-image retrieval application](https://github.com/duongngyn0510/text-image-retrieval). 111 | 112 | The requests will initially arrive at the Nginx Ingress Gateway and will subsequently be routed to the service within the `model-serving` namespace of the GKE cluster. 113 | 114 | ```bash 115 | cd helm_charts/app 116 | kubectl create ns model-serving 117 | kubens model-serving 118 | helm upgrade --install app --set image.repository=duong05102002/text-image-retrieval-serving --set image.tag=v1.5 . 119 | ``` 120 | 121 | After that, application will be deployed successfully on GKE cluster. To test the api, you can do the following steps: 122 | 123 | + Obtain the IP address of nginx-ingress. 124 | ```bash 125 | kubectl get ing 126 | ``` 127 | 128 | + Add the domain name `retrieval.com` (set up in `helm_charts/app/templates/app_ingress.yaml`) of this IP to `/etc/hosts` 129 | ```bash 130 | sudo nano /etc/hosts 131 | [YOUR_INGRESS_IP_ADDRESS] retrieval.com 132 | ``` 133 | or you can utilize my Ingress IP address (valid until 27/11/2023 during the free trial period). 134 | ```bash 135 | 34.133.25.217 retrieval.com 136 | ``` 137 | 138 | + Open web brower and type `retrieval.com/docs` to access the FastAPI UI and test the API. 139 | + For more intuitive responses, you can run `client.py` (Refresh the html page to display the images.) 140 | 141 | + Image query 142 | ```bash 143 | $ python client.py --save_dir temp.html --image_query your_image_file 144 | ``` 145 | 146 | + **Top 8 products images similar with image query:** 147 | 148 | ![](app/images/woman_blazers.png) 149 | 150 | 151 | 152 |
153 | ImageImageImageImageImageImageImageImage 154 | 155 | 156 | + Text query 157 | ```bash 158 | $ python client.py --save_dir temp.html --text_query your_text_query 159 | ``` 160 | + **Top 8 products images similar with text query: crop top** 161 | 162 | 163 |
164 | ImageImageImageImageImageImageImageImage 165 | 166 | 167 | 168 | ## 3. Deploy monitoring service 169 | I'm using Prometheus and Grafana for monitoring the health of both Node and pods that running application. 170 | 171 | Prometheus will scrape metrics from both Node and pods in GKE cluster. Subsequently, Grafana will display information such as CPU and RAM usage for system health monitoring, and system health alerts will be sent to Discord. 172 | 173 | ### How-to Guide 174 | 175 | #### 3.1. Deploy Prometheus service 176 | 177 | + Create Prometheus CRDs 178 | ```bash 179 | cd helm_charts/prometheus-operator-crds 180 | kubectl create ns monitoring 181 | kubens monitoring 182 | helm upgrade --install prometheus-crds . 183 | ``` 184 | 185 | + Deploy Prometheus service (with `NodePort` type) to GKE cluster 186 | ```bash 187 | cd helm_charts/prometheus 188 | kubens monitoring 189 | helm upgrade --install prometheus . 190 | ``` 191 | 192 | *Warnings about the health of the node and the pod running the application will be alerted to Discord. In this case, the alert will be triggered and sent to Discord when there is only 10% memory available in the node.* 193 | 194 | Prometheus UI can be accessed by `[YOUR_NODEIP_ADDRESS]:30001` 195 | 196 | **Note**: 197 | + Open [Firewall policies](https://console.cloud.google.com/net-security/firewall-manager/firewall-policies) to modify the protocols and ports corresponding to the node `Targets` in a GKE cluster. This will be accept incoming traffic on ports that you specific. 198 | + I'm using ephemeral IP addresses for the node, and these addresses will automatically change after a 24-hour period. You can change to static IP address for more stability or permanence. 199 | 200 | 201 | #### 3.2. Deploy Grafana service 202 | + Deploy Grafana service (with `NodePort` type) to GKE cluster 203 | 204 | ```bash 205 | cd helm_charts/grafana 206 | kubens monitoring 207 | helm upgrade --install grafana . 208 | ``` 209 | 210 | Grafana UI can be accessed by `[YOUR_NODEIP_ADDRESS]:30000` (with both user and password is `admin`) 211 | 212 | Add Prometheus connector to Grafana with Prometheus server URL is: `[YOUR_NODEIP_ADDRESS]:30001`. 213 | 214 | This is some `PromSQL` that you can use for monitoring the health of node and pod: 215 | + RAM usage of 2 pods that running application 216 | ```shell 217 | container_memory_usage_bytes{container='app', namespace='model-serving'} 218 | ``` 219 | + CPU usage of 2 pods that running application 220 | ```shell 221 | rate(container_cpu_usage_seconds_total{container='app', namespace='model-serving'}[5m]) * 100 222 | ``` 223 | 224 | ![](images/app_pod_metrics.png) 225 | 226 | + Node usage 227 | ![](images/node_metrics.png) 228 | 229 | ## 4. Continuous deployment to GKE using Jenkins pipeline 230 | 231 | Jenkins is deployed on Google Compute Engine using [Ansible](https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_intro.html) with a machine type is **n1-standard-2**. 232 | 233 | ### 4.1. Spin up your instance 234 | Create your [service account](https://console.cloud.google.com/), and select [Compute Admin](https://cloud.google.com/compute/docs/access/iam#compute.admin) role (Full control of all Compute Engine resources) for your service account. 235 | 236 | Create new key as json type for your service account. Download this json file and save it in `secret_keys` directory. Update your `project` and `service_account_file` in `ansible/deploy_jenkins/create_compute_instance.yaml`. 237 | 238 | ![](gifs/create_svc_acc_out.gif) 239 | 240 | Go back to your terminal, please execute the following commands to create the Compute Engine instance: 241 | ```bash 242 | cd ansible/deploy_jenkins 243 | ansible-playbook create_compute_instance.yaml 244 | ``` 245 | 246 | ![](gifs/create_compute_instance.gif) 247 | 248 | Go to Settings, select [Metadata](https://console.cloud.google.com/compute/metadata) and add your SSH key. 249 | 250 | Update the IP address of the newly created instance and the SSH key for connecting to the Compute Engine in the inventory file. 251 | 252 | ![](gifs/ssh_key_out.gif) 253 | ### 4.2. Install Docker and Jenkins in GCE 254 | 255 | ```bash 256 | cd ansible/deploy_jenkins 257 | ansible-playbook -i ../inventory deploy_jenkins.yaml 258 | ``` 259 | 260 | Wait a few minutes, if you see the output like this it indicates that Jenkins has been successfully installed on a Compute Engine instance. 261 | ![](images/install_jenkins_vm.png) 262 | ### 4.3. Connect to Jenkins UI in Compute Engine 263 | Access the instance using the command: 264 | ```bash 265 | ssh -i ~/.ssh/id_rsa YOUR_USERNAME@YOUR_EXTERNAL_IP 266 | ``` 267 | Check if jenkins container is already running ? 268 | ```bash 269 | sudo docker ps 270 | ``` 271 | 272 | ![](gifs/connect_vm_out.gif) 273 | Open web brower and type `[YOUR_EXTERNAL_IP]:8081` for access Jenkins UI. To Unlock Jenkins, please execute the following commands: 274 | ```shell 275 | sudo docker exec -ti jenkins bash 276 | cat /var/jenkins_home/secrets/initialAdminPassword 277 | ``` 278 | Copy the password and you can access Jenkins UI. 279 | 280 | It will take a few minutes for Jenkins to be set up successfully on their Compute Engine instance. 281 | 282 | ![](gifs/connect_jenkins_ui_out.gif) 283 | 284 | Create your user ID, and Jenkins will be ready :D 285 | 286 | ### 4.4. Setup Jenkins 287 | #### 4.4.1. Connect to Github repo 288 | + Add Jenkins url to webhooks in Github repo 289 | 290 | ![](gifs/add_webhook_out.gif) 291 | + Add Github credential to Jenkins (select appropriate scopes for the personal access token) 292 | 293 | 294 | ![](gifs/connect_github_out.gif) 295 | 296 | 297 | #### 4.4.2. Add `PINECONE_APIKEY` for connecting to Pinecone Vector DB in the global environment varibles at `Manage Jenkins/System` 298 | 299 | 300 | ![](gifs/pinecone_apikey_out.gif) 301 | 302 | 303 | #### 4.4.3. Add Dockerhub credential to Jenkins at `Manage Jenkins/Credentials` 304 | 305 | 306 | ![](gifs/dockerhub_out.gif) 307 | 308 | 309 | #### 4.4.4. Install the Kubernetes, Docker, Docker Pineline, GCloud SDK Plugins at `Manage Jenkins/Plugins` 310 | 311 | After successful installation, restart the Jenkins container in your Compute Engine instance: 312 | ```bash 313 | sudo docker restart jenkins 314 | ``` 315 | 316 | ![](gifs/install_plugin_out.gif) 317 | 318 | 319 | #### 4.4.5. Set up a connection to GKE by adding the cluster certificate key at `Manage Jenkins/Clouds`. 320 | 321 | Don't forget to grant permissions to the service account which is trying to connect to our cluster by the following command: 322 | 323 | ```shell 324 | kubectl create clusterrolebinding cluster-admin-binding --clusterrole=cluster-admin --user=system:anonymous 325 | 326 | kubectl create clusterrolebinding cluster-admin-default-binding --clusterrole=cluster-admin --user=system:serviceaccount:model-serving:default 327 | ``` 328 | 329 | ![](gifs/connect_gke_out.gif) 330 | 331 | #### 4.4.6. Install Helm on Jenkins to enable application deployment to GKE cluster. 332 | 333 | + You can use the `Dockerfile-jenkins-k8s` to build a new Docker image. After that, push this newly created image to Dockerhub. Finally replace the image reference at `containerTemplate` in `Jenkinsfile` or you can reuse my image `duong05102002/jenkins-k8s:latest` 334 | 335 | 336 | ### 4.5. Continuous deployment 337 | Create `model-serving` namespace first in your GKE cluster 338 | ```bash 339 | kubectl create ns model-serving 340 | ``` 341 | 342 | The CI/CD pipeline will consist of three stages: 343 | + Tesing model correctness. 344 | + Replace the new pretrained model in `app/main.py`. I recommend accessing the pretrained model by downloading it from another storage, such as Google Drive or Hugging Face. 345 | + If you store the pretrained model directly in a directory and copy it to the Docker image during the application build, it may consume a significant amount of resource space (RAM) in the pod. This can result in pods not being started successfully. 346 | + Building the image, and pushing the image to Docker Hub. 347 | + Finally, it will deploy the application with the latest image from DockerHub to GKE cluster. 348 | 349 | ![](gifs/run_cicd_out.gif) 350 | 351 | 352 | The pipeline will take about 8 minutes. You can confirm the successful deployment of the application to the GKE cluster if you see the following output in the pipeline log: 353 | ![](images/deploy_successfully_2gke.png) 354 | 355 | Here is the Stage view in Jenkins pipeline: 356 | 357 | ![](images/pipeline.png) 358 | 359 | Check whether the pods have been deployed successfully in the `models-serving` namespace. 360 | 361 | ![](gifs/get_pod_out.gif) 362 | 363 | Test the API 364 | 365 | ![](gifs/test_api_out.gif) 366 | -------------------------------------------------------------------------------- /ansible/deploy_jenkins/create_compute_instance.yaml: -------------------------------------------------------------------------------- 1 | - name: Create a Compute Engine instance 2 | hosts: localhost 3 | tasks: 4 | - name: create a disk 5 | gcp_compute_disk: 6 | name: disk-instance 7 | size_gb: 50 8 | source_image: projects/ubuntu-os-cloud/global/images/ubuntu-2204-jammy-v20230727 9 | zone: us-central1-f 10 | project: mle-course-398013 11 | auth_kind: serviceaccount 12 | service_account_file: ../secret_keys/mle-course-398013-80ecbd13cd59.json 13 | state: present 14 | register: disk 15 | 16 | - name: Start an instance 17 | gcp_compute_instance: 18 | name: jenkins-instance 19 | machine_type: n1-standard-2 20 | zone: us-central1-f 21 | project: mle-course-398013 22 | auth_kind: serviceaccount 23 | service_account_file: ../secret_keys/mle-course-398013-80ecbd13cd59.json 24 | disks: 25 | - auto_delete: 'true' 26 | boot: 'true' 27 | source: "{{ disk }}" 28 | - auto_delete: 'true' 29 | interface: NVME 30 | type: SCRATCH 31 | initialize_params: 32 | disk_type: local-ssd 33 | network_interfaces: 34 | - network: 35 | selfLink: global/networks/default 36 | access_configs: 37 | - name: External NAT 38 | type: ONE_TO_ONE_NAT 39 | state: present 40 | 41 | - name: Create inbound firewall rule for port 8081 and 50000 42 | gcp_compute_firewall: 43 | name: allow-port-8081-50000 44 | network: 45 | selfLink: global/networks/default 46 | allowed: 47 | - ip_protocol: TCP 48 | ports: 49 | - 8081 50 | - 50000 51 | source_ranges: 52 | - 0.0.0.0/0 53 | direction: INGRESS 54 | description: Allow incoming traffic on port 50000 and 8081 (Jenkins UI) 55 | project: mle-course-398013 56 | auth_kind: serviceaccount 57 | service_account_file: ../secret_keys/mle-course-398013-80ecbd13cd59.json 58 | -------------------------------------------------------------------------------- /ansible/deploy_jenkins/deploy_jenkins.yaml: -------------------------------------------------------------------------------- 1 | # https://www.digitalocean.com/community/tutorials/how-to-use-ansible-to-install-and-set-up-docker-on-ubuntu-22-04 2 | - name: Deploy Jenkins 3 | hosts: servers # Which host to apply, you can replace by `servers`, or by `servers_1, servers_2` for multiple groups 4 | become: yes # To run commands as a superuser (e.g., sudo) 5 | vars: 6 | default_container_name: jenkins 7 | default_container_image: fullstackdatascience/jenkins:lts 8 | tasks: 9 | - name: Install aptitude 10 | apt: 11 | name: aptitude 12 | state: latest 13 | update_cache: true 14 | 15 | - name: Install prerequisites 16 | apt: 17 | pkg: 18 | - apt-transport-https 19 | - ca-certificates 20 | - curl 21 | - software-properties-common 22 | - python3-pip 23 | - virtualenv 24 | - python3-setuptools 25 | state: latest 26 | update_cache: true 27 | 28 | - name: Add Docker GPG apt Key 29 | apt_key: 30 | url: https://download.docker.com/linux/ubuntu/gpg 31 | state: present 32 | 33 | - name: Add Docker Repository 34 | apt_repository: 35 | repo: deb https://download.docker.com/linux/ubuntu focal stable 36 | state: present 37 | 38 | - name: Update apt and install docker-ce 39 | apt: 40 | name: docker-ce 41 | state: latest 42 | update_cache: true 43 | 44 | - name: Pull the Docker image 45 | community.docker.docker_image: 46 | name: "{{ default_container_image }}" 47 | source: pull 48 | 49 | # https://docs.ansible.com/ansible/latest/collections/community/docker/docker_container_module.html 50 | - name: Create the container 51 | community.docker.docker_container: 52 | name: "{{ default_container_name }}" 53 | image: "{{ default_container_image }}" 54 | state: started 55 | privileged: true 56 | user: root 57 | volumes: 58 | - jenkins_home:/var/jenkins_home 59 | - /var/run/docker.sock:/var/run/docker.sock 60 | ports: 61 | - 8081:8080 62 | - 50000:50000 63 | detach: yes # Run the container in the background 64 | -------------------------------------------------------------------------------- /ansible/inventory: -------------------------------------------------------------------------------- 1 | [servers] 2 | 34.123.220.224 ansible_ssh_private_key_file=/home/user_name/.ssh/id_rsa 3 | -------------------------------------------------------------------------------- /ansible/secret_keys/.gitignore: -------------------------------------------------------------------------------- 1 | *.json 2 | -------------------------------------------------------------------------------- /app/config.py: -------------------------------------------------------------------------------- 1 | import torch 2 | 3 | 4 | class AppConfig: 5 | INPUT_RESOLUTION = 224 6 | INDEX_NAME = "fashion" 7 | DEVICE = "cuda" if torch.cuda.is_available() else "cpu" 8 | DATA_PATH = "./data.csv" 9 | TOP_IMAGES = 8 10 | PORT_EXPOSE = 30000 11 | -------------------------------------------------------------------------------- /app/images/bikini.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duongngyn0510/continuous-deployment-to-gke-cluster/8a87b724dc9c603380e026f233105c1fca6a96aa/app/images/bikini.png -------------------------------------------------------------------------------- /app/images/woman_blazers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duongngyn0510/continuous-deployment-to-gke-cluster/8a87b724dc9c603380e026f233105c1fca6a96aa/app/images/woman_blazers.png -------------------------------------------------------------------------------- /app/main.py: -------------------------------------------------------------------------------- 1 | import os 2 | from io import BytesIO 3 | 4 | import gdown 5 | import imagehash 6 | import torch 7 | from config import AppConfig 8 | from fastapi import FastAPI, File, UploadFile 9 | from fastapi.responses import HTMLResponse 10 | from loguru import logger 11 | from PIL import Image 12 | from pinecone_utils import get_index, search 13 | from utils import * 14 | 15 | INDEX_NAME = AppConfig.INDEX_NAME 16 | index = get_index(INDEX_NAME) 17 | logger.info(f"Connect to index {INDEX_NAME} in Pinecone successfully!") 18 | 19 | DEVICE = AppConfig.DEVICE 20 | 21 | if os.path.isfile("pretrained_clip.pt"): 22 | logger.info("Pretrained model already exists!") 23 | else: 24 | file_id = "1dmqfp-yb8EhzwSjI9pZi6ZAeKjngdtaT" 25 | pretrained_file = "pretrained_clip.pt" 26 | gdown.download( 27 | f"https://drive.google.com/uc?id={file_id}", pretrained_file, quiet=False 28 | ) 29 | logger.info("Download pretrained model successfully!") 30 | 31 | model = torch.load("pretrained_clip.pt", map_location=torch.device(DEVICE)) 32 | model.eval() 33 | 34 | if DEVICE == "cpu": 35 | for p in model.parameters(): 36 | p.data = p.data.float() 37 | 38 | logger.info("Load pretrained model successfully!") 39 | 40 | app = FastAPI() 41 | image_cache = {} 42 | text_cache = {} 43 | 44 | 45 | @app.post("/image_url") 46 | async def image_url(image_file: UploadFile = File(...)): 47 | """Get image url with image file query 48 | 49 | Args: 50 | image_file (UploadFile) 51 | 52 | Returns: 53 | (List): List of top images url 54 | """ 55 | request_image_content = await image_file.read() 56 | pil_image = Image.open(BytesIO(request_image_content)) 57 | pil_hash = imagehash.average_hash(pil_image) 58 | logger.info(pil_hash) 59 | 60 | if pil_hash not in image_cache: 61 | logger.info("Getting related products!") 62 | image_embedding = get_image_embedding(model, DEVICE, pil_image) 63 | match_ids = search(index, image_embedding, top_k=AppConfig.TOP_IMAGES) 64 | image_cache[pil_hash] = match_ids 65 | else: 66 | logger.info("Getting related products from cache!") 67 | match_ids = image_cache[pil_hash] 68 | 69 | images_url = get_image_url( 70 | match_ids, 71 | ) 72 | return images_url 73 | 74 | 75 | @app.post("/display_image") 76 | async def display_image(image_file: UploadFile = File(...)): 77 | """Display images from their urls with image file query 78 | 79 | Args: 80 | image_file (UploadFile) 81 | 82 | Returns: 83 | HTMLResponse 84 | """ 85 | images_url = await image_url(image_file) 86 | html_content = display_html(images_url) 87 | return HTMLResponse(content=html_content) 88 | 89 | 90 | @app.post("/text_url") 91 | async def text_url(text_query: str): 92 | """Get image url with text query 93 | 94 | Args: 95 | text_query (str) 96 | 97 | Returns: 98 | (List): List of top images url 99 | """ 100 | print 101 | if text_query not in text_cache: 102 | logger.info("Getting related products!") 103 | text_embedding = get_text_embedding(model, DEVICE, text_query) 104 | match_ids = search(index, text_embedding, top_k=AppConfig.TOP_IMAGES) 105 | text_cache[text_query] = match_ids 106 | else: 107 | logger.info("Getting related products from cache!") 108 | match_ids = text_cache[text_query] 109 | 110 | images_url = get_image_url(match_ids) 111 | return images_url 112 | 113 | 114 | @app.post("/display_text") 115 | async def display_text(text_query: str): 116 | """Display images from their urls with text query 117 | 118 | Args: 119 | text_query (str) 120 | 121 | Returns: 122 | HTMLResponse 123 | """ 124 | images_url = await text_url(text_query) 125 | html_content = display_html(images_url) 126 | return HTMLResponse(content=html_content) 127 | -------------------------------------------------------------------------------- /app/pinecone_utils.py: -------------------------------------------------------------------------------- 1 | import os 2 | from typing import List 3 | 4 | import pinecone 5 | 6 | PINECONE_APIKEY = os.environ["PINECONE_APIKEY"] 7 | 8 | 9 | def get_index(index_name: str) -> pinecone.Index: 10 | """Get index in Pinecone vector database 11 | 12 | Args: 13 | index_name (str): Index name 14 | 15 | Returns: 16 | pinecone.Index 17 | """ 18 | pinecone.init(api_key=PINECONE_APIKEY, environment="us-west1-gcp") 19 | index = pinecone.Index(index_name) 20 | return index 21 | 22 | 23 | def search(index: str, input_emb: List[float], top_k: int) -> List[int]: 24 | """Search the IDs of top similar images 25 | 26 | Args: 27 | index (str): index name 28 | input_emb (List[float]): input embedding 29 | top_k (int): number of top similar images 30 | 31 | Returns: 32 | List[int]: The IDs of top similar images 33 | """ 34 | matching = index.query(vector=input_emb, top_k=top_k, include_values=True)[ 35 | "matches" 36 | ] 37 | match_ids = [match_id["id"] for match_id in matching] 38 | return match_ids 39 | -------------------------------------------------------------------------------- /app/requirements.txt: -------------------------------------------------------------------------------- 1 | fastapi==0.96.0 2 | gdown 3 | imagehash==4.3.1 4 | loguru 5 | pinecone-client 6 | python-dotenv 7 | python-multipart==0.0.6 8 | torch==1.13.1 9 | torchvision 10 | uvicorn[standard]==0.22.0 11 | -------------------------------------------------------------------------------- /app/utils/__init__.py: -------------------------------------------------------------------------------- 1 | from .data_processing import * 2 | from .images_response import * 3 | -------------------------------------------------------------------------------- /app/utils/data_processing.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | 3 | import clip 4 | import PIL 5 | import torch 6 | from torchvision.transforms import ( 7 | CenterCrop, 8 | Compose, 9 | InterpolationMode, 10 | Normalize, 11 | Resize, 12 | ToTensor, 13 | ) 14 | 15 | BICUBIC = InterpolationMode.BICUBIC 16 | INPUT_RESOLUTION = 224 17 | 18 | 19 | def _convert_image_to_rgb(image): 20 | return image.convert("RGB") 21 | 22 | 23 | def preprocess_image(n_px=INPUT_RESOLUTION): 24 | """ 25 | A torchvision transform that converts a PIL image into a tensor that the returned model can take as its input 26 | 27 | Args: 28 | n_px (int, default=224) : Input resolution 29 | 30 | Returns: 31 | preprocess : Callable[[PIL.Image], torch.Tensor] 32 | """ 33 | return Compose( 34 | [ 35 | Resize(n_px, interpolation=BICUBIC), 36 | CenterCrop(n_px), 37 | _convert_image_to_rgb, 38 | ToTensor(), 39 | Normalize( 40 | (0.48145466, 0.4578275, 0.40821073), 41 | (0.26862954, 0.26130258, 0.27577711), 42 | ), 43 | ] 44 | ) 45 | 46 | 47 | def get_image_embedding( 48 | model: torch.nn.Module, device: str, pil_image: PIL.Image 49 | ) -> List[float]: 50 | """Get image embedding 51 | 52 | Args: 53 | model (torch.nn.Module) 54 | device (str) 55 | pil_image (PIL.Image) 56 | 57 | Returns: 58 | List[float]: image embedding 59 | """ 60 | image_tensor = preprocess_image()(pil_image).unsqueeze(0).to(device) 61 | image_embedding = model.encode_image(image_tensor) 62 | image_embedding = image_embedding.detach().cpu().numpy()[0].tolist() 63 | return image_embedding 64 | 65 | 66 | def get_text_embedding( 67 | model: torch.nn.Module, device: str, text_query: str 68 | ) -> List[float]: 69 | """Get text embedding 70 | 71 | Args: 72 | model (torch.nn.Module) 73 | device (str) 74 | text_query (str) 75 | 76 | Returns: 77 | List[float]: text embedding 78 | """ 79 | text_token = clip.tokenize(text_query) 80 | text_embedding = model.encode_text(text_token.to(device)) 81 | text_embedding = text_embedding.detach().cpu().numpy()[0].tolist() 82 | return text_embedding 83 | -------------------------------------------------------------------------------- /app/utils/images_response.py: -------------------------------------------------------------------------------- 1 | import json 2 | from typing import List 3 | 4 | 5 | def get_image_url(match_ids: List[int]) -> List[str]: 6 | """Get images url from their IDS 7 | 8 | Args: 9 | match_ids (List[int]) : The images's IDs 10 | 11 | Returns: 12 | List[str]: The images's url 13 | """ 14 | with open("./id2url.json", "r") as f: 15 | id2url = json.load(f) 16 | images_url = [] 17 | for i in match_ids: 18 | images_url.append(id2url[i]) 19 | return images_url 20 | 21 | 22 | def display_html(images_url: List[str]) -> str: 23 | """Display the html content from images url 24 | Args: 25 | match_ids (List[str]) : The images's url 26 | 27 | Returns: 28 | str : html content 29 | """ 30 | 31 | html_content = """ 32 | 33 | 34 | Dynamic Images 35 | 46 | 47 | 48 |
49 | """ 50 | 51 | for url in images_url: 52 | html_content += f'Image' 53 | 54 | html_content += """ 55 | 56 | 57 | """ 58 | return html_content 59 | -------------------------------------------------------------------------------- /client.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import webbrowser 3 | 4 | import requests 5 | 6 | base_api = f"http://retrieval.com" 7 | 8 | 9 | class DisplayImage: 10 | def __init__(self) -> None: 11 | parser = argparse.ArgumentParser(description="arguments") 12 | parser.add_argument( 13 | "--save_dir", type=str, help="html file to display", required=True 14 | ) 15 | 16 | query_group = parser.add_mutually_exclusive_group() 17 | query_group.add_argument("--text_query", type=str, help="text query") 18 | query_group.add_argument("--image_query", type=str, help="image file query") 19 | 20 | args = parser.parse_args() 21 | print(args) 22 | self.save_dir = args.save_dir 23 | self.image_query = args.image_query 24 | self.text_query = args.text_query 25 | 26 | def request_text(self, text_query): 27 | text_api = f"{base_api}/display_text" 28 | 29 | headers = { 30 | "accept": "application/json", 31 | "content-type": "application/x-www-form-urlencoded", 32 | } 33 | 34 | params = {"text_query": text_query} 35 | 36 | response = requests.post(text_api, params=params, headers=headers) 37 | if response.status_code == 200: 38 | self._display(response) 39 | 40 | def request_image(self, image_file): 41 | image_api = f"{base_api}/display_image" 42 | image = open(image_file, "rb") 43 | files = {"image_file": image} 44 | 45 | response = requests.post(image_api, files=files) 46 | if response.status_code == 200: 47 | self._display(response) 48 | 49 | @staticmethod 50 | def _display(response): 51 | with open("temp.html", "w", encoding="utf-8") as f: 52 | f.write(response.text) 53 | webbrowser.open("temp.html") 54 | 55 | def main(self): 56 | if self.text_query is not None: 57 | self.request_text(self.text_query) 58 | else: 59 | self.request_image(self.image_query) 60 | 61 | 62 | if __name__ == "__main__": 63 | DisplayImage().main() -------------------------------------------------------------------------------- /gifs/add_webhook_out.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duongngyn0510/continuous-deployment-to-gke-cluster/8a87b724dc9c603380e026f233105c1fca6a96aa/gifs/add_webhook_out.gif -------------------------------------------------------------------------------- /gifs/connect_github_out.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duongngyn0510/continuous-deployment-to-gke-cluster/8a87b724dc9c603380e026f233105c1fca6a96aa/gifs/connect_github_out.gif -------------------------------------------------------------------------------- /gifs/connect_gke_out.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duongngyn0510/continuous-deployment-to-gke-cluster/8a87b724dc9c603380e026f233105c1fca6a96aa/gifs/connect_gke_out.gif -------------------------------------------------------------------------------- /gifs/connect_jenkins_ui_out.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duongngyn0510/continuous-deployment-to-gke-cluster/8a87b724dc9c603380e026f233105c1fca6a96aa/gifs/connect_jenkins_ui_out.gif -------------------------------------------------------------------------------- /gifs/connect_vm_out.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duongngyn0510/continuous-deployment-to-gke-cluster/8a87b724dc9c603380e026f233105c1fca6a96aa/gifs/connect_vm_out.gif -------------------------------------------------------------------------------- /gifs/create_compute_instance.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duongngyn0510/continuous-deployment-to-gke-cluster/8a87b724dc9c603380e026f233105c1fca6a96aa/gifs/create_compute_instance.gif -------------------------------------------------------------------------------- /gifs/create_svc_acc_out.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duongngyn0510/continuous-deployment-to-gke-cluster/8a87b724dc9c603380e026f233105c1fca6a96aa/gifs/create_svc_acc_out.gif -------------------------------------------------------------------------------- /gifs/dockerhub_out.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duongngyn0510/continuous-deployment-to-gke-cluster/8a87b724dc9c603380e026f233105c1fca6a96aa/gifs/dockerhub_out.gif -------------------------------------------------------------------------------- /gifs/get_pod_out.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duongngyn0510/continuous-deployment-to-gke-cluster/8a87b724dc9c603380e026f233105c1fca6a96aa/gifs/get_pod_out.gif -------------------------------------------------------------------------------- /gifs/install_plugin_out.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duongngyn0510/continuous-deployment-to-gke-cluster/8a87b724dc9c603380e026f233105c1fca6a96aa/gifs/install_plugin_out.gif -------------------------------------------------------------------------------- /gifs/pinecone_apikey_out.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duongngyn0510/continuous-deployment-to-gke-cluster/8a87b724dc9c603380e026f233105c1fca6a96aa/gifs/pinecone_apikey_out.gif -------------------------------------------------------------------------------- /gifs/run_cicd_out.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duongngyn0510/continuous-deployment-to-gke-cluster/8a87b724dc9c603380e026f233105c1fca6a96aa/gifs/run_cicd_out.gif -------------------------------------------------------------------------------- /gifs/ssh_key_out.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duongngyn0510/continuous-deployment-to-gke-cluster/8a87b724dc9c603380e026f233105c1fca6a96aa/gifs/ssh_key_out.gif -------------------------------------------------------------------------------- /gifs/test_api_out.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duongngyn0510/continuous-deployment-to-gke-cluster/8a87b724dc9c603380e026f233105c1fca6a96aa/gifs/test_api_out.gif -------------------------------------------------------------------------------- /helm_charts/app/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: retrieval 3 | description: my helm chart for retrieval app 4 | 5 | type: application 6 | 7 | version: 0.1.0 8 | appVersion: "1.0.0" 9 | 10 | maintainers: 11 | - email: duong05102002@gmail.com 12 | name: duongnguyen 13 | -------------------------------------------------------------------------------- /helm_charts/app/templates/app_ingress.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: Ingress 3 | metadata: 4 | name: {{ .Release.Name }}-nginx-ingress 5 | namespace: model-serving 6 | annotations: 7 | kubernetes.io/ingress.class: "nginx" 8 | spec: 9 | rules: 10 | - host: retrieval.com 11 | http: 12 | paths: 13 | - path: /docs 14 | pathType: Prefix 15 | backend: 16 | service: 17 | name: {{ .Release.Name }} 18 | port: 19 | number: 30000 20 | 21 | - path: /openapi.json 22 | pathType: Prefix 23 | backend: 24 | service: 25 | name: {{ .Release.Name }} 26 | port: 27 | number: 30000 28 | 29 | - path: /image_url 30 | pathType: Prefix 31 | backend: 32 | service: 33 | name: {{ .Release.Name }} 34 | port: 35 | number: 30000 36 | 37 | - path: /display_image 38 | pathType: Prefix 39 | backend: 40 | service: 41 | name: {{ .Release.Name }} 42 | port: 43 | number: 30000 44 | 45 | - path: /text_url 46 | pathType: Prefix 47 | backend: 48 | service: 49 | name: {{ .Release.Name }} 50 | port: 51 | number: 30000 52 | 53 | - path: /display_text 54 | pathType: Prefix 55 | backend: 56 | service: 57 | name: {{ .Release.Name }} 58 | port: 59 | number: 30000 60 | -------------------------------------------------------------------------------- /helm_charts/app/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ .Release.Name }} 5 | namespace: model-serving 6 | 7 | spec: 8 | replicas: 2 9 | selector: 10 | matchLabels: 11 | app: {{ .Release.Name }} 12 | template: 13 | metadata: 14 | labels: 15 | app: {{ .Release.Name }} 16 | spec: 17 | containers: 18 | - name: {{ .Release.Name }} 19 | image: {{ .Values.image.repository }}:{{ .Values.image.tag }} 20 | ports: 21 | - containerPort: 30000 22 | resources: 23 | limits: 24 | memory: 1300Mi 25 | cpu: 400m 26 | requests: 27 | memory: 1200Mi 28 | cpu: 300m 29 | -------------------------------------------------------------------------------- /helm_charts/app/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ .Release.Name }} 5 | labels: 6 | app: {{ .Release.Name }} 7 | namespace: model-serving 8 | spec: 9 | selector: 10 | app: {{ .Release.Name }} 11 | ports: 12 | - port: 30000 13 | protocol: TCP 14 | targetPort: 30000 15 | type: NodePort 16 | -------------------------------------------------------------------------------- /helm_charts/grafana/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: grafana 3 | description: my helm chart for grafana monitoring retrieval app 4 | 5 | type: application 6 | 7 | version: 0.1.0 8 | appVersion: "1.0.0" 9 | 10 | maintainers: 11 | - email: duong05102002@gmail.com 12 | name: duongnguyen 13 | -------------------------------------------------------------------------------- /helm_charts/grafana/README.md: -------------------------------------------------------------------------------- 1 | # kubernetes-grafana 2 | 3 | Read about the grafana implementation on Kubernetes here https://devopscube.com/setup-grafana-kubernetes/ 4 | -------------------------------------------------------------------------------- /helm_charts/grafana/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ .Release.Name }} 5 | namespace: monitoring 6 | spec: 7 | replicas: 1 8 | selector: 9 | matchLabels: 10 | app: {{ .Release.Name }} 11 | template: 12 | metadata: 13 | name: {{ .Release.Name }} 14 | labels: 15 | app: {{ .Release.Name }} 16 | spec: 17 | containers: 18 | - name: {{ .Release.Name }} 19 | image: {{ .Values.image.repository }}:{{ .Values.image.tag }} 20 | ports: 21 | - name: {{ .Release.Name }} 22 | containerPort: 3000 23 | volumeMounts: 24 | - mountPath: /var/lib/grafana 25 | name: grafana-storage 26 | - mountPath: /etc/grafana/provisioning/datasources 27 | name: grafana-datasources 28 | readOnly: false 29 | volumes: 30 | - name: grafana-storage 31 | emptyDir: {} 32 | - name: grafana-datasources 33 | configMap: 34 | defaultMode: 420 35 | name: grafana-datasources 36 | -------------------------------------------------------------------------------- /helm_charts/grafana/templates/grafana-datasource-config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: grafana-datasources 5 | namespace: monitoring 6 | data: 7 | prometheus.yaml: |- 8 | { 9 | "apiVersion": 1, 10 | "datasources": [ 11 | { 12 | "access":"proxy", 13 | "editable": true, 14 | "name": "prometheus", 15 | "orgId": 1, 16 | "type": "prometheus", 17 | "url": "http://prometheus-service.monitoring.svc:9090", 18 | "version": 1 19 | } 20 | ] 21 | } 22 | -------------------------------------------------------------------------------- /helm_charts/grafana/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ .Release.Name }} 5 | namespace: monitoring 6 | annotations: 7 | prometheus.io/scrape: 'true' 8 | prometheus.io/port: '3000' 9 | spec: 10 | selector: 11 | app: {{ .Release.Name }} 12 | type: NodePort 13 | ports: 14 | - port: 3000 15 | targetPort: 3000 16 | nodePort: 30000 17 | -------------------------------------------------------------------------------- /helm_charts/grafana/values.yaml: -------------------------------------------------------------------------------- 1 | image: 2 | repository: grafana/grafana 3 | tag: latest 4 | -------------------------------------------------------------------------------- /helm_charts/nginx_ingress/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | *.png 3 | -------------------------------------------------------------------------------- /helm_charts/nginx_ingress/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | appVersion: 3.2.1 3 | description: NGINX Ingress Controller 4 | home: https://github.com/nginxinc/kubernetes-ingress 5 | icon: https://raw.githubusercontent.com/nginxinc/kubernetes-ingress/v3.2.1/deployments/helm-chart/chart-icon.png 6 | keywords: 7 | - ingress 8 | - nginx 9 | kubeVersion: '>= 1.22.0-0' 10 | maintainers: 11 | - email: kubernetes@nginx.com 12 | name: nginxinc 13 | name: nginx-ingress 14 | sources: 15 | - https://github.com/nginxinc/kubernetes-ingress/tree/v3.2.1/deployments/helm-chart 16 | type: application 17 | version: 0.18.1 18 | -------------------------------------------------------------------------------- /helm_charts/nginx_ingress/README.md: -------------------------------------------------------------------------------- 1 | # NGINX Ingress Controller Helm Chart 2 | 3 | ## Introduction 4 | 5 | This chart deploys the NGINX Ingress Controller in your Kubernetes cluster. 6 | 7 | ## Prerequisites 8 | 9 | - A [Kubernetes Version Supported by the Ingress Controller](https://docs.nginx.com/nginx-ingress-controller/technical-specifications/#supported-kubernetes-versions) 10 | - Helm 3.0+. 11 | - If you’d like to use NGINX Plus: 12 | - To pull from the F5 Container registry, configure a docker registry secret using your JWT token from the MyF5 portal by following the instructions from [here](https://docs.nginx.com/nginx-ingress-controller/installation/using-the-jwt-token-docker-secret). Make sure to specify the secret using `controller.serviceAccount.imagePullSecretName` parameter. 13 | - Alternatively, pull an Ingress Controller image with NGINX Plus and push it to your private registry by following the instructions from [here](https://docs.nginx.com/nginx-ingress-controller/installation/pulling-ingress-controller-image). 14 | - Alternatively, you can build an Ingress Controller image with NGINX Plus and push it to your private registry by following the instructions from [here](https://docs.nginx.com/nginx-ingress-controller/installation/building-ingress-controller-image). 15 | - Update the `controller.image.repository` field of the `values-plus.yaml` accordingly. 16 | - If you’d like to use App Protect DoS, please install App Protect DoS Arbitrator [helm chart](https://github.com/nginxinc/nap-dos-arbitrator-helm-chart). Make sure to install in the same namespace as the NGINX Ingress Controller. Note that if you install multiple NGINX Ingress Controllers in the same namespace, they will need to share the same Arbitrator because it is not possible to install more than one Arbitrator in a single namespace. 17 | 18 | ## CRDs 19 | 20 | By default, the Ingress Controller requires a number of custom resource definitions (CRDs) installed in the cluster. The Helm client will install those CRDs. If the CRDs are not installed, the Ingress Controller pods will not become `Ready`. 21 | 22 | If you do not use the custom resources that require those CRDs (which corresponds to `controller.enableCustomResources` set to `false` and `controller.appprotect.enable` set to `false` and `controller.appprotectdos.enable` set to `false`), the installation of the CRDs can be skipped by specifying `--skip-crds` for the helm install command. 23 | 24 | ### Upgrading the CRDs 25 | 26 | To upgrade the CRDs, pull the chart sources as described in [Pulling the Chart](#pulling-the-chart) and then run: 27 | 28 | ```console 29 | kubectl apply -f crds/ 30 | ``` 31 | 32 | > **Note** 33 | > 34 | > The following warning is expected and can be ignored: `Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply`. 35 | > 36 | > Make sure to check the [release notes](https://www.github.com/nginxinc/kubernetes-ingress/releases) for a new release for any special upgrade procedures. 37 | 38 | ### Uninstalling the CRDs 39 | 40 | To remove the CRDs, pull the chart sources as described in [Pulling the Chart](#pulling-the-chart) and then run: 41 | 42 | ```console 43 | kubectl delete -f crds/ 44 | ``` 45 | 46 | > **Note** 47 | > 48 | > This command will delete all the corresponding custom resources in your cluster across all namespaces. Please ensure there are no custom resources that you want to keep and there are no other Ingress Controller releases running in the cluster. 49 | 50 | ## Managing the Chart via OCI Registry 51 | 52 | ### Installing the Chart 53 | 54 | To install the chart with the release name my-release (my-release is the name that you choose): 55 | 56 | For NGINX: 57 | 58 | ```console 59 | helm install my-release oci://ghcr.io/nginxinc/charts/nginx-ingress --version 0.18.1 60 | ``` 61 | 62 | For NGINX Plus: (assuming you have pushed the Ingress Controller image `nginx-plus-ingress` to your private registry `myregistry.example.com`) 63 | 64 | ```console 65 | helm install my-release oci://ghcr.io/nginxinc/charts/nginx-ingress --version 0.18.1 --set controller.image.repository=myregistry.example.com/nginx-plus-ingress --set controller.nginxplus=true 66 | ``` 67 | 68 | This will install the latest `edge` version of the Ingress Controller from GitHub Container Registry. If you prefer to use Docker Hub, you can replace `ghcr.io/nginxinc/charts/nginx-ingress` with `registry-1.docker.io/nginxcharts/nginx-ingress`. 69 | 70 | ### Upgrading the Chart 71 | 72 | Helm does not upgrade the CRDs during a release upgrade. Before you upgrade a release, see [Upgrading the CRDs](#upgrading-the-crds). 73 | 74 | To upgrade the release `my-release`: 75 | 76 | ```console 77 | helm upgrade my-release oci://ghcr.io/nginxinc/charts/nginx-ingress --version 0.18.1 78 | ``` 79 | 80 | ### Uninstalling the Chart 81 | 82 | To uninstall/delete the release `my-release`: 83 | 84 | ```console 85 | helm uninstall my-release 86 | ``` 87 | 88 | The command removes all the Kubernetes components associated with the release and deletes the release. 89 | 90 | Uninstalling the release does not remove the CRDs. To remove the CRDs, see [Uninstalling the CRDs](#uninstalling-the-crds). 91 | 92 | ### Edge Version 93 | 94 | To test the latest changes in NGINX Ingress Controller before a new release, you can install the `edge` version. This version is built from the `main` branch of the NGINX Ingress Controller repository. 95 | You can install the `edge` version by specifying the `--version` flag with the value `0.0.0-edge`: 96 | 97 | ```console 98 | helm install my-release oci://ghcr.io/nginxinc/charts/nginx-ingress --version 0.0.0-edge 99 | ``` 100 | 101 | > **Warning** 102 | > 103 | > The `edge` version is not intended for production use. It is intended for testing and development purposes only. 104 | 105 | ## Managing the Chart via Sources 106 | 107 | ### Pulling the Chart 108 | 109 | This step is required if you're installing the chart using its sources. Additionally, the step is also required for managing the custom resource definitions (CRDs), which the Ingress Controller requires by default, or for upgrading/deleting the CRDs. 110 | 111 | 1. Pull the chart sources: 112 | 113 | ```console 114 | helm pull oci://ghcr.io/nginxinc/charts/nginx-ingress --untar --version 0.18.1 115 | ``` 116 | 117 | 2. Change your working directory to nginx-ingress: 118 | 119 | ```console 120 | cd nginx-ingress 121 | ``` 122 | 123 | ### Installing the Chart 124 | 125 | To install the chart with the release name my-release (my-release is the name that you choose): 126 | 127 | For NGINX: 128 | 129 | ```console 130 | helm install my-release . 131 | ``` 132 | 133 | For NGINX Plus: 134 | 135 | ```console 136 | helm install my-release -f values-plus.yaml . 137 | ``` 138 | 139 | The command deploys the Ingress Controller in your Kubernetes cluster in the default configuration. The configuration section lists the parameters that can be configured during installation. 140 | 141 | ### Upgrading the Chart 142 | 143 | Helm does not upgrade the CRDs during a release upgrade. Before you upgrade a release, see [Upgrading the CRDs](#upgrading-the-crds). 144 | 145 | To upgrade the release `my-release`: 146 | 147 | ```console 148 | helm upgrade my-release . 149 | ``` 150 | 151 | ### Uninstalling the Chart 152 | 153 | To uninstall/delete the release `my-release`: 154 | 155 | ```console 156 | helm uninstall my-release 157 | ``` 158 | 159 | The command removes all the Kubernetes components associated with the release and deletes the release. 160 | 161 | Uninstalling the release does not remove the CRDs. To remove the CRDs, see [Uninstalling the CRDs](#uninstalling-the-crds). 162 | 163 | ## Running Multiple Ingress Controllers 164 | 165 | If you are running multiple Ingress Controller releases in your cluster with enabled custom resources, the releases will share a single version of the CRDs. As a result, make sure that the Ingress Controller versions match the version of the CRDs. Additionally, when uninstalling a release, ensure that you don’t remove the CRDs until there are no other Ingress Controller releases running in the cluster. 166 | 167 | See [running multiple Ingress Controllers](https://docs.nginx.com/nginx-ingress-controller/installation/running-multiple-ingress-controllers/) for more details. 168 | 169 | ## Configuration 170 | 171 | The following tables lists the configurable parameters of the NGINX Ingress Controller chart and their default values. 172 | 173 | |Parameter | Description | Default | 174 | | --- | --- | --- | 175 | |`controller.name` | The name of the Ingress Controller daemonset or deployment. | Autogenerated | 176 | |`controller.kind` | The kind of the Ingress Controller installation - deployment or daemonset. | deployment | 177 | |`controller.annotations` | Allows for setting of `annotations` for deployment or daemonset. | {} | 178 | |`controller.nginxplus` | Deploys the Ingress Controller for NGINX Plus. | false | 179 | |`controller.nginxReloadTimeout` | The timeout in milliseconds which the Ingress Controller will wait for a successful NGINX reload after a change or at the initial start. | 60000 | 180 | |`controller.hostNetwork` | Enables the Ingress Controller pods to use the host's network namespace. | false | 181 | |`controller.dnsPolicy` | DNS policy for the Ingress Controller pods. | ClusterFirst | 182 | |`controller.nginxDebug` | Enables debugging for NGINX. Uses the `nginx-debug` binary. Requires `error-log-level: debug` in the ConfigMap via `controller.config.entries`. | false | 183 | |`controller.logLevel` | The log level of the Ingress Controller. | 1 | 184 | |`controller.image.digest` | The image digest of the Ingress Controller. | None | 185 | |`controller.image.repository` | The image repository of the Ingress Controller. | nginx/nginx-ingress | 186 | |`controller.image.tag` | The tag of the Ingress Controller image. | 3.2.1 | 187 | |`controller.image.pullPolicy` | The pull policy for the Ingress Controller image. | IfNotPresent | 188 | |`controller.lifecycle` | The lifecycle of the Ingress Controller pods. | {} | 189 | |`controller.customConfigMap` | The name of the custom ConfigMap used by the Ingress Controller. If set, then the default config is ignored. | "" | 190 | |`controller.config.name` | The name of the ConfigMap used by the Ingress Controller. | Autogenerated | 191 | |`controller.config.annotations` | The annotations of the Ingress Controller configmap. | {} | 192 | |`controller.config.entries` | The entries of the ConfigMap for customizing NGINX configuration. See [ConfigMap resource docs](https://docs.nginx.com/nginx-ingress-controller/configuration/global-configuration/configmap-resource/) for the list of supported ConfigMap keys. | {} | 193 | |`controller.customPorts` | A list of custom ports to expose on the NGINX Ingress Controller pod. Follows the conventional Kubernetes yaml syntax for container ports. | [] | 194 | |`controller.defaultTLS.cert` | The base64-encoded TLS certificate for the default HTTPS server. **Note:** By default, a pre-generated self-signed certificate is used. It is recommended that you specify your own certificate. Alternatively, omitting the default server secret completely will configure NGINX to reject TLS connections to the default server. | A pre-generated self-signed certificate. | 195 | |`controller.defaultTLS.key` | The base64-encoded TLS key for the default HTTPS server. **Note:** By default, a pre-generated key is used. It is recommended that you specify your own key. Alternatively, omitting the default server secret completely will configure NGINX to reject TLS connections to the default server. | A pre-generated key. | 196 | |`controller.defaultTLS.secret` | The secret with a TLS certificate and key for the default HTTPS server. The value must follow the following format: `/`. Used as an alternative to specifying a certificate and key using `controller.defaultTLS.cert` and `controller.defaultTLS.key` parameters. **Note:** Alternatively, omitting the default server secret completely will configure NGINX to reject TLS connections to the default server. | None | 197 | |`controller.wildcardTLS.cert` | The base64-encoded TLS certificate for every Ingress/VirtualServer host that has TLS enabled but no secret specified. If the parameter is not set, for such Ingress/VirtualServer hosts NGINX will break any attempt to establish a TLS connection. | None | 198 | |`controller.wildcardTLS.key` | The base64-encoded TLS key for every Ingress/VirtualServer host that has TLS enabled but no secret specified. If the parameter is not set, for such Ingress/VirtualServer hosts NGINX will break any attempt to establish a TLS connection. | None | 199 | |`controller.wildcardTLS.secret` | The secret with a TLS certificate and key for every Ingress/VirtualServer host that has TLS enabled but no secret specified. The value must follow the following format: `/`. Used as an alternative to specifying a certificate and key using `controller.wildcardTLS.cert` and `controller.wildcardTLS.key` parameters. | None | 200 | |`controller.nodeSelector` | The node selector for pod assignment for the Ingress Controller pods. | {} | 201 | |`controller.terminationGracePeriodSeconds` | The termination grace period of the Ingress Controller pod. | 30 | 202 | |`controller.tolerations` | The tolerations of the Ingress Controller pods. | [] | 203 | |`controller.affinity` | The affinity of the Ingress Controller pods. | {} | 204 | |`controller.topologySpreadConstraints` | The topology spread constraints of the Ingress controller pods. | {} | 205 | |`controller.env` | The additional environment variables to be set on the Ingress Controller pods. | [] | 206 | |`controller.volumes` | The volumes of the Ingress Controller pods. | [] | 207 | |`controller.volumeMounts` | The volumeMounts of the Ingress Controller pods. | [] | 208 | |`controller.initContainers` | InitContainers for the Ingress Controller pods. | [] | 209 | |`controller.extraContainers` | Extra (eg. sidecar) containers for the Ingress Controller pods. | [] | 210 | |`controller.resources` | The resources of the Ingress Controller pods. | requests: cpu=100m,memory=128Mi | 211 | |`controller.replicaCount` | The number of replicas of the Ingress Controller deployment. | 1 | 212 | |`controller.ingressClass` | A class of the Ingress Controller. An IngressClass resource with the name equal to the class must be deployed. Otherwise, the Ingress Controller will fail to start. The Ingress Controller only processes resources that belong to its class - i.e. have the "ingressClassName" field resource equal to the class. The Ingress Controller processes all the VirtualServer/VirtualServerRoute/TransportServer resources that do not have the "ingressClassName" field for all versions of kubernetes. | nginx | 213 | |`controller.setAsDefaultIngress` | New Ingresses without an `"ingressClassName"` field specified will be assigned the class specified in `controller.ingressClass`. | false | 214 | |`controller.watchNamespace` | Comma separated list of namespaces the Ingress Controller should watch for resources. By default the Ingress Controller watches all namespaces. Mutually exclusive with `controller.watchNamespaceLabel`. Please note that if configuring multiple namespaces using the Helm cli `--set` option, the string needs to wrapped in double quotes and the commas escaped using a backslash - e.g. `--set controller.watchNamespace="default\,nginx-ingress"`. | "" | 215 | |`controller.watchNamespaceLabel` | Configures the Ingress Controller to watch only those namespaces with label foo=bar. By default the Ingress Controller watches all namespaces. Mutually exclusive with `controller.watchNamespace`. | "" | 216 | |`controller.watchSecretNamespace` | Comma separated list of namespaces the Ingress Controller should watch for resources of type Secret. If this arg is not configured, the Ingress Controller watches the same namespaces for all resources. See `controller.watchNamespace` and `controller.watchNamespaceLabel`. Please note that if configuring multiple namespaces using the Helm cli `--set` option, the string needs to wrapped in double quotes and the commas escaped using a backslash - e.g. `--set controller.watchSecretNamespace="default\,nginx-ingress"`. | "" | 217 | |`controller.enableCustomResources` | Enable the custom resources. | true | 218 | |`controller.enablePreviewPolicies` | Enable preview policies. This parameter is deprecated. To enable OIDC Policies please use `controller.enableOIDC` instead. | false | 219 | |`controller.enableOIDC` | Enable OIDC policies. | false | 220 | |`controller.enableTLSPassthrough` | Enable TLS Passthrough on port 443. Requires `controller.enableCustomResources`. | false | 221 | |`controller.enableCertManager` | Enable x509 automated certificate management for VirtualServer resources using cert-manager (cert-manager.io). Requires `controller.enableCustomResources`. | false | 222 | |`controller.enableExternalDNS` | Enable integration with ExternalDNS for configuring public DNS entries for VirtualServer resources using [ExternalDNS](https://github.com/kubernetes-sigs/external-dns). Requires `controller.enableCustomResources`. | false | 223 | |`controller.globalConfiguration.create` | Creates the GlobalConfiguration custom resource. Requires `controller.enableCustomResources`. | false | 224 | |`controller.globalConfiguration.spec` | The spec of the GlobalConfiguration for defining the global configuration parameters of the Ingress Controller. | {} | 225 | |`controller.enableSnippets` | Enable custom NGINX configuration snippets in Ingress, VirtualServer, VirtualServerRoute and TransportServer resources. | false | 226 | |`controller.healthStatus` | Add a location "/nginx-health" to the default server. The location responds with the 200 status code for any request. Useful for external health-checking of the Ingress Controller. | false | 227 | |`controller.healthStatusURI` | Sets the URI of health status location in the default server. Requires `controller.healthStatus`. | "/nginx-health" | 228 | |`controller.nginxStatus.enable` | Enable the NGINX stub_status, or the NGINX Plus API. | true | 229 | |`controller.nginxStatus.port` | Set the port where the NGINX stub_status or the NGINX Plus API is exposed. | 8080 | 230 | |`controller.nginxStatus.allowCidrs` | Add IP/CIDR blocks to the allow list for NGINX stub_status or the NGINX Plus API. Separate multiple IP/CIDR by commas. | 127.0.0.1,::1 | 231 | |`controller.priorityClassName` | The PriorityClass of the Ingress Controller pods. | None | 232 | |`controller.service.create` | Creates a service to expose the Ingress Controller pods. | true | 233 | |`controller.service.type` | The type of service to create for the Ingress Controller. | LoadBalancer | 234 | |`controller.service.externalTrafficPolicy` | The externalTrafficPolicy of the service. The value Local preserves the client source IP. | Local | 235 | |`controller.service.annotations` | The annotations of the Ingress Controller service. | {} | 236 | |`controller.service.extraLabels` | The extra labels of the service. | {} | 237 | |`controller.service.loadBalancerIP` | The static IP address for the load balancer. Requires `controller.service.type` set to `LoadBalancer`. The cloud provider must support this feature. | "" | 238 | |`controller.service.externalIPs` | The list of external IPs for the Ingress Controller service. | [] | 239 | |`controller.service.loadBalancerSourceRanges` | The IP ranges (CIDR) that are allowed to access the load balancer. Requires `controller.service.type` set to `LoadBalancer`. The cloud provider must support this feature. | [] | 240 | |`controller.service.name` | The name of the service. | Autogenerated | 241 | |`controller.service.customPorts` | A list of custom ports to expose through the Ingress Controller service. Follows the conventional Kubernetes yaml syntax for service ports. | [] | 242 | |`controller.service.httpPort.enable` | Enables the HTTP port for the Ingress Controller service. | true | 243 | |`controller.service.httpPort.port` | The HTTP port of the Ingress Controller service. | 80 | 244 | |`controller.service.httpPort.nodePort` | The custom NodePort for the HTTP port. Requires `controller.service.type` set to `NodePort`. | "" | 245 | |`controller.service.httpPort.targetPort` | The target port of the HTTP port of the Ingress Controller service. | 80 | 246 | |`controller.service.httpsPort.enable` | Enables the HTTPS port for the Ingress Controller service. | true | 247 | |`controller.service.httpsPort.port` | The HTTPS port of the Ingress Controller service. | 443 | 248 | |`controller.service.httpsPort.nodePort` | The custom NodePort for the HTTPS port. Requires `controller.service.type` set to `NodePort`. | "" | 249 | |`controller.service.httpsPort.targetPort` | The target port of the HTTPS port of the Ingress Controller service. | 443 | 250 | |`controller.serviceAccount.annotations` | The annotations of the Ingress Controller service account. | {} | 251 | |`controller.serviceAccount.name` | The name of the service account of the Ingress Controller pods. Used for RBAC. | Autogenerated | 252 | |`controller.serviceAccount.imagePullSecretName` | The name of the secret containing docker registry credentials. Secret must exist in the same namespace as the helm release. | "" | 253 | |`controller.serviceMonitor.name` | The name of the serviceMonitor. | Autogenerated | 254 | |`controller.serviceMonitor.create` | Create a ServiceMonitor custom resource. | false | 255 | |`controller.serviceMonitor.labels` | Kubernetes object labels to attach to the serviceMonitor object. | "" | 256 | |`controller.serviceMonitor.selectorMatchLabels` | A set of labels to allow the selection of endpoints for the ServiceMonitor. | "" | 257 | |`controller.serviceMonitor.endpoints` | A list of endpoints allowed as part of this ServiceMonitor. | "" | 258 | |`controller.reportIngressStatus.enable` | Updates the address field in the status of Ingress resources with an external address of the Ingress Controller. You must also specify the source of the external address either through an external service via `controller.reportIngressStatus.externalService`, `controller.reportIngressStatus.ingressLink` or the `external-status-address` entry in the ConfigMap via `controller.config.entries`. **Note:** `controller.config.entries.external-status-address` takes precedence over the others. | true | 259 | |`controller.reportIngressStatus.externalService` | Specifies the name of the service with the type LoadBalancer through which the Ingress Controller is exposed externally. The external address of the service is used when reporting the status of Ingress, VirtualServer and VirtualServerRoute resources. `controller.reportIngressStatus.enable` must be set to `true`. The default is autogenerated and enabled when `controller.service.create` is set to `true` and `controller.service.type` is set to `LoadBalancer`. | Autogenerated | 260 | |`controller.reportIngressStatus.ingressLink` | Specifies the name of the IngressLink resource, which exposes the Ingress Controller pods via a BIG-IP system. The IP of the BIG-IP system is used when reporting the status of Ingress, VirtualServer and VirtualServerRoute resources. `controller.reportIngressStatus.enable` must be set to `true`. | "" | 261 | |`controller.reportIngressStatus.enableLeaderElection` | Enable Leader election to avoid multiple replicas of the controller reporting the status of Ingress resources. `controller.reportIngressStatus.enable` must be set to `true`. | true | 262 | |`controller.reportIngressStatus.leaderElectionLockName` | Specifies the name of the ConfigMap, within the same namespace as the controller, used as the lock for leader election. controller.reportIngressStatus.enableLeaderElection must be set to true. | Autogenerated | 263 | |`controller.reportIngressStatus.annotations` | The annotations of the leader election configmap. | {} | 264 | |`controller.pod.annotations` | The annotations of the Ingress Controller pod. | {} | 265 | |`controller.pod.extraLabels` | The additional extra labels of the Ingress Controller pod. | {} | 266 | |`controller.appprotect.enable` | Enables the App Protect WAF module in the Ingress Controller. | false | 267 | |`controller.appprotectdos.enable` | Enables the App Protect DoS module in the Ingress Controller. | false | 268 | |`controller.appprotectdos.debug` | Enable debugging for App Protect DoS. | false | 269 | |`controller.appprotectdos.maxDaemons` | Max number of ADMD instances. | 1 | 270 | |`controller.appprotectdos.maxWorkers` | Max number of nginx processes to support. | Number of CPU cores in the machine | 271 | |`controller.appprotectdos.memory` | RAM memory size to consume in MB. | 50% of free RAM in the container or 80MB, the smaller | 272 | |`controller.readyStatus.enable` | Enables the readiness endpoint `"/nginx-ready"`. The endpoint returns a success code when NGINX has loaded all the config after the startup. This also configures a readiness probe for the Ingress Controller pods that uses the readiness endpoint. | true | 273 | |`controller.readyStatus.port` | The HTTP port for the readiness endpoint. | 8081 | 274 | |`controller.readyStatus.initialDelaySeconds` | The number of seconds after the Ingress Controller pod has started before readiness probes are initiated. | 0 | 275 | |`controller.enableLatencyMetrics` | Enable collection of latency metrics for upstreams. Requires `prometheus.create`. | false | 276 | |`controller.minReadySeconds` | Specifies the minimum number of seconds for which a newly created Pod should be ready without any of its containers crashing, for it to be considered available. [docs](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#min-ready-seconds) | 0 | 277 | |`controller.autoscaling.enabled` | Enables HorizontalPodAutoscaling. | false | 278 | |`controller.autoscaling.annotations` | The annotations of the Ingress Controller HorizontalPodAutoscaler. | {} | 279 | |`controller.autoscaling.minReplicas` | Minimum number of replicas for the HPA. | 1 | 280 | |`controller.autoscaling.maxReplicas` | Maximum number of replicas for the HPA. | 3 | 281 | |`controller.autoscaling.targetCPUUtilizationPercentage` | The target CPU utilization percentage. | 50 | 282 | |`controller.autoscaling.targetMemoryUtilizationPercentage` | The target memory utilization percentage. | 50 | 283 | |`controller.podDisruptionBudget.enabled` | Enables PodDisruptionBudget. | false | 284 | |`controller.podDisruptionBudget.annotations` | The annotations of the Ingress Controller pod disruption budget | {} | 285 | |`controller.podDisruptionBudget.minAvailable` | The number of Ingress Controller pods that should be available. This is a mutually exclusive setting with "maxUnavailable". | 0 | 286 | |`controller.podDisruptionBudget.maxUnavailable` | The number of Ingress Controller pods that can be unavailable. This is a mutually exclusive setting with "minAvailable". | 0 | 287 | |`controller.strategy` | Specifies the strategy used to replace old Pods with new ones. Docs for [Deployment update strategy](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/#strategy) and [Daemonset update strategy](https://kubernetes.io/docs/tasks/manage-daemon/update-daemon-set/#daemonset-update-strategy) | {} | 288 | |`controller.disableIPV6` | Disable IPV6 listeners explicitly for nodes that do not support the IPV6 stack. | false | 289 | |`controller.readOnlyRootFilesystem` | Configure root filesystem as read-only and add volumes for temporary data. | false | 290 | |`rbac.create` | Configures RBAC. | true | 291 | |`prometheus.create` | Expose NGINX or NGINX Plus metrics in the Prometheus format. | true | 292 | |`prometheus.port` | Configures the port to scrape the metrics. | 9113 | 293 | |`prometheus.scheme` | Configures the HTTP scheme to use for connections to the Prometheus endpoint. | http | 294 | |`prometheus.secret` | The namespace / name of a Kubernetes TLS Secret. If specified, this secret is used to secure the Prometheus endpoint with TLS connections. | "" | 295 | |`serviceInsight.create` | Expose NGINX Plus Service Insight endpoint. | false | 296 | |`serviceInsight.port` | Configures the port to expose endpoints. | 9114 | 297 | |`serviceInsight.scheme` | Configures the HTTP scheme to use for connections to the Service Insight endpoint. | http | 298 | |`serviceInsight.secret` | The namespace / name of a Kubernetes TLS Secret. If specified, this secret is used to secure the Service Insight endpoint with TLS connections. | "" | 299 | |`nginxServiceMesh.enable` | Enable integration with NGINX Service Mesh. See the NGINX Service Mesh [docs](https://docs.nginx.com/nginx-service-mesh/tutorials/kic/deploy-with-kic/) for more details. Requires `controller.nginxplus`. | false | 300 | |`nginxServiceMesh.enableEgress` | Enable NGINX Service Mesh workloads to route egress traffic through the Ingress Controller. See the NGINX Service Mesh [docs](https://docs.nginx.com/nginx-service-mesh/tutorials/kic/deploy-with-kic/#enabling-egress) for more details. Requires `nginxServiceMesh.enable`. | false | 301 | 302 | ## Notes 303 | 304 | - The values-icp.yaml file is used for deploying the Ingress Controller on IBM Cloud Private. See the [blog post](https://www.nginx.com/blog/nginx-ingress-controller-ibm-cloud-private/) for more details. 305 | - The values-nsm.yaml file is used for deploying the Ingress Controller with NGINX Service Mesh. See the NGINX Service Mesh [docs](https://docs.nginx.com/nginx-service-mesh/tutorials/kic/deploy-with-kic/) for more details. 306 | -------------------------------------------------------------------------------- /helm_charts/nginx_ingress/crds/appprotect.f5.com_aplogconfs.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apiextensions.k8s.io/v1 2 | kind: CustomResourceDefinition 3 | metadata: 4 | annotations: 5 | controller-gen.kubebuilder.io/version: v0.10.0 6 | creationTimestamp: null 7 | name: aplogconfs.appprotect.f5.com 8 | spec: 9 | group: appprotect.f5.com 10 | names: 11 | kind: APLogConf 12 | listKind: APLogConfList 13 | plural: aplogconfs 14 | singular: aplogconf 15 | preserveUnknownFields: false 16 | scope: Namespaced 17 | versions: 18 | - name: v1beta1 19 | schema: 20 | openAPIV3Schema: 21 | description: APLogConf is the Schema for the APLogConfs API 22 | properties: 23 | apiVersion: 24 | description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 25 | type: string 26 | kind: 27 | description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 28 | type: string 29 | metadata: 30 | type: object 31 | spec: 32 | description: APLogConfSpec defines the desired state of APLogConf 33 | properties: 34 | content: 35 | properties: 36 | escaping_characters: 37 | items: 38 | properties: 39 | from: 40 | type: string 41 | to: 42 | type: string 43 | type: object 44 | type: array 45 | format: 46 | enum: 47 | - splunk 48 | - arcsight 49 | - default 50 | - user-defined 51 | - grpc 52 | type: string 53 | format_string: 54 | type: string 55 | list_delimiter: 56 | type: string 57 | list_prefix: 58 | type: string 59 | list_suffix: 60 | type: string 61 | max_message_size: 62 | pattern: ^([1-9]|[1-5][0-9]|6[0-4])k$ 63 | type: string 64 | max_request_size: 65 | pattern: ^([1-9]|[1-9][0-9]|[1-9][0-9]{2}|1[0-9]{3}|20[1-3][0-9]|204[1-8]|any)$ 66 | type: string 67 | type: object 68 | filter: 69 | properties: 70 | request_type: 71 | enum: 72 | - all 73 | - illegal 74 | - blocked 75 | type: string 76 | type: object 77 | type: object 78 | type: object 79 | served: true 80 | storage: true 81 | -------------------------------------------------------------------------------- /helm_charts/nginx_ingress/crds/appprotect.f5.com_apusersigs.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apiextensions.k8s.io/v1 2 | kind: CustomResourceDefinition 3 | metadata: 4 | annotations: 5 | controller-gen.kubebuilder.io/version: v0.10.0 6 | creationTimestamp: null 7 | name: apusersigs.appprotect.f5.com 8 | spec: 9 | group: appprotect.f5.com 10 | names: 11 | kind: APUserSig 12 | listKind: APUserSigList 13 | plural: apusersigs 14 | singular: apusersig 15 | preserveUnknownFields: false 16 | scope: Namespaced 17 | versions: 18 | - name: v1beta1 19 | schema: 20 | openAPIV3Schema: 21 | description: APUserSig is the Schema for the apusersigs API 22 | properties: 23 | apiVersion: 24 | description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 25 | type: string 26 | kind: 27 | description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 28 | type: string 29 | metadata: 30 | type: object 31 | spec: 32 | description: APUserSigSpec defines the desired state of APUserSig 33 | properties: 34 | properties: 35 | type: string 36 | signatures: 37 | items: 38 | properties: 39 | accuracy: 40 | enum: 41 | - high 42 | - medium 43 | - low 44 | type: string 45 | attackType: 46 | properties: 47 | name: 48 | type: string 49 | type: object 50 | description: 51 | type: string 52 | name: 53 | type: string 54 | references: 55 | properties: 56 | type: 57 | enum: 58 | - bugtraq 59 | - cve 60 | - nessus 61 | - url 62 | type: string 63 | value: 64 | type: string 65 | type: object 66 | risk: 67 | enum: 68 | - high 69 | - medium 70 | - low 71 | type: string 72 | rule: 73 | type: string 74 | signatureType: 75 | enum: 76 | - request 77 | - response 78 | type: string 79 | systems: 80 | items: 81 | properties: 82 | name: 83 | type: string 84 | type: object 85 | type: array 86 | type: object 87 | type: array 88 | tag: 89 | type: string 90 | type: object 91 | type: object 92 | served: true 93 | storage: true 94 | -------------------------------------------------------------------------------- /helm_charts/nginx_ingress/crds/appprotectdos.f5.com_apdoslogconfs.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apiextensions.k8s.io/v1 2 | kind: CustomResourceDefinition 3 | metadata: 4 | annotations: 5 | controller-gen.kubebuilder.io/version: v0.9.2 6 | creationTimestamp: null 7 | name: apdoslogconfs.appprotectdos.f5.com 8 | spec: 9 | group: appprotectdos.f5.com 10 | names: 11 | kind: APDosLogConf 12 | listKind: APDosLogConfList 13 | plural: apdoslogconfs 14 | singular: apdoslogconf 15 | preserveUnknownFields: false 16 | scope: Namespaced 17 | versions: 18 | - name: v1beta1 19 | schema: 20 | openAPIV3Schema: 21 | description: APDosLogConf is the Schema for the APDosLogConfs API 22 | properties: 23 | apiVersion: 24 | description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 25 | type: string 26 | kind: 27 | description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 28 | type: string 29 | metadata: 30 | type: object 31 | spec: 32 | description: APDosLogConfSpec defines the desired state of APDosLogConf 33 | properties: 34 | content: 35 | properties: 36 | format: 37 | enum: 38 | - splunk 39 | - arcsight 40 | - user-defined 41 | type: string 42 | format_string: 43 | type: string 44 | max_message_size: 45 | pattern: ^([1-9]|[1-5][0-9]|6[0-4])k$ 46 | type: string 47 | type: object 48 | filter: 49 | properties: 50 | traffic-mitigation-stats: 51 | enum: 52 | - none 53 | - all 54 | default: all 55 | type: string 56 | bad-actors: 57 | pattern: ^(none|all|top ([1-9]|[1-9][0-9]|[1-9][0-9]{2,4}|100000))$ 58 | default: top 10 59 | type: string 60 | attack-signatures: 61 | pattern: ^(none|all|top ([1-9]|[1-9][0-9]|[1-9][0-9]{2,4}|100000))$ 62 | default: top 10 63 | type: string 64 | type: object 65 | type: object 66 | type: object 67 | served: true 68 | storage: true 69 | -------------------------------------------------------------------------------- /helm_charts/nginx_ingress/crds/appprotectdos.f5.com_apdospolicy.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apiextensions.k8s.io/v1 2 | kind: CustomResourceDefinition 3 | metadata: 4 | annotations: 5 | controller-gen.kubebuilder.io/version: v0.9.2 6 | creationTimestamp: null 7 | name: apdospolicies.appprotectdos.f5.com 8 | spec: 9 | group: appprotectdos.f5.com 10 | names: 11 | kind: APDosPolicy 12 | listKind: APDosPoliciesList 13 | plural: apdospolicies 14 | singular: apdospolicy 15 | preserveUnknownFields: false 16 | scope: Namespaced 17 | versions: 18 | - name: v1beta1 19 | schema: 20 | openAPIV3Schema: 21 | type: object 22 | description: APDosPolicy is the Schema for the APDosPolicy API 23 | properties: 24 | apiVersion: 25 | description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 26 | type: string 27 | kind: 28 | description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 29 | type: string 30 | metadata: 31 | type: object 32 | spec: 33 | type: object 34 | description: APDosPolicySpec defines the desired state of APDosPolicy 35 | properties: 36 | mitigation_mode: 37 | enum: 38 | - "standard" 39 | - "conservative" 40 | - "none" 41 | default: "standard" 42 | type: string 43 | signatures: 44 | enum: 45 | - "on" 46 | - "off" 47 | default: "on" 48 | type: string 49 | bad_actors: 50 | enum: 51 | - "on" 52 | - "off" 53 | default: "on" 54 | type: string 55 | automation_tools_detection: 56 | enum: 57 | - "on" 58 | - "off" 59 | default: "on" 60 | type: string 61 | tls_fingerprint: 62 | enum: 63 | - "on" 64 | - "off" 65 | default: "on" 66 | type: string 67 | served: true 68 | storage: true 69 | -------------------------------------------------------------------------------- /helm_charts/nginx_ingress/crds/appprotectdos.f5.com_dosprotectedresources.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apiextensions.k8s.io/v1 2 | kind: CustomResourceDefinition 3 | metadata: 4 | annotations: 5 | controller-gen.kubebuilder.io/version: v0.12.1 6 | name: dosprotectedresources.appprotectdos.f5.com 7 | spec: 8 | group: appprotectdos.f5.com 9 | names: 10 | kind: DosProtectedResource 11 | listKind: DosProtectedResourceList 12 | plural: dosprotectedresources 13 | shortNames: 14 | - pr 15 | singular: dosprotectedresource 16 | scope: Namespaced 17 | versions: 18 | - name: v1beta1 19 | schema: 20 | openAPIV3Schema: 21 | description: DosProtectedResource defines a Dos protected resource. 22 | type: object 23 | properties: 24 | apiVersion: 25 | description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 26 | type: string 27 | kind: 28 | description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 29 | type: string 30 | metadata: 31 | type: object 32 | spec: 33 | description: DosProtectedResourceSpec defines the properties and values a DosProtectedResource can have. 34 | type: object 35 | properties: 36 | apDosMonitor: 37 | description: 'ApDosMonitor is how NGINX App Protect DoS monitors the stress level of the protected object. The monitor requests are sent from localhost (127.0.0.1). Default value: URI - None, protocol - http1, timeout - NGINX App Protect DoS default.' 38 | type: object 39 | properties: 40 | protocol: 41 | description: Protocol determines if the server listens on http1 / http2 / grpc / websocket. The default is http1. 42 | type: string 43 | enum: 44 | - http1 45 | - http2 46 | - grpc 47 | - websocket 48 | timeout: 49 | description: Timeout determines how long (in seconds) should NGINX App Protect DoS wait for a response. Default is 10 seconds for http1/http2 and 5 seconds for grpc. 50 | type: integer 51 | format: int64 52 | uri: 53 | description: 'URI is the destination to the desired protected object in the nginx.conf:' 54 | type: string 55 | apDosPolicy: 56 | description: ApDosPolicy is the namespace/name of a ApDosPolicy resource 57 | type: string 58 | dosAccessLogDest: 59 | description: DosAccessLogDest is the network address for the access logs 60 | type: string 61 | dosSecurityLog: 62 | description: DosSecurityLog defines the security log of the DosProtectedResource. 63 | type: object 64 | properties: 65 | apDosLogConf: 66 | description: ApDosLogConf is the namespace/name of a APDosLogConf resource 67 | type: string 68 | dosLogDest: 69 | description: DosLogDest is the network address of a logging service, can be either IP or DNS name. 70 | type: string 71 | enable: 72 | description: Enable enables the security logging feature if set to true 73 | type: boolean 74 | enable: 75 | description: Enable enables the DOS feature if set to true 76 | type: boolean 77 | name: 78 | description: Name is the name of protected object, max of 63 characters. 79 | type: string 80 | served: true 81 | storage: true 82 | -------------------------------------------------------------------------------- /helm_charts/nginx_ingress/crds/externaldns.nginx.org_dnsendpoints.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apiextensions.k8s.io/v1 2 | kind: CustomResourceDefinition 3 | metadata: 4 | annotations: 5 | controller-gen.kubebuilder.io/version: v0.12.1 6 | name: dnsendpoints.externaldns.nginx.org 7 | spec: 8 | group: externaldns.nginx.org 9 | names: 10 | kind: DNSEndpoint 11 | listKind: DNSEndpointList 12 | plural: dnsendpoints 13 | singular: dnsendpoint 14 | scope: Namespaced 15 | versions: 16 | - name: v1 17 | schema: 18 | openAPIV3Schema: 19 | description: DNSEndpoint is the CRD wrapper for Endpoint 20 | type: object 21 | properties: 22 | apiVersion: 23 | description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 24 | type: string 25 | kind: 26 | description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 27 | type: string 28 | metadata: 29 | type: object 30 | spec: 31 | description: DNSEndpointSpec holds information about endpoints. 32 | type: object 33 | properties: 34 | endpoints: 35 | type: array 36 | items: 37 | description: Endpoint describes DNS Endpoint. 38 | type: object 39 | properties: 40 | dnsName: 41 | description: The hostname for the DNS record 42 | type: string 43 | labels: 44 | description: Labels stores labels defined for the Endpoint 45 | type: object 46 | additionalProperties: 47 | type: string 48 | providerSpecific: 49 | description: ProviderSpecific stores provider specific config 50 | type: array 51 | items: 52 | description: ProviderSpecificProperty represents provider specific config property. 53 | type: object 54 | properties: 55 | name: 56 | description: Name of the property 57 | type: string 58 | value: 59 | description: Value of the property 60 | type: string 61 | recordTTL: 62 | description: TTL for the record 63 | type: integer 64 | format: int64 65 | recordType: 66 | description: RecordType type of record, e.g. CNAME, A, SRV, TXT, MX 67 | type: string 68 | targets: 69 | description: The targets the DNS service points to 70 | type: array 71 | items: 72 | type: string 73 | status: 74 | description: DNSEndpointStatus represents generation observed by the external dns controller. 75 | type: object 76 | properties: 77 | observedGeneration: 78 | description: The generation observed by by the external-dns controller. 79 | type: integer 80 | format: int64 81 | served: true 82 | storage: true 83 | subresources: 84 | status: {} 85 | -------------------------------------------------------------------------------- /helm_charts/nginx_ingress/crds/k8s.nginx.org_globalconfigurations.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apiextensions.k8s.io/v1 2 | kind: CustomResourceDefinition 3 | metadata: 4 | annotations: 5 | controller-gen.kubebuilder.io/version: v0.12.1 6 | name: globalconfigurations.k8s.nginx.org 7 | spec: 8 | group: k8s.nginx.org 9 | names: 10 | kind: GlobalConfiguration 11 | listKind: GlobalConfigurationList 12 | plural: globalconfigurations 13 | shortNames: 14 | - gc 15 | singular: globalconfiguration 16 | scope: Namespaced 17 | versions: 18 | - name: v1alpha1 19 | schema: 20 | openAPIV3Schema: 21 | description: GlobalConfiguration defines the GlobalConfiguration resource. 22 | type: object 23 | properties: 24 | apiVersion: 25 | description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 26 | type: string 27 | kind: 28 | description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 29 | type: string 30 | metadata: 31 | type: object 32 | spec: 33 | description: GlobalConfigurationSpec is the spec of the GlobalConfiguration resource. 34 | type: object 35 | properties: 36 | listeners: 37 | type: array 38 | items: 39 | description: Listener defines a listener. 40 | type: object 41 | properties: 42 | name: 43 | type: string 44 | port: 45 | type: integer 46 | protocol: 47 | type: string 48 | served: true 49 | storage: true 50 | -------------------------------------------------------------------------------- /helm_charts/nginx_ingress/crds/k8s.nginx.org_policies.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apiextensions.k8s.io/v1 2 | kind: CustomResourceDefinition 3 | metadata: 4 | annotations: 5 | controller-gen.kubebuilder.io/version: v0.12.1 6 | name: policies.k8s.nginx.org 7 | spec: 8 | group: k8s.nginx.org 9 | names: 10 | kind: Policy 11 | listKind: PolicyList 12 | plural: policies 13 | shortNames: 14 | - pol 15 | singular: policy 16 | scope: Namespaced 17 | versions: 18 | - additionalPrinterColumns: 19 | - description: Current state of the Policy. If the resource has a valid status, it means it has been validated and accepted by the Ingress Controller. 20 | jsonPath: .status.state 21 | name: State 22 | type: string 23 | - jsonPath: .metadata.creationTimestamp 24 | name: Age 25 | type: date 26 | name: v1 27 | schema: 28 | openAPIV3Schema: 29 | description: Policy defines a Policy for VirtualServer and VirtualServerRoute resources. 30 | type: object 31 | properties: 32 | apiVersion: 33 | description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 34 | type: string 35 | kind: 36 | description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 37 | type: string 38 | metadata: 39 | type: object 40 | spec: 41 | description: PolicySpec is the spec of the Policy resource. The spec includes multiple fields, where each field represents a different policy. Only one policy (field) is allowed. 42 | type: object 43 | properties: 44 | accessControl: 45 | description: AccessControl defines an access policy based on the source IP of a request. 46 | type: object 47 | properties: 48 | allow: 49 | type: array 50 | items: 51 | type: string 52 | deny: 53 | type: array 54 | items: 55 | type: string 56 | basicAuth: 57 | description: 'BasicAuth holds HTTP Basic authentication configuration policy status: preview' 58 | type: object 59 | properties: 60 | realm: 61 | type: string 62 | secret: 63 | type: string 64 | egressMTLS: 65 | description: EgressMTLS defines an Egress MTLS policy. 66 | type: object 67 | properties: 68 | ciphers: 69 | type: string 70 | protocols: 71 | type: string 72 | serverName: 73 | type: boolean 74 | sessionReuse: 75 | type: boolean 76 | sslName: 77 | type: string 78 | tlsSecret: 79 | type: string 80 | trustedCertSecret: 81 | type: string 82 | verifyDepth: 83 | type: integer 84 | verifyServer: 85 | type: boolean 86 | ingressClassName: 87 | type: string 88 | ingressMTLS: 89 | description: IngressMTLS defines an Ingress MTLS policy. 90 | type: object 91 | properties: 92 | clientCertSecret: 93 | type: string 94 | crlFileName: 95 | type: string 96 | verifyClient: 97 | type: string 98 | verifyDepth: 99 | type: integer 100 | jwt: 101 | description: JWTAuth holds JWT authentication configuration. 102 | type: object 103 | properties: 104 | jwksURI: 105 | type: string 106 | keyCache: 107 | type: string 108 | realm: 109 | type: string 110 | secret: 111 | type: string 112 | token: 113 | type: string 114 | oidc: 115 | description: OIDC defines an Open ID Connect policy. 116 | type: object 117 | properties: 118 | accessTokenEnable: 119 | type: boolean 120 | authEndpoint: 121 | type: string 122 | authExtraArgs: 123 | type: array 124 | items: 125 | type: string 126 | clientID: 127 | type: string 128 | clientSecret: 129 | type: string 130 | jwksURI: 131 | type: string 132 | redirectURI: 133 | type: string 134 | scope: 135 | type: string 136 | tokenEndpoint: 137 | type: string 138 | zoneSyncLeeway: 139 | type: integer 140 | rateLimit: 141 | description: RateLimit defines a rate limit policy. 142 | type: object 143 | properties: 144 | burst: 145 | type: integer 146 | delay: 147 | type: integer 148 | dryRun: 149 | type: boolean 150 | key: 151 | type: string 152 | logLevel: 153 | type: string 154 | noDelay: 155 | type: boolean 156 | rate: 157 | type: string 158 | rejectCode: 159 | type: integer 160 | zoneSize: 161 | type: string 162 | waf: 163 | description: WAF defines an WAF policy. 164 | type: object 165 | properties: 166 | apBundle: 167 | type: string 168 | apPolicy: 169 | type: string 170 | enable: 171 | type: boolean 172 | securityLog: 173 | description: SecurityLog defines the security log of a WAF policy. 174 | type: object 175 | properties: 176 | apLogConf: 177 | type: string 178 | enable: 179 | type: boolean 180 | logDest: 181 | type: string 182 | securityLogs: 183 | type: array 184 | items: 185 | description: SecurityLog defines the security log of a WAF policy. 186 | type: object 187 | properties: 188 | apLogConf: 189 | type: string 190 | enable: 191 | type: boolean 192 | logDest: 193 | type: string 194 | status: 195 | description: PolicyStatus is the status of the policy resource 196 | type: object 197 | properties: 198 | message: 199 | type: string 200 | reason: 201 | type: string 202 | state: 203 | type: string 204 | served: true 205 | storage: true 206 | subresources: 207 | status: {} 208 | - name: v1alpha1 209 | schema: 210 | openAPIV3Schema: 211 | description: Policy defines a Policy for VirtualServer and VirtualServerRoute resources. 212 | type: object 213 | properties: 214 | apiVersion: 215 | description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 216 | type: string 217 | kind: 218 | description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 219 | type: string 220 | metadata: 221 | type: object 222 | spec: 223 | description: PolicySpec is the spec of the Policy resource. The spec includes multiple fields, where each field represents a different policy. Only one policy (field) is allowed. 224 | type: object 225 | properties: 226 | accessControl: 227 | description: AccessControl defines an access policy based on the source IP of a request. 228 | type: object 229 | properties: 230 | allow: 231 | type: array 232 | items: 233 | type: string 234 | deny: 235 | type: array 236 | items: 237 | type: string 238 | egressMTLS: 239 | description: EgressMTLS defines an Egress MTLS policy. 240 | type: object 241 | properties: 242 | ciphers: 243 | type: string 244 | protocols: 245 | type: string 246 | serverName: 247 | type: boolean 248 | sessionReuse: 249 | type: boolean 250 | sslName: 251 | type: string 252 | tlsSecret: 253 | type: string 254 | trustedCertSecret: 255 | type: string 256 | verifyDepth: 257 | type: integer 258 | verifyServer: 259 | type: boolean 260 | ingressMTLS: 261 | description: IngressMTLS defines an Ingress MTLS policy. 262 | type: object 263 | properties: 264 | clientCertSecret: 265 | type: string 266 | verifyClient: 267 | type: string 268 | verifyDepth: 269 | type: integer 270 | jwt: 271 | description: JWTAuth holds JWT authentication configuration. 272 | type: object 273 | properties: 274 | realm: 275 | type: string 276 | secret: 277 | type: string 278 | token: 279 | type: string 280 | rateLimit: 281 | description: RateLimit defines a rate limit policy. 282 | type: object 283 | properties: 284 | burst: 285 | type: integer 286 | delay: 287 | type: integer 288 | dryRun: 289 | type: boolean 290 | key: 291 | type: string 292 | logLevel: 293 | type: string 294 | noDelay: 295 | type: boolean 296 | rate: 297 | type: string 298 | rejectCode: 299 | type: integer 300 | zoneSize: 301 | type: string 302 | served: true 303 | storage: false 304 | -------------------------------------------------------------------------------- /helm_charts/nginx_ingress/crds/k8s.nginx.org_transportservers.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apiextensions.k8s.io/v1 2 | kind: CustomResourceDefinition 3 | metadata: 4 | annotations: 5 | controller-gen.kubebuilder.io/version: v0.12.1 6 | name: transportservers.k8s.nginx.org 7 | spec: 8 | group: k8s.nginx.org 9 | names: 10 | kind: TransportServer 11 | listKind: TransportServerList 12 | plural: transportservers 13 | shortNames: 14 | - ts 15 | singular: transportserver 16 | scope: Namespaced 17 | versions: 18 | - additionalPrinterColumns: 19 | - description: Current state of the TransportServer. If the resource has a valid status, it means it has been validated and accepted by the Ingress Controller. 20 | jsonPath: .status.state 21 | name: State 22 | type: string 23 | - jsonPath: .status.reason 24 | name: Reason 25 | type: string 26 | - jsonPath: .metadata.creationTimestamp 27 | name: Age 28 | type: date 29 | name: v1alpha1 30 | schema: 31 | openAPIV3Schema: 32 | description: TransportServer defines the TransportServer resource. 33 | type: object 34 | properties: 35 | apiVersion: 36 | description: 'APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 37 | type: string 38 | kind: 39 | description: 'Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 40 | type: string 41 | metadata: 42 | type: object 43 | spec: 44 | description: TransportServerSpec is the spec of the TransportServer resource. 45 | type: object 46 | properties: 47 | action: 48 | description: Action defines an action. 49 | type: object 50 | properties: 51 | pass: 52 | type: string 53 | host: 54 | type: string 55 | ingressClassName: 56 | type: string 57 | listener: 58 | description: TransportServerListener defines a listener for a TransportServer. 59 | type: object 60 | properties: 61 | name: 62 | type: string 63 | protocol: 64 | type: string 65 | serverSnippets: 66 | type: string 67 | sessionParameters: 68 | description: SessionParameters defines session parameters. 69 | type: object 70 | properties: 71 | timeout: 72 | type: string 73 | streamSnippets: 74 | type: string 75 | tls: 76 | description: TLS defines TLS configuration for a TransportServer. 77 | type: object 78 | properties: 79 | secret: 80 | type: string 81 | upstreamParameters: 82 | description: UpstreamParameters defines parameters for an upstream. 83 | type: object 84 | properties: 85 | connectTimeout: 86 | type: string 87 | nextUpstream: 88 | type: boolean 89 | nextUpstreamTimeout: 90 | type: string 91 | nextUpstreamTries: 92 | type: integer 93 | udpRequests: 94 | type: integer 95 | udpResponses: 96 | type: integer 97 | upstreams: 98 | type: array 99 | items: 100 | description: Upstream defines an upstream. 101 | type: object 102 | properties: 103 | failTimeout: 104 | type: string 105 | healthCheck: 106 | description: HealthCheck defines the parameters for active Upstream HealthChecks. 107 | type: object 108 | properties: 109 | enable: 110 | type: boolean 111 | fails: 112 | type: integer 113 | interval: 114 | type: string 115 | jitter: 116 | type: string 117 | match: 118 | description: Match defines the parameters of a custom health check. 119 | type: object 120 | properties: 121 | expect: 122 | type: string 123 | send: 124 | type: string 125 | passes: 126 | type: integer 127 | port: 128 | type: integer 129 | timeout: 130 | type: string 131 | loadBalancingMethod: 132 | type: string 133 | maxConns: 134 | type: integer 135 | maxFails: 136 | type: integer 137 | name: 138 | type: string 139 | port: 140 | type: integer 141 | service: 142 | type: string 143 | status: 144 | description: TransportServerStatus defines the status for the TransportServer resource. 145 | type: object 146 | properties: 147 | message: 148 | type: string 149 | reason: 150 | type: string 151 | state: 152 | type: string 153 | served: true 154 | storage: true 155 | subresources: 156 | status: {} 157 | -------------------------------------------------------------------------------- /helm_charts/nginx_ingress/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | The NGINX Ingress Controller has been installed. 2 | -------------------------------------------------------------------------------- /helm_charts/nginx_ingress/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* vim: set filetype=mustache: */}} 2 | 3 | {{/* 4 | Expand the name of the chart. 5 | */}} 6 | {{- define "nginx-ingress.name" -}} 7 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 8 | {{- end }} 9 | 10 | {{/* 11 | Create a default fully qualified app name. 12 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 13 | If release name contains chart name it will be used as a full name. 14 | */}} 15 | {{- define "nginx-ingress.fullname" -}} 16 | {{- if .Values.fullnameOverride }} 17 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 18 | {{- else }} 19 | {{- $name := default .Chart.Name .Values.nameOverride }} 20 | {{- if contains $name .Release.Name }} 21 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 22 | {{- else }} 23 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 24 | {{- end }} 25 | {{- end }} 26 | {{- end }} 27 | 28 | {{/* 29 | Create a default fully qualified controller name. 30 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 31 | */}} 32 | {{- define "nginx-ingress.controller.fullname" -}} 33 | {{- printf "%s-%s" (include "nginx-ingress.fullname" .) .Values.controller.name | trunc 63 | trimSuffix "-" -}} 34 | {{- end -}} 35 | 36 | {{/* 37 | Create a default fully qualified controller service name. 38 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 39 | */}} 40 | {{- define "nginx-ingress.controller.service.name" -}} 41 | {{- default (include "nginx-ingress.controller.fullname" .) .Values.serviceNameOverride | trunc 63 | trimSuffix "-" -}} 42 | {{- end -}} 43 | 44 | {{/* 45 | Create chart name and version as used by the chart label. 46 | */}} 47 | {{- define "nginx-ingress.chart" -}} 48 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} 49 | {{- end }} 50 | 51 | {{/* 52 | Common labels 53 | */}} 54 | {{- define "nginx-ingress.labels" -}} 55 | helm.sh/chart: {{ include "nginx-ingress.chart" . }} 56 | {{ include "nginx-ingress.selectorLabels" . }} 57 | {{- if .Chart.AppVersion }} 58 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 59 | {{- end }} 60 | app.kubernetes.io/managed-by: {{ .Release.Service }} 61 | {{- end }} 62 | 63 | {{/* 64 | Selector labels 65 | */}} 66 | {{- define "nginx-ingress.selectorLabels" -}} 67 | app.kubernetes.io/name: {{ include "nginx-ingress.name" . }} 68 | app.kubernetes.io/instance: {{ .Release.Name }} 69 | {{- end }} 70 | 71 | {{/* 72 | Expand the name of the configmap. 73 | */}} 74 | {{- define "nginx-ingress.configName" -}} 75 | {{- if .Values.controller.customConfigMap -}} 76 | {{ .Values.controller.customConfigMap }} 77 | {{- else -}} 78 | {{- default (include "nginx-ingress.fullname" .) .Values.controller.config.name -}} 79 | {{- end -}} 80 | {{- end -}} 81 | 82 | {{/* 83 | Expand leader election lock name. 84 | */}} 85 | {{- define "nginx-ingress.leaderElectionName" -}} 86 | {{- if .Values.controller.reportIngressStatus.leaderElectionLockName -}} 87 | {{ .Values.controller.reportIngressStatus.leaderElectionLockName }} 88 | {{- else -}} 89 | {{- printf "%s-%s" (include "nginx-ingress.fullname" .) "leader-election" -}} 90 | {{- end -}} 91 | {{- end -}} 92 | 93 | {{/* 94 | Expand service account name. 95 | */}} 96 | {{- define "nginx-ingress.serviceAccountName" -}} 97 | {{- default (include "nginx-ingress.fullname" .) .Values.controller.serviceAccount.name -}} 98 | {{- end -}} 99 | 100 | {{/* 101 | Expand default TLS name. 102 | */}} 103 | {{- define "nginx-ingress.defaultTLSName" -}} 104 | {{- printf "%s-%s" (include "nginx-ingress.fullname" .) "default-server-tls" -}} 105 | {{- end -}} 106 | 107 | {{/* 108 | Expand wildcard TLS name. 109 | */}} 110 | {{- define "nginx-ingress.wildcardTLSName" -}} 111 | {{- printf "%s-%s" (include "nginx-ingress.fullname" .) "wildcard-tls" -}} 112 | {{- end -}} 113 | 114 | {{- define "nginx-ingress.tag" -}} 115 | {{- default .Chart.AppVersion .Values.controller.image.tag -}} 116 | {{- end -}} 117 | 118 | {{/* 119 | Expand image name. 120 | */}} 121 | {{- define "nginx-ingress.image" -}} 122 | {{- if .Values.controller.image.digest -}} 123 | {{- printf "%s@%s" .Values.controller.image.repository .Values.controller.image.digest -}} 124 | {{- else -}} 125 | {{- printf "%s:%s" .Values.controller.image.repository (include "nginx-ingress.tag" .) -}} 126 | {{- end -}} 127 | {{- end -}} 128 | -------------------------------------------------------------------------------- /helm_charts/nginx_ingress/templates/controller-configmap.yaml: -------------------------------------------------------------------------------- 1 | {{- if not .Values.controller.customConfigMap -}} 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: {{ include "nginx-ingress.configName" . }} 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | {{- include "nginx-ingress.labels" . | nindent 4 }} 9 | {{- if .Values.controller.config.annotations }} 10 | annotations: 11 | {{ toYaml .Values.controller.config.annotations | indent 4 }} 12 | {{- end }} 13 | data: 14 | {{- if .Values.controller.config.entries }} 15 | {{ toYaml .Values.controller.config.entries | indent 2 }} 16 | {{- end }} 17 | {{- end }} 18 | -------------------------------------------------------------------------------- /helm_charts/nginx_ingress/templates/controller-daemonset.yaml: -------------------------------------------------------------------------------- 1 | {{- if eq .Values.controller.kind "daemonset" }} 2 | apiVersion: apps/v1 3 | kind: DaemonSet 4 | metadata: 5 | name: {{ include "nginx-ingress.controller.fullname" . }} 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | {{- include "nginx-ingress.labels" . | nindent 4 }} 9 | {{- if .Values.controller.annotations }} 10 | annotations: {{ toYaml .Values.controller.annotations | nindent 4 }} 11 | {{- end }} 12 | spec: 13 | selector: 14 | matchLabels: 15 | {{- include "nginx-ingress.selectorLabels" . | nindent 6 }} 16 | template: 17 | metadata: 18 | labels: 19 | {{- include "nginx-ingress.selectorLabels" . | nindent 8 }} 20 | {{- if .Values.nginxServiceMesh.enable }} 21 | nsm.nginx.com/enable-ingress: "true" 22 | nsm.nginx.com/enable-egress: "{{ .Values.nginxServiceMesh.enableEgress }}" 23 | nsm.nginx.com/daemonset: {{ include "nginx-ingress.controller.fullname" . }} 24 | {{- end }} 25 | {{- if .Values.controller.pod.extraLabels }} 26 | {{ toYaml .Values.controller.pod.extraLabels | indent 8 }} 27 | {{- end }} 28 | {{- if or .Values.prometheus.create .Values.controller.pod.annotations }} 29 | annotations: 30 | {{- if .Values.prometheus.create }} 31 | prometheus.io/scrape: "true" 32 | prometheus.io/port: "{{ .Values.prometheus.port }}" 33 | prometheus.io/scheme: "{{ .Values.prometheus.scheme }}" 34 | {{- end }} 35 | {{- if .Values.controller.pod.annotations }} 36 | {{ toYaml .Values.controller.pod.annotations | indent 8 }} 37 | {{- end }} 38 | {{- end }} 39 | spec: 40 | serviceAccountName: {{ include "nginx-ingress.serviceAccountName" . }} 41 | automountServiceAccountToken: true 42 | securityContext: 43 | seccompProfile: 44 | type: RuntimeDefault 45 | terminationGracePeriodSeconds: {{ .Values.controller.terminationGracePeriodSeconds }} 46 | {{- if .Values.controller.nodeSelector }} 47 | nodeSelector: 48 | {{ toYaml .Values.controller.nodeSelector | indent 8 }} 49 | {{- end }} 50 | {{- if .Values.controller.tolerations }} 51 | tolerations: 52 | {{ toYaml .Values.controller.tolerations | indent 6 }} 53 | {{- end }} 54 | {{- if .Values.controller.affinity }} 55 | affinity: 56 | {{ toYaml .Values.controller.affinity | indent 8 }} 57 | {{- end }} 58 | {{- if or .Values.controller.readOnlyRootFilesystem .Values.controller.volumes }} 59 | volumes: 60 | {{- end }} 61 | {{- if .Values.controller.readOnlyRootFilesystem }} 62 | - name: nginx-etc 63 | emptyDir: {} 64 | - name: nginx-cache 65 | emptyDir: {} 66 | - name: nginx-lib 67 | emptyDir: {} 68 | - name: nginx-log 69 | emptyDir: {} 70 | {{- end }} 71 | {{- if .Values.controller.volumes }} 72 | {{ toYaml .Values.controller.volumes | indent 6 }} 73 | {{- end }} 74 | {{- if .Values.controller.priorityClassName }} 75 | priorityClassName: {{ .Values.controller.priorityClassName }} 76 | {{- end }} 77 | hostNetwork: {{ .Values.controller.hostNetwork }} 78 | dnsPolicy: {{ .Values.controller.dnsPolicy }} 79 | containers: 80 | - name: {{ include "nginx-ingress.name" . }} 81 | image: {{ include "nginx-ingress.image" . }} 82 | imagePullPolicy: "{{ .Values.controller.image.pullPolicy }}" 83 | {{- if .Values.controller.lifecycle }} 84 | lifecycle: 85 | {{ toYaml .Values.controller.lifecycle | indent 10 }} 86 | {{- end }} 87 | ports: 88 | - name: http 89 | containerPort: 80 90 | hostPort: 80 91 | - name: https 92 | containerPort: 443 93 | hostPort: 443 94 | {{ if .Values.controller.customPorts }} 95 | {{ toYaml .Values.controller.customPorts | indent 8 }} 96 | {{ end }} 97 | {{- if .Values.prometheus.create }} 98 | - name: prometheus 99 | containerPort: {{ .Values.prometheus.port }} 100 | {{- end }} 101 | {{- if .Values.serviceInsight.create }} 102 | - name: service-insight 103 | containerPort: {{ .Values.serviceInsight.port }} 104 | {{- end }} 105 | {{- if .Values.controller.readyStatus.enable }} 106 | - name: readiness-port 107 | containerPort: {{ .Values.controller.readyStatus.port }} 108 | readinessProbe: 109 | httpGet: 110 | path: /nginx-ready 111 | port: readiness-port 112 | periodSeconds: 1 113 | initialDelaySeconds: {{ .Values.controller.readyStatus.initialDelaySeconds }} 114 | {{- end }} 115 | securityContext: 116 | allowPrivilegeEscalation: false 117 | readOnlyRootFilesystem: {{ .Values.controller.readOnlyRootFilesystem }} 118 | runAsUser: 101 #nginx 119 | runAsNonRoot: true 120 | capabilities: 121 | drop: 122 | - ALL 123 | add: 124 | - NET_BIND_SERVICE 125 | {{- if or .Values.controller.readOnlyRootFilesystem .Values.controller.volumeMounts }} 126 | volumeMounts: 127 | {{- end }} 128 | {{- if .Values.controller.readOnlyRootFilesystem }} 129 | - mountPath: /etc/nginx 130 | name: nginx-etc 131 | - mountPath: /var/cache/nginx 132 | name: nginx-cache 133 | - mountPath: /var/lib/nginx 134 | name: nginx-lib 135 | - mountPath: /var/log/nginx 136 | name: nginx-log 137 | {{- end }} 138 | {{- if .Values.controller.volumeMounts }} 139 | {{ toYaml .Values.controller.volumeMounts | indent 8 }} 140 | {{- end }} 141 | env: 142 | - name: POD_NAMESPACE 143 | valueFrom: 144 | fieldRef: 145 | fieldPath: metadata.namespace 146 | - name: POD_NAME 147 | valueFrom: 148 | fieldRef: 149 | fieldPath: metadata.name 150 | {{- if .Values.controller.env }} 151 | {{ toYaml .Values.controller.env | indent 8 }} 152 | {{- end }} 153 | {{- if .Values.nginxServiceMesh.enable }} 154 | - name: POD_SERVICEACCOUNT 155 | valueFrom: 156 | fieldRef: 157 | fieldPath: spec.serviceAccountName 158 | {{- end }} 159 | resources: 160 | {{ toYaml .Values.controller.resources | indent 10 }} 161 | args: 162 | - -nginx-plus={{ .Values.controller.nginxplus }} 163 | - -nginx-reload-timeout={{ .Values.controller.nginxReloadTimeout }} 164 | - -enable-app-protect={{ .Values.controller.appprotect.enable }} 165 | {{- if and .Values.controller.appprotect.enable .Values.controller.appprotect.logLevel }} 166 | - -app-protect-log-level={{ .Values.controller.appprotect.logLevel }} 167 | {{ end }} 168 | - -enable-app-protect-dos={{ .Values.controller.appprotectdos.enable }} 169 | {{- if .Values.controller.appprotectdos.enable }} 170 | - -app-protect-dos-debug={{ .Values.controller.appprotectdos.debug }} 171 | - -app-protect-dos-max-daemons={{ .Values.controller.appprotectdos.maxDaemons }} 172 | - -app-protect-dos-max-workers={{ .Values.controller.appprotectdos.maxWorkers }} 173 | - -app-protect-dos-memory={{ .Values.controller.appprotectdos.memory }} 174 | {{ end }} 175 | - -nginx-configmaps=$(POD_NAMESPACE)/{{ include "nginx-ingress.configName" . }} 176 | {{- if .Values.controller.defaultTLS.secret }} 177 | - -default-server-tls-secret={{ .Values.controller.defaultTLS.secret }} 178 | {{ else if and (.Values.controller.defaultTLS.cert) (.Values.controller.defaultTLS.key) }} 179 | - -default-server-tls-secret=$(POD_NAMESPACE)/{{ include "nginx-ingress.defaultTLSName" . }} 180 | {{- end }} 181 | - -ingress-class={{ .Values.controller.ingressClass }} 182 | {{- if .Values.controller.watchNamespace }} 183 | - -watch-namespace={{ .Values.controller.watchNamespace }} 184 | {{- end }} 185 | {{- if .Values.controller.watchNamespaceLabel }} 186 | - -watch-namespace-label={{ .Values.controller.watchNamespaceLabel }} 187 | {{- end }} 188 | {{- if .Values.controller.watchSecretNamespace }} 189 | - -watch-secret-namespace={{ .Values.controller.watchSecretNamespace }} 190 | {{- end }} 191 | - -health-status={{ .Values.controller.healthStatus }} 192 | - -health-status-uri={{ .Values.controller.healthStatusURI }} 193 | - -nginx-debug={{ .Values.controller.nginxDebug }} 194 | - -v={{ .Values.controller.logLevel }} 195 | - -nginx-status={{ .Values.controller.nginxStatus.enable }} 196 | {{- if .Values.controller.nginxStatus.enable }} 197 | - -nginx-status-port={{ .Values.controller.nginxStatus.port }} 198 | - -nginx-status-allow-cidrs={{ .Values.controller.nginxStatus.allowCidrs }} 199 | {{- end }} 200 | {{- if .Values.controller.reportIngressStatus.enable }} 201 | - -report-ingress-status 202 | {{- if .Values.controller.reportIngressStatus.ingressLink }} 203 | - -ingresslink={{ .Values.controller.reportIngressStatus.ingressLink }} 204 | {{- else if .Values.controller.reportIngressStatus.externalService }} 205 | - -external-service={{ .Values.controller.reportIngressStatus.externalService }} 206 | {{- else if and (.Values.controller.service.create) (eq .Values.controller.service.type "LoadBalancer") }} 207 | - -external-service={{ include "nginx-ingress.controller.service.name" . }} 208 | {{- end }} 209 | {{- end }} 210 | - -enable-leader-election={{ .Values.controller.reportIngressStatus.enableLeaderElection }} 211 | {{- if .Values.controller.reportIngressStatus.enableLeaderElection }} 212 | - -leader-election-lock-name={{ include "nginx-ingress.leaderElectionName" . }} 213 | {{- end }} 214 | {{- if .Values.controller.wildcardTLS.secret }} 215 | - -wildcard-tls-secret={{ .Values.controller.wildcardTLS.secret }} 216 | {{- else if and .Values.controller.wildcardTLS.cert .Values.controller.wildcardTLS.key }} 217 | - -wildcard-tls-secret=$(POD_NAMESPACE)/{{ include "nginx-ingress.wildcardTLSName" . }} 218 | {{- end }} 219 | - -enable-prometheus-metrics={{ .Values.prometheus.create }} 220 | - -prometheus-metrics-listen-port={{ .Values.prometheus.port }} 221 | - -prometheus-tls-secret={{ .Values.prometheus.secret }} 222 | - -enable-service-insight={{ .Values.serviceInsight.create }} 223 | - -service-insight-listen-port={{ .Values.serviceInsight.port }} 224 | - -service-insight-tls-secret={{ .Values.serviceInsight.secret }} 225 | - -enable-custom-resources={{ .Values.controller.enableCustomResources }} 226 | - -enable-snippets={{ .Values.controller.enableSnippets }} 227 | - -include-year={{ .Values.controller.includeYear }} 228 | - -disable-ipv6={{ .Values.controller.disableIPV6 }} 229 | {{- if .Values.controller.enableCustomResources }} 230 | - -enable-tls-passthrough={{ .Values.controller.enableTLSPassthrough }} 231 | - -enable-preview-policies={{ .Values.controller.enablePreviewPolicies }} 232 | - -enable-cert-manager={{ .Values.controller.enableCertManager }} 233 | - -enable-oidc={{ .Values.controller.enableOIDC }} 234 | - -enable-external-dns={{ .Values.controller.enableExternalDNS }} 235 | {{- if .Values.controller.globalConfiguration.create }} 236 | - -global-configuration=$(POD_NAMESPACE)/{{ include "nginx-ingress.controller.fullname" . }} 237 | {{- end }} 238 | {{- end }} 239 | - -ready-status={{ .Values.controller.readyStatus.enable }} 240 | - -ready-status-port={{ .Values.controller.readyStatus.port }} 241 | - -enable-latency-metrics={{ .Values.controller.enableLatencyMetrics }} 242 | {{- if .Values.controller.extraContainers }} 243 | {{ toYaml .Values.controller.extraContainers | nindent 6 }} 244 | {{- end }} 245 | {{- if or .Values.controller.readOnlyRootFilesystem .Values.controller.initContainers }} 246 | initContainers: 247 | {{- end }} 248 | {{- if .Values.controller.readOnlyRootFilesystem }} 249 | - name: init-{{ include "nginx-ingress.name" . }} 250 | image: {{ include "nginx-ingress.image" . }} 251 | imagePullPolicy: "{{ .Values.controller.image.pullPolicy }}" 252 | command: ['cp', '-vdR', '/etc/nginx/.', '/mnt/etc'] 253 | securityContext: 254 | allowPrivilegeEscalation: false 255 | readOnlyRootFilesystem: true 256 | runAsUser: 101 #nginx 257 | runAsNonRoot: true 258 | capabilities: 259 | drop: 260 | - ALL 261 | volumeMounts: 262 | - mountPath: /mnt/etc 263 | name: nginx-etc 264 | {{- end }} 265 | {{- if .Values.controller.initContainers }} 266 | {{ toYaml .Values.controller.initContainers | indent 6 }} 267 | {{- end }} 268 | {{- if .Values.controller.strategy }} 269 | updateStrategy: 270 | {{ toYaml .Values.controller.strategy | indent 4 }} 271 | {{- end }} 272 | {{- if .Values.controller.minReadySeconds }} 273 | minReadySeconds: {{ .Values.controller.minReadySeconds }} 274 | {{- end }} 275 | {{- end }} 276 | -------------------------------------------------------------------------------- /helm_charts/nginx_ingress/templates/controller-deployment.yaml: -------------------------------------------------------------------------------- 1 | {{- if eq .Values.controller.kind "deployment" }} 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: {{ include "nginx-ingress.controller.fullname" . }} 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | {{- include "nginx-ingress.labels" . | nindent 4 }} 9 | {{- if .Values.controller.annotations }} 10 | annotations: {{ toYaml .Values.controller.annotations | nindent 4 }} 11 | {{- end }} 12 | spec: 13 | {{- if not .Values.controller.autoscaling.enabled }} 14 | replicas: {{ .Values.controller.replicaCount }} 15 | {{- end }} 16 | selector: 17 | matchLabels: 18 | {{- include "nginx-ingress.selectorLabels" . | nindent 6 }} 19 | template: 20 | metadata: 21 | labels: 22 | {{- include "nginx-ingress.selectorLabels" . | nindent 8 }} 23 | {{- if .Values.nginxServiceMesh.enable }} 24 | nsm.nginx.com/enable-ingress: "true" 25 | nsm.nginx.com/enable-egress: "{{ .Values.nginxServiceMesh.enableEgress }}" 26 | nsm.nginx.com/deployment: {{ include "nginx-ingress.controller.fullname" . }} 27 | {{- end }} 28 | {{- if .Values.controller.pod.extraLabels }} 29 | {{ toYaml .Values.controller.pod.extraLabels | indent 8 }} 30 | {{- end }} 31 | {{- if or .Values.prometheus.create .Values.controller.pod.annotations }} 32 | annotations: 33 | {{- if .Values.prometheus.create }} 34 | prometheus.io/scrape: "true" 35 | prometheus.io/port: "{{ .Values.prometheus.port }}" 36 | prometheus.io/scheme: "{{ .Values.prometheus.scheme }}" 37 | {{- end }} 38 | {{- if .Values.controller.pod.annotations }} 39 | {{ toYaml .Values.controller.pod.annotations | indent 8 }} 40 | {{- end }} 41 | {{- end }} 42 | spec: 43 | {{- if .Values.controller.nodeSelector }} 44 | nodeSelector: 45 | {{ toYaml .Values.controller.nodeSelector | indent 8 }} 46 | {{- end }} 47 | {{- if .Values.controller.tolerations }} 48 | tolerations: 49 | {{ toYaml .Values.controller.tolerations | indent 6 }} 50 | {{- end }} 51 | {{- if .Values.controller.affinity }} 52 | affinity: 53 | {{ toYaml .Values.controller.affinity | indent 8 }} 54 | {{- end }} 55 | {{- if .Values.controller.topologySpreadConstraints }} 56 | topologySpreadConstraints: 57 | {{ toYaml .Values.controller.topologySpreadConstraints | indent 8 }} 58 | {{- end }} 59 | {{- if or .Values.controller.readOnlyRootFilesystem .Values.controller.volumes }} 60 | volumes: 61 | {{- end }} 62 | {{- if .Values.controller.readOnlyRootFilesystem }} 63 | - name: nginx-etc 64 | emptyDir: {} 65 | - name: nginx-cache 66 | emptyDir: {} 67 | - name: nginx-lib 68 | emptyDir: {} 69 | - name: nginx-log 70 | emptyDir: {} 71 | {{- end }} 72 | {{- if .Values.controller.volumes }} 73 | {{ toYaml .Values.controller.volumes | indent 6 }} 74 | {{- end }} 75 | {{- if .Values.controller.priorityClassName }} 76 | priorityClassName: {{ .Values.controller.priorityClassName }} 77 | {{- end }} 78 | serviceAccountName: {{ include "nginx-ingress.serviceAccountName" . }} 79 | automountServiceAccountToken: true 80 | securityContext: 81 | seccompProfile: 82 | type: RuntimeDefault 83 | terminationGracePeriodSeconds: {{ .Values.controller.terminationGracePeriodSeconds }} 84 | hostNetwork: {{ .Values.controller.hostNetwork }} 85 | dnsPolicy: {{ .Values.controller.dnsPolicy }} 86 | containers: 87 | - image: {{ include "nginx-ingress.image" . }} 88 | name: {{ include "nginx-ingress.name" . }} 89 | imagePullPolicy: "{{ .Values.controller.image.pullPolicy }}" 90 | {{- if .Values.controller.lifecycle }} 91 | lifecycle: 92 | {{ toYaml .Values.controller.lifecycle | indent 10 }} 93 | {{- end }} 94 | ports: 95 | - name: http 96 | containerPort: 80 97 | - name: https 98 | containerPort: 443 99 | {{- if .Values.controller.customPorts }} 100 | {{ toYaml .Values.controller.customPorts | indent 8 }} 101 | {{- end }} 102 | {{- if .Values.prometheus.create }} 103 | - name: prometheus 104 | containerPort: {{ .Values.prometheus.port }} 105 | {{- end }} 106 | {{- if .Values.serviceInsight.create }} 107 | - name: service-insight 108 | containerPort: {{ .Values.serviceInsight.port }} 109 | {{- end }} 110 | {{- if .Values.controller.readyStatus.enable }} 111 | - name: readiness-port 112 | containerPort: {{ .Values.controller.readyStatus.port }} 113 | readinessProbe: 114 | httpGet: 115 | path: /nginx-ready 116 | port: readiness-port 117 | periodSeconds: 1 118 | initialDelaySeconds: {{ .Values.controller.readyStatus.initialDelaySeconds }} 119 | {{- end }} 120 | resources: 121 | {{ toYaml .Values.controller.resources | indent 10 }} 122 | securityContext: 123 | allowPrivilegeEscalation: false 124 | readOnlyRootFilesystem: {{ .Values.controller.readOnlyRootFilesystem }} 125 | runAsUser: 101 #nginx 126 | runAsNonRoot: true 127 | capabilities: 128 | drop: 129 | - ALL 130 | add: 131 | - NET_BIND_SERVICE 132 | {{- if or .Values.controller.readOnlyRootFilesystem .Values.controller.volumeMounts }} 133 | volumeMounts: 134 | {{- end }} 135 | {{- if .Values.controller.readOnlyRootFilesystem }} 136 | - mountPath: /etc/nginx 137 | name: nginx-etc 138 | - mountPath: /var/cache/nginx 139 | name: nginx-cache 140 | - mountPath: /var/lib/nginx 141 | name: nginx-lib 142 | - mountPath: /var/log/nginx 143 | name: nginx-log 144 | {{- end }} 145 | {{- if .Values.controller.volumeMounts}} 146 | {{ toYaml .Values.controller.volumeMounts | indent 8 }} 147 | {{- end }} 148 | env: 149 | - name: POD_NAMESPACE 150 | valueFrom: 151 | fieldRef: 152 | fieldPath: metadata.namespace 153 | - name: POD_NAME 154 | valueFrom: 155 | fieldRef: 156 | fieldPath: metadata.name 157 | {{- if .Values.controller.env }} 158 | {{ toYaml .Values.controller.env | indent 8 }} 159 | {{- end }} 160 | {{- if .Values.nginxServiceMesh.enable }} 161 | - name: POD_SERVICEACCOUNT 162 | valueFrom: 163 | fieldRef: 164 | fieldPath: spec.serviceAccountName 165 | {{- end }} 166 | args: 167 | - -nginx-plus={{ .Values.controller.nginxplus }} 168 | - -nginx-reload-timeout={{ .Values.controller.nginxReloadTimeout }} 169 | - -enable-app-protect={{ .Values.controller.appprotect.enable }} 170 | {{- if and .Values.controller.appprotect.enable .Values.controller.appprotect.logLevel }} 171 | - -app-protect-log-level={{ .Values.controller.appprotect.logLevel }} 172 | {{ end }} 173 | - -enable-app-protect-dos={{ .Values.controller.appprotectdos.enable }} 174 | {{- if .Values.controller.appprotectdos.enable }} 175 | - -app-protect-dos-debug={{ .Values.controller.appprotectdos.debug }} 176 | - -app-protect-dos-max-daemons={{ .Values.controller.appprotectdos.maxDaemons }} 177 | - -app-protect-dos-max-workers={{ .Values.controller.appprotectdos.maxWorkers }} 178 | - -app-protect-dos-memory={{ .Values.controller.appprotectdos.memory }} 179 | {{ end }} 180 | - -nginx-configmaps=$(POD_NAMESPACE)/{{ include "nginx-ingress.configName" . }} 181 | {{- if .Values.controller.defaultTLS.secret }} 182 | - -default-server-tls-secret={{ .Values.controller.defaultTLS.secret }} 183 | {{ else if and (.Values.controller.defaultTLS.cert) (.Values.controller.defaultTLS.key) }} 184 | - -default-server-tls-secret=$(POD_NAMESPACE)/{{ include "nginx-ingress.defaultTLSName" . }} 185 | {{- end }} 186 | - -ingress-class={{ .Values.controller.ingressClass }} 187 | {{- if .Values.controller.watchNamespace }} 188 | - -watch-namespace={{ .Values.controller.watchNamespace }} 189 | {{- end }} 190 | {{- if .Values.controller.watchNamespaceLabel }} 191 | - -watch-namespace-label={{ .Values.controller.watchNamespaceLabel }} 192 | {{- end }} 193 | {{- if .Values.controller.watchSecretNamespace }} 194 | - -watch-secret-namespace={{ .Values.controller.watchSecretNamespace }} 195 | {{- end }} 196 | - -health-status={{ .Values.controller.healthStatus }} 197 | - -health-status-uri={{ .Values.controller.healthStatusURI }} 198 | - -nginx-debug={{ .Values.controller.nginxDebug }} 199 | - -v={{ .Values.controller.logLevel }} 200 | - -nginx-status={{ .Values.controller.nginxStatus.enable }} 201 | {{- if .Values.controller.nginxStatus.enable }} 202 | - -nginx-status-port={{ .Values.controller.nginxStatus.port }} 203 | - -nginx-status-allow-cidrs={{ .Values.controller.nginxStatus.allowCidrs }} 204 | {{- end }} 205 | {{- if .Values.controller.reportIngressStatus.enable }} 206 | - -report-ingress-status 207 | {{- if .Values.controller.reportIngressStatus.ingressLink }} 208 | - -ingresslink={{ .Values.controller.reportIngressStatus.ingressLink }} 209 | {{- else if .Values.controller.reportIngressStatus.externalService }} 210 | - -external-service={{ .Values.controller.reportIngressStatus.externalService }} 211 | {{- else if and (.Values.controller.service.create) (eq .Values.controller.service.type "LoadBalancer") }} 212 | - -external-service={{ include "nginx-ingress.controller.service.name" . }} 213 | {{- end }} 214 | {{- end }} 215 | - -enable-leader-election={{ .Values.controller.reportIngressStatus.enableLeaderElection }} 216 | {{- if .Values.controller.reportIngressStatus.enableLeaderElection }} 217 | - -leader-election-lock-name={{ include "nginx-ingress.leaderElectionName" . }} 218 | {{- end }} 219 | {{- if .Values.controller.wildcardTLS.secret }} 220 | - -wildcard-tls-secret={{ .Values.controller.wildcardTLS.secret }} 221 | {{- else if and .Values.controller.wildcardTLS.cert .Values.controller.wildcardTLS.key }} 222 | - -wildcard-tls-secret=$(POD_NAMESPACE)/{{ include "nginx-ingress.wildcardTLSName" . }} 223 | {{- end }} 224 | - -enable-prometheus-metrics={{ .Values.prometheus.create }} 225 | - -prometheus-metrics-listen-port={{ .Values.prometheus.port }} 226 | - -prometheus-tls-secret={{ .Values.prometheus.secret }} 227 | - -enable-service-insight={{ .Values.serviceInsight.create }} 228 | - -service-insight-listen-port={{ .Values.serviceInsight.port }} 229 | - -service-insight-tls-secret={{ .Values.serviceInsight.secret }} 230 | - -enable-custom-resources={{ .Values.controller.enableCustomResources }} 231 | - -enable-snippets={{ .Values.controller.enableSnippets }} 232 | - -include-year={{ .Values.controller.includeYear }} 233 | - -disable-ipv6={{ .Values.controller.disableIPV6 }} 234 | {{- if .Values.controller.enableCustomResources }} 235 | - -enable-tls-passthrough={{ .Values.controller.enableTLSPassthrough }} 236 | - -enable-preview-policies={{ .Values.controller.enablePreviewPolicies }} 237 | - -enable-cert-manager={{ .Values.controller.enableCertManager }} 238 | - -enable-oidc={{ .Values.controller.enableOIDC }} 239 | - -enable-external-dns={{ .Values.controller.enableExternalDNS }} 240 | {{- if .Values.controller.globalConfiguration.create }} 241 | - -global-configuration=$(POD_NAMESPACE)/{{ include "nginx-ingress.controller.fullname" . }} 242 | {{- end }} 243 | {{- end }} 244 | - -ready-status={{ .Values.controller.readyStatus.enable }} 245 | - -ready-status-port={{ .Values.controller.readyStatus.port }} 246 | - -enable-latency-metrics={{ .Values.controller.enableLatencyMetrics }} 247 | {{- if .Values.controller.extraContainers }} 248 | {{ toYaml .Values.controller.extraContainers | nindent 6 }} 249 | {{- end }} 250 | {{- if or .Values.controller.readOnlyRootFilesystem .Values.controller.initContainers }} 251 | initContainers: 252 | {{- end }} 253 | {{- if .Values.controller.readOnlyRootFilesystem }} 254 | - name: init-{{ include "nginx-ingress.name" . }} 255 | image: {{ include "nginx-ingress.image" . }} 256 | imagePullPolicy: "{{ .Values.controller.image.pullPolicy }}" 257 | command: ['cp', '-vdR', '/etc/nginx/.', '/mnt/etc'] 258 | securityContext: 259 | allowPrivilegeEscalation: false 260 | readOnlyRootFilesystem: true 261 | runAsUser: 101 #nginx 262 | runAsNonRoot: true 263 | capabilities: 264 | drop: 265 | - ALL 266 | volumeMounts: 267 | - mountPath: /mnt/etc 268 | name: nginx-etc 269 | {{- end }} 270 | {{- if .Values.controller.initContainers }} 271 | {{ toYaml .Values.controller.initContainers | indent 6 }} 272 | {{- end }} 273 | {{- if .Values.controller.strategy }} 274 | strategy: 275 | {{ toYaml .Values.controller.strategy | indent 4 }} 276 | {{- end }} 277 | {{- if .Values.controller.minReadySeconds }} 278 | minReadySeconds: {{ .Values.controller.minReadySeconds }} 279 | {{- end }} 280 | {{- end }} 281 | -------------------------------------------------------------------------------- /helm_charts/nginx_ingress/templates/controller-globalconfiguration.yaml: -------------------------------------------------------------------------------- 1 | {{ if .Values.controller.globalConfiguration.create }} 2 | apiVersion: k8s.nginx.org/v1alpha1 3 | kind: GlobalConfiguration 4 | metadata: 5 | name: {{ include "nginx-ingress.controller.fullname" . }} 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | {{- include "nginx-ingress.labels" . | nindent 4 }} 9 | spec: 10 | {{ toYaml .Values.controller.globalConfiguration.spec | indent 2 }} 11 | {{- end }} 12 | -------------------------------------------------------------------------------- /helm_charts/nginx_ingress/templates/controller-hpa.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.controller.autoscaling.enabled (eq .Values.controller.kind "deployment") (semverCompare ">=1.23.0" .Capabilities.KubeVersion.Version) -}} 2 | apiVersion: autoscaling/v2 3 | kind: HorizontalPodAutoscaler 4 | metadata: 5 | name: {{ include "nginx-ingress.controller.fullname" . }} 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | {{- include "nginx-ingress.labels" . | nindent 4 }} 9 | {{- if .Values.controller.autoscaling.annotations }} 10 | annotations: 11 | {{ toYaml .Values.controller.autoscaling.annotations | indent 4 }} 12 | {{- end }} 13 | spec: 14 | scaleTargetRef: 15 | apiVersion: apps/v1 16 | kind: Deployment 17 | name: {{ include "nginx-ingress.controller.fullname" . }} 18 | minReplicas: {{ .Values.controller.autoscaling.minReplicas }} 19 | maxReplicas: {{ .Values.controller.autoscaling.maxReplicas }} 20 | metrics: 21 | {{- if .Values.controller.autoscaling.targetMemoryUtilizationPercentage }} 22 | - type: Resource 23 | resource: 24 | name: memory 25 | target: 26 | type: Utilization 27 | averageUtilization: {{ .Values.controller.autoscaling.targetMemoryUtilizationPercentage }} 28 | {{- end }} 29 | {{- if .Values.controller.autoscaling.targetCPUUtilizationPercentage }} 30 | - type: Resource 31 | resource: 32 | name: cpu 33 | target: 34 | type: Utilization 35 | averageUtilization: {{ .Values.controller.autoscaling.targetCPUUtilizationPercentage }} 36 | {{- end }} 37 | {{- end }} 38 | -------------------------------------------------------------------------------- /helm_charts/nginx_ingress/templates/controller-ingress-class.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: networking.k8s.io/v1 2 | kind: IngressClass 3 | metadata: 4 | name: {{ .Values.controller.ingressClass }} 5 | labels: 6 | {{- include "nginx-ingress.labels" . | nindent 4 }} 7 | {{- if .Values.controller.setAsDefaultIngress }} 8 | annotations: 9 | ingressclass.kubernetes.io/is-default-class: "true" 10 | {{- end }} 11 | spec: 12 | controller: nginx.org/ingress-controller 13 | -------------------------------------------------------------------------------- /helm_charts/nginx_ingress/templates/controller-leader-election-configmap.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.controller.reportIngressStatus.enableLeaderElection }} 2 | apiVersion: v1 3 | kind: ConfigMap 4 | metadata: 5 | name: {{ include "nginx-ingress.leaderElectionName" . }} 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | {{- include "nginx-ingress.labels" . | nindent 4 }} 9 | {{- if .Values.controller.reportIngressStatus.annotations }} 10 | annotations: 11 | {{ toYaml .Values.controller.reportIngressStatus.annotations | indent 4 }} 12 | {{- end }} 13 | {{- end }} 14 | -------------------------------------------------------------------------------- /helm_charts/nginx_ingress/templates/controller-pdb.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.controller.podDisruptionBudget.enabled -}} 2 | apiVersion: policy/v1 3 | kind: PodDisruptionBudget 4 | metadata: 5 | name: {{ include "nginx-ingress.controller.fullname" . }} 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | {{- include "nginx-ingress.labels" . | nindent 4 }} 9 | {{- if .Values.controller.podDisruptionBudget.annotations }} 10 | annotations: 11 | {{ toYaml .Values.controller.podDisruptionBudget.annotations | indent 4 }} 12 | {{- end }} 13 | spec: 14 | selector: 15 | matchLabels: 16 | {{- include "nginx-ingress.selectorLabels" . | nindent 6 }} 17 | {{- if .Values.controller.podDisruptionBudget.minAvailable }} 18 | minAvailable: {{ .Values.controller.podDisruptionBudget.minAvailable }} 19 | {{- end }} 20 | {{- if .Values.controller.podDisruptionBudget.maxUnavailable }} 21 | maxUnavailable: {{ .Values.controller.podDisruptionBudget.maxUnavailable }} 22 | {{- end }} 23 | {{- end }} 24 | -------------------------------------------------------------------------------- /helm_charts/nginx_ingress/templates/controller-secret.yaml: -------------------------------------------------------------------------------- 1 | {{ if and (not .Values.controller.defaultTLS.secret) (.Values.controller.defaultTLS.cert) (.Values.controller.defaultTLS.key) }} 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | name: {{ include "nginx-ingress.defaultTLSName" . }} 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | {{- include "nginx-ingress.labels" . | nindent 4 }} 9 | type: kubernetes.io/tls 10 | data: 11 | tls.crt: {{ .Values.controller.defaultTLS.cert }} 12 | tls.key: {{ .Values.controller.defaultTLS.key }} 13 | {{- end }} 14 | -------------------------------------------------------------------------------- /helm_charts/nginx_ingress/templates/controller-service.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.controller.service.create }} 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: {{ include "nginx-ingress.controller.service.name" . }} 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | {{- include "nginx-ingress.labels" . | nindent 4 }} 9 | {{- if .Values.controller.service.extraLabels }} 10 | {{ toYaml .Values.controller.service.extraLabels | indent 4 }} 11 | {{- end }} 12 | {{- if .Values.controller.service.annotations }} 13 | annotations: 14 | {{ toYaml .Values.controller.service.annotations | indent 4 }} 15 | {{- end }} 16 | spec: 17 | {{- if or (eq .Values.controller.service.type "LoadBalancer") (eq .Values.controller.service.type "NodePort") }} 18 | {{- if .Values.controller.service.externalTrafficPolicy }} 19 | externalTrafficPolicy: {{ .Values.controller.service.externalTrafficPolicy }} 20 | {{- end }} 21 | {{- end }} 22 | {{- if eq .Values.controller.service.type "LoadBalancer" }} 23 | {{- if hasKey .Values.controller.service "allocateLoadBalancerNodePorts" }} 24 | allocateLoadBalancerNodePorts: {{ .Values.controller.service.allocateLoadBalancerNodePorts }} 25 | {{- end }} 26 | {{- if .Values.controller.service.loadBalancerIP }} 27 | loadBalancerIP: {{ .Values.controller.service.loadBalancerIP }} 28 | {{- end }} 29 | {{- if .Values.controller.service.loadBalancerSourceRanges }} 30 | loadBalancerSourceRanges: 31 | {{ toYaml .Values.controller.service.loadBalancerSourceRanges | indent 4 }} 32 | {{- end }} 33 | {{- end }} 34 | type: {{ .Values.controller.service.type }} 35 | {{- if .Values.controller.service.ipFamilyPolicy }} 36 | ipFamilyPolicy: {{ .Values.controller.service.ipFamilyPolicy }} 37 | {{- end }} 38 | {{- if .Values.controller.service.ipFamilies }} 39 | ipFamilies: {{ .Values.controller.service.ipFamilies }} 40 | {{- end }} 41 | ports: 42 | {{- if .Values.controller.service.customPorts }} 43 | {{ toYaml .Values.controller.service.customPorts | indent 2 }} 44 | {{ end }} 45 | {{- if .Values.controller.service.httpPort.enable }} 46 | - port: {{ .Values.controller.service.httpPort.port }} 47 | targetPort: {{ .Values.controller.service.httpPort.targetPort }} 48 | protocol: TCP 49 | name: http 50 | {{- if eq .Values.controller.service.type "NodePort" }} 51 | nodePort: {{ .Values.controller.service.httpPort.nodePort }} 52 | {{- end }} 53 | {{- end }} 54 | {{- if .Values.controller.service.httpsPort.enable }} 55 | - port: {{ .Values.controller.service.httpsPort.port }} 56 | targetPort: {{ .Values.controller.service.httpsPort.targetPort }} 57 | protocol: TCP 58 | name: https 59 | {{- if eq .Values.controller.service.type "NodePort" }} 60 | nodePort: {{ .Values.controller.service.httpsPort.nodePort }} 61 | {{- end }} 62 | {{- end }} 63 | selector: 64 | {{- include "nginx-ingress.selectorLabels" . | nindent 4 }} 65 | {{- if .Values.controller.service.externalIPs }} 66 | externalIPs: 67 | {{ toYaml .Values.controller.service.externalIPs | indent 4 }} 68 | {{- end }} 69 | {{- end }} 70 | -------------------------------------------------------------------------------- /helm_charts/nginx_ingress/templates/controller-serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.rbac.create }} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: {{ include "nginx-ingress.serviceAccountName" . }} 6 | {{- if .Values.controller.serviceAccount.annotations }} 7 | annotations: {{- toYaml .Values.controller.serviceAccount.annotations | nindent 4 }} 8 | {{- end }} 9 | namespace: {{ .Release.Namespace }} 10 | labels: 11 | {{- include "nginx-ingress.labels" . | nindent 4 }} 12 | {{- if .Values.controller.serviceAccount.imagePullSecretName }} 13 | imagePullSecrets: 14 | - name: {{ .Values.controller.serviceAccount.imagePullSecretName }} 15 | {{- end }} 16 | {{- end }} 17 | -------------------------------------------------------------------------------- /helm_charts/nginx_ingress/templates/controller-servicemonitor.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.controller.serviceMonitor.create }} 2 | apiVersion: monitoring.coreos.com/v1 3 | kind: ServiceMonitor 4 | metadata: 5 | name: {{ include "nginx-ingress.controller.fullname" . }} 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | {{- include "nginx-ingress.labels" . | nindent 4 }} 9 | {{- if .Values.controller.serviceMonitor.labels -}} 10 | {{- toYaml .Values.controller.serviceMonitor.labels | nindent 4 }} 11 | {{- end }} 12 | spec: 13 | selector: 14 | matchLabels: 15 | {{- if .Values.controller.serviceMonitor.selectorMatchLabels -}} 16 | {{- toYaml .Values.controller.serviceMonitor.selectorMatchLabels | nindent 6 }} 17 | {{- end }} 18 | {{- include "nginx-ingress.selectorLabels" . | nindent 6 }} 19 | endpoints: 20 | {{- toYaml .Values.controller.serviceMonitor.endpoints | nindent 4 }} 21 | {{- end }} 22 | -------------------------------------------------------------------------------- /helm_charts/nginx_ingress/templates/controller-wildcard-secret.yaml: -------------------------------------------------------------------------------- 1 | {{ if and (not .Values.controller.wildcardTLS.secret) (and .Values.controller.wildcardTLS.cert .Values.controller.wildcardTLS.key) }} 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | name: {{ include "nginx-ingress.wildcardTLSName" . }} 6 | namespace: {{ .Release.Namespace }} 7 | labels: 8 | {{- include "nginx-ingress.labels" . | nindent 4 }} 9 | type: kubernetes.io/tls 10 | data: 11 | tls.crt: {{ .Values.controller.wildcardTLS.cert }} 12 | tls.key: {{ .Values.controller.wildcardTLS.key }} 13 | {{- end }} 14 | -------------------------------------------------------------------------------- /helm_charts/nginx_ingress/templates/rbac.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.rbac.create }} 2 | kind: ClusterRole 3 | apiVersion: rbac.authorization.k8s.io/v1 4 | metadata: 5 | name: {{ include "nginx-ingress.fullname" . }} 6 | labels: 7 | {{- include "nginx-ingress.labels" . | nindent 4 }} 8 | rules: 9 | {{- if .Values.controller.appprotect.enable }} 10 | - apiGroups: 11 | - appprotect.f5.com 12 | resources: 13 | - appolicies 14 | - aplogconfs 15 | - apusersigs 16 | verbs: 17 | - get 18 | - watch 19 | - list 20 | {{- end }} 21 | {{- if .Values.controller.appprotectdos.enable }} 22 | - apiGroups: 23 | - appprotectdos.f5.com 24 | resources: 25 | - apdospolicies 26 | - apdoslogconfs 27 | - dosprotectedresources 28 | verbs: 29 | - get 30 | - watch 31 | - list 32 | {{- end }} 33 | - apiGroups: 34 | - discovery.k8s.io 35 | resources: 36 | - endpointslices 37 | verbs: 38 | - get 39 | - list 40 | - watch 41 | - apiGroups: 42 | - "" 43 | resources: 44 | - services 45 | verbs: 46 | - get 47 | - list 48 | - watch 49 | - apiGroups: 50 | - "" 51 | resources: 52 | - secrets 53 | verbs: 54 | - get 55 | - list 56 | - watch 57 | - apiGroups: 58 | - "" 59 | resources: 60 | - configmaps 61 | verbs: 62 | - get 63 | - list 64 | - watch 65 | {{- if .Values.controller.reportIngressStatus.enableLeaderElection }} 66 | - update 67 | - create 68 | {{- end }} 69 | - apiGroups: 70 | - "" 71 | resources: 72 | - pods 73 | verbs: 74 | - get 75 | - list 76 | - watch 77 | - update 78 | - apiGroups: 79 | - "" 80 | resources: 81 | - namespaces 82 | verbs: 83 | - get 84 | - list 85 | - watch 86 | - apiGroups: 87 | - "" 88 | resources: 89 | - events 90 | verbs: 91 | - create 92 | - patch 93 | - list 94 | - apiGroups: 95 | - coordination.k8s.io 96 | resources: 97 | - leases 98 | verbs: 99 | - get 100 | - list 101 | - watch 102 | - update 103 | - create 104 | - apiGroups: 105 | - networking.k8s.io 106 | resources: 107 | - ingresses 108 | verbs: 109 | - get 110 | - list 111 | - watch 112 | - apiGroups: 113 | - networking.k8s.io 114 | resources: 115 | - ingressclasses 116 | verbs: 117 | - get 118 | {{- if .Values.controller.reportIngressStatus.enable }} 119 | - apiGroups: 120 | - networking.k8s.io 121 | resources: 122 | - ingresses/status 123 | verbs: 124 | - update 125 | {{- end }} 126 | {{- if .Values.controller.enableCustomResources }} 127 | - apiGroups: 128 | - k8s.nginx.org 129 | resources: 130 | - virtualservers 131 | - virtualserverroutes 132 | - globalconfigurations 133 | - transportservers 134 | - policies 135 | verbs: 136 | - list 137 | - watch 138 | - get 139 | - apiGroups: 140 | - k8s.nginx.org 141 | resources: 142 | - virtualservers/status 143 | - virtualserverroutes/status 144 | - policies/status 145 | - transportservers/status 146 | verbs: 147 | - update 148 | {{- end }} 149 | {{- if .Values.controller.reportIngressStatus.ingressLink }} 150 | - apiGroups: 151 | - cis.f5.com 152 | resources: 153 | - ingresslinks 154 | verbs: 155 | - list 156 | - watch 157 | - get 158 | {{- end }} 159 | {{- if .Values.controller.enableCertManager }} 160 | - apiGroups: 161 | - cert-manager.io 162 | resources: 163 | - certificates 164 | verbs: 165 | - list 166 | - watch 167 | - get 168 | - update 169 | - create 170 | - delete 171 | {{- end }} 172 | {{- if .Values.controller.enableExternalDNS }} 173 | - apiGroups: 174 | - externaldns.nginx.org 175 | resources: 176 | - dnsendpoints 177 | verbs: 178 | - list 179 | - watch 180 | - get 181 | - update 182 | - create 183 | - delete 184 | - apiGroups: 185 | - externaldns.nginx.org 186 | resources: 187 | - dnsendpoints/status 188 | verbs: 189 | - update 190 | {{- end }} 191 | --- 192 | kind: ClusterRoleBinding 193 | apiVersion: rbac.authorization.k8s.io/v1 194 | metadata: 195 | name: {{ include "nginx-ingress.fullname" . }} 196 | labels: 197 | {{- include "nginx-ingress.labels" . | nindent 4 }} 198 | subjects: 199 | - kind: ServiceAccount 200 | name: {{ include "nginx-ingress.serviceAccountName" . }} 201 | namespace: {{ .Release.Namespace }} 202 | roleRef: 203 | kind: ClusterRole 204 | name: {{ include "nginx-ingress.fullname" . }} 205 | apiGroup: rbac.authorization.k8s.io 206 | {{- end }} 207 | -------------------------------------------------------------------------------- /helm_charts/nginx_ingress/values-icp.yaml: -------------------------------------------------------------------------------- 1 | controller: 2 | name: controller 3 | kind: daemonset 4 | nginxplus: true 5 | image: 6 | repository: mycluster.icp:8500/kube-system/nginx-plus-ingress 7 | tag: "3.2.1" 8 | nodeSelector: 9 | beta.kubernetes.io/arch: "amd64" 10 | proxy: true 11 | terminationGracePeriodSeconds: 60 12 | tolerations: 13 | - key: "dedicated" 14 | operator: "Exists" 15 | effect: "NoSchedule" 16 | - key: "CriticalAddonsOnly" 17 | operator: "Exists" 18 | -------------------------------------------------------------------------------- /helm_charts/nginx_ingress/values-nsm.yaml: -------------------------------------------------------------------------------- 1 | controller: 2 | name: controller 3 | enableLatencyMetrics: true 4 | nginxServiceMesh: 5 | enable: true 6 | enableEgress: true 7 | -------------------------------------------------------------------------------- /helm_charts/nginx_ingress/values-plus.yaml: -------------------------------------------------------------------------------- 1 | controller: 2 | name: controller 3 | nginxplus: true 4 | image: 5 | repository: nginx-plus-ingress 6 | tag: "3.2.1" 7 | -------------------------------------------------------------------------------- /helm_charts/nginx_ingress/values.yaml: -------------------------------------------------------------------------------- 1 | controller: 2 | ## The name of the Ingress Controller daemonset or deployment. 3 | name: controller 4 | 5 | ## The kind of the Ingress Controller installation - deployment or daemonset. 6 | kind: deployment 7 | 8 | ## Annotations for deployments and daemonsets 9 | annotations: {} 10 | 11 | ## Deploys the Ingress Controller for NGINX Plus. 12 | nginxplus: false 13 | 14 | # Timeout in milliseconds which the Ingress Controller will wait for a successful NGINX reload after a change or at the initial start. 15 | nginxReloadTimeout: 60000 16 | 17 | ## Support for App Protect WAF 18 | appprotect: 19 | ## Enable the App Protect WAF module in the Ingress Controller. 20 | enable: false 21 | ## Sets log level for App Protect WAF. Allowed values: fatal, error, warn, info, debug, trace 22 | # logLevel: fatal 23 | 24 | ## Support for App Protect DoS 25 | appprotectdos: 26 | ## Enable the App Protect DoS module in the Ingress Controller. 27 | enable: false 28 | ## Enable debugging for App Protect DoS. 29 | debug: false 30 | ## Max number of nginx processes to support. 31 | maxWorkers: 0 32 | ## Max number of ADMD instances. 33 | maxDaemons: 0 34 | ## RAM memory size to consume in MB. 35 | memory: 0 36 | 37 | ## Enables the Ingress Controller pods to use the host's network namespace. 38 | hostNetwork: false 39 | 40 | ## DNS policy for the Ingress Controller pods 41 | dnsPolicy: ClusterFirst 42 | 43 | ## Enables debugging for NGINX. Uses the nginx-debug binary. Requires error-log-level: debug in the ConfigMap via `controller.config.entries`. 44 | nginxDebug: false 45 | 46 | ## The log level of the Ingress Controller. 47 | logLevel: 1 48 | 49 | ## A list of custom ports to expose on the NGINX Ingress Controller pod. Follows the conventional Kubernetes yaml syntax for container ports. 50 | customPorts: [] 51 | 52 | image: 53 | ## The image repository of the Ingress Controller. 54 | repository: nginx/nginx-ingress 55 | 56 | ## The tag of the Ingress Controller image. If not specified the appVersion from Chart.yaml is used as a tag. 57 | # tag: "3.2.1" 58 | 59 | ## The digest of the Ingress Controller image. 60 | ## If digest is specified it has precedence over tag and will be used instead 61 | # digest: "sha256:CHANGEME" 62 | 63 | ## The pull policy for the Ingress Controller image. 64 | pullPolicy: IfNotPresent 65 | 66 | ## The lifecycle of the Ingress Controller pods. 67 | lifecycle: {} 68 | 69 | ## The custom ConfigMap to use instead of the one provided by default 70 | customConfigMap: "" 71 | 72 | config: 73 | ## The name of the ConfigMap used by the Ingress Controller. 74 | ## Autogenerated if not set or set to "". 75 | # name: nginx-config 76 | 77 | ## The annotations of the Ingress Controller configmap. 78 | annotations: {} 79 | 80 | ## The entries of the ConfigMap for customizing NGINX configuration. 81 | entries: {} 82 | 83 | ## It is recommended to use your own TLS certificates and keys 84 | defaultTLS: 85 | ## The base64-encoded TLS certificate for the default HTTPS server. By default, a pre-generated self-signed certificate is used. 86 | ## Note: It is recommended that you specify your own certificate. Alternatively, omitting the default server secret completely will configure NGINX to reject TLS connections to the default server. 87 | cert: "" 88 | 89 | ## The base64-encoded TLS key for the default HTTPS server. By default, a pre-generated key is used. 90 | ## Note: It is recommended that you specify your own key. Alternatively, omitting the default server secret completely will configure NGINX to reject TLS connections to the default server. 91 | key: "" 92 | 93 | ## The secret with a TLS certificate and key for the default HTTPS server. 94 | ## The value must follow the following format: `/`. 95 | ## Used as an alternative to specifying a certificate and key using `controller.defaultTLS.cert` and `controller.defaultTLS.key` parameters. 96 | ## Note: Alternatively, omitting the default server secret completely will configure NGINX to reject TLS connections to the default server. 97 | ## Format: / 98 | secret: "" 99 | 100 | wildcardTLS: 101 | ## The base64-encoded TLS certificate for every Ingress/VirtualServer host that has TLS enabled but no secret specified. 102 | ## If the parameter is not set, for such Ingress/VirtualServer hosts NGINX will break any attempt to establish a TLS connection. 103 | cert: "" 104 | 105 | ## The base64-encoded TLS key for every Ingress/VirtualServer host that has TLS enabled but no secret specified. 106 | ## If the parameter is not set, for such Ingress/VirtualServer hosts NGINX will break any attempt to establish a TLS connection. 107 | key: "" 108 | 109 | ## The secret with a TLS certificate and key for every Ingress/VirtualServer host that has TLS enabled but no secret specified. 110 | ## The value must follow the following format: `/`. 111 | ## Used as an alternative to specifying a certificate and key using `controller.wildcardTLS.cert` and `controller.wildcardTLS.key` parameters. 112 | ## Format: / 113 | secret: "" 114 | 115 | ## The node selector for pod assignment for the Ingress Controller pods. 116 | # nodeSelector: {} 117 | 118 | ## The termination grace period of the Ingress Controller pod. 119 | terminationGracePeriodSeconds: 30 120 | 121 | ## HorizontalPodAutoscaling (HPA) 122 | autoscaling: 123 | ## Enables HorizontalPodAutoscaling. 124 | enabled: false 125 | ## The annotations of the Ingress Controller HorizontalPodAutoscaler. 126 | annotations: {} 127 | ## Minimum number of replicas for the HPA. 128 | minReplicas: 1 129 | ## Maximum number of replicas for the HPA. 130 | maxReplicas: 3 131 | ## The target cpu utilization percentage. 132 | targetCPUUtilizationPercentage: 50 133 | ## The target memory utilization percentage. 134 | targetMemoryUtilizationPercentage: 50 135 | 136 | ## The resources of the Ingress Controller pods. 137 | resources: 138 | requests: 139 | cpu: 100m 140 | memory: 128Mi 141 | # limits: 142 | # cpu: 1 143 | # memory: 1Gi 144 | 145 | ## The tolerations of the Ingress Controller pods. 146 | tolerations: [] 147 | 148 | ## The affinity of the Ingress Controller pods. 149 | affinity: {} 150 | 151 | ## The topology spread constraints of the Ingress controller pods. 152 | # topologySpreadConstraints: {} 153 | 154 | ## The additional environment variables to be set on the Ingress Controller pods. 155 | env: [] 156 | # - name: MY_VAR 157 | # value: myvalue 158 | 159 | ## The volumes of the Ingress Controller pods. 160 | volumes: [] 161 | # - name: extra-conf 162 | # configMap: 163 | # name: extra-conf 164 | 165 | ## The volumeMounts of the Ingress Controller pods. 166 | volumeMounts: [] 167 | # - name: extra-conf 168 | # mountPath: /etc/nginx/conf.d/extra.conf 169 | # subPath: extra.conf 170 | 171 | ## InitContainers for the Ingress Controller pods. 172 | initContainers: [] 173 | # - name: init-container 174 | # image: busybox:1.34 175 | # command: ['sh', '-c', 'echo this is initial setup!'] 176 | 177 | ## The minimum number of seconds for which a newly created Pod should be ready without any of its containers crashing, for it to be considered available. 178 | minReadySeconds: 0 179 | 180 | ## Pod disruption budget for the Ingress Controller pods. 181 | podDisruptionBudget: 182 | ## Enables PodDisruptionBudget. 183 | enabled: false 184 | ## The annotations of the Ingress Controller pod disruption budget. 185 | annotations: {} 186 | ## The number of Ingress Controller pods that should be available. This is a mutually exclusive setting with "maxUnavailable". 187 | # minAvailable: 1 188 | ## The number of Ingress Controller pods that can be unavailable. This is a mutually exclusive setting with "minAvailable". 189 | # maxUnavailable: 1 190 | 191 | ## Strategy used to replace old Pods by new ones. .spec.strategy.type can be "Recreate" or "RollingUpdate" for Deployments, and "OnDelete" or "RollingUpdate" for Daemonsets. "RollingUpdate" is the default value. 192 | strategy: {} 193 | 194 | ## Extra containers for the Ingress Controller pods. 195 | extraContainers: [] 196 | # - name: container 197 | # image: busybox:1.34 198 | # command: ['sh', '-c', 'echo this is a sidecar!'] 199 | 200 | ## The number of replicas of the Ingress Controller deployment. 201 | replicaCount: 1 202 | 203 | ## A class of the Ingress Controller. 204 | 205 | ## IngressClass resource with the name equal to the class must be deployed. Otherwise, 206 | ## the Ingress Controller will fail to start. 207 | ## The Ingress Controller only processes resources that belong to its class - i.e. have the "ingressClassName" field resource equal to the class. 208 | 209 | ## The Ingress Controller processes all the resources that do not have the "ingressClassName" field for all versions of kubernetes. 210 | ingressClass: nginx 211 | 212 | ## New Ingresses without an ingressClassName field specified will be assigned the class specified in `controller.ingressClass`. 213 | setAsDefaultIngress: false 214 | 215 | ## Comma separated list of namespaces to watch for Ingress resources. By default the Ingress Controller watches all namespaces. Mutually exclusive with "controller.watchNamespaceLabel". 216 | watchNamespace: "" 217 | 218 | ## Configures the Ingress Controller to watch only those namespaces with label foo=bar. By default the Ingress Controller watches all namespaces. Mutually exclusive with "controller.watchNamespace". 219 | watchNamespaceLabel: "" 220 | 221 | ## Comma separated list of namespaces to watch for Secret resources. By default the Ingress Controller watches all namespaces. 222 | watchSecretNamespace: "" 223 | 224 | ## Enable the custom resources. 225 | enableCustomResources: true 226 | 227 | ## Enable preview policies. This parameter is deprecated. To enable OIDC Policies please use controller.enableOIDC instead. 228 | enablePreviewPolicies: false 229 | 230 | ## Enable OIDC policies. 231 | enableOIDC: false 232 | 233 | ## Include year in log header. This parameter will be removed in release 2.7 and the year will be included by default. 234 | includeYear: false 235 | 236 | ## Enable TLS Passthrough on port 443. Requires controller.enableCustomResources. 237 | enableTLSPassthrough: false 238 | 239 | ## Enable cert manager for Virtual Server resources. Requires controller.enableCustomResources. 240 | enableCertManager: false 241 | 242 | ## Enable external DNS for Virtual Server resources. Requires controller.enableCustomResources. 243 | enableExternalDNS: false 244 | 245 | globalConfiguration: 246 | ## Creates the GlobalConfiguration custom resource. Requires controller.enableCustomResources. 247 | create: false 248 | 249 | ## The spec of the GlobalConfiguration for defining the global configuration parameters of the Ingress Controller. 250 | spec: {} 251 | # listeners: 252 | # - name: dns-udp 253 | # port: 5353 254 | # protocol: UDP 255 | # - name: dns-tcp 256 | # port: 5353 257 | # protocol: TCP 258 | 259 | ## Enable custom NGINX configuration snippets in Ingress, VirtualServer, VirtualServerRoute and TransportServer resources. 260 | enableSnippets: false 261 | 262 | ## Add a location based on the value of health-status-uri to the default server. The location responds with the 200 status code for any request. 263 | ## Useful for external health-checking of the Ingress Controller. 264 | healthStatus: false 265 | 266 | ## Sets the URI of health status location in the default server. Requires controller.healthStatus. 267 | healthStatusURI: "/nginx-health" 268 | 269 | nginxStatus: 270 | ## Enable the NGINX stub_status, or the NGINX Plus API. 271 | enable: true 272 | 273 | ## Set the port where the NGINX stub_status or the NGINX Plus API is exposed. 274 | port: 8080 275 | 276 | ## Add IPv4 IP/CIDR blocks to the allow list for NGINX stub_status or the NGINX Plus API. Separate multiple IP/CIDR by commas. 277 | allowCidrs: "127.0.0.1" 278 | 279 | service: 280 | ## Creates a service to expose the Ingress Controller pods. 281 | create: true 282 | 283 | ## The type of service to create for the Ingress Controller. 284 | type: LoadBalancer 285 | 286 | ## The externalTrafficPolicy of the service. The value Local preserves the client source IP. 287 | externalTrafficPolicy: Local 288 | 289 | ## The annotations of the Ingress Controller service. 290 | annotations: {} 291 | 292 | ## The extra labels of the service. 293 | extraLabels: {} 294 | 295 | ## The static IP address for the load balancer. Requires controller.service.type set to LoadBalancer. The cloud provider must support this feature. 296 | loadBalancerIP: "" 297 | 298 | ## The list of external IPs for the Ingress Controller service. 299 | externalIPs: [] 300 | 301 | ## The IP ranges (CIDR) that are allowed to access the load balancer. Requires controller.service.type set to LoadBalancer. The cloud provider must support this feature. 302 | loadBalancerSourceRanges: [] 303 | 304 | ## Whether to automatically allocate NodePorts (only for LoadBalancers). 305 | # allocateLoadBalancerNodePorts: false 306 | 307 | ## Dual stack preference. 308 | ## Valid values: SingleStack, PreferDualStack, RequireDualStack 309 | # ipFamilyPolicy: SingleStack 310 | 311 | ## List of IP families assigned to this service. 312 | ## Valid values: IPv4, IPv6 313 | # ipFamilies: 314 | # - IPv6 315 | 316 | httpPort: 317 | ## Enables the HTTP port for the Ingress Controller service. 318 | enable: true 319 | 320 | ## The HTTP port of the Ingress Controller service. 321 | port: 80 322 | 323 | ## The custom NodePort for the HTTP port. Requires controller.service.type set to NodePort. 324 | # nodePort: 80 325 | 326 | ## The HTTP port on the POD where the Ingress Controller service is running. 327 | targetPort: 80 328 | 329 | httpsPort: 330 | ## Enables the HTTPS port for the Ingress Controller service. 331 | enable: true 332 | 333 | ## The HTTPS port of the Ingress Controller service. 334 | port: 443 335 | 336 | ## The custom NodePort for the HTTPS port. Requires controller.service.type set to NodePort. 337 | # nodePort: 443 338 | 339 | ## The HTTPS port on the POD where the Ingress Controller service is running. 340 | targetPort: 443 341 | 342 | ## A list of custom ports to expose through the Ingress Controller service. Follows the conventional Kubernetes yaml syntax for service ports. 343 | customPorts: [] 344 | 345 | serviceAccount: 346 | ## The annotations of the service account of the Ingress Controller pods. 347 | annotations: {} 348 | 349 | ## The name of the service account of the Ingress Controller pods. Used for RBAC. 350 | ## Autogenerated if not set or set to "". 351 | # name: nginx-ingress 352 | 353 | ## The name of the secret containing docker registry credentials. 354 | ## Secret must exist in the same namespace as the helm release. 355 | imagePullSecretName: "" 356 | 357 | serviceMonitor: 358 | ## Creates a serviceMonitor to expose statistics on the kubernetes pods. 359 | create: false 360 | 361 | ## Kubernetes object labels to attach to the serviceMonitor object. 362 | labels: {} 363 | 364 | ## A set of labels to allow the selection of endpoints for the ServiceMonitor. 365 | selectorMatchLabels: {} 366 | 367 | ## A list of endpoints allowed as part of this ServiceMonitor. 368 | endpoints: [] 369 | 370 | reportIngressStatus: 371 | ## Updates the address field in the status of Ingress resources with an external address of the Ingress Controller. 372 | ## You must also specify the source of the external address either through an external service via controller.reportIngressStatus.externalService, 373 | ## controller.reportIngressStatus.ingressLink or the external-status-address entry in the ConfigMap via controller.config.entries. 374 | ## Note: controller.config.entries.external-status-address takes precedence over the others. 375 | enable: true 376 | 377 | ## Specifies the name of the service with the type LoadBalancer through which the Ingress Controller is exposed externally. 378 | ## The external address of the service is used when reporting the status of Ingress, VirtualServer and VirtualServerRoute resources. 379 | ## controller.reportIngressStatus.enable must be set to true. 380 | ## The default is autogenerated and matches the created service (see controller.service.create). 381 | # externalService: nginx-ingress 382 | 383 | ## Specifies the name of the IngressLink resource, which exposes the Ingress Controller pods via a BIG-IP system. 384 | ## The IP of the BIG-IP system is used when reporting the status of Ingress, VirtualServer and VirtualServerRoute resources. 385 | ## controller.reportIngressStatus.enable must be set to true. 386 | ingressLink: "" 387 | 388 | ## Enable Leader election to avoid multiple replicas of the controller reporting the status of Ingress resources. controller.reportIngressStatus.enable must be set to true. 389 | enableLeaderElection: true 390 | 391 | ## Specifies the name of the ConfigMap, within the same namespace as the controller, used as the lock for leader election. controller.reportIngressStatus.enableLeaderElection must be set to true. 392 | ## Autogenerated if not set or set to "". 393 | # leaderElectionLockName: "nginx-ingress-leader-election" 394 | 395 | ## The annotations of the leader election configmap. 396 | annotations: {} 397 | 398 | pod: 399 | ## The annotations of the Ingress Controller pod. 400 | annotations: {} 401 | 402 | ## The additional extra labels of the Ingress Controller pod. 403 | extraLabels: {} 404 | 405 | ## The PriorityClass of the Ingress Controller pods. 406 | # priorityClassName: "" 407 | 408 | readyStatus: 409 | ## Enables readiness endpoint "/nginx-ready". The endpoint returns a success code when NGINX has loaded all the config after startup. 410 | enable: true 411 | 412 | ## Set the port where the readiness endpoint is exposed. 413 | port: 8081 414 | 415 | ## The number of seconds after the Ingress Controller pod has started before readiness probes are initiated. 416 | initialDelaySeconds: 0 417 | 418 | ## Enable collection of latency metrics for upstreams. Requires prometheus.create. 419 | enableLatencyMetrics: false 420 | 421 | ## Disable IPV6 listeners explicitly for nodes that do not support the IPV6 stack. 422 | disableIPV6: false 423 | 424 | ## Configure root filesystem as read-only and add volumes for temporary data. 425 | readOnlyRootFilesystem: false 426 | 427 | rbac: 428 | ## Configures RBAC. 429 | create: true 430 | 431 | prometheus: 432 | ## Expose NGINX or NGINX Plus metrics in the Prometheus format. 433 | create: true 434 | 435 | ## Configures the port to scrape the metrics. 436 | port: 9113 437 | 438 | ## Specifies the namespace/name of a Kubernetes TLS Secret which will be used to protect the Prometheus endpoint. 439 | secret: "" 440 | 441 | ## Configures the HTTP scheme used. 442 | scheme: http 443 | 444 | serviceInsight: 445 | ## Expose NGINX Plus Service Insight endpoint. 446 | create: false 447 | 448 | ## Configures the port to expose endpoint. 449 | port: 9114 450 | 451 | ## Specifies the namespace/name of a Kubernetes TLS Secret which will be used to protect the Service Insight endpoint. 452 | secret: "" 453 | 454 | ## Configures the HTTP scheme used. 455 | scheme: http 456 | 457 | nginxServiceMesh: 458 | ## Enables integration with NGINX Service Mesh. 459 | enable: false 460 | 461 | ## Enables NGINX Service Mesh workload to route egress traffic through the Ingress Controller. 462 | ## Requires nginxServiceMesh.enable 463 | enableEgress: false 464 | -------------------------------------------------------------------------------- /helm_charts/prometheus-operator-crds/.gitignore: -------------------------------------------------------------------------------- 1 | !charts/crds/ 2 | !charts/crds/** 3 | !charts/crds/templates/ 4 | !charts/crds/templates/** -------------------------------------------------------------------------------- /helm_charts/prometheus-operator-crds/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /helm_charts/prometheus-operator-crds/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | type: application 3 | version: 6.0.0 4 | name: prometheus-operator-crds 5 | icon: https://raw.githubusercontent.com/prometheus/prometheus.github.io/master/assets/prometheus_logo-cb55bb5c346.png 6 | description: | 7 | A Helm chart that collects custom resource definitions (CRDs) from the Prometheus Operator, allowing for seamless 8 | integration with GitOps tools 9 | keywords: 10 | - prometheus 11 | - crds 12 | appVersion: v0.68.0 13 | kubeVersion: ">=1.16.0-0" 14 | sources: 15 | - https://github.com/prometheus-community/helm-charts 16 | maintainers: 17 | - name: dacamposol 18 | email: dacamposol@gmail.com 19 | - name: desaintmartin 20 | email: cedric@desaintmartin.fr 21 | - name: QuentinBisson 22 | email: quentin.bisson@gmail.com 23 | - name: jkroepke 24 | email: github@jkroepke.de 25 | annotations: 26 | artifacthub.io/links: | 27 | - name: Chart Source 28 | url: https://github.com/prometheus-community/helm-charts 29 | artifacthub.io/maintainers: | 30 | - name: dacamposol 31 | email: dacamposol@gmail.com 32 | - name: desaintmartin 33 | email: cedric@desaintmartin.fr 34 | - name: QuentinBisson 35 | email: quentin.bisson@gmail.com 36 | 37 | dependencies: 38 | - name: crds 39 | version: "0.0.0" 40 | -------------------------------------------------------------------------------- /helm_charts/prometheus-operator-crds/README.md: -------------------------------------------------------------------------------- 1 | # Prometheus Operator CRDs 2 | 3 | This chart brings Custom Resource Definitions (CRD) used by Prometheus Operator introducing the API group `monitoring.coreos.com`. The Prometheus Operator uses Kubernetes custom resources to simplify the deployment and configuration of Prometheus, Alertmanager and related monitoring components. 4 | 5 | For more information on Prometheus Operator and CRDs, please, see [documentation](https://prometheus-operator.dev/docs/operator/design/). 6 | 7 | ## Prerequisites 8 | 9 | - Kubernetes >= 1.16.0 10 | - Helm 3 11 | 12 | ## Get Repository Info 13 | 14 | ```console 15 | helm repo add prometheus-community https://prometheus-community.github.io/helm-charts 16 | helm repo update 17 | ``` 18 | 19 | _See [`helm repo`](https://helm.sh/docs/helm/helm_repo/) for command documentation._ 20 | 21 | 22 | ## Install Chart 23 | 24 | ```console 25 | helm install [RELEASE_NAME] prometheus-community/prometheus-operator-crds 26 | ``` 27 | 28 | _See [configuration](#configuring) below._ 29 | 30 | _See [helm install](https://helm.sh/docs/helm/helm_install/) for command documentation._ 31 | 32 | ## Uninstall Chart 33 | 34 | ```console 35 | helm uninstall [RELEASE_NAME] 36 | ``` 37 | 38 | This removes all the Kubernetes components associated with the chart and deletes the release 39 | _including_ resources of Kind `Prometheus`, `Alertmanager`, `ServiceMonitor`, etc. 40 | 41 | _See [helm uninstall](https://helm.sh/docs/helm/helm_uninstall/) for command documentation._ 42 | 43 | ## Upgrading Chart 44 | 45 | ```console 46 | helm upgrade [RELEASE_NAME] [CHART] --install 47 | ``` 48 | 49 | _See [helm upgrade](https://helm.sh/docs/helm/helm_upgrade/) for command documentation._ 50 | 51 | ## Upgrading to v6.0.0 52 | 53 | The upgraded chart now the following changes: 54 | 55 | - `annotations` value has moved to `crds.annotations` 56 | 57 | ## Configuring 58 | 59 | See [Customizing the Chart Before Installing](https://helm.sh/docs/intro/using_helm/#customizing-the-chart-before-installing). To see all configurable options with detailed comments, visit the chart's [values.yaml](./values.yaml), or run these configuration commands: 60 | 61 | ```console 62 | helm show values prometheus-community/prometheus-operator-crds 63 | ``` 64 | -------------------------------------------------------------------------------- /helm_charts/prometheus-operator-crds/charts/crds/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: crds 3 | version: 0.0.0 4 | -------------------------------------------------------------------------------- /helm_charts/prometheus-operator-crds/charts/crds/templates/crd-prometheusrules.yaml: -------------------------------------------------------------------------------- 1 | # https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/v0.68.0/example/prometheus-operator-crd/monitoring.coreos.com_prometheusrules.yaml 2 | --- 3 | apiVersion: apiextensions.k8s.io/v1 4 | kind: CustomResourceDefinition 5 | metadata: 6 | annotations: 7 | {{- with .Values.annotations }} 8 | {{- toYaml . | nindent 4 }} 9 | {{- end }} 10 | controller-gen.kubebuilder.io/version: v0.11.1 11 | creationTimestamp: null 12 | name: prometheusrules.monitoring.coreos.com 13 | spec: 14 | group: monitoring.coreos.com 15 | names: 16 | categories: 17 | - prometheus-operator 18 | kind: PrometheusRule 19 | listKind: PrometheusRuleList 20 | plural: prometheusrules 21 | shortNames: 22 | - promrule 23 | singular: prometheusrule 24 | scope: Namespaced 25 | versions: 26 | - name: v1 27 | schema: 28 | openAPIV3Schema: 29 | description: PrometheusRule defines recording and alerting rules for a Prometheus 30 | instance 31 | properties: 32 | apiVersion: 33 | description: 'APIVersion defines the versioned schema of this representation 34 | of an object. Servers should convert recognized schemas to the latest 35 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' 36 | type: string 37 | kind: 38 | description: 'Kind is a string value representing the REST resource this 39 | object represents. Servers may infer this from the endpoint the client 40 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' 41 | type: string 42 | metadata: 43 | type: object 44 | spec: 45 | description: Specification of desired alerting rule definitions for Prometheus. 46 | properties: 47 | groups: 48 | description: Content of Prometheus rule file 49 | items: 50 | description: RuleGroup is a list of sequentially evaluated recording 51 | and alerting rules. 52 | properties: 53 | interval: 54 | description: Interval determines how often rules in the group 55 | are evaluated. 56 | pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ 57 | type: string 58 | limit: 59 | description: Limit the number of alerts an alerting rule and 60 | series a recording rule can produce. Limit is supported starting 61 | with Prometheus >= 2.31 and Thanos Ruler >= 0.24. 62 | type: integer 63 | name: 64 | description: Name of the rule group. 65 | minLength: 1 66 | type: string 67 | partial_response_strategy: 68 | description: 'PartialResponseStrategy is only used by ThanosRuler 69 | and will be ignored by Prometheus instances. More info: https://github.com/thanos-io/thanos/blob/main/docs/components/rule.md#partial-response' 70 | pattern: ^(?i)(abort|warn)?$ 71 | type: string 72 | rules: 73 | description: List of alerting and recording rules. 74 | items: 75 | description: 'Rule describes an alerting or recording rule 76 | See Prometheus documentation: [alerting](https://www.prometheus.io/docs/prometheus/latest/configuration/alerting_rules/) 77 | or [recording](https://www.prometheus.io/docs/prometheus/latest/configuration/recording_rules/#recording-rules) 78 | rule' 79 | properties: 80 | alert: 81 | description: Name of the alert. Must be a valid label 82 | value. Only one of `record` and `alert` must be set. 83 | type: string 84 | annotations: 85 | additionalProperties: 86 | type: string 87 | description: Annotations to add to each alert. Only valid 88 | for alerting rules. 89 | type: object 90 | expr: 91 | anyOf: 92 | - type: integer 93 | - type: string 94 | description: PromQL expression to evaluate. 95 | x-kubernetes-int-or-string: true 96 | for: 97 | description: Alerts are considered firing once they have 98 | been returned for this long. 99 | pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ 100 | type: string 101 | keep_firing_for: 102 | description: KeepFiringFor defines how long an alert will 103 | continue firing after the condition that triggered it 104 | has cleared. 105 | minLength: 1 106 | pattern: ^(0|(([0-9]+)y)?(([0-9]+)w)?(([0-9]+)d)?(([0-9]+)h)?(([0-9]+)m)?(([0-9]+)s)?(([0-9]+)ms)?)$ 107 | type: string 108 | labels: 109 | additionalProperties: 110 | type: string 111 | description: Labels to add or overwrite. 112 | type: object 113 | record: 114 | description: Name of the time series to output to. Must 115 | be a valid metric name. Only one of `record` and `alert` 116 | must be set. 117 | type: string 118 | required: 119 | - expr 120 | type: object 121 | type: array 122 | required: 123 | - name 124 | type: object 125 | type: array 126 | x-kubernetes-list-map-keys: 127 | - name 128 | x-kubernetes-list-type: map 129 | type: object 130 | required: 131 | - spec 132 | type: object 133 | served: true 134 | storage: true 135 | -------------------------------------------------------------------------------- /helm_charts/prometheus-operator-crds/hack/update_crds.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) 4 | 5 | if [[ $(uname -s) = "Darwin" ]]; then 6 | VERSION="$(grep ^appVersion "${SCRIPT_DIR}/../Chart.yaml" | sed 's/appVersion: //g')" 7 | else 8 | VERSION="$(grep ^appVersion "${SCRIPT_DIR}/../Chart.yaml" | sed 's/appVersion:\s//g')" 9 | fi 10 | 11 | FILES=( 12 | "crd-alertmanagerconfigs.yaml : monitoring.coreos.com_alertmanagerconfigs.yaml" 13 | "crd-alertmanagers.yaml : monitoring.coreos.com_alertmanagers.yaml" 14 | "crd-podmonitors.yaml : monitoring.coreos.com_podmonitors.yaml" 15 | "crd-probes.yaml : monitoring.coreos.com_probes.yaml" 16 | "crd-prometheusagents.yaml : monitoring.coreos.com_prometheusagents.yaml" 17 | "crd-prometheuses.yaml : monitoring.coreos.com_prometheuses.yaml" 18 | "crd-prometheusrules.yaml : monitoring.coreos.com_prometheusrules.yaml" 19 | "crd-scrapeconfigs.yaml : monitoring.coreos.com_scrapeconfigs.yaml" 20 | "crd-servicemonitors.yaml : monitoring.coreos.com_servicemonitors.yaml" 21 | "crd-thanosrulers.yaml : monitoring.coreos.com_thanosrulers.yaml" 22 | ) 23 | 24 | for line in "${FILES[@]}"; do 25 | DESTINATION=$(echo "${line%%:*}" | xargs) 26 | SOURCE=$(echo "${line##*:}" | xargs) 27 | 28 | URL="https://raw.githubusercontent.com/prometheus-operator/prometheus-operator/$VERSION/example/prometheus-operator-crd/$SOURCE" 29 | 30 | echo -e "Downloading Prometheus Operator CRD with Version ${VERSION}:\n${URL}\n" 31 | 32 | echo "# ${URL}" > "${SCRIPT_DIR}/../charts/crds/templates/${DESTINATION}" 33 | 34 | if ! curl --silent --retry-all-errors --fail --location "${URL}" >> "${SCRIPT_DIR}/../charts/crds/templates/${DESTINATION}"; then 35 | echo -e "Failed to download ${URL}!" 36 | exit 1 37 | fi 38 | 39 | # Update or insert annotations block 40 | if yq -e '.metadata.annotations' "${SCRIPT_DIR}/../charts/crds/crds/" >/dev/null; then 41 | sed -i '/^ annotations:$/a {{- with .Values.annotations }}\n{{- toYaml . | nindent 4 }}\n{{- end }}' "${SCRIPT_DIR}/../charts/crds/templates/${DESTINATION}" 42 | else 43 | sed -i '/^metadata:$/a {{- with .Values.annotations }}\n annotations:\n{{- toYaml . | nindent 4 }}\n{{- end }}' "${SCRIPT_DIR}/../charts/crds/templates/${DESTINATION}" 44 | fi 45 | done 46 | -------------------------------------------------------------------------------- /helm_charts/prometheus-operator-crds/values.yaml: -------------------------------------------------------------------------------- 1 | ## Annotations for CRDs 2 | ## 3 | crds: 4 | annotations: {} 5 | -------------------------------------------------------------------------------- /helm_charts/prometheus/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /helm_charts/prometheus/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: prometheus 3 | description: my helm chart for prometheus monitoring retrieval app 4 | 5 | type: application 6 | 7 | version: 0.1.0 8 | appVersion: "1.0.0" 9 | 10 | maintainers: 11 | - email: duong05102002@gmail.com 12 | name: duongnguyen 13 | -------------------------------------------------------------------------------- /helm_charts/prometheus/templates/alert-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: alertmanager 5 | namespace: monitoring 6 | spec: 7 | replicas: 1 8 | selector: 9 | matchLabels: 10 | app: alertmanager 11 | template: 12 | metadata: 13 | name: alertmanager 14 | labels: 15 | app: alertmanager 16 | spec: 17 | containers: 18 | - name: alertmanager 19 | image: prom/alertmanager:latest 20 | args: 21 | - "--config.file=/etc/alertmanager/config.yml" 22 | - "--storage.path=/alertmanager" 23 | ports: 24 | - name: alertmanager 25 | containerPort: 9093 26 | resources: 27 | requests: 28 | cpu: 200m 29 | memory: 300M 30 | limits: 31 | cpu: 300m 32 | memory: 400M 33 | volumeMounts: 34 | - name: config-volume 35 | mountPath: /etc/alertmanager 36 | - name: alertmanager 37 | mountPath: /alertmanager 38 | volumes: 39 | - name: config-volume 40 | configMap: 41 | name: alertmanager-config 42 | - name: alertmanager 43 | emptyDir: {} -------------------------------------------------------------------------------- /helm_charts/prometheus/templates/alert-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: alertmanager 5 | namespace: monitoring 6 | annotations: 7 | prometheus.io/scrape: 'true' 8 | prometheus.io/port: '9093' 9 | spec: 10 | selector: 11 | app: alertmanager 12 | type: NodePort 13 | ports: 14 | - port: 9093 15 | targetPort: 9093 16 | nodePort: 30002 -------------------------------------------------------------------------------- /helm_charts/prometheus/templates/clusterRole.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: prometheus 5 | rules: 6 | - apiGroups: [""] 7 | resources: 8 | - nodes 9 | - nodes/proxy 10 | - nodes/metrics 11 | - services 12 | - endpoints 13 | - pods 14 | - ingresses 15 | - configmaps 16 | - deployments 17 | verbs: ["get", "list", "watch"] 18 | - apiGroups: 19 | - extensions 20 | resources: 21 | - ingresses 22 | verbs: ["get", "list", "watch"] 23 | - nonResourceURLs: ["/metrics"] 24 | verbs: ["get"] 25 | --- 26 | apiVersion: rbac.authorization.k8s.io/v1 27 | kind: ClusterRoleBinding 28 | metadata: 29 | name: prometheus 30 | roleRef: 31 | apiGroup: rbac.authorization.k8s.io 32 | kind: ClusterRole 33 | name: prometheus 34 | subjects: 35 | - kind: ServiceAccount 36 | name: default 37 | namespace: monitoring 38 | -------------------------------------------------------------------------------- /helm_charts/prometheus/templates/config-map-alert.yaml: -------------------------------------------------------------------------------- 1 | kind: ConfigMap 2 | apiVersion: v1 3 | metadata: 4 | name: alertmanager-config 5 | namespace: monitoring 6 | data: 7 | config.yml: |- 8 | global: 9 | templates: 10 | - '/etc/alertmanager/*.tmpl' 11 | route: 12 | group_by: ['alertname', 'job'] 13 | 14 | group_wait: 10s 15 | repeat_interval: 1m 16 | receiver: discord 17 | 18 | receivers: 19 | - name: discord 20 | discord_configs: 21 | - webhook_url: https://discord.com/api/webhooks/1154759146474840154/X7_9b2GJttnnGACz321salEfNCDrS81RMGI3CNP09v_YqHxEKTHyIkTVpAUtes6fm3sj 22 | -------------------------------------------------------------------------------- /helm_charts/prometheus/templates/config-map.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: ConfigMap 3 | metadata: 4 | name: prometheus-server-conf 5 | labels: 6 | name: prometheus-server-conf 7 | namespace: monitoring 8 | data: 9 | prometheus.rules: |- 10 | groups: 11 | - name: System alerts 12 | rules: 13 | - alert: NodeOutOfMemory 14 | expr: node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes * 100 < 10 15 | for: 1m 16 | labels: 17 | severity: warning 18 | annotations: 19 | summary: Node out of memory 20 | description: Node memory has reached 90% 21 | prometheus.yaml: |- 22 | global: 23 | scrape_interval: 5s 24 | evaluation_interval: 5s 25 | rule_files: 26 | - /etc/prometheus/prometheus.rules 27 | alerting: 28 | alertmanagers: 29 | - scheme: http 30 | static_configs: 31 | - targets: 32 | - "alertmanager.monitoring.svc:9093" 33 | scrape_configs: 34 | - job_name: 'node-exporter' 35 | kubernetes_sd_configs: 36 | - role: endpoints 37 | relabel_configs: 38 | - source_labels: [__meta_kubernetes_endpoints_name] 39 | regex: 'node-exporter' 40 | action: keep 41 | - job_name: 'kubernetes-apiservers' 42 | kubernetes_sd_configs: 43 | - role: endpoints 44 | scheme: https 45 | tls_config: 46 | ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt 47 | bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token 48 | relabel_configs: 49 | - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name] 50 | action: keep 51 | regex: default;kubernetes;https 52 | - job_name: 'kubernetes-nodes' 53 | scheme: https 54 | tls_config: 55 | ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt 56 | bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token 57 | kubernetes_sd_configs: 58 | - role: node 59 | relabel_configs: 60 | - action: labelmap 61 | regex: __meta_kubernetes_node_label_(.+) 62 | - target_label: __address__ 63 | replacement: kubernetes.default.svc:443 64 | - source_labels: [__meta_kubernetes_node_name] 65 | regex: (.+) 66 | target_label: __metrics_path__ 67 | replacement: /api/v1/nodes/${1}/proxy/metrics 68 | - job_name: 'kubernetes-pods' 69 | kubernetes_sd_configs: 70 | - role: pod 71 | relabel_configs: 72 | - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape] 73 | action: keep 74 | regex: true 75 | - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path] 76 | action: replace 77 | target_label: __metrics_path__ 78 | regex: (.+) 79 | - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port] 80 | action: replace 81 | regex: ([^:]+)(?::\d+)?;(\d+) 82 | replacement: $1:$2 83 | target_label: __address__ 84 | - action: labelmap 85 | regex: __meta_kubernetes_pod_label_(.+) 86 | - source_labels: [__meta_kubernetes_namespace] 87 | action: replace 88 | target_label: kubernetes_namespace 89 | - source_labels: [__meta_kubernetes_pod_name] 90 | action: replace 91 | target_label: kubernetes_pod_name 92 | - job_name: 'kube-state-metrics' 93 | static_configs: 94 | - targets: ['kube-state-metrics.kube-system.svc.cluster.local:8080'] 95 | - job_name: 'kubernetes-cadvisor' 96 | scheme: https 97 | tls_config: 98 | ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt 99 | bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token 100 | kubernetes_sd_configs: 101 | - role: node 102 | relabel_configs: 103 | - action: labelmap 104 | regex: __meta_kubernetes_node_label_(.+) 105 | - target_label: __address__ 106 | replacement: kubernetes.default.svc:443 107 | - source_labels: [__meta_kubernetes_node_name] 108 | regex: (.+) 109 | target_label: __metrics_path__ 110 | replacement: /api/v1/nodes/${1}/proxy/metrics/cadvisor 111 | - job_name: 'kubernetes-service-endpoints' 112 | kubernetes_sd_configs: 113 | - role: endpoints 114 | relabel_configs: 115 | - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scrape] 116 | action: keep 117 | regex: true 118 | - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_scheme] 119 | action: replace 120 | target_label: __scheme__ 121 | regex: (https?) 122 | - source_labels: [__meta_kubernetes_service_annotation_prometheus_io_path] 123 | action: replace 124 | target_label: __metrics_path__ 125 | regex: (.+) 126 | - source_labels: [__address__, __meta_kubernetes_service_annotation_prometheus_io_port] 127 | action: replace 128 | target_label: __address__ 129 | regex: ([^:]+)(?::\d+)?;(\d+) 130 | replacement: $1:$2 131 | - action: labelmap 132 | regex: __meta_kubernetes_service_label_(.+) 133 | - source_labels: [__meta_kubernetes_namespace] 134 | action: replace 135 | target_label: kubernetes_namespace 136 | - source_labels: [__meta_kubernetes_service_name] 137 | action: replace 138 | target_label: kubernetes_name 139 | -------------------------------------------------------------------------------- /helm_charts/prometheus/templates/node_exporter.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | apiVersion: apps/v1 3 | kind: DaemonSet 4 | metadata: 5 | labels: 6 | app: node-exporter 7 | name: node-exporter 8 | namespace: monitoring 9 | spec: 10 | selector: 11 | matchLabels: 12 | app: node-exporter 13 | template: 14 | metadata: 15 | annotations: 16 | cluster-autoscaler.kubernetes.io/safe-to-evict: "true" 17 | labels: 18 | app: node-exporter 19 | spec: 20 | containers: 21 | - args: 22 | - --web.listen-address=0.0.0.0:9100 23 | - --path.procfs=/host/proc 24 | - --path.sysfs=/host/sys 25 | image: quay.io/prometheus/node-exporter:v0.18.1 26 | imagePullPolicy: IfNotPresent 27 | name: node-exporter 28 | ports: 29 | - containerPort: 9100 30 | hostPort: 9100 31 | name: metrics 32 | protocol: TCP 33 | resources: 34 | limits: 35 | cpu: 200m 36 | memory: 50Mi 37 | requests: 38 | cpu: 100m 39 | memory: 30Mi 40 | volumeMounts: 41 | - mountPath: /host/proc 42 | name: proc 43 | readOnly: true 44 | - mountPath: /host/sys 45 | name: sys 46 | readOnly: true 47 | hostNetwork: true 48 | hostPID: true 49 | restartPolicy: Always 50 | tolerations: 51 | - effect: NoSchedule 52 | operator: Exists 53 | - effect: NoExecute 54 | operator: Exists 55 | volumes: 56 | - hostPath: 57 | path: /proc 58 | type: "" 59 | name: proc 60 | - hostPath: 61 | path: /sys 62 | type: "" 63 | name: sys 64 | --- 65 | apiVersion: v1 66 | kind: Service 67 | metadata: 68 | labels: 69 | app: node-exporter 70 | name: node-exporter 71 | namespace: monitoring 72 | spec: 73 | ports: 74 | - name: node-exporter 75 | port: 9100 76 | protocol: TCP 77 | targetPort: 9100 78 | selector: 79 | app: node-exporter 80 | sessionAffinity: None 81 | type: ClusterIP 82 | --- 83 | apiVersion: monitoring.coreos.com/v1 84 | kind: ServiceMonitor 85 | metadata: 86 | labels: 87 | app: node-exporter 88 | serviceMonitorSelector: prometheus 89 | name: node-exporter 90 | namespace: monitoring 91 | spec: 92 | endpoints: 93 | - honorLabels: true 94 | interval: 30s 95 | path: /metrics 96 | targetPort: 9100 97 | jobLabel: node-exporter 98 | namespaceSelector: 99 | matchNames: 100 | - prometheus 101 | selector: 102 | matchLabels: 103 | app: node-exporter -------------------------------------------------------------------------------- /helm_charts/prometheus/templates/prometheus-deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ .Release.Name }} 5 | namespace: monitoring 6 | labels: 7 | app: {{ .Release.Name }} 8 | spec: 9 | replicas: 1 10 | selector: 11 | matchLabels: 12 | app: {{ .Release.Name }} 13 | template: 14 | metadata: 15 | labels: 16 | app: {{ .Release.Name }} 17 | spec: 18 | containers: 19 | - name: {{ .Release.Name }} 20 | image: prom/prometheus 21 | args: 22 | - "--storage.tsdb.retention.time=12h" 23 | - "--config.file=/etc/prometheus/prometheus.yaml" 24 | - "--storage.tsdb.path=/prometheus/" 25 | ports: 26 | - containerPort: 9090 27 | volumeMounts: 28 | - name: prometheus-config-volume 29 | mountPath: /etc/prometheus/ 30 | - name: prometheus-storage-volume 31 | mountPath: /prometheus/ 32 | volumes: 33 | - name: prometheus-config-volume 34 | configMap: 35 | defaultMode: 420 36 | name: prometheus-server-conf 37 | 38 | - name: prometheus-storage-volume 39 | emptyDir: {} 40 | -------------------------------------------------------------------------------- /helm_charts/prometheus/templates/prometheus-service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ .Release.Name }} 5 | namespace: monitoring 6 | annotations: 7 | prometheus.io/scrape: 'true' 8 | prometheus.io/port: '9090' 9 | spec: 10 | selector: 11 | app: {{ .Release.Name }} 12 | type: NodePort 13 | ports: 14 | - port: 9090 15 | protocol: TCP 16 | targetPort: 9090 17 | nodePort: 30001 18 | -------------------------------------------------------------------------------- /helm_charts/prometheus/values.yaml: -------------------------------------------------------------------------------- 1 | image: 2 | repository: prom/prometheus 3 | -------------------------------------------------------------------------------- /images/app_pod_metrics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duongngyn0510/continuous-deployment-to-gke-cluster/8a87b724dc9c603380e026f233105c1fca6a96aa/images/app_pod_metrics.png -------------------------------------------------------------------------------- /images/architecture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duongngyn0510/continuous-deployment-to-gke-cluster/8a87b724dc9c603380e026f233105c1fca6a96aa/images/architecture.png -------------------------------------------------------------------------------- /images/connect_gke.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duongngyn0510/continuous-deployment-to-gke-cluster/8a87b724dc9c603380e026f233105c1fca6a96aa/images/connect_gke.png -------------------------------------------------------------------------------- /images/deploy_successfully_2gke.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duongngyn0510/continuous-deployment-to-gke-cluster/8a87b724dc9c603380e026f233105c1fca6a96aa/images/deploy_successfully_2gke.png -------------------------------------------------------------------------------- /images/gke_ui.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duongngyn0510/continuous-deployment-to-gke-cluster/8a87b724dc9c603380e026f233105c1fca6a96aa/images/gke_ui.png -------------------------------------------------------------------------------- /images/grant_access.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duongngyn0510/continuous-deployment-to-gke-cluster/8a87b724dc9c603380e026f233105c1fca6a96aa/images/grant_access.png -------------------------------------------------------------------------------- /images/install_jenkins_vm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duongngyn0510/continuous-deployment-to-gke-cluster/8a87b724dc9c603380e026f233105c1fca6a96aa/images/install_jenkins_vm.png -------------------------------------------------------------------------------- /images/jenkins_cicd.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duongngyn0510/continuous-deployment-to-gke-cluster/8a87b724dc9c603380e026f233105c1fca6a96aa/images/jenkins_cicd.png -------------------------------------------------------------------------------- /images/k8s_jenkins.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duongngyn0510/continuous-deployment-to-gke-cluster/8a87b724dc9c603380e026f233105c1fca6a96aa/images/k8s_jenkins.png -------------------------------------------------------------------------------- /images/node_metrics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duongngyn0510/continuous-deployment-to-gke-cluster/8a87b724dc9c603380e026f233105c1fca6a96aa/images/node_metrics.png -------------------------------------------------------------------------------- /images/pipeline.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/duongngyn0510/continuous-deployment-to-gke-cluster/8a87b724dc9c603380e026f233105c1fca6a96aa/images/pipeline.png -------------------------------------------------------------------------------- /terraform/.gitignore: -------------------------------------------------------------------------------- 1 | .terraform 2 | terraform.tfstate 3 | terraform.tfstate.backup 4 | .terraform.lock.hcl 5 | -------------------------------------------------------------------------------- /terraform/main.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_providers { 3 | google = { 4 | source = "hashicorp/google" 5 | version = "4.80.0" // Provider version 6 | } 7 | } 8 | required_version = "1.5.7" // Terraform version 9 | } 10 | 11 | provider "google" { 12 | credentials = "./mle-course-398013-0ff13b4f23e1.json" 13 | project = var.project_id 14 | region = var.region 15 | } 16 | 17 | // Google Kubernetes Engine 18 | resource "google_container_cluster" "primary" { 19 | name = "${var.k8s}-gke" 20 | location = var.region 21 | remove_default_node_pool = true 22 | initial_node_count = 1 23 | } 24 | 25 | resource "google_container_node_pool" "primary_preemptible_nodes" { 26 | name = "my-node-pool" 27 | location = var.region 28 | cluster = google_container_cluster.primary.name 29 | node_count = 1 30 | 31 | node_config { 32 | preemptible = true 33 | machine_type = "n2-standard-2" # 2 CPU and 8 GB RAM 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /terraform/outputs.tf: -------------------------------------------------------------------------------- 1 | output "project_id" { 2 | value = var.project_id 3 | description = "Project ID" 4 | } 5 | 6 | output "kubernetes_cluster_name" { 7 | value = google_container_cluster.primary.name 8 | description = "GKE Cluster Name" 9 | } 10 | 11 | output "kubernetes_cluster_host" { 12 | value = google_container_cluster.primary.endpoint 13 | description = "GKE Cluster Host" 14 | } 15 | 16 | output "region" { 17 | value = var.region 18 | description = "GKE region" 19 | } 20 | -------------------------------------------------------------------------------- /terraform/variables.tf: -------------------------------------------------------------------------------- 1 | variable "project_id" { 2 | description = "The project ID to host the cluster in" 3 | default = "mle-course-398013" 4 | } 5 | 6 | variable "region" { 7 | description = "The region the cluster in" 8 | default = "us-central1-f" 9 | } 10 | 11 | variable "k8s" { 12 | description = "GKE for text_image_retrieval" 13 | default = "text-image-retrieval" 14 | } 15 | --------------------------------------------------------------------------------