Published: Jul 7, 2023 by Isaac Johnson
Portainer.io has long been on my list to check out. It is one of the leading container management apps for docker, though it can also be used to monitor Swarm, Kubernetes, ACI, Nomad or even spin up a new K8s (microk8s or a Cloud Provider).
Today we’ll setup and test Portainer CE and BE (with a free 3 node license). I just want to preface the rest by saying I clearly had some gripes about the limitations of the Community Edition and the endless push to upgrade to their commercial. However, about half way down I pivot to the free 1y 3 node environment license which really unlocks quite a lot.
I’ll be following up the last post and using the same Synology DS220+ NAS to host Portainer as I did the registry. However, you can run Portainer in Kubernetes just as easily.
Use Case
Now that we have a registry container running in docker, as described in the last post:
ijohnson@sirnasilot:~$ sudo docker ps
Password:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
83af22fb4b32 registry:latest "/entrypoint.sh /etc…" 3 days ago Up 3 days 0.0.0.0:5050->5000/tcp, :::5050->5000/tcp registry-1
We may wish to monitor it. This is where portainer comes into play.
Portainer Installation
I’ll first need to create a volume for Portainer data
$ sudo docker volume create portainer_data
portainer_data
Next, I can download and run the Portainer-ce pod directly
ijohnson@sirnasilot:~$ sudo docker run -d -p 8000:8000 -p 9443:9443 --name portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest
Unable to find image 'portainer/portainer-ce:latest' locally
latest: Pulling from portainer/portainer-ce
772227786281: Pull complete
96fd13befc87: Pull complete
5171176db7f2: Pull complete
a143fdc4fa02: Pull complete
b622730c7bdc: Pull complete
c1cad9f5200f: Pull complete
d8a77b01f2cb: Pull complete
0d4d8543f764: Pull complete
c6fd0bcf10c9: Pull complete
889200668c1c: Pull complete
4f4fb700ef54: Pull complete
Digest: sha256:94c3056dbe879f3a3df06b427713392a0962924914f5c2fc557de3797f59f926
Status: Downloaded newer image for portainer/portainer-ce:latest
42b68c9ce6a190f85adb0e11cb394c2fdef0996272ad435c4f5b8c74f1a0d8cf
I can now see we are serving traffic on 8000, 9443 and 9000
ijohnson@sirnasilot:~$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
42b68c9ce6a1 portainer/portainer-ce:latest "/portainer" 25 seconds ago Up 22 seconds 0.0.0.0:8000->8000/tcp, :::8000->8000/tcp, 0.0.0.0:9443->9443/tcp, :::9443->9443/tcp, 9000/tcp portainer
83af22fb4b32 registry:latest "/entrypoint.sh /etc…" 3 days ago Up 3 days 0.0.0.0:5050->5000/tcp, :::5050->5000/tcp registry-1
I can now access the setup UI on 9443
I’ll create a user with a password which then brings me to the Quick Setup home page
Adding Registries
I’ll want to add both my NAS hosted registry and my Harbor one
Since the NAS registry exists within the network, I need no auth
My Harbor, however, requires auth
I can now see them added, but apparently the best features are behind the business edition. This is rather ugly. Too much harassment to upgrade for my taste
Even the logs are paywalled with giant ugly orange lockout screens. Seriously, this is terrible
Images
Let’s look at images. We can see them in the “local” section
I was surprised I could see Volumes details without more Upgrade graphics
The host details confirm I did what is not officially allowed - I jammed an 8Gb SODIM in my new DS220+ and it’s running with 10Gb of RAM
Environments
We can add all, i mean, well some of the environment types, but Upgrade Now and we can do the rest.
I clicked Kubernetes then “Start Wizard”. They honestly locked the import of a kubeconfig as a “business feature”.
I’ll try node port as I know my k8s won’t do the LB
builder@DESKTOP-QADGF36:~$ kubectl apply -f https://downloads.portainer.io/ce2-18/portainer-agent-k8s-nodeport.yaml
namespace/portainer created
serviceaccount/portainer-sa-clusteradmin created
clusterrolebinding.rbac.authorization.k8s.io/portainer-crb-clusteradmin created
service/portainer-agent created
service/portainer-agent-headless created
deployment.apps/portainer-agent created
I’ll see what is serving 9001
builder@DESKTOP-QADGF36:~$ kubectl get svc --all-namespaces | grep portainer
portainer portainer-agent NodePort 10.43.156.218 <none> 9001:30778/TCP 50s
portainer portainer-agent-headless ClusterIP None <none> <none> 50s
That shows the NodPort as 30778
$ kubectl describe svc portainer-agent -n portainer
Name: portainer-agent
Namespace: portainer
Labels: <none>
Annotations: field.cattle.io/publicEndpoints: [{"port":30778,"protocol":"TCP","serviceName":"portainer:portainer-agent","allNodes":true}]
Selector: app=portainer-agent
Type: NodePort
IP Family Policy: SingleStack
IP Families: IPv4
IP: 10.43.156.218
IPs: 10.43.156.218
Port: http 9001/TCP
TargetPort: 9001/TCP
NodePort: http 30778/TCP
Endpoints: 10.42.3.219:9001
Session Affinity: None
External Traffic Policy: Cluster
Events: <none>
I decided to use the Node that the pod lived on
$ kubectl describe pod portainer-agent-69b4d67ff-thrfm -n portainer
Name: portainer-agent-69b4d67ff-thrfm
Namespace: portainer
Priority: 0
Node: builder-hp-elitebook-850-g2/192.168.1.215
Start Time: Thu, 06 Jul 2023 19:32:03 -0500
Labels: app=portainer-agent
pod-template-hash=69b4d67ff
Annotations: <none>
Status: Running
IP: 10.42.3.219
... snip ...
So I used 192.168.1.215:30778
in the Portainer UI
I can now see my K8s stack there in the UI
We can see some of the objects there
I can view some of the details of Applications
For example, the Azure Vote App
Though, when I went to “edit” the application, I couldn’t see anything
I found services went out to lunch and never came back
Though, Ingresses worked which was more interesting
Volumes was handy as it showed some waste I have to cleanup
Cluster Details
We can view Cluster Health
I can pick a node and view some stats, which did as it suggested and refreshed every 30s, which was the min setting
I can view events on a node which is handy when troubleshooting problems
I can also pause and drain from the UI which is really useful for planned maintenance
And on Security Constraints we can… oh wait, yet another paywall
Users
While I can add users
and teams
I can only use Admin and Standard as Roles, yes, you guessed it, got to upgrade for that
Take 3
Seems they have a promotion at the moment to signup and get 3 nodes for free.
You have to love radio buttons with only “yes” on contact
I did get a license key and a welcome email from my success liaison a minute later
We can now click the “Upgrade” link in the upper right, paste our key and get an error
Let me pull and push into my registry hosted on the NAS, maybe it will find it there
ijohnson@sirnasilot:~$ sudo docker pull portainer/portainer-ee:2.18.4
Password:
2.18.4: Pulling from portainer/portainer-ee
772227786281: Already exists
96fd13befc87: Already exists
5171176db7f2: Already exists
a143fdc4fa02: Already exists
b622730c7bdc: Already exists
c1cad9f5200f: Already exists
69ae32ddde08: Pull complete
4a0d116cdc71: Pull complete
08962690b30c: Pull complete
78e44cf728cd: Pull complete
4f4fb700ef54: Pull complete
Digest: sha256:656ca138b68f9aaafd0923ad85e89e84d0be7001faa6ff2c9155bbdab0527ae4
Status: Downloaded newer image for portainer/portainer-ee:2.18.4
docker.io/portainer/portainer-ee:2.18.4
ijohnson@sirnasilot:~$ sudo docker tag docker.io/portainer/portainer-ee:2.18.4 registry.freshbrewed.science:8443/portainer/portainer-ee:2.18.4
ijohnson@sirnasilot:~$ sudo docker push registry.freshbrewed.science:8443/portainer/portainer-ee:2.18.4
The push refers to repository [registry.freshbrewed.science:8443/portainer/portainer-ee]
5f70bf18a086: Pushed
5edb9da25c2d: Pushed
bc109744fe98: Pushed
538e17c76df3: Pushed
77a53a9a27d0: Pushed
c6713b0b1e7a: Pushed
b4960c616612: Pushed
1ee41f4fbd13: Pushed
df0cbd66321a: Pushed
4776464837fd: Pushed
8c004456aeb5: Pushed
2.18.4: digest: sha256:ae7e5a29fd2ec299f542f228ada65710980ae42cf100d87ce37ccb7c8e86ecc0 size: 2626
ijohnson@sirnasilot:~$
Still no go. Let’s kill this instance and try with EE
Portainer EE
First I have to kill the last
ijohnson@sirnasilot:~$ sudo docker ps
Password:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
42b68c9ce6a1 portainer/portainer-ce:latest "/portainer" 26 minutes ago Up 26 minutes 0.0.0.0:8000->8000/tcp, :::8000->8000/tcp, 0.0.0.0:9443->9443/tcp, :::9443->9443/tcp, 9000/tcp portainer
83af22fb4b32 registry:latest "/entrypoint.sh /etc…" 3 days ago Up 3 days 0.0.0.0:5050->5000/tcp, :::5050->5000/tcp registry-1
ijohnson@sirnasilot:~$ sudo docker stop 42b68c9ce6a1
42b68c9ce6a1
ijohnson@sirnasilot:~$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
83af22fb4b32 registry:latest "/entrypoint.sh /etc…" 3 days ago Up 3 days 0.0.0.0:5050->5000/tcp, :::5050->5000/tcp registry-1
Just to keep it simple, I’ll create a new volume for EE
ijohnson@sirnasilot:~$ sudo docker volume create portainer_data2
portainer_data2
Now I can launch it
ijohnson@sirnasilot:~$ sudo docker run -d -p 8000:8000 -p 9443:9443 --name portaineree --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data2:/data portainer/portainer-ee:latest
5fa76248b69dd6d9ba552064aaa35bd5960a37406eafc30104bc73df6538b010
ijohnson@sirnasilot:~$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5fa76248b69d portainer/portainer-ee:latest "/portainer" 23 seconds ago Up 20 seconds 0.0.0.0:8000->8000/tcp, :::8000->8000/tcp, 0.0.0.0:9443->9443/tcp, :::9443->9443/tcp, 9000/tcp portaineree
83af22fb4b32 registry:latest "/entrypoint.sh /etc…" 3 days ago Up 3 days 0.0.0.0:5050->5000/tcp, :::5050->5000/tcp registry-1
This time after I connect and add the Admin user, I have to add a License Key
I now see a “business edition”
I’ll add back my registries
And I see Browse now available
I worked with the UI to test the ports and IPs until I figured out the proper localnas endpoint.
I could then browse the contents:
That is a pretty powerful feature, in my opinion.
I can also see tags, sizes and even add a tag
As you can see, we can add tags and view things like Exposed ports
Now that I’m using the “EE” image, I can delete the old CE version
I initially got an error
A force warned it will be removed even if used by stopped containers
So I first removed the stopped container
which let me remove non-persistent volumes (nice!)
I can now see it is unused in the Images area
This time, removing worked just fine
I found the license will last me a year
Setting up a K8s
We can use Portainer to create new Kubernetes environments as well.
On Prem
The On-prem install will setup MicroK8s
After I create a credential, I can setup the AddOns, set a name and list the IPs to use
I can go to environments to see it is creating
Once done, I can view the details in the Kubernetes dashboard
I can see it indeed added the Registry service
As you might expect, I can also see Host details like CPU and Memory
Though even in BE mode, we can only select between 30s and 60s for stats
If I want to use this locally with Kubectl commands, I can go to environments
and click the “Kubeconfig” button
this downloads a YAML file we can use with kubeconfig
builder@DESKTOP-QADGF36:~/Workspaces$ kubectl get nodes --kubeconfig=/mnt/c/Users/isaac/Downloads/admin-t100.yaml
NAME STATUS ROLES AGE VERSION
builder-t100 Ready <none> 16m v1.24.13-2+cd9733de84ad4b
I gave it some time, the Memory graph was fine, but the CPU one had a rather interesting Y axis
KaaS Provider
Let’s create a CIVO cluster first. Presently I have no Civo k8s
I’ll need to get my API key from settings
And use that for the Credentials section
I can now name it, set the node count, region, etc
Clicking Provision shows it’s now creating the cluster in CIVO
When done, I can see it listed in the Environments page
And back in CIVO, I can see the new cluster listed
To remove, I can just select the cluster and click remove
which will confirm
Though, as you would expect, this just removes it from Portainer, not from CIVO. The cluster is still live and running in the cloud
To save some money, I’ll click Delete from the CIVO K8s page
And a quick pro-tip for clouds like CIVO, Linode (Akamai) and DO - make sure to check Volumes as well as often PVCs do not auto-delete (and then you’ll get billed for object storage at the end of the month)
Licensing
Clearly, they used to give 5 nodes for free but decided the roll that back to just 3.
Even the “Take 5” link really forwards to the Take 3 page
The pricing page does have a home and student edition for $150/year
I actually think their pricing is pretty fair. I’m quite tempted to pay for the Home edition because that just equates to about $12/mo and that is streaming-service pricing.
Summary
I think Portainer is pretty solid offering. Certianly, it covers a lot of ground from the Kubernetes observability and interaction to the local docker environments. I loved the Registry browsing and having the ability to spin up on-prem clusters with ease.
What I was less thrilled with was the endless “buy now” decorations. I get it - you want to sell me an upgrade. I do not fault a company for trying to flip a freebee to a premium. But I do take issue with locking essential features like access logs behind a paywall. Again, I’m not so annoyed as not to pay - I might very well pull the trigger on the Home Edition. But I really wish the entry level business offered more than 5 nodes for the $1000.
Clearly they had more in the past; we can see G2 pricing said it has a free 5-node business version same with Sourceforge
And the G2 page was updated as recently as Jan 17 2023 so the change happened in the last 6 months without any sort of announcement.
This just leads to a bit of a trust issue. If you reduce an offering without any kind of announcement, even the “Take 5” links go to a “Take 3”, then I have trust issues with the vendor.
But less us set aside pricing for a moment - the product is quite solid and worth looking into and I’ll likely keep this in my stack as it really solves a lot of problems. I just wish they would be more forthright with their pricing and plans.