docker的介绍:

容器:容器技术是一种虚拟化的方案
容器:docker , k8s
docker:docker是能将开发的应用程序自动部署到容器的开源引擎。
Github地址:https://github.com/docker/docker
docker官网:www.docker.com
hub.docker.com  上传下载docker镜像的网站
docker的特别之处:
docker在虚拟化的容器执行环境中,增加了一个应用程序部署引擎。
该引擎的目标:
提供一个轻量快速的环境,能够运行开发者的程序,便于方便高效的从开发者环境部署到测试环境,然后再部署到生产环境。
docker的优点:
1、提供简单轻量的建模方式,运行秒级
2、职责的逻辑分离。开发人员只需要关系容器中运行的程序,而运维人员只需要关心如何管理程序。docker设计的目的性就是加强开发人员写代码的开发环境与应用环境要部署的生产环境的一致性。
3、快速高效的开发生命周期。缩短代码从开发到测试,再到上线运行的生命周期。让应用和程序具备可移植性。在容器中开发,以容器的形式去交付。
4、鼓励使用面向服务的架构。docker推荐单个容器只运行一个程序或者一个进程。这样就形成了一个分布式的应用程序模型。
在这种模型下,应用程序或服务都可以表示为一系列内部互联的容器,从而使分布式互联的程序扩展或调试应用程序都变得非常简单。
这就是在开发中常用的思想:高内聚低耦合
docker的使用场景:
1、使用docker容器开发、测试、部署服务;
2、创建隔离的运行环境
3、搭建测试环境
4、构建多用户的平台即服务(PaaS)基础设施
5、提供软件即服务(SaaS)应用程序
6、高性能、超大规模的宿主机部署
三大核心理念:
构建   基于镜像构建容器
运输   传输到系统中
运行    运行于容器

docker容器的安装:

安装docker容器:
注:centos虚拟机必须要联网,不然无法安装。
1.配置repo仓库
cd /etc/yum.repos.d/

vi docker.repo
[dockerrepo]
name=Docker Repository
baseurl=https://yum.dockerproject.org/repo/main/centos/$releasever/
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg

yum clean all
yum makecache

2.安装docker
yum -y install docker
cd
检查有木有安装方法:
docker version

3.启动并设置开启自启动
systemctl start docker
systemctl enable docker
docker version
到此,docker容器安装完成,并且启动成功。

docker镜像操作:

获取镜像的三种方式:
1)下载镜像(默认从Docker Hub下载)
2)把容器转换为镜像
3)制作镜像(通过dockerfile生成镜像)

查找镜像(默认从Docker Hub查询)
docker search httpd     //查找所有httpd相关的镜像

下载镜像(默认从Docker Hub查询)
docker pull docker.io/httpd

查看本机镜像列表
docker images   //查看所有镜像  (也可以单独查询 后面跟仓库名称和标签)
docker inspect  2211e1f06c4e或docker.io/httpd    //指定ID号查看 详细信息

REPOSITORY:表示镜像的仓库源docker.io
TAG:表示镜像的标签
IMAGE ID:表示镜像的ID
CREATED:表示镜像创建时间
SIZE:表示镜像大小

添加新名称  新标签 ,用于改名称
docker tag httpd  httpd:centos

删除镜像
删除之前确保没有被容器使用,若有容器使用需要先删除容器。  
docker rmi 镜像名称 或者镜像id
镜像没有使用才能删除成功,且只是删除名称

docker  rmi  -f   镜像ID //永久删除
docker rmi -f $(docker images | grep "" | awk "{print \$3}") 
删除所有没有使用的镜像

存出镜像和载入镜像
docker save -o httpd httpd    //将本地镜像存为文件httpd,保存在当前所在的目录中
docker save -o 文件名   镜像名称
docker load < cobbler     //将镜像文件导入到docker镜像中

小结:

镜像操作:
搜索 : docker search 关键字
下载 : docker pull 关键字
查看:docker images
查看镜像内容信息:docker inspect 镜像名(ID)
删除:docker rmi 镜像名(ID)
导出镜像:docker sava -o 保存的文件名 镜像名(ID)
导入镜像:docker load < 保存的文件
更改镜像名称及标签docker tag 镜像id 新的镜像名: 标签

docker容器操作:

docker容器操作
容器是镜像的一个运行实例。所不同的是,镜像是静态的只读文件,而容器带有运行时需要的可写文件层。如果认为虚拟机是模拟运行的一整套操作系统(包括内核、应用运行态环境和其他系统环境)和跑在上面的应用,那么Docker容器就是独立运行的一个(或一组)应用,以及它们必需的运行环境。

