分类 容器与云 下的文章

本文的主角是容器,一种类似虚拟机但更轻量级的构造。你可以轻易地在你的 Ubuntu 桌面系统中创建一堆容器!

虚拟机会虚拟出整个电脑让你来安装客户机操作系统。相比之下,容器复用了主机的 Linux 内核,只是简单地 包容 了我们选择的根文件系统(也就是运行时环境)。Linux 内核有很多功能可以将运行的 Linux 容器与我们的主机分割开(也就是我们的 Ubuntu 桌面)。

Linux 本身需要一些手工操作来直接管理他们。好在,有 LXD(读音为 Lex-deeh),这是一款为我们管理 Linux 容器的服务。

我们将会看到如何:

  1. 在我们的 Ubuntu 桌面上配置容器,
  2. 创建容器,
  3. 安装一台 web 服务器,
  4. 测试一下这台 web 服务器,以及
  5. 清理所有的东西。

设置 Ubuntu 容器

如果你安装的是 Ubuntu 16.04,那么你什么都不用做。只要安装下面所列出的一些额外的包就行了。若你安装的是 Ubuntu 14.04.x 或 Ubuntu 15.10,那么按照 LXD 2.0 系列(二):安装与配置 来进行一些操作,然后再回来。

确保已经更新了包列表:

sudo apt update
sudo apt upgrade

安装 lxd 包:

sudo apt install lxd

若你安装的是 Ubuntu 16.04,那么还可以让你的容器文件以 ZFS 文件系统的格式进行存储。Ubuntu 16.04 的 Linux kernel 包含了支持 ZFS 必要的内核模块。若要让 LXD 使用 ZFS 进行存储,我们只需要安装 ZFS 工具包。没有 ZFS,容器会在主机文件系统中以单独的文件形式进行存储。通过 ZFS,我们就有了写入时拷贝等功能,可以让任务完成更快一些。

安装 zfsutils-linux 包(若你安装的是 Ubuntu 16.04.x):

sudo apt install zfsutils-linux

安装好 LXD 后,包安装脚本应该会将你加入 lxd 组。该组成员可以使你无需通过 sudo 就能直接使用 LXD 管理容器。根据 Linux 的习惯,你需要先登出桌面会话然后再登录 才能应用 lxd 的组成员关系。(若你是高手,也可以通过在当前 shell 中执行 newgrp lxd 命令,就不用重登录了)。

在开始使用前,LXD 需要初始化存储和网络参数。

运行下面命令:

$ sudo lxd init
Name of the storage backend to use (dir or zfs): zfs
Create a new ZFS pool (yes/no)? yes
Name of the new ZFS pool: lxd-pool
Would you like to use an existing block device (yes/no)? no
Size in GB of the new loop device (1GB minimum): 30
Would you like LXD to be available over the network (yes/no)? no
Do you want to configure the LXD bridge (yes/no)? yes 
> You will be asked about the network bridge configuration. Accept all defaults and continue.
Warning: Stopping lxd.service, but it can still be activated by:
 lxd.socket
 LXD has been successfully configured.
$ _

我们在一个(单独)的文件而不是块设备(即分区)中构建了一个文件系统来作为 ZFS 池,因此我们无需进行额外的分区操作。在本例中我指定了 30GB 大小,这个空间取之于根(/) 文件系统中。这个文件就是 /var/lib/lxd/zfs.img

行了!最初的配置完成了。若有问题,或者想了解其他信息,请阅读 https://www.stgraber.org/2016/03/15/lxd-2-0-installing-and-configuring-lxd-212/

创建第一个容器

所有 LXD 的管理操作都可以通过 lxc 命令来进行。我们通过给 lxc 不同参数来管理容器。

lxc list

可以列出所有已经安装的容器。很明显,这个列表现在是空的,但这表示我们的安装是没问题的。

lxc image list

列出可以用来启动容器的(已经缓存的)镜像列表。很明显这个列表也是空的,但这也说明我们的安装是没问题的。

lxc image list ubuntu:

列出可以下载并启动容器的远程镜像。而且指定了显示 Ubuntu 镜像。

lxc image list images:

列出可以用来启动容器的(已经缓存的)各种发行版的镜像列表。这会列出各种发行版的镜像比如 Alpine、Debian、Gentoo、Opensuse 以及 Fedora。

