2016
Nov
27

如何使用 Docker 建立一個 Linux Server (CentOS 7) 呢 ,我要用 Docker 建一個 Linux container ,並且讓我可以從遠端登入這個 container ,把它當作一台 Linux Server 開發機。

如果你還不知道 Docker 是什麼,請先閱讀以下文章:

在沒有 Docker 以前,我時常用 VirtualBox 裝一台Linux Server 拿來當做開發機,甚至我曾經用 VirtualBox 的機器當線上環境使用,會使用 VirtualBox 最重要的原因是很容易還原整個環境,假如今天我的機器硬碟壞掉了,那麼我只要再買一顆硬碟,裝上 OS 與 VirtualBox ,再把備份的 VirtualBox Image 複製過來就完成了系統還原。

新技術 Docker 現在已經可以取代 VirtualBox 大部分的功能,而且效能比 VirtualBox 好,最棒的是 Docker 可以用 Terminal 來操作,完全不需要使用到 GUI 介面,我只要用 SSH client 登入 OS ,就能單靠指令來完成 Docker container 任何作業, VirtualBox 理論上也可以用指令來完成所有作業,只是 VirtualBox 的指令有點難懂,而且網路上的文件很少。


建立 Centos 7 Contatiner

我們要先建立一個 Dockerfile ,這支 Dockerfile 會執行以下指令:

Dockerfile for logining linux
  1. FROM centos
  2. RUN yum install -y sudo wget telnet openssh-server vim git
  3. RUN useradd puritys
  4.  
  5. COPY files/authorized_keys /home/puritys/.ssh/
  6. COPY files/start.sh /root/
  7.  
  8. # Enable sshd
  9. COPY files/sshd_config /etc/ssh/
  10. RUN ssh-keygen -f /etc/ssh/ssh_host_rsa_key -N '' -t rsa
  11.  
  12. # Add account into sudoers and this account don't need to type password
  13. COPY files/sudoers /etc/
  • 第 1 行:安裝 Centos 。
  • 第 3 行:用 yum 安裝常用的軟體 。
  • 第 4 行:建立一個帳號,我的帳號是 "puritys" ,你要改成你自已的帳號 。
  • 第 6 行:複製 authorized_keys 這個檔案,這個檔案主要是用來給 ssh private key 登入
  • 第 7 行:複製 /root/start.sh ,這個 script 主要是寫下 container 開機時要啟動的 command ,因為 Docker 預設開機是不會執行任何程式,我們必須要手動執行寫好的 script ,還記得我們需要 Remote Login 的功能嗎, Remote Login 的功能需要啟動 sshd 這個程式,後面會說明 start.sh 要寫些什麼。
  • 第 10 行:複製 /etc/sshd_config ,這個檔案是 sshd 的設定檔。
  • 第 11 行: 產生一組 sshd 專用的 rsa private key 。
  • 第 14 行: 複製 /etc/sudoers , 這個檔案是 sudo 的設定檔,登入 container 後,我們會需要用到 sudo 的功能,所以要修改 /etc/sudoers 的設定。

authorized_keys

第 6 行的 authorized_keys 這個檔案存的資料是 public key ,你可以用 ssh-keygen -t rsa -b 4096 這個指令建立 private/public key ,成功建立後,你會看到兩個檔案,分別是 id_rsa, id_rsa.pub ,而 authorized_keys 就是 id_rsa.pub 。

ssh-keygen
  1. > ssh-keygen -t rsa -b 4096
  2. Generating public/private rsa key pair.
  3. Enter file in which to save the key (/Users/account/.ssh/id_rsa):
  4. Enter passphrase (empty for no passphrase):
  5. Enter same passphrase again:
  6. Your identification has been saved in id_rsa.
  7. Your public key has been saved in id_rsa.pub.
  8. The key fingerprint is:
  9. ---
  10. The key's randomart image is:
  11. +--[ RSA 4096]----+
  12. | .oo. + |
  13. | o =.* |
  14. | z..oB + |
  15. | ..o = . |
  16. | z. o c |
  17. | . . + |
  18. | . S |
  19. | |
  20. | |
  21. +-----------------+

sshd_config

還記得第 3 行 yum 安裝的軟體嗎,其中一個 openssh-server 就是 sshd 的軟體,必需先安裝這個軟體,我們才能遠端登入 container 。

我建立的 container 不希望有 "登入打密碼" 的功能,只要開放 ssh private key 登入功能即可,所以我要覆寫原有的 sshd_config ,把 ChallengeResponseAuthentication, PasswordAuthentication, PermitEmptyPasswords 這三個值設成 no 。

