-Spring Boot 4.1.0 · Java 25 · Fabric8 Kubernetes Client 7.1.0-
Ko‘plab zamonaviy backend tizimlari Kubernetes’da ishlaydi va xizmat holatini tekshirish uchun Pod qidiruvlari juda tez-tez amalga oshiriladi. Shu paytgacha operatorlar (yoki bunga mas’ul dasturchilar) serverga ulanib, kubectl buyruqlarini bevosita kiritish orqali bu ishni bajarib kelishgan. Biroq operatsion ko‘lam kengaygani sari bu yondashuv bir nechta cheklovlarni yuzaga chiqarmoqda.
Ushbu maqolada Spring Boot ilovasida Fabric8 Kubernetes Client’dan foydalanib, Kubernetes API’ni to‘g‘ridan-to‘g‘ri servis qatlamidan chaqirish va Pod holatini olish funksiyasini joriy etish jarayoni tanishtiriladi. Unda klaster ulanishi haqidagi ma’lumotlarni tekshirishdan tortib, kodni joriy etish va deploy uchun zarur ruxsatlarni sozlashgacha bo‘lgan barcha bosqichlar yoritiladi.
1. Ishlab chiqish asoslari
1.1. Shell asosidagi qidiruvning cheklovlari
Avvalroq Pod holati noodatiy bo‘lishi gumon qilinganda, operator serverga SSH orqali ulanib, kubectl buyruqlarini bevosita kiritardi. Dastlab bu yondashuv yetarli edi, ammo servis kengaygani sari quyidagi muammolar to‘planib bordi.
-
Dasturchilar va ekspluatatsiya xodimlaridan tashqari, PM’lar va mijozlarni qo‘llab-quvvatlash vakillari kabi a’zolar ham holatni darhol tekshirishni xohlashdi, biroq ularga klasterga kirish huquqini berish xavfsizlik nuqtayi nazaridan murakkab vazifa edi.
-
Barcha ishtirokchilarga kubeconfig tarqatish boshqaruv nuqtalari sonini oshirdi hamda ruxsatlarni bekor qilish va auditni kuzatishni qiyinlashtirdi.
-
Shell buyruqlari natijalari faqat matn ko‘rinishida taqdim etilardi, shu sababli ularni dashboard va ogohlantirish tizimlariga integratsiya qilish yoki tarixiy yozuvlar sifatida jamlash qiyin edi.
Oxir-oqibat, ushbu muammolar "Pod holatini qidirishni servis (API) qatlamiga ko‘chirish" talabining paydo bo‘lishiga olib keldi.
1.2. Ishlab chiqishning boshqa asoslari
-
Insidentlarga javob berishni avtomatlashtirish: Ilova holatdagi o‘zgarishlarni bevosita aniqlashi va qayta ishga tushirish hamda ogohlantirish kabi keyingi amallarni kod orqali sozlashi kerak.
-
Dashboard bilan integratsiya: Pod holati, node’lar va label’larni vizuallashtirish uchun ushbu ma’lumotlarni REST API orqali taqdim etadigan backend zarur.
-
Bir nechta namespace’larni boshqarish: Bitta ekranda bir nechta namespace’ni integratsiyalashgan tarzda ko‘rish ehtiyoji mavjud edi.
2. Kutubxonani tanlash: Nega Fabric8
Java ekotizimidagi yetakchi Kubernetes klientlari rasmiy client-java va Fabric8 kubernetes-client hisoblanadi. Ushbu loyiha quyidagi sabablarga ko‘ra Fabric8’ni tanladi.
|
Band |
Tavsif |
|---|---|
|
API uslubi |
.pods().inNamespace().withLabel() ko‘rinishidagi Fluent API yuqori o‘qiluvchanlikni ta’minlaydi. |
|
Spring bilan moslik |
Spring Cloud Kubernetes Fabric8 asosida qurilgani sababli, Spring Boot bilan integratsiya tabiiy tarzda amalga oshiriladi. |
|
Konfiguratsiyani avtomatik aniqlash |
Config.autoConfigure() in-cluster konfiguratsiyasi yoki mahalliy kubeconfig’dan foydalanish kerakligini avtomatik aniqlaydi. |
3. Zarur shartlar: Klaster ulanishi haqidagi ma’lumotlarni tekshirish
Kodni yozishdan oldin API server manzili, autentifikatsiya usuli, CA sertifikati va tegishli hisob qaydnomasining ruxsatlarini (RBAC) aniq belgilab olish kerak.
3.1. API server manzilini tekshirish
Agar kubectl sozlangan bo‘lsa, quyidagi buyruq yordamida uni oson tekshirishingiz mumkin.
$ kubectl cluster-info
Kubernetes control plane is running at https://127.0.0.1:6443
Agar 127.0.0.1 ko‘rsatilsa, ehtiyot bo‘lish kerak. Bu control plane node’ining o‘zini anglatadi, shuning uchun undan faqat ilova ayni serverda ishlaganda to‘g‘ridan-to‘g‘ri foydalanish mumkin. Agar ilovani klaster ichida Pod sifatida deploy qilsangiz, in-cluster konfiguratsiyasidan foydalaniladi, shu sababli manzilni bilish shart emas (KUBERNETES_SERVICE_HOST avtomatik inject qilinadi). Agar tashqi serverdan masofadan ulansangiz, node’ning haqiqiy IP manzilini tekshirishingiz kerak (kubectl get nodes -o wide, hostname -I). Cloud tomonidan boshqariladigan klaster uchun endpoint’ni aws eks describe-cluster va gcloud container clusters describe kabi buyruqlar yordamida topishingiz mumkin.
3.2. Server javob berayotganini tezda tekshirish
Manzilni tekshirgandan so‘ng, health check endpoint’ini curl orqali chaqirib, server javob berayotganini tekshiring. -k TLS tekshiruvini self-signed CA uchun o‘tkazib yuboradi va undan faqat ulanishni sinash maqsadida foydalanish kerak.
$ curl -k https://<주소>:6443/healthz
ok
$ curl -k https://<주소>:6443/api # 토큰 없이 호출 시 401이 와도 연결은 정상
3.3. Autentifikatsiya usuli · CA sertifikatini tekshirish
Autentifikatsiya usulini kubectl config view buyrug‘ining users bo‘limi ostidagi maydonlardan aniqlashingiz mumkin.
|
kubeconfig maydoni |
Autentifikatsiya usuli |
|---|---|
|
client-certificate / client-key |
mTLS (klient sertifikati) |
|
token |
Statik token yoki ServiceAccount token’i |
|
exec bloki mavjud |
Cloud CLI bilan integratsiyalangan autentifikatsiya (masalan, aws eks get-token) |
Klaster ichida Pod sifatida deploy qilinganda, mahalliy kubeconfig’dan mustaqil ravishda ServiceAccount token’i avtomatik mount qilinadigan in-cluster yondashuvidan foydalanish odatiy hol. CA sertifikati kubeconfig ichida base64 formatida bo‘lgani uchun, uni quyidagicha ajratib oling.
$ kubectl config view --raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}' \
| base64 -d > ca.crt
3.4. RBAC’ni dastlabki tekshirish
Tegishli hisob qaydnomasida Pod’larni olish uchun haqiqatan ham ruxsat bor-yo‘qligini oldindan tekshiring. Ikkala natija ham yes bo‘lishi kerak; agar ulardan biri no bo‘lsa, administrator’dan 4.5-bo‘limda tavsiflangan Role/RoleBinding’ni yaratishni so‘rang.
$ kubectl auth can-i list pods --namespace=<대상-네임스페이스>
$ kubectl auth can-i get pods --namespace=<대상-네임스페이스>
4. Spring Boot’da joriy etish
4.1. Bog‘liqliklarni qo‘shish
// build.gradle.kts
implementation("io.fabric8:kubernetes-client:7.1.0")
<!-- pom.xml -->
<dependency>
<groupId>io.fabric8</groupId>
<artifactId>kubernetes-client</artifactId>
<version>7.1.0</version>
</dependency>
※ Deploy vaqtida versiyani Maven Central’da yana bir bor tekshirish tavsiya etiladi.
4.2. KubernetesClient bean’ini ro‘yxatdan o‘tkazish
Config.autoConfigure(null) avval in-cluster konfiguratsiyasini, so‘ngra mahalliy kubeconfig’ni avtomatik aniqlaydi. Shu tariqa alohida tarmoqlanishlarsiz bir xil koddan ishlab chiqish va production muhitlarida foydalanish mumkin.
@Configuration
public class KubernetesConfig {
@Bean
public KubernetesClient kubernetesClient() {
Config config = Config.autoConfigure(null); // in-cluster → kubeconfig 순 탐지
return new KubernetesClientBuilder().withConfig(config).build();
}
}
4.3. Pod qidirish servisi
Eng ko‘p so‘raladigan uchta funksiya — to‘liq ro‘yxatni olish, yorliq bo‘yicha filtrlash va bitta elementni olish.
@Service
public class PodQueryService {
private final KubernetesClient kubernetesClient;
public PodQueryService(KubernetesClient kubernetesClient) {
this.kubernetesClient = kubernetesClient;
}
// 특정 네임스페이스 Pod 목록 조회
public List<PodSummary> getPods(String namespace) {
PodList podList = kubernetesClient.pods()
.inNamespace(namespace)
.list();
return podList.getItems().stream()
.map(this::toSummary)
.toList();
}
// 라벨 셀렉터로 필터링 조회
public List<PodSummary> getPodsByLabel(String namespace, String key, String value) {
PodList podList = kubernetesClient.pods()
.inNamespace(namespace)
.withLabel(key, value)
.list();
return podList.getItems().stream()
.map(this::toSummary)
.toList();
}
// 단건 조회
public PodSummary getPod(String namespace, String podName) {
Pod pod = kubernetesClient.pods()
.inNamespace(namespace)
.withName(podName)
.get();
if (pod == null) {
throw new NoSuchElementException("Pod not found: " + podName);
}
return toSummary(pod);
}
private PodSummary toSummary(Pod pod) {
return new PodSummary(
pod.getMetadata().getName(),
pod.getMetadata().getNamespace(),
pod.getStatus().getPhase(),
pod.getSpec().getNodeName(),
pod.getMetadata().getLabels(),
pod.getMetadata().getCreationTimestamp()
);
}
}
public record PodSummary(
String name,
String namespace,
String phase,
String nodeName,
Map<String, String> labels,
String createdAt
) {}
4.4 Kontroller
Xizmat qatlamidagi ma’lumotlarni REST API orqali taqdim etish orqali operatsiyalar panellari va ichki vositalar Pod holatini tekshirish uchun ularga bevosita murojaat qilishi mumkin.
@RestController
@RequestMapping("/api/pods")
public class PodController {
private final PodQueryService podQueryService;
public PodController(PodQueryService podQueryService) {
this.podQueryService = podQueryService;
}
@GetMapping
public List<PodSummary> list(
@RequestParam String namespace,
@RequestParam(required = false) String labelKey,
@RequestParam(required = false) String labelValue
) {
if (labelKey != null && labelValue != null) {
return podQueryService.getPodsByLabel(namespace, labelKey, labelValue);
}
return podQueryService.getPods(namespace);
}
@GetMapping("/{name}")
public PodSummary get(@RequestParam String namespace, @PathVariable String name) {
return podQueryService.getPod(namespace, name);
}
}
4.5 Deployment uchun RBAC konfiguratsiyasi
Klaster ichida Pod sifatida joylashtirilganda, Pod’ning ServiceAccount’iga faqat minimal ruxsatlarni (get/list/watch) bering.
apiVersion: v1
kind: ServiceAccount
metadata:
name: my-backend-sa
namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: default
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: my-backend-pod-reader-binding
namespace: default
subjects:
- kind: ServiceAccount
name: my-backend-sa
namespace: default
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io
Deployment’da serviceAccountName: my-backend-sa ni ko‘rsating. Bir nechta namespace’ni so‘rashingiz kerak bo‘lsa, qamrovni ClusterRole/ClusterRoleBinding yordamida kengaytirishingiz mumkin.
4.6 Istisnolarni qayta ishlash
Kubernetes API chaqiruvlari autentifikatsiya xatosi (401) yoki yetarli ruxsatlarning yo‘qligi (403) kabi holatlarda KubernetesClientException istisnosini chiqaradi. Aniq status kodlarini qaytarish uchun bu istisnolarni umumiy istisnolarni qayta ishlovchi orqali moslang.
@RestControllerAdvice
public class KubernetesExceptionHandler {
@ExceptionHandler(KubernetesClientException.class)
public ResponseEntity<String> handleK8sException(KubernetesClientException e) {
// 403이면 RBAC 권한 부족, 401이면 인증 실패로 해석
int code = e.getCode();
return ResponseEntity.status(code).body("K8s API 호출 실패: " + e.getMessage());
}
}
5. Xulosa
Ushbu ish operatorlarning har safar serverga ulanib, kubectl buyruqlarini kiritish jarayonini xizmat darajasidagi REST API chaqiruvlari bilan almashtirish uchun asos yaratdi. Klasterga kirish ruxsatiga ega bo‘lmagan a’zolar endi o‘zlariga kerakli ma’lumotlarni xavfsiz tekshirishlari mumkin, shuningdek, panellar va ogohlantirish tizimlari bilan integratsiya qilish uchun ham asos yaratildi.
Ushbu amalga oshirish Pod’larni olishning yagona funksiyasidan boshlangan bo‘lsa-da, xuddi shu tuzilmadan foydalanish uni Deployments, Services va Nodes kabi boshqa resurslarning holatini olishga tabiiy ravishda kengaytirish imkonini beradi. Keyinchalik to‘plangan ushbu API’larni ogohlantirish tizimlari yoki ichki operatsiyalar panellariga ulash mumkin; bu nosozlik alomatlarini tezroq aniqlash va ularga javob berish uchun asos bo‘lib xizmat qiladi.
Jsia