ARTIFACTORY: Helm Quick Start Guide

Paul Pan
2022-01-13 21:28

What will you get?

User-added image

This example will demonstrate how to create a production ready artifactory helm deployment. We will demonstrate the installation on a GKE cluster. All commands are given is helm3+ format. 

For advanced users, please also check out our advance user guide for questions that’s not covered in this quick starter guide.

Prerequisites

Source Code and Releases

Artifactory-HA charts can be found on github or chartcenter

Please refer to the release notes for the default Artifactory version of each chart version and our official documents for the latest update. 

Note, from chart version 107.18.6 and above, the number after chart version 107.x is the default artifactory version of that chart. So chart version 107.18.6 comes with artifactory 7.18.6.

Environment Details

In the table below we will list the environment details for the sample deployment we are going to demonstrate. You can find more information about the system resources requirements here.

Environment details

Aspect

Detail

Versions

107.21.12

Resources

  • 2-6 cpu

  • 4GI – 8GI memory

  • 4 – 6 GI JVM memory

  • 3 node cluster with one node not serving traffic

Network

  • Public Load Balancer ( L4 )

  • SSL is terminate with nginx deployment

Persistence

Cloud file system with S3

Database

Bundled Postgresql Database

License

3 enterprise/enterprise plus licenses are needed

We will be deploying the release under namespace: artifactory-ha and as release-name: artifactory-ha

Steps to Install

Get the chart

Before installing JFrog helm charts, you need to add the JFrog helm repository to your helm client

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

Now, update the repository.

$ helm repo update

Prepare Keys and Secrets

Master Key and Join Key

Artifactory will generate the following keys. However, it’s mandatory for a fresh install on the production environment or you will be using the default dummy key values. Make sure you save the key values. 

Create a unique Master Key

# Create a key
export MASTER_KEY=$(openssl rand -hex 32)
echo ${MASTER_KEY}

Create a “masterkey-secret” to hold the value

$ kubectl create secret generic masterkey-secret --from-literal=master-key=${MASTER_KEY}

Create a unique Join Key

By default the chart will also set a Join Key value for you. For a production environment we highly recommend setting a unique value.

# Create a join key
export JOIN_KEY=$(openssl rand -hex 32)
echo ${JOIN_KEY}

Create a secret containing the key. The key in the secret must be named join-key

$ kubectl create secret generic joinkey-secret --from-literal=join-key=${JOIN_KEY}

Database secret

Database credentials can also be supplied with a secret.
For this release, we are installing a bundled postgresql, so we will just pass the credentials with properties

$ export POSTGRES_USERNAME=artifactory
$ export POSTGRES_PASSWORD=password
# Pass the value to helm
$ helm upgrade --install <myrelease> --namespace artifactory-ha jfrog/artifactory-ha --set postgresql.postgresqlPassword=${POSTGRES_PASSWORD} --set postgresql.postgresqlUsername=${POSTGRES_USERNAME}

We can also let the release generates a random password and retrieve it from a secret.

Tls secret

There are many ways to expose artifactory service and set up ssl connections. For this release, we will deploy the bundled nginx deployment and expose it with loadBalancer service type. We will also use nginx to terminate ssl connections and then forward traffic to artifactory service. So we will put the certificate in a tls secret first. 

$ kubectl create secret tls artifactory-tls --cert=path/to/tls.cert --key=path/to/tls.key

License secret

For activating Artifactory HA, you must install appropriate licenses. 

In this example, we will pass license as a secret: 
1. Prepare a text file with the license(s) written in it. If writing multiple licenses (must be in the same file), it's important to put **two new lines between each license block**!
2. Create the Kubernetes secret (assuming the local license file is 'art.lic')
 

$ kubectl create secret generic artifactory-cluster-license -n artifactory-ha --from-file=./art.lic# Pass the license to helm
helm upgrade --install artifactory-ha --set artifactory.license.secret=artifactory-cluster-license,artifactory.license.dataKey=art.lic

NOTE. This method is relevant for initial deployment only! Once Artifactory is deployed, you should not keep passing these parameters as the license is already persisted into Artifactory's storage (they will be ignored). Updating the license should be done via Artifactory UI or REST API after initial deployment or managed through a license bucket.

Resources:

In this sample deployment, we increased the minimum cpu and memory request to 2cpu and 4G memory with an upper limit of 6cpu and 8G memory for each artifactory node. We also increased Jvm memory to 4g xms and 6g xmx. For detailed system resources recommendation, please refer to here

The default properties that artifactor use may not be fully utilizing the available system resources. If you find artifactory underperformed with enough physical resources please check out the tuning section in the glossary. 

Scalability is controlled by artifactory.node.replicaCount. We kept the default value 2, which results in a 3 node cluster. 

