1. 环境说明

  对于一个配置略高的工作站如果一个人使用有点浪费了,可以考虑把资源分享给小组成员,大家时分复用或者资源复用可以有效的提高生产力,现在容器化和虚拟技术为我们提供了这样的方式,并且可以很方便的管理和分配。Windows 10 已经可以很好的实现工作站级别的容器和虚拟化,比如 Hyper-V 与 Docker for Windows 的组合,但是从容器的效率来讲,还是采用 Linux 平台比较精彩。下面来记录一下我将自己的工作站容器化(Docker)和虚拟化(KVM)的实践过程。
   相对于服务器级别的容器化和虚拟化,在工作站上面要轻松许多,因为毕竟工作站的主要用途是开发的调试和测试,对服务的稳定性和安全性都和服务器不再一个等级上,可以大胆的使用社区版的软件,可以大胆的手动解决开源软件中的Bug .
  首先需要一个用着顺手的 Linux 发行版,从安装的便捷性和大众性考虑我这里使用 Ubuntu 16.04 作为本次实践的宿主操作系统(host). 使用下面命令检测以下工作站硬件是否支持虚拟化:

egrep '(vmx|svm)' /proc/cpuinfo

然后是网络连接方式,一个人使用的工作站生成的虚拟机或者容器可以采用NAT的方式,这样比较安全,也是很多虚拟化软件的默认网络配置,但如果想把宿主主机生成的容器和虚拟机分享给组织内的其他成员,就需要使用网桥(bridge)的方式来连接host生成的容器和虚拟机,下面是需要实现的工作站网络连接示意图:

安全提示:修改网络操作可能会导致工作站不可远程访问,配置时请尽可能使用本地显示器+本地键盘的方式进行

Ubuntu 16.04默认情况下有线网卡的命名是 enp3sxx 的格式,把它还原成 eth0 的命名方式。在 /etc/default/grub 中,GRUB_CMDLINE_LINUX里添加参数net.ifnames=0 biosdevname=0,sudo方式执行下面命令:

echo "GRUB_CMDLINE_LINUX=\"net.ifnames=0 biosdevname=0\"" >> /etc/default/grub && update-grub

安装 bridge-utils 网桥管理工具

apt-get install bridge-utils

停止使用 NetworkManager 自动化网络配置工具,因为我们要使用纯手动的方式(networking)来管理网络配置:

systemctl stop NetworkManager && systemctl disable NetworkManager

手动修改网络配置文件 /etc/network/interfaces

auto lo
iface lo inet loopbackauto eth0
iface eth0 inet loopbackauto br0
iface br0 inet static
address /*YOUR_HOST_IP_ADDRESS*/
netmask /*YOUR_HOST_NET_MASK*/
gateway /*YOUR_HOST_GATEWAY*/
dns-nameservers /*YOUR_HOST_DNS*/
bridge_stp off
bridge_fd 0
bridge_ports eth0

保存文件并重启(reboot)后通过 ifconfig 或者 ls /proc/sys/net/ipv4/conf 看到生成的网桥配置
如果出现问题,可以通过 systemctl status networking 或者 journalctl -xe 查看日志排除问题。


2. 容器化

  Docker CE 的安装这里就不去赘述了,可以参考这个链接: https://docs.docker.com/install/linux/docker-ce/ubuntu/
如果是Nvidia显卡的主机,建议安装 nvidia-docker 插件 https://github.com/NVIDIA/nvidia-docker ,使用 nvidia-container-runtime 可以将硬件GPU映射到容器内,对于视频处理和深度学习的容器非常有用。
Docker CE 默认情况下容器是不能直接暴露到真实网络中的,这时你需要docker工程师自己写的一个脚本 pipework

wget -P /usr/local/bin/ \
https://raw.githubusercontent.com/jpetazzo/pipework/master/pipework

Docker CE 只提供了命令行的访问和控制方式,掌握CLI(command line interface)的方式是必须的,但对于多人协作时,还是WBI(web interface)的方式比较靠谱,综合对比了几种 Docker web UI 的软件( DockerUI, Shipyard, Portainer ),最后还是觉得 Portainer 比较适合工作站上面部署,首先把 portainer 的镜像 pull 到本地:

docker pull portainer/portainer

通过下面命令查看 portainer/portainer 镜像需要映射的 port 和需要挂载的 volume :