让我们启动一个 Ubuntu 16.04 容器,并称之为 c1

$ lxc launch ubuntu:x c1
Creating c1
Starting c1
$ 

我们使用 launch 动作,然后选择镜像 ubuntu:xx 表示 Xenial/16.04 镜像),最后我们使用名字 c1 作为容器的名称。

让我们来看看安装好的首个容器,

$ lxc list

+---------|---------|----------------------|------|------------|-----------+
| NAME | STATE | IPV4 | IPV6 | TYPE | SNAPSHOTS |
+---------|---------|----------------------|------|------------|-----------+
| c1 | RUNNING | 10.173.82.158 (eth0) | | PERSISTENT | 0 |
+---------|---------|----------------------|------|------------|-----------+

我们的首个容器 c1 已经运行起来了,它还有自己的 IP 地址(可以本地访问)。我们可以开始用它了!

安装 web 服务器

我们可以在容器中运行命令。运行命令的动作为 exec

$ lxc exec c1 -- uptime
 11:47:25 up 2 min,0 users,load average:0.07,0.05,0.04
$ _

exec 后面,我们指定容器、最后输入要在容器中运行的命令。该容器的运行时间只有 2 分钟,这是个新出炉的容器:-)。

命令行中的 -- 跟我们 shell 的参数处理过程有关。若我们的命令没有任何参数,则完全可以省略 -

$ lxc exec c1 -- df -h

这是一个必须要 - 的例子,由于我们的命令使用了参数 -h。若省略了 -,会报错。

然后我们运行容器中的 shell 来更新包列表。

$ lxc exec c1 bash
root@c1:~# apt update
Ign http://archive.ubuntu.com trusty InRelease
Get:1 http://archive.ubuntu.com trusty-updates InRelease [65.9 kB]
Get:2 http://security.ubuntu.com trusty-security InRelease [65.9 kB]
...
Hit http://archive.ubuntu.com trusty/universe Translation-en 
Fetched 11.2 MB in 9s (1228 kB/s) 
Reading package lists... Done
root@c1:~# apt upgrade
Reading package lists... Done
Building dependency tree 
...
Processing triggers for man-db (2.6.7.1-1ubuntu1) ...
Setting up dpkg (1.17.5ubuntu5.7) ...
root@c1:~# _

我们使用 nginx 来做 web 服务器。nginx 在某些方面要比 Apache web 服务器更酷一些。

root@c1:~# apt install nginx
Reading package lists... Done
Building dependency tree
...
Setting up nginx-core (1.4.6-1ubuntu3.5) ...
Setting up nginx (1.4.6-1ubuntu3.5) ...
Processing triggers for libc-bin (2.19-0ubuntu6.9) ...
root@c1:~# _

让我们用浏览器访问一下这个 web 服务器。记住 IP 地址为 10.173.82.158,因此你需要在浏览器中输入这个 IP。

lxd-nginx

让我们对页面文字做一些小改动。回到容器中,进入默认 HTML 页面的目录中。

root@c1:~# cd /var/www/html/
root@c1:/var/www/html# ls -l
total 2
-rw-r--r-- 1 root root 612 Jun 25 12:15 index.nginx-debian.html
root@c1:/var/www/html#

使用 nano 编辑文件,然后保存:

lxd-nginx-nano

之后,再刷一下页面看看,

lxd-nginx-modified

清理

让我们清理一下这个容器,也就是删掉它。当需要的时候我们可以很方便地创建一个新容器出来。

$ lxc list
+---------+---------+----------------------+------+------------+-----------+
| NAME | STATE   | IPV4                 | IPV6 | TYPE       | SNAPSHOTS    |
+---------+---------+----------------------+------+------------+-----------+
| c1   | RUNNING | 10.173.82.169 (eth0) |      | PERSISTENT | 0            |
+---------+---------+----------------------+------+------------+-----------+
$ lxc stop c1
$ lxc delete c1
$ lxc list
+---------+---------+----------------------+------+------------+-----------+
| NAME | STATE   | IPV4                 | IPV6 | TYPE       | SNAPSHOTS    |
+---------+---------+----------------------+------+------------+-----------+
+---------+---------+----------------------+------+------------+-----------+

