Adding a private Docker registry to a PKS 1.5 Windows Kubernetes cluster

Pivotal Container Service (PKS) 1.5 and Kubernetes 1.14 bring *beta* support for Workers running Windows.  This means that we can provide the advantages of Kubernetes to a huge array of applications running on Windows.  I see this especially useful for Windows applications that you don’t have the source code for and/or do not want to invest in reworking it for .NET core or languages that run on Linux.

In nearly all cases, you’ll need an image with your applications’ dependencies or configuration and in the real world, we don’t want those in the public space like dockerhub.  Enter Private Docker Repositories.

PKS Enterprise includes VMware Harbor as a private registry, it’s very easy to deploy alongside PKS and provides a lot of important functionality.  The Harbor interface uses TLS/SSL; you may use a self-signed, enterprise PKI-signed or public CA-signed certificate.  If you chose to not use a public CA-signed certificate ($!), the self-signed or PKI-signed certificate must be trusted by the docker engine on each Kubernetes worker node.

Clusters based on Ubuntu Xenial Stemcells:

  • The operator/administrator simply puts the CA certificate into the “Trusted Certificates” box of the Security section in Ops Manager.
  • When BOSH creates the VMs for kubernetes clusters, the trusted certificates are added to the certificate store automatically.
  • If using an enterprise PKI where all of the internal certificates are signed by the Enterprise CA, this method makes it very easy to trust and “un-trust” CAs.

Clusters based on Windows 2019 Stemcells:

This is one of those tasks that is easier to perform on Linux that it is on Windows.  Unfortunately, Windows does not automatically add the Trusted Certificates from Ops Manager to the certificate store, so extra steps are required.

    1. Obtain the Registry CA Certificate.  In Harbor, you may click the “REGISTRY CERTIFICATE” link while in a Project.  Save the certificate to where the BOSH cli is installed (Ops Manager typically).
    2.  Connect BOSH cli to director.  This may be done on the Ops Manager.
    3. List BOSH-managed vms to identify the service_instance deployment corresponding to the targeted K8s cluster by matching the VM IP address to the IP address of the master node as reported by PKS cluster.
    4. Run this command to copy the certificate to the Windows worker
      bosh -e ENV -d DEPLOYMENT scp root.cer WINDOWS-WORKER:/
      • ENV – your environment alias in the BOSH cli
      • DEPLOYMENT – the BOSH deployment that corresponds to the k8s cluster; ex: service-instance_921bd35d-c46d-4e7a-a289-b577ff743e15
      • WINDOWS-WORKER – the instance name of the specific Windows worker VM; ex: windows-worker/277536dd-a7e6-446b-acf7-97770be18144

      This command copies the local file named root.cer to the root folder on the Windows VM

    5. Use BOSH to SSH into the Windows Worker.
      bosh -e ENV -d DEPLOYMENT ssh WINDOWS-WORKER
      • ENV – your environment alias in the BOSH cli
      • DEPLOYMENT – the BOSH deployment that corresponds to the k8s cluster; ex: service-instance_921bd35d-c46d-4e7a-a289-b577ff743e15
      • WINDOWS-WORKER – the instance name of the specific Windows worker VM; ex: windows-worker/277536dd-a7e6-446b-acf7-97770be18144

      SSH into Windows node, notice root.cer on the filesystem
    6. In the Windows SSH session run “powershell.exe” to enter powershell
    7. At the PS prompt, enter
      Import-certificate -filepath .\root.cer -CertStoreLocation 
      Cert:\LocalMachine\Root

      The example above imports the local file “root.cer” into the Trusted Root Certificate Store

    8. Type “exit” twice to exit PS and SSH
    9. Repeat steps 5-8 for each worker node.

Add docker-registry secret to k8s cluster

Whether the k8s cluster is running Windows workers or not, you’ll want to add credentials for authenticating to harbor.  These credentials are stored in a secret. To add the secret, use this command:

kubectl create secret docker-registry harbor \
--docker-server=HARBOR_FQDN \
--docker-username=HARBOR_USER \
--docker-password=USER_PASS \
--docker-email=USER_EMAIL
  • HARBOR_FQDN – FQDN for local/private Harbor registry
  • HARBOR_USER – name of user in Harbor with access to project and repos containing the desired images
  • USER_PASS – username for the above account
  • USER_EMAIL – email adddress for the above account