image="portainer/portainer"
docker inspect ${image} | jq -r '.[0].ContainerConfig.Volumes'
docker inspect ${image} | jq -r '.[0].ContainerConfig.ExposedPorts'

下面描述三种部署 Portainer 的方式:
1. 以 Docker container 的方式运行:

docker run -d \
--name portainer \
--privileged=true \
--restart=always \
-p 9000:9000 \
-v /data/volume/portainer-data:/data \
-v /var/run/docker.sock:/var/run/docker.sock \
portainer/portainer

2. 以 Docker service 的方式运行:

docker swarm init
docker service create \
--name portainer \
--publish 9000:9000 \
--constraint 'node.role == manager' \
--mount type=bind,src=//var/run/docker.sock,dst=/var/run/docker.sock \
--mount type=bind,src=//data/volume/portainer-data,dst=/data \
portainer/portainer \
-H unix:///var/run/docker.sock

3. 以系统服务的方式运行:

新建并编辑文件 /etc/systemd/system/docker-portainer.service :

 [Unit]
Description=Docker portainer Server
After=docker.service
Requires=docker.service[Service]
ExecStartPre=/usr/bin/docker kill portainer
ExecStartPre=/usr/bin/docker rm portainer
ExecStart=/usr/bin/docker run --name portainer --privileged=true -v /data/volume/portainer-data:/data -v /var/run/docker.sock:/var/run/docker.sock portainer/portainer
ExecStartPost=/usr/local/bin/pipework br0 portainer YOUR_IP_ADDRESS/YOUR_NET_MASK@YOUR_GATEWAY
ExecStop=/usr/bin/docker stop portainer[Install]
WantedBy=multi-user.target

然后启动服务:

systemctl start docker-portainer.service
systemctl enable docker-portainer.service

第3种方法的优点是:我们可以通过将容器封装成系统服务的同时,在容器启动后自动执行 pipework 将容器的网络映射到真实网络中。
下面是 portainer 容器运行后的截图,管理工作站的 docker 服务非常方便并且一目了然。

  在这里填一个小坑,默认情况下使用 ‘docker exec -it xxx bash’ 进入一个容器时,默认打开的terminal大小是 80X24 的分辨率,使用起来非常不方便,与自己的显示器极不协调,尤其是想在容器内使用 tmux 的情况,在 stackoverflow 上找到了一种解决方法,把下面代码加入到 ~/.bashrc 文件中,然后 srouce ~/.bashrc 使其生效:

# docker 容器 tty 默认分辨率修改
docker-inside(){docker exec -it $1 bash -c "stty cols $COLUMNS rows $LINES && bash";
}
export -f docker-inside

使用 stty 将进入的容器的 terminfo 参数修改成当前 shell 相同的行数和列数,使用起来非常方便。


3. 虚拟化

  虚拟组件的系统堆栈是这样子的:

  下面来描述虚拟化的实践过程,Ubuntu 发行版的内核中已经默认挂载了 KVM 模块:

lsmod | grep kvm

检查一下CPU是否支持虚拟化,执行一下命令来检查/proc/cpuinfo文件中是否又虚拟化相关的字眼,如果有的话表明CPU支持虚拟化技术。

egrep -c '(svm|vmx)' /proc/cpuinfo

上面命令执行结果如果返回0,表示CPU不支持虚拟化技术。当然主板BIOS中的虚拟化技术也可能不是默认开启的,如果没有开启需要手动开启一下。

需要安装 libvirtd 服务,通过 libvirtd 服务与 libvirt API 通信来管理和控制虚拟机的运行。

  • Libvirtd 是一个 daemon 进程,可以被本地的virsh调用,也可以被远程的virsh调用
  • Libvirtd 调用 qemu-kvm 操作KVM 虚拟机

安装必要的虚拟化组件:

apt-get install kvm libvirt-bin bridge-utils sasl2-bin

修改 libvirtd 的配置文件,使其可以远程访问:

sed -i 's/#libvirtd_opts=""/libvirtd_opts="-l"/g' /etc/default/libvirt-binsed -i 's/#listen_tls/listen_tls/g' /etc/libvirt/libvirtd.conf
sed -i 's/#listen_tcp/listen_tcp/g' /etc/libvirt/libvirtd.conf
sed -i 's/#auth_tcp/auth_tcp/g'     /etc/libvirt/libvirtd.confsed -i 's/#vnc_listen/vnc_listen/g' /etc/libvirt/qemu.conf

