Mọi người chắc hẳn cũng đã quen thuộc với ứng dụng viết bằng ngôn ngữ Go. Tuy nhiên, cũng giống với các ngôn ngữ khác, Golang cũng gặp vấn đề khi triển khai ứng dụng lên các máy chủ cloud:

  • Việc biên dịch ứng dụng trở lên khá phức tạp: do phải sử 2 images, 1 image dùng để build file chạy, 1 image dùng để chạy ứng dụng. Tham khảo: multi-stage build
  • Phụ thuộc vào docker.
  • Khó khăn khi xây dựng image với nhiều OS khác nhau cùng lúc.
  • Khó khăn khi triển khai ứng dụng lên k8s.
  • Tốn thời gian xây dựng các container image trên các hệ thống sử dụng CI/CD.

Với những tồn tại nêu trên, ko.build đã được tạo ra để khắc phục và tối ưu chúng.

ko.build là gì?

ko là một công cụ dùng để xây dựng container image nhanh chóng cho các ứng dụng viết bằng Golang. Ý tưởng của ko khá đơn giản, có thể sử dụng chính máy cá nhân để xây dựng các images (sử dụng câu lệnh go build) mà không yêu cầu sử dụng docker

Cách sử dụng

Cài đặt

Có vài cách để cài đặt ko mà bạn có thể cân nhắc

  • Cài đặt với go package:
1
go install github.com/google/ko@latest
  • Dùng Homebrew:
1
brew install ko
  • ko cũng cung cấp 1 Github Action, giúp bạn có thể tích hợp vào trong CI/CD pipeline
1
2
steps:
- uses: imjasonh/[email protected]

Xây dựng và xuất bản 1 image

Mỗi khi chạy câu lệnh ko build là bạn đã thực hiện cả câu lệnh go build để biên dịch các mã Golang tự động tạo 1 container image, và xuất bản image đó đến 1 local hoặc remote repository.

Để cho dễ hiểu mình sẽ lấy ví dụ một chương trình Go đơn giản, in ra thời gian của hiện tại. Sau đó sử dụng ko.build

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
package main

import (
  "fmt"
  "time"
)

func main() {
  fmt.Println(time.Now())
}

Cấu hình

Xây dựng image

Trước khi sử dụng ko.build cho ứng dụng production của bạn, hãy thử cấu hình ko xây dựng image và xuất bản chúng trên máy local của bạn. Việc này sẽ yêu cầu bạn đã cài sẵn Docker trên máy tính. Sau đó hãy chạy dòng lệnh này:

1
KO_DOCKER_REPO=ko.local ko build .

Sau đó đợi câu lệnh này chạy xong, bạn hãy mở Docker Desktop để thấy image của mình đã được xuất bản trên đó. Nếu như bạn thích dùng giao diện câu lệnh hãy thử xem image mới xuất bản bằng câu lệnh này:

$> docker images

REPOSITORY                         TAG      IMAGE ID       CREATED        SIZE
ko.local/timeapp-fc793bb2a14c1eb1  latest   47c3a0cf49d7   11 hours ago   3.1MB

Hãy chú ý câu lệnh ko build có sử dụng import path. Trong ví dụ này là thư mục hiện tại ".". ko sẽ tự động tạo tên của image bằng việc sử dụng package name và một chuỗi ngẫu nhiên. ko cũng sẽ có cấu hình để bạn có thể loại bỏ chuỗi ngẫu nhiên bằng việc thêm flag --preserve-import-paths hoặc --base-import-paths. Chi tiết 2 flag này khác nhau như thế nào, bạn hãy tự trải nghiệm và đọc thêm trong documentation chính thức của ko.build tại đây.

Ngoài cách sử dụng KO_DOCKER_REPO=ko.local ra bạn có thể dùng cách khác thay thế khi sử dụng dưới local bằng câu lệnh sau:

1
2
3
ko build -L .
# equivalent to
ko build --local .

Về cơ bản, ko sử dụng một biến môi trường KO_DOCKER_REPO để cấu hình địa chỉ của repository, nơi mà các OCI image sẽ được xuất bản. Bạn có thể cấu hình để ko có thể xuất bản image của bạn lên Github (hoặc bất kì remote repository), theo ví dụ dưới đây:

