打开微信扫一扫,关注微信公众号【数据与算法联盟】
转载请注明出处: http://blog.csdn.net/gamer_gyt
博主微博: http://weibo.com/234654758
Github: https://github.com/thinkgamer
Docker江湖
写在前边的话
在之前便想学习Docker技术了,但是一直没有机会,最近在做elk的一个项目,需要在一个不能连接外网的机器上安装各种环境,本来想一步步下载rpm包,进行安装,然而事实证明我太单纯,各种依赖包,搞的我头大,然后便想到了docker,一个可以装载环境和便于移植的小船。
环境介绍
本地 win10
VMware 虚拟机 安装的redhat 7.1 server版(模拟服务器环境)
redhat 7.1(server)上部署docker
在linux部署
安装的方法有很多种,可以选择rpm包安装,也可以使用二进制包安装,不同的os 在线安装的方式也有所不同,我这是是基于redhat7.1进行安装的,其他的一些安装方式可以参考官网(https://docs.docker.com/)
我这里采用的是安装二进制包的形式:
1、内核版本要求
查看内核版本
[redhat@localhost ~]$ uname -r
3.10.0-229.el7.x86_64
官方建议不低于3.10.0
2、下载二进制包并解压
https://get.docker.com/builds/Linux/x86_64/docker-latest.tgz
tar -xvzf docker-latest.tar
3、加载到全局变量
mv docker/* /usr/bin/
4、关闭防火墙
避免一些不必要的麻烦
systemctl status firewalld (redhat查看防火墙状态)
systemctl stop firewalld (redhat暂时关闭防火墙)
systemctl disable firewalld (redhat永久关闭防火墙)
systemctl enable firewalld (redhat打开防火墙)
5、启动服务
sudo dockerd &
6、测试
sudo docker run hello-world
会弹出来一系列看似正常的东东,然后就ok了
闲谈Docker
1、Docker是什么
Docker是一个诞生于2013年的开源项目,基于Go语言实现,遵从apache2.0协议。目标是实现轻量级的操作系统虚拟化解决方案,其基础是Linux容器(LXC)等技术。
在LXC的基础上Docker进行了进一步的封装,让用户不需要去关心容器的管理,使得操作更为简便,用户操作Docker的容器就像操作一个快速轻量级的虚拟机一样简单。
下面的图片比较了Docker和传统虚拟化方式的不同之处,可见容器是在操作系统层面上实现虚拟化,直接复用本地主机的操作系统,而传统方式则是在硬件层面实现。
推荐一篇docker架构的文章,个人感觉不错:
http://www.infoq.com/cn/articles/docker-source-code-analysis-part1/
2、为什么要使用Docker
1)、启动在秒级实现
Docker容器的启动可以在秒级实现,占用的资源也较少,其次对系统的资源利用率高,传统虚拟机方式运行10个不同的应用就要起10个虚拟机,而Docker只要启动10个隔离的应用即可,这些都决定的Docker容器的启动速度
2)、更快速的交付和部署
开发者可以使用一个标准的镜像来构建一套开发容器,开发完成之后,运维人员可以直接使用这个容器来部署代码。Docker可以快速创建容器,快速迭代应用程序,并让整个过程全程可见,使团队中的其他成员更容易理解应用程序是如何创建和工作的。Docker容器很轻很快!容器的启动时间是秒级的,大量地节约开发、测试、部署的时间。
3)、更高效的虚拟化
Docker 容器的运行不需要额外的hypervisor支持,它是内核级的虚拟化,因此可以实现更高的性能和效率。
4)、更轻松的迁移和扩展
Docker 容器几乎可以在任意的平台上运行,包括物理机、虚拟机、公有云、私有 云、个人电脑、服务器等。这种兼容性可以让用户把一个应用程序从一个平台直接迁移到另外一个。
5)、更简单的管理
使用Docker,只需要小小的修改,就可以替代以往大量的更新工作。所有的修改都以增量的方式被分发和更新,从而实现自动化并且高效的管理。
6)、对比传统虚拟机总结
特性 | 容器 | 虚拟机 |
启动 | 秒级 | 分钟级 |
硬盘使用 | 一般为MB | 一般为GB |
性能 | 接近原生 | 弱于 |
系统支持量 | 单机支持上千个容器 | 一般几十个 |
3、Docker的三个基本概念
镜像(Image)
Docker 镜像(Image)就是一个只读的模板。
例如:一个镜像可以包含一个完整的 ubuntu 操作系统环境,里面仅安装了 Apache 或用户需要的其它应用程序。
镜像可以用来创建 Docker 容器。
Docker 提供了一个很简单的机制来创建镜像或者更新现有的镜像,用户甚至可以 直接从其他人那里下载一个已经做好的镜像来直接使用。容器(Container)
Docker 利用容器(Container)来运行应用。
容器是从镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是 相互隔离的、保证安全的平台。
可以把容器看做是一个简易版的 Linux 环境(包括root用户权限、进程空间、用户 空间和网络空间等)和运行在其中的应用程序。
*注:镜像是只读的,容器在启动的时候创建一层可写层作为最上层。仓库(Repository)
仓库(Repository)是集中存放镜像文件的场所。有时候会把仓库和仓库注册服务 器(Registry)混为一谈,并不严格区分。实际上,仓库注册服务器上往往存放着 多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。
仓库分为公开仓库(Public)和私有仓库(Private)两种形式。
最大的公开仓库是 Docker Hub,存放了数量庞大的镜像供用户下载。
国内的公开仓库包括 时速云 、网易云 等,可以提供大陆用户更稳定快速的访问。
当然,用户也可以在本地网络内创建一个私有仓库(参考本文“私有仓库”部分)。
当用户创建了自己的镜像之后就可以使用 push 命令将它上传到公有或者私有仓 库,这样下次在另外一台机器上使用这个镜像时候,只需要从仓库上 pull 下来 就可以了。
*注:Docker 仓库的概念跟 Git 类似,注册服务器可以理解为 GitHub 这样的托管服 务。
docker的基本操作
执行sudo docker –help(-h)可以看到docker所支持的命令,同时有其对应的解释
attach: 进入到正在运行的容器
build: 从Dockerfile构建镜像
commit: 容器更改之后创建新镜像
cp: 在容器和本地之间拷贝文件和文件夹
create: 创建一个新的容器
diff: 检查容器文件系统上的更改
events: 从服务器上获取实时事件
exec: 在正在运行的容器中运行命令
export: 将容器的文件系统导出为tar存档
history: 显示镜像的历史记录
images: 列出镜像
import: 从tar包导入创建新的文件系统镜像
info: 显示系统范围的信息
inspect: 返回容器,映像或任务的低级信息
kill: 杀死一个或者多个正在运行的容器
load: 加载一个打包好的镜像
login: 登录到docker的服务
logout: 退出docker服务
logs: 获取容器的日志
network: 管理docker的网络
node: 管理docker swarm节点
pause: 暂停一个或多个容器中的进程
port: 列出端口映射或者容器的特定映射
ps: 列出正在运行的容器(ps -a 列出正在运行和已经停止的容器)
pull: 从注册表中加载一个镜像
push: 将镜像提交到注册表中
rename: 重命名容器
restart: 重新启动容器
rm: 删除一个或者多个容器
rmi: 删除一个或者多个容器
run: 在容器中运行命令
save: 将镜像保存成tar文件
search: 在docker 仓库中搜索镜像
service: 管理镜像服务
start: 启动一个或者多个已经停止的容器
stats: 显示容器资源使用的实时信息流
stop: 停止一个或者多个正在运行的容器
swarm: 管理docker swarm
tag: 将镜像保存在仓库中,也可以作为重命名使用
top: 显示容器的运行进程
unpause: 取消暂停一个或多个容器中的所有进程
update: 更新一个或者多个容器的配置
version: 显示docker版本信息
volume: 管理docker卷
wait: 阻塞知道容器停止,然后打印推出代码
这里我们要注意几点问题:
1:start 和run的区别
run是根据现存的镜像启动一个新的容器,而start是开始一个停止的容器,即退出时是使用exit或者stop的
2:commit和save
这个意思就是每次对容器做一些修改之后,我们需要先提交到本地库,然后save成tar包以供其他使用,若不进行commit直接save的话,正在对容器所做的改变则不能save下来
3:export和save的区别
两者都是导出镜像为tar形式,但是export导出的文件要比save保存的小,原因是export导出的会丢失一些log信息和镜像的层信息,具体可参考:
http://www.server110.com/docker/201411/11213.html
Docker应用实例
1:docker部署ELK
需求分析:
将ELK封装在Docker中便于封装成成型的产品进行出售和转移
PS:由于Docker容器登录之后,进入的是root用户,而ELK不允许在root用户运行,所以这里我们新建了elk用户作为ELK的执行用户
1):运行一个ubuntu的容器
sudo docker pull ubuntu
sudo docker run -i -t ubuntu
以下是在docker容器中运行
2):创建elk用户的目录(root用户下进行)
mkdir /home/elk
3):新建elk用户和elk用户组
groupadd elk
useradd elk -g elk
4):给elk用户赋予密码
passwd elk
5):安装ELK stack
2:docker部署rails服务环境
需求分析:
在一台联网的机器上安装docker,并在其中部署好rails服务环境,保存成tar,并load进另外一台没有网络的环境
PS:docker容器内运行一个操作系统,好多依赖的包都会缺少,这一点要注意
1):接着1中进行
2):安装git
apt-get install git
3):安装rbenv,并加入到环境变量
git clone https://github.com/rbenv/rbenv.git ~/.rbenv
echo ‘export PATH=”HOME/.rbenv/bin: PATH”’ >> ~/.bashrc
再把 eval “$(rbenv init -)” 写入.bashrc
使环境变量生效:
Source .bashrc
初始化
~/.rbenv/bin/rbenv init
type rbenv
4):安装ruby-build
git clone https://github.com/rbenv/ruby-build.git ~/.rbenv/plugins/ruby-build
测试是否成功
rbenv install
5):安wget
apt-get install wget
6):安装其他一些依赖
apt-get install -y build-essential nodejs
apt-get install bzip2 libssl-dev libreadline-dev zlib1g-dev
7):安装ruby
rbenv install -l (查看支持安装的版本)
rbenv install 2.3.0(以2.3.0为例)
此时应该是没有问题的,如果还有问题的话具具体情况定
8):安装rails
gem install rails
9):打包
提交到本地库
sudo docker commit containerID new_image_name
保存成tar包
sudo dockek save -o *.tar new_image_name
10):在断网的服务器运行
拷贝tar包到该服务器
sudo scp ubuntu_rails **.tar ip:/home/master
加载镜像
sudo docker load –input *.tar
3、ELK在Docker中的端口映射
需求分析:
elk部署之后,端口的访问仅限于运行ELK的Docker容器,所以要建立端口映射将端口暴露给外部以供访问
1):启动docker 指定端口,注意不能使部署docker的服务器和docker内所映射的端口一致
Es:9201-9200 kibana:5600-5601
sudo docker run -t -i -d -p 9201:9200 -p 5600:5601 ubuntu/rails:elk_ok(ubuntu/rails:elk_ok镜像)
然后进入容器启动镜像
2):由于我的是在虚拟机中部署的docker和elk服务,在本地window上并不能直接访问web端口,但是这里我们可以加一个映射
netsh interface portproxy add v4tov4 listenport=9200 connectaddress=192.168.197.128 connectport=9201
netsh interface portproxy add v4tov4 listenport=5601 connectaddress=192.168.197.128 connectport=5600
这里之所以是9201和5600是因为我在linux服务器和docker容器的端口映射时将9200映射为9201,将5601映射为5600