Skip to content

Commit 64fc7af

Browse files
authored
Merge pull request #155 from hasbro17/haseeb/replace-readme-for-0.0.2
*: move readme and user-guide for 0.0.2
2 parents 5d024ca + 4ace7b2 commit 64fc7af

File tree

3 files changed

+36
-368
lines changed

3 files changed

+36
-368
lines changed

README.md

Lines changed: 34 additions & 293 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,11 @@
44

55
The project is currently pre-alpha and it is expected that breaking changes to the API will be made in the upcoming releases.
66

7-
See the [design docs][design_docs] for planned work on upcoming milestones:
8-
- [Query API](doc/design/milestone-0.0.2/query-api.md)
9-
- [Action API](doc/design/milestone-0.0.2/action-api.md)
7+
See the [design docs][design_docs] for planned work on upcoming milestones.
108

119
## Overview
1210

13-
[Operators][operator_link] make it easy to manage complex stateful applications on top of Kubernetes. However writing an operator today can be a significant effort that involves challenges like using low level APIs, writing boilerplate, and a lack of modularity which leads to duplication.
11+
[Operators][operator_link] make it easy to manage complex stateful applications on top of Kubernetes. However writing an operator today can be difficult because of challenges such as using low level APIs, writing boilerplate, and a lack of modularity which leads to duplication.
1412

1513
The Operator SDK is a framework designed to make writing operators easier by providing:
1614
- High level APIs and abstractions to write the operational logic more intuitively
@@ -26,307 +24,50 @@ The SDK provides the following workflow to develop a new operator:
2624
4. Define the operator reconciling logic in a designated handler and use the SDK API to interact with resources
2725
5. Use the SDK CLI to build and generate the operator deployment manifests
2826

29-
At a high level the architecture of an operator using the SDK looks as shown below. The operator processes events for watched resources in a user defined handler and takes actions to reconcile the state of the application.
27+
At a high level an operator using the SDK processes events for watched resources in a user defined handler and takes actions to reconcile the state of the application.
3028

31-
<p align="center">
32-
<img src="doc/images/architecture.png" width="400" height="400" />
33-
</p>
29+
## Quick Start
3430

35-
# Getting Started
31+
First, checkout and install the operator-sdk CLI:
3632

37-
This guide is designed for beginners who want to start an operator project from scratch.
38-
39-
## Guide prerequisites
40-
41-
Before creating any project, this guide has the following prerequisites:
42-
43-
- [dep][dep_tool] version v0.4.1+.
44-
- [go][go_tool] version v1.10+.
45-
- [docker][docker_tool] version 17.03+.
46-
This guide uses image repository `quay.io/example/memcached-operator` as an example.
47-
- [kubectl][kubectl_tool] version v1.9.0+.
48-
- (optional) [minikube][minikube_tool] version v0.25.0+.
49-
This guide uses minikube as a quickstart Kubernetes playground. Run the command:
50-
```
51-
minikube start
52-
```
53-
This will start minikube in the background and set up kubectl configuration accordingly.
54-
55-
## Installing Operator SDK CLI
56-
57-
The Operator SDK comes with a CLI tool that manages the development lifecycle. It helps create the project scaffolding, preprocess custom resource API to generate Kubernetes related code, and generate deployment scripts.
58-
59-
Checkout the desired release tag and install the SDK CLI tool:
60-
```
61-
git checkout tags/v0.0.1
62-
go install github.com/coreos/operator-sdk/commands/operator-sdk
63-
```
64-
65-
This will install the CLI binary `operator-sdk` at `$GOPATH/bin`.
66-
67-
## Creating a new project
68-
69-
Navigate to `$GOPATH/src/github.com/example-inc/`.
70-
71-
Use the `new` command to create a new operator project:
72-
73-
```
74-
operator-sdk new memcached-operator --api-version=cache.example.com/v1alpha1 --kind=Memcached
75-
```
76-
77-
This creates the project directory `memcached-operator` and generates the API pkg tree for a custom resource with APIVersion `cache.example.com/v1apha1` and Kind `Memcached`.
78-
79-
Navigate to the project folder:
80-
81-
```
82-
cd memcached-operator
83-
```
84-
85-
More details about the project directory structure can be found in the [project layout][scaffold_doc] doc.
86-
87-
## Up and running
88-
89-
At this point we are ready to build and run a functional operator.
90-
91-
The default operator behaviour defined in the entry point `cmd/memcached-operator/main.go` is to watch for Deployments in the default namespace and print out their names.
92-
93-
> Note: This example watches Deployments for the APIVersion `apps/v1` which is only present in k8s versions 1.9+. So for k8s versions < 1.9 change the APIVersion to something that is supported e.g `apps/v1beta1`.
94-
95-
To see it, first build the memcached-operator container and then push it to a public registry:
96-
97-
```
98-
operator-sdk build quay.io/example/memcached-operator:v0.0.1
99-
docker push quay.io/example/memcached-operator:v0.0.1
33+
```sh
34+
$ git checkout tags/v0.0.2
35+
$ go install github.com/coreos/operator-sdk/commands/operator-sdk
10036
```
10137

102-
Kubernetes deployment manifests are generated in `deploy/operator.yaml`. The deployment image is set to the container image specified above.
103-
104-
Deploy the memcached-operator:
105-
106-
```
107-
kubectl create -f deploy/rbac.yaml
108-
kubectl create -f deploy/operator.yaml
109-
```
38+
Create and deploy an app-operator using the SDK CLI:
11039

111-
Verify that the memcached-operator is up and running:
40+
```sh
41+
# Create an app-operator project that defines the App CR.
42+
$ cd $GOPATH/src/github.com/example-inc/
43+
$ operator-sdk new app-operator --api-version=app.example.com/v1alpha1 --kind=App
44+
$ cd app-operator
11245

