Skip to content

Resolve "Reduce Pod and Deployment cached data"

What does this MR do?

Issue: #195978 (closed)

Slices the Pod and Deployment Hashes from:

https://gitlab.com/gitlab-org/gitlab/blob/master/app/models/clusters/platforms/kubernetes.rb#L95

https://gitlab.com/gitlab-org/gitlab/blob/master/ee/app/models/ee/clusters/platforms/kubernetes.rb#L16

So that we avoid abusing our ReactiveCaching with data we are not using.

Full Kubernetes Response Sample (Before the Change: 15Kb)
{
    "pods": [
        {
            "metadata": {
                "name": "staging-5cdb5f6dc6-wsvzj",
                "generateName": "staging-5cdb5f6dc6-",
                "namespace": "nodejs-19-staging",
                "selfLink": "/api/v1/namespaces/nodejs-19-staging/pods/staging-5cdb5f6dc6-wsvzj",
                "uid": "3fb76cea-3349-11ea-b3f7-42010a84010d",
                "resourceVersion": "40574",
                "creationTimestamp": "2020-01-10T01:33:48Z",
                "labels": {
                    "app": "staging",
                    "pod-template-hash": "5cdb5f6dc6",
                    "release": "staging",
                    "tier": "web",
                    "track": "stable"
                },
                "annotations": {
                    "app.gitlab.com/app": "root-nodejs",
                    "app.gitlab.com/env": "staging",
                    "checksum/application-secrets": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
                },
                "ownerReferences": [
                    {
                        "apiVersion": "apps/v1",
                        "kind": "ReplicaSet",
                        "name": "staging-5cdb5f6dc6",
                        "uid": "3fae5048-3349-11ea-b3f7-42010a84010d",
                        "controller": true,
                        "blockOwnerDeletion": true
                    }
                ]
            },
            "spec": {
                "volumes": [
                    {
                        "name": "default-token-sln2c",
                        "secret": {
                            "secretName": "default-token-sln2c",
                            "defaultMode": 420
                        }
                    }
                ],
                "containers": [
                    {
                        "name": "auto-deploy-app",
                        "image": "29696.qa-tunnel.gitlab.info:443/root/nodejs/master:3677ea89021e8f5436e6dc3e01f53a87f824d442",
                        "ports": [
                            {
                                "name": "web",
                                "containerPort": 5000,
                                "protocol": "TCP"
                            }
                        ],
                        "envFrom": [
                            {
                                "secretRef": {
                                    "name": "staging-secret"
                                }
                            }
                        ],
                        "env": [
                            {
                                "name": "DATABASE_URL",
                                "value": "postgres://user:testing-password@staging-postgres:5432/staging"
                            },
                            {
                                "name": "GITLAB_ENVIRONMENT_NAME",
                                "value": "staging"
                            },
                            {
                                "name": "GITLAB_ENVIRONMENT_URL",
                                "value": "http://root-nodejs-staging.34.77.230.38.nip.io"
                            }
                        ],
                        "resources": {},
                        "volumeMounts": [
                            {
                                "name": "default-token-sln2c",
                                "readOnly": true,
                                "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount"
                            }
                        ],
                        "livenessProbe": {
                            "httpGet": {
                                "path": "/",
                                "port": 5000,
                                "scheme": "HTTP"
                            },
                            "initialDelaySeconds": 15,
                            "timeoutSeconds": 15,
                            "periodSeconds": 10,
                            "successThreshold": 1,
                            "failureThreshold": 3
                        },
                        "readinessProbe": {
                            "httpGet": {
                                "path": "/",
                                "port": 5000,
                                "scheme": "HTTP"
                            },
                            "initialDelaySeconds": 5,
                            "timeoutSeconds": 3,
                            "periodSeconds": 10,
                            "successThreshold": 1,
                            "failureThreshold": 3
                        },
                        "terminationMessagePath": "/dev/termination-log",
                        "terminationMessagePolicy": "File",
                        "imagePullPolicy": "IfNotPresent"
                    }
                ],
                "restartPolicy": "Always",
                "terminationGracePeriodSeconds": 30,
                "dnsPolicy": "ClusterFirst",
                "serviceAccountName": "default",
                "serviceAccount": "default",
                "nodeName": "gke-jcunha-2020-01-09t19-default-pool-c1938372-14qz",
                "securityContext": {},
                "imagePullSecrets": [
                    {}
                ],
                "schedulerName": "default-scheduler",
                "tolerations": [
                    {
                        "key": "node.kubernetes.io/not-ready",
                        "operator": "Exists",
                        "effect": "NoExecute",
                        "tolerationSeconds": 300
                    },
                    {
                        "key": "node.kubernetes.io/unreachable",
                        "operator": "Exists",
                        "effect": "NoExecute",
                        "tolerationSeconds": 300
                    }
                ],
                "priority": 0,
                "enableServiceLinks": true
            },
            "status": {
                "phase": "Running",
                "conditions": [
                    {
                        "type": "Initialized",
                        "status": "True",
                        "lastProbeTime": null,
                        "lastTransitionTime": "2020-01-10T01:33:48Z"
                    },
                    {
                        "type": "Ready",
                        "status": "True",
                        "lastProbeTime": null,
                        "lastTransitionTime": "2020-01-10T01:34:31Z"
                    },
                    {
                        "type": "ContainersReady",
                        "status": "True",
                        "lastProbeTime": null,
                        "lastTransitionTime": "2020-01-10T01:34:31Z"
                    },
                    {
                        "type": "PodScheduled",
                        "status": "True",
                        "lastProbeTime": null,
                        "lastTransitionTime": "2020-01-10T01:33:48Z"
                    }
                ],
                "hostIP": "10.132.0.50",
                "podIP": "10.12.2.11",
                "startTime": "2020-01-10T01:33:48Z",
                "containerStatuses": [
                    {
                        "name": "auto-deploy-app",
                        "state": {
                            "running": {
                                "startedAt": "2020-01-10T01:34:24Z"
                            }
                        },
                        "lastState": {},
                        "ready": true,
                        "restartCount": 0,
                        "image": "29696.qa-tunnel.gitlab.info:443/root/nodejs/master:3677ea89021e8f5436e6dc3e01f53a87f824d442",
                        "imageID": "docker-pullable://29696.qa-tunnel.gitlab.info:443/root/nodejs/master@sha256:43a7217ed656a8135a31d3677d501b8e36d1e4a12e8a93343353b66c70c2df48",
                        "containerID": "docker://73f948aec10398e2f5467c7ee6a68637a679772dc1d612caf42f2eff8ab58e27"
                    }
                ],
                "qosClass": "BestEffort"
            }
        }
    ],
    "deployments": [
        {
            "metadata": {
                "name": "staging",
                "namespace": "nodejs-19-staging",
                "selfLink": "/apis/extensions/v1beta1/namespaces/nodejs-19-staging/deployments/staging",
                "uid": "3fabdd32-3349-11ea-b3f7-42010a84010d",
                "resourceVersion": "40577",
                "generation": 1,
                "creationTimestamp": "2020-01-10T01:33:48Z",
                "labels": {
                    "app": "staging",
                    "chart": "auto-deploy-app-0.4.1",
                    "heritage": "Tiller",
                    "release": "staging",
                    "tier": "web",
                    "track": "stable"
                },
                "annotations": {
                    "app.gitlab.com/app": "root-nodejs",
                    "app.gitlab.com/env": "staging",
                    "deployment.kubernetes.io/revision": "1"
                }
            },
            "spec": {
                "replicas": 1,
                "selector": {
                    "matchLabels": {
                        "app": "staging",
                        "release": "staging",
                        "tier": "web",
                        "track": "stable"
                    }
                },
                "template": {
                    "metadata": {
                        "creationTimestamp": null,
                        "labels": {
                            "app": "staging",
                            "release": "staging",
                            "tier": "web",
                            "track": "stable"
                        },
                        "annotations": {
                            "app.gitlab.com/app": "root-nodejs",
                            "app.gitlab.com/env": "staging",
                            "checksum/application-secrets": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
                        }
                    },
                    "spec": {
                        "containers": [
                            {
                                "name": "auto-deploy-app",
                                "image": "29696.qa-tunnel.gitlab.info:443/root/nodejs/master:3677ea89021e8f5436e6dc3e01f53a87f824d442",
                                "ports": [
                                    {
                                        "name": "web",
                                        "containerPort": 5000,
                                        "protocol": "TCP"
                                    }
                                ],
                                "envFrom": [
                                    {
                                        "secretRef": {
                                            "name": "staging-secret"
                                        }
                                    }
                                ],
                                "env": [
                                    {
                                        "name": "DATABASE_URL",
                                        "value": "postgres://user:testing-password@staging-postgres:5432/staging"
                                    },
                                    {
                                        "name": "GITLAB_ENVIRONMENT_NAME",
                                        "value": "staging"
                                    },
                                    {
                                        "name": "GITLAB_ENVIRONMENT_URL",
                                        "value": "http://root-nodejs-staging.34.77.230.38.nip.io"
                                    }
                                ],
                                "resources": {},
                                "livenessProbe": {
                                    "httpGet": {
                                        "path": "/",
                                        "port": 5000,
                                        "scheme": "HTTP"
                                    },
                                    "initialDelaySeconds": 15,
                                    "timeoutSeconds": 15,
                                    "periodSeconds": 10,
                                    "successThreshold": 1,
                                    "failureThreshold": 3
                                },
                                "readinessProbe": {
                                    "httpGet": {
                                        "path": "/",
                                        "port": 5000,
                                        "scheme": "HTTP"
                                    },
                                    "initialDelaySeconds": 5,
                                    "timeoutSeconds": 3,
                                    "periodSeconds": 10,
                                    "successThreshold": 1,
                                    "failureThreshold": 3
                                },
                                "terminationMessagePath": "/dev/termination-log",
                                "terminationMessagePolicy": "File",
                                "imagePullPolicy": "IfNotPresent"
                            }
                        ],
                        "restartPolicy": "Always",
                        "terminationGracePeriodSeconds": 30,
                        "dnsPolicy": "ClusterFirst",
                        "securityContext": {},
                        "imagePullSecrets": [
                            {}
                        ],
                        "schedulerName": "default-scheduler"
                    }
                },
                "strategy": {
                    "type": "RollingUpdate",
                    "rollingUpdate": {
                        "maxUnavailable": 1,
                        "maxSurge": 1
                    }
                },
                "revisionHistoryLimit": 2147483647,
                "progressDeadlineSeconds": 2147483647
            },
            "status": {
                "observedGeneration": 1,
                "replicas": 1,
                "updatedReplicas": 1,
                "readyReplicas": 1,
                "availableReplicas": 1,
                "conditions": [
                    {
                        "type": "Available",
                        "status": "True",
                        "lastUpdateTime": "2020-01-10T01:33:48Z",
                        "lastTransitionTime": "2020-01-10T01:33:48Z",
                        "reason": "MinimumReplicasAvailable",
                        "message": "Deployment has minimum availability."
                    }
                ]
            }
        }
    ]
}

