Skip to content

Instantly share code, notes, and snippets.

@tahoward
Last active March 25, 2019 18:34
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save tahoward/f7f20516a0b256f25ffc431645f29e90 to your computer and use it in GitHub Desktop.
Save tahoward/f7f20516a0b256f25ffc431645f29e90 to your computer and use it in GitHub Desktop.
Home Lab CoreOS Ignition
passwd:
users:
- name: core
password_hash: "$6$wXQZxh8d0BU4Eg$lVJQdLN08erJvBBgA0kS30yq5x8.gx1VKffmtjtD2GAgRdAzcpn1xO.3alXeOvSX92L72pGmx1EnSUTJvomLy1"
ssh_authorized_keys:
- "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAgEA1AJonpQaUOGKJKY/EOBOaMGYaHDdI6WPOLtVPgcmJhG/lb7lAT+YbUdn/7xAz0dbJhAh2XlJK++LQehhw4q7MnJ5ckgS5yoCx2VkJY//56T/Gv+q1cAxBcsq/5CF8rj8+cNR1Ztpf2Kq3gKZTdhvOytBjr7mh3Ui8bAMGBMf/KYWLbPCTybEam9BbyZeM5edf9N6q4vKSsx1SbpAOGEdnDjz2ttEJ8aaCWDvFbYOzjJwlgVXhRtbUvkjuct3/d72OpBRBhY0jlzwh4LSK1WGD6TbWOpZZP+RxvUTiKAGaMufmc6VKuN+jQQdxodyq9p/1DT8O9gspgolfVQpV0n7Lg+/FtGEh7Aq/eOB0VIRA7FCrvk38q4EZIatS7QaqdreIRtOUjCiu8EyOlnRuI5Ow7qIqWyAcZC9b5yi+q0LHuuDujmxBu9OdXPjZzj9EZl9OfPeHrhbNoRun6+CsRtBRh2rTjf2lPU5H0MLFZ3bZKNMxgnyxqoHQKCfim+4b1TTdv6Bengr4hN28IxIWW35vEBd0I1TQ6TKjOnvR3evjuHYefEtdAJqSo0QrKfPwzdL57VELre7JaCe4qZocTcCxOu/1hrkhlT1bX3QguB9/PL/m+kh7dEneajs6sVi3ewGXch9Sa3qEwKuiCisC6zumDQMcn+9VoYqXlr8igaziZ8= rsa-key-20180428"
storage:
files:
- filesystem: root
path: /etc/hostname
mode: 0644
contents:
inline: compute
- filesystem: root
path: /etc/rancher/agent-launch.sh
mode: 0755
contents:
inline: |
#!/bin/bash
CLUSTER_NAME=compute
ADDRESSES=($(ip -o -4 a show bond0 | cut -d' ' -f7 | cut -d'/' -f1))
SERVER="${ADDRESSES[0]}:8443"
RANCHER_AGENT_PATH="/mnt/rancher/agent"
API_TOKEN_FILE="token"
ROLE_FLAGS="--etcd --controlplane --worker"
WAIT_LIMIT=300
WAIT_INTERVAL=5
waitForRancher() {
COUNTER=0
while ! curl -k "https://${SERVER}/ping" && [ $COUNTER -lt $WAIT_LIMIT ]; do
sleep $WAIT_INTERVAL
let COUNTER+=$WAIT_INTERVAL
done
}
waitForCluster() {
COUNTER=0
getClusterStatus
while [ "${CLUSTER_STATUS}" = "active" ] && [ $COUNTER -lt $WAIT_LIMIT ]; do
sleep $WAIT_INTERVAL
let COUNTER+=$WAIT_INTERVAL
getClusterStatus
done
while [ "$CLUSTER_STATUS" != "${1}" ] && [ $COUNTER -lt $WAIT_LIMIT ]; do
if [ "${CLUSTER_STATUS}" = "null" ]; then
break
fi
sleep $WAIT_INTERVAL
let COUNTER+=$WAIT_INTERVAL
getClusterStatus
done
if [ "${1}" = "active" ]; then
if [ "${CLUSTER_STATUS}" != "active" ]; then
echo "[ERROR] No active cluster found"
exit 1
else
exit 0
fi
fi
}
setLoginToken() {
LOGIN_TOKEN=$(curl -s "https://${SERVER}/v3-public/localProviders/local?action=login" \
-H 'content-type: application/json' \
--data-binary '{
"username": "admin",
"password":"admin"
}' \
--insecure | jq -r .token
)
}
readAPIToken() {
API_TOKEN=$(cat ${RANCHER_AGENT_PATH}/${API_TOKEN_FILE})
}
writeAPIToken() {
echo ${API_TOKEN} > ${RANCHER_AGENT_PATH}/${API_TOKEN_FILE}
}
getAPIToken() {
API_TOKEN=$(curl -s "https://${SERVER}/v3/token" \
-H 'content-type: application/json' \
-H "Authorization: Bearer ${LOGIN_TOKEN}" \
--data-binary '{
"type": "token",
"description": "automation"
}' \
--insecure | jq -r .token)
}
setAPIToken() {
mkdir -p ${RANCHER_AGENT_PATH}
touch ${RANCHER_AGENT_PATH}/${API_TOKEN_FILE}
readAPIToken
if [ "${API_TOKEN}" = "null" ] || [ "${API_TOKEN}" = "" ]; then
setLoginToken
getAPIToken
writeAPIToken
fi
}
getServerURL() {
SERVER_URL=$(curl -s "https://${SERVER}/v3/settings/server-url" \
-H "Authorization: Bearer ${API_TOKEN}" \
--insecure | jq -r .value
)
}
setServerURL() {
getServerURL
if [ "${SERVER_URL}" = "" ]; then
SERVER_URL=$(curl -s -X PUT "https://${SERVER}/v3/settings/server-url" \
-H 'content-type: application/json' \
-H "Authorization: Bearer ${API_TOKEN}" \
--data-binary '{
"value": "https://'${SERVER}'"
}' \
--insecure | jq -r .value
)
fi
}
getClusterID() {
CLUSTER_ID=$(curl -s "https://${SERVER}/v3/clusters?name=${CLUSTER_NAME}" \
-H "Authorization: Bearer ${API_TOKEN}" \
--insecure | jq -r .data[0].id
)
}
setClusterID() {
CLUSTER_ID=$(curl -s "https://${SERVER}/v3/cluster" \
-H 'content-type: application/json' \
-H "Authorization: Bearer ${API_TOKEN}" \
--data-binary '{
"type": "cluster",
"nodes": [],
"rancherKubernetesEngineConfig": {
"ignoreDockerVersion": true
},
"name": "'${CLUSTER_NAME}'"
}' \
--insecure | jq -r .id
)
}
getClusterStatus() {
CLUSTER_STATUS=$(curl -s "https://${SERVER}/v3/clusters?name=${CLUSTER_NAME}" \
-H "Authorization: Bearer ${API_TOKEN}" \
--insecure | jq -r .data[0].state
)
}
getAgentImage() {
AGENT_IMAGE=$(curl -s "https://${SERVER}/v3/settings/agent-image" \
-H "Authorization: Bearer ${API_TOKEN}" \
--insecure | jq -r .value
)
}
getClusterToken() {
CLUSTER_TOKEN=$(curl -s "https://${SERVER}/v3/clusterregistrationtokens?creatorId_ne=&clusterId=${CLUSTER_ID}" \
-H "Authorization: Bearer ${API_TOKEN}" \
--insecure | jq -r .data[0].token
)
}
setClusterToken() {
getClusterToken
if [ "${CLUSTER_TOKEN}" = "null" ]; then
CLUSTER_TOKEN=$(curl -s "https://${SERVER}/v3/clusterregistrationtoken" \
-H 'content-type: application/json' \
-H "Authorization: Bearer ${API_TOKEN}" \
--data-binary '{
"type": "clusterRegistrationToken",
"clusterId": "'${CLUSTER_ID}'"
}' \
--insecure | jq -r .token
)
fi
}
getCAChecksum() {
CA_CHECKSUM=$(curl -s "https://${SERVER}/v3/settings/cacerts" \
-H "Authorization: Bearer $API_TOKEN" \
--insecure | jq -r .value | sha256sum | awk '{ print $1 }'
)
}
getNodeCommand() {
NODE_COMMAND="sudo docker run -d --privileged --restart=unless-stopped --net=host -v /etc/kubernetes:/etc/kubernetes -v /var/run:/var/run ${AGENT_IMAGE} --server ${SERVER_URL} --token ${CLUSTER_TOKEN} --ca-checksum ${CA_CHECKSUM} --address ${ADDRESSES[0]} ${ROLE_FLAGS}"
}
runNodeCommand() {
$NODE_COMMAND
}
echo "Waiting for Rancher..."
waitForRancher
echo "Retrieving API Token..."
setAPIToken
echo "API_TOKEN: ${API_TOKEN}"
echo "Checking Server URL..."
setServerURL
echo "SERVER_URL: ${SERVER_URL}"
echo "Retrieving Cluster ID..."
getClusterID
if [ "${CLUSTER_ID}" != "null" ]; then
echo "CLUSTER_ID: ${CLUSTER_ID}"
echo "Waiting for Active Cluster..."
waitForCluster active
echo "DONE!"
fi
setClusterID
echo "CLUSTER_ID: ${CLUSTER_ID}"
waitForCluster provisioning
echo "Retrieving Cluster Token..."
setClusterToken
echo "CLUSTER_TOKEN: ${CLUSTER_TOKEN}"
echo "Retrieving Agent Image..."
getAgentImage
echo "AGENT_IMAGE: ${AGENT_IMAGE}"
echo "Retrieving CA Checksum..."
getCAChecksum
echo "CA_CHECKSUM: ${CA_CHECKSUM}"
echo "Retrieving Node Command..."
getNodeCommand
echo "NODE_COMMAND: ${NODE_COMMAND}"
runNodeCommand
echo "Waiting for Active Cluster..."
waitForCluster active
echo "DONE!"
networkd:
units:
- name: enp2s0f.network
contents: |
[Match]
Name=enp2s0f*
[Network]
Bond=bond0
- name: enp6s0.network
contents: |
[Match]
Name=enp6s0
[Network]
Address=10.0.0.2/30
- name: bond0.netdev
contents: |
[NetDev]
Name=bond0
Kind=bond
[Bond]
Mode=802.3ad
LACPTransmitRate=fast
TransmitHashPolicy=layer2
MIIMonitorSec=1s
- name: bond0.network
contents: |
[Match]
Name=bond0
[Network]
Address=192.168.0.6/24
Gateway=192.168.0.1
DNS=192.168.0.1
systemd:
units:
- name: mnt-kubernetes.mount
enable: true
contents: |
[Unit]
Description=Mount for kube config backups
Before=remote-fs.target
[Mount]
What=10.0.0.1:/mnt/perseus-pool/compute/kubernetes
Where=/mnt/kubernetes
Type=nfs
[Install]
WantedBy=remote-fs.target
- name: mnt-rancher.mount
enable: true
contents: |
[Unit]
Description=Mount for rancher service volumes
Before=remote-fs.target
[Mount]
What=10.0.0.1:/mnt/perseus-pool/compute/rancher
Where=/mnt/rancher
Type=nfs
[Install]
WantedBy=remote-fs.target
- name: rancher.service
enable: true
contents: |
[Unit]
Description=Rancher service for docker management
After=docker.service
After=mnt-rancher.mount
Requires=docker.service
Requires=mnt-rancher.mount
[Service]
Type=oneshot
RemainAfterExit=true
ExecStartPre=-/usr/bin/docker kill rancher
ExecStartPre=-/usr/bin/docker rm rancher
ExecStartPre=/usr/bin/docker pull rancher/rancher
ExecStart=/usr/bin/docker run -d --restart=always --name rancher -p 192.168.0.6:8080:80 -p 192.168.0.6:8443:443 -v /mnt/rancher/server:/var/lib/rancher rancher/rancher
ExecStartPost=/usr/bin/bash /etc/rancher/agent-launch.sh
ExecStop=/usr/bin/docker stop -t 2 rancher
[Install]
WantedBy=multi-user.target
# Specify Config Transpiler version
CT_VER=v0.8.0
ARCH=x86_64
OS=unknown-linux-gnu
# Specify download URL
DOWNLOAD_URL=https://github.com/coreos/container-linux-config-transpiler/releases/download
# Download Config Transpiler binary
curl -L ${DOWNLOAD_URL}/${CT_VER}/ct-${CT_VER}-${ARCH}-${OS} -o /tmp/ct
chmod u+x /tmp/ct
# Download and import CoreOS application signing GPG key
curl https://coreos.com/dist/pubkeys/app-signing-pubkey.gpg -o /tmp/coreos-app-signing-pubkey.gpg
gpg2 --import --keyid-format LONG /tmp/coreos-app-signing-pubkey.gpg
# Download and import CoreOS application signing GPG key if it has not already been imported
curl -L ${DOWNLOAD_URL}/${CT_VER}/ct-${CT_VER}-${ARCH}-${OS}.asc -o /tmp/ct.asc
gpg2 --verify /tmp/ct.asc /tmp/ct
# Download container config
wget https://gist.githubusercontent.com/tahoward/f7f20516a0b256f25ffc431645f29e90/raw/823582826c0ec69d3e9073dae5acfe312007760e/container_config.yml
# Run Config Transpiler
/tmp/ct --in-file container_config.yml > ignition.json
# Install CoreOS to disk
sudo coreos-install -d /dev/sda -i ignition.json
# Reboot
sudo reboot
@onedr0p
Copy link

onedr0p commented Jun 27, 2018

Do you have any set up guide for how to use these scripts with Rancher 2.0? I am using vSphere and don't know exactly how to tie it all together using the CoreOS ISO or OVA files.

@tahoward
Copy link
Author

tahoward commented Jul 19, 2018

Hello, you may need to make modifications to this script for vSphere (the network device names and config will be different, also need your own password hash and public key) This assumes a specific hardware and network config I use at home.

Once you make the necessary edits you'll need to change line https://gist.github.com/tahoward/f7f20516a0b256f25ffc431645f29e90#file-coreos_bootstrap-sh-L22 to point at the new yaml config and run it locally on your deployed CoreOS image. Once the Rancher service is fully started you should just be able to hit the Rancher Web UI where it will ask for new credentials.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment