Step 1: install Docker
https://blog.kimconnect.com/linux-installing-docker-community-edition-on-centos-8/

Step 2: install network
There are two modes: bridge or 802.1q trunk bridge mode
– Bridge is connecting directly to the host’s NIC
– 802.1q is a sub-interface within Docker with additional routing and filtering capability

In this exercise, we’re creating a standard bridge using the host’s single physical nic as its parent:

# List the NICs
[root@server01 ~]# ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:83:2f:d7:b4  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

eno1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.0.10  netmask 255.255.255.0  broadcast 192.168.0.255
        inet6 fe80::96c6:91ff:feab:b6e2  prefixlen 64  scopeid 0x20<link>
        ether 94:c6:91:ab:b6:e2  txqueuelen 1000  (Ethernet)
        RX packets 215264  bytes 319293312 (304.5 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 101530  bytes 7597691 (7.2 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device interrupt 16  memory 0xb8a00000-b8a20000

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 24  bytes 2040 (1.9 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 24  bytes 2040 (1.9 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

# Now, create a bridge to interface eno1
# Network: x.x.x.128/25 Range: x.x.x.129-254 broadcast: x.x.x.255
# Please be certain to exclude this range in the DHCP server's scope to prevent overlapping
docker network create -d macvlan \
--subnet=192.168.100.0/24 \
--gateway=192.168.100.1 \
--ip-range=192.168.100.128/25 \
-o parent=eno1 \
lab-vlan

# Check Result
docker network ls

[root@server01 ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
ee34429xxxxx        bridge              bridge              local
42ca7edxxxxx        host                host                local
122a513xxxxx        lab-vlan            macvlan             local
f215a39xxxxx        none                null                local

# SELinux configuration – Enable IP forwarding
sysctl net.ipv4.conf.all.forwarding=1
sudo iptables -P FORWARD ACCEPT

Step 3: install Portainer

In the example below, we’ll be generating creating persistent storage, SSL certs, create a new Portainer container, and set Centos firewall to permit its HTTPS port 9000 traffic.

# Create persistent volume
docker volume create portainer_data
 
# check for the existence of the newly created volumes
ls /var/lib/docker/volumes/

# Generate certs
openssl genrsa -out portainer.key 2048
openssl ecparam -genkey -name secp384r1 -out portainer.key
openssl req -new -x509 -sha256 -key portainer.key -out portainer.crt -days 3650

# Sample Output
Country Name (2 letter code) [XX]:US
State or Province Name (full name) []:California
Locality Name (eg, city) [Default City]:Long Beach
Organization Name (eg, company) [Default Company Ltd]:KimConnect.com
Organizational Unit Name (eg, section) []:Lab
Common Name (eg, your name or your server's hostname) []:lab01.kimconnect.com
Email Address []:[email protected]

# move files into /certs directory
mkdir /var/lib/docker/volumes/portainer_data/certs
mv ~/portainer.crt /var/lib/docker/volumes/portainer_data/certs --force
mv ~/portainer.key /var/lib/docker/volumes/portainer_data/certs --force

# Run portainer with priviledged mode, SSL, persistent volume and company logo
companyLogo="https://blog.kimconnect.com/wp-content/uploads/2020/02/kimconnect-logo.png"
docker run -d --privileged -p 9000:9000 --name portainer --restart always -v /var/lib/docker/volumes/portainer_data/certs:/certs -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/portainer_data portainer/portainer --ssl --sslcert /certs/portainer.crt --sslkey /certs/portainer.key --logo $companyLogo

# Configure firewall to open port 9000
# First discover the active zone of current machine
firewall-cmd --get-active-zones

[root@server01 ~]# firewall-cmd --get-active-zones
public
  interfaces: eno1

# Open port 9000 to the public zone and reload firewalld
firewall-cmd --zone=public --add-port=9000/tcp --permanent
firewall-cmd --reload

Troubleshooting

# Sign of healthy Portainer running for more than a few seconds
[root@server01 ~]# docker ps -a
CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS              PORTS                    NAMES
c64854e72eca        portainer/portainer   "/portainer --ssl --…"   4 minutes ago       Up 4 minutes        0.0.0.0:9000->9000/tcp   portainer

# Sign of unhealthy Portainer
[root@server01 ~]# docker ps -a
CONTAINER ID        IMAGE                 COMMAND                  CREATED             STATUS                         PORTS               NAMES
1da59a946502        portainer/portainer   "/portainer --ssl –s…"   15 seconds ago      Restarting (1) 5 seconds ago                       portainer

# How to remove a running instance
docker rm --force portainer