Note that this secret is namespaced; it needs to be added to the namespace of the deployments that will reference it

More info

Here’s an example deployment yaml for a Windows K8s cluster that uses a local private docker registry.  Note that Windows clusters cannot leverage NSX-T yet, so this example uses a NodePort to expose the service.

Advertisement

Logging into a Kubernetes cluster with an OIDC LDAP account

I confess, most of my experience with Kubernetes is with Pivotal Container Service (PKS) Enterprise.  PKS makes it rather easy to get started and I found that I took some tasks for granted.

In PKS Enterprise, one can use the pks cli to not only life-cycle clusters, but to obtain the credentials to the cluster and automatically update the kubeconfig with the account information.  So, administrative/operations users can run the command “pks get-credentials my-cluster” to have a kubeconfig updated with the authentication tokens and parameters to connect to my-cluster.

K8s OIDC using UAA on PKS

The PKS controller includes the User Account and Authentication (UAA) component, which is used to authenticate users into PKS Enterprise.  UAA can also be easily configured to connect to an existing LDAP service – this is the desired configuration in most organizations so that users account exist in one place (Active Directory in my example).

So, I found myself wondering “I don’t want to provide the PKS CLI to developers, so how can they connect kubectl to the cluster?”

Assumptions:

  • PKS Enterprise on vSphere (with or without NSX-T)
  • Active Directory
  • Developer user account belongs to the k8s-devs security group in AD

Prerequisite configuration:

  1. UAA on PKS configured a with UAA User Account Store: LDAP Server.  This links UAA to LDAP/Active Directory
  2. User Search Filter: userPrincipalName={0}  This means that users can login as user@domain.tld
  3. Group Search Filter: member={0} This ensures that AD groups may be used rather than specifying individual users
  4. Configure created clusters to use UAA as the OIDC provider: Enabled  This pre-configures the kubernetes API to use OpenID Connect with UAA. If not using PKS Enterprise, you’ll need to provide another OpenID Connect-Compliant endpoint (like Dex), link it to Active Directory and update the kubernetes cluster api manually to use the OpenID Authentication.

 

Operator: Create Role and RoleBinding:

While authentication is handled by OIDC/UAA/LDAP, Authorization must be configured on the cluster to provide access to resources via RBAC.  This is done by defining a Role (or clusterRole) that indicates what actions may be taken on what resources and a RoleBinding which links the Role to one or more “subjects”.

  1.  Authenticate to kubernetes cluster with an administrative account (for example, using PKS cli to connect)
  2.  Create yaml file for our Role and RoleBinding:
    kind: Role
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
      name: developers
    rules:
    - apiGroups: ["", "extensions", "apps"]
      resources: ["deployments", "replicasets", "pods"]
      verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] 
      # You can also use ["*"]
    ---
    kind: RoleBinding
    apiVersion: rbac.authorization.k8s.io/v1beta1
    metadata:
      name: developer-dev-binding
    subjects:
    - kind: Group
      name: k8s-devs
      apiGroup: rbac.authorization.k8s.io
    roleRef:
      kind: Role
      name: developers
      apiGroup: rbac.authorization.k8s.io
    

    In the example above, we’re creating a Role named “developers”, granting access to the core, extensions and apps API groups and several actions against deployments, replicaSets and pods. Notice that developers in this role would have have access to secrets (for example)
    The example RoleBinding binds a group named “k8s-devs” to the developers role. Notice that we have not created the k8s-devs group in Kubernetes or UAA; it exists in Active Directory

  3. Use Kubectl to apply the yaml, creating the Role and Rolebinding in the targeted namespace

 

Creating the kubeconfig – the hard way

