【117】利用 macvlan 把容器當成虛擬機器使用
一、製作可以遠端登入的Docker容器,系統是Ubuntu14.04。
這個章節記錄下了製作一個支援SSH遠端登入的容器的全過程。這篇文章使用 Ubuntu 14.04 做例子。其他的作業系統應該大同小異。
我這種用法,相當於把容器當成了虛擬機器。使用者可以遠端登入容器,在容器內進行各種操作。
第一個要面對的問題是:如何才能讓容器持久執行下去?眾所周知,容器要執行必須要有一個主程序。如果主程序終止,那麼容器就會自動退出。一開始我用 Ubuntu 14.04 的映象的時候就碰到了這個問題。比如你要是執行如下命令:
docker run --name ubuntu1 -d ubuntu:14.04
那麼你會發現容器 ubuntu1 根本沒有執行起來:
因此,我們需要一個程式作為容器的主程序無限執行下去。很多人也把這種無限執行的程式稱為守護程序(daemon)。
現在就需要編寫一個程式做主程序了。因為我熟悉 Java ,所以我使用 Java 來編寫主程序。Java 的開發工具使用 Eclipse 和 Maven。
Eclipse 中點選 File 選單,選中 New 選單項,在子選單中點選 Maven Project。在對話方塊中選中下面三項: Create a simple project
、User default Workspace location
和 Resolve Workspace projects
整個專案只需要一個包和一個 Java 類即可。src/main/java
下的包名是 dockerCmd,包中只有一個類 Main.java。
Main.java 的程式碼如下:
package dockerCmd;
import java.io.IOException;
/**
* Docker 容器 Ubuntu 14.04 的主程序,保證容器一直執行。
* @author 張超
*
*/
public class Main {
public static void main(String[] args) {
try {
// 啟動 ssh 服務。
Runtime.getRuntime().exec("sudo service ssh start");
} catch (IOException e1) {
e1.printStackTrace();
}
// 無限迴圈的主程序。
while (true){
try {
Thread.sleep(30L * 60L * 1000L);
} catch (InterruptedException e) {
}
}
}
}
pom.xml :
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>qst</groupId>
<artifactId>dockerCmd</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>dockerCmd.Main</mainClass> <!-- 你的主類名 -->
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>
右鍵點選 dockerCmd 專案,快捷選單中選擇 Run As
,子選單中點選 Maven build...
,彈出對話方塊。在對話方塊中, Goals 文字框中填入 clean package,點選 Run 按鈕。 在專案資料夾下會生成一個 target 資料夾,裡面有個 dockerCmd-0.0.1-SNAPSHOT.jar 檔案,就是我們需要的可執行 jar 包。
有了 java 程式後,就可以製作映象了。
新建一個 名為 qstubuntu-v3 的資料夾,目錄結構如下:
qstubuntu-v3
|
├─ dockerCmd-0.0.1-SNAPSHOT.jar
├─ Dockerfile
├─ jre-8u171-linux-x64.tar.gz
├─ sshd_config
└─ user.txt
Dockerfile
FROM ubuntu:14.04
# Set timezone as china/shanghai
RUN cp /usr/share/zoneinfo/PRC /etc/localtime
RUN mkdir /usr/java
# Copy jre install file
COPY jre-8u171-linux-x64.tar.gz /usr/java/
WORKDIR /usr/java/
RUN tar zxvf /usr/java/jre-8u171-linux-x64.tar.gz
RUN rm -rf /usr/java/jre-8u171-linux-x64.tar.gz
# Run server
RUN mkdir /qst
# Copy app jar file
COPY dockerCmd-0.0.1-SNAPSHOT.jar /qst/
# Install openssh
RUN sudo apt-get update && sudo apt-get install openssh-server -y
# Copy ssh config file.
COPY sshd_config /etc/ssh/
# Change root user's password.
COPY user.txt /qst/
RUN chpasswd < /qst/user.txt
EXPOSE 1-65535
CMD ["/usr/java/jre1.8.0_171/bin/java", "-jar", "/qst/dockerCmd-0.0.1-SNAPSHOT.jar"]
sshd_config
# Package generated configuration file
# See the sshd_config(5) manpage for details
# What ports, IPs and protocols we listen for
Port 22
# Use these options to restrict which interfaces/protocols sshd will bind to
#ListenAddress ::
#ListenAddress 0.0.0.0
Protocol 2
# HostKeys for protocol version 2
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
#Privilege Separation is turned on for security
UsePrivilegeSeparation yes
# Lifetime and size of ephemeral version 1 server key
KeyRegenerationInterval 3600
ServerKeyBits 1024
# Logging
SyslogFacility AUTH
LogLevel INFO
# Authentication:
LoginGraceTime 120
PermitRootLogin yes
StrictModes yes
RSAAuthentication yes
PubkeyAuthentication yes
#AuthorizedKeysFile %h/.ssh/authorized_keys
# Don't read the user's ~/.rhosts and ~/.shosts files
IgnoreRhosts yes
# For this to work you will also need host keys in /etc/ssh_known_hosts
RhostsRSAAuthentication no
# similar for protocol version 2
HostbasedAuthentication no
# Uncomment if you don't trust ~/.ssh/known_hosts for RhostsRSAAuthentication
#IgnoreUserKnownHosts yes
# To enable empty passwords, change to yes (NOT RECOMMENDED)
PermitEmptyPasswords no
# Change to yes to enable challenge-response passwords (beware issues with
# some PAM modules and threads)
ChallengeResponseAuthentication no
# Change to no to disable tunnelled clear text passwords
#PasswordAuthentication yes
# Kerberos options
#KerberosAuthentication no
#KerberosGetAFSToken no
#KerberosOrLocalPasswd yes
#KerberosTicketCleanup yes
# GSSAPI options
#GSSAPIAuthentication no
#GSSAPICleanupCredentials yes
X11Forwarding yes
X11DisplayOffset 10
PrintMotd no
PrintLastLog yes
TCPKeepAlive yes
#UseLogin no
#MaxStartups 10:30:60
#Banner /etc/issue.net
# Allow client to pass locale environment variables
AcceptEnv LANG LC_*
Subsystem sftp /usr/lib/openssh/sftp-server
# Set this to 'yes' to enable PAM authentication, account processing,
# and session processing. If this is enabled, PAM authentication will
# be allowed through the ChallengeResponseAuthentication and
# PasswordAuthentication. Depending on your PAM configuration,
# PAM authentication via ChallengeResponseAuthentication may bypass
# the setting of "PermitRootLogin without-password".
# If you just want the PAM account and session checks to run without
# PAM authentication, then enable this but set PasswordAuthentication
# and ChallengeResponseAuthentication to 'no'.
UsePAM yes
user.txt
root:123456
把整個 qstubuntu-v3 資料夾上傳到裝有 Docker 的伺服器上,通過 cd 命令進入 qstubuntu-v3 目錄,然後執行如下命令 docker build -t qst/qstubuntu:v3 .
就可以了。
二、Centos7如何建立docker的macvlan網路模式,讓物理機能和容器通訊。
我在虛擬機器下安裝了一個 centos 7 系統。在centos 7 中實驗了 Docker 的 macvlan 網路模式。本章節記錄了我的實驗過程。
虛擬機器軟體選擇 virtualbox, 版本號是5.2。
安裝好 virtulabox 後,點選新建按鈕,彈出對話方塊。在對話方塊中,名稱填寫server-centos,型別選擇 Linux ,版本選擇 Other Linux(64-bit),點選下一步。
記憶體我填寫了 4096 M,多少根據自己物理機的實際配置決定。點選下一步。
虛擬硬碟步驟中選擇現在建立虛擬硬碟
點選建立。
虛擬硬碟檔案型別選擇 VDI(VirtualBox磁碟映像)
,點選下一步。
“儲存在物理硬碟上” 這一步的時候,選擇動態分配。下一步。
“檔案位置和大小”:位置是預設的,當然你也可以選擇。大小我填寫了40G。點選建立。
然後在視窗左邊你就可以看到已經建立好的虛擬機器了。這個時候虛擬機器沒有安裝任何作業系統。你需要更改虛擬機器的設定。滑鼠移動到server-centos 虛擬機器上,右鍵,點選設定。在彈出的對話方塊中,左側選擇網路。右邊會出現四個網絡卡的選項卡。確保只有第一個網絡卡被選中 啟用網路連線
。其他的選項如圖所示:
這裡要注意,因為使用 macvlan,所以網絡卡必須允許混雜模式。如果你在物理機上配置,也得確保你的網絡卡支援混雜模式。為了方便後續安裝軟體,連線方式選擇橋接網絡卡,這樣此虛擬機器就加入了物理機的辦公區域網中。只要辦公環境能上網,這臺虛擬機器就能上網。同時此虛擬機器的IP、網段都是辦公區域網的,辦公區域網內的其他物理機可以ping通或連線此虛擬機器(比如SSH遠端登入)。
設定好網路後,左側欄點選儲存,如下圖:
選擇 1 框中,沒有碟片選單項。再點選 2 框中的按鈕,在開啟的檔案選擇對話方塊中選擇一開始下載的 CentOS 映象。點選 OK 關閉對話方塊,啟動虛擬機器,進入裝機介面。在裝機介面中,語言選擇中文-簡體中文。
裝機介面如圖:
軟體選擇,點進去後,選擇 GUI 就行,其他多餘的不用選。
安裝位置,點進去後,預設配置,直接點選上方的完成按鈕就好。
網路和主機名,點選後進入如下頁面:
右上角,開啟狀態,並點選完成按鈕。
SECURITY POLICY 不需要做任何設定,然後點選開始安裝。接著系統進入下圖:
安裝提示設定好 ROOT 密碼,以及建立使用者。
等待安裝完成後,進入 CentOS 7 的桌面。在桌面空白處右鍵彈出快捷選單,點選“開啟終端”。
用 ip addr
命令查到網絡卡名稱,這裡假設網絡卡的名稱是 enp0s3。雖然我在虛擬機器中設定了網絡卡的混雜模式,但是還需要在 CentOS 7 作業系統中開啟網絡卡的混雜模式,命令如下:
ip link set enp0s3 promisc on
為了檢視是否已經開啟混雜模式,用如下命令
[[email protected]]# ip link show enp0s3
2: enp0s3: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000
link/ether 08:00:27:3a:29:5e brd ff:ff:ff:ff:ff:ff
回顯的資訊中有 PROMISC ,表示已經開啟網絡卡的混雜模式。注意,重啟機器後,混雜模式又會變成關閉狀態。
建立 macvlan 模式的 docker 網路,取名為 macnet1:
docker network create -d macvlan --subnet 10.30.1.254/24 --gateway 10.30.1.254 -o parent=enp0s3 macnet1
上面命令的含義解釋一下。 –subnet 表示子網,這裡 24 表示 IPv4 32位地址的前24位,即 10.30.1 字首。 –gateway 是閘道器IP,這裡是辦公環境的閘道器。 parent 表示宿主機的網絡卡名。
建立使用 macnet1 網路的容器:
docker run --network macnet1 --ip=10.30.1.23 --name qu1 -d qst/qstubuntu:v3
這樣在其他機器上,就可以通過 IP 直接訪問容器,比如 SSH 遠端登入。此時容器更像是個虛擬機器。需要注意的是,因為使用了macvlan 宿主機和容器之間無法訪問,這是由於 Linux 的 macvlan 機制決定的。應該沒什麼解決方法。出處在此 https://yq.aliyun.com/articles/192998