Sử dụng Fabric8 Kubernetes Client để quản lý Higress thực chất là thao tác trên các Custom Resource (CRD) mà Higress cung cấp, bao gồm:
Domain: Cấu hình tên miền (kết nối chứng chỉ, cổng lắng nghe)Route: Định nghĩa quy tắc định tuyến đường dẫn (chuyển hướng yêu cầu đến dịch vụ backend)
Bài viết cung cấp ví dụ Java đầy đủ và chạy được, bao gồm:
- Xây dựng lớp Java tương ứng với
DomainvàRoute - Tạo động tên miền HTTPS + định tuyến
- Liên kết chứng chỉ TLS
- Kiểm tra và dọn dẹp tài nguyên
Điều kiện tiên quyết
- Đã triển khai Higress trong cụm
kubectl get crd domains.networking.higress.io
kubectl get crd routes.networking.higress.io
- Chuẩn bị chứng chỉ TLS (tùy chọn)
kubectl create secret tls my-tls-secret \
--cert=your-cert.pem \
--key=your-key.pem \
-n default
- Phụ thuộc Maven
<dependency>
<groupId>io.fabric8</groupId>
<artifactId>kubernetes-client</artifactId>
<version>6.12.1</version>
</dependency>
Định nghĩa lớp Java cho CRD Higress
- Lớp
Domain(tương ứngdomains.networking.higress.io/v1)
// Domain.java
import io.fabric8.kubernetes.api.model.Namespaced;
import io.fabric8.kubernetes.client.CustomResource;
import io.fabric8.kubernetes.model.annotation.Group;
import io.fabric8.kubernetes.model.annotation.Version;
@Group("networking.higress.io")
@Version("v1")
public class Domain extends CustomResource<DomainSpec, Void> implements Namespaced {
}
// DomainSpec.java
import java.util.List;
public class DomainSpec {
private String domainName; // Tên miền, ví dụ: api.example.com
private List<String> certificateSecrets; // Danh sách tên Secret chứa chứng chỉ
private Integer httpPort; // Cổng HTTP (mặc định 80)
private Integer httpsPort; // Cổng HTTPS (mặc định 443)
// Getter và Setter
public String getDomainName() { return domainName; }
public void setDomainName(String domainName) { this.domainName = domainName; }
public List<String> getCertificateSecrets() { return certificateSecrets; }
public void setCertificateSecrets(List<String> certificateSecrets) { this.certificateSecrets = certificateSecrets; }
public Integer getHttpPort() { return httpPort; }
public void setHttpPort(Integer httpPort) { this.httpPort = httpPort; }
public Integer getHttpsPort() { return httpsPort; }
public void setHttpsPort(Integer httpsPort) { this.httpsPort = httpsPort; }
}
- Lớp
Route(tương ứngroutes.networking.higress.io/v1)
// Route.java
import io.fabric8.kubernetes.api.model.Namespaced;
import io.fabric8.kubernetes.client.CustomResource;
import io.fabric8.kubernetes.model.annotation.Group;
import io.fabric8.kubernetes.model.annotation.Version;
@Group("networking.higress.io")
@Version("v1")
public class Route extends CustomResource<RouteSpec, Void> implements Namespaced {
}
// RouteSpec.java
import java.util.List;
public class RouteSpec {
private String targetDomain; // Tên miền mục tiêu (phải khớp với Domain.domainName)
private List<String> routePaths; // Danh sách đường dẫn, ví dụ: ["/api/user/", "/user/"]
private Backend targetService; // Dịch vụ backend
public String getTargetDomain() { return targetDomain; }
public void setTargetDomain(String targetDomain) { this.targetDomain = targetDomain; }
public List<String> getRoutePaths() { return routePaths; }
public void setRoutePaths(List<String> routePaths) { this.routePaths = routePaths; }
public Backend getTargetService() { return targetService; }
public void setTargetService(Backend targetService) { this.targetService = targetService; }
}
// Backend.java
public class Backend {
private String serviceName; // Tên Service Kubernetes
private int servicePort; // Cổng dịch vụ
public String getServiceName() { return serviceName; }
public void setServiceName(String serviceName) { this.serviceName = serviceName; }
public int getServicePort() { return servicePort; }
public void setServicePort(int servicePort) { this.servicePort = servicePort; }
}
Ví dụ Java hoàn chỉnh: Tạo tên miền HTTPS + định tuyến
import io.fabric8.kubernetes.client.DefaultKubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClient;
import java.util.Arrays;
public class HigressManager {
private static final String NAMESPACE = "default";
private static final String DOMAIN_NAME = "api.example.com";
private static final String TLS_SECRET_NAME = "my-tls-secret"; // Phải tồn tại trước
private static final String BACKEND_SERVICE = "user-service";
private static final int BACKEND_PORT = 8080;
public static void main(String[] args) {
try (KubernetesClient client = new DefaultKubernetesClient()) {
// === 1. Tạo Domain (kích hoạt HTTPS)===
Domain domain = new Domain();
domain.getMetadata().setName("example-domain");
domain.getMetadata().setNamespace(NAMESPACE);
DomainSpec domainSpec = new DomainSpec();
domainSpec.setDomainName(DOMAIN_NAME);
domainSpec.setCertificateSecrets(Arrays.asList(TLS_SECRET_NAME)); // Liên kết chứng chỉ
domainSpec.setHttpsPort(443);
domain.setSpec(domainSpec);
client.resources(Domain.class)
.inNamespace(NAMESPACE)
.createOrReplace(domain);
System.out.println("✅ Domain đã được tạo: " + DOMAIN_NAME);
// === 2. Tạo Route ===
Route route = new Route();
route.getMetadata().setName("user-api-route");
route.getMetadata().setNamespace(NAMESPACE);
RouteSpec routeSpec = new RouteSpec();
routeSpec.setTargetDomain(DOMAIN_NAME); // Phải khớp với Domain.domainName
routeSpec.setRoutePaths(Arrays.asList("/api/user/", "/user/"));
Backend backend = new Backend();
backend.setServiceName(BACKEND_SERVICE);
backend.setServicePort(BACKEND_PORT);
routeSpec.setTargetService(backend);
route.setSpec(routeSpec);
client.resources(Route.class)
.inNamespace(NAMESPACE)
.createOrReplace(route);
System.out.println("✅ Route đã được tạo cho tên miền: " + DOMAIN_NAME);
// === 3. Kiểm tra ===
Domain fetchedDomain = client.resources(Domain.class)
.inNamespace(NAMESPACE)
.withName("example-domain")
.get();
System.out.println("Tên miền truy xuất: " + fetchedDomain.getSpec().getDomainName());
} catch (Exception e) {
System.err.println("❌ Lỗi: " + e.getMessage());
e.printStackTrace();
}
}
}
Lưu ý quan trọng
- Mối quan hệ giữa Domain và Route
Route.spec.targetDomainphải bằngDomain.spec.domainName- Nếu không tạo Domain, Higress sẽ dùng lắng nghe chung (không hỗ trợ HTTPS)
- Hỗ trợ HTTPS
- Chỉ kích hoạt HTTPS khi
DomaincócertificateSecrets - Secret phải là kiểu
kubernetes.io/tlsvà nằm trong cùng namespace
- Quy tắc định tuyến
- Đường dẫn phải kết thúc bằng
/(ví dụ:/api/user/) - Hỗ trợ nhiều đường dẫn: một Route có thể định tuyến nhiều đường dẫn về cùng backend
- Quyền RBAC Đảm bảo ServiceAccount của ứng dụng Java có quyền thao tác CRD Higress:
# rbac.yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: higress-manager
rules:
- apiGroups: ["networking.higress.io"]
resources: ["domains", "routes"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: java-app-higress
namespace: default
subjects:
- kind: ServiceAccount
name: default # Hoặc SA tùy chỉnh
namespace: default
roleRef:
kind: Role
name: higress-manager
apiGroup: rbac.authorization.k8s.io
Kiểm tra hiệu quả
- Xem tài nguyên
kubectl get domains -n default
kubectl get routes -n default
- Thử nghiệm truy cập
# HTTP
curl -H "Host: api.example.com" http://<higress-gateway-ip>/api/user/
# HTTPS (cần tin cậy chứng chỉ)
curl -k -H "Host: api.example.com" https://<higress-gateway-ip>/api/user/
Địa chỉ IP gateway Higress lấy từ
kubectl get svc -n higress-system higress-gateway
Dọn dẹp tài nguyên
// Xóa Route
client.resources(Route.class)
.inNamespace(NAMESPACE)
.withName("user-api-route")
.delete();
// Xóa Domain
client.resources(Domain.class)
.inNamespace(NAMESPACE)
.withName("example-domain")
.delete();
Mở rộng cho các tình huống phức tạp
| Yêu cầu | Cách thực hiện |
|---|---|
| **Chuyển hướng HTTP → HTTPS** | Thiết lập redirectEnabled: true trong DomainSpec (yêu cầu Higress v1.3+) |
| **Cấu hình plugin (JWT)** | Thêm trường plugins trong RouteSpec (cần định nghĩa lớp Plugin) |
| **Phát hành từng phần** | Tạo nhiều Route, sử dụng trọng số hoặc header để phân luồng |