Skip to content
This repository has been archived by the owner on Mar 26, 2024. It is now read-only.

Commit

Permalink
build: initilization the project
Browse files Browse the repository at this point in the history
issue #1
  • Loading branch information
smhmayboudi committed Jan 14, 2024
1 parent fa92fc9 commit 8902afa
Show file tree
Hide file tree
Showing 40 changed files with 5,199 additions and 0 deletions.
211 changes: 211 additions & 0 deletions .doc/1-objects-in-kubernetes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
# Objects In Kubernetes

## Reference

https://kubernetes.io/docs/concepts/overview/working-with-objects/

## Kubernetes Object Management

```shell
kubectl create deployment nginx --image nginx
kubectl create -f nginx.yaml # create a object
kubectl delete -f nginx.yaml -f redis.yaml # delete a object
kubectl replace -f nginx.yaml # update a object
kubectl diff -f configs/ && kubectl apply -f configs/ # make a patch & apply it
```

## Object Names and IDs

```yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-demo # RFC1123 & RFC1035(start with char), len(name) <= 63
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
```
## Labels and Selectors
```yaml
apiVersion: v1
kind: Pod
metadata:
name: label-demo
labels:
environment: production # [a-z0-9A-Z], (-, _, .), len(key) <= 63
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
```
> Note: For some API types, such as ReplicaSets, the label selectors of two instances must not overlap within a namespace, or the controller can see that as conflicting instructions and fail to determine how many replicas should be present.
> Caution: For both equality-based and set-based conditions there is no logical OR (||) operator. Ensure your filter statements are structured accordingly.
```yaml
apiVersion: v1
kind: Pod
metadata:
name: cuda-test
spec:
containers:
- name: cuda-test
image: "registry.k8s.io/cuda-vector-add:v0.1"
resources:
limits:
nvidia.com/gpu: 1
nodeSelector:
accelerator: nvidia-tesla-p100 # accelerator==nvidia-tesla-p100, in,notin and exists
```
```yaml
labelSelector=environment%3Dproduction,tier%3Dfrontend
```

```shell
kubectl get pods -l environment=production,tier=frontend
```

```yaml
?labelSelector=environment+in+%28production%2Cqa%29%2Ctier+in+%28frontend%29
```

```shell
kubectl get pods -l 'environment in (production),tier in (frontend)'
```

examples: https://github.com/kubernetes/examples/tree/master/guestbook/

```shell
kubectl label pods -l app=nginx tier=fe # select all ngnix and add tier to fe
kubectl get pods -l app=nginx -L tier # (--label-columns) to see it
```

## Namespaces