113-
```
114-
$ kubectl get deploy
115-
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
116-
memcached-operator 1 1 1 1 1m
117-
```
46+
# Build and push the app-operator image to a public registry such as quay.io
47+
$ operator-sdk build quay.io/example/app-operator
48+
$ docker push quay.io/example/app-operator
11849

119-
Check the memcached-operator pod’s log:
50+
# Deploy the app-operator
51+
$ kubectl create -f deploy/rbac.yaml
52+
$ kubectl create -f deploy/operator.yaml
12053

121-
```
122-
$ kubectl get pod | grep memcached-operator | cut -d' ' -f1 | xargs kubectl logs
123-
Received Deployment: memcached-operator
124-
```
54+
# By default, creating a custom resource (App) triggers the app-operator to deploy a busybox pod
55+
$ kubectl create -f deploy/cr.yaml
12556

126-
Clean up resources:
57+
# Verify that the busybox pod is created
58+
$ kubectl get pod -l app=busy-box
59+
NAME READY STATUS RESTARTS AGE
60+
busy-box 1/1 Running 0 50s
12761

62+
# Cleanup
63+
$ kubectl delete -f deploy/cr.yaml
64+
$ kubectl delete -f deploy/operator.yaml
65+
$ kubectl delete -f deploy/rbac.yaml
12866
```
129-
kubectl delete -f deploy/operator.yaml
130-
```
131-
132-
This is a basic test that verifies everything works correctly. Next we are going to write the business logic and do something more interesting.
133-
134-
135-
## Customizing operator logic
136-
137-
An operator is used to extend the kube-API and codify application domain knowledge. Operator SDK is designed to provide non-Kubernetes developers an easy way to write the business logic.
13867

139-
In the following steps we are adding a custom resource `Memcached`, and customizing the operator logic that creating a new Memcached CR will create a Memcached Deployment and (optional) Service.
68+
To learn more about the operator-sdk, see the [user guide][guide].
14069

