Skip to content

Commit c44f7df

Browse files
committed
Initial commit
0 parents  commit c44f7df

File tree

4 files changed

+251
-0
lines changed

4 files changed

+251
-0
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
kube-config
2+
*.crt
3+
*.key
4+
kubectl

README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# github-actions-k8s
2+
3+
- Running `kubectl` against a K8s cluster using GitHub Actions
4+
- This example runs a minikube cluster inside a VM managed by incus, then runs a `kubectl apply` against that cluster from a Github Actions runner
5+
- A publicly accessibly IP address/domain is required
6+
7+
- First up, read through/follow [manual-remote-access.md](./manual-remote-access.md) for setting up the cluster and general knowledge remote `kubectl` management of clusters

kube-config.example

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
apiVersion: v1
2+
kind: Config
3+
4+
clusters:
5+
- name: minikube
6+
cluster:
7+
server: <server-url>
8+
9+
users:
10+
- name: remote-user
11+
user:
12+
token: <JWT>
13+
14+
contexts:
15+
- name: remote-context
16+
context:
17+
cluster: minikube
18+
user: remote-user
19+
20+
current-context: remote-context

manual-remote-access.md

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
# Steps
2+
3+
1. Create and enter VM with the required resources
4+
5+
```shell
6+
$ incus launch --vm -c security.secureboot=false -c limits.cpu=6 -c limits.memory=8GiB images:ubuntu/24.04 kubectl-ghactions-test
7+
$ incus exec kubectl-ghactions-test -- su -l ubuntu
8+
```
9+
10+
2. Update the VM and install docker
11+
12+
```shell
13+
ubuntu@kubectl-ghactions-test:~$ sudo apt update && sudo apt upgrade
14+
ubuntu@kubectl-ghactions-test:~$ sudo apt install docker.io
15+
ubuntu@kubectl-ghactions-test:~$ sudo usermod -aG docker ubuntu
16+
ubuntu@kubectl-ghactions-test:~$ newgrp docker
17+
ubuntu@kubectl-ghactions-test:~$ sudo systemctl enable --now docker
18+
```
19+
20+
3. Install minikube
21+
22+
```shell
23+
sudo apt install curl # It's not preinstalled
24+
25+
curl -LO https://github.com/kubernetes/minikube/releases/latest/download/minikube-linux-amd64
26+
27+
# Install minikube binary to /usr/local/bin/minikube
28+
sudo install minikube-linux-amd64 /usr/local/bin/minikube && rm minikube-linux-amd64
29+
```
30+
31+
- Check by running `minikube`
32+
33+
```shell
34+
ubuntu@kubectl-ghactions-test:~$ minikube
35+
minikube provisions and manages local Kubernetes clusters optimized for development workflows.
36+
...
37+
```
38+
39+
- We'll also just use minikube's provided kubectl for testing
40+
41+
```shell
42+
ubuntu@kubectl-ghactions-test:~$ alias kubectl="minikube kubectl --"
43+
```
44+
45+
4. Start a cluster
46+
47+
```shell
48+
ubuntu@kubectl-ghactions-test:~$ minikube start --nodes 3
49+
```
50+
51+
- Confirm it's running
52+
53+
```shell
54+
ubuntu@kubectl-ghactions-test:~$ minikube status
55+
minikube
56+
type: Control Plane
57+
host: Running
58+
kubelet: Running
59+
apiserver: Running
60+
kubeconfig: Configured
61+
62+
minikube-m02
63+
type: Worker
64+
host: Running
65+
kubelet: Running
66+
67+
minikube-m03
68+
type: Worker
69+
host: Running
70+
kubelet: Running
71+
```
72+
73+
5. Disable anonymous API access
74+
75+
```shell
76+
ubuntu@kubectl-ghactions-test:~$ minikube ssh
77+
docker@minikube:~$ sudo vi /etc/kubernetes/manifests/kube-apiserver.yaml
78+
```
79+
80+
- Add `--anonymous-auth=false` under `command`
81+
- Save and exit, minikube will automatically restart the API server, you may have to wait a few seconds
82+
83+
- See that anonymous requests are blocked
84+
85+
```shell
86+
ubuntu@kubectl-ghactions-test:~$ curl -k https://$(minikube ip):8443/api/v1/namespaces/default/pods
87+
{
88+
"kind": "Status",
89+
"apiVersion": "v1",
90+
"metadata": {},
91+
"status": "Failure",
92+
"message": "Unauthorized",
93+
"reason": "Unauthorized",
94+
"code": 401
95+
}
96+
97+
ubuntu@kubectl-ghactions-test:~$ curl --cert /home/ubuntu/.minikube/profiles/minikube/client.crt \
98+
--key /home/ubuntu/.minikube/profiles/minikube/client.key \
99+
-k https://$(minikube ip):8443/api/v1/namespaces/default/pods
100+
{
101+
"kind": "PodList",
102+
"apiVersion": "v1",
103+
"metadata": {
104+
"resourceVersion": "1080"
105+
},
106+
"items": []
107+
}
108+
```
109+
110+
7. Run the kube-API proxy on the server
111+
112+
- We're going to use an apache2 webserver to proxy requests to the server to the minikube kube-API
113+
114+
1. Install `apache2`
115+
116+
```shell
117+
ubuntu@kubectl-ghactions-test:~$ sudo apt install apache2
118+
ubuntu@kubectl-ghactions-test:~$ sudo systemctl enable --now apache2
119+
```
120+
121+
- Note you can do this in a container if you want (podman/docker) but for simplicity's sake, I'm not.
122+
123+
2. Add virtualhost to proxy requests to the kubctl proxy (words)
124+
125+
```
126+
# In /etc/apache2/sites-available/kubectl.conf
127+
128+
<VirtualHost *:80>
129+
ServerName <domain or IP>
130+
131+
ProxyPass / https://<minikube-ip>:8443/
132+
ProxyPassReverse / https://<minikube-ip>:8443/
133+
134+
# Allow minikube's self signed certs
135+
SSLProxyEngine on
136+
SSLProxyVerify none
137+
SSLProxyCheckPeerCN off
138+
SSLProxyCheckPeerName off
139+
140+
ErrorLog ${APACHE_LOG_DIR}/kubectl-error.log
141+
CustomLog ${APACHE_LOG_DIR}/kubectl-access.log combined
142+
</VirtualHost>
143+
```
144+
145+
3. Enable modules and start `apache2`
146+
147+
```shell
148+
ubuntu@kubectl-ghactions-test:~$ sudo a2enmod proxy
149+
ubuntu@kubectl-ghactions-test:~$ sudo a2enmod proxy_http
150+
ubuntu@kubectl-ghactions-test:~$ sudo a2enmod ssl
151+
ubuntu@kubectl-ghactions-test:~$ sudo systemctl enable --now apache2
152+
ubuntu@kubectl-ghactions-test:~$ sudo a2ensite kubectl
153+
```
154+
155+
8. Check if the API is accessible remotely
156+
157+
```shell
158+
$ curl -X GET <your-server-url>/api
159+
{
160+
"kind": "Status",
161+
"apiVersion": "v1",
162+
"metadata": {},
163+
"status": "Failure",
164+
"message": "Unauthorized",
165+
"reason": "Unauthorized",
166+
"code": 401
167+
}
168+
```
169+
170+
9. Authorize with the API
171+
172+
- See [Using RBAC Authorization | Kubernetes](https://kubernetes.io/docs/reference/access-authn-authz/rbac/)
173+
174+
- On the minikube host:
175+
1. Create a service account, `ClusterRoleBinding`, and token
176+
177+
```shell
178+
ubuntu@kubectl-ghactions-test:~$ kubectl create serviceaccount remote-dev
179+
ubuntu@kubectl-ghactions-test:~$ kubectl create clusterrolebinding remote-dev-binding \
180+
--clusterrole=cluster-admin \
181+
--serviceaccount=default:remote-dev
182+
ubuntu@kubectl-ghactions-test:~$ kubectl create token remote-dev
183+
```
184+
185+
- On your local machine, create a kubectl config to point to and authenticate with the remote server
186+
- Put the below in a file named kube-config, replacing `<server-url>` and `<JWT>` with their appropriate values
187+
188+
```yaml
189+
apiVersion: v1
190+
kind: Config
191+
192+
clusters:
193+
- name: minikube
194+
cluster:
195+
server: <server-url>
196+
197+
users:
198+
- name: remote-user
199+
user:
200+
token: <JWT>
201+
202+
contexts:
203+
- name: remote-context
204+
context:
205+
cluster: minikube
206+
user: remote-user
207+
208+
current-context: remote-context
209+
```
210+
211+
- Test access by making a request
212+
213+
```shell
214+
$ KUBECONFIG=$(pwd)/kube-config ./kubectl get ns
215+
NAME STATUS AGE
216+
default Active 7m57s
217+
kube-node-lease Active 7m57s
218+
kube-public Active 7m57s
219+
kube-system Active 7m57s
220+
```

0 commit comments

Comments
 (0)