Docker

 

Docker

 

 

 

Docker历史

 

在容器技术出来之前,我们都是使用虚拟机技术

vm :(笨重,启动分钟级)Docker(轻巧,启动秒级)

2010年,几个搞IT的年轻人,在美国成立了一家公司dotCloud,做一些pass的云计算服务、LXC有关的容器技术,他们将自己的技术(容器化技术)命名为 : Docker

Docker刚诞生的时候,并没有引起行业的注意,面临着 "活不下去"的问题

决定开源

2013年,Docker开源

开源以后越来越多的人发现了docker的优点 >>> 火了 >>> Docker每个月都会更新一个版本

2014年4月 Docker1.0发布

 

前戏

 

run的运行流程图

 

 

 

底层原理

 

Docker是一个Client - Server结构的系统,Docker的守护进程运行在主机上,通过Socket从客户端访问

DockerServer接收到Docker - Client的指令,就会执行这个命令

 

 

 

 

 

 

 

 

 

 

1 Docker的三大核心概念

 

1 容器(Container)  : 容器是对外提供服务的入口

2 镜像(Image)     : 镜像是启动容器的模板

3 仓库(Repository) : 存放镜像的仓库

 

2 在CentOS中安装docker

 

1 删除老版本中的dockers残留
    yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engine
    
2 更换源
    2.1 cp /etc/yum.repos.d/CentOS-Base.repo/etc/yum.repos.d/CentOS-Base.repo.bak
    
    2.2 curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
    
3 建立yum源缓存
    yum makecache
    
4 更新操作系统
    yum update -y --exclud=kernel*
    
5 安装基础软件
    yum install -y yum-utils device-mapper-persistent-data lvm2
    
6 安装docker yum源
    yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
    
7 安装docker
    7.1 yum makecache fast
    
    7.2 yum -y install docker-ce
    
8 启动docker
    systemctl start docker
    
9 验证docker
    docker run -p 8080:80 -d nginx
    (测试能通过8080端口访问服务器即为成功)

 

 

 

 

3 镜像(Image)

 

# 镜像是什么
    镜像是一种轻量级、可执行的独立软件包,用来打包软件运行环境和基于环境开发的软件,它包含运行某个软件所需的所有内容,包括代码、运行时、库、环境变量和配置文件
​
    所有的应用,直接打包docker镜像,就可以直接跑起来
​
# docker镜像 : 启动容器的模板,镜像一般情况下定义的是容器启动的服务
​
1 获取镜像
    docker pull 获取的镜像名称
    
2 公共的仓库(dockerHub官方、阿里云镜像仓库、华为云镜像仓库、腾讯云镜像仓库)
    registry.cn-hangzhou.aliyuncs.com/alvinos/docsfiy:v2
​
    镜像仓库 : registry.cn-hangzhou.aliyuncs.com(默认:docker.io)
    命名空间 : alvinos(默认:library)
    仓库名称 : docsfiy
    版本号   : v2(默认: latest)
       
3 私有的仓库(Harbor)
    登录仓库 : docker login 仓库url(默认docker.io)
​
4 版本镜像号(tag)
    docker tag 原来的tag 新的tag
    
5 获取当前系统上所有的docker镜像
    docker images 或 docker image ls
        参数
        -a : 列出系统中所有的临时镜像
        --digests=true : 列出系统中所有镜像的数字摘要值
        -q : 仅显示镜像id
        
6 上传镜像
    6.1 创建阿里云仓库
    6.2 登录阿里云仓库
        docker login
    6.3 修改镜像名称
        docker tag
    6.4 上传镜像
        docker push 镜像tag
​
7 查看镜像详细信息
    docker inspect 镜像名称或id
        参数
        -f : 获取镜像部分详细信息
        
8 删除镜像
    docker rmi 镜像名称或id
        参数
        -f : 强制删除镜像
​
9 清空机器上所有镜像
    docker rmi $(docker images -q)
