Portainer with k3s
To use Portainer with your k3s home lab, which consists of three virtual machines across two physical machines, you can deploy Portainer as a Kubernetes application within your k3s cluster. Portainer provides a web-based interface to manage your k3s cluster, making it easier to handle containerized applications. Below are the detailed steps to set it up, including optional persistence using NFS since you mentioned having it configured in your lab.
Prerequisites
-
k3s Cluster: Ensure your k3s cluster is running with one master and two worker nodes.
-
kubectl: Verify that kubectl is configured to interact with your k3s cluster. Run the following command to check:
bash
kubectl get nodesYou should see all three nodes listed. If not, configure your kubeconfig file (typically located at ~/.kube/config or /etc/rancher/k3s/k3s.yaml on the master node) accordingly.
Step 1: Create a Namespace for Portainer
Organize your resources by creating a dedicated namespace for Portainer:
bash
kubectl create namespace portainerStep 2: Set Up Persistence (Optional)
Portainer stores its configuration data in a volume. By default, without persistence, this data is lost if the pod restarts. Since you have NFS set up, you can use it to persist Portainer’s data. If you skip this step, Portainer will still work but won’t retain data across restarts.
-
Create a PersistentVolume (PV): Create a file named portainer-pv.yaml with the following content, replacing the NFS server IP and path with your own:
yaml
apiVersion: v1 kind: PersistentVolume metadata: name: portainer-pv spec: capacity: storage: 1Gi accessModes: - ReadWriteOnce nfs: server: 192.168.123.100 # Replace with your NFS server IP path: /nfs/portainer # Replace with your NFS export pathApply it:
bash
kubectl apply -f portainer-pv.yaml -
Create a PersistentVolumeClaim (PVC): Create a file named portainer-pvc.yaml:
yaml
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: portainer-pvc namespace: portainer spec: accessModes: - ReadWriteOnce resources: requests: storage: 1GiApply it:
bash
kubectl apply -f portainer-pvc.yaml
Step 3: Deploy Portainer
Deploy Portainer as a Kubernetes application in your k3s cluster. You’ll create a Deployment and a Service, and if you set up persistence, you’ll mount the PVC.
Create a file named portainer-deployment.yaml with the following content:
apiVersion: apps/v1
kind: Deployment
metadata:
name: portainer
namespace: portainer
spec:
replicas: 1
selector:
matchLabels:
app: portainer
template:
metadata:
labels:
app: portainer
spec:
containers:
- name: portainer
image: portainer/portainer-ce:latest
ports:
- containerPort: 9000
volumeMounts:
- name: data
mountPath: /data
volumes:
- name: data
persistentVolumeClaim:
claimName: portainer-pvc # Omit this if not using persistence
apiVersion: v1
kind: Service
metadata:
name: portainer
namespace: portainer
spec:
type: ClusterIP
ports:
- port: 9000
targetPort: 9000
selector:
app: portainer
```text
**Notes**:
- If you skipped the persistence step, replace the `volumes` section with:
```yaml
volumes:
- name: data
emptyDir: {}- The portainer-ce:latest image is the Community Edition of Portainer, which is free and suitable for a home lab.
Apply the manifest:
bash
kubectl apply -f portainer-deployment.yamlVerify that Portainer is running:
bash
kubectl get pods -n portainerLook for a pod with a name like portainer-xxxxx in the Running state.
Step 4: Access the Portainer UI
Portainer’s web interface runs on port 9000. Since the Service is of type ClusterIP, it’s only accessible within the cluster by default. Here are two ways to access it from your local machine:
Option 1: Use kubectl port-forward (Temporary Access)
Run:
bash
kubectl port-forward -n portainer service/portainer 9000:9000Then, open your browser and navigate to:
http://localhost:9000This method is great for initial setup and testing but stops when you terminate the command.
Option 2: Use Ingress (Permanent Access)
Since you have an Nginx Ingress Controller in your k3s cluster, you can expose Portainer via a domain name. Create a file named portainer-ingress.yaml:
yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: portainer-ingress
namespace: portainer
spec:
rules:
- host: portainer.example.com # Replace with your desired domain
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: portainer
port:
number: 9000Apply it:
bash
kubectl apply -f portainer-ingress.yamlUpdate your local /etc/hosts file (or equivalent) to point portainer.example.com to one of your k3s node IPs (e.g., 192.168.123.221). Then, access:
http://portainer.example.comStep 5: Configure Portainer
-
Set Up Admin User: When you first access the Portainer UI, you’ll be prompted to create an admin password. Enter a secure password and save it.
-
Connect to k3s Cluster: Since Portainer is running inside your k3s cluster, it automatically detects and connects to the local cluster using in-cluster authentication. After logging in, you should see your k3s cluster listed as the “local” environment.
-
Manage Your Cluster: Use the Portainer interface to deploy applications, monitor resources, view logs, and manage your k3s cluster.
Additional Notes
-
Compatibility: Portainer is fully compatible with k3s because k3s adheres to Kubernetes APIs. You shouldn’t encounter any issues specific to k3s.
-
Managing Other Environments: If you want to manage additional Docker instances or Kubernetes clusters, you can add them in Portainer later via the UI.
-
Security: For a home lab, the setup above is sufficient. In a production environment, consider securing Portainer with HTTPS by configuring your Ingress with a TLS certificate.
With these steps, Portainer will be integrated into your k3s home lab, providing a user-friendly interface to manage your cluster and applications like Nextcloud or Vaultwarden. If you need further assistance, feel free to ask!