分类 容器与云 下的文章

什么是 Docker Compose

Docker Compose 是一个运行多容器 Docker 应用的工具。Compose 通过一个配置文件来配置一个应用的服务,然后通过一个命令创建并启动所有在配置文件中指定的服务。

Docker Compose 适用于许多不同的项目,如:

  • 开发:利用 Compose 命令行工具,我们可以创建一个隔离(而可交互)的环境来承载正在开发中的应用程序。通过使用 Compose 文件,开发者可以记录和配置所有应用程序的服务依赖关系。
  • 自动测试:此用例需求一个测试运行环境。Compose 提供了一种方便的方式来管理测试套件的隔离测试环境。完整的环境在 Compose 文件中定义。

Docker Compose 是在 Fig 的源码上构建的,这个社区项目现在已经没有使用了。

在本教程中,我们将看到如何在 Ubuntn 16.04 上安装 Docker Compose。

安装 Docker

我们需要安装 Docker 来安装 Docker Compose。首先为官方 Docker 仓库添加公钥。

$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -

接下来,添加 Docker 仓库到 apt 源列表:

$ sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"

更新包数据库,并使用 apt 安装 Docker

$ sudo apt-get update
$ sudo apt install docker-ce

在安装进程结束后,Docker 守护程序应该已经启动并设为开机自动启动。我们可以通过下面的命令来查看它的状态:

$ sudo systemctl status docker
---------------------------------

● docker.service - Docker Application Container Engine
 Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
 Active: active (running) 

安装 Docker Compose

现在可以安装 Docker Compose 了。通过执行以下命令下载当前版本。

# curl -L https://github.com/docker/compose/releases/download/1.14.0/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose

为二进制文件添加执行权限:

# chmod +x /usr/local/bin/docker-compose

检查 Docker Compose 版本:

$ docker-compose -v

输出应该如下:

docker-compose version 1.14.0, build c7bdf9e

测试 Docker Compose

Docker Hub 包含了一个用于演示的 Hello World 镜像,可以用来说明使用 Docker Compose 来运行一个容器所需的配置。

创建并打开一个目录:

$ mkdir hello-world
$ cd hello-world

创建一个新的 YAML 文件:

$ $EDITOR docker-compose.yml

在文件中粘贴如下内容:

unixmen-compose-test:
 image: hello-world

注意: 第一行是容器名称的一部分。

保存并退出。

运行容器

接下来,在 hello-world 目录执行以下命令:

$ sudo docker-compose up

如果一切正常,Compose 输出应该如下:

Pulling unixmen-compose-test (hello-world:latest)...
latest: Pulling from library/hello-world
b04784fba78d: Pull complete
Digest: sha256:f3b3b28a45160805bb16542c9531888519430e9e6d6ffc09d72261b0d26ff74f
Status: Downloaded newer image for hello-world:latest
Creating helloworld_unixmen-compose-test_1 ... 
Creating helloworld_unixmen-compose-test_1 ... done
Attaching to helloworld_unixmen-compose-test_1
unixmen-compose-test_1 | 
unixmen-compose-test_1 | Hello from Docker!
unixmen-compose-test_1 | This message shows that your installation appears to be working correctly.
unixmen-compose-test_1 | 
unixmen-compose-test_1 | To generate this message, Docker took the following steps:
unixmen-compose-test_1 | 1\. The Docker client contacted the Docker daemon.
unixmen-compose-test_1 | 2\. The Docker daemon pulled the "hello-world" image from the Docker Hub.
unixmen-compose-test_1 | 3\. The Docker daemon created a new container from that image which runs the
unixmen-compose-test_1 | executable that produces the output you are currently reading.
unixmen-compose-test_1 | 4\. The Docker daemon streamed that output to the Docker client, which sent it
unixmen-compose-test_1 | to your terminal.
unixmen-compose-test_1 | 
unixmen-compose-test_1 | To try something more ambitious, you can run an Ubuntu container with:
unixmen-compose-test_1 | $ docker run -it ubuntu bash
unixmen-compose-test_1 | 
unixmen-compose-test_1 | Share images, automate workflows, and more with a free Docker ID:
unixmen-compose-test_1 | https://cloud.docker.com/
unixmen-compose-test_1 | 
unixmen-compose-test_1 | For more examples and ideas, visit:
unixmen-compose-test_1 | https://docs.docker.com/engine/userguide/
unixmen-compose-test_1 | 
helloworld_unixmen-compose-test_1 exited with code 0

Docker 容器只能在命令(LCTT 译注:此处应为容器中的命令)还处于活动状态时运行,因此当测试完成运行时,容器将停止运行。

结论

本文是关于在 Ubuntu 16.04 中安装 Docker Compose 的教程。我们还看到了如何通过一个 YAML 格式的 Compose 文件构建一个简单的项目。


via: https://www.unixmen.com/container-docker-compose-ubuntu-16-04/

作者:Giuseppe Molica 译者:Locez 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

介绍

当 LXD 2.0 随着 Ubuntu 16.04 一起发布时,LXD 联网就简单了。要么你可以使用 lxd init 来配置,为你的容器自己提供一个 “lxdbr0” 网桥,要么使用一个已存在的物理接口。

虽然这确实有效,但是有点混乱,因为大部分的桥接配置发生在 Ubuntu 打包的 LXD 之外。那些脚本只能支持一个桥接,并且没有通过 API 暴露,这使得远程配置有点痛苦。

直到 LXD 2.3,LXD 终于发展了自己的网络管理 API ,并有相应的命令行工具。这篇文章试图来简述这些新的功能。

