容器介绍

  容器其实是一种沙盒技术。沙盒就是能够像一个集装箱一样,把你的应用"装"起来的技术。这样,应用与应用之间,就因为有了边界而不至于相互干扰;而被装进集装箱的应用,也可以被方便地搬来搬去。
  容器的本质到底是什么?
  容器的本质是进程。容器镜像就是Windows系统里的".exe"安装包.

一、Docker介绍:

  Docker是Docker.Inc公司开源的一个基于轻量级虚拟化技术的容器引擎项目,整个项目基于Go语言开发,并遵从Apache 2.0协议。通过分层镜像标准化和内核虚拟化技术,Docker使得应用开发者和运维工程师可以以统一的方式跨平台发布应用,并且以几乎没有额外开销的情况下提供资源隔离的应用运行环境。

  Docker 是一个开源工具,它可以让创建和管理 Linux 容器变得简单。容器就像是轻量级的虚拟机,并且可以以秒级的速度来启动或停止

官网:

docker.com
docker.io  ---docker官方库也叫docker-hub  

Docker跟原有的工具区别:

传统的部署模式是:安装(包管理工具或者源码包编译)->配置->运行;
Docker的部署模式是:复制->运行。

Docker对服务器端开发/部署带来的变化:

方便快速部署
对于部署来说可以极大的减少部署的时间成本和人力成本
Docker支持将应用打包进一个可以移植的容器中,重新定义了应用开发,测试,部署上线的过程,核心理念
是 Build once, Run anywhere
1)标准化应用发布,docker容器包含了运行环境和可执行程序,可以跨平台和主机使用;
2)节约时间,快速部署和启动,VM启动一般是分钟级,docker容器启动是秒级;
3)方便构建基于微服务架构的系统,通过服务编排,更好的松耦合;
4)节约成本,以前一个虚拟机至少需要几个G的磁盘空间,docker容器可以减少到MB级;

Docker 优势:

1、交付物标准化
Docker的标准化交付物称为"镜像",它包含了应用程序及其所依赖的运行环境,大大简化了应用交付的模式。

2、应用隔离
Docker可以隔离不同应用程序之间的相互影响,但是比虚拟机开销更小。总之,容器技术部署速度快,开发、测试更敏捷;提高系统利用率,降低资源成本.

3、一次构建,多次交付
类似于集装箱的"一次装箱,多次运输",Docker镜像可以做到"一次构建,多次交付"。

Docker的度量:

  Docker是利用容器来实现的一种轻量级的虚拟技术,从而在保证隔离性的同时达到节省资源的目的。Docker的

可移植性可以让它一次建立,到处运行。Docker的度量可以从以下四个方面进行:

1)隔离性
通过内核的命名空间来实现的,将容器的进程、网络、消息、文件系统和主机名进行隔离。

2)可度量性
Docker主要通过cgroups控制组来控制资源的度量和分配。

3)移植性
Docker利用AUFS来实现对容器的快速更新。
AUFS是一种支持将不同目录挂载到同一个虚拟文件系统下的文件系统,支持对每个目录的读写权限管理。AUFS具有层
的概念,每一次修改都是在已有的只写层进行增量修改,修改的内容将形成新的文件层,不影响原有的层。

4)安全性
安全性可以分为容器内部之间的安全性;容器与托管主机之间的安全性。

容器内部之间的安全性主要是通过命名空间和cgroups来保证的。
容器与托管主机之间的安全性主要是通过内核能力机制的控制,可以防止Docker非法入侵托管主机。

Docker容器使用AUFS作为文件系统的优势:

1)节省存储空间
多个容器可以共享同一个基础镜像存储。

2)快速部署

3)升级方便
升级一个基础镜像即可影响到所有基于它的容器。需要注意已经在运行的docker不受影响

二、Docker安装

docker版本:

docker版本分为moby、docker-ce与docker-ee
最早时docker是一个开源项目,主要由docker公司维护。
2017年3月1日起,docker公司将原先的docker项目改名为moby,并创建了docker-ce和docker-ee。

三者关系:

moby是继承了原先的docker的项目,是社区维护的的开源项目,谁都可以在moby的基础打造自己的容器产品

docker-ce是docker公司维护的开源项目,是一个基于moby项目的免费的容器产品

docker-ee是docker公司维护的闭源产品,是docker公司的商业产品

moby project由社区维护,docker-ce project是docker公司维护,docker-ee是闭源的docker公司维护。

1、直接使用yum安装

CentOS 7默认安装的docker版本为1.13.1,也是从这个版本之后,docker版本的命名规则变成以时间来命名。

# yum install -y epel*
# yum install docker
启动 Docker 服务:
# service docker start
# chkconfig docker on
CentOS 7    
# systemctl start docker.service
# systemctl enable docker.service

# docker version
Client:
 Version:         1.13.1

2、CentOS官方安装(时间久)

wget :

# cd /etc/yum.repos.d/
# wget https://download.docker.com/linux/centos/docker-ce.repo
# yum -y install docker-ce

rpm :

# wget https://download.docker.com/linux/centos/7/x86_64/stable/Packages/docker-ce-17.09.0.ce-1.el7.centos.x86_64.rpm

# yum localinstall docker-ce-17.09.0.ce-1.el7.centos.x86_64.rpm

3、国内源安装最新版docker

删除已安装的Docker:

# yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-selinux \
docker-engine-selinux \
docker-engine

配置阿里云Docker Yum源 :

# yum install -y yum-utils device-mapper-persistent-data lvm2 git
# yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

安装指定版本

查看Docker版本 :
# yum list docker-ce --showduplicates

安装较旧版本(比如Docker 17.03.2) :
需要指定完整的rpm包的包名,并且加上--setopt=obsoletes=0 参数 :

# yum install -y --setopt=obsoletes=0 \
docker-ce-17.03.2.ce-1.el7.centos.x86_64 \
docker-ce-selinux-17.03.2.ce-1.el7.centos.noarch

安装Docker新版本

# yum install -y docker-ce

启动Docker服务:
#systemctl enable docker
#systemctl start docker

# docker -v
Docker version 19.03.2, build 6a30dfc
# docker version
Client: Docker Engine - Community
 Version:           19.03.7
 API version:       1.40
 Go version:        go1.12.17
 Git commit:        7141c199a2
 Built:             Wed Mar  4 01:24:10 2020
 OS/Arch:           linux/amd64
 Experimental:      false
...
查看docker运行状态:
# docker info
Client:
 Debug Mode: false

Server:
 Containers: 2
  Running: 2
  Paused: 0
  Stopped: 0
 Images: 2
 Server Version: 19.03.7
 Storage Driver: overlay2
...
报错1:
docker info的时候报如下错误
bridge-nf-call-iptables is disabled

解决1:
追加如下配置,然后重启系统
# vim /etc/sysctl.conf   
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-arptables = 1

 
问题2:
虚拟机ping百度也能ping通,但是需要等好几秒才出结果,关键是下载镜像一直报错如下
# docker pull daocloud.io/library/nginx

 Using default tag: latest
 Error response from daemon: Get https://daocloud.io/v2/: dial tcp: lookup daocloud.io on 192.168.1.2:53: read udp   192.168.1.189:41335->192.168.1.2:53: i/o timeout