重新启动 libvirtd 服务:

systemctl daemon-reload
systemctl restart libvirtd

  • 创建一个可以远程访问 libvirtd 的用户:
saslpasswd2 -a libvirt aggresss
  • 查看用户列表:
sasldblistusers2 -f /etc/libvirt/passwd.db
  • 删除一个可以远程访问 libvirtd 的用户:
saslpasswd2 -a libvirt -d aggresss

测试 libvirtd 服务是否可以远程访问:

virsh -c qemu+tcp://localhost/system nodeinfo

创建虚拟机的磁盘空间(参考命令,请根据自己的磁盘结构自行划分):

lvcreate -L 200G -n lv-virt vgpool
mkfs.ext4 /dev/vgpool/lv-virt
blkid
vim /etc/fstab
mount -a

  理论上现在就可以使用 virsh 来管理虚拟机了,就像CLI模式下的 docker命令,但是 virsh 命令要比 docker 命令复杂很多,而且用它来创建虚拟机的参数文件需要使用 xml 格式,如果没有可视化的管理工具,实施起来将非常耗时,如果不需要远程管理虚拟机,virt-manager 是一个不错的轻量化管理工具,同时还有很多支持 KVM 的管理工具,可以在这个链接里选择: https://www.linux-kvm.org/page/Management_Tools
   管理工具的配置可能比较繁琐,而且管理工具可能会更换,所以我的原则是管理工具尽量不运行在宿主主机的环境下,一个更好的方式是将管理工具容器化,达到一个用过即抛的效果,同时也便于迁移和数据管理,经过筛选最后使用 webvirtmgr 来通过WBI的方式管理虚拟服务,并且将 webvirtmgr 容器化到一个镜像里面,可以通过下面的 GitHub repository 构建镜像: https://github.com/aggresss/docker-webvirtmgr ,也可以使用命令直接下载镜像:

docker pull aggresss/docker-webvirtmgr

运行镜像:

docker run -d \
--name webvirtmgr \
--privileged=true \
--restart=always \
-p 8080:8080 \
-p 6080:6080 \
aggresss/webvirtmgr

webvirtmgr 从2016年就没有更新了,GitHub 上的 Issues 和 Pull requests 也没有人处理,所以作为工作站的虚拟机管理还勉强能用,遇到 Bug 需要自行解决了。
webvirtmgr 在创建网络时不能创建本地的网桥网络,会提示 “The pool bridge name must not contain any special characters” 的 Bug,需要手动将本地网桥添加到 libvirtd 服务的配置文件中:

创建一个xml文件,比如 host-bridge.xml ,内容如下:

<network><name>host-bridge</name><forward mode="bridge"/><bridge name="br0"/>
</network>

然后执行:

virsh net-define ./host-bridge.xml
virsh net-autostart host-bridge
virsh net-start host-bridge

webvirtmgr 默认通过 noVNC 的方式远程控制Guest主机,下面是运行截图:


4. 总结

  将工作站容器化和虚拟化的过程记录了下来,方便大家填坑,感谢参考文档中各位大神的文章的帮助,在这里表示真诚的感谢。欢迎各位提出指导意见。


参考文档

  1. Docker网络详解及pipework源码解读与实践
  2. Advanced Docker Networking with Pipework
  3. KVM 介绍(5):libvirt 介绍 [ Libvrit for KVM/QEMU ]
  4. CentOS7.2部署KVM虚拟机
  5. libvirt.org -> Network XML format
  6. 通过noVNC和websockify连接到QEMU/KVM
  7. Use virt-manager as a non-root user on Linux

