Docker 介绍

2019-11-30  本文已影响0人  那年角落的喇叭

systemctl start docker
systemctl stop docker
systemctl restart docker

1、Docker三个基本概念
镜像(Image)
容器(Container)
仓库(Repository)
理解了这三个概念,就理解了Docker的整个生命周期。

2、Docker镜像(Image)
镜像就是一个只读的模板。它包括了操作系统+软件运行环境+用户应用(OS + SOFTWARE ENV + USER APP)。
比如一个镜像可以包含一个完整的ubuntu操作系统环境,里面仅安装了Apache或用户需要的其它应用程序。
镜像的作用:用来创建Docker容器。由镜像实例化为容器(Image --> Class)。

Docker运行容器前需要本地存在对应的镜像,如果镜像不存在本地,
Docker会从镜像仓库下载(默认是Docker Hub公共注册服务器中的仓库https://hub.docker.com/)

(1)从仓库中获取(拉取)镜像
    docker pull image:tag
    docker pull registry-server/image:tag
    docker pull host:port/image:tag
    
    docker pull ubuntu:12.04
    docker pull registry.hub.docker.com/ubuntu:12.04
    docker pull dl.dockerpool.com:5000/ubuntu:12.04

(2)列出本地所有镜像
    docker images
    REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
    redis               5.0.6               01a52b3b5cd1        3 days ago          98.2MB
    hello-world         latest              4ab4c602aa5e        12 months ago       1.84kB

(3)创建镜像
    <1>修改并更新已有镜像
        1)使用已下载镜像启动容器
            docker run -t -i training/sinatra /bin/bash
        2)在容器中添加json和gem两个应用。对容器做出修改。
            gem install json
        3)提交修改
            docker commit -m "message" -a "user info" <container id> <repository>:<tag>
            docker commit -m "Added json gem" -a "Docker Newbee" 0b2616b0e5a8 ouruser/sinatra:v2
    <2>利用Dockerfile创建镜像
        1)新建一个目录与一个Dockerfile文件
            mkdir xxx
            cd xxx
            touch Dockerfile
        2)编写Dockerfile内容
            使用#来注释
            FROM指令告诉Docker使用哪个镜像作为基础
            MAINTAINER维护者的信息
            RUN开头的指令会在创建中运行,
        3)构建镜像
            docker build -t="tag" Dockerfile-path
            docker build -t="ouruser/sinatra:v2" ./sinaxx
            docker build -t="ouruser/sinatra:v2" ./sinaxx/Dockerfile //不需要到Dockerfile
            unable to prepare context: context must be a directory: /root/sinaxx/Dockerfile
            
            build构建流程
                上传这个Dockerfile内容
                Dockerfile中的指令被一条一条的执行
                每一步都创建了一个新的容器,在容器中执行指令并提交修改
                当所有的指令都执行完毕之后,返回了最终的镜像id
                所有的中间步骤所产生的容器都被删除和清理了
            注意:一个镜像不能超过127层
            其他命令:
                ADD: 复制本地文件到镜像
                EXPOSE: 向外部开放端口
                CMD: 描述容器启动后运行的程序等
    <3>从本地文件系统导入
        使用openvz(容器虚拟化的先锋技术)的模板来创建
        openvz的模板下载地址为https://wiki.openvz.org/Download/template/precreated
        先下载ubuntu-14.04-x86_64-minimal.tar.gz
        后执行导入命令
            cat ubuntu-14.04-x86_64-minimal.tar.gz | docker import - ubuntu:14.04

(4)修改镜像标签
        docker tag image_id <tag>   

(5)上传镜像到仓库
        docker push image
        docker push ouruser/sinatra

(6)存出镜像/载入镜像
        存出(检出)镜像:
            docker save -o target-file target-image
            docker save -o ubuntu_14.04.tar ubuntu:14.04
        载入或导入镜像:
            docker load --input/< target-file
            docker load --input ubuntu_14.04.tar
            docker load < ubuntu_14.04.tar

(7)移除本地镜像
    docker rmi repository:tag
    docker rmi image_id
    Notice: 在删除镜像之前要先用docker rm删掉依赖于这个镜像的所有容器。
    
    遇到的异常:
        1)同个镜像存在多个Repository
            Error response from daemon: conflict: unable to delete 14455c0a4b72 (must be forced) 
                - image is referenced in multiple repositories
            解决:使用强制删除-f或使用repository:tag
        2)镜像被子镜像依赖,即子镜像FROM了该镜像
            Error response from daemon: conflict: unable to delete 2ca708c1c9cc (cannot be forced) 
                - image has dependent child images
            解决:先删除其他子镜像(FROM了这个镜像的镜像)
            docker image inspect --format='{{.RepoTags}} {{.Id}} {{.Parent}}' $(docker image ls -q --filter since=image_id)