解决2:
我的虚拟机用的网关和dns都是虚拟机自己的.1或者.2,把DNS改成8.8.8.8问题就解决了,ping百度也秒出结果
# vim /etc/resolv.conf
nameserver 8.8.8.8

测试 :

运行一个容器:
[root@docker_server ~]# docker run -it daocloud.io/library/ubuntu /bin/bash
Unable to find image 'daocloud.io/library/ubuntu:latest' locally
latest: Pulling from library/ubuntu
423ae2b273f4: Pull complete 
de83a2304fa1: Pull complete 
f9a83bce3af0: Pull complete 
b6b53be908de: Pull complete 
Digest: sha256:0925d086715714114c1988f7c947db94064fd385e171a63c07730f1fa014e6f9
Status: Downloaded newer image for daocloud.io/library/ubuntu:latest

如果自动进入下面的容器环境,说明ubuntu镜像运行成功,Docker的安装也没有问题:可以操作容器了
root@67872e58e76f:/#

退出:Ctrl+p+q

三、国内镜像源

国内比较好的镜像源:
  • daocloud.io
  • aliyun
  • 网易蜂巢

Docker 加速器

    使用 Docker 的时候,需要经常从官方获取镜像,但是由于显而易见的网络原因,拉取镜像的过程非常耗时,
严重影响使用 Docker 的体验。因此 DaoCloud 推出了加速器工具解决这个难题,通过智能路由和缓存机制,
极大提升了国内网络访问 Docker Hub 的速度。

Docker 加速器对 Docker 的版本有要求吗?    
需要 Docker 1.8 或更高版本才能使用。

Docker 加速器支持什么系统?    
Linux, MacOS 以及 Windows 平台。

Docker 加速器是否收费?    
提供永久免费的加速器服务,请放心使用。
1、daocloud.io

进入网站:https://daocloud.io/
注册账号登陆

image.png

image.png

随便点击一个,点击CentOS的镜像
image.png

image.png

image.png

每个镜像的命令不一样,再去点击另一个镜像

image.png

image.png
[root@biudefor ~]# docker pull daocloud.io/library/nginx   //拉取镜像,不加版本号默认是latest(最新版)
Using default tag: latest
latest: Pulling from library/nginx
0a4690c5d889: Pull complete 
9719afee3eb7: Pull complete 
44446b456159: Pull complete 
Digest: sha256:f83b2ffd963ac911f9e638184c8d580cc1f3139d5c8c33c87c3fb90aebdebf76
Status: Downloaded newer image for daocloud.io/library/nginx:latest
daocloud.io/library/nginx:latest

使用daocloud的web页面

image.png

image.png
[root@biudefor ~]# curl -sSL https://get.daocloud.io/daomonit/install.sh | sh -s 8cedad51898e9303f72a192706f1b6a24cd9b044 
 * Installing Daomonit...
 * Downloading Daomonit from https://get.daocloud.io/daomonit/daomonit.x86_64.rpm
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   279  100   279    0     0    841      0 --:--:-- --:--:-- --:--:--   842
100   337  100   337    0     0     78      0  0:00:04  0:00:04 --:--:--   116
100 3349k  100 3349k    0     0   736k      0  0:00:04  0:00:04 --:--:--  736k
Preparing...                          ################################# [100%]
Updating / installing...
   1:daomonit-0.1.70-1                ################################# [100%]
Created symlink from /etc/systemd/system/multi-user.target.wants/daomonit.service to /usr/lib/systemd/system/daomonit.service.
 * Configuring Daomonit...
[03/14/20 08:44:44] [DEBG] Writing configuration file /etc/daocloud/daomonit.yml
[03/14/20 08:44:44] [INFO] You have successfully saved your config file.
 * Start Daomonit...
Starting daomonit (via systemctl):                         [  OK  ]

You can view daomonit log at /var/log/daomonit.log
And You can Start or Stop daomonit with: service daomonit start/stop/restart/status

*********************************************************************
*********************************************************************
***
***  Installed and Started Daomonit 0.1.70
***
***  NOTICE: 
***  You can pull image very Fast by dao, For Example: 
***     dao pull ubuntu
***
*********************************************************************
*********************************************************************

[root@biudefor ~]#

执行完成之后

image.png

点击查看主机
image.png

启动容器

[root@biudefor ~]# docker images
REPOSITORY                              TAG                 IMAGE ID            CREATED             SIZE
daocloud.io/library/nginx               latest              98ebf73aba75        8 months ago        109MB
daocloud.io/daocloud/daocloud-toolset   latest              bbdc71e950ea        2 years ago         147MB
[root@biudefor ~]# docker run -it daocloud.io/library/nginx /bin/bash
root@873a085e35e7:/#

刷新一下web页面

image.png

2、配置阿里云的仓库

https://cr.console.aliyun.com/cn-hangzhou/instances/images

image.png

image.png

image.png

image.png

image.png
[root@biudefor ~]# docker pull registry.cn-hangzhou.aliyuncs.com/bzvs/mysql5.7
Using default tag: latest
latest: Pulling from bzvs/mysql5.7
3b254c794ffe: Pull complete 
000dad75f945: Pull complete 
a1728469536d: Pull complete 
a9b22a8edeb4: Pull complete 
178176b5f6b9: Pull complete 
0d12893e3c54: Pull complete 
a84d3360bbe4: Pull complete 
bc1f08e53ff7: Pull complete 
04525edde588: Pull complete 
d598c6cf02f0: Pull complete 
b025ce85955f: Pull complete 
45146d8b2666: Pull complete 
Digest: sha256:e24a3b05970a40aeb3cce4adc942dd681d301b3a793853fa6b5e0ed5e9dc8bb6
Status: Downloaded newer image for registry.cn-hangzhou.aliyuncs.com/bzvs/mysql5.7:latest
registry.cn-hangzhou.aliyuncs.com/bzvs/mysql5.7:latest
[root@biudefor ~]# docker images
REPOSITORY                                        TAG                 IMAGE ID            CREATED             SIZE
daocloud.io/library/nginx                         latest              98ebf73aba75        8 months ago        109MB
registry.cn-hangzhou.aliyuncs.com/bzvs/mysql5.7   latest              1ea5eee8966a        13 months ago       372MB
daocloud.io/daocloud/daocloud-toolset             latest              bbdc71e950ea        2 years ago         147MB

配置加速器

image.png

如果这个目录/etc/docker/不存在就创建
[root@biudefor ~]# vim /etc/docker/daemon.json
{
  "registry-mirrors": ["https://br003st4.mirror.aliyuncs.com"]
}
[root@biudefor ~]# systemctl daemon-reload
[root@biudefor ~]# systemctl restart docker
3、网易蜂巢

https://c.163yun.com/hub#/hom

微信截图_20200309191527.png

四、docker基本概念