我们停止(关闭)这个容器,然后删掉它了。

本文至此就结束了。关于容器有很多玩法。而这只是配置 Ubuntu 并尝试使用容器的第一步而已。


via: https://blog.simos.info/trying-out-lxd-containers-on-our-ubuntu/

作者:Simos Xenitellis 译者:lujun9972 校对:wxy

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

容器正在改变我们对应用程序和基础设施的看法。无论容器内的代码量是大还是小,容器架构都会引起代码如何与硬件相互作用方式的改变 —— 它从根本上将其从基础设施中抽象出来。对于容器安全来说,在 Docker 中,容器的安全性有三个关键组成部分,它们相互作用构成本质上更安全的应用程序。

Docker Security

构建更安全的应用程序的一个关键因素是与系统和其他应用程序进行安全通信,这通常需要证书、令牌、密码和其他类型的验证信息凭证 —— 通常称为应用程序 涉密信息 secrets 。我们很高兴可以推出 Docker Secrets,这是一个容器原生的解决方案,它是加强容器安全的 可信赖交付 Trusted Delivery 组件,用户可以在容器平台上直接集成涉密信息分发功能。

有了容器,现在应用程序是动态的,可以跨越多种环境移植。这使得现存的涉密信息分发的解决方案略显不足,因为它们都是针对静态环境。不幸的是,这导致了应用程序涉密信息管理不善的增加,在不安全的、土造的方案中(如将涉密信息嵌入到 GitHub 这样的版本控制系统或者同样糟糕的其它方案),这种情况十分常见。

Docker 涉密信息管理介绍

根本上我们认为,如果有一个标准的接口来访问涉密信息,应用程序就更安全了。任何好的解决方案也必须遵循安全性实践,例如在传输的过程中,对涉密信息进行加密;在不用的时候也对涉密数据进行加密;防止涉密信息在应用最终使用时被无意泄露;并严格遵守最低权限原则,即应用程序只能访问所需的涉密信息,不能多也不能不少。

通过将涉密信息整合到 Docker 编排,我们能够在遵循这些确切的原则下为涉密信息的管理问题提供一种解决方案。

下图提供了一个高层次视图,并展示了 Docker swarm 模式体系架构是如何将一种新类型的对象 —— 一个涉密信息对象,安全地传递给我们的容器。

Docker Secrets Management

在 Docker 中,涉密信息是任意的数据块,比如密码、SSH 密钥、TLS 凭证,或者任何其他本质上敏感的数据。当你将一个涉密信息加入 swarm 集群(通过执行 docker secret create )时,利用在引导新集群时自动创建的内置证书颁发机构,Docker 通过相互认证的 TLS 连接将密钥发送给 swarm 集群管理器。

$ echo "This is a secret" | docker secret create my_secret_data -

一旦,涉密信息到达某个管理节点,它将被保存到内部的 Raft 存储区中。该存储区使用 NACL 开源加密库中的 Salsa20、Poly1305 加密算法生成的 256 位密钥进行加密,以确保从来不会把任何涉密信息数据写入未加密的磁盘。将涉密信息写入到内部存储,赋予了涉密信息跟其它 swarm 集群数据一样的高可用性。

当 swarm 集群管理器启动时,包含涉密信息的加密 Raft 日志通过每一个节点独有的数据密钥进行解密。此密钥以及用于与集群其余部分通信的节点 TLS 证书可以使用一个集群级的加密密钥进行加密。该密钥称为“解锁密钥”,也使用 Raft 进行传递,将且会在管理器启动的时候使用。

当授予新创建或运行的服务权限访问某个涉密信息权限时,其中一个管理器节点(只有管理器可以访问被存储的所有涉密信息)会通过已经建立的 TLS 连接将其分发给正在运行特定服务的节点。这意味着节点自己不能请求涉密信息,并且只有在管理器提供给他们的时候才能访问这些涉密信息 —— 严格地控制请求涉密信息的服务。

$ docker service  create --name="redis" --secret="my_secret_data" redis:alpine

未加密的涉密信息被挂载到一个容器,该容器位于 /run/secrets/<secret_name> 的内存文件系统中。

$ docker exec $(docker ps --filter name=redis -q) ls -l /run/secrets
total 4
-r--r--r--    1 root     root            17 Dec 13 22:48 my_secret_data

