Skip to content

Commit e104272

Browse files
committed
doc: introducing kubectl equivalence
1 parent 8180143 commit e104272

File tree

1 file changed

+235
-7
lines changed

1 file changed

+235
-7
lines changed

docs/kubectl-equivalence-in-java.md

Lines changed: 235 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,246 @@
11
#Kubectl Equivalence in Java
22

3-
__TL;DR__: Get used to kubectl? Now the kubernetes Java client library has releases a set of
4-
helpful client utilities which has the similar input argument interface as the kubectl binary
5-
does. Especially the developers who're already familiar with kubectl commands, after reading
6-
this document, you will know how to program to operate kubernetes as neat as kubectl.
3+
__TL;DR__: Get used to kubectl? Now our kubernetes Java client library has releases a set of
4+
helpful client utilities which has the similar input argument interface as the kubectl binary.
5+
Especially the developers who're already familiar with kubectl commands, after reading this
6+
document, you will know how to program to operate kubernetes as neat as kubectl.
77

88

9-
### Kubectl vs Direct HTTP client
9+
### What is Java Kubectl
1010

11+
The Java Kubectl is not only a more user-friendly wrapper for our direct HTTP kubernetes client,
12+
but also contains implementation of commonly-used kubectl advanced commands. All these kubectl
13+
equivalences are accessible as a group of static helper functions under `io.kubernetes.client.extended.kubectl.Kubectl`
14+
class. You can import them by adding the following dependency to your project:
1115

12-
### Difference between kubectl commands and direct
16+
```xml
17+
<dependency>
18+
<groupId>io.kubernetes</groupId>
19+
<artifactId>client-java-extended</artifactId>
20+
<version>${latest project version}</version>
21+
</dependency>
22+
```
1323

24+
Now you're all set, invoke the kubectl commands as Java static functions wherever you like in
25+
your project.
26+
27+
#### (Optional) Setting a Global Client-Config
28+
29+
Kubectl static helpers doesn't know its client-config (or kubeconfig if the name makes more sense to
30+
you) unless you set it when your application starts. You can either specifies the client-config upon
31+
invoking kubectl helpers or simply set a global config at the start of your application:
32+
33+
```java
34+
Configuration.setDefaultApiClient(ClientBuilder.defaultClient());
35+
```
1436

1537
### Manifest of Supported Commands
1638

1739

