diff --git a/.gitignore b/.gitignore index e57b9b5..c4123de 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,5 @@ .vscode terraform.tfvars install-config.yaml +.lego +local.env diff --git a/README.md b/README.md index c6dde3a..329e316 100644 --- a/README.md +++ b/README.md @@ -36,165 +36,59 @@ make make install ``` -### On the hypervisor - -```sh -curl https://mirror.openshift.com/pub/openshift-v4/dependencies/rhcos/4.7/4.7.0/rhcos-4.7.0-x86_64-qemu.x86_64.qcow2.gz |gunzip -c > /var/lib/libvirt/images/rhcos-4.7.0-x86_64-qemu.x86_64.qcow2 -curl -Lo /var/lib/libvirt/images/centos-stream-8.qcow2 http://cloud.centos.org/centos/8-stream/x86_64/images/CentOS-Stream-GenericCloud-8-20210210.0.x86_64.qcow2 -``` - -## Install - -Define the cluster name and the bastion. - -```sh -cluster=ocp4 -bastion=nicolas@hp-ml350.itix.fr -``` - -Install **openshift-installer** and **oc** on the bastion. - -```sh -ssh -A "$bastion" curl -Lo /tmp/openshift-installer.tgz https://mirror.openshift.com/pub/openshift-v4/clients/ocp/latest-4.7/openshift-install-linux.tar.gz -ssh -A "$bastion" sudo tar zxvf /tmp/openshift-installer.tgz -C /usr/local/bin openshift-install -ssh -A "$bastion" curl -Lo /tmp/oc.tgz https://mirror.openshift.com/pub/openshift-v4/clients/ocp/latest-4.7/openshift-client-linux.tar.gz -ssh -A "$bastion" sudo tar zxvf /tmp/oc.tgz -C /usr/local/bin oc kubectl -``` - -Create the cluster configuration files. - -```sh -mkdir "$cluster" -cp install-config.yaml.sample "$cluster/install-config.yaml" -openshift-install create manifests --dir="$cluster" -openshift-install create ignition-configs --dir="$cluster" -``` - -Customize the terraform variables. - -```sh -cat > terraform.tfvars <> terraform.tfvars -terraform apply -``` - -Approve the pending CSRs. - -```sh -for i in {0..120}; do - ssh -A "$bastion" oc --kubeconfig="$cluster/auth/kubeconfig" get csr --no-headers \ - | awk '/Pending/ {print $1}' \ - | xargs --no-run-if-empty ssh -A "$bastion" oc --kubeconfig="$cluster/auth/kubeconfig" adm certificate approve - sleep 15 -done & -``` - -Make sure all CSRs have been issued. - -```sh -ssh -A "$bastion" oc --kubeconfig="$cluster/auth/kubeconfig" get csr --no-headers -``` - -Provision storage for the registry. +Install lego. ```sh -ssh -A "$bastion" oc apply --kubeconfig="$cluster/auth/kubeconfig" -f - < "$cluster/registry-pv.yaml" +curl -Lo /tmp/lego.tgz https://github.com/go-acme/lego/releases/download/v4.3.1/lego_v4.3.1_linux_amd64.tar.gz +sudo tar zxvf /tmp/lego.tgz -C /usr/local/bin lego ``` -Patch the registry to use the new storage. - -```sh -ssh -A "$bastion" oc patch --kubeconfig="$cluster/auth/kubeconfig" configs.imageregistry.operator.openshift.io cluster --type='json' --patch-file=/dev/fd/0 < /var/lib/libvirt/images/rhcos-4.7.0-x86_64-qemu.x86_64.qcow2 +curl -Lo /var/lib/libvirt/images/centos-stream-8.qcow2 http://cloud.centos.org/centos/8-stream/x86_64/images/CentOS-Stream-GenericCloud-8-20210210.0.x86_64.qcow2 ``` -## Let's encrypt certificates - -Install lego. - -```sh -curl -Lo /tmp/lego.tgz https://github.com/go-acme/lego/releases/download/v4.3.1/lego_v4.3.1_linux_amd64.tar.gz -sudo tar zxvf /tmp/lego.tgz -C /usr/local/bin lego -``` +## Install -Request a public certificate. +Create the template files from their sample. ```sh -export GANDIV5_API_KEY="123...456" -. "$cluster/dns.env" -lego -m "nmasse@redhat.com" -d "$LE_API_HOSTNAME" -d "$LE_ROUTER_HOSTNAME" -a --dns gandi run --no-bundle +cp terraform.tfvars.sample terraform.tfvars +cp local.env.sample local.env +cp install-config.yaml.sample install-config.yaml ``` -Create a secret containing the new router certificate. +Initialize a new cluster. ```sh -oc create secret tls router-certs-$(date "+%Y-%m-%d") --cert=$HOME/.lego/certificates/$LE_API_HOSTNAME.crt --key=$HOME/.lego/certificates/$LE_API_HOSTNAME.key -n openshift-ingress --dry-run -o yaml > router.yaml -ssh -A "$bastion" oc apply -f - -n openshift-ingress < router.yaml +./cluster init my-cluster ``` -Update the ingress configuration. +Deploy the cluster. ```sh -ssh -A "$bastion" oc patch ingresscontroller default -n openshift-ingress-operator --type=merge --patch-file=/dev/fd/0 < api.yaml -ssh -A "$bastion" oc apply -f - -n openshift-config < api.yaml +./cluster post-install my-cluster ``` - -Update the apiserver configuration. - -```sh -oc patch apiserver cluster --type=merge --patch-file=/dev/fd/0 < "$cluster_name/install-config.yaml" + sed "s/__CLUSTER_NAME__/$cluster_name/" terraform.tfvars > "$cluster_name/terraform.tfvars" + + echo "Cluster $cluster_name initialized successfully!" + echo + echo "Review and adjust the following files to your needs:" + echo "- $cluster_name/install-config.yaml" + echo "- $cluster_name/terraform.tfvars" + echo + exit 0 +} + +function destroy () { + local cluster_name="${1:-}" + + if [ ! -d "$cluster_name" ]; then + echo "Cluster '$cluster_name' does not exist!" + exit 1 + fi + + terraform destroy -var-file="$cluster_name/terraform.tfvars" -state="$cluster_name/terraform.tfstate" + sed -i.bak 's/^\s*bootstrap_nodes\s*=\s*.*$/bootstrap_nodes = 1/' "$cluster_name/terraform.tfvars" +} + +function apply () { + local cluster_name="${1:-}" + + if [ ! -d "$cluster_name" ]; then + echo "Cluster '$cluster_name' does not exist!" + exit 1 + fi + + # Create installation files + openshift-install create manifests --dir="$cluster_name" + openshift-install create ignition-configs --dir="$cluster_name" + + # Provision the infrastructure and wait for bootstrap to complete + terraform apply -var-file="$cluster_name/terraform.tfvars" -state="$cluster_name/terraform.tfstate" -auto-approve + openshift-install --dir="$cluster_name" wait-for bootstrap-complete --log-level=info + + # Destroy the bootstrap node + sed -i.bak 's/^\s*bootstrap_nodes\s*=\s*.*$/bootstrap_nodes = 0/' "$cluster_name/terraform.tfvars" + terraform apply -var-file="$cluster_name/terraform.tfvars" -state="$cluster_name/terraform.tfstate" -auto-approve + + # Auto-approve all pending CSRs + for i in {0..240}; do + oc --insecure-skip-tls-verify --kubeconfig="$cluster_name/auth/kubeconfig" get csr --no-headers \ + | awk '/Pending/ {print $1}' \ + | xargs --no-run-if-empty oc --insecure-skip-tls-verify --kubeconfig="$cluster_name/auth/kubeconfig" adm certificate approve + sleep 15 + done & + + # Wait for the installation to complete + openshift-install --dir="$cluster_name" wait-for install-complete +} + +function post_install_nfs () { + local cluster_name="${1:-}" + + oc apply --insecure-skip-tls-verify --kubeconfig="$cluster_name/auth/kubeconfig" -f "$cluster_name/registry-pv.yaml" + oc patch --insecure-skip-tls-verify --kubeconfig="$cluster_name/auth/kubeconfig" configs.imageregistry.operator.openshift.io cluster --type=json --patch-file=/dev/fd/0 < "$cluster_name/router-certs.yaml" + oc --insecure-skip-tls-verify --kubeconfig="$cluster_name/auth/kubeconfig" apply -f "$cluster_name/router-certs.yaml" -n openshift-ingress + oc --insecure-skip-tls-verify --kubeconfig="$cluster_name/auth/kubeconfig" patch ingresscontroller default -n openshift-ingress-operator --type=merge --patch-file=/dev/fd/0 < "$cluster_name/api-certs.yaml" + oc --insecure-skip-tls-verify --kubeconfig="$cluster_name/auth/kubeconfig" apply -f "$cluster_name/router-certs.yaml" -n openshift-ingress + oc --insecure-skip-tls-verify --kubeconfig="$cluster_name/auth/kubeconfig" patch apiserver cluster --type=merge --patch-file=/dev/fd/0 < "$cluster_name/sso-secret.yaml" + oc --insecure-skip-tls-verify --kubeconfig="$cluster_name/auth/kubeconfig" apply -f "$cluster_name/sso-secret.yaml" + oc --insecure-skip-tls-verify --kubeconfig="$cluster_name/auth/kubeconfig" apply -f - <