Thursday, 1 October 2020

CIDR Calculation for AWS VPC Subnet

 Following post provide the formulas for calculating CIDR for VPC Subnet.

Considering a VPC with CIDR 172.31.0.0/16. 

1) What will be the CIDR notation for subnets inside 172.31.0.0/16 VPC?

The VPC can be divided into subnets with CIDR notation starting from /17 to /28.

2) What will be the CIDR notation for subnets if we have to divide 172.31.0.0/16 VPC into 'X' number of subnets?

If we have to divide 172.31.0.0/16 into 4 subnets, then following if the formula to calculate network bits (CIDR notation) for subnets. 

2 ^ (32 minus VPC CIDR Notation) / 2 ^ ( 32 minus SUBNET CIDR Notation)  =  NUMBER OF SUBNETS

considering 'SUBNET CIDR Notation' which is to be derived as a variable x, the above formula will be:

2 ^ ( 32 - 16) / 2 ^ (32 - x) = 4

Now consider 32 - x as variable y, above equation will be:

2 ^ 16 / 2 ^ y = 4

2 ^ (16 - y) = 4

which derives, y as 14. So 'x' will be 32 - 14 = 18.

That means, the CIDR notation of 4 subnets inside 172.31.0.0/16 will be /18.

3) How many subnets can be created with specific CIDR notation?

To find out how many subnets can be created for a given CIDR notation, same formula can be used:

2 ^ (32 minus VPC CIDR Notation) / 2 ^ ( 32 minus SUBNET CIDR Notation)  =  NUMBER OF SUBNETS

Considering 'SUBNET CIDR Notation' to be 20, above formula will be :

 2 ^ ( 32 - 16) / 2 ^ (32 - 20) = NUMBER OF SUBNETS

2 ^ 16 / 2 ^ 12 = NUMBER OF SUBNETS

2 ^ (16-12) = NUMBER OF SUBNETS

2 ^ 4 = NUMBER OF SUBNETS

that means, 16 subnets can be created with CIDR notation of /20.

4) How many IP Addressed will be available in subnet with CIDR notation /20?

Formula: 2 ^ ( 32 minus SUBNET CIDR Notation)

with /20, above will be 2 ^ ( 32 - 20 ) i.e. 2 ^ 12 i.e. 4096 IP Addresses

5) How to calculate Subnet addresses for each subnet?

Considering that we decided to divide 172.31.0.0/16 into subnets with /20 CIDR notation, following can be used to determine subnet address for each subnet. 

First subnet address will be 172.31.0.0/20. Since we know there will be total of 4096 IP addresses in this subnet and the range of IP address is 0 to 255 i.e. 256 values on fourth octet, so 4096 / 256 i.e.16 which mean 0 to 15 third octet value will cover total IP address range. 

So next subnet will start from 172.31.(0 + 16).0/20 and so on.

172.31.0.0/20    (IP Range: 172.31.0.0 to 172.31.15.255) 

172.31.16.0/20  (IP Range: 172.31.16.0 to 172.31.31.255) 

172.31.32.0/20

172.31.48.0/20

........

172.31.240.0/20


Hope this helps ✌

Useful Link: https://www.davidc.net/sites/default/subnets/subnets.html

Wednesday, 30 September 2020

Kubernetes (k8s) Disaster Recovery with Heptio Velero on AWS

Following post list down the steps to perform manual disaster recovery of an kubernetes cluster on AWS using Velero. 

Pre-requisites: Kubernetes cluster is up and running with one master node and one node acting as worker. Please refer following post  to setup kubernetes cluster with kubeadm on AWS free tier. 

AWS CLI is installed 

Kubernetes Cluster with kubeadm

1) Create s3 bucket to be used for backup.

export BUCKET=velero-backup-bkt

export REGION=ap-southeast-2

aws s3api create-bucket --bucket $BUCKET --region $REGION --create-bucket-configuration LocationConstraint=$REGION
 

2) Create IAM role to access bucket to be used by Velero

cat > assume-role-policy-document.json <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    },
    {
      "Sid": "",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::<ACCOUNT_ID>:role/InstanceRole"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF

aws iam create-role --role-name velero \
  --assume-role-policy-document \
  file://assume-role-policy-document.json
Where, InstanceRole,  is the role assigned to worker node EC2 instance. If no role is assigned, then create a new role.
 
3) Create and assign policy to above role to access S3

cat > velero-trust-policy.json <<EOF
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "ec2:DescribeVolumes",
                "ec2:DescribeSnapshots",
                "ec2:CreateTags",
                "ec2:CreateVolume",
                "ec2:CreateSnapshot",
                "ec2:DeleteSnapshot"
            ],
            "Resource": "*"
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:DeleteObject",
                "s3:PutObject",
                "s3:AbortMultipartUpload",
                "s3:ListMultipartUploadParts"
            ],
            "Resource": [
                "arn:aws:s3:::${BUCKET}/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::${BUCKET}"
            ]
        }
    ]
}
EOF

aws iam put-role-policy \
  --role-name velero \
  --policy-name s3 \
  --policy-document file://velero-trust-policy.json

4) Download velero client

wget https://github.com/vmware-tanzu/velero/releases/download/v1.3.2/velero-v1.3.2-linux-amd64.tar.gz

tar -xvf velero-v1.3.2-linux-amd64.tar.gz -C /tmp sudo mv /tmp/velero-v1.3.2-linux-amd64/velero /usr/local/bin

5) Install velero

velero install \

--provider aws \

--plugins velero/velero-plugin-for-aws:v1.0.1 \

--bucket ${BUCKET} \

--backup-location-config region=${REGION} \

--snapshot-location-config region=${REGION} \

--pod-annotations iam.amazonaws.com/role=arn:aws:iam::<ACCOUNT_ID>:role/velero \

--no-secret

kubectl get all -n velero





6) Install sample NGINX application on worker node that will serve as our test application to perform disaster recovery.


cat > nginx-deployment.yaml <<EOF apiVersion: v1 kind: Namespace metadata: name: nginx-example labels: app: nginx --- apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment namespace: nginx-example spec: replicas: 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - image: nginx:1.17.6 name: nginx ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: labels: app: nginx name: my-nginx namespace: nginx-example spec: ports: - port: 80 targetPort: 80 selector: app: nginx type: LoadBalancer EOF kubectl apply -f nginx-deployment.yaml

Verify all the resources are up and running

kubectl get all -n nginx-example









7) Create backup either based on app selector or namespace

velero backup create nginx-backup --selector app=nginx

OR

velero backup create nginx-backup --include-namespaces nginx-example

Check the status. Should show completion time once completed successfully.

velero backup describe nginx-backup


To create scheduled backups

velero create schedule daily-backup-at-7am --schedule="0 7 * * *" --include-namespaces nginx-example

8) Check S3 bucket to confirm backup is created:








9) Now to simulate disaster, lets delete nginx-example namespace. This will delete deployment and all running NGINX pods

kubectl delete namespace nginx-example


10) Restore all resources from backup

velero restore create --from-backup nginx-backup



Check restore status:

velero restore describe nginx-backup-20200930060821

Once restore completes, exactly same nginx resources should be up and running.







To restore scheduled backup. We can either do it using specific backup or with latest backup created by schedule:

#Specific backup

velero restore create --from-backup <BACKUP_NAME>

# Latest backup from schedule

velero restore create --from-schedule <SCHEDULE-NAME>