基础联网

在初始情况下,LXD 2.3 没有定义任何网络。lxd init 会为你设置一个,并且默认情况下将所有新的容器连接到它,但是让我们亲手尝试看下究竟发生了些什么。

要创建一个新的带有随机 IPv4 和 IP6 子网,并启用 NAT 的网络,只需要运行:

stgraber@castiana:~$ lxc network create testbr0
Network testbr0 created

你可以如下查看它的配置:

stgraber@castiana:~$ lxc network show testbr0
name: testbr0
config:
 ipv4.address: 10.150.19.1/24
 ipv4.nat: "true"
 ipv6.address: fd42:474b:622d:259d::1/64
 ipv6.nat: "true"
managed: true
type: bridge
usedby: []

如果你不想要那些自动配置的子网,你可以这么做:

stgraber@castiana:~$ lxc network create testbr0 ipv6.address=none ipv4.address=10.0.3.1/24 ipv4.nat=true
Network testbr0 created

那就会这样:

stgraber@castiana:~$ lxc network show testbr0
name: testbr0
config:
 ipv4.address: 10.0.3.1/24
 ipv4.nat: "true"
 ipv6.address: none
managed: true
type: bridge
usedby: []

如果你的容器没有使用它,那么创建的网络对你也没什么用。要将你新创建的网络连接到所有容器,你可以这么做:

stgraber@castiana:~$ lxc network attach-profile testbr0 default eth0

要将一个网络连接到一个已存在的容器中,你可以这么做:

stgraber@castiana:~$ lxc network attach my-container default eth0

现在,假设你已经在机器中安装了 openvswitch,并且要将这个网桥转换成 OVS 网桥,只需更改为正确的驱动:

stgraber@castiana:~$ lxc network set testbr0 bridge.driver openvswitch

如果你想要一次性做一系列修改。lxc network edit 可以让你在编辑器中交互编辑网络配置。

静态租约及端口安全

使用 LXD 管理 DHCP 服务器的一个好处是可以使得管理 DHCP 租约很简单。你所需要的是一个容器特定的网卡设备以及正确的属性设置。

root@yak:~# lxc init ubuntu:16.04 c1
Creating c1
root@yak:~# lxc network attach testbr0 c1 eth0
root@yak:~# lxc config device set c1 eth0 ipv4.address 10.0.3.123
root@yak:~# lxc start c1
root@yak:~# lxc list c1
+------+---------+-------------------+------+------------+-----------+
| NAME |  STATE  |        IPV4       | IPV6 |    TYPE    | SNAPSHOTS |
+------+---------+-------------------+------+------------+-----------+
|  c1  | RUNNING | 10.0.3.123 (eth0) |      | PERSISTENT | 0         |
+------+---------+-------------------+------+------------+-----------+

IPv6 也是相同的方法,但是换成 ipv6.address 属性。

相似地,如果你想要阻止你的容器更改它的 MAC 地址或者为其他 MAC 地址转发流量(比如嵌套),你可以用下面的命令启用端口安全:

root@yak:~# lxc config device set c1 eth0 security.mac_filtering true

DNS

LXD 在网桥上运行 DNS 服务器。除了设置网桥的 DNS 域( dns.domain 网络属性)之外,还支持 3 种不同的操作模式(dns.mode):

  • managed :每个容器都会有一条 DNS 记录,匹配它的名字以及已知的 IP 地址。容器无法通过 DHCP 改变这条记录。
  • dynamic :允许容器通过 DHCP 在 DNS 中自行注册。因此,在 DHCP 协商期间容器发送的任何主机名最终都出现在 DNS 中。
  • none : 针对那些没有任何本地 DNS 记录的递归 DNS 服务器。

默认的模式是 managed,并且典型的是最安全以及最方便的,因为它为容器提供了 DNS 记录,但是不允许它们通过 DHCP 发送虚假主机名嗅探其他的记录。

使用隧道

除了这些,LXD 还支持使用 GRE 或者 VXLAN 隧道连接到其他主机。

LXD 网络可以连接任何数量的隧道,从而轻松地创建跨多个主机的网络。这对于开发、测试和演示非常有用,生产环境通常更喜欢使用 VLAN 进行分割。

所以说,你想在主机 “edfu” 上有一个运行 IPv4 和 IPv6 的基础 “testbr0” 网络,并希望在主机 “djanet” 上使用它来生成容器。最简单的方法是使用组播 VXLAN 隧道。这种类型的隧道仅在两个主机位于同一物理段上时才起作用。

root@edfu:~# lxc network create testbr0 tunnel.lan.protocol=vxlan
Network testbr0 created
root@edfu:~# lxc network attach-profile testbr0 default eth0

它在主机 “edfu” 上定义了一个 “testbr0” 桥接,并为其他主机能加入它设置了一个组播 VXLAN。在这个设置中,“edfu” 为这个网络扮演了一个路由器角色,提供 DHCP、DNS 等等,其他主机只是通过隧道转发流量。

root@djanet:~# lxc network create testbr0 ipv4.address=none ipv6.address=none tunnel.lan.protocol=vxlan
Network testbr0 created
root@djanet:~# lxc network attach-profile testbr0 default eth0

现在你可以在任何一台主机上启动容器,并看到它们从同一个地址池中获取 IP,通过隧道直接互相通讯。

如先前所述,这个使用了组播,它通常在跨越路由器时无法很好工作。在这些情况下,你可以用单播模式使用 VXLAN 或者 GRE 隧道。

