This article will illustrate how to run a Kubernetes in mac M1 local, and learn how to use kubectl command to deploy a service. More detailed concept can reference Kubernetes documents

install minikube

Install minikube for M1 chip:

curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-darwin-arm64
sudo install minikube-darwin-arm64 /usr/local/bin/minikube

Start the minikube and specifies the driver as Docker:

minikube start --driver=docker --alsologtostderr

Checkout the minikube status: System

minikube status

Here we prepare a Kubernetes object:

pod.yaml

apiVersion: v1
kind: Service
metadata:
  name: go-app-service
spec:
  selector:
    app: go-test
  ports:
  - protocol: "TCP"
    port: 8080
    targetPort: 8080
  type: LoadBalancer

---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: go-test
spec:
  selector:
    matchLabels:
      app: go-test
  replicas: 4
  template:
    metadata:
      labels:
        app: go-test
    spec:
      containers:
      - name: go-app
        image: adon988/go-github-action-helloworld:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 8080

Apply the k8s to create the deployment.

kubectl create -f pod.yaml

Check the Pod status:

> kubectl get pods

NAME                       READY   STATUS    RESTARTS   AGE
go-test-799f45cd65-947p6   1/1     Running   0          2m24s
go-test-799f45cd65-b8ql5   1/1     Running   0          2m24s
go-test-799f45cd65-btjmh   1/1     Running   0          2m24s
go-test-799f45cd65-r8n97   1/1     Running   0          2m24s

Port-forward

kubectl port-forward service/go-app-service 7080:8080

Checking the service status

> kubectl get services
NAME             TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
go-app-service   LoadBalancer   10.102.211.248   127.0.0.1     8080:31230/TCP   37m
kubernetes       ClusterIP      10.96.0.1        <none>        443/TCP          6h14m

Open browser and access http://localhost:7080

reset the number of the replicas in deployment yaml and renew

Update the deployment replicas to 2, and save the file.

nginx.yaml

...
spec:
  replicas: 2
...

Next, re-execute the apply command will update deployment settings:

kubectl apply -f nginx.yaml

check pods

> kubectl get pods

NAME                               READY   STATUS    RESTARTS   AGE
nginx-deployment-9456bbbf9-d5h5n   1/1     Running   0          24m
nginx-deployment-9456bbbf9-l8kqt   1/1     Running   0          24m

update container image version and update deployment

Update deployment image version settings from latest to v0.1

    spec:
      containers:
      - name: go-app
        image: adon988/go-github-action-helloworld:v0.1

Next, re-execute the apply command will update deployment settings:

kubectl apply -f pod.yaml

Finally, you can see the deployment are updated image with “zero downtime”, and pod status on container creating:

> keubectl get pod

NAME                       READY   STATUS              RESTARTS   AGE
go-test-68669b9989-796xj   0/1     ContainerCreating   0          1s
go-test-68669b9989-9hntz   1/1     Running             0          10s
go-test-799f45cd65-btjmh   1/1     Running             0          6m27s

Description scaling policy for the pods

kubectl autoscale deployment.apps/go-test --min=2 --max=5 --cpu-percent=80

Rollup to the previous version

We can rollback to the previous version,

Rollout command:

(go-test is deployment name)

kubectl rollout undo deploy go-test 

Checking the rollout status:

> kubectl get pods

NAME                       READY   STATUS    RESTARTS   AGE
go-test-799f45cd65-n2qqn   1/1     Running   0          28s
go-test-799f45cd65-rl7hk   1/1     Running   0          33s

troubleshoot

How to re-install minikube

If your mac already installs the Minikube and does not work, please remove it first, and reinstall again.

minikube stop
minikube delete
rm -rf ~/.minikube/

Kubernetes external-IP still pending

Why still show <Pending> when exposing deployment?

kubectl expose deployment hello-world --type=LoadBalancer --name=my-service

If you are using minikube, you should start minikube tunnel that can solve this problem.

Execute the following command to start minikube tunnel:

minikube tunnel

Now, try to get service will get the external IP:

> kubectl get services

NAME             TYPE           CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
go-app-service   LoadBalancer   10.102.211.248   127.0.0.1     8080:31230/TCP   20m
kubernetes       ClusterIP      10.96.0.1        <none>        443/TCP          5h57m