Instalasi Gitlab Runner Autoscale
Setelah kita berhasil memasang Gitlab CE di Google Cloud Platform, sekarang kita akan lanjutkan untuk memasang Gitlab Runner. Ada satu fitur menarik dari Gitlab Runner ini, yaitu autoscale
. Fitur ini memungkinkan kita untuk menghemat biaya sewa VPS di penyedia layanan cloud seperti Digital Ocean, Amazon, Google, dan lainnya. Caranya adalah dengan membuat VPS untuk menjalankan build sesuai kebutuhan. Bila sedang ramai antrian, Gitlab akan membuat banyak VPS. Bila antrian sepi, VPS tersebut akan dihapus sehingga tidak menimbulkan biaya.
Berikut langkah-langkah untuk memasang Gitlab Runner dengan fitur autoscale
:
- Setup CI Cache dan Docker Registry Proxy
- Setup Gitlab Runner
- Registrasi Gitlab Runner
- Test Gitlab Runner
Sebelum kita mulai, kita bahas dulu tentang cara kerja Gitlab CI Runner. Banyak di antara kita yang sebelumnya terbiasa menggunakan aplikasi CI yang terpisah dengan source code repository seperti misalnya Jenkins, Travis CI, Circle CI, dan sebagainya. Untuk aplikasi CI yang standalone, skema cara kerjanya seperti ini:
Biasanya untuk meningkatkan kapasitas build, aplikasi CI ini memiliki fitur slave, yaitu mesin lain yang khusus berfungsi untuk menjalankan build, terpisah dari master
nya, yaitu mesin utama yang bertugas mengontrol proses build. Kalau digambarkan skemanya kira-kira seperti ini:
Untuk Gitlab, fitur CInya sudah terintegrasi dengan aplikasi source code repositorynya. Kita hanya perlu memasang Runner
yang kira-kira fungsinya sama seperti slave
pada diagram di atas.
Runner menggunakan executor
untuk menjalankan proses build. Ada beberapa executor yang disediakan oleh Gitlab, yaitu:
- Shell
- Docker
- Docker Machine
- Virtual Box
- Parallels
- SSH
- Kubernetes
Shell executor akan menjalankan proses build di dalam mesin Runner, sama seperti kita menjalankan build di laptop kita sendiri. Di laptop kita, agar proses build bisa berjalan, kita harus menyediakan semua yang dibutuhkan dalam proses build. Misalnya kita membuat aplikasi Java yang dibuild dengan Apache Maven dan menggunakan database MySQL, maka kita harus menginstal dulu:
- Java SDK
- Apache Maven
- Database MySQL
Kemudian mengkonfigurasikan semuanya agar aplikasi kita bisa dibuild. Kurang lebih prosesnya sama seperti yang dijelaskan di artikel project setup.
Demikian juga halnya dengan Shell executor. Kita harus menginstal dan mengkonfigurasikan kebutuhan tersebut di mesin Runner. Untuk sistem Linux, caranya bisa dibaca di sini. Setelah melakukan persiapan tersebut, kita bisa lanjut menginstal runner.
Penggunaan shell executor relatif mudah kalau semua project kita menggunakan teknologi yang sama. Walaupun demikian, kita tetap perlu membuatkan user database dan databasenya untuk masing-masing project kita. Ini akan sangat merepotkan kalau projectnya banyak. Apalagi kalau project kita menggunakan framework dan bahasa pemrograman yang berbeda-beda.
Agar lebih mudah, kita bisa gunakan executor Docker. Dengan executor ini, proses build kita akan dijalankan dalam docker container. Bila belum paham apa itu Docker, bisa baca pembahasan tentang apa itu docker dan workflow development dengan Docker.
Yang lebih canggih dari executor Docker adalah executor Docker Machine, yang akan kita bahas pada artikel ini. Executor ini akan membuatkan VPS khusus untuk masing-masing proses build, tidak seperti executor Docker biasa yang menjalankan semua project dalam satu host. Executor ini cocok dikombinasikan dengan layanan VPS modern yang umumnya sekarang menghitung biaya dalam satuan jam. Jadi kita cukup sewa VPS selama proses build jalan. Setelah build selesai, VPS didestroy dan kita tidak perlu bayar. Fitur ini di Gitlab CI disebut dengan istilah autoscale
.
Executor yang lain tidak kita bahas, silahkan baca sendiri dokumentasinya kalau penasaran.
Baiklah, mari kita mulai instalasi dan setup Gitlab Runner Autoscale.
Setup CI Cache dan Docker Registry Proxy
Kegiatan build kita umumnya dijalankan di docker container. Untuk menjalankan container, docker perlu mengunduh image dulu (misalnya image mysql:latest
dan maven:latest
), yang besarnya bisa mencapai ratusan MB per image. Agar build lebih cepat, kita ingin menyimpan image ini supaya build kedua dan seterusnya tidak perlu donlod ulang.
Demikian juga dengan dependensi dan library. Bila kita menggunakan Maven, Gradle, npm, dan sejenisnya, ada banyak file yang dia unduh. File-file ini umumnya tidak berubah, sehingga bisa kita simpan agar build selanjutnya tidak perlu donlod lagi.
Untuk dua keperluan di atas, kita membutuhkan dua aplikasi:
- docker registry
- build cache
Docker registry sudah ada docker imagenya. Tinggal kita jalankan saja dengan perintah berikut
docker run -d -p 6000:5000 \
-e REGISTRY_PROXY_REMOTEURL=https://registry-1.docker.io \
--restart always \
--name registry registry:2
Gitlab mendukung build cache dalam format penyimpanan Amazon S3. Buat kita yang tidak ingin langganan S3, sudah ada yang membuatkan aplikasi tiruannya, yaitu minio. Inipun sudah ada docker imagenya, bisa dijalankan dengan perintah berikut
docker run -it --restart always -p 9005:9000 \
-v /.minio:/root/.minio -v /export:/export \
--name minio \
minio/minio:latest server /export
Agar lebih mudah, kita bisa gabungkan keduanya dalam docker compose sebagai berikut. Simpan konfigurasi ini dengan nama file docker-compose.yml
version: "2.1"
services:
docker-registry:
image: registry:2
restart: always
environment:
- REGISTRY_PROXY_REMOTEURL=https://registry-1.docker.io
ports:
- 6000:5000
build-cache:
image: minio/minio:latest
restart: always
volumes:
- /.minio:/root/.minio
- /export:/export
ports:
- 9005:9000
command: server /export
Untuk menjalankannya, kita buat dulu docker host di Google Cloud Platform menggunakan docker-machine
. Projectnya kita gunakan project gitlab-family
, sama dengan instalasi Gitlab CE di artikel sebelumnya
docker-machine create --driver google --google-zone asia-southeast1-a --google-project gitlab-family docker-registry-cache
Kemudian kita login ke dalam docker host tersebut untuk membuat folder yang dibutuhkan oleh minio
docker-machine ssh docker-registry-cache
Buat folder yang dibutuhkan minio
sudo mkdir -p /export/runner
Mumpung di sana, sekalian saja update dan upgrade
sudo apt-get update && sudo apt-get upgrade -y
Buka terminal satu lagi, kemudian kita jalankan docker-compose.yml
sebagai berikut
docker-compose up -d
Berikut outputnya
Creating network "cloudautomation_default" with the default driver
Pulling build-cache (minio/minio:latest)...
latest: Pulling from minio/minio
627beaf3eaaf: Pull complete
ac75cd34934f: Pull complete
f2a61a9fdfc0: Pull complete
8ad25f7f1798: Pull complete
Digest: sha256:e061d9ca378755ebb8fd9887ec71e78891b85afc09181c2542953606bd486319
Status: Downloaded newer image for minio/minio:latest
Pulling docker-registry (registry:2)...
2: Pulling from library/registry
709515475419: Pull complete
df6e278d8f96: Pull complete
4b0b08c1b8f7: Pull complete
80119f43a01e: Pull complete
acf34ba23c50: Pull complete
Digest: sha256:412e3b6494f623a9f03f7f9f8b8118844deaecfea19e3a5f1ce54eed4f400296
Status: Downloaded newer image for registry:2
Creating cloudautomation_docker-registry_1
Creating cloudautomation_build-cache_1
Kita bisa lihat statusnya dengan perintah docker ps
. Kalau semua berjalan normal, outputnya seperti ini
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dd6e0e7511c8 minio/minio:latest "minio server /export" 39 seconds ago Up 38 seconds 0.0.0.0:9005->9000/tcp cloudautomation_build-cache_1
a6c743b43de8 registry:2 "/entrypoint.sh /e..." 40 seconds ago Up 38 seconds 0.0.0.0:6000->5000/tcp cloudautomation_docker-registry_1
Setelah jalan, kita perlu melihat konfigurasi accessKey
dan secret
untuk kita gunakan nanti. Konfigurasi ini ada dalam folder /.minio/config.json
.
Kembali ke terminal yang sudah login ke docker host tadi, lalu tampilkan konfigurasi minio
sudo cat /.minio/config.json
Kita butuh accessKey
dan secretKey
seperti ini
"credential": {
"accessKey": "6X7LFVH3V7HU7SHHF60U",
"secretKey": "8ftRtZDOSv/pXNiRe1yqKoQHCu5IRvsZfx35YijI"
}
Cache server dan docker registry kita sudah selesai disetup. Terakhir, kita butuh informasi alamat IP untuk dipasang di konfigurasi runner. Jalankan perintah berikut untuk melihat semua instance VPS kita.
gcloud compute instances list
Outputnya seperti ini
NAME ZONE MACHINE_TYPE PREEMPTIBLE INTERNAL_IP EXTERNAL_IP STATUS
docker-registry-cache asia-southeast1-a n1-standard-1 10.148.0.3 35.185.181.204 RUNNING
gitlab-ce asia-southeast1-a n1-standard-1 10.148.0.2 35.185.188.31 RUNNING
Kita butuh INTERNAL_IP
untuk dipasang di runner nantinya. Sebagai rekap, berikut informasi yang sudah kita dapatkan:
- Docker Registry Proxy
- IP dan Port :
10.148.0.3:6000
- IP dan Port :
- Minio untuk Build Cache
- IP dan Port :
10.148.0.3:9005
- Access Key :
6X7LFVH3V7HU7SHHF60U
- Secret Key :
8ftRtZDOSv/pXNiRe1yqKoQHCu5IRvsZfx35YijI
- IP dan Port :
Selanjutnya, kita bisa mulai setup runner.
Setup Gitlab Runner
Setup runner terdiri dari dua kegiatan, yaitu:
- instalasi runner, yang berisi: docker engine, docker-machine, dan gitlab-ci-multi-runner
- registrasi runner
Membuat VPS Runner
Untuk menjalankan runner, kita butuh satu VM lagi. Buat dulu dengan menggunakan GCloud SDK.
gcloud compute instances create gitlab-runner --image-family ubuntu-1604-lts --image-project ubuntu-os-cloud
Di dalam VM ini, kita akan menginstal:
- Docker Engine
- Docker Machine
- Gitlab Runner
Setelah VPS siap, login dengan ssh
gcloud compute ssh gitlab-runner
Instalasi Docker Engine
Petunjuk instalasi lengkapnya bisa dibaca di dokumentasi resminya. Sesuai petunjuk di website tersebut, pertama kita harus instal dulu software yang dibutuhkan :
sudo apt-get install \
apt-transport-https \
ca-certificates \
curl \
software-properties-common
Tambahkan GPG key Docker
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
Pastikan fingerprintnya 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
dengan perintah berikut
sudo apt-key fingerprint 0EBFCD88
Outputnya seperti ini
pub 4096R/0EBFCD88 2017-02-22
Key fingerprint = 9DC8 5822 9FC7 DD38 854A E2D8 8D81 803C 0EBF CD88
uid Docker Release (CE deb) <docker@docker.com>
sub 4096R/F273FCD8 2017-02-22
Selanjutnya, tambahkan repository Docker
sudo add-apt-repository \
"deb [arch=amd64] https://download.docker.com/linux/ubuntu \
$(lsb_release -cs) \
stable"
Baru kita bisa install
sudo apt-get update && sudo apt-get install docker-ce -y
Kita bisa test instalasinya dengan melihat versi docker yang terinstal
docker --version
Test juga dengan menjalankan container
sudo docker run hello-world
Install Docker Machine
Docker Machine adalah aplikasi untuk membuat Docker Engine di VPS lain. Kita butuh ini karena kita menggunakan fitur autoscale
. Pada saat ada build yang harus dikerjakan, Gitlab menggunakan docker-machine
untuk membuat VPS dan menjalankan build dalam docker container di VPS tersebut. Setelah build selesai, Gitlab kembali akan menggunakan docker-machine
untuk menghapus VPS.
Petunjuk instalasi docker-machine
paling lengkap bisa dibaca di website resminya. Pada intinya, kita jalankan script berikut di command line:
curl -L https://github.com/docker/machine/releases/download/v0.10.0/docker-machine-`uname -s`-`uname -m` >/tmp/docker-machine &&
chmod +x /tmp/docker-machine &&
sudo cp /tmp/docker-machine /usr/local/bin/docker-machine
Test dengan melihat versi yang terinstal
docker-machine --version
Jangan lupa untuk memeriksa dulu ke website resminya untuk memastikan versi yang diinstal sudah yang paling baru.
Agar docker-machine
bisa berjalan dalam Google Compute Engine, kita perlu inisialisasi otentikasi Google dulu. Kalau tidak, kita akan mendapati error seperti ini pada saat membuat docker-machine
.
docker-machine create --driver google --google-project gitlab-family --google-zone asia-southeast1-a testcoba
Pesan errornya seperti ini :
Running pre-create checks...
(testcoba) Check that the project exists
Error with pre-create check: "Project with ID \"gitlab-family\" not found. googleapi: Error 403: Insufficient Permission, insufficientPermissions"
Untuk mengatasinya, kita harus otentikasi dulu. Caranya, kita login dulu dengan Google Cloud SDK. Yang penting untuk diperhatikan, proses otentikasi ini harus kita lakukan sebagai user root
, karena nantinya proses gitlab-runner
akan berjalan dengan user root
.
sudo -i
Kemudian baru kita lakukan otentikasi.
gcloud auth application-default login
Kita akan disuruh untuk login di browser dengan URL yang diberikan
You are running on a Google Compute Engine virtual machine.
The service credentials associated with this virtual machine
will automatically be used by Application Default
Credentials, so it is not necessary to use this command.
If you decide to proceed anyway, your user credentials may be visible
to others with access to this virtual machine. Are you sure you want
to authenticate with your personal account?
Do you want to continue (Y/n)?
Go to the following link in your browser:
https://accounts.google.com/o/oauth2/auth?redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob&prompt=select_account&response_type=code&client_id=764086051850-6qr4p6gpi6hn506pt8ejuq83di341hur.apps.googleusercontent.com&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform&access_type=offline
Setelah login di web, kita akan diberikan kode otorisasi
Masukkan di command line
Enter verification code: 4/yyu66l80diOCGNgMEjqH3Jj6UEK3w_QeJ9G1hmdWNx4
Credentials saved to file: [/home/endymuhardin/.config/gcloud/application_default_credentials.json]
These credentials will be used by any library that requests
Application Default Credentials.
Selanjutnya, kita bisa test apakah docker-machine
bisa dijalankan
docker-machine create --driver google --google-project gitlab-family --google-zone asia-southeast1-a testcoba
Kali ini harusnya sukses, berikut outputnya
Running pre-create checks...
(testcoba) Check that the project exists
(testcoba) Check if the instance already exists
Creating machine...
(testcoba) Generating SSH Key
(testcoba) Creating host...
(testcoba) Opening firewall ports
(testcoba) Creating instance
(testcoba) Waiting for Instance
(testcoba) Uploading SSH Key
Waiting for machine to be running, this may take a few minutes...
Detecting operating system of created instance...
Waiting for SSH to be available...
Detecting the provisioner...
Provisioning with ubuntu(systemd)...
Installing Docker...
Copying certs to the local machine directory...
Copying certs to the remote machine...
Setting Docker configuration on the remote daemon...
Checking connection to Docker...
Docker is up and running!
To see how to connect your Docker Client to the Docker Engine running on this virtual machine, run: docker-machine env testcoba
Kita bisa lihat apakah docker-machine sudah terbentuk dengan perintah berikut
docker-machine ls
Outputnya seperti ini
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
testcoba - google Running tcp://35.186.158.152:2376 v17.04.0-ce
Setelah sukses, jangan lupa dihapus lagi agar tidak membebani tagihan.
docker-machine rm testcoba
Selanjutnya, kita teruskan menginstal gitlab-ci-multi-runner
.
Install Gitlab Runner
Petunjuk instalasi bisa dibaca di sini. Sesuai petunjuk di link barusan, kita bisa eksekusi satu baris perintah seperti ini untuk mendaftarkan repository Ubuntu
curl -L https://packages.gitlab.com/install/repositories/runner/gitlab-ci-multi-runner/script.deb.sh | sudo bash
Selanjutnya kita akan install Gitlab Runner
sudo apt-get install gitlab-ci-multi-runner
Registrasi Gitlab Runner
Untuk melakukan registrasi, kita butuh token yang bisa didapatkan di menu admin/runners
di aplikasi web Gitlab CE.
Kemudian kita daftarkan Runner dengan token tersebut
sudo gitlab-ci-multi-runner register
Kita akan ditanyai beberapa pertanyaan. Berikut adalah pertanyaan dan jawaban yang saya berikan
Running in system-mode.
Please enter the gitlab-ci coordinator URL (e.g. https://gitlab.com/):
https://gitlab.artivisi.id
Please enter the gitlab-ci token for this runner:
A6pwrshn7xoeVPvMYAEh
Please enter the gitlab-ci description for this runner:
[gitlab-runner]:
Please enter the gitlab-ci tags for this runner (comma separated):
Whether to lock Runner to current project [true/false]:
[false]:
Registering runner... succeeded runner=A6pwrshn
Please enter the executor: shell, virtualbox, docker+machine, docker-ssh+machine, kubernetes, docker, docker-ssh, parallels, ssh:
docker+machine
Please enter the default Docker image (e.g. ruby:2.1):
alpine:latest
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
Kita akan edit file konfigurasinya. Sebelumnya kita backup dulu config aslinya
sudo cp /etc/gitlab-runner/config.toml /etc/gitlab-runner/config.bak
Kemudian kita edit file /etc/gitlab-runner/config.toml
seperti ini
concurrent = 1
check_interval = 0
[[runners]]
name = "gcloud-autoscale"
url = "https://gitlab.artivisi.id"
token = "5b6e2b425a2ebb04ab10de5344ec52"
executor = "docker+machine"
[runners.docker]
tls_verify = false
image = "alpine:latest"
privileged = true
disable_cache = false
volumes = ["/cache"]
shm_size = 0
[runners.cache]
Type = "s3"
ServerAddress = "10.148.0.3:9005"
AccessKey = "6X7LFVH3V7HU7SHHF60U"
SecretKey = "8ftRtZDOSv/pXNiRe1yqKoQHCu5IRvsZfx35YijI"
BucketName = "runner"
Insecure = true
Shared = true
[runners.machine]
IdleCount = 0
IdleTime = 600
MaxBuilds = 5
MachineDriver = "google"
MachineName = "%s"
MachineOptions = [
"google-project=gitlab-family",
"google-zone=asia-southeast1-a",
"google-machine-image=coreos-cloud/global/images/coreos-stable-1298-7-0-v20170401",
"google-machine-type=g1-small",
"engine-registry-mirror=http://10.148.0.3:6000"
]
Ada beberapa hal yang kita konfigurasi pada runner kita, yaitu:
IdleCount = 0
: kalau tidak ada kerjaan build, tidak perlu bikin VPSIdleTime = 600
: kalau ada VPS yang nganggur selama 600 detik (10 menit), segera removeMaxBuilds = 5
: maksimal kerjaan yang jalan berbarengan adalah5
. Kalau ada 7 permintaan, maka yang 2 antri dulu. Setting ini bisa kita gunakan untuk membatasi jumlah VPS yang akan dibuat oleh Gitlab sehingga tagihan tidak membengkak.MachineDriver = "google"
: provider VPS yang kita gunakan. Kita bisa menggunakan berbagai provider yang didukung olehdocker-machine
engine-registry-mirror
: lokasi registry mirror yang sudah kita install tadi.runners.cache
: lokasi penyimpanan cache. Arahkan ke konfigurasiminio
yang sudah kita buat tadi.
Setelah diedit, restart Gitlab Runner
sudo gitlab-ci-multi-runner restart
Kita bisa lihat hasilnya di antarmuka web Gitlab CE di menu Admin > Runners
Test Gitlab Runner
Ada beberapa hal yang perlu kita test, yaitu:
- build bisa dijalankan dengan baik
- docker registry proxy bisa melakukan cache, sehingga build kedua dan seterusnya lebih cepat
- build cache berfungsi dengan baik, ada file yang ditaruh ke
minio
dan build selanjutnya tidak perlu download dependensi
Untuk melakukan test, kita bisa gunakan contoh project belajar-ci
yang sudah diuji dan berjalan baik di Gitlab versi hosted yang dikelola tim Gitlab sendiri. Kita bisa create project di Gitlab hasil instalasi kita, kemudian push projectnya kesana.
Beberapa hal yang perlu kita amati:
- Build harusnya berjalan sukses, minimal job
maven-build
. Untuk job lain memang butuh konfigurasi credential agar bisa push ke DockerHub. - Build cache terisi, bisa dicek dengan cara ssh ke
docker-registry-cache
, kemudian lihat isi folder/export/runner
. Harusnya ada isinya. Lihat juga logmaven-build
untuk build kedua dan seterusnya, harusnya dia tidak lagi mengunduh banyakjar
. Di logmaven-build
seharusnya ada tulisanChecking cache for default...
danSuccessfully extracted cache
- Registry cache terisi. Bisa dicek dengan cara login ke docker containernya dengan perintah
docker exec -it namacontainer /bin/sh
. Nama container dapat diperoleh dengan perintahdocker ps
. Setelah berhasil login, coba liat isi folder/var/lib/registry/
. Seharusnya di dalamnya ada folderdocker/registry/v2/repositories/library/
yang isinya image-image yang digunakan oleh proses build kita. Untuk projectbelajar-ci
akan ada imagedocker
,mysql
, danmaven
.
Demikianlah cara setup Gitlab Runner. Sekarang server Gitlab kita selain bisa menjadi server version control Git, juga sudah bisa menangani proses Continuous Integration/Delivery. Dengan adanya fitur autoscale
ini, VPS hanya dibuat pada saat dibutuhkan saja. Begitu tidak ada proses berjalan, VPSnya akan didestroy. Ini akan sangat menghemat biaya, apalagi layanan cloud jaman sekarang sudah mengenakan biaya dalam satuan jam. Bukan lagi bulanan.
Semoga bermanfaat.