141-
In `pkg/apis/cache/v1alpha1/types.go`, add to `MemcachedSpec` a new field `WithService`:
142-
143-
```Go
144-
type MemcachedSpec struct {
145-
WithService bool `json:"withService"`
146-
}
147-
```
148-
149-
Re-render the generated code for custom resource:
150-
151-
```
152-
operator-sdk generate k8s
153-
```
154-
155-
In `cmd/memcached-operator/main.go`, modify `sdk.Watch` to watch on `Memcached` custom resource:
156-
157-
```Go
158-
func main() {
159-
sdk.Watch("cache.example.com/v1alpha1", "Memcached", "default")
160-
sdk.Handle(stub.NewHandler())
161-
sdk.Run(context.TODO())
162-
}
163-
```
164-
165-
In `pkg/stub/handler.go`, modify `Handle()` to create a `Memcached` Deployment and an (optional) Service:
166-
167-
```Go
168-
import (
169-
v1alpha1 "github.com/example-inc/memcached-operator/pkg/apis/cache/v1alpha1"
170-
171-
"github.com/coreos/operator-sdk/pkg/sdk/action"
172-
"github.com/coreos/operator-sdk/pkg/sdk/handler"
173-
"github.com/coreos/operator-sdk/pkg/sdk/types"
174-
"github.com/sirupsen/logrus"
175-
appsv1 "k8s.io/api/apps/v1"
176-
"k8s.io/api/core/v1"
177-
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
178-
)
179-
180-
func (h *Handler) Handle(ctx types.Context, event types.Event) []types.Action {
181-
var actions []types.Action
182-
switch obj := event.Object.(type) {
183-
case *v1alpha1.Memcached:
184-
logrus.Infof("Received Memcached: %v", obj.Name)
185-
ls := map[string]string{
186-
"app": "memcached",
187-
"name": obj.Name,
188-
}
189-
ns := "default"
190-
d := &appsv1.Deployment{
191-
TypeMeta: metav1.TypeMeta{
192-
APIVersion: "apps/v1",
193-
Kind: "Deployment",
194-
},
195-
ObjectMeta: metav1.ObjectMeta{
196-
Name: obj.Name,
197-
Namespace: ns,
198-
},
199-
Spec: appsv1.DeploymentSpec{
200-
Selector: &metav1.LabelSelector{
201-
MatchLabels: ls,
202-
},
203-
Template: v1.PodTemplateSpec{
204-
ObjectMeta: metav1.ObjectMeta{
205-
Labels: ls,
206-
},
207-
Spec: v1.PodSpec{
208-
Containers: []v1.Container{{
209-
Image: "memcached:1.4.36-alpine",
210-
Name: "memcached",
211-
Command: []string{"memcached", "-m=64", "-o", "modern", "-v"},
212-
Ports: []v1.ContainerPort{{
213-
ContainerPort: 11211,
214-
Name: "memcached",
215-
}},
216-
}},
217-
},
218-
},
219-
},
220-
}
221-
logrus.Infof("Creating Deployment: %v", obj.Name)
222-
actions = append(actions, types.Action{
223-
Object: d,
224-
Func: action.KubeApplyFunc,
225-
})
226-
227-
if !obj.Spec.WithService {
228-
break
229-
}
230-
231-
svc := &v1.Service{
232-
TypeMeta: metav1.TypeMeta{
233-
APIVersion: "v1",
234-
Kind: "Service",
235-
},
236-
ObjectMeta: metav1.ObjectMeta{
237-
Name: obj.Name,
238-
Namespace: ns,
239-
},
240-
Spec: v1.ServiceSpec{
241-
Selector: ls,
242-
Ports: []v1.ServicePort{{
243-
Port: 11211,
244-
Name: "memcached",
245-
}},
246-
},
247-
}
248-
logrus.Infof("Creating Service: %v", obj.Name)
249-
actions = append(actions, types.Action{
250-
Object: svc,
251-
Func: action.KubeApplyFunc,
252-
})
253-
}
254-
return actions
255-
}
256-
```
257-
258-
Rebuild the container:
259-
260-
```
261-
operator-sdk build quay.io/example/memcached-operator:v0.0.2
262-
docker push quay.io/example/memcached-operator:v0.0.2
263-
```
264-
265-
Deploy operator:
266-
```
267-
kubectl create -f deploy/operator.yaml
268-
```
269-
270-
Create a `Memcached` custom resource with the following spec:
271-
272-
```yaml
273-
apiVersion: "cache.example.com/v1alpha1"
274-
kind: "Memcached"
275-
metadata:
276-
name: "example"
277-
spec:
278-
withService: true
279-
```
280-
281-
There will be a new Memcached Deployment:
282-
```
283-
$ kubectl get deploy
284-
example
285-
```
286-
287-
There will be a new Memcached Service:
288-
```
289-
$ kubectl get service
290-
example
291-
```
292-
293-
We can test the Memcached service by opening a telnet session and running commands via [Memcached protocols][mc_protocol]:
294-
295-
1. Open a telnet session in another pod in order to talk to the service:
296-
```
297-
kubectl run -it --rm busybox --image=busybox --restart=Never -- telnet example 11211
298-
```
299-
2. In the telnet prompt, enter the following commands to set a key:
300-
```
301-
set foo 0 0 3
302-
bar
303-
```
304-
3. Enter the following command to get the key:
305-
```
306-
get foo
307-
```
308-
It should output:
309-
```
310-
VALUE foo 0 3
311-
bar
312-
```
313-
314-
Now we have successfully customized the event handling logic to deploy a Memcached service for us.
315-
316-
Clean up the resources:
317-
318-
```
319-
kubectl delete memcached example
320-
kubectl delete -f deploy/operator.yaml
321-
kubectl delete deployment/example service/example
322-
```
32370

324-
[scaffold_doc]:./doc/project_layout.md
325-
[mc_protocol]:https://github.com/memcached/memcached/blob/master/doc/protocol.txt
326-
[dep_tool]:https://golang.github.io/dep/docs/installation.html
327-
[go_tool]:https://golang.org/dl/
328-
[docker_tool]:https://docs.docker.com/install/
329-
[kubectl_tool]:https://kubernetes.io/docs/tasks/tools/install-kubectl/
330-
[minikube_tool]:https://github.com/kubernetes/minikube#installation
331-
[operator_link]:https://coreos.com/operators/
332-
[design_docs]:./doc/design
71+
[operator_link]: https://coreos.com/operators/
72+
[design_docs]: ./doc/design
73+
[guide]: ./doc/user-guide.md

0 commit comments

Comments
 (0)