要使用 GRE 加入另一台主机,首先配置服务主机:

root@edfu:~# lxc network set testbr0 tunnel.nuturo.protocol gre
root@edfu:~# lxc network set testbr0 tunnel.nuturo.local 172.17.16.2
root@edfu:~# lxc network set testbr0 tunnel.nuturo.remote 172.17.16.9

接着是“客户端”主机:

root@nuturo:~# lxc network create testbr0 ipv4.address=none ipv6.address=none tunnel.edfu.protocol=gre tunnel.edfu.local=172.17.16.9 tunnel.edfu.remote=172.17.16.2
Network testbr0 created
root@nuturo:~# lxc network attach-profile testbr0 default eth0

如果你像使用 VXLAN,只要这么做:

root@edfu:~# lxc network set testbr0 tunnel.edfu.id 10
root@edfu:~# lxc network set testbr0 tunnel.edfu.protocol vxlan

还有:

root@nuturo:~# lxc network set testbr0 tunnel.edfu.id 10
root@nuturo:~# lxc network set testbr0 tunnel.edfu.protocol vxlan

这里需要隧道 id 以防与已经配置的多播 VXLAN 隧道冲突。

这就是如何使用最近的 LXD 简化跨主机联网了!

总结

LXD 使得从简单的单主机网络到数千个容器的非常复杂的跨主机网络的定义变得更加容易。它也使为一些容器定义一个新网络或者给容器添加第二个设备,并连接到隔离的私有网络变得很简单。

虽然这篇文章介绍了支持的大部分功能,但仍有一些可以微调 LXD 网络体验的窍门。可以在这里找到完整的列表:https://github.com/lxc/lxd/blob/master/doc/configuration.md

额外信息


via: https://www.stgraber.org/2016/10/27/network-management-with-lxd-2-3/

作者:Stéphane Graber 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

如果你正在寻找一种管理运行容器的 Linux 服务器的简单方法,那么你应该看看 Cockpit。

如果你管理着一台 Linux 服务器,那么你可能正在寻找一个可靠的管理工具。为了这个你可能已经看了 WebmincPanel 这类软件。但是,如果你正在寻找一种简单的方法来管理还包括了 Docker 的 Linux 服务器,那么有一个工具可以用于这个需求:Cockpit

为什么使用 Cockpit?因为它可以处理这些管理任务:

  • 连接并管理多台机器
  • 通过 Docker 管理容器
  • 与 Kubernetes 或 Openshift 集群进行交互
  • 修改网络设置
  • 管理用户帐号
  • 通过基于 Web 的 shell 访问
  • 通过图表查看系统性能信息
  • 查看系统服务和日志文件

Cockpit 可以安装在 Debian、Red Hat、CentOS、Arch Linux 和 Ubuntu 之上。在这里,我将使用一台已经安装了 Docker 的 Ubuntu 16.04 服务器来安装系统。

在上面的功能列表中,其中最突出的是容器管理。为什么?因为它使安装和管理容器变得非常简单。事实上,你可能很难找到更好的容器管理解决方案。

因此,让我们来安装这个方案并看看它的使用是多么简单。

安装

正如我前面提到的,我将在一台运行着 Docker 的 Ubuntu 16.04 实例上安装 Cockpit。安装步骤很简单。你要做的第一件事是登录你的 Ubuntu 服务器。接下来,你必须使用下面的命令添加必要的仓库:

sudo add-apt-repository ppa:cockpit-project/cockpit

出现提示时,按下键盘上的回车键,等待提示返回。一旦返回到 bash 提示符,使用下面的命令来更新 apt:

sudo apt-get get update

使用下面的命令安装 Cockpit:

sudo apt-get -y install cockpit cockpit-docker

安装完成后,需要启动 Cockpit 服务并使它开机自动启动。要做到这个,使用下面的两个命令:

sudo systemctl start cockpit
sudo systemctl enable cockpit

安装就到这里了。

登录到 Cockpit

要访问 Cockpit 的 web 界面,打开浏览器(与 Cockpit 服务器在同一个网络内),输入 http://IP_OF_SERVER:9090,你就会看到登录页面(图 1)。

图 1:Cockpit 登录页面。

在 Ubuntu 中使用 Cockpit 有个警告。Cockpit 中的很多任务需要管理员权限。如果你使用普通用户登录,则无法使用 Docker 等一些工具。 要解决这个问题,你可以在 Ubuntu 上启用 root 用户。但这并不总是一个好主意。通过启用 root 帐户,你将绕过已经建立多年的安全系统。但是,在本文的用途中,我将使用以下两个命令启用 root 用户:

sudo passwd root
sudo passwd -u root 

注意,请确保给 root 帐户一个强壮的密码。

你想恢复这个修改的话,你只需输入下面的命令:

sudo passwd -l root

在其他发行版(如 CentOS 和 Red Hat)中,你可以使用用户名 root 及其密码登录 Cockpit,而无需像上面那样需要额外的步骤。

如果你对启用 root 用户感到担心,则可以在服务器的终端窗口拉取镜像(使用命令 docker pull IMAGE_NAME, 这里的 IMAGE_NAME 是你要拉取的镜像)。这会将镜像添加到你的 docker 服务器中,然后可以通过普通用户进行管理。唯一需要注意的是,普通用户必须使用以下命令将自己添加到 Docker 组:

sudo usermod -aG docker USER

其中,USER 是实际添加到组的用户名。在你完成后,重新登出并登入,接着使用下面的命令重启 Docker:

sudo service docker restart

