<p>When I deployment IPFS-Cluster on Kubernetes, I get the following error (these are <code>ipfs-cluster</code> logs):</p>
<pre><code> error applying environment variables to configuration: error loading cluster secret from config: encoding/hex: invalid byte: U+00EF 'ï'
 2022-01-04T10:23:08.103Z   INFO    service ipfs-cluster-service/daemon.go:47   Initializing. For verbose output run with &quot;-l debug&quot;. Please wait...
 2022-01-04T10:23:08.103Z   ERROR   config  config/config.go:352    error reading the configuration file: open /data/ipfs-cluster/service.json: no such file or directory
 error loading configurations: open /data/ipfs-cluster/service.json: no such file or directory
</code></pre>
<p>These are <code>initContainer</code> logs:</p>
<pre><code> + user=ipfs
 + mkdir -p /data/ipfs
 + chown -R ipfs /data/ipfs
 + '[' -f /data/ipfs/config ]
 + ipfs init '--profile=badgerds,server'
 initializing IPFS node at /data/ipfs
 generating 2048-bit RSA keypair...done
 peer identity: QmUHmdhauhk7zdj5XT1zAa6BQfrJDukysb2PXsCQ62rBdS
 to get started, enter:

    ipfs cat /ipfs/QmS4ustL54uo8FzR9455qaxZwuMiUhyvMcX9Ba8nUH4uVv/readme

 + ipfs config Addresses.API /ip4/0.0.0.0/tcp/5001
 + ipfs config Addresses.Gateway /ip4/0.0.0.0/tcp/8080
 + ipfs config --json Swarm.ConnMgr.HighWater 2000
 + ipfs config --json Datastore.BloomFilterSize 1048576
 + ipfs config Datastore.StorageMax 100GB
</code></pre>
<p>These are <code>ipfs</code> container logs:</p>
<pre><code> Changing user to ipfs
 ipfs version 0.4.18
 Found IPFS fs-repo at /data/ipfs
 Initializing daemon...
 go-ipfs version: 0.4.18-aefc746
 Repo version: 7
 System version: amd64/linux
 Golang version: go1.11.1
 Error: open /data/ipfs/config: permission denied
 Received interrupt signal, shutting down...
 (Hit ctrl-c again to force-shutdown the daemon.)
