Skip to content

Instantly share code, notes, and snippets.

@clemenko
Last active July 15, 2025 03:11
Show Gist options
  • Save clemenko/00dcbb344476aafda18dbae207952d71 to your computer and use it in GitHub Desktop.
Save clemenko/00dcbb344476aafda18dbae207952d71 to your computer and use it in GitHub Desktop.

My Portworx

This is my little cheat sheet for deploying Portworx and other stuff. This includes backup and monitoring.

Docs

install you k8s of choice

I like Digital Ocean : https://github.com/clemenko/rke2

add volumes on DO if needed

I need to add volumes.

for num in 1 2 3; do
   doctl compute volume-action attach $(doctl compute volume create port$num --region nyc1 --size 60GiB | grep -v ID| awk '{print $1}') $(doctl compute droplet list | grep rke$num | awk '{print $1}')
done

Create PX StorageCluster spec

Create an account and get the spec from https://central.portworx.com/specGen

We will need 3 things. A. The operator install. B. The StorageCluster and C. A patch for the storageclass.

install portworx

# operator
kubectl apply -f 'https://install.portworx.com/3.3?comp=pxoperator&kbver=1.31.0&ns=portworx'

# StorageCluster spec
kubectl apply -f 'https://install.portworx.com/3.3?operator=true&mc=false&kbver=1.31.0&ns=portworx&b=true&iop=6&c=px-cluster1&stork=true&csi=true&mon=true&tel=false&st=k8s&promop=true'

# make a default storage class
kubectl patch storageclass px-csi-db -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'

Note you may need to either use k8s 1.31.x or add portworx.io/health-check: "skip" as an annotation in the storagecluster object.

Add monitor/gui

add portworx central

helm repo add portworx http://charts.portworx.io/ --force-update

helm upgrade -i px-central portworx/px-central --namespace px-central --create-namespace --set persistentStorage.enabled=true,persistentStorage.storageClassName="px-csi-db",service.pxCentralUIServiceType="ClusterIP",pxbackup.enabled=true,pxmonitor.enabled=true,installCRDs=true

cat <<EOF | kubectl apply -n px-central -f - 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: px-central-ui
  namespace: px-central
spec:
  rules:
  - host: px.rfed.io
    http:
      paths:
      - backend:
          service:
            name: px-central-ui
            port:
              number: 80
        path: /
        pathType: ImplementationSpecific
EOF

Add Grafana

https://docs.portworx.com/portworx-enterprise/operations/operate-kubernetes/monitoring/monitor-portworx-cluster#configure-grafana

tl:dr

export PX_URL="https://docs.portworx.com/samples/portworx-enterprise/k8s/pxc"

# create config maps
kubectl create configmap -n portworx  grafana-dashboard-config --from-literal=grafana-dashboard-config.yaml="$(curl -sk $PX_URL/grafana-dashboard-config.yaml)"
kubectl create configmap -n portworx  grafana-source-config --from-literal=grafana-dashboard-config.yaml="$(curl -sk $PX_URL/grafana-datasource.yaml)"

# dashboards
kubectl -n portworx create configmap grafana-dashboards \
--from-literal=portworx-cluster-dashboard.json="$(curl -sk $PX_URL/portworx-cluster-dashboard.json)" \
--from-literal=portworx-performance-dashboard.json="$(curl -sk $PX_URL/portworx-performance-dashboard.json)" \
--from-literal=portworx-node-dashboard.json="$(curl -sk $PX_URL/portworx-node-dashboard.json)" \
--from-literal=portworx-volume-dashboard.json="$(curl -sk $PX_URL/portworx-volume-dashboard.json)" \
--from-literal=portworx-etcd-dashboard.json="$(curl -sk $PX_URL/portworx-etcd-dashboard.json)"

# install with ingress
cat << EOF | kubectl apply -n portworx -f -
apiVersion: v1
kind: Service
metadata:
  name: grafana
  labels:
    app: grafana
spec:
  type: ClusterIP
  ports:
    - port: 3000
  selector:
    app: grafana
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: grafana
  labels:
    app: grafana
spec:
  replicas: 1
  selector:
    matchLabels:
      app: grafana
  template:
    metadata:
      labels:
        app: grafana
    spec:
      containers:
        - image: grafana/grafana
          name: grafana
          imagePullPolicy: IfNotPresent
          volumeMounts:
            - name: grafana-dash-config
              mountPath: /etc/grafana/provisioning/dashboards
            - name: dashboard-templates
              mountPath: /var/lib/grafana/dashboards
            - name: grafana-source-config
              mountPath: /etc/grafana/provisioning/datasources
      volumes:
        - name: grafana-source-config
          configMap:
            name: grafana-source-config
        - name: grafana-dash-config
          configMap:
            name: grafana-dashboard-config
        - name: dashboard-templates
          configMap:
            name: grafana-dashboards
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: grafana
spec:
  rules:
  - host: grafana.rfed.io
    http:
      paths:
      - backend:
          service:
            name: grafana
            port:
              number: 3000
        path: /
        pathType: ImplementationSpecific
EOF

Now navigate to URL you replace grafana.rfed.io with and login with admin and admin.

Air Gap

Here is the list of images : https://install.portworx.com/3.2/images?kbver=1.31.0

And for central : https://docs.portworx.com/portworx-central-on-prem/install/air-gapped-install

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