- default
- kube-node-lease: [Lease](https://kubernetes.io/docs/concepts/architecture/leases/) Objects to send [heartbeats](https://kubernetes.io/docs/concepts/architecture/nodes/#heartbeats)
- kube-public
- kube-system

```shell
kubectl get namespace
```

DNS: <service-name>.<namespace-name>.svc.cluster.local

> By creating namespaces with the same name as [public top-level domains](https://data.iana.org/TLD/tlds-alpha-by-domain.txt), Services in these namespaces can have short DNS names that overlap with public DNS records. Workloads from any namespace performing a DNS lookup without a [trailing dot](https://datatracker.ietf.org/doc/html/rfc1034#page-8) will be redirected to those services, taking precedence over public DNS.
To mitigate this, limit privileges for creating namespaces to trusted users. If required, you could additionally configure third-party security controls, such as [admission webhooks](https://kubernetes.io/docs/reference/access-authn-authz/extensible-admission-controllers/), to block creating any namespace with the name of [public TLDs](https://data.iana.org/TLD/tlds-alpha-by-domain.txt).

namespace resources are not themselves in a namespace. And low-level resources, such as [nodes](https://kubernetes.io/docs/concepts/architecture/nodes/) and [persistentVolumes](https://kubernetes.io/docs/concepts/storage/persistent-volumes/), are not in any namespace.
```shell
kubectl api-resources --namespaced=true # in a namespace
kubectl api-resources --namespaced=false # not in a namespace
```

`kubernetes.io/metadata.name` is atomic labelling which is set by the control plane.

## Annotations

You can use Kubernetes annotations to attach arbitrary non-identifying metadata to [objects](https://kubernetes.io/docs/concepts/overview/working-with-objects/#kubernetes-objects). Clients such as tools and libraries can retrieve this metadata.

```yaml
apiVersion: v1
kind: Pod
metadata:
name: annotations-demo
annotations:
imageregistry: "https://hub.docker.com/" # it shows the imageregistry
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
```
# Field Selectors
```shell
kubectl get pods --field-selector metadata.name=my-service
kubectl get pods --field-selector metadata.namespace!=default
kubectl get pods --field-selector status.phase=Pending
```

```shell
kubectl get pods,statefulsets,services --all-namespaces --field-selector=status.phase!=Running,spec.restartPolicy=Always
```

# Finalizers

Finalizers are namespaced keys that tell Kubernetes to wait until specific conditions are met before it fully deletes resources marked for deletion. Finalizers alert controllers to clean up resources the deleted object owned.

When you tell Kubernetes to delete an object that has finalizers specified for it, the Kubernetes API marks the object for deletion by populating `.metadata.deletionTimestamp`, and returns a 202 status code (HTTP "Accepted"). The target object remains in a terminating state while the control plane, or other components, take the actions defined by the finalizers. After these actions are complete, the controller removes the relevant finalizers from the target object. When the `metadata.finalizers` field is empty, Kubernetes considers the deletion complete and deletes the object.

> When you DELETE an object, Kubernetes adds the deletion timestamp for that object and then immediately starts to restrict changes to the .metadata.finalizers field for the object that is now pending deletion. You can remove existing finalizers (deleting an entry from the finalizers list) but you cannot add a new finalizer. You also cannot modify the deletionTimestamp for an object once it is set.
After the deletion is requested, you can not resurrect this object. The only way is to delete it and make a new similar object.

> Note: In cases where objects are stuck in a deleting state, avoid manually removing finalizers to allow deletion to continue. Finalizers are usually added to resources for a reason, so forcefully removing them can lead to issues in your cluster. This should only be done when the purpose of the finalizer is understood and is accomplished in another way (for example, manually cleaning up some dependent object).
# Owners and Dependents

A valid owner reference (`metadata.ownerReferences`) consists of the object name and a UID within the same namespace as the dependent object.
`ownerReferences.blockOwnerDeletion`

> Note: Cross-namespace owner references are disallowed by design. Namespaced dependents can specify cluster-scoped or namespaced owners. A namespaced owner must exist in the same namespace as the dependent. If it does not, the owner reference is treated as absent, and the dependent is subject to deletion once all owners are verified absent.
Cluster-scoped dependents can only specify cluster-scoped owners. In v1.20+, if a cluster-scoped dependent specifies a namespaced kind as an owner, it is treated as having an unresolvable owner reference, and is not able to be garbage collected.
In v1.20+, if the garbage collector detects an invalid cross-namespace ownerReference, or a cluster-scoped dependent with an ownerReference referencing a namespaced kind, a warning Event with a reason of OwnerRefInvalidNamespace and an involvedObject of the invalid dependent is reported. You can check for that kind of Event by running `kubectl get events -A --field-selector=reason=OwnerRefInvalidNamespace`.

# Recommended Labels

Shared labels and annotations share a common prefix: `app.kubernetes.io`. Labels without a prefix are private to users. The shared prefix ensures that shared labels do not interfere with custom user labels.

```yaml
# This is an excerpt StatefulSet object
apiVersion: apps/v1
kind: StatefulSet
metadata:
labels:
app.kubernetes.io/name: mysql
app.kubernetes.io/instance: mysql-abcxzy # every instance of an application must have a unique name.
app.kubernetes.io/version: "5.7.21"
app.kubernetes.io/component: database
app.kubernetes.io/part-of: wordpress
app.kubernetes.io/managed-by: helm
```
```yaml
# This is an excerpt Deployment object, to oversee the pods running the application itself
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/name: wordpress
app.kubernetes.io/instance: wordpress-abcxzy # every instance of an application must have a unique name.
app.kubernetes.io/version: "4.9.4"
app.kubernetes.io/component: server
app.kubernetes.io/part-of: wordpress
app.kubernetes.io/managed-by: helm
```
```yaml
# This is an excerpt Service object, to expose the application
apiVersion: apps/v1
kind: Service
metadata:
labels:
app.kubernetes.io/name: wordpress
app.kubernetes.io/instance: wordpress-abcxzy # every instance of an application must have a unique name.
app.kubernetes.io/version: "4.9.4"
app.kubernetes.io/component: server
app.kubernetes.io/part-of: wordpress
app.kubernetes.io/managed-by: helm
```
23 changes: 23 additions & 0 deletions .doc/2-controller.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Controller

## Reference

https://kubernetes.io/docs/concepts/architecture/controller/

In robotics and automation, a control loop is a non-terminating loop that regulates the state of a system.

LOOP
Current State => Job Controller (via Calling API Server) => Desired State

> Note: There can be several controllers that create or update the same kind of object. Behind the scenes, Kubernetes controllers make sure that they only pay attention to the resources linked to their controlling resource.
For example, you can have Deployments and Jobs; these both create Pods. The Job controller does not delete the Pods that your Deployment created, because there is information (labels) the controllers can use to tell those Pods apart.

Kubernetes comes with a set of built-in controllers that run inside the kube-controller-manager. These built-in controllers provide important core behaviors.

The Deployment controller and Job controller are examples of controllers that come as part of Kubernetes itself ("built-in" controllers). Kubernetes lets you run a resilient control plane, so that if any of the built-in controllers were to fail, another part of the control plane will take over the work.

The most common way to deploy an operator is to add the Custom Resource Definition and its associated Controller to your cluster. The Controller will normally run outside of the control plane, much as you would run any containerized application. For example, you can run the controller in your cluster as a Deployment.

> Note: This section links to third party projects that provide functionality required by Kubernetes. The Kubernetes project authors aren't responsible for these projects, which are listed alphabetically. To add a project to this list, read the [content guide](https://kubernetes.io/docs/contribute/style/content-guide/#third-party-content) before submitting a change. [More information](https://kubernetes.io/docs/concepts/extend-kubernetes/operator/#third-party-content-disclaimer).
> Note: [Operator SDK](https://github.com/operator-framework/operator-sdk/blob/v1.33.0/) uses the [kubebuilder](https://github.com/kubernetes-sigs/kubebuilder/tree/v3.12.0) plugin feature to include non-Go operators e.g. operator-sdk's Ansible and Helm-based language Operators. To learn more see [how to create your own plugins](https://book.kubebuilder.io/plugins/creating-plugins.html).
10 changes: 10 additions & 0 deletions .doc/3-operator.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Operator

## Reference

https://kubernetes.io/docs/concepts/extend-kubernetes/operator/

Operators are software extensions to Kubernetes that make use of [custom resources](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/) to manage applications and their components. Operators follow Kubernetes principles, notably the control loop.

Kubernetes' operator pattern concept lets you extend the cluster's behaviour without modifying the code of Kubernetes itself by linking controllers to one or more custom resources. Operators are clients of the Kubernetes API that act as controllers for a [Custom Resource](https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/).

11 changes: 11 additions & 0 deletions .doc/4-installation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Installation

## Reference

https://sdk.operatorframework.io/docs/installation/

## Installation

```shell
brew install operator-sdk
```
85 changes: 85 additions & 0 deletions .doc/5-tutorial.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Tutorial

## Reference

https://sdk.operatorframework.io/docs/building-operators/golang/tutorial/

```shell
mkdir -p $HOME/Developer/custom-kubernetes-controller
cd $HOME/Developer/custom-kubernetes-controller
# we'll use a domain of smhmayboudi.github.io
# so all API groups will be <group>.smhmayboudi.github.io
operator-sdk init --domain=smhmayboudi.github.io --repo=github.com/smhmayboudi/custom-kubernetes-controller
```

### MacOS

https://kubebuilder.io/plugins/available-plugins

```shell
mkdir -p $HOME/Developer/custom-kubernetes-controller
cd $HOME/Developer/custom-kubernetes-controller
# we'll use a domain of smhmayboudi.github.io
# so all API groups will be <group>.smhmayboudi.github.io
operator-sdk init --domain=smhmayboudi.github.io --repo=github.com/smhmayboudi/custom-kubernetes-controller --plugins=go/v4
```

## Manager

https://book.kubebuilder.io/cronjob-tutorial/empty-main.html

https://sdk.operatorframework.io/docs/building-operators/golang/operator-scope/

## Question

https://book.kubebuilder.io/cronjob-tutorial/empty-main.html

```go
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
Scheme: scheme,
Cache: cache.Options{
DefaultNamespaces: map[string]cache.Config{
namespace: {},
},
},
Metrics: server.Options{
BindAddress: metricsAddr,
},
WebhookServer: webhook.NewServer(webhook.Options{Port: 9443}),
HealthProbeBindAddress: probeAddr,
LeaderElection: enableLeaderElection,
LeaderElectionID: "80807133.tutorial.kubebuilder.io",
})
```

The above example will change the scope of your project to a single Namespace. In this scenario, it is also suggested to restrict the provided authorization to this namespace by replacing the default ClusterRole and ClusterRoleBinding to Role and RoleBinding respectively. For further information see the Kubernetes documentation about Using [RBAC Authorization](https://kubernetes.io/docs/reference/access-authn-authz/rbac/).


```go
var namespaces []string // List of Namespaces
defaultNamespaces := make(map[string]cache.Config)

for _, ns := range namespaces {
defaultNamespaces[ns] = cache.Config{}
}

mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
Scheme: scheme,
Cache: cache.Options{
DefaultNamespaces: defaultNamespaces,
},
Metrics: server.Options{
BindAddress: metricsAddr,
},
WebhookServer: webhook.NewServer(webhook.Options{Port: 9443}),
HealthProbeBindAddress: probeAddr,
LeaderElection: enableLeaderElection,
LeaderElectionID: "80807133.tutorial.kubebuilder.io",
})
```

Also, it is possible to use the [DefaultNamespaces](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/cache#Options) from cache.Options{} to cache objects in a specific set of namespaces. For further information see [cache.Options{}](https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/cache#Options)

```shell
operator-sdk create api --group=cache --version=v1alpha1 --kind=Memcached --resource --controller
```
7 changes: 7 additions & 0 deletions .doc/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# References

1. https://kubernetes.io/docs/concepts/overview/working-with-objects/
2. https://kubernetes.io/docs/concepts/architecture/controller/
3. https://kubernetes.io/docs/concepts/extend-kubernetes/operator/
4. https://sdk.operatorframework.io/docs/installation/
5. https://sdk.operatorframework.io/docs/building-operators/golang/tutorial/
3 changes: 3 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# More info: https://docs.docker.com/engine/reference/builder/#dockerignore-file
# Ignore build and test binaries.
bin/
26 changes: 26 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@

# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib
bin/*
Dockerfile.cross

# Test binary, build with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Kubernetes Generated files - skip generated files, except for vendored files

!vendor/**/zz_generated.*

# editor and IDE paraphernalia
.idea
.vscode
*.swp
*.swo
*~
Loading

0 comments on commit 8902afa

Please sign in to comment.