sshd_config
  1. HostKey /etc/ssh/ssh_host_rsa_key
  2. SyslogFacility AUTHPRIV
  3.  
  4. RSAAuthentication yes
  5. PubkeyAuthentication yes
  6. AuthorizedKeysFile .ssh/authorized_keys
  7.  
  8. ChallengeResponseAuthentication no
  9. PasswordAuthentication no
  10. PermitEmptyPasswords no
  11.  
  12. UsePAM yes
  13. X11Forwarding yes
  14. UsePrivilegeSeparation sandbox
  15.  
  16. AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
  17. AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
  18. AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
  19. AcceptEnv XMODIFIERS
  20.  
  21. # override default of no subsystems
  22. Subsystem sftp /usr/libexec/openssh/sftp-server

sudoers

第 14 行的 COPY sudoers ,如何要使用 sudo 的功能,就要安裝 sudo 這個軟體,所以 Dockerfile 第 3 行的 yum 指令就已經包含了 yum install sudo ,另一個問題是,一般我們在使用 sudo 的時候,系統會要求我們輸入密碼,但是我們新建的帳號並沒有密碼,所以我要在 sudoers 檔案裡加入一行 "puritys ALL=(ALL) NOPASSWD:ALL",讓我的帳號在執行 sudo 時,可以不用輸入密碼 (記得把 puritys 改成你的帳號)。

/etc/sudoers
  1. Defaults requiretty
  2. Defaults !visiblepw
  3.  
  4. Defaults always_set_home
  5.  
  6. Defaults !env_reset
  7.  
  8. Defaults secure_path = /sbin:/bin:/usr/sbin:/usr/bin
  9. root ALL=(ALL) ALL
  10. %wheel ALL=(ALL) ALL
  11.  
  12. puritys ALL=(ALL) NOPASSWD:ALL

start.sh

第 7 行的 start.sh ,這是指開機啟動要執行的程式,因為我只需要啟動 sshd ,所以加入 "/usr/sbin/sshd -D&" 就行囉。

start.sh
  1. #!/bin/bash
  2. /usr/sbin/sshd -D&

把上述的檔案都放都 files/ 這個資料夾下即可,請比對下圖的檔案結構,是否每個檔案都存在,再來就要建立我們設定的這台 docker image。

tree
  1. ├── centos7
  2. │ ├── Dockerfile
  3. │ ├── files
  4. │ │ ├── authorized_keys
  5. │ │ ├── sshd_config
  6. │ │ ├── start.sh
  7. │ │ └── sudoers

建立 Docker Image

完成上述的檔案建置後,我們要 build Docker Image ,再啟動 Docker ,執行 start.sh ,然後用另一個帳號登入 container 。

首先我要設定兩個變數,一個是 image name ,另一個是 container name ,因為接下來的指令都會一直用到這兩個名字,所以習慣上我要建設定好變數。

Image/Container
  1. imageName=my/my-centos7
  2. containerName=my-centos7

使用 docker build 建立 Image。

  • docker build -t $(imageName) .

使用 docker run -d ,啟動 container 並放在背景執行,再用 docker exec 執行開機啟動檔。

  • docker run -d -t -p 8001:22 --name $(containerName) $(imageName) /bin/bash
  • docker exec -d $(containerName) bash -c "sh /root/start.sh"

這兩步做完之後,我們就成功啟動了一台 Linux 環境,裡面有我的帳號 puritys ,以及可以用來登入的 public key ,另外我用 "-p 8001:22" ,將Docker Host 8001 port 轉到 container 22 port ,所以你只要知道 Docker Host 的 IP ,就可以用 8001 登入 container ,例如我會用下面這個 ssh 登入我的 container 。

ssh 192.168.99.100 -p8001

我習慣把所有的指令寫在 Makefile ,這樣不但可以避免忘記指令,也方便我組合各種不同的 Linux 指令,下面提供給大家參考:

Makefile
  1. imageName=my/my-centos7
  2. containerName=my-centos7
  3.  
  4. build:
  5. docker build -t $(imageName) .
  6.  
  7. stop:
  8. docker stop -f $(containerName) || true
  9. docker rm -f $(containerName) || true
  10.  
  11. start:
  12. make stop
  13. docker run -d -t -p 8001:22 --name $(containerName) $(imageName) /bin/bash
  14. docker exec -d $(containerName) bash -c "sh /root/start.sh"
  15.  
  16. root:
  17. make stop
  18. docker run -t -i -p 8001:22 --name $(containerName) $(imageName) /bin/bash
  19.  
  20. login:
  21. ssh [email protected] -p8001

回應 (Leave a comment)