You can test the properties with the following dry-run installation:$ helm install artifactory-ha \
--set artifactory.primary.resources.requests.cpu="2" \
--set artifactory.primary.resources.limits.cpu="6" \
--set artifactory.primary.resources.requests.memory="4Gi" \
--set artifactory.primary.resources.limits.memory="8Gi" \
--set artifactory.primary.javaOpts.xms="4g" \
--set artifactory.primary.javaOpts.xmx="6g" \
--set artifactory.node.resources.requests.cpu="2" \
--set artifactory.node.resources.limits.cpu="6" \
--set artifactory.node.resources.requests.memory="4Gi" \
--set artifactory.node.resources.limits.memory="8Gi" \
--set artifactory.node.javaOpts.xms="4g" \
--set artifactory.node.javaOpts.xmx="6g" \
--set artifactory.node.replicaCount=2\
--namespace artifactory-ha jfrog/artifactory-ha --version 107.21.12 --dry-run
We will add the properties above to a values.yaml.artifactory:
primary:
resources:
requests:
memory: "4Gi"
cpu: "2"
limits:
memory: "8Gi"
cpu: "6"
javaOpts:
xms: "4g"
xmx: "6g"
node:
replicaCount: 2
resources:
requests:
memory: "4Gi"
cpu: "2"
limits:
memory: "8Gi"
cpu: "6"
javaOpts:
xms: "4g"
xmx: "6g"

Persistence

Default installation will dynamically provision PVC for each artifactory pod. For Artifactory HA the filestore will share the storage among the local data folder on each node. 

In this example, we will be configuring cloud s3 storage with explicit credentials. You may also checkout the filestore provider documents for all other options. 
 $ helm install artifactory-ha \
--set artifactory.persistence.type=aws-s3-v3 \
--set artifactory.persistence.awsS3V3.identity=yourIdentity\
--set artifactory.persistence.awsS3V3.credential=yourIdentity\
--set artifactory.persistence.awsS3V3.region=usw2\
--set artifactory.persistence.awsS3V3.bucketName=artifactory-aws \
--set artifactory.persistence.awsS3V3.path=artifactory/filestore\
--set artifactory.persistence.awsS3.endpoint=AWS_S3_ENDPOINT \
--namespace artifactory-ha jfrog/artifactory-ha --version 107.21.12 --dry-run
We will add the properties above to a values.yaml artifactory:
persistence:
type: aws-s3-v3
awsS3V3:
identity: yourIdentity
credential: yourIdentity
region: usw2
bucketName: artifactory-aws
path: artifactory/filestore
Endpoint: AWS_S3_ENDPOINT

Database:

Default deployment will install a bundled postgresql database. For production, we suggested using an external postgresql database. In this example, we will be deploying with a bundled postgresql database. For other database choice, please refer to the external database documentation.$ helm install artifactory-ha \
--set postgresql.enabled=true \
--set postgresql.postgresqlUsername=artifactory \
--set postgresql.postgresqlPassword=password \
--set postgresql.postgresqlDatabase=artifactory\
--set postgresql.postgresqlExtendedConf.maxConnections=1000\
--namespace artifactory-ha jfrog/artifactory-ha --version 107.21.12 --dry-run

For external database settings, please refer to the external database setting link at the end of this instruction. 

We will add the properties above to a values.yaml postgresql:
enabled: true
postgresqlUsername: artifactory
postgresqlPassword: password
postgresqlDatabase: artifactory
postgresqlExtendedConf:
maxConnections: 1000

Network:

For this example we expose artifactory service with an nginx deployment and an Load Balancer service. 

There are many ways to terminate ssl on kubernetes including ingress, L7 load balancing. For this release, because we will be deploying on GKE with loadBalancer type, GKE will allocate the LB for us. However, since the load balancer is a layer-4 loadBalancer only, thus we will not be terminating the ssl on LB but on our nginx deployment. $ helm install artifactory-ha \
--set nginx.enabled=false \
--set nginx.tlsSecretName=artifactory-tls \
--set nginx.replicaCount: 2 \
--set nginx.resources.requests.cpu="100m" \
--set nginx.resources.limits.cpu="250m" \
--set nginx.resources.requests.memory="250Mi" \
--set nginx.resources.limits.memory="500Mi" \
--namespace artifactory-ha jfrog/artifactory-ha --version 107.21.12 --dry-run
We will add the properties above to a values.yaml nginx:
enabled: true
tlsSecretName: artifactory-tls
replicaCount: 2
resources:
requests:
cpu: 100m
memory: 250Mi
limits:
cpu: 250m
memory: 500Mi

Install your releases:

Now that we have all the properties in place, we are ready to deploy
Here are all the env variables we will be passing to chart:

$ env
POSTGRES_USERNAME=artifactory
POSTGRES_PASSWORD=password

Here is the final values.yaml file:

