Halo semuanya! Menjelang peluncuran kursus Platform Infrastruktur berbasis Kubernetes, kami menyiapkan terjemahan materi menarik lainnya.
Artikel ini ditujukan bagi para pendatang baru di Kubernetes, yang akan tertarik untuk memahami contoh praktis tentang cara menulis Golang API untuk mengelola daftar TODO, dan kemudian bagaimana cara menyebarkannya ke Kubernetes.Setiap pengembang menyukai daftar TODO yang bagus, bukan? Bagaimana lagi kita bisa mengatur diri kita sendiri sebaliknya?
Setiap pengembang menyukai aplikasi TODO yang bagus, bukan?Kami akan mulai dengan meninjau daftar komponen yang diperlukan, kemudian pergi untuk mengkonfigurasi Kubernetes, menyediakan database Postgresql, dan kemudian menginstal kerangka kerja aplikasi yang akan membantu kami dengan mudah menggunakan Go API di Kubernetes, tanpa berfokus pada detail.Kami akan membuat dua titik akhir di API - satu untuk membuat catatan TODO baru, yang lain untuk memilih semua catatan TODO.Semua kode dari tutorial ini tersedia di GitHub.Daftar komponen yang diperlukan:
- Docker yang Diinstal Secara Lokal
Kubernetes menjalankan kode dalam gambar kontainer, jadi Anda harus menginstal Docker di komputer Anda.Instal Docker: https://www.docker.comDaftarkan akun Docker Hub untuk menyimpan gambar Docker Anda: https://hub.docker.com/Anda dapat memilih salah satu kluster lokal atau jauh, tetapi yang mana yang lebih baik? Opsi yang disederhanakan, seperti k3d, berfungsi di komputer mana pun yang dapat dijalankan Docker, jadi menjalankan cluster lokal tidak lagi membutuhkan banyak RAM. Cluster jarak jauh juga bisa menjadi solusi yang sangat efisien, tetapi perlu diingat bahwa semua gambar Docker Anda perlu diunggah dan diunggah untuk setiap perubahan.Instal k3d: https://github.com/rancher/k3dk3d tidak akan menginstal kubectl (ini adalah CLI untuk Kubernetes), jadi instal secara terpisah dari sini: https://kubernetes.io/docs/tasks/tools / install-kubectlAnda juga perlu menginstal Golang dengan IDE di komputer Anda. Go gratis dan Anda dapat mengunduhnya untuk MacOS, Windows atau Linux dari tautan berikut: https://golang.org/dlSaya akan merekomendasikan menggunakan Visual Studio Code, ini gratis dan memiliki satu set plugin untuk Go yang dapat Anda tambahkan. Beberapa rekan lebih suka Goland dari Jetbrains. Jika Anda seorang programmer Java, Anda mungkin lebih suka membayar untuk Goland, karena akan mengingatkan Anda pada produk mereka yang lain.Instal VSCode atau Golang .Buat sebuah cluster
Anda perlu menginstal semua perangkat lunak yang ditentukan di bagian sebelumnya.Buat cluster baru menggunakan k3d:
k3d create
Konfigurasikan kubectl sehingga menunjuk ke sebuah cluster baru. Ingatlah bahwa banyak kluster dapat digunakan dari satu komputer, jadi sangat penting untuk menunjuk ke yang benar:export KUBECONFIG="$(k3d get-kubeconfig --name='k3s-default')"
Pastikan bahwa cluster memiliki setidaknya satu simpul. Di sini Anda dapat melihat bahwa saya telah menginstal Kubernetes 1.17 - versi yang relatif baru:kubectl get node
NAME STATUS ROLES AGE VERSION
k3d-k3s-default-server Ready master 48s v1.17.0+k3s.1
Kami akan menyimpan catatan TODO kami di tabel database, jadi sekarang kita perlu menginstalnya. Postgresql adalah database relasional populer yang dapat kita instal dalam sebuah cluster menggunakan grafik Helm.Instal bahtera
arkade adalah CLI Go, mirip dengan "buatan" atau "apt-get", tetapi untuk aplikasi Kubernetes. Ini menggunakan proyek Helm, kubectl, atau CLI untuk menginstal proyek atau produk ke cluster Anda.curl -sLS https:
Sekarang instal Postgresqlarkade install postgresql
===================================================================== = PostgreSQL has been installed. =
=====================================================================
Anda juga akan melihat informasi tentang string koneksi dan cara memulai CLI Postgresql melalui gambar Docker di dalam cluster.Anda dapat memperoleh informasi ini kapan saja menggunakan arkade info postgresql
.Kami akan merancang tata letak tabelCREATE TABLE todo (
id INT GENERATED ALWAYS AS IDENTITY,
description text NOT NULL,
created_date timestamp NOT NULL,
completed_date timestamp NOT NULL
);
Jalankan arkade info postgresql
untuk mendapatkan informasi koneksi lagi. Seharusnya terlihat seperti ini:export POSTGRES_PASSWORD=$(kubectl get secret --namespace default postgresql -o jsonpath="{.data.postgresql-password}" | base64 --decode)
kubectl run postgresql-client --rm --tty -i --restart='Never' --namespace default --image docker.io/bitnami/postgresql:11.6.0-debian-9-r0 --env="PGPASSWORD=$POSTGRES_PASSWORD" --command -- psql --host postgresql -U postgres -d postgres -p 5432
Sekarang Anda memiliki command prompt :, postgres = #
Anda dapat membuat tabel dengan menyalinnya di dalam, lalu jalankan \dt
untuk memperlihatkan tabel:postgres=# \dt
List of relations
Schema | Name | Type | Owner
--------+------+-------+----------
public | todo | table | postgres
(1 row)
Instal kerangka kerja aplikasi
Sama seperti pengembang PHP mempercepat alur kerja mereka menggunakan LAMP (Linux Apache + Mysql + PHP) dan pengembang Rails menggunakan tumpukan yang sudah disiapkan, pengembang Kubernetes dapat menggunakan kerangka kerja aplikasi.Tumpukan PLONK adalah singkatan dari Prometheus, Linux, OpenFaaS, NATS, dan Kubernetes.- Prometheus menyediakan metrik, penskalaan otomatis, dan kemampuan pengamatan untuk menguji kesehatan sistem Anda, memungkinkannya merespons lonjakan permintaan dan memangkas biaya dengan menyediakan metrik untuk membuat keputusan tentang penskalaan ke nol.
- Linux, meskipun bukan satu-satunya pilihan untuk menjalankan beban kerja di Kubernetes, adalah standar dan termudah untuk digunakan.
- Awalnya, OpenFaaS menyediakan fungsi portabel untuk pengembang, tetapi berfungsi dengan baik ketika menggunakan API dan layanan mikro. Fleksibilitasnya berarti bahwa setiap wadah Docker dengan server HTTP dapat digunakan dan dikelola.
- NATS adalah proyek CNCF populer yang digunakan untuk pengiriman pesan dan pub / sub. Dalam tumpukan PLONK, ia menyediakan kemampuan untuk mengeksekusi permintaan secara tidak sinkron dan untuk antri.
- Kubernetes adalah alasan kita ada di sini. Ini menyediakan infrastruktur terukur, penyembuhan diri, dan deklaratif. Dan jika Anda tidak lagi membutuhkan bagian dari semua keagungan ini, API-nya disederhanakan dengan OpenFaaS.
Instal tumpukan PLONK melalui bahtera:arkade install openfaas
Baca pesan informasi dan jalankan setiap perintah:- Instal faas-cli.
- Dapatkan kata sandi Anda.
- Redirect gateway OpenFaaS UI (melalui port 8080)
- Dan masuk ke sistem melalui CLI.
Seperti sebelumnya, Anda dapat menerima pesan informasi menggunakan info openfaas
.Sebarkan API Go Pertama Anda
Ada beberapa cara untuk membuat API Go menggunakan PLONK. Opsi pertama adalah menggunakan Dockerfile dan secara manual menentukan port TCP, pemeriksaan kesehatan, server HTTP, dan sebagainya. Ini dapat dilakukan dengan menggunakan faas-cli new --lang dockerfile API_NAME
, tetapi ada cara yang lebih sederhana dan lebih otomatis.Cara kedua adalah dengan menggunakan templat bawaan yang ditawarkan oleh Function Store:faas-cli template store list | grep go
go openfaas Classic Golang template
golang-http openfaas-incubator Golang HTTP template
golang-middleware openfaas-incubator Golang Middleware template
Karena kami ingin membuat API gaya HTTP tradisional, templat golang-middleware akan paling tepat.Di awal tutorial, Anda mendaftar dengan akun Docker Hub Anda untuk menyimpan gambar Docker Anda. Setiap beban kerja Kubernet harus tertanam dalam gambar Docker sebelum dapat digunakan.Tarik pola khusus:faas-cli template store pull golang-middleware
Gunakan Scaffold untuk API Anda dengan golang-middleware dan nama pengguna Anda di Docker Hub:export PREFIX=alexellis2
export LANG=golang-middleware
export API_NAME=todo
faas-cli new --lang $LANG --prefix $PREFIX $API_NAME
Anda akan melihat dua file yang dihasilkan:./todo.yml
- menyediakan cara untuk mengkonfigurasi, menyebarkan, dan menginstal templat dan nama./todo/handler.go
- di sini Anda menulis kode dan menambahkan file atau paket lain yang Anda butuhkan
Mari kita lakukan beberapa pengeditan dan kemudian kembangkan kode.package function
import (
"net/http"
"encoding/json"
)
type Todo struct {
Description string `json:"description"`
}
func Handle(w http.ResponseWriter, r *http.Request) {
todos := []Todo{}
todos = append(todos, Todo{Description: "Run faas-cli up"})
res, _ := json.Marshal(todos)
w.WriteHeader(http.StatusOK)
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(res))
}
Jika Anda tidak menggunakan VScode dan pluginnya untuk mengedit dan memformat kode, kemudian jalankan setelah setiap perubahan untuk memastikan bahwa file diformat dengan benar.gofmt -w -s ./todo/handler.go
Sekarang sebarkan kode - pertama buat gambar baru, luncurkan di Hub Docker dan sebarkan ke cluster menggunakan OpenFaaS API:Invoke your endpoint when ready:
curl http:
{
"description": "Run faas-cli up"
}
Izinkan pengguna membuat catatan TODO baru
Sekarang mari kita izinkan pengguna untuk membuat entri baru dalam daftar TODO mereka. Pertama, Anda perlu menambahkan tautan atau "ketergantungan" untuk Pergi ke perpustakaan Postgresql.Kita bisa mendapatkannya menggunakan modul vending atau Go yang diperkenalkan di Go 1.11 dan diinstal secara default di Go 1.13.Edit handler.go
dan tambahkan modul yang kita butuhkan untuk mengakses Postgresql:import (
"database/sql"
_ "github.com/lib/pq"
...
Agar modul Go untuk mendeteksi dependensi, kita perlu mendeklarasikan sesuatu di dalam file, yang akan kita gunakan nanti. Jika tidak, maka VSCode akan menghapus baris-baris ini ketika disimpan.Tambahkan ini di bawah impor dalam filevar db *sql.DB
Selalu jalankan perintah ini di todo
folder di mana ia berada handler.go
, dan bukan di level root c todo.yml
.Inisialisasi modul Go yang baru:cd todo/
ls
handler.go
export GO111MODULE=on
go mod init
Sekarang perbarui file menggunakan pq library:go get
go mod tidy
cat go.mod
module github.com/alexellis/todo1/todo
go 1.13
require github.com/lib/pq v1.3.0
Apa pun yang ada di dalam go.mod
, salin isinya keGO_REPLACE.txt
cat go.mod > GO_REPLACE.txt
Sekarang mari kita pastikan bahwa perakitan masih berfungsi sebelum menambahkan kode yang dimasukkan.faas-cli build -f todo.yml --build-arg GO111MODULE=on
Anda mungkin memperhatikan bahwa sekarang kami masuk --build-arg
untuk melaporkan pola penggunaan modul Go.Selama perakitan, Anda akan melihat bahwa modul diunduh sesuai kebutuhan dari Internet.Step 16/29 : RUN go test ./... -cover
---> Running in 9a4017438500
go: downloading github.com/lib/pq v1.3.0
go: extracting github.com/lib/pq v1.3.0
go: finding github.com/lib/pq v1.3.0
? github.com/alexellis/todo1/todo [no test files]
Removing intermediate container 9a4017438500
Mengkonfigurasi Rahasia untuk Akses Postgresql
Kita dapat membuat kumpulan koneksi init ()
, metode yang hanya akan berjalan sekali ketika program dimulai.
func init() {
if _, err := os.Stat("/var/openfaas/secrets/password"); err == nil {
password, _ := sdk.ReadSecret("password")
user, _ := sdk.ReadSecret("username")
host, _ := sdk.ReadSecret("host")
dbName := os.Getenv("postgres_db")
port := os.Getenv("postgres_port")
sslmode := os.Getenv("postgres_sslmode")
connStr := "postgres://" + user + ":" + password + "@" + host + ":" + port + "/" + dbName + "?sslmode=" + sslmode
var err error
db, err = sql.Open("postgres", connStr)
if err != nil {
panic(err.Error())
}
err = db.Ping()
if err != nil {
panic(err.Error())
}
}
}
Seperti yang Anda perhatikan, beberapa informasi diambil dari apa yang os.Getenv
dibaca dari lingkungan. Saya akan menganggap nilai-nilai ini non-rahasia, mereka ditetapkan dalam file todo.y
.Selebihnya, seperti kata sandi dan host, yang bersifat rahasia, disimpan dalam rahasia Kubernetes .Anda dapat membuatnya melalui faas-cli secret create
atau melalui kubectl create secret generic -n openfaas-fn
.String sdk.ReadSecret
berasal dari OpenFaaS Cloud SDK, dengan impor berikut: github.com/openfaas/openfaas-cloud/sdk
. Itu membaca file rahasia dari disk dan mengembalikan nilai atau kesalahan.Dapatkan nilai rahasia dari arkade info postgresql
.Sekarang untuk setiap kata sandi, lakukan hal berikut:export POSTGRES_PASSWORD=$(kubectl get secret --namespace default postgresql -o jsonpath="{.data.postgresql-password}" | base64 --decode)
export USERNAME="postgres"
export PASSWORD=$POSTGRES_PASSWORD
export HOST="postgresql.default"
faas-cli secret create username --from-literal $USERNAME
faas-cli secret create password --from-literal $PASSWORD
faas-cli secret create host --from-literal $HOST
Periksa rahasia untuk ketersediaan dan kepatuhan:faas-cli secret ls
NAME
username
password
host
# And via kubectl:
kubectl get secret -n openfaas-fn
NAME TYPE DATA AGE
username Opaque 1 13s
password Opaque 1 13s
host Opaque 1 12s
Edit file YAML kami dan tambahkan yang berikut:secrets:
- host
- password
- username
environment:
postgres_db: postgres
postgres_sslmode: "disable"
postgres_port: 5432
Selanjutnya, perbarui modul Go dan jalankan build lagi:cd todo
go get
go mod tidy
cd ..
faas-cli build -f todo.yml --build-arg GO111MODULE=on
Successfully built d2c609f8f559
Successfully tagged alexellis2/todo:latest
Image: alexellis2/todo:latest built.
[0] < Building todo done in 22.50s.
[0] Worker done.
Total build time: 22.50s
Majelis berfungsi seperti yang diharapkan, jadi mari kita jalankan faas-cli
dengan argumen yang sama untuk memulai dan menggunakan gambar. Jika kredensial dan konfigurasi SQL benar, kami tidak akan melihat kesalahan dalam log, namun, jika mereka salah, kami akan mendapatkan kode panik di init ().Periksa log:faas-cli logs todo
2020-03-26T14:10:03Z Forking - ./handler []
2020-03-26T14:10:03Z 2020/03/26 14:10:03 Started logging stderr from function.
2020-03-26T14:10:03Z 2020/03/26 14:10:03 Started logging stdout from function.
2020-03-26T14:10:03Z 2020/03/26 14:10:03 OperationalMode: http
2020-03-26T14:10:03Z 2020/03/26 14:10:03 Timeouts: read: 10s, write: 10s hard: 10s.
2020-03-26T14:10:03Z 2020/03/26 14:10:03 Listening on port: 8080
2020-03-26T14:10:03Z 2020/03/26 14:10:03 Metrics listening on port: 8081
2020-03-26T14:10:03Z 2020/03/26 14:10:03 Writing lock-file to: /tmp/.lock
Sementara semuanya terlihat bagus, sekarang mari kita coba memanggil titik akhir:echo | faas-cli invoke todo -f todo.yml
2020-03-26T14:11:02Z 2020/03/26 14:11:02 POST / - 200 OK - ContentLength: 35
Jadi, sekarang kami telah berhasil membuat koneksi ke database, dan kami dapat melakukan insert. Bagaimana kita tahu itu? Karena itu db.Ping ()
mengembalikan kesalahan, jika tidak maka akan membuat panik:err = db.Ping()
if err != nil {
panic(err.Error())
}
Ikuti tautan untuk detail lebih lanjut tentang paket database / sql .Menulis kode penyisipan
Kode ini menyisipkan baris baru ke dalam tabel todo
dan menggunakan sintaksis khusus di mana nilainya tidak dilampirkan dalam tanda kutip, tetapi diganti dengan kode db.Query. Dalam "masa lalu" pemrograman LAMP, kesalahan umum yang menyebabkan banyak sistem menjadi tidak aman adalah kurangnya sanitasi data input dan penyatuan input pengguna langsung ke pernyataan SQL.Bayangkan seseorang memasukkan deskripsi; drop table todo
Itu tidak akan terlalu menyenangkan.Oleh karena itu, kita menjalankan db.Query
, lalu meneruskan pernyataan SQL menggunakan $1
, $2
dll untuk setiap nilai, dan kemudian kita bisa mendapatkan hasil dan / atau kesalahan. Kita juga harus menutup hasil ini, jadi gunakan penundaan untuk ini.func insert(description string) error {
res, err := db.Query(`insert into todo (id, description, created_date) values (DEFAULT, $1, now());`,
description)
if err != nil {
return err
}
defer res.Close()
return nil
}
Sekarang mari kita hubungkan ini ke kode.func Handle(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodPost && r.URL.Path == "/create" {
defer r.Body.Close()
body, _ := ioutil.ReadAll(r.Body)
if err := insert(string(body)); err != nil {
http.Error(w, fmt.Sprintf("unable to insert todo: %s", err.Error()), http.StatusInternalServerError)
}
}
}
Mari kita gunakan dan jalankan.echo | faas-cli invoke todo -f todo.yml
curl http:
curl http:
curl http:
Periksa log API:faas-cli logs todo
2020-03-26T14:35:29Z 2020/03/26 14:35:29 POST /create - 200 OK - ContentLength: 0
Periksa isi tabel menggunakan pgsql:export POSTGRES_PASSWORD=$(kubectl get secret
kubectl run postgresql-client
postgres=
id | description | created_date | completed_date
1 | faas-cli build | 2020-03-26 14:36:03.367789 |
2 | faas-cli push | 2020-03-26 14:36:03.389656 |
3 | faas-cli deploy | 2020-03-26 14:36:03.797881 |
Selamat, Anda sekarang memiliki API TODO yang dapat menerima permintaan masuk melalui curl
atau klien HTTP lainnya dan menuliskannya ke tabel database.Catat Permintaan
Mari kita membuat fungsi baru untuk meminta catatan TODO dari tabel:func selectTodos() ([]Todo, error) {
var error err
var todos []Todo
return todos, err
}
Kami tidak dapat memberi nama metode pemilihan ini karena ini adalah kata kunci yang disediakan untuk bekerja dengan goroutine.Sekarang hubungkan metode ke pengendali utama:} else if r.Method == http.MethodGet && r.URL.Path == "/list" {
todos, err := selectTodos()
if err != nil {
http.Error(w, fmt.Sprintf("unable to get todos: %s", err.Error()), http.StatusInternalServerError)
}
out, _ := json.Marshal(todos)
w.Header().Set("Content-Type", "application/json")
w.Write(out)
}
Sekarang ada bidang tambahan untuk tanggal dalam skema data kami, perbarui struktur Todo:type Todo struct {
ID int `json:"id"`
Description string `json:"description"`
CreatedDate *time.Time `json:"created_date"`
CompletedDate *time.Time `json:"completed_date"`
}
Sekarang mari kita tambahkan selectTodos()
kode permintaan ke metode kami :func selectTodos() ([]Todo, error) {
rows, getErr := db.Query(`select id, description, created_date, completed_date from todo;`)
if getErr != nil {
return []Todo{}, errors.Wrap(getErr, "unable to get from todo table")
}
todos := []Todo{}
defer rows.Close()
for rows.Next() {
result := Todo{}
scanErr := rows.Scan(&result.ID, &result.Description, &result.CreatedDate, &result.CompletedDate)
if scanErr != nil {
log.Println("scan err:", scanErr)
}
todos = append(todos, result)
}
return todos, nil
}
Seperti sebelumnya, kita perlu menunda menutup baris untuk permintaan. Setiap nilai dimasukkan ke dalam struktur baru menggunakan metode rows.Scan. Di akhir metode, kami memiliki konten Todo.Mari mencoba:faas-cli up -f todo.yml
curl http://127.0.0.1:8080/function/todo/list
Inilah hasilnya:[
{
"id": 2,
"description": "faas-cli build",
"created_date": "2020-03-26T14:36:03.367789Z",
"completed_date": null
},
{
"id": 3,
"description": "faas-cli push",
"created_date": "2020-03-26T14:36:03.389656Z",
"completed_date": null
},
{
"id": 4,
"description": "faas-cli deploy",
"created_date": "2020-03-26T14:36:03.797881Z",
"completed_date": null
}
]
Untuk menghapus nilai, kita dapat memperbarui anotasi struktur dengan menambahkan omitempty
:CompletedDate *time.Time `json:"completed_date,omitempty"`
Untuk meringkas pekerjaan yang dilakukan
Kami belum selesai, tetapi ini adalah saat yang tepat untuk berhenti dan meninjau kembali apa yang telah kami capai sejauh ini. Kita:- Instal Go, Docker, kubectl dan VSCode (IDE)
- Dikerahkan Kubernetes di komputer lokal kami
- Menginstal Postgresql menggunakan bahtera dan helm3
- Menginstal OpenFaaS dan tumpukan PLONK untuk pengembang aplikasi Kubernetes
- Membuat API REST statis awal menggunakan Go dan
golang-middleware
templat OpenFaaS - Menambahkan fungsi "masukkan" ke API TODO kami
- Menambahkan fungsi pilih ke API TODO kami
Contoh kode lengkap yang telah kami buat sejauh ini tersedia di akun GitHub saya: alexellis / kubernetes-todo-go-appKemudian kita dapat melakukan lebih banyak lagi, misalnya:- Menambahkan Otentikasi Menggunakan Token Pembawa Statis
- Buat halaman web menggunakan HTML statis atau React template untuk merender daftar TODO dan membuat elemen baru.
- Menambahkan dukungan multi-pengguna ke API
Dan banyak lagi. Kami juga dapat mempelajari tumpukan PLONK dan menggunakan dasbor Grafana untuk mulai memantau API kami dan memahami berapa banyak sumber daya yang digunakan dengan dasbor Kubernetes atau server metrik (diinstal menggunakan arkade install
).Pelajari lebih lanjut tentang arkade: https://get-arkade.devHadiri lokakarya OpenFaaS untuk mempelajari lebih lanjut tentang hal di atas: https://github.com/openfaas/workshop/Anda dapat berlangganan buletin Pembaruan Orang Dalam premium saya dihttps: / /www.alexellis.io/dan di twitter saya Alex Ellis
Pelajari lebih lanjut tentang kursus