To get our developer connected with kubectl, they’ll need a kubeconfig with the authentication and connection details.  The Hard way steps are:

  1. Operator obtains the cluster’s certificate authority data.  This can be done via curl or by copying the value from the existing kubeconfig.
  2. Operator creates a template kubeconfig, replacing the value specified, then sends it to the developer user
    apiVersion: v1
    clusters:
    - cluster:
      certificate-authority-data: <OBTAINED IN STEP 1 >
      server: < FQDN to Master Node. >
      name: PROVIDED-BY-ADMIN
    contexts:
    - context:
        cluster: PROVIDED-BY-ADMIN
        user: PROVIDED-BY-USER
      name:  PROVIDED-BY-ADMIN
    current-context: PROVIDED-BY-ADMIN
    kind: Config
    preferences: {}
    users:
    - name: PROVIDED-BY-USER
      user:
        auth-provider:
          config:
            client-id: pks_cluster_client
            cluster_client_secret: ""
            id-token: PROVIDED-BY-USER
            idp-issuer-url: https://PROVIDED-BY-ADMIN:8443/oauth/token
            refresh-token:  PROVIDED-BY-USER
          name: oidc
  3. The developer user obtains the id_token and refresh_token from UAA, via a curl command
    curl 'https://PKS-API:8443/oauth/token' -k -XPOST -H
    'Accept: application/json' -d "client_id=pks_cluster_client&client_secret=""&grant_type=password&username=UAA-USERNAME&response_type=id_token" --data-urlencode password=UAA-PASSWORD
  4. The developer user updates the kubeconfig with the id_token and refresh token in the kubeconfig

 

Creating the kubeconfig – the easy way

Assuming the developer is using Mac or Linux…

  1. Install jq on developer workstation
  2. Download the get-pks-k8s-config.sh script, make it executable (chmod +x get-pks.k8s.config.sh)
  3. Execute the script (replace the params with your own)
    ./get-pks-k8s-config.sh --API=api.pks.mydomain.com \
    --CLUSTER=cl1.pks.mydomain.com \
    --USER=dev1@mydomain.com \
    --NS=scratch
    • API – FQDN to PKS Controller, for UAA
    • CLUSTER – FQDN to master node of k8s cluster
    • USER – userPrincipalName for the user
    • NS – Namespace to target; optional
  4. After entering the user’s password, the script will set the params in the kubeconfig and switch context automatically

Try it out
Our developer user should able to “see” pods but not namespaces for example:

dev1 can see pods but not namespaces

 

Creating the kubeconfig – the easiest way

  1. Provide the developer with the PKS CLI tool, remember we have not added them to any group or role with PKS admin permissions.
  2. Provide the developer with the PKS API endpoint FQDN and the cluster name
  3. The developer may run this command to generate the updated kubeconfig and set the current context
    pks get-kubeconfig CLUSTERNAME -a API -u USER -k

    • CLUSTERNAME is the name of the cluster
    • API – FQDN to PKS Controller
    • USER – userPrincipalName for the user
  4. You’ll be prompted for the account password. Once entered, the tool will fetch the user-specific kubeconfig.
Use PKS CLI to get the kubeconfig

 

BOSH Stemcell 3541.2 breaks Concourse 3.9.0

Looks like there was a breaking change in stemcell v3541.2 where the default umask was set to 077.  If this stemcell is used with BOSH-deployed-Concourse.CI v3.9.0, resource checking fails with a “permission denied” error.

Note that Pivotal (as of Feb 22 2018)  has not updated their stemcells to 3541.x and their latest is still in the 3468 chain.

 

Building Stand-Alone BOSH and Concourse

This should be the last “how to install concourse” post; With this, I think I’ve covered all the interesting ways to install it.  Using BOSH is by-far my favorite approach.  After this, I hope to post more related to the use of concourse and pipelines.

Overview

There are three phases to this deployment:

  1. BOSH-start – We’ll set up an ubuntu VM to create the BOSH director from.  We’ll be using BOSH v2 and not bosh-init
  2. BOSH Director – This does all the work for us, but has to be instructed how to connect to vSphere
  3. Concourse – We’ll use a deployment manifest in BOSH to deploy concourse

I took the approach that – where possible – I would manually download the files and transfer them to the target, rather than having the install process pull the files down automatically.  In my case, I went through a lot of trial-and-error, so I did not want to pull down the files every time.  In addition, I’d like to get a feel for what a self-contained (no Internet access) solution would look like. BTW, concourse requires Internet access in order to get to docker hub for a container to run its pipelines.

Starting position

