From e7b328ff08b8153741a733a686ab203b01354f4d Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Thu, 1 Jun 2023 13:54:49 -0700 Subject: [PATCH 1/8] add minikube tutorial --- minikube/.gitignore | 2 ++ minikube/Dockerfile | 16 +++++++++ minikube/README.md | 87 +++++++++++++++++++++++++++++++++++++++++++++ minikube/go.mod | 3 ++ minikube/k8s.yaml | 43 ++++++++++++++++++++++ minikube/main.go | 38 ++++++++++++++++++++ 6 files changed, 189 insertions(+) create mode 100644 minikube/.gitignore create mode 100644 minikube/Dockerfile create mode 100644 minikube/go.mod create mode 100644 minikube/k8s.yaml create mode 100644 minikube/main.go diff --git a/minikube/.gitignore b/minikube/.gitignore new file mode 100644 index 0000000..ab59273 --- /dev/null +++ b/minikube/.gitignore @@ -0,0 +1,2 @@ +local-dev-example-with-minikube +.DS_Store \ No newline at end of file diff --git a/minikube/Dockerfile b/minikube/Dockerfile new file mode 100644 index 0000000..2b4dd13 --- /dev/null +++ b/minikube/Dockerfile @@ -0,0 +1,16 @@ +FROM golang:alpine + +# Set the Current Working Directory inside the container +WORKDIR $GOPATH/src/github.com/medyagh/local-dev-example-with-minikube/ + +# Copy everything from the current directory to the PWD (Present Working Directory) inside the container +COPY . . + +# Install the package +RUN go install -v ./... + +# This container exposes port 8080 to the outside world +EXPOSE 8080 + +# Run the executable +CMD ["local-dev-example-with-minikube"] \ No newline at end of file diff --git a/minikube/README.md b/minikube/README.md index e69de29..5aa0d6c 100644 --- a/minikube/README.md +++ b/minikube/README.md @@ -0,0 +1,87 @@ +# local-dev-example-with-minikube + + +This repo demos a simple go app being deployed to a Kubernetes cluster using minikube, and demonstrates changing the code and re-deploying a new version. + + +## Requirements +- Clone this repo! +- Install [minikube](https://minikube.sigs.k8s.io/docs/start/) +- Install [Docker CLI](https://minikube.sigs.k8s.io/docs/tutorials/docker_desktop_replacement/) (Docker Desktop is not required, Docker CLI is sufficent) + + +## Build and deploy the app to minikube for the first time! + +1. Start minikube + ```console + minikube start + ``` + +2. Point your terminal to minikube's Docker using `minikube docker-env` + ```console + # on Mac or Linux + eval $(minikube docker-env) + ``` + + ```console + # on Windows PowerShell + & minikube docker-env | Invoke-Expression + ``` + + Tip 1: if you close your terminal you will have to re-point your docker-env. + + Tip 2: to verify that your terminal is pointing to minikube's Docker you can run `minikube status` and it will show "docker-env: in-use" + +4. Build Docker image inside minikube + + ```console + docker build -t local/devex:v1 . + ``` +4. Deploy to Kubernetes + ```console + kubectl apply -f deploy/k8s.yaml + ``` +5. Accees the deployed service in your browser + ```console + minikube service local-devex-svc + ``` + Tip: you can try `$ minikube service list` to see all exposed serivces. + + +## Iterative development (how to redeploy after a code change) + +1. Make a change in the code (for example bump the version in `main.go`) +2. Ensure you're still pointing to minikube's Docker using `minikube docker-env`) +3. Delete the deployment and the image + ```console + kubectl delete -f deploy/k8s.yaml + docker rmi local/devex:v1 + ``` +4. Rebuild the image and re-deploy to Kubernetes + ```console + docker build -t local/devex:v1 . + kubectl apply -f deploy/k8s.yaml + ``` +5. Access the deployed service in your browser + ```console + minikube service local-devex-svc + ``` + +(for faster development you can combine steps 3 and 4 the commands in one) +``` +kubectl delete -f deploy/k8s.yaml;docker rmi local/devex:v1;docker build -t local/devex:v1 .;kubectl apply -f deploy/k8s.yaml +``` + + +### Mount Files to minikube (persistent storage example) + +- let's create a example file on our workstation (laptop) to share with our deployment in minikube +```console +mkdir -p ~/Desktop/local-devex +echo "Hello from laptop" > ~/Desktop/local-devex/hello-world.text +``` + +in a separate window run: +```console + minikube mount ~/Desktop/local-devex:/data/ +``` diff --git a/minikube/go.mod b/minikube/go.mod new file mode 100644 index 0000000..cf6c4f3 --- /dev/null +++ b/minikube/go.mod @@ -0,0 +1,3 @@ +module local-dev-example-with-minikube + +go 1.19 diff --git a/minikube/k8s.yaml b/minikube/k8s.yaml new file mode 100644 index 0000000..32b9f5e --- /dev/null +++ b/minikube/k8s.yaml @@ -0,0 +1,43 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: local-devex-deploy + labels: + app: local-devex +spec: + replicas: 1 + selector: + matchLabels: + app: local-devex + template: + metadata: + labels: + app: local-devex + spec: + containers: + - name: app + image: local/devex:v1 + ports: + - containerPort: 8080 + volumeMounts: + - mountPath: /data + name: test-volume + volumes: + - name: test-volume + hostPath: + # directory location on host + path: /data +--- +apiVersion: v1 +kind: Service +metadata: + name: local-devex-svc +spec: + type: NodePort + selector: + app: local-devex + ports: + - name: local-devex-port + protocol: TCP + port: 8080 + targetPort: 8080 \ No newline at end of file diff --git a/minikube/main.go b/minikube/main.go new file mode 100644 index 0000000..6d8d8f8 --- /dev/null +++ b/minikube/main.go @@ -0,0 +1,38 @@ +package main + +import ( + "fmt" + "net/http" + "os" + "time" +) + +var version = "0.0.2" + +func indexHandler(w http.ResponseWriter, req *http.Request) { + localFile, err := os.ReadFile("/data/hello-world.txt") + if err != nil { + fmt.Printf("couldn't read file %v\n", err) + + } + fmt.Fprintf(w, "

