AWS/Azure/OpenShift Linux

Charmed Kubernetes: How to install CNF certified Kubernetes in AWS

chamedk8s-featured

The open-source technology called Kubernetes is used to deploy, scale, and manage workloads and applications in containers automatically. Google created it initially, and the Cloud Native Computing Foundation CNF now looks after it. To deploy and manage Kubernetes from BareMetal to the cloud Charmed Kubernetes uses a completely automated, model-driven method. Whether your objective is to create multi-cloud topologies, connect your favorite tools into your Kubernetes cloud, and build it from the ground up, charmed Kubernetes is up to the task. Charmed Kubernetes is available for usage without charge, and Canonical, the company behind Ubuntu software supports it through management, consultancy, and enterprise support services. It is safe and simple to deploy, run, and update thanks to Canonical.

Ubuntu is your quick route to durable business Kubernetes with no lock-in, whether you want a development cluster on VMware, a production cluster on bare metal powered by GPUs for AI and machine learning, or an easy-to-deploy and grow cluster in a public cloud. Other similar guides can be found here: How to create and deploy an app using the AKS manifest and monitoring it and how to create a static pod in Kubernetes.

To help organizations create clusters from the ground up and provide “containers as a service”, Charmed Kubernetes offers a carefully selected collection of tools which is based on Ubuntu, it’s an all-in-one suite that offers a simplified multi-cloud experience with unmatched price-performance and lifecycle management.

Benefits of Charmed Kubernetes

  • All essential Kubernetes components receive regular upgrades and security fixes automatically.
  • Docker and Containerd runtimes are fully Open Container Initiative compatible.
  • Adaptable & flexible third-party ecosystem for networking and storage
  • By default, high availability is set up

Requirements

Setting up for AWS

AWS CLI can be installed with the command:

curl "https://s3.amazonaws.com/aws-cli/awscli-bundle.zip" -o "awscli-bundle.zip"
unzip awscli-bundle.zip
sudo ./awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws

Alternatively, you can run the command below.

sudo apt install awscli
awscliaptcli
curl aws cli vs apt installed awscli


To verify that we now have awscli installed on our machine, we can run the command shown below :

awscli --version
aws-cli-installed
awscli installed

You can configure the machine with the command:

aws configure 

we would need security credentials from our aws account as shown below

secrets
credentials

The screenshot below shows the output of running the command aws configure

awsconfigure
aws configured

Now that our local machine is ready here is the list of steps containing all the commands that must be typed into your console in order to install Charmed Kubernetes on AWS.

Step 1: Install Juju

To Juju, a cloud is a resource that offers computers (instances), perhaps with storage, so those application units may be deployed upon them. Public clouds like Amazon Web Services, Google Compute Engine, Microsoft Azure, and Kubernetes as well as personal OpenStack-based clouds are included in this. In addition, Juju is capable of using settings that aren’t really clouds but that it may nonetheless treat like one. In this final group, MAAS and LXD belong. A cloud is frequently referred to as a substrate in Juju as a result. On public or private clouds, Juju is a tool for deploying, setting up, and running complicated applications. It can be quickly installed with the command:

sudo snap install juju --classic
juju-
juju installed

Step 2: Find AWS cloud with Juju

AWS, Azure, and Google are just a few of the public clouds that Juju is already familiar with. Run the following command to determine which are available for use:

juju clouds

If you have run the command before and tried a second time you will get an error as shown below. The way to tackle that is to exit the root shell and run as a normal user.

jujuclouds
Juju clouds as a non-root user

POSSIBLE ERROR: ERROR cannot acquire lock file to read all the controllers: unable to open /tmp/juju-store-lock-3635383939333230: permission denied

Step3: Add cloud credentials

For Juju, you will need to provide credentials since most clouds need them so they can determine which activities are authorized. The ‘add-credentials’ function provides a straightforward, step-by-step instruction to link Juju to your cloud. This is like the step we took above with the aws configure command

juju add-credential aws

Below is the Output.

rdgmh@ubuntu:~$ juju add-credential aws
This operation can be applied to both a copy on this client and to the one on a controller.
No current controller was detected and there are no registered controllers on this client: either bootstrap one or register one.
Enter credential name: techdirectarchive

A credential "techdirectarchive" already exists locally on this client.
Replace local credential? (y/N): y

