Portal/Notes πŸ“
Cka

Secret

Versi Bahasa Indonesia. Baca dalam Bahasa Inggris

Kubernetes Secrets digunakan untuk menyimpan informasi sensitif seperti kata sandi, API key, dan sertifikat dengan cara yang aman. Mereka membantu memisahkan konfigurasi dari kode aplikasi, meningkatkan keamanan dan pengelolaan.

Tipe Secret

Berikut adalah tipe secret bawaan yang tersedia di Kubernetes:

TypePenggunaan
Opaque:data user-defined arbitrer.
kubernetes.io/service-account-token:Token ServiceAccount.
kubernetes.io/dockercfg:file ~/.dockercfg yang diserialisasi.
kubernetes.io/dockerconfigjson:file ~/.docker/config.json yang diserialisasi.
kubernetes.io/basic-auth:kredensial untuk autentikasi dasar.
kubernetes.io/ssh-auth:kredensial untuk autentikasi SSH.
kubernetes.io/tls:data untuk klien atau server TLS.
bootstrap.kubernetes.io/token:data token bootstrap.

Opaque Secret

Sebelumnya kita sudah membuat service postgres dengan persistent volume. Tapi kita masih menggunakan teks biasa sebagai konfigurasi username dan password. Kita dapat menggunakan secret untuk menyimpan konfigurasi sensitif dengan benar dan menggunakannya di deployment postgres kita.

Buat file baru bernama postgres-secret.yaml dan masukkan definisi secret di sana.

apiVersion: v1
kind: Secret
metadata:
  name: postgres-secret
type: Opaque
data:
  POSTGRES_USER: "YWRtaW4="
  POSTGRES_PASSWORD: "cGFzc3dvcmQ="

Bagian data berisi pasangan key-value dari data sensitif kita. Di sini kita menyimpan 2 data untuk username dan password dengan key POSTGRES_USERNAME dan POSTGRES_PASSWORD. Nilai dari pasangan tersebut perlu di-encode base64 terlebih dahulu. Kita dapat menggunakan perintah echo -n "admin" | base64 untuk meng-encode-nya.

Mari kita terapkan dan validasi secret kita.

➜ kubectl apply -f postgres-secret.yaml 
secret/postgres-secret created
➜ kubectl get secret  
NAME              TYPE     DATA   AGE
postgres-secret   Opaque   2      21s

Seperti yang Anda lihat di atas, secret telah dibuat dengan panjang DATA adalah 2. Kita juga dapat mendeskripsikannya untuk melihat detailnya.

➜ kubectl describe secrets postgres-secret
Name:         postgres-secret
Namespace:    default
Labels:       <none>
Annotations:  <none>

Type:  Opaque

Data
====
POSTGRES_PASSWORD:  8 bytes
POSTGRES_USER:      5 bytes

Menggunakan Secret

Postgres

Untuk menggunakan secret di deployment postgres kita, kita perlu memperbarui env dari teks biasa menjadi nilai dari secret.

env:
- name: POSTGRES_USER
  value: "admin"
- name: POSTGRES_PASSWORD
  value: "password"

Ganti bagian di atas dengan bagian di bawah ini. Ini akan memberi tahu Kubernetes untuk mencari nilai dari secret dengan nama postgres-secret dan key POSTGRES_USER untuk user dan POSTGRES_PASSWORD untuk password.

env:
- name: POSTGRES_USER
  valueFrom:
    secretKeyRef:
      name: postgres-secret
      key: POSTGRES_USER
- name: POSTGRES_PASSWORD
  valueFrom:
    secretKeyRef:
      name: postgres-secret
      key: POSTGRES_PASSWORD

Mari kita terapkan dan validasi apakah pod berjalan tanpa error. Kita dapat melakukan pengujian serupa seperti sebelumnya, dengan melakukan port forward dan kemudian menghubungkan menggunakan psql. Kita seharusnya masih dapat terhubung dan melihat data tanpa error.

admin=# \c mydb
You are now connected to database "mydb" as user "admin".
mydb=# SELECT * FROM message;
 id | content 
----+---------
  1 | Hello!
(1 row)

Simple V2