1
KO_DOCKER_REPO=ghcr.io/dzungtran/services ko build .

Xuất bản image

Tuy nhiên, để thực sự xuất bản image của mình lên các remote repository, bạn có thể cần làm nhiều bước khác trước khi chạy câu lệnh ko build. Trước nhất có lẽ là xác thực định danh của bạn trên remote repository, bằng việc sử dụng câu lệnh ko login. Dưới đây là ví dụ khi bạn sử dụng với Github repository:

1
ko login ghcr.com -u your-gh-username -p your-gh-app-password

Ngoài ra nếu máy bạn đã xác thực định danh của bạn trên remote repository bằng docker login thì câu lệnh bên trên không cần thiết.

Cấu hình bằng file

Một cách khác ko có thể được cấu hình thông qua tệp cấu hình .ko.yaml khi được đặt trong thư mục build (hoặc chỉ định vị trí của nó bằng biến môi trường KO_CONFIG_PATH). Đoạn mã sau hiển thị tệp cấu hình với các lệnh xây dựng cho mã Go:

1
2
3
4
5
6
7
8
builds:
- id: timeapp
  main: ./timeapp
  env:
  - CGO_ENABLED=0
  ldflags:
  - -s -w
  - -extldflags "-static"

Xây dựng image cho nhiều nền tảng cùng lúc

ko hiện tại hỗ trợ việc xây dựng và xuất bản image cho nhiều nền tảng khác nhau trong 1 câu lệnh.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
$> KO_DOCKER_REPO=ko.local ko build -B --platform=all .

13:29:31 Building github.com/dzungtran/timeapp for linux/amd64
13:29:31 Building github.com/dzungtran/timeapp for linux/arm64
13:29:31 Building github.com/dzungtran/timeapp for linux/arm/v6
13:29:31 Building github.com/dzungtran/timeapp for linux/ppc64le
13:29:31 Building github.com/dzungtran/timeapp for linux/s390x
13:29:31 Building github.com/dzungtran/timeapp for linux/arm/v7
13:29:31 Building github.com/dzungtran/timeapp for linux/386
13:29:31 Building github.com/dzungtran/timeapp for linux/riscv64

Như ví dụ trên, ta thấy được ko đã xây dựng image cho nhiều nền tảng cùng 1 lúc. Ngoài ra, bạn cũng có thể lựa chọn các nền tảng mà bạn muốn xây dựng image trên đó:

1
KO_DOCKER_REPO=ko.local ko build -B --platform=linux/amd64,linux/arm64 .

Nếu bạn đang sử dụng cấu hình file, bạn cũng có thể thêm tuỳ chỉnh nền tảng để xây dựng image bằng việc thêm cấu hình như sau:

1
2
3
defaultPlatforms:
- linux/arm64
- linux/amd64

Hạn chế của ko

Mặc dù ko giúp chúng ta rất nhiều trong việc đơn giản hoá việc xây dựng và xuất bản ứng dụng, nhưng ko hiện tại vẫn mắc 1 vài hạn chế:

  • Hạn chế lớn nhất có lẽ là ko chỉ hỗ trợ các ứng dụng viết bằng Go.
  • Chỉ phù hợp với những ứng dụng không phụ thuộc quá nhiều vào các thành phần của hệ điều hành (vd: cgo, cái gói thư viện trong hệ điều hành).

Tổng kết lại

Nếu chu trình xây dựng phát triển Go của bạn liên quan đến việc tạo các image container, chắc chắn bạn sẽ hoan nghênh sự cải thiện tốc độ trong quy trình làm việc của mình. Bài viết này cho thấy cách sử dụng ko có thể nhanh chóng xây dựng các chương trình Go thành các sản phẩm được đóng gói tự động được đẩy lên các remote repository nhanh chóng, giúp tăng năng suất đáng kể.

Và những tính năng của ko được nêu ra trên đây mới chỉ là 1 phần nhỏ mà công cụ này có thể làm. Nếu bạn cảm thấy hứng thú với nó, và muốn áp dụng cho dự án của mình hãy vào website chính thức để tìm hiểu thêm nhé ko.build