Regions
  us-east-1
  us-east-2
  us-west-1
  us-west-2
  ca-central-1
  eu-west-1
  eu-west-2
  eu-west-3
  eu-central-1
  eu-north-1
  eu-south-1
  af-south-1
  ap-east-1
  ap-south-1
  ap-southeast-1
  ap-southeast-2
  ap-southeast-3
  ap-northeast-1
  ap-northeast-2
  ap-northeast-3
  me-south-1
  sa-east-1

Select region [any region, credential is not region specific]: us-east-1

Using auth-type "access-key".

Enter access-key: AKIAZOXKHX6TJ6VSYGYG

Enter secret-key: 

Credential "techdirectarchive" updated locally for cloud "aws".

Note: the access-Key was revealed because it will be deleted immediately after the exercise. It’s not good practice to reveal your access key in public. By default, the secret key is not shown but it was copied and added.

Step 4: Add juju controller

From deployment through updates to day-two operations, the software deployed using Juju is managed by the Juju controller. Multiple projects or workspaces, known as “models” in Juju, may be managed by a single controller.

juju bootstrap aws my-controller
my-controller
my-controller

Step 5: Add a Kubernetes model

The deployment is stored in the model. A fresh one should be made especially for each deployment.

juju add-model k8s
k8s-model
model added

Step 6: Deploy Kubernetes

Set up the model with the Kubernetes bundle. This will deploy the necessary programs and add instances to the model. Depending on your computer, this might take up to 20 minutes. For this experiment, it took less than 5 minutes. Here is the commend “juju deploy charmed-Kubernetes”

rdgmh@ubuntu:~$ juju deploy charmed-kubernetes 

Step 7: Monitor the deployment

Currently, Juju is working to bring the various components of the cluster together, install software, and create instances, all of which might take a while. Run the commands below to keep track of what’s happening.

watch -c juju status --color
watch
juju status

For the “k8s” model’s most recent twenty log entries, see:

juju debug-log -m k8s -n 20

output