工作站的容器化和虚拟化实践相关推荐

  1. 容器化技术最佳实践1--容器化技术简介与Docker入门

    容器化技术最佳实践1–容器化技术简介与Docker入门 文章目录 容器化技术最佳实践1--容器化技术简介与Docker入门 容器化简介 通过虚拟化了解容器化 对开发和运维的好处 容器化部署特点 什么情 ...

  2. 应用容器化之Kubernetes实践

    容器是一种轻量级的虚拟化技术,拥有持续集成.版本控制.可移植性.隔离性和安全性等优点,越来越多的应用跑在容器里面.但也有其缺陷,并不是所有场景都适合如高性能计算,已经满负荷运行的应用没有必要虚拟化,一 ...

  3. 最简容器化动手小实践——再战flappybird

    <Flappy Bird>是一名越南开发者所开发的游戏,这款游戏的主要内容是帮助一只小鸟穿越水管的层层阻碍,玩家所需要的只是点击屏幕从而调整小鸟的高度.而令这款游戏与众不同的是,这款游戏的 ...

  4. 实践 | 百信银行基础设施容器化改造之路

    [百度云原生导读]作为国内首家国有控股的互联网银行,百信银行致力于用AI加速金融数字化.普惠化.在面临传统架构存在的弹性伸缩不够.资源浪费严重等问题时,百信银行借助百度天合Stack容器云平台,完成了 ...

  5. 容器化(docker)

    1.什么是容器 有效的将单个操作系统的资源划分到孤立的组中,以便更好的在孤立的组之间平衡有冲突的资源使用需求. 1.1.容器化与虚拟化 一.容器    容器是一个不依赖于操作系统,运行应用程序的环境. ...

  6. 【巨杉数据库SequoiaDB】巨杉 Tech | 几分钟实现巨杉数据库容器化部署

    随着业务负载的不断加重,容器化.虚拟化也成为各类在线应用必须要具备的能力.对于分布式数据库,容器化也是提升快速部署.提高运维效率的一个很好的路径. 我们重新优化了 Docker部署的方式,帮助大家更快 ...

  7. 工行分布式数据库选型与大规模容器化实践

    来自:DBAplus社群 本文根据顾龚磊老师在[2019 DAMS中国数据智能管理峰会]现场演讲内容整理而成. 讲师介绍 顾龚磊,工商银行开源数据库运维牵头人,带领团队管理上千个MySQL节点的日常维 ...

  8. 容器化技术如何在数据中心实践

    容器化技术是大势所趋,容器云将凭借快速部署.便捷运维等特性在物联网.边缘计算等行业中大放异彩. 主讲人|又拍云首席布道师 运维总监 邵海杨 自从虚拟化技术和云计算服务出现以来,IT公司都将虚拟机作为降 ...

  9. Coding-Job:从研发到生产的容器化融合实践

    大家好,我是来自 CODING 的全栈开发工程师,我有幸在 CODING 参与了 Coding-Job 这个容器化的编排平台的研发.大家对 CODING 可能比较了解, Coding.net 是一个一 ...

最新文章

  1. 【Python】青少年蓝桥杯_每日一题_8.19_数字组合
  2. 读债务危机0812:接管房利美和房地美
  3. 盘点18个免费的WordPress主题后台选项开发框架
  4. leetcode No.2 两数相加
  5. 20190313_C#反转绘制字符串
  6. mysql mgr 读写分离_MySQL Group Replication mgr 单主 proxysql 读写分离配置过程
  7. php libev扩展使用
  8. 虚拟机VMware镜像下载及安装Linux系统
  9. C语言程序设计知识点总结归纳(全书)
  10. 设计并实现一个员工(Employee)类(C++)
  11. 【修真院java小课堂】Shiro
  12. VUE定时器任务(每天定时12点执行)
  13. 谷歌浏览器无法访问怎么办
  14. Java中IO流-18-flush和close方法的区别
  15. java equals和==的区别
  16. MySQL 运维 日志 -- 错误日志、二进制日志、查询日志、慢查询日志
  17. 毫米波雷达AWR1642BOOST代码走读学习笔记
  18. 兄弟俩畅游Tomcat城市的SpringMVC科技园区(文末有惊喜)
  19. 麒麟操作系统之重置密码
  20. 新能源汽车产业深度研究报告:从2.0迈入3.0时代(113页)

热门文章

  1. 深信服校园招聘c/c++软件开发B卷
  2. latex附录中放python代码_LaTeX之附录设置
  3. [Linux]关于SIGCHLD
  4. 华为---ACL配置
  5. 张朝阳开课手推E=mc²,李永乐现场狂做笔记!CEO当太久都忘了他是MIT物理博士
  6. 《老路用得上的商学课》21-30学习笔记
  7. 十个高质量自学网站,让你的技术突飞猛进
  8. 一款基于企业微信的固定资产管理软件
  9. 杰力科创七彩灯雾化器芯片--DLT8P60SC
  10. 【小学信息技术教资面试】教案模板