创建容器
对容器进行操作就跟直接操作应用一样简单、快速。Docker容器实在太轻量级了,用户可以随时创建或删除容器。

1.新建容器
可以使用docker create命令新建一个容器,例如:
docker create -it ubuntu:latest   //基于镜像创建容器,默认是没有运行的
docker ps -a   //查看所有容器

使用docker create命令新建的容器处于停止状态,可以使用docker start命令来启动它。
create命令和后续的run命令支持的选项都十分复杂,主要包括如下几大类:与容器运行模式相关、与容器和环境配置相关、与容器资源限制和安全保护相关。

create命令与容器运行模式相关的选项:
选项  说明
-a,--attach=[]  是否绑定到标准输入、输出和错误
-d,--detach=true|false  是否在后台运行容器,默认为否
--detach-keys=""    从attach模式退出的快捷键
--expose=[] 指定容器会暴露出来的端口或端口范围
--group-add=[]  运行容器的用户组
-i,--interactive=true|false 保持标准输入打开,默认为false
--ipc=""    容器IPC命名空间,可以为其它容器或主机
--isolation="default"   容器使用的隔离机制
--log-driver="json-file"    指定容器的日志驱动类型,可以为json-file,syslog,journald,gelf,fluentd,awslogs,splunk,etwlogs,gcplogs或none
--log-opt=[]    传递给日志驱动的选项
--net="bridge"  指定容器网络模式,包括bridge,none,其它容器网络,host的网络或者某个现有网络
--net-alias=[]  容器在网络中的别名
-P,--publish-all=true|false 通过NAT机制将容器标记暴露的端口自动映射到本地主机的临时端口
-p,--publish=[] 指定如何映射到本地主机端口,例如-p 11234-12234:1234-2234
--pid=host  容器的PID命名空间
--userns="" 启用userns-remap时配置用户命名空间的模式
--uts=host  容器的PID命名空间
--restart="no"  容器的重启策略,包括no、on-failure[:max-retry]、always、unless-stopped等
--rm=true|false 容器退出后是否自动删除,不能跟-d同时使用
-t,--tty=true|false 容器运行时指定伪终端
--tmpfs=[]  挂载临时文件系统到容器
-v|--volume  host-dir:container-dir 挂载主机上的文件卷到容器内
--volume-driver=""  挂载文件卷的驱动类型
--volumes-from=[]   从其他容器挂载卷
-w,--workdir="" 容器内的默认工作目录

create命令与容器环境和配置相关的选项:
选项 说明
--add-host=[ ] 在容器内添加一个主机名到IP地址的映射关系(通过/etc/hosts文件)
--device=[ ] 映射物理机上的设备到容器内
--dns-search=[ ] DNS搜索域
--dns-opt=[ ] 自定义的DNS选项
--dns=[ ] 自定义的DNS服务器
-e,--env=[ ] 指定容器内环境变量
--env-file=[ ] 从文件中读取环境变量到容器内
-h,--hostname="" 指定容器内的主机名
--ip=“” 指定容器的IPv4地址
--ip6="" 指定容器的IPv6地址
--link=[ :alias] 连接到其它容器
--mac-address="" 指定容器的Mac地址
--name="" 指定容器的别名

create命令与容器资源限制和安全保护相关的选项:
选项    说明
--blkio-weight=10~1000  容器读写块设备的I/O性能权重,默认为0
--blkio-weight-device=[device_name:weight]  指定各个块设备的I/O性能权重
--cpu-shares=0  允许容器使用CPU资源的相对权重,默认一个容器能用满一个核的CPU
--cap-add=[ ]   增加容器的linux指定安全能力
--cap-drop=[ ]  移除容器的linux指定安全能力
--cgroup-parent=""  容器cgroups限制的创建路径
--cidfile=""    指定容器的进程ID号写到文件
--cpu-period=0  限制容器在CFS调度器下的CPU占用时间片
--cpuset-cpus=""    限制容器能使用哪些CPU核心
--cpuset-mems=""    NUMA架构下使用哪些核心的内存
--device-read-bps=[ ]   挂载设备的读吞吐率(以bps为单位)限制
--device-write-bps=[ ]  挂载设备的写吞吐率(以bps为单位)限制
--device-read-iops=[ ]  挂载设备的读速率(以每秒i/o次数为单位)限制
--device-write-iops=[ ] 挂载设备的写速率(以每秒i/o次数为单位)限制
--kernel-memory=""  限制容器使用内核的内存大小,单位可以是b,k,m或g
-m,--memory=""  限制容器内应用使用的内存,单位可以是b、k、m或g
--memory-reservation="" 当系统中内存过低时,容器会被强制限制内存到给定值,默认情况下等于内存限制值
--memory-swap="LIMIT"   限制容器使用内存和交换区的总大小
--oom-kill-disable=true|false   内存耗尽(out-of-memory)时是否杀死容器
--oom-score-adj=""  调整容器的内存耗尽参数
--pids-limit="" 限制容器的pid个数
--privileged=true|false 是否给容器以高权限,这意味着容器内应用将不受权限下限制,一般不推荐
--read-only=true|false  是否让容器内的文件系统只读
--security-opt=[ ]  指定一些安全参数,包括权限、安全能力、apparmor等
--stop-signal=STGTERM   指定停止容器的系统信号
--shm-size=""   /dev/shm的大小
--sig-proxy=true|false  是否代理收到的信号给应用,默认为true,不能代理SIGCHLD、SIGSTOP和SIGKILL信号
--memory-swappiness="0-100" 调整容器的内存交换区参数
-u,--user=""    指定在容器内执行命令的用户信息
--ulimit=[ ]    通过ulimit来限制最大文件数、最大进程数等

