作者: iuu

Docker网络的学习

  • 用户是使用Docker Client与 Docker Daemon建立通信,并发送请求给后者
  • Docker Daemon作为Docker架构中主体部分,首先提供Docker Server的功能使其可以接受Docker Client的请求
  • Docker Engine执行Docker内部的一系列工作,每一项工作都是以Job的形式存在
  • Job的运行过程中,当需要容器镜像时则从Docker Registry中下载镜像,并通过镜像管理驱动Graph driver将下载镜像以Graph的形式存储
  • 当需要为Docker创建网络环境时,通过网络管理驱动Network driver 创建并配置Docker容器网络环境
  • 当需要限制Docker容器运行资源或执行用户指令等操作时,则通过Exec driver来完成
  • Libcontainer是一项独立的容器管理包,Network driver以及Exec driver都是通过Libcontainer来实现具体对容器进行的操作

操作系统本身网络

  • 桥接模式 - 直接连接物理网络
  • NAT模式 - 用于共享主机的IP地址
  • 仅主机模式 - 与主机共享的专用网络
  • 用户自定义模式 - 特定的虚拟网络

docker 不启动 默认网络情况

docker 启动后 网络情况
docker 启动后会产生一个名为docker0的虚拟网桥

ifconfig
docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:e9ff:fee5:668a  prefixlen 64  scopeid 0x20<link>
        ether 02:42:e9:e5:66:8a  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 3  bytes 266 (266.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

Docker 网络的常用命令

默认创建3大网络模式
bridge 网桥模式
host  主机网络
none 无网络
还有两种:
容器模式
自定义模式
共计5种

docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
f14cce59440e   bridge    bridge    local
b171456906be   host      host      local
73342418fb83   none      null      local

查看命令帮助
docker network --help 
创建网络
docker network create a_network
删除网络 
docker network rm a_network
查看网络数据源
docker network inspect bridge

Docker 网络能干啥

容器间的互联和通信以及端口映射
容器IP变动的时候可以通过服务名直接网络通信而不收到影响

Docker 网络模式

默认三大网络模式 共计5种
bridge 网桥模式
host 主机网络
none 无网络
容器模式
自定义模式

bridge

为每个容器分配、设置IP等,并将容器连接到一个docker0的虚拟网桥,默认为该模式
bridge模式:使用--network bridge 指定,默认使用docker0

host

容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口
host模式:使用--network host 指定

none

容器有独立的Network namespace,但并没有对其进行任何网络设置,如分配veth pair和网桥连接,IP等
none模式:使用--network none指定

container

新创建的容器不会创建自己的网卡和配置自己的IP,而是和一个指定的容器共享IP、端口范围等。
container模式:使用--network container:NAME或者容器ID指定

自定义模式

Docker虚悬镜像

虚悬镜像就是仓库名、标签都是的镜像,俗称dangling image
查看系统的虚悬镜像

docker image ls -f dangling=true

虚悬镜像已经失去存在价值,可以删除

docker image prune

Dockerfile的基础学习

DockerFile

DockerFile是用来构建Docker镜像的文本文件,是由一条条构建镜像所需要的指令和参数构成的脚本。

https://docs.docker.com/reference/dockerfile/

构建三步骤

  • 1、编写Dockerfile文件
  • 2、docker build 命令构建镜像
  • 3、docker run 依照新生成的镜像运行容器实例

Dockerfile基础知识

  • 1、每条保留字指令都必须为大写字母 且后边要跟随至少一个参数
  • 2、指令从上到下顺序执行
  • 3、#表示注视
  • 4、每条指令都会创建一个新的镜像层并对镜像进行提交

Docker执行Dockerfile的大致流程

  • 1、docker从基础镜像运行一个容器
  • 2、执行一条指令 并对容器作出修改
  • 3、执行类似docker commit的操作提交一个新的镜像层
  • 4、docker再基于刚提交的镜像运行一个新容器
  • 5、执行dockerfile中的下一条指令 一直到所有指令都执行完成

从应用软件的角度来看Dockerfile Docker镜像与Docker容器分别代表软件的三个不同阶段,Dockerfile是软件的原材料,Docker镜像是软件的交付品,Docker容器则可以认为是软件镜像的运行状态,即是依照镜像运行的容器实例。

Dockerfile面向开发,Docker镜像成为交付标准,Docker容器则涉及部署与运维,三者缺一不可。

1、Dockerfile定义了程序需要的一切东西。包括执行代码或文件,环境变量、依赖包、运行时环境、动态链接库、操作系统的发行版、服务进程和内核进程(当应用进程需要和系统服务和内核进程打交道,这时需要考虑如何设计namespace的权限控制)等等
2、Docker镜像 在用Dockerfile定义过一个文件后,docker build 时会产生一个Docker镜像,当运行Docker镜像时会真正开始提供服务
3、Docker容器 容器是直接提供服务的。

Dockerfile常用保留字指令

FROM 继承的基础父镜像

RUN 容器构建时需要运行的命令
    两种格式 
      一种是shell格式 
      RUN 命令
      一种是exec格式
      RUN ['./test.php',"参数1","参数2"]
    RUN是在docker build 时运行

EXPOSE 当前容器对外暴露出的端口

WORKDIR 指定在创建容器后,终端默认登陆进来的工作目录,一个落脚点

USER 指定该镜像以什么样的用户去执行,如果都不指定,默认root用户

ENV 用来在构建镜像过程中设置环境变量,这个环境变量可以在后续的任何RUN指令中使用,也可以在其他指令中直接使用这些环境变量

VOLUME 容器数据卷,用于数据保存和持久化工作

ADD 将宿主机目录下的文件拷贝进镜像且会自动处理URL和解压tar压缩包

COPY 类似ADD 拷贝文件和目录到镜像中
     将从构建上下文目录中<源路径>的文件/目录复制到新的一层镜像内的<目标路径>位置
     COPY src dest
     COPY ['src','dest']
     目标路径是容器内的指定路径 该路径不哦那个事先建好

CMD 指定容器启动后要干的事情
    Dockerfile中可以有多个CMD指令,但只有最后一个生效,CMD会被docker run之后的参数替换
    他跟RUN命令的区别
    CMD是在docker run时运行
    RUN是在docker build时运行

ENTRYPOINT 也是用来指定一个容器启动时要运行的命令
    类似于CMD指令,但是ENTRYPOINT不会被docker run后边的命令覆盖,而且这些命令行参数会被当作参数发送给ENTRYPOINT指令指定的程序
    注意 ENTRYPOINT可以和CMD一起用,一般是变参才会使用CMD 这里的CMD是等于在给 ENTRYPOINT传递参数。当指定了 ENTRYPOINT 后 CMD的含义就发生了变化,不再是直接运行命令,而是将CMD的内容作为参数传递给ENTRYPOINT指令,他们两个组合会变成 <ENTRYPOINT><CMD>
    优点
    案例:
    定义nginx:test镜像
    FROM nginx

    ENTRYPOINT ["nginx","-c"] # 定参
    CMD ["/etc/nginx/nginx.conf"] # 变参
docker run nginx:test docker run nginx:test -c /new.conf
nginx -c /etc/nginx/nginx.conf nginx -c /new.conf

构建

docker build -t 新镜像名字:TAG .

Docker的基础学习(三)

容器数据卷

用于完成数据的持久化,重要资料的备份存储,就是主机的目录和容器内的目录进行映射,将容器内的数据备份+持久化到本地主机目录。
坑:容器卷记得加入参数 --privileged=true
Docker挂载主机目录访问如果出现 cannot open directory.:Permission denied
解决办法:在挂载目录后多加一个 --privileged=true 参数即可
why

如果是在CentOS7安全模块会比之前系统版本加强,不安全的会先禁止,所以目录挂载的情况被默认为不安全的行为,在SELinux里边挂在挂载目录被禁止,如果要开启,我们一般使用--privileged=true 命令。扩大容器的权限解决挂载目录没有权限的问题,也即使用该参数,容器内的root用户会拥有真正的root权限,否则容器内的root只是外部的一个普通用户的权限。

卷就是目录或文件,存在于一个或者多个容器中,由docker挂载到容器,但不属于联合文件系统,因此能够绕过UnionFileSystem提供一些用于持续存储或共享数据的特性。

卷的设计目的就是数据持久化,完全独立于容器的生存周期,因此Docker不会在容器删除时删除其挂载的数据卷。

Docker容器产生的数据,如果不备份,那么当容器实例删除之后,容器内的数据自然也就没有了。为了能保存数据 所以在docker中我们使用卷。

特点:

  • 1、数据卷可在容器之间共享或者重用数据
  • 2、卷中的更改可以直接实时生效
  • 3、数据卷中的更改不会包含在镜像的更新中
  • 4、数据卷的生命周期一直持续到没有容器使用它为止
docker run -v 本地宿主机路径:容器内部路径 --privileged=true
-v 添加自定义容器卷 可以多个
--privileged=true 放开权限

运行一个带有容器卷存储功能的容器实例
docker run -it --privileged=true -v 本地宿主机绝对路径:容器内部路径 镜像名
docker run -it --name=quan --privileged=true  -v /Users/iuu/Developer/docker/quan/:/home/ 192.168.1.8:5001/iuu_local_ubuntu /bin/bash 
============================
查看数据卷是否挂载成功
docker inspect  quan
输出如下信息
"Mounts": [
            {
                "Type": "bind",
                "Source": "/host_mnt/Users/iuu/Developer/docker/quan",
                "Destination": "/home",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],
============================

读写规则映射添加说明
读写 rw (默认)
docker run -it --privileged=true -v 本地宿主机绝对路径:容器内部路径:rw 镜像名

只读 ro 容器内部被限制只能读取不能写入 宿主机不受影响
docker run -it --privileged=true -v 本地宿主机绝对路径:容器内部路径:ro 镜像名

docker inspect  quan
输出如下信息
"Mounts": [
            {
                "Type": "bind",
                "Source": "/host_mnt/Users/iuu/Developer/docker/quan",
                "Destination": "/home",
                "Mode": "ro",
                "RW": false,
                "Propagation": "rprivate"
            }
        ],
============================
卷的继承和共享
--volumes-from 容器ID/容器名称 

容器quan3-ext-quan2继承容器quan2的卷 包含挂载目录 和权限都继承quan2的
docker run -it --name=quan3-ext-quan2 --privileged=true --volumes-from quan2   192.168.1.8:5001/iuu_local_ubuntu 

Docker的基础学习(二)

镜像分层概念

镜像是什么?

镜像 是一种轻量级、可执行的独立软件包,他包含运行某个软件所需要的所有内容,我们把应用程序和配置依赖打包好形成一个可交付的运行环境(包括代码、运行时需要的库、环境变量、配置文件等),这个打包好的运行环境就是image镜像文件。
只有通过这个镜像文件才能生成Docker容器实例

分层的镜像

镜像就像是一个蛋糕,一层一层堆叠出来的。
以pull命令为例子,在下载的过程中我们可以看到docker的镜像好像是在一层一层的下载。

iuu@iuudeMac-mini ~ % docker pull tomcat
Using default tag: latest
latest: Pulling from library/tomcat
94a23d3cb5be: Downloading [========>                                          ]   9.51MB/53.6MB
ac9d381bd1e9: Download complete 
aa9c5b49b9db: Download complete 
841dd868500b: Downloading [============================>                      ]  31.17MB/54.67MB
42dee876d816: Downloading [========================================>          ]  4.358MB/5.42MB
c4851c976ae9: Waiting 
e80a0433b650: Waiting 
e10afb8c99ce: Waiting 
7870523e466f: Waiting 

UnionFS(联合文件系统)

UnionFS文件系统是一种分层、轻量级并且高性能的文件系统,他支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下。Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。

特性:一次同时加载多个文件系统,但从外边来看,只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有底层的文件和目录

Docker镜像的加载原理

docker的镜像实际上由一层一层的文件系统组成,这种层级的文件系统就是UnionFS。
bootfs(boot file system)主要包含bootloader和kernel,bootloader主要是引导加载kernel,Linux刚启动时会加载bootfs文件系统,在Docker镜像的最底层是引导文件系统bootfs。这一层与我们典型的Linux/Unix系统是一样的,包含boot加载器和内核。当boot加载完成之后整个内核就都在内存中了,此时内存的使用权已由bootfs转交给内核,此时系统也会卸载bootfs。

rootfs(foot file system),在bootfs之上。包含的就是典型Linux系统中的/dev,/proc,/bin,/etc 等标准目录和文件。rootfs就是各种不同的操作系统发行版,比如Ubuntu,Centos等等。

对于一个精简的OS,rootfs可以很小,只需要包括最基本的命令、工具和程序库就可以了,因为底层直接用HOST的kernel,自己只需要提供rootfs就行了。由此可见对于不同的linux发行版,bootfs基本是一致的,rootfs会有差别,因此不同的发行版可以公用bootfs。

镜像分层最大的一个好处就是共享资源,方便复制迁移,就是为了复用。

比如说有多个镜像都从相同的base镜像构建而来,那么Docker Host只需在磁盘上保存一份base镜像;同时内存中也只需要加载一份base镜像,就可以为所有容器服务了。而镜像的每一层都可以被共享。

Docker镜像层都是只读的,容器层是可写的,当容器启动时,一个新的可写层被加载到镜像的顶部,这一层通常被称作容器层,容器层之下都叫做镜像层。

制作自己的镜像

docker commit 提交容器副本使之成为一个新的镜像
docker commit -m="备注" -a="作者" 容器ID/容器名 目标镜像名:[标签名 不写则为latest]

基于官方 ubuntu 创建一个容器
docker run -it --name=u02 ubuntu /bin/bash

ubuntu 安装 vim 命令
apt-get update
apt-get -y install vim

将现在的容器生成一个新的镜像
docker commit -m='新增vim命令' -a='iuu' u01 iuu/vim_ubuntu:1.0
docker commit -m='新增vim命令' -a='iuu' u01 vim_ubuntu:1.0
docker commit -m='新增vim命令' -a='iuu' 2d4263116d7f vim_ubuntu:1.0

使用生成的镜像
docker run --name=vim_ubuntu -it vim_ubuntu:1.0 /bin/bash
docker run --name=iuu_vim_ubuntu -it iuu/vim_ubuntu:1.0 /bin/bash

容器发布到阿里云/DockerHub

阿里云

容器镜像服务 创建命名空间 创建仓库

登陆
docker login --username=41760@qq.com registry.cn-hangzhou.aliyuncs.com

TAG
docker tag  镜像ID  registry.cn-hangzhou.aliyuncs.com/iuu_me/vim_ubuntu:[镜像版本号]

推送
docker push registry.cn-hangzhou.aliyuncs.com/iuu_me/vim_ubuntu:[镜像版本号]

拉取
docker pull registry.cn-hangzhou.aliyuncs.com/iuu_me/vim_ubuntu:1.0

DockerHub

登陆网站 创建仓库

命令行登陆
docker login

TAG
docker tag 镜像ID  DockerHub用户名/仓库名:镜像版本号
docker tag 2fad279b3143  jianchaodada/tree_ubuntu:1.0

推送
docker push jianchaodada/tree_ubuntu:1.0

案例 没带版本号 则默认用 latest
docker commit -m='删除无用文件' -a='iuu' aliyun  iuu_ubuntu 
docker tag 2fad279b3143  jianchaodada/iuu_ubuntu 
docker push jianchaodada/iuu_ubuntu  

Docker私有仓库

DockerRegistry是官方提供的工具,可以用于构建私有镜像仓库

下载DockerRegistry镜像
docker pull registry 
运行私服实例
docker run -d -p 5000:5000  --name=DockerRegistry   -v /Users/iuu/Developer/docker/DockerRegistry:/var/lib/registry --privileged=true registry
默认情况下仓库被创建在容器的 /var/lib/registry/ 目录下 建议用容器卷映射,方便与宿主机联调

案例:
在ubuntu镜像中安装ifconfig命令
apt-get update
apt-get install -y net-tools

ifconfig

基于容器生成镜像 上传到dockerhub
docker commit -m='安装ifconfig' -a='iuu' aliyun  iuu_ubuntu 
docker images 
docker tag 5e2a0179f0d8  jianchaodada/iuu_ubuntu
docker push jianchaodada/iuu_ubuntu  

curl验证私服库上有什么镜像
curl -XGET http://127.0.0.1:5001/v2/_catalog

修改配置文件让docker 支持http协议推送 默认不允许http协议推送 修改完重启docker 
修改 daemon.json 在配置加速地址的地方加: 
"insecure-registries":["192.168.1.8:5001"]

基于容器生成镜像 上传到私服
docker commit -m='安装ifconfig' -a='iuu' aliyun  iuu_local_ubuntu
docker tag 0f72c1a675f3 192.168.1.8:5001/iuu_local_ubuntu
docker push 192.168.1.8:5001/iuu_local_ubuntu
curl -XGET http://127.0.0.1:5001/v2/_catalog

拉取私服库里的镜像
docker pull 192.168.1.8:5001/iuu_local_ubuntu 
1 10 11 12 13 14 16