github.com/nilium/gitlab-runner@v12.5.0+incompatible/docs/executors/kubernetes.md (about) 1 # The Kubernetes executor 2 3 GitLab Runner can use Kubernetes to run builds on a Kubernetes cluster. This is 4 possible with the use of the **Kubernetes** executor. 5 6 The **Kubernetes** executor, when used with GitLab CI, connects to the Kubernetes 7 API in the cluster creating a Pod for each GitLab CI Job. This Pod is made 8 up of, at the very least, a build container and an additional container for each 9 `service` defined by the GitLab CI yaml. The names for these containers 10 are as follows: 11 12 - The build container is `build` 13 - The services containers are `svc-X` where `X` is `[0-9]+` 14 15 Note that when services and containers are running in the same Kubernetes 16 pod, they are all sharing the same localhost address. The following restrictions 17 are then applicable: 18 19 - The services are *not* accessible via their DNS name, you need to use localhost 20 instead. 21 - You cannot use several services using the same port (e.g., you cannot have two 22 `mysql` services at the same time). 23 24 ## Workflow 25 26 The Kubernetes executor divides the build into multiple steps: 27 28 1. **Prepare**: Create the Pod against the Kubernetes Cluster. 29 This creates the containers required for the build and services to run. 30 1. **Pre-build**: Clone, restore cache and download artifacts from previous 31 stages. This is run on a special container as part of the Pod. 32 1. **Build**: User build. 33 1. **Post-build**: Create cache, upload artifacts to GitLab. This also uses 34 the special container as part of the Pod. 35 36 ## Connecting to the Kubernetes API 37 38 The following options are provided, which allow you to connect to the Kubernetes API: 39 40 - `host`: Optional Kubernetes apiserver host URL (auto-discovery attempted if not specified) 41 - `cert_file`: Optional Kubernetes apiserver user auth certificate 42 - `key_file`: Optional Kubernetes apiserver user auth private key 43 - `ca_file`: Optional Kubernetes apiserver ca certificate 44 45 The user account provided must have permission to create, list and attach to Pods in 46 the specified namespace in order to function. 47 48 If you are running the GitLab CI Runner within the Kubernetes cluster you can omit 49 all of the above fields to have the Runner auto-discovery the Kubernetes API. This 50 is the recommended approach. 51 52 If you are running it externally to the Cluster then you will need to set each 53 of these keywords and make sure that the Runner has access to the Kubernetes API 54 on the cluster. 55 56 ## The keywords 57 58 The following keywords help to define the behaviour of the Runner within Kubernetes: 59 60 - `namespace`: Namespace to run Kubernetes Pods in 61 - `namespace_overwrite_allowed`: Regular expression to validate the contents of 62 the namespace overwrite environment variable (documented following). When empty, 63 it disables the namespace overwrite feature 64 - `privileged`: Run containers with the privileged flag 65 - `cpu_limit`: The CPU allocation given to build containers 66 - `memory_limit`: The amount of memory allocated to build containers 67 - `service_cpu_limit`: The CPU allocation given to build service containers 68 - `service_memory_limit`: The amount of memory allocated to build service containers 69 - `helper_cpu_limit`: The CPU allocation given to build helper containers 70 - `helper_memory_limit`: The amount of memory allocated to build helper containers 71 - `cpu_request`: The CPU allocation requested for build containers 72 - `memory_request`: The amount of memory requested from build containers 73 - `service_cpu_request`: The CPU allocation requested for build service containers 74 - `service_memory_request`: The amount of memory requested for build service containers 75 - `helper_cpu_request`: The CPU allocation requested for build helper containers 76 - `helper_memory_request`: The amount of memory requested for build helper containers 77 - `pull_policy`: specify the image pull policy: `never`, `if-not-present`, `always`. The cluster default will be used if not set. 78 - `node_selector`: A `table` of `key=value` pairs of `string=string`. Setting this limits the creation of pods to Kubernetes nodes matching all the `key=value` pairs 79 - `node_tolerations`: A `table` of `"key=value" = "Effect"` pairs in the format of `string=string:string`. Setting this allows pods to schedule to nodes with all or a subset of tolerated taints. Only one toleration can be supplied through environment variable configuration. The `key`, `value`, and `effect` match with the corresponding field names in Kubernetes pod toleration configuration. 80 - `image_pull_secrets`: A array of secrets that are used to authenticate docker image pulling 81 - `helper_image`: (Advanced) [Override the default helper image](../configuration/advanced-configuration.md#helper-image) used to clone repos and upload artifacts. 82 - `terminationGracePeriodSeconds`: Duration after the processes running in the pod are sent a termination signal and the time when the processes are forcibly halted with a kill signal 83 - `poll_interval`: How frequently, in seconds, the runner will poll the Kubernetes pod it has just created to check its status (default = 3). 84 - `poll_timeout`: The amount of time, in seconds, that needs to pass before the runner will time out attempting to connect to the container it has just created. Useful for queueing more builds that the cluster can handle at a time (default = 180). 85 - `pod_labels`: A set of labels to be added to each build pod created by the runner. The value of these can include environment variables for expansion. 86 - `pod_annotations`: A set of annotations to be added to each build pod created by the Runner. The value of these can include environment variables for expansion. Pod annotations can be overwritten in each build. 87 - `pod_annotations_overwrite_allowed`: Regular expression to validate the contents of 88 the pod annotations overwrite environment variable. When empty, 89 it disables the pod annotations overwrite feature 90 - `pod_security_context`: Configured through the config file, this sets a pod security context for the build pod. [Read more about security context](#using-security-context) 91 - `service_account`: default service account to be used for making Kubernetes api calls. 92 - `service_account_overwrite_allowed`: Regular expression to validate the contents of 93 the service account overwrite environment variable. When empty, 94 it disables the service account overwrite feature 95 - `bearer_token`: Default bearer token used to launch build pods. 96 - `bearer_token_overwrite_allowed`: Boolean to allow projects to specify a bearer token that will be used to create the build pod. 97 - `volumes`: configured through the config file, the list of volumes that will be mounted in the build container. [Read more about using volumes.](#using-volumes) 98 - `services`: configured through the config file, the list of [services](https://docs.gitlab.com/ee/ci/docker/using_docker_images.html#what-is-a-service) attached to the build container using the [sidecar pattern](https://docs.microsoft.com/en-us/azure/architecture/patterns/sidecar). 99 - `services`: 100 [Since GitLab Runner 101 12.5](https://gitlab.com/gitlab-org/gitlab-runner/issues/4470), list of 102 [services](https://docs.gitlab.com/ee/ci/services/) attached to the build 103 container using the [sidecar 104 pattern](https://docs.microsoft.com/en-us/azure/architecture/patterns/sidecar). 105 Read more about [using services](#using-services). 106 107 ### Configuring executor Service Account 108 109 You can set the `KUBERNETES_SERVICE_ACCOUNT` environment variable or use `--service-account` flag 110 111 ### Overwriting Kubernetes Namespace 112 113 Additionally, Kubernetes namespace can be overwritten on `.gitlab-ci.yml` file, by using the variable 114 `KUBERNETES_NAMESPACE_OVERWRITE`. 115 116 This approach allow you to create a new isolated namespace dedicated for CI purposes, and deploy a custom 117 set of Pods. The `Pods` spawned by the runner will take place on the overwritten namespace, for simple 118 and straight forward access between container during the CI stages. 119 120 ``` yaml 121 variables: 122 KUBERNETES_NAMESPACE_OVERWRITE: ci-${CI_COMMIT_REF_SLUG} 123 ``` 124 125 Furthermore, to ensure only designated namespaces will be used during CI runs, inform the configuration 126 `namespace_overwrite_allowed` with proper regular expression. When left empty the overwrite behaviour is 127 disabled. 128 129 ### Overwriting Kubernetes Default Service Account 130 131 Additionally, Kubernetes service account can be overwritten on `.gitlab-ci.yml` file, by using the variable 132 `KUBERNETES_SERVICE_ACCOUNT_OVERWRITE`. 133 134 This approach allow you to specify a service account that is attached to the namespace, useful when dealing 135 with complex RBAC configurations. 136 137 ``` yaml 138 variables: 139 KUBERNETES_SERVICE_ACCOUNT_OVERWRITE: ci-service-account 140 ``` 141 142 useful when overwritting the namespace and RBAC is setup in the cluster. 143 144 To ensure only designated service accounts will be used during CI runs, inform the configuration 145 `service_account_overwrite_allowed` or set the environment variable `KUBERNETES_SERVICE_ACCOUNT_OVERWRITE_ALLOWED` 146 with proper regular expression. When left empty the overwrite behaviour is disabled. 147 148 ### Setting Bearer Token to be Used When Making Kubernetes API calls 149 150 In conjunction with setting the namespace and service account as mentioned above, you may set the bearer token used when making API calls to create the build pods. This will allow project owners to use project secret variables to specify a bearer token. When specifying the bearer token, it is required that you set the `Host` config keyword. 151 152 ``` yaml 153 variables: 154 KUBERNETES_BEARER_TOKEN: thebearertokenfromanothernamespace 155 ``` 156 157 ### Overwriting pod annotations 158 159 Additionally, Kubernetes pod annotations can be overwritten on the `.gitlab-ci.yml` file, by using `KUBERNETES_POD_ANNOTATIONS_*` for variables and `key=value` for the value. The pod annotations will be overwritten to the `key=value`. Also, multiple annotations can be applied. For example: 160 161 ```yaml 162 variables: 163 KUBERNETES_POD_ANNOTATIONS_1: "Key1=Val1" 164 KUBERNETES_POD_ANNOTATIONS_2: "Key2=Val2" 165 KUBERNETES_POD_ANNOTATIONS_3: "Key3=Val3" 166 ``` 167 168 NOTE: **Note:** 169 You must specify [`pod_annotations_overwrite_allowed`](#the-keywords) to override pod annotations via the `.gitlab-ci.yml` file. 170 171 ## Define keywords in the config toml 172 173 Each of the keywords can be defined in the `config.toml` for the GitLab Runner. 174 175 Here is an example `config.toml`: 176 177 ```toml 178 concurrent = 4 179 180 [[runners]] 181 name = "Kubernetes Runner" 182 url = "https://gitlab.com/ci" 183 token = "......" 184 executor = "kubernetes" 185 [runners.kubernetes] 186 host = "https://45.67.34.123:4892" 187 cert_file = "/etc/ssl/kubernetes/api.crt" 188 key_file = "/etc/ssl/kubernetes/api.key" 189 ca_file = "/etc/ssl/kubernetes/ca.crt" 190 namespace = "gitlab" 191 namespace_overwrite_allowed = "ci-.*" 192 bearer_token_overwrite_allowed = true 193 privileged = true 194 cpu_limit = "1" 195 memory_limit = "1Gi" 196 service_cpu_limit = "1" 197 service_memory_limit = "1Gi" 198 helper_cpu_limit = "500m" 199 helper_memory_limit = "100Mi" 200 poll_interval = 5 201 poll_timeout = 3600 202 [runners.kubernetes.node_selector] 203 gitlab = "true" 204 [runners.kubernetes.node_tolerations] 205 "node-role.kubernetes.io/master" = "NoSchedule" 206 "custom.toleration=value" = "NoSchedule" 207 "empty.value=" = "PreferNoSchedule" 208 "onlyKey" = "" 209 ``` 210 211 ## Using volumes 212 213 As described earlier, volumes can be mounted in the build container. 214 At this time _hostPath_, _PVC_, _configMap_, and _secret_ volume types 215 are supported. User can configure any number of volumes for each of 216 mentioned types. 217 218 Here is an example configuration: 219 220 ```toml 221 concurrent = 4 222 223 [[runners]] 224 # usual configuration 225 executor = "kubernetes" 226 [runners.kubernetes] 227 [[runners.kubernetes.volumes.host_path]] 228 name = "hostpath-1" 229 mount_path = "/path/to/mount/point" 230 read_only = true 231 host_path = "/path/on/host" 232 [[runners.kubernetes.volumes.host_path]] 233 name = "hostpath-2" 234 mount_path = "/path/to/mount/point_2" 235 read_only = true 236 [[runners.kubernetes.volumes.pvc]] 237 name = "pvc-1" 238 mount_path = "/path/to/mount/point1" 239 [[runners.kubernetes.volumes.config_map]] 240 name = "config-map-1" 241 mount_path = "/path/to/directory" 242 [runners.kubernetes.volumes.config_map.items] 243 "key_1" = "relative/path/to/key_1_file" 244 "key_2" = "key_2" 245 [[runners.kubernetes.volumes.secret]] 246 name = "secrets" 247 mount_path = "/path/to/directory1" 248 read_only = true 249 [runners.kubernetes.volumes.secret.items] 250 "secret_1" = "relative/path/to/secret_1_file" 251 [[runners.kubernetes.volumes.empty_dir]] 252 name = "empty_dir" 253 mount_path = "/path/to/empty_dir" 254 medium = "Memory" 255 ``` 256 257 ### Host Path volumes 258 259 [_HostPath_ volume][k8s-host-path-volume-docs] configuration instructs Kubernetes to mount 260 a specified host path inside of the container. The volume can be configured with 261 following options: 262 263 | Option | Type | Required | Description | 264 |------------|---------|----------|-------------| 265 | name | string | yes | The name of the volume | 266 | mount_path | string | yes | Path inside of container where the volume should be mounted | 267 | host_path | string | no | Host's path that should be mounted as volume. If not specified then set to the same path as `mount_path`. | 268 | read_only | boolean | no | Set's the volume in read-only mode (defaults to false) | 269 270 ### PVC volumes 271 272 [_PVC_ volume][k8s-pvc-volume-docs] configuration instructs Kubernetes to use a _PersistentVolumeClaim_ 273 that is defined in Kubernetes cluster and mount it inside of the container. The volume 274 can be configured with following options: 275 276 | Option | Type | Required | Description | 277 |------------|---------|----------|-------------| 278 | name | string | yes | The name of the volume and at the same time the name of _PersistentVolumeClaim_ that should be used | 279 | mount_path | string | yes | Path inside of container where the volume should be mounted | 280 | read_only | boolean | no | Set's the volume in read-only mode (defaults to false) | 281 282 ### Config Map volumes 283 284 _ConfigMap_ volume configuration instructs Kubernetes to use a [_configMap_][k8s-config-map-docs] 285 that is defined in Kubernetes cluster and mount it inside of the container. 286 287 | Option | Type | Required | Description | 288 |------------|---------|----------|-------------| 289 | name | string | yes | The name of the volume and at the same time the name of _configMap_ that should be used | 290 | mount_path | string | yes | Path inside of container where the volume should be mounted | 291 | read_only | boolean | no | Set's the volume in read-only mode (defaults to false) | 292 | items | `map[string]string` | no | Key-to-path mapping for keys from the _configMap_ that should be used. | 293 294 When using _configMap_ volume, each key from selected _configMap_ will be changed into a file 295 stored inside of the selected mount path. By default all keys are present, _configMap's_ key 296 is used as file's name and value is stored as file's content. The default behavior can be 297 changed with `items` option. 298 299 `items` option is defining a mapping between key that should be used and path (relative 300 to volume's mount path) where _configMap's_ value should be saved. When using `items` option 301 **only selected keys** will be added to the volumes and all other will be skipped. 302 303 > **Notice**: If a non-existing key will be used then job will fail on Pod creation stage. 304 305 ### Secret volumes 306 307 [_Secret_ volume][k8s-secret-volume-docs] configuration instructs Kubernetes to use 308 a _secret_ that is defined in Kubernetes cluster and mount it inside of the container. 309 310 | Option | Type | Required | Description | 311 |------------|---------|----------|-------------| 312 | name | string | yes | The name of the volume and at the same time the name of _secret_ that should be used | 313 | mount_path | string | yes | Path inside of container where the volume should be mounted | 314 | read_only | boolean | no | Set's the volume in read-only mode (defaults to false) | 315 | items | `map[string]string` | no | Key-to-path mapping for keys from the _configMap_ that should be used. | 316 317 When using _secret_ volume each key from selected _secret_ will be changed into a file 318 stored inside of the selected mount path. By default all keys are present, _secret's_ key 319 is used as file's name and value is stored as file's content. The default behavior can be 320 changed with `items` option. 321 322 `items` option is defining a mapping between key that should be used and path (relative 323 to volume's mount path) where _secret's_ value should be saved. When using `items` option 324 **only selected keys** will be added to the volumes and all other will be skipped. 325 326 > **Notice**: If a non-existing key will be used then job will fail on Pod creation stage. 327 328 ### Empty Dir volumes 329 330 [_emptyDir_ volume][k8s-empty-dir-volume-docs] configuration instructs Kubernetes to mount an empty directory inside of the container. 331 332 | Option | Type | Required | Description | 333 |------------|---------|----------|-------------| 334 | name | string | yes | The name of the volume | 335 | mount_path | string | yes | Path inside of container where the volume should be mounted | 336 | medium | String | no | "Memory" will provide a tmpfs, otherwise it defaults to the node disk storage (defaults to "") | 337 338 ## Using Security Context 339 340 [Pod security context][k8s-pod-security-docs] configuration instructs executor to set a pod security policy on the build pod. 341 342 | Option | Type | Required | Description | 343 |---------------------|----------|----------|-------------| 344 | fs_group | int | no | A special supplemental group that applies to all containers in a pod | 345 | run_as_group | int | no | The GID to run the entrypoint of the container process | 346 | run_as_non_root | boolean | no | Indicates that the container must run as a non-root user | 347 | run_as_user | int | no | The UID to run the entrypoint of the container process | 348 | supplemental_groups | int list | no | A list of groups applied to the first process run in each container, in addition to the container's primary GID | 349 350 Assigining a security context to pods provides security to your Kubernetes cluster. For this to work you'll need to provide a helper 351 image that conforms to the policy you set here. 352 353 More about the helper image can be found [here](https://docs.gitlab.com/runner/configuration/advanced-configuration.html#helper-image). 354 Example of building your own helper image: 355 356 ```Dockerfile 357 ARG tag 358 FROM gitlab/gitlab-runner-helper:${tag} 359 RUN addgroup -g 59417 -S nonroot && \ 360 adduser -u 59417 -S nonroot -G nonroot 361 WORKDIR /home/nonroot 362 USER 59417:59417 363 ``` 364 365 This example creates a user and group called `nonroot` and sets the image to run as that user. 366 367 Example of setting pod security context in your config.toml: 368 369 ```toml 370 concurrent = %(concurrent)s 371 check_interval = 30 372 [[runners]] 373 name = "myRunner" 374 url = "gitlab.example.com" 375 executor = "kubernetes" 376 [runners.kubernetes] 377 helper_image = "gitlab-registy.example.com/helper:latest" 378 [runners.kubernetes.pod_security_context] 379 run_as_non_root = true 380 run_as_user = 59417 381 run_as_group = 59417 382 fs_group = 59417 383 ``` 384 385 ## Using services 386 387 > [Introduced](https://gitlab.com/gitlab-org/gitlab-runner/issues/4470) in GitLab Runner 12.5. 388 389 Define a list of [services](https://docs.gitlab.com/ee/ci/services/). 390 Currently, only `name` can be defined. 391 392 ```toml 393 concurrent = 1 394 check_interval = 30 395 [[runners]] 396 name = "myRunner" 397 url = "gitlab.example.com" 398 executor = "kubernetes" 399 [runners.kubernetes] 400 helper_image = "gitlab-registy.example.com/helper:latest" 401 [[runners.kubernetes.services]] 402 name = "postgres:12-alpine" 403 [[runners.kubernetes.services]] 404 name = "percona:latest" 405 ``` 406 407 ## Using Docker in your builds 408 409 There are a couple of caveats when using docker in your builds while running on 410 a Kubernetes cluster. Most of these issues are already discussed in the 411 [**Using Docker Build**](https://docs.gitlab.com/ee/ci/docker/using_docker_build.html) 412 section of the GitLab CI 413 documentation but it is worth it to revisit them here as you might run into 414 some slightly different things when running this on your cluster. 415 416 ### Exposing `/var/run/docker.sock` 417 418 Exposing your host's `/var/run/docker.sock` into your build container, using the 419 `runners.kubernetes.volumes.host_path` option, brings the same risks with it as 420 always. That node's containers are accessible from the build container and 421 depending if you are running builds in the same cluster as your production 422 containers it might not be wise to do that. 423 424 ### Using `docker:dind` 425 426 Running the `docker:dind` also known as the `docker-in-docker` image is also 427 possible but sadly needs the containers to be run in privileged mode. 428 If you're willing to take that risk other problems will arise that might not 429 seem as straight forward at first glance. Because the docker daemon is started 430 as a `service` usually in your `.gitlab-ci.yaml` it will be run as a separate 431 container in your Pod. Basically containers in Pods only share volumes assigned 432 to them and an IP address by which they can reach each other using `localhost`. 433 `/var/run/docker.sock` is not shared by the `docker:dind` container and the `docker` 434 binary tries to use it by default. To overwrite this and make the client use tcp 435 to contact the docker daemon in the other container be sure to include 436 `DOCKER_HOST=tcp://localhost:2375` in your environment variables of the build container. 437 438 ### Not supplying Git 439 440 Do *not* try to use an image that doesn't supply Git and add the `GIT_STRATEGY=none` 441 environment variable for a job that you think doesn't need to do a fetch or clone. 442 Because Pods are ephemeral and do not keep state of previously run jobs your 443 checked out code will not exist in both the build and the docker service container. 444 Error's you might run into are things like `could not find git binary` and 445 the docker service complaining that it cannot follow some symlinks into your 446 build context because of the missing code. 447 448 ### Resource separation 449 450 In both the `docker:dind` and `/var/run/docker.sock` cases the docker daemon 451 has access to the underlying kernel of the host machine. This means that any 452 `limits` that had been set in the Pod will not work when building docker images. 453 The docker daemon will report the full capacity of the node regardless of 454 the limits imposed on the docker build containers spawned by Kubernetes. 455 456 One way to help minimize the exposure of the host's kernel to any build container 457 when running in privileged mode or by exposing `/var/run/docker.sock` is to use 458 the `node_selector` option to set one or more labels that have to match a node 459 before any containers are deployed to it. For example build containers may only run 460 on nodes that are labeled with `role=ci` while running all other production services 461 on other nodes. Further separation of build containers can be achieved using node 462 [taints](https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/). 463 This will disallow other pods from scheduling on the same nodes as the 464 build pods without extra configuration for the other pods. 465 466 ### Using kaniko 467 468 Another approach for building Docker images inside a Kubernetes cluster is using [kaniko](https://github.com/GoogleContainerTools/kaniko). 469 kaniko: 470 471 - Allows you to build images without privileged access. 472 - Works without the Docker daemon. 473 474 For more information, see [Building images with kaniko and GitLab CI/CD](https://docs.gitlab.com/ee/ci/docker/using_kaniko.html). 475 476 [k8s-host-path-volume-docs]: https://kubernetes.io/docs/concepts/storage/volumes/#hostpath 477 [k8s-pvc-volume-docs]: https://kubernetes.io/docs/concepts/storage/volumes/#persistentvolumeclaim 478 [k8s-secret-volume-docs]: https://kubernetes.io/docs/concepts/storage/volumes/#secret 479 [k8s-config-map-docs]: https://kubernetes.io/docs/tasks/configure-pod-container/configure-pod-configmap/ 480 [k8s-empty-dir-volume-docs]:https://kubernetes.io/docs/concepts/storage/volumes/#emptydir 481 [k8s-pod-security-docs]:https://kubernetes.io/docs/concepts/policy/pod-security-policy/