Make sure you have the following:

  • Working vSphere environment with some available storage and compute capacity
  • At least one network on a vSwitch or Distributed vSwitch with available IP addresses
  • Account for BOSH to connect to vSphere with permissions to create folders, resource pools, and VMs
  • An Ubuntu  VM template.  Mine is 16.04 LTS
  • PuTTY, Win-SCP or similar tools

BOSH-start

  1. Deploy a VM from your Ubuntu template.  Give it a name – I call mine BOSH-start – and IP address, power it on.  In my case, I’m logged in as my account to avoid using root unless necessary.
  2. Install dependencies:
    sudo apt-get install -y build-essential zlibc zlib1g-dev ruby ruby-dev openssl \
    libxslt-dev libxml2-dev libssl-dev libreadline6 libreadline6-dev \
    libyaml-dev libsqlite3-dev sqlite3
  3. Download BOSH CLI v2, make it executable and move it to the path.  Get the latest version of the BOSH v2 CLI here.
    wget https://s3.amazonaws.com/bosh-cli-artifacts/bosh-cli-2.0.16-linux-amd64
    chmod +x ~/Downloads/bosh-cli-*
    sudo mv ~/Downloads/bosh-cli-* /usr/local/bin/bosh

BOSH Director

  1. Git Director templates
    mkdir ~/bosh-1
    cd ~/bosh-1
    git clone https://github.com/cloudfoundry/bosh-deployment
  2. Create a folder and use bosh to create the environment.  This command will create several “state” files and our BOSH director with the information you provide.  Replace the values in red with your own.
    
    bosh create-env bosh-deployment/bosh.yml \
        --state=state.json \
        --vars-store=creds.yml \
        -o bosh-deployment/vsphere/cpi.yml \
        -o bosh-deployment/vsphere/resource-pool.yml \
        -o bosh-deployment/misc/dns.yml \
        -v internal_dns=<DNS Servers ex: [192.168.100.10,192.168.100.11]>
        -v director_name=<name of BOSH director. eg:boshdir> \
        -v internal_cidr=<CIDR for network ex: 172.16.9.0/24> \
        -v internal_gw=<Gateway Address> \
        -v internal_ip=<IP Address to assign to BOSH director> \
        -v network_name="<vSphere vSwitch Port Group>" \
        -v vcenter_dc=<vSphere Datacenter> \
        -v vcenter_ds=<vSphere Datastore> \
        -v vcenter_ip=<IP address of vCenter Server> \
        -v vcenter_user=<username for connecting to vCenter Server> \
        -v vcenter_password=<password for that account> \
        -v vcenter_templates=<location for templates ex:/BOSH/templates> \
        -v vcenter_vms=<location for VM.  ex:/BOSH/vms> \
        -v vcenter_disks=<folder on datastore for bosh disks.  ex:bosh-1-disks> \
        -v vcenter_cluster=<vCenter Cluster Name> \
        -v vcenter_rp=<Resource Pool Name>

    One note here; if you do not add the line for dns.yml and internal_dns, your BOSH director will use 8.8.8.8 as its DNS server and won’t be able to find anything internal. This will take a little while to download the bits and set up the Director for you.

  3. Connect to Director.  The following commands will create an alias for the new BOSH environment named “bosh-1”. Replace 10.0.0.6 with the IP of your BOSH Director from the create-env command:
    # Configure local alias
    bosh alias-env bosh-1 -e 10.0.0.6 --ca-cert <(bosh int ./creds.yml --path /director_ssl/ca)
    export BOSH_CLIENT=admin
    export BOSH_CLIENT_SECRET=`bosh int ./creds.yml --path /admin_password`
    bosh -e bosh-1 env
  4. Next we’ll need a “cloud config”.  This indicates to BOSH Director how to configure the CPI for interaction with vSphere.  You can find examples and details here.  For expediency, What I ended up with is below. As usual, you’ll want to update the values in red to match your environment.  Save this file as ~/bosh-1/cloud-config.yml on the BOSH-start VM
    azs:
    - name: z1
      cloud_properties:
        datacenters:
        - name: <vSphere Datacenter Name>
        - clusters: 
          - <vSphere Cluster Name>: {resource_pool: <Resource Pool in that cluster>}
    properties:
      vcenter:
        address: <IP of FQDN of vCenter Server>
        user: <account to connect to vSphere with>
        password: <Password for that account>
        default_disk_type: thin
        enable_auto_anti_affinity_drs_rules: false
        datacenters:
        - name: <vSphere Datacenter Name>
          vm_folder: /BOSH/vms
          template_folder: /BOSH/templates
          disk_path: prod-disks
          datastore_pattern: <regex filter for datastores to use ex: '\AEQL-THICK0\d' >
          persistent_datastore_pattern: <regex filter for datastores to use ex: '\AEQL-THICK0\d' >
          clusters:
          - <vSphere Cluster Name>: {resource_pool: <Resource Pool in that cluster>}
    
    vm_types:
    - name: default
      cloud_properties:
        cpu: 2
        ram: 4096
        disk: 16_384
    - name: large
      cloud_properties:
        cpu: 2
        ram: 8192
        disk: 32_768
    
    disk_types:
    - name: default
      disk_size: 16_384
      cloud_properties:
        type: thin
    - name: large
      disk_size: 32_768
      cloud_properties:
        type: thin
    
    networks:
    - name: default
      type: manual
      subnets:
      - range: <network CIDR where to place VMs ex:192.168.10.0/26>
        reserved: <reserved range in that CIDR ex:[192.168.10.1-192.168.10.42] >
        gateway: <gateway address for that network>
        az: z1
        dns: <DNS Server IPs ex: [192.168.100.50,192.168.100.150] >
        cloud_properties:
          name: <name of port group to attach created VMs to>
    
    compilation:
      workers: 5
      reuse_compilation_vms: true
      az: z1
      vm_type: large
      network: default
    
    
  5. Update Cloud Config with our file:
    bosh -e bosh-1 update-cloud-config ./cloud-config

    This is surprisingly fast.  You should now have a functional BOSH Director.