Kemudian mari kita perbarui aplikasi kita untuk menulis dan membaca dari database. Anda dapat menyalin kode ini dan kemudian jalankan go get . untuk mengunduh semua dependensi.

package main

import (
    "encoding/json"
    "fmt"
    "log"
    "net/http"
    "os"

    "github.com/gorilla/mux"
    "github.com/jmoiron/sqlx"
    _ "github.com/lib/pq"
)

type Message struct {
    ID      int    `json:"id" db:"id"`
    Content string `json:"content" db:"content"`
}

func main() {
    // Get user and password from env
    user := os.Getenv("POSTGRES_USER")
    password := os.Getenv("POSTGRES_PASSWORD")
    // Database connection
    host := "postgres.default.svc.cluster.local"
    connectionStr := fmt.Sprintf("host=%s user=%s password=%s dbname=mydb sslmode=disable", host, user, password)
    db, err := sqlx.Connect("postgres", connectionStr)
    if err != nil {
        log.Fatal(err)
    }

    // handlers
    mux := mux.NewRouter()
    mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        // fetch data from database
        messages := []Message{}
        err := db.SelectContext(
            r.Context(),
            &messages,
            "SELECT * FROM message",
        )
        if err != nil {
            w.WriteHeader(http.StatusInternalServerError)
            w.Write([]byte(err.Error()))
            return
        }
        // return it as json response
        err = json.NewEncoder(w).Encode(messages)
        if err != nil {
            w.WriteHeader(http.StatusInternalServerError)
            w.Write([]byte(err.Error()))
            return
        }
    }).Methods(http.MethodGet)
    mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        // get content from json body
        message := &Message{}
        err := json.NewDecoder(r.Body).Decode(message)
        if err != nil {
            w.WriteHeader(http.StatusInternalServerError)
            w.Write([]byte(err.Error()))
            return
        }
        // save to database
        _, err = db.NamedExecContext(
            r.Context(),
            "INSERT INTO message (content) VALUES (:content)",
            message,
        )
        if err != nil {
            w.WriteHeader(http.StatusInternalServerError)
            w.Write([]byte(err.Error()))
            return
        }
        w.Write([]byte("SUCCESS"))
    }).Methods(http.MethodPost)

    // start server
    fmt.Println("Server is running on port 8080...")
    err = http.ListenAndServe(":8080", mux)
    if err != nil {
        log.Fatal(err)
    }
}

Aplikasi ini akan mendapatkan konfigurasi user dan password dari environment variable dan menggunakannya untuk terhubung ke server. Dan untuk mengakses service (postgres) dari dalam klaster, kita dapat menggunakan format <service_name>.<namespace>.svc.cluster.local.

Bangun aplikasi kita dan beri tag simple-go:v2.

➜ docker build --tag simple-go:v2 .

Perbarui deployment kita untuk menggunakan image simple-go:v2 dan ganti env dengan yang di bawah ini. Ini akan membuat environment variable POSTGRES_USER dan POSTGRES_PASSWORD tersedia di aplikasi kita.

env:
- name: POSTGRES_USER
  valueFrom:
    secretKeyRef:
      name: postgres-secret
      key: POSTGRES_USER
- name: POSTGRES_PASSWORD
  valueFrom:
    secretKeyRef:
      name: postgres-secret
      key: POSTGRES_PASSWORD

Terapkan dan periksa apakah pod berjalan seperti yang diharapkan.

Untuk mengujinya, kita dapat menggunakan perintah minikube service untuk mengekspos service kita. Kemudian jalankan curl ke url yang diberikan.

➜ curl 'http://localhost:58834'
[{"id":1,"content":"Hello!"}]

Kita akan melihat data kita di sana. Coba kirim permintaan POST untuk memasukkan data baru dan GET lagi.

➜ curl -X POST -d '{"content": "Good Morning!"}' 'http://localhost:58834/'
SUCCESS
➜ curl 'http://localhost:58834'                                           
[{"id":1,"content":"Hello!"},{"id":2,"content":"Good Morning!"}]

Kita akan melihat data baru berhasil dimasukkan dan dikembalikan.

Referensi


Edit on GitHub

Last updated on

Secret | Faisal Affan