现在常规用户可以启动并停止 Docker 镜像/容器而无需启用 root 用户了。唯一一点是用户不能通过 Cockpit 界面添加新的镜像。

使用 Cockpit

一旦你登录后,你可以看到 Cockpit 的主界面(图 2)。

图 2:Cockpit 主界面。

你可以通过每个栏目来检查服务器的状态等,但是我们想要直接进入容器。单击 “Containers” 那栏以显示当前运行的以及可用的镜像(图3)。

图 3:使用 Cockpit 管理容器难以置信地简单。

要启动一个镜像,只要找到镜像并点击关联的启动按钮。在弹出的窗口中(图 4),你可以在点击运行之前查看所有镜像的信息(并根据需要调整)。

图 4: 使用 Cockpit 运行 Docker 镜像。

镜像运行后,你可以点击它查看状态,并可以停止、重启、删除实例。你也可以点击修改资源限制并接着调整内存限制还有(或者)CPU 优先级。

添加新的镜像

假设你以 root 用户身份登录。如果是这样,那么你可以在 Cockpit GUI 的帮助下添加新的镜像。在“ Container” 栏目下,点击获取新的镜像按钮,然后在新的窗口中搜索要添加的镜像。假设你要添加 CentOS 的最新官方版本。在搜索栏中输入 centos,在得到搜索结果后,选择官方列表,然后单击下载(图5)。

图 5:使用 Cockpit 添加最新的官方构建 CentOS 镜像到 Docker 中。

镜像下载完后,那它就在 Docker 中可用了,并可以通过 Cockpit 运行。

如获取它那样简单

管理 Docker 并不容易。是的,在 Ubuntu 上运行 Cockpit 会有一个警告,但如果这是你唯一的选择,那么也有办法让它工作。在 Cockpit 的帮助下,你不仅可以轻松管理 Docker 镜像,也可以在任何可以访问 Linux 服务器的 web 浏览器上这样做。请享受这个新发现的让 Docker 易用的方法。


via: https://www.linux.com/learn/intro-to-linux/2017/3/make-container-management-easy-cockpit

作者:JACK WALLEN 译者:geekpi 校对:jasminepeng

本文由 LCTT 原创编译,Linux中国 荣誉推出

Anbox 以基于容器的方式,在像 Ubuntu 这样的常规的 GNU Linux 系统上启动一个完整的 Android 系统。

概述

Anbox 使用 Linux 命名空间(user、pid、uts、net、mount、ipc)来在容器中运行完整的 Android 系统,并在任何基于 GNU Linux 平台上提供 Android 应用。

容器内的 Android 无法直接访问任何硬件。所有硬件访问都通过主机上的 anbox 守护进程进行。我们重用基于 QEMU 的模拟器实现的 Android 中的 GL、ES 加速渲染。容器内的 Android 系统使用不同的管道与主机系统通信,并通过它发送所有硬件访问命令。

有关更多详细信息,请参考下文档:

Anbox 目前适合桌面使用,但也用在移动操作系统上,如 Ubuntu Touch、Sailfish OS 或 Lune OS。然而,由于 Android 程序的映射目前只针对桌面环境,因此还需要额外的工作来支持其他的用户界面。

Android 运行时环境带有一个基于 Android 开源项目镜像的最小自定义 Android 系统。所使用的镜像目前基于 Android 7.1.1。

安装

目前,安装过程包括一些添加额外组件到系统的步骤。包括:

  • 启用用于 binder 和 ashmen 的非发行的树外内核模块。
  • 使用 udev 规则为 /dev/binder 和 /dev/ashmem 设置正确权限。
  • 能够启动 Anbox 会话管理器作为用户会话的一个启动任务。