Concourse

Let’s deploy something with BOSH!

Prereqs:

  • Copy the URLs for the Concourse and Garden runC BOSH releases from here
  • Copy the URL for the latest Ubuntu Trusty stemcell for vSphere from here
  1. Upload Stemcell.  You’ll see it create a VM with a name beginning with “sc” in vSphere
    bosh -e bosh-1 upload-stemcell <URL to stemcell>
  2. Upload Garden runC release to BOSH
    bosh -e bosh-1 upload-release <URL to garden-runc tgz>
  3. Upload Concourse release to BOSH
    bosh -e bosh-1 upload-release <URL to concourse tgz>
  4. A BOSH deployment must have a stemcell, a release and a manifest.  You can get a concourse manifest from here, or start with the one I’m using.  You’ll notice that a lot of the values here must match those in our cloud-config.  Save the concourse manifest as ~/concourse.yml
    ---
    name: concourse
    
    releases:
    - name: concourse
      version: latest
    - name: garden-runc
      version: latest
    
    stemcells:
    - alias: trusty
      os: ubuntu-trusty
      version: latest
    
    instance_groups:
    - name: web
      instances: 1
      # replace with a VM type from your BOSH Director's cloud config
      vm_type: default
      stemcell: trusty
      azs: [z1]
      networks: [{name: default}]
      jobs:
      - name: atc
        release: concourse
        properties:
          # replace with your CI's externally reachable URL, e.g. https://ci.foo.com
          external_url: http://concourse.mydomain.com
    
          # replace with username/password, or configure GitHub auth
          basic_auth_username: myuser
          basic_auth_password: mypass
    
          postgresql_database: &atc_db atc
      - name: tsa
        release: concourse
        properties: {}
    
    - name: db
      instances: 1
      # replace with a VM type from your BOSH Director's cloud config
      vm_type: large
      stemcell: trusty
      # replace with a disk type from your BOSH Director's cloud config
      persistent_disk_type: default
      azs: [z1]
      networks: [{name: default}]
      jobs:
      - name: postgresql
        release: concourse
        properties:
          databases:
          - name: *atc_db
            # make up a role and password
            role: atc_db
            password: mypass
    
    - name: worker
      instances: 1
      # replace with a VM type from your BOSH Director's cloud config
      vm_type: default
      stemcell: trusty
      azs: [z1]
      networks: [{name: default}]
      jobs:
      - name: groundcrew
        release: concourse
        properties: {}
      - name: baggageclaim
        release: concourse
        properties: {}
      - name: garden
        release: garden-runc
        properties:
          garden:
            listen_network: tcp
            listen_address: 0.0.0.0:7777
    
    update:
      canaries: 1
      max_in_flight: 1
      serial: false
      canary_watch_time: 1000-60000
      update_watch_time: 1000-60000

    A couple of notes:

    • The Worker instance will need plenty of space, especially if you’re planning to use PCF Pipeline Automation, as it’ll have to download the massive binaries from PivNet. You’ll want to make sure that you have a sufficiently large vm type defined in your cloud config and assigned as worker in the Concourse manifest
  5. Now, we have everything we need to deploy concourse.  Notice that we’re using BOSH v2 and the deployment syntax is a little different than in BOSH v1.  This command will create a handful of VMs, compile a bunch of packages and push them to the VMs.  You’ll a couple extra IPs for the compilation VMs – these will go away after the deployment is complete.
    bosh -e bosh-1 -d concourse deploy ./concourse.yml
  6. Odds are that you’ll have to make adjustments to the cloud-config and deployment manifest.  If so, you can easily apply updates to the cloud-config with the bosh update-cloud-config command.
  7. If the deployment is completely hosed up and you need to remove it, you can do so with
    bosh -e bosh-1 -d concourse stop &&  bosh -e bosh-1 -d concourse deld