(8)搜索查找镜像
        docker search [OPTIONS] TERM
        OPTIONS说明:
            --filter=is-automated=true : 只列出automated build类型的镜像
            --no-trunc : 显示完整的镜像描述
            --filter=stars=5 : 列出收藏数不小于指定值的镜像
        NAME    DESCRIPTION    STARS    OFFICIAL    AUTOMATED
    
    自动创建
    自动创建(Automated Builds)功能对于需要经常升级镜像内程序来说,十分方便。 
    有时候,用户创建了镜像,安装了某个软件,如果软件发布新版本则需要手动更新镜像。。
    而自动创建允许用户通过 Docker Hub 指定跟踪一个目标网站(目前支持 GitHub 或 BitBucket)上的项目,一旦项目发生新的提交,则自动执行创建。
    要配置自动创建,包括如下的步骤:
    创建并登录 Docker Hub,以及目标网站;
    在目标网站中连接帐户到 Docker Hub;
    在 Docker Hub 中 配置一个自动创建;
    选取一个目标网站中的项目(需要含 Dockerfile)和分支;
    指定 Dockerfile 的位置,并提交创建。
    之后,可以 在Docker Hub 的 自动创建页面 中跟踪每次创建的状态。

    
    配置镜像加速
        提高从远程仓库拉取镜像的速度
        docker自身镜像注册服务器Registry: https://index.docker.io/v1/
        docker中国区:https://registry.docker-cn.com
        清华大学:https://docker.mirrors.ustc.edu.cn
        阿里云:需要登录阿里云账号在容器服务中获取
        七牛云:https://reg-mirror.qiniu.com
    
        方法一:在拉取镜像时指定镜像源地址
            docker pull registry.docker-cn.com/library/ubuntu:16.04
    
        方法二:使用--registry-mirror配置Docker守护进程,临时会话,无需在每次拉取时指定镜像源地址
            docker --registry-mirror=https://registry.docker-cn.com daemon
            docker pull ubuntu:16.04
        
        方法三:修改配置文件/etc/docker/daemon.json,添加registry-mirrors键值
            {
                "registry-mirrors": [
                    "https://registry.docker-cn.com",
                    "https://docker.mirrors.ustc.edu.cn",
                    "https://index.docker.io/v1/"
                ]
            }
            修改保存后重启Docker以使配置生效。
                systemctl daemon-reload
                systemctl restart docker
                
                发现是insecure-registries 设置冲突造成

                vim /usr/lib/systemd/system/docker.service

                查看环境变量

                EnvironmentFile=-/etc/sysconfig/docker

                在/etc/systemconfig/docker里面果然有所发现
                StartLimitInterval=30min

3、Docker容器(Container)
容器是独立运行的一个或一组应用以及它们的运行态环境。
可以把容器看做是一个简易版的 Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。
虚拟机(VM)为模拟运行的一整套操作系统(提供了运行态环境和其他系统环境)和跑在上面的应用。即虚拟机应用中架设另外的操作系统。
容器的作用
用来运行应用
创建容器
容器是从镜像创建的运行实例(Container --> Instance Of Image)。它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。
镜像是只读的,容器在启动的时候创建一层可写层作为最上层。

(1)启动容器
    方式一:基于镜像创建并启动
        docker run image[repository:tag] command
        
        docker run ubuntu:14.04 /bin/echo 'Hello world'
        docker run -t -i ubuntu:12.04 /bin/bash
            -t: 让Docker分配一个伪终端(pseudo-tty)并绑定到容器的标准输入上
            -i: 让容器的标准输入保持打开
        
        docker run的标准操作流程:
            检查本地是否存在指定的镜像,不存在就从公有仓库下载
            利用镜像创建并启动一个容器
            分配一个文件系统,并在只读的镜像层外面挂载一层可读写层
            从宿主主机配置的网桥接口中桥接一个虚拟接口到容器中去
            从地址池配置一个ip地址给容器
            执行用户指定的应用程序
            执行完毕后容器被终止

    方式二:启动已终止的容器
        docker start container id/name
        
        容器的核心为所执行的应用程序,所需要的资源都是应用程序运行所必需的。除此之外,并没有其它的资源。
        可以在伪终端中利用ps或top来查看进程信息。
        可见,容器中仅运行了指定的bash应用。这种特点使得Docker对资源的利用率极高,是货真价实的轻量级虚拟化。

    方式三:重启运行中/运行态的容器
        docker restart container id/name    

(2)以守护态运行容器
    docker run -d image[repository:tag] command
        -d: 让容器在后台以守护态(Daemonized)形式运行
    
    查看容器的输出信息:
        docker logs container_name

(3)终止容器
    <1>终止(退出)终端容器
        exit
        当Docker容器中指定的应用终结时,容器也自动终止。
    <2>终止守护态的容器
        docker stop container_id