如果一个服务被删除或者被重新安排在其他地方,集群管理器将立即通知所有不再需要访问该涉密信息的节点,这些节点将不再有权访问该应用程序的涉密信息。

$ docker service update --secret-rm="my_secret_data" redis

$ docker exec -it $(docker ps --filter name=redis -q) cat /run/secrets/my_secret_data

cat: can't open '/run/secrets/my_secret_data': No such file or directory

查看 Docker Secret 文档以获取更多信息和示例,了解如何创建和管理您的涉密信息。同时,特别感谢 Laurens Van Houtven 与 Docker 安全和核心团队合作使这一特性成为现实。

通过 Docker 更安全地使用应用程序

Docker 涉密信息旨在让开发人员和 IT 运营团队可以轻松使用,以用于构建和运行更安全的应用程序。它是首个被设计为既能保持涉密信息安全,并且仅在特定的容器需要它来进行必要的涉密信息操作的时候使用。从使用 Docker Compose 定义应用程序和涉密数据,到 IT 管理人员直接在 Docker Datacenter 中部署的 Compose 文件,涉密信息、网络和数据卷都将加密并安全地与应用程序一起传输。

更多相关学习资源:


via: https://blog.docker.com/2017/02/docker-secrets-management/

作者:Ying Li 译者:HardworkFish 校对:imquanquan, wxy

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

在早先的教程中,我们学过了在 RHEL CentOS 7 上安装 Docker 并创建 docker 容器。 在本教程中,我们会学习管理 docker 容器的其他命令。

Docker 命令语法

$ docker [option] [command] [arguments]

要列出 docker 支持的所有命令,运行

$ docker

我们会看到如下结果,

attach Attach to a running container
build  Build an image from a Dockerfile
commit  Create a new image from a container's changes
cp  Copy files/folders between a container and the local filesystem
create  Create a new container
diff  Inspect changes on a container's filesystem
events  Get real time events from the server
exec  Run a command in a running container
export  Export a container's filesystem as a tar archive
history  Show the history of an image
images  List images
import  Import the contents from a tarball to create a filesystem image
info  Display system-wide information
inspect  Return low-level information on a container or image
kill  Kill a running container
load  Load an image from a tar archive or STDIN
login  Log in to a Docker registry
logout  Log out from a Docker registry
logs  Fetch the logs of a container
network  Manage Docker networks
pause  Pause all processes within a container
port  List port mappings or a specific mapping for the CONTAINER
ps  List containers
pull  Pull an image or a repository from a registry
push  Push an image or a repository to a registry
rename  Rename a container
restart  Restart a container
rm  Remove one or more containers
rmi  Remove one or more images
run  Run a command in a new container
save  Save one or more images to a tar archive
search  Search the Docker Hub for images
start  Start one or more stopped containers
stats  Display a live stream of container(s) resource usage statistics
stop  Stop a running container
tag  Tag an image into a repository
top  Display the running processes of a container
unpause  Unpause all processes within a container
update  Update configuration of one or more containers
version  Show the Docker version information
volume  Manage Docker volumes
wait  Block until a container stops, then print its exit code

要进一步查看某个命令支持的选项,运行:

$ docker docker-subcommand info

就会列出 docker 子命令所支持的选项了。

测试与 Docker Hub 的连接

默认,所有镜像都是从 Docker Hub 中拉取下来的。我们可以从 Docker Hub 上传或下载操作系统镜像。为了检查我们是否能够正常地通过 Docker Hub 上传/下载镜像,运行

$ docker run hello-world

结果应该是:

Hello from Docker.
This message shows that your installation appears to be working correctly.
…

输出结果表示你可以访问 Docker Hub 而且也能从 Docker Hub 下载 docker 镜像。

搜索镜像

搜索容器的镜像,运行

$ docker search Ubuntu

我们应该会得到可用的 Ubuntu 镜像的列表。记住,如果你想要的是官方的镜像,请检查 official 这一列上是否为 [OK]

下载镜像

一旦搜索并找到了我们想要的镜像,我们可以运行下面语句来下载它:

$ docker pull Ubuntu

要查看所有已下载的镜像,运行:

$ docker images

运行容器

使用已下载镜像来运行容器,使用下面命令:

$ docker run -it Ubuntu