Docker系统

Docker系统有两个程序:docker服务端和docker客户端

docker服务端:是一个服务进程,管理着所有的容器。也叫docker engine

docker客户端:扮演着docker服务端的远程控制器,可以用来控制docker的服务端进程。

大部分情况下,docker服务端和客户端运行在一台机器上

Docker三大核心组件:

Docker 镜像 - Docker  images 

Docker 仓库 - Docker  registeries

Docker 容器 - Docker  containers

容器的三大组成要素:

名称空间 namespace   容器隔离(pid,net,mnt,user)
 
资源限制 cgroups   资源(内存,cpu,)

文件系统 overlay2(UnionFS) 

docker 仓库:

用来保存镜像,可以理解为代码控制中的代码仓库。同样的,Docker 仓库也有公有和私有的概念。

公有的 Docker 仓库名字是 Docker Hub。Docker Hub 提供了庞大的镜像集合供使用。这些镜像可以是自己创建,或者在别人的镜像基础上创建。

仓库(registry) -->Repository-->镜像(按版本区分)
registry/repository:tag
docker.io/centos:7

docker 国内仓库:
aliyun
网易蜂巢
daocloud
=========================
docker公有仓库
docker.io -------docker官方库也叫docker-hub
类似于github一样,面向全球的一个docker镜像的公共仓库。如果在国内使用速度太慢。
===============================
docker私有仓库
个人或者公司部署的非公开库

Docker 镜像 :

Docker 镜像是 Docker 容器运行时的只读模板,每一个镜像由一系列的层 (layers) 组成。Docker 使用 UnionFS 来将这些层联合到单独的镜像中。正因为有了这些层的存在,Docker 是如此的轻量。当你改变了一个 Docker 镜像,比如升级到某个程序到新的版本,一个新的层会被创建。因此,不用替换整个原先的镜像或者重新建立(在使用虚拟机的时候你可能会这么做),只是一个新的层被添加或升级了。

在 Docker 的术语里,一个只读层被称为镜像,一个镜像是永久不会变的。由于 Docker 使用一个统一文件系统,由于镜像不可写,所以镜像是无状态的。

镜像由三部分组成:
镜像名称:仓库名称+镜像分类+tag名称(镜像版本)

1.存储对象:images
2.格式:库名/分类:tag
3.tag:表示镜像版本

镜像ID:

所有镜像都是通过一个 64 位十六进制字符串来标识的。 为简化使用,前 12 个字符可以组成一个短ID,可以在命令行中使用。短ID还是有一定的碰撞机率,所以服务器总是返回长ID。

镜像ID:64位的id号,一般我们看到的是12位的我们称之为短ID,只要我们每个ID号不冲突就可以了

wps1.jpg
   镜像本身:是由一层一层的镜像合在一起的,最底层的镜像我们称为基础镜像,在这个基础镜像的基础上还可
以在做镜像,在做的镜像称为子镜像,对于子镜像来讲在谁的基础之上做的就是父镜像。

基础镜像:一个没有任何父镜像的镜像,谓之基础镜像。
centos7   镜像
centos7+nginx 镜像

Docker 容器

Docker 容器和文件夹很类似,一个Docker容器包含了所有的某个应用运行所需要的环境。每一个 Docker 容器都是从 Docker 镜像创建的。Docker 容器可以运行、开始、停止、移动和删除。每一个 Docker 容器都是独立和安全的应用平台,Docker 容器是 Docker 的运行部分。

五、docker镜像命名解析

镜像是Docker最核心的技术之一,也是应用发布的标准格式。无论你是用docker pull image,或者是在
Dockerfile里面写FROM image,从Docker官方Registry下载镜像应该是Docker操作里面最频繁的动作之一
了。那么docker镜像是如何命名的,这也是Docker里面比较容易令人混淆的一块概念:Registry,Repository, Tag and Image。
那么Registry又是什么呢?Registry存储镜像数据,并且提供拉取和上传镜像的功能。Registry中镜像是通过
Repository来组织的,而每个Repository又包含了若干个Image。

下面是在本地机器运行docker images的输出结果:


image.png

常说的"nginx"镜像其实不是一个镜像名称,而是代表了一个名为nginx的Repository,同时在这个Repository下面有一系列打了tag的Image,Image的标记是一个GUID,为了方便也可以通过Repository:tag来引用。

Image[:tag]

当一个镜像的名称不足以分辨这个镜像所代表的含义时,你可以通过tag将版本信息添加到run命令中,以执行特定版本的镜像。

如:docker run centos:7

六、docker镜像和容器的区别

1、Docker镜像

一个Docker镜像可以构建于另一个Docker镜像之上,这种层叠关系可以是多层的。第1层的镜像层我们称之为基础镜像(Base Image),其他层的镜像(除了最顶层)我们称之为父层镜像(Parent Image)。这些镜像继承了他们的父层镜像的所有属性和设置。

Docker镜像通过镜像ID进行识别。镜像ID是一个64字符的十六进制的字符串。但是当我们运行镜像时,通常我们不会使用镜像ID来引用镜像,而是使用镜像名来引用。

要列出本地所有有效的镜像,可以使用命令

# docker images

镜像可以发布为不同的版本,这种机制我们称之为标签(Tag)。

可以使用pull命令加上指定的标签:

# docker pull ubuntu:14.04

# docker pull ubuntu:12.04
2、Docker容器

它会在所有的镜像层之上增加一个可写层。这个可写层有运行在CPU上的进程,而且有两个不同的状态:运行态(Running)和退出态 (Exited)。这就是Docker容器。当我们使用docker run启动容器,Docker容器就进入运行态,当我们停止Docker容器时,它就进入退出态。
当我们有一个正在运行的Docker容器时,从运行态到停止态,我们对它所做的一切变更都会永久地写到容器的文件系统中。要切记,对容器的变更是写入到容器的文件系统的,而不是写入到Docker镜像中的。我们可以用同一个镜像启动多个Docker容器,这些容器启动后都是活动的,彼此还是相互隔离的。我们对其中一个容器所做的变更只会局限于那个容器本身。如果对容器的底层镜像进行修改,那么当前正在运行的容器是不受影响的,不会发生自动更新现象。

Docker容器可以使用命令创建:

# docker run  -it  镜像名称或ID  /bin/bash

退出:

Ctrl + p + q
exit    #使用exit可能会使容器也退出

进入容器:

docker exec -it [ID] /bin/bash
docker attach 容器名称或ID    #前提是启动容器时指定了登陆的shell

做一个小实验:

下载一个CentOS7的镜像
[root@biudefor ~]# docker pull daocloud.io/library/centos:7
启动一个容器:
[root@biudefor ~]# docker run -it --name c7-1 daocloud.io/library/centos:7 /bin/bash
[root@32ece634f41a /]# touch a.txt
[root@32ece634f41a /]# ls
a.txt              bin  etc   lib    media  opt   root  sbin  sys  usr
anaconda-post.log  dev  home  lib64  mnt    proc  run   srv   tmp  var