(4)查看容器运行状态
        docker ps -a
        [CONTAINER ID]    [IMAGE]    [COMMAND]    [CREATED]    [STATUS]    [PORTS]    [NAMES]

(5)导出/导入容器
    <1>导出容器
        docker export container_id > target-file
    <2>导入容器快照
        cat ubuntu.tar | docker import - test/ubuntu:v1.0
        docker import http://example.com/exampleimage.tgz example/imagerepo
    
    导入镜像到本地镜像库的两种方式:
        <1>使用docker load来导入镜像存储文件到本地镜像库
        <2>使用docker import来导入一个容器快照到本地镜像库
    这两者的区别:
        容器快照文件将丢弃所有的历史记录和元数据信息(即仅保存容器当时的快照状态),可以重新指定标签等元数据信息
        镜像存储文件将保存完整记录,体积也要大

(6)删除容器
    <1>删除终止态的容器
        docker rm container id/name
    <2>删除运行态的容器
        docker rm -f container id/name
        Docker会发送SIGKILL信号给容器
        
(7)进入守护态容器
    <1>使用attach命令
        docker attach container_id/name
    缺点:
        当多个窗口同时attach到同一个容器的时候,所有窗口都会同步显示。
        当某个窗口因命令阻塞时,其他窗口也无法执行操作了。
    <2>使用nsenter命令
        1->安装nsenter
            (1)wget https://www.kernel.org/pub/linux/utils/util-linux/v2.34/util-linux-2.34.tar.gz
            (2)tar -xzf util-linux-2.34.tar.gz
            (3)cd util-linux-2.34
            (4)./configure --without-ncurses && make nsenter
            (5)cp nsenter /usr/local/bin
        2->使用nsenter
            PID=$(docker inspect --format "{{ .State.Pid }}" <container>)
                |--docker inspect --format[-f] "{{ .State.Pid }}" d52055ce5ef9
            nsenter --target $PID --mount --uts --ipc --net --pid
                |--nsenter --target 3825 --mount --uts --ipc --net --pid /bin/bash
            遇到的异常:
                mesg: ttyname failed: No such device
                mesg: ttyname failed: No such file or directory
            解决:在nsenter指令后面指定一个执行的shell,比如/bin/bash 
    <3>使用exec
        docker exec -it
        
(8)查看容器具体信息
    docker inspect container_id

(9)停止所有运行中的容器
    docker ps -a | grep "Up" | awk '{print $1 }' | xargs docker stop

(10)删除所有已终止的容器
    docker ps -a | grep "Exited" | awk '{print $1 }'|xargs docker rm

(11)删除所有none容器
    docker images | grep none | awk '{print $3 }' | xargs docker rmi

4、Docker仓库(Repository)
仓库是集中存放镜像文件的场所。
仓库注册服务器(Registry)是管理仓库的具体服务器。
仓库和仓库注册服务器的区分:
仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。
每个服务器上可以有多个仓库,而每个仓库下面有多个镜像。
从这方面来说,仓库可以被认为是一个具体的项目或目录。
仓库类似github中的repository: https://github.com/ljxcolin/{repository}

    示例:dl.dockerpool.com/ubuntu,dl.dockerpool.com是注册服务器地址,ubuntu是仓库名。

仓库分为公开仓库(Public)和私有仓库(Private)两种形式。
最大的公开仓库是Docker Hub,存放了数量庞大的镜像供用户下载。 
国内的公开仓库包括Docker Pool等,可以提供大陆用户更稳定快速的访问。

registry.cn-hangzhou.aliyuncs.com
https://registry-1.docker.io/v2/

(1)登录/登出仓库注册服务器
    docker login/logout --username[-u] uname --password[-p] upassword [registry-server]
    cat ~/my_password.txt | docker login --username foo --password-stdin
    Your password will be stored unencrypted in /root/.docker/config.json.
(2)

当然,用户也可以在本地网络内创建一个私有仓库。
当用户创建了自己的镜像之后就可以使用push命令将它上传到公有或者私有仓库,
这样下次在另外一台机器上使用这个镜像时候,只需要从仓库上 pull 下来就可以了。

注:Docker仓库的概念跟Git或Maven类似,注册服务器可以理解为GitHub/Mvnrepository这样的托管服务。

登录
docker login
docker search

docker-registry 是官方提供的工具,可以用于构建私有的镜像仓库。
安装运行 docker-registry
docker run -d -p 5000:5000 -v /opt/data/registry:/tmp/registry registry

docker文件存放目录
Docker实际上把所有东西都放到/var/lib/docker路径下了。
1 [root@localhost docker]# ls -F
/etc/systemd/system/docker.service.d
mv 10-machine.conf 10-machine.conf-bak
systemctl daemon-reload
systemctl start docker.service

上一篇下一篇

猜你喜欢

热点阅读