diff --git a/.travis.yml b/.travis.yml index d48c38eb..2c01f36d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,17 +1,17 @@ language: go go: - - 1.13.5 + - 1.13.8 install: - go get golang.org/x/tools/cmd/cover - go get github.com/mattn/goveralls - go get -u golang.org/x/lint/golint script: -- hack/verify-codegen.sh -- hack/verify-boilerplate.sh -- hack/verify-gofmt.sh -- hack/verify-golint.sh -- hack/verify-govet.sh -- make fledged-image -- make client-image -- make test -- $(go env GOPATH | awk 'BEGIN{FS=":"} {print $1}')/bin/goveralls -coverprofile=coverage.out -service=travis-ci + - hack/verify-codegen.sh + - hack/verify-boilerplate.sh + - hack/verify-gofmt.sh + - hack/verify-golint.sh + - hack/verify-govet.sh + - make fledged-dev + - make GIT_BRANCH=${TRAVIS_BRANCH} build-images + - make test + - $(go env GOPATH | awk 'BEGIN{FS=":"} {print $1}')/bin/goveralls -coverprofile=coverage.out -service=travis-ci diff --git a/Makefile b/Makefile index 8306f9c4..f689a20d 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -.PHONY: clean clean-fledged clean-client fledged-image client-image push-images test deploy update remove +.PHONY: clean clean-fledged clean-client clean-operator fledged-dev fledged-image client-image operator-image build-images push-images test deploy update remove # Default tag and architecture. Can be overridden TAG?=$(shell git describe --tags --dirty) ARCH?=amd64 @@ -23,30 +23,48 @@ else CGO_ENABLED=0 endif -# Go version to use for builds -GO_VERSION=1.11.1 +GOARM=7 -# K8s version used for Makefile helpers -K8S_VERSION=v1.12.0 +ifndef FLEDGED_IMAGE_REPO + FLEDGED_IMAGE_REPO=docker.io/senthilrch/fledged +endif -GOARM=7 +ifndef FLEDGED_DOCKER_CLIENT_IMAGE_REPO + FLEDGED_DOCKER_CLIENT_IMAGE_REPO=docker.io/senthilrch/fledged-docker-client +endif -ifndef FLEDGED_IMAGE_NAME - FLEDGED_IMAGE_NAME=senthilrch/fledged:latest +ifndef OPERATOR_IMAGE_REPO + OPERATOR_IMAGE_REPO=docker.io/senthilrch/kubefledged-operator endif -ifndef FLEDGED_DOCKER_CLIENT_IMAGE_NAME - FLEDGED_DOCKER_CLIENT_IMAGE_NAME=senthilrch/fledged-docker-client:latest +ifndef RELEASE_VERSION + RELEASE_VERSION=v0.6.0 endif ifndef DOCKER_VERSION - DOCKER_VERSION=19.03.5 + DOCKER_VERSION=19.03.7 endif ifndef CRICTL_VERSION CRICTL_VERSION=v1.17.0 endif +ifndef GOLANG_VERSION + GOLANG_VERSION=1.13.8 +endif + +ifndef ALPINE_VERSION + ALPINE_VERSION=3.11 +endif + +ifndef OPERATORSDK_VERSION + OPERATORSDK_VERSION=v0.15.2 +endif + +ifndef GIT_BRANCH + GIT_BRANCH=master +endif + HTTP_PROXY_CONFIG= ifdef HTTP_PROXY HTTP_PROXY_CONFIG=--build-arg http_proxy=${HTTP_PROXY} @@ -59,59 +77,71 @@ endif ### BUILDING -clean: clean-fledged clean-client +clean: clean-fledged clean-client clean-operator clean-fledged: -rm -f build/fledged - -rm -f build/fledged.tar.gz - -docker image rm $(FLEDGED_IMAGE_NAME) + -docker image rm $(FLEDGED_IMAGE_REPO):$(RELEASE_VERSION) -docker image rm `docker image ls -f dangling=true -q` clean-client: - -rm -f build/fledged-docker-client.tar.gz - -docker image rm $(FLEDGED_DOCKER_CLIENT_IMAGE_NAME) + -docker image rm $(FLEDGED_DOCKER_CLIENT_IMAGE_REPO):$(RELEASE_VERSION) + -docker image rm `docker image ls -f dangling=true -q` + +clean-operator: + -docker image rm $(OPERATOR_IMAGE_REPO):$(RELEASE_VERSION) -docker image rm `docker image ls -f dangling=true -q` -fledged: - CGO_ENABLED=0 go build -o build/fledged \ - -ldflags '-s -w -extldflags "-static"' cmd/fledged.go +fledged-dev: clean-fledged + CGO_ENABLED=0 go build -o build/fledged -ldflags '-s -w -extldflags "-static"' cmd/fledged.go && \ + cd build && docker build -t $(FLEDGED_IMAGE_REPO):$(RELEASE_VERSION) -f Dockerfile.fledged_dev \ + --build-arg ALPINE_VERSION=${ALPINE_VERSION} . -fledged-image: clean-fledged fledged - cd build && docker build -t $(FLEDGED_IMAGE_NAME) . && \ - docker save -o fledged.tar $(FLEDGED_IMAGE_NAME) && \ - gzip fledged.tar +fledged-image: clean-fledged + cd build && docker build -t $(FLEDGED_IMAGE_REPO):$(RELEASE_VERSION) -f Dockerfile.fledged \ + ${HTTP_PROXY_CONFIG} ${HTTPS_PROXY_CONFIG} --build-arg GIT_BRANCH=${GIT_BRANCH} \ + --build-arg GOLANG_VERSION=${GOLANG_VERSION} --build-arg ALPINE_VERSION=${ALPINE_VERSION} . client-image: clean-client - cd build && docker build -t $(FLEDGED_DOCKER_CLIENT_IMAGE_NAME) \ + cd build && docker build -t $(FLEDGED_DOCKER_CLIENT_IMAGE_REPO):$(RELEASE_VERSION) \ -f Dockerfile.docker_client ${HTTP_PROXY_CONFIG} ${HTTPS_PROXY_CONFIG} \ - --build-arg DOCKER_VERSION=${DOCKER_VERSION} --build-arg CRICTL_VERSION=${CRICTL_VERSION} . && \ - docker save -o fledged-docker-client.tar $(FLEDGED_DOCKER_CLIENT_IMAGE_NAME) && \ - gzip fledged-docker-client.tar + --build-arg DOCKER_VERSION=${DOCKER_VERSION} --build-arg CRICTL_VERSION=${CRICTL_VERSION} \ + --build-arg ALPINE_VERSION=${ALPINE_VERSION} . + +operator-image: clean-operator + cd deploy/kubefledged-operator && \ + docker build -t $(OPERATOR_IMAGE_REPO):$(RELEASE_VERSION) -f ./build/Dockerfile \ + --build-arg OPERATORSDK_VERSION=${OPERATORSDK_VERSION} . + +build-images: fledged-image client-image operator-image + +push-images: + -docker push $(FLEDGED_IMAGE_REPO):$(RELEASE_VERSION) + -docker push $(FLEDGED_DOCKER_CLIENT_IMAGE_REPO):$(RELEASE_VERSION) + -docker push $(OPERATOR_IMAGE_REPO):$(RELEASE_VERSION) -push-image: - -docker push $(FLEDGED_IMAGE_NAME) - -docker push $(FLEDGED_DOCKER_CLIENT_IMAGE_NAME) +release: build-images push-images test: -rm -f coverage.out bash hack/run-unit-tests.sh deploy: - kubectl apply -f deploy/fledged-crd.yaml && sleep 2 && \ - kubectl apply -f deploy/fledged-namespace.yaml && sleep 2 && \ - kubectl apply -f deploy/fledged-serviceaccount.yaml && \ - kubectl apply -f deploy/fledged-clusterrole.yaml && \ - kubectl apply -f deploy/fledged-clusterrolebinding.yaml && \ - kubectl apply -f deploy/fledged-deployment.yaml + kubectl apply -f deploy/kubefledged-crd.yaml && sleep 2 && \ + kubectl apply -f deploy/kubefledged-namespace.yaml && sleep 2 && \ + kubectl apply -f deploy/kubefledged-serviceaccount.yaml && \ + kubectl apply -f deploy/kubefledged-clusterrole.yaml && \ + kubectl apply -f deploy/kubefledged-clusterrolebinding.yaml && \ + kubectl apply -f deploy/kubefledged-deployment.yaml update: - kubectl scale deployment fledged --replicas=0 -n kube-fledged && sleep 5 && \ - kubectl scale deployment fledged --replicas=1 -n kube-fledged && sleep 5 && \ - kubectl get pods -l app=fledged -n kube-fledged + kubectl scale deployment kubefledged --replicas=0 -n kube-fledged && sleep 5 && \ + kubectl scale deployment kubefledged --replicas=1 -n kube-fledged && sleep 5 && \ + kubectl get pods -l app=kubefledged -n kube-fledged remove: - kubectl delete -f deploy/fledged-namespace.yaml && \ - kubectl delete -f deploy/fledged-clusterrolebinding.yaml && \ - kubectl delete -f deploy/fledged-clusterrole.yaml && \ - kubectl delete -f deploy/fledged-crd.yaml + kubectl delete -f deploy/kubefledged-namespace.yaml && \ + kubectl delete -f deploy/kubefledged-clusterrolebinding.yaml && \ + kubectl delete -f deploy/kubefledged-clusterrole.yaml && \ + kubectl delete -f deploy/kubefledged-crd.yaml diff --git a/README.md b/README.md index ef901133..8f456085 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,6 @@ -# kube-fledged + + +# [![Build Status](https://travis-ci.org/senthilrch/kube-fledged.svg?branch=master)](https://travis-ci.org/senthilrch/kube-fledged) [![Coverage Status](https://coveralls.io/repos/github/senthilrch/kube-fledged/badge.svg?branch=master)](https://coveralls.io/github/senthilrch/kube-fledged?branch=master) @@ -11,6 +13,34 @@ of images and onto which worker nodes those images should be cached (i.e. pre-pu _kube-fledged_ provides CRUD APIs to manage the lifecycle of the image cache, and supports several configurable parameters to customize the functioning as per one's needs. +## Table of contents + + + + +- [Use cases](#use-cases) +- [Prerequisites](#prerequisites) +- [Quick Install using YAML manifests](#quick-install-using-yaml-manifests) +- [Quick Install using Helm operator](#quick-install-using-helm-operator) +- [Build and Deploy](#build-and-deploy) + - [Build](#build) + - [Deploy](#deploy) +- [How to use](#how-to-use) + - [Create image cache](#create-image-cache) + - [View the status of image cache](#view-the-status-of-image-cache) + - [Add/remove images in image cache](#addremove-images-in-image-cache) + - [Refresh image cache](#refresh-image-cache) + - [Delete image cache](#delete-image-cache) + - [Remove kube-fledged](#remove-kube-fledged) +- [How it works](#how-it-works) +- [Configuration Flags](#configuration-flags) +- [Supported Platforms](#supported-platforms) +- [Built With](#built-with) +- [Contributing](#contributing) +- [License](#license) + + + ## Use cases - Applications that require rapid start-up. For e.g. an application performing real-time data processing needs to scale rapidly due to a burst in data volume. @@ -25,9 +55,9 @@ _kube-fledged_ provides CRUD APIs to manage the lifecycle of the image cache, an - Supported container runtimes: docker, containerd, cri-o - git, make, go, docker and kubectl installed on a local linux machine. kubectl configured properly to access the cluster. -## Quick Install +## Quick Install using YAML manifests -These instructions install _kube-fledged_ using pre-built images of the latest stable release in [Docker Hub.](https://hub.docker.com/u/senthilrch) +These instructions install _kube-fledged_ to a separate namespace called "kube-fledged", using YAML manifests and pre-built images in [Docker Hub.](https://hub.docker.com/u/senthilrch) - Clone the source code repository @@ -46,14 +76,57 @@ These instructions install _kube-fledged_ using pre-built images of the latest s - Verify if _kube-fledged_ deployed successfully ``` - $ kubectl get pods -n kube-fledged -l app=fledged + $ kubectl get pods -n kube-fledged -l app=kubefledged + $ kubectl logs -f -n kube-fledged + $ kubectl get imagecaches -n kube-fledged (Output should be: 'No resources found') + ``` + +## Quick Install using Helm operator + +These instructions install _kube-fledged_ to a separate namespace called "kube-fledged", using Helm operator and pre-built images in [Docker Hub.](https://hub.docker.com/u/senthilrch) + +- Clone the source code repository + + ``` + $ mkdir -p $HOME/src/github.com/senthilrch + $ git clone https://github.com/senthilrch/kube-fledged.git $HOME/src/github.com/senthilrch/kube-fledged + $ cd $HOME/src/github.com/senthilrch/kube-fledged + ``` + +- Deploy the operator to a separate namespace called "operators" + + ``` + $ sed -i "s|OPERATOR_NAMESPACE|operators|g" deploy/kubefledged-operator/deploy/service_account.yaml + $ sed -i "s|OPERATOR_NAMESPACE|operators|g" deploy/kubefledged-operator/deploy/clusterrole_binding.yaml + $ sed -i "s|OPERATOR_NAMESPACE|operators|g" deploy/kubefledged-operator/deploy/operator.yaml + $ kubectl create namespace operators + $ kubectl create -f deploy/kubefledged-operator/deploy/crds/charts.helm.k8s.io_kubefledgeds_crd.yaml + $ kubectl create -f deploy/kubefledged-operator/deploy/service_account.yaml + $ kubectl create -f deploy/kubefledged-operator/deploy/clusterrole.yaml + $ kubectl create -f deploy/kubefledged-operator/deploy/clusterrole_binding.yaml + $ kubectl create -f deploy/kubefledged-operator/deploy/operator.yaml + ``` + +- Deploy _kube-fledged_ to a separate namespace called "kube-fledged" + + ``` + $ sed -i "s|OPERATOR_NAMESPACE|operators|g" deploy/kubefledged-operator/deploy/crds/charts.helm.k8s.io_v1alpha1_kubefledged_cr.yaml + $ sed -i "s|KUBEFLEDGED_NAMESPACE|kube-fledged|g" deploy/kubefledged-operator/deploy/crds/charts.helm.k8s.io_v1alpha1_kubefledged_cr.yaml + $ kubectl create namespace kube-fledged + $ kubectl create -f deploy/kubefledged-operator/deploy/crds/charts.helm.k8s.io_v1alpha1_kubefledged_cr.yaml + ``` + +- Verify if _kube-fledged_ deployed successfully + + ``` + $ kubectl get pods -n kube-fledged -l app.kubernetes.io/name=kubefledged $ kubectl logs -f -n kube-fledged $ kubectl get imagecaches -n kube-fledged (Output should be: 'No resources found') ``` ## Build and Deploy -These instructions will help you build _kube-fledged_ from source and deploy it on a kubernetes cluster. +These instructions will help you build _kube-fledged_ from source and deploy it to a separate namespace called "kube-fledged". If you need to deploy it to a different namespace, edit the namespace field of the manifests in "kube-fledged/deploy" accordingly. ### Build @@ -75,18 +148,18 @@ These instructions will help you build _kube-fledged_ from source and deploy it - Build and push the docker images to registry (e.g. Docker hub) ``` - $ export FLEDGED_IMAGE_NAME=/fledged: - $ export FLEDGED_DOCKER_CLIENT_IMAGE_NAME=/fledged-docker-client: - $ export DOCKER_VERSION= + $ export RELEASE_VERSION= + $ export FLEDGED_IMAGE_REPO=/fledged + $ export FLEDGED_DOCKER_CLIENT_IMAGE_REPO=/fledged-docker-client $ docker login -u -p - $ make fledged-image && make client-image && make push-image + $ make fledged-image && make client-image && make push-images ``` ### Deploy _Note:- You need to have 'cluster-admin' privileges to deploy_ -- All manifests required for deploying _kube-fledged_ are present inside 'kube-fledged/deploy'. These steps deploy _kube-fledged_ into a separate namespace called "kube-fledged" with default configuration flags. Edit "fledged-deployment.yaml". +- All manifests required for deploying _kube-fledged_ are present in 'kube-fledged/deploy' directory. Edit "kubefledged-deployment.yaml". Set "image" to "/fledged:" @@ -94,10 +167,10 @@ _Note:- You need to have 'cluster-admin' privileges to deploy_ image: /fledged: ``` -- If you pushed the image to a private repository, add 'imagePullSecrets' to the end of "fledged-deployment.yaml". Refer to kubernetes documentation on [Specifying ImagePullSecrets on a Pod](https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod). The secret should be created in "kube-fledged" namespace. +- If you pushed the image to a private repository, add 'imagePullSecrets' to the end of "kubefledged-deployment.yaml". Refer to kubernetes documentation on [Specifying ImagePullSecrets on a Pod](https://kubernetes.io/docs/concepts/containers/images/#specifying-imagepullsecrets-on-a-pod). The secret should be created in "kube-fledged" namespace. ``` - serviceAccountName: fledged + serviceAccountName: kubefledged imagePullSecrets: - name: ``` @@ -111,7 +184,7 @@ _Note:- You need to have 'cluster-admin' privileges to deploy_ - Verify if _kube-fledged_ deployed successfully ``` - $ kubectl get pods -n kube-fledged -l app=fledged + $ kubectl get pods -n kube-fledged -l app=kubefledged $ kubectl logs -f -n kube-fledged $ kubectl get imagecaches -n kube-fledged (Output should be: 'No resources found') ``` @@ -122,7 +195,7 @@ _kube-fledged_ provides APIs to perform CRUD operations on image cache. These A ### Create image cache -Refer to sample image cache manifest in "deploy/fledged-imagecache.yaml". Edit it as per your needs before creating image cache. If images are in private repositories requiring credentials to pull, add "imagePullSecrets" to the end. +Refer to sample image cache manifest in "deploy/kubefledged-imagecache.yaml". Edit it as per your needs before creating image cache. If images are in private repositories requiring credentials to pull, add "imagePullSecrets" to the end. ``` imagePullSecrets: @@ -132,7 +205,7 @@ Refer to sample image cache manifest in "deploy/fledged-imagecache.yaml". Edit i Create the image cache using kubectl. Verify successful creation ``` -$ kubectl create -f deploy/fledged-imagecache.yaml +$ kubectl create -f deploy/kubefledged-imagecache.yaml $ kubectl get imagecaches -n kube-fledged ``` diff --git a/build/Dockerfile.docker_client b/build/Dockerfile.docker_client index 536df98e..ce87e732 100644 --- a/build/Dockerfile.docker_client +++ b/build/Dockerfile.docker_client @@ -12,7 +12,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM alpine:3.10 +ARG ALPINE_VERSION +FROM alpine:$ALPINE_VERSION RUN apk add --no-cache bash curl openssh-client diff --git a/build/Dockerfile.fledged b/build/Dockerfile.fledged new file mode 100644 index 00000000..db3b7d88 --- /dev/null +++ b/build/Dockerfile.fledged @@ -0,0 +1,30 @@ +# Copyright 2018 The kube-fledged authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ARG GOLANG_VERSION +ARG ALPINE_VERSION + +FROM golang:$GOLANG_VERSION AS builder +LABEL stage=builder +ARG GIT_BRANCH +RUN mkdir -p /go/src/github.com/senthilrch && \ + git clone --depth=1 --single-branch --branch=$GIT_BRANCH https://github.com/senthilrch/kube-fledged /go/src/github.com/senthilrch/kube-fledged && \ + cd /go/src/github.com/senthilrch/kube-fledged && \ + CGO_ENABLED=0 go build -o build/fledged -ldflags '-s -w -extldflags "-static"' cmd/fledged.go + +FROM alpine:$ALPINE_VERSION +LABEL maintainer="senthilrch " +COPY --from=builder /go/src/github.com/senthilrch/kube-fledged/build/fledged /opt/bin/fledged +RUN chmod 755 /opt/bin/fledged +ENTRYPOINT ["/opt/bin/fledged"] diff --git a/build/Dockerfile b/build/Dockerfile.fledged_dev similarity index 93% rename from build/Dockerfile rename to build/Dockerfile.fledged_dev index 45748b3d..d002f012 100644 --- a/build/Dockerfile +++ b/build/Dockerfile.fledged_dev @@ -12,7 +12,9 @@ # See the License for the specific language governing permissions and # limitations under the License. -FROM alpine:3.10 +ARG ALPINE_VERSION + +FROM alpine:$ALPINE_VERSION LABEL maintainer="senthilrch " COPY fledged /opt/bin/fledged diff --git a/cmd/app/controller.go b/cmd/app/controller.go index 39976efe..e17c9ab4 100644 --- a/cmd/app/controller.go +++ b/cmd/app/controller.go @@ -45,7 +45,6 @@ import ( ) const controllerAgentName = "fledged" -const fledgedNameSpace = "kube-fledged" const fledgedCacheSpecValidationKey = "fledged.k8s.io/cachespecvalidation" const imageCachePurgeAnnotationKey = "fledged.k8s.io/purge-imagecache" const imageCacheRefreshAnnotationKey = "fledged.k8s.io/refresh-imagecache" @@ -65,6 +64,7 @@ type Controller struct { // fledgedclientset is a clientset for fledged.k8s.io API group fledgedclientset clientset.Interface + fledgedNameSpace string nodesLister corelisters.NodeLister nodesSynced cache.InformerSynced imageCachesLister listers.ImageCacheLister @@ -88,6 +88,7 @@ type Controller struct { func NewController( kubeclientset kubernetes.Interface, fledgedclientset clientset.Interface, + namespace string, nodeInformer coreinformers.NodeInformer, imageCacheInformer informers.ImageCacheInformer, imageCacheRefreshFrequency time.Duration, @@ -105,6 +106,7 @@ func NewController( controller := &Controller{ kubeclientset: kubeclientset, fledgedclientset: fledgedclientset, + fledgedNameSpace: namespace, nodesLister: nodeInformer.Lister(), nodesSynced: nodeInformer.Informer().HasSynced, imageCachesLister: imageCacheInformer.Lister(), @@ -115,7 +117,7 @@ func NewController( imageCacheRefreshFrequency: imageCacheRefreshFrequency, } - imageManager, _ := images.NewImageManager(controller.workqueue, controller.imageworkqueue, controller.kubeclientset, fledgedNameSpace, imagePullDeadlineDuration, dockerClientImage, imagePullPolicy) + imageManager, _ := images.NewImageManager(controller.workqueue, controller.imageworkqueue, controller.kubeclientset, controller.fledgedNameSpace, imagePullDeadlineDuration, dockerClientImage, imagePullPolicy) controller.imageManager = imageManager glog.Info("Setting up event handlers") @@ -147,7 +149,7 @@ func (c *Controller) PreFlightChecks() error { // danglingJobs finds and removes dangling or stuck jobs func (c *Controller) danglingJobs() error { - joblist, err := c.kubeclientset.BatchV1().Jobs(fledgedNameSpace).List(metav1.ListOptions{}) + joblist, err := c.kubeclientset.BatchV1().Jobs(c.fledgedNameSpace).List(metav1.ListOptions{}) if err != nil { glog.Errorf("Error listing jobs: %v", err) return err @@ -159,7 +161,7 @@ func (c *Controller) danglingJobs() error { } deletePropagation := metav1.DeletePropagationBackground for _, job := range joblist.Items { - err := c.kubeclientset.BatchV1().Jobs(fledgedNameSpace). + err := c.kubeclientset.BatchV1().Jobs(c.fledgedNameSpace). Delete(job.Name, &metav1.DeleteOptions{PropagationPolicy: &deletePropagation}) if err != nil { glog.Errorf("Error deleting job(%s): %v", job.Name, err) @@ -174,7 +176,7 @@ func (c *Controller) danglingJobs() error { // image caches will get refreshed in the next cycle func (c *Controller) danglingImageCaches() error { dangling := false - imagecachelist, err := c.fledgedclientset.FledgedV1alpha1().ImageCaches(fledgedNameSpace).List(metav1.ListOptions{}) + imagecachelist, err := c.fledgedclientset.FledgedV1alpha1().ImageCaches(c.fledgedNameSpace).List(metav1.ListOptions{}) if err != nil { glog.Errorf("Error listing imagecaches: %v", err) return err @@ -391,7 +393,7 @@ func (c *Controller) processNextWorkItem() bool { // runRefreshWorker is resposible of refreshing the image cache func (c *Controller) runRefreshWorker() { // List the ImageCache resources - imageCaches, err := c.imageCachesLister.ImageCaches(fledgedNameSpace).List(labels.Everything()) + imageCaches, err := c.imageCachesLister.ImageCaches(c.fledgedNameSpace).List(labels.Everything()) if err != nil { glog.Errorf("Error in listing image caches: %v", err) return diff --git a/cmd/app/controller_test.go b/cmd/app/controller_test.go index e0fb3f42..b52a0eb1 100644 --- a/cmd/app/controller_test.go +++ b/cmd/app/controller_test.go @@ -40,6 +40,8 @@ import ( core "k8s.io/client-go/testing" ) +const fledgedNameSpace = "kube-fledged" + // noResyncPeriodFunc returns 0 for resyncPeriod in case resyncing is not needed. func noResyncPeriodFunc() time.Duration { return 0 @@ -63,7 +65,7 @@ func newTestController(kubeclientset kubernetes.Interface, fledgedclientset clie fledgedInformerFactory.Start(stopCh) } */ - controller := NewController(kubeclientset, fledgedclientset, nodeInformer, imagecacheInformer, + controller := NewController(kubeclientset, fledgedclientset, fledgedNameSpace, nodeInformer, imagecacheInformer, imageCacheRefreshFrequency, imagePullDeadlineDuration, dockerClientImage, imagePullPolicy) controller.nodesSynced = func() bool { return true } controller.imageCachesSynced = func() bool { return true } diff --git a/cmd/fledged.go b/cmd/fledged.go index 89d61ab0..af1ee8a5 100644 --- a/cmd/fledged.go +++ b/cmd/fledged.go @@ -18,6 +18,7 @@ package main import ( "flag" + "os" "time" "github.com/golang/glog" @@ -38,6 +39,7 @@ var ( imagePullDeadlineDuration time.Duration dockerClientImage string imagePullPolicy string + fledgedNameSpace string ) func main() { @@ -64,7 +66,7 @@ func main() { kubeInformerFactory := kubeinformers.NewSharedInformerFactory(kubeClient, time.Second*30) fledgedInformerFactory := informers.NewSharedInformerFactory(fledgedClient, time.Second*30) - controller := app.NewController(kubeClient, fledgedClient, + controller := app.NewController(kubeClient, fledgedClient, fledgedNameSpace, kubeInformerFactory.Core().V1().Nodes(), fledgedInformerFactory.Fledged().V1alpha1().ImageCaches(), imageCacheRefreshFrequency, imagePullDeadlineDuration, dockerClientImage, imagePullPolicy) @@ -88,4 +90,7 @@ func init() { flag.DurationVar(&imageCacheRefreshFrequency, "image-cache-refresh-frequency", time.Minute*15, "The image cache is refreshed periodically to ensure the cache is up to date. Setting this flag to 0s will disable refresh") flag.StringVar(&dockerClientImage, "docker-client-image", "senthilrch/fledged-docker-client:latest", "The image name of the docker client. the docker client is used when deleting images during purging the cache") flag.StringVar(&imagePullPolicy, "image-pull-policy", "", " Image pull policy for pulling images into the cache. Possible values are 'IfNotPresent' and 'Always'. Default value is 'IfNotPresent'. Default value for Images with ':latest' tag is 'Always'") + if fledgedNameSpace = os.Getenv("KUBEFLEDGED_NAMESPACE"); fledgedNameSpace == "" { + fledgedNameSpace = "kube-fledged" + } } diff --git a/deploy/fledged-clusterrole.yaml b/deploy/kubefledged-clusterrole.yaml similarity index 97% rename from deploy/fledged-clusterrole.yaml rename to deploy/kubefledged-clusterrole.yaml index bb6f1c37..9a39a6f0 100644 --- a/deploy/fledged-clusterrole.yaml +++ b/deploy/kubefledged-clusterrole.yaml @@ -1,7 +1,7 @@ kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: - name: fledged + name: kubefledged annotations: rbac.authorization.kubernetes.io/autoupdate: "true" rules: diff --git a/deploy/fledged-clusterrolebinding.yaml b/deploy/kubefledged-clusterrolebinding.yaml similarity index 82% rename from deploy/fledged-clusterrolebinding.yaml rename to deploy/kubefledged-clusterrolebinding.yaml index 447d44bf..c9b6a57b 100644 --- a/deploy/fledged-clusterrolebinding.yaml +++ b/deploy/kubefledged-clusterrolebinding.yaml @@ -1,14 +1,14 @@ kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 metadata: - name: fledged + name: kubefledged roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole - name: fledged + name: kubefledged subjects: - kind: ServiceAccount - name: fledged + name: kubefledged namespace: kube-fledged - apiGroup: rbac.authorization.k8s.io kind: Group diff --git a/deploy/fledged-crd.yaml b/deploy/kubefledged-crd.yaml similarity index 100% rename from deploy/fledged-crd.yaml rename to deploy/kubefledged-crd.yaml diff --git a/deploy/fledged-deployment.yaml b/deploy/kubefledged-deployment.yaml similarity index 64% rename from deploy/fledged-deployment.yaml rename to deploy/kubefledged-deployment.yaml index e380d8cd..34f1288a 100644 --- a/deploy/fledged-deployment.yaml +++ b/deploy/kubefledged-deployment.yaml @@ -1,29 +1,34 @@ apiVersion: apps/v1 kind: Deployment metadata: - name: fledged + name: kubefledged namespace: kube-fledged spec: replicas: 1 selector: matchLabels: - app: fledged + app: kubefledged template: metadata: labels: - app: fledged + app: kubefledged spec: containers: - - image: senthilrch/fledged:v0.5.0 + - image: senthilrch/fledged:v0.6.0 command: ["/opt/bin/fledged"] args: - "--stderrthreshold=INFO" - "--image-pull-deadline-duration=5m" - "--image-cache-refresh-frequency=15m" - - "--docker-client-image=senthilrch/fledged-docker-client:v0.5.0" + - "--docker-client-image=senthilrch/fledged-docker-client:v0.6.0" - "--image-pull-policy=IfNotPresent" imagePullPolicy: Always name: fledged - serviceAccountName: fledged + env: + - name: KUBEFLEDGED_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + serviceAccountName: kubefledged diff --git a/deploy/fledged-imagecache.yaml b/deploy/kubefledged-imagecache.yaml similarity index 65% rename from deploy/fledged-imagecache.yaml rename to deploy/kubefledged-imagecache.yaml index 524bc2b7..76894823 100644 --- a/deploy/fledged-imagecache.yaml +++ b/deploy/kubefledged-imagecache.yaml @@ -7,13 +7,8 @@ metadata: spec: cacheSpec: - images: - - senthilrch/my-private-app:1.0 - nginx - images: - redis - - jenkins - - docker - nodeSelector: - kubernetes.io/hostname: worker1 imagePullSecrets: - name: myregistrykey diff --git a/deploy/fledged-namespace.yaml b/deploy/kubefledged-namespace.yaml similarity index 100% rename from deploy/fledged-namespace.yaml rename to deploy/kubefledged-namespace.yaml diff --git a/deploy/kubefledged-operator/build/Dockerfile b/deploy/kubefledged-operator/build/Dockerfile new file mode 100644 index 00000000..d84a900c --- /dev/null +++ b/deploy/kubefledged-operator/build/Dockerfile @@ -0,0 +1,6 @@ +ARG OPERATORSDK_VERSION + +FROM quay.io/operator-framework/helm-operator:${OPERATORSDK_VERSION} + +COPY watches.yaml ${HOME}/watches.yaml +COPY helm-charts/ ${HOME}/helm-charts/ diff --git a/deploy/kubefledged-operator/deploy/clusterrole.yaml b/deploy/kubefledged-operator/deploy/clusterrole.yaml new file mode 100644 index 00000000..9b82197e --- /dev/null +++ b/deploy/kubefledged-operator/deploy/clusterrole.yaml @@ -0,0 +1,149 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + creationTimestamp: null + name: kubefledged-operator +rules: +- apiGroups: + - "" + resources: + - namespaces + verbs: + - get +- apiGroups: + - "" + resources: + - configmaps + - secrets + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - "" + resources: + - events + verbs: + - create +- apiGroups: + - "" + resources: + - serviceaccounts + - services + verbs: + - '*' +- apiGroups: + - apps + resources: + - deployments + verbs: + - '*' +- apiGroups: + - monitoring.coreos.com + resources: + - servicemonitors + verbs: + - get + - create +- apiGroups: + - apps + resourceNames: + - kubefledged-operator + resources: + - deployments/finalizers + verbs: + - update +- apiGroups: + - "" + resources: + - pods + verbs: + - get + - list + - watch +- apiGroups: + - apps + resources: + - replicasets + - deployments + verbs: + - get +- apiGroups: + - charts.helm.k8s.io + resources: + - '*' + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - create + - delete + - get + - patch +- apiGroups: + - rbac.authorization.k8s.io + resources: + - clusterroles + - clusterrolebindings + verbs: + - create + - delete + - get + - patch +- apiGroups: + - "fledged.k8s.io" + resources: + - imagecaches + verbs: + - get + - list + - watch + - update + - patch +- apiGroups: + - "fledged.k8s.io" + resources: + - imagecaches/status + verbs: + - patch +- apiGroups: + - "" + resources: + - nodes + verbs: + - list + - watch + - get +- apiGroups: + - "" + resources: + - events + verbs: + - get + - list + - create + - update + - patch +- apiGroups: + - "batch" + resources: + - jobs + verbs: + - get + - list + - create + - delete + diff --git a/deploy/kubefledged-operator/deploy/clusterrole_binding.yaml b/deploy/kubefledged-operator/deploy/clusterrole_binding.yaml new file mode 100644 index 00000000..7a2d2c8c --- /dev/null +++ b/deploy/kubefledged-operator/deploy/clusterrole_binding.yaml @@ -0,0 +1,12 @@ +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: kubefledged-operator +subjects: +- kind: ServiceAccount + name: kubefledged-operator + namespace: OPERATOR_NAMESPACE +roleRef: + kind: ClusterRole + name: kubefledged-operator + apiGroup: rbac.authorization.k8s.io diff --git a/deploy/kubefledged-operator/deploy/crds/charts.helm.k8s.io_kubefledgeds_crd.yaml b/deploy/kubefledged-operator/deploy/crds/charts.helm.k8s.io_kubefledgeds_crd.yaml new file mode 100644 index 00000000..a88b4865 --- /dev/null +++ b/deploy/kubefledged-operator/deploy/crds/charts.helm.k8s.io_kubefledgeds_crd.yaml @@ -0,0 +1,22 @@ +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: kubefledgeds.charts.helm.k8s.io +spec: + group: charts.helm.k8s.io + names: + kind: KubeFledged + listKind: KubeFledgedList + plural: kubefledgeds + singular: kubefledged + scope: Namespaced + subresources: + status: {} + validation: + openAPIV3Schema: + type: object + x-kubernetes-preserve-unknown-fields: true + versions: + - name: v1alpha1 + served: true + storage: true diff --git a/deploy/kubefledged-operator/deploy/crds/charts.helm.k8s.io_v1alpha1_kubefledged_cr.yaml b/deploy/kubefledged-operator/deploy/crds/charts.helm.k8s.io_v1alpha1_kubefledged_cr.yaml new file mode 100644 index 00000000..121d0bb7 --- /dev/null +++ b/deploy/kubefledged-operator/deploy/crds/charts.helm.k8s.io_v1alpha1_kubefledged_cr.yaml @@ -0,0 +1,8 @@ +apiVersion: charts.helm.k8s.io/v1alpha1 +kind: KubeFledged +metadata: + name: mykubefledged + namespace: OPERATOR_NAMESPACE +spec: + # Defaults defined in /helm-charts/kubefledged/values.yaml + kubefledgedNameSpace: KUBEFLEDGED_NAMESPACE diff --git a/deploy/kubefledged-operator/deploy/operator.yaml b/deploy/kubefledged-operator/deploy/operator.yaml new file mode 100644 index 00000000..d23e88ab --- /dev/null +++ b/deploy/kubefledged-operator/deploy/operator.yaml @@ -0,0 +1,32 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: kubefledged-operator + namespace: OPERATOR_NAMESPACE +spec: + replicas: 1 + selector: + matchLabels: + name: kubefledged-operator + template: + metadata: + labels: + name: kubefledged-operator + spec: + serviceAccountName: kubefledged-operator + containers: + - name: kubefledged-operator + # Replace this with the built image name + image: docker.io/senthilrch/kubefledged-operator:v0.6.0 + imagePullPolicy: Always + env: + - name: WATCH_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: OPERATOR_NAME + value: "kubefledged-operator" diff --git a/deploy/kubefledged-operator/deploy/service_account.yaml b/deploy/kubefledged-operator/deploy/service_account.yaml new file mode 100644 index 00000000..1cb416f5 --- /dev/null +++ b/deploy/kubefledged-operator/deploy/service_account.yaml @@ -0,0 +1,5 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: kubefledged-operator + namespace: OPERATOR_NAMESPACE diff --git a/deploy/kubefledged-operator/helm-charts/kubefledged/.helmignore b/deploy/kubefledged-operator/helm-charts/kubefledged/.helmignore new file mode 100644 index 00000000..50af0317 --- /dev/null +++ b/deploy/kubefledged-operator/helm-charts/kubefledged/.helmignore @@ -0,0 +1,22 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/deploy/kubefledged-operator/helm-charts/kubefledged/Chart.yaml b/deploy/kubefledged-operator/helm-charts/kubefledged/Chart.yaml new file mode 100644 index 00000000..e13768d7 --- /dev/null +++ b/deploy/kubefledged-operator/helm-charts/kubefledged/Chart.yaml @@ -0,0 +1,21 @@ +apiVersion: v2 +name: kubefledged +description: A Helm chart for Kubernetes + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +version: v0.6.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. +appVersion: v0.6.0 diff --git a/deploy/kubefledged-operator/helm-charts/kubefledged/templates/NOTES.txt b/deploy/kubefledged-operator/helm-charts/kubefledged/templates/NOTES.txt new file mode 100644 index 00000000..fac79dcb --- /dev/null +++ b/deploy/kubefledged-operator/helm-charts/kubefledged/templates/NOTES.txt @@ -0,0 +1,21 @@ +1. Get the application URL by running these commands: +{{- if .Values.ingress.enabled }} +{{- range $host := .Values.ingress.hosts }} + {{- range .paths }} + http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }} + {{- end }} +{{- end }} +{{- else if contains "NodePort" .Values.service.type }} + export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "kubefledged.fullname" . }}) + export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") + echo http://$NODE_IP:$NODE_PORT +{{- else if contains "LoadBalancer" .Values.service.type }} + NOTE: It may take a few minutes for the LoadBalancer IP to be available. + You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "kubefledged.fullname" . }}' + export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "kubefledged.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") + echo http://$SERVICE_IP:{{ .Values.service.port }} +{{- else if contains "ClusterIP" .Values.service.type }} + export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "kubefledged.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") + echo "Visit http://127.0.0.1:8080 to use your application" + kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:80 +{{- end }} diff --git a/deploy/kubefledged-operator/helm-charts/kubefledged/templates/_helpers.tpl b/deploy/kubefledged-operator/helm-charts/kubefledged/templates/_helpers.tpl new file mode 100644 index 00000000..824d7fa9 --- /dev/null +++ b/deploy/kubefledged-operator/helm-charts/kubefledged/templates/_helpers.tpl @@ -0,0 +1,85 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "kubefledged.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +If release name contains chart name it will be used as a full name. +*/}} +{{- define "kubefledged.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- if contains $name .Release.Name -}} +{{- .Release.Name | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "kubefledged.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Common labels +*/}} +{{- define "kubefledged.labels" -}} +helm.sh/chart: {{ include "kubefledged.chart" . }} +{{ include "kubefledged.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end -}} + +{{/* +Selector labels +*/}} +{{- define "kubefledged.selectorLabels" -}} +app.kubernetes.io/name: {{ include "kubefledged.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end -}} + +{{/* +Create the name of the service account to use +*/}} +{{- define "kubefledged.serviceAccountName" -}} +{{- if .Values.serviceAccount.create -}} + {{ default (include "kubefledged.fullname" .) .Values.serviceAccount.name }} +{{- else -}} + {{ default "default" .Values.serviceAccount.name }} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the cluster role to use +*/}} +{{- define "kubefledged.clusterRoleName" -}} +{{- if .Values.clusterRole.create -}} + {{ default (include "kubefledged.fullname" .) .Values.clusterRole.name }} +{{- else -}} + {{ default "default" .Values.clusterRole.name }} +{{- end -}} +{{- end -}} + +{{/* +Create the name of the cluster role binding to use +*/}} +{{- define "kubefledged.clusterRoleBindingName" -}} +{{- if .Values.clusterRoleBinding.create -}} + {{ default (include "kubefledged.fullname" .) .Values.clusterRoleBinding.name }} +{{- else -}} + {{ default "default" .Values.clusterRoleBinding.name }} +{{- end -}} +{{- end -}} diff --git a/deploy/kubefledged-operator/helm-charts/kubefledged/templates/clusterrole.yaml b/deploy/kubefledged-operator/helm-charts/kubefledged/templates/clusterrole.yaml new file mode 100644 index 00000000..d09b5c45 --- /dev/null +++ b/deploy/kubefledged-operator/helm-charts/kubefledged/templates/clusterrole.yaml @@ -0,0 +1,61 @@ +{{- if .Values.clusterRole.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "kubefledged.clusterRoleName" . }} + labels: + {{ include "kubefledged.labels" . | nindent 4 }} + annotations: + rbac.authorization.kubernetes.io/autoupdate: "true" +rules: + - apiGroups: + - "fledged.k8s.io" + resources: + - imagecaches + verbs: + - get + - list + - watch + - update + - apiGroups: + - "fledged.k8s.io" + resources: + - imagecaches/status + verbs: + - patch + - apiGroups: + - "" + resources: + - nodes + verbs: + - list + - watch + - get + - apiGroups: + - "" + resources: + - events + verbs: + - get + - list + - create + - update + - patch + - apiGroups: + - "batch" + resources: + - jobs + verbs: + - get + - list + - create + - delete + - apiGroups: + - "" + resources: + - pods + verbs: + - list + - watch + - get +{{- end -}} \ No newline at end of file diff --git a/deploy/kubefledged-operator/helm-charts/kubefledged/templates/clusterrolebinding.yaml b/deploy/kubefledged-operator/helm-charts/kubefledged/templates/clusterrolebinding.yaml new file mode 100644 index 00000000..78a171a9 --- /dev/null +++ b/deploy/kubefledged-operator/helm-charts/kubefledged/templates/clusterrolebinding.yaml @@ -0,0 +1,19 @@ +{{- if .Values.clusterRoleBinding.create -}} +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "kubefledged.clusterRoleBindingName" . }} + labels: + {{ include "kubefledged.labels" . | nindent 4 }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "kubefledged.clusterRoleName" . }} +subjects: +- kind: ServiceAccount + name: {{ include "kubefledged.serviceAccountName" . }} + namespace: {{ .Values.kubefledgedNameSpace }} +- apiGroup: rbac.authorization.k8s.io + kind: Group + name: system:nodes +{{- end -}} diff --git a/deploy/kubefledged-operator/helm-charts/kubefledged/templates/crd.yaml b/deploy/kubefledged-operator/helm-charts/kubefledged/templates/crd.yaml new file mode 100644 index 00000000..89198a4b --- /dev/null +++ b/deploy/kubefledged-operator/helm-charts/kubefledged/templates/crd.yaml @@ -0,0 +1,112 @@ +apiVersion: apiextensions.k8s.io/v1beta1 +kind: CustomResourceDefinition +metadata: + name: imagecaches.fledged.k8s.io + labels: +{{ include "kubefledged.labels" . | nindent 4 }} +spec: + group: fledged.k8s.io + versions: + - name: v1alpha1 + served: true + storage: true + scope: Namespaced + names: + plural: imagecaches + singular: imagecache + kind: ImageCache + shortNames: + - ic + "validation": + "openAPIV3Schema": + description: ImageCache is a specification for a ImageCache resource + type: object + required: + - spec + properties: + apiVersion: + description: 'APIVersion defines the versioned schema of this representation + of an object. Servers should convert recognized schemas to the latest + internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + type: string + kind: + description: 'Kind is a string value representing the REST resource this + object represents. Servers may infer this from the endpoint the client + submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + type: string + metadata: + type: object + spec: + description: ImageCacheSpec is the spec for a ImageCache resource + type: object + required: + - cacheSpec + properties: + cacheSpec: + type: array + items: + description: CacheSpecImages specifies the Images to be cached + type: object + required: + - images + properties: + images: + type: array + items: + type: string + nodeSelector: + type: object + additionalProperties: + type: string + imagePullSecrets: + type: array + items: + description: LocalObjectReference contains enough information to let + you locate the referenced object inside the same namespace. + type: object + properties: + name: + description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid?' + type: string + status: + description: ImageCacheStatus is the status for a ImageCache resource + type: object + required: + - message + - reason + - startTime + - status + properties: + completionTime: + type: string + format: date-time + failures: + type: object + additionalProperties: + type: array + items: + description: NodeReasonMessage has failure reason and message for + a node + type: object + required: + - message + - node + - reason + properties: + message: + type: string + node: + type: string + reason: + type: string + message: + type: string + reason: + type: string + startTime: + type: string + format: date-time + status: + description: ImageCacheActionStatus defines the status of ImageCacheAction + type: string diff --git a/deploy/kubefledged-operator/helm-charts/kubefledged/templates/deployment.yaml b/deploy/kubefledged-operator/helm-charts/kubefledged/templates/deployment.yaml new file mode 100644 index 00000000..b2692105 --- /dev/null +++ b/deploy/kubefledged-operator/helm-charts/kubefledged/templates/deployment.yaml @@ -0,0 +1,56 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "kubefledged.fullname" . }} + labels: + {{- include "kubefledged.labels" . | nindent 4 }} + namespace: {{ .Values.kubefledgedNameSpace }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + {{- include "kubefledged.selectorLabels" . | nindent 6 }} + template: + metadata: + labels: + {{- include "kubefledged.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "kubefledged.serviceAccountName" . }} + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: {{ .Values.image.fledgedRepository }}:{{ .Chart.AppVersion }} + command: {{ .Values.command }} + args: + - "--stderrthreshold={{ .Values.args.logLevel}}" + - "--image-pull-deadline-duration={{ .Values.args.imagePullDeadlineDuration}}" + - "--image-cache-refresh-frequency={{ .Values.args.imageCacheRefreshFrequency}}" + - "--docker-client-image={{ .Values.image.dockerClientRepository }}:{{ .Chart.AppVersion }}" + - "--image-pull-policy={{ .Values.args.imagePullPolicy}}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + env: + - name: KUBEFLEDGED_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + resources: + {{- toYaml .Values.resources | nindent 12 }} + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/deploy/kubefledged-operator/helm-charts/kubefledged/templates/serviceaccount.yaml b/deploy/kubefledged-operator/helm-charts/kubefledged/templates/serviceaccount.yaml new file mode 100644 index 00000000..c0708ee6 --- /dev/null +++ b/deploy/kubefledged-operator/helm-charts/kubefledged/templates/serviceaccount.yaml @@ -0,0 +1,9 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "kubefledged.serviceAccountName" . }} + labels: + {{ include "kubefledged.labels" . | nindent 4 }} + namespace: {{ .Values.kubefledgedNameSpace }} +{{- end -}} diff --git a/deploy/kubefledged-operator/helm-charts/kubefledged/templates/tests/test-connection.yaml b/deploy/kubefledged-operator/helm-charts/kubefledged/templates/tests/test-connection.yaml new file mode 100644 index 00000000..365aebc4 --- /dev/null +++ b/deploy/kubefledged-operator/helm-charts/kubefledged/templates/tests/test-connection.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Pod +metadata: + name: "{{ include "kubefledged.fullname" . }}-test-connection" + labels: +{{ include "kubefledged.labels" . | nindent 4 }} + annotations: + "helm.sh/hook": test-success +spec: + containers: + - name: wget + image: busybox + command: ['wget'] + args: ['{{ include "kubefledged.fullname" . }}:{{ .Values.service.port }}'] + restartPolicy: Never diff --git a/deploy/kubefledged-operator/helm-charts/kubefledged/values.yaml b/deploy/kubefledged-operator/helm-charts/kubefledged/values.yaml new file mode 100644 index 00000000..0df55072 --- /dev/null +++ b/deploy/kubefledged-operator/helm-charts/kubefledged/values.yaml @@ -0,0 +1,86 @@ +# Default values for kubefledged. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 1 +kubefledgedNameSpace: kube-fledged +image: + fledgedRepository: docker.io/senthilrch/fledged + dockerClientRepository: docker.io/senthilrch/fledged-docker-client + pullPolicy: IfNotPresent +command: ["/opt/bin/fledged"] +args: + logLevel: INFO + imagePullDeadlineDuration: 5m + imageCacheRefreshFrequency: 15m + imagePullPolicy: IfNotPresent +imagePullSecrets: [] +nameOverride: "" +fullnameOverride: "" + +serviceAccount: + # Specifies whether a service account should be created + create: true + # The name of the service account to use. + # If not set and create is true, a name is generated using the fullname template + name: + +clusterRole: + # Specifies whether a cluster role should be created + create: true + # The name of the cluster role to use. + # If not set and create is true, a name is generated using the fullname template + name: + +clusterRoleBinding: + # Specifies whether a cluster role binding should be created + create: true + # The name of the cluster role binding to use. + # If not set and create is true, a name is generated using the fullname template + name: + +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + +service: + type: ClusterIP + port: 80 + +ingress: + enabled: false + annotations: {} + # kubernetes.io/ingress.class: nginx + # kubernetes.io/tls-acme: "true" + hosts: + - host: chart-example.local + paths: [] + tls: [] + # - secretName: chart-example-tls + # hosts: + # - chart-example.local + +resources: {} + # We usually recommend not to specify default resources and to leave this as a conscious + # choice for the user. This also increases chances charts run on environments with little + # resources, such as Minikube. If you do want to specify resources, uncomment the following + # lines, adjust them as necessary, and remove the curly braces after 'resources:'. + # limits: + # cpu: 100m + # memory: 128Mi + # requests: + # cpu: 100m + # memory: 128Mi + +nodeSelector: {} + +tolerations: [] + +affinity: {} diff --git a/deploy/kubefledged-operator/watches.yaml b/deploy/kubefledged-operator/watches.yaml new file mode 100644 index 00000000..f08cce01 --- /dev/null +++ b/deploy/kubefledged-operator/watches.yaml @@ -0,0 +1,5 @@ +--- +- version: v1alpha1 + group: charts.helm.k8s.io + kind: KubeFledged + chart: helm-charts/kubefledged diff --git a/deploy/fledged-serviceaccount.yaml b/deploy/kubefledged-serviceaccount.yaml similarity index 78% rename from deploy/fledged-serviceaccount.yaml rename to deploy/kubefledged-serviceaccount.yaml index 14cbe920..ea7ebbd0 100644 --- a/deploy/fledged-serviceaccount.yaml +++ b/deploy/kubefledged-serviceaccount.yaml @@ -1,5 +1,5 @@ apiVersion: v1 kind: ServiceAccount metadata: - name: fledged + name: kubefledged namespace: kube-fledged diff --git a/hack/boilerplate/boilerplate.py b/hack/boilerplate/boilerplate.py index 798f605f..2918b689 100755 --- a/hack/boilerplate/boilerplate.py +++ b/hack/boilerplate/boilerplate.py @@ -147,7 +147,7 @@ def file_extension(filename): skipped_dirs = ['Godeps', 'third_party', '_gopath', '_output', '.git', 'cluster/env.sh', "vendor", "test/e2e/generated/bindata.go", "hack/boilerplate/test", - "pkg/generated/bindata.go"] + "pkg/generated/bindata.go", "deploy/kubefledged-operator"] # list all the files contain 'DO NOT EDIT', but are not generated skipped_ungenerated_files = ['hack/build-ui.sh', 'hack/lib/swagger.sh', diff --git a/logo.png b/logo.png new file mode 100644 index 00000000..f7fd6f79 Binary files /dev/null and b/logo.png differ diff --git a/pkg/images/image_manager.go b/pkg/images/image_manager.go index cb0298ce..cca91d93 100644 --- a/pkg/images/image_manager.go +++ b/pkg/images/image_manager.go @@ -39,7 +39,6 @@ import ( ) const controllerAgentName = "fledged" -const fledgedNameSpace = "kube-fledged" const ( // ImageWorkResultStatusSucceeded means image pull/delete succeeded @@ -54,6 +53,7 @@ const ( // ImageManager provides the functionalities for pulling and deleting images type ImageManager struct { + fledgedNameSpace string workqueue workqueue.RateLimitingInterface imageworkqueue workqueue.RateLimitingInterface kubeclientset kubernetes.Interface @@ -121,6 +121,7 @@ func NewImageManager( podInformer := kubeInformerFactory.Core().V1().Pods() imagemanager := &ImageManager{ + fledgedNameSpace: namespace, workqueue: workqueue, imageworkqueue: imageworkqueue, kubeclientset: kubeclientset, @@ -196,7 +197,7 @@ func (m *ImageManager) updatePendingImageWorkResults(imageCacheName string) erro for job, iwres := range m.imageworkstatus { if iwres.ImageWorkRequest.Imagecache.Name == imageCacheName { if iwres.Status == ImageWorkResultStatusJobCreated { - pods, err := m.podsLister.Pods(fledgedNameSpace). + pods, err := m.podsLister.Pods(m.fledgedNameSpace). List(labels.Set(map[string]string{"job-name": job}).AsSelector()) if err != nil { glog.Errorf("Error listing Pods: %v", err) @@ -235,11 +236,11 @@ func (m *ImageManager) updatePendingImageWorkResults(imageCacheName string) erro fieldSelector := fields.Set{ "involvedObject.kind": "Pod", "involvedObject.name": pods[0].Name, - "involvedObject.namespace": fledgedNameSpace, + "involvedObject.namespace": m.fledgedNameSpace, "reason": "Failed", }.AsSelector().String() - eventlist, err := m.kubeclientset.CoreV1().Events(fledgedNameSpace). + eventlist, err := m.kubeclientset.CoreV1().Events(m.fledgedNameSpace). List(metav1.ListOptions{FieldSelector: fieldSelector}) if err != nil { glog.Errorf("Error listing events for pod (%s): %v", pods[0].Name, err) @@ -297,7 +298,7 @@ func (m *ImageManager) updateImageCacheStatus(imageCacheName string, errCh chan< imageCache = iwres.ImageWorkRequest.Imagecache delete(m.imageworkstatus, job) // delete jobs - if err := m.kubeclientset.BatchV1().Jobs(fledgedNameSpace). + if err := m.kubeclientset.BatchV1().Jobs(m.fledgedNameSpace). Delete(job, &metav1.DeleteOptions{PropagationPolicy: &deletePropagation}); err != nil { glog.Errorf("Error deleting job %s: %v", job, err) m.lock.Unlock() @@ -437,7 +438,7 @@ func (m *ImageManager) pullImage(iwr ImageWorkRequest) (*batchv1.Job, error) { return nil, err } // Create a Job to pull the image into the node - job, err := m.kubeclientset.BatchV1().Jobs(fledgedNameSpace).Create(newjob) + job, err := m.kubeclientset.BatchV1().Jobs(m.fledgedNameSpace).Create(newjob) if err != nil { glog.Errorf("Error creating job in node %s: %v", iwr.Node, err) return nil, err @@ -454,7 +455,7 @@ func (m *ImageManager) deleteImage(iwr ImageWorkRequest) (*batchv1.Job, error) { return nil, err } // Create a Job to delete the image from the node - job, err := m.kubeclientset.BatchV1().Jobs(fledgedNameSpace).Create(newjob) + job, err := m.kubeclientset.BatchV1().Jobs(m.fledgedNameSpace).Create(newjob) if err != nil { glog.Errorf("Error creating job in node %s: %v", iwr.Node, err) return nil, err diff --git a/pkg/images/image_manager_test.go b/pkg/images/image_manager_test.go index 699cc2bd..f8333ab1 100644 --- a/pkg/images/image_manager_test.go +++ b/pkg/images/image_manager_test.go @@ -36,6 +36,8 @@ import ( "k8s.io/client-go/util/workqueue" ) +const fledgedNameSpace = "kube-fledged" + func newTestImageManager(kubeclientset kubernetes.Interface) (*ImageManager, coreinformers.PodInformer) { imagePullDeadlineDuration := time.Millisecond * 10 dockerClientImage := "senthilrch/fledged-docker-client:latest"