Categories
gcp Kubernetes

Artifactory HA with Google Cloud Storage & Google SQL

I will be using helm to install Artifactory High Availability onto a GKE cluster.

Goal

  • Install using helm 3
  • Chart version 2.0.19, App version 7.2.1 (Artifactory 7)
  • Google Cloud Storage (bucket) — artifacts
  • Google SQL — application database
  • Nginx Internal Load Balancer (default is external)

Example Diagram

Google Cloud Storage

Go to https://console.cloud.google.com/storage/settings and click the Interoperability tab.

Storage → Settings

Scroll down and click Create a key. This will provide you with an Access key and Secret.

GCP_ID=[ACCESS_KEY]
GCP_KEY=[SECRET]

Helm snippet

This will create a bucket called artifactory-ha.

...
  --set artifactory.persistence.type=google-storage \
  --set artifactory.persistence.googleStorage.bucketName=artifactory-ha \
  --set artifactory.persistence.googleStorage.identity=${GCP_ID} \
  --set artifactory.persistence.googleStorage.credential=${GCP_KEY} \
...

Google SQL

Create a Google SQL PostgreSQL database

Choose PostgreSQL.

Fill out the necessary fields.

I recommend you choose High availability (regional) for production environments.

Click Create.

Create a user

I created a user called artifactory-ha.

Create a database

I created a database called artifactory-ha.

Create a secret

Create a secret including your database username, password, and URL.

DB_USER=[DATABASE_USERNAME]
DB_PASSWORD='[DATABASE_PASSWORD]'
DB_URL=jdbc:postgresql://${DB_HOST}:${DB_PORT}/${DATABASE_NAME}

# Example
DB_USER=artifactory-ha
DB_PASSWORD='SuperSecretPassword'
DB_URL=jdbc:postgresql://XXX.XXX.XXX.XXX:5432/artifactory-ha

kubectl create secret generic artifactory-ha-db \
  --from-literal=user=${DB_USER} \
  --from-literal=password=${DB_PASSWORD} \
  --from-literal=url=${DB_URL}

Helm snippet

...
  --set postgresql.enabled=false \
  --set database.type=postgresql \
  --set database.driver=org.postgresql.Driver \
  --set database.secrets.url.name=artifactory-ha-db \
  --set database.secrets.url.key=url \
  --set database.secrets.user.name=artifactory-ha-db \
  --set database.secrets.user.key=user \
  --set database.secrets.password.name=artifactory-ha-db \
  --set database.secrets.password.key=password \
...

Master Key

Create a unique Master Key secret

export MASTER_KEY=$(openssl rand -hex 32)
echo ${MASTER_KEY}

# Create a secret containing the key. The key in the secret must be named master-key
kubectl create secret generic artifactory-ha-master-key --from-literal=master-key=${MASTER_KEY}

Helm snippet

...
  --set artifactory.masterKeySecretName=artifactory-ha-master-key \
...

NGINX Load Balancer

I chose to change the NGINX artifactory-ha-nginx service Load Balancer type to internal, instead of using the default external.

Helm snippet

...
  --set nginx.service.annotations."cloud\.google\.com/load-balancer-type"=Internal \
...

NGINX Deployment

Scale the NGINX deployment from 1 (default) to 3.

Helm snippet

...
  --set nginx.replicaCount=3 \
...

Headers

Because Artifactory will be behind a proxy, we need forward headers.

Helm snippet

...
  --set-string controller.config.use-forwarded-headers=true \
...

Install

Add repo

helm repo add jfrog https://charts.jfrog.io

Update repo

helm repo update

Add recommended resources and limits

I will be using the values-large.yaml option as the recommended resources and limits. You can choose from values-small.yaml, values-medium.yaml or values-large.yaml.

Download values-large.yaml.

wget https://raw.githubusercontent.com/jfrog/charts/master/stable/artifactory-ha/values-large.yaml

Install chart

helm install artifactory-ha \
  --set initContainers.resources.requests.cpu="10m" \
  --set initContainers.resources.limits.cpu="250m" \
  --set initContainers.resources.requests.memory="64Mi" \
  --set initContainers.resources.limits.memory="128Mi" \
  --set nginx.resources.requests.cpu="100m" \
  --set nginx.resources.limits.cpu="250m" \
  --set nginx.resources.requests.memory="250Mi" \
  --set nginx.resources.limits.memory="500Mi" \
  --set artifactory.persistence.type=google-storage \
  --set artifactory.persistence.googleStorage.bucketName=artifactory-ha \
  --set artifactory.persistence.googleStorage.identity=${GCP_ID} \
  --set artifactory.persistence.googleStorage.credential=${GCP_KEY} \
  --set postgresql.enabled=false \
  --set database.type=postgresql \
  --set database.driver=org.postgresql.Driver \
  --set database.secrets.url.name=artifactory-ha-db \
  --set database.secrets.url.key=url \
  --set database.secrets.user.name=artifactory-ha-db \
  --set database.secrets.user.key=user \
  --set database.secrets.password.name=artifactory-ha-db \
  --set database.secrets.password.key=password \
  --set artifactory.masterKeySecretName=artifactory-ha-master-key \
  --set nginx.service.annotations."cloud\.google\.com/load-balancer-type"=Internal \
  --set nginx.replicaCount=3 \
  --set-string controller.config.use-forwarded-headers=true \
  -f values-large.yaml \
  jfrog/artifactory-ha --version 2.0.19

Output.

NAME: artifactory-ha
 LAST DEPLOYED: Fri Feb 28 07:45:43 2020
 NAMESPACE: itsmetommy
 STATUS: deployed
 REVISION: 1
 TEST SUITE: None
 NOTES:
 Congratulations. You have just deployed JFrog Artifactory HA!
 SETUP:
 Get the Artifactory IP and URL
 NOTE: It may take a few minutes for the LoadBalancer public IP to be available!
 You can watch the status of the service by running 'kubectl get svc -w artifactory-ha-nginx'
 export SERVICE_IP=$(kubectl get svc --namespace itsmetommy artifactory-ha-nginx -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
 echo http://$SERVICE_IP/
 Open Artifactory in your browser
 Default credential for Artifactory:
 user:     admin
 password: password
 Add HA licenses to activate Artifactory HA through the Artifactory UI
 NOTE: Each Artifactory node requires a valid license. See https://www.jfrog.com/confluence/display/RTF/HA+Installation+and+Setup for more details. 

Watch your pods.

watch kubectl get pods -l app=artifactory-ha

It should take ~6 minutes for your pods to all be in a running state.

NAME                                      READY   STATUS    RESTARTS   AGE
artifactory-ha-artifactory-ha-member-0    1/1     Running   0          5m59s
artifactory-ha-artifactory-ha-member-1    1/1     Running   0          3m32s
artifactory-ha-artifactory-ha-member-2    1/1     Running   0          2m2s
artifactory-ha-artifactory-ha-primary-0   1/1     Running   0          5m59s
artifactory-ha-nginx-7d794d69d9-drwg5     1/1     Running   0          5m59s
artifactory-ha-nginx-7d794d69d9-n7p89     1/1     Running   0          5m59s
artifactory-ha-nginx-7d794d69d9-xb9nz     1/1     Running   0          5m59s

Access Artifactory

Port forward

kubectl port-forward svc/artifactory-ha-nginx 5000:80

Open browser

open http://localhost:5000/ui/login/

Uninstall

helm uninstall artifactory-ha && sleep 90 && kubectl delete pvc -l app=artifactory-ha

Delete storage bucket and SQL database.

gsutil rm -r gs://artifactory-ha
gcloud sql instances delete artifactory-ha
Comments