Skip to content

Commit

Permalink
add: kube-scheduler-simulator
Browse files Browse the repository at this point in the history
f
  • Loading branch information
sanposhiho committed Aug 20, 2021
1 parent a14c6ae commit 7ff2258
Show file tree
Hide file tree
Showing 138 changed files with 77,163 additions and 26 deletions.
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
web/*
submodules/kubernetes/*
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bin/
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "submodules/kubernetes"]
path = submodules/kubernetes
url = [email protected]:kubernetes/kubernetes.git
59 changes: 59 additions & 0 deletions .golangci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
linters-settings:
gci:
local-prefixes: github.com/kubernetes-sigs/kube-scheduler-simulator
gocritic:
disabled-checks:
- appendAssign

linters:
disable-all: true
enable:
- unused
- govet
- staticcheck
- typecheck
- varcheck
- errcheck
- gosimple
- asciicheck
- bodyclose
- cyclop
- dogsled
- durationcheck
- errorlint
- exportloopref
- forcetypeassert
- funlen
- gci
- gochecknoinits
- gocognit
- gocritic
- gocyclo
- godot
- goerr113
- gofmt
- gofumpt
- gosec
- ifshort
- makezero
- nakedret
- nestif
- nilerr
- nolintlint
- paralleltest
- predeclared
- revive
- rowserrcheck
- sqlclosecheck
- thelper
- unconvert
- unparam
- wastedassign

issues:
exclude-rules:
- path: _test\.go
linters:
- funlen
- goerr113
- errcheck
33 changes: 19 additions & 14 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,26 @@ _As contributors and maintainers of this project, and in the interest of fosteri

## Getting Started

We have full documentation on how to get started contributing here:
For the frontend, please see [README.md](./web/README.md) on ./web dir.

<!---
If your repo has certain guidelines for contribution, put them here ahead of the general k8s resources
-->
The first step, you have to prepare tools with make.

```bash
make tools
```

Also, you can run lint, format and test with make.

```bash
# test
make test
# lint
make lint
# format
make format
```

see [Makefile](Makefile) for more details.

- [Contributor License Agreement](https://git.k8s.io/community/CLA.md) Kubernetes projects require that you sign a Contributor License Agreement (CLA) before we can accept your pull requests
- [Kubernetes Contributor Guide](https://git.k8s.io/community/contributors/guide) - Main contributor documentation, or you can just jump directly to the [contributing section](https://git.k8s.io/community/contributors/guide#contributing)
Expand All @@ -19,13 +34,3 @@ If your repo has certain guidelines for contribution, put them here ahead of the
## Mentorship

- [Mentoring Initiatives](https://git.k8s.io/community/mentoring) - We have a diverse set of mentorship programs available that are always looking for volunteers!

<!---
Custom Information - if you're copying this template for the first time you can add custom content here, for example:
## Contact Information
- [Slack channel](https://kubernetes.slack.com/messages/kubernetes-users) - Replace `kubernetes-users` with your slack channel string, this will send users directly to your channel.
- [Mailing list](URL)
-->
22 changes: 22 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
FROM golang:1.16.6 AS build-env

ENV GOOS=linux
ENV GOARCH=amd64
ENV CGO_ENABLED=0
ENV GO111MODULE=on

WORKDIR /go/src/simulator-server

COPY go.mod go.sum ./
RUN go mod download

COPY . .
RUN go build -v -o ./bin/simulator simulator.go

FROM alpine:3.14.0

COPY --from=build-env /go/src/simulator-server/bin/simulator /simulator
RUN chmod a+x /simulator

EXPOSE 1212
CMD ["/simulator"]
55 changes: 55 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
.PHONY: tools
tools:
cd ./tools; \
cat tools.go | grep "_" | awk -F'"' '{print $$2}' | xargs -tI % go install %

.PHONY: generate
generate:
go generate ./...

.PHONY: lint
lint:
golangci-lint run ./...

.PHONY: format
format:
golangci-lint run --fix ./...

.PHONY: test
test:
go test ./...

.PHONY: build
build:
go build -o ./bin/simulator ./simulator.go

.PHONY: start
serve: build
./hack/start_simulator.sh

# re-generate openapi file for running api-server
.PHONY: openapi
openapi:
./hack/openapi.sh

.PHONY: docker_build
docker_build: docker_build_server docker_build_front

.PHONY: docker_build_server
docker_build_server:
docker build -t simulator-server .

.PHONY: docker_build_front
docker_build_front:
docker build -t simulator-frontend ./web/

.PHONY: docker_up
docker_up:
docker-compose up -d

.PHONY: docker_build_and_up
docker_build_and_up: docker_build docker_up

.PHONY: docker_down
docker_down:
docker-compose down
94 changes: 82 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,86 @@
# Kubernetes Template Project
# Web-based Kubernetes scheduler simulator

The Kubernetes Template Project is a template for starting new projects in the GitHub organizations owned by Kubernetes. All Kubernetes projects, at minimum, must have the following files:
Hello world. Here is web-based Kubernetes scheduler simulator.

- a `README.md` outlining the project goals, sponsoring sig, and community contact information
- an `OWNERS` with the project leads listed as approvers ([docs on `OWNERS` files][owners])
- a `CONTRIBUTING.md` outlining how to contribute to the project
- an unmodified copy of `code-of-conduct.md` from this repo, which outlines community behavior and the consequences of breaking the code
- a `LICENSE` which must be Apache 2.0 for code projects, or [Creative Commons 4.0] for documentation repositories, without any custom content
- a `SECURITY_CONTACTS` with the contact points for the Product Security Team
to reach out to for triaging and handling of incoming issues. They must agree to abide by the
[Embargo Policy](https://git.k8s.io/security/private-distributors-list.md#embargo-policy)
and will be removed and replaced if they violate that agreement.
On the simulator, you can create/edit/delete these resources to simulate a cluster.

- Nodes
- Pods
- Persistent Volumes
- Persistent Volume Claims
- Storage Classes

![list resources](./docs/images/resources.png)

You can create resources with yaml file as usual.

![create node](./docs/images/create-node.png)

And, after pods are scheduled, you can see the results of

- Each Filter plugins
- Each Score plugins
- Final score (normalized and applied Plugin Weight)

![result](./docs/images/result.jpg)

You can configure the scheduler on the simulator through KubeSchedulerConfiguration.

[Scheduler Configuration | Kubernetes](https://kubernetes.io/docs/reference/scheduling/config/)

Note: changes to any fields other than `.profiles` are disabled on simulator, since they do not affect the results of the scheduling.

![configure scheduler](./docs/images/schedulerconfiguration.jpg)

## Background

In real Kubernetes, we cannot know the results of scheduling in detail without reading the logs, which usually requires privileged access to the control plane.
Therefore, we have developed a simulator for kube-scheduler -- you can try out the behavior of the scheduler with web UI while checking which plugin made what decision for which Node.

It can be used to learn about the Kubernetes scheduler or to examine the detailed behavior of plugins, etc.

## Getting started

### Run with Docker

We have [docker-compose.yml](./docker-compose.yml) to use the simulator easily.

You can use it with the below command.

```bash
make docker_build_and_up
```

Then, you can access the simulator with http://localhost:3000

### Run Locally

You have to run frontend, server and etcd.

#### Run simulator server and etcd

To run this simulator's server, you have to install Go and etcd.

You can install etcd with [kubernetes/kubernetes/hack/install-etcd.sh](https://github.com/kubernetes/kubernetes/blob/master/hack/install-etcd.sh).

```bash
make start
```

It starts etcd and simulator-server locally.

#### Run simulator frontend

To run the frontend, please see [README.md](./web/README.md) on ./web dir.

## Contributing

see [CONTRIBUTING.md](./CONTRIBUTING.md)

### other docs

- [how the simulator works](./docs/how-it-works.md)
- [API Reference](./docs/api.md)

## Community, discussion, contribution, and support

Expand All @@ -26,4 +96,4 @@ You can reach the maintainers of this project at:
Participation in the Kubernetes community is governed by the [Kubernetes Code of Conduct](code-of-conduct.md).

[owners]: https://git.k8s.io/community/contributors/guide/owners.md
[Creative Commons 4.0]: https://git.k8s.io/website/LICENSE
[creative commons 4.0]: https://git.k8s.io/website/LICENSE
75 changes: 75 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package config

import (
"errors"
"os"
"strconv"

"golang.org/x/xerrors"
)

// ErrEmptyEnv represents the required environment variable don't exist.
var ErrEmptyEnv = errors.New("env is needed, but empty")

// Config is configuration for simulator.
type Config struct {
Port int
EtcdURL string
FrontendURL string
}

// NewConfig gets some settings from environment variables.
func NewConfig() (*Config, error) {
port, err := getPort()
if err != nil {
return nil, xerrors.Errorf("get port: %w", err)
}

etcdurl, err := getEtcdURL()
if err != nil {
return nil, xerrors.Errorf("get etcd URL: %w", err)
}

frontendurl, err := getFrontendURL()
if err != nil {
return nil, xerrors.Errorf("get frontend URL: %w", err)
}

return &Config{
Port: port,
EtcdURL: etcdurl,
FrontendURL: frontendurl,
}, nil
}

// getPort gets Port from the environment variable named PORT.
func getPort() (int, error) {
p := os.Getenv("PORT")
if p == "" {
return 0, xerrors.Errorf("get PORT from env: %w", ErrEmptyEnv)
}

port, err := strconv.Atoi(p)
if err != nil {
return 0, xerrors.Errorf("convert PORT of string to int: %w", err)
}
return port, nil
}

func getEtcdURL() (string, error) {
e := os.Getenv("KUBE_SCHEDULER_SIMULATOR_ETCD_URL")
if e == "" {
return "", xerrors.Errorf("get KUBE_SCHEDULER_SIMULATOR_ETCD_URL from env: %w", ErrEmptyEnv)
}

return e, nil
}

func getFrontendURL() (string, error) {
e := os.Getenv("FRONTEND_URL")
if e == "" {
return "", xerrors.Errorf("get FRONTEND_URL from env: %w", ErrEmptyEnv)
}

return e, nil
}
Loading

0 comments on commit 7ff2258

Please sign in to comment.