其他比较重要的选项还包括:
·-l,--label=[]:以键值对方式指定容器的标签信息;
·--label-file=[]:从文件中读取标签信息。
启动容器
使用docker start命令来启动一个已经创建的容器:
docker start 容器ID       //开启容器
docker stop 容器ID       //关闭容器

docker容器的状态:
up   开启状态
Exited    终止状态
Create    创建状态
(Paused)   暂停状态
状态没有        停止状态

docker pause/unpause centos/httpd    //暂停docker容器
docker stop  centos/httpd      //停止指定docker容器
新建并启动容器
除了创建容器后通过start命令来启动,也可以直接新建并启动容器。所需要的命令主要为docker run,等价于先执行docker create命令,再执行docker start命令。

docker run centos/lamp /bin/bash -c ls / 
//创建容器的同时启动并运行相关程序,命令完成容器就停止。

启动一个bash终端,允许用户进行交互:
docker run -it ubuntu:14.04 /bin/bash

root@af8bae53bdd3:/#

其中,-t选项让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上,-i则让容器的标准输入保持打开。

更多的命令选项可以通过man docker-run命令来查看。在交互模式下,用户可以通过所创建的终端来输入命令。

守护态运行
更多的时候,需要让Docker容器在后台以守护态(Daemonized)形式运行。此时,可以通过添加-d参数来实现。

下面的命令会在后台运行容器:
docker run -d ubuntu  /bin/sh -c "while true; do echo hello world; sleep 1; done"

进入运行中的容器中,对容器做各种操作:
docker exec -it 容器id  /bin/bash    进入容器中
退出方法:
1、输入exit
2、Ctrl+p, Ctrl+q键返回主机控制台

连接到容器的会话
docker attach 容器id号

//将容器导出成文件
docker export 13198d132fbe > centoslamp
将指定容器导出成名为centoslamp的文件,该文件为docker镜像文件

//将容器文件生成镜像
docker import  文件名  镜像名:标签

//删除容器
docker rm d4e863a654aa  指定删除某个容器
docker rm -f d4e863a654aa  
强制删除运行中的容器,不建议
docker container prune   删除所有停止的容器
docker rm $(docker ps -qf status=exited)    删除指定状态的容器
扩展:
硬件资源相关
1、 显示容器硬件资源使用情况
docker stats [选项] [0个或多个正在运行容器]
docker stats          不指定容器时显示所有正在运行的容器

2、更新容器的硬件资源限制
docker update [选项]
有可能报错:
vi   /etc/default/grub
GRUB_CMDLINE_LINUX="...   cgroup_enable=memory swapaccount=1"

3、使用压力测试工具 stress 验证效果
使用已有的stress镜像 progrium/stress, 开两个终端, 在一个终端中执行下面命令
docker run -m 100m --rm -it progrium/stress --cpu 2 --io 1 --vm 10 --vm-bytes 9M

在另一个终端执行 docker stats 进行监控
再开一个终端执行

9eb0为容器id开头, 请根据实际情况替换。内存限制只能调大不能调小
docker update -m 200m 9eb0

小结:

容器操作:
创建:docker create -it 镜像名(ID) /bin/bash
启动容器: docker start 容器名(ID)
停止容器:docker stop 容器名(ID)
暂停:docker pause 容器名(ID)
取消暂停:docker unpause 容器名(ID)
删除:docker rm -f 容器名(ID)
删除所有停止的容器:docker container prune
查看容器详细信息:docker inspect 容器id
查看容器列表:docker ps -a
创建并运行:docker run -itd 镜像id /bin/bash
将容器存入文件:docker export 容器id > 文件名
将容器文件导入镜像:docker import 文件名 镜像名: 标签

docker网络:

docker 网络覆盖范围可分为:单个host上的容器网络和跨多个host的网络
docker 安装时会自动在host上创建三个网络,可以使用docker network ls查看到  none 、host、bridge
此外还有另外两种方式
1、none网络
在这个网络下只有容器的lo网卡,在创建容器时可以使用--network=none指定使用none网络

正常不指定网络的情况下:
eth0    inet  addr:172.17.0.7

指定网络为none的情况下:
docker  run  -it  --network=none  --name  network1    busybox
只有一个lo网卡
一般来讲,这个封闭的网络有什么用处呢?
可用于一些安全性较高的并且不需要联网的应用可以使用none网络,比如:某个容器唯一用途就是生成随机密码,就可以放到none网络中避免密码被窃取;但是大部分容器是需要网络的
2、host网络:
连接到host网络的容器共享docker host的网络栈,容器的网络配置与host完全一致,可以通过--network=host指定host网络
docker  run  -it  --network=host  --name  network2    busybox

在容器中可以看到真机的所有网卡,并且连hostname也是真机的
host网络的使用场景是什么呢?
host网络的最大好处就是:性能;
如果容器对网络传输效率要求较高,则可以选择host网络。
但是host网络也有缺点:灵活性不高,比如:要考虑多口灵活性的问题,docker host上已经使用的端口容器就不能使用了
doker host另一个用途就是:让容器可以直接配置host网络,比如:一些跨host的网络解决方案,本身也是以容器运行的,这些方案需要对网络进行配置,比如,iptables。
3、bridge网络:
容器默认使用的时bridge网络
docker安装时会创建一个 命令为docker0的linux bridge。如果不指定--network=,运行的容器会默认挂到docker0上
可以用“brctl   show”命令查看桥接的网卡

容器中“eth0”——》真机的 veth9cfd9f7
——桥接——》docker0  

注:interface一列就是容器的虚拟网卡,如果容器都处于关闭的状态,会没有网卡信息
需要docker在开启状态下才能看到接口网卡

如:看到interfaces一列是veth48a8eca
进入容器中可以看一下网卡的信息eth0

其实:eth0和veth48a8eca是一对veth pair。veth pair是一种成对出现的特殊网络设备,可以把他想像成由一根虚拟网线连起来的一对网卡,网卡的一头叫做:eth0@if315,另一头是veth48a8eca挂在了docker0上,其效果就是将eth0@if315挂在了docker0上

看到eth0@if315配置了172.17.0.2/16的ip,再运行一个容器,看看他的ip是否也是同样的

新运行的容器的IP由172.17.0.3顺延下去了,而不是一个独立的网段,而且都是172.17.0的网段的

为什么都是这个网段上面的呢?

可以通过docker network inspect bridge

看到网卡的配置信息:subnet是172.17.0.0/16,gateway是172.17.0.1,这个网管来自哪呢?

可以看到host主机上面的docker0的ip就是172.17.0.1,所以这个网管就是docker0
4、自定义网络:
通常默认的情况下使用的是docker的bridge的网络,用户也可以根据自己的业务需要,创建user-defined

docker 提供三种user-defined网络驱动:bridge,overlay,macvlan。

其中overlay和macvlan用于创建跨主机的网络

可以通过bridge驱动创建类似前面默认的bridge网络docker0

docker network create --driver bridge brnet1

通过brctl show看到我们新建的网络

新增加了一个网桥br-32a5cb322311 ,这里的32a5cb322311正好是新建的brnet1的容器ID

通过docker network inspect brnet1查看

可以看到新建的brnet1的subnet是172.18.0.0/16,网关是172.18.0.1,这里的172.18.0.0/16网段是docker自动分配的网段

也可以自己指定网段和网关:--subent和--gateway

docker   network  create  --driver  bridge  --subnet   192.168.2.0/24   --gateway  192.168.2.1  brnet2

容器要使用新的网络,需要在新建运行(docker run)的时候,通过--network=去指定

指定一个静态ip地址
可以通过--ip指定

docker  run -it  --network=brnet2  --ip   192.168.2.222   busybox

注:只有通过--subnet创建的网络才能指定静态IP。