rdgmh@ubuntu:~$ juju debug-log -m k8s -n 20
unit-containerd-0: 04:34:44 INFO unit.containerd/0.juju-log Invoking reactive handler: reactive/container_runtime_common.py:15:enable_grub_cgroups
unit-containerd-0: 04:34:44 INFO unit.containerd/0.juju-log Invoking reactive handler: reactive/containerd.py:677:publish_config
unit-containerd-0: 04:34:44 INFO unit.containerd/0.juju-log Invoking reactive handler: hooks/relations/untrusted-container-runtime/provides.py:18:broken:untrusted
unit-containerd-0: 04:34:44 INFO unit.containerd/0.juju-log Invoking reactive handler: hooks/relations/docker-registry/requires.py:58:remove_ready:docker-registry
unit-containerd-0: 04:34:44 INFO unit.containerd/0.juju-log status-set: active: Container runtime available
unit-containerd-0: 04:34:44 INFO juju.worker.uniter.operation ran "update-status" hook (via explicit, bespoke hook script)
unit-etcd-1: 04:35:18 INFO unit.etcd/1.juju-log Reactive main running for hook update-status
unit-etcd-1: 04:35:19 INFO unit.etcd/1.juju-log Initializing Leadership Layer (is follower)
unit-etcd-1: 04:35:19 INFO unit.etcd/1.juju-log Initializing Snap Layer
unit-etcd-1: 04:35:19 INFO unit.etcd/1.juju-log Invoking reactive handler: reactive/tls_client.py:18:store_ca
unit-etcd-1: 04:35:19 INFO unit.etcd/1.juju-log Invoking reactive handler: reactive/tls_client.py:44:store_server
unit-etcd-1: 04:35:19 INFO unit.etcd/1.juju-log Invoking reactive handler: reactive/tls_client.py:71:store_client
unit-etcd-1: 04:35:19 INFO unit.etcd/1.juju-log Invoking reactive handler: reactive/etcd.py:113:check_cluster_health
unit-etcd-1: 04:35:19 INFO unit.etcd/1.juju-log Invoking reactive handler: reactive/etcd.py:143:set_app_version
unit-etcd-1: 04:35:19 INFO unit.etcd/1.juju-log Invoking reactive handler: reactive/etcd.py:157:prepare_tls_certificates
unit-etcd-1: 04:35:19 INFO unit.etcd/1.juju-log Invoking reactive handler: reactive/etcd.py:275:set_db_ingress_address
unit-etcd-1: 04:35:19 INFO unit.etcd/1.juju-log Invoking reactive handler: reactive/etcd.py:282:send_cluster_connection_details
unit-etcd-1: 04:35:20 INFO unit.etcd/1.juju-log Invoking reactive handler: hooks/relations/tls-certificates/requires.py:79:joined:certificates
unit-etcd-1: 04:35:20 INFO unit.etcd/1.juju-log status-set: active: Healthy with 2 known peers
unit-etcd-1: 04:35:20 INFO juju.worker.uniter.operation ran "update-status" hook (via explicit, bespoke hook script)
unit-kubeapi-load-balancer-0: 04:34:24 WARNING unit.unit-kubeapi-load-balancer-0.collect-metrics /var/lib/juju/agents/unit-kubeapi-load-balancer-0/charm/hooks/collect-metrics:43: YAMLLoadWarning: calling yaml.load() without Loader=... is deprecated, as the default Loader is unsafe. Please read https://msg.pyyaml.org/load for full details.
unit-kubeapi-load-balancer-0: 04:34:24 WARNING unit.unit-kubeapi-load-balancer-0.collect-metrics   doc = yaml.load(f)
unit-kubernetes-worker-1: 04:34:34 INFO unit.kubernetes-worker/1.juju-log Reactive main running for hook update-status
unit-kubernetes-worker-1: 04:34:35 INFO unit.kubernetes-worker/1.juju-log Initializing Leadership Layer (is follower)
unit-kubernetes-worker-1: 04:34:35 INFO unit.kubernetes-worker/1.juju-log Coordinator: Initializing coordinator layer
unit-kubernetes-worker-1: 04:34:35 INFO unit.kubernetes-worker/1.juju-log Initializing Snap Layer
unit-kubernetes-worker-1: 04:34:35 INFO unit.kubernetes-worker/1.juju-log Initializing Apt Layer
unit-kubernetes-worker-1: 04:34:36 INFO unit.kubernetes-worker/1.juju-log Invoking reactive handler: reactive/tls_client.py:18:store_ca
unit-kubernetes-worker-1: 04:34:36 INFO unit.kubernetes-worker/1.juju-log Invoking reactive handler: reactive/tls_client.py:71:store_client
unit-kubernetes-worker-1: 04:34:36 INFO unit.kubernetes-worker/1.juju-log Invoking reactive handler: reactive/kubernetes_worker.py:396:set_app_version
unit-kubernetes-worker-1: 04:34:36 INFO unit.kubernetes-worker/1.juju-log Invoking reactive handler: reactive/apt.py:50:ensure_package_status
unit-kubernetes-worker-1: 04:34:36 INFO unit.kubernetes-worker/1.juju-log Invoking reactive handler: hooks/relations/gcp-integration/requires.py:116:remove_ready:gcp
unit-kubernetes-worker-1: 04:34:36 INFO unit.kubernetes-worker/1.juju-log Invoking reactive handler: hooks/relations/aws-integration/requires.py:106:remove_ready:aws
unit-kubernetes-worker-1: 04:34:36 INFO unit.kubernetes-worker/1.juju-log Invoking reactive handler: hooks/relations/azure-integration/requires.py:114:remove_ready:azure
unit-kubernetes-worker-1: 04:34:36 INFO unit.kubernetes-worker/1.juju-log Invoking reactive handler: hooks/relations/http/requires.py:15:broken:kube-api-endpoint
unit-kubernetes-worker-1: 04:34:36 INFO unit.kubernetes-worker/1.juju-log Invoking reactive handler: hooks/relations/http/provides.py:15:broken:ingress-proxy
unit-kubernetes-worker-1: 04:34:36 INFO unit.kubernetes-worker/1.juju-log Invoking reactive handler: hooks/relations/vsphere-integration/requires.py:81:remove_ready:vsphere
unit-kubernetes-worker-1: 04:34:36 INFO unit.kubernetes-worker/1.juju-log Invoking reactive handler: hooks/relations/mount/requires.py:18:broken:nfs
unit-kubernetes-worker-1: 04:34:36 INFO unit.kubernetes-worker/1.juju-log Invoking reactive handler: hooks/relations/openstack-integration/requires.py:84:remove_ready:openstack
unit-kubernetes-worker-1: 04:34:36 INFO unit.kubernetes-worker/1.juju-log Invoking reactive handler: hooks/relations/tls-certificates/requires.py:79:joined:certificates
unit-kubernetes-worker-1: 04:34:36 INFO unit.kubernetes-worker/1.juju-log status-set: waiting: Waiting for kubernetes-control-plane to become ready
unit-kubernetes-worker-1: 04:34:36 INFO juju.worker.uniter.operation ran "update-status" hook (via explicit, bespoke hook script)
unit-calico-0: 04:34:42 INFO unit.calico/0.juju-log Reactive main running for hook update-status
unit-calico-0: 04:34:42 INFO unit.calico/0.juju-log Initializing Leadership Layer (is leader)
unit-calico-0: 04:34:42 INFO unit.calico/0.juju-log Invoking reactive handler: reactive/calico.py:146:update_calicoctl_env
unit-calico-0: 04:34:42 INFO unit.calico/0.juju-log Invoking reactive handler: reactive/calico.py:223:create_calico_node_token
unit-calico-0: 04:34:42 INFO unit.calico/0.juju-log status-set: maintenance: Creating system:calico-node user token
unit-calico-0: 04:34:42 INFO unit.calico/0.juju-log Executing ['kubectl', '--kubeconfig=/root/.kube/config', 'get', 'secrets', '-n', 'kube-system', '--field-selector', 'type=juju.is/token-auth', '-o', 'json']
unit-calico-0: 04:34:42 WARNING unit.calico/0.update-status error: stat /root/.kube/config: no such file or directory
unit-calico-0: 04:34:42 WARNING unit.calico/0.juju-log Unable to get existing secrets
unit-calico-0: 04:34:42 INFO unit.calico/0.juju-log Executing ['kubectl', '--kubeconfig=/root/.kube/config', 'apply', '-f', '/tmp/tmpn8mxv2f5']
unit-calico-0: 04:34:43 WARNING unit.calico/0.update-status error: stat /root/.kube/config: no such file or directory
unit-calico-0: 04:34:43 INFO unit.calico/0.juju-log WARN: Unable to create secret for system:calico-node
unit-calico-0: 04:34:43 INFO unit.calico/0.juju-log Failed to create system:calico-node user token, will retry
unit-calico-0: 04:34:43 INFO unit.calico/0.juju-log Invoking reactive handler: reactive/calico.py:484:configure_node
unit-calico-0: 04:34:43 INFO unit.calico/0.juju-log status-set: maintenance: Configuring Calico node
unit-calico-0: 04:34:43 INFO unit.calico/0.juju-log b'null\nresource does not exist: Node(ip-172-31-59-88) with error: <nil>\n'
unit-calico-0: 04:34:43 INFO unit.calico/0.juju-log Traceback (most recent call last):
  File "/var/lib/juju/agents/unit-calico-0/charm/reactive/calico.py", line 494, in configure_node
    node = calicoctl_get('node', node_name)
  File "/var/lib/juju/agents/unit-calico-0/charm/reactive/calico.py", line 684, in calicoctl_get
    output = calicoctl(*args)
  File "/var/lib/juju/agents/unit-calico-0/charm/reactive/calico.py", line 617, in calicoctl
    return check_output(cmd, env=env, stderr=STDOUT)
  File "/usr/lib/python3.8/subprocess.py", line 415, in check_output
    return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
  File "/usr/lib/python3.8/subprocess.py", line 516, in run
    raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['/opt/calicoctl/calicoctl', 'get', '-o', 'yaml', '--export', 'node', 'ip-172-31-59-88']' returned non-zero exit status 1.

