<commit_before>= Create Kubernetes cluster using Kops
:toc:

This tutorial will walk you through how to install a Kubernetes cluster using kops on AWS.

https://github.com/kubernetes/kops[Kops], short for Kubernetes Operations, is a set of tools for installing, operating, and deleting Kubernetes clusters in the cloud. A rolling upgrade of an older version of Kubernetes to a new version can also be performed. It also manages the cluster add-ons. After the cluster is created, the usual kubectl CLI can be used to manage resources in the cluster.

== Install kops

There is no need to download a Kubernetes binary distribution for creating a cluster using kops. However, you do need to download the kops CLI. It then takes care of downloading the right Kubernetes binary in the cloud, and provisions the cluster.
  
==== MacOS:
    brew update && brew install kops

==== Linux:
    wget https://github.com/kubernetes/kops/releases/download/1.7.1/kops-linux-amd64
    sudo chmod +x kops-linux-amd64
    sudo mv kops-linux-amd64 /usr/local/bin/kops

Kops is available on Mac OSX, Linux or the Windows 10 Linux Subsystem. Complete installation instructions are available at https://github.com/kubernetes/kops#installing.

For MacOS, if Kops is already installed, you can run the following command to upgrade to the latest the latest version:

    brew upgrade kops

Check kops version:

    $ kops version
    Version 1.7.1

Latest and early versions of kops can be downloaded from https://github.com/kubernetes/kops/releases.

In addition, you also need kubectl CLI to manage the resources on Kubernetes cluster. Instructions to install kubectl CLI are covered in link:../getting-started#setup-local-development-environment[].

== IAM user permission

Make sure the latest version of http://docs.aws.amazon.com/cli/latest/userguide/installing.html[AWS CLI]
is installed. User permissions used in this workshop must have these http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies.html[IAM policies] attached.

    AmazonEC2FullAccess
    AmazonRoute53FullAccess
    AmazonS3FullAccess
    IAMFullAccess
    AmazonVPCFullAccess

Please review these links for additional info on IAM permissions:
https://github.com/kubernetes/kops/blob/master/docs/aws.md#setup-iam-user. https://github.com/kubernetes/kops/blob/master/docs/iam_roles.md

== S3 bucket to store Kubernetes config

Kops needs a "`state store`" to store configuration information of the cluster.  For example, how many nodes in the cluster, the instance type of each node, and the Kubernetes version. The state is stored during the initial cluster creation. Any subsequent changes to the cluster are also persisted to this store. As of now, Amazon S3 is the only supported storage mechanism. Create an S3 bucket and pass that to the kops CLI during cluster creation.

NOTE: The bucket name must be unique otherwise you will encounter an error on deployment. For demonstration purposes only, we will use an example bucket name of `example-state-store`.
    
    # create variables for bucket, state store and cluster names
    export S3_BUCKET=example-state-store
    export KOPS_STATE_STORE=s3://${S3_BUCKET}

    # use aws cli to create bucket
    aws s3 mb $KOPS_STATE_STORE
    
    # enable versioning and export
    aws s3api put-bucket-versioning \
      --bucket $S3_BUCKET \
      --versioning-configuration \
      Status=Enabled

== Create cluster

The Kops CLI can be used to create a highly available cluster, with multiple master nodes spread across multiple Availability Zones. Workers can be spread across multiple zones as well. Some of the tasks that happen behind the scene during cluster creation are:

- Provisioning EC2 instances
- Setting up AWS resources such as networks, Auto Scaling groups, IAM users, and security groups
- Installing Kubernetes

When setting up a cluster you have two options on how the nodes in the cluster communicate:

. *Using DNS* - Creating a Kubernetes that uses DNS for node discovery requires a top-level domain or a subdomain and setting up Route 53 hosted zones. This allows the various Kubernetes components to find and communicate with each other. This is also needed for kubectl to be able to talk directly with the master.
. *Using the gossip protocol* - Kops has experimental support for a gossip-based cluster. This does not require a top-level domain, subdomain or a Route53 hosted zone to be registered. A gossip-based cluster is therefore easier and quicker to setup.

You'll need to choose one of the two options. Instructions for both options are provided below, and the examples in the workshop should work with either option. Creating a gossip-based cluster requires less setup and will be used in this workshop, unless otherwise specified.

=== Create a gossip-based Kubernetes cluster

Kops also has experimental support for a gossip-based cluster. It uses Weave Mesh behind the scenes. This makes the process of creating a Kubernetes cluster using kops DNS-free, and much simpler. This also means a top-level domain or a subdomain is no longer required to create the cluster. To create a cluster using the gossip protocol, indicate this to Kops by using a cluster name with a suffix of `.k8s.local`. In the following steps, we will use example.cluster.k8s.local as a sample gossip cluster name.

This is a fairly recent feature, so we recommend you continue to use DNS for production clusters. However, setting up a gossip-based cluster allows you to get started rather quickly.

We show two examples of creating gossip-based clusters below. You can choose whether to create a single-master or multi-master cluster. Workshop exercises will work on both types of cluster.