</code></pre>
<p>The following is my kubernetes yaml file:</p>
<pre class="lang-yaml prettyprint-override"><code>apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: ipfs-cluster
spec:
  serviceName: ipfs-cluster
  replicas: 3
  selector:
    matchLabels:
      app: ipfs-cluster
  template:
    metadata:
      labels:
        app: ipfs-cluster
    spec:
      initContainers:
        - name: configure-ipfs
          image: &quot;ipfs/go-ipfs:v0.4.18&quot;
          command: [&quot;sh&quot;, &quot;/custom/configure-ipfs.sh&quot;]
          volumeMounts:
            - name: ipfs-storage
              mountPath: /data/ipfs
            - name: configure-script
              mountPath: /custom/entrypoint.sh
              subPath: entrypoint.sh
            - name: configure-script-2
              mountPath: /custom/configure-ipfs.sh
              subPath: configure-ipfs.sh
      containers:
        - name: ipfs
          image: &quot;ipfs/go-ipfs:v0.4.18&quot;
          imagePullPolicy: IfNotPresent
          env:
            - name: IPFS_FD_MAX
              value: &quot;4096&quot;
          ports:
            - name: swarm
              protocol: TCP
              containerPort: 4001
            - name: swarm-udp
              protocol: UDP
              containerPort: 4002
            - name: api
              protocol: TCP
              containerPort: 5001
            - name: ws
              protocol: TCP
              containerPort: 8081
            - name: http
              protocol: TCP
              containerPort: 8080
          livenessProbe:
            tcpSocket:
              port: swarm
            initialDelaySeconds: 30
            timeoutSeconds: 5
            periodSeconds: 15
          volumeMounts:
            - name: ipfs-storage
              mountPath: /data/ipfs
            - name: configure-script
              mountPath: /custom
          resources:
            {}
        - name: ipfs-cluster
          image: &quot;ipfs/ipfs-cluster:latest&quot;
          imagePullPolicy: IfNotPresent
          command: [&quot;sh&quot;, &quot;/custom/entrypoint.sh&quot;]
          envFrom:
            - configMapRef:
                name: env-config
          env:
            - name: BOOTSTRAP_PEER_ID
              valueFrom:
                configMapRef:
                  name: env-config
                  key: bootstrap-peer-id
            - name: BOOTSTRAP_PEER_PRIV_KEY
              valueFrom:
                secretKeyRef:
                  name: secret-config
                  key: bootstrap-peer-priv-key
            - name: CLUSTER_SECRET
              valueFrom:
                secretKeyRef:
                  name: secret-config
                  key: cluster-secret
            - name: CLUSTER_MONITOR_PING_INTERVAL
              value: &quot;3m&quot;
            - name: SVC_NAME
              value: $(CLUSTER_SVC_NAME)
          ports:
            - name: api-http
              containerPort: 9094
              protocol: TCP
            - name: proxy-http
              containerPort: 9095
              protocol: TCP
            - name: cluster-swarm
              containerPort: 9096
              protocol: TCP
          livenessProbe:
            tcpSocket:
              port: cluster-swarm
            initialDelaySeconds: 5
            timeoutSeconds: 5
            periodSeconds: 10
          volumeMounts:
            - name: cluster-storage
              mountPath: /data/ipfs-cluster
            - name: configure-script
              mountPath: /custom/entrypoint.sh
              subPath: entrypoint.sh
          resources:
            {}
      volumes:
      - name: configure-script
        configMap:
          name: ipfs-cluster-set-bootstrap-conf
      - name: configure-script-2
        configMap:
          name: configura-ipfs
  volumeClaimTemplates:
    - metadata:
        name: cluster-storage
      spec:
        storageClassName: gp2
        accessModes: [&quot;ReadWriteOnce&quot;]
        persistentVolumeReclaimPolicy: Retain
        resources:
          requests:
            storage: 5Gi
    - metadata:
        name: ipfs-storage
      spec:
        storageClassName: gp2
        accessModes: [&quot;ReadWriteOnce&quot;]
        persistentVolumeReclaimPolicy: Retain
        resources:
          requests:
            storage: 200Gi

---

kind: Secret
apiVersion: v1
metadata:
  name: secret-config
  namespace: weex-ipfs
  annotations:
    kubesphere.io/creator: tom
data:
  bootstrap-peer-priv-key: &gt;-
    UTBGQlUzQjNhM2RuWjFOcVFXZEZRVUZ2U1VKQlVVTjBWbVpUTTFwck9ETkxVWEZNYzJFemFGWlZaV2xKU0doUFZGRTBhRmhrZVhCeFJGVmxVbmR6Vmt4Nk9IWndZ...
  cluster-secret: 7d4c019035beb7da7275ea88315c39b1dd9fdfaef017596550ffc1ad3fdb556f
type: Opaque

---

kind: ConfigMap
apiVersion: v1
metadata:
  name: env-config
  namespace: weex-ipfs
  annotations:
    kubesphere.io/creator: tom
data:
  bootstrap-peer-id: QmWgEHZEmJhuoDgFmBKZL8VtpMEqRArqahuaX66cbvyutP

---

kind: ConfigMap
apiVersion: v1
metadata:
  name: ipfs-cluster-set-bootstrap-conf
  namespace: weex-ipfs
  annotations:
    kubesphere.io/creator: tom
data:
  entrypoint.sh: |2
        #!/bin/sh
        user=ipfs

        # This is a custom entrypoint for k8s designed to connect to the bootstrap
        # node running in the cluster. It has been set up using a configmap to
        # allow changes on the fly.


        if [ ! -f /data/ipfs-cluster/service.json ]; then
          ipfs-cluster-service init
        fi

        PEER_HOSTNAME=`cat /proc/sys/kernel/hostname`

        grep -q &quot;.*ipfs-cluster-0.*&quot; /proc/sys/kernel/hostname
        if [ $? -eq 0 ]; then
          CLUSTER_ID=${BOOTSTRAP_PEER_ID} \
          CLUSTER_PRIVATEKEY=${BOOTSTRAP_PEER_PRIV_KEY} \
          exec ipfs-cluster-service daemon --upgrade
        else
          BOOTSTRAP_ADDR=/dns4/${SVC_NAME}-0/tcp/9096/ipfs/${BOOTSTRAP_PEER_ID}

          if [ -z $BOOTSTRAP_ADDR ]; then
            exit 1
          fi
          # Only ipfs user can get here
          exec ipfs-cluster-service daemon --upgrade --bootstrap $BOOTSTRAP_ADDR --leave
        fi