Sample response of what we really need (After the Change: ~ 1Kb)
{  
  "pods" => [{
    "metadata" => {
      "name" => name,
      "namespace" => namespace,
      "generateName" => "generated-name-with-suffix",
      "creationTimestamp" => "2016-11-25T19:55:19Z",
      "annotations" => {
        "app.gitlab.com/env" => environment_slug,
        "app.gitlab.com/app" => project_slug
      },
      "labels" => {
        "track" => track
      }.compact
    },
    "spec" => {
      "containers" => [
        { "name" => "container-0" },
        { "name" => "container-1" }
      ]
    },
    "status" => { "phase" => status }
  }],
  "deployments" => [{
    "metadata" => {
      "name" => name,
      "generation" => 4,
      "annotations" => {
        "app.gitlab.com/env" => environment_slug,
        "app.gitlab.com/app" => project_slug
      },
      "labels" => {
        "track" => track
      }.compact
    },
    "spec" => { "replicas" => 3 },
    "status" => {
      "observedGeneration" => 4
    }
  }]
}

Extra Work: typo fix

There's a small typo fix where we were reading a Kubernetes attribute generate_name instead of generateName. My gut feel is that this never worked. But we only use this as a fallback for the pod name if the pod name is null, which I'm even curios if it ever happens:

https://gitlab.com/gitlab-org/gitlab/blob/7596cb21f77c0fdaa2c057f9f0762acd7b7e7420/ee/lib/gitlab/kubernetes/deployment.rb#L50

Screenshots

Does this MR meet the acceptance criteria?

Conformity

Availability and Testing

Security

If this MR contains changes to processing or storing of credentials or tokens, authorization and authentication methods and other items described in the security review guidelines:

  • [-] Label as security and @ mention @gitlab-com/gl-security/appsec
  • [-] The MR includes necessary changes to maintain consistency between UI, API, email, or other methods
  • [-] Security reports checked/validated by a reviewer from the AppSec team
Edited by 🤖 GitLab Bot 🤖

Merge request reports