├── .gitattributes ├── .gitignore ├── .travis.yml ├── LICENSE ├── Makefile ├── README.md ├── ansible ├── ansible.cfg ├── etcd.yml ├── inventory │ └── production │ │ ├── group_vars │ │ └── all.yml │ │ ├── host.ini │ │ ├── host.yaml-bak │ │ └── hosts.yaml ├── master.yml ├── node.yml ├── remove-node.yml ├── roles │ └── kubernetes │ │ ├── etcd │ │ ├── defaults │ │ │ └── main.yml │ │ └── tasks │ │ │ └── main.yml │ │ ├── master │ │ ├── defaults │ │ │ └── main.yml │ │ └── tasks │ │ │ └── main.yml │ │ ├── node │ │ ├── defaults │ │ │ └── main.yml │ │ └── tasks │ │ │ └── main.yml │ │ ├── preinstall │ │ ├── default │ │ │ └── main.yml │ │ └── tasks │ │ │ ├── 0010-swapoff.yml │ │ │ └── main.yml │ │ └── remove-node │ │ ├── defaults │ │ └── main.yml │ │ └── tasks │ │ └── main.yml ├── scaledown-node.yml ├── scaleup-node.yml └── terminating.yml ├── build ├── ansible │ └── Dockerfile └── kube-operator │ ├── Dockerfile │ ├── build.sh │ └── control.sh ├── cmd ├── installer │ ├── grpc │ │ ├── agent │ │ │ ├── app │ │ │ │ └── app.go │ │ │ └── main.go │ │ └── server │ │ │ ├── app │ │ │ └── app.go │ │ │ └── main.go │ └── ssh │ │ └── ansibleinit.go └── kube-operator │ └── app.go ├── configs ├── ansible │ └── ansibleinit.toml ├── installer │ └── grpc │ │ └── agent │ │ └── agent.service └── kube-operator │ └── check_k8s.sh ├── deploy ├── cr │ └── ecs_v1_kubernetescluster_cr.yaml ├── ecs_v1_kubernetescluster_crd.yaml ├── kube-operator.yaml └── role.yaml ├── doc └── images │ └── image-20190805195135765.png ├── go.mod ├── go.sum ├── images └── base │ ├── Dockerfile │ ├── kubeadm.conf │ ├── manifests │ └── default-cni.yaml │ ├── systemd │ └── kubelet.service │ └── version ├── main.go ├── pkg ├── apis │ ├── ecs │ │ ├── register.go │ │ └── v1 │ │ │ ├── doc.go │ │ │ ├── register.go │ │ │ ├── types.go │ │ │ └── zz_generated.deepcopy.go │ └── installer │ │ └── v1 │ │ ├── installer.pb.go │ │ ├── installer.pb.gw.go │ │ └── installer.proto ├── client │ ├── clientset │ │ └── versioned │ │ │ ├── clientset.go │ │ │ ├── doc.go │ │ │ ├── fake │ │ │ ├── clientset_generated.go │ │ │ ├── doc.go │ │ │ └── register.go │ │ │ ├── scheme │ │ │ ├── doc.go │ │ │ └── register.go │ │ │ └── typed │ │ │ └── ecs │ │ │ └── v1 │ │ │ ├── doc.go │ │ │ ├── ecs_client.go │ │ │ ├── fake │ │ │ ├── doc.go │ │ │ ├── fake_ecs_client.go │ │ │ └── fake_kubernetescluster.go │ │ │ ├── generated_expansion.go │ │ │ └── kubernetescluster.go │ ├── informers │ │ └── externalversions │ │ │ ├── ecs │ │ │ ├── interface.go │ │ │ └── v1 │ │ │ │ ├── interface.go │ │ │ │ └── kubernetescluster.go │ │ │ ├── factory.go │ │ │ ├── generic.go │ │ │ └── internalinterfaces │ │ │ └── factory_interfaces.go │ └── listers │ │ └── ecs │ │ └── v1 │ │ ├── expansion_generated.go │ │ └── kubernetescluster.go ├── container │ └── docker │ │ ├── cp.go │ │ ├── exec.go │ │ ├── pull.go │ │ └── run.go ├── controller │ ├── cluster_controller.go │ ├── cluster_operate.go │ ├── cluster_operate_test.go │ ├── cluster_precheck.go │ ├── cluster_precheck_test.go │ ├── cluster_status.go │ ├── cluster_status_test.go │ ├── utils.go │ └── utils_test.go ├── enum │ └── task.go ├── exec │ ├── exec.go │ └── local.go ├── fs │ └── fs.go ├── installer │ ├── cluster │ │ ├── constants │ │ │ └── constants.go │ │ ├── context.go │ │ ├── create │ │ │ └── cluster.go │ │ └── nodes │ │ │ ├── command.go │ │ │ ├── node.go │ │ │ ├── role.go │ │ │ └── systemd.go │ ├── grpc │ │ ├── agent │ │ │ ├── server.go │ │ │ ├── server_test.go │ │ │ └── util.go │ │ └── server │ │ │ ├── install.go │ │ │ ├── server.go │ │ │ └── util.go │ ├── interface.go │ ├── ssh │ │ ├── batchjob.go │ │ ├── batchjob_test.go │ │ ├── configmap.go │ │ ├── install.go │ │ ├── job_ttl.go │ │ ├── ssh.go │ │ ├── utils.go │ │ └── utils_test.go │ └── util │ │ └── protobuf │ │ ├── convert.go │ │ └── convert_test.go ├── internal │ ├── apis │ │ └── config │ │ │ ├── encoding │ │ │ └── scheme.go │ │ │ └── types.go │ ├── cluster │ │ ├── context │ │ │ └── context.go │ │ ├── create │ │ │ ├── actions │ │ │ │ ├── action.go │ │ │ │ ├── config │ │ │ │ │ └── config.go │ │ │ │ ├── installcni │ │ │ │ │ └── cni.go │ │ │ │ ├── kubeadminit │ │ │ │ │ └── init.go │ │ │ │ ├── kubeadmjoin │ │ │ │ │ └── join.go │ │ │ │ └── waitforready │ │ │ │ │ └── waitforready.go │ │ │ ├── create.go │ │ │ ├── images.go │ │ │ ├── nodes.go │ │ │ ├── types │ │ │ │ └── types.go │ │ │ └── validate.go │ │ ├── delete │ │ │ └── delete.go │ │ └── kubeadm │ │ │ ├── config.go │ │ │ └── const.go │ └── util │ │ ├── cli │ │ └── status.go │ │ └── env │ │ ├── homedir.go │ │ └── term.go ├── kuberesource │ ├── configmap.go │ └── resourcelock.go ├── precheck │ ├── interface.go │ └── precheck.go ├── server │ ├── controller │ │ ├── cluster │ │ │ ├── cluster.go │ │ │ └── cluster_test.go │ │ ├── controller.go │ │ └── utils.go │ ├── middleware │ │ └── auth.go │ ├── service │ │ ├── callback.go │ │ ├── cluster.go │ │ ├── interface.go │ │ ├── logs.go │ │ ├── scale.go │ │ └── valid.go │ └── serving.go ├── sshserver │ ├── interface.go │ ├── sftp.go │ ├── sftp_test.go │ └── sshserver.go ├── test │ ├── gen.sh │ └── mock_service │ │ └── service.go ├── types │ ├── ansible.go │ ├── ecsclient.go │ ├── installer.go │ └── precheck.go └── utils │ ├── pointer │ ├── pointer.go │ └── pointer_test.go │ ├── signals │ └── signals.go │ └── valid_base64.go ├── scripts ├── README.md ├── bin │ ├── README.md │ ├── certs │ │ ├── cfssl │ │ ├── cfssljson │ │ └── hosts │ ├── docker-ce-18.06.1.ce │ │ ├── docker │ │ ├── docker-containerd │ │ ├── docker-containerd-ctr │ │ ├── docker-containerd-shim │ │ ├── docker-init │ │ ├── docker-proxy │ │ ├── docker-runc │ │ └── dockerd │ ├── etcd_v3.3.13 │ │ ├── etcd │ │ └── etcdctl │ ├── extra │ │ └── bash-completion │ └── kubernetes_v1.14.0 │ │ ├── kube-apiserver │ │ ├── kube-controller-manager │ │ ├── kube-proxy │ │ ├── kube-scheduler │ │ ├── kubectl │ │ └── kubelet ├── certs │ ├── etcd │ │ ├── ca-config.json │ │ ├── etcd-root-ca-csr.json │ │ ├── gen_cert.sh │ │ └── server.json │ ├── master │ │ ├── admin-csr.json │ │ ├── apiserver-kubelet-client-csr.json │ │ ├── ca-config.json │ │ ├── ca-csr.json │ │ ├── gen_cert.sh │ │ ├── kube-apiserver-csr.json │ │ ├── kube-controller-manager-csr.json │ │ ├── kube-proxy-csr.json │ │ ├── kube-scheduler-csr.json │ │ ├── kubelet-csr.json │ │ └── service-account-csr.json │ └── node │ │ ├── ca-config.json │ │ ├── gen_cert.sh │ │ ├── kube-proxy-csr.json │ │ └── kubelet-csr.json ├── config │ ├── etcd │ │ └── etcd.conf │ ├── master │ │ ├── apiserver │ │ ├── config │ │ ├── controller-manager │ │ └── scheduler │ └── node │ │ ├── config │ │ ├── config.yaml │ │ ├── kube-proxy │ │ └── kubelet ├── deploy │ ├── base_env_01.sh │ ├── config.sh │ ├── deploy.sh │ ├── deploy_calico.sh │ ├── deploy_coredns.sh │ ├── deploy_docker.sh │ ├── deploy_etcd.sh │ ├── deploy_kube_proxy.sh │ ├── deploy_kubelet.sh │ ├── deploy_master.sh │ └── hosts_env ├── images │ └── README.md ├── kubeconfig │ ├── generate_master_kubeconfig.sh │ └── generate_node_kubeconfig.sh ├── remove │ ├── remove_etcd.sh │ ├── remove_master.sh │ └── remove_node.sh ├── systemd │ ├── docker.service │ ├── etcd.service │ ├── kube-apiserver.service │ ├── kube-controller-manager.service │ ├── kube-proxy.service │ ├── kube-scheduler.service │ └── kubelet.service ├── test │ └── create_cluster.sh └── yaml │ ├── calico_v3.7 │ └── calico-etcd.yaml │ └── coredns_v1.4.0 │ └── coredns.yaml └── test ├── create_callback.sh ├── create_ecs.sh ├── delete_callback.sh ├── delete_ecs.sh ├── get_logs.sh ├── scale_down.sh ├── scale_up.sh └── scale_up_callback.sh /.gitattributes: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # ---> Go 2 | # Binaries for programs and plugins 3 | *.exe 4 | *.exe~ 5 | *.dll 6 | *.so 7 | *.dylib 8 | 9 | # Test binary, build with `go test -c` 10 | *.test 11 | 12 | # Output of the go coverage tool, specifically when used with LiteIDE 13 | *.out 14 | 15 | # log 16 | *.log 17 | logs/ 18 | log/ 19 | output/ 20 | 21 | # other 22 | .DS_Store 23 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | # Force-enable Go modules. Also force go to use the code in vendor/ 4 | # These will both be unnecessary when Go 1.13 lands. 5 | env: 6 | - GO111MODULE=on 7 | - GOFLAGS='-mod vendor' 8 | 9 | # You don't need to test on very old versions of the Go compiler. It's the user's 10 | # responsibility to keep their compiler up to date. 11 | go: 12 | - 1.12.x 13 | - master 14 | 15 | # Only clone the most recent commit. 16 | git: 17 | depth: 1 18 | 19 | # Don't email me the results of the test runs. 20 | notifications: 21 | email: false 22 | 23 | # Anything in before_script that returns a nonzero exit code will flunk the 24 | # build and immediately stop. It's sorta like having set -e enabled in bash. 25 | # Make sure golangci-lint is vendored. 26 | before_script: 27 | - go install github.com/golangci/golangci-lint/cmd/golangci-lint 28 | 29 | 30 | # script always runs to completion (set +e). If we have linter issues AND a 31 | # failing test, we want to see both. Configure golangci-lint with a 32 | # .golangci.yml file at the top level of your repo. 33 | script: 34 | - golangci-lint run # run a bunch of code checkers/linters in parallel 35 | - go test -v -race ./... # Run all the tests with the race detector enabled 36 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | GOFILES := $(shell find . -name '*.go' | grep -v -E '(./vendor)') 2 | BIN := $(shell basename $(CURDIR)) 3 | # PLATFORM := $(shell go env GOOS) 4 | PLATFORM := linux 5 | AnsibleinitPath := cmd/installer/ssh/ansibleinit.go 6 | OperatorPath := cmd/kube-operator/app.go 7 | 8 | # ifneq (PLATFORM, "windows") 9 | # PLATFORM = linux 10 | # endif 11 | 12 | .DEFAULT_GOAL := default 13 | 14 | default: $(PLATFORM) 15 | 16 | all: linux darwin windows 17 | 18 | linux: output/$(BIN) 19 | darwin: output/$(BIN) 20 | windows: output/$(BIN) 21 | 22 | .PHONY: images 23 | images: 24 | mkdir -p output 25 | GO111MODULE=on GOPROXY=https://mirrors.aliyun.com/goproxy/ GOOS=$(PLATFORM) GOARCH=amd64 go build -ldflags "$(LDFLAGS)" -o output/ansibleinit $(AnsibleinitPath) 26 | docker build --no-cache -f build/ansible/Dockerfile -t ansibleinit . 27 | 28 | GO111MODULE=on GOPROXY=https://mirrors.aliyun.com/goproxy/ GOOS=$(PLATFORM) GOARCH=amd64 go build -ldflags "$(LDFLAGS)" -o output/kubernetes-operator $(OperatorPath) 29 | docker build --no-cache -f build/kube-operator/Dockerfile -t kubernetes-operator . 30 | @rm -rf output 31 | 32 | check: 33 | @find . -name vendor -prune -o -name '*.go' -exec gofmt -s -d {} + 34 | @go vet $(shell go list ./... | grep -v '/vendor/') 35 | @go test -v $(shell go list ./... | grep -v '/vendor/') 36 | 37 | vendor: 38 | dep ensure 39 | 40 | clean: 41 | @rm -rf output 42 | 43 | output/%: LDFLAGS=-s -w 44 | output/%: $(GOFILES) 45 | mkdir -p $(dir $@) 46 | GO111MODULE=on GOPROXY=https://mirrors.aliyun.com/goproxy/ GOOS=$(PLATFORM) GOARCH=amd64 go build -ldflags "$(LDFLAGS)" -o $@ 47 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # kubernetes-operator 2 | 3 | [![License](https://img.shields.io/badge/license-Apache%202-4EB1BA.svg)](https://www.apache.org/licenses/LICENSE-2.0.html) 4 | [![Go Report Card](https://goreportcard.com/badge/github.com/gosoon/kubernetes-operator)](https://goreportcard.com/report/github.com/gosoon/kubernetes-operator) 5 | 6 | kubernetes-operator is a control plane and manage all kubernetes cluster lifecycle. 7 | 8 | 9 | 10 | ## Introduce 11 | 12 | **kubernetes-operator contains several large parts**: 13 | 14 | - kubernetes-proxy: is a proxy and all requests pass through,look like a gateway. 15 | - kube-operator: is a kubernetes operator deploy in meta kubernetes and manage all kubernetes clusters(create、scale、delete). 16 | - cluster deploy: At present, the main focus is on kube-on-kube,and use ansible deploy kubernetes cluster and multiple kubernetes cluster applications, eg: metric-server、 promethus、log-polit、helm... 17 | - node-operator: Manage cluster upgrade, fault self-healing, etc. 18 | 19 | **The kubernetes-operator goal**: 20 | 21 | - kube-on-kube:Similar to Ant Financial kube-on-kube-operator. 22 | - kube-to-kube:The difference with `kube-on-kube` is that the master component of the business cluster is not in the meta cluster. 23 | - kube-to-cloud-kube : Manage clusters on multiple cloud environments. 24 | 25 | 26 | ## Getting started 27 | 28 | First you need to make two images,one is kubernetes-operator,the other one is ansibleinit。And deploy kubernetes-operator in your kubernetes-cluster,if you don't have a kubernetes cluster,please see `scripts/REAEME.md` and deploy one. 29 | 30 | ``` 31 | $ make images 32 | ``` 33 | 34 | ``` 35 | // update your image address and deploy kubernetes-operator 36 | $ kubectl create -f deploy/ 37 | namespace/ecs-system created 38 | customresourcedefinition.apiextensions.k8s.io/kubernetesclusters.ecs.yun.com created 39 | deployment.apps/kubernetes-operator created 40 | clusterrole.rbac.authorization.k8s.io/kubernetes-operator created 41 | clusterrolebinding.rbac.authorization.k8s.io/kubernetes-operator created 42 | serviceaccount/kubernetes-operator created 43 | 44 | 45 | // CustomResources is KubernetesCluster,"ecs" for short in the kubernetes-operator 46 | $ kubectl get crd 47 | NAME CREATED AT 48 | kubernetesclusters.ecs.yun.com 2019-08-05T12:23:52Z 49 | 50 | // update operator server in create_ecs.sh and create a cluster 51 | $ bash test/create_ecs.sh 52 | 53 | $ kubectl get ecs 54 | NAME STATUS AGE 55 | test-cluster Prechecking 45m 56 | ``` 57 | 58 | 59 | 60 | ## Development Plan 61 | 62 | 1. support deploy k3s、kubeedge cluster 63 | 2. support use kops deploy cluster 64 | 3. support for multiple version deploy 65 | 4. development node-operator 66 | 5. support admission control 67 | 68 | ## Detailed instructions 69 | 70 | - [kube-on-kube-operator 开发(一)](http://blog.tianfeiyu.com/2019/08/05/kube_on_kube_operator_1/) 71 | - [kube-on-kube-operator 开发(二)](http://blog.tianfeiyu.com/2019/08/07/kube_on_kube_operator_2/) 72 | - [kube-on-kube-operator 开发(三)](http://blog.tianfeiyu.com/2019/09/01/kube_on_kube_operator_3/) 73 | 74 | 75 | -------------------------------------------------------------------------------- /ansible/ansible.cfg: -------------------------------------------------------------------------------- 1 | [ssh_connection] 2 | pipelining=True 3 | ssh_args = -o ControlMaster=auto -o ControlPersist=30m -o ConnectionAttempts=100 -o UserKnownHostsFile=/dev/null 4 | #control_path = ~/.ssh/ansible-%%r@%%h:%%p 5 | [defaults] 6 | strategy_plugins = plugins/mitogen/ansible_mitogen/plugins/strategy 7 | # https://github.com/ansible/ansible/issues/56930 (to ignore group names with - and .) 8 | force_valid_group_names = ignore 9 | 10 | host_key_checking=False 11 | gathering = smart 12 | fact_caching = jsonfile 13 | fact_caching_connection = /tmp 14 | stdout_callback = skippy 15 | library = ./library 16 | callback_whitelist = profile_tasks 17 | roles_path = roles:$VIRTUAL_ENV/usr/local/share/kubespray/roles:$VIRTUAL_ENV/usr/local/share/ansible/roles:/usr/share/kubespray/roles 18 | deprecation_warnings=False 19 | inventory_ignore_extensions = ~, .orig, .bak, .ini, .cfg, .retry, .pyc, .pyo, .creds 20 | [inventory] 21 | ignore_patterns = artifacts, credentials 22 | enable_plugins = yaml 23 | -------------------------------------------------------------------------------- /ansible/etcd.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: false 4 | become: no 5 | tasks: 6 | - name: "Check ansible version >=2.7.6" 7 | assert: 8 | msg: "Ansible must be v2.7.6 or higher" 9 | that: 10 | - ansible_version.string is version("2.7.6", ">=") 11 | tags: 12 | - check 13 | vars: 14 | ansible_connection: local 15 | 16 | - hosts: etcd 17 | gather_facts: false 18 | any_errors_fatal: "{{ any_errors_fatal | default(true) }}" 19 | environment: 20 | ETCD_HOSTS: ${ETCD_HOSTS} 21 | roles: 22 | - { role: kubernetes/preinstall, tags: preinstall } 23 | - { role: kubernetes/etcd, tags: etcd } 24 | -------------------------------------------------------------------------------- /ansible/inventory/production/group_vars/all.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # docker version 3 | DOCKER_VER: "docker-ce-18.06.1.ce" 4 | 5 | # k8s version 6 | KUBERNETES_VER: "kubernetes_v1.14.0" 7 | 8 | KUBERNETES_DOWNLOAD_URL: "https://dl.k8s.io/v1.14.0/kubernetes.tar.gz" 9 | 10 | # etcd version 11 | ETCD_VER: "etcd_v3.3.13" 12 | 13 | # calico version 14 | CALICO_VER: "v3.7" 15 | 16 | # coredns version 17 | COREDNS_VER: "v1.4.0" 18 | 19 | # etcd hosts, eg : "10.0.2.15,10.0.2.16" 20 | ETCD_HOSTS: "10.0.2.15" 21 | 22 | # master hosts, eg : "10.0.2.15,10.0.2.16" 23 | MASTER_HOSTS: "10.0.2.15" 24 | 25 | # host ip 26 | #LOCAL_IP: $(ip route get 1 | awk '{print $NF;exit}') 27 | 28 | disable_swap: true 29 | -------------------------------------------------------------------------------- /ansible/inventory/production/host.ini: -------------------------------------------------------------------------------- 1 | [all] 2 | node1 ansible_host=192.168.75.32 ansible_user=root ip=192.168.75.32 etcd_member_name=node1 3 | node2 ansible_host=192.168.75.32 ansible_user=root ip=192.168.75.32 4 | 5 | [kube-node] 6 | node1 7 | 8 | [kube-master] 9 | node1 10 | -------------------------------------------------------------------------------- /ansible/inventory/production/host.yaml-bak: -------------------------------------------------------------------------------- 1 | all: 2 | hosts: 3 | 192.168.75.104: 4 | ansible_host: 192.168.75.104 5 | ip: 192.168.75.104 6 | access_ip: 192.168.75.104 7 | node_lable: 8 | children: 9 | kube-master: 10 | hosts: 11 | 192.168.75.104: 12 | kube-node: 13 | hosts: 14 | 192.168.75.104: 15 | etcd: 16 | hosts: 17 | 192.168.75.104: 18 | k8s-cluster: 19 | children: 20 | kube-master: 21 | kube-node: 22 | calico-rr: 23 | hosts: {} 24 | -------------------------------------------------------------------------------- /ansible/inventory/production/hosts.yaml: -------------------------------------------------------------------------------- 1 | all: 2 | hosts: 3 | 192.168.75.104: 4 | ansible_host: 192.168.75.104 5 | ip: 192.168.75.104 6 | access_ip: 192.168.75.104 7 | node_lable: 8 | children: 9 | kube-master: 10 | hosts: 11 | 192.168.75.104: 12 | kube-node: 13 | hosts: 14 | 192.168.75.104: 15 | etcd: 16 | hosts: 17 | 192.168.75.104: 18 | k8s-cluster: 19 | children: 20 | kube-master: 21 | kube-node: 22 | calico-rr: 23 | hosts: {} 24 | -------------------------------------------------------------------------------- /ansible/master.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: false 4 | become: no 5 | tasks: 6 | - name: "Check ansible version >=2.7.6" 7 | assert: 8 | msg: "Ansible must be v2.7.6 or higher" 9 | that: 10 | - ansible_version.string is version("2.7.6", ">=") 11 | tags: 12 | - check 13 | vars: 14 | ansible_connection: local 15 | 16 | - hosts: kube-master 17 | gather_facts: false 18 | any_errors_fatal: "{{ any_errors_fatal | default(true) }}" 19 | environment: 20 | MASTER_HOSTS: ${MASTER_HOSTS} 21 | MASTER_VIP: ${MASTER_VIP} 22 | NODE_HOSTS: ${NODE_HOSTS} 23 | ETCD_HOSTS: ${ETCD_HOSTS} 24 | roles: 25 | - { role: kubernetes/preinstall, tags: preinstall } 26 | - { role: kubernetes/master, tags: master } 27 | -------------------------------------------------------------------------------- /ansible/node.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: false 4 | become: no 5 | tasks: 6 | - name: "Check ansible version >=2.7.6" 7 | assert: 8 | msg: "Ansible must be v2.7.6 or higher" 9 | that: 10 | - ansible_version.string is version("2.7.6", ">=") 11 | tags: 12 | - check 13 | vars: 14 | ansible_connection: local 15 | 16 | - hosts: kube-node 17 | gather_facts: false 18 | environment: 19 | MASTER_HOSTS: ${MASTER_HOSTS} 20 | MASTER_VIP: ${MASTER_VIP} 21 | NODE_HOSTS: ${NODE_HOSTS} 22 | any_errors_fatal: "{{ any_errors_fatal | default(true) }}" 23 | roles: 24 | - { role: kubernetes/preinstall, tags: preinstall } 25 | - { role: kubernetes/node, tags: node } 26 | -------------------------------------------------------------------------------- /ansible/remove-node.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: false 4 | become: no 5 | tasks: 6 | - name: "Check ansible version >=2.7.6" 7 | assert: 8 | msg: "Ansible must be v2.7.6 or higher" 9 | that: 10 | - ansible_version.string is version("2.7.6", ">=") 11 | tags: 12 | - check 13 | vars: 14 | ansible_connection: local 15 | 16 | - hosts: kube-node 17 | gather_facts: false 18 | any_errors_fatal: "{{ any_errors_fatal | default(true) }}" 19 | environment: 20 | MASTER_HOSTS: ${MASTER_HOSTS} 21 | MASTER_VIP: ${MASTER_VIP} 22 | NODE_HOSTS: ${NODE_HOSTS} 23 | roles: 24 | - { role: kubernetes/remove-node, tags: remove-node } 25 | -------------------------------------------------------------------------------- /ansible/roles/kubernetes/etcd/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | ignore_assert_errors: true 3 | -------------------------------------------------------------------------------- /ansible/roles/kubernetes/etcd/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | #- name: Install git cmd 3 | #command: yum install git -y 4 | #ignore_errors: "{{ ignore_assert_errors }}" 5 | 6 | #- name: clone deploy script 7 | # command: git clone https://github.com/gosoon/kubernetes-operator /home/kubernetes-operator 8 | # ignore_errors: "{{ ignore_assert_errors }}" 9 | 10 | - name: Copy etcd deploy config 11 | file: 12 | src: /home/kubernetes-operator/scripts 13 | dest: /home/kubernetes-operator/ 14 | follow: yes 15 | force: yes 16 | 17 | - name: Copy private key 18 | copy: 19 | src: /home/kubernetes-operator/private-key 20 | dest: /home/kubernetes-operator/private-key 21 | force: yes 22 | mode: 0600 23 | 24 | - name: Deploy etcd 25 | command: bash deploy.sh etcd 26 | args: 27 | chdir: /home/kubernetes-operator/scripts/deploy 28 | -------------------------------------------------------------------------------- /ansible/roles/kubernetes/master/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | ignore_assert_errors: true 3 | -------------------------------------------------------------------------------- /ansible/roles/kubernetes/master/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Copy master deploy config 3 | copy: 4 | src: /home/kubernetes-operator/scripts 5 | dest: /home/kubernetes-operator/ 6 | force: yes 7 | 8 | - name: Copy private key 9 | copy: 10 | src: /home/kubernetes-operator/private-key 11 | dest: /home/kubernetes-operator/private-key 12 | force: yes 13 | 14 | - name: deploy master 15 | command: bash deploy.sh master 16 | args: 17 | chdir: /home/kubernetes-operator/scripts/deploy 18 | 19 | -------------------------------------------------------------------------------- /ansible/roles/kubernetes/node/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | ignore_assert_errors: true 3 | -------------------------------------------------------------------------------- /ansible/roles/kubernetes/node/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | #- name: install git cmd 3 | #command: yum install git -y 4 | #ignore_errors: "{{ ignore_assert_errors }}" 5 | 6 | #- name: clone deploy script 7 | #command: git clone https://github.com/gosoon/kubernetes-operator /home/kube/kubernetes-operator 8 | #ignore_errors: "{{ ignore_assert_errors }}" 9 | 10 | - name: Copy node deploy config 11 | copy: 12 | src: /home/kubernetes-operator/scripts 13 | dest: /home/kubernetes-operator/ 14 | force: yes 15 | 16 | - name: Copy private key 17 | copy: 18 | src: /home/kubernetes-operator/private-key 19 | dest: /home/kubernetes-operator/private-key 20 | force: yes 21 | 22 | - name: deploy node 23 | command: bash deploy.sh node 24 | args: 25 | chdir: /home/kubernetes-operator/scripts/deploy 26 | -------------------------------------------------------------------------------- /ansible/roles/kubernetes/preinstall/default/main.yml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gosoon/kubernetes-operator/ff55af68d380065a6173dc4028125ed54c0bc60f/ansible/roles/kubernetes/preinstall/default/main.yml -------------------------------------------------------------------------------- /ansible/roles/kubernetes/preinstall/tasks/0010-swapoff.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Remove swapfile from /etc/fstab 3 | mount: 4 | name: "{{ item }}" 5 | fstype: swap 6 | state: absent 7 | with_items: 8 | - swap 9 | - none 10 | 11 | # kubelet fails even if ansible_swaptotal_mb = 0 12 | - name: check swap 13 | command: /sbin/swapon -s 14 | register: swapon 15 | changed_when: no 16 | - name: Disable swap 17 | command: /sbin/swapoff -a 18 | when: swapon.stdout 19 | -------------------------------------------------------------------------------- /ansible/roles/kubernetes/preinstall/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # Disable swap 3 | - import_tasks: 0010-swapoff.yml 4 | when: 5 | - disable_swap 6 | -------------------------------------------------------------------------------- /ansible/roles/kubernetes/remove-node/defaults/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | ignore_assert_errors: true 3 | -------------------------------------------------------------------------------- /ansible/roles/kubernetes/remove-node/tasks/main.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - name: Copy private key 3 | copy: 4 | src: /home/kubernetes-operator/private-key 5 | dest: /home/kubernetes-operator/private-key 6 | force: yes 7 | 8 | - name: remove node 9 | command: bash remove_node.sh 10 | args: 11 | chdir: /home/kube/kubernetes-operator/scripts/remove 12 | -------------------------------------------------------------------------------- /ansible/scaledown-node.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: false 4 | become: no 5 | tasks: 6 | - name: "Check ansible version >=2.7.6" 7 | assert: 8 | msg: "Ansible must be v2.7.6 or higher" 9 | that: 10 | - ansible_version.string is version("2.7.6", ">=") 11 | tags: 12 | - check 13 | vars: 14 | ansible_connection: local 15 | 16 | - hosts: kube-node 17 | gather_facts: false 18 | any_errors_fatal: "{{ any_errors_fatal | default(true) }}" 19 | environment: 20 | MASTER_HOSTS: ${MASTER_HOSTS} 21 | MASTER_VIP: ${MASTER_VIP} 22 | NODE_HOSTS: ${NODE_HOSTS} 23 | roles: 24 | - { role: kubernetes/remove-node, tags: remove-node } 25 | -------------------------------------------------------------------------------- /ansible/scaleup-node.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: false 4 | become: no 5 | tasks: 6 | - name: "Check ansible version >=2.7.6" 7 | assert: 8 | msg: "Ansible must be v2.7.6 or higher" 9 | that: 10 | - ansible_version.string is version("2.7.6", ">=") 11 | tags: 12 | - check 13 | vars: 14 | ansible_connection: local 15 | 16 | - hosts: kube-node 17 | gather_facts: false 18 | any_errors_fatal: "{{ any_errors_fatal | default(true) }}" 19 | environment: 20 | MASTER_HOSTS: ${MASTER_HOSTS} 21 | MASTER_VIP: ${MASTER_VIP} 22 | NODE_HOSTS: ${NODE_HOSTS} 23 | roles: 24 | - { role: kubernetes/remove-node, tags: remove-node } 25 | -------------------------------------------------------------------------------- /ansible/terminating.yml: -------------------------------------------------------------------------------- 1 | --- 2 | - hosts: localhost 3 | gather_facts: false 4 | become: no 5 | tasks: 6 | - name: "Check ansible version >=2.7.6" 7 | assert: 8 | msg: "Ansible must be v2.7.6 or higher" 9 | that: 10 | - ansible_version.string is version("2.7.6", ">=") 11 | tags: 12 | - check 13 | vars: 14 | ansible_connection: local 15 | 16 | - hosts: kube-master 17 | gather_facts: false 18 | any_errors_fatal: "{{ any_errors_fatal | default(true) }}" 19 | environment: 20 | MASTER_HOSTS: ${MASTER_HOSTS} 21 | MASTER_VIP: ${MASTER_VIP} 22 | NODE_HOSTS: ${NODE_HOSTS} 23 | ETCD_HOSTS: ${ETCD_HOSTS} 24 | roles: 25 | - { role: kubernetes/preinstall, tags: preinstall } 26 | - { role: kubernetes/master, tags: master } 27 | -------------------------------------------------------------------------------- /build/ansible/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.12-alpine 2 | 3 | RUN apk add --no-cache \ 4 | wget \ 5 | make \ 6 | git \ 7 | openssh-client \ 8 | ansible \ 9 | openssh \ 10 | vim 11 | #FROM golang:alpine 12 | 13 | RUN mkdir -p /home/kubernetes-operator \ 14 | && mkdir -p /home/kubernetes-operator/configs/ansible 15 | 16 | # test 17 | ENV OPERATION creating 18 | 19 | ADD ./scripts/ /home/kubernetes-operator/scripts 20 | ADD ./ansible/ /home/kubernetes-operator/ansible 21 | ADD ./output/ansibleinit /home/kubernetes-operator/ 22 | 23 | ADD ./configs/ansible/ansibleinit.toml /home/kubernetes-operator/configs/ansible/ 24 | 25 | WORKDIR /home/kubernetes-operator 26 | ENTRYPOINT ["./ansibleinit","-config","configs/ansible/ansibleinit.toml"] 27 | -------------------------------------------------------------------------------- /build/kube-operator/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM golang:1.12-alpine 2 | 3 | RUN mkdir -p /home/kubernetes-operator/logs && 4 | mkdir /home/kubernetes-operator/configs 5 | 6 | ADD ./output/kubernetes-operator /home/kubernetes-operator 7 | ADD ./build/operator/control.sh /home/kubernetes-operator \ 8 | && chmod +x /home/kubernetes-operator/control.sh 9 | 10 | ADD ./configs/kube-operator /home/kubernetes-operator/configs 11 | 12 | WORKDIR /home/kubernetes-operator 13 | ENTRYPOINT ["control.sh","start"] 14 | -------------------------------------------------------------------------------- /build/kube-operator/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export GO111MODULE="on" 4 | export GOPROXY="https://goproxy.io" 5 | export CGO_ENABLED="0" 6 | export GOOS="linux" 7 | export GOARCH=amd64 8 | 9 | go mod vendor 10 | go build -ldflags "-s -w" -a -installsuffix cgo -o kubernetes-operator . 11 | -------------------------------------------------------------------------------- /build/kube-operator/control.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | export LC_ALL=en_US.UTF-8 3 | export LANG=en_US.UTF-8 4 | 5 | ROOT=`cd $(dirname $0); pwd` 6 | BIN=${ROOT}/kubernetes-operator 7 | LOGDIR=${ROOT}/logs/ 8 | 9 | mkdir -p ${LOGDIR} 10 | process="kubernetes-operator" 11 | 12 | #使用pgrep判断程序是否执行 13 | function check_pid(){ 14 | run_pid=$(pgrep $process) 15 | echo $run_pid 16 | } 17 | pid=$(check_pid) 18 | 19 | function status(){ 20 | if [ "x_$pid" != "x_" ]; then 21 | echo "$process running with pid: $pid" 22 | else 23 | echo "ERROR: kubernetes-operator may not running!" 24 | fi 25 | } 26 | 27 | start() { 28 | echo -n "starting kubernetes-operator... " 29 | exec ${ROOT}/kubernetes-operator 30 | } 31 | 32 | stop() { 33 | echo -n "stopping kubernetes-operator... " 34 | kill `cat ${pid}` 35 | return 0 36 | } 37 | 38 | restart() { 39 | echo -n "restarting kubernetes-operator... " 40 | stop 41 | start 42 | echo "finished, plz check by urself" 43 | } 44 | 45 | case "$1" in 46 | start) 47 | start 48 | ;; 49 | 50 | stop) 51 | stop 52 | ;; 53 | 54 | restart) 55 | restart 56 | ;; 57 | *) 58 | echo "Usage: $0 {start|stop|restart}" 59 | exit 1 60 | esac 61 | -------------------------------------------------------------------------------- /cmd/installer/grpc/agent/app/app.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package app 18 | 19 | import ( 20 | "net" 21 | "time" 22 | 23 | "github.com/gosoon/glog" 24 | "github.com/spf13/cobra" 25 | "google.golang.org/grpc" 26 | 27 | installerv1 "github.com/gosoon/kubernetes-operator/pkg/apis/installer/v1" 28 | grpcagent "github.com/gosoon/kubernetes-operator/pkg/installer/grpc/agent" 29 | ) 30 | 31 | type Flagpole struct { 32 | Config string 33 | Retain bool 34 | Wait time.Duration 35 | Port string 36 | } 37 | 38 | // NewServerCommand returns a new cobra.Command for kube-on-kube server 39 | func NewServerCommand() *cobra.Command { 40 | flags := &Flagpole{} 41 | cmd := &cobra.Command{ 42 | Args: cobra.NoArgs, 43 | Use: "cluster", 44 | Short: "Creates a local Kubernetes cluster", 45 | Long: "Creates a local Kubernetes cluster ", 46 | Run: func(cmd *cobra.Command, args []string) { 47 | run(flags) 48 | }, 49 | } 50 | cmd.Flags().DurationVar(&flags.Wait, "wait", time.Duration(0), "Wait for control plane node to be ready (default 0s)") 51 | cmd.Flags().StringVar(&flags.Port, "port", "10023", "installer grpc agent port(default 10023)") 52 | return cmd 53 | } 54 | 55 | func run(flags *Flagpole) { 56 | // start grpc server 57 | l, err := net.Listen("tcp", ":"+flags.Port) 58 | if err != nil { 59 | glog.Fatalf("failed to listen: %v", err) 60 | } 61 | server := grpc.NewServer() 62 | 63 | agent := grpcagent.NewAgent(&grpcagent.Options{ 64 | Port: flags.Port, 65 | Server: server, 66 | }) 67 | 68 | // register grpc server 69 | installerv1.RegisterInstallerServer(server, agent) 70 | glog.Fatal(server.Serve(l)) 71 | } 72 | -------------------------------------------------------------------------------- /cmd/installer/grpc/agent/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "fmt" 21 | "math/rand" 22 | "os" 23 | "time" 24 | 25 | "github.com/gosoon/kubernetes-operator/cmd/installer/grpc/agent/app" 26 | ) 27 | 28 | func main() { 29 | rand.Seed(time.Now().UnixNano()) 30 | 31 | command := app.NewServerCommand() 32 | if err := command.Execute(); err != nil { 33 | fmt.Fprintf(os.Stderr, "%v\n", err) 34 | os.Exit(1) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /cmd/installer/grpc/server/main.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import ( 20 | "fmt" 21 | "math/rand" 22 | "os" 23 | "time" 24 | 25 | "github.com/gosoon/kubernetes-operator/cmd/installer/grpc/server/app" 26 | ) 27 | 28 | func main() { 29 | rand.Seed(time.Now().UnixNano()) 30 | 31 | command := app.NewServerCommand() 32 | if err := command.Execute(); err != nil { 33 | fmt.Fprintf(os.Stderr, "%v\n", err) 34 | os.Exit(1) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /configs/ansible/ansibleinit.toml: -------------------------------------------------------------------------------- 1 | # config 2 | title = "dockerinit" 3 | 4 | [config] 5 | timeout = 600 6 | server = "http://192.168.75.179:8000" 7 | region = "default" 8 | token = "" 9 | creatingCallbackPath = "/api/v1/region/{region}/cluster/{name}/create/callback" 10 | scalingUpCallbackPath = "/api/v1/region/{region}/cluster/{name}/scaleup/callback" 11 | scalingDownCallbackPath = "/api/v1/region/{region}/cluster/{name}/scaledown/callback" 12 | terminatingCallbackPath = "/api/v1/region/{region}/cluster/{name}/delete/callback" 13 | -------------------------------------------------------------------------------- /configs/installer/grpc/agent/agent.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=kubernetes-opeartor grpc installer agent service 3 | After=network.target 4 | 5 | [Service] 6 | ExecStart=/usr/bin/installer-agent 7 | Restart=on-failure 8 | RestartSec=5 9 | Type=notify 10 | LimitNOFILE=65536 11 | 12 | [Install] 13 | WantedBy=multi-user.target 14 | -------------------------------------------------------------------------------- /configs/kube-operator/check_k8s.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | kernel_num_1=$(uname -r | awk -F '.' '{print $1}') 4 | kernel_num_2=$(uname -r | awk -F '.' '{print $2}') 5 | if [ ${kernel_num_1} -lt 3 ];then 6 | echo "kernel version is minor < 3.0" 7 | exit 1 8 | fi 9 | 10 | if [ ${kernel_num_1} -eq 3 -a ${kernel_num_2} -lt 10 ];then 11 | echo "kernel version is minor < 3.10" 12 | exit 1 13 | fi 14 | -------------------------------------------------------------------------------- /deploy/cr/ecs_v1_kubernetescluster_cr.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: ecs.yun.com/v1 2 | kind: KubernetesCluster 3 | metadata: 4 | name: test-cluster 5 | spec: 6 | clusterType: kubernetes 7 | masterList: 8 | - ip: 192.168.1.10 9 | - ip: 192.168.1.11 10 | nodeList: 11 | - ip: 192.168.1.12 12 | - ip: 192.168.1.12 13 | etcdList: 14 | - ip: 192.168.1.12 15 | - ip: 192.168.1.12 16 | privateSSHKey: '' 17 | serviceCIDR: '' 18 | status: {} 19 | -------------------------------------------------------------------------------- /deploy/ecs_v1_kubernetescluster_crd.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Namespace 3 | metadata: 4 | name: ecs-system 5 | --- 6 | apiVersion: apiextensions.k8s.io/v1beta1 7 | kind: CustomResourceDefinition 8 | metadata: 9 | name: kubernetesclusters.ecs.yun.com 10 | spec: 11 | group: ecs.yun.com 12 | names: 13 | kind: KubernetesCluster 14 | listKind: KubernetesClusterList 15 | plural: kubernetesclusters 16 | singular: kubernetescluster 17 | shortNames: 18 | - ecs 19 | scope: Namespaced 20 | additionalPrinterColumns: 21 | - name: Status 22 | type: string 23 | JSONPath: .status.phase 24 | - name: Age 25 | type: date 26 | JSONPath: .metadata.creationTimestamp 27 | subresources: 28 | status: {} 29 | validation: 30 | openAPIV3Schema: 31 | properties: 32 | apiVersion: 33 | description: 'APIVersion defines the versioned schema of this representation 34 | of an object. Servers should convert recognized schemas to the latest 35 | internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources' 36 | type: string 37 | kind: 38 | description: 'Kind is a string value representing the REST resource this 39 | object represents. Servers may infer this from the endpoint the client 40 | submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds' 41 | type: string 42 | metadata: 43 | type: object 44 | spec: 45 | type: object 46 | status: 47 | type: object 48 | version: v1 49 | versions: 50 | - name: v1 51 | served: true 52 | storage: true 53 | -------------------------------------------------------------------------------- /deploy/kube-operator.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: kubernetes-operator 5 | namespace: ecs-system 6 | spec: 7 | replicas: 3 8 | selector: 9 | matchLabels: 10 | name: kubernetes-operator 11 | template: 12 | metadata: 13 | labels: 14 | name: kubernetes-operator 15 | spec: 16 | serviceAccountName: kubernetes-operator 17 | containers: 18 | - name: kubernetes-operator 19 | # Replace this with the built image name 20 | image: REPLACE_IMAGE 21 | imagePullPolicy: Always 22 | env: 23 | - name: WATCH_NAMESPACE 24 | valueFrom: 25 | fieldRef: 26 | fieldPath: metadata.namespace 27 | - name: POD_NAME 28 | valueFrom: 29 | fieldRef: 30 | fieldPath: metadata.name 31 | - name: OPERATOR_NAME 32 | value: "kubernetes-operator" 33 | -------------------------------------------------------------------------------- /deploy/role.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: rbac.authorization.k8s.io/v1 2 | kind: ClusterRole 3 | metadata: 4 | name: kubernetes-operator 5 | namespace: ecs-system 6 | rules: 7 | - apiGroups: 8 | - "" 9 | resources: 10 | - pods 11 | - services 12 | - endpoints 13 | - persistentvolumeclaims 14 | - events 15 | - configmaps 16 | - secrets 17 | verbs: 18 | - '*' 19 | - apiGroups: 20 | - apps 21 | resources: 22 | - deployments 23 | - daemonsets 24 | - replicasets 25 | - statefulsets 26 | verbs: 27 | - '*' 28 | - apiGroups: 29 | - batch 30 | resources: 31 | - cronjobs 32 | - jobs 33 | verbs: 34 | - '*' 35 | - apiGroups: 36 | - monitoring.coreos.com 37 | resources: 38 | - servicemonitors 39 | verbs: 40 | - get 41 | - create 42 | - apiGroups: 43 | - apps 44 | resourceNames: 45 | - kubernetes-operator 46 | resources: 47 | - deployments/finalizers 48 | verbs: 49 | - update 50 | - apiGroups: 51 | - ecs.yun.com 52 | resources: 53 | - '*' 54 | verbs: 55 | - '*' 56 | --- 57 | kind: ClusterRoleBinding 58 | apiVersion: rbac.authorization.k8s.io/v1 59 | metadata: 60 | name: kubernetes-operator 61 | subjects: 62 | - kind: ServiceAccount 63 | name: kubernetes-operator 64 | namespace: ecs-system 65 | roleRef: 66 | kind: ClusterRole 67 | name: kubernetes-operator 68 | apiGroup: rbac.authorization.k8s.io 69 | --- 70 | apiVersion: v1 71 | kind: ServiceAccount 72 | metadata: 73 | name: kubernetes-operator 74 | namespace: ecs-system 75 | -------------------------------------------------------------------------------- /doc/images/image-20190805195135765.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gosoon/kubernetes-operator/ff55af68d380065a6173dc4028125ed54c0bc60f/doc/images/image-20190805195135765.png -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/gosoon/kubernetes-operator 2 | 3 | go 1.12 4 | 5 | require ( 6 | github.com/cloudflare/cfssl v0.0.0-20190911221928-1a911ca1b1d6 7 | github.com/deckarep/golang-set v1.7.1 8 | github.com/gogo/protobuf v1.2.1 9 | github.com/golang/mock v1.1.1 10 | github.com/golang/protobuf v1.3.1 11 | github.com/gorilla/mux v1.7.3 12 | github.com/gosoon/glog v0.0.0-20180521124921-a5fbfb162a81 13 | github.com/grpc-ecosystem/grpc-gateway v1.9.0 14 | github.com/kr/fs v0.1.0 // indirect 15 | github.com/mitchellh/go-homedir v1.1.0 16 | github.com/pkg/errors v0.8.1 17 | github.com/pkg/sftp v1.10.0 18 | github.com/sirupsen/logrus v1.2.0 19 | github.com/spf13/cobra v0.0.5 20 | github.com/spf13/viper v1.4.0 21 | github.com/stretchr/testify v1.3.0 22 | golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 23 | google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8 24 | google.golang.org/grpc v1.21.0 25 | k8s.io/api v0.0.0-20190718062839-c8a0b81cb10e 26 | k8s.io/apimachinery v0.0.0-20190717022731-0bb8574e0887 27 | sigs.k8s.io/yaml v1.1.0 28 | ) 29 | -------------------------------------------------------------------------------- /images/base/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:19.04 2 | MAINTAINER gosoon 3 | 4 | # start a sshd service in image so that the container cannot exit 5 | # 6 | 7 | RUN apt-get update; apt-get upgrade -y \ 8 | && apt-get install -y openssh-server 9 | 10 | RUN sed -i 's/UsePAM yes/UsePAM no/g' /etc/ssh/sshd_config 11 | 12 | RUN mkdir /var/run/sshd 13 | 14 | RUN mkdir -pv /kubernetes/bin \ 15 | && mkdir -pv /kubernetes/manifests \ 16 | && mkdir -pv /kubernetes/systemd 17 | 18 | Add ./bin /kubernetes/bin/ 19 | Add ./manifests /kubernetes/manifests/ 20 | Add ./systemd /kubernetes/systemd/ 21 | Add ./version /kubernetes/ 22 | Add ./kubeadm.conf /kubernetes/ 23 | 24 | EXPOSE 22 25 | ENTRYPOINT /usr/sbin/sshd -D 26 | -------------------------------------------------------------------------------- /images/base/kubeadm.conf: -------------------------------------------------------------------------------- 1 | apiServer: 2 | certSANs: 3 | - localhost 4 | - 127.0.0.1 5 | apiVersion: kubeadm.k8s.io/v1beta2 6 | clusterName: kind 7 | controlPlaneEndpoint: 172.17.0.2:6443 8 | controllerManager: 9 | extraArgs: 10 | enable-hostpath-provisioner: "true" 11 | kind: ClusterConfiguration 12 | kubernetesVersion: v1.15.3 13 | networking: 14 | podSubnet: 10.244.0.0/16 15 | serviceSubnet: 10.96.0.0/12 16 | scheduler: 17 | extraArgs: null 18 | --- 19 | apiVersion: kubeadm.k8s.io/v1beta2 20 | bootstrapTokens: 21 | - token: abcdef.0123456789abcdef 22 | kind: InitConfiguration 23 | localAPIEndpoint: 24 | advertiseAddress: 172.17.0.5 25 | bindPort: 6443 26 | nodeRegistration: 27 | criSocket: /run/containerd/containerd.sock 28 | kubeletExtraArgs: 29 | fail-swap-on: "false" 30 | node-ip: 172.17.0.5 31 | --- 32 | apiVersion: kubeadm.k8s.io/v1beta2 33 | controlPlane: 34 | localAPIEndpoint: 35 | advertiseAddress: 172.17.0.5 36 | bindPort: 6443 37 | discovery: 38 | bootstrapToken: 39 | apiServerEndpoint: 172.17.0.2:6443 40 | token: abcdef.0123456789abcdef 41 | unsafeSkipCAVerification: true 42 | kind: JoinConfiguration 43 | nodeRegistration: 44 | criSocket: /run/containerd/containerd.sock 45 | kubeletExtraArgs: 46 | fail-swap-on: "false" 47 | node-ip: 172.17.0.5 48 | --- 49 | apiVersion: kubelet.config.k8s.io/v1beta1 50 | evictionHard: 51 | imagefs.available: 0% 52 | nodefs.available: 0% 53 | nodefs.inodesFree: 0% 54 | imageGCHighThresholdPercent: 100 55 | kind: KubeletConfiguration 56 | --- 57 | apiVersion: kubeproxy.config.k8s.io/v1alpha1 58 | kind: KubeProxyConfiguration 59 | -------------------------------------------------------------------------------- /images/base/systemd/kubelet.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=kubelet: The Kubernetes Node Agent 3 | Documentation=http://kubernetes.io/docs/ 4 | 5 | [Service] 6 | ExecStart=/usr/bin/kubelet 7 | Restart=always 8 | StartLimitInterval=0 9 | # NOTE: kind deviates from upstream here with a lower RestartSecuse 10 | RestartSec=1s 11 | 12 | [Install] 13 | WantedBy=multi-user.target 14 | -------------------------------------------------------------------------------- /images/base/version: -------------------------------------------------------------------------------- 1 | v1.15.3 -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package main 18 | 19 | import kubeoperator "github.com/gosoon/kubernetes-operator/cmd/kube-operator" 20 | 21 | func main() { 22 | kubeoperator.Execute() 23 | } 24 | -------------------------------------------------------------------------------- /pkg/apis/ecs/register.go: -------------------------------------------------------------------------------- 1 | package ecs 2 | 3 | const ( 4 | GroupName = "ecs.yun.com" 5 | ) 6 | -------------------------------------------------------------------------------- /pkg/apis/ecs/v1/doc.go: -------------------------------------------------------------------------------- 1 | // Package v1 contains API Schema definitions for the ecs v1 API group 2 | // +k8s:deepcopy-gen=package,register 3 | // +groupName=ecs.yun.com 4 | package v1 5 | -------------------------------------------------------------------------------- /pkg/apis/ecs/v1/register.go: -------------------------------------------------------------------------------- 1 | package v1 2 | 3 | import ( 4 | "github.com/gosoon/kubernetes-operator/pkg/apis/ecs" 5 | 6 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 7 | "k8s.io/apimachinery/pkg/runtime" 8 | "k8s.io/apimachinery/pkg/runtime/schema" 9 | ) 10 | 11 | // SchemeGroupVersion is group version used to register these objects 12 | var SchemeGroupVersion = schema.GroupVersion{Group: ecs.GroupName, Version: "v1"} 13 | 14 | // Kind takes an unqualified kind and returns back a Group qualified GroupKind 15 | func Kind(kind string) schema.GroupKind { 16 | return SchemeGroupVersion.WithKind(kind).GroupKind() 17 | } 18 | 19 | // Resource takes an unqualified resource and returns a Group qualified GroupResource 20 | func Resource(resource string) schema.GroupResource { 21 | return SchemeGroupVersion.WithResource(resource).GroupResource() 22 | } 23 | 24 | var ( 25 | SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes) 26 | AddToScheme = SchemeBuilder.AddToScheme 27 | ) 28 | 29 | // Adds the list of known types to Scheme. 30 | func addKnownTypes(scheme *runtime.Scheme) error { 31 | scheme.AddKnownTypes(SchemeGroupVersion, 32 | &KubernetesCluster{}, 33 | &KubernetesClusterList{}, 34 | ) 35 | metav1.AddToGroupVersion(scheme, SchemeGroupVersion) 36 | return nil 37 | } 38 | -------------------------------------------------------------------------------- /pkg/client/clientset/versioned/clientset.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | package versioned 20 | 21 | import ( 22 | ecsv1 "github.com/gosoon/kubernetes-operator/pkg/client/clientset/versioned/typed/ecs/v1" 23 | discovery "k8s.io/client-go/discovery" 24 | rest "k8s.io/client-go/rest" 25 | flowcontrol "k8s.io/client-go/util/flowcontrol" 26 | ) 27 | 28 | type Interface interface { 29 | Discovery() discovery.DiscoveryInterface 30 | EcsV1() ecsv1.EcsV1Interface 31 | } 32 | 33 | // Clientset contains the clients for groups. Each group has exactly one 34 | // version included in a Clientset. 35 | type Clientset struct { 36 | *discovery.DiscoveryClient 37 | ecsV1 *ecsv1.EcsV1Client 38 | } 39 | 40 | // EcsV1 retrieves the EcsV1Client 41 | func (c *Clientset) EcsV1() ecsv1.EcsV1Interface { 42 | return c.ecsV1 43 | } 44 | 45 | // Discovery retrieves the DiscoveryClient 46 | func (c *Clientset) Discovery() discovery.DiscoveryInterface { 47 | if c == nil { 48 | return nil 49 | } 50 | return c.DiscoveryClient 51 | } 52 | 53 | // NewForConfig creates a new Clientset for the given config. 54 | func NewForConfig(c *rest.Config) (*Clientset, error) { 55 | configShallowCopy := *c 56 | if configShallowCopy.RateLimiter == nil && configShallowCopy.QPS > 0 { 57 | configShallowCopy.RateLimiter = flowcontrol.NewTokenBucketRateLimiter(configShallowCopy.QPS, configShallowCopy.Burst) 58 | } 59 | var cs Clientset 60 | var err error 61 | cs.ecsV1, err = ecsv1.NewForConfig(&configShallowCopy) 62 | if err != nil { 63 | return nil, err 64 | } 65 | 66 | cs.DiscoveryClient, err = discovery.NewDiscoveryClientForConfig(&configShallowCopy) 67 | if err != nil { 68 | return nil, err 69 | } 70 | return &cs, nil 71 | } 72 | 73 | // NewForConfigOrDie creates a new Clientset for the given config and 74 | // panics if there is an error in the config. 75 | func NewForConfigOrDie(c *rest.Config) *Clientset { 76 | var cs Clientset 77 | cs.ecsV1 = ecsv1.NewForConfigOrDie(c) 78 | 79 | cs.DiscoveryClient = discovery.NewDiscoveryClientForConfigOrDie(c) 80 | return &cs 81 | } 82 | 83 | // New creates a new Clientset for the given RESTClient. 84 | func New(c rest.Interface) *Clientset { 85 | var cs Clientset 86 | cs.ecsV1 = ecsv1.New(c) 87 | 88 | cs.DiscoveryClient = discovery.NewDiscoveryClient(c) 89 | return &cs 90 | } 91 | -------------------------------------------------------------------------------- /pkg/client/clientset/versioned/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | // This package has the automatically generated clientset. 20 | package versioned 21 | -------------------------------------------------------------------------------- /pkg/client/clientset/versioned/fake/clientset_generated.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | package fake 20 | 21 | import ( 22 | clientset "github.com/gosoon/kubernetes-operator/pkg/client/clientset/versioned" 23 | ecsv1 "github.com/gosoon/kubernetes-operator/pkg/client/clientset/versioned/typed/ecs/v1" 24 | fakeecsv1 "github.com/gosoon/kubernetes-operator/pkg/client/clientset/versioned/typed/ecs/v1/fake" 25 | "k8s.io/apimachinery/pkg/runtime" 26 | "k8s.io/apimachinery/pkg/watch" 27 | "k8s.io/client-go/discovery" 28 | fakediscovery "k8s.io/client-go/discovery/fake" 29 | "k8s.io/client-go/testing" 30 | ) 31 | 32 | // NewSimpleClientset returns a clientset that will respond with the provided objects. 33 | // It's backed by a very simple object tracker that processes creates, updates and deletions as-is, 34 | // without applying any validations and/or defaults. It shouldn't be considered a replacement 35 | // for a real clientset and is mostly useful in simple unit tests. 36 | func NewSimpleClientset(objects ...runtime.Object) *Clientset { 37 | o := testing.NewObjectTracker(scheme, codecs.UniversalDecoder()) 38 | for _, obj := range objects { 39 | if err := o.Add(obj); err != nil { 40 | panic(err) 41 | } 42 | } 43 | 44 | cs := &Clientset{tracker: o} 45 | cs.discovery = &fakediscovery.FakeDiscovery{Fake: &cs.Fake} 46 | cs.AddReactor("*", "*", testing.ObjectReaction(o)) 47 | cs.AddWatchReactor("*", func(action testing.Action) (handled bool, ret watch.Interface, err error) { 48 | gvr := action.GetResource() 49 | ns := action.GetNamespace() 50 | watch, err := o.Watch(gvr, ns) 51 | if err != nil { 52 | return false, nil, err 53 | } 54 | return true, watch, nil 55 | }) 56 | 57 | return cs 58 | } 59 | 60 | // Clientset implements clientset.Interface. Meant to be embedded into a 61 | // struct to get a default implementation. This makes faking out just the method 62 | // you want to test easier. 63 | type Clientset struct { 64 | testing.Fake 65 | discovery *fakediscovery.FakeDiscovery 66 | tracker testing.ObjectTracker 67 | } 68 | 69 | func (c *Clientset) Discovery() discovery.DiscoveryInterface { 70 | return c.discovery 71 | } 72 | 73 | func (c *Clientset) Tracker() testing.ObjectTracker { 74 | return c.tracker 75 | } 76 | 77 | var _ clientset.Interface = &Clientset{} 78 | 79 | // EcsV1 retrieves the EcsV1Client 80 | func (c *Clientset) EcsV1() ecsv1.EcsV1Interface { 81 | return &fakeecsv1.FakeEcsV1{Fake: &c.Fake} 82 | } 83 | -------------------------------------------------------------------------------- /pkg/client/clientset/versioned/fake/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | // This package has the automatically generated fake clientset. 20 | package fake 21 | -------------------------------------------------------------------------------- /pkg/client/clientset/versioned/fake/register.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | package fake 20 | 21 | import ( 22 | ecsv1 "github.com/gosoon/kubernetes-operator/pkg/apis/ecs/v1" 23 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 24 | runtime "k8s.io/apimachinery/pkg/runtime" 25 | schema "k8s.io/apimachinery/pkg/runtime/schema" 26 | serializer "k8s.io/apimachinery/pkg/runtime/serializer" 27 | utilruntime "k8s.io/apimachinery/pkg/util/runtime" 28 | ) 29 | 30 | var scheme = runtime.NewScheme() 31 | var codecs = serializer.NewCodecFactory(scheme) 32 | var parameterCodec = runtime.NewParameterCodec(scheme) 33 | var localSchemeBuilder = runtime.SchemeBuilder{ 34 | ecsv1.AddToScheme, 35 | } 36 | 37 | // AddToScheme adds all types of this clientset into the given scheme. This allows composition 38 | // of clientsets, like in: 39 | // 40 | // import ( 41 | // "k8s.io/client-go/kubernetes" 42 | // clientsetscheme "k8s.io/client-go/kubernetes/scheme" 43 | // aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" 44 | // ) 45 | // 46 | // kclientset, _ := kubernetes.NewForConfig(c) 47 | // _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) 48 | // 49 | // After this, RawExtensions in Kubernetes types will serialize kube-aggregator types 50 | // correctly. 51 | var AddToScheme = localSchemeBuilder.AddToScheme 52 | 53 | func init() { 54 | v1.AddToGroupVersion(scheme, schema.GroupVersion{Version: "v1"}) 55 | utilruntime.Must(AddToScheme(scheme)) 56 | } 57 | -------------------------------------------------------------------------------- /pkg/client/clientset/versioned/scheme/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | // This package contains the scheme of the automatically generated clientset. 20 | package scheme 21 | -------------------------------------------------------------------------------- /pkg/client/clientset/versioned/scheme/register.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | package scheme 20 | 21 | import ( 22 | ecsv1 "github.com/gosoon/kubernetes-operator/pkg/apis/ecs/v1" 23 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 24 | runtime "k8s.io/apimachinery/pkg/runtime" 25 | schema "k8s.io/apimachinery/pkg/runtime/schema" 26 | serializer "k8s.io/apimachinery/pkg/runtime/serializer" 27 | utilruntime "k8s.io/apimachinery/pkg/util/runtime" 28 | ) 29 | 30 | var Scheme = runtime.NewScheme() 31 | var Codecs = serializer.NewCodecFactory(Scheme) 32 | var ParameterCodec = runtime.NewParameterCodec(Scheme) 33 | var localSchemeBuilder = runtime.SchemeBuilder{ 34 | ecsv1.AddToScheme, 35 | } 36 | 37 | // AddToScheme adds all types of this clientset into the given scheme. This allows composition 38 | // of clientsets, like in: 39 | // 40 | // import ( 41 | // "k8s.io/client-go/kubernetes" 42 | // clientsetscheme "k8s.io/client-go/kubernetes/scheme" 43 | // aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" 44 | // ) 45 | // 46 | // kclientset, _ := kubernetes.NewForConfig(c) 47 | // _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) 48 | // 49 | // After this, RawExtensions in Kubernetes types will serialize kube-aggregator types 50 | // correctly. 51 | var AddToScheme = localSchemeBuilder.AddToScheme 52 | 53 | func init() { 54 | v1.AddToGroupVersion(Scheme, schema.GroupVersion{Version: "v1"}) 55 | utilruntime.Must(AddToScheme(Scheme)) 56 | } 57 | -------------------------------------------------------------------------------- /pkg/client/clientset/versioned/typed/ecs/v1/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | // This package has the automatically generated typed clients. 20 | package v1 21 | -------------------------------------------------------------------------------- /pkg/client/clientset/versioned/typed/ecs/v1/ecs_client.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | package v1 20 | 21 | import ( 22 | v1 "github.com/gosoon/kubernetes-operator/pkg/apis/ecs/v1" 23 | "github.com/gosoon/kubernetes-operator/pkg/client/clientset/versioned/scheme" 24 | rest "k8s.io/client-go/rest" 25 | ) 26 | 27 | type EcsV1Interface interface { 28 | RESTClient() rest.Interface 29 | KubernetesClustersGetter 30 | } 31 | 32 | // EcsV1Client is used to interact with features provided by the ecs.yun.com group. 33 | type EcsV1Client struct { 34 | restClient rest.Interface 35 | } 36 | 37 | func (c *EcsV1Client) KubernetesClusters(namespace string) KubernetesClusterInterface { 38 | return newKubernetesClusters(c, namespace) 39 | } 40 | 41 | // NewForConfig creates a new EcsV1Client for the given config. 42 | func NewForConfig(c *rest.Config) (*EcsV1Client, error) { 43 | config := *c 44 | if err := setConfigDefaults(&config); err != nil { 45 | return nil, err 46 | } 47 | client, err := rest.RESTClientFor(&config) 48 | if err != nil { 49 | return nil, err 50 | } 51 | return &EcsV1Client{client}, nil 52 | } 53 | 54 | // NewForConfigOrDie creates a new EcsV1Client for the given config and 55 | // panics if there is an error in the config. 56 | func NewForConfigOrDie(c *rest.Config) *EcsV1Client { 57 | client, err := NewForConfig(c) 58 | if err != nil { 59 | panic(err) 60 | } 61 | return client 62 | } 63 | 64 | // New creates a new EcsV1Client for the given RESTClient. 65 | func New(c rest.Interface) *EcsV1Client { 66 | return &EcsV1Client{c} 67 | } 68 | 69 | func setConfigDefaults(config *rest.Config) error { 70 | gv := v1.SchemeGroupVersion 71 | config.GroupVersion = &gv 72 | config.APIPath = "/apis" 73 | config.NegotiatedSerializer = scheme.Codecs.WithoutConversion() 74 | 75 | if config.UserAgent == "" { 76 | config.UserAgent = rest.DefaultKubernetesUserAgent() 77 | } 78 | 79 | return nil 80 | } 81 | 82 | // RESTClient returns a RESTClient that is used to communicate 83 | // with API server by this client implementation. 84 | func (c *EcsV1Client) RESTClient() rest.Interface { 85 | if c == nil { 86 | return nil 87 | } 88 | return c.restClient 89 | } 90 | -------------------------------------------------------------------------------- /pkg/client/clientset/versioned/typed/ecs/v1/fake/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | // Package fake has the automatically generated clients. 20 | package fake 21 | -------------------------------------------------------------------------------- /pkg/client/clientset/versioned/typed/ecs/v1/fake/fake_ecs_client.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | package fake 20 | 21 | import ( 22 | v1 "github.com/gosoon/kubernetes-operator/pkg/client/clientset/versioned/typed/ecs/v1" 23 | rest "k8s.io/client-go/rest" 24 | testing "k8s.io/client-go/testing" 25 | ) 26 | 27 | type FakeEcsV1 struct { 28 | *testing.Fake 29 | } 30 | 31 | func (c *FakeEcsV1) KubernetesClusters(namespace string) v1.KubernetesClusterInterface { 32 | return &FakeKubernetesClusters{c, namespace} 33 | } 34 | 35 | // RESTClient returns a RESTClient that is used to communicate 36 | // with API server by this client implementation. 37 | func (c *FakeEcsV1) RESTClient() rest.Interface { 38 | var ret *rest.RESTClient 39 | return ret 40 | } 41 | -------------------------------------------------------------------------------- /pkg/client/clientset/versioned/typed/ecs/v1/generated_expansion.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by client-gen. DO NOT EDIT. 18 | 19 | package v1 20 | 21 | type KubernetesClusterExpansion interface{} 22 | -------------------------------------------------------------------------------- /pkg/client/informers/externalversions/ecs/interface.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by informer-gen. DO NOT EDIT. 18 | 19 | package ecs 20 | 21 | import ( 22 | v1 "github.com/gosoon/kubernetes-operator/pkg/client/informers/externalversions/ecs/v1" 23 | internalinterfaces "github.com/gosoon/kubernetes-operator/pkg/client/informers/externalversions/internalinterfaces" 24 | ) 25 | 26 | // Interface provides access to each of this group's versions. 27 | type Interface interface { 28 | // V1 provides access to shared informers for resources in V1. 29 | V1() v1.Interface 30 | } 31 | 32 | type group struct { 33 | factory internalinterfaces.SharedInformerFactory 34 | namespace string 35 | tweakListOptions internalinterfaces.TweakListOptionsFunc 36 | } 37 | 38 | // New returns a new Interface. 39 | func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { 40 | return &group{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} 41 | } 42 | 43 | // V1 returns a new v1.Interface. 44 | func (g *group) V1() v1.Interface { 45 | return v1.New(g.factory, g.namespace, g.tweakListOptions) 46 | } 47 | -------------------------------------------------------------------------------- /pkg/client/informers/externalversions/ecs/v1/interface.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by informer-gen. DO NOT EDIT. 18 | 19 | package v1 20 | 21 | import ( 22 | internalinterfaces "github.com/gosoon/kubernetes-operator/pkg/client/informers/externalversions/internalinterfaces" 23 | ) 24 | 25 | // Interface provides access to all the informers in this group version. 26 | type Interface interface { 27 | // KubernetesClusters returns a KubernetesClusterInformer. 28 | KubernetesClusters() KubernetesClusterInformer 29 | } 30 | 31 | type version struct { 32 | factory internalinterfaces.SharedInformerFactory 33 | namespace string 34 | tweakListOptions internalinterfaces.TweakListOptionsFunc 35 | } 36 | 37 | // New returns a new Interface. 38 | func New(f internalinterfaces.SharedInformerFactory, namespace string, tweakListOptions internalinterfaces.TweakListOptionsFunc) Interface { 39 | return &version{factory: f, namespace: namespace, tweakListOptions: tweakListOptions} 40 | } 41 | 42 | // KubernetesClusters returns a KubernetesClusterInformer. 43 | func (v *version) KubernetesClusters() KubernetesClusterInformer { 44 | return &kubernetesClusterInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} 45 | } 46 | -------------------------------------------------------------------------------- /pkg/client/informers/externalversions/generic.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by informer-gen. DO NOT EDIT. 18 | 19 | package externalversions 20 | 21 | import ( 22 | "fmt" 23 | 24 | v1 "github.com/gosoon/kubernetes-operator/pkg/apis/ecs/v1" 25 | schema "k8s.io/apimachinery/pkg/runtime/schema" 26 | cache "k8s.io/client-go/tools/cache" 27 | ) 28 | 29 | // GenericInformer is type of SharedIndexInformer which will locate and delegate to other 30 | // sharedInformers based on type 31 | type GenericInformer interface { 32 | Informer() cache.SharedIndexInformer 33 | Lister() cache.GenericLister 34 | } 35 | 36 | type genericInformer struct { 37 | informer cache.SharedIndexInformer 38 | resource schema.GroupResource 39 | } 40 | 41 | // Informer returns the SharedIndexInformer. 42 | func (f *genericInformer) Informer() cache.SharedIndexInformer { 43 | return f.informer 44 | } 45 | 46 | // Lister returns the GenericLister. 47 | func (f *genericInformer) Lister() cache.GenericLister { 48 | return cache.NewGenericLister(f.Informer().GetIndexer(), f.resource) 49 | } 50 | 51 | // ForResource gives generic access to a shared informer of the matching type 52 | // TODO extend this to unknown resources with a client pool 53 | func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource) (GenericInformer, error) { 54 | switch resource { 55 | // Group=ecs.yun.com, Version=v1 56 | case v1.SchemeGroupVersion.WithResource("kubernetesclusters"): 57 | return &genericInformer{resource: resource.GroupResource(), informer: f.Ecs().V1().KubernetesClusters().Informer()}, nil 58 | 59 | } 60 | 61 | return nil, fmt.Errorf("no informer found for %v", resource) 62 | } 63 | -------------------------------------------------------------------------------- /pkg/client/informers/externalversions/internalinterfaces/factory_interfaces.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by informer-gen. DO NOT EDIT. 18 | 19 | package internalinterfaces 20 | 21 | import ( 22 | time "time" 23 | 24 | versioned "github.com/gosoon/kubernetes-operator/pkg/client/clientset/versioned" 25 | v1 "k8s.io/apimachinery/pkg/apis/meta/v1" 26 | runtime "k8s.io/apimachinery/pkg/runtime" 27 | cache "k8s.io/client-go/tools/cache" 28 | ) 29 | 30 | // NewInformerFunc takes versioned.Interface and time.Duration to return a SharedIndexInformer. 31 | type NewInformerFunc func(versioned.Interface, time.Duration) cache.SharedIndexInformer 32 | 33 | // SharedInformerFactory a small interface to allow for adding an informer without an import cycle 34 | type SharedInformerFactory interface { 35 | Start(stopCh <-chan struct{}) 36 | InformerFor(obj runtime.Object, newFunc NewInformerFunc) cache.SharedIndexInformer 37 | } 38 | 39 | // TweakListOptionsFunc is a function that transforms a v1.ListOptions. 40 | type TweakListOptionsFunc func(*v1.ListOptions) 41 | -------------------------------------------------------------------------------- /pkg/client/listers/ecs/v1/expansion_generated.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | // Code generated by lister-gen. DO NOT EDIT. 18 | 19 | package v1 20 | 21 | // KubernetesClusterListerExpansion allows custom methods to be added to 22 | // KubernetesClusterLister. 23 | type KubernetesClusterListerExpansion interface{} 24 | 25 | // KubernetesClusterNamespaceListerExpansion allows custom methods to be added to 26 | // KubernetesClusterNamespaceLister. 27 | type KubernetesClusterNamespaceListerExpansion interface{} 28 | -------------------------------------------------------------------------------- /pkg/container/docker/cp.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package docker 18 | 19 | import ( 20 | "github.com/gosoon/kubernetes-operator/pkg/exec" 21 | ) 22 | 23 | // CopyTo copies the file at hostPath to the container at destPath 24 | func CopyTo(hostPath, containerNameOrID, destPath string) error { 25 | cmd := exec.Command( 26 | "docker", "cp", 27 | hostPath, // from the source file 28 | containerNameOrID+":"+destPath, // to the node, at dest 29 | ) 30 | return cmd.Run() 31 | } 32 | 33 | // CopyFrom copies the file or dir in the container at srcPath to the host at hostPath 34 | func CopyFrom(containerNameOrID, srcPath, hostPath string) error { 35 | cmd := exec.Command( 36 | "docker", "cp", 37 | containerNameOrID+":"+srcPath, // from the node, at src 38 | hostPath, // to the host 39 | ) 40 | return cmd.Run() 41 | } 42 | -------------------------------------------------------------------------------- /pkg/container/docker/pull.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package docker 18 | 19 | import ( 20 | "os/exec" 21 | "time" 22 | 23 | "github.com/gosoon/glog" 24 | ) 25 | 26 | // PullIfNotPresent will pull an image if it is not present locally 27 | // retrying up to retries times 28 | // it returns true if it attempted to pull, and any errors from pulling 29 | func PullIfNotPresent(image string, retries int) (bool, error) { 30 | cmd := exec.Command("docker", "inspect", image) 31 | if err := cmd.Run(); err != nil { 32 | glog.Infof("Image: %s present locally", image) 33 | return false, nil 34 | } 35 | return pull(image, retries) 36 | 37 | } 38 | 39 | // Pull pulls an image, retrying up to retries times 40 | func pull(image string, retries int) (bool, error) { 41 | glog.Infof("Pulling image: %s ...", image) 42 | err := exec.Command("docker", "pull", image).Run() 43 | // retry pulling up to retries times if necessary 44 | if err != nil { 45 | for i := 0; i < retries; i++ { 46 | time.Sleep(time.Second * time.Duration(i)) 47 | glog.Infof("Trying again to pull image: %s ...", image) 48 | err = exec.Command("docker", "pull", image).Run() 49 | if err == nil { 50 | break 51 | } 52 | } 53 | } 54 | 55 | if err != nil { 56 | glog.Infof("Failed to pull image: %s", image) 57 | return false, err 58 | } 59 | return true, nil 60 | } 61 | -------------------------------------------------------------------------------- /pkg/container/docker/run.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package docker 18 | 19 | import ( 20 | "github.com/gosoon/glog" 21 | "github.com/gosoon/kubernetes-operator/pkg/exec" 22 | ) 23 | 24 | // RunOpt is an option for Run 25 | type RunOpt func(*runOpts) *runOpts 26 | 27 | // actual options struct 28 | type runOpts struct { 29 | RunArgs []string 30 | ContainerArgs []string 31 | } 32 | 33 | // WithRunArgs sets the args for docker run 34 | // as in the args portion of `docker run args... image containerArgs...` 35 | func WithRunArgs(args ...string) RunOpt { 36 | return func(r *runOpts) *runOpts { 37 | r.RunArgs = args 38 | return r 39 | } 40 | } 41 | 42 | // WithContainerArgs sets the args to the container 43 | // as in the containerArgs portion of `docker run args... image containerArgs...` 44 | // NOTE: this is only the args portion before the image 45 | func WithContainerArgs(args ...string) RunOpt { 46 | return func(r *runOpts) *runOpts { 47 | r.ContainerArgs = args 48 | return r 49 | } 50 | } 51 | 52 | // Run creates a container with "docker run", with some error handling 53 | func Run(image string, opts ...RunOpt) error { 54 | o := &runOpts{} 55 | for _, opt := range opts { 56 | o = opt(o) 57 | } 58 | 59 | // construct the actual docker run argv 60 | args := []string{"run"} 61 | args = append(args, o.RunArgs...) 62 | args = append(args, image) 63 | cmd := exec.Command("docker", args...) 64 | 65 | output, err := exec.CombinedOutputLines(cmd) 66 | if err != nil { 67 | // log error output if there was any 68 | for _, line := range output { 69 | glog.Error(line) 70 | } 71 | return err 72 | } 73 | return nil 74 | } 75 | -------------------------------------------------------------------------------- /pkg/controller/cluster_precheck_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package controller 18 | 19 | import ( 20 | "testing" 21 | 22 | ecsv1 "github.com/gosoon/kubernetes-operator/pkg/apis/ecs/v1" 23 | ecsfake "github.com/gosoon/kubernetes-operator/pkg/client/clientset/versioned/fake" 24 | informers "github.com/gosoon/kubernetes-operator/pkg/client/informers/externalversions" 25 | "github.com/gosoon/kubernetes-operator/pkg/enum" 26 | 27 | "github.com/stretchr/testify/assert" 28 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 29 | "k8s.io/client-go/kubernetes/fake" 30 | "k8s.io/kubernetes/pkg/controller" 31 | ) 32 | 33 | func TestProcessClusterPrecheck(t *testing.T) { 34 | fakeClient := fake.NewSimpleClientset() 35 | kubernetesClusterClient := ecsfake.NewSimpleClientset() 36 | informerFactory := informers.NewSharedInformerFactory(kubernetesClusterClient, controller.NoResyncPeriodFunc()) 37 | ecsv1Controller := NewController(fakeClient, kubernetesClusterClient, 38 | informerFactory.Ecs().V1().KubernetesClusters()) 39 | ecsv1Controller.kubernetesClusterSynced = alwaysReady 40 | 41 | testCases := []*ecsv1.KubernetesCluster{ 42 | &ecsv1.KubernetesCluster{ 43 | ObjectMeta: metav1.ObjectMeta{ 44 | Name: "test-1", 45 | }, 46 | Status: ecsv1.KubernetesClusterStatus{ 47 | Phase: enum.Running, 48 | }, 49 | }, 50 | &ecsv1.KubernetesCluster{ 51 | ObjectMeta: metav1.ObjectMeta{ 52 | Name: "test-2", 53 | }, 54 | Status: ecsv1.KubernetesClusterStatus{ 55 | Phase: enum.Failed, 56 | }, 57 | }, 58 | } 59 | 60 | for _, test := range testCases { 61 | _, err := kubernetesClusterClient.EcsV1().KubernetesClusters("").Create(test) 62 | if err != nil { 63 | t.Fatalf("error injecting ecs add: %v", err) 64 | } 65 | err = ecsv1Controller.processClusterPrecheck(test) 66 | if !assert.Equal(t, nil, err) { 67 | t.Fatalf("expected: %v but get %v", nil, err) 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /pkg/enum/task.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package enum 18 | 19 | import ecsv1 "github.com/gosoon/kubernetes-operator/pkg/apis/ecs/v1" 20 | 21 | const ( 22 | // Operation is operate annotation key 23 | Operation = "app.kubernetes.io/operation" 24 | 25 | // Spec is echo operate success and record the spec 26 | Spec = "app.kubernetes.io/spec" 27 | 28 | // state 29 | KubeCreating = string("creating") 30 | KubeCreateFailed = string("create-failed") 31 | KubeCreateFinished = string("create-finished") 32 | KubeScalingUp = string("scaling-up") 33 | KubeScaleUpFailed = string("scale-up-failed") 34 | KubeScaleUpFinished = string("scale-up-finished") 35 | KubeScalingDown = string("scaling-down") 36 | KubeScaleDownFailed = string("scale-down-failed") 37 | KubeScaleDownFinished = string("scale-down-finished") 38 | KubeTerminating = string("terminating") 39 | KubeTerminateFinished = string("terminate-finished") 40 | KubeTerminateFailed = string("terminate-failed") 41 | 42 | // TODO:to do it 43 | KubeUpdating = string("updating") 44 | KubeUpdateFailed = string("update-failed") 45 | KubeUpdateFinished = string("update-finished") 46 | KubeRollbacking = string("rollbacking") 47 | KubeRollbackFailed = string("rollback-failed") 48 | KubeRollbackFinished = string("rollback-finished") 49 | 50 | // phase 51 | New = ecsv1.KubernetesOperatorPhase("") 52 | Creating = ecsv1.KubernetesOperatorPhase("Creating") 53 | Prechecking = ecsv1.KubernetesOperatorPhase("Prechecking") 54 | Scaling = ecsv1.KubernetesOperatorPhase("Scaling") 55 | Running = ecsv1.KubernetesOperatorPhase("Running") 56 | Failed = ecsv1.KubernetesOperatorPhase("Failed") 57 | Terminating = ecsv1.KubernetesOperatorPhase("Terminating") 58 | 59 | // event message 60 | EcsSyncSuccess = string("ecs synced successfully") 61 | 62 | // event reason 63 | SyncedSuccess = string("Synced") 64 | 65 | // job events 66 | CreateKubeJobSuccess = string("CreateKubeJobSuccess") 67 | CreateKubeJobFailed = string("CreateKubeJobFailed") 68 | CreateScaleUpJobSuccess = string("CreateScaleUpJobSuccess") 69 | CreateScaleUpJobFailed = string("CreateScaleUpJobFailed") 70 | CreateScaleDownJobSuccess = string("CreateScaleDownJobSuccess") 71 | CreateScaleDownJobFailed = string("CreateScaleDownJobFailed") 72 | SetFinalizersSuccess = string("SetFinalizersSuccess") 73 | SetFinalizersFailed = string("SetFinalizersFailed") 74 | DeleteKubeJobSuccess = string("DeleteKubeJobSuccess") 75 | DeleteKubeJobFailed = string("DeleteKubeJobFailed") 76 | ) 77 | -------------------------------------------------------------------------------- /pkg/exec/local.go: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright 2018 The Kubernetes Authors. 3 | 4 | Licensed under the Apache License, Version 2.0 (the "License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing, software 11 | distributed under the License is distributed on an "AS IS" BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | 17 | package exec 18 | 19 | import ( 20 | "io" 21 | osexec "os/exec" 22 | 23 | "github.com/gosoon/glog" 24 | ) 25 | 26 | // LocalCmd wraps os/exec.Cmd, implementing interface 27 | type LocalCmd struct { 28 | *osexec.Cmd 29 | } 30 | 31 | var _ Cmd = &LocalCmd{} 32 | 33 | // LocalCmder is a factory for LocalCmd, implementing Cmder 34 | type LocalCmder struct{} 35 | 36 | var _ Cmder = &LocalCmder{} 37 | 38 | // Command returns a new exec.Cmd backed by Cmd 39 | func (c *LocalCmder) Command(name string, arg ...string) Cmd { 40 | return &LocalCmd{ 41 | Cmd: osexec.Command(name, arg...), 42 | } 43 | } 44 | 45 | // SetEnv sets env 46 | func (cmd *LocalCmd) SetEnv(env ...string) Cmd { 47 | cmd.Env = env 48 | return cmd 49 | } 50 | 51 | // SetStdin sets stdin 52 | func (cmd *LocalCmd) SetStdin(r io.Reader) Cmd { 53 | cmd.Stdin = r 54 | return cmd 55 | } 56 | 57 | // SetStdout set stdout 58 | func (cmd *LocalCmd) SetStdout(w io.Writer) Cmd { 59 | cmd.Stdout = w 60 | return cmd 61 | } 62 | 63 | // SetStderr sets stderr 64 | func (cmd *LocalCmd) SetStderr(w io.Writer) Cmd { 65 | cmd.Stderr = w 66 | return cmd 67 | } 68 | 69 | // Run runs 70 | func (cmd *LocalCmd) Run() error { 71 | glog.Infof("Running: %v %v", cmd.Path, cmd.Args) 72 | return cmd.Cmd.Run() 73 | } 74 | -------------------------------------------------------------------------------- /pkg/installer/cluster/constants/constants.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package constants 18 | 19 | // DefaultClusterName is the default cluster Context name 20 | const DefaultClusterName = "default" 21 | 22 | const ( 23 | // ExternalLoadBalancerNodeRoleValue identifies a node that hosts an 24 | // external load balancer for the API server in HA configurations. 25 | ExternalLoadBalancerNodeRoleValue string = "external-load-balancer" 26 | 27 | // ExternalEtcdNodeRoleValue identifies a node that hosts an external-etcd 28 | // instance. 29 | // 30 | // WARNING: this node type is not yet implemented! 31 | // 32 | ExternalEtcdNodeRoleValue string = "external-etcd" 33 | 34 | // InstallPath is write kubeadm config default path 35 | InstallPath string = "/tmp/install/" 36 | ) 37 | -------------------------------------------------------------------------------- /pkg/installer/cluster/context.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package cluster 18 | 19 | import ( 20 | "github.com/gosoon/kubernetes-operator/pkg/installer/cluster/constants" 21 | "github.com/gosoon/kubernetes-operator/pkg/installer/cluster/create" 22 | internalcontext "github.com/gosoon/kubernetes-operator/pkg/internal/cluster/context" 23 | internalcreate "github.com/gosoon/kubernetes-operator/pkg/internal/cluster/create" 24 | "google.golang.org/grpc" 25 | ) 26 | 27 | // DefaultName is the default cluster name 28 | const DefaultName = constants.DefaultClusterName 29 | 30 | // Context is used to create / manipulate kubernetes-in-docker clusters 31 | // See: NewContext() 32 | type Context struct { 33 | // the internal context type, shared between implementations of more 34 | // advanced methods like create 35 | ic *internalcontext.Context 36 | } 37 | 38 | // NewContext returns a new cluster management context 39 | // if name is "" the default name will be used (constants.DefaultClusterName) 40 | func NewContext(name string, server *grpc.Server, port string) *Context { 41 | // wrap a new internal context 42 | return &Context{ 43 | ic: internalcontext.NewContext(name, server, port), 44 | } 45 | } 46 | 47 | // Create provisions and starts a kubernetes-in-docker cluster 48 | func (c *Context) Create(options ...create.ClusterOption) error { 49 | return internalcreate.Cluster(c.ic, options...) 50 | } 51 | -------------------------------------------------------------------------------- /pkg/installer/cluster/nodes/command.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package nodes 18 | 19 | import ( 20 | "github.com/gosoon/kubernetes-operator/pkg/exec" 21 | ) 22 | 23 | // Command returns a new exec.Cmd that will run on the node 24 | func Command(command string, args ...string) exec.Cmd { 25 | return exec.Command(command, args...) 26 | } 27 | -------------------------------------------------------------------------------- /pkg/installer/cluster/nodes/role.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package nodes 18 | 19 | import ( 20 | ecsv1 "github.com/gosoon/kubernetes-operator/pkg/apis/ecs/v1" 21 | "github.com/gosoon/kubernetes-operator/pkg/internal/apis/config" 22 | 23 | "github.com/pkg/errors" 24 | ) 25 | 26 | // BootstrapControlPlaneNode returns a handle to the bootstrap control plane node 27 | func BootstrapControlPlaneNode(allNodes []config.Node) (*config.Node, error) { 28 | controlPlaneNode := &config.Node{} 29 | for _, node := range allNodes { 30 | if node.Role == ecsv1.ControlPlaneRole { 31 | controlPlaneNode.IP = node.IP 32 | controlPlaneNode.Role = node.Role 33 | } 34 | } 35 | 36 | if controlPlaneNode == nil { 37 | return nil, errors.Errorf( 38 | "expected at least one %s node", 39 | ecsv1.ControlPlaneRole, 40 | ) 41 | } 42 | return controlPlaneNode, nil 43 | } 44 | -------------------------------------------------------------------------------- /pkg/installer/cluster/nodes/systemd.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package nodes 18 | 19 | const ( 20 | // KubeletServicePath is systemd service path 21 | KubeletServicePath = "/usr/lib/systemd/system/kubelet.service" 22 | 23 | KubeletServiceConfigDir = "/usr/lib/systemd/system/kubelet.service.d/" 24 | KubeletServicrDefaultConfig = "/etc/sysconfig/kubelet" 25 | ) 26 | 27 | // slightly modified from 28 | // https://github.com/kubernetes/kubernetes/blob/ba8fcafaf8c502a454acd86b728c857932555315/build/debs/kubelet.service 29 | const KubeletServiceContents = `[Unit] 30 | Description=kubelet: The Kubernetes Node Agent 31 | Documentation=http://kubernetes.io/docs/ 32 | 33 | [Service] 34 | ExecStart=/usr/bin/kubelet --address=127.0.0.1 --pod-manifest-path=/etc/kubernetes/manifests --cgroup-driver=systemd 35 | Restart=always 36 | StartLimitInterval=0 37 | RestartSec=10 38 | 39 | 40 | [Install] 41 | WantedBy=multi-user.target 42 | ` 43 | 44 | // https://github.com/kubernetes/kubernetes/blob/ba8fcafaf8c502a454acd86b728c857932555315/build/debs/10-kubeadm.conf 45 | const Kubeadm10conf = `# Note: This dropin only works with kubeadm and kubelet v1.11+ 46 | [Service] 47 | Environment="KUBELET_KUBECONFIG_ARGS=--bootstrap-kubeconfig=/etc/kubernetes/bootstrap-kubelet.conf --kubeconfig=/etc/kubernetes/kubelet.conf" 48 | Environment="KUBELET_CONFIG_ARGS=--config=/var/lib/kubelet/config.yaml" 49 | # This is a file that "kubeadm init" and "kubeadm join" generates at runtime, populating the KUBELET_KUBEADM_ARGS variable dynamically 50 | EnvironmentFile=-/var/lib/kubelet/kubeadm-flags.env 51 | # This is a file that the user can use for overrides of the kubelet args as a last resort. Preferably, the user should use 52 | # the .NodeRegistration.KubeletExtraArgs object in the configuration files instead. KUBELET_EXTRA_ARGS should be sourced from this file. 53 | EnvironmentFile=-/etc/default/kubelet 54 | ExecStart= 55 | ExecStart=/usr/bin/kubelet $KUBELET_KUBECONFIG_ARGS $KUBELET_CONFIG_ARGS $KUBELET_KUBEADM_ARGS $KUBELET_EXTRA_ARGS 56 | ` 57 | -------------------------------------------------------------------------------- /pkg/installer/grpc/agent/server_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package agent 18 | 19 | import ( 20 | "net" 21 | "testing" 22 | 23 | "github.com/gosoon/glog" 24 | ecsv1 "github.com/gosoon/kubernetes-operator/pkg/apis/ecs/v1" 25 | installerv1 "github.com/gosoon/kubernetes-operator/pkg/apis/installer/v1" 26 | 27 | "google.golang.org/grpc" 28 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 29 | ) 30 | 31 | const port = "10023" 32 | 33 | func TestInstallCluster(t *testing.T) { 34 | // start grpc server 35 | l, err := net.Listen("tcp", ":"+"10023") 36 | if err != nil { 37 | glog.Fatalf("failed to listen: %v", err) 38 | } 39 | server := grpc.NewServer() 40 | agent := NewAgent(&Options{ 41 | Server: server, 42 | Port: port, 43 | }) 44 | 45 | // register grpc server 46 | installerv1.RegisterInstallerServer(server, agent) 47 | 48 | go func() { 49 | glog.Fatal(server.Serve(l)) 50 | }() 51 | 52 | kubernetesCluster := &ecsv1.KubernetesCluster{ 53 | TypeMeta: metav1.TypeMeta{ 54 | Kind: "KubernetesCluster", 55 | APIVersion: "ecs.yun.com/v1", 56 | }, 57 | ObjectMeta: metav1.ObjectMeta{ 58 | Name: "test", 59 | Namespace: "default", 60 | }, 61 | Spec: ecsv1.KubernetesClusterSpec{ 62 | Cluster: ecsv1.Cluster{ 63 | ClusterType: ecsv1.KubernetesClusterType, 64 | PodCIDR: "192.168.0.0/16", 65 | ServiceCIDR: "10.233.0.0/18", 66 | MasterList: []ecsv1.Node{{IP: "192.168.72.224", Role: ecsv1.ControlPlaneRole}}, 67 | ExternalLoadBalancer: "127.0.0.1", 68 | Region: "default", 69 | KubeVersion: "v1.15.3", 70 | }, 71 | }, 72 | } 73 | 74 | err = agent.ClusterNew(kubernetesCluster) 75 | if err != nil { 76 | glog.Error(err) 77 | } 78 | 79 | } 80 | -------------------------------------------------------------------------------- /pkg/installer/grpc/agent/util.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package agent 18 | 19 | import ( 20 | "sort" 21 | 22 | ecsv1 "github.com/gosoon/kubernetes-operator/pkg/apis/ecs/v1" 23 | ) 24 | 25 | type nodeList []ecsv1.Node 26 | 27 | func (n nodeList) Less(i, j int) bool { return n[i].IP < n[j].IP } 28 | func (n nodeList) Swap(i, j int) { n[i], n[j] = n[j], n[i] } 29 | func (n nodeList) Len() int { return len(n) } 30 | 31 | // injectClusterNodeRole is set role for cluster all nodes 32 | // when installing a cluster, kubeadm first install a controlplane,then secondarycontrolplane should join controlplane, 33 | // the workers node also join controlplane 34 | // ps: 35 | // this action is implementation in server at first,because proto3 not support type define alias,the NodeRole is a NodeRole type not string 36 | // in order to reduce complexity so can do it in agent 37 | func injectClusterNodeRole(cluster *ecsv1.KubernetesCluster) *ecsv1.KubernetesCluster { 38 | // set master role 39 | // grpc server select some node and set to ControlPlaneRole,SecondaryControlPlaneRole,WorkerRole 40 | if len(cluster.Spec.Cluster.MasterList) > 0 { 41 | masterList := cluster.Spec.Cluster.MasterList 42 | sort.Sort(nodeList(masterList)) 43 | for idx, master := range cluster.Spec.Cluster.MasterList { 44 | cluster.Spec.Cluster.MasterList[idx].Role = ecsv1.SecondaryControlPlaneRole 45 | if master.IP == masterList[0].IP { 46 | cluster.Spec.Cluster.MasterList[idx].Role = ecsv1.ControlPlaneRole 47 | } 48 | } 49 | } 50 | 51 | // set node role,default all node is worker 52 | if len(cluster.Spec.Cluster.NodeList) > 0 { 53 | for idx := range cluster.Spec.Cluster.NodeList { 54 | cluster.Spec.Cluster.NodeList[idx].Role = ecsv1.WorkerRole 55 | } 56 | } 57 | 58 | return cluster 59 | } 60 | -------------------------------------------------------------------------------- /pkg/installer/grpc/server/install.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package server 18 | 19 | import ( 20 | "context" 21 | 22 | "github.com/gosoon/glog" 23 | ecsv1 "github.com/gosoon/kubernetes-operator/pkg/apis/ecs/v1" 24 | "github.com/gosoon/kubernetes-operator/pkg/installer/util/protobuf" 25 | ) 26 | 27 | // ClusterNew is creating a new cluster 28 | func (inst *installer) ClusterNew(cluster *ecsv1.KubernetesCluster) error { 29 | clusterRequest, err := protobuf.ClusterConvertToProtobuf(cluster) 30 | if err != nil { 31 | glog.Errorf("clusterRequest convert to protobuf failed with:%v", err) 32 | return err 33 | } 34 | 35 | _, err = inst.InstallCluster(context.Background(), clusterRequest) 36 | if err != nil { 37 | glog.Errorf("installCluster failed with %v", err) 38 | return err 39 | } 40 | 41 | return nil 42 | } 43 | 44 | // ClusterScaleUp is scale up a cluster node 45 | func (inst *installer) ClusterScaleUp(cluster *ecsv1.KubernetesCluster, scaleUpNodeList []ecsv1.Node) error { 46 | // TODO 47 | return nil 48 | } 49 | 50 | // ClusterScaleDown is scale down a cluster node 51 | func (inst *installer) ClusterScaleDown(cluster *ecsv1.KubernetesCluster, scaleDownNodeList []ecsv1.Node) error { 52 | // TODO 53 | return nil 54 | } 55 | 56 | // ClusterTerminating is delete a cluster 57 | func (inst *installer) ClusterTerminating(cluster *ecsv1.KubernetesCluster) error { 58 | // TODO 59 | return nil 60 | } 61 | -------------------------------------------------------------------------------- /pkg/installer/grpc/server/util.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package server 18 | 19 | import installerv1 "github.com/gosoon/kubernetes-operator/pkg/apis/installer/v1" 20 | 21 | // injectClusterConfig is set some config by server,eg:image registry and node role 22 | // current only inject images registry 23 | func (inst *installer) injectClusterConfig(cluster *installerv1.KubernetesClusterRequest) *installerv1.KubernetesClusterRequest { 24 | cluster.Spec.Cluster.ImagesRegistry = inst.opt.ImagesRegistry 25 | return cluster 26 | } 27 | -------------------------------------------------------------------------------- /pkg/installer/interface.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package installer 18 | 19 | import ( 20 | ecsv1 "github.com/gosoon/kubernetes-operator/pkg/apis/ecs/v1" 21 | ) 22 | 23 | // Interface is a installer interface define all installer implementation operation 24 | // you can define your self installer 25 | type Interface interface { 26 | // ClusterNew is creating a new cluster 27 | ClusterNew(cluster *ecsv1.KubernetesCluster) error 28 | 29 | // ClusterScaleUp is scale up a cluster node 30 | ClusterScaleUp(cluster *ecsv1.KubernetesCluster, scaleUpNodeList []ecsv1.Node) error 31 | 32 | // ClusterScaleDown is scale down a cluster node 33 | ClusterScaleDown(cluster *ecsv1.KubernetesCluster, scaleDownNodeList []ecsv1.Node) error 34 | 35 | // ClusterTerminating is delete a cluster 36 | ClusterTerminating(cluster *ecsv1.KubernetesCluster) error 37 | } 38 | -------------------------------------------------------------------------------- /pkg/installer/ssh/batchjob_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package ssh 18 | 19 | import ( 20 | "testing" 21 | 22 | ecsv1 "github.com/gosoon/kubernetes-operator/pkg/apis/ecs/v1" 23 | "github.com/gosoon/kubernetes-operator/pkg/enum" 24 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 25 | ) 26 | 27 | func TestNewCreateKubernetesClusterJob(t *testing.T) { 28 | testCases := []*ecsv1.KubernetesCluster{ 29 | &ecsv1.KubernetesCluster{ 30 | ObjectMeta: metav1.ObjectMeta{ 31 | Name: "test-1", 32 | }, 33 | Status: ecsv1.KubernetesClusterStatus{ 34 | Phase: enum.Running, 35 | }, 36 | }, 37 | } 38 | for _, test := range testCases { 39 | _ = newCreateKubernetesClusterJob(test) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /pkg/installer/ssh/configmap.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package ssh 18 | 19 | import ( 20 | "fmt" 21 | 22 | "github.com/gosoon/kubernetes-operator/pkg/apis/ecs" 23 | ecsv1 "github.com/gosoon/kubernetes-operator/pkg/apis/ecs/v1" 24 | "github.com/gosoon/kubernetes-operator/pkg/enum" 25 | "github.com/gosoon/kubernetes-operator/pkg/utils/pointer" 26 | 27 | corev1 "k8s.io/api/core/v1" 28 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 29 | "k8s.io/apimachinery/pkg/util/uuid" 30 | ) 31 | 32 | // newConfigMap is record all operate for echo kubernetes cluster. 33 | // TODO: set ttl for operate 34 | func newConfigMap(cluster *ecsv1.KubernetesCluster, jobName string) *corev1.ConfigMap { 35 | name := fmt.Sprintf("kube-%s-%s", cluster.Annotations[enum.Operation], string(uuid.NewUUID())[0:5]) 36 | configMap := &corev1.ConfigMap{ 37 | ObjectMeta: metav1.ObjectMeta{ 38 | Name: name, 39 | Namespace: cluster.Namespace, 40 | OwnerReferences: []metav1.OwnerReference{ 41 | { 42 | APIVersion: fmt.Sprintf("%v/v1", ecs.GroupName), 43 | Kind: Kind, 44 | Name: cluster.Name, 45 | UID: cluster.UID, 46 | Controller: pointer.BoolPtr(true), 47 | BlockOwnerDeletion: pointer.BoolPtr(true), 48 | }, 49 | }, 50 | }, 51 | Data: map[string]string{"job-name": jobName}, 52 | } 53 | return configMap 54 | } 55 | -------------------------------------------------------------------------------- /pkg/installer/ssh/job_ttl.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package ssh 18 | 19 | import ( 20 | "fmt" 21 | "time" 22 | 23 | ecsv1 "github.com/gosoon/kubernetes-operator/pkg/apis/ecs/v1" 24 | "github.com/gosoon/kubernetes-operator/pkg/enum" 25 | 26 | "github.com/gosoon/glog" 27 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 28 | "k8s.io/apimachinery/pkg/util/wait" 29 | ) 30 | 31 | const ( 32 | // retry 33 | period = 10 * time.Second 34 | 35 | // ten minutes timeout 36 | timeout = int64(10 * 60) 37 | ) 38 | 39 | // jobTTLControl is handle job create failed or job running timeout. 40 | func (inst *installer) jobTTLControl(cluster *ecsv1.KubernetesCluster) { 41 | name := cluster.Name 42 | namespace := cluster.Namespace 43 | 44 | stopCh := make(chan struct{}) 45 | defer close(stopCh) 46 | 47 | wait.Until(func() { 48 | curCluster, err := inst.opt.KubernetesClusterClientset.EcsV1().KubernetesClusters(namespace).Get(name, metav1.GetOptions{}) 49 | if err != nil { 50 | glog.Errorf("get %s/%s kubernetesCluster object failed with:%v", namespace, name, err) 51 | stopCh <- struct{}{} 52 | return 53 | } 54 | 55 | // if job finished and return 56 | oldOperation := cluster.Annotations[enum.Operation] 57 | newOperation := curCluster.Annotations[enum.Operation] 58 | if oldOperation != newOperation { 59 | stopCh <- struct{}{} 60 | return 61 | } 62 | 63 | // TODO: handle job failed 64 | // if job running timeout and set operation status to failed 65 | lastTransitionTime := cluster.Status.LastTransitionTime.Unix() 66 | nowTime := time.Now().Unix() 67 | if nowTime-lastTransitionTime > timeout { 68 | curCluster = curCluster.DeepCopy() 69 | // update kubernetesCluster annotation operation and status 70 | curCluster.Status.Reason = fmt.Sprintf("the [%v] job running timeout(>%vs)", oldOperation, timeout) 71 | curCluster.Status.Phase = enum.Failed 72 | curCluster.Status.LastTransitionTime = metav1.Now() 73 | _, err := inst.opt.KubernetesClusterClientset.EcsV1().KubernetesClusters(namespace).UpdateStatus(curCluster) 74 | if err != nil { 75 | glog.Errorf("jobTTLTimeout update %s/%s cluster status failed with:%v", namespace, name, err) 76 | } 77 | stopCh <- struct{}{} 78 | return 79 | } 80 | }, period, stopCh) 81 | } 82 | -------------------------------------------------------------------------------- /pkg/installer/ssh/ssh.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package ssh 18 | 19 | import ( 20 | clientset "github.com/gosoon/kubernetes-operator/pkg/client/clientset/versioned" 21 | 22 | "k8s.io/client-go/kubernetes" 23 | "k8s.io/client-go/tools/record" 24 | ) 25 | 26 | // Options is ssh installer must flags. 27 | type Options struct { 28 | Kubeclientset kubernetes.Interface 29 | KubernetesClusterClientset clientset.Interface 30 | Recorder record.EventRecorder 31 | } 32 | 33 | type installer struct { 34 | opt *Options 35 | } 36 | 37 | // NewSSHInstaller is new a ssh installer object. 38 | func NewSSHInstaller(o *Options) *installer { 39 | return &installer{opt: o} 40 | } 41 | -------------------------------------------------------------------------------- /pkg/internal/apis/config/encoding/scheme.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package encoding 18 | 19 | import ( 20 | ecsv1 "github.com/gosoon/kubernetes-operator/pkg/apis/ecs/v1" 21 | "github.com/gosoon/kubernetes-operator/pkg/internal/apis/config" 22 | "github.com/gosoon/kubernetes-operator/pkg/internal/cluster/kubeadm" 23 | ) 24 | 25 | // Ecsv1ToInternalCluster is convert ecsv1.KubernetesCluster to internal cluster config 26 | func Ecsv1ToInternalCluster(cluster *ecsv1.KubernetesCluster, nodeAddress string) *config.Cluster { 27 | out := &config.Cluster{ 28 | ExternalLoadBalancer: cluster.Spec.Cluster.ExternalLoadBalancer, 29 | Networking: config.Networking{ 30 | APIServerPort: kubeadm.APIServerPort, 31 | APIServerAddress: nodeAddress, 32 | PodSubnet: cluster.Spec.Cluster.PodCIDR, 33 | ServiceSubnet: cluster.Spec.Cluster.ServiceCIDR, 34 | }, 35 | KubeVersion: cluster.Spec.Cluster.KubeVersion, 36 | } 37 | 38 | var clusterNodeList []ecsv1.Node 39 | clusterNodeList = append(clusterNodeList, cluster.Spec.Cluster.NodeList...) 40 | clusterNodeList = append(clusterNodeList, cluster.Spec.Cluster.MasterList...) 41 | 42 | var workerList []config.Node 43 | for _, node := range clusterNodeList { 44 | workerList = append(workerList, config.Node{ 45 | IP: node.IP, 46 | Role: node.Role, 47 | }) 48 | } 49 | out.Nodes = workerList 50 | return out 51 | } 52 | -------------------------------------------------------------------------------- /pkg/internal/cluster/context/context.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package context 18 | 19 | import ( 20 | "github.com/gosoon/kubernetes-operator/pkg/installer/cluster/constants" 21 | createtypes "github.com/gosoon/kubernetes-operator/pkg/internal/cluster/create/types" 22 | "google.golang.org/grpc" 23 | ) 24 | 25 | // Context is the private shared context underlying pkg/cluster.Context 26 | // 27 | // NOTE: this is the internal one, it should contain reasonably trivial 28 | // methods that are safe to share between various user facing methods 29 | // pkg/cluster.Context is a superset of this, packages like create and delete 30 | // consume this 31 | type Context struct { 32 | Name string 33 | ClusterOptions *createtypes.ClusterOptions 34 | Server *grpc.Server 35 | Port string 36 | } 37 | 38 | // NewContext returns a new internal cluster management context 39 | // if name is "" the default name will be used 40 | func NewContext(name string, server *grpc.Server, port string) *Context { 41 | if name == "" { 42 | name = constants.DefaultClusterName 43 | } 44 | return &Context{ 45 | Name: name, 46 | Server: server, 47 | Port: port, 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /pkg/internal/cluster/create/actions/action.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package actions 18 | 19 | import ( 20 | createtypes "github.com/gosoon/kubernetes-operator/pkg/internal/cluster/create/types" 21 | "github.com/gosoon/kubernetes-operator/pkg/internal/util/cli" 22 | "google.golang.org/grpc" 23 | ) 24 | 25 | type Action interface { 26 | Execute(ctx *ActionContext) error 27 | } 28 | 29 | // ActionContext is data supplied to all actions 30 | type ActionContext struct { 31 | Status *cli.Status 32 | Cluster *createtypes.ClusterOptions 33 | Server *grpc.Server 34 | Port string 35 | } 36 | 37 | func NewActionContext( 38 | cluster *createtypes.ClusterOptions, 39 | server *grpc.Server, 40 | port string, 41 | status *cli.Status, 42 | ) *ActionContext { 43 | return &ActionContext{ 44 | Status: status, 45 | Cluster: cluster, 46 | Server: server, 47 | Port: port, 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /pkg/internal/cluster/create/actions/installcni/cni.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package installcni 18 | 19 | import ( 20 | "bytes" 21 | "html/template" 22 | "strings" 23 | 24 | "github.com/gosoon/kubernetes-operator/pkg/exec" 25 | "github.com/gosoon/kubernetes-operator/pkg/internal/cluster/create/actions" 26 | "github.com/pkg/errors" 27 | ) 28 | 29 | type action struct{} 30 | 31 | // NewAction returns a new action for installing default CNI 32 | func NewAction() actions.Action { 33 | return &action{} 34 | } 35 | 36 | // Execute runs the action 37 | func (a *action) Execute(ctx *actions.ActionContext) error { 38 | ctx.Status.Start("Installing CNI") 39 | defer ctx.Status.End(false) 40 | 41 | // read the manifest from the node 42 | var raw bytes.Buffer 43 | if err := exec.Command("cat", "/tmp/install/kubernetes/manifests/default-cni.yaml").SetStdout(&raw).Run(); err != nil { 44 | return errors.Wrap(err, "failed to read CNI manifest") 45 | } 46 | manifest := raw.String() 47 | 48 | // note:the default networking is calico, version is v3.8 49 | if strings.Contains(manifest, "networking manifest") { 50 | t, err := template.New("cni-manifest").Parse(manifest) 51 | if err != nil { 52 | return errors.Wrap(err, "failed to parse CNI manifest template") 53 | } 54 | var out bytes.Buffer 55 | err = t.Execute(&out, &struct { 56 | PodSubnet string 57 | }{ 58 | PodSubnet: ctx.Cluster.Config.Networking.PodSubnet, 59 | }) 60 | if err != nil { 61 | return errors.Wrap(err, "failed to execute CNI manifest template") 62 | } 63 | manifest = out.String() 64 | } 65 | 66 | // install the manifest 67 | if err := exec.Command( 68 | "kubectl", "create", "--kubeconfig=/etc/kubernetes/admin.conf", 69 | "-f", "-", 70 | ).SetStdin(strings.NewReader(manifest)).Run(); err != nil { 71 | return errors.Wrap(err, "failed to apply overlay network") 72 | } 73 | 74 | // mark success 75 | ctx.Status.End(true) 76 | return nil 77 | } 78 | -------------------------------------------------------------------------------- /pkg/internal/cluster/create/actions/waitforready/waitforready.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package waitforready 18 | 19 | import ( 20 | "fmt" 21 | "time" 22 | 23 | "github.com/gosoon/kubernetes-operator/pkg/installer/cluster/nodes" 24 | "github.com/gosoon/kubernetes-operator/pkg/internal/cluster/create/actions" 25 | ) 26 | 27 | // Action implements an action for waiting for the cluster to be ready 28 | type Action struct { 29 | waitTime time.Duration 30 | } 31 | 32 | // NewAction returns a new action for waiting for the cluster to be ready 33 | func NewAction(waitTime time.Duration) actions.Action { 34 | return &Action{ 35 | waitTime: waitTime, 36 | } 37 | } 38 | 39 | // Execute runs the action 40 | func (a *Action) Execute(ctx *actions.ActionContext) error { 41 | // skip entirely if the wait time is 0 42 | if a.waitTime == time.Duration(0) { 43 | return nil 44 | } 45 | ctx.Status.Start( 46 | fmt.Sprintf( 47 | "Waiting ≤ %s for control-plane = Ready", 48 | formatDuration(a.waitTime), 49 | ), 50 | ) 51 | 52 | // Wait for the nodes to reach Ready status. 53 | startTime := time.Now() 54 | isReady := nodes.WaitForReady(startTime.Add(a.waitTime)) 55 | if !isReady { 56 | ctx.Status.End(false) 57 | fmt.Println(" • WARNING: Timed out waiting for Ready ⚠️") 58 | return nil 59 | } 60 | // mark success 61 | ctx.Status.End(true) 62 | fmt.Printf(" • Ready after %s 💚\n", formatDuration(time.Since(startTime))) 63 | return nil 64 | } 65 | 66 | func formatDuration(duration time.Duration) string { 67 | return duration.Round(time.Second).String() 68 | } 69 | -------------------------------------------------------------------------------- /pkg/internal/cluster/create/images.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package create 18 | 19 | import ( 20 | "fmt" 21 | "strings" 22 | 23 | "github.com/gosoon/kubernetes-operator/pkg/container/docker" 24 | "github.com/gosoon/kubernetes-operator/pkg/internal/util/cli" 25 | ) 26 | 27 | // ensureNodeImages ensures that the node images used by the create 28 | // configuration are present 29 | func ensureNodeImages(status *cli.Status, image string) { 30 | // prints user friendly message 31 | if strings.Contains(image, "@sha256:") { 32 | image = strings.Split(image, "@sha256:")[0] 33 | } 34 | status.Start(fmt.Sprintf("Ensuring node image (%s) ", image)) 35 | 36 | fmt.Println("pull image ...") 37 | // attempt to explicitly pull the image if it doesn't exist locally 38 | // we don't care if this errors, we'll still try to run which also pulls 39 | _, _ = docker.PullIfNotPresent(image, 3) 40 | } 41 | -------------------------------------------------------------------------------- /pkg/internal/cluster/create/types/types.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package types 18 | 19 | import ( 20 | "time" 21 | 22 | ecsv1 "github.com/gosoon/kubernetes-operator/pkg/apis/ecs/v1" 23 | "github.com/gosoon/kubernetes-operator/pkg/internal/apis/config" 24 | ) 25 | 26 | // ClusterOptions holds cluster creation options 27 | // NOTE: this is only exported for usage by the parent package and the options 28 | // package 29 | // See ClusterOption instead 30 | type ClusterOptions struct { 31 | Name string 32 | Config *config.Cluster 33 | NodeImage string 34 | WaitForReady time.Duration 35 | SetupKubernetes bool 36 | NodeAddress string 37 | Role ecsv1.NodeRole 38 | ExternalLoadBalancer string 39 | KubeConfigPath string 40 | } 41 | -------------------------------------------------------------------------------- /pkg/internal/cluster/create/validate.go: -------------------------------------------------------------------------------- 1 | package create 2 | 3 | import ( 4 | "errors" 5 | "strings" 6 | 7 | createtypes "github.com/gosoon/kubernetes-operator/pkg/internal/cluster/create/types" 8 | ) 9 | 10 | func validate(cluster *createtypes.ClusterOptions) error { 11 | errs := []string{} 12 | if cluster.Config == nil { 13 | errs = append(errs, "invalid config") 14 | } 15 | 16 | if cluster.NodeImage == "" { 17 | errs = append(errs, "invalid node image") 18 | 19 | } 20 | 21 | if cluster.NodeAddress == "" { 22 | errs = append(errs, "invalid local ip") 23 | } 24 | 25 | if cluster.Role == "" { 26 | errs = append(errs, "invalid role") 27 | } 28 | 29 | if len(errs) > 0 { 30 | return errors.New(strings.Join(errs, "\n")) 31 | } 32 | return nil 33 | } 34 | -------------------------------------------------------------------------------- /pkg/internal/cluster/delete/delete.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package delete 18 | 19 | import ( 20 | "github.com/gosoon/kubernetes-operator/pkg/internal/cluster/context" 21 | ) 22 | 23 | // Cluster cleanup the cluster 24 | func Cluster(c *context.Context) error { 25 | return nil 26 | } 27 | -------------------------------------------------------------------------------- /pkg/internal/cluster/kubeadm/const.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package kubeadm 18 | 19 | // APIServerPort is the expected default APIServerPort on the control plane node(s) 20 | // https://kubernetes.io/docs/reference/access-authn-authz/controlling-access/#api-server-ports-and-ips 21 | const APIServerPort = 6443 22 | 23 | // Token defines a dummy, well known token for automating TLS bootstrap process 24 | const Token = "abcdef.0123456789abcdef" 25 | 26 | // ObjectName is the name every generated object will have 27 | // I.E. `metadata:\nname: config` 28 | const ObjectName = "config" 29 | -------------------------------------------------------------------------------- /pkg/internal/util/env/term.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package env 18 | 19 | import ( 20 | "io" 21 | "os" 22 | 23 | "golang.org/x/crypto/ssh/terminal" 24 | ) 25 | 26 | // IsTerminal returns true if the writer w is a terminal 27 | func IsTerminal(w io.Writer) bool { 28 | if v, ok := (w).(*os.File); ok { 29 | return terminal.IsTerminal(int(v.Fd())) 30 | } 31 | return false 32 | } 33 | -------------------------------------------------------------------------------- /pkg/kuberesource/configmap.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package kuberesource 18 | 19 | import ( 20 | "fmt" 21 | 22 | "github.com/gosoon/kubernetes-operator/pkg/apis/ecs" 23 | ecsv1 "github.com/gosoon/kubernetes-operator/pkg/apis/ecs/v1" 24 | "github.com/gosoon/kubernetes-operator/pkg/utils/pointer" 25 | 26 | corev1 "k8s.io/api/core/v1" 27 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 28 | ) 29 | 30 | func NewConfigMap(cluster *ecsv1.KubernetesCluster) *corev1.ConfigMap { 31 | configMap := &corev1.ConfigMap{ 32 | ObjectMeta: metav1.ObjectMeta{ 33 | Name: "", 34 | Namespace: cluster.Namespace, 35 | OwnerReferences: []metav1.OwnerReference{ 36 | { 37 | APIVersion: fmt.Sprintf("%v/v1", ecs.GroupName), 38 | Kind: "KubernetesCluster", 39 | Name: cluster.Name, 40 | UID: cluster.UID, 41 | Controller: pointer.BoolPtr(true), 42 | BlockOwnerDeletion: pointer.BoolPtr(true), 43 | }, 44 | }, 45 | }, 46 | Data: map[string]string{}, 47 | } 48 | return configMap 49 | } 50 | -------------------------------------------------------------------------------- /pkg/kuberesource/resourcelock.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package kuberesource 18 | 19 | import ( 20 | "os" 21 | 22 | "github.com/gosoon/kubernetes-operator/pkg/client/clientset/versioned/scheme" 23 | "github.com/gosoon/kubernetes-operator/pkg/controller" 24 | 25 | "github.com/gosoon/glog" 26 | v1 "k8s.io/api/core/v1" 27 | "k8s.io/apimachinery/pkg/util/uuid" 28 | "k8s.io/client-go/kubernetes" 29 | typedcorev1 "k8s.io/client-go/kubernetes/typed/core/v1" 30 | "k8s.io/client-go/tools/leaderelection/resourcelock" 31 | "k8s.io/client-go/tools/record" 32 | ) 33 | 34 | func NewResourceLock(kubeClient *kubernetes.Clientset) (resourcelock.Interface, error) { 35 | // init eventRecorder 36 | eventBroadcaster := record.NewBroadcaster() 37 | eventRecorder := eventBroadcaster.NewRecorder(scheme.Scheme, v1.EventSource{Component: controller.ComponentName}) 38 | eventBroadcaster.StartLogging(glog.Infof) 39 | eventBroadcaster.StartRecordingToSink(&typedcorev1.EventSinkImpl{Interface: kubeClient.CoreV1().Events("")}) 40 | 41 | // init host identity 42 | id, err := os.Hostname() 43 | if err != nil { 44 | glog.Errorf("get hostname error: %v", err) 45 | return nil, err 46 | } 47 | id = id + "_" + string(uuid.NewUUID()) 48 | 49 | rl, err := resourcelock.New("endpoints", 50 | "kube-system", 51 | controller.ComponentName, 52 | kubeClient.CoreV1(), 53 | kubeClient.CoordinationV1(), 54 | resourcelock.ResourceLockConfig{ 55 | Identity: id, 56 | EventRecorder: eventRecorder, 57 | }) 58 | 59 | if err != nil { 60 | glog.Errorf("error creating lock: %v", err) 61 | return nil, err 62 | } 63 | return rl, nil 64 | } 65 | -------------------------------------------------------------------------------- /pkg/precheck/interface.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package precheck 18 | 19 | import ( 20 | ecsv1 "github.com/gosoon/kubernetes-operator/pkg/apis/ecs/v1" 21 | "github.com/gosoon/kubernetes-operator/pkg/types" 22 | ) 23 | 24 | // Interface xxx 25 | type Interface interface { 26 | HostEnv(cluster *ecsv1.KubernetesCluster, results []chan types.PrecheckResult, finished chan bool) 27 | } 28 | -------------------------------------------------------------------------------- /pkg/server/controller/controller.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package controller 18 | 19 | import ( 20 | clientset "github.com/gosoon/kubernetes-operator/pkg/client/clientset/versioned" 21 | "github.com/gosoon/kubernetes-operator/pkg/server/service" 22 | 23 | "github.com/gorilla/mux" 24 | "k8s.io/client-go/kubernetes" 25 | ) 26 | 27 | type Options struct { 28 | KubernetesClusterClientset clientset.Interface 29 | KubeClientset kubernetes.Interface 30 | Service service.Interface 31 | } 32 | 33 | type Controller interface { 34 | Register(router *mux.Router) 35 | } 36 | -------------------------------------------------------------------------------- /pkg/server/middleware/auth.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package middleware 18 | 19 | // Authenticate is check client source 20 | //func Authenticate(next http.Handler) http.HandlerFunc { 21 | //return func(w http.ResponseWriter, r *http.Request) { 22 | //token := r.Header.Get("Authorization") 23 | //// check token 24 | //if len(token) != 0 { 25 | //bearerValue := strings.Split(token, " ")[1] 26 | //userInfo, err := Db.GetUserByToken(bearerValue) 27 | //if err != nil { 28 | //glog.Errorf("get user info by token with err [%v]", err) 29 | //public.FailedResponse(w, r, fmt.Sprintf("Authenticate failed,plz check your token."), 30 | //httpcode.StatusUnauthorized) 31 | //} else { 32 | //// set username and role in cookie 33 | //expiration := time.Now().Add(24 * time.Hour) 34 | //r.AddCookie(&http.Cookie{Name: "username", Value: userInfo.Name, Expires: expiration}) 35 | //r.AddCookie(&http.Cookie{Name: "role", Value: userInfo.Role, Expires: expiration}) 36 | //valueCtx := context.WithValue(r.Context(), "opUser", userInfo.Name) 37 | //r = r.WithContext(valueCtx) 38 | //next.ServeHTTP(w, r) 39 | //} 40 | //} 41 | //} 42 | //} 43 | -------------------------------------------------------------------------------- /pkg/server/service/interface.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package service 18 | 19 | import ( 20 | "context" 21 | 22 | clientset "github.com/gosoon/kubernetes-operator/pkg/client/clientset/versioned" 23 | "github.com/gosoon/kubernetes-operator/pkg/types" 24 | 25 | "k8s.io/client-go/kubernetes" 26 | ) 27 | 28 | type Options struct { 29 | KubernetesClusterClientset clientset.Interface 30 | KubeClientset kubernetes.Interface 31 | } 32 | 33 | type service struct { 34 | opt *Options 35 | } 36 | 37 | func New(opt *Options) Interface { 38 | return &service{opt: opt} 39 | } 40 | 41 | type Interface interface { 42 | // cluster 43 | CreateCluster(ctx context.Context, region string, namespace string, name string, clusterInfo *types.EcsClient) error 44 | DeleteCluster(ctx context.Context, region string, namespace string, name string, clusterInfo *types.EcsClient) error 45 | 46 | // scale 47 | ScaleUp(ctx context.Context, region string, namespace string, name string, clusterInfo *types.EcsClient) error 48 | ScaleDown(ctx context.Context, region string, namespace string, name string, clusterInfo *types.EcsClient) error 49 | 50 | // callback 51 | CreateClusterCallback(ctx context.Context, region string, namespace string, name string, result *types.Callback) error 52 | ScaleUpCallback(ctx context.Context, region string, namespace string, name string, result *types.Callback) error 53 | ScaleDownCallback(ctx context.Context, region string, namespace string, name string, result *types.Callback) error 54 | DeleteClusterCallback(ctx context.Context, region string, namespace string, name string, result *types.Callback) error 55 | 56 | // logs 57 | GetClusterOperationLogs(ctx context.Context, region string, namespace string, name string) (string, error) 58 | } 59 | -------------------------------------------------------------------------------- /pkg/server/service/logs.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package service 18 | 19 | import ( 20 | "bufio" 21 | "context" 22 | "fmt" 23 | "io" 24 | 25 | "github.com/gosoon/glog" 26 | "github.com/pkg/errors" 27 | v1 "k8s.io/api/core/v1" 28 | metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 29 | ) 30 | 31 | const ( 32 | jobLabelKey = "job-name" 33 | ) 34 | 35 | func (s *service) GetClusterOperationLogs(ctx context.Context, region string, namespace string, name string) (string, error) { 36 | clusterClientset := s.opt.KubernetesClusterClientset 37 | var logs string 38 | kubernetesCluster, err := clusterClientset.EcsV1().KubernetesClusters(namespace).Get(name, metav1.GetOptions{}) 39 | if err != nil { 40 | glog.Errorf("get kubernetesCluster %s/%s failed with:%v", namespace, name, err) 41 | return logs, err 42 | } 43 | 44 | jobName := kubernetesCluster.Status.JobName 45 | if jobName == "" { 46 | return logs, errors.New("no opreation logs") 47 | } 48 | 49 | kubeClientset := s.opt.KubeClientset 50 | // get job's pod by labelSelector 51 | labelSelector := fmt.Sprintf("%v=%v", jobLabelKey, jobName) 52 | listOptions := metav1.ListOptions{LabelSelector: labelSelector} 53 | podList, err := kubeClientset.CoreV1().Pods(namespace).List(listOptions) 54 | if err != nil { 55 | glog.Errorf("list [%v=%v] lable pod failed with:%v", jobLabelKey, jobName, err) 56 | return logs, errors.Errorf("get job %v logs failed with:%v", jobName, err) 57 | } 58 | 59 | if len(podList.Items) == 0 { 60 | return logs, errors.Errorf("get job %v logs failed with:%v", jobName, err) 61 | } 62 | 63 | // get the pod logs 64 | podName := podList.Items[0].Name 65 | logOptions := &v1.PodLogOptions{} 66 | req := kubeClientset.CoreV1().Pods(namespace).GetLogs(podName, logOptions) 67 | readCloser, err := req.Stream() 68 | if err != nil { 69 | return logs, errors.Errorf("get job %v logs failed with:%v", jobName, err) 70 | } 71 | defer readCloser.Close() 72 | 73 | r := bufio.NewReader(readCloser) 74 | for { 75 | bytes, err := r.ReadBytes('\n') 76 | if err != nil { 77 | if err != io.EOF { 78 | return logs, errors.Errorf("get job %v logs failed with:%v", jobName, err) 79 | } 80 | break 81 | } 82 | logs += string(bytes) 83 | } 84 | return logs, nil 85 | } 86 | -------------------------------------------------------------------------------- /pkg/server/service/valid.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package service 18 | 19 | import ( 20 | ecsv1 "github.com/gosoon/kubernetes-operator/pkg/apis/ecs/v1" 21 | "github.com/gosoon/kubernetes-operator/pkg/enum" 22 | ) 23 | 24 | // valid operate 25 | func validPhase(kubernetesCluster *ecsv1.KubernetesCluster) bool { 26 | phase := kubernetesCluster.Status.Phase 27 | if phase == enum.New || phase == enum.Creating || phase == enum.Scaling || 28 | phase == enum.Terminating { 29 | return false 30 | } 31 | return true 32 | } 33 | -------------------------------------------------------------------------------- /pkg/server/serving.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package server 18 | 19 | import ( 20 | "net/http" 21 | "time" 22 | 23 | ctrl "github.com/gosoon/kubernetes-operator/pkg/server/controller" 24 | "github.com/gosoon/kubernetes-operator/pkg/server/controller/cluster" 25 | "github.com/gosoon/kubernetes-operator/pkg/server/service" 26 | 27 | "github.com/gorilla/mux" 28 | ) 29 | 30 | type Server interface { 31 | http.Handler 32 | ListenAndServe() error 33 | } 34 | 35 | type Options struct { 36 | CtrlOptions *ctrl.Options 37 | ListenAddr string 38 | } 39 | 40 | type server struct { 41 | opt Options 42 | router *mux.Router 43 | } 44 | 45 | func New(opt Options) Server { 46 | // init service 47 | options := &service.Options{ 48 | KubernetesClusterClientset: opt.CtrlOptions.KubernetesClusterClientset, 49 | KubeClientset: opt.CtrlOptions.KubeClientset, 50 | } 51 | 52 | opt.CtrlOptions.Service = service.New(options) 53 | 54 | router := mux.NewRouter().StrictSlash(true) 55 | cluster.New(opt.CtrlOptions).Register(router) 56 | 57 | return &server{ 58 | opt: opt, 59 | router: router, 60 | } 61 | } 62 | 63 | func (s *server) ServeHTTP(w http.ResponseWriter, r *http.Request) { 64 | s.router.ServeHTTP(w, r) 65 | } 66 | 67 | func (s *server) ListenAndServe() error { 68 | server := &http.Server{ 69 | Handler: s.router, 70 | Addr: s.opt.ListenAddr, 71 | // Good practice: enforce timeouts for servers you create! 72 | WriteTimeout: 15 * time.Second, 73 | ReadTimeout: 15 * time.Second, 74 | MaxHeaderBytes: 1 << 20, 75 | } 76 | if err := server.ListenAndServe(); err != nil { 77 | return err 78 | } 79 | return nil 80 | } 81 | -------------------------------------------------------------------------------- /pkg/sshserver/interface.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package sshserver 18 | 19 | import ( 20 | "github.com/gosoon/kubernetes-operator/pkg/types" 21 | ) 22 | 23 | // Interface xxx 24 | type Interface interface { 25 | Dossh(ch chan<- types.PrecheckResult) 26 | CopyFile(localFilePath string, remoteDir string) error 27 | } 28 | -------------------------------------------------------------------------------- /pkg/sshserver/sftp.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package sshserver 18 | 19 | import ( 20 | "os" 21 | 22 | "github.com/gosoon/glog" 23 | ) 24 | 25 | func (s *sshServer) CopyFile(localFilePath string, remoteFilePath string) error { 26 | srcFile, err := os.Open(localFilePath) 27 | if err != nil { 28 | glog.Errorf("scp to %v err: %v", s.IP, err) 29 | return err 30 | } 31 | defer srcFile.Close() 32 | 33 | dstFile, err := s.SftpClient.Create(remoteFilePath) 34 | if err != nil { 35 | glog.Errorf("scp to %v err: %v", s.IP, err) 36 | return err 37 | } 38 | defer dstFile.Close() 39 | 40 | buf := make([]byte, 1024) 41 | for { 42 | n, _ := srcFile.Read(buf) 43 | if n == 0 { 44 | break 45 | } 46 | dstFile.Write(buf[0:n]) 47 | } 48 | return nil 49 | } 50 | -------------------------------------------------------------------------------- /pkg/sshserver/sftp_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package sshserver 18 | 19 | import ( 20 | "testing" 21 | "time" 22 | 23 | "github.com/gosoon/kubernetes-operator/pkg/types" 24 | 25 | "github.com/stretchr/testify/assert" 26 | ) 27 | 28 | var CheckCmd = []string{"chmod +x /tmp/check.sh", "/tmp/check.sh"} 29 | 30 | func TestCopyFile(t *testing.T) { 31 | testCases := []types.SSHInfo{ 32 | { 33 | IP: "192.168.75.178", 34 | Username: "root", 35 | Port: 22, 36 | CmdList: CheckCmd, 37 | Key: "", 38 | Timeout: 35 * time.Second, 39 | }, 40 | { 41 | IP: "192.168.75.178", 42 | Username: "root", 43 | Port: 22, 44 | CmdList: CheckCmd, 45 | Key: "asdas", 46 | Timeout: 35 * time.Second, 47 | }, 48 | { 49 | IP: "", 50 | Username: "root", 51 | Port: 22, 52 | CmdList: CheckCmd, 53 | Key: "asdas", 54 | Timeout: 35 * time.Second, 55 | }, 56 | } 57 | 58 | for _, test := range testCases { 59 | t.Log(test) 60 | sshServer, err := NewSSHServer(&test) 61 | if err != nil { 62 | t.Log(err) 63 | } 64 | ch := make(chan types.PrecheckResult) 65 | sshServer.Dossh(ch) 66 | if !assert.Equal(t, nil, err) { 67 | t.Fatalf("expected: %v but get %v", nil, err) 68 | } 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /pkg/test/gen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2019 gosoon. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | mockgen github.com/gosoon/kubernetes-operator/pkg/server/service Interface >mock_service/service.go 18 | mockgen github.com/gosoon/kubernetes-operator/pkg/client/clientset/versioned Interface >mock_versioned/service.go 19 | mockgen k8s.io/client-go/kubernetes Interface >mock_kubernetes/service.go 20 | -------------------------------------------------------------------------------- /pkg/types/ansible.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package types 18 | 19 | // HostsYamlFormat xxx 20 | type HostsYamlFormat struct { 21 | All AllHosts `json:"all"` 22 | } 23 | 24 | // AllHosts xxx 25 | type AllHosts struct { 26 | Hosts map[string]*Host `json:"hosts"` 27 | Children Children `json:"children"` 28 | } 29 | 30 | // Children xxx 31 | type Children struct { 32 | KubeMaster map[string]map[string]*Host `json:"kube-master"` 33 | KubeNode map[string]map[string]*Host `json:"kube-node"` 34 | Etcd map[string]map[string]*Host `json:"etcd"` 35 | Calico map[string]map[string]*Host `json:"calico-rr"` 36 | } 37 | 38 | // Host xxx 39 | type Host struct { 40 | AnsibleHost string `json:"ansible_host,omitempty"` 41 | IP string `json:"ip,omitempty"` 42 | AccessIP string `json:"access_ip,omitempty"` 43 | } 44 | -------------------------------------------------------------------------------- /pkg/types/ecsclient.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package types 18 | 19 | import ecsv1 "github.com/gosoon/kubernetes-operator/pkg/apis/ecs/v1" 20 | 21 | // EcsClient xxx 22 | type EcsClient struct { 23 | Name string `json:"name"` 24 | Namespace string `json:"namespace"` 25 | Region string `json:"region"` 26 | TimeoutMins string `json:"timeoutMins"` 27 | ClusterType string `json:"clusterType"` 28 | PodCIDR string `json:"podCIDR"` 29 | ServiceCIDR string `json:"serviceCIDR"` 30 | MasterList []ecsv1.Node `json:"masterList"` 31 | ExternalLoadBalancer string `json:"externalLoadBalancer"` 32 | NodeList []ecsv1.Node `json:"nodeList"` 33 | EtcdList []ecsv1.Node `json:"etcdList"` 34 | KubeVersion string `json:"kubeVersion"` 35 | 36 | // PrivateSSHKey,because of ssh private key has multiple special characters, use base64 encode in it 37 | PrivateSSHKey string `json:"privateSSHKey"` 38 | Retry bool `json:"retry"` 39 | } 40 | 41 | // Callback xxx 42 | type Callback struct { 43 | Name string `json:"name"` 44 | Namespace string `json:"namespace"` 45 | Region string `json:"region"` 46 | MasterList []ecsv1.Node `json:"masterList"` 47 | NodeList []ecsv1.Node `json:"nodeList"` 48 | EtcdList []ecsv1.Node `json:"etcdList"` 49 | KubeConfig string `json:"kubeconfig"` 50 | Success bool `json:"success"` 51 | Message string `json:"message"` 52 | } 53 | -------------------------------------------------------------------------------- /pkg/types/installer.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package types 18 | 19 | // DispatchClusterResult xxx 20 | type DispatchConfigResult struct { 21 | Host string 22 | Success bool 23 | Message string 24 | } 25 | -------------------------------------------------------------------------------- /pkg/types/precheck.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package types 18 | 19 | import "time" 20 | 21 | // SSHInfo xxx 22 | type SSHInfo struct { 23 | IP string 24 | Port int 25 | Username string 26 | Password string 27 | CmdFile string 28 | Cmds string 29 | CmdList []string 30 | Key string 31 | CipherList []string 32 | Timeout time.Duration 33 | Result PrecheckResult 34 | } 35 | 36 | // PrecheckResult xxx 37 | type PrecheckResult struct { 38 | Host string 39 | CmdList []string 40 | Success bool 41 | Result string 42 | } 43 | -------------------------------------------------------------------------------- /pkg/utils/pointer/pointer.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package pointer 18 | 19 | // reference: https://github.com/kubernetes/utils 20 | 21 | // Int32Ptr returns a pointer to an int64 22 | func Int32Ptr(i int32) *int32 { 23 | return &i 24 | } 25 | 26 | // Int64Ptr returns a pointer to an int64 27 | func Int64Ptr(i int64) *int64 { 28 | return &i 29 | } 30 | 31 | // BoolPtr returns a pointer to an bool 32 | func BoolPtr(b bool) *bool { 33 | return &b 34 | } 35 | -------------------------------------------------------------------------------- /pkg/utils/pointer/pointer_test.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package pointer 18 | 19 | import ( 20 | "testing" 21 | 22 | "github.com/stretchr/testify/assert" 23 | ) 24 | 25 | func TestInt32Ptr(t *testing.T) { 26 | testCases := []struct { 27 | int32Value int32 28 | }{ 29 | { 30 | int32Value: int32(1), 31 | }, 32 | { 33 | int32Value: int32(-1), 34 | }, 35 | } 36 | 37 | for _, test := range testCases { 38 | ptr := Int32Ptr(test.int32Value) 39 | if !assert.Equal(t, &test.int32Value, ptr) { 40 | t.Fatalf("expected: %v but get %v", &test.int32Value, ptr) 41 | } 42 | } 43 | } 44 | 45 | func TestInt64Ptr(t *testing.T) { 46 | testCases := []struct { 47 | int64Value int64 48 | }{ 49 | { 50 | int64Value: int64(1), 51 | }, 52 | { 53 | int64Value: int64(-1), 54 | }, 55 | } 56 | 57 | for _, test := range testCases { 58 | ptr := Int64Ptr(test.int64Value) 59 | if !assert.Equal(t, &test.int64Value, ptr) { 60 | t.Fatalf("expected: %v but get %v", &test.int64Value, ptr) 61 | } 62 | } 63 | } 64 | 65 | func TestBoolPtr(t *testing.T) { 66 | testCases := []struct { 67 | boolValue bool 68 | }{ 69 | { 70 | boolValue: true, 71 | }, 72 | { 73 | boolValue: false, 74 | }, 75 | } 76 | 77 | for _, test := range testCases { 78 | ptr := BoolPtr(test.boolValue) 79 | if !assert.Equal(t, &test.boolValue, ptr) { 80 | t.Fatalf("expected: %v but get %v", &test.boolValue, ptr) 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /pkg/utils/signals/signals.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package signals 18 | 19 | import ( 20 | "os" 21 | "os/signal" 22 | "syscall" 23 | ) 24 | 25 | var onlyOneSignalHandler = make(chan struct{}) 26 | var shutdownSignals = []os.Signal{os.Interrupt, syscall.SIGTERM} 27 | 28 | // SetupSignalHandler registered for SIGTERM and SIGINT. A stop channel is returned 29 | // which is closed on one of these signals. If a second signal is caught, the program 30 | // is terminated with exit code 1. 31 | func SetupSignalHandler() (stopCh <-chan struct{}) { 32 | close(onlyOneSignalHandler) // panics when called twice 33 | 34 | stop := make(chan struct{}) 35 | c := make(chan os.Signal, 2) 36 | signal.Notify(c, shutdownSignals...) 37 | go func() { 38 | <-c 39 | close(stop) 40 | <-c 41 | os.Exit(1) // second signal. Exit directly. 42 | }() 43 | 44 | return stop 45 | } 46 | -------------------------------------------------------------------------------- /pkg/utils/valid_base64.go: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019 gosoon. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package utils 18 | 19 | import "encoding/base64" 20 | 21 | func ValidBase64Str(s string) (bool, string) { 22 | decodeBytes, err := base64.StdEncoding.DecodeString(s) 23 | if err != nil { 24 | return false, "" 25 | } 26 | return true, string(decodeBytes) 27 | } 28 | -------------------------------------------------------------------------------- /scripts/README.md: -------------------------------------------------------------------------------- 1 | Scripts dir is use binary deploy kubernetes cluster,default version is v1.14.0.Kubernetes-operator use ansible call this scripts and deploy kubernetes cluster. 2 | 3 | use scripts deploy kubernetes: 4 | 5 | 1. clone kubernetes-operator scripts in localhost `/home/kubernetes-operator/scripts` path 6 | 2. define version and hosts in `deploy/config.sh`,default bin file in `bin/`,the `bin/` dir file is mock, and you need to replace with `https://github.com/gosoon/kubernetes-utils/tree/master/scripts/bin` 7 | 3. define host list in `deploy/hosts_env` 8 | 4. configure host login using the private key,put the public key on all hosts,and save ssh private-key in `/home/kubernetes-operator/private-key` 9 | 5. exec scripts to deploy 10 | 11 | ``` 12 | $ cd deploy/ 13 | $ bash deploy.sh etcd 14 | $ bash deploy.sh master 15 | $ bash deploy.sh node 16 | ``` 17 | -------------------------------------------------------------------------------- /scripts/bin/README.md: -------------------------------------------------------------------------------- 1 | Since the files are too large, here are the mock files.If you need to use these file in this directory,please to [https://github.com/gosoon/kubernetes-utils/tree/master/scripts/bin](https://github.com/gosoon/kubernetes-utils/tree/master/scripts/bin) 2 | -------------------------------------------------------------------------------- /scripts/bin/certs/cfssl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gosoon/kubernetes-operator/ff55af68d380065a6173dc4028125ed54c0bc60f/scripts/bin/certs/cfssl -------------------------------------------------------------------------------- /scripts/bin/certs/cfssljson: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gosoon/kubernetes-operator/ff55af68d380065a6173dc4028125ed54c0bc60f/scripts/bin/certs/cfssljson -------------------------------------------------------------------------------- /scripts/bin/certs/hosts: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gosoon/kubernetes-operator/ff55af68d380065a6173dc4028125ed54c0bc60f/scripts/bin/certs/hosts -------------------------------------------------------------------------------- /scripts/bin/docker-ce-18.06.1.ce/docker: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gosoon/kubernetes-operator/ff55af68d380065a6173dc4028125ed54c0bc60f/scripts/bin/docker-ce-18.06.1.ce/docker -------------------------------------------------------------------------------- /scripts/bin/docker-ce-18.06.1.ce/docker-containerd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gosoon/kubernetes-operator/ff55af68d380065a6173dc4028125ed54c0bc60f/scripts/bin/docker-ce-18.06.1.ce/docker-containerd -------------------------------------------------------------------------------- /scripts/bin/docker-ce-18.06.1.ce/docker-containerd-ctr: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gosoon/kubernetes-operator/ff55af68d380065a6173dc4028125ed54c0bc60f/scripts/bin/docker-ce-18.06.1.ce/docker-containerd-ctr -------------------------------------------------------------------------------- /scripts/bin/docker-ce-18.06.1.ce/docker-containerd-shim: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gosoon/kubernetes-operator/ff55af68d380065a6173dc4028125ed54c0bc60f/scripts/bin/docker-ce-18.06.1.ce/docker-containerd-shim -------------------------------------------------------------------------------- /scripts/bin/docker-ce-18.06.1.ce/docker-init: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gosoon/kubernetes-operator/ff55af68d380065a6173dc4028125ed54c0bc60f/scripts/bin/docker-ce-18.06.1.ce/docker-init -------------------------------------------------------------------------------- /scripts/bin/docker-ce-18.06.1.ce/docker-proxy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gosoon/kubernetes-operator/ff55af68d380065a6173dc4028125ed54c0bc60f/scripts/bin/docker-ce-18.06.1.ce/docker-proxy -------------------------------------------------------------------------------- /scripts/bin/docker-ce-18.06.1.ce/docker-runc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gosoon/kubernetes-operator/ff55af68d380065a6173dc4028125ed54c0bc60f/scripts/bin/docker-ce-18.06.1.ce/docker-runc -------------------------------------------------------------------------------- /scripts/bin/docker-ce-18.06.1.ce/dockerd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gosoon/kubernetes-operator/ff55af68d380065a6173dc4028125ed54c0bc60f/scripts/bin/docker-ce-18.06.1.ce/dockerd -------------------------------------------------------------------------------- /scripts/bin/etcd_v3.3.13/etcd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gosoon/kubernetes-operator/ff55af68d380065a6173dc4028125ed54c0bc60f/scripts/bin/etcd_v3.3.13/etcd -------------------------------------------------------------------------------- /scripts/bin/etcd_v3.3.13/etcdctl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gosoon/kubernetes-operator/ff55af68d380065a6173dc4028125ed54c0bc60f/scripts/bin/etcd_v3.3.13/etcdctl -------------------------------------------------------------------------------- /scripts/bin/extra/bash-completion: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gosoon/kubernetes-operator/ff55af68d380065a6173dc4028125ed54c0bc60f/scripts/bin/extra/bash-completion -------------------------------------------------------------------------------- /scripts/bin/kubernetes_v1.14.0/kube-apiserver: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gosoon/kubernetes-operator/ff55af68d380065a6173dc4028125ed54c0bc60f/scripts/bin/kubernetes_v1.14.0/kube-apiserver -------------------------------------------------------------------------------- /scripts/bin/kubernetes_v1.14.0/kube-controller-manager: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gosoon/kubernetes-operator/ff55af68d380065a6173dc4028125ed54c0bc60f/scripts/bin/kubernetes_v1.14.0/kube-controller-manager -------------------------------------------------------------------------------- /scripts/bin/kubernetes_v1.14.0/kube-proxy: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gosoon/kubernetes-operator/ff55af68d380065a6173dc4028125ed54c0bc60f/scripts/bin/kubernetes_v1.14.0/kube-proxy -------------------------------------------------------------------------------- /scripts/bin/kubernetes_v1.14.0/kube-scheduler: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gosoon/kubernetes-operator/ff55af68d380065a6173dc4028125ed54c0bc60f/scripts/bin/kubernetes_v1.14.0/kube-scheduler -------------------------------------------------------------------------------- /scripts/bin/kubernetes_v1.14.0/kubectl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gosoon/kubernetes-operator/ff55af68d380065a6173dc4028125ed54c0bc60f/scripts/bin/kubernetes_v1.14.0/kubectl -------------------------------------------------------------------------------- /scripts/bin/kubernetes_v1.14.0/kubelet: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gosoon/kubernetes-operator/ff55af68d380065a6173dc4028125ed54c0bc60f/scripts/bin/kubernetes_v1.14.0/kubelet -------------------------------------------------------------------------------- /scripts/certs/etcd/ca-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "signing": { 3 | "default": { 4 | "expiry": "8760h" 5 | }, 6 | "profiles": { 7 | "server": { 8 | "expiry": "8760h", 9 | "usages": [ 10 | "signing", 11 | "key encipherment", 12 | "server auth", 13 | "client auth" 14 | ] 15 | }, 16 | "client": { 17 | "expiry": "8760h", 18 | "usages": [ 19 | "signing", 20 | "key encipherment", 21 | "client auth" 22 | ] 23 | }, 24 | "peer": { 25 | "expiry": "8760h", 26 | "usages": [ 27 | "signing", 28 | "key encipherment", 29 | "server auth", 30 | "client auth" 31 | ] 32 | } 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /scripts/certs/etcd/etcd-root-ca-csr.json: -------------------------------------------------------------------------------- 1 | { 2 | "CN": "etcd-root-ca", 3 | "key": { 4 | "algo": "rsa", 5 | "size": 4096 6 | }, 7 | "names": [ 8 | { 9 | "O": "etcd", 10 | "OU": "etcd Security", 11 | "L": "Beijing", 12 | "ST": "Beijing", 13 | "C": "CN" 14 | } 15 | ], 16 | "ca": { 17 | "expiry": "87600h" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /scripts/certs/etcd/gen_cert.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | [ -e ../../deploy/config.sh ] && . ../../deploy/config.sh || exit 4 | [ -d output ] || mkdir output 5 | 6 | # etcd server cert/key 7 | cfssl gencert --initca=true etcd-root-ca-csr.json | cfssljson -bare output/ca 8 | 9 | # etcd server 10 | cfssl gencert \ 11 | -ca=output/ca.pem \ 12 | -ca-key=output/ca-key.pem \ 13 | -config=ca-config.json \ 14 | -hostname=127.0.0.1,${ETCD_HOSTS} \ 15 | -profile=server \ 16 | server.json | cfssljson -bare output/etcd-server 17 | 18 | # etcd peer 19 | cfssl gencert \ 20 | -ca=output/ca.pem \ 21 | -ca-key=output/ca-key.pem \ 22 | -config=ca-config.json \ 23 | -hostname=127.0.0.1,${ETCD_HOSTS} \ 24 | -profile=peer \ 25 | server.json | cfssljson -bare output/etcd-peer 26 | -------------------------------------------------------------------------------- /scripts/certs/etcd/server.json: -------------------------------------------------------------------------------- 1 | { 2 | "key": { 3 | "algo": "rsa", 4 | "size": 2048 5 | }, 6 | "names": [ 7 | { 8 | "O": "etcd", 9 | "OU": "etcd Security", 10 | "L": "Beijing", 11 | "ST": "Beijing", 12 | "C": "CN" 13 | } 14 | ], 15 | "CN": "etcd" 16 | } 17 | -------------------------------------------------------------------------------- /scripts/certs/master/admin-csr.json: -------------------------------------------------------------------------------- 1 | { 2 | "CN": "admin", 3 | "key": { 4 | "algo": "rsa", 5 | "size": 2048 6 | }, 7 | "names": [ 8 | { 9 | "C": "China", 10 | "L": "Shanghai", 11 | "O": "system:masters", 12 | "OU": "Kubernetes", 13 | "ST": "Shanghai" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /scripts/certs/master/apiserver-kubelet-client-csr.json: -------------------------------------------------------------------------------- 1 | { 2 | "CN": "system:kubelet-api-admin", 3 | "key": { 4 | "algo": "rsa", 5 | "size": 2048 6 | }, 7 | "names": [ 8 | { 9 | "C": "China", 10 | "L": "Shanghai", 11 | "O": "system:masters", 12 | "OU": "Kubernetes", 13 | "ST": "Shanghai" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /scripts/certs/master/ca-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "signing": { 3 | "default": { 4 | "expiry": "8760h" 5 | }, 6 | "profiles": { 7 | "kubernetes": { 8 | "usages": ["signing", "key encipherment", "server auth", "client auth"], 9 | "expiry": "8760h" 10 | } 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /scripts/certs/master/ca-csr.json: -------------------------------------------------------------------------------- 1 | { 2 | "CN": "Kubernetes", 3 | "key": { 4 | "algo": "rsa", 5 | "size": 2048 6 | }, 7 | "names": [ 8 | { 9 | "C": "China", 10 | "L": "Shanghai", 11 | "O": "Kubernetes", 12 | "OU": "Shanghai", 13 | "ST": "Shanghai" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /scripts/certs/master/gen_cert.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | [ -e ../../deploy/config.sh ] && . ../../deploy/config.sh || exit 4 | [ -d output ] || mkdir output 5 | 6 | cfssl gencert -initca ca-csr.json | cfssljson -bare output/ca 7 | 8 | # apiserver 9 | cfssl gencert \ 10 | -ca=output/ca.pem \ 11 | -ca-key=output/ca-key.pem \ 12 | -config=ca-config.json \ 13 | -hostname=10.250.0.1,${MASTER_HOSTS},${MASTER_VIP},127.0.0.1,kubernetes,kubernetes.default,kubernetes.default.svc \ 14 | -profile=kubernetes \ 15 | kube-apiserver-csr.json | cfssljson -bare output/kube-apiserver 16 | 17 | # kubelet 18 | for node in `echo ${NODE_HOSTS} | tr ',' ' '`;do 19 | sed -i -e "s##${node}#g" kubelet-csr.json 20 | cfssl gencert \ 21 | -ca=output/ca.pem \ 22 | -ca-key=output/ca-key.pem \ 23 | -config=ca-config.json \ 24 | -hostname=${NODE_HOSTS} \ 25 | -profile=kubernetes \ 26 | kubelet-csr.json | cfssljson -bare output/kubelet 27 | done 28 | 29 | # other component 30 | for component in kube-controller-manager kube-scheduler kube-proxy apiserver-kubelet-client admin service-account;do 31 | cfssl gencert \ 32 | -ca=output/ca.pem \ 33 | -ca-key=output/ca-key.pem \ 34 | -config=ca-config.json \ 35 | -profile=kubernetes \ 36 | ${component}-csr.json | cfssljson -bare output/${component} 37 | done 38 | -------------------------------------------------------------------------------- /scripts/certs/master/kube-apiserver-csr.json: -------------------------------------------------------------------------------- 1 | { 2 | "CN": "kubernetes", 3 | "key": { 4 | "algo": "rsa", 5 | "size": 2048 6 | }, 7 | "names": [ 8 | { 9 | "C": "China", 10 | "L": "Shanghai", 11 | "O": "Kubernetes", 12 | "OU": "Kubernetes", 13 | "ST": "Shanghai" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /scripts/certs/master/kube-controller-manager-csr.json: -------------------------------------------------------------------------------- 1 | { 2 | "CN": "system:kube-controller-manager", 3 | "key": { 4 | "algo": "rsa", 5 | "size": 2048 6 | }, 7 | "names": [ 8 | { 9 | "C": "China", 10 | "L": "Shanghai", 11 | "O": "system:kube-controller-manager", 12 | "OU": "Kubernetes", 13 | "ST": "Shanghai" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /scripts/certs/master/kube-proxy-csr.json: -------------------------------------------------------------------------------- 1 | { 2 | "CN": "system:kube-proxy", 3 | "key": { 4 | "algo": "rsa", 5 | "size": 2048 6 | }, 7 | "names": [ 8 | { 9 | "C": "China", 10 | "L": "Shanghai", 11 | "O": "system:node-proxier", 12 | "OU": "Kubernetes", 13 | "ST": "Shanghai" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /scripts/certs/master/kube-scheduler-csr.json: -------------------------------------------------------------------------------- 1 | { 2 | "CN": "system:kube-scheduler", 3 | "key": { 4 | "algo": "rsa", 5 | "size": 2048 6 | }, 7 | "names": [ 8 | { 9 | "C": "China", 10 | "L": "Shanghai", 11 | "O": "system:kube-scheduler", 12 | "OU": "Kubernetes", 13 | "ST": "Shanghai" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /scripts/certs/master/kubelet-csr.json: -------------------------------------------------------------------------------- 1 | { 2 | "CN": "system:node:", 3 | "key": { 4 | "algo": "rsa", 5 | "size": 2048 6 | }, 7 | "names": [ 8 | { 9 | "C": "China", 10 | "L": "Shanghai", 11 | "O": "system:nodes", 12 | "OU": "Kubernetes", 13 | "ST": "Shanghai" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /scripts/certs/master/service-account-csr.json: -------------------------------------------------------------------------------- 1 | { 2 | "CN": "service-accounts", 3 | "key": { 4 | "algo": "rsa", 5 | "size": 2048 6 | }, 7 | "names": [ 8 | { 9 | "C": "China", 10 | "L": "Shanghai", 11 | "O": "Kubernetes", 12 | "OU": "Kubernetes", 13 | "ST": "Shanghai" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /scripts/certs/node/ca-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "signing": { 3 | "default": { 4 | "expiry": "8760h" 5 | }, 6 | "profiles": { 7 | "kubernetes": { 8 | "usages": ["signing", "key encipherment", "server auth", "client auth"], 9 | "expiry": "8760h" 10 | } 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /scripts/certs/node/gen_cert.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | [ -e ../../deploy/config.sh ] && . ../../deploy/config.sh || exit 4 | 5 | CERTS_DIR="/etc/kubernetes/ssl" 6 | [ -d output ] || mkdir output 7 | 8 | # kubelet 9 | cfssl gencert \ 10 | -ca=${CERTS_DIR}/ca.pem \ 11 | -ca-key=${CERTS_DIR}/ca-key.pem \ 12 | -config=ca-config.json \ 13 | -hostname=${NODE_HOSTNAME},${NODE_HOSTS} \ 14 | -profile=kubernetes \ 15 | kubelet-csr.json | cfssljson -bare output/kubelet 16 | 17 | # other component 18 | cfssl gencert \ 19 | -ca=${CERTS_DIR}/ca.pem \ 20 | -ca-key=${CERTS_DIR}/ca-key.pem \ 21 | -config=ca-config.json \ 22 | -profile=kubernetes \ 23 | kube-proxy-csr.json | cfssljson -bare output/kube-proxy 24 | -------------------------------------------------------------------------------- /scripts/certs/node/kube-proxy-csr.json: -------------------------------------------------------------------------------- 1 | { 2 | "CN": "system:kube-proxy", 3 | "key": { 4 | "algo": "rsa", 5 | "size": 2048 6 | }, 7 | "names": [ 8 | { 9 | "C": "China", 10 | "L": "Shanghai", 11 | "O": "system:node-proxier", 12 | "OU": "Kubernetes", 13 | "ST": "Shanghai" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /scripts/certs/node/kubelet-csr.json: -------------------------------------------------------------------------------- 1 | { 2 | "CN": "system:node:10.0.2.15", 3 | "key": { 4 | "algo": "rsa", 5 | "size": 2048 6 | }, 7 | "names": [ 8 | { 9 | "C": "China", 10 | "L": "Shanghai", 11 | "O": "system:nodes", 12 | "OU": "Kubernetes", 13 | "ST": "Shanghai" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /scripts/config/etcd/etcd.conf: -------------------------------------------------------------------------------- 1 | ETCD_NAME="node1" 2 | ETCD_DATA_DIR="/home/etcd_1/data" 3 | ETCD_LISTEN_PEER_URLS="https://0.0.0.0:2380" 4 | ETCD_LISTEN_CLIENT_URLS="https://0.0.0.0:2379,https://0.0.0.0:4001" 5 | ETCD_INITIAL_ADVERTISE_PEER_URLS="https://xxx:2380" 6 | ETCD_ADVERTISE_CLIENT_URLS="https://xxx:2379" 7 | ETCD_INITIAL_CLUSTER_TOKEN="local" 8 | ETCD_INITIAL_CLUSTER="node0=https://xxx:2380,node1=https://xxx:2380,node2=https://xxx:2380,node3=https://xxx:2380,node4=https://xxx:2380" 9 | ETCD_INITIAL_CLUSTER_STATE="new" 10 | #ETCD_INITIAL_CLUSTER_STATE="existing" 11 | 12 | ETCD_HEARTBEAT_INTERVAL="300" 13 | ETCD_ELECTION_TIMEOUT="1500" 14 | ETCD_MAX_SNAPSHOTS="10" 15 | ETCD_MAX_WALS="10" 16 | ETCD_QUOTA_BACKEND_BYTES="8589934592" 17 | 18 | ETCD_CERT_FILE="/etc/etcd/ssl/etcd-server.pem" 19 | ETCD_KEY_FILE="/etc/etcd/ssl/etcd-server-key.pem" 20 | ETCD_PEER_CERT_FILE="/etc/etcd/ssl/etcd-peer.pem" 21 | ETCD_PEER_KEY_FILE="/etc/etcd/ssl/etcd-peer-key.pem" 22 | ETCD_TRUSTED_CA_FILE="/etc/etcd/ssl/ca.pem" 23 | ETCD_PEER_TRUSTED_CA_FILE="/etc/etcd/ssl/ca.pem" 24 | ETCD_CLIENT_CERT_AUTH="true" 25 | ETCD_PEER_CLIENT_CERT_AUTH="true" 26 | 27 | ETCD_DEBUG="false" 28 | ETCD_LOG_PACKAGE_LEVELS="etcdserver=WARNING,security=DEBUG" 29 | -------------------------------------------------------------------------------- /scripts/config/master/apiserver: -------------------------------------------------------------------------------- 1 | ### 2 | # kubernetes system config 3 | 4 | # The following values are used to configure the kube-apiserver 5 | 6 | # The address on the local server to listen to. 7 | #KUBE_API_ADDRESS="--insecure-bind-address=0.0.0.0" 8 | 9 | # The port on the local server to listen on. 10 | # KUBE_API_PORT="--port=8080" 11 | 12 | # Comma separated list of nodes in the etcd cluster 13 | KUBE_ETCD_SERVERS="--etcd-servers=" 14 | 15 | # Address range to use for services 16 | KUBE_SERVICE_ADDRESSES="--service-cluster-ip-range=192.168.0.0/16 --secure-port=6443 --bind-address=0.0.0.0 --insecure-bind-address=0.0.0.0" 17 | 18 | # default admission control policies 19 | KUBE_ADMISSION_CONTROL="--enable-admission-plugins=NamespaceLifecycle,LimitRanger,ServiceAccount,DefaultStorageClass,DefaultTolerationSeconds,MutatingAdmissionWebhook,ValidatingAdmissionWebhook,Priority,ResourceQuota,NodeRestriction" 20 | 21 | # Add your own! 22 | KUBE_API_ARGS=" --storage-backend=etcd3 --storage-media-type=application/json \ 23 | --log-dir=/var/log/kubernetes \ 24 | --stderrthreshold=3 --enable-garbage-collector=true \ 25 | --anonymous-auth=false \ 26 | --authorization-mode=Node,RBAC \ 27 | --kubelet-https=true \ 28 | --enable-bootstrap-token-auth=true \ 29 | --service-cluster-ip-range=10.250.0.0/24 \ 30 | --service-account-key-file=/etc/kubernetes/ssl/ca.pem \ 31 | --tls-cert-file=/etc/kubernetes/ssl/kube-apiserver.pem \ 32 | --tls-private-key-file=/etc/kubernetes/ssl/kube-apiserver-key.pem \ 33 | --client-ca-file=/etc/kubernetes/ssl/ca.pem \ 34 | --etcd-cafile=/etc/etcd/ssl/ca.pem \ 35 | --etcd-certfile=/etc/etcd/ssl/etcd-server.pem \ 36 | --etcd-keyfile=/etc/etcd/ssl/etcd-server-key.pem \ 37 | --etcd-compaction-interval=0s \ 38 | --kubelet-client-certificate=/etc/kubernetes/ssl/apiserver-kubelet-client.pem \ 39 | --kubelet-client-key=/etc/kubernetes/ssl/apiserver-kubelet-client-key.pem" 40 | -------------------------------------------------------------------------------- /scripts/config/master/config: -------------------------------------------------------------------------------- 1 | ### 2 | # kubernetes system config 3 | # 4 | # The following values are used to configure various aspects of all 5 | # kubernetes services, including 6 | # 7 | # kube-apiserver.service 8 | # kube-controller-manager.service 9 | # kube-scheduler.service 10 | # kubelet.service 11 | # kube-proxy.service 12 | # logging to stderr means we get it in the systemd journal 13 | KUBE_LOGTOSTDERR="--logtostderr=false" 14 | 15 | # journal message level, 0 is debug 16 | KUBE_LOG_LEVEL="--v=3" 17 | 18 | # Should this cluster be allowed to run privileged docker containers 19 | KUBE_ALLOW_PRIV="--allow-privileged=true" 20 | 21 | # How the controller-manager, scheduler, and proxy find the apiserver 22 | KUBE_MASTER="--master=https://:6443 --log-dir=/var/log/kubernetes" 23 | -------------------------------------------------------------------------------- /scripts/config/master/controller-manager: -------------------------------------------------------------------------------- 1 | ### 2 | # The following values are used to configure the kubernetes controller-manager 3 | 4 | # defaults from config and apiserver should be adequate 5 | 6 | # Add your own! 7 | KUBE_CONTROLLER_MANAGER_ARGS=" --bind-address=127.0.0.1 \ 8 | --allocate-node-cidrs=true \ 9 | --cluster-cidr=10.244.0.0/16 \ 10 | --cluster-signing-cert-file=/etc/kubernetes/ssl/ca.pem \ 11 | --cluster-signing-key-file=/etc/kubernetes/ssl/ca-key.pem \ 12 | --service-account-private-key-file=/etc/kubernetes/ssl/ca-key.pem \ 13 | --service-cluster-ip-range=10.250.0.0/24 \ 14 | --leader-elect=true \ 15 | --use-service-account-credentials=true \ 16 | --kubeconfig=/etc/kubernetes/kube-controller-manager.kubeconfig" 17 | -------------------------------------------------------------------------------- /scripts/config/master/scheduler: -------------------------------------------------------------------------------- 1 | ### 2 | # The following values are used to configure the kubernetes scheduler 3 | 4 | # defaults from config and scheduler should be adequate 5 | 6 | # Add your own! 7 | KUBE_SCHEDULER_ARGS="--bind-address=127.0.0.1 \ 8 | --kubeconfig=/etc/kubernetes/kube-scheduler.kubeconfig \ 9 | --leader-elect=true" 10 | -------------------------------------------------------------------------------- /scripts/config/node/config: -------------------------------------------------------------------------------- 1 | ### 2 | # kubernetes system config 3 | # 4 | # The following values are used to configure various aspects of all 5 | # kubernetes services, including 6 | # 7 | # kube-apiserver.service 8 | # kube-controller-manager.service 9 | # kube-scheduler.service 10 | # kubelet.service 11 | # kube-proxy.service 12 | # logging to stderr means we get it in the systemd journal 13 | KUBE_LOGTOSTDERR="--logtostderr=false" 14 | 15 | # journal message level, 0 is debug 16 | KUBE_LOG_LEVEL="--v=3" 17 | 18 | # Should this cluster be allowed to run privileged docker containers 19 | #KUBE_ALLOW_PRIV="--allow-privileged=true" 20 | 21 | # How the controller-manager, scheduler, and proxy find the apiserver 22 | KUBE_MASTER="--master=https://:6443 --log-dir=/var/log/kubernetes" 23 | -------------------------------------------------------------------------------- /scripts/config/node/config.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: kubelet.config.k8s.io/v1beta1 2 | kind: KubeletConfiguration 3 | address: 0.0.0.0 4 | authentication: 5 | anonymous: 6 | enabled: false 7 | webhook: 8 | cacheTTL: 2m0s 9 | enabled: true 10 | x509: 11 | clientCAFile: /etc/kubernetes/ssl/ca.pem 12 | authorization: 13 | mode: Webhook 14 | webhook: 15 | cacheAuthorizedTTL: 5m0s 16 | cacheUnauthorizedTTL: 30s 17 | cgroupDriver: systemd 18 | clusterDomain: cluster.local 19 | runtimeRequestTimeout: 15m 20 | clusterDNS: 21 | - 10.250.0.10 22 | cgroupDriver: systemd 23 | -------------------------------------------------------------------------------- /scripts/config/node/kube-proxy: -------------------------------------------------------------------------------- 1 | #### 2 | ## kubernetes proxy config 3 | #### 4 | # 5 | ## The address for the info server to serve on (set to 0.0.0.0 or "" for all interfaces) 6 | KUBE_PROXY_ADDRESS="--bind-address=0.0.0.0" 7 | # 8 | ## You may leave this blank to use the actual hostname 9 | KUBE_PROXY_HOSTNAME="--hostname-override=" 10 | # 11 | ## Add your own! 12 | KUBE_PROXY_ARGS="--proxy-mode=ipvs \ 13 | --cluster-cidr=10.240.0.0/16 \ 14 | --kubeconfig=/etc/kubernetes/kube-proxy.kubeconfig" 15 | -------------------------------------------------------------------------------- /scripts/config/node/kubelet: -------------------------------------------------------------------------------- 1 | ### 2 | # kubernetes kubelet (minion) config 3 | 4 | # The address for the info server to serve on (set to 0.0.0.0 or "" for all interfaces) 5 | #KUBELET_ADDRESS="--address=0.0.0.0" 6 | 7 | # The port for the info server to serve on 8 | # KUBELET_PORT="--port=10250" 9 | 10 | # You may leave this blank to use the actual hostname 11 | KUBELET_HOSTNAME="--hostname_override=" 12 | 13 | # location of the api-server 14 | #KUBELET_API_SERVER="--api_servers=http://:8080" 15 | 16 | # pod infrastructure container 17 | KUBELET_POD_INFRA_CONTAINER="" 18 | 19 | # Add your own! 20 | KUBELET_ARGS="--config=/etc/kubernetes/config.yaml \ 21 | --kubeconfig=/etc/kubernetes/kubelet.kubeconfig \ 22 | --tls-cert-file=/etc/kubernetes/ssl/kubelet.pem \ 23 | --tls-private-key-file=/etc/kubernetes/ssl/kubelet-key.pem \ 24 | --stderrthreshold=3 \ 25 | --log-dir=/var/log/kubernetes \ 26 | --network-plugin=cni" 27 | -------------------------------------------------------------------------------- /scripts/deploy/base_env_01.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # disable swap 4 | swapoff -a 5 | 6 | # Set SELinux in permissive mode (effectively disabling it) 7 | setenforce 0 8 | sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config 9 | 10 | # disable firewall 11 | systemctl disable firewalld.service && systemctl stop firewalld.service 12 | 13 | # use aliyun kubernetes yum source 14 | cat < /etc/yum.repos.d/kubernetes.repo 15 | [kubernetes] 16 | name=Kubernetes 17 | baseurl=https://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64 18 | enabled=1 19 | gpgcheck=1 20 | repo_gpgcheck=1 21 | gpgkey=https://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg https://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg 22 | EOF 23 | 24 | cat < /etc/sysctl.d/k8s.conf 25 | net.bridge.bridge-nf-call-ip6tables = 1 26 | net.bridge.bridge-nf-call-iptables = 1 27 | EOF 28 | sysctl --system &> /dev/null 29 | 30 | # install scp 31 | if [ ! -f /usr/bin/scp ];then 32 | yum install openssh-clients -y 33 | [ $? -eq 0 ] || { echo "install scp failed"; exit 1; } 34 | fi 35 | -------------------------------------------------------------------------------- /scripts/deploy/config.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # this section is glabel vars,do not edit 4 | # deploy home 5 | DEPLOY_HOME_DIR="/home/kubernetes-operator" 6 | 7 | # export certs bin 8 | CERTS_BIN_DIR="scripts/bin/certs" 9 | export PATH=$PATH:${DEPLOY_HOME_DIR}/${CERTS_BIN_DIR} 10 | 11 | # ---------------- 12 | # this section is define by users 13 | # docker version 14 | DOCKER_VER="docker-ce-18.06.1.ce" 15 | 16 | # k8s version 17 | KUBERNETES_VER="kubernetes_v1.14.0" 18 | KUBERNETES_DOWNLOAD_URL="https://dl.k8s.io/v1.14.0/kubernetes.tar.gz" 19 | 20 | # etcd version 21 | ETCD_VER="etcd_v3.3.13" 22 | 23 | # calico version 24 | CALICO_VER="v3.7" 25 | 26 | # coredns version 27 | COREDNS_VER="v1.4.0" 28 | 29 | LOCAL_IP=$(ifconfig | grep -Eo 'inet (addr:)?([0-9]*\.){3}[0-9]*' | grep -Eo '([0-9]*\.){3}[0-9]*' | grep -v '127.0.0.1') 30 | 31 | # if in docker and use env 32 | ENV_FILE="${DEPLOY_HOME_DIR}/scripts/deploy/hosts_env" 33 | if ! grep docker /proc/1/cgroup -qa; then 34 | [ -f ${ENV_FILE} ] && source ${ENV_FILE} || exit 1 35 | fi 36 | -------------------------------------------------------------------------------- /scripts/deploy/deploy.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | export LC_ALL=en_US.UTF-8 4 | export LANG=en_US.UTF-8 5 | 6 | ROOT=`cd $(dirname $0); pwd` 7 | DEPLOY_MASTER_LOG="/var/log/deploy_master.log" 8 | DEPLOY_NODE_LOG="/var/log/deploy_node.log" 9 | DEPLOY_ETCD_LOG="/var/log/deploy_etcd.log" 10 | DEPLOY_MASTER_FINISHED="/var/log/master_deployed" 11 | DEPLOY_NODE_FINISHED="/var/log/node_deployed" 12 | DEPLOY_ETCD_FINISHED="/var/log/etcd_deployed" 13 | 14 | master() { 15 | echo -n "starting deploy master... " 16 | [ -f ${DEPLOY_MASTER_FINISHED} ] && { echo "master is deployed"; exit 1; } || > ${DEPLOY_MASTER_LOG} 17 | [ -f base_env_01.sh ] && bash -x base_env_01.sh &>> ${DEPLOY_MASTER_LOG} || exit 1 18 | [ -f deploy_master.sh ] && bash -x deploy_master.sh &>> ${DEPLOY_MASTER_LOG} || exit 1 19 | [ -f deploy_coredns.sh ] && bash -x deploy_coredns.sh &>> ${DEPLOY_MASTER_LOG} || exit 1 20 | [ -f deploy_calico.sh ] && bash -x deploy_calico.sh &>> ${DEPLOY_MASTER_LOG} || exit 1 21 | touch ${DEPLOY_MASTER_FINISHED} 22 | } 23 | 24 | node() { 25 | echo -n "starting deploy node... " 26 | [ -f ${DEPLOY_NODE_FINISHED} ] && { echo "node is deployed"; exit 1; } || > ${DEPLOY_NODE_LOG} 27 | [ -f base_env_01.sh ] && bash -x base_env_01.sh &>> ${DEPLOY_NODE_LOG} || exit 1 28 | [ -f deploy_docker.sh ] && bash -x deploy_docker.sh &>> ${DEPLOY_NODE_LOG} || exit 1 29 | [ -f deploy_kubelet.sh ] && bash -x deploy_kubelet.sh &>> ${DEPLOY_NODE_LOG} || exit 1 30 | [ -f deploy_kube_proxy.sh ] && bash -x deploy_kube_proxy.sh &>> ${DEPLOY_NODE_LOG} || exit 1 31 | touch ${DEPLOY_NODE_FINISHED} 32 | } 33 | 34 | etcd() { 35 | echo -n "starting deploy etcd... " 36 | [ -f ${DEPLOY_ETCD_FINISHED} ] && { echo "etcd is deployed"; exit 1; } || > ${DEPLOY_ETCD_LOG} 37 | [ -f base_env_01.sh ] && bash -x base_env_01.sh &>> ${DEPLOY_ETCD_LOG} || exit 1 38 | [ -f deploy_etcd.sh ] && bash -x deploy_etcd.sh &>> ${DEPLOY_ETCD_LOG} || exit 1 39 | touch ${DEPLOY_ETCD_FINISHED} 40 | } 41 | 42 | 43 | case "$1" in 44 | master) 45 | master 46 | ;; 47 | 48 | node) 49 | node 50 | ;; 51 | 52 | etcd) 53 | etcd 54 | ;; 55 | 56 | *) 57 | echo "Usage: $0 {master|node|etcd}" 58 | exit 1 59 | esac 60 | -------------------------------------------------------------------------------- /scripts/deploy/deploy_calico.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | [ -e ./config.sh ] && . ./config.sh || exit 4 | 5 | CALICO_CONFIG="../yaml/calico_${CALICO_VER}/calico-etcd.yaml" 6 | 7 | download_calico(){ 8 | wget -O ${CALICO_CONFIG} https://docs.projectcalico.org/${CALICO_VER}/manifests/calico-etcd.yaml 9 | } 10 | 11 | # config etcd server 12 | etcd_num=$(echo ${ETCD_HOSTS} | awk -F ',' '{print NF}') 13 | etcd_cluster="" 14 | for i in `seq 1 ${etcd_num}`;do 15 | ip=$(echo ${ETCD_HOSTS} | awk -v idx=$i -F ',' '{print $idx}') 16 | cluster=$(echo "https://${ip}:2379") 17 | if [ $i -ne ${etcd_num} ];then 18 | cluster="${cluster}," 19 | fi 20 | etcd_cluster="${etcd_cluster}${cluster}" 21 | done 22 | 23 | # update secrets etcd info 24 | etcd_key_base64=$(cat /etc/etcd/ssl/etcd-server-key.pem | base64 -w 0) 25 | etcd_cert_base64=$(cat /etc/etcd/ssl/etcd-server.pem | base64 -w 0) 26 | etcd_ca_base64=$(cat /etc/etcd/ssl/ca.pem | base64 -w 0) 27 | sed -i -e "s@# etcd-key:.*@etcd-key: ${etcd_key_base64}@g" ${CALICO_CONFIG} 28 | sed -i -e "s@# etcd-cert:.*@etcd-cert: ${etcd_cert_base64}@g" ${CALICO_CONFIG} 29 | sed -i -e "s@# etcd-ca:.*@etcd-ca: ${etcd_ca_base64}@g" ${CALICO_CONFIG} 30 | 31 | # update configmap etcd info 32 | sed -i -e 's#etcd_endpoints:.*#etcd_endpoints: \"${etcd_cluster}\"#g' ${CALICO_CONFIG} 33 | sed -i -e 's#etcd_ca:.*#etcd_ca: \"/calico-secrets/etcd-ca\"#g' ${CALICO_CONFIG} 34 | sed -i -e 's#etcd_cert:.*#etcd_cert: \"/calico-secrets/etcd-cert\"#g' ${CALICO_CONFIG} 35 | sed -i -e 's#etcd_key:.*#etcd_key: \"/calico-secrets/etcd-key\"#g' ${CALICO_CONFIG} 36 | 37 | # TODO : check download_calico 38 | kubectl apply -f ${CALICO_CONFIG} 39 | if [ $? -ne 0 ];then 40 | echo "deploy calico failed !!!" && exit 1 41 | fi 42 | -------------------------------------------------------------------------------- /scripts/deploy/deploy_coredns.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | [ -e /etc/init.d/functions ] && . /etc/init.d/functions || exit 4 | [ -e ./config.sh ] && . ./config.sh || exit 5 | 6 | # k8s version >= v1.9 7 | # docs: https://github.com/coredns/deployment/tree/master/kubernetes 8 | 9 | # TODO : download coredns 10 | download_coredns(){ 11 | git clone https://github.com/coredns/deployment 12 | } 13 | 14 | COERDNS_CONFIG="../yaml/coredns_${COREDNS_VER}/coredns.yaml" 15 | 16 | kubectl apply -f ${COERDNS_CONFIG} 17 | if [ $? -ne 0 ];then 18 | echo "deploy coredns failed !!!" && exit 1 19 | fi 20 | -------------------------------------------------------------------------------- /scripts/deploy/deploy_docker.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # docker releases download docs: https://kubernetes.io/docs/setup/production-environment/container-runtimes/ 4 | [ -e ./config.sh ] && . ./config.sh || exit 5 | 6 | DOCKER_BIN_DIR="../bin/${DOCKER_VER}" 7 | DOCKER_SYSTEMD_CONFIG_DIR="../systemd" 8 | DEST_SYSTEMD_DIR="/usr/lib/systemd/system" 9 | 10 | install_docker() { 11 | # Install Docker CE 12 | ## Set up the repository 13 | ### Install required packages. 14 | yum install yum-utils device-mapper-persistent-data lvm2 15 | 16 | ### Add docker repository. 17 | yum-config-manager \ 18 | --add-repo \ 19 | https://download.docker.com/linux/centos/docker-ce.repo 20 | 21 | ## Install docker ce. 22 | yum update && yum install ${DOCKER_VER} 23 | } 24 | 25 | if [ -f ${DOCKER_BIN_DIR}/dockerd ];then 26 | cp ${DOCKER_BIN_DIR}/* /usr/bin/ 27 | cp ${DOCKER_SYSTEMD_CONFIG_DIR}/docker.service ${DEST_SYSTEMD_DIR}/ 28 | else 29 | install_docker 30 | fi 31 | 32 | ## Create /etc/docker directory. 33 | mkdir /etc/docker 34 | 35 | # Setup daemon. 36 | cat > /etc/docker/daemon.json <> /etc/sysctl.conf <> /etc/modules <#--hostname_override=${LOCAL_IP}#g" ${DEST_CONFIG_DIR}/kube-proxy 60 | 61 | [ -d ${KUBE_MASTER_LOG} ] || mkdir -pv ${KUBE_MASTER_LOG} 62 | 63 | systemctl daemon-reload 64 | systemctl enable kube-proxy 65 | systemctl start kube-proxy 66 | systemctl status kube-proxy 67 | 68 | if [ $? -ne 0 ];then 69 | echo "deploy kube-proxy failed !!!" && exit 1 70 | fi 71 | -------------------------------------------------------------------------------- /scripts/deploy/deploy_kubelet.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | [ -e /etc/init.d/functions ] && . /etc/init.d/functions || exit 4 | [ -e ./config.sh ] && . ./config.sh || exit 5 | 6 | KUBE_NODE_BIN_DIR="../bin/${KUBERNETES_VER}" 7 | KUBE_NODE_CONFIG_DIR="../config/node" 8 | KUBE_NODE_SYSTEMD_CONFIG_DIR="../systemd" 9 | CERTS_DIR="../certs" 10 | KUBECONFIG_DIR="../kubeconfig/" 11 | GENERATE_CERTS_FILE="../certs/node" 12 | GENERATE_KUBECONFIG_FILE="../kubeconfig" 13 | 14 | DEST_CERTS_DIR="/etc/kubernetes/ssl" 15 | DEST_SYSTEMD_DIR="/usr/lib/systemd/system" 16 | DEST_CONFIG_DIR="/etc/kubernetes" 17 | KUBE_MASTER_LOG="/var/log/kubernetes" 18 | 19 | cp ${KUBE_NODE_BIN_DIR}/kubelet /usr/bin/ && \ 20 | chmod +x /usr/bin/kubelet 21 | cp ${KUBE_NODE_SYSTEMD_CONFIG_DIR}/kubelet.service ${DEST_SYSTEMD_DIR} 22 | 23 | [ -d ${DEST_CONFIG_DIR} ] || mkdir ${DEST_CONFIG_DIR} 24 | cp ${KUBE_NODE_CONFIG_DIR}/{config,config.yaml,kubelet} ${DEST_CONFIG_DIR}/ 25 | 26 | # update config master ip 27 | sed -i -e "s#--master=https://:6443#--master=https://${MASTER_VIP}:6443#g" ${DEST_CONFIG_DIR}/config 28 | sed -i -e "s#--hostname_override=#--hostname_override=${LOCAL_IP}#g" ${DEST_CONFIG_DIR}/kubelet 29 | sed -i -e "s#hostnameOverride: #hostnameOverride: ${LOCAL_IP}#g" ${DEST_CONFIG_DIR}/config.yaml 30 | 31 | # scp ssl from master 32 | for master in `echo ${MASTER_HOSTS} | tr ',' ' '`;do 33 | scp -i ${DEPLOY_HOME_DIR}/private-key root@${master}:${DEST_CERTS_DIR}/{ca.pem,ca-key.pem} ${DEST_CERTS_DIR}/ 34 | [ $? -eq 0 ] && break 35 | done 36 | 37 | # generate ssl 38 | #cd ${GENERATE_CERTS_FILE} && bash gen_cert.sh 39 | #[ $? -eq 0 ] && echo "generate certs success" || exit 1 40 | #cd - 41 | #[ -d ${DEST_CERTS_DIR} ] || mkdir ${DEST_CERTS_DIR} 42 | #cp ${GENERATE_CERTS_FILE}/output/{ca.pem,ca-key.pem,kube-proxy-key.pem,kube-proxy.pem,kubelet-client-key.pem, \ 43 | #kubelet-client.pem} ${DEST_CERTS_DIR}/ 44 | 45 | # scp kubeconfig from master 46 | for master in `echo ${MASTER_HOSTS} | tr ',' ' '`;do 47 | scp -i ${DEPLOY_HOME_DIR}/private-key \ 48 | root@${master}:/home/kubernetes-operator/scripts/kubeconfig/output/kubelet-${LOCAL_IP}.kubeconfig \ 49 | ${DEST_CONFIG_DIR}/kubelet.kubeconfig 50 | [ $? -eq 0 ] && break 51 | done 52 | 53 | # generate kubeconfig 54 | #cp ${GENERATE_KUBECONFIG_FILE}/output/{kubelet.kubeconfig,bootstrap.kubeconfig} ${DEST_CONFIG_DIR}/ 55 | #sed -i -e "s#https://:6443#https://${MASTER_VIP}:6443#g" ${GENERATE_KUBECONFIG_FILE}/generate_node_kubeconfig.sh 56 | #cd ${GENERATE_KUBECONFIG_FILE} && bash generate_node_kubeconfig.sh 57 | #[ $? -eq 0 ] && echo "generate kubeconfig success" || exit 1 58 | #cp ${GENERATE_KUBECONFIG_FILE}/output/* ${DEST_CONFIG_DIR}/ 59 | #cd - 60 | 61 | # mkdir log dir 62 | [ -d ${KUBE_MASTER_LOG} ] || mkdir -pv ${KUBE_MASTER_LOG} 63 | 64 | # start service 65 | systemctl daemon-reload 66 | systemctl enable kubelet 67 | systemctl start kubelet 68 | systemctl status kubelet 69 | 70 | if [ $? -ne 0 ];then 71 | echo "deploy kubelet failed !!!" && exit 1 72 | fi 73 | -------------------------------------------------------------------------------- /scripts/deploy/hosts_env: -------------------------------------------------------------------------------- 1 | MASTER_HOSTS="192.168.72.81" 2 | ETCD_HOSTS="192.168.73.150,192.168.72.81" 3 | CLUSTER_NAMESPACE="default" 4 | CLUSTER_NAME="test-cluster" 5 | NODE_HOSTS="192.168.72.81,192.168.73.150" 6 | MASTER_VIP="192.168.72.81" 7 | OPERATION="creating" 8 | -------------------------------------------------------------------------------- /scripts/images/README.md: -------------------------------------------------------------------------------- 1 | Since the files are too large, here are the mock files.If you need to use these file in this directory,please to [https://github.com/gosoon/kubernetes-utils/tree/master/scripts/images](https://github.com/gosoon/kubernetes-utils/tree/master/scripts/images) 2 | -------------------------------------------------------------------------------- /scripts/kubeconfig/generate_node_kubeconfig.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | [ -e ../deploy/config.sh ] && . ../deploy/config.sh || exit 1 4 | 5 | KUBE_APISERVER="https://${MASTER_VIP}:6443" 6 | CERTS_DIR="${DEPLOY_HOME_DIR}/kubernetes-operator/scripts/certs/master/output" 7 | 8 | [ -d output ] || mkdir output 9 | 10 | for node in `echo ${NODE_HOSTS} | tr ',' ' '`;do 11 | # 生成 kubelet 配置文件 12 | echo "Create kubelet kubeconfig..." 13 | kubectl config set-cluster kubernetes \ 14 | --certificate-authority=${CERTS_DIR}/ca.pem \ 15 | --embed-certs=true \ 16 | --server=${KUBE_APISERVER} \ 17 | --kubeconfig=output/kubelet-${node}.kubeconfig 18 | 19 | kubectl config set-credentials system:node:${node} \ 20 | --client-certificate=${CERTS_DIR}/kubelet.pem \ 21 | --client-key=${CERTS_DIR}/kubelet-key.pem \ 22 | --embed-certs=true \ 23 | --kubeconfig=output/kubelet-${node}.kubeconfig 24 | 25 | kubectl config set-context default \ 26 | --cluster=kubernetes \ 27 | --user=system:node:${node} \ 28 | --kubeconfig=output/kubelet-${node}.kubeconfig 29 | 30 | kubectl config use-context default --kubeconfig=output/kubelet-${node}.kubeconfig 31 | done 32 | 33 | # 生成 kube-proxy 配置文件 34 | echo "Create kube-proxy kubeconfig..." 35 | kubectl config set-cluster kubernetes \ 36 | --certificate-authority=${CERTS_DIR}/ca.pem \ 37 | --embed-certs=true \ 38 | --server=${KUBE_APISERVER} \ 39 | --kubeconfig=output/kube-proxy.kubeconfig 40 | 41 | kubectl config set-credentials "system:kube-proxy" \ 42 | --client-certificate=${CERTS_DIR}/kube-proxy.pem \ 43 | --client-key=${CERTS_DIR}/kube-proxy-key.pem \ 44 | --embed-certs=true \ 45 | --kubeconfig=output/kube-proxy.kubeconfig 46 | 47 | kubectl config set-context default \ 48 | --cluster=kubernetes \ 49 | --user=system:kube-proxy \ 50 | --kubeconfig=output/kube-proxy.kubeconfig 51 | 52 | kubectl config use-context default --kubeconfig=output/kube-proxy.kubeconfig 53 | -------------------------------------------------------------------------------- /scripts/remove/remove_etcd.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | [ -e ../deploy/config.sh ] && . ../deploy/config.sh || exit 4 | 5 | CONFIG_DIR="/etc/etcd" 6 | source ${CONFIG_DIR}/etcd.conf 7 | 8 | systemctl stop etcd 9 | userdel etcd 10 | rm -f /usr/bin/etcd 11 | rm -rf ${ETCD_DATA_DIR} 12 | rm -rf ${CONFIG_DIR} 13 | rm -f /var/log/deploy_etcd.log 14 | -------------------------------------------------------------------------------- /scripts/remove/remove_master.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | systemctl stop kube-apiserver kube-controller-manager kube-scheduler 4 | rm -f /usr/bin/{kube-apiserver,kube-controller-manager,kube-schedule,kubectl} 5 | rm -rf /etc/kubernetes/ 6 | rm -rf /root/.kube/ 7 | rm -f /var/log/deploy_master.log 8 | rm -rf /var/log/kubernetes/ 9 | -------------------------------------------------------------------------------- /scripts/remove/remove_node.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | systemctl stop docker kubelet kube-proxy 4 | rm -f /usr/bin/{kubelet,kube-proxy} 5 | rm -rf /var/lib/kubelet/ 6 | rm -rf /usr/lib/systemd/system/kubelet.service.d/ 7 | rm -rf /etc/kubernetes/ 8 | rm -f /var/log/deploy_node.log 9 | -------------------------------------------------------------------------------- /scripts/systemd/docker.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Docker Application Container Engine 3 | Documentation=https://docs.docker.com 4 | After=network-online.target firewalld.service 5 | Wants=network-online.target 6 | 7 | [Service] 8 | Type=notify 9 | # the default is not to use systemd for cgroups because the delegate issues still 10 | # exists and systemd currently does not support the cgroup feature set required 11 | # for containers run by docker 12 | ExecStart=/usr/bin/dockerd 13 | ExecReload=/bin/kill -s HUP $MAINPID 14 | # Having non-zero Limit*s causes performance problems due to accounting overhead 15 | # in the kernel. We recommend using cgroups to do container-local accounting. 16 | LimitNOFILE=infinity 17 | LimitNPROC=infinity 18 | LimitCORE=infinity 19 | # Uncomment TasksMax if your systemd version supports it. 20 | # Only systemd 226 and above support this version. 21 | #TasksMax=infinity 22 | TimeoutStartSec=0 23 | # set delegate yes so that systemd does not reset the cgroups of docker containers 24 | Delegate=yes 25 | # kill only the docker process, not all processes in the cgroup 26 | KillMode=process 27 | # restart the docker process if it exits prematurely 28 | Restart=on-failure 29 | StartLimitBurst=3 30 | StartLimitInterval=60s 31 | 32 | [Install] 33 | WantedBy=multi-user.target 34 | -------------------------------------------------------------------------------- /scripts/systemd/etcd.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Etcd Server 3 | After=network.target 4 | After=network-online.target 5 | Wants=network-online.target 6 | 7 | [Service] 8 | Type=notify 9 | WorkingDirectory=/var/lib/etcd/ 10 | EnvironmentFile=-/etc/etcd/etcd.conf 11 | User=root 12 | # set GOMAXPROCS to number of processors 13 | ExecStart=/bin/bash -c "GOMAXPROCS=$(nproc) /usr/bin/etcd --name=\"${ETCD_NAME}\" --data-dir=\"${ETCD_DATA_DIR}\" --listen-client-urls=\"${ETCD_LISTEN_CLIENT_URLS}\"" 14 | Restart=on-failure 15 | RestartSec=5 16 | LimitNOFILE=65536 17 | 18 | [Install] 19 | WantedBy=multi-user.target 20 | -------------------------------------------------------------------------------- /scripts/systemd/kube-apiserver.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Kubernetes API Server 3 | Documentation=https://github.com/GoogleCloudPlatform/kubernetes 4 | After=network.target 5 | After=etcd.service 6 | 7 | [Service] 8 | EnvironmentFile=-/etc/kubernetes/config 9 | EnvironmentFile=-/etc/kubernetes/apiserver 10 | ExecStart=/usr/bin/kube-apiserver \ 11 | $KUBE_LOGTOSTDERR \ 12 | $KUBE_LOG_LEVEL \ 13 | $KUBE_ETCD_SERVERS \ 14 | $KUBE_API_ADDRESS \ 15 | $KUBE_API_PORT \ 16 | $KUBELET_PORT \ 17 | $KUBE_ALLOW_PRIV \ 18 | $KUBE_SERVICE_ADDRESSES \ 19 | $KUBE_ADMISSION_CONTROL \ 20 | $KUBE_API_ARGS 21 | Restart=on-failure 22 | RestartSec=5 23 | Type=notify 24 | LimitNOFILE=65536 25 | 26 | [Install] 27 | WantedBy=multi-user.target 28 | -------------------------------------------------------------------------------- /scripts/systemd/kube-controller-manager.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Kubernetes Controller Manager 3 | Documentation=https://github.com/GoogleCloudPlatform/kubernetes 4 | 5 | [Service] 6 | EnvironmentFile=-/etc/kubernetes/config 7 | EnvironmentFile=-/etc/kubernetes/controller-manager 8 | ExecStart=/usr/bin/kube-controller-manager \ 9 | $KUBE_LOGTOSTDERR \ 10 | $KUBE_LOG_LEVEL \ 11 | $KUBE_MASTER \ 12 | $KUBE_CONTROLLER_MANAGER_ARGS 13 | Restart=on-failure 14 | RestartSec=5 15 | LimitNOFILE=65536 16 | 17 | [Install] 18 | WantedBy=multi-user.target 19 | -------------------------------------------------------------------------------- /scripts/systemd/kube-proxy.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Kubernetes Kube-Proxy Server 3 | Documentation=https://github.com/GoogleCloudPlatform/kubernetes 4 | After=network.target 5 | 6 | [Service] 7 | EnvironmentFile=-/etc/kubernetes/config 8 | EnvironmentFile=-/etc/kubernetes/kube-proxy 9 | ExecStart=/usr/bin/kube-proxy \ 10 | $KUBE_LOGTOSTDERR \ 11 | $KUBE_LOG_LEVEL \ 12 | $KUBE_MASTER \ 13 | $KUBE_PROXY_ARGS 14 | Restart=on-failure 15 | RestartSec=5 16 | LimitNOFILE=65536 17 | 18 | [Install] 19 | WantedBy=multi-user.target 20 | -------------------------------------------------------------------------------- /scripts/systemd/kube-scheduler.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Kubernetes Scheduler Plugin 3 | Documentation=https://github.com/GoogleCloudPlatform/kubernetes 4 | 5 | [Service] 6 | EnvironmentFile=-/etc/kubernetes/config 7 | EnvironmentFile=-/etc/kubernetes/scheduler 8 | ExecStart=/usr/bin/kube-scheduler \ 9 | $KUBE_LOGTOSTDERR \ 10 | $KUBE_LOG_LEVEL \ 11 | $KUBE_MASTER \ 12 | $KUBE_SCHEDULER_ARGS 13 | Restart=on-failure 14 | RestartSec=5 15 | LimitNOFILE=65536 16 | 17 | [Install] 18 | WantedBy=multi-user.target 19 | -------------------------------------------------------------------------------- /scripts/systemd/kubelet.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Kubernetes Kubelet Server 3 | Documentation=https://github.com/GoogleCloudPlatform/kubernetes 4 | After=docker.service 5 | Requires=docker.service 6 | 7 | [Service] 8 | WorkingDirectory=/var/lib/kubelet 9 | EnvironmentFile=-/etc/kubernetes/config 10 | EnvironmentFile=-/etc/kubernetes/kubelet 11 | ExecStart=/usr/bin/kubelet \ 12 | $KUBE_LOGTOSTDERR \ 13 | $KUBE_LOG_LEVEL \ 14 | $KUBELET_API_SERVER \ 15 | $KUBELET_ADDRESS \ 16 | $KUBELET_PORT \ 17 | $KUBELET_HOSTNAME \ 18 | $KUBE_ALLOW_PRIV \ 19 | $KUBELET_ARGS 20 | Restart=on-failure 21 | RestartSec=5 22 | KillMode=process 23 | 24 | [Install] 25 | WantedBy=multi-user.target 26 | -------------------------------------------------------------------------------- /scripts/test/create_cluster.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | request_body=$((cat <