​
10 部署一个Django
    10.1 拉取镜像
        docker pull 镜像名称(alvinos/django:v3)
    10.2 启动
        docker run -d -p 80:80 alvinos/django:v3
    10.3 关闭服务
        docker stop 容器名称

 

 

 

 

4 容器(Container)

 

# 容器的本质是进程
​
1 运行一个容器
​
前提:
    docker容器启动的前提 : 至少有一个应用进程运行在前台
    
    格式
        docker run 参数 镜像名称/id 启动容器执行的命令
        
    启动命令    : 不指定则执行默认的启动命令
    镜像名称/id : 可以使用镜像名称,也可以使用镜像id
    
    ps : docker create + docker start = docker run
    
启动流程
    1.1 检查本地是否存在需要被使用的镜像,如果有则直接使用,没有则去公网下载
    
    1.2 根据镜像创建容器
    
    参数
        -d     : 以守护进程方式运行
        -p     : (固定)端口映射
        -P     : (随机)端口映射
        -i     : 打开标准输出
        -t     : 创建一个终端     (it通常一起使用)
        -v     : 将宿主主机上的目录映射到容器中
        --rm   : 当容器的生命周期结束时立即删除容器
        --name : 将容器自定义一个容器名称,将容器的名称加入DNS解析
        -e     : 设置容器内部的环境变量
        -h     : 设置容器内部的主机名
        
2 展示docker容器列表
​
    docker ps   (默认情况下展示当前系统上所有正在运行的容器)
    
    CONTAINER ID : 容器ID
    IMAGE        : 镜像ID|镜像名称
    COMMAND      : 容器启动执行的命令
    CREATED      : 创建距离现在的时间
    STATUS       : 状态
    PORTS        : 端口信息
    NAMES        : 容器的名称
    
    参数
        -a : 展示所有的容器
        -q : 仅展示容器的id
        
3 删除容器
    
    格式
        docker rm 容器的名称/id
        
    参数
        -f : 强制删除
        
    ps : docker rm -f $(docker ps -a -q)    (清空所有容器)
    
4 创建容器
​
    docker create
    
5 启动容器
​
    docker start
    
6 进入容器
    
    6.1 attach
        建立一个宿主主机到容器中pid为1的进程上的一个管道,但是一旦attach断开链接,docker容器随即退出
        
    6.2 exec(推荐)
        使用其可以在宿主主机上执行一个容器内部的命令
        docker exec -it relaxed_bhabha bash
        
    6.3 nsenter
        建立一个宿主主机和容器之间的一个管道
        nsenter --target $( docker inspect -f {{.State.Pid}} elegant_margulis ) --mount --uts --ipc --net --pid
        
    6.4 ssh(不推荐)
    
ps : 添加数据库用户
    
    # 创建用户并授权
GRANT ALL PRIVILEGES ON *.* TO 'username'@'%' IDENTIFIED BY 'password' WITH GRANT OPTION;   
​
    # 刷新权限
FLUSH PRIVILEGES;
​
7 容器和镜像的导出和导入
​
    7.1 export和import(针对的是容器)
    
        格式
            docker export -o 打包的文件名 容器id或名称
            docker export -o django.tar elegant_margulis
            
            docker import 文件名 镜像名及版本号
            docker import django.tar django:v1
            
    7.2 save和load(针对的是镜像)
    
        格式
            docker save -o 打包的文件名 镜像名称及版本号
            docker save > 打包的文件名 镜像名称及版本号
            docker save -o python.tar:3.6.8 alvinos/django:v3
            
            docker load < 打包的文件名
            docker load < python.tar
            
    7.3 import及export 和 save及load之间的区别
        
        7.3.1 import可以自定义镜像名称,load不可以
        
        7.3.2 save可以同时保存多个镜像,export不可以同时保存多个容器
        
        7.3.3 save保存的镜像大小要大于export保存的镜像大小
        
        7.3.4 两者之间不能互相导入
        
