一、制作可以远程登录的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
。 点击 Next ,进入下一步的对话框。Group Id 填写 qst,Artifact Id 填写 dockerCmd,直接点击 Finish 就可以创建项目了。项目文件夹中会自动加入一个 pom.xml 文件。
整个项目只需要一个包和一个 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
jre-8u171-linux-x64.tar.gz 文件是 Linux 版本的 JRE,你可以从 Oracle 下载,或者这个地址下载:
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。
首先,我下载了一个 CentOS 安装镜像。打开这个页面:https://www.centos.org/download/ 我选择了 DVD ISO 进行下载。
安装好 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
为了查看是否已经打开混杂模式,用如下命令
[root@bogon]# 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 机制决定的。应该没什么解决方法。