这里,使用 -it 会打开一个 shell 与容器交互。容器启动并运行后,我们就可以像普通机器那样来使用它了,我们可以在容器中执行任何命令。

显示所有的 docker 容器

要列出所有 docker 容器,运行:

$ docker ps

会输出一个容器列表,每个容器都有一个容器 id 标识。

停止 docker 容器

要停止 docker 容器,运行:

$ docker stop container-id

从容器中退出

要从容器中退出,执行:

$ exit

保存容器状态

容器运行并更改后(比如安装了 apache 服务器),我们可以保存容器状态。这会在本地系统上保存新创建镜像。

运行下面语句来提交并保存容器状态:

$ docker commit 85475ef774 repository/image_name

这里,commit 命令会保存容器状态,85475ef774,是容器的容器 id,repository,通常为 docker hub 上的用户名 (或者新加的仓库名称)image_name,是新镜像的名称。

我们还可以使用 -m-a 来添加更多信息。通过 -m,我们可以留个信息说 apache 服务器已经安装好了,而 -a 可以添加作者名称。

像这样:

 docker commit -m "apache server installed"-a "Dan Daniels" 85475ef774 daniels_dan/Cent_container

我们的教程至此就结束了,本教程讲解了一下 Docker 中的那些重要的命令,如有疑问,欢迎留言。


via: http://linuxtechlab.com/important-docker-commands-beginners/

作者:Shusain 译者:lujun9972 校对:wxy

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

为什么选择 Docker 和 Kubernetes 呢?

容器允许我们构建、发布和运行分布式应用。它们使应用程序摆脱了机器限制,可以让我们以一定的方式创建一个复杂的应用程序。

使用容器编写应用程序可以使开发、QA 更加接近生产环境(如果你努力这样做的话)。通过这样做,可以更快地发布修改,并且可以更快地测试整个系统。

Docker 这个容器式平台就是为此为生,可以使软件独立于云提供商。

但是,即使使用容器,移植应用程序到任何一个云提供商(或私有云)所需的工作量也是不可忽视的。应用程序通常需要自动伸缩组、持久远程磁盘、自动发现等。但是每个云提供商都有不同的机制。如果你想使用这些功能,很快你就会变的依赖于云提供商。

这正是 Kubernetes 登场的时候。它是一个容器 编排 orchestration 系统,它允许您以一定的标准管理、缩放和部署应用程序的不同部分,并且成为其中的重要工具。它的可移植抽象层兼容主要云的提供商(Google Cloud,Amazon Web Services 和 Microsoft Azure 都支持 Kubernetes)。

可以这样想象一下应用程序、容器和 Kubernetes。应用程序可以视为一条身边的鲨鱼,它存在于海洋中(在这个例子中,海洋就是您的机器)。海洋中可能还有其他一些宝贵的东西,但是你不希望你的鲨鱼与小丑鱼有什么关系。所以需要把你的鲨鱼(你的应用程序)移动到一个密封的水族馆中(容器)。这很不错,但不是特别的健壮。你的水族馆可能会被打破,或者你想建立一个通道连接到其他鱼类生活的另一个水族馆。也许你想要许多这样的水族馆,以防需要清洁或维护……这正是应用 Kubernetes 集群的作用。

进化到 Kubernetes

主流云提供商对 Kubernetes 提供了支持,从开发环境到生产环境,它使您和您的团队能够更容易地拥有几乎相同的环境。这是因为 Kubernetes 不依赖专有软件、服务或基础设施。

事实上,您可以在您的机器中使用与生产环境相同的部件启动应用程序,从而缩小了开发和生产环境之间的差距。这使得开发人员更了解应用程序是如何构建在一起的,尽管他们可能只负责应用程序的一部分。这也使得在开发流程中的应用程序更容易的快速完成测试。

如何使用 Kubernetes 工作?

随着更多的人采用 Kubernetes,新的问题出现了;应该如何针对基于集群环境进行开发?假设有 3 个环境,开发、质量保证和生产, 他们如何适应 Kubernetes?这些环境之间仍然存在着差异,无论是在开发周期(例如:在运行中的应用程序中我的代码的变化上花费时间)还是与数据相关的(例如:我不应该在我的质量保证环境中测试生产数据,因为它里面有敏感信息)。