最好不要将容器设置成与host相同网段的,否则host的主机将被干扰,当然如果收到了干扰也不用怕,可以使用docker network rm <自己设置的bridge的名称>  将这个bridge删除

小结:

使用指定网络创建容器:
docker run -it --network bridge 镜像id /bin/bash
docker网络查看:
docker network ls
创建docker网络:
docker network create --driver=bridge 自定义的网络名称
创建docker网络并且自定义可分配的网段和网关:
docker network create --driver=bridge --subnet 192.168.80.0/24 --gateway 192.168.80.1 自定义的网络名称
使用指定网络创建容器并且分配一个静态IP地址:
docker run -it --network 网络名称(自定义) --ip 192.168.80.100 镜像名 /bin/bash
注意:静态IP地址只要自定义网段并且使用“--subnet”指定网段才能分配
查看docker网络的详细信息:
docker network inspect 网络名称
删除docker网络:
docker network rm 网络名称

端口映射:

1、容器访问外部网络
容器默认指定了网关为docker0网桥上的docker0内部接口。docker0内部接口同时也是宿主机的一个本地接口。因此,容器默认情况下是可以访问到宿主机本地的。更进一步,容器要想通过宿主机访问到外部网络,需要宿主机进行转发。 

# sysctl  net.ipv4.ip_forward    查看转发是否打开,1代表打开
net.ipv4.ip_forward = 1

如果为0,则没有开启转发,则需要手动打开:

# sysctl -w net.ipv4.ip_forward=1 

更简单的,在启动Docker服务的时候设定--ip-forward=true,Docker服务会自动打开宿主机系统的转发服务。
2、端口映射
容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 -P(大写) 或 -p (小写) 参数来指定端口映射。

1、当使用 -P 标记时,Docker 会随机映射一个 49000~49900 的端口到内部容器开放的网络端口
2、-p(小写)则可以指定要映射的IP和端口,但是在一个指定端口上只可以绑定一个容器。
支持的格式有 :真机Port:容器Port 

        hostPort:containerPort(映射所有接口地址)
        将本地的 5000 端口映射到容器的 5000 端口:
        docker run -d -p 5000:5000 training/webapp   /bin/bash
        此时默认会绑定本地所有接口上的所有地址。

        ip:hostPort:containerPort (映射指定地址的指定端口)
        指定映射使用一个特定地址,比如 localhost 地址 127.0.0.1
        docker run -d -p 127.0.0.1:5000:5000 training/webapp /bin/bash

        ip::containerPort (映射指定地址的任意端口)
        绑定 localhost 的任意端口到容器的 5000 端口,本地主机会自动分配一个端口。
        docker run -d -p 127.0.0.1::5000 training/webapp  /bin/bash
        还可以使用 udp 标记来指定 udp 端口
        docker run -d -p 127.0.0.1:5000:5000/udp training/webapp  /bin/bash

    查看映射端口配置
    使用 docker port 来查看当前映射的端口配置,也可以查看到绑定的地址
    docker  ps  -a
端口——>端口
注:
容器有自己的内部网络和 ip 地址(使用 docker inspect 可以获取所有的变量,Docker 还可以有一个可变的网络配置。)
    -p 标记可以多次使用来绑定多个端口
    例如:
    docker run -d -p 5000:5000 -p 3000:80 training/webapp  /bin/bash

容器互联:

1、必须两个容器处于同一网段,同时制定统一网络
2、DNS:只用自定义的网络并且自定义的网段才能使用dns

如何让两个不同的网段之间能够ping通

1.增加路由:
如果host上对每个网络都有一个路由,同时操作系统上打开了ip forwarding,host就成了一个路由,挂在不同的网桥上的网络就能够互相ping通
可以看一下host上是否满足这个条件
ip r查看host上的路由表
打开路由转发功能
centos7版本:
vi   /etc/sysctl.conf
net.ipv4.ip_forward = 1

centos  6版本:
echo  1  >  /proc/sys/net/ipv4/ip_forward
sysctl  -p

cat   /proc/sys/net/ipv4/ip_forward      看是不是1

但是iptables DROP 掉了网桥 docker0 与 br-5d863e9f78b6 之间双向的流量。 
从规则的命名 DOCKER-ISOLATION 可知 docker 在设计上就是要隔离不同的 netwrok。 
2、通过docker另外的增加网卡的办法来解决:
使用docker network connect给容器增加一块新的网卡   
docker  network   connect  brnet2   --ip  192.168.2.22   容器ID
通过docker network connect 这个命令给容器添加网卡eth1,并让这个网卡使用另外的bridge,现在不同bridge之间的容器建可以进行通信