18-
#### Kubectl get
40+
#### Kubectl get
41+
42+
You can either query single resource or list multiple resources using the `Kubectl#get` helper depending
43+
on whether you're passing `name()` in the flow. Here is a few illustrative examples for querying pod
44+
resources:
45+
46+
```java
47+
// kubectl get -n default pod foo
48+
V1Pod pod = Kubectl.get(V1Pod.class)
49+
.namespace("default")
50+
.name("foo")
51+
.execute();
52+
// kubectl get -n default pod
53+
List<V1Pod> pods = Kubectl.get(V1Pod.class)
54+
.namespace("default")
55+
.execute();
56+
// kubectl get pod --all-namespaces
57+
List<V1Pod> pods = Kubectl.get(V1Pod.class)
58+
.execute();
59+
```
60+
61+
#### Kubectl create
62+
63+
Currently the `Kubectl#create` helper only accepts a desired instance of resource object, you need to do the
64+
deserialization from the source or manually craft an instance of the resource.
65+
66+
```java
67+
// kubectl create -f <file>
68+
V1Pod creatingPod = /* load it from file or else */;
69+
V1Pod createdPod = Kubectl.create(V1Pod.class)
70+
.resource(creatingPod)
71+
.execute();
72+
```
73+
74+
#### Kubectl delete
75+
76+
`Kubectl#delete` works the same as `kubectl delete` command.
77+
78+
```java
79+
// kubectl delete -n default pod foo
80+
V1Pod deletedPod = Kubectl.delete(V1Pod.class)
81+
.namespace("default")
82+
.name("foo")
83+
.execute();
84+
```
85+
86+
#### Kubectl patch
87+
88+
`Kubectl#patch` works the same as `kubectl patch` command.
89+
90+
```java
91+
// kubectl patch --type='strategic' --patch="{\"metadata\":{\"labels\":{\"foo\":\"bar\"}}"
92+
V1Pod patchedPod = Kubectl.patch(V1Pod.class)
93+
.patchType(V1Patch.PATCH_FORMAT_STRATEGIC_MERGE_PATCH)
94+
.patchContent(new V1Patch("{\"metadata\":{\"labels\":{\"foo\":\"bar\"}}"))
95+
.execute();
96+
```
97+
98+
#### Kubectl apply
99+
100+
Note that for now only server-side apply supported, so your apiserver version is required to
101+
be greater than 1.18.0. `Kubectl#apply` works the same as `kubectl apply --server-side=true`.
102+
103+
```java
104+
// kubectl apply --server-side=true --field-manager=java-kubectl --force-conflict=true -f <file>
105+
V1Pod applyingPod = /* load it from file or else */;
106+
V1Pod appliedPod = Kubectl.apply(V1Pod.class)
107+
.fieldManager("java-kubectl")
108+
.forceConflict(true)
109+
.resource(applyingPod)
110+
.execute();
111+
```
112+
113+
#### Kubectl scale
114+
115+
```java
116+
// kubectl scale -n default rs foo --replicas=2
117+
V1ReplicaSet scaledRs = Kubectl.scale(V1ReplicaSet.class)
118+
.namespace("default")
119+
.name("foo")
120+
.replicas(2)
121+
.execute();
122+
```
123+
124+
125+
#### Kubectl drain
126+
127+
```java
128+
// kubectl drain node1
129+
V1Node drainedNode = Kubectl.drain()
130+
.name("node1")
131+
.execute();
132+
```
133+
134+
135+
#### Kubectl cordon/uncordon
136+
137+
```java
138+
// kubectl cordon node1
139+
V1Node cordondNode = Kubectl.cordon()
140+
.name("node1")
141+
.execute();
142+
// kubectl uncordon node1
143+
V1Node uncordondNode = Kubectl.uncordon()
144+
.name("node1")
145+
.execute();
146+
```
147+
148+
#### Kubectl taint
149+
150+
```java
151+
// kubectl taint nodes foo dedicated:NoSchedule
152+
V1Node taintedNode = Kubectl.taint()
153+
.addTaint("dedicated", "NoSchedule")
154+
.execute()
155+
// kubectl taint nodes foo dedicated=special-user:NoSchedule
156+
V1Node taintedNode = Kubectl.taint()
157+
.addTaint("dedicated", "special-user", "NoSchedule")
158+
.execute()
159+
// kubectl taint nodes foo dedicated:NoSchedule-
160+
V1Node taintedNode = Kubectl.taint()
161+
.removeTaint("dedicated", "NoSchedule")
162+
.execute()
163+
```
164+
165+
166+
167+
#### Kubectl label/annotate
168+
169+
```java
170+
// kubectl label -n default pod foo key1=value1 key2=value2
171+
V1Pod labelledPod = Kubectl.label(V1Pod)
172+
.addLabel("key1", "value1")
173+
.addLabel("key2", "value2")
174+
.namespace("default")
175+
.name("foo")
176+
.execute();
177+
// kubectl annotate -n default pod foo key1=value1 key2=value2
178+
V1Pod annotatedPod = Kubectl.annotate(V1Pod)
179+
.addLabel("key1", "value1")
180+
.addLabel("key2", "value2")
181+
.namespace("default")
182+
.name("foo")
183+
.execute();
184+
```
185+
186+
#### Kubectl api-resources
187+
188+
```java
189+
// kubectl api-resources
190+
Set<Discovery.APIResource> apiResourceSet = Kubectl.apiResources()
191+
.execute()
192+
```
193+
194+
#### Kubectl exec
195+
196+
```java
197+
// kubectl exec -n default foo -c test-container echo test
198+
int retCode = Kubectl.exec()
199+
.namespace("default")
200+
.name("foo")
201+
.container("test-container")
202+
.command(new String[]{"echo","test"})
203+
.execute();
204+
```
205+
206+
207+
#### Kubectl logs
208+
209+
```java
210+
// kubectl logs -n default foo -c test-container
211+
InputStream logStream = Kubectl.log()
212+
.namespace("default")
213+
.name("foo")
214+
.container("test-container")
215+
.execute();
216+
```
217+
218+
#### Kubectl top
219+
220+
```java
221+
// kubectl top node
222+
List<Pair<V1Node, NodeMetrics>> metrics = Kubectl.top(V1Node.class, NodeMetrics.class)
223+
.metric("cpu")
224+
.execute();
225+
```
226+
227+
### Advanced Tips
228+
229+
#### API Discovery for custom models
230+
231+
Kubernetes allows you to extend new kubernetes API types by either [CustomResourceDefinition](https://kubernetes.io/docs/tasks/extend-kubernetes/custom-resources/custom-resource-definitions/)
232+
or [APIServerAggregation](https://kubernetes.io/docs/tasks/extend-kubernetes/setup-extension-api-server/),
233+
and api-discovery is basically a process of discovering new kubernetes resources types from the client-side.
234+
The java client is managing all the api-discovery information at `io.kubernetes.client.util.ModelMapper`.
235+
In order to make the java client know the connection between new kubernetes api and custom Java models, you're
236+
supposed to manually set up the mappings for them by:
237+
238+
```java
239+
ModelMapper.addModelMap(
240+
"example.io", // api-group
241+
"v1", // api-version
242+
"Foo", // kind name -- camel-case'd singular resource name.
243+
"foos", // resource name -- lowercase plural resource name
244+
true, // is namespace-scoped
245+
Foo.class); // java model class
246+
```

0 commit comments

Comments
 (0)