那么,我是否应该总是在 Kubernetes 集群中编码、构建映像、重新部署服务,在我编写代码时重新创建部署和服务?或者,我是否不应该尽力让我的开发环境也成为一个 Kubernetes 集群(或一组集群)呢?还是,我应该以混合方式工作?

用本地集群进行开发

如果继续我们之前的比喻,上图两边的洞表示当使其保持在一个开发集群中的同时修改应用程序的一种方式。这通常通过来实现

Kubernetes 系列

本 Kubernetes 系列资源是开源的,可以在这里找到: https://github.com/red-gate/ks

我们写这个系列作为以不同的方式构建软件的练习。我们试图约束自己在所有环境中都使用 Kubernetes,以便我们可以探索这些技术对数据和数据库的开发和管理造成影响。

这个系列从使用 Kubernetes 创建基本的 React 应用程序开始,并逐渐演变为能够覆盖我们更多开发需求的系列。最后,我们将覆盖所有应用程序的开发需求,并且理解在数据库生命周期中如何最好地迎合容器和集群。

以下是这个系列的前 5 部分:

  1. ks1:使用 Kubernetes 构建一个 React 应用程序
  2. ks2:使用 minikube 检测 React 代码的更改
  3. ks3:添加一个提供 API 的 Python Web 服务器
  4. ks4:使 minikube 检测 Python 代码的更改
  5. ks5:创建一个测试环境

本系列的第二部分将添加一个数据库,并尝试找出最好的方式来开发我们的应用程序。

通过在各种环境中运行 Kubernetes,我们被迫在解决新问题的同时也尽量保持开发周期。我们不断尝试 Kubernetes,并越来越习惯它。通过这样做,开发团队都可以对生产环境负责,这并不困难,因为所有环境(从开发到生产)都以相同的方式进行管理。

下一步是什么?

我们将通过整合数据库和练习来继续这个系列,以找到使用 Kubernetes 获得数据库生命周期的最佳体验方法。

这个 Kubernetes 系列是由 Redgate 研发部门 Foundry 提供。我们正在努力使数据和容器的管理变得更加容易,所以如果您正在处理数据和容器,我们希望听到您的意见,请直接联系我们的开发团队。 [email protected]


我们正在招聘。您是否有兴趣开发产品、创建未来技术 并采取类似创业的方法(没有风险)?看看我们的软件工程师 - 未来技术的角色吧,并阅读更多关于在 英国剑桥的 Redgate 工作的信息。


via: https://medium.com/ingeniouslysimple/adopting-kubernetes-step-by-step-f93093c13dfe

作者:santiago arias 译者:aiwhj 校对:wxy

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

嵌套虚拟化意味着在虚拟机内配置虚拟化环境。换句话说,我们可以说嵌套虚拟化是 虚拟机管理程序 hypervisor 的一个特性,它允许我们通过虚拟化管理程序(宿主机)的硬件加速在虚拟服务器内安装和运行虚拟机。

在这篇文章中,我们将讨论如何在 CentOS 7 / RHEL 7 的 KVM 上启用嵌套虚拟化。我假定您已经配置过 KVM 管理程序。如果您不熟悉如何安装和配置 KVM 管理程序,请参考以下文章。

在 CentOS 7.x 和 RHEL 7.x 安装 KVM 管理程序

让我们进入虚拟化管理程序,验证您的 KVM 宿主机是否启用了嵌套虚拟化。

基于 Intel 的处理器运行以下命令:

[root@kvm-hypervisor ~]# cat /sys/module/kvm_intel/parameters/nested
N

基于 AMD 的处理器运行以下命令:

[root@kvm-hypervisor ~]# cat /sys/module/kvm_amd/parameters/nested
N

上述命令输出 N 表示嵌套虚拟化是禁用的。如果我们得到的输出是 Y 则表示在您的宿主机已启用嵌套虚拟化。

现在启用嵌套虚拟化,使用以下内容创建一个文件名为 /etc/modprobe.d/kvm-nested.conf 的文件:

[root@kvm-hypervisor ~]# vi /etc/modprobe.d/kvm-nested.conf
options kvm-intel nested=1
options kvm-intel enable_shadow_vmcs=1
options kvm-intel enable_apicv=1
options kvm-intel ept=1

