.. _minio-k8s-deploy-operator-helm:
=========================
Deploy Operator With Helm
=========================
.. default-domain:: minio
.. contents:: Table of Contents
:local:
:depth: 2
Overview
--------
Helm is a tool for automating the deployment of applications to Kubernetes clusters.
A `Helm chart `__ is a set of YAML files, templates, and other files that define the deployment details.
The following procedure uses a Helm Chart to install the :ref:`MinIO Kubernetes Operator ` to a Kubernetes cluster.
Prerequisites
-------------
To install the Operator with Helm you will need the following:
* An existing Kubernetes cluster.
* The ``kubectl`` CLI tool on your local host, the same version as the cluster.
* `Helm `__ version 3.8 or greater.
* `yq `__ version 4.18.1 or greater.
* Access to run ``kubectl`` commands on the cluster from your local host.
For more about Operator installation requirements, including supported Kubernetes versions and TLS certificates, see the :ref:`Operator deployment prerequisites `.
This procedure assumes familiarity the with referenced Kubernetes concepts and utilities.
While this documentation may provide guidance for configuring or deploying Kubernetes-related resources on a best-effort basis, it is not a replacement for the official :kube-docs:`Kubernetes Documentation <>`.
Procedure
---------
Install Operator
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#. Download the Helm charts
On your local host, download the Operator and Tenant Helm charts to a convenient directory:
.. code-block:: shell
:class: copyable
:substitutions:
curl -O https://raw.githubusercontent.com/minio/operator/master/helm-releases/operator-|operator-version-stable|.tgz
curl -O https://raw.githubusercontent.com/minio/operator/master/helm-releases/tenant-|operator-version-stable|.tgz
Each chart contains a ``values.yaml`` file you can customize to suit your needs.
For example, you may wish to change the MinIO root user credentials or the Tenant name.
For more about customizations, see `Helm Charts `__.
#. Deploy Operator
The following Helm command deploys the MinIO Operator using the downloaded chart:
.. code-block:: shell
:class: copyable
:substitutions:
helm install \
--namespace minio-operator \
--create-namespace \
minio-operator operator-|operator-version-stable|.tgz
#. Configure Operator
A. Create the YAML configuration files
Use ``kubectl`` and ``yq`` to create the following files:
* service.yaml:
.. code-block:: shell
:class: copyable
kubectl get service console -n minio-operator -o yaml > service.yaml
yq e -i '.spec.type="NodePort"' service.yaml
yq e -i '.spec.ports[0].nodePort = PORT_NUMBER' service.yaml
Replace ``PORT_NUMBER`` with the port on which to serve the Operator GUI.
The file contents resemble the following:
.. dropdown:: Example ``service.yaml`` file
.. code-block:: yaml
apiVersion: v1
kind: Service
metadata:
annotations:
meta.helm.sh/release-name: minio-operator
meta.helm.sh/release-namespace: minio-operator
creationTimestamp: "2023-05-11T14:57:42Z"
labels:
app.kubernetes.io/instance: minio-operator
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: operator
app.kubernetes.io/version: v5.0.4
helm.sh/chart: operator-5.0.4
name: console
namespace: minio-operator
resourceVersion: "907"
uid: 9297fd97-806a-4715-8bd5-a1f6103149a8
spec:
clusterIP: 10.96.157.135
clusterIPs:
- 10.96.157.135
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- name: http
port: 9090
protocol: TCP
targetPort: 9090
nodePort: 30080
- name: https
port: 9443
protocol: TCP
targetPort: 9443
selector:
app.kubernetes.io/instance: minio-operator-console
app.kubernetes.io/name: operator
sessionAffinity: None
type: NodePort
status:
loadBalancer: {}
* operator.yaml:
.. code-block:: shell
:class: copyable
kubectl get deployment minio-operator -n minio-operator -o yaml > operator.yaml
yq -i -e '.spec.replicas |= 1' operator.yaml
The file contents resemble the following:
.. dropdown:: Example ``operator.yaml`` file
.. code-block:: shell
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "1"
meta.helm.sh/release-name: minio-operator
meta.helm.sh/release-namespace: minio-operator
creationTimestamp: "2023-05-11T14:57:43Z"
generation: 1
labels:
app.kubernetes.io/instance: minio-operator
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: operator
app.kubernetes.io/version: v5.0.4
helm.sh/chart: operator-5.0.4
name: minio-operator
namespace: minio-operator
resourceVersion: "947"
uid: f395171e-d17c-4645-9854-3dd92f23be59
spec:
progressDeadlineSeconds: 600
replicas: 1
revisionHistoryLimit: 10
selector:
matchLabels:
app.kubernetes.io/instance: minio-operator
app.kubernetes.io/name: operator
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
app.kubernetes.io/instance: minio-operator
app.kubernetes.io/name: operator
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: name
operator: In
values:
- minio-operator
topologyKey: kubernetes.io/hostname
containers:
- args:
- controller
image: quay.io/minio/operator:v5.0.4
imagePullPolicy: IfNotPresent
name: operator
resources:
requests:
cpu: 200m
ephemeral-storage: 500Mi
memory: 256Mi
securityContext:
runAsGroup: 1000
runAsNonRoot: true
runAsUser: 1000
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext:
fsGroup: 1000
runAsGroup: 1000
runAsNonRoot: true
runAsUser: 1000
serviceAccount: minio-operator
serviceAccountName: minio-operator
terminationGracePeriodSeconds: 30
status:
conditions:
- lastTransitionTime: "2023-05-11T14:57:43Z"
lastUpdateTime: "2023-05-11T14:57:43Z"
message: Deployment does not have minimum availability.
reason: MinimumReplicasUnavailable
status: "False"
type: Available
- lastTransitionTime: "2023-05-11T14:57:43Z"
lastUpdateTime: "2023-05-11T14:57:44Z"
message: ReplicaSet "minio-operator-674cf5cf78" is progressing.
reason: ReplicaSetUpdated
status: "True"
type: Progressing
observedGeneration: 1
replicas: 2
unavailableReplicas: 2
updatedReplicas: 2
* console-secret.yaml:
Create a ``console-secret.yaml`` file with the following contents:
.. code-block:: shell
:class: copyable
apiVersion: v1
kind: Secret
metadata:
name: console-sa-secret
namespace: minio-operator
annotations:
kubernetes.io/service-account.name: console-sa
type: kubernetes.io/service-account-token
B. Apply the configuration to your deployment with ``kubectl apply``:
.. code-block:: shell
:class: copyable
kubectl apply -f service.yaml
kubectl apply -f operator.yaml
kubectl apply -f console-secret.yaml
#. To verify the installation, run the following command:
.. code-block:: shell
:class: copyable
kubectl get all --namespace minio-operator
If you initialized the Operator with a custom namespace, replace
``minio-operator`` with that namespace.
The output resembles the following:
.. code-block:: shell
NAME READY STATUS RESTARTS AGE
pod/console-59b769c486-cv7zv 1/1 Running 0 81m
pod/minio-operator-7976b4df5b-rsskl 1/1 Running 0 81m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/console ClusterIP 10.105.218.94 9090/TCP,9443/TCP 81m
service/operator ClusterIP 10.110.113.146 4222/TCP,4233/TCP 81m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/console 1/1 1 1 81m
deployment.apps/minio-operator 1/1 1 1 81m
NAME DESIRED CURRENT READY AGE
replicaset.apps/console-59b769c486 1 1 1 81m
replicaset.apps/minio-operator-7976b4df5b 1 1 1 81m
#. Connect to the Operator Console
To connect to the Console, first retrieve the JSON Web Token (JWT) for your deployment and then forward the Console port.
A. Retrieve the JWT
The Operator Console uses a JWT to authenticate and log in.
The following commands retrieve the token for your deployment:
.. code-block:: shell
:class: copyable
SA_TOKEN=$(kubectl -n minio-operator get secret console-sa-secret -o jsonpath="{.data.token}" | base64 --decode)
echo $SA_TOKEN
B. Forward the Operator Console port to allow access from another host.
The following command temporarily forwards the Console to port 9090:
.. code-block:: shell
:class: copyable
kubectl --namespace minio-operator port-forward svc/console 9090:9090
This command forwards the pod port ``9090`` to the matching port on the local machine while active in the shell.
The ``kubectl port-forward`` command only functions while active in the shell session.
Terminating the session closes the ports on the local machine.
C. Access the Console by navigating to ``http://localhost:9090`` in a browser and login with the JWT.
.. note::
Some Kubernetes deployments may experience issues with timeouts during port-forwarding operations with the Operator Console.
Select the :guilabel:`NodePorts` section to view instructions for alternative access.
You can alternatively configure your preferred Ingress to grant access to the Operator Console service.
See https://github.com/kubernetes/kubectl/issues/1368 for more information.
.. dropdown:: NodePorts
Use the following command to identify the :kube-docs:`NodePorts ` configured for the Operator Console.
If your local host does not have the ``jq`` utility installed, you can run the first command and locate the ``spec.ports`` section of the output.
.. code-block:: shell
:class: copyable
kubectl get svc/console -n minio-operator -o json | jq -r '.spec.ports'
The output resembles the following:
.. code-block:: json
[
{
"name": "http",
"nodePort": 31055,
"port": 9090,
"protocol": "TCP",
"targetPort": 9090
},
{
"name": "https",
"nodePort": 31388,
"port": 9443,
"protocol": "TCP",
"targetPort": 9443
}
]
Use the ``http`` or ``https`` port depending on whether you deployed the Operator with Console TLS enabled via :mc-cmd:`kubectl minio init --console-tls`.
Append the ``nodePort`` value to the externally-accessible IP address of a worker node in your Kubernetes cluster.
Deploy a Tenant
~~~~~~~~~~~~~~~
You can deploy a MinIO Tenant using either the :ref:`Operator Console ` or Helm.
To deploy a Tenant with the Console, see :ref:`Deploy and Manage MinIO Tenants `.
To deploy a Tenant with Helm:
#. The following Helm command creates a MinIO Tenant using the standard chart:
.. code-block:: shell
:class: copyable
:substitutions:
helm install \
--namespace Tenant-ns \
--create-namespace \
Tenant-ns Tenant-|operator-version-stable|.tgz
To deploy more than one Tenant, create a Helm chart with the details of the new Tenant and repeat the deployment steps.
Redeploying the same chart updates the previously deployed Tenant.
#. Expose the Tenant Console port
Use ``kubectl port-forward`` to temporarily forward traffic from the MinIO pod to your local machine:
.. code-block:: shell
:class: copyable
kubectl --namespace Tenant-ns port-forward svc/myminio-console 9443:9443
.. note::
To configure long term access to the pod, configure :kube-docs:`Ingress ` or similar network control components within Kubernetes to route traffic to and from the pod.
Configuring Ingress is out of the scope for this documentation.
#. Login to the MinIO Console
Access the Tenant's :ref:`minio-console` by navigating to ``http://localhost:9443`` in a browser.
Log in to the Console with the default credentials ``myminio | minio123``.
#. Expose the Tenant MinIO port
To test the MinIO Client :mc:`mc` from your local machine, forward the MinIO port and create an alias.
* Forward the Tenant's MinIO port:
.. code-block:: shell
:class: copyable
kubectl port-forward svc/myminio-hl 9000 -n tenant-ns
* Create an alias for the Tenant service:
.. code-block:: shell
:class: copyable
mc alias set myminio https://localhost:9000 minio minio123 --insecure
This example uses the non-TLS ``myminio-hl`` service, which requires :std:option:`--insecure `.
If you have a TLS cert configured, omit ``--insecure`` and use ``svc/minio`` instead.
You can use :mc:`mc mb` to create a bucket on the Tenant:
.. code-block:: shell
:class: copyable
mc mb myminio/mybucket --insecure