Skip to content

Commit

Permalink
Add Portworx CSI support (#1167)
Browse files Browse the repository at this point in the history
  • Loading branch information
mnaser authored May 18, 2024
1 parent 5534605 commit afcf0a1
Show file tree
Hide file tree
Showing 14 changed files with 362 additions and 1 deletion.
32 changes: 32 additions & 0 deletions doc/source/deploy/csi.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ This section details how to configure Container Storage Interfaces (CSI) for
your Kubernetes cluster that Atmosphere runs on. You will need to follow the
steps below to enable specific CSI drivers based on your storage requirements.

.. admonition:: Storing secrets securely
:class: tip

When configuring CSI drivers, it is important to store sensitive
information securely. You can use Ansible Vault to encrypt your inventory
file and store it in a secure location. For more information on how to
use Ansible Vault, refer to the `Ansible documentation <https://docs.ansible.com/ansible/latest/user_guide/vault.html>`_.

********
Ceph RBD
********
Expand Down Expand Up @@ -40,6 +48,30 @@ PowerStore configuration. This includes specifying the block protocol, which
can either be Fibre Channel (FC) or iSCSI, depending on your network
infrastructure.

********
Portworx
********

If you are using a Pure Storage array for your block storage, you can use the
Portworx CSI driver to integrate it with your Kubernetes cluster. Portworx
automatically enables a custom license when integrated with Pure Storage
arrays (FA/FB edition).

To configure the Portworx CSI driver, update your Ansible inventory as follows:

.. code-block:: yaml
csi_driver: portworx
portworx_pure_flasharray_san_type: <FILL IN> # FC or ISCSI
portworx_pure_json:
FlaskBlades: []
FlashArrays:
- MgmtEndPoint: <FILL IN>
APIToken: <FILL IN>
For more information about how the ``portworx_pure_json`` variable is used,
you can refer to the `Pure Storage FlashArray and FlashBlade JSON file reference <https://docs.portworx.com/portworx-enterprise/reference/pure-reference/pure-json-reference>`_.

********
StorPool
********
Expand Down
2 changes: 1 addition & 1 deletion playbooks/csi.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.

- hosts: controllers[0]
- hosts: controllers
gather_facts: false
become: true
roles:
Expand Down
2 changes: 2 additions & 0 deletions roles/csi/meta/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,7 @@ dependencies:
when: csi_driver == "rbd"
- role: powerstore_csi
when: csi_driver == "powerstore"
- role: portworx
when: csi_driver == "portworx"
- role: storpool_csi
when: csi_driver == "storpool"
4 changes: 4 additions & 0 deletions roles/multipathd/handlers/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,7 @@
ansible.builtin.service:
name: multipathd
state: reloaded

- name: Reconfigure "multipathd"
ansible.builtin.shell:
cmd: multipathd -k'reconfigure'
13 changes: 13 additions & 0 deletions roles/multipathd/tasks/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,18 @@
# License for the specific language governing permissions and limitations
# under the License.

- name: Add backports PPA
ansible.builtin.apt_repository:
repo: ppa:vexxhost/backports

- name: Install the multipathd package
ansible.builtin.package:
name: multipath-tools
state: latest
notify:
- Reload "multipathd"
- Reconfigure "multipathd"

- name: Install the configuration file
ansible.builtin.template:
src: multipath.conf.j2
Expand All @@ -21,3 +33,4 @@
mode: "0644"
notify:
- Reload "multipathd"
- Reconfigure "multipathd"
43 changes: 43 additions & 0 deletions roles/multipathd/templates/multipath.conf.j2
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,47 @@

defaults {
user_friendly_names {{ multipathd_user_friendly_names | bool | ternary('yes', 'no') }}
find_multipaths yes
}

devices {
device {
vendor "NVME"
product "Pure Storage FlashArray"
path_selector "queue-length 0"
path_grouping_policy group_by_prio
prio ana
failback immediate
fast_io_fail_tmo 10
user_friendly_names no
no_path_retry 0
features 0
dev_loss_tmo 60
find_multipaths yes
}
device {
vendor "PURE"
product "FlashArray"
path_selector "service-time 0"
hardware_handler "1 alua"
path_grouping_policy group_by_prio
prio alua
failback immediate
path_checker tur
fast_io_fail_tmo 10
user_friendly_names no
no_path_retry 0
features 0
dev_loss_tmo 600
find_multipaths yes
}
}

blacklist {
devnode "^pxd[0-9]*"
devnode "^pxd*"
device {
vendor "VMware"
product "Virtual disk"
}
}
16 changes: 16 additions & 0 deletions roles/portworx/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Copyright (c) 2024 VEXXHOST, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

# portworx_pure_flasharray_san_type:
# portworx_pure_json:
33 changes: 33 additions & 0 deletions roles/portworx/meta/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# Copyright (c) 2024 VEXXHOST, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

galaxy_info:
author: VEXXHOST, Inc.
description: Ansible role for Portworx
license: Apache-2.0
min_ansible_version: 5.5.0
standalone: false
platforms:
- name: EL
versions:
- "8"
- "9"
- name: Ubuntu
versions:
- focal
- jammy

dependencies:
- role: defaults
- role: multipathd
63 changes: 63 additions & 0 deletions roles/portworx/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
# Copyright (c) 2024 VEXXHOST, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

- name: Detect if InitiatorName is set
ansible.builtin.slurp:
src: /etc/iscsi/initiatorname.iscsi
register: portworx_iscsi_initiatorname

- name: Configure InitiatorName
when: "'InitiatorName' not in portworx_iscsi_initiatorname.content | b64decode"
block:
- name: Generate a new InitiatorName
ansible.builtin.shell:
cmd: iscsi-iname
register: portworx_iscsi_iname

- name: Write the new InitiatorName
ansible.builtin.copy:
content: "InitiatorName={{ portworx_iscsi_iname.stdout }}"
dest: /etc/iscsi/initiatorname.iscsi
owner: root
group: root
mode: "0644"

- name: Install Portworx
run_once: true
kubernetes.core.k8s:
state: present
template:
- portworx.yml
- config.yml

- name: Wait till the CRDs are created
run_once: true
kubernetes.core.k8s_info:
api_version: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
name: storageclusters.core.libopenstorage.org
# NOTE(mnaser): Portworx operator creates the CRDs for the cluster
# so we need to make sure they're created before we proceed.
retries: 60
delay: 5
register: _result
until: _result.resources | length > 0

- name: Create Portworx Storage Cluster
run_once: true
kubernetes.core.k8s:
state: present
template:
- storage_cluster.yml
- storage_class.yml
8 changes: 8 additions & 0 deletions roles/portworx/templates/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
apiVersion: v1
kind: Secret
metadata:
name: px-pure-secret
namespace: portworx
stringData:
pure.json: '{{ portworx_pure_json | to_json }}'
80 changes: 80 additions & 0 deletions roles/portworx/templates/portworx.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# SOURCE: https://install.portworx.com/?comp=pxoperator

apiVersion: v1
kind: ServiceAccount
metadata:
name: portworx-operator
namespace: kube-system
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: portworx-operator
rules:
- apiGroups: ["*"]
resources: ["*"]
verbs: ["*"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: portworx-operator
subjects:
- kind: ServiceAccount
name: portworx-operator
namespace: kube-system
roleRef:
kind: ClusterRole
name: portworx-operator
apiGroup: rbac.authorization.k8s.io
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: portworx-operator
namespace: kube-system
spec:
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
type: RollingUpdate
replicas: 1
selector:
matchLabels:
name: portworx-operator
template:
metadata:
labels:
name: portworx-operator
spec:
containers:
- name: portworx-operator
imagePullPolicy: Always
image: portworx/px-operator:23.10.5
command:
- /operator
- --verbose
- --driver=portworx
- --leader-elect=true
env:
- name: OPERATOR_NAME
value: portworx-operator
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: "name"
operator: In
values:
- portworx-operator
topologyKey: "kubernetes.io/hostname"
serviceAccountName: portworx-operator
# NOTE(mnaser): Add this to keep running on control plane
nodeSelector:
openstack-control-plane: enabled
10 changes: 10 additions & 0 deletions roles/portworx/templates/storage_class.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: general
annotations:
storageclass.kubernetes.io/is-default-class: "true"
provisioner: pxd.portworx.com
parameters:
backend: pure_block
allowVolumeExpansion: true
Loading

0 comments on commit afcf0a1

Please sign in to comment.