---

kind: ConfigMap
apiVersion: v1
metadata:
  name: configura-ipfs
  namespace: weex-ipfs
  annotations:
    kubesphere.io/creator: tom
data:
  configure-ipfs.sh: &gt;-
    #!/bin/sh
    set -e
    set -x
    user=ipfs

    # This is a custom entrypoint for k8s designed to run ipfs nodes in an
    appropriate
    # setup for production scenarios.

    mkdir -p /data/ipfs &amp;&amp; chown -R ipfs /data/ipfs

    if [ -f /data/ipfs/config ]; then
      if [ -f /data/ipfs/repo.lock ]; then
        rm /data/ipfs/repo.lock
      fi
      exit 0
    fi

    ipfs init --profile=badgerds,server
    ipfs config Addresses.API /ip4/0.0.0.0/tcp/5001
    ipfs config Addresses.Gateway /ip4/0.0.0.0/tcp/8080
    ipfs config --json Swarm.ConnMgr.HighWater 2000
    ipfs config --json Datastore.BloomFilterSize 1048576
    ipfs config Datastore.StorageMax 100GB
</code></pre>
<p>I follow the <a href="https://cluster.ipfs.io/documentation/guides/k8s/" rel="nofollow noreferrer">official steps</a> to build.</p>
<p>I follow the official steps and use the following command to generate cluster-secret：</p>
<pre><code>$ od  -vN 32 -An -tx1 /dev/urandom | tr -d ' \n' | base64 -w 0 -
</code></pre>
<p>But I get:</p>
<pre><code> error applying environment variables to configuration: error loading cluster secret from config: encoding/hex: invalid byte: U+00EF 'ï'
</code></pre>
<p>I saw the same problem from the official <a href="https://github.com/ipfs/ipfs-cluster/issues/1005" rel="nofollow noreferrer">github issue</a>. So, I use <code>openssl rand -hex</code> command is not ok.</p>

Jason Tom
<p>To clarify I am posting community Wiki answer.</p>
<hr />
<p>To solve following error:</p>
<pre><code>no such file or directory
</code></pre>
<p>you used <code>runAsUser: 0</code>.</p>
<hr />
<p>The second error:</p>
<pre><code>error applying environment variables to configuration: error loading cluster secret from config: encoding/hex: invalid byte: U+00EF 'ï'
</code></pre>
<p>was caused by different encoding than hex to <code>CLUSTER_SECRET</code>.</p>
<p>According to <a href="https://rossbulat.medium.com/using-ipfs-cluster-service-for-global-ipfs-data-persistence-69a260a0711c" rel="nofollow noreferrer">this page</a>:</p>
<blockquote>
<h4>The Cluster Secret Key</h4>
<p>The secret key of a cluster is a 32-bit <em><strong>hex encoded</strong></em> random string, of which  <em>every cluster peer needs in their</em> <code>_service.json_</code> <em>configuration</em>.</p>
<p>A secret key can be generated and predefined in the <code>CLUSTER_SECRET</code> environment variable, and will subsequently be used upon running <code>ipfs-cluster-service init</code>.</p>
</blockquote>
<p><a href="https://github.com/ipfs/ipfs-cluster/issues/1005" rel="nofollow noreferrer">Here</a> is link to solved issue.</p>
<hr />
<p>See also:</p>
<ul>
<li><a href="https://cluster.ipfs.io/documentation/reference/configuration/" rel="nofollow noreferrer">Configuration reference</a></li>
<li><a href="https://labs.eleks.com/2019/03/ipfs-network-data-replication.html" rel="nofollow noreferrer">IPFS Tutorial</a></li>
<li>Documentation guide <a href="https://cluster.ipfs.io/documentation/guides/security/#the-cluster-secret" rel="nofollow noreferrer">Security and ports</a></li>
</ul>