保存并退出文件。

现在移除 kvm_intel 模块然后通过 modprobe 命令添加同样的模块。在移除模块之前,确保虚拟机已关机,否则我们会得到像 “modprobe: FATAL: Module kvm\_intel is in use” 这样的错误信息。

[root@kvm-hypervisor ~]# modprobe -r kvm_intel
[root@kvm-hypervisor ~]# modprobe -a kvm_intel

现在验证嵌套虚拟化功能是否启用。

[root@kvm-hypervisor ~]# cat /sys/module/kvm_intel/parameters/nested
Y

测试嵌套虚拟化

假设我们在 KVM 管理程序上有一台已经启用了嵌套虚拟化的名为 “director” 的虚拟机。在测试之前,确保 CPU 模式为 “host-modle” 或 “host-passthrough” ,使用 Virt-Manager 或 virtsh 编辑命令检查虚拟机的 CPU 模式。

cpu_mode_vm_kvm

现在登录 director 这台虚拟机并运行 lscpulsmod 命令。

[root@kvm-hypervisor ~]# ssh 192.168.126.1 -l root
[email protected]'s password:
Last login: Sun Dec 10 07:05:59 2017 from 192.168.126.254
[root@director ~]# lsmod | grep kvm
kvm_intel             170200  0
kvm                   566604  1 kvm_intel
irqbypass              13503  1 kvm
[root@director ~]# lscpu

lscpu_command_rhel7_centos7

让我们试着在 director 这台虚拟机的虚拟管理器 GUI 或 virt-install 命令创建一台虚拟机,在我的情况下我使用 virt-install 命令。

[root@director ~]# virt-install  -n Nested-VM  --description "Test Nested VM"  --os-type=Linux  --os-variant=rhel7  --ram=2048  --vcpus=2  --disk path=/var/lib/libvirt/images/nestedvm.img,bus=virtio,size=10  --graphics none  --location /var/lib/libvirt/images/CentOS-7-x86_64-DVD-1511.iso --extra-args console=ttyS0
Starting install...
Retrieving file .treeinfo...                                                   | 1.1 kB  00:00:00
Retrieving file vmlinuz...                                                     | 4.9 MB  00:00:00
Retrieving file initrd.img...                                                  |  37 MB  00:00:00
Allocating 'nestedvm.img'                                                      |  10 GB  00:00:00
Connected to domain Nested-VM
Escape character is ^]
[    0.000000] Initializing cgroup subsys cpuset
[    0.000000] Initializing cgroup subsys cpu
[    0.000000] Initializing cgroup subsys cpuacct
[    0.000000] Linux version 3.10.0-327.el7.x86_64 ([email protected]) (gcc version 4.8.3 20140911 (Red Hat 4.8.3-9) (GCC) ) #1 SMP Thu Nov 19 22:10:57 UTC 2015
………………………………………………

cli-installer-virt-install-command-kvm

这证实了嵌套虚拟化已成功启用,因为我们能在虚拟机内创建虚拟机。

这篇文章到此结束,请分享您的反馈和意见。


via: https://www.linuxtechi.com/enable-nested-virtualization-kvm-centos-7-rhel-7/

作者:Pradeep Kumar 译者:zjon 校对:wxy

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

Ansible Container 解决了 Dockerfile 的不足,并对容器化项目提供了完整的管理。

 title=

Image by : opensource.com

我喜欢容器,并且每天都使用这个技术。即便如此,容器并不完美。不过,在过去几个月里,一系列项目已经解决了我遇到的一些问题。

我刚开始时,用 Docker 使用容器,这个项目使得这种技术非常流行。除了使用这个容器引擎之外,我学到了怎么去使用 docker-compose 以及怎么去用它管理我的项目。使用它使得我的生产力猛增!一个命令就可以运行我的项目,而不管它有多复杂。因此,我太高兴了。

使用一段时间之后,我发现了一些问题。最明显的问题是创建容器镜像的过程。Docker 工具使用一个定制的文件格式作为生成容器镜像的依据:Dockerfile。这个格式易于学习,并且很短的一段时间之后,你就可以自己制作容器镜像了。但是,一旦你希望进一步掌握它或者考虑到复杂场景,问题就会出现。