==== Default gossip-based cluster

By default, `create cluster` command creates a single master node and two worker nodes in the specified zones.

Create a Kubernetes cluster using the following command. This will create a cluster with a single master, multi-node and multi-az configuration:

    kops create cluster \
      --name example.cluster.k8s.local \
      --zones $AWS_AVAILABILITY_ZONES \
      --yes

The `create cluster` command only creates and stores the cluster config in the S3 bucket. Adding `--yes` option ensures that the cluster is immediately created as well.

Alternatively, you may not specify the `--yes` option as part of the `kops create cluster` command. Then you can use `kops edit cluster example.cluster.k8s.local` command to view the current cluster state and make changes. The cluster creation, in that case, is started with the following command:

    kops update cluster example.cluster.k8s.local --yes

The cluster can be verified as shown:

```
$ kops validate cluster
Using cluster from kubectl context: example.cluster.k8s.local

Validating cluster example.cluster.k8s.local

INSTANCE GROUPS
NAME      ROLE  MACHINETYPE MIN MAX SUBNETS
master-eu-central-1a Master  m3.medium 1 1 eu-central-1a
nodes     Node  t2.medium 2 2 eu-central-1a,eu-central-1b

NODE STATUS
NAME        ROLE  READY
ip-172-20-57-94.ec2.internal  master  True
ip-172-20-63-55.ec2.internal  node  True
ip-172-20-75-78.ec2.internal  node  True

Your cluster example.cluster.k8s.local is ready
```

==== Multi-master, multi-node, multi-az gossip-based cluster

Check the list of Availability Zones that exist for your region using the following command:

    aws --region <region> ec2 describe-availability-zones

Create a cluster with multi-master, multi-node and multi-az configuration. We can create and build the cluster in
one step by passing the `--yes` flag.

    kops create cluster \
      --name example.cluster.k8s.local \
      --master-count 3 \
      --master-zones $AWS_AVAILABILITY_ZONES \
      --node-count 5 \
      --zones $AWS_AVAILABILITY_ZONES \
      --yes

A multi-master cluster can be created by using the `--master-count` option and using an odd number value. The AZs for master can be specified using the `--master-zones` option. Kops will spread the servers across different AZs.

`--zones` is used to distribute the worker nodes. The number of workers is specified using the `--node-count` option.

Validate the cluster:

