Skip to content

Instantly share code, notes, and snippets.

@superherointj
Last active January 17, 2022 20:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save superherointj/d31326441dd2fff5e7f92ea12e584df9 to your computer and use it in GitHub Desktop.
Save superherointj/d31326441dd2fff5e7f92ea12e584df9 to your computer and use it in GitHub Desktop.
Gitlab-Runner: topologySpreadConstraints

GitLab-Runner -> topologySpreadConstraints

Por padrão o cluster kubernetes tem topologySpreadConstraints com maxSkew 3 por hostname. Consequentemente o gitlab-runner gera 3 workers num mesmo node antes de gerar workers em novo node. O que deixa builds até 3 vezes mais lentas.

Uma build de 8 minutos, se executada com jobs em paralelo identicos leva 24 minutos. :o)

Possibilidades:

Plano A) Alterar o topologySpreadConstraints padrão do cluster.

Preciso ativar o tipo KubeSchedulerConfiguration.

A configuração tem que ser feita em arquivo fora do Kubernetes. O arquivo no K3s tem caminho/nome diferente. Imagino que seja: /var/lib/rancher/k3s/server/cred/kubeconfig-system.yaml

Referências:

Desisti após experimentos. Não consegui ativar no K3s. (Deve ter um jeito só não achei.)

Plano B) Configurar o topologySpreadConstraints no gitlab-runner.

Objetivo: Configurar pods dos workers com:

      topologySpreadConstraints:
        - maxSkew: 1
          topologyKey: kubernetes.io/hostname
          whenUnsatisfiable: "DoNotSchedule"
          labelSelector:
            matchLabels:
              app: gitlab-runner-worker

Monkey patch OK

Alterei o código do gitlab-runner (monkey patch - fiz hardcoded inicialmente pra teste) para permitir configurar topologySpreadConstraints, e parece estar funcionando (vide build Nix). Repositório: https://gitlab.com/superherointj/gitlab-runner-patched

Build

Makefile (upstream)

Depois de muitos experimentos desisti. Tava complicado de acertar. Tá confuso o que fizeram.

Do Zero em Alpine Go

Bloquei em um erro de download de dependências, exemplo de uma dependência:

go: finding module for package gitlab.com/gitlab-org/gitlab-runner/cache/gcs

gitlab.com/gitlab-org/gitlab-runner imports
  gitlab.com/gitlab-org/gitlab-runner/cache/gcs: no matching versions for query "latest"

A url existe: https://gitlab.com/gitlab-org/gitlab-runner/-/tree/main/cache/gcs Porém o caminho não é o mesmo. Não sei se o Go faz mágica pro download de dependencias. Ou o que deveria fazer aqui.

IMPORTANTE: Os pacotes são locais no repositório do gitlab-runner.

Não saber Go dá nisso. Erro idiota! :@

Do Zero em Nix buildGoModule

Build OK! Aplicativo executou. Containerizei usando o Nix. Funcionou em testes locais. Mas apareceu problemas na produção qdo troquei a docker image da Helm Chart (que tem entrypoint diferente), aí o container novo foi atualizado mas ficou em CrashLoop.

Acredito que o problema seja na containerização que fiz do GitLab-Runner. Algum detalhe... Alguma coisinha.

Helm Chart docs:

[To-Do: Adicionar logs do Kubernetes do pod em loop. Mas não lembro de ter visto nada especial.]

Plano C - affinity

affinity: podAntiAffinity: preferredDuringSchedulingIgnoredDuringExecution: - weight: 100
podAffinityTerm: labelSelector: matchExpressions: - key: security operator: In values: - S2 topologyKey: kubernetes.io/hostname

Workaround que funcionou:

       affinity:
         podAntiAffinity:
           requiredDuringSchedulingIgnoredDuringExecution:
             - topologyKey: kubernetes.io/hostname
               labelSelector:
                 matchLabels:
                   gitlab-runner: worker

Parei os esforços aqui.