让我们打断一下,先去了解一个不同的东西:Ansible 的世界。你知道它吗?它棒极了,是吗?你不这么认为?好吧,是时候去学习一些新事物了。Ansible 是一个允许你通过写一些任务去管理你的基础设施,并在你选择的环境中运行它们的项目。不需要去安装和设置任何的服务;你可以从你的笔记本电脑中很容易地做任何事情。许多人已经接受 Ansible 了。

想像一下这样的场景:你在 Ansible 中,你写了很多的 Ansible 角色 role 剧本 playbook ,你可以用它们去管理你的基础设施,并且你想把它们运用到容器中。你应该怎么做?通过 shell 脚本和 Dockerfile 去写容器镜像定义?听起来好像不对。

来自 Ansible 开发团队的一些人问到这个问题,并且他们意识到,人们每天编写和使用的那些同样的 Ansible 角色和剧本也可以用来制作容器镜像。但是 Ansible 能做到的不止这些 —— 它可以被用于去管理容器化项目的完整生命周期。从这些想法中,Ansible Container 项目诞生了。它利用已有的 Ansible 角色转变成容器镜像,甚至还可以被用于生产环境中从构建到部署的完整生命周期。

现在让我们讨论一下,我之前提到过的在 Dockerfile 环境中的最佳实践问题。这里有一个警告:这将是非常具体且技术性的。出现最多的三个问题有:

1、 在 Dockerfile 中内嵌的 Shell 脚本

当写 Dockerfile 时,你可以指定会由 /bin/sh -c 解释执行的脚本。它类似如下:

RUN dnf install -y nginx

这里 RUN 是一个 Dockerfile 指令,其它的都是参数(它们传递给 shell)。但是,想像一个更复杂的场景:

RUN set -eux; \
    \
# this "case" statement is generated via "update.sh"
    %%ARCH-CASE%%; \
    \
    url="https://golang.org/dl/go${GOLANG_VERSION}.${goRelArch}.tar.gz"; \
    wget -O go.tgz "$url"; \
    echo "${goRelSha256} *go.tgz" | sha256sum -c -; \

这仅是从 golang 官方镜像 中拿来的一段。它看起来并不好看,是不是?

2、 解析 Dockerfile 并不容易

Dockerfile 是一个没有正式规范的新格式。如果你需要在你的基础设施(比如,让构建过程自动化一点)中去处理 Dockerfile 将会很复杂。仅有的规范是 这个代码,它是 dockerd 的一部分。问题是你不能使用它作为一个 library 来使用。最容易的解决方案是你自己写一个解析器,然后祈祷它运行的很好。使用一些众所周知的标记语言不是更好吗?比如,YAML 或者 JSON。

3、 管理困难

如果你熟悉容器镜像的内部结构,你可能知道每个镜像是由 layer 构成的。一旦容器被创建,这些层就使用联合文件系统技术堆叠在一起(像煎饼一样)。问题是,你并不能显式地管理这些层 — 你不能说,“这儿开始一个新层”,你被迫使用一种可读性不好的方法去改变你的 Dockerfile。最大的问题是,必须遵循一套最佳实践以去达到最优结果 — 新来的人在这个地方可能很困难。

Ansible 语言和 Dockerfile 比较

相比 Ansible,Dockerfile 的最大缺点,也是 Ansible 的优点,作为一个语言,Ansible 更强大。例如,Dockerfile 没有直接的变量概念,而 Ansible 有一个完整的模板系统(变量只是它其中的一个特性)。Ansible 包含了很多更易于使用的模块,比如,wait\_for,它可以被用于服务就绪检查,比如,在处理之前等待服务准备就绪。在 Dockerfile 中,做任何事情都通过一个 shell 脚本。因此,如果你想去找出已准备好的服务,它必须使用 shell(或者独立安装)去做。使用 shell 脚本的其它问题是,它会变得很复杂,维护成为一种负担。很多人已经发现了这个问题,并将这些 shell 脚本转到 Ansible。

关于作者

Tomas Tomecek - 工程师、Hacker、演讲者、Tinker、Red Hatter。喜欢容器、linux、开源软件、python 3、rust、zsh、tmux。More about me


via: https://opensource.com/article/17/10/dockerfiles-ansible-container

作者:Tomas Tomecek 译者:qhwdw 校对:wxy

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