hello world :)

\n Version %s\n File Content:%s", version, localFile) +} + +func headersHandler(w http.ResponseWriter, req *http.Request) { + + for name, headers := range req.Header { + for _, h := range headers { + fmt.Fprintf(w, "%v: %v\n", name, h) + } + } +} + +func main() { + + http.HandleFunc("/", indexHandler) + http.HandleFunc("/headers", headersHandler) + + welcomeText := fmt.Sprintf("%s Starting example version %s, Listening on port 8080 ...", time.Now().String(), version) + fmt.Println(welcomeText) + http.ListenAndServe(":8080", nil) +} From 87a0f7e445f43c529fa36493e48a7927d510bfb2 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Thu, 1 Jun 2023 13:58:19 -0700 Subject: [PATCH 2/8] add minikube gh action workflow --- .github/dependabot.yml | 7 ++++++ .github/workflows/build.yaml | 42 ++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/build.yaml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..88ea017 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,7 @@ +--- +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml new file mode 100644 index 0000000..35a70d2 --- /dev/null +++ b/.github/workflows/build.yaml @@ -0,0 +1,42 @@ +name: build +on: + workflow_dispatch: + push: + pull_request: + schedule: + # every day at 6am & 6pm pacific + - cron: "0 1,13 * * *" +jobs: + build: + strategy: + matrix: + os: [ubuntu-latest, macos-12] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab + - uses: azure/setup-kubectl@901a10e89ea615cf61f57ac05cecdf23e7de06d8 + - uses: medyagh/setup-minikube@latest + - name: install tools for mac os + if: matrix.os == 'macos-12' + shell: bash + run: | + brew install docker-machine docker + sudo docker --version + sysctl hw.physicalcpu hw.logicalcpu + sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setglobalstate off + sudo /usr/libexec/ApplicationFirewall/socketfilterfw -k + + - name: Build Docker images inside minikube + run: | + eval $(minikube docker-env) + docker build -t local/devex:v1 . + - name: Deploy to to Kubernetes + run: | + kubectl apply -f minikiube/deploy/k8s.yaml + - name: Verify Deployment + run: | + minikube service list + minikube service local-devex-svc --url --wait=10 + kubectl get pods -A + kubectl wait --for=condition=ready pod -l app=local-devex + curl -vvv $(minikube service local-devex-svc --url) From 005f714a81e63988556da1390d3af18ce844e624 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Thu, 1 Jun 2023 14:01:58 -0700 Subject: [PATCH 3/8] fix Dockerfile path --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 35a70d2..2176afa 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -29,7 +29,7 @@ jobs: - name: Build Docker images inside minikube run: | eval $(minikube docker-env) - docker build -t local/devex:v1 . + docker build -f ./minikube -t local/devex:v1 . - name: Deploy to to Kubernetes run: | kubectl apply -f minikiube/deploy/k8s.yaml From d4e2f55880663d6c043a625e4627cee55bf3f7a0 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Thu, 1 Jun 2023 14:04:08 -0700 Subject: [PATCH 4/8] fix Dockerfile path --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 2176afa..8c48d9c 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -29,7 +29,7 @@ jobs: - name: Build Docker images inside minikube run: | eval $(minikube docker-env) - docker build -f ./minikube -t local/devex:v1 . + docker build -f ./minikube/Dockerfile -t local/devex:v1 . - name: Deploy to to Kubernetes run: | kubectl apply -f minikiube/deploy/k8s.yaml From 4156f5c1b6baf46378826b5ebb45a91f9005d411 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Thu, 1 Jun 2023 14:07:11 -0700 Subject: [PATCH 5/8] fix Dockerfile path --- .github/workflows/build.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 8c48d9c..ccd8ad8 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -29,7 +29,8 @@ jobs: - name: Build Docker images inside minikube run: | eval $(minikube docker-env) - docker build -f ./minikube/Dockerfile -t local/devex:v1 . + cd minikube + docker build -t local/devex:v1 . - name: Deploy to to Kubernetes run: | kubectl apply -f minikiube/deploy/k8s.yaml From 2ca2f2cca6091eb6edc84a43dc3657750080a4bf Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Thu, 1 Jun 2023 14:21:53 -0700 Subject: [PATCH 6/8] fix spelling --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index ccd8ad8..57e9e8f 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -33,7 +33,7 @@ jobs: docker build -t local/devex:v1 . - name: Deploy to to Kubernetes run: | - kubectl apply -f minikiube/deploy/k8s.yaml + kubectl apply -f minikube/deploy/k8s.yaml - name: Verify Deployment run: | minikube service list From f6392a3e30c3107edd8c0c845ecdd370ec82afe3 Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Thu, 1 Jun 2023 14:30:58 -0700 Subject: [PATCH 7/8] remove macos test --- .github/workflows/build.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 57e9e8f..7bca064 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -10,7 +10,7 @@ jobs: build: strategy: matrix: - os: [ubuntu-latest, macos-12] + os: [ubuntu-latest] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@8e5e7e5ab8b370d6c329ec480221332ada57f0ab From 2a37697d4ac998a928dffe37189d46d84ef1ce7b Mon Sep 17 00:00:00 2001 From: Medya Gh Date: Thu, 1 Jun 2023 14:37:01 -0700 Subject: [PATCH 8/8] add k8s deploy files --- minikube/deploy/k8s.yaml | 43 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 minikube/deploy/k8s.yaml diff --git a/minikube/deploy/k8s.yaml b/minikube/deploy/k8s.yaml new file mode 100644 index 0000000..32b9f5e --- /dev/null +++ b/minikube/deploy/k8s.yaml @@ -0,0 +1,43 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: local-devex-deploy + labels: + app: local-devex +spec: + replicas: 1 + selector: + matchLabels: + app: local-devex + template: + metadata: + labels: + app: local-devex + spec: + containers: + - name: app + image: local/devex:v1 + ports: + - containerPort: 8080 + volumeMounts: + - mountPath: /data + name: test-volume + volumes: + - name: test-volume + hostPath: + # directory location on host + path: /data +--- +apiVersion: v1 +kind: Service +metadata: + name: local-devex-svc +spec: + type: NodePort + selector: + app: local-devex + ports: + - name: local-devex-port + protocol: TCP + port: 8080 + targetPort: 8080 \ No newline at end of file