Try it out

  1. Get the IP address of the web instance by running
    bosh -e bosh-1 vms

    From the results, identify the IP address of the web instance:

  2. Point your browser to http://<IP of web instance>:8080
  3. Click Login, Select “main” team and login with the username and password (myuser and mypass in the example) you used in the manifest

References:

 

Getting started with BOSH Backup and Restore – Pt.1 Backup

Starting with a working PCF 1.11 deployment, a random linux VM and the BOSH Backup and Restore bits, let’s try it out!

Background

  • We’ll perform two types of backup jobs using BBR; one against the BOSH director and one against the Elastic Runtime deployment. The command and parameters are different between the jobs.
  • BBR stores the backup data in subfolders where the executable is run
  • Tiles other than Elastic Runtime (CF) may be backed up with BBR later, but as of late June 2017, they do not have the BBR scripts in place.
  • If you don’t turn on MySQL backups and the Backup Prepare Node in Elastic Runtime, the CF deployment backup job will fail in that it cannot find the backup scripts for the MySQL database
  • I’m using a CentOS VM in the environment as the jumpbox to run BBR.  You’ll want to make sure that the jumpbox is able to reach the BOSH director on TCP22 and TCP25555.

Steps

  1. Prepare PCF
    • Logon to Ops Manager
    • Click the “Pivotal Elastic Runtime” tile
    • Assuming you’re using the internal MySQL, click “Internal MySQL” on the Settings tab
    • Under Automated Backups Configuration, select “Enable automated backups from MySQL to and S3 bucket or other S3-compatible file store”.  Right here, you’re thinking, “but I don’t have an S3 server or account or whatever”.  That’s ok, just fake it.  Put bogus values in the fields and an unreachable date (like February 31st).  Click Save.

      Bogus S3 info
    • Under Resource Config, make sure the Backup Prepare Node instance count is 1 (or more?).  Click Save
    • Return to the Installation Dashboard and Apply Changes
  2. Get the BBR credentials.
    • Logon to Ops Manager
    • Click the “Ops Manager Director” tile
    • Click the “Credentials” tab
    • Click the “Link to Credential” link beside “Bbr Ssh Credentials”

      BBR Director Backup Credential
    • The page the loads will display a yml-type file with the PEM-encoded Private and Public Keys.  Select and copy from “—–BEGIN RSA PRIVATE KEY—–” through “—–END RSA PRIVATE KEY—–“.
    • Paste this into a text editor.  In my case, on Windows, the content used literally “/n” to indicate new-line rather than an actual newline.  So, to convert it, I used Notepad++ to replace “//n” with “/n” in the Extended Search Mode.

      Using Notepad++
    • The username that BBR will use for the director job is “bbr”
    • Back on the “Credentials” tab of Ops Manager Director, click “Link to Credential” beside “Uaa Bbr Client Credentials”
    • On the page that loads, note that the identity is”bbr_client” and record the password value. This will be used for the BBR deployment job(s)
    • Back on the “Credentials” tab of Ops Manager Director, click “Link to Credential” beside “Director Credentials”
    • On the page that loads, note that the identity is”director” and record the password value.  You’ll need this to login to BOSH in order to get the deployment name next
  3. Get the deployment name
    • Open an SSH session to the Ops Manager, logging on as ubuntu
    • Run this:

      uaac target –ca-cert /var/tempest/workspaces/default/root_ca_certificate https://DIRECTOR-IP-ADDRESS:8443

      bosh –ca-cert /var/tempest/workspaces/default/root_ca_certificate target DIRECTOR-IP-ADDRESS

      Logon as “director” with the password saved earlier

    • Run this:

      bosh deployments

    • In the results, copy the deployment name that begins with “cf-“. (eg: cf-67afe56410858743331)
  4. Prepare the jumpbox
    • Logon with a privileged account
    • Using SCP or similar, copy “/var/tempest/workspaces/default/root_ca_certificate” from Ops Manager to the jump box
    • Copy the bbr-0.1.2.tar file to the jumpbox
    • Extract it – tar -xvf bbr-0.1.2.tar
    • Make sure you have plenty of space on the jumpbox.  In my case, I mounted a NFS share and ran BBR from the mount point.
    • Copy <extracted files>/release/bbr to the root folder where you want the backups to reside.
    • Save the PEM-encoded RSA Private Key from above to the jumpbox, making a note of it’s path and filename.  I just stuck it in the same folder as the bbr executable.
    • Make sure you can connect to the BOSH director via ssh
      ssh -i bbr@
  5. Director Backup
    • On the jumpbox, navigate to where you placed the bbr executable.  Remember that it will create a time-stamped subfolder here and dump all the backups into it.
    • Run this, replacing the values in red with the correct path to the private key file and BOSH Director IP address :Director Pre-check
      ./bbr director –private-key-path ./private.key –username bbr –host 172.16.9.16 pre-backup-check
    • Check that the pre-check results indicate that the director can be backed up
    • Run this to perform the backup: (same as before, just passing the “backup” sub-command instead of the “pre-backup-check’ subcommand)Director Backup
      ./bbr director –private-key-path ./private.key –username bbr –host 172.16.9.16 backup
    • Wait a while for the backup to complete
  6. What’d it do?
    • Backed up BOSH director database to bosh-0-director.tar
    • Dumped credhub database to bosh-0-credhub.tar
    • Dumped uaa database to bosh-0-uaa.tar
    • Backed up the BOSH director blobstore to bosh-0-blobstore.tar
    • Saved the blobstore metadata to a file named metadata
  7. Elastic Runtime Backup
    • On the jumpbox, navigate to where you placed the bbr executable.  Remember that it will create a time-stamped subfolder here and dump all the backups into it.
    • Run this, replacing the values in red with the IP/FQDN of your BOSH director, password for the bbr_client account retrieved from Ops Manager, the Elastic Runtime deployment name and path to the root_ca-certificate copied from the Ops Manager:
      Deployment Pre-check

      ./bbr deployment –target 172.16.9.16 –username bbr_client –password abc123 –deployment cf-abcdef123456 –ca-cert ./root_ca_certificate pre-backup-check

    • Check that the pre-check results indicate that the director can be backed up
    • Run this to perform the backup: (same as before, just passing the “backup” sub-command instead of the “pre-backup-check’ subcommand)
      Deployment Backup

      ./bbr deployment –target 172.16.9.16 –username bbr_client –password abc123 –deployment cf-abcdef123456 –ca-cert ./root_ca_certificate backup

    • Wait a while for the backup to complete
  8. What’d it do this time?
    • Backed up the MySQL Cloud Controller Database to mysql-artifact.tar
    • Backed up uaa to uaa-0-uaa.tar (this is different from the UAA backup performed against the director)
    • Backed up the blobstore (in my case, from the internal NFS server) to nfs_server-0-blobstore-backup.tar
    • Saved the blobstore metadata to a file named metadata

 

References: