Skip to content

Migrate from GCP to AWS with CloudFormation templates #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
# Kubernetes The Hard Way
# Kubernetes The Hard Way "on AWS"

This tutorial walks you through setting up Kubernetes the hard way. This guide is not for people looking for a fully automated command to bring up a Kubernetes cluster. If that's you then check out [Google Kubernetes Engine](https://cloud.google.com/kubernetes-engine), or the [Getting Started Guides](https://kubernetes.io/docs/setup).
![](./docs/images/k8s_the_hard_way_on_aws_diagram.png)

Kubernetes The Hard Way is optimized for learning, which means taking the long route to ensure you understand each task required to bootstrap a Kubernetes cluster.
This tutorial walks you through setting up Kubernetes the hard way on AWS. Note that this repository is a fork from [kelseyhightower/kubernetes-the-hard-way](https://github.com/kelseyhightower/kubernetes-the-hard-way) and tweaked to use AWS instead of GCP.

This guide is not for people looking for a fully automated command to bring up a Kubernetes cluster. Kubernetes The Hard Way is optimized for learning, which means taking the long route to ensure you understand each task required to bootstrap a Kubernetes cluster.

> The results of this tutorial should not be viewed as production ready, and may receive limited support from the community, but don't let that stop you from learning!


## Copyright

<a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-nc-sa/4.0/88x31.png" /></a><br />This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International License</a>.
Expand All @@ -25,9 +28,10 @@ Kubernetes The Hard Way guides you through bootstrapping a highly available Kube
* [cni](https://github.com/containernetworking/cni) v0.7.1
* [etcd](https://github.com/coreos/etcd) v3.4.0


## Labs

This tutorial assumes you have access to the [Google Cloud Platform](https://cloud.google.com). While GCP is used for basic infrastructure requirements the lessons learned in this tutorial can be applied to other platforms.
This tutorial assumes you have access to the [Amazon Web Services (AWS)](https://aws.amazon.com). While AWS is used for basic infrastructure requirements the lessons learned in this tutorial can be applied to other platforms.

* [Prerequisites](docs/01-prerequisites.md)
* [Installing the Client Tools](docs/02-client-tools.md)
Expand Down
12 changes: 12 additions & 0 deletions cloudformation/hard-k8s-eip.cfn.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
Resources:
HardK8sEIP:
Type: AWS::EC2::EIP
Properties:
Tags:
- Key: Name
Value: eip-kubernetes-the-hard-way

Outputs:
EipAllocation:
Value: !GetAtt HardK8sEIP.AllocationId
Export: { Name: hard-k8s-eipalloc }
140 changes: 140 additions & 0 deletions cloudformation/hard-k8s-master-nodes.cfn.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
Resources:
HardK8sMaster0:
Type: AWS::EC2::Instance
Properties:
InstanceType: t3.micro
SubnetId: !ImportValue hard-k8s-subnet
SecurityGroupIds:
- !ImportValue hard-k8s-sg
ImageId:
Fn::FindInMap: [UbuntuAMIs, !Ref "AWS::Region", "id"]
KeyName: !Ref ParamKeyName
PrivateIpAddress: 10.240.0.10
# SourceDestCheck: false
UserData:
Fn::Base64: |-
#cloud-config
fqdn: master-0.k8shardway.local
hostname: master-0
runcmd:
- echo "preserve_hostname: true" >> /etc/cloud/cloud.cfg
write_files:
- path: /etc/hosts
permissions: '0644'
content: |
127.0.0.1 localhost localhost.localdomain
# Kubernetes the Hard Way - hostnames
10.240.0.10 master-0
10.240.0.11 master-1
10.240.0.12 master-2
10.240.0.20 worker-0
10.240.0.21 worker-1
10.240.0.22 worker-2
Tags: [ { "Key": "Name", "Value": "master-0" } ]

HardK8sMaster1:
Type: AWS::EC2::Instance
Properties:
InstanceType: t3.micro
SubnetId: !ImportValue hard-k8s-subnet
SecurityGroupIds:
- !ImportValue hard-k8s-sg
ImageId:
Fn::FindInMap: [UbuntuAMIs, !Ref "AWS::Region", "id"]
KeyName: !Ref ParamKeyName
PrivateIpAddress: 10.240.0.11
# SourceDestCheck: false
UserData:
Fn::Base64: |-
#cloud-config
fqdn: master-1.k8shardway.local
hostname: master-1
runcmd:
- echo "preserve_hostname: true" >> /etc/cloud/cloud.cfg
write_files:
- path: /etc/hosts
permissions: '0644'
content: |
127.0.0.1 localhost localhost.localdomain
# Kubernetes the Hard Way - hostnames
10.240.0.10 master-0
10.240.0.11 master-1
10.240.0.12 master-2
10.240.0.20 worker-0
10.240.0.21 worker-1
10.240.0.22 worker-2
Tags: [ { "Key": "Name", "Value": "master-1" } ]

HardK8sMaster2:
Type: AWS::EC2::Instance
Properties:
InstanceType: t3.micro
SubnetId: !ImportValue hard-k8s-subnet
SecurityGroupIds:
- !ImportValue hard-k8s-sg
ImageId:
Fn::FindInMap: [UbuntuAMIs, !Ref "AWS::Region", "id"]
KeyName: !Ref ParamKeyName
PrivateIpAddress: 10.240.0.12
# SourceDestCheck: false
UserData:
Fn::Base64: |-
#cloud-config
fqdn: master-2.k8shardway.local
hostname: master-2
runcmd:
- echo "preserve_hostname: true" >> /etc/cloud/cloud.cfg
write_files:
- path: /etc/hosts
permissions: '0644'
content: |
127.0.0.1 localhost localhost.localdomain
# Kubernetes the Hard Way - hostnames
10.240.0.10 master-0
10.240.0.11 master-1
10.240.0.12 master-2
10.240.0.20 worker-0
10.240.0.21 worker-1
10.240.0.22 worker-2
Tags: [ { "Key": "Name", "Value": "master-2" } ]

Parameters:
ParamKeyName:
Type: AWS::EC2::KeyPair::KeyName
Default: ec2-key

# $ aws ec2 describe-regions --query 'Regions[].RegionName' --output text \
# | tr "\t" "\n" | sort \
# | xargs -I _R_ aws --region _R_ ec2 describe-images \
# --filters Name=name,Values="ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-20191002" \
# --query 'Images[0].ImageId' --output
Mappings:
UbuntuAMIs:
ap-northeast-1: { "id": "ami-0cd744adeca97abb1" }
ap-northeast-2: { "id": "ami-00379ec40a3e30f87" }
ap-northeast-3: { "id": "ami-0bd42271bb31d96d2" }
ap-south-1: { "id": "ami-0123b531fc646552f" }
ap-southeast-1: { "id": "ami-061eb2b23f9f8839c" }
ap-southeast-2: { "id": "ami-00a54827eb7ffcd3c" }
ca-central-1: { "id": "ami-0b683aae4ee93ef87" }
eu-central-1: { "id": "ami-0cc0a36f626a4fdf5" }
eu-north-1: { "id": "ami-1dab2163" }
eu-west-1: { "id": "ami-02df9ea15c1778c9c" }
eu-west-2: { "id": "ami-0be057a22c63962cb" }
eu-west-3: { "id": "ami-087855b6c8b59a9e4" }
sa-east-1: { "id": "ami-02c8813f1ea04d4ab" }
us-east-1: { "id": "ami-04b9e92b5572fa0d1" }
us-east-2: { "id": "ami-0d5d9d301c853a04a" }
us-west-1: { "id": "ami-0dd655843c87b6930" }
us-west-2: { "id": "ami-06d51e91cea0dac8d" }

Outputs:
Master0:
Value: !Ref HardK8sMaster0
Export: { Name: hard-k8s-master-0 }
Master1:
Value: !Ref HardK8sMaster1
Export: { Name: hard-k8s-master-1 }
Master2:
Value: !Ref HardK8sMaster2
Export: { Name: hard-k8s-master-2 }
46 changes: 46 additions & 0 deletions cloudformation/hard-k8s-network.cfn.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
Resources:
HardK8sVpc:
Type: AWS::EC2::VPC
Properties:
CidrBlock: "10.240.0.0/16"
EnableDnsHostnames: true
EnableDnsSupport: true
HardK8sSubnet:
Type: AWS::EC2::Subnet
Properties:
VpcId: !Ref HardK8sVpc
CidrBlock: "10.240.0.0/24"
MapPublicIpOnLaunch: true
HardK8sRtb:
Type: AWS::EC2::RouteTable
Properties:
VpcId: !Ref HardK8sVpc
HardK8sRtbAssociation:
Type: AWS::EC2::SubnetRouteTableAssociation
Properties:
RouteTableId: !Ref HardK8sRtb
SubnetId: !Ref HardK8sSubnet
HardK8sIgw:
Type: AWS::EC2::InternetGateway
HardK8sGwAttach:
Type: AWS::EC2::VPCGatewayAttachment
Properties:
VpcId: !Ref HardK8sVpc
InternetGatewayId: !Ref HardK8sIgw
HardK8sDefaultRoute:
Type: AWS::EC2::Route
Properties:
DestinationCidrBlock: 0.0.0.0/0
RouteTableId: !Ref HardK8sRtb
GatewayId: !Ref HardK8sIgw

Outputs:
VpcId:
Value: !Ref HardK8sVpc
Export: { Name: hard-k8s-vpc }
SubnetId:
Value: !Ref HardK8sSubnet
Export: { Name: hard-k8s-subnet }
RouteTableId:
Value: !Ref HardK8sRtb
Export: { Name: hard-k8s-rtb }
31 changes: 31 additions & 0 deletions cloudformation/hard-k8s-nlb.cfn.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
Resources:
HardK8sNLB:
Type: AWS::ElasticLoadBalancingV2::LoadBalancer
Properties:
Type: network
Scheme: internet-facing
SubnetMappings:
- AllocationId: !ImportValue hard-k8s-eipalloc
SubnetId: !ImportValue hard-k8s-subnet

HardK8sListener:
Type: AWS::ElasticLoadBalancingV2::Listener
Properties:
DefaultActions:
- TargetGroupArn: !Ref HardK8sTargetGroup
Type: forward
LoadBalancerArn: !Ref HardK8sNLB
Port: 6443
Protocol: TCP

HardK8sTargetGroup:
Type: AWS::ElasticLoadBalancingV2::TargetGroup
Properties:
VpcId: !ImportValue hard-k8s-vpc
Protocol: TCP
Port: 6443
Targets:
- Id: !ImportValue hard-k8s-master-0
- Id: !ImportValue hard-k8s-master-1
- Id: !ImportValue hard-k8s-master-2
HealthCheckPort: "80" # default is "traffic-port", which means 6443.
16 changes: 16 additions & 0 deletions cloudformation/hard-k8s-nodeport-sg-ingress.cfn.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Parameters:
ParamNodePort:
Type: Number
# ref: https://kubernetes.io/docs/concepts/services-networking/service/#nodeport
MinValue: 30000
MaxValue: 32767

Resources:
HardK8sSmokeIngress:
Type: AWS::EC2::SecurityGroupIngress
Properties:
GroupId: !ImportValue hard-k8s-sg
CidrIp: 0.0.0.0/0
IpProtocol: tcp
FromPort: !Ref ParamNodePort
ToPort: !Ref ParamNodePort
21 changes: 21 additions & 0 deletions cloudformation/hard-k8s-pod-routes.cfn.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
Resources:
RouteWorker0:
Type: AWS::EC2::Route
Properties:
DestinationCidrBlock: 10.200.0.0/24
RouteTableId: !ImportValue hard-k8s-rtb
InstanceId: !ImportValue hard-k8s-worker-0

RouteWorker1:
Type: AWS::EC2::Route
Properties:
DestinationCidrBlock: 10.200.1.0/24
RouteTableId: !ImportValue hard-k8s-rtb
InstanceId: !ImportValue hard-k8s-worker-1

RouteWorker2:
Type: AWS::EC2::Route
Properties:
DestinationCidrBlock: 10.200.2.0/24
RouteTableId: !ImportValue hard-k8s-rtb
InstanceId: !ImportValue hard-k8s-worker-2
19 changes: 19 additions & 0 deletions cloudformation/hard-k8s-security-groups.cfn.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Resources:
HardK8sSg:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: security group for Kubernetes the hard way
VpcId: !ImportValue hard-k8s-vpc
SecurityGroupIngress:
# ingress internal traffic - allow all protocols/ports
- { "CidrIp": "10.240.0.0/24", "IpProtocol": "-1" } # master/worker nodes cidr range
- { "CidrIp": "10.200.0.0/16", "IpProtocol": "-1" } # pod cidr range
# ingress external traffic
- { "CidrIp": "0.0.0.0/0", "IpProtocol": "tcp", "FromPort": 6443, "ToPort": 6443 }
- { "CidrIp": "0.0.0.0/0", "IpProtocol": "tcp", "FromPort": 22, "ToPort": 22 }
- { "CidrIp": "0.0.0.0/0", "IpProtocol": "icmp", "FromPort": -1, "ToPort": -1 }

Outputs:
SgId:
Value: !Ref HardK8sSg
Export: { Name: hard-k8s-sg }
Loading