這部份會提供的 Script:
- 建立一個 CentOS 7 Container
- 啟用一組 Container、查看現有 Container
- 登入 Container
- 停用所有 Container
以下部份,以簡化操作的 Script 進行 Container 的使用。Script 裡面有一些預設資訊,可以自行依需要調整。
此外,這邊的 Container 都是 root 權限去使用的,因此操作這些 Script 都要用 sudo 去執行。
以下內容的安排,先說明 Script 的使用方法,Script 的內文附在最後,可以直接複製到文字檔裡面使用。
建立一個 Container
第一次產生 Container 會下載 Package 到 /var/lxc/cache/ 裡面;若後續有調整初始 Container 內容,可以清掉 cache/ 目錄的 rootfs/ 再執行即可。通常第二次執行僅會檢查有無 Package 更新而已。
另外,所產生的 Container 會下載最新的 CentOS 7 環境,沒辦法指定舊的子版本
[user@lxc-lab ~]$ chmod +x ~/addcontainer.sh [user@lxc-lab ~]$ sudo ./addcontainer.sh container1 Host CPE ID from /etc/os-release: cpe:/o:centos:centos:7 Checking cache download in /var/cache/lxc/centos/x86_64/7/rootfs ... Downloading CentOS minimal ... Loaded plugins: fastestmirror Determining fastest mirrors * base: repos.lax.quadranet.com * updates: repos.lax.quadranet.com base | 3.6 kB 00:00:00 updates | 3.4 kB 00:00:00 Resolving Dependencies --> Running transaction check ---> Package chkconfig.x86_64 0:1.7.4-1.el7 will be installed 。。。中間略。。。 rmdir: failed to remove ‘/var/cache/lxc/centos/x86_64/7/partial/var/run’: Not a directory Download complete. Copy /var/cache/lxc/centos/x86_64/7/rootfs to /var/lib/lxc/container1/rootfs ... Copying rootfs to /var/lib/lxc/container1/rootfs ... sed: can't read /var/lib/lxc/container1/rootfs/etc/init/tty.conf: No such file or directory Storing root password in '/var/lib/lxc/container1/tmp_root_pass' chpasswd: cannot open /etc/passwd Expiring password for user root. passwd: Libuser error at line: 413 - Error replacing `/etc/passwd': Permission denied. passwd: Error sed: can't read /var/lib/lxc/container1/rootfs/etc/rc.sysinit: No such file or directory sed: can't read /var/lib/lxc/container1/rootfs/etc/rc.d/rc.sysinit: No such file or directory Container rootfs and config have been created. Edit the config file to check/enable networking setup. The temporary root password is stored in: '/var/lib/lxc/container1/tmp_root_pass' The root password is set up as expired and will require it to be changed at first login, which you should do as soon as possible. If you lose the root password or wish to change it without starting the container, you can change it from the host by running the following command (which will also reset the expired flag): chroot /var/lib/lxc/container1/rootfs passwd Done! [user@lxc-lab ~]$ [user@lxc-lab ~]$ sudo ./addcontainer.sh container2 Host CPE ID from /etc/os-release: cpe:/o:centos:centos:7 Checking cache download in /var/cache/lxc/centos/x86_64/7/rootfs ... Cache found. Updating... Loaded plugins: fastestmirror Determining fastest mirrors * base: mirrors.usc.edu * extras: repos-lax.psychz.net * updates: repos.lax.quadranet.com base | 3.6 kB 00:00:00 extras | 3.4 kB 00:00:00 updates | 3.4 kB 00:00:00 (1/4): extras/7/x86_64/primary_db | 156 kB 00:00:00 (2/4): base/7/x86_64/group_gz | 166 kB 00:00:00 (3/4): updates/7/x86_64/primary_db | 1.4 MB 00:00:01 (4/4): base/7/x86_64/primary_db | 6.0 MB 00:00:02 No packages marked for update Loaded plugins: fastestmirror Cleaning repos: base extras updates 0 package files removed Update finished Copy /var/cache/lxc/centos/x86_64/7/rootfs to /var/lib/lxc/container2/rootfs ... Copying rootfs to /var/lib/lxc/container2/rootfs ... sed: can't read /var/lib/lxc/container2/rootfs/etc/init/tty.conf: No such file or directory Storing root password in '/var/lib/lxc/container2/tmp_root_pass' Expiring password for user root. passwd: Success sed: can't read /var/lib/lxc/container2/rootfs/etc/rc.sysinit: No such file or directory sed: can't read /var/lib/lxc/container2/rootfs/etc/rc.d/rc.sysinit: No such file or directory Container rootfs and config have been created. Edit the config file to check/enable networking setup. The temporary root password is stored in: '/var/lib/lxc/container2/tmp_root_pass' The root password is set up as expired and will require it to be changed at first login, which you should do as soon as possible. If you lose the root password or wish to change it without starting the container, you can change it from the host by running the following command (which will also reset the expired flag): chroot /var/lib/lxc/container2/rootfs passwd Done! [user@lxc-lab ~]$
建議需要 Container 時,就直接用 Script 產生。若是直接複製 Container 目錄,還需要注意 Container 網卡 MAC 的調整,比較麻煩一點。
產生之後的東西都在 /var/lib/lxc/ 底下
[user@lxc-lab ~]$ sudo tree -L 2 /var/lib/lxc/ /var/lib/lxc/ ├── container1 │ ├── config │ ├── rootfs │ ├── rootfs.dev -> /dev/.lxc/container1.8eba53f8cf6dee28 │ └── tmp_root_pass └── container2 ├── config ├── rootfs ├── rootfs.dev -> /dev/.lxc/container2.8eba56f8cf6df341 └── tmp_root_pass 6 directories, 4 files [user@lxc-lab ~]$
其中所有資料都在 rootfs/ 子目錄裡面,裡面有完整的 OS 目錄樹,平時放檔案可以從外面直接放進去也沒關係
[user@lxc-lab ~]$ sudo tree -d -L 2 /var/lib/lxc/container1 /var/lib/lxc/container1 ├── rootfs │ ├── bin -> usr/bin │ ├── boot │ ├── dev │ ├── etc │ ├── home │ ├── lib -> usr/lib │ ├── lib64 -> usr/lib64 │ ├── media │ ├── mnt │ ├── opt │ ├── proc │ ├── root │ ├── run │ ├── sbin -> usr/sbin │ ├── selinux │ ├── srv │ ├── sys │ ├── tmp │ ├── usr │ └── var └── rootfs.dev -> /dev/.lxc/container1.8eba53f8cf6dee28 22 directories [user@lxc-lab ~]$
查看現有 Container
這邊列出長兩個 Container 的狀況
[user@lxc-lab ~]$ chmod +x ~/startenv.sh [user@lxc-lab ~]$ sudo ./startenv.sh Below is the List of Available containers NAME STATE IPV4 IPV6 AUTOSTART ------------------------------------------ container1 STOPPED - - YES container2 STOPPED - - YES [user@lxc-lab ~]$
這邊的 Autostart 是透過 systemctl 指令控制 lxc 啟動停止的功能。
啟用一組 Container
這邊示範的是直接手動啟動 Container,不是使用 systemctl 指令啟動。兩種啟動方式的差異,主要是透過 SystemD 去啟動的 Container,Container 裡面的 SystemD 服務也會隨著 Container 「開機」而一併啟動;本處手動啟動的方式則否,需要進入 Container 之後手動以 systemctl 指令啟動 Container 裡面的服務
[user@lxc-lab ~]$ sudo ./startenv.sh container1 container2 Starting container environment container1 Starting container environment container2 [user@lxc-lab ~]$ [user@lxc-lab ~]$ sudo ./startenv.sh Below is the List of Available containers NAME STATE IPV4 IPV6 AUTOSTART --------------------------------------------------- container1 RUNNING 192.168.68.11 - YES container2 RUNNING 192.168.68.12 - YES [user@lxc-lab ~]$ sudo lxc-info -n container1 Name: container1 State: RUNNING PID: 4169 IP: 192.168.68.11 CPU use: 0.13 seconds BlkIO use: 8.20 MiB Memory use: 6.95 MiB KMem use: 0 bytes Link: vethK3UW2X TX bytes: 1.65 KiB RX bytes: 2.62 KiB Total bytes: 4.27 KiB [user@lxc-lab ~]$ sudo lxc-info -n container2 Name: container2 State: RUNNING PID: 4213 IP: 192.168.68.12 CPU use: 0.19 seconds BlkIO use: 4.12 MiB Memory use: 4.23 MiB KMem use: 0 bytes Link: veth4LSL5W TX bytes: 2.32 KiB RX bytes: 3.20 KiB Total bytes: 5.52 KiB [user@lxc-lab ~]$
透過 systemctl 啟動 Container 的方式如下
[user@lxc-lab ~]$ sudo service lxc start Redirecting to /bin/systemctl start lxc.service [user@lxc-lab ~]$
登入某個 Container 的 TTY Console
由於 CentOS 的 LXC Container Template 主要是在 CentOS 6 的時候準備的,在 CentOS 7 的部份,TTY Console 美有確切啟用多組的設定,因此目前僅以 TTY0 登入。若需要更多的登入,可以使用 ssh 登入。
登入之後,可以觀察到 Container 裡面的網卡界面都是 eth0(不用管@ 後面的部份),也可以用來綁 Virtual IP(限同網段的 IP?)
以下分別 ping 外部 網址(Google 首頁)、另一個 Container、Container Host 確認網路有通,另外再用 curl 存取一個網站確認不是只有 ping 的通而已。若需要以 Container Hostname 相互溝通,請直接調整個別 Container 的 /etc/hosts 內容(可以直接從「外面」修改 /var/lib/lxc/xxx/rootfs/etc/hosts 就好了~不用一個個登入)
另外,裡面也可以正常使用 SystemD 的指令,以下簡單用查看狀態作示範
[user@lxc-lab ~]$ chmod +x ~/envlogin.sh [user@lxc-lab ~]$ sudo ./envlogin.sh container1 Connected to tty 0 Typeto exit the console, to enter Ctrl+a itself ↲ CentOS Linux 7 (Core) Kernel 3.10.0-957.1.3.el7.x86_64 on an x86_64 container1 login: root Password: root [root@container1 ~]# [root@container1 ~]# ping www.google.com PING www.google.com (74.125.69.99) 56(84) bytes of data. 64 bytes from iq-in-f99.1e100.net (74.125.69.99): icmp_seq=1 ttl=51 time=0.805 ms 64 bytes from iq-in-f99.1e100.net (74.125.69.99): icmp_seq=2 ttl=51 time=0.478 ms 64 bytes from iq-in-f99.1e100.net (74.125.69.99): icmp_seq=3 ttl=51 time=0.309 ms ^C --- www.google.com ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2001ms rtt min/avg/max/mdev = 0.309/0.530/0.805/0.207 ms [root@container1 ~]# [root@container1 ~]# ip a 1: lo: mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 4: eth0@if5: mtu 1500 qdisc noqueue state UP group default qlen 1000 link/ether fe:07:3c:13:65:26 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 192.168.68.11/24 brd 192.168.68.255 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::fc07:3cff:fe13:6526/64 scope link valid_lft forever preferred_lft forever [root@container1 ~]# [root@container1 ~]# ping 192.168.68.12 PING 192.168.68.12 (192.168.68.12) 56(84) bytes of data. 64 bytes from 192.168.68.12: icmp_seq=1 ttl=64 time=0.079 ms 64 bytes from 192.168.68.12: icmp_seq=2 ttl=64 time=0.063 ms 64 bytes from 192.168.68.12: icmp_seq=3 ttl=64 time=0.064 ms --- 192.168.68.12 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 1999ms rtt min/avg/max/mdev = 0.063/0.068/0.079/0.012 ms [root@container1 ~]# ping 192.168.68.10 PING 192.168.68.10 (192.168.68.10) 56(84) bytes of data. 64 bytes from 192.168.68.10: icmp_seq=1 ttl=64 time=0.051 ms 64 bytes from 192.168.68.10: icmp_seq=2 ttl=64 time=0.071 ms 64 bytes from 192.168.68.10: icmp_seq=3 ttl=64 time=0.071 ms --- 192.168.68.10 ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 1999ms rtt min/avg/max/mdev = 0.051/0.064/0.071/0.011 ms [root@container1 ~]# [root@container1 ~]# curl http://ftp.twaren.net/Linux/CentOS/7/ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <html> <head> <title>Index of /Linux/CentOS/7</title> </head> <body> <h1>Index of /Linux/CentOS/7</h1> <pre><img src="/icons/blank.gif" alt="Icon "> <a href="?C=N;O=D">Name</a> <a href="?C=M;O=A">Last modified</a> <a href="?C=S;O=A">Size</a> <a href="?C=D;O=A">Description</a><hr><img src="/icons/back.gif" alt="[DIR]"> <a href="/Linux/CentOS/">Parent Directory</a> - <img src="/icons/folder.gif" alt="[DIR]"> <a href="atomic/">atomic/</a> 29-Nov-2018 07:58 - <img src="/icons/folder.gif" alt="[DIR]"> <a href="centosplus/">centosplus/</a> 29-Nov-2018 23:54 - <img src="/icons/folder.gif" alt="[DIR]"> <a href="cloud/">cloud/</a> 29-Nov-2018 06:59 - <img src="/icons/folder.gif" alt="[DIR]"> <a href="configmanagement/">configmanagement/</a> 29-Nov-2018 07:59 - <img src="/icons/folder.gif" alt="[DIR]"> <a href="cr/">cr/</a> 02-Dec-2018 22:34 - <img src="/icons/folder.gif" alt="[DIR]"> <a href="dotnet/">dotnet/</a> 29-Sep-2017 20:33 - <img src="/icons/folder.gif" alt="[DIR]"> <a href="extras/">extras/</a> 29-Nov-2018 23:55 - <img src="/icons/folder.gif" alt="[DIR]"> <a href="fasttrack/">fasttrack/</a> 01-Sep-2017 19:08 - <img src="/icons/folder.gif" alt="[DIR]"> <a href="isos/">isos/</a> 27-Nov-2018 16:05 - <img src="/icons/folder.gif" alt="[DIR]"> <a href="nfv/">nfv/</a> 29-Nov-2018 07:59 - <img src="/icons/folder.gif" alt="[DIR]"> <a href="opstools/">opstools/</a> 29-Nov-2018 07:59 - <img src="/icons/folder.gif" alt="[DIR]"> <a href="os/">os/</a> 11-Dec-2018 05:51 - <img src="/icons/folder.gif" alt="[DIR]"> <a href="paas/">paas/</a> 29-Nov-2018 07:58 - <img src="/icons/folder.gif" alt="[DIR]"> <a href="rt/">rt/</a> 11-Feb-2017 05:18 - <img src="/icons/folder.gif" alt="[DIR]"> <a href="sclo/">sclo/</a> 29-Nov-2018 07:56 - <img src="/icons/folder.gif" alt="[DIR]"> <a href="storage/">storage/</a> 29-Nov-2018 07:58 - <img src="/icons/folder.gif" alt="[DIR]"> <a href="updates/">updates/</a> 29-Nov-2018 23:57 - <img src="/icons/folder.gif" alt="[DIR]"> <a href="virt/">virt/</a> 29-Nov-2018 07:58 - <hr></pre> <address>Microsoft-IIS/6.0 Server at ftp.twaren.net Port 80</address> </body></html> [root@container1 ~]# [root@container1 ~]# service httpd status Redirecting to /bin/systemctl status httpd.service ● httpd.service - The Apache HTTP Server Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled) Active: inactive (dead) Docs: man:httpd(8) man:apachectl(8) [root@container1 ~]# [root@container1 ~]# exit logout ↲ CentOS Linux 7 (Core) Kernel 3.10.0-957.1.3.el7.x86_64 on an x86_64 container1 login: ^a q[user@lxc-lab ~]$ ↲ [user@lxc-lab ~]$
停止所有 Container
停止每個 Container 會花約一分鐘的時間,請耐心等候。也可以直接 VM 關機
[user@lxc-lab ~]$ chmod +x ~/stopenv.sh [user@lxc-lab ~]$ sudo ./stopenv.sh Stopping container environment container1 Stopping container environment container2 [user@lxc-lab ~]$ [user@lxc-lab ~]$ sudo ./startenv.sh Below is the List of Available containers NAME STATE IPV4 IPV6 AUTOSTART ------------------------------------------ container1 STOPPED - - YES container2 STOPPED - - YES [user@lxc-lab ~]$
設定開機啟動 Container
不要開機啟動的 Container,把 config 裡面的 autostart 功能(lxc.start.auto)註解掉就好
[user@lxc-lab ~]$ sudo service lxc start Redirecting to /bin/systemctl start lxc.service [user@lxc-lab ~]$ sudo ./startenv.sh Below is the List of Available containers NAME STATE IPV4 IPV6 AUTOSTART --------------------------------------------------- container1 RUNNING 192.168.68.11 - YES container2 RUNNING 192.168.68.12 - YES [user@lxc-lab ~]$ [user@lxc-lab ~]$ sudo chkconfig lxc on Note: Forwarding request to 'systemctl enable lxc.service'. Created symlink from /etc/systemd/system/multi-user.target.wants/lxc.service to /usr/lib/systemd/system/lxc.service. [user@lxc-lab ~]$
相關的 Script 與常用的 LXC 指令
1) 初始化一個 Container:預設:
- 檔名 ~/addcontainer.sh
- root 密碼為 root
- IP 從 192.168.68.11 開始抽,簡單的靠現在 Container 數量來數新增的 IP
- 有放置開機啟動的選項,可以隨 lxc 服務被帶起來
- Gateway 為 Host 的 virbr0 的 IP,192.168.68.10
- 在 Container 裡面設定 DNS 主機為 Host OS
#!/bin/bash CONTAINERNAME=$1 CNT="`lxc-ls |wc -l`" IPLAST=$((11+$CNT)) lxc-create -t centos -n $CONTAINERNAME cat << EOF >> /var/lib/lxc/${CONTAINERNAME}/config # Manual Setting lxc.network.ipv4 = 192.168.68.$IPLAST/24 lxc.network.ipv4.gateway = 192.168.68.10 lxc.start.auto = 1 # Fix some portential journald high CPU consumption lxc.kmsg = 0 EOF setenforce 0 echo "root:root" | chroot /var/lib/lxc/${CONTAINERNAME}/rootfs chpasswd echo "nameserver 192.168.68.10" >> /var/lib/lxc/${CONTAINERNAME}/rootfs/etc/resolv.conf echo "Done!" exit 0;
2) 啟動(數個)Container
- 檔名:~/startenv.sh
- 接受數個 container 名稱一起啟動
- 不給參數時,直接列出現有的 Container 清單
#!/bin/bash if [ "$#" -eq 0 ] then echo "Below is the List of Available containers" lxc-ls -f exit 0 fi STARTLST=( "$@" ) for i in "${STARTLST[@]}" do echo "Starting container environment $i" lxc-start -d -n $i done
3) 登入 Container
- 檔名:~/envlogin.sh
- 指定 TTY0 登入
- 接受已經啟動的 Container 名稱
- 要跳離開 Console,請先按 Ctrl+a 然後按 q 即可跳出
#!/bin/bash lxc-console -t 0 -n $1
4) 停止全部 Container
- 檔名:~/stopenv.sh
- 直接停止全部 Container
#!/bin/bash LXCLST=(`lxc-ls`) for i in "${LXCLST[@]}" do echo "Stopping container environment $i" lxc-stop -n $i done
5) 一些 LXC 常用指令
以下指令在執行時接需要以 root 執行
列出現有的 Container
|
lxc-ls -f
|
查看一個 Container 的狀態
|
lxc-info -n <Container 名稱>
|
啟動一個 Container
|
lxc-start -d -n <Container 名稱>
|
停止一個 Container
|
lxc-stop -n <Container 名稱>
|
登入一個 Container 的 TTY Terminal
|
lxc-console -t 0 -n <Container 名稱>
|
不登入,直接執行指令
|
lxc-attach -n <Container 名稱> -- <指令>
|
停止 Container 之後作備份&解開
|
## 備份
cd /var/lib/lxc/<Container 名稱>/
tar --numeric-owner -czvf container_fs.tar.gz ./*
|
## 解開
mkdir /var/lib/lxc/<Container 名稱>/
cd /var/lib/lxc/<Container 名稱>/
tar --numeric-owner -xzvf container_fs.tar.gz ./
| |
刪掉指定的 Container
|
lxc-destroy -n <Container 名稱>
|
沒有留言:
張貼留言