8 容器复制
​
    8.1 将文件复制到容器内
        docker cp 宿主主机文件路径 容器名称或id:容器内路径
        
    8.2 将容器文件复制到宿主主机
        docker cp 容器名称或id:容器内路径 宿主主机文件路径

 

 

 

 

5 Linux网络

 

5.1 网络名称空间

 

 

 

 

 

 

 

 

5.2 Veth设备

  引入Veth设备是为了在不同的网络名称空间之间进行通信,利用它可以直接将两个网络名称空间连接起来
    由于要连接的两个网络命名空间,所以Veth设备是成对出现的,很像一对以太网卡,并且中间有一根直连的'网线'
    我们将其中一端称为另一端的peer
    在Veth设备的一端发送数据时,它会将数据直接发送到另一端,并触发另一端的接收操作
    
    # 总结
    两个虚拟网卡组成的数据通道,在Docker中,用于连接Docker容器和Linux Bridge,一端在容器中作为eth0网卡,另一端在Linux Bridge中作为网桥的一个端口

 

 

 

 

 

 

 

 

5.3 常用命令

# 创建一个命名空间
    ip netns add test01
    
# 查看创建过的命名空间
    ip netns list
​
# 创建Veth设备对
    ip link add veth type peer name veth001
    
# 将Veth设备分发至test01命名空间
    ip link set veth001 netns test01
    
# 将test01中的veth001分配ip
    ip netns exec test01 ip addr 172.16.0.111/20 dev veth001
    
    ip addr add 172.16.0.112/20 dev veth
    
# 重启veth设备对
    ip netns exec test01 ip link set dev veth001 up/down
    
# 总结:
    可想象成创建veth设备对(对象双方互相结识),给其中一个veth设备分发至其他命名空间(异地恋),给veth设备对分配ip(给双方各配一部手机并插上手机卡(拥有各自的电话号码)),重启veth设备对(手机重启) ---> 达成互通(通过手机相互联系)

 

 

 

 

6 Docker网络模式

 

Docker使用Linux桥接的方式,在宿主机虚拟一个Docker容器网桥(docker0)

Docker启动一个容器时都会根据Docker网桥的网段分配给一个容器一个IP地址,称为Container-IP,同时Docker网桥是每个容器的默认网关,因为在同一宿主机内的容器都接入同一个网桥,这样容器之间就能够通过容器的Container-IP直接通信

Docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻找到的,这也意味着外部网络无法直接通过Container-IP访问到容器

如果容器希望外部能够访问到,可以通过映射容器端口到宿主主机(端口映射),即docker run 运行容器时使用 -p 或 -P 参数,访问容器的时候就通过宿主机IP:容器端口访问容器

 

1 HOST模式(网络隔离性不好)
​
    # 使用host模式的容器可以直接使用宿主机的IP地址与外界通信(不需要自己映射端口),容器内部的服务端口也可以使用宿主机的端口,host最大的优势就是网络性能比较好,但docker host上已经使用的端口就不能再用了,网络的隔离性不好
    
    # 使用宿主主机的网卡
    docker run --network host 镜像名称或id
    
2 Container模式(共享指定容器的网络)
​
    # 这个模式指定新创建的容器和已经存在的一个容器共享一个Network Namespace(网络名称空间),而不是和宿主机共享,新创建的容器不会创建自己的网卡、配置自己的IP,而是和一个指定的容器共享IP、端口范围等,同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的,两个容器的进程可以通过lo网卡设备通信
    
    # 共享一个容器的网络
    docker run -d --network "container:共享容器的名称" nginx
    
3 None模式(封闭的网络能很好的保证容器的安全性)
​
    # 使用None模式,Docker容器拥有自己的Network Namespace,但是,并不为Docker容器进行任何网络配置,也就是说,这个Docker容器没有网卡、IP、路由等信息,需要我们自己为Docker容器添加网卡、配置IP等
    
    # 这种网络模式下容器只有lo回环网络,没有其他网卡,None模式可以在容器创建时通过--network=none来指定,这种类型的网络没有办法联网,封闭的网络能很好的保证容器的安全性
    
    # 不为容器提供任何网络
    docker run -d --network none centos
    
