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 安装Goreplay 使用docker 安装kvm_centos


使用docker 安装Goreplay 使用docker 安装kvm_centos_02


提示:目前的版本是如果docker的服务端挂了,运行在docker上的所有容器都会挂掉

Docker组件

镜像(Image)
容器(Container)
仓库(Repository)
 
镜像介绍:类似于虚拟机,作用和虚拟机是一样的,唯独是组成部分会有些区别。简单的说如果我们想启动一个容器就必须要有镜像

容器介绍: docker是通过容器来运行业务的,就像运行一个kvm虚拟机是一样的。容器其实就是从镜像创建的一个实例。
  我们可以对容器进行增删改查,容器之间也是相互隔离的。和虚拟机最大的区别就是一个是虚拟的一个是隔离的。
缺点:不会像虚拟机那样隔离的那么彻底,我们可以将容器理解为简化版的linux,有进程运行在里面。

仓库介绍: 根据docker的三大理念构建 运输 运行,我们就需要一个仓库来存放镜像
简单的说:我们将镜像创建完成就需要存放到仓库里面,进行集中式的管理。仓库这点类似于github,docker也有一个dockerhub,他也是一个公共对外的仓库。

虚拟机和docker的区别

使用docker 安装Goreplay 使用docker 安装kvm_docker_03


  简单解释,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 安装Goreplay 使用docker 安装kvm_使用docker 安装Goreplay_04


一、简化配置

  这是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

例如:

使用docker 安装Goreplay 使用docker 安装kvm_使用docker 安装Goreplay_05


提示:如果镜像已经创建了一个容器,那么将无法进行删除

删除容器:

[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,有可能会对容器造成一些意外的影响