watch
k8s很多命令都有watch机制,持续检测状态变化,如pod列表,如果pod状态发生变化,就会输出
kubectl get pod -w 或者--watch
JAVA Cient watch podList
官网介绍:https://kubernetes.io/zh/docs/reference/using-api/api-concepts/#standard-api-terminology
K8sJavaClient官方github有一个watch namespace的例子,https://github.com/kubernetes-client/java/blob/master/examples/examples-release-11/src/main/java/io/kubernetes/client/examples/WatchExample.java
我们改成watchpod列表。watch 命名空间为default、标签为userId=user1Id的pod,将listNamespacedPodCall方法的watch参数设置为true
@BeforeAll
public static void connectK8s() throws IOException {
String kubeConfigPath = "config";
//加载k8s, config
client = ClientBuilder.kubeconfig(KubeConfig.loadKubeConfig(new FileReader(kubeConfigPath))).build();
//设置http的读取超时时间,设置为0永远不超时,但不安全,如果watch的时间大于此时间,则会socket read timeout异常
client.setReadTimeout(20000);
Configuration.setDefaultApiClient(client);
}
@Test
public void watchPod() throws ApiException, InterruptedException, IOException {
System.out.println("重新访问");
CoreV1Api api = new CoreV1Api();
Call call = api.listNamespacedPodCall("default", null, null, null, null,
"userId=user1Id",
null, null, null, true, new ApiCallback() {
public void onFailure(ApiException e, int statusCode, Map responseHeaders) {
System.out.println("fail");
}
public void onSuccess(Object result, int statusCode, Map responseHeaders) {
System.out.println("sucess" + statusCode + result);
}
public void onUploadProgress(long bytesWritten, long contentLength, boolean done) {
System.out.println("upload");
}
public void onDownloadProgress(long bytesRead, long contentLength, boolean done) {
System.out.println("download");
}
});
Watch<V1Pod> watch = Watch.createWatch(
client,
call,
new TypeToken<Watch.Response<V1Pod>>() {
}.getType());
try {
for (Watch.Response<V1Pod> item : watch) {
System.out.printf("%s : %s : %s%n", item.object.getMetadata().getName(), item.type, item.object.getStatus().getPhase());
}
} finally {
watch.close();
}
}
SocketTimeoutException: Read timed out
按官方例子,大概10s后会报出超时异常。
在官方github的Issues中找到答案,这方面中文资料少,要多看官方文档,有问题在github的Issues找也是很好的办法。https://github.com/kubernetes-client/java/issues/287
原因是watch是一直持续,时间超出了httpclient默认的时间。k8sjavaclient发起http调用默认使用的是OkHttpClient,所以在OkHttpClient设置超时时间即可。listNamespacedPodCall方法的timeout参数要小于okhttpclient的超时参数。
@BeforeAll
public static void connectK8s() throws IOException {
String kubeConfigPath = "config";
//加载k8s, config
client = ClientBuilder.kubeconfig(KubeConfig.loadKubeConfig(new FileReader(kubeConfigPath))).build();
//设置http的读取超时时间,设置为0永远不超时,但不安全,如果watch的时间大于此时间,则会socket read timeout异常
client.setReadTimeout(20000);
Configuration.setDefaultApiClient(client);
}
如果设置为0,没有读取超时限制,但k8sgit上的管理员不建议这么做,他认为网络不稳定、建议在循环中watch。其实程序如果没及时关掉连接,导致k8s apiserver浪费很多连接、压力大,所以不应该watch时间太长,并且及时关闭掉watch连接。