Deploy services
The kubectl
commands on this page can be executed on the k3s-master
node
installed in the previous chapters. Alternatively, you can install kubectl
on
your laptop and operator Kubernetes remotely (which is however out of the scope
of this tutorial).
Deploy nginx
Let's deploy nginx to all nodes in the cluster. The easiest way to do is using a
daemonset. Create a file nginx-daemon-set.yml
and populate it as follows:
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: nginx-daemonset
labels:
app: nginx
spec:
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:latest
ports:
- containerPort: 80
After this use kubectl to apply the file:
kubectl apply -f nginx-daemon-set.yml
You should receive the output: daemonset.apps/nginx-daemonset created
. You can
check the deployment with the kubectl command:
[root@k3s-master k8s]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-daemonset-6k4t8 1/1 Running 0 10s 10.42.3.4 k3s-node-2 <none> <none>
nginx-daemonset-n7nxg 1/1 Running 0 10s 10.42.1.3 k3s-node-1 <none> <none>
nginx-daemonset-t2sn2 1/1 Running 0 10s 10.42.0.9 k3s-master <none> <none>
As you can see in this output, nginx
go deployed to each individual DeTEE VM.
Expose nginx
In order to expose nginx
, we can use a service
of type NopePort
, because
we created the VMs using public IPv4 addresses. Alternative solutions are
possible, but for demonstration purposes let's create a file called
nginx-svc.yml
with the following contents:
apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
type: NodePort
selector:
app: nginx
ports:
- port: 80
targetPort: 80
nodePort: 30080
And apply it using kubectl apply -f nginx-svc.yml
. We can now obtain all
information about our service in YAML format by using the kubectl command:
[root@k3s-master ~]# kubectl get svc nginx-service -o yaml
apiVersion: v1
kind: Service
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"name":"nginx-service","namespace":"default"},"spec":{"ports":[{"nodePort":30080,"port":80,"targetPort":80}],"selector":{"app":"nginx"},"type":"NodePort"}}
creationTimestamp: "2025-04-01T00:26:38Z"
name: nginx-service
namespace: default
resourceVersion: "4076"
uid: aeac57fe-381d-486c-96a1-cc0f31f3db2f
spec:
clusterIP: 10.43.250.23
clusterIPs:
- 10.43.250.23
externalTrafficPolicy: Cluster
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- nodePort: 30080
port: 80
protocol: TCP
targetPort: 80
selector:
app: nginx
sessionAffinity: None
type: NodePort
status:
loadBalancer: {}
Accessing nginx
We can get the individual IPs of each VM and use curl
to call the service on
port 30080
(exposed via NodePort
in the service
above). It would be
however very cool if we did this using one single command to:
- get the list of VMs
- filter the VMs that are part of the k3s cluster
- get the UUID of each VM
- inspect each VM using its UUID to obtain the public address
- use the public address to access nginx on port 30080
- grab the title of the webpage from the nginx output
The oneliner (split on multiple lines) would look like this:
detee-cli --format yaml vm list |
grep -B 1 k3s |
grep uuid | awk '{ print $2 }' |
xargs -i detee-cli --format yaml vm inspect {} | grep ipv4 | awk '{ print $2 }' |
xargs -i curl {}:30080 |
grep title
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 615 100 615 0 0 1553 0 --:--:-- --:--:-- --:--:-- 1556
<title>Welcome to nginx!</title>
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 615 100 615 0 0 1552 0 --:--:-- --:--:-- --:--:-- 1549
<title>Welcome to nginx!</title>
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 615 100 615 0 0 2194 0 --:--:-- --:--:-- --:--:-- 2196
<title>Welcome to nginx!</title>
Congratulations!
If you got this far, congratulations on completing this Kubernetes tutorial!
We also prepared an automation combinding all these steps in our examples repo.