S3 Health Check
On this page
- Sekilas
- Yang dikerjakannya
- A. Terhubung lebih dulu, dan berhenti di situ bila gagal
- B. Memakai tiap bucket seperti client memakainya
- C. Membuktikan file besar selamat
- D. Menguji batas proxy
- E. Melapor dalam bentuk yang bisa dipakai orang maupun script
- F. Membersihkan jejaknya sendiri
- Cara saya memakainya
- Keputusan rancangan
- Spesifikasi
- Terkait
- Istilah
S3 Health Check adalah satu script Python yang membuktikan server storage kompatibel S3 sudah siap sebelum aplikasi mana pun diizinkan bergantung padanya. Ia tak sekadar bertanya apakah server menjawab; ia memakai server itu persis seperti client sungguhan — dengan kredensial yang sama dan lewat jenis tautan yang sama — lalu melaporkan, satu pemeriksaan demi satu pemeriksaan, apakah tiap bucket berperilaku sebagaimana mestinya.
Object storage menyimpan file sebagai objek di dalam bucket bernama, yang dijangkau lewat HTTP; Amazon S3 yang mendefinisikan antarmukanya, dan server seperti MinIO mengimplementasikannya untuk dipasang sendiri. Presigned URL adalah tautan sementara yang ditandatangani dengan kredensial storage, sehingga browser bisa mengunggah atau mengunduh satu objek tertentu tanpa pernah memegang kredensial itu. Kebanyakan kesalahan pada object storage terjadi di tautan-tautan itu, dan kebanyakan terjadi tanpa suara — itulah alasan tool ini ada.
Sekilas
| Bentuk | Satu script command-line |
|---|---|
| Bahasa | Python 3, dengan boto3 dan requests |
| Status | Stabil, dipakai |
| Kode sumber | Privat |
Yang dikerjakannya
A. Terhubung lebih dulu, dan berhenti di situ bila gagal
Pemeriksaan pertama adalah terhubung dan login ke server. Bila gagal, tak ada pemeriksaan lain yang dijalankan: endpoint yang salah, persoalan sertifikat, atau key yang ditolak dilaporkan sekali dengan jelas, bukan sebagai rentetan kegagalan di setiap bucket yang menyembunyikan satu-satunya penyebab sebenarnya. Koneksinya diuji dengan mendaftar bucket, jadi jawaban pertama pun sudah membuktikan kredensialnya diterima.
B. Memakai tiap bucket seperti client memakainya
Setiap bucket di konfigurasi menyatakan apakah upload dan download butuh autentikasi, dan script mengikuti kedua flag itu persis. Bucket yang flag-nya tak ditulis dianggap privat. Bila autentikasi dibutuhkan, ia membuat presigned link lalu mengirim objek acak kecil lewat tautan itu; bila tidak, ia mengunggah atau mengunduh tanpa kredensial sama sekali. Sebelum semua itu ia bertanya ke server apakah bucket-nya ada dan boleh dipakai key tersebut, jadi bucket yang hilang disebut hilang, tak terkubur di bawah error upload, dan bucket yang tercantum di konfigurasi tapi tak dimiliki server langsung dilaporkan di awal. Sesudah itu ia memeriksa policy akses bucket yang sebenarnya secara tersendiri: bucket privat wajib menolak orang asing, dan bucket publik wajib melayaninya.
C. Membuktikan file besar selamat
File besar diunggah dalam beberapa part, dan server atau proxy di depannya yang salah menangani part itu biasanya melakukannya tanpa error. Objek uji bawaannya 16 MiB, cukup besar sehingga ujinya tak mungkin lolos tanpa part sungguhan. Script mengunggahnya dalam part-part, lalu membaca jumlah part dari jawaban server sendiri, dan memakai akhiran ETag bila server tak melaporkannya. Ukuran yang tersimpan diperiksa dengan bertanya sekali lagi tanpa nomor part, karena ukuran yang dilaporkan bersama nomor part hanyalah ukuran satu part itu. Sesudah itu objeknya diunduh dan MD5 byte-nya dibandingkan, karena ETag objek multipart bukan MD5 isinya. Kedua arah berjalan sebagai stream: upload dibangkitkan sambil dikirim dan download di-hash sambil tiba, jadi memory tetap datar walau ukurannya gigabyte. Run ini melaporkan lama upload dan throughput-nya, dan uji besar hanya jalan bila pemeriksaan kecil bucket itu lolos, supaya jalur dasar yang rusak tak tertutup oleh noise multipart.
D. Menguji batas proxy
Bila ukuran part disamakan dengan ukuran objek, upload dikirim sebagai satu request, bukan part-part, dan berubah menjadi uji langsung atas batas ukuran request di proxy. Ukuran part diperiksa sebelum apa pun dikirim: di bawah minimum 5 MiB, atau lebih dari 10.000 part, run berhenti dan menyarankan ukuran part terkecil yang bisa dipakai. Uji multipart dan uji satu-request memakai SDK storage terhadap endpoint di konfigurasi, bukan presigned link, karena upload multipart adalah tiga panggilan API berurutan yang tak bisa diwakili satu presigned link, sementara jalur presigned sudah diuji oleh file kecil.
E. Melapor dalam bentuk yang bisa dipakai orang maupun script
Ia mencetak satu baris per pemeriksaan, ringkasan per bucket yang mendaftar kegagalannya, dan status keseluruhan: HEALTHY bila semua bucket lolos, DEGRADED bila hanya sebagian, dan UNHEALTHY bila tak satu pun lolos atau server tak terjangkau. Semuanya diakhiri exit code. Pemeriksaan yang gagal diterjemahkan ke penyebabnya yang paling mungkin: 413 menunjuk ke batas ukuran request di proxy, part yang terlalu kecil menunjuk ke ukuran part, dan error sertifikat, timeout koneksi, serta timeout baca dibedakan satu sama lain. Orang membaca baris-barisnya; script deployment membaca exit code-nya dan berhenti sebelum aplikasi menyala di atas storage yang belum siap.
F. Membersihkan jejaknya sendiri
Setiap objek uji diberi nama berawalan tetap, timestamp, dan akhiran acak, lalu dihapus begitu pemeriksaannya selesai, juga ketika pemeriksaan sebelumnya gagal. Penghapusan itu sendiri dihitung sebagai pemeriksaan: objek yang tak bisa dihapus script menandai bucket-nya gagal. Bila satu run terputus, sisa-sisanya mudah ditemukan lewat awalan itu, jadi menjalankan tool ini terhadap server production tak meninggalkan jejak di bucket.
Cara saya memakainya
Tiga perintah mencakup hampir semua pemakaian: run penuh, run cepat tanpa uji file besar, dan run dengan objek uji yang jauh lebih besar ketika ada proxy yang dicurigai.
Konfigurasi menyebut server, kredensial, alamat yang sebenarnya dipakai client, dan tiap bucket beserta kedua flag-nya. File aslinya menyimpan kredensial hidup dan tak pernah meninggalkan mesin; salinan berisi placeholder disimpan di samping script sebagai titik awal.
| Opsi | Bawaan | Efek |
|---|---|---|
--config FILE | config.json | file konfigurasi yang dibaca |
--large-size SIZE | 16MiB | ukuran objek uji multipart, mis. 512MB, 1GiB |
--part-size SIZE | 5MiB | ukuran tiap part; 5 MiB adalah minimum protokol, dan ukuran objek penuh menghasilkan uji satu-request |
--skip-large | mati | lewati uji multipart untuk run cepat |
--timeout SECONDS | 30 | batas waktu tiap operasi jaringan |
--keep-artifacts | mati | simpan objek uji untuk diperiksa |
--verbose | mati | cetak detail tambahan, dengan signature di URL disamarkan |
Exit code adalah bagian dari kontraknya: 0 bila semua pemeriksaan lolos, 1 bila setidaknya satu gagal, 2 bila konfigurasi atau nilai command-line tak sah atau library yang dibutuhkan belum terpasang — disertai perintah pemasangannya, bukan traceback — dan 130 bila run dihentikan. Berikut run sungguhan yang dipendekkan, terhadap server dengan satu bucket privat dan satu bucket publik, dengan nama host diganti; tool ini melapor dalam bahasa Indonesia:
===
[ &
===
[
[
[
[
Keputusan rancangan
Ia menguji seperti client menguji, jadi lolosnya berarti sesuatu. Server yang menjawab koneksi baru membuktikan ada proses yang mendengarkan. Saya membuat script memakai presigned link di tempat client memakainya dan request anonim di tempat client melakukannya, lalu mengirim keduanya ke alamat publik yang sebenarnya dipakai client. Jadi lolos berarti tautan berfungsi bagi user sungguhan di alamat yang sebenarnya mereka pakai, bukan sekadar pintu belakang yang terbuka.
Ia menangkap kegagalan yang tak mengumumkan dirinya. HTTP 200 tak membuktikan byte-nya tiba utuh, jadi setiap unduhan dibandingkan lewat MD5. Flag bucket di konfigurasi tak membuktikan policy-nya yang sebenarnya, jadi policy diuji terpisah, dan perbedaan keduanya dilaporkan sebagai POLICY MISMATCH yang menyebut kedua sisi. Upload multipart yang berhasil tak membuktikan ia benar-benar dipecah, jadi tool membaca jumlah part dari ETag objeknya. Tanpa itu, masing-masing kegagalan baru muncul jauh belakangan, sebagai gambar yang rusak, atau lebih buruk lagi, sebagai file privat yang ternyata publik.
Ia gagal cepat, jadi bisa duduk di dalam otomasi. Client storage hanya diberi dua percobaan per operasi, bukan bawaannya yang banyak: health check yang diam-diam me-retry berulang-ulang justru menyembunyikan kelambatan yang semestinya ia laporkan. Ditambah berhenti di kegagalan konektivitas pertama dan exit code yang artinya tetap, deployment bisa menjalankannya sebagai gerbang dan bertindak atas jawabannya.
Ia aman dijalankan di mana saja, sesering apa pun. Objek uji membawa awalan yang mudah dikenali dan dihapus sesudah dipakai. Payload besar dibangkitkan sambil dikirim, bukan ditampung di memory, dan dibangkitkan dari seed, sehingga posisi yang sama selalu menghasilkan byte yang sama — penting karena SDK mengirim ulang satu part saat me-retry, dan byte ulangan yang berbeda akan menggagalkan checksum dengan alasan yang tak ada hubungannya dengan server. Stream yang dibangkitkan itu juga menjawab panggilan close yang dilakukan SDK pada upload satu-request, panggilan yang dulu pernah menghentikan run dengan error atribut. Di mode verbose, signature dan kredensial di URL disamarkan, jadi log satu run bisa dibagikan, dan baik konfigurasi asli maupun output yang disimpan dijauhkan dari version control, karena output-nya menyebut endpoint yang sebenarnya.
Setelan yang terlupa gagal ke arah aman, dan setelan yang salah gagal sejak awal. Bucket tanpa flag upload atau download diharapkan privat, jadi lupa menulis flag tak akan pernah membuat script menerima bucket publik sebagai benar. Konfigurasi divalidasi sebelum koneksi apa pun: flag harus boolean sungguhan, umur tautan tak boleh melewati tujuh hari yang diizinkan signature SigV4, gaya addressing harus yang dikenal, nama bucket tak boleh berulang, dan kredensial tak boleh kosong. Salah ketik pun berakhir dengan exit code 2, bukan muncul sebagai kegagalan uji yang menyesatkan. Endpoint-nya juga dinormalkan — skema yang hilang ditambahkan, dan port hanya disambung bila bukan port bawaan — supaya host yang ditandatangani SDK sama dengan host yang benar-benar dikirim.
Spesifikasi
| Masukan | Konfigurasi JSON: endpoint, region, gaya addressing, kredensial, alamat publik, umur tautan, dan bucket beserta flag upload dan download-nya |
|---|---|
| Keluaran | Satu baris per pemeriksaan, ringkasan per bucket, status keseluruhan HEALTHY, DEGRADED, atau UNHEALTHY, throughput upload, dan exit code 0, 1, 2, atau 130 |
| Pemeriksaan | Konektivitas, keberadaan dan akses bucket, upload dan download presigned maupun anonim, integritas MD5, policy akses anonim, upload multipart beserta jumlah part dan ukurannya, batas ukuran satu request, pembersihan |
| Konfigurasi | Susunan bersarang atau susunan datar yang lebih lama; umur tautan diatur global atau per bucket, paling lama tujuh hari; ukuran dalam satuan desimal maupun biner seperti MB atau MiB; verifikasi TLS menyala kecuali sengaja dimatikan |
| Ketergantungan | Python 3, boto3, botocore, requests |
| Keamanan | Objek uji berawalan dihapus sesudah dipakai; bisa disimpan untuk diperiksa; rahasia disamarkan di keluaran verbose; tak mengubah bucket maupun policy |
| Bekerja dengan | Server apa pun yang kompatibel S3, seperti MinIO, termasuk yang berada di balik reverse proxy |
Terkait
Cerita di balik pemeriksaan-pemeriksaan ini, dan alasan masing-masing ada.
Bentuknya mengikuti bentuk yang saya berikan pada setiap tool kecil: satu file, satu tugas, dan kontrak exit code di bagian atas.
Inilah jenis pemeriksaan kesiapan yang dijalankan prosedur rilis saya sebelum kode mulai bergantung pada layanan eksternal.
Template yang melahirkan bucket privat dan publik yang kesiapannya dibuktikan pemeriksaan ini.
Istilah
- Presigned URL
- Tautan sementara yang ditandatangani dengan kredensial storage, yang membolehkan satu upload atau download tertentu tanpa memberikan kredensial itu kepada client.
- Upload multipart
- Mengunggah objek besar sebagai beberapa part yang dikirim terpisah, lalu disatukan server menjadi satu objek.
- ETag
- Identifier yang dikembalikan server untuk objek yang tersimpan; untuk upload multipart ia diakhiri tanda hubung dan jumlah part-nya.
- Checksum MD5
- Sidik jari pendek dari isi file; dua salinan dengan checksum yang sama, untuk keperluan ini, dianggap identik.
- Exit code
- Angka yang dikembalikan program saat selesai, yang dibaca script lain untuk menentukan langkah berikutnya.
Technologies covered
- Python
- boto3
- MinIO
- S3