unit-calico-0: 04:34:43 INFO unit.calico/0.juju-log Invoking reactive handler: hooks/relations/kubernetes-cni/requires.py:21:changed:cni
unit-calico-0: 04:34:43 INFO unit.calico/0.juju-log status-set: waiting: Waiting to retry Calico node configuration
unit-calico-0: 04:34:43 INFO juju.worker.uniter.operation ran "update-status" hook (via explicit, bespoke hook script)
unit-containerd-0: 04:34:44 INFO unit.containerd/0.juju-log Reactive main running for hook update-status
unit-containerd-0: 04:34:44 INFO unit.containerd/0.juju-log Invoking reactive handler: reactive/containerd.py:324:update_status
unit-containerd-1: 04:35:53 INFO unit.containerd/1.juju-log Reactive main running for hook update-status
unit-containerd-1: 04:35:53 INFO unit.containerd/1.juju-log Invoking reactive handler: reactive/containerd.py:324:update_status
unit-containerd-1: 04:35:53 INFO unit.containerd/1.juju-log Invoking reactive handler: reactive/container_runtime_common.py:15:enable_grub_cgroups
unit-containerd-1: 04:35:53 INFO unit.containerd/1.juju-log Invoking reactive handler: reactive/containerd.py:677:publish_config
unit-containerd-1: 04:35:53 INFO unit.containerd/1.juju-log Invoking reactive handler: hooks/relations/untrusted-container-runtime/provides.py:18:broken:untrusted
unit-containerd-1: 04:35:53 INFO unit.containerd/1.juju-log Invoking reactive handler: hooks/relations/docker-registry/requires.py:58:remove_ready:docker-registry
unit-containerd-1: 04:35:53 INFO unit.containerd/1.juju-log status-set: active: Container runtime available
unit-containerd-1: 04:35:54 INFO juju.worker.uniter.operation ran "update-status" hook (via explicit, bespoke hook script)
unit-calico-1: 04:35:54 INFO unit.calico/1.juju-log Reactive main running for hook update-status
unit-calico-1: 04:35:55 INFO unit.calico/1.juju-log Initializing Leadership Layer (is follower)
unit-calico-1: 04:35:55 INFO unit.calico/1.juju-log Invoking reactive handler: reactive/calico.py:146:update_calicoctl_env
unit-calico-1: 04:35:55 INFO unit.calico/1.juju-log Invoking reactive handler: reactive/calico.py:484:configure_node
unit-calico-1: 04:35:55 INFO unit.calico/1.juju-log status-set: maintenance: Configuring Calico node
unit-calico-1: 04:35:55 INFO unit.calico/1.juju-log b'null\nresource does not exist: Node(ip-172-31-33-117) with error: <nil>\n'
unit-calico-1: 04:35:55 INFO unit.calico/1.juju-log Traceback (most recent call last):
  File "/var/lib/juju/agents/unit-calico-1/charm/reactive/calico.py", line 494, in configure_node
    node = calicoctl_get('node', node_name)
  File "/var/lib/juju/agents/unit-calico-1/charm/reactive/calico.py", line 684, in calicoctl_get
    output = calicoctl(*args)
  File "/var/lib/juju/agents/unit-calico-1/charm/reactive/calico.py", line 617, in calicoctl
    return check_output(cmd, env=env, stderr=STDOUT)
  File "/usr/lib/python3.8/subprocess.py", line 415, in check_output
    return run(*popenargs, stdout=PIPE, timeout=timeout, check=True,
  File "/usr/lib/python3.8/subprocess.py", line 516, in run
    raise CalledProcessError(retcode, process.args,
subprocess.CalledProcessError: Command '['/opt/calicoctl/calicoctl', 'get', '-o', 'yaml', '--export', 'node', 'ip-172-31-33-117']' returned non-zero exit status 1.

unit-calico-1: 04:35:55 INFO unit.calico/1.juju-log Invoking reactive handler: hooks/relations/kubernetes-cni/requires.py:21:changed:cni
unit-calico-1: 04:35:55 INFO unit.calico/1.juju-log status-set: waiting: Waiting to retry Calico node configuration
unit-calico-1: 04:35:55 INFO juju.worker.uniter.operation ran "update-status" hook (via explicit, bespoke hook script)

Step 8: Put your cluster to use now!

Congratulations! Let’s use your Kubernetes cluster now that it is operational!

Step 9: Other useful installations

To utilize your Kubernetes cluster, you must have kubectl. It is simple to add using a snap package if it isn’t already there:

sudo snap install kubectl --classic
kubectl
kubectl

The cluster itself stores the configuration file for accessing the recently deployed cluster, which will be available as soon as the installation is complete. To get it back, execute the command below (or make a.kube directory if one didn’t already exist after installing kubectl):

make a directory for the config file with the command

mkdir /.kube/conf
juju scp kubernetes-control-plane/0:config ~/.kube/config

for service :

kubectl get services

for proxy:

kubectl proxy

You can check if everything is running properly with the command:

kubectl cluster-info

you should be able to access your dashboard with the URL: http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/

dashboard
Kubernetes dashboard

We were able to install Kubernetes that comes with all the packages(charmed) in a very simple way by following the series of steps above.

I hope you found this blog post helpful. If you have any questions, please let me know in the comment session.

Subscribe
Notify of
guest

0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x