Docker 基础介绍及配置安装 [一]
标签(空格分隔): Docker 时间:2016年11月2日
Docker介绍
Docker是Docker.lnc
公司开源的一个基于LXC技术
之上构建的Container容器引擎
,源代码托管在Github
上,基于Go语言并遵从Apache2.0
协议开源
Docker是通过内核
虚拟化技术(namespaces及cgroups等)来提供容器的资源隔离与安全保障等。由于Docker通过操作系统层的虚拟化实现隔离,所以Docker容器在运行时,不需要类似虚拟机(VM)额外的操作系统开销,提高资源利用率
Docker的三大理念
构建 运输 运行
Docker组成
Docker的组成部分docker类似于cs结构
Docker Client
Docker Server
我们可以将docker启动
比喻成Docker server
,我们执行命令的时候相当于Docker client
提示:目前的版本是如果docker的服务端
挂了,运行在docker上的所有容器
都会挂掉
Docker组件
镜像(Image)
容器(Container)
仓库(Repository)
镜像介绍:类似于虚拟机,作用和虚拟机是一样的,唯独是组成部分会有些区别。简单的说如果我们想启动一个容器就必须要有镜像
容器介绍: docker是通过容器来运行业务的,就像运行一个kvm虚拟机是一样的。容器其实就是从镜像创建的一个实例。
我们可以对容器进行增删改查,容器之间也是相互隔离的。和虚拟机最大的区别就是一个是虚拟的一个是隔离的。 缺点:
不会像虚拟机那样隔离的那么彻底,我们可以将容器理解为简化版的linux,有进程运行在里面。
仓库介绍: 根据docker的三大理念构建 运输 运行,我们就需要一个仓库来存放镜像
简单的说:我们将镜像创建完成就需要存放到仓库里面,进行集中式的管理。仓库这点类似于github,docker也有一个dockerhub,他也是一个公共对外的仓库。
虚拟机和docker的区别
简单解释,VMware运行在操作系统上,而docker是直接运行在应用上。所以docker无法提供一个像VMware那样完全的隔离,甚至到很多地方都没有进行隔离,比如说用户空间。
这里可以解释一下 如果你用的是centos5版本那你就别想安装docker了,如果是centos6的你可以看一眼。因为内核版本比较低,但是如果使用乌班图就可以,因为乌班图的内核更新的比较快。
如果公司服务器是centos5和centos6 用docker就需要升级内核,相对比较麻烦.
Docker与OpenStack区别
类别 | Docker | openstack/KVM |
部署男刀 | 非常简单 | 组件多,部署复杂 |
启动速度 | 秒级 | 分钟级 |
执行性能 | 和物理系统几乎一致 | VM会占用一些资源 |
镜像体积 | 镜像是MB级别 | 虚拟机镜像GB级别 |
管理效率 | 管理简单 | 组件相互依赖,管理复杂 |
隔离性 | 隔离性高 | 彻底隔离 |
可管理性 | 单进程、不建议启动SSH | 完整的系统管理 |
网络连接 | 比较弱 | 借助Neutron可以灵活组件各类网络架构 |
提示:在这里可以简单的说一下,有些场景是不适合用到docker。例如我前端web使用docker,此时docker挂掉了,里面不会像数据库那样有数据写入。这时候我从新起一个docker就可以了。所以有的场景是不适合使用docker的
Docker能干什么?
一、简化配置
这是Docker公司宣传的Docker的主要使用场景。虚拟机的最大好处是能在你的硬件设施上运行各种配置不一样的平 台(软件、系统),Docker在降低额外开销的情况下提供了同样的功能。它能让你将运行环境和配置放在代码中然后部署,同一个Docker的配置可以在 不同的环境中使用,这样就降低了硬件要求和应用环境之间耦合度。
二、代码流水线(Code Pipeline
)管理
前一个场景对于管理代码的流水线起到了很大的帮助。代码从开发者的机器到最终在生产环境上的部署,需要经过很多的中间环境。而每一个中间环境都有自己微小的差别,Docker给应用提供了一个从开发到上线均一致的环境,让代码的流水线变得简单不少。
三、提高开发效率
这就带来了一些额外的好处:Docker能提升开发者的开发效率。如果你想看一个详细一点的例子,可以参考Aater在DevOpsDays Austin 2014 大会
或者是DockerCon
上的演讲。
不同的开发环境中,我们都想把两件事做好。一是我们想让开发环境尽量贴近生产环境,二是我们想快速搭建开发环境。
理想状态中,要达到第一个目标,我们需要将每一个服务都跑在独立的虚拟机中以便监控生产环境中服务的运行状态。然而,我们却不想每次都需要网络连 接,每次重新编译的时候远程连接上去特别麻烦。这就是Docker做的特别好的地方,开发环境的机器通常内存比较小,之前使用虚拟的时候,我们经常需要为 开发环境的机器加内存,而现在Docker可以轻易的让几十个服务在Docker中跑起来。
四、隔离应用
有很多种原因会让你选择在一个机器上运行不同的应用,比如之前提到的提高开发效率的场景等
五、整合服务器
正如通过虚拟机来整合多个应用,Docker隔离应用的能力使得Docker可以整合多个服务器以降低成本。由于没有多个操作系统的内存占用,以及能在多个实例之间共享没有使用的内存,Docker可以比虚拟机提供更好的服务器整合解决方案
六、调试能力
Docker提供了很多的工具,这些工具不一定只是针对容器,但是却适用于容器。它们提供了很多的功能,包括可以为容器设置检查点、设置版本和查看两个容器之间的差别,这些特性可以帮助调试Bug。你可以在《Docker拯救世界》
的文章中找到这一点的例证。
七、多租户环境
另外一个Docker有意思的使用场景是在多租户的应用中,它可以避免关键应用的重写。我们一个特别的关于这个场景的 例子是为IoT(译者注:物联网)的应用开发一个快速、易用的多租户环境。这种多租户的基本代码非常复杂,很难处理,重新规划这样一个应用不但消耗时间, 也浪费金钱。
使用Docker,可以为每一个租户的应用层的多个实例创建隔离的环境,这不仅简单而且成本低廉,当然这一切得益于Docker环境的启动速度和其高效的diff命令。
八、快速部署
在虚拟机之前,引入新的硬件资源需要消耗几天的时间。Docker的虚拟化技术将这个时间降到了几分钟,Docker只是创建一个容器进程而无需启动操作系统,这个过程只需要秒级的时间。这正是Google和Facebook都看重的特性。
你可以在数据中心创建销毁资源而无需担心重新启动带来的开销。通常数据中心的资源利用率只有30%,通过使用Docker并进行有效的资源分配可以提高资源的利用率。
小结: 一句话说明docker
的本质就是 低开销(系统文件、内存 共用)的虚拟机
Docker改变了什么?
面向产品:产品交付
面向开发:简化环境配置
面向测试:多版本测试
面向运维:环境一致
面向架构:自动化扩容(微服务)
Docker入门安装
一、环境
[root@linux-node1 ~]# cat /etc/redhat-release
CentOS Linux release 7.2.1511 (Core)
[root@linux-node1 ~]# uname -r
3.10.0-327.36.2.el7.x86_64
二、安装
[root@linux-node1 ~]# yum install docker
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
* base: mirrors.aliyun.com
* epel: mirrors.tuna.tsinghua.edu.cn
* extras: mirrors.aliyun.com
* updates: mirrors.aliyun.com
Package docker-1.10.3-46.el7.centos.14.x86_64 already installed and latest version
Nothing to do
Centos7默认安装docker1.10
,我们可以通过官方的yum源安装docker1.12
Docker官网:http://www.docker.com/
最新版本我们可以去官方网站进行下载。
温馨提示:使用docker最好使用最新版,因为功能比较完善。
三、启动
[root@linux-node1 ~]# systemctl start docker
启动之后我们可以查看一下docker的状态
[root@linux-node1 ~]# systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/usr/lib/systemd/system/docker.service; disabled; vendor preset: disabled)
Active: active (running) since Wed 2016-10-19 02:32:37 CST; 3h 54min ago
Docs: http://docs.docker.com
Main PID: 31807 (docker-current)
CGroup: /system.slice/docker.service
└─31807 /usr/bin/docker-current daemon --exec-opt native.cgroupdriver=systemd --selinux-enabled --log-driver=journald
Oct 19 02:32:37 linux-node1.abcdocker.com docker-current[31807]: time="2016-10-19T02:32:37.832703497+08:00" level=info msg="Graph migration to content-addressability took 0.00 seconds"
Oct 19 02:32:37 linux-node1.abcdocker.com docker-current[31807]: time="2016-10-19T02:32:37.840719984+08:00" level=warning msg="Running modprobe bridge br_netfilter failed with message: m...
Oct 19 02:32:37 linux-node1.abcdocker.com docker-current[31807]: time="2016-10-19T02:32:37.854022259+08:00" level=info msg="Firewalld running: false"
Oct 19 02:32:37 linux-node1.abcdocker.com docker-current[31807]: time="2016-10-19T02:32:37.908314481+08:00" level=info msg="Default bridge (docker0) is assigned with an IP addr...P address"
Oct 19 02:32:37 linux-node1.abcdocker.com docker-current[31807]: time="2016-10-19T02:32:37.967870654+08:00" level=info msg="Loading containers: start."
Oct 19 02:32:37 linux-node1.abcdocker.com docker-current[31807]: time="2016-10-19T02:32:37.967930460+08:00" level=info msg="Loading containers: done."
Oct 19 02:32:37 linux-node1.abcdocker.com docker-current[31807]: time="2016-10-19T02:32:37.967937814+08:00" level=info msg="Daemon has completed initialization"
Oct 19 02:32:37 linux-node1.abcdocker.com docker-current[31807]: time="2016-10-19T02:32:37.967961305+08:00" level=info msg="Docker daemon" commit=cb079f6-unsupported execdriver...ion=1.10.3
Oct 19 02:32:37 linux-node1.abcdocker.com systemd[1]: Started Docker Application Container Engine.
Oct 19 02:32:37 linux-node1.abcdocker.com docker-current[31807]: time="2016-10-19T02:32:37.972026130+08:00" level=info msg="API listen on /var/run/docker.sock"
Hint: Some lines were ellipsized, use -l to show in full.
我们可以使用ifconfig查看网卡
[root@linux-node1 ~]# ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
inet 172.17.0.1 netmask 255.255.0.0 broadcast 0.0.0.0
ether 02:42:c5:44:7d:3b txqueuelen 0 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.56.11 netmask 255.255.255.0 broadcast 192.168.56.255
inet6 fe80::20c:29ff:fef4:affe prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:f4:af:fe txqueuelen 1000 (Ethernet)
RX packets 167717 bytes 175534600 (167.4 MiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 69646 bytes 12187530 (11.6 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 0 (Local Loopback)
RX packets 2322 bytes 247665 (241.8 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 2322 bytes 247665 (241.8 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
提示: 我们启动docker的时候,docker会帮我们创建一个docker 0的网桥
四、Docker基础命令
查看当前镜像 docker images
[root@linux-node1 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
搜索镜像 docker search [镜像名字]
执行docker search centos 会从dockerhub上搜索镜像
[root@linux-node1 ~]# docker search centos
INDEX NAME DESCRIPTION STARS OFFICIAL AUTOMATED
docker.io docker.io/centos The official build of CentOS. 2757 [OK]
docker.io docker.io/ansible/centos7-ansible Ansible on Centos7 90 [OK]
docker.io docker.io/jdeathe/centos-ssh CentOS-6 6.8 x86_64 / CentOS-7 7.2.1511 x8... 42 [OK]
docker.io docker.io/jdeathe/centos-ssh-apache-php CentOS-6 6.8 x86_64 / Apache / PHP / PHP M... 21 [OK]
docker.io docker.io/nimmis/java-centos This is docker images of CentOS 7 with dif... 17 [OK]
docker.io docker.io/gluster/gluster-centos Official GlusterFS Image [ CentOS7 + Glus... 12 [OK]
docker.io docker.io/million12/centos-supervisor Base CentOS-7 with supervisord launcher, h... 12 [OK]
docker.io docker.io/torusware/speedus-centos Always updated official CentOS docker imag... 8 [OK]
docker.io docker.io/nickistre/centos-lamp LAMP on centos setup 7 [OK]
docker.io docker.io/kinogmt/centos-ssh CentOS with SSH 6 [OK]
docker.io docker.io/nathonfowlie/centos-jre Latest CentOS image with the JRE pre-insta... 4 [OK]
docker.io docker.io/centos/mariadb55-centos7 3 [OK]
docker.io docker.io/consol/sakuli-centos-xfce Sakuli JavaScript based end-2-end testing ... 2 [OK]
docker.io docker.io/blacklabelops/centos CentOS Base Image! Built and Updates Daily! 1 [OK]
docker.io docker.io/darksheer/centos Base Centos Image -- Updated hourly 1 [OK]
docker.io docker.io/harisekhon/centos-java Java on CentOS (OpenJDK, tags jre/jdk7-8) 1 [OK]
docker.io docker.io/harisekhon/centos-scala Scala + CentOS (OpenJDK tags 2.10-jre7 - 2... 1 [OK]
docker.io docker.io/timhughes/centos Centos with systemd installed and running 1 [OK]
docker.io docker.io/grayzone/centos auto build for centos. 0 [OK]
docker.io docker.io/januswel/centos yum update-ed CentOS image 0 [OK]
docker.io docker.io/labengine/centos Centos image base 0 [OK]
docker.io docker.io/repositoryjp/centos Docker Image for CentOS. 0 [OK]
docker.io docker.io/smartentry/centos centos with smartentry 0 [OK]
docker.io docker.io/ustclug/centos USTC centos 0 [OK]
docker.io docker.io/vcatechnology/centos A CentOS Image which is updated daily 0 [OK]
下载镜像
我们可以使用docker pull centos
docker pull nginx
来安装centos和nginx的镜像
导出镜像 docker save -o [镜像名称] [镜像]
[root@linux-node1 ~]# docker save -o centos.tar centos
[root@linux-node1 ~]# ls
anaconda-ks.cfg centos.tar
需要将docker导出为tar,后面为镜像名称
导入镜像
[root@linux-node1 ~]#docker load --input centos.tar
#使用input导入
[root@linux-node1 ~]# docker load < nginx.tar #使用重定向导入
删除镜像
docker删除可以使用docker rmi 后面加上docker的ID
例如:
提示:如果镜像已经创建了一个容器,那么将无法进行删除
删除容器:
[root@linux-node1 ~]# docker rm abcdocker
或者使用
[root@linux-node1 ~]# docker rm -f abcdocker
第二种会提示容器在将它关闭
docker另一种删除方式
启动一个容器 echo
完就删除
[root@linux-node1 ~]# docker run --rm centos /bin/echo "www.abcdocker.com"
www.abcdocker.com
[root@linux-node1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f974696a121a centos "/bin/bash" 2 minutes ago Up About a minute abcdocker
bcededa4b82c centos "/bin/echo hello" 6 hours ago Exited (0) 4 hours ago awesome_dijkstra
启动容器 docker run [镜像]
[root@linux-node1 ~]# docker run centos
centos是镜像的名称,镜像的名称必须在选项的后面
启动镜像,输入Hello,并关闭
[root@linux-node1 ~]# docker run centos /bin/echo 'Hello Wordl
本命令的意思是启动一个docker进程,并echo 执行后面的命令可以有可以没有(hello),如果我们的镜像启动就会执行一个进程就不需要我们输入
查看启动镜像 docker ps -a
ps
是显示正在运行的容器 -a
是显示不运行的
[root@linux-node1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bcededa4b82c centos "/bin/echo hello" 32 seconds ago Exited (0) 32 seconds ago awesome_dijkstra
我们可以看到,现在容器并没有启动。因为docker启动需要在前台启动一个进程。容器的名称可以我们指定或自动生成
提示: 管理docker容器可以通过名称也可以通过ID
五、Docker管理案例
例如:我要新建一个abcdocker
的容器,它的镜像是centos.
他有三个参数,第一个是给容器起一个名称,-t 分配一个伪终端(tty)-i标准输入打开,我要在里面输入命令
[root@linux-node1 ~]# docker run --name abcdocker -t -i centos /bin/bash
--name 容器的名称
-t 让docker分配一个伪终端
-i 让docker的标准输入打开{input}
提示:最后的/bin/bash
可以省略,但是最后一个如果不是命令,那就是镜像的名称
输入上方的命令之后会直接进入到容器里面
[root@f8c8c8156e26 /]# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 11752 1920 ? Ss 19:38 0:00 /bin/bash
root 18 0.0 0.0 47424 1660 ? R+ 21:32 0:00 ps aux
[root@f8c8c8156e26 /]#
温馨提示:容器不是一个虚拟机,因为他就是一个进程,如果我们退出,这个进程就退出了。
如果我们执行创建容器的时候,里面没有我们指定的镜像,那么他会从dockerhub
上进行下载然后在启动
容器启动
我们通过docker ps -a
可以查看到没有启动的容器
使用docker start [名称或PORTS]
[root@linux-node1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f8c8c8156e26 centos "/bin/bash" 2 hours ago Exited (0) 34 minutes ago abcdocker
bcededa4b82c centos "/bin/echo hello" 2 hours ago Exited (0) 2 hours ago awesome_dijkstra
[root@linux-node1 ~]# docker start abcdocker
abcdocker
[root@linux-node1 ~]# docker start bcededa4b82c
bcededa4b82c
进入容器
[root@linux-node1 ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f8c8c8156e26 centos "/bin/bash" 2 hours ago Up 24 minutes abcdocker
bcededa4b82c centos "/bin/echo hello" 3 hours ago Exited (0) 23 minutes ago awesome_dijkstra
[root@linux-node1 ~]# docker attach abcdocker
[root@f8c8c8156e26 /]# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.1 11776 1872 ? Ss 22:09 0:00 /bin/bash
root 14 0.0 0.0 47424 1660 ? R+ 22:33 0:00 ps aux
这样进入容器的缺点就是如果在开一个窗口就会同步操作,类似于单用户模式(windows远程桌面)
提示:生产场景是不使用docker attach
的,需要我们使用nsenter
这个工具,这个工具包含在util-linux
软件包里面
[root@linux-node1 ~]# yum install util-linux -y
Centos7默认最小化已经安装
我们通过nsenter
就可以进入容器
,但是nsenter是通过pid
进入容器里,所以我们需要知道容器的pid。我们可以通过docker inspect
来获取到pid
[root@linux-node1 ~]# docker start abcdocker
abcdocker
[root@linux-node1 ~]# docker inspect -f "{{ .State.Pid }}" abcdocker
37434
[root@linux-node1 ~]# nsenter -t 37434 -m -u -i -n -p
docker inspect -f {{.State.Pid}}
容器名或者容器id
#每一个容器都有.State.Pid,所以这个命令除了容器的id需要我们根据docker ps
-a
去查找,其他的全部为固定的格式 nsenter --target
上面查到的进程id --mount --uts --ipc --net --pid
#输入该命令便进入到容器中
解释nsenter指令中进程id之后的参数的含义:
* –mount参数是进去到mount namespace中
* –uts参数是进入到uts namespace中
* –ipc参数是进入到System V IPC namaspace中
* –net参数是进入到network namespace中
* –pid参数是进入到pid namespace中
* –user参数是进入到user namespace中
更多参数我们可以通过nsenter --help
进行获取
我们进入容器中查看进程
以下是以nsenter启动的进程
[root@f8c8c8156e26 /]# ps aux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 1 0.0 0.0 11776 1664 ? Ss+ Oct18 0:00 /bin/bash
root 27 0.0 0.1 13376 1984 ? S Oct18 0:00 -bash
root 40 0.0 0.0 49024 1808 ? R+ 00:11 0:00 ps aux
/bin/bash
是我们运行容器产生的进程 -bash
是我们使用nsenter产生的,这样如果我们退出容器,容器就不会退出,因为-bash
还在运行
[root@f8c8c8156e26 /]# exit
logout
[root@linux-node1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f8c8c8156e26 centos "/bin/bash" 4 hours ago Up 48 minutes abcdocker
因为每次进入容器都需要输入那两条命令,所以我们可以写一个脚本来获取。
脚本内容如下:
[root@linux-node1 ~]# cat docker_in.sh
#!/bin/bash
# Use nsenter to access docker
docker_in(){
NAME_ID=$1
PID=$(docker inspect -f "{{ .State.Pid }}" $NAME_ID)
nsenter -t $PID -m -u -i -n -p
}
docker_in $1
执行结果如下:
[root@linux-node1 ~]# chmod +x docker_in.sh
[root@linux-node1 ~]# ./docker_in.sh abcdocker
[root@f8c8c8156e26 /]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 Oct18 ? 00:00:00 /bin/bash
root 54 0 0 00:23 ? 00:00:00 -bash
root 67 54 0 00:23 ? 00:00:00 ps -ef
[root@f8c8c8156e26 /]#
我们也可以不进入容器进行查看
[root@linux-node1 ~]# docker exec abcdocker ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 0 Oct18 ? 00:00:00 /bin/bash
root 85 0 0 00:28 ? 00:00:00 ps -ef
[root@linux-node1 ~]# docker exec abcdocker ls /
anaconda-post.log
bin
dev
提示:可以使用exec
参数,不进入容器查看内容
我们还可以使用exec进入docker容器中
[root@linux-node1 ~]# docker exec -it abcdocker /bin/bash
但是最好还是少使用exec
,有可能会对容器造成一些意外的影响