```
$ kops validate cluster
Using cluster from kubectl context: example.cluster.k8s.local<commit_msg>removing redundant instructions<commit_after>= Create Kubernetes cluster using Kops
:toc:

This tutorial will walk you through how to install a Kubernetes cluster using kops on AWS.

https://github.com/kubernetes/kops[Kops], short for Kubernetes Operations, is a set of tools for installing, operating, and deleting Kubernetes clusters in the cloud. A rolling upgrade of an older version of Kubernetes to a new version can also be performed. It also manages the cluster add-ons. After the cluster is created, the usual kubectl CLI can be used to manage resources in the cluster.

== Install kops

There is no need to download a Kubernetes binary distribution for creating a cluster using kops. However, you do need to download the kops CLI. It then takes care of downloading the right Kubernetes binary in the cloud, and provisions the cluster.
  
==== MacOS:
    brew update && brew install kops

==== Linux:
    wget https://github.com/kubernetes/kops/releases/download/1.7.1/kops-linux-amd64
    sudo chmod +x kops-linux-amd64
    sudo mv kops-linux-amd64 /usr/local/bin/kops

Kops is available on Mac OSX, Linux or the Windows 10 Linux Subsystem. Complete installation instructions are available at https://github.com/kubernetes/kops#installing.

For MacOS, if Kops is already installed, you can run the following command to upgrade to the latest the latest version:

    brew upgrade kops

Check kops version:

    $ kops version
    Version 1.7.1

Latest and early versions of kops can be downloaded from https://github.com/kubernetes/kops/releases.

In addition, you also need kubectl CLI to manage the resources on Kubernetes cluster. Instructions to install kubectl CLI are covered in link:../getting-started#setup-local-development-environment[].

== IAM user permission

Make sure the latest version of http://docs.aws.amazon.com/cli/latest/userguide/installing.html[AWS CLI]
is installed. User permissions used in this workshop must have these http://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies.html[IAM policies] attached.

    AmazonEC2FullAccess
    AmazonRoute53FullAccess
    AmazonS3FullAccess
    IAMFullAccess
    AmazonVPCFullAccess

Please review these links for additional info on IAM permissions:
https://github.com/kubernetes/kops/blob/master/docs/aws.md#setup-iam-user. https://github.com/kubernetes/kops/blob/master/docs/iam_roles.md

== S3 bucket to store Kubernetes config

Kops needs a "`state store`" to store configuration information of the cluster.  For example, how many nodes in the cluster, the instance type of each node, and the Kubernetes version. The state is stored during the initial cluster creation. Any subsequent changes to the cluster are also persisted to this store. As of now, Amazon S3 is the only supported storage mechanism. Create an S3 bucket and pass that to the kops CLI during cluster creation.

NOTE: The bucket name must be unique otherwise you will encounter an error on deployment. For demonstration purposes only, we will use an example bucket name of `example-state-store`.
    
    # create variables for bucket, state store and cluster names
    export S3_BUCKET=example-state-store
    export KOPS_STATE_STORE=s3://${S3_BUCKET}

    # use aws cli to create bucket
    aws s3 mb $KOPS_STATE_STORE
    
    # enable versioning and export
    aws s3api put-bucket-versioning \
      --bucket $S3_BUCKET \
      --versioning-configuration \
      Status=Enabled

== Create cluster

The Kops CLI can be used to create a highly available cluster, with multiple master nodes spread across multiple Availability Zones. Workers can be spread across multiple zones as well. Some of the tasks that happen behind the scene during cluster creation are:

- Provisioning EC2 instances
- Setting up AWS resources such as networks, Auto Scaling groups, IAM users, and security groups
- Installing Kubernetes

When setting up a cluster you have two options on how the nodes in the cluster communicate:

. *Using DNS* - Creating a Kubernetes that uses DNS for node discovery requires a top-level domain or a subdomain and setting up Route 53 hosted zones. This allows the various Kubernetes components to find and communicate with each other. This is also needed for kubectl to be able to talk directly with the master.
. *Using the gossip protocol* - Kops has experimental support for a gossip-based cluster. This does not require a top-level domain, subdomain or a Route53 hosted zone to be registered. A gossip-based cluster is therefore easier and quicker to setup.

You'll need to choose one of the two options. Instructions for both options are provided below, and the examples in the workshop should work with either option. Creating a gossip-based cluster requires less setup and will be used in this workshop, unless otherwise specified.

=== Create a gossip-based Kubernetes cluster

Kops also has experimental support for a gossip-based cluster. It uses Weave Mesh behind the scenes. This makes the process of creating a Kubernetes cluster using kops DNS-free, and much simpler. This also means a top-level domain or a subdomain is no longer required to create the cluster. To create a cluster using the gossip protocol, indicate this to Kops by using a cluster name with a suffix of `.k8s.local`. In the following steps, we will use example.cluster.k8s.local as a sample gossip cluster name.

This is a fairly recent feature, so we recommend you continue to use DNS for production clusters. However, setting up a gossip-based cluster allows you to get started rather quickly.

We show two examples of creating gossip-based clusters below. You can choose whether to create a single-master or multi-master cluster. Workshop exercises will work on both types of cluster.

==== Default gossip-based cluster

By default, `create cluster` command creates a single master node and two worker nodes in the specified zones.

Create a Kubernetes cluster using the following command. This will create a cluster with a single master, multi-node and multi-az configuration:

    kops create cluster \
      --name example.cluster.k8s.local \
      --zones $AWS_AVAILABILITY_ZONES \
      --yes

The `create cluster` command only creates and stores the cluster config in the S3 bucket. Adding `--yes` option ensures that the cluster is immediately created as well.

Alternatively, you may not specify the `--yes` option as part of the `kops create cluster` command. Then you can use `kops edit cluster example.cluster.k8s.local` command to view the current cluster state and make changes. The cluster creation, in that case, is started with the following command:

    kops update cluster example.cluster.k8s.local --yes

The cluster can be verified as shown:

```
$ kops validate cluster
Using cluster from kubectl context: example.cluster.k8s.local

Validating cluster example.cluster.k8s.local

INSTANCE GROUPS
NAME      ROLE  MACHINETYPE MIN MAX SUBNETS
master-eu-central-1a Master  m3.medium 1 1 eu-central-1a
nodes     Node  t2.medium 2 2 eu-central-1a,eu-central-1b

NODE STATUS
NAME        ROLE  READY
ip-172-20-57-94.ec2.internal  master  True
ip-172-20-63-55.ec2.internal  node  True
ip-172-20-75-78.ec2.internal  node  True

Your cluster example.cluster.k8s.local is ready
```

==== Multi-master, multi-node, multi-az gossip-based cluster

Create a cluster with multi-master, multi-node and multi-az configuration. We can create and build the cluster in
one step by passing the `--yes` flag.

    kops create cluster \
      --name example.cluster.k8s.local \
      --master-count 3 \
      --master-zones $AWS_AVAILABILITY_ZONES \
      --node-count 5 \
      --zones $AWS_AVAILABILITY_ZONES \
      --yes

A multi-master cluster can be created by using the `--master-count` option and using an odd number value. The AZs for master can be specified using the `--master-zones` option. Kops will spread the servers across different AZs.

`--zones` is used to distribute the worker nodes. The number of workers is specified using the `--node-count` option.

Validate the cluster:

```
$ kops validate cluster
Using cluster from kubectl context: example.cluster.k8s.local
{'fraction_non_alphanumeric': 0.05792070162616481, 'fraction_numerical': 0.010414763383884524, 'mean_word_length': 3.8825453464168898, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 4, 'https://': 12, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 10, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4793929', 'n_tokens_mistral': 4470, 'n_tokens_neox': 4225, 'n_words': 2173}