Skip to content

Instantly share code, notes, and snippets.

@clemenko
Last active April 15, 2025 14:41
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

You will get an install command like:

# kubectl apply -f 'https://install.portworx.com/3.2?operator=true&mc=false&kbver=1.31.0&ns=portworx&b=true&iop=6&c=px-cluster-b6440f55-b41b-46b4-bcd8-303a3f8f35e2&stork=true&csi=true&mon=true&tel=false&st=k8s&promop=true'

Or you can use the spec below.

install portworx

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

# spec
cat << EOF | kubectl apply -n portworx  -f -
kind: StorageCluster
apiVersion: core.libopenstorage.org/v1
metadata:
  name: px-cluster
spec:
  image: portworx/oci-monitor:3.2.1.2
  imagePullPolicy: Always
  kvdb:
    internal: true
  storage:
    useAll: true
  secretsProvider: k8s
  stork:
    enabled: true
    args:
      webhook-controller: "true"
  autopilot:
    enabled: true
  csi:
    enabled: true
  monitoring:
    telemetry:
      enabled: false
    prometheus:
      enabled: true
      exportMetrics: true
EOF

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

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-db",service.pxCentralUIServiceType="ClusterIP",pxbackup.enabled=true,pxmonitor.enabled=false,installCRDs=true

cat <<EOF | kubectl apply -n px-central -f - 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: px-central-ui
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
          resources:
            limits:
              cpu: 100m
              memory: 100Mi
            requests:
              cpu: 100m
              memory: 100Mi
          readinessProbe:
            httpGet:
              path: /login
              port: 3000
          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: v1
kind: Service
metadata:
  name: grafana
spec:
  ports:
    - port: 3000
      protocol: TCP
      targetPort: 3000
  selector:
    app: grafana
  sessionAffinity: None
  type: ClusterIP
---
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