這裡只有試著把 docker container 單純當作作業系統的操作,如果要完整的學習,可以到 Play with Docker Classroom 進行線上互動式教學~
Docker 要運作,首先要先弄到基底的 Container 映像檔,作為運作的虛擬 Linux 平台(該映像檔稱作 Base Image)。docker 有很活絡的社群(官方維護的平台 Docker Hub),或是企業服務(Docker Store),毋需自己建立 Base Image,直接上網「拉過來」。這裡讓我拉一個 CentOS 7 的 Container 過來~
願意的人,其實建議嘗試基於 Alpine Linux 的 Base Image,這款 Linux 的 Image 大小很輕量,使用的 C library 不是 glibc 而是 musi-c,是目前熱門的 Docker base Image~
先到 Docker Hub 找出要拉的映像檔,放到指令內:有很多人提供,這裡直接用官網的就好
bash-4.4$ docker pull centos:7
7: Pulling from library/centos
d9aaf4d82f24: Downloading [=======================================> ] 57.93MB/73.39MB
d9aaf4d82f24: Extracting [=============================================> ] 66.29MB/73.39MB
d9aaf4d82f24: Pull complete
Digest: sha256:4565fe2dd7f4770e825d4bd9c761a81b26e49cc9e3c9631c58cfc3188be9505a
Status: Downloaded newer image for centos:7
bash-4.4$
從 image 初始化一個 Container
直接進入一個 Container:一個 docker container 可以只有透過類似 chroot 的方式進入裡面的環境,而沒有將它「開機」。切入一個 docker container 有很多參數可以設置,例如資源限制(記憶體等~)、外部目錄(Volume)或是網路設置(IP,Port 等等~),具體可以用 docker run --help 查看
這裡用基本款:-i 指定 STDIN 繼續存在,-t 產生一個 TTY Console,兩個合併起來,就是切換到該 Container 的 Shell 環境
bash-4.4$ docker run -it --name my1stcontainer centos:7 /bin/bash [root@72d49d4d069d /]# cat /etc/*release CentOS Linux release 7.4.1708 (Core) NAME="CentOS Linux" VERSION="7 (Core)" ID="centos" ID_LIKE="rhel fedora" VERSION_ID="7" PRETTY_NAME="CentOS Linux 7 (Core)" ANSI_COLOR="0;31" CPE_NAME="cpe:/o:centos:centos:7" HOME_URL="https://www.centos.org/" BUG_REPORT_URL="https://bugs.centos.org/" CENTOS_MANTISBT_PROJECT="CentOS-7" CENTOS_MANTISBT_PROJECT_VERSION="7" REDHAT_SUPPORT_PRODUCT="centos" REDHAT_SUPPORT_PRODUCT_VERSION="7" CentOS Linux release 7.4.1708 (Core) CentOS Linux release 7.4.1708 (Core) [root@72d49d4d069d /]# exit exit bash-4.4$
跳出 Container 後,查看一下 docker 專用的 ps 指令
bash-4.4$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
72d49d4d069d centos:7 "/bin/bash" 4 minutes ago Exited (0) About a minute ago my1stcontainer
bash-4.4$
發現 Container 處在關機的狀態。
要再連到裡面的話,就正常的啟動(類似 lxc-start)
直接啟動一個 Container(開機):這裡使 docker container 正常的「開機」,然後便可以用 docker exec 登入的 terminal
bash-4.4$ ##查看外面 Kernel 版本 bash-4.4$ uname -a Linux darkstar 4.9.53 #2 SMP Thu Oct 5 21:45:02 CDT 2017 x86_64 Intel(R) Core(TM) i3-2310M CPU @ 2.10GHz GenuineIntel GNU/Linux bash-4.4$ docker start my1stcontainer my1stcontainer bash-4.4$ docker exec -it my1stcontainer /bin/bash [root@72d49d4d069d /]# ##查看裡面 Lernel 版本 [root@72d49d4d069d /]# uname -a Linux 72d49d4d069d 4.9.53 #2 SMP Thu Oct 5 21:45:02 CDT 2017 x86_64 x86_64 x86_64 GNU/Linux [root@72d49d4d069d /]# ps aux USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 5 0.0 0.5 11780 2740 pts/1 Ss 17:05 0:00 /bin/sh root 9 0.0 0.6 47456 3336 pts/1 R+ 17:05 0:00 ps aux [root@72d49d4d069d /]#
上面查看一下 Container 裡面的 Linux Kernel 版本,發現跟外面的是一樣的~這也是 Container 與 Host OS 共用 Kernel 的例證之一。
此外,查看裡面運行的 Process,會發現裡面的程序不像完整的作業系統,有很多 OS 的程序,僅包含當前運行的程式而已。這也是 Container 與 VM 的顯著差異點之一。
再看一下這個 CentOS 7 預先安裝了哪些套件,並裝一下 EPEL-release
[root@72d49d4d069d /]# rpm -qa centos-release-7-4.1708.el7.centos.x86_64 filesystem-3.2-21.el7.x86_64 basesystem-10.0-7.el7.centos.noarch nss-softokn-freebl-3.28.3-8.el7_4.x86_64 glibc-2.17-196.el7.x86_64 libstdc++-4.8.5-16.el7.x86_64 bash-4.2.46-29.el7_4.x86_64 pcre-8.32-17.el7.x86_64 zlib-1.2.7-17.el7.x86_64 xz-libs-5.2.2-1.el7.x86_64 libcom_err-1.42.9-10.el7.x86_64 popt-1.13-16.el7.x86_64 sed-4.2.2-5.el7.x86_64 elfutils-libelf-0.168-8.el7.x86_64 libffi-3.0.13-18.el7.x86_64 libattr-2.4.46-12.el7.x86_64 libacl-2.2.51-12.el7.x86_64 libuuid-2.23.2-43.el7.x86_64 readline-6.2-10.el7.x86_64 gawk-4.0.2-4.el7_3.1.x86_64 libcap-ng-0.7.5-4.el7.x86_64 sqlite-3.7.17-8.el7.x86_64 findutils-4.5.11-5.el7.x86_64 expat-2.1.0-10.el7_3.x86_64 nss-softokn-3.28.3-8.el7_4.x86_64 p11-kit-0.23.5-3.el7.x86_64 file-libs-5.11-33.el7.x86_64 hostname-3.13-3.el7.x86_64 tar-1.26-32.el7.x86_64 pinentry-0.8.1-17.el7.x86_64 libdb-utils-5.3.21-20.el7.x86_64 libss-1.42.9-10.el7.x86_64 elfutils-default-yama-scope-0.168-8.el7.noarch ncurses-5.9-14.20130511.el7_4.x86_64 gmp-6.0.0-15.el7.x86_64 libsemanage-2.5-8.el7.x86_64 libtasn1-4.10-1.el7.x86_64 ca-certificates-2017.2.14-71.el7.noarch openssl-libs-1.0.2k-8.el7.x86_64 libblkid-2.23.2-43.el7.x86_64 libmount-2.23.2-43.el7.x86_64 shared-mime-info-1.8-3.el7.x86_64 cracklib-2.9.0-11.el7.x86_64 libpwquality-1.2.3-4.el7.x86_64 systemd-libs-219-42.el7_4.1.x86_64 pkgconfig-0.27.1-4.el7.x86_64 dbus-glib-0.100-7.el7.x86_64 binutils-2.25.1-32.base.el7_4.1.x86_64 nss-3.28.4-11.el7_4.x86_64 nss-tools-3.28.4-11.el7_4.x86_64 curl-7.29.0-42.el7.x86_64 rpm-4.11.3-25.el7.x86_64 libuser-0.60-7.el7_1.x86_64 hardlink-1.0-19.el7.x86_64 qrencode-libs-3.4.1-3.el7.x86_64 device-mapper-1.02.140-8.el7.x86_64 cryptsetup-libs-1.7.4-3.el7.x86_64 kmod-20-15.el7_4.2.x86_64 dbus-1.6.12-17.el7.x86_64 gdbm-1.10-8.el7.x86_64 python-2.7.5-58.el7.x86_64 dbus-python-1.1.1-9.el7.x86_64 pyliblzma-0.5.3-11.el7.x86_64 yum-metadata-parser-1.1.4-10.el7.x86_64 python-urlgrabber-3.10-8.el7.noarch pyxattr-0.5.1-5.el7.x86_64 python-kitchen-1.1.1-5.el7.noarch gnupg2-2.0.22-4.el7.x86_64 pygpgme-0.3-9.el7.x86_64 rpm-python-4.11.3-25.el7.x86_64 yum-3.4.3-154.el7.centos.noarch yum-plugin-ovl-1.1.31-42.el7.noarch passwd-0.79-4.el7.x86_64 vim-minimal-7.4.160-2.el7.x86_64 libgcc-4.8.5-16.el7.x86_64 setup-2.8.71-7.el7.noarch bind-license-9.9.4-51.el7.noarch ncurses-base-5.9-14.20130511.el7_4.noarch tzdata-2017b-1.el7.noarch glibc-common-2.17-196.el7.x86_64 nspr-4.13.1-1.0.el7_3.x86_64 ncurses-libs-5.9-14.20130511.el7_4.x86_64 libsepol-2.5-6.el7.x86_64 libselinux-2.5-11.el7.x86_64 info-5.1-4.el7.x86_64 bzip2-libs-1.0.6-13.el7.x86_64 libdb-5.3.21-20.el7.x86_64 chkconfig-1.7.4-1.el7.x86_64 nss-util-3.28.4-3.el7.x86_64 libxml2-2.9.1-6.el7_2.3.x86_64 libgpg-error-1.12-3.el7.x86_64 libcap-2.22-9.el7.x86_64 grep-2.20-3.el7.x86_64 libgcrypt-1.5.3-14.el7.x86_64 lua-5.1.4-15.el7.x86_64 cpio-2.11-25.el7_4.x86_64 audit-libs-2.7.6-3.el7.x86_64 libidn-1.28-4.el7.x86_64 diffutils-3.3-4.el7.x86_64 dbus-libs-1.6.12-17.el7.x86_64 libassuan-2.1.0-3.el7.x86_64 xz-5.2.2-1.el7.x86_64 keyutils-libs-1.5.8-3.el7.x86_64 acl-2.2.51-12.el7.x86_64 cyrus-sasl-lib-2.1.26-21.el7.x86_64 kmod-libs-20-15.el7_4.2.x86_64 elfutils-libs-0.168-8.el7.x86_64 ustr-1.0.4-16.el7.x86_64 libverto-0.2.5-4.el7.x86_64 p11-kit-trust-0.23.5-3.el7.x86_64 coreutils-8.22-18.el7.x86_64 krb5-libs-1.15.1-8.el7.x86_64 shadow-utils-4.1.5.1-24.el7.x86_64 glib2-2.50.3-3.el7.x86_64 gzip-1.5-9.el7.x86_64 cracklib-dicts-2.9.0-11.el7.x86_64 pam-1.1.8-18.el7.x86_64 procps-ng-3.3.10-16.el7.x86_64 gobject-introspection-1.50.0-1.el7.x86_64 libutempter-1.1.6-4.el7.x86_64 libssh2-1.4.3-10.el7_2.1.x86_64 nss-pem-1.0.3-4.el7.x86_64 nss-sysinit-3.28.4-11.el7_4.x86_64 libcurl-7.29.0-42.el7.x86_64 rpm-libs-4.11.3-25.el7.x86_64 openldap-2.4.44-5.el7.x86_64 util-linux-2.23.2-43.el7.x86_64 kpartx-0.4.9-111.el7.x86_64 device-mapper-libs-1.02.140-8.el7.x86_64 dracut-033-502.el7.x86_64 systemd-219-42.el7_4.1.x86_64 iputils-20160308-10.el7.x86_64 python-libs-2.7.5-58.el7.x86_64 python-iniparse-0.4-9.el7.noarch python-pycurl-7.19.0-19.el7.x86_64 python-gobject-base-3.22.0-1.el7.x86_64 libxml2-python-2.9.1-6.el7_2.3.x86_64 python-chardet-2.2.1-1.el7_1.noarch pth-2.0.7-23.el7.x86_64 gpgme-1.3.2-5.el7.x86_64 rpm-build-libs-4.11.3-25.el7.x86_64 yum-plugin-fastestmirror-1.1.31-42.el7.noarch yum-utils-1.1.31-42.el7.noarch qemu-guest-agent-2.8.0-2.el7.x86_64 rootfiles-8.1-11.el7.noarch [root@72d49d4d069d /]# [root@72d49d4d069d /]# yum install -y epel-release Loaded plugins: fastestmirror, ovl base | 3.6 kB 00:00:00 extras | 3.4 kB 00:00:00 updates | 3.4 kB 00:00:00 (1/4): base/7/x86_64/group_gz | 156 kB 00:00:00 (2/4): extras/7/x86_64/primary_db | 129 kB 00:00:01 (3/4): base/7/x86_64/primary_db | 5.7 MB 00:00:10 (4/4): updates/7/x86_64/primary_db | 3.6 MB 00:00:53 Determining fastest mirrors * base: ftp.yzu.edu.tw * extras: ftp.yzu.edu.tw * updates: ftp.yzu.edu.tw Resolving Dependencies --> Running transaction check ---> Package epel-release.noarch 0:7-9 will be installed --> Finished Dependency Resolution Dependencies Resolved ===================================================================================== Package Arch Version Repository Size ===================================================================================== Installing: epel-release noarch 7-9 extras 14 k Transaction Summary ===================================================================================== Install 1 Package Total download size: 14 k Installed size: 24 k Is this ok [y/d/N]: y Downloading packages: warning: /var/cache/yum/x86_64/7/extras/packages/epel-release-7-9.noarch.rpm: Header V3 RSA/SHA256 Signature, key ID f4a80eb5: NOKEY Public key for epel-release-7-9.noarch.rpm is not installed epel-release-7-9.noarch.rpm | 14 kB 00:00:00 Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 Importing GPG key 0xF4A80EB5: Userid : "CentOS-7 Key (CentOS 7 Official Signing Key)" Fingerprint: 6341 ab27 53d7 8a78 a7c2 7bb1 24c6 a8a7 f4a8 0eb5 Package : centos-release-7-4.1708.el7.centos.x86_64 (@CentOS) From : /etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7 Is this ok [y/N]: y Running transaction check Running transaction test Transaction test succeeded Running transaction Installing : epel-release-7-9.noarch 1/1 Verifying : epel-release-7-9.noarch 1/1 Installed: epel-release.noarch 0:7-9 Complete! [root@72d49d4d069d /]# [root@72d49d4d069d /]# exit exit bash-4.4$ docker stop my1stcontainer my1stcontainer bash-4.4$
檢查自己是不是位在 Container 裡面
linux - Determining if a process runs inside lxc/Docker - Stack Overflow
bash-4.4$ #正常 OS 中 PID 1 的 proc 目錄的 cgroup 內容 bash-4.4$ cat /proc/1/cgroup 11:pids:/ 10:net_prio:/ 9:perf_event:/ 8:net_cls:/ 7:freezer:/ 6:devices:/ 5:memory:/ 4:blkio:/ 3:cpuacct:/ 2:cpu:/ 1:cpuset:/ bash-4.4$ bash-4.4$ docker exec -it my1stcontainer /bin/bash [root@72d49d4d069d /]# cat /proc/1/cgroup 11:pids:/docker/72d49d4d069d6045aa97496672979777964bbdf3b66a48c167957f4dbdd13178 10:net_prio:/docker/72d49d4d069d6045aa97496672979777964bbdf3b66a48c167957f4dbdd13178 9:perf_event:/docker/72d49d4d069d6045aa97496672979777964bbdf3b66a48c167957f4dbdd13178 8:net_cls:/docker/72d49d4d069d6045aa97496672979777964bbdf3b66a48c167957f4dbdd13178 7:freezer:/docker/72d49d4d069d6045aa97496672979777964bbdf3b66a48c167957f4dbdd13178 6:devices:/docker/72d49d4d069d6045aa97496672979777964bbdf3b66a48c167957f4dbdd13178 5:memory:/docker/72d49d4d069d6045aa97496672979777964bbdf3b66a48c167957f4dbdd13178 4:blkio:/docker/72d49d4d069d6045aa97496672979777964bbdf3b66a48c167957f4dbdd13178 3:cpuacct:/docker/72d49d4d069d6045aa97496672979777964bbdf3b66a48c167957f4dbdd13178 2:cpu:/docker/72d49d4d069d6045aa97496672979777964bbdf3b66a48c167957f4dbdd13178 1:cpuset:/docker/72d49d4d069d6045aa97496672979777964bbdf3b66a48c167957f4dbdd13178 [root@72d49d4d069d /]#
查看狀況:使用 docker 的 ps 與 top,也可以搭配 watch
bash-4.4$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 72d49d4d069d centos:7 "/bin/bash" 4 weeks ago Up 49 seconds my1stcontainer bash-4.4$ docker top my1stcontainer UID PID PPID C STIME TTY TIME CMD root 2111 2095 0 15:30 pts/0 00:00:00 /bin/bash bash-4.4$ #用 watch 一直刷新 top bash-4.4$ watch docker top my1stcontainer bash-4.4$
從外面複製檔案到 Container 裡面的指令
bash-4.4$ echo 'hello' > ./local_file.txt bash-4.4$ docker cp ./local_file.txt my1stcontainer:/tmp/myfile.txt bash-4.4$ docker exec -it my1stcontainer /bin/ls /tmp ks-script-q6TWGF myfile.txt yum.log bash-4.4$ docker exec -it my1stcontainer /bin/cat /tmp/myfile.txt hello bash-4.4$ docker exec -it my1stcontainer /bin/rm /tmp/myfile.txt bash-4.4$ docker exec -it my1stcontainer /bin/ls /tmp ks-script-q6TWGF yum.log bash-4.4$
docker container 的「關機」:其實他是一個 Process,這裡作的是 Process 的中止
bash-4.4$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 72d49d4d069d centos:7 "/bin/bash" 3 days ago Up 7 seconds my1stcontainer bash-4.4$ docker stop my1stcontainer my1stcontainer bash-4.4$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 72d49d4d069d centos:7 "/bin/bash" 3 days ago Exited (137) 6 seconds ago my1stcontainer bash-4.4$ docker exec -it my1stcontainer /bin/bash Error response from daemon: Container 72d49d4d069d6045aa97496672979777964bbdf3b66a48c167957f4dbdd13178 is not running bash-4.4$
把現在建立的 Container 再打包起來:打包方式有兩種,一個是使用 Commit 打包成 Image;或是用 Export 匯出 Image。兩者的差別只有在 Export 會把操作的紀錄弄掉,產生出來的 Image 比 Commit 小~(資料:知名的 Docker —— 从入门到实践:匯入匯出容器的小節)
bash-4.4$ docker commit my1stcontainer sha256:61933ff730d0d1cbfd50a7a23770dec30887377ce71427ccdacbd311891a2f38 bash-4.4$ docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE61933ff730d0 30 seconds ago 276MB centos 7 d123f4e55e12 5 weeks ago 197MB bash-4.4$ docker export my1stcontainer -o ~/my1stimage.tar bash-4.4$ ls ~ Desktop Downloads local_file.txt my1stimage.tar bash-4.4$ du -h ~/my1stimage.tar 253M /home/cchsu/my1stimage.tar bash-4.4$
然後我們就可以複製剛剛異動過的 Container 所打包的 Image,再匯入一次:這裡會先匯入 Image,再依照新匯入的 Image 啟動一個 Contianer。
bash-4.4$ # 查看打包的內容~ bash-4.4$ tar --exclude="*/*" -tf ~/my1stimage.tar .dockerenv anaconda-post.log bin dev/ etc/ home/ lib lib64 lost+found/ media/ mnt/ opt/ proc/ root/ run/ sbin srv/ sys/ tmp/ usr/ var/ bash-4.4$ docker import ~/my1stimage.tar sha256:d376b22b96cc65b5abb97615bda87091b11e69f48f1b099f26b8e46fd4df294f bash-4.4$ docker image ls REPOSITORY TAG IMAGE ID CREATED SIZEd376b22b96cc 8 seconds ago 256MB 61933ff730d0 19 minutes ago 276MB centos 7 d123f4e55e12 5 weeks ago 197MB bash-4.4$
這樣一來,就可以簡單的把自己的設置帶著走,到處複製自己的環境了~
最後,把匯入的 image 刪掉
bash-4.4$ docker image rm d376b22b96cc Deleted: sha256:d376b22b96cc65b5abb97615bda87091b11e69f48f1b099f26b8e46fd4df294f Deleted: sha256:60ec8d737cd94f092b44ad1ae10c7eb5f7ba36fdbf2e9686e70f14711c445763 bash-4.4$ docker image ls REPOSITORY TAG IMAGE ID CREATED SIZE61933ff730d0 20 minutes ago 276MB centos 7 d123f4e55e12 5 weeks ago 197MB bash-4.4$
把 Container 打包成 Image,就類比成把 VM 映像檔「燒成光碟」一樣,讓人可以複製到他處重複開啟(甚至在裡面),但是 Container Image 比起 VM Image 實在是輕量太多了~
最後一提,上面登入 Container 好像都是以 root 帳號的樣子~~下次再來了解這部份。
上面的使用,主要只是單純把 Docker Container 當成作業系統在使用(由於 Base Image 都經過瘦身,因此需要自己多裝一點工具比較方便操作);然而真正 Docker 的強項,是利用輕巧的映像檔優化開發流程,建構流暢的 CI/CD 開發環境;或是利用 Docker 映像檔(dockerfile)堆疊+唯讀的特性,進行微服務的開發~不過這再等後續再來了解吧。
參考
Docker 實在是太熱門了~~不缺我這篇筆記,底下聊舉幾個參考資料
前言 · Docker —— 从入门到实践 (最新版)(主要!!)
沒有留言:
張貼留言