再使用CentOS7镜像启动一个容器:
[root@biudefor ~]# docker run -it --name c7-2 daocloud.io/library/centos:7 /bin/bash
[root@a96f57e7a520 /]# ls
anaconda-post.log  dev  home  lib64  mnt  proc  run   srv  tmp  var
bin                etc  lib   media  opt  root  sbin  sys  usr

  发现,对容器做出的改变不会影响到镜像,容器所做变更只会局限于容器本身。同理,如果对镜像做出了变
更,已经启动的容器也是不受影响的

七、名字空间--namespace

namespace    空间隔离

名字空间是 Linux 内核一个强大的特性。每个容器都有自己单独的名字空间,运行在其中的应用都像是在独立的操作系统中运行一样。名字空间保证了容器之间彼此互不影响。

1. pid 名字空间

不同用户的进程就是通过 pid 名字空间隔离开的,且不同名字空间中可以有相同 pid。所有的 LXC 进程在 Docker中的父进程为Docker进程,每个 LXC 进程具有不同的名字空间。同时由于允许嵌套,因此可以很方便的实现嵌套的 Docker 容器。

2. net 名字空间

有 了 pid 名字空间, 每个名字空间中的 pid 能够相互隔离,但是网络端口还是共享 host 的端口。网络隔离是通过 net 名字空间实现的, 每个 net 名字空间有独立的 网络设备, IP 地址, 路由表, /proc/net 目录。这样每个容器的网络就能隔离开来。

3. ipc 名字空间

容器中进程交互还是采用了 Linux 常见的进程间交互方法(interprocess communication - IPC), 包括信号量、消息队列和共享内存、socket、管道等。

4. mnt名字空间

mnt 名字空间允许不同名字空间的进程看到的文件结构不同,这样每个名字空间 中的进程所看到的文件目录就被隔离开了。

5. uts 名字空间

UTS("UNIX Time-sharing System") 名字空间允许每个容器拥有独立的 hostname 和 domain name, 使其在网络上可以被视作一个独立的节点而非主机上的一个进程。

6. user 名字空间

每个容器可以有不同的用户和组 id, 也就是说可以在容器内用容器内部的用户执行程序而非主机上的用户。

八、镜像管理

搜索镜像:

这种方法只能用于官方镜像库
搜索基于 centos 操作系统的镜像

[root@biudefor ~]# docker search centos

按星级搜索镜像:

查找 star 数至少为 100 的镜像,默认不加 s 选项找出所有相关 centos 镜像:         
[root@biudefor ~]## docker search centos -s 100
或者
[root@biudefor ~]## docker search ubuntu -f stars=100   

拉取镜像:

# docker pull centos
注:没有加registry,默认是从docker.io下载的
[root@biudefor ~]# docker pull daocloud.io/library/tomcat:7
[root@biudefor ~]# docker pull daocloud.io/library/centos:6

查看本地镜像:

[root@biudefor ~]# docker image list 
或者
[root@biudefor ~]# docker images

查看镜像详情:

[root@biudefor ~]# docker inspect 镜像ID

删除镜像:

前提:没有使用这个镜像正在运行的容器
删除一个或多个,多个之间用空格隔开,可以使用镜像名称或id
[root@biudefor ~]# docker rmi daocloud.io/library/mysql
或者
[root@biudefor ~]# docker rmi 81debc

参数解释:
rm          Remove one or more containers  ---移除一个或多个容器
rmi         Remove one or more images   ---删除一个或多个镜像

强制删除:--force

如果镜像正在被使用中可以使用--force强制删除    
# docker rmi docker.io/ubuntu:latest --force
-f, --force      Force removal of the image

注意: 容器运行中不能删除,将容器停止后,删除容器在删除镜像。

只查看所有镜像的id:

[root@biudefor ~]# docker images -q
98ebf73aba75
81debc95563d
d0957ffdf8a2

-q, --quiet

删除所有镜像:

 [root@biudefor ~]# docker rmi $(docker images -q) 

查看镜像制作的过程:

相当于dockfile

[root@biudefor ~]# docker history daocloud.io/library/nginx  #使用镜像名或者镜像ID都可以

九、容器管理

创建新容器但不启动:

# docker create -it daocloud.io/library/centos:5 /bin/bash

创建并运行一个新Docker 容器:同一个镜像可以启动多个容器,每次执行run子命令都会运行一个全新的容器

# docker run -it --restart=always centos /bin/bash   #最常用
-i :标准输入输出
-t:分配一个终端或控制台
--restart=always:容器随docker engine自启动,因为在重启docker的时候默认容器都会被关闭   
也适用于create选项
-d  后台运行容器,并返回容器ID;

如果执行成功,说明CentOS 容器已经被启动,并且应该已经得到了 bash 提示符。

--rm:默认情况下,每个容器在退出时,它的文件系统也会保存下来.另一方面,也可以保存容器所产生的数
据。但是当你仅仅需要短暂的运行一个容器,并且这些数据不需要保存,你可能就希望Docker能在容器结束
时自动清理其所产生的数据。这个时候就需要--rm
参数了。退出或停止就会将容器删除。

注意:--rm 和 -d不能共用

容器名称

为容器分配一个名字,如果没有指定,docker会自动分配一个随机名称是 docker run子命令的参数
--name= Assign a name to the container
# docker run -it --name 名字  daocloud.io/centos:6    #名字自定义

如果你在执行docker run时没有指定--name,那么自动生成一个随机字符串UUID。这个UUID标识是由Docker deamon生成的。但是对于一个容器来说有个name会非常方便,当你需要连接其它容器时或者类似需要区分其它容器时,使用容器名称可以简化操作。无论容器运行在前台或者后台,这个名字都是有效的。

若要断开与容器的连接,并且关闭容器:容器内部执行如下命令

root@37b8b8cdd75f:/# exit

如果只想断开和容器的连接而不关闭容器:

 快捷键:ctrl+p+q

查看容器:

1.只查看运行状态的容器:
#docker ps
2.-a  查看所有容器
#docker ps -a
3.只查看所有容器id:
# docker ps -a -q  

查看容器详细信息:

inspect :用于查看容器的配置信息,包含容器名、环境变量、运行命令、主机配置、网络配置和数据卷配置等。

目标:查找某一个运行中容器的id,然后使用docker inspect命令查看容器的信息。

提示:可以使用容器id的前面部分,不需要完整的id。

