zoukankan      html  css  js  c++  java
  • Docker从入门到放弃

      为什么要学习 docker 呢?深有体会,由于一些原因只能在他人电脑上搭建环境,明明在自己电脑上的程序跑的好好的,在他人的电脑上就是死活出错。折磨人呀!!!!!可是能怎么办,工作还得继续,曲线救国呗,折腾了一天终于搞好了,那么以后呢?想到了之前搭建靶机时候用到的docker,时间长了也忘了,准备好好梳理学习入门一波。《十分感谢大神的文章,本文基于大神的文章学习整理。》

    一、入门基础

       Docker 使用 Google 公司推出的 Go 语言进行开发实现,基于 Linux 内核的 cgroup,namespace,以及 AUFS 类的 Union FS 等技术,对进程进行封装隔离,属于 操作系统层面的虚拟化技术。由于隔离的进程独立于宿主和其它的隔离的进程,因此也称其为容器。

    Docker架构

      热衷于 Ubuntu,后面的所有操作都是基于 Ubuntu的。

    1. 基本概念

      Docker的三大组件:镜像、容器、仓库

    1.1 镜像

      操作系统分为内核和用户空间,内核启动后会挂在root文件系统为用户控件提供支撑。

      Docker镜像就相当于一个root文件系统,但它是一个特殊的文件系统。提供了

    (1)容器运行时所需的程序、库、资源、配置等文件,
    (2)为运行时准备的一些配置参数(如匿名卷、环境变量、用户等)。
    

      镜像构建时,会一层层构建,前一层是后一层的基础。每一层构建完就不会再发生改变,后一层上的任何改变只发生在自己这一层。比如,删除前一层文件的操作,实际不是真的删除前一层的文件,而是仅在当前层标记为该文件已删除。

    1.2 容器

      镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的 类 和 实例 一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。

      容器的实质是进程,容器进程运行于属于自己的命名空间。容器可以拥有自己的root文件系统、网络配置、进程空间、自己的用户ID空间,是在一个隔离的环境里。

    1.3 仓库

      镜像构建完成后,可以很容易的在当前宿主机上运行,但是,如果需要在其它服务器上使用这个镜像,我们就需要一个集中的存储、分发镜像的服务,Docker Registry 就是这样的服务。一个 Docker Registry 中可以包含多个 仓库(Repository);每个仓库可以包含多个 标签(Tag);每个标签对应一个镜像。

      <仓库名>:<标签> 的格式来指定具体是这个软件哪个版本的镜像。仓库名经常以 两段式路径 形式出现,比如 jwilder/nginx-proxy。

    仓库服务分类为:

    Docker Registry 公开服务
    私有 Docker Registry
    

    2. Ubuntu安装Docker服务

    # 将apt源使用https以确保软件下载过程中不被篡改,添加使用HTTPS传输的软件包以及CA证书
    sudo apt-get install apt-transport-https ca-certificates curl software-properties-common
    
    # 为确保下载软件包的合法性,需要添加软件源的GPG秘钥
    curl -fsSL https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
    
    # 向 source.list 中添加 Docker软件源
    sudo add-apt-repository \
        "deb [arch=amd64] https://mirrors.ustc.edu.cn/docker-ce/linux/ubuntu \
        $(lsb_release -cs) \
        stable"
        
    # 更新Ubuntu源
    sudo apt-get update
    
    
    # 安装 Docker CE
    sudo apt-get install docker-ce
    
    # 使用脚本自动安装
    curl -fsSL get.docker.com -o get-docker.sh
    # 可以国内源进行安装
    sudo sh get-docker.sh --mirror Aliyun
    
    # 启动 Docker CE
    sudo systemctl enable docker
    sudo systemctl start docker
    
    # 建立 docker 用户组
    sudo groupadd docker
    # 将当前用户加入到 docker组中
    sudo usermod -aG docker $USER
    
    # 关闭当前Terminal重新连接Ubuntu
    
    # 测试Docker是否安装正确,执行命令,看到下面的输出就说明正确安装了
    docker run hello-word
    
    
    # 卸载旧版本的docker
    sudo apt-get remove docker docker-engine docker.io
    
    

    二、Docker使用

    1. 镜像操作

    1.1 获取镜像

    从下载过程中,我们可以看到docker的镜像是由多层存储所构成的,下载也是一层层的下载,下载过程中给出了没一层的ID的前12位,并且下载结束后,给出该镜像完整的sha256的摘要,以确保下载一致性。

    # 获取镜像格式
    docker pull [选项] [Docker Registry 地址[:端口号]/]仓库名[:标签]
    # 查看docker获取镜像帮助
    docker pull --help
    # 例如
    docker pull ubuntu:18.04
    
    
    # jenkins的下载过程
    docker pull jenkins
    Using default tag: latest
    latest: Pulling from library/jenkins
    55cbf04beb70: Pulling fs layer 
    55cbf04beb70: Downloading [=========>                                         ]  8.289MB/45.31MB
    9a8ea045c926: Pulling fs layer 
    d4eee24d4dac: Downloading [============>                                      ]  12.71MB/50.06MB
    c58988e753d7: Pulling fs layer 
    d4eee24d4dac: Downloading [==========>                                        ]  10.68MB/50.06MB
    70fcfa476f73: Download complete 
    0539c80a02be: Downloading  6.405MB
    54fefc6dcf80: Waiting 
    911bc90e47a8: Waiting 
    38430d93efed: Waiting 
    7e46ccda148a: Waiting 
    c0cbcb5ac747: Waiting 
    35ade7a86a8e: Waiting 
    aa433a6a56b1: Waiting 
    841c1dd38d62: Waiting 
    b865dcb08714: Waiting 
    5a3779030005: Waiting 
    12b47c68955c: Waiting 
    1322ea3e7bfd: Waiting
    # 下载安装完就会出现下面输出信息
    Digest: sha256:eeb4850eb65f2d92500e421b430ed1ec58a7ac909e91f518926e02473904f668
    Status: Downloaded newer image for jenkins:latest
    docker.io/library/jenkins:latest
    
    

    docker run的相关参数解释:

    # docker启动Jenkins服务
    sudo docker run -d -p 8099:8080 -v /opt/data/jenkins_home:/var/jenkins_home --name wjenkins jenkins:latest
    
    docker run -it --rm ubuntu:18.04 bash
    
    -it: -i,交互式操作;t,终端;
    -rm:容器退出后随之将其删除,避免浪费空间
    -d:是后台启用jenkins服务
    -p:端口映射
    --name:为容器命名
    ubuntu:18.04:指用 ubuntu:18.04 镜像为基础来启动容器
    bash:放在镜像后的是命令,可以创造一个交互式的shell
    -v:挂载数据 /opt/data/jenkins_home:/var/jenkins_home   映射 jenkins_home到本地/opt/data/jenkins_home目录。例如启动jenkins的初始密码,秘钥库等都从这里面找
    

    1.2 查看镜像

    # 查看docker中全部的镜像
    docker images
    # 查看docker中部分的镜像
    docker image ls jenkins
    REPOSITORY(仓库名)  TAG(版本)          IMAGE ID(镜像ID)    CREATED(创建时间)   SIZE(所占用空间)
    jenkins             latest              cd14cecfdb3a        17 months ago       696MB
    
    
    # 镜像体积
    # 查看镜像、容器、数据卷所占用的空间
    docker system df
    TYPE                TOTAL               ACTIVE              SIZE                RECLAIMABLE
    Images              2                   1                   695.7MB             695.7MB (99%)
    Containers          2                   0                   0B                  0B
    Local Volumes       0                   0                   0B                  0B
    Build Cache         0                   0                   0B                  0B
    
    
    # 虚悬镜像(dangling image)--- 目前没看到,也没看到有什么用
    # 查看虚悬镜像
    docker image ls -f dangling=true
    # 删除虚悬镜像
    docker image prune
    
    
    # 中间层镜像(为了加速镜像构建、重复利用资源,Docker 会利用 中间层镜像。所以在使用一段时间后,可能会看到一些依赖的中间层镜像)
    docker image ls -a
    
    
    # 以特定格式显示
    docker image ls --format "{{.ID}}: {{.Repository}}"
    fce289e99eb9: hello-world
    cd14cecfdb3a: jenkins
    
    
    # 以表格等距显示,并且有标题行
    docker image ls --format "table {{.ID}}\t{{.Repository}}\t{{.Tag}}"
    IMAGE ID            REPOSITORY          TAG
    fce289e99eb9        hello-world         latest
    cd14cecfdb3a        jenkins             latest
    
    docker image ls 列表中的镜像体积总和并非是所有镜像实际硬盘消耗。由于 Docker 镜像是多层存储结构,并且可以继承、复用,因此不同镜像可能会因为使用相同的基础镜像,从而拥有共同的层。
    

    1.3 删除镜像

    # 删除镜像格式
    docker image rm [选项] <镜像1> [<镜像2> ...]
    
    # docker中存在的镜像
    docker image ls
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    hello-world         latest              fce289e99eb9        12 months ago       1.84kB
    jenkins             latest              cd14cecfdb3a        17 months ago       696MB
    
    # 长ID删除
    docker image rm fce289e99eb9
    # 短ID删除,一般去长ID的前三位就能区分镜像
    docker image rm fce
    
    
    # 通过镜像名删除镜像
    docker image rm hello-world
    
    
    # 查看镜像摘要
    docker image ls --digests
    # 通过镜像摘要删除镜像
    docker image rm node@sha256:4fe721ccc2e8dc7362278a29dc660d833570ec2682f4e4194f4ee23e415e1064
    
    
    # docker image ls 命令来配合删除
    docker image rm $(docker image ls -q redis)
    
    

    2. 容器操作

    容器是独立运行的一个或一组应用,以及他们的运行态环境。

    2.1 启动

    启动容器的两种方式:

    1.基于镜像新建一个容器并启动:docker run,该命令的标准操作
        (1)检查本地是否存在指定的镜像,不存在就从公有仓库下载
        (2)利用镜像创建并启动一个容器
        (3)分配一个文件系统,并在制度的镜像层外爱你挂载一层可读写层
        (4)从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
        (5)从地址池配置一个IP地址给容器
        (6)执行用户指定的应用程序
        (7)执行完毕后容器被终止
    2.在终止状态的容器重启启动:docker container start
    
    # 新建并启动
    # 用ubuntu输出打印
    docker run ubuntu:18.04 /bin/echo "Hello Ubuntu"
    
    # 启动一个bash终端,允许用户交互
    docker run -t -i ubuntu /bin/bash
    
    
    # 启动已终止容器
    docker container start [容器的名称NAMES]
    

    2.2 守护态进行

    大多数是需要让docker在后台运行而不是直接把执行命令的结果输出在当前宿主机下。通过-d参数来实现。

    # 不加-d参数运行容器,容器回吧输出的结果(STDOUT)打印到宿主机上
    docker run ubuntu /bin/sh -c "while true; do echo hello world; sleep 1;done;"
    hello world
    hello world
    hello world
    ...
    
    
    # 加-d参数在后台运行
     docker run -d ubuntu /bin/sh -c "while true; do echo hello world; sleep 1;done;"
    014d585a42f3974814e8d00d3be17b0babeda887456c8539e1922bc5d749368f
    
    
    # 查看容器的信息docker container ls
    docker container ls 
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
    014d585a42f3        ubuntu              "/bin/sh -c 'while t…"   52 seconds ago      Up 47 seconds                           zealous_gauss
    
    
    
    # 查看容器后台打印的日志信息docker container logs [docker container -d后的那个ID]
    docker container logs 014d585a42f3974814e8d00d3be17b0babeda887456c8539e1922bc5d749368f
    hello world
    hello world
    hello world
    ...
    
    

    2.3 终止

    # 查看容器的运行状态
    docker container ls -a
    
    # 终止一个运行中的容器
    docker container stop [ID]
    
    # 启动一个容器
    docker container start [容器的名称NAMES]
    
    # 重新启动一个容器
    docker container restart [容器的名称NAMES]
    

    2.4 进入容器

    使用-d参数,容器启动后会进入后台。那么怎么进入容器操作呢?

    docker attch [ID或ID的前三位:docker container ls出的]
        exit 退出的时候回导致容器停止
    docker exec(推荐使用)
        -i -t: 可以使用熟悉的 Linux命令提示符
        exit 退出的时候不会使容器退出
    
    # 后台交互式启动ubuntu
    docker run -dit ubuntu
    5f7cbebeb2b97f8ac8de6a8b79e196dcd7583a37435781ef6669e9237ad9f39d
    
    
    # 查看容器的运行
    docker container ls
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    5f7cbebeb2b9        ubuntu              "/bin/bash"         39 seconds ago      Up 34 seconds                           hopeful_spence
    
    
    # docker exec 进入容器
     docker exec -it 5f7 bash
    root@5f7cbebeb2b9:/# 
    
    # docker attach J进入容器
    docker attach 57f bash
    
    

    2.5 导出和导入

    # 导出容器 docker export
     docker container ls -a
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                         PORTS               NAMES
    5f7cbebeb2b9        ubuntu              "/bin/bash"              3 minutes ago       Up 3 minutes                                       hopeful_spence
    docker export 5f7cbebeb2b9 > ubuntu.tar
    
    
    # 导入容器快照docker import
    cat ubuntu.tar | docker import - test/ubuntu:v1.0
    sha256:e27783b11623f2f56137ab8469963296d14545aac6607febe5e7d4c83a92c6f3
    # 通过执行的URL或者某个目录来导入
    docker import http://example.com/exampleimage.tgz example/imagerepo
    # 查看导入的容器
    docker image ls
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    test/ubuntu         v1.0                e27783b11623        10 seconds ago      64.2MB
    
    

    2.6 删除

    # 删除容器 docker container rm [容器的名字:通过docker contaniner ls 可以查看]
    ubuntu@VM-0-8-ubuntu:~$ docker container ls
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    5f7cbebeb2b9        ubuntu              "/bin/bash"         9 minutes ago       Up 9 minutes                            hopeful_spence
    ubuntu@VM-0-8-ubuntu:~$ docker container rm hopeful_spence
    Error response from daemon: You cannot remove a running container 5f7cbebeb2b97f8ac8de6a8b79e196dcd7583a37435781ef6669e9237ad9f39d. Stop the container before attempting removal or force remove
    ubuntu@VM-0-8-ubuntu:~$ docker container stop hopeful_spence
    hopeful_spence
    ubuntu@VM-0-8-ubuntu:~$ docker container rm hopeful_spence
    hopeful_spence
    
    
    # 清理所有处于终止状态的容器 docker container prune
    # 用 docker container ls -a 命令可以查看所有已经创建的包括终止状态的容器
    ubuntu@VM-0-8-ubuntu:~$ docker container ls -a
    CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                         PORTS               NAMES
    014d585a42f3        ubuntu              "/bin/sh -c 'while t…"   About an hour ago   Exited (0) 17 minutes ago                          zealous_gauss
    28ceff128046        ubuntu              "/bin/sh -c 'while t…"   About an hour ago   Exited (0) About an hour ago                       cocky_bohr
    9ae9bef2e2d5        ubuntu              "/bin/bash"              About an hour ago   Exited (0) About an hour ago                       trusting_tereshkova
    978423cea835        ubuntu              "/bin/echo 'Hello Ub…"   2 hours ago         Exited (0) 2 hours ago                             angry_bose
    0a73192e9dfd        hello-world         "/hello"                 2 hours ago         Exited (0) 2 hours ago                             eloquent_wilbur
    81f60b6062e3        hello-world         "/hello"                 26 hours ago        Exited (0) 26 hours ago                            elegant_almeida
    d9d4d77cbf25        hello-world         "/hello"                 2 days ago          Exited (0) 2 days ago                              condescending_easley
    ubuntu@VM-0-8-ubuntu:~$ docker container prune
    WARNING! This will remove all stopped containers.
    Are you sure you want to continue? [y/N] y
    Deleted Containers:
    014d585a42f3974814e8d00d3be17b0babeda887456c8539e1922bc5d749368f
    28ceff12804603c73d3516654b0b915a909053268529855e234d58ca7567663b
    9ae9bef2e2d56680a2056a7853fee9b87eb90186db9ff44823030f3266faf0b6
    978423cea83542f1120f8c27451107c2a00df48becbc2e99a62da977acd899f9
    0a73192e9dfdd6f4969cf50286fcd3bc36a6e00f2a14822d73dd85f62749c616
    81f60b6062e394ab3dc3e6e560e17522472a84cccf768865f88652b02af4a7d4
    d9d4d77cbf258ffcb2bf5d6375284bd303517bc3c5e69c60a17a29592023d439
    
    Total reclaimed space: 12B
    ubuntu@VM-0-8-ubuntu:~$ docker container ls -a
    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
    
    

    3.访问仓库

    仓库是集中存放镜像的地方。

    3.1 Docker Hub

    1.注册官方的docker账号:https://hub.docker.com

    2.登录docker login; 退出docker logout

    3.拉取镜像:docker search ubuntu

    4.拉取镜像:docker pull ubuntu

    5.推送镜像:docker push 自己的镜像

    docker tag ubuntu:18.04 username/ubuntu:18.04

    docker image ls

    docker push username/ubuntu:18.04

    docker search username

    3.2 私有仓库

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

    # 获取官方register镜像来运行
    docker run -d -p 5000:5000 --restart=always --name registry registry
    
    # 启动私有仓库
    # -v参数来将镜像文件存在本地的指定路径
    docker run -d -p 5000:5000 -v /opt/data/registry:/var/lib/registry registry
    
    # 然后和共有仓的操作就一样了
    
    # 但是Registry 创建的仓库面临一些维护问题。比如某些镜像删除以后空间默认是不会回收的,需要一些命令去回收空间然后重启 Registry 程序。Nexus可以很好解决这个问题
    # 启动 Nexus 容器
    # 第一次启动 Nexus 的默认帐号是 admin 密码是 admin123 登录以后点击页面上方的齿轮按钮进行设置
    docker run -d --name nexus3 --restart=always \
        -p 8081:8081 \
        --mount src=nexus-data,target=/nexus-data \
        sonatype/nexus3
    

    4.数据管理

    在容器中管理数据主要有两种方式:

    数据卷
    挂在主机目录
    

    Docker数据管理

    4.1 数据卷

    4.2 挂在主机目录

    5.使用网络

    Docker允许通过外部访问容器或容器互联的方式提供网络服务。

    5.1 外部访问容器

    通过 -P 或 -p 参数来指定端口映射,Docker会随机映射一个49000~49900的端口到内部容器开放的网络端口。

    docker run -d -p tranining/webapp python app.py
    
    # 查看容器的端口映射
    docker container ls -l
    # 查看应用信息
    docker logs -f nostalgic_morse
    
    
    # 映射所有接口地址(使用 hostPort:containerPort 格式本地的 5000 端口映射到容器的 5000 端口)
    docker run -d -p 5000:5000 training/webapp python app.py
    
    
    # 映射到指定地址的指定接口(可以使用 ip:hostPort:containerPort 格式指定映射使用一个特定地址)
    docker run -d -p 127.0.0.1:5000:5000 training/webapp python app.py
    
    # 映射到指定地址的任意端口(使用 ip::containerPort 绑定 localhost 的任意端口到容器的 5000 端口,本地主机会自动分配一个端口)
    docker run -d -p 127.0.0.1::5000 training/webapp python app.py
    
    # 查看映射端口配置
    docker port nostalgic_morse[容器名称] 5000
    
    

    5.2 容器互联

    强烈建议将容器加入自定义的Docker网络开连接多个容器

    # 新建网络my-net
    docker run -it --rm --name busybox1 --network my-net busybox sh
    # 运行容器并加入到my-net网络中
    docker run -it --rm --name busybox2 --network my-net busybox sh
    # 查看容器信息
    docker container ls
    # ping 来证明 busybox1 容器和 busybox2 容器建立了互联关系,分别在容器中去ping对方
    
    

    5.3 配置DNS

    6. Kubernetes

    Kubernetes是一个开源的,用于管理云平台中多个主机上的容器化的应用,Kubernetes的目标是让部署容器化的应用简单并且高效(powerful),Kubernetes提供了应用部署,规划,更新,维护的一种机制。

    听过一个演讲课,目前行业中流行的是K8S+Docker架构。

    7.靶机搭建(Docker实战)

    学习转载pageuo的FreeBuf.com文章】,谢谢大佬的分享。

    项目实际中为了验证扫描器的扫描准确性和扫描器的性能,由于长期扫描国外开源的扫描靶机会被封禁IP,影响扫描结果。为了项目的可持续性,想到了自己来搭建靶场验证扫描器的功能和性能。感谢pageuo大佬的靶机搭建经验。

    7.1 搭建Vulhub

    Vulhub是由 Phithon 维护的一款面向大众的开源漏洞靶场,只需要根据命令编译、运行就可搭建一个完整的漏洞靶场镜像。

    # 配置docker基础环境
    # 安装pip
    curl -shttps://bootstrap.pypa.io/get-pip.py | python3
    # 安装docker
    sudo apt-get update && apt-get install docker.io
    # 启动docker服务
    sudo service docker start
    # 安装compose
    pip install docker-compose
    
    # 拉取编译运行靶机
    # 拉取vulhub
    git clone git@github.com:phith0n/vulhub.git
    # 在线编译docker环境
    cd vulhub/struts/s2-016
    docker-compose build
    # 启动靶机
    docker-compose up -d
    
    

    7.2 搭建Vulapp

    Vulapp手机各种漏洞环境,统一采用Dockerfile进行管理,同事也手机了安全工具环境。

    # 拉取Vulapp
    git clone git@github.com:Medicean/VulApps.git
    
    
    
    Be a simple myself!
  • 相关阅读:
    【并发编程】并发编程随笔索引
    主题记录
    Java技术栈思维导图
    【ES 6.5.4 】ElasticSearch知识点
    Logstash Oracle同步设置
    【ES】【Reference 7.8 译】官方文档Mapping说明
    【ES】【Java High Level REST Client】官方索引和文档操作指导
    【ES】JAVA集成ES与基本操作及官方查询指导
    【实践】Effective Java实践总结
    【MyBatis】Spring集成MyBatis示例
  • 原文地址:https://www.cnblogs.com/secoder/p/12904734.html
Copyright © 2011-2022 走看看