Skip to content

Commit 7b71401

Browse files
authored
Merge pull request #38 from renoki-co/feature/daemonset
[feature] DaemonSet
2 parents 12852e1 + 02ed333 commit 7b71401

10 files changed

+636
-5
lines changed

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ Each existent resource has its own documentation, filled with examples.
3434
- [Pod](docs/kinds/Pod.md)
3535
- [Statefulset](docs/kinds/StatefulSet.md)
3636
- [Deployment](docs/kinds/Deployment.md)
37+
- [Daemonset](docs/kinds/DaemonSet.md)
3738
- [Jobs](docs/kinds/Job.md)
3839

3940
For other resources, you can check the [WIP resources](docs/RESOURCES.md)

docs/RESOURCES.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ Before diving in the resource docs, please check [All Resources docs](kinds/Reso
2121
- [Pod](kinds/Pod.md)
2222
- [Statefulset](kinds/StatefulSet.md)
2323
- [Deployment](kinds/Deployment.md)
24+
- [DaemonSet](kinds/DaemonSet.md)
2425
- [Jobs](kinds/Job.md)
2526

2627
# Work in Progress
2728

2829
The following list of resources are work in progress and they will be available soon:
2930

30-
- daemonsets
3131
- horizontalpodautoscalers
3232
- cronjobs
3333
- serviceaccounts

docs/kinds/DaemonSet.md

+147
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
# DaemonSet
2+
3+
- [Official Documentation](https://kubernetes.io/docs/concepts/workloads/controllers/daemonset/)
4+
5+
## Example
6+
7+
### DaemonSet Creation
8+
9+
DaemonSets are just configurations that relies on a Pod. So before diving in, make sure you read the [Pod Documentation](Pod.md)
10+
11+
```php
12+
use RenokiCo\PhpK8s\K8s;
13+
14+
$container = K8s::container()
15+
->setName('mysql')
16+
->setImage('mysql', '5.7')
17+
->setPorts([
18+
['name' => 'mysql', 'protocol' => 'TCP', 'containerPort' => 3306],
19+
]);
20+
21+
$pod = K8s::pod()
22+
->setName('mysql')
23+
->setLabels(['tier' => 'backend'])
24+
->setContainers([$mysql]);
25+
26+
$ds = $this->cluster->daemonSet()
27+
->setName('mysql')
28+
->setLabels(['tier' => 'backend'])
29+
->setUpdateStrategy('RollingUpdate')
30+
->setMinReadySeconds(0)
31+
->setTemplate($pod);
32+
```
33+
34+
DaemonSets supports only labels:
35+
36+
```php
37+
$ds->setLabels([
38+
'matchesLabel' => ['app' => 'backend'],
39+
]);
40+
```
41+
42+
While the DaemonSet kind has `spec`, you can avoid writing this:
43+
44+
```php
45+
$ds->setAttribute('spec.template', [...]);
46+
```
47+
48+
And use the `setSpec()` method:
49+
50+
```php
51+
$ds->setSpec('template', [...]);
52+
```
53+
54+
Dot notation is supported:
55+
56+
```php
57+
$ds->setSpec('some.nested.path', [...]);
58+
```
59+
60+
### Retrieval
61+
62+
```php
63+
$ds->getTemplate();
64+
```
65+
66+
Retrieving the spec attributes can be done like the `setSpec()` method:
67+
68+
```php
69+
$ds->getSpec('template', []);
70+
```
71+
72+
The second value for the `getSpec()` method is the default value, in case the found path is not existent.
73+
74+
Dot notation is supported:
75+
76+
```php
77+
$ds->getSpec('some.nested.path', []);
78+
```
79+
80+
### DaemonSet's Pod Template Retrieval
81+
82+
DaemonSets rely on pods, so you can get the pod template as `K8sPod` class:
83+
84+
```php
85+
$template = $ds->getTemplate();
86+
87+
$podName = $template->getName();
88+
```
89+
90+
To retrieve the pod template as an array, pass `false` to the retrieval method:
91+
92+
```php
93+
$pod = $ds->getTemplate(false);
94+
95+
$podName = $template['name'];
96+
```
97+
98+
### DaemonSet's Pods
99+
100+
You can retrieve the pods as resources controlled by the DaemonSet by issuing `->getPods()`:
101+
102+
```php
103+
foreach ($ds->getPods() as $pod) {
104+
// $pod->logs()
105+
}
106+
```
107+
108+
### Scaling
109+
110+
The Scaling API is available via a `K8sScale` resource:
111+
112+
```php
113+
$scaler = $ds->scaler();
114+
115+
$scaler->setReplicas(3)->update(); // autoscale the DaemonSet to 3 replicas
116+
```
117+
118+
Shorthand, you can use `scale()` directly from the DaemonSet
119+
120+
```php
121+
$scaler = $ds->scale(3);
122+
123+
$pods = $ds->getPods(); // Expecting 3 pods
124+
```
125+
126+
### DaemonSet Status
127+
128+
The Status API is available to be accessed for fresh instances:
129+
130+
```php
131+
$ds->refresh();
132+
133+
$ds->getScheduledCount();
134+
$ds->getMisscheduledCount();
135+
$ds->getNodesCount();
136+
$ds->getDesiredCount();
137+
$ds->getReadyCount();
138+
$ds->getUnavailableClount();
139+
```
140+
141+
You can check if all the pods within the DaemonSet are running:
142+
143+
```php
144+
if ($ds->allPodsAreRunning()) {
145+
//
146+
}
147+
```

src/K8s.php

+12
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,18 @@ public static function job($cluster = null, array $attributes = [])
148148
return new Kinds\K8sJob($cluster, $attributes);
149149
}
150150

151+
/**
152+
* Create a new DaemonSet kind.
153+
*
154+
* @param \RenokiCo\PhpK8s\KubernetesCluster $cluster
155+
* @param array $attributes
156+
* @return \RenokiCo\PhpK8s\Kinds\K8sJob
157+
*/
158+
public static function daemonSet($cluster = null, array $attributes = [])
159+
{
160+
return new Kinds\K8sDaemonSet($cluster, $attributes);
161+
}
162+
151163
/**
152164
* Create a new container instance.
153165
*

src/Kinds/K8sDaemonSet.php

+176
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
<?php
2+
3+
namespace RenokiCo\PhpK8s\Kinds;
4+
5+
use RenokiCo\PhpK8s\Contracts\InteractsWithK8sCluster;
6+
use RenokiCo\PhpK8s\Contracts\Podable;
7+
use RenokiCo\PhpK8s\Contracts\Watchable;
8+
use RenokiCo\PhpK8s\Traits\HasLabels;
9+
use RenokiCo\PhpK8s\Traits\HasMinimumSurge;
10+
use RenokiCo\PhpK8s\Traits\HasPods;
11+
use RenokiCo\PhpK8s\Traits\HasSelector;
12+
use RenokiCo\PhpK8s\Traits\HasSpec;
13+
use RenokiCo\PhpK8s\Traits\HasStatus;
14+
use RenokiCo\PhpK8s\Traits\HasStatusConditions;
15+
use RenokiCo\PhpK8s\Traits\HasTemplate;
16+
17+
class K8sDaemonSet extends K8sResource implements InteractsWithK8sCluster, Podable, Watchable
18+
{
19+
use HasLabels;
20+
use HasMinimumSurge;
21+
use HasPods;
22+
use HasSelector;
23+
use HasSpec;
24+
use HasStatus;
25+
use HasStatusConditions;
26+
use HasTemplate;
27+
28+
/**
29+
* The resource Kind parameter.
30+
*
31+
* @var null|string
32+
*/
33+
protected static $kind = 'DaemonSet';
34+
35+
/**
36+
* The default version for the resource.
37+
*
38+
* @var string
39+
*/
40+
protected static $stableVersion = 'apps/v1';
41+
42+
/**
43+
* Wether the resource has a namespace.
44+
*
45+
* @var bool
46+
*/
47+
protected static $namespaceable = true;
48+
49+
/**
50+
* Set the updating strategy for the set.
51+
*
52+
* @param string $strategy
53+
* @param int $maxUnavailable
54+
* @return $this
55+
*/
56+
public function setUpdateStrategy(string $strategy, int $maxUnavailable = 1)
57+
{
58+
if ($strategy === 'RollingUpdate') {
59+
$this->setSpec('updateStrategy.rollingUpdate.maxUnavailable', $maxUnavailable);
60+
}
61+
62+
return $this->setSpec('updateStrategy.type', $strategy);
63+
}
64+
65+
/**
66+
* Get the path, prefixed by '/', that points to the resources list.
67+
*
68+
* @return string
69+
*/
70+
public function allResourcesPath(): string
71+
{
72+
return "/apis/{$this->getApiVersion()}/namespaces/{$this->getNamespace()}/daemonsets";
73+
}
74+
75+
/**
76+
* Get the path, prefixed by '/', that points to the specific resource.
77+
*
78+
* @return string
79+
*/
80+
public function resourcePath(): string
81+
{
82+
return "/apis/{$this->getApiVersion()}/namespaces/{$this->getNamespace()}/daemonsets/{$this->getIdentifier()}";
83+
}
84+
85+
/**
86+
* Get the path, prefixed by '/', that points to the resource watch.
87+
*
88+
* @return string
89+
*/
90+
public function allResourcesWatchPath(): string
91+
{
92+
return "/apis/{$this->getApiVersion()}/watch/daemonsets";
93+
}
94+
95+
/**
96+
* Get the path, prefixed by '/', that points to the specific resource to watch.
97+
*
98+
* @return string
99+
*/
100+
public function resourceWatchPath(): string
101+
{
102+
return "/apis/{$this->getApiVersion()}/watch/namespaces/{$this->getNamespace()}/daemonsets/{$this->getIdentifier()}";
103+
}
104+
105+
/**
106+
* Get the selector for the pods that are owned by this resource.
107+
*
108+
* @return array
109+
*/
110+
public function podsSelector(): array
111+
{
112+
return [
113+
'daemonset-name' => $this->getName(),
114+
];
115+
}
116+
117+
/**
118+
* Get the number of scheduled nodes that run the DaemonSet.
119+
*
120+
* @return int
121+
*/
122+
public function getScheduledCount(): int
123+
{
124+
return $this->getStatus('currentNumberScheduled', 0);
125+
}
126+
127+
/**
128+
* Get the number of scheduled nodes that should not run the DaemonSet.
129+
*
130+
* @return int
131+
*/
132+
public function getMisscheduledCount(): int
133+
{
134+
return $this->getStatus('numberMisscheduled', 0);
135+
}
136+
137+
/**
138+
* Get the number of total nodes that should run the DaemonSet.
139+
*
140+
* @return int
141+
*/
142+
public function getNodesCount(): int
143+
{
144+
return $this->getStatus('numberAvailable', 0);
145+
}
146+
147+
/**
148+
* Get the total desired nodes that run the DaemonSet.
149+
*
150+
* @return int
151+
*/
152+
public function getDesiredCount(): int
153+
{
154+
return $this->getStatus('desiredNumberScheduled', 0);
155+
}
156+
157+
/**
158+
* Get the total nodes that are running the DaemonSet.
159+
*
160+
* @return int
161+
*/
162+
public function getReadyCount(): int
163+
{
164+
return $this->getStatus('numberReady', 0);
165+
}
166+
167+
/**
168+
* Get the total nodes that are unavailable to process the DaemonSet.
169+
*
170+
* @return int
171+
*/
172+
public function getUnavailableClount(): int
173+
{
174+
return $this->getStatus('numberUnavailable', 0);
175+
}
176+
}

src/Kinds/K8sScale.php

+26
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,30 @@ public function setScalableResource(K8sResource $resource)
7171

7272
return $this;
7373
}
74+
75+
/**
76+
* Make a call to the cluster to get a fresh instance.
77+
*
78+
* @param array $query
79+
* @return $this
80+
*/
81+
public function refresh(array $query = ['pretty' => 1])
82+
{
83+
$this->resource->refresh($query);
84+
85+
return $this->syncWith($this->get($query)->toArray());
86+
}
87+
88+
/**
89+
* Make a call to teh cluster to get fresh original values.
90+
*
91+
* @param array $query
92+
* @return $this
93+
*/
94+
public function refreshOriginal(array $query = ['pretty' => 1])
95+
{
96+
$this->resource->refreshOriginal($query);
97+
98+
return $this->syncOriginalWith($this->get($query)->toArray());
99+
}
74100
}

0 commit comments

Comments
 (0)