[root@biudefor ~]# docker inspect bbdc71e   #机器上运行的一个容器ID或者名称
[
    {
        "Id": "d95a220a498e352cbfbc098c949fc528dbf5a5c911710b108ea3a9b4aa3a4761",
        "Created": "2017-07-08T03:59:16.18225183Z",
        "Path": "bash",
        "Args": [],
        "State": {
            "Status": "exited",
           "Running": false,
            "Paused": false,
           "Restarting": false,
            "OOMKilled": false,
            "Dead": false,
            "Pid": 0,

容器信息很多,这里只粘贴了一部分 

启动容器:

# docker start  name   #容器ID也可以
这里的名字是状态里面NAMES列列出的名字,这种方式同样会让容器运行在后台

关闭容器:

# docker stop  name

# docker kill  name      --强制终止容器 

杀死所有running状态的容器

# docker kill $(docker ps  -q) 

stop和kill的区别:

docker stop命令给容器中的进程发送SIGTERM信号,默认行为是会导致容器退出,当然,容器内程序可以捕获该信号并自行处理,例如可以选择忽略。而docker kill则是给容器的进程发送SIGKILL信号,该信号将会使容器必然退出。

删除容器:

# docker rm 容器id或名称
要删除一个运行中的容器,添加 -f 参数 --慎用。先stop在删除   

根据格式删除所有容器:

# docker rm $(docker ps -qf status=exited)
-f:过滤

pause :暂停容器中所有的进程
unpause:恢复容器内暂停的进程,与pause对应

[root@biudefor ~]# docker pause c7
[root@biudefor ~]# docker ps 
CONTAINER ID        IMAGE                          COMMAND             CREATED             STATUS                  PORTS               NAMES
3c0e0f43807d        98ebf73aba                     "/bin/bash"         7 minutes ago       Up 7 minutes (Paused)   80/tcp              c7
[root@biudefor ~]# docker unpause c7  #恢复

重启容器:

#docker restart name   

让容器运行在后台:

# docker run -dit 镜像ID /bin/bash
-d后台运行必须要加-it

如果在docker run后面追加-d=true或者-d,那么容器将会运行在后台模式。此时所有I/O数据只能通过网络资源或者共享卷组来进行交互。因为容器不再监听你执行docker run的这个终端命令行窗口。但你可以通过执行

docker attach来重新附着到该容器的回话中。

[root@biudefor ~]# docker attach 容器ID/容器名字

注:

容器运行在后台模式下,是不能使用--rm选项的(老版本是这样,新版本已经可以同时生效)

rename ---修改容器名称

[root@biudefor ~]# docker rename mytest testmy
[root@biudefor ~]# docker ps -a 
CONTAINER ID        IMAGE                       COMMAND                  CREATED             STATUS              PORTS               NAMES
774c02898fb1        daocloud.io/library/nginx   "/bin/bash -c 'while…"   5 minutes ago       Up About a minute   80/tcp              testmy  

stats
Display a live stream of container(s) resource usage statistics---显示容器资源使用统计信息的实时流

[root@biudefor ~]# docker stats
--当有容器在运行的时候动态显示容器的资源消耗情况,包括:CPU、内存、网络I/O

连接容器:前提是容器在运行状态中

方法1.attach

# docker attach 容器id   #前提是容器创建时必须指定了交互shell 

方法2.exec

通过exec命令可以创建两种任务:后台型任务和交互型任务

1.交互型任务:
[root@biudefor ~]# docker exec -it  容器id  /bin/bash
root@68656158eb8e:/# ls

2.后台型任务:不进入容器里面执行命令
[root@biudefor ~]# docker exec 容器id touch /testfile

监控容器的运行:

可以使用logs、top、wait这些子命令

logs:使用logs命令查看守护式容器

可以通过使用docker logs命令来查看容器的运行日志,其中--tail选项可以指定查看最后几条日志,使用-f选项可以跟踪日志的输出,直到手动停止。

[root@biudefor ~]# docker pull daocloud.io/library/nginx
[root@biudefor ~]# docker images 
[root@biudefor ~]# docker run -it --name nginx1 98ebf73 /bin/bash 
root@8459191dbe7c:/# /usr/sbin/nginx   #启动nginx
ctrl+p+q --- 退出
[root@biudefor ~]# docker inspect nginx1  #找到ip地址
[root@biudefor ~]# curl -I http://172.17.0.3  #宿主机访问容器可以访问成功
HTTP/1.1 200 OK
Server: nginx/1.17.1
Date: Mon, 09 Mar 2020 14:49:40 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 25 Jun 2019 12:19:45 GMT
Connection: keep-alive
ETag: "5d121161-264"
Accept-Ranges: bytes
[root@biudefor ~]# curl -I http://172.17.0.3  #继续测试访问

在开启一个终端:
[root@biudefor ~]# docker logs -f nginx1  
root@8459191dbe7c:/# /usr/sbin/nginx
root@8459191dbe7c:/# 172.17.0.1 - - [09/Mar/2020:14:49:33 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.29.0" "-"
172.17.0.1 - - [09/Mar/2020:14:49:40 +0000] "HEAD / HTTP/1.1" 200 0 "-" "curl/7.29.0" "-"

# docker logs --tail -2 App_Conainer

top:显示一个运行的容器里面的进程信息

[root@biudefor ~]# docker top  nginx   #容器ID也可以

wait :--捕捉容器停止时的退出码

执行此命令后,该命令会"hang"在当前终端,直到容器停止,此时,会打印出容器的退出码

在第一个终端执行停止容器命令
[root@biudefor ~]# docker stop nginx1
===============================
[root@biudefor ~]# docker wait 01d8aa  #第二个终端操作
0

docker run 之后容器退出的状态码:
0,表示正常退出
非0,表示异常退出(退出状态码采用chroot标准)
125,Docker守护进程本身的错误
126,容器启动后,要执行的默认命令无法调用
127,容器启动后,要执行的默认命令不存在

宿主机和容器之间相互COPY文件

cp的用法如下:

Usage: 
docker cp [OPTIONS] CONTAINER:PATH LOCALPATH   --从容器拷贝到本机
docker cp [OPTIONS] LOCALPATH CONTAINER:PATH   --从本机拷贝到容器

如:容器nginx中/usr/local/bin/存在test.sh文件,可如下方式copy到宿主机

[root@biudefor ~]# docker exec -it nginx /bin/bash
root@2a9a18b4a485:/# cd /usr/local/bin/
root@2a9a18b4a485:/usr/local/bin# touch test.sh
ctrl+p+q  退出
[root@biudefor ~]# docker cp mytest:/usr/local/bin/test.sh /root/ 

修改完毕后,将该文件重新copy回容器

[root@biudefor ~]# ls
anaconda-ks.cfg  test.sh
[root@biudefor ~]# echo "123" >> test.sh
[root@biudefor ~]# docker cp /root/test.sh mytest:/usr/local/bin/

十、docker镜像制作

1、容器文件系统打包

将容器的文件系统打包成tar文件,也就是把正在运行的容器直接导出为tar包的镜像文件

有两种方式:

第一种:

[root@biudefor ~]# docker run -it --name c7 daocloud.io/library/centos:7 /bin/bas
[root@567e260b11b4 /]# touch a.txt
[root@biudefor ~]# docker export -o new_c7.tar c7
[root@biudefor ~]# ls    #保存到当前目录下
new_c7.tar

第二种:

[root@biudefor ~]# docker export 容器名称 > 镜像.tar

导入镜像import :

[root@biudefor ~]# docker import new_c7.tar c7-1
sha256:523115789788a5bdcd46b9046da70d8e84c44c9830397c0b7c6bf4d31d7baef5
[root@biudefor ~]# docker images
REPOSITORY                                        TAG                 IMAGE ID            CREATED             SIZE
c7-1                                              latest              523115789788        3 seconds ago       203MB

[root@biudefor ~]# docker run -it c7-1 /bin/bash
[root@90ea8c3dce29 /]# ls
a.txt  anaconda-post.log  bin  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
2、通过容器创建本地镜像

使用 docker commit 指令,把一个正在运行的容器,直接提交为一个镜像。

commit 是提交的意思,类似告诉svn服务器我要生成一个新的版本。

[root@biudefor ~]# docker run -it --name c7 daocloud.io/library/centos:7 /bin/bash
[root@16d235af558d /]# touch b.txt
[root@16d235af558d /]# [root@biudefor ~]# docker commit c7 test/c7
sha256:eb4508cfef177bf9118905023b70be2a0238d3141f40a0655fdfa1343c45213c
[root@biudefor ~]# docker images
REPOSITORY                                        TAG                 IMAGE ID            CREATED             SIZE
test/c7                                           latest              eb4508cfef17        4 seconds ago       203MB

[root@biudefor ~]# docker run -it test/c7 /bin/bash
[root@44ba93472ac7 /]# ls
anaconda-post.log  b.txt  bin  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  tmp  usr  var
3、镜像迁移

将镜像打包,然后可以导入到其他宿主机上

save

[root@biudefor ~]# docker save -o centos-7.tar daocloud.io/library/centos:7

load

[root@biudefor ~]# docker load < centos-7.tar

总结:

把容器导出成tar包 export   import 

把容器做成镜像  commit

把镜像保存为tar包 save    load

十一、Dockerfile创建镜像

Docker 提供了一种更便捷的方式,叫作 Dockerfile

docker build命令用于根据给定的Dockerfile构建Docker镜像。

docker build语法:

# docker build [OPTIONS] <PATH | URL | ->
常用选项说明
--build-arg,设置构建时的变量
--no-cache,默认false。设置该选项,将不使用Build Cache构建镜像
--pull,默认false。设置该选项,总是尝试pull镜像的最新版本
--compress,默认false。设置该选项,将使用gzip压缩构建的上下文
--disable-content-trust,默认true。设置该选项,将对镜像进行验证
--file, -f,Dockerfile的完整路径,默认值为‘PATH/Dockerfile’
--isolation,默认--isolation="default",即Linux命名空间;其他还有process或hyperv
--label,为生成的镜像设置metadata
--squash,默认false。设置该选项,将新构建出的多个层压缩为一个新层,但是将无法在多个镜像之间共享新层;设置该选项,实际上是创建了新image,同时保留原有image。
--tag, -t,镜像的名字及tag,通常name:tag或者name格式;可以在一次构建中为一个镜像设置多个tag
--network,默认default。设置该选项,Set the networking mode for the RUN instructions during build
--quiet, -q ,默认false。设置该选项,Suppress the build output and print image ID on success
--force-rm,默认false。设置该选项,总是删除掉中间环节的容器
--rm,默认--rm=true,即整个构建过程成功后删除中间环节的容器
示例: 
docker build -t test/cenos:v1 .

docker build  是docker创建镜像的命令 
-t 是标识新建的镜像属于 soso的 bbauto镜像 
:v1 是tag 
"."是用来指明 我们的使用的Dockerfile文件当前目录的 
1.1、创建文件夹和Dockerfile文件
[root@biudefor ~]# mkdir test
[root@biudefor ~]# cd test/
[root@biudefor test]# vim Dockerfile   #Dockerfile是语法,文件名必须是这个
FROM daocloud.io/library/centos:7
MAINTAINER test biudefor
RUN yum install -y wget  && yum clean all
RUN touch a.txt
RUN mkdir /test
命令要大写
每一个指令后面需要跟空格,语法。
FROM 命令是告诉docker 我们的镜像什么从哪里下载。 
MAINTAINER 描述 镜像的创建人 
RUN 命令是在镜像内部执行。就是说他后面的命令应该是针对镜像可以运行的命令。 
1. 2、创建镜像
[root@biudefor test]# docker build -t test/c7-1 .

docker build  是docker创建镜像的命令 
image.png
[root@biudefor test]# docker images
REPOSITORY                                        TAG                 IMAGE ID            CREATED              SIZE
test/c7-1                                         latest              2471ce64c222        About a minute ago   227MB
[root@biudefor test]# docker run -it test/c7-1 /bin/bash
[root@09b81e91e608 /]# ls
a.txt  anaconda-post.log  bin  dev  etc  home  lib  lib64  media  mnt  opt  proc  root  run  sbin  srv  sys  test  tmp  usr  var
[root@09b81e91e608 /]# ls | grep test
test

十二、部署私有仓库应用

私有仓库镜像:

registry --官方出品, 没有图形界面.Docker hub官方已提供容器镜像registry,用于搭建私有仓库

拉取镜像:
[root@docker_server ~]# docker pull daocloud.io/library/registry
运行容器:
[root@docker_server ~]# docker run -d -v /home/dockerdata/registry:/var/lib/registry --name registry --restart=always -p 5000:5000 daocloud.io/library/registry

参数解释:
/home/dockerdata/registry表示为宿主机的目录,如果不存在自动创建
-v映射目录:  宿主机的目录:容器目录
把宿主机的目录挂载到容器中,将数据目录挂载出来就是为了防止docker私有仓库这个容器被删除的时候,仓库里面的镜像也被删除。
-p 端口映射:本地端口:容器端口

注:如果创建容器不成功,报错防火墙,解决方案如

#systemctl stop firewalld
#yum install iptaqbles*
#systemctl start iptables
#iptables -F
#systemctl restart docker  
[root@docker_server ~]# docker ps
CONTAINER ID        IMAGE                          COMMAND                  CREATED             STATUS              PORTS                    NAMES
bc64c57125a5        daocloud.io/library/registry   "/entrypoint.sh /etc…"   2 minutes ago       Up 2 minutes        0.0.0.0:5000->5000/tcp   registry
连接容器查看端口状态:
[root@docker_server ~]# docker exec -it registry /bin/sh
/ # netstat -lntp     #查看5000端口是否开启
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 :::5000                 :::*                    LISTEN      1/registry
/ #

在另一台机器查看能否访问该私有仓库, 看看状态码是不是200

[root@biudefor ~]# curl -I http://39.96.41.205:5000
HTTP/1.1 200 OK

下载一个mysql镜像测试:

[root@biudefor ~]# docker pull daocloud.io/library/mysql:5.7

上传前必须给镜像打tag 注明ip和端口:

[root@biudefor ~]# docker tag daocloud.io/library/mysql:5.7 39.96.41.205:5000/mysql5.7
[root@biudefor ~]# docker images
REPOSITORY                                        TAG                 IMAGE ID            CREATED             SIZE
39.96.41.205:5000/mysql5.7                      latest              a1aa4f76fab9        9 months ago        373MB

注:tag后面可以使用镜像名称也可以使用id,我这里使用的镜像名称,如果使用官方的镜像,不需要加前缀,但是daocloud.io的得加前缀.

修改请求方式为http:

默认为https,不改会报以下错误:
Get https://master.up.com:5000/v1/_ping: http: server gave HTTP response to HTTPS client

[root@biudefor ~]# vim /etc/docker/daemon.json    #不存在则创建
{
  "insecure-registries":["39.96.41.205:5000"]
}

重启docker:
[root@biudefor ~]# systemctl restart docker

上传镜像到私有仓库:

[root@biudefor ~]# docker push 39.96.41.205:5000/mysql5.7

查看私有仓库里的所有镜像:

语法: # curl  http://ip:port/v2/repo名字/tags/list

[root@biudefor ~]# curl http://39.96.41.205:5000/v2/mysql5.7/tags/list
{"name":"mysql5.7","tags":["latest"]}

查看仓库下面所有的镜像:
[root@biudefor ~]# curl http://39.96.41.205:5000/v2/_catalog
{"repositories":["mysql5.7"]}

拉取镜像测试:

1.先将刚才打了tags的镜像和daocloud的镜像删掉
[root@biudefor ~]# docker rmi 39.96.41.205:5000/mysql5.7
2.拉取镜像:
[root@biudefor ~]# docker pull 39.96.41.205:5000/mysql5.7
[root@biudefor ~]# docker images

十三、部署docker web ui应用

下载并运行容器:

[root@biudefor ~]# docker pull uifd/ui-for-docker
[root@biudefor ~]# docker run -it -d --name docker-web -p 9000:9000 -v /var/run/docker.sock:/var/run/docker.sock docker.io/uifd/ui-for-docker

浏览器访问ip+9000端口

image.png

十四、docker资源限制

在使用 docker 运行容器时,一台主机上可能会运行几百个容器,这些容器虽然互相隔离,但是底层却使用着相同的 CPU、内存和磁盘资源。如果不对容器使用的资源进行限制,那么容器之间会互相影响,小的来说会导致容器资源使用不公平;大的来说,可能会导致主机和集群资源耗尽,服务完全不可用。

CPU 和内存的资源限制已经是比较成熟和易用,能够满足大部分用户的需求。磁盘限制也是不错的,虽然现在无法动态地限制容量,但是限制磁盘读写速度也能应对很多场景。

至于网络,docker 现在并没有给出网络限制的方案,也不会在可见的未来做这件事情,因为目前网络是通过插件来实现的,和容器本身的功能相对独立,不是很容易实现,扩展性也很差。

资源限制一方面可以让我们为容器(应用)设置合理的 CPU、内存等资源,方便管理;另外一方面也能有效地预防恶意的攻击和异常,对容器来说是非常重要的功能

系统压力测试工具stress

stress是一个linux下的压力测试工具,专门为那些想要测试自己的系统,完全高负荷和监督这些设备运行的用户。

CPU资源限制

限制CPU Share

什么是cpu share:

docker 允许用户为每个容器设置一个数字,代表容器的 CPU share,默认情况下每个容器的 share 是 1024。这个 share 是相对的,本身并不能代表任何确定的意义。当主机上有多个容器运行时,每个容器占用的 CPU 时间比例为它的 share 在总额中的比例。docker 会根据主机上运行的容器和进程动态调整每个容器使用 CPU 的时间比例。

例子:

如果主机上有两个一直使用 CPU 的容器(为了简化理解,不考虑主机上其他进程),其 CPU share 都是 1024,那么两个容器 CPU 使用率都是 50%;如果把其中一个容器的 share 设置为 512,那么两者 CPU 的使用率分别为 67% 和 33%;如果删除 share 为 1024 的容器,剩下来容器的 CPU 使用率将会是 100%。

好处:

能保证 CPU 尽可能处于运行状态,充分利用 CPU 资源,而且保证所有容器的相对公平;

缺点:

无法指定容器使用 CPU 的确定值。

设置 CPU share 的参数:

-c --cpu-shares,它的值是一个整数

限制CPU核数

限制容器能使用的 CPU 核数

-c --cpu-shares 参数只能限制容器使用 CPU 的比例,或者说优先级,无法确定地限制容器使用 CPU 的具体核数;从 1.13 版本之后,docker 提供了 --cpus 参数可以限定容器能使用的 CPU 核数。这个功能可以让我们更精确地设置容器 CPU 使用量,是一种更容易理解也因此更常用的手段.

--cpus 后面跟着一个浮点数,代表容器最多使用的核数,可以精确到小数点二位,也就是说容器最小可以使用 0.01 核 CPU。

# docker pull progrium/stress
# yum install -y htop
# docker run --rm -it --cpus 1 progrium/stress --cpu 4

我的机器是 2 核 CPU,限制容器只能使用 1 核数 CPU,运行一个stress容器,使用 stress 启动 4 个进程来产生计算压力:(无CPU限制)

image.png

可以看出,4个进程每个进程的CPU占用率都大概在25%,加起来就是100%,符合1核的设置。

# docker run --rm -it --cpus 2 progrium/stress --cpu 4
image.png

这次设置使用2核,开启4个进程,2核的CPU利用率应该是200%,图中四个进程的CPU使用率加起来,刚好是200%,符合2核的设置

mem资源限制

docker 默认没有对容器内存进行限制,容器可以使用主机提供的所有内存。

不限制内存带来的问题:

这是非常危险的事情,如果某个容器运行了恶意的内存消耗软件,或者代码有内存泄露,很可能会导致主机内存耗尽,因此导致服务不可用。可以为每个容器设置内存使用的上限,一旦超过这个上限,容器会被杀死,而不是耗尽主机的内存。

限制内存带来的问题:

限制内存上限虽然能保护主机,但是也可能会伤害到容器里的服务。如果为服务设置的内存上限太小,会导致服务还在正常工作的时候就被 OOM 杀死;如果设置的过大,会因为调度器算法浪费内存。

合理做法:

  1. 为应用做内存压力测试,理解正常业务需求下使用的内存情况,然后才能进入生产环境使用
  2. 一定要限制容器的内存使用上限,尽量保证主机的资源充足,一旦通过监控发现资源不足,就进行扩容或者对容器进行迁移如果可以(内存资源充足的情况)
  3. 尽量不要使用 swap,swap 的使用会导致内存计算复杂,对调度器非常不友好

docker 限制容器内存使用量:

docker 启动参数中,和内存限制有关的包括(参数的值一般是内存大小,也就是一个正数,后面跟着内存单位 b、k、m、g,分别对应 bytes、KB、MB、和 GB):

-m --memory:容器能使用的最大内存大小,最小值为 4m

如果限制容器的内存使用为 64M,在申请 64M 资源的情况下,容器运行正常(如果主机上内存非常紧张,并不一定能保证这一点):

[root@biudefor ~]# docker run --rm -it -m 100m db646a8f4 --vm 1 --vm-bytes 64M --vm-hang 0
stress: info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] --> hogvm worker 1 [6] forked
stress: dbug: [6] allocating 67108864 bytes ...
stress: dbug: [6] touching bytes in strides of 4096 bytes ...
stress: dbug: [6] sleeping forever with allocated memory

容器可以正常运行。
-m 100m:限制你这个容器只能使用100M
--vm-bytes 64M:将内存撑到64兆是不会报错,因为我有100兆内存可用。
hang:就是卡在这里。
--vm:生成几个占用内存的进程

而如果申请 150M 内存,会发现容器里的进程被 kill 掉了(worker 6 got signal 9,signal 9 就是 kill 信号)

[root@biudefor ~]# docker run --rm -it -m 100m db646a8f4 --vm 1 --vm-bytes 150M --vm-hang 0
stress: info: [1] dispatching hogs: 0 cpu, 0 io, 1 vm, 0 hdd
stress: dbug: [1] using backoff sleep of 3000us
stress: dbug: [1] --> hogvm worker 1 [6] forked
stress: dbug: [6] allocating 157286400 bytes ...
stress: dbug: [6] touching bytes in strides of 4096 bytes ...
stress: FAIL: [1] (416) <-- worker 6 got signal 9
stress: WARN: [1] (418) now reaping child worker processes
stress: FAIL: [1] (422) kill error: No such process
stress: FAIL: [1] (452) failed run completed in 0s

十五、端口转发

使用端口转发解决容器端口访问问题

-p:创建应用容器的时候,一般会做端口映射,这样是为了让外部能够访问这些容器里的应用。可以用多个-p指定多个端口映射关系。

MySQL应用端口转发:

查看本地地址:

[root@biudefor ~]# ip a
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:16:3e:04:2c:37 brd ff:ff:ff:ff:ff:ff
    inet 172.18.254.146/20 brd 172.18.255.255 scope global dynamic eth0
       valid_lft 314848732sec preferred_lft 314848732sec

运行容器:使用-p作端口转发,把本地3307转发到容器的3306,其他参数需要查看发布容器的页面提示

[root@biudefor ~]# docker pull daocloud.io/library/mysql:5.7
[root@biudefor ~]# docker run -d --name mysql -p 3307:3306 -e MYSQL_ROOT_PASSWORD=Duan@123 daocloud.io/library/mysql:5.7

-e MYSQL_ROOT_PASSWORD= 设置环境变量,这里是设置mysql的root用户的密码

通过本地登录测试:

[root@biudefor ~]# mysql -uroot -pDuan@123 -h 172.18.254.146 -P3307
mysql>

十六、容器卷

把本地宿主机上面的某一个目录挂载到容器里面的目录去。这两个目录都不用提前存在,会自动创建

新卷只能在容器创建过程当中挂载

[root@biudefor ~]# docker run -it --name c7 -v /root/test:/test centos:7 /bin/bash
[root@f9f9b7124263 /]# ls
[root@f9f9b7124263 /]# ctrl+p+q  #退出

[root@biudefor ~]# cd test/
[root@biudefor test]# touch a.txt
[root@biudefor test]# mkdir dir
[root@biudefor test]# ls
a.txt  dir
[root@biudefor test]# docker exec -it c7 /bin/bash
[root@f9f9b7124263 /]# cd test/
[root@f9f9b7124263 test]# ls
a.txt  dir

运行一个容器共享已运行容器的卷

[root@biudefor ~]# docker run -it --name c7-v1 --volumes-from c7 centos:7 /bin/bash
[root@cffa7d79836d /]# cd test/
[root@cffa7d79836d test]# ls
a.txt  dir

实际应用中可以利用多个-v选项把宿主机上的多个目录同时共享给新建容器:

# docker run -it -v /abc:/abc -v /def:/def 1ae9

十七、部署CentOS7容器应用

镜像下载:

# docker pull daocloud.io/library/centos:7

systemd 整合:
官网:daocloud.io

因为 systemd 要求 CAPSYSADMIN 权限,从而得到了读取到宿主机 cgroup 的能力,CentOS7 中已经用 fakesystemd 代替了 systemd 。 但是我们使用 systemd,可用参考下面的 Dockerfile:

[root@biudefor ~]# mkdir test
[root@biudefor ~]# cd test/
[root@biudefor test]# vim Dockerfile
FROM daocloud.io/centos:7
MAINTAINER "you" <your@email.here>
ENV container docker
RUN yum -y swap -- remove fakesystemd -- install systemd systemd-libs
RUN yum -y update; yum clean all; \
(cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \
rm -f /lib/systemd/system/multi-user.target.wants/*;\
rm -f /etc/systemd/system/*.wants/*;\
rm -f /lib/systemd/system/local-fs.target.wants/*; \
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*;\
rm -f /lib/systemd/system/anaconda.target.wants/*;
VOLUME [ "/sys/fs/cgroup" ]
CMD ["/usr/sbin/init"]

这个Dockerfile删除fakesystemd 并安装了 systemd。然后再构建基础镜像:

[root@biudefor test]# docker build --rm -t local/c7-systemd .

执行没有问题这就生成一个包含 systemd 的应用容器示例:

[root@biudefor test]# docker images
REPOSITORY                   TAG                 IMAGE ID            CREATED              SIZE
local/c7-systemd             latest              f7ddb5c951a9        About a minute ago   314MB

为了使用像上面那样包含 systemd 的容器,需要创建一个类似下面的Dockerfile:

[root@biudefor test]# mkdir http
[root@biudefor test]# cd http/
[root@biudefor http]# vim Dockerfile
FROM local/c7-systemd
RUN yum -y install httpd; yum clean all; systemctl enable httpd.service
EXPOSE 80
CMD ["/usr/sbin/init"]

构建镜像:

[root@biudefor http]# docker build -t http .

运行包含 systemd 的应用容器:

为了运行一个包含 systemd 的容器,需要使用--privileged选项, 并且挂载主机的 cgroups 文件夹。 下面是运行包含 systemd 的 httpd 容器的示例命令:

[root@biudefor http]# docker run --privileged -itd -v /sys/fs/cgroup:/sys/fs/cgroup:ro -p 80:80 http

注意:如果不加会运行在前台(没有用-d),可以用ctrl+p+q放到后台去

测试:

# yum install -y elinks
# elinks --dump http://ip  #apache的默认页面

十八、docker数据存储位置

查看存储路径:
[root@biudefor http]# docker info | grep -i root
 Docker Root Dir: /var/lib/docker

修改默认存储位置:
在dockerd的启动命令后面追加--data-root参数指定新的位置
[root@biudefor ~]# vim  /usr/lib/systemd/system/docker.service
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --data-root=/data

[root@biudefor ~]# systemctl daemon-reload 
[root@biudefor ~]# systemctl restart docker

查看是否生效:
[root@biudefor ~]# docker info | grep Root
 Docker Root Dir: /data
 
[root@biudefor ~]# cd /data/
[root@biudefor data]# ls
builder  buildkit  containers  image  network  overlay2  plugins  runtimes  swarm  tmp  trust  volumes

推荐阅读更多精彩内容