4 网桥(bridge模式(默认))
​
    # 当Docker进程启动时,会在主机上创建一个名为docker0的虚拟网桥,此主机上启动的Docker容器会连接到这个虚拟网桥上,虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中
    
    # 从docker0子网中分配一个IP给容器使用,并设置docker0的IP地址为容器的默认网关,在主机上创建一对虚拟网卡veth设备对,Docker将veth设备对的一端放在新创建的容器中,并命名为eth0(容器的网卡),另一端放在主机中,以vethXXX这样类似的名字命名,并将这个网络设备加入到docker0网桥中,可以通过brctl show命令查看
    
    # 将多个容器使用docker网桥进行地址转换的方式实现网络互通
    
    4.1 创建网桥
        docker network create chenyang
        
    4.2 查看网桥
        docker network ls
        
    4.3 使用网桥
        docker run -d --network chenyang nginx

 

 

 

6.1 Docker network

 

1 展示当前主机上的网桥列表
    docker network ls
    
2 创建网桥
    docker network create
    
    参数
        -d        : 指定网桥的类型
        --gateway : 指定网关
        --subnet  : 指定子网
        
3 查看网桥的详细信息
    docker network inspect 网桥名称或id
    
4 删除网桥
    docker network rm
    
5 清空自创的且空闲的网桥
    docker network prune -f
    
6 连接上一个网桥
    docker network connect 参数 网桥名称 容器名称
    
7 断开链接
    docker network disconnect 参数 网桥名称 容器名称
    
8 连接上一个容器
    docker run --link "连接的容器名称:连接别名"
    docker run --link "nginx:nginx" -it centos bash
    (相当于两个容器连上了,不用link的话,两个容器相连要知道容器端口号)

 

 

 

 

7 构建镜像

 7.1 构建镜像的特征

7.1.1 需要基础环境
    7.1.2 可执行命令
    7.1.3 启动命令
    
7.2 Dockerfile
​
    7.2.1 Dockerfile命名:Dockerfile
    7.2.2 Dockerfile是由指令组成(Dockerfile指令必须大写)
    7.2.3 实现基础环境 : FROM
    7.2.4 可执行命令 : RUN
    7.2.5 启动命令(指定命令必须运行在前台) : CMD
    7.2.6 开始构建 : docker build -t 镜像名称
    7.2.7 禁止构建使用缓存 : --no-cache
    
7.3 Dockerfile指令
    
    FROM    : 指定基础镜像
    RUN     : 执行一个命令
    CMD     : 设置一个启动命令
    WORKDIR : 设置工作目录
    ADD     : 添加文件到镜像
    COPY    : 复制文件到镜像
    EXPOSE  : 指定与外界交互的端口
    ENV     : 设置容器内默认的环境变量
VOLUME : 指定存储卷
ARG : 指定运行时的变量
ONBUILD : 触发器(当当前镜像作为基础镜像时执行)
7.4 ADD和COPY之间的区别
​
    7.4.1 ADD支持解压(tar类型的压缩包),COPY不支持
    7.4.2 ADD支持网络下载(不支持解压),COPY不支持
    7.4.3 ADD和COPY : 当镜像中目录不存在时,需要加/结尾,当镜像中目录存在时,则没有区别
    
ps : 部署mysql数据库时(注意添加环境变量-e MYSQL_DATABASE)

 

 

8 帮助命令

docker version      # 显示docker的版本信息
docker info         # 显示docker的系统信息,包括镜像和容器的数量
docker 命令 --help   # 帮助命令
# 帮助文档的地址:  https://docs.docker.com/reference/
 

 

posted @ 2021-06-25 11:26  Jerry`  阅读(75)  评论(0编辑  收藏  举报