LXC (Linux Containers) คือ Operating-system-level virtualization หรือเป็นที่รู้จักกันในชื่อ container นั่นเอง ซึ่งมนุษย์ในสายงาน IT ทุกวันนี้(น่าจะ)รู้จักกันดีอยู่แล้ว จริงๆ LXC มีมานานมากแล้วแต่ไม่เป็นที่รู้จักเพราะการใช้งานของมันจะยุ่งยากพอควร (เมื่อเทียบกับ Docker) แต่ไม่ใช่อุปสรรคสำหรับการเรียนรู้ครับ ^^
อาจารย์ชาญวิทย์ อธิบายไว้แบบนี้:
Container จะเรียกให้ถูกต้องเป๊ะ ๆ คือ Software Container เป็น concept ของการสร้างสภาพแวดล้อมเฉพาะให้ซอฟต์แวร์ทำงานได้โดยไม่กวนกับซอฟต์แวร์ตัวอื่นบนระบบปฏิบัติการเดียวกัน โดยเฉพาะ Sun หรือ Linux นั้นมี concept ของ Container มานานแล้ว เช่น ใน Linux มี LXC เป็นตัวจัดการ container มาตั้งแต่ปี 2007-2008 หรือใน Solaris ก็มีระบบแบบเดียวกันมาตั้งแต่ปี 2004-2005
debit: https://sites.google.com/site/chanwit/blogs/what-is-container
- Labtop ที่ Office ให้ใช้มันไม่เพียงพอกับการรัน VM (Virtual Machine) แค่รัน OS อย่างเดียวยังเกือบไม่รอด!
- ถ้าพูดถึง Container มีเจ้าหนึ่งที่ทำให้การใช้งาน Container แบบง่ายแสนง่ายก็คือ Docker แต่เราศึกษามาแล้วเลยอยากลอง LXC ดูบ้าง (เป็นความตั้งใจตั้งแต่สมัย Docker ยังไม่ดัง)
- Docker ทำให้การใช้งาน Container ง่ายก็จริง แต่!!! Docker ออกแบบมาเพื่อให้รัน เพียง 1 service ต่อ 1 container (จริงๆ รันหลายๆ service ได้มีท่าให้ทำแต่ไม่แนะนำ)
- LXC มีความเข้าใกล้ VM มากกว่า แต่ก็ยังคงความเป็น Container ได้ดี ฉะนั้นตัวเลือกนี้เหมาะที่สุดสำหรับการรันหลายๆ Services ใน Container เดียว LXC... ฉันเลือกนายยย!!!
สสำหรับบทความนี้ Fedora 26 ในการอธิบาย ฉะนั้นหากใครที่หลงมาอ่านแล้วใช้ Linux เจ้าอื่นอยู่ลอง Search ดูจากเน็ตนะครับ มีเพียบ!
$ sudo dnf install lxc lxc-templates lxc-extra debootstrap libvirt perl gpg
$ sudo systemctl start libvirtd.service
$ sudo systemctl enable libvirtd.service
$ sudo systemctl start lxc.service
$ sudo systemctl enable lxc.service
$ sudo systemctl status libvirtd.service
- Output:
● libvirtd.service - Virtualization daemon
Loaded: loaded (/usr/lib/systemd/system/libvirtd.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2017-09-21 20:43:53 +07; 3min 3s ago
Docs: man:libvirtd(8)
http://libvirt.org
Main PID: 979 (libvirtd)
Tasks: 18 (limit: 32768)
Memory: 38.6M
CPU: 521ms
CGroup: /system.slice/libvirtd.service
├─ 979 /usr/sbin/libvirtd
├─1316 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script=/usr/libexec/libvirt_leaseshelper
└─1317 /usr/sbin/dnsmasq --conf-file=/var/lib/libvirt/dnsmasq/default.conf --leasefile-ro --dhcp-script=/usr/libexec/libvirt_leaseshelper
Sep 21 20:44:01 fedora-vm dnsmasq[1316]: compile time options: IPv6 GNU-getopt DBus no-i18n IDN DHCP DHCPv6 no-Lua TFTP no-conntrack ipset auth DNSSEC loop-detect inotify
Sep 21 20:44:01 fedora-vm dnsmasq-dhcp[1316]: DHCP, IP range 192.168.124.2 -- 192.168.124.254, lease time 1h
Sep 21 20:44:01 fedora-vm dnsmasq-dhcp[1316]: DHCP, sockets bound exclusively to interface virbr0
Sep 21 20:44:01 fedora-vm dnsmasq[1316]: reading /etc/resolv.conf
Sep 21 20:44:01 fedora-vm dnsmasq[1316]: using nameserver 192.168.1.1#53
Sep 21 20:44:01 fedora-vm dnsmasq[1316]: using nameserver 110.164.252.222#53
Sep 21 20:44:01 fedora-vm dnsmasq[1316]: using nameserver 110.164.252.223#53
Sep 21 20:44:01 fedora-vm dnsmasq[1316]: read /etc/hosts - 2 addresses
Sep 21 20:44:01 fedora-vm dnsmasq[1316]: read /var/lib/libvirt/dnsmasq/default.addnhosts - 0 addresses
Sep 21 20:44:01 fedora-vm dnsmasq-dhcp[1316]: read /var/lib/libvirt/dnsmasq/default.hostsfile
$ sudo systemctl status lxc.service
- Output:
● lxc.service - LXC Container Initialization and Autoboot Code
Loaded: loaded (/usr/lib/systemd/system/lxc.service; enabled; vendor preset: disabled)
Active: active (exited) since Thu 2017-09-21 20:44:01 +07; 6min ago
Docs: man:lxc-autostart
man:lxc
Process: 1302 ExecStart=/usr/libexec/lxc/lxc-containers start (code=exited, status=0/SUCCESS)
Process: 1300 ExecStartPre=/usr/libexec/lxc/lxc-apparmor-load (code=exited, status=0/SUCCESS)
Main PID: 1302 (code=exited, status=0/SUCCESS)
Tasks: 0 (limit: 4915)
Memory: 0B
CPU: 0
CGroup: /system.slice/lxc.service
Sep 21 20:44:00 fedora-vm systemd[1]: Starting LXC Container Initialization and Autoboot Code...
Sep 21 20:44:01 fedora-vm systemd[1]: Started LXC Container Initialization and Autoboot Code.
LXC ที่ติดตั้งนั้นจะใช้ bridge network เพื่อคุยกันระหว่าง Container ด้วยกันเอง และที่สำคัญต้องใช้วิ่งออกข้างนอกได้ด้วย หรือออกเน็ตนั่นเอง (ถ้าไม่มี bridge ให้สร้างขึ้นมาเองนะครับ)
เช็ค bridge ที่มีในเครื่องกันด้วยคำสั่ง:
$ sudo brctl show
- Output:
bridge name bridge id STP enabled interfaces
virbr0 8000.5254003d02b3 yes virbr0-nic
ได้ชื่อ bridge แล้ว (virbr0) ต่อไปก็แก้ไขไฟล์คอนฟิกของ lxc ให้ตรงกับ bridge ที่ได้
sudo vi /etc/lxc/default.conf
แก้บรรทัดที่ขึ้นต้นด้วย lxc.network.link
แล้วใส่ชื่อ bridge ที่ลงไป
lxc.network.type = veth
lxc.network.link = virbr0
lxc.network.flags = up
lxc.network.hwaddr = 00:16:3e:xx:xx:xx
ก่อนเริ่มใช้งาน LXC เช็คทุกอย่างว่าพร้อมแล้วหรือยังด้วยคำสั่ง:
$ lxc-checkconfig
- Output:
Kernel configuration not found at /proc/config.gz; searching...
Kernel configuration found at /boot/config-4.12.12-300.fc26.x86_64
--- Namespaces ---
Namespaces: enabled
Utsname namespace: enabled
Ipc namespace: enabled
Pid namespace: enabled
User namespace: enabled
Network namespace: enabled
--- Control groups ---
Cgroup: enabled
Cgroup clone_children flag: enabled
Cgroup device: enabled
Cgroup sched: enabled
Cgroup cpu account: enabled
Cgroup memory controller: enabled
Cgroup cpuset: enabled
--- Misc ---
Veth pair device: enabled
Macvlan: enabled
Vlan: enabled
Bridges: enabled
Advanced netfilter: enabled
CONFIG_NF_NAT_IPV4: enabled
CONFIG_NF_NAT_IPV6: enabled
CONFIG_IP_NF_TARGET_MASQUERADE: enabled
CONFIG_IP6_NF_TARGET_MASQUERADE: enabled
CONFIG_NETFILTER_XT_TARGET_CHECKSUM: enabled
FUSE (for use with lxcfs): enabled
--- Checkpoint/Restore ---
checkpoint restore: enabled
CONFIG_FHANDLE: enabled
CONFIG_EVENTFD: enabled
CONFIG_EPOLL: enabled
CONFIG_UNIX_DIAG: enabled
CONFIG_INET_DIAG: enabled
CONFIG_PACKET_DIAG: enabled
CONFIG_NETLINK_DIAG: enabled
File capabilities: enabled
Note : Before booting a new kernel, you can check its configuration
usage : CONFIG=/path/to/config /usr/bin/lxc-checkconfig
ณ เวลาที่ผมติดตั้ง ถ้ามันไม่สามารถใช้งานได้ผมยังไม่รู้ว่ามันจะขึ้นแบบไหน 555+
วิธีการสร้าง container ก็อารมณ์เดียวกันกับ Docker นั่นแหละครับ คือมันก็ต้องมี template ตั้งต้นไว้สำหรับรัน container อาจสร้างขึ้นมาเอง หรือ Download ของที่เขาทำไว้ให้แล้วก็ได้:
$ sudo lxc-create -t download -n container_name -- -d centos -r 6 -a amd64
อธิบาย:
คำสั่ง | ความหมาย | หมายเหตุ |
---|---|---|
lxc-create | คำสั่งสำหรับสร้าง container | - |
-t | template ที่จะใช้สร้าง container | ตัวอย่างระบุเป็น download |
-n | ตั้งชื่อให้ container | - |
-- | template-options | lxc-create -t download -h |
-d | distribution เช่น centos, ubuntu, debian, alpine เป็นต้น | ข้อมูลเพิ่มเติม |
-r | Release name หรือ version สำหรับ distribution นั้นๆ | ข้อมูลเพิ่มเติม |
-a | architecture ที่จะสร้าง i386 หรือ amd64 | ข้อมูลเพิ่มเติม |
- Output:
Setting up the GPG keyring
Downloading the image index
Downloading the rootfs
Downloading the metadata
The image cache is now ready
Unpacking the rootfs
---
You just created a CentOS container (release=6, arch=amd64, variant=default)
To enable sshd, run: yum install openssh-server
For security reason, container images ship without user accounts
and without a root password.
Use lxc-attach or chroot directly into the rootfs to set a root password
or create user accounts.
สร้าง container เสร็จก็จะโชวผลลัพธ์คล้ายๆ กับด้านบนนั่นแหละ จุดที่สำคัญๆ และควรให้ความสนใจ มีดังนี้
- container ที่สร้างจะไม่ได้ลง openssh-server เราต้อง console เข้าไปลงเองนะจ๊ะ เดี๋ยวจะ ssh เข้าเครื่องไม่ได้
- ให้คำสั่ง lxc-attach หรือ chroot เพื่อเข้าไปเปลี่ยน password ของ root ซะ ไม่งั้นถ้า ssh เข้าเครื่องไม่ได้อย่าหาว่าไม่เตือน
$ sudo chroot /var/lib/lxc/container_name/rootfs/ passwd
อธิบาย:
คำสั่ง | ความหมาย |
---|---|
sudo chroot /var/lib/lxc/container_name/rootfs/ passwd |
เปลี่ยน password ของ root |
sudo chroot /var/lib/lxc/container_name/rootfs/ passwd user_name |
เปลี่ยน password ของ user_name |
- Output:
Changing password for user root.
New password:
BAD PASSWORD: it is based on a dictionary word
Retype new password:
passwd: all authentication tokens updated successfully.
sudo lxc-start -n container_name
$ sudo lxc-ls -f
- Output:
NAME STATE AUTOSTART GROUPS IPV4 IPV6
centos-6 RUNNING 0 - 192.168.124.80 -
centos-7 STOPPED 0 - - -
debian-stretch STOPPED 0 - - -
ubuntu-xenial STOPPED 0 - - -
ในที่นี้ผมสั่ง start container ที่ชื่อ centos-6 จะเห็นว่า STATE เป็น RUNNING และได้รับ IP มาเป็นที่เรียบร้อย (แต่ละ container ก็จะมี IP เป็นของตัวเอง)
$ lxc-attach -n container_name
- lxc-attach - start a process inside a running container.
หรือแบบนี้ก็ได้:
$ lxc-console -n container_name
-
lxc-console - Launch a console for the specified container
-
Output:
[root@container_name /]#
- เข้าหน้า console แล้วก็ติดตั้ง package openssh-server เพื่อใช้สำหรับ ssh หรือใช้คำสั่งอื่นๆ เสมือนว่ามันคือ VM ที่เราสร้างปกตินั่นแหละ
[root@container_name /]# yum install openssh-server
Loaded plugins: fastestmirror
Setting up Install Process
Determining fastest mirrors
* base: mirrors.bangmodhosting.com
* extras: mirrors.bangmodhosting.com
* updates: mirrors.bangmodhosting.com
base | 3.7 kB 00:00
base/primary_db | 4.7 MB 00:12
extras | 3.4 kB 00:00
extras/primary_db | 29 kB 00:00
updates | 3.4 kB 00:00
updates/primary_db | 3.6 MB 00:03
Resolving Dependencies
--> Running transaction check
---> Package openssh-server.x86_64 0:5.3p1-123.el6_9 will be installed
--> Finished Dependency Resolution
Dependencies Resolved
==============================================================================================================================================================================================
Package Arch Version Repository Size
==============================================================================================================================================================================================
Installing:
openssh-server x86_64 5.3p1-123.el6_9 updates 329 k
Transaction Summary
==============================================================================================================================================================================================
Install 1 Package(s)
Total download size: 329 k
Installed size: 706 k
Is this ok [y/N]: y
Downloading Packages:
openssh-server-5.3p1-123.el6_9.x86_64.rpm | 329 kB 00:00
warning: rpmts_HdrFromFdno: Header V3 RSA/SHA1 Signature, key ID c105b9de: NOKEY
Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
Importing GPG key 0xC105B9DE:
Userid : CentOS-6 Key (CentOS 6 Official Signing Key) <centos-6-key@centos.org>
Package: centos-release-6-9.el6.12.3.x86_64 (@base)
From : /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-6
Is this ok [y/N]: y
Running rpm_check_debug
Running Transaction Test
Transaction Test Succeeded
Running Transaction
Installing : openssh-server-5.3p1-123.el6_9.x86_64 1/1
Verifying : openssh-server-5.3p1-123.el6_9.x86_64 1/1
Installed:
openssh-server.x86_64 0:5.3p1-123.el6_9
Complete!
- สั่งให้ openssh-server ทำงานทุกครั้งตอน เปิดเครื่อง หรือ boot
[root@container_name /]# chkconfig sshd on
[root@container_name /]# chkconfig --list sshd
sshd 0:off 1:off 2:on 3:on 4:on 5:on 6:off
$ sudo lxc-stop -n container_name
$ sudo lxc-destroy -f -n container_name
- Output:
Destroyed container container_name
CentOS 7 container:
$ sudo lxc-create -t download -n centos-7 -- -d centos -r 7 -a amd64
Ubuntu container:
$ sudo lxc-create -t download -n ubuntu-c1 -- -d ubuntu -r xenial -a amd64
Debian container:
$ sudo lxc-create -t download -n debian-stretch -- -d debian -r stretch -a amd64
Fedora container:
$ sudo lxc-create -t download -n fedora-c1 -- -d fedora -r 26 -a amd64
จบกันไปเรียบร้อยแล้ว สำหรับการติดตั้งและใช้งาน Linux Container หรือ LXC เพียงเท่านี้เราก็จะได้ server ที่เบาหวิว (เบากว่า VM มากกกกก) เป็นมิตรกับ Labtop กากๆ และพร้อมทำ Lab Ansible แล้วครับ แต่กว่าจะมาถึงจุดนี้ได้ มันไม่ง่ายเลย T_T สำหรับใครที่สนใจก็ลองไปศึกษาเพิ่มเติมได้ครับ มันยังอะไรให้ศึกษาอีกเยอะ ส่วนถ้าอะไรขาดหาย หรือ ผิดพลาดยังไง คอนเม้นต์ไว้เลยเดี๋ยวผมแวะเข้ามาแก้ไขให้ ^_^