Finally did the next run in the 5 to 10 k. Still hurts when I run for an hour, and a tried slightly a different running route. Just over 8k today. Have no idea why the app registered only 5.7k.
This article is a guide on how to setup a Kubernetes cluster in AWS using kops and plugging it into your own subnets and VPC. We attempt to minimise the external IPs used in this method.
Export your AWS API keys into environment variables
Create the cluster (you can change some of these switches to match your requirements. I would suggest only using one worker node and one master node to begin with and then increase them once you have confirmed the config is good. The more workers and master nodes you have, the longer it will take to run a rolling-update.
Important note: There must be an ODD number of master zones. If you tell kops to use an even number zones for master, it will complain.
If you want to use additional security groups, don’t add them yet – add them after you have confirmed the cluster is working.
Internal IPs: You must have a VPN connection into your VPC or you will not be able to ssh into the instances. The alternative is to use the bastion functionality using the –bastion flag with the create command. Then doing this:
However, if you do this method, you MUST then use public IP addressing on the api load balancer, as you will not be able to do kops validate otherwise.
If you have a VPN connection into the VPC, change spec.api.loadBalancer.type to “Internal”, otherwise, leave it as “Public”
Change spec.subnets to match your private subnets. To use existing private subnets, they should also include the id of the subnet and match the CIDR range, e.g.:
The utility subnet is where the Bastion hosts will be placed, and these should be in a public subnet, since they will be the inbound route into the cluster from the internet.
If you need to change or add specific IAM permissions, add them under spec.additionalPolicies like this to add additional policies to the node IAM policy (apologies about the formatting. WordPress is doing something weird to it.)
Edit the bastion, nodes, and master configs (MASTER_REGION is the zone where you placed the master. If you are running a multi-region master config, you’ll have to do this for each region)
If you want a mixture of instance types (e.g. t2.mediums and r3.larges), you’ll need to separate these using new instance groups ($SUBNETS is the subnets where you want the nodes to appear – for example, you can provide a list “eu-west-2a,eu-west-2b)
(You can apply the yaml directly onto the cluster via the dashboard. Make sure you change the filter to match your domain or subdomain. )
Note that if you use this, you’ll need to change the node IAM policy on the cluster config as the default IAM policy won’t allow the External DNS container to modify Route 53 entries, and also annotate (use kubectl annotate $service_name key:value) your service with text such as:
And also you might need this annotation, to make the ELB internal rather than public - otherwise Kubernetes will complain “Error creating load balancer (will retry): Failed to ensure load balancer for service namespace/service: could not find any suitable subnets for creating the ELB”
It will allow you to visually see a topology of your cluster at a cluster and also provides some management features too. For example, here’s my cluster. It contains 5 nodes (1 master, 4 workers and is running 4 services (Kubernetes, external-dns, cockpit, and dashboard). Cockpit creates a replication controller so it knows about the changes.
Add any additional security groups by adding this under the spec section of the node/master/bastions config, then do a rolling-update (you might need to use the –force switch), do this as soon as you can after creating and verifying the cluster updates work.
[code lang=text]
additionalSecurityGroups:
sg-xxxxxxxx
sg-xxxxxxxx
[/code]
If the cluster breaks after this (i.e. the nodes haven’t shown up on the master), reboot the server (don’t terminate, use the reboot option from the AWS console), and see if that helps. If it still doesn’t show up, there’s something wrong with the security groups attached – i.e. they’re conflicting somehow with the Kubernetes access. Remove those groups and then do another rolling-update but use both the –force and –cloudonly switches to force a “dirty” respin.
If the cluster comes up good, then you can change the node counts on the configs and apply the update.
Note that if you change the node count and then apply the update, the cluster attempts to make the update without rolling-update. For example, if you change the node count from 1 to 3, the cluster attempts to bring up the 2 additional nodes.
Other things you can look at:
Kompose - which converts a docker-compose configuration into Kubernetes resources
First run of the final week and ended up dropping to a walk near the end of the 28 minutes. Disappointed, even though I was slow-jogging and making a pace of about 5:30 min/km on average for the main kms in the middle..
Well, it’s the day after Boxing Day. The day where the majority of people who haven’t taken the interim days off on holiday, go back to work.
There was definitely a run-down feeling on the train ride into work and the trains were running a reduced (probably a Sunday service), so I ended up running for the earlier train since my normal one wasn’t there today.
Christmas Day. Jammed up by an accident on the way, but lots (and lots) of food, movies and Wii-ing (is that even a word?)
Was pouring with rain on the way home. So bad, in fact that we had to slow down severely on the motorway. That however did not stop a 4x4 zooming past us. Christmas Day always brings out the idiots. 😑😒😔
First long run since my week away. 25 minutes running non stop and my body screamed at me to stop at 4km. Busted through and did one more round, taking it to 5.6 km. Strava logged it as 5.9 km, with moving time of 39:49, with a best km time of 5:24 min/km.
I was using the Spotify running playlist to keep my cadence steady and it showed.
The first and last kilometres were the warm up and cool down walks, hence the skewed time.
dig the nameservers for the hosted zone you created
dig NS k8stest.blenderfox.uk
If your internet connection already has DNS setup to the hosted zone, you’ll see the nameservers in the output:
;; QUESTION SECTION:
;k8stest.blenderfox.uk. IN NS
;; ANSWER SECTION:
k8stest.blenderfox.uk. 172800 IN NS ns-1353.awsdns-41.org.
k8stest.blenderfox.uk. 172800 IN NS ns-1816.awsdns-35.co.uk.
k8stest.blenderfox.uk. 172800 IN NS ns-404.awsdns-50.com.
k8stest.blenderfox.uk. 172800 IN NS ns-644.awsdns-16.net.
Export your AWS credentials as environment variables (I’ve found Kubernetes doesn’t reliably pick up the credentials from the aws cli especially if you have multiple profiles
You can also add it to a bash script and source it.
Create the cluster using kops. Note that the master zones must have an odd count (1, 3, etc.) since eu-west-2 only has two zones (a and b), I have to have only one zone here
While the cluster starts up, all the new records will be set up with placeholder IPs.
NOTE: Kubernetes needs an externally resolvable DNS name. Basically, you need to be able to create a hosted zone on a domain you control. You can’t use Kops on a domain you can’t control, even if you hack the resolver config.
The cluster can take a while to come up. Use
kops validate cluster –state s3://k8sstate
To check the cluster state.
When ready, you’ll see something like this:
Using cluster from kubectl context: cluster.k8stest.blenderfox.co.uk
Validating cluster cluster.k8stest.blenderfox.co.uk
INSTANCE GROUPS
NAME ROLE MACHINETYPE MIN MAX SUBNETS
master-eu-west-2a Master m4.large 1 1 eu-west-2a
nodes Node m4.large 3 3 eu-west-2a,eu-west-2b
NODE STATUS
NAME ROLE READY
ip-172-20-35-51.eu-west-2.compute.internal master True
ip-172-20-49-10.eu-west-2.compute.internal node True
ip-172-20-72-100.eu-west-2.compute.internal node True
ip-172-20-91-236.eu-west-2.compute.internal node True
Your cluster cluster.k8stest.blenderfox.co.uk is ready
Now you can start interacting with the cluster. First thing is to deploy the Kubernetes dashboard
$ kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/alternative/kubernetes-dashboard.yaml
serviceaccount "kubernetes-dashboard" created
role "kubernetes-dashboard-minimal" created
rolebinding "kubernetes-dashboard-minimal" created
deployment "kubernetes-dashboard" created
service "kubernetes-dashboard" created
Now setup a proxy to the api
$ kubectl proxy
Starting to serve on 127.0.0.1:8001
Next, access
http://localhost:8001/ui
To get the dashboard
Now let’s create a job to deploy on to the cluster.
The classic rm -rf / is there, along with accidental dd‘ing or mkfs‘ing the wrong disk (I’ve done that before), but the lesser known fork bombs and moving to /dev/null are in there (I often redirect output to /dev/null, but not moved files into there. That’s an interesting way of getting rid of files.