Restore disconnected workshop content.

Signed-off-by: James Blair <mail@jamesblair.net>
This commit is contained in:
2024-05-29 11:54:45 +12:00
parent 4f225728ba
commit 9769fefa79
9 changed files with 1005 additions and 262 deletions

View File

@ -1,135 +1,119 @@
---
title: Provisioning a windows worker node
title: Preparing our high side
exercise: 3
date: '2024-05-26'
tags: ['openshift','windows','kubernetes','containers']
date: '2023-12-19'
tags: ['openshift','containers','kubernetes','disconnected']
draft: false
authors: ['default']
summary: "Auto scaling nodes with machine sets!"
summary: "Setting up a bastion server and transferring content"
---
In this exercise, we'll prepare the **High side**. This involves creating a bastion server on the **High side** that will host our mirror registry.
Now that our cluster is ready to support Windows nodes lets provision one through the Machine API.
The Machine API is a combination of primary resources that are based on the upstream [Cluster API](https://github.com/kubernetes-sigs/cluster-api) project and custom OpenShift Container Platform resources.
The two primary resources are:
**1. Machines**
> A fundamental unit that describes the host for a Node. A machine has a providerSpec, which describes the types of compute nodes that are offered for different cloud platforms. For example, a machine type for a worker node on Amazon Web Services (AWS) might define a specific machine type and required metadata.
**2. MachineSets**
> Groups of machines. MachineSets are to machines as ReplicaSets are to Pods. If you need more machines or must scale them down, you change the **replicas** field on the MachineSet to meet your compute need.
> Note: We have an interesting dilemma for this excercise: the Amazon Machine Image we used for the prep system earlier does not have `podman` installed. We need `podman`, since it is a key dependency for `mirror-registry`.
>
> We could rectify this by running `sudo dnf install -y podman` on the bastion system, but the bastion server won't have Internet access, so we need another option for this lab. To solve this problem, we need to build our own RHEL image with podman pre-installed. Real customer environments will likely already have a solution for this, but one approach is to use the [Image Builder](https://console.redhat.com/insights/image-builder) in the Hybrid Cloud Console, and that's exactly what has been done for this lab.
>
> [workshop](/workshops/static/images/disconnected/image-builder.png)
>
> In the home directory of your web terminal you will find an `ami.txt` file containng our custom image AMI which will be used by the command that creates our bastion ec2 instance.
## 3.1 Create a single replica machineset
## 3.1 - Creating a bastion server
In this exercise we will create a `MachineSet`. Once created this will automatically begin provisoning a Windows machine and adding it to our cluster as a worker node.
First up for this exercise we'll grab the ID of one of our **High side** private subnets as well as our ec2 security group.
Below is a YAML snippet we will use as base to create our `MachineSet`:
```yaml
apiVersion: machine.openshift.io/v1beta1
kind: MachineSet
metadata:
name: cluster-<id>-windows-ap-southeast-<zone>
namespace: openshift-machine-api
labels:
machine.openshift.io/cluster-api-cluster: cluster-<id>
spec:
replicas: 1
selector:
matchLabels:
machine.openshift.io/cluster-api-cluster: cluster-<id>
machine.openshift.io/cluster-api-machineset: cluster-<id>-worker-ap-southeast-<zone>
template:
metadata:
labels:
machine.openshift.io/cluster-api-cluster: cluster-<id>
machine.openshift.io/cluster-api-machine-role: worker
machine.openshift.io/cluster-api-machine-type: worker
machine.openshift.io/cluster-api-machineset: cluster-<id>-worker-ap-southeast-<zone>
machine.openshift.io/os-id: Windows
spec:
lifecycleHooks: {}
metadata:
labels:
node-role.kubernetes.io/worker: ''
providerSpec:
value:
userDataSecret:
name: windows-user-data
placement:
availabilityZone: ap-southeast-<zone>
region: ap-southeast-1
credentialsSecret:
name: aws-cloud-credentials
instanceType: m5a.4xlarge
metadata:
creationTimestamp: null
blockDevices:
- ebs:
iops: 0
kmsKey: {}
volumeSize: 120
volumeType: gp2
securityGroups:
- filters:
- name: 'tag:Name'
values:
- cluster-<id>-worker-sg
kind: AWSMachineProviderConfig
metadataServiceOptions: {}
tags:
- name: kubernetes.io/cluster/cluster-<id>
value: owned
deviceIndex: 0
ami:
id: ami-0e76083a67107f741
subnet:
filters:
- name: 'tag:Name'
values:
- cluster-<id>-private-ap-southeast-<zone>
apiVersion: awsproviderconfig.openshift.io/v1beta1
iamInstanceProfile:
id: cluster-<id>-worker-profile
```
There are ten references to `<id>` in the sample that we need to find & replace with the actual cluster id for the cluster we have been allocated for the workshop and five references to the availability `<zone>` for our cluster nodes that we also need to update with our actual zone in use.
Run the following command in your bastion host terminal session to find your cluster id and zone:
Copy the commands below into your web terminal:
```bash
name=$(oc get machineset -A -o jsonpath={.items[0].metadata.name})
echo "Cluster id is: ${name:8:11}"
echo "Cluster availability zone is: ${name:40:2}"
PRIVATE_SUBNET=$(aws ec2 describe-subnets | jq '.Subnets[] | select(.Tags[].Value=="Private Subnet - disco").SubnetId' -r)
echo $PRIVATE_SUBNET
SG_ID=$(aws ec2 describe-security-groups --filters "Name=tag:Name,Values=disco-sg" | jq -r '.SecurityGroups[0].GroupId')
echo $SG_ID
```
After retrieving your cluster id and zone update the sample `MachineSet` using your preferred text editor, then select and copy all of the text to clipboard.
Once we know our subnet and security group ID's we can spin up our **High side** bastion server. Copy the commands below into your web terminal to complete this:
Within OpenShift you can then click the button in the top right hand corner, paste in your yaml and click **Create**.
```bash
aws ec2 run-instances --image-id $(cat ami.txt) \
--count 1 \
--instance-type t3.large \
--key-name disco-key \
--security-group-ids $SG_ID \
--subnet-id $PRIVATE_SUBNET \
--tag-specifications "ResourceType=instance,Tags=[{Key=Name,Value=disco-bastion-server}]" \
--block-device-mappings "DeviceName=/dev/sdh,Ebs={VolumeSize=50}"
```
<Zoom>
|![workshop](/workshops/static/images/windows/create-machineset.gif) |
|![workshop](/workshops/static/images/disconnected/launch-bastion-ec2.gif) |
|:-----------------------------------------------------------------------------:|
| *Create a windows machineset* |
| *Launching bastion ec2 instance* |
</Zoom>
## 3.2 Verify windows machine status
## 3.2 - Accessing the high side
After creating the `MachineSet` a new Windows machine will be automatically provisioned and added to our OpenShift cluster, as we set our desired replicas in the YAML to `1`.
Now we need to access our bastion server on the high side. In real customer environments, this might entail use of a VPN, or physical access to a workstation in a secure facility such as a SCIF.
To make things a bit simpler for our lab, we're going to restrict access to our bastion to its private IP address. So we'll use the prep system as a sort of bastion-to-the-bastion.
Let's get access by grabbing the bastion's private IP.
```bash
HIGHSIDE_BASTION_IP=$(aws ec2 describe-instances --filters "Name=tag:Name,Values=disco-bastion-server" | jq -r '.Reservations[0].Instances[0].PrivateIpAddress')
echo $HIGHSIDE_BASTION_IP
```
Our next step will be to `exit` back to our web terminal and copy our private key to the prep system so that we can `ssh` to the bastion from there. You may have to wait a minute for the VM to finish initializing:
```bash
PREP_SYSTEM_IP=$(aws ec2 describe-instances --filters "Name=tag:Name,Values=disco-prep-system" | jq -r '.Reservations[0].Instances[0].PublicIpAddress')
scp -i disco_key disco_key ec2-user@$PREP_SYSTEM_IP:/home/ec2-user/disco_key
```
To make life a bit easier down the track let's set an environment variable on the prep system so that we can preserve the bastion's IP:
```bash
ssh -i disco_key ec2-user@$PREP_SYSTEM_IP "echo HIGHSIDE_BASTION_IP=$(echo $HIGHSIDE_BASTION_IP) > highside.env"
```
Finally - Let's now connect all the way through to our **High side** bastion 🚀
```bash
ssh -t -i disco_key ec2-user@$PREP_SYSTEM_IP "ssh -t -i disco_key ec2-user@$HIGHSIDE_BASTION_IP"
```
<Zoom>
|![workshop](/workshops/static/images/windows/check-machine.gif) |
|![workshop](/workshops/static/images/disconnected/connect-bastion-ec2.gif) |
|:-----------------------------------------------------------------------------:|
| *Check the status of the new windows machine* |
| *Connecting to our bastion ec2 instance* |
</Zoom>
Creating, provisioning and configuring a new Windows host can be a lengthy process taking 15-30 minutes so now is a good time to take a break ☕.
You can keep an eye on the status of your Machine in the OpenShift web console. Once it reaches the **✅ Provisioned as node** status you are ready to proceed to the next exercise.
## 3.3 - Sneakernetting content to the high side
We'll now deliver the **High side** gift basket to the bastion server. Start by mounting our EBS volume on the bastion server to ensure that we don't run out of space:
```bash
sudo mkfs -t xfs /dev/nvme1n1
sudo mkdir /mnt/high-side
sudo mount /dev/nvme1n1 /mnt/high-side
sudo chown ec2-user:ec2-user /mnt/high-side
```
With the mount in place we can exit back to our base web terminal and send over our gift basket at `/mnt/high-side` using `rsync`. This can take 10-15 minutes depending on the size of the mirror tarball.
```bash
ssh -t -i disco_key ec2-user@$PREP_SYSTEM_IP "rsync -avP -e 'ssh -i disco_key' /mnt/high-side ec2-user@$HIGHSIDE_BASTION_IP:/mnt"
```
<Zoom>
|![workshop](/workshops/static/images/disconnected/sneakernet-transfer.gif) |
|:-----------------------------------------------------------------------------:|
| *Initiating the sneakernet transfer via rsync* |
</Zoom>
Once your transfer has finished pushing you are finished with exercise 3, well done! 🎉