global:
joinKeySecretName: joinkey-secret
masterKeySecretName: masterkey-secret
artifactory:
persistence:
type: aws-s3-v3
awsS3V3:
identity: yourIdentity
credential: yourIdentity
region: usw2
bucketName: artifactory-aws
path: artifactory/filestore
Endpoint: AWS_S3_ENDPOINT
primary:
resources:
requests:
memory: "4Gi"
cpu: "2"
limits:
memory: "8Gi"
cpu: "6"
javaOpts:
xms: "4g"
xmx: "6g"
node:
replicaCount: 2
resources:
requests:
memory: "4Gi"
cpu: "2"
limits:
memory: "8Gi"
cpu: "6"
javaOpts:
xms: "4g"
xmx: "6g"
postgresql:
enabled: true
postgresqlUsername: artifactory
postgresqlPassword: password
postgresqlDatabase: artifactory
postgresqlExtendedConf:
maxConnections: 1000
nginx:
enabled: true
tlsSecretName: artifactory-tls
replicaCount: 2
resources:
requests:
cpu: 100m
memory: 250Mi
limits:
cpu: 250m
memory: 500Mi

Let’s Go:

$ helm install artifactory-ha \
--set artifactory.license.secret=artifactory-cluster-license \
--set artifactory.license.dataKey=art.lic \
--set postgresql.postgresqlPassword=${POSTGRES_PASSWORD} \
--set postgresql.postgresqlUsername=${POSTGRES_USERNAME} \
-f values.yaml \
--namespace artifactory-ha jfrog/artifactory-ha --version 107.21.12

Deleting Installation

If you ever need to delete the current release, you can do

helm delete artifactory-ha --namespace artifactory-ha

However, this will not remove any persistent volumes. You need to explicitly remove the pvc if you intend for a fresh start.

kubectl delete pvc -l release=artifactory-ha -n artifactory-ha
kubectl delete pvc -l app.kubernetes.io/instance=artifactory-ha -n artifactory-ha

Upgrade Artifactory

It’s recommended to pass all the values in the previous release explicitly when running the upgrade command. This is to avoid falling back to any default values. Pay extreme attention to the secret you created, as failing to reference those in an upgrade action could result in new different values generated and breaking artifactory. It'd be difficult to recover from such a case. 

Updates minor version or updating values.yaml

For regular upgrade command when you just want to upgrade values:helm upgrade --install artifactory-ha \
--set databaseUpgradeReady=true \
--set postgresql.postgresqlPassword=${POSTGRES_PASSWORD} \
--set postgresql.postgresqlUsername=${POSTGRES_USERNAME} \
-f values-new.yaml \
--namespace artifactory-ha jfrog/artifactory-ha --version 107.21.12

If you want to upgrade the artifactory version but the version does not come default with the current chart version. Note that you must always pass the version explicitly after doing this to avoid falling back to an old version:

helm upgrade --install artifactory-ha \
--set databaseUpgradeReady=true \
--set postgresql.postgresqlPassword=${POSTGRES_PASSWORD} \
--set postgresql.postgresqlUsername=${POSTGRES_USERNAME} \
--set global.versions.artifactory= 7.21.13\
-f values.yaml \
--namespace artifactory-ha jfrog/artifactory-ha --version 107.21.12

Updates chart version:

helm upgrade --install artifactory-ha \
--set databaseUpgradeReady=true \
--set postgresql.postgresqlPassword=${POSTGRES_PASSWORD} \
--set postgresql.postgresqlUsername=${POSTGRES_USERNAME} \
-f values.yaml \
--namespace artifactory-ha jfrog/artifactory-ha --version 107.24.3

Always check upgrade_notes first for any major version jump.

It’s recommended to upgrade the chart version when you are upgrading Artifactory to a version that comes default to a new chart version.

Note: 
1. We are no longer passing in license information as this is an upgrade. 
2. databaseUpgradeReady flag is only needed when you are using a bundled postgresql chart. This is to force you to take cautions and check if any unwanted property change is introduced to the bundled database. Consider using the –dry-run option to check if there’s any unexpected change introduced to the bundled postgresql db. 
3. If you are upgrading from a chart version (< 4.x.x) that has postgresql.image.tag of 9.x or 10.x or 12.x, make sure to pass the current postgresql.image.tag and set databaseUpgradeReady=true

Glossary

– Tuning Artifactory – https://jfrog.com/knowledge-base/how-do-i-tune-artifactory-for-heavy-loads/
– System Requirements: https://www.jfrog.com/confluence/display/JFROG/System+Requirements
– Filestore – https://www.jfrog.com/confluence/display/JFROG/Configuring+the+Filestore
– External Database – https://www.jfrog.com/confluence/display/JFROG/Configuring+the+Database
– Chart Source Code – https://github.com/jfrog/charts/tree/master/stable/artifactory-ha
– Official Artifactory Helm documents – https://www.jfrog.com/confluence/display/JFROG/Installing+Artifactory#InstallingArtifactory-HelmHAInstallation
– Helm charts for Advanced users – https://www.jfrog.com/confluence/display/JFROG/Helm+Charts+for+Advanced+Users
– Kubernetes Load Balancer Service –
https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/
– Kubernetes Default Storage Class
https://kubernetes.io/docs/tasks/administer-cluster/change-default-storage-class/
– Kubernetes dynamic provision PV –
https://kubernetes.io/docs/concepts/storage/dynamic-provisioning/