{ pkgs, gitlab-runner, ... }:
let entrypoint = pkgs.writeShellScriptBin "entrypoint" ''
DATA_DIR="/etc/gitlab-runner"
CONFIG_FILE=''${CONFIG_FILE:-''$DATA_DIR/config.toml}
exec gitlab-runner "''$@"
'';
in
pkgs.dockerTools.buildLayeredImage
{
name = "gitlab-runner-container-image";
contents = [
entrypoint
gitlab-runner
pkgs.bash
pkgs.coreutils
pkgs.curl
pkgs.dumb-init
pkgs.git
pkgs.openssh
pkgs.wget
pkgs.tzdata
];
config = {
# User =
Cmd = [
"dumb-init"
"--"
"entrypoint"
];
#ExposedPorts = {
# "8000/tcp" = { };
#};
Env = [
"PATH=\$PATH:/bin/:/usr/bin/:/run/wrappers/bin:/run/current-system/sw/bin"
];
# Entrypoint = [
# "/bin/dumb-init"
# "/bin/entrypoint"
# ];
# Volumes = {
# "/etc/gitlab-runner" = {};
# # "/home/gitlab-runner" = {};
# };
};
# extraCommands = ''
# ln -s /bin/bash /bin/sh
# ln -s /bin/dumb-init /usr/bin/dumb-init
# ln -s /bin/entrypoint /usr/bin/entrypoint
# '';
}
# apt-transport-https \
# ca-certificates \
# command: ["/usr/bin/dumb-init", "--", "/bin/bash", "/configmaps/entrypoint"]
# ${gitlab-runner}/bin/gitlab-runner
FROM golang:1.17-alpine
RUN apk add --no-cache \
bash \
ca-certificates \
git \
tzdata \
openssh-client \
curl
RUN mkdir /app
WORKDIR /app
COPY *.* /app/
ENV GO111MODULE "on"
# RUN go clean -modcache
# RUN go mod tidy
### Teste já falha!!!
#RUN go get -u gitlab.com/gitlab-org/gitlab-runner/cache/azure
RUN go get gitlab.com/gitlab-org/gitlab-runner/cache/gcs
# RUN go get gitlab.com/gitlab-org/gitlab-runner/cache/s3
# gitlab.com/gitlab-org/gitlab-runner/commands
# gitlab.com/gitlab-org/gitlab-runner/commands/helpers
# gitlab.com/gitlab-org/gitlab-runner/common
# gitlab.com/gitlab-org/gitlab-runner/executors/custom
# gitlab.com/gitlab-org/gitlab-runner/executors/docker
# gitlab.com/gitlab-org/gitlab-runner/executors/docker/machine
# gitlab.com/gitlab-org/gitlab-runner/executors/kubernetes
# gitlab.com/gitlab-org/gitlab-runner/executors/parallels
# gitlab.com/gitlab-org/gitlab-runner/executors/shell
# gitlab.com/gitlab-org/gitlab-runner/executors/ssh
# gitlab.com/gitlab-org/gitlab-runner/executors/virtualbox
# gitlab.com/gitlab-org/gitlab-runner/helpers/cli
# gitlab.com/gitlab-org/gitlab-runner/helpers/secrets/resolvers/vault
# gitlab.com/gitlab-org/gitlab-runner/log
# gitlab.com/gitlab-org/gitlab-runner/shells
RUN go mod vendor
RUN go build -mod=vendor
# CMD [ "/gitlab-runner" ]
# https://docs.docker.com/language/golang/build-images/
{
inputs = {
nixpkgs.url = "github:nixos/nixpkgs";
flake-utils.url = "github:numtide/flake-utils";
};
outputs = { self, nixpkgs, flake-utils }:
flake-utils.lib.eachDefaultSystem (system:
let pkgs = nixpkgs.legacyPackages.${system};
in rec {
packages.container = import ./containerImage.nix { inherit pkgs; inherit (packages) gitlab-runner; };
packages.gitlab-runner = pkgs.callPackage ./default.nix { };
defaultPackage = packages.gitlab-runner;
devShell = import ./shell.nix { inherit pkgs; };
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment