Blog ตอนนี้มาติดตั้ง Portainer เอามาแทน VM อันเดียวที่ลงไว้ 3-4 ปีก่อน แล้วพังไปครับ รอบนี้ไหนๆก็ลงใหม่แล้ว และรอบก่อนที่สอน Docker @BSRU มีคนถามถึง Portainer เยอะเหมือนกัน เลยคิดว่ามาเขียน Blog ไว้ด้วยครับ
Portainer คือ อะไร ?
เครื่องมือที่ใช้จัดการ Container ผ่าน Web Interface ครับ โดยสามารถจัดการได้ทั้ง docker / podman (ทำได้ แต่ต้องมี Step นิดนึง) / Kubernetes / Azure Container Instance เป็นต้น จริงๆมันทำได้มากกว่านี้นะ แต่ต้องซื่อ Business Edition แทนครับ สำหรับใน Blog นี้จะใช้ตัว Community Edition ครับ
อย่างที่เกริ่นไปจัดการ Container ได้ ทำอะไรได้บ้าง เช่น
- การจัดการ Container Registry
- การเพิ่ม/ลบ/จัดการ Image
- การสร้าง/ลบ/จัดการ Container รวมถึงพวก Network / Volume ด้วยครับ
- และแน่นอน ถ้ามีหลายเครื่อง เราสามารถเพิ่มเครื่องเข้ามาเป็น Environment นึงในระบบ ซึ่งความสามารถนี้แหละ ผมเลย Setup ให้ทางทีม Operation มาดูแลได้ครับ
สำหรับ Blog นี้สอน 3 ส่วนครับ ติดค้างเรื่องกับคนที่เรียน Blog Docker เมื่อเดือนก่อนไว้ด้วย
ติดตั้ง Portainer
การติดตั้ง Portainer ของจะเลือกใช้ docker compose นะครับ แต่สามารถใช้ Command ได้ครับ
- docker
docker run -d \ --name portainer \ --security-opt no-new-privileges:true \ -p 8000:8000 \ -p 9443:9443 \ -v $(pwd)/portainer-data:/data \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /etc/localtime:/etc/localtime:ro \ -e AGENT_SECRET=my_secret_token \ --restart unless-stopped \ portainer/portainer-ce:latest
- docker compose
อธิบายกันสักนิด ผมจะอิงจาก docker compose
- container_name - ชื่อ Container
- image - ตัว portainer-ce ใน docker hub เลยครับ สำหรับ production อย่างลืมกำหนด Version ผมใช้เป็น latest
- security_opt กำหนด no-new-privileges:true ไม่ให้ Process ของ Container ได้รับสิทธิเพิ่มเติมครับ
- port ที่ให้ Portainer ใช้งาน
- 9443 สำหรับใช้ Portainer UI https + self-signed SSL certificate ถ้าไม่ต้องการใช้ port 9000 ได้ครับ
- 8000 สำหรับ TCP tunnel server เปิดไว้กรณีที่ใช้ Edge Compute อันนี้ผมเปิดเผื่อไปเลยครับ - Volume
- ข้อมูลใช้ได้ 2 แบบทั้งแบบ mount / volume ตรงนี้ผมจะเลือก mount ครับ
- '/var/run/docker.sock:/var/run/docker.sock' - เปิด Portainer เข้ามาจัดการ docker
- /etc/localtime:/etc/localtime:ro - mount timezome จาก host เข้ามา แบบ read only - environment
- AGENT_SECRET อันนี้ให้ Agent เอาไปใส่ตอน Start Container อารมณ์แบบ API Key จะได้รู้ว่า Register ถูกเครื่องนะ - restart: unless-stopped - ถ้า Container สถานะ Exit ผิดปกติมันจะ restart ให้ ยกเว้น เราจะ Stop ก่อน
หลังจากเตรียมอะไรเรียบร้อยแล้ว ผมใช้ docker compose เป็นหลักนครับ สามารถ Run คำสั่งตามนี้ได้เลย

เมื่อเข้า https://localhost:9443 เป็น https นะ เพราะเราใช้ portainer generate self-cert แล้ว จะเข้าสูดหน้าจอ setup portainer เพิ่งกำหนด ข้อมูลของ admin ใช้งานได้เลยครับ

หรือ ถ้าใครเจอหน้าจอนี้ อันนี้แสดงว่าเราทิ้งเวลาไว้นานไป เช่น สายเข้า แล้วลืมไป มันจะ Timeout ให้ stop start docer compose ใหม่ครับ

หลังจาก set up เรียบร้อยลองเข้าไปดู path ที่ mount มัน Gen ข้อมูลอะไร อย่างไปยุ่งครับ

กลับมาที่หน้าเว็บ Portainer ตอนนี้จะอยู่ที่หน้าจอ Get Start แล้ว

ตรงนี้จะพบว่ามันเอาตัวข้อมูล docker ที่ Run เครื่อง host ขึ้นมาแล้วครับ ตรงนี้มันดึงข้อมูลจากที่เรา mount เข้าไป ในส่วนของ docker.sock '/var/run/docker.sock:/var/run/docker.sock'

การใช้งาน Portainer เบื่องต้น
สำหรับเมนูทางซ้าย มีเมนูหลักๆ ดังนี้ครับ
- Users - กำหนด Users / Teams / Roles (เสียเงินนะ) สาหรับตัวฟรีมี 2 Role administrator / user ซึ่งจัดการ Container ได้เหมือนกัน ต่างกันที่ administrator จะมา config ได้
- Environment - เครื่อง Container Host / Cluster ที่เราเอามา registry ใส่ลงไปครับ กำหนด
- Groups - กำหนดกลุ่ม Resource ของ Environment เช่น develop / stating / production
- Tags - เอาไว้บอกข้อมูลอื่น เช่น อยู่ deportment ไหน / ตัว Physical อยู่ที่ไหนครับ - Registries - กำหนด registry + user pass / access token ไว้ ให้แต่ละ Environment เรียกใช้ ถ้าใช่กับตัว Nexus ไปในทาง Custom

- Authentication Logs - ส่วนเสียเงิน เอาไว้ดู logs Authentication
- Notifications - แจ้ง Noti ของระบบ
- Settings กำหนดการตั้งค่าของระบบ จะมี 2 ส่วน
- Authentication - Local / LDAP ที่ฟรี
- Edge Compute

การเพิ่ม Enviroment ใน Portainer เพื่อจัดการ
เราสามารถเพิ่ม Enviroment ได้ จากเมนู Enviroment > Add Enviroment ครับ
ตรงนี้จะมี Enviroment หลายๆอย่างให้เลือกครับ ทั้ง docker / docker swarm / kubernetes / Azure Container Instance ที่ฟรี

ของผมตอนนี้ลองยกตัวอย่างของ docker standalone ครับ มี 2 แบบ
- Socker - อันที่เรา mount docker sock ใน docker command / docker compose file พวก
- '/var/run/docker.sock:/var/run/docker.sock'
- Remote API ไม่ค่อยแนะนำเท่าไหร่ เพราะมันไม่มีกลไกการ Authenticate ในตัว ต้องให้ตัวอื่นๆ เช่น HA Proxy / SSH + TLS
- ติดต้ัง Portainer Agent แนะนำตัวนี้นะ ง่ายดี ถ้ามีกำหนด AGENT_SECRET ตอน Start Container ต้องมาเพิ่มใน environment ด้วย
ใน Blog ตอนนี้จะแนะนำเป็นท่า Portainer Agent
- เมนู Enviroment > Add Enviroment
- เลือก Docker Standalone > Start Wizard

- จากนั้นเลือก docker agent ครับ
- มันจะมี Command มาให้ตรงนี้ Copy ไปใช้ได้เลย
docker run -d \ -p 9001:9001 \ --name portainer_agent \ --restart=always \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /var/lib/docker/volumes:/var/lib/docker/volumes \ portainer/agent:2.19.5
- แต่เดี๋ยวก่อน ถ้า Start Porttainer แล้วใส่ AGENT_SECRET
docker run -d \ -p 9001:9001 \ --name portainer_agent \ --restart=always \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /var/lib/docker/volumes:/var/lib/docker/volumes \ -e AGENT_SECRET=yoursecret \ portainer/agent:2.19.5
- จากนั้นมากำหนดค่ากันครับ
- name ตั้งชื่อให้สื่อ
- Environment address อันนี้กำหนดเป็น <HOST>:<PORT> หรือ <IP>:<PORT> ตรงนี้ใช้ IP / Host ของ Agent + Port ที่เรา Expose ตอน docker command ครับ จาก Script เราจะใช้ Port 9001
metadata เราสามารถกำหนด group / tag ได้
- group เอาไว้กำหนดกลุ่ม Resource ของ Environment เช่น develop / stating / production
- tag กำหนดข้อมูล

สุดท้ายผมจะได้ผมตามภาพนี้ครับ ผมเอา nuc ที่ลง ubuntu + docker เข้ามาแล้วครับ

ส่วนอีกตัวที่เป็น Podman มันสามารถ Add ได้นะครับ ที่ผมลองมา โดยที่ผมทดสอบมา จะใช้ท่า
- Enable Remote API in Podman (ภาษาอังกฤษ)
- How to add Podman as an Agent in Portainer (ภาษาอังกฤษ) - ได้บาง Feature แต่ไม่ครบทั้งหมด
การจัดการ Enviroment
จากหน้า Dashboard ถ้าเราเลือก Enviroment มา 1 ตัว เราจะเห็นเมนู ดังนี้
- Dashboard - บอกภาพรวมของระบบ Spec อะไร มี Image / Container / Volume / Network อะไรบ้าง ใช้ Stack ไหน
- App Template
- Stacks - Container ของเราที่ Run ขึ้นมา โดยหลักผมจะใช้ไฟล์ docker compose ครับ
- Containers - List Container ที่มีในเครื่องนั้นๆออกมาครับ เหมือนเรา ssh เข้าไป
docker ps -a
- Images - List Image ที่มีในเครื่องนั้นๆออกมาครับ เหมือนเรา ssh เข้าไป
docker images
- Volumes - List Volume ที่มีในเครื่องนั้นๆออกมาครับ เหมือนเรา ssh เข้าไป
docker volume ls
- Events - สรุปเหตุการณ์ทั้งหมดในเครื่องนั้นๆ
- Host - บอกข้อมูลสรุป Host
- Setup การตั้งค่าค่าๆ เช่น GPU สำหรับงาน AI
- การกำหนด Container Registry ให้ใช้งาน นอกเหนือจากส่วนกลางที่กำหนดไว้
แต่ถ้าไปแอบ ssh แล้ว docker run แยกเอง Portainer มันเห็นในส่วน Containers แต่ Stacks ไม่เห็นนะครับ
Enviroment > Public IP
ที่หน้าจอ Enviroment ตอนเข้าไปในแต่ละ Enviroment อย่าลืมไป กำหนด Public IP (ใส่ IP / DNS) จะได้กดเข้า Access Service ได้ครับ

ถ้าลืมใส่ที่หน้าจอ List Container มันจะพาไป http://0.0.0.0:9101/ ครับ

ลอง Deploy สัก App
ที่ตัว Portainer มันรองรับ Deploy
- App Template
- Stack
Note: ถ้า App นั้นๆ ใช้ mount file จาก host path เข้าไป ตรงนี้ใน Portainer ต้องย้ายไปใช้ Docker Volume ครับ
- App Template
เขาไป Menu App Template แล้วมันจะมี App ให้เราเลือกใช้เลย เช่น ubuntu / Postgres / MariaDB / MSSQL สำหรับผมจะเลือกตัว minio (Object Storage และมี API แบบ S3 ด้วย) โดยมีหน้าตา Config ตามนี้เลยครับ

- กำหนด ENV ของแต่ละ Image ถ้าเลือก minio จะมีให้กำหนด root user / root password เพิ่ม แต่ถ้าเลือก WordPress มันจะเปลี่ยนไปครับ
- กำหนดสิทธิของ User ที่ Run อันนี้ผมเอาง่ายๆ admin ครับ แต่จริงๆให้ user Team มาลองก็ได้
- กำหนด port อันนี้ผมต้องไปดู doc ของ minio และ port ที่เครื่องเราใช้ อย่างเคส ผม Port 9000 Portainer ใช้ไปแล้วต้องเลี่ยงครับ
- กำหนด Volume ผมเอาตาม Default ของ minio
- กำหนด Hostname ถ้าไม่ใส่กด Deploy โลดครับ
จากนั้นมาที่ Container รอสักพัก มันขึ้นมาให้พร้อมใช้ครับ (ชื่อ Container Name แปลก เดี๋ยวมาแก้ที่หลังได้ครับ

ลอง Login ตาม User ที่ได้ใส่ไว้ตอน Deploy Template

- Stack
ส่วนนี้จะให้เราเอา docker compose มา run ครับ โดยภาพรวมนี้ เมื่อเข้าจาก Stack > Add Stack
- ส่วน Build Method มี 4 แบบ
- Web Editor - เอาไฟล์ docker compose มาแปะเลย
- Upload เอาไฟล์ docker compose ขึ้นมา
- Repository ดึงมาจาก Git ทำพวก GitOps แบบ ArgoCD
- Custom Template
ตอนเลือกแต่ละแบบ การตั้งแต่ของแต่ละ Build Method ไว้เดี๋ยวหาทางแยก Blog
มันรองรับ GitOps ด้วยนะ แต่ผมว่า Blog นี้เริ่มยาวแล้ว เดี๋ยวไปต่อ Blog หน้าดีกว่าครับ


- ส่วนที่สอง การกำหนดสิทธิ ผมเอาง่าย จะให้ administrator เป็นหลักครับ
- ถ้าพร้อมแล้วกด Deploy The Stack ครับ
ลอง Deploy สัก Stack ผมได้เตรียม docker compose ไว้แล้วตามนี้
- เข้าจาก Stack > Add Stack จากนั้นเอา docker compose มาแปะได้เลยครับ จริงๆ พวก Enviroment ถ้าไม่อยาก Fixed ค่าลง Text เอามาเป็นตัวแปรไว้ใน Section Enviroment ด้านล่างได้ครับ

- ถ้าไม่มีอะไรแก้แล้วกด Deploy The Stack จากนั้นรอ เพราะช่วงนี้มันทำคำสั่ง
docker compose up -d
ให้ - เมื่อลงเสร็จ กลับมาที่ Enviroment > Container จะพบ Container ขึ้นมาแล้ว และถ้าลองเข้าไปจะเ็นหน้าจอ Setup WordPress ครับ


- ถ้าลองไปดู Network / Volume มันจะสร้างมาให้ด้วย


- ถ้ากลับไปดูที Stack มีข้อมูลสรุป + การจัดการ ถ้าใช้บ่อย ยกเป็นไปเป็น Template ได้ (Create Template)

Container Management
สำหรับส่วนนี้มาเน้นเฉพาะ Container กันแล้ว ว่าเราทำอะไรกับมันได้บ้าง
- Actions คุม Container Start Stop Restart

- Container status - ดูข้อมูลทั่วไปแบบ docker ps แต่จะมี
- Log
- docker inspect
- docker stats ดู resource Resource
- console Access เข้าไปใน Container docker exex ....

- Access control - บอกว่า user ของ portainer เองใครมายุ่งกับ Container นี้ได้บ้าง

- Create image - สำหรับต้องการ Commit ให้ได้ image ใหม่ แล้วไปใช้งานที่อื่น ถ้า Command ประกาศนี้
docker commit c3f279d12e0a dev.ds.local/invsapi:v1.2.5

- Container details - ข้อมูล Container เรียกว่าสรุปจาก docker inspect มาให้ ว่า ใช้ image อะไร / port mapping / env / labels เป็นต้น
- Volumes - บอกว่ามี Volume อะไรที่ใช้งานบ้าง
- Connected networks - บอกว่า Container ตัวนี้ต่อกับ Network ไหนบ้าง

Add Container Registry
เราสามารถเพิ่ม registry ได้ นอกจากที่ระบบ default docker.io ได้จาก 2 จุดครับ

- จากส่วนกลาง Setting > Registries ทุก Environment เห็มหมด
- จากแต่ละ Environment โดยจาก Host > registries (Environment registries) จะเห็นใน Environment นั้นๆ
ตัวอย่าง Add Registry



ถ้าไปดูในส่วน Environment registries จริงๆเราเห็นเท่ากันหมดทุกอันนะ แต่เราจะกำหนด Access ได้ ว่า user ไหน team ไหนใช้งานได้ครับ จากตรง Manage Access แต่ปกติผมเปิดหมดแหละ

ถ้าไปดูจุดที่ใช้ registry จากเดิม Dropdown จะมีตัวเดว ตอนนี้จะมีตามที่เรากำหนดไว้แล้วครับ

น่าจะหมดและสำหรับการติดตั้ง และแนะนำการใช้งาน Portainer เบื้องต้นครับ เด๊๋ยวว่างๆจะมาเขียนตัว Portainer กับงานด้าน GitOps ครับ และต่อกับอื่นๆที่ไม่ใช่ docker พวก Kubernetes / ACI ด้วยครับ
Reference
Discover more from naiwaen@DebuggingSoft
Subscribe to get the latest posts sent to your email.