为了使这个过程尽可能简单,我们将必要的步骤绑定在一个 snap(见 https://snapcraft.io ) 中,称之为 “anbox-installer”。这个安装程序会执行所有必要的步骤。你可以在所有支持 snap 的系统运行下面的命令安装它。

$ snap install --classic anbox-installer

另外你可以通过下面的命令下载安装脚本。

$ wget https://raw.githubusercontent.com/anbox/anbox-installer/master/installer.sh -O anbox-installer

请注意,我们还不支持除所有 Linux 发行版。请查看下面的章节了解支持的发行版。

运行下面的命令进行安装。

$ anbox-installer

它会引导你完成安装过程。

注意: Anbox 目前处于 pre-alpha 开发状态。不要指望它具有生产环境你需要的所有功能。你肯定会遇到错误和崩溃。如果你遇到了,请不要犹豫并报告它们!

注意: Anbox snap 目前 完全没有约束,因此它只能从边缘渠道获取。正确的约束是我们想要在未来实现的,但由于 Anbox 的性质和复杂性,这不是一个简单的任务。

已支持的 Linux 发行版

目前我们官方支持下面的 Linux 发行版:

  • Ubuntu 16.04 (xenial)

未测试但可能支持的:

  • Ubuntu 14.04 (trusty)
  • Ubuntu 16.10 (yakkety)
  • Ubuntu 17.04 (zesty)

安装并运行 Android 程序

从源码构建

要构建 Anbox 运行时不需要特别了解什么,我们使用 cmake 作为构建系统。你的主机系统中应已有下面这些构建依赖:

  • libdbus
  • google-mock
  • google-test
  • libboost
  • libboost-filesystem
  • libboost-log
  • libboost-iostreams
  • libboost-program-options
  • libboost-system
  • libboost-test
  • libboost-thread
  • libcap
  • libdbus-cpp
  • mesa (libegl1, libgles2)
  • glib-2.0
  • libsdl2
  • libprotobuf
  • protobuf-compiler
  • lxc

在 Ubuntu 系统中你可以用下面的命令安装所有的依赖:

$ sudo apt install build-essential cmake cmake-data debhelper dbus \  
    google-mock libboost-dev libboost-filesystem-dev libboost-log-dev \  
    libboost-iostreams-dev libboost-program-options-dev libboost-system-dev \  
    libboost-test-dev libboost-thread-dev libcap-dev libdbus-1-dev \  
    libdbus-cpp-dev libegl1-mesa-dev libgles2-mesa-dev libglib2.0-dev \  
    libglm-dev libgtest-dev liblxc1 libproperties-cpp-dev libprotobuf-dev \  
    libsdl2-dev lxc-dev pkg-config protobuf-compiler

之后用下面的命令构建 Anbox:

$ mkdir build
$ cd build
$ cmake ..
$ make

一个简单的命令会将必要的二进制安装到你的系统中,如下。

$ make install

如果你想要构建 anbox snap,你可以按照下面的步骤:

$ mkdir android-images
$ cp /path/to/android.img android-images/android.img
$ snapcraft

结果会有一个 .snap 文件,你可以在支持 snap 的系统上安装。

$ snap install --dangerous --devmode anbox_1_amd64.snap

运行 Anbox

要从本地构建运行 Anbox ,你需要了解更多一点。请参考“运行时步骤”文档。

文档

在项目源代码的子目录下,你可以找到额外的关于 Anbox 的文档。

有兴趣可以看下:

报告 bug

如果你发现了一个 Anbox 问题,请提交 bug

取得联系

如果你想要与开发者联系,你可以在 FreeNode 中加入 #anbox 的 IRC 频道。

版权与许可

Anbox 重用了像 Android QEMU 模拟器这样的其他项目的代码。这些项目可在外部/带有许可声明的子目录中得到。

anbox 源码本身,如果没有在相关源码中声明其他的许可,默认是 GPLv3 许可。


via: https://github.com/anbox/anbox/blob/master/README.md

作者:Anbox 译者:geekpi 校对:jasminepeng

本文由 LCTT 原创编译,Linux中国 荣誉推出

介绍

终于要结束了!这个大约一年前开始的这系列文章的最后一篇博文。

  1. LXD 入门
  2. 安装与配置
  3. 你的第一个 LXD 容器
  4. 资源控制
  5. 镜像管理
  6. 远程主机及容器迁移
  7. LXD 中的 Docker
  8. LXD 中的 LXD
  9. 实时迁移
  10. LXD 和 Juju
  11. LXD 和 OpenStack
  12. 调试,及给 LXD 做贡献

如果你从一开始就关注了这个系列,你应该已经使用了 LXD 相当长的时间了,并且非常熟悉它的日常操作和功能。

但如果出现问题怎么办?你可以做什么来自己跟踪问题?如果你不能,你应该记录什么信息,以便上游可以跟踪问题?

如果你想自己解决问题或通过实现你需要的功能来帮助改善LXD怎么办?如何构建,测试和贡献 LXD 代码库?

调试 LXD 并填写 bug 报告

LXD 日志文件

/var/log/lxd/lxd.log

这是 LXD 日志的主文件。为了避免它快速充满你的磁盘,默认只会记录 INFOWARNING 或者 ERROR 级别的日志。你可以在 LXD 守护进程中使用 –debug 改变其行为。

/var/log/lxd/CONTAINER/lxc.conf

每当你启动容器时,此文件将更新为传递给 LXC 的配置。

这里会展示容器将如何配置,包括其所有的设备、绑定挂载等等。

/var/log/lxd/CONTAINER/forkexec.log

这个文件包含 LXC 命令执行失败时产生的错误。这个情况是非常罕见的,因为 LXD 通常会在发生之前处理大多数错误。

/var/log/lxd/CONTAINER/forkstart.log

这个文件包含 LXC 在启动容器时的错误信息。含 LXC 命令执行失败时产生的错误。

CRIU 日志 (对于实时迁移)

如果使用 CRIU 进行容器实时迁移或实时快照,则每次生成 CRIU 转储或恢复转储时都会记录额外的日志文件。

这些日志也可以在 /var/log/lxd/CONTAINER/ 中找到,并且有时间戳,以便你可以找到与你最近的操作所匹配的那些日志。它们包含 CRIU 转储和恢复的所有内容的详细记录,并且比典型的迁移/快照错误消息更容器理解。

LXD 调试消息

如上所述,你可以使用 -debug 选项将守护进程切换为执行调试日志记录。另一种方法是连接到守护进程的事件接口,它将显示所有日志条目,而不管配置的日志级别(即使是远程工作)。

举例说,对于 lxc init ubuntu:16.04 xen 来说,

lxd.log 会是这样:

INFO[02-24|18:14:09] Starting container action=start created=2017-02-24T23:11:45+0000 ephemeral=false name=xen stateful=false used=1970-01-01T00:00:00+0000
INFO[02-24|18:14:10] Started container action=start created=2017-02-24T23:11:45+0000 ephemeral=false name=xen stateful=false used=1970-01-01T00:00:00+0000

lxc monitor –type=logging 会是:

metadata:
  context: {}
  level: dbug
  message: 'New events listener: 9b725741-ffe7-4bfc-8d3e-fe620fc6e00a'
timestamp: 2017-02-24T18:14:01.025989062-05:00
type: logging

metadata:
  context:
    ip: '@'
    method: GET
    url: /1.0
  level: dbug
  message: handling
timestamp: 2017-02-24T18:14:09.341283344-05:00
type: logging

metadata:
  context:
    driver: storage/zfs
  level: dbug
  message: StorageCoreInit
timestamp: 2017-02-24T18:14:09.341536477-05:00
type: logging

metadata:
  context:
    ip: '@'
    method: GET
    url: /1.0/containers/xen
  level: dbug
  message: handling
timestamp: 2017-02-24T18:14:09.347709394-05:00
type: logging

metadata:
  context:
    ip: '@'
    method: PUT
    url: /1.0/containers/xen/state
  level: dbug
  message: handling
timestamp: 2017-02-24T18:14:09.357046302-05:00
type: logging

metadata:
  context: {}
  level: dbug
  message: 'New task operation: 2e2cf904-c4c4-4693-881f-57897d602ad3'
timestamp: 2017-02-24T18:14:09.358387853-05:00
type: logging

metadata:
  context: {}
  level: dbug
  message: 'Started task operation: 2e2cf904-c4c4-4693-881f-57897d602ad3'
timestamp: 2017-02-24T18:14:09.358578599-05:00
type: logging

metadata:
  context:
    ip: '@'
    method: GET
    url: /1.0/operations/2e2cf904-c4c4-4693-881f-57897d602ad3/wait
  level: dbug
  message: handling
timestamp: 2017-02-24T18:14:09.366213106-05:00
type: logging

metadata:
  context:
    driver: storage/zfs
  level: dbug
  message: StoragePoolInit
timestamp: 2017-02-24T18:14:09.369636451-05:00
type: logging

metadata:
  context:
    driver: storage/zfs
  level: dbug
  message: StoragePoolCheck
timestamp: 2017-02-24T18:14:09.369771164-05:00
type: logging

metadata:
  context:
    container: xen
    driver: storage/zfs
  level: dbug
  message: ContainerMount
timestamp: 2017-02-24T18:14:09.424696767-05:00
type: logging

metadata:
  context:
    driver: storage/zfs
    name: xen
  level: dbug
  message: ContainerUmount
timestamp: 2017-02-24T18:14:09.432723719-05:00
type: logging

metadata:
  context:
    container: xen
    driver: storage/zfs
  level: dbug
  message: ContainerMount
timestamp: 2017-02-24T18:14:09.721067917-05:00
type: logging

metadata:
  context:
    action: start
    created: 2017-02-24 23:11:45 +0000 UTC
    ephemeral: "false"
    name: xen
    stateful: "false"
    used: 1970-01-01 00:00:00 +0000 UTC
  level: info
  message: Starting container
timestamp: 2017-02-24T18:14:09.749808518-05:00
type: logging

metadata:
  context:
    ip: '@'
    method: GET
    url: /1.0
  level: dbug
  message: handling
timestamp: 2017-02-24T18:14:09.792551375-05:00
type: logging

metadata:
  context:
    driver: storage/zfs
  level: dbug
  message: StorageCoreInit
timestamp: 2017-02-24T18:14:09.792961032-05:00
type: logging

metadata:
  context:
    ip: '@'
    method: GET
    url: /internal/containers/23/onstart
  level: dbug
  message: handling
timestamp: 2017-02-24T18:14:09.800803501-05:00
type: logging

metadata:
  context:
    driver: storage/zfs
  level: dbug
  message: StoragePoolInit
timestamp: 2017-02-24T18:14:09.803190248-05:00
type: logging

metadata:
  context:
    driver: storage/zfs
  level: dbug
  message: StoragePoolCheck
timestamp: 2017-02-24T18:14:09.803251188-05:00
type: logging

metadata:
  context:
    container: xen
    driver: storage/zfs
  level: dbug
  message: ContainerMount
timestamp: 2017-02-24T18:14:09.803306055-05:00
type: logging

metadata:
  context: {}
  level: dbug
  message: 'Scheduler: container xen started: re-balancing'
timestamp: 2017-02-24T18:14:09.965080432-05:00
type: logging

metadata:
  context:
    action: start
    created: 2017-02-24 23:11:45 +0000 UTC
    ephemeral: "false"
    name: xen
    stateful: "false"
    used: 1970-01-01 00:00:00 +0000 UTC
  level: info
  message: Started container
timestamp: 2017-02-24T18:14:10.162965059-05:00
type: logging

metadata:
  context: {}
  level: dbug
  message: 'Success for task operation: 2e2cf904-c4c4-4693-881f-57897d602ad3'
timestamp: 2017-02-24T18:14:10.163072893-05:00
type: logging

lxc monitor 的格式有点不同于每个条目都缩合成一行的日志文件,但更重要的是,你可以看到所有 level:dbug 条目。

如何报告 bug

LXD 的 bug

最好报告 bug 的地方是 https://github.com/lxc/lxd/issues。确保完整填写了 bug 报告模板中的内容,这些信息可以节省我们我们时间来复现环境。

Ubuntu 的 bug

如果你发现 Ubuntu 包本身有问题,无法安装、升级或删除。或者遇到 LXD init 脚本的问题。报告此类错误的最好是在 Launchpad 上。

在 Ubuntu 系统上,你可以使用:ubuntu-bug lxd ,它将自动包括一些日志文件和包信息供我们查看。

CRIU 的 bug

与 CRIU 相关的 Bug,你可以通过 CRIU 的错误输出发现,你应该在 Launchpad 上报告这些:ubuntu-bug criu

请注意,通过 LXD 使用 CRIU 属于测试版功能,除非你愿意通过 Canonical 的支持合同付费支持,要么可能需要一段时间才能查看你的错误报告。

贡献给 LXD

LXD 用 Go 写成并托管在 Github。我们欢迎任外部的贡献。为 LXD 贡献不需要 CLA 或类似的法律协议签署,只是通常的开发者所有权证书(Signed-off-by: 行)。

在我们的问题追踪器工具中,我们列有许多潜在的功能需求,新的贡献者可以以此作为良好的起点。通常最好在开始处理代码先发出 issue,这样每个人都知道你正在做这项工作,以便我们可以提供一些早期反馈。

从源码源码构建 LXD

这里有上游的维护说明:https://github.com/lxc/lxd#building-from-source

你需要在 Github 上 fork 上游仓库,然后将你的更改推送到你的分支。我们建议每天 rebase 上游的 LXD,因为我们倾向于定期合并更改。

运行测试套件

LXD 维护了两套测试集,单元测试和集成测试。你可以用下面的命令测试所有:

sudo -E make check

要只运行单元测试,使用:

sudo -E go test ./...

要运行集成测试,使用:

cd test
sudo -E ./main.sh

后者支持相当多的环境变量来测试各种存储后端、禁用网络测试、使用 ramdisk 或只是调整日志输出。其中一些是:

  • LXD_BACKENDbtrfsdirlvmzfs” 之一(默认为 dir
    运行 LXD 存储驱动程序相关的所有测试。
  • LXD_CONCURRENTtruefalse(默认为 false
    这启用一些额外的并发测试。
  • LXD_DEBUGtruefalse(默认为 false
    记录所有 shell 命令,并在调试模式下运行所有​​ LXD 命令。
  • LXD_INSPECTtruefalse(默认为 false
    测试程序会在故障时挂起,以便你可以检查环境。
  • LXD_LOGS:将所有 LXD 日志文件转储到的目录(默认为 “”)
    所有生成的 LXD 守护进程的 logs 目录将被复制到此路径。
  • LXD_OFFLINEtruefalse(默认为 false
    禁用任何依赖于外部网络连接的测试。
  • LXD_TEST_IMAGE: unified 格式的 LXD 镜像的路径(默认为 “”)
    可以使用自定义测试镜像,而不是默认的最小 busybox 镜像。
  • LXD_TMPFStruefalse(默认为 false
    tmpfs 安装中运行整个测试套件,这会使用相当多的内存,但会使测试速度明显更快。
  • LXD_VERBOSEtruefalse(默认为 false
    不太极端的 LXD_DEBUG 版本。shell 命令仍然会记录,但 -debug 不会传递给 LXC 命令,LXD 守护进程只能使用 -verbose 运行。

测试程序将在实际运行之前提醒你任何缺失的依赖项。在相当快的机器上运行该测试可在 10 分钟内完成。

发送你的分支

发送拉取请求(PR)之前,你需要确认:

  • 你已经 rebase 了上游分支
  • 你的所有提交信息都包括 Signed-off-by: First Last <email> 这行
  • 已删除任何你的临时调试代码
  • 你已经将相关的提交 squash 在一起,以保持你的分支容易审查
  • 单元和集成测试全部通过

一切完成后,在 Github 上发起一个拉取请求。我们的 Jenkins 将验证提交是否全部有 signed-off,在 MacOS 和 Windows 上的测试将自动执行,如果看起来不错,我们将触发一个完整的 Jenkins 测试,它将在所有存储后端、32 位和 64 位以及我们关心的所有 Go 版本上测试你的分支。

假设我们有人触发了 Jenkins,这通常需要不到一个小时的时间。

一旦所有测试完成,我们对代码本身感到满意,你的分支将会被合并,你的代码会出现在下一个 LXD 发布中。如果更改适用于 LXD stable-2.0 分支,我们将为你向后移植。

总结

我希望这个系列的博客文章有助于你了解什么是 LXD,以及它可以做什么!

本系列的范围仅限于 LXD(2.0.x),但我们也为那些想要最新功能的用户提供每月功能版本。你可以找到一些其他涵盖了原来的 LXD 2.0系列文章中列出的功能的博客文章。

额外的信息

LXD 的主站在: https://linuxcontainers.org/lxd

LXD 的 GitHub 开发仓库: https://github.com/lxc/lxd

LXD 的邮件列表: https://lists.linuxcontainers.org

LXD 的 IRC 频道:#lxcontainers on irc.freenode.net

在线尝试 LXD: https://linuxcontainers.org/lxd/try-it


作者简介:我是 Stéphane Graber。我是 LXC 和 LXD 项目的领导者,目前在加拿大魁北克蒙特利尔的家所在的 Canonical 有限公司担任 LXD 的技术主管。


via: https://stgraber.org/2017/02/27/lxd-2-0-debugging-and-contributing-to-lxd-1212/

作者:Stéphane Graber 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

这是 LXD 2.0 系列介绍文章的第十一篇。

  1. LXD 入门
  2. 安装与配置
  3. 你的第一个 LXD 容器
  4. 资源控制
  5. 镜像管理
  6. 远程主机及容器迁移
  7. LXD 中的 Docker
  8. LXD 中的 LXD
  9. 实时迁移
  10. LXD 和 Juju
  11. LXD 和 OpenStack
  12. 调试,及给 LXD 做贡献

介绍

首先对这次的延期抱歉。为了让一切正常我花了很长时间。我第一次尝试是使用 devstack 时遇到了一些必须解决问题。 然而即使这样,我还是不能够使网络正常。

我终于放弃了 devstack,并使用用户友好的 Juju 尝试使用 “conjure-up” 部署完整的 Ubuntu OpenStack。它终于工作了!

下面是如何运行一个完整的 OpenStack,使用 LXD 容器而不是 VM,并在 LXD 容器中运行所有这些(嵌套的!)。

要求

这篇文章假设你有一个可以工作的 LXD 设置,提供容器网络访问,并且你有一个非常强大的 CPU,大约 50GB 给容器空间和至少 16G B的内存。

记住,我们在这里运行一个完整的 OpenStack,这东西不是很轻量!

设置容器

OpenStack 由大量不同做不同事情的组件组成。 一些需要一些额外的特权,为了可以使设置更简单,我们将使用特权容器。

我们将配置支持嵌套的容器,预加载所有需要的内核模块,并允许它访问 /dev/mem(显然是需要的)。

请注意,这意味着 LXD 容器的大部分安全特性对该容器被禁用。 然而由 OpenStack 自身产生的容器将是无特权的,并且可以正常使用 LXD 的安全特性。

lxc launch ubuntu:16.04 openstack -c security.privileged=true -c security.nesting=true -c "linux.kernel_modules=iptable_nat, ip6table_nat, ebtables, openvswitch"
lxc config device add openstack mem unix-char path=/dev/mem

LXD 中有一个小 bug,它会尝试加载已经加载到主机上的内核模块。这已在LXD 2.5中得到修复,并将在LXD 2.0.6 中修复,但在此之前,可以使用以下方法:

lxc exec openstack -- ln -s /bin/true /usr/local/bin/modprobe

我们需要加几条 PPA 并安装 conjure-up,它是我们用来安装 OpenStack 的部署工具。

lxc exec openstack -- apt-add-repository ppa:conjure-up/next -y
lxc exec openstack -- apt-add-repository ppa:juju/stable -y
lxc exec openstack -- apt update
lxc exec openstack -- apt dist-upgrade -y
lxc exec openstack -- apt install conjure-up -y

最后一步是在容器内部配置 LXD 网络。

所有问题都选择默认,除了:

  • 使用 dir 存储后端( zfs 不在嵌套容器中用)
  • 不要配置 IPv6 网络(conjure-up/juju 不太兼容它)
lxc exec openstack -- lxd init

现在配置完容器了,现在我们部署 OpenStack!

用 conjure-up 部署 OpenStack

如先前提到的,我们用 conjure-up 部署 OpenStack。

这是一个很棒的用户友好的可以与 Juju 交互来部署复杂服务的工具。

首先:

lxc exec openstack -- sudo -u ubuntu -i conjure-up
  • 选择 “OpenStack with NovaLXD”
  • 选择 “localhost” 作为部署目标(使用 LXD)
  • 点击 “Deploy all remaining applications”

接下来会部署 OpenStack。整个过程会花费一个多小时,这取决于你运行的机器。你将看到所有服务会被分配一个容器,然后部署并最终互连。

Conjure-Up deploying OpenStack

部署完成后会显示一个安装完成的界面。它会导入一些初始镜像、设置 SSH 权限、配置网络最后会显示面板的 IP 地址。

访问面板并生成一个容器

面板运行在一个容器中,因此你不能直接从浏览器中访问。

最简单的方法是设置一条 NAT 规则:

lxc exec openstack -- iptables -t nat -A PREROUTING -p tcp --dport 80 -j DNAT --to <IP>

其中 <ip> 是 conjure-up 在安装结束时给你的面板 IP 地址。

你现在可以获取 “openstack” 容器的 IP 地址(来自 lxc info openstack),并将浏览器指向:http:///horizon 。

第一次加载可能需要几分钟。 一旦显示了登录界面,输入默认登录名和密码(admin/openstack),你就会看到OpenStack的欢迎面板!

oslxd-dashboard

现在可以选择左边的 “Project” 选项卡,进入 “Instances” 页面。 要启动一个使用 nova-lxd 的新实例,点击 “Launch instance”,选择你想要的镜像,网络等,接着你的实例就产生了。

一旦它运行后,你可以为它分配一个浮动 IP,它将允许你从你的 “openstack” 容器中访问你的实例。

总结

OpenStack 是一个非常复杂的软件,你也不会想在家里或在单个服务器上运行它。 但是,不管怎样在你的机器上包含这些服务在一个容器中都是非常有趣的。

conjure-up 是部署这种复杂软件的一个很好的工具,背后使用 Juju 驱动部署,为每个单独的服务使用 LXD 容器,最后是实例本身。

它也是少数几个容器嵌套多层并实际上有意义的情况之一!

额外信息

conjure-up 网站: http://conjure-up.io

Juju 网站: http://www.ubuntu.com/cloud/juju

LXD 的主站在: https://linuxcontainers.org/lxd

LXD 的 GitHub 仓库: https://github.com/lxc/lxd

LXD 的邮件列表: https://lists.linuxcontainers.org

LXD 的 IRC 频道: #lxcontainers on irc.freenode.net

如果你不想或者不能在你的机器上安装 LXD ,你可以在 web 上试试在线版的 LXD。


作者简介:我是 Stéphane Graber。我是 LXC 和 LXD 项目的领导者,目前在加拿大魁北克蒙特利尔的家所在的 Canonical 有限公司担任 LXD 的技术主管。


via: https://www.stgraber.org/2016/10/26/lxd-2-0-lxd-and-openstack-1112/

作者:Stéphane Graber 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出