|
| 1 | +# Create a Kubernetes cluster and expose a service |
| 2 | + |
| 3 | +This example demonstrates how to create a Kubernetes cluster with `upctl`, create a deployment, and expose it to the internet using a service. |
| 4 | + |
| 5 | +To keep track of resources created during this example, we will use common prefix in all resource names. The variable definitions also include configuration for the cluster, node-group, and service. By default, we will use `NodePort` service type (as it is faster to deploy), but you can change `svc_type` value to `LoadBalancer` if you want to use UpCloud Load Balancer to expose the service. |
| 6 | + |
| 7 | +```env |
| 8 | +prefix=example-upctl-kubernetes- |
| 9 | +zone=pl-waw1 |
| 10 | +
|
| 11 | +# Network |
| 12 | +cidr=172.30.100.0/24 |
| 13 | +
|
| 14 | +# Cluster |
| 15 | +plan=dev-md |
| 16 | +
|
| 17 | +# Node-group |
| 18 | +ng_count=1 |
| 19 | +ng_name=default |
| 20 | +ng_plan=2xCPU-4GB |
| 21 | +test_label=upctl-example |
| 22 | +
|
| 23 | +# Service |
| 24 | +svc_type=NodePort |
| 25 | +
|
| 26 | +KUBECONFIG=./kubeconfig.yaml |
| 27 | +``` |
| 28 | + |
| 29 | +First, we will need a private network for the cluster. |
| 30 | + |
| 31 | +```sh |
| 32 | +upctl network create \ |
| 33 | + --name ${prefix}net \ |
| 34 | + --zone $zone \ |
| 35 | + --ip-network address=$cidr,dhcp=true; |
| 36 | +``` |
| 37 | + |
| 38 | +Next, we can create the Kubernetes cluster. |
| 39 | + |
| 40 | +```sh |
| 41 | +upctl kubernetes create \ |
| 42 | + --name ${prefix}cluster \ |
| 43 | + --network ${prefix}net \ |
| 44 | + --plan $plan \ |
| 45 | + --zone $zone \ |
| 46 | + --kubernetes-api-allow-ip "0.0.0.0/0" \ |
| 47 | + --node-group count=$ng_count,name=$ng_name,plan=$ng_plan,label="test=$test_label" \ |
| 48 | + --wait=all; |
| 49 | +``` |
| 50 | + |
| 51 | +Once the cluster is created, we can get the kubeconfig file to interact with the cluster using `kubectl`. |
| 52 | + |
| 53 | +```sh |
| 54 | +upctl kubernetes config ${prefix}cluster \ |
| 55 | + --write $KUBECONFIG; |
| 56 | +``` |
| 57 | + |
| 58 | +Now we can create a deployment and expose it using a service. |
| 59 | + |
| 60 | +```sh |
| 61 | +kubectl create deployment --image=ghcr.io/upcloudltd/hello hello-uks |
| 62 | +kubectl expose deployment hello-uks --port=80 --target-port=80 --type=$svc_type |
| 63 | +``` |
| 64 | + |
| 65 | +If using `NodePort` service type, we need to get the node IP and service port to access the service. |
| 66 | + |
| 67 | +```sh when='svc_type == "NodePort"' |
| 68 | +# Get node IP |
| 69 | +node_ip=$(kubectl get node -o json | jq -r '.items[0].status.addresses.[] | select(.type == "ExternalIP").address') |
| 70 | +# Get service port |
| 71 | +svc_port=$(kubectl get service hello-uks -o json | jq -r '.spec.ports[0].nodePort') |
| 72 | + |
| 73 | +# Wait until the service is reachable |
| 74 | +until curl -sSf $node_ip:$svc_port; do |
| 75 | + sleep 15; |
| 76 | +done; |
| 77 | +``` |
| 78 | + |
| 79 | +If using `LoadBalancer` service type, we need to wait until the load balancer has been created and assigned a public hostname. Once the hostname is available, we can try to access the service. |
| 80 | + |
| 81 | +```sh when='svc_type == "LoadBalancer"' |
| 82 | +# Wait for hostname to be available in service status |
| 83 | +until kubectl get service hello-uks -o json | jq -re .status.loadBalancer.ingress[0].hostname; do |
| 84 | + sleep 15; |
| 85 | +done; |
| 86 | + |
| 87 | +# Wait until the service is reachable |
| 88 | +hostname=$(kubectl get service hello-uks -o json | jq -re .status.loadBalancer.ingress[0].hostname) |
| 89 | +until curl -sSf $hostname; do |
| 90 | + sleep 15; |
| 91 | +done; |
| 92 | +``` |
| 93 | + |
| 94 | +Finally, we can clean up the created resources. |
| 95 | + |
| 96 | +```sh cleanup |
| 97 | +kubectl delete service hello-uks |
| 98 | + |
| 99 | +upctl all purge --include "*${prefix}*"; |
| 100 | +``` |
0 commit comments