• 2、Docker基础用法


    容器镜像:https://hub.docker.com/

    Docker架构图:  https://ruby-china.org/topics/22004

    Docker使用客户端-服务器(client-server)架构模式。Docker客户端会与Docker守护进程进行通信。Docker守护进程会处理复杂繁重的任务,例如建立、运行、发布你的Docker容器。

    Docker客户端和守护进程可以运行在同一个系统上,当然你也可以使用Docker客户端去连接一个远程的Docker守护进程。Docker客户端和守护进程之间通过socket或者RESTful API进行通信。

    Docker_host端运行一个子程序:Docker_daemon即守护进程,所以运行docker_daemon的进程的服务器就是守护进程服务器。docker_daemon可以监听在套接字上,为了安全,docker_daemon默认只提供本机的unix socket文件的套接字,支持三种类型的套接字:ipv4+端口、ipv6+端口、UNIX Socket file(本地文件),docker_daemon只监听了第三种套接字即本地文件,像mysql只监听了127.0.0.1,所以docker_daemon只允许客户端是本地的。

    镜像是分层构建的,需要把镜像下载到本地用以共享,镜像需要在docker主机的本地存储。

    由于所有镜像都是只读的,所以启动容器时都是基于镜像来启动,在已有镜像的基础上,为容器创建一个专用的可写层,从而来启动一个容器。

    Docker有两个主要的部件:

    Docker: 开源的容器虚拟化平台。

    Docker Hub: 用于分享、管理Docker容器的Docker SaaS平台。

    Docker守护进程

    如上图所示,Docker守护进程运行在一台主机上。用户并不直接和守护进程进行交互,而是通过Docker客户端间接和其通信。

    Docker客户端

    Docker客户端,实际上是docker的二进制程序,是主要的用户与Docker交互方式。它接收用户指令并且与背后的Docker守护进程通信,如此来回往复。

    Docker的内部

    要理解Docker的内部构建,必须知道以下三种部件:

    • Docker镜像 (Docker images)
    • Docker仓库 (Docker registeries)
    • Docker容器(Docker containers)

    Docker镜像

    Docker镜像是一个只读的模板。举个例子,一个镜像可以包含一个运行在Apache上的Web应用和其使用的Ubuntu操作系统。

    镜像是用来创建容器的。Docker提供了简单的来建立新的镜像或者升级现有的镜像,你也可以下载别人已经创建好的镜像。Docker镜像是Docker的构造部分。

    镜像是分层构建的,需要把镜像下载到本地用以共享,镜像需要在docker主机的本地存储。

    由于所有镜像都是只读的,所以启动容器时都是基于镜像来启动,在已有镜像的基础上,为容器创建一个专用的可写层,从而来启动一个容器。

    Docker仓库

    Docker仓库用来保存镜像。可以理解为代码控制中的代码仓库。同样的,Docker仓库也有公有和私有的概念。

    公有的Docker仓库名字是Docker Hub。Docker Hub提供了庞大的镜像集合供使用。这些镜像可以是你自己创建的,或者你也可以在别人的镜像基础上创建。Docker仓库是Docker的分发部分。

    Docker对象  https://docs.docker.com/engine/docker-overview/

    使用Docker时,可以创建和使用图像,容器,网络,卷,插件和其他对象。可以对对象进行增、删、改、查。

    Docker容器

    Docker容器和文件夹很类似。一个Docker容器包含了所有的某个应用运行所需要的环境。每一个Docker容器都是从Docker镜像创建的。

    Docker容器可以运行、开始、停止、移动和删除。每一个Docker容器都是独立和安全的应用平台。Docker容器是Docker的运行部分。

    Docker Registry  http://dockone.io/article/104

    1、提供镜像存储的仓库

    2、提供用户获取镜像时的认证功能

    3、提供当前服务器提供的所有服务器的搜索索引

    Docker Registry有很多仓库,一个仓库有一个名称,一个仓库只存放一个应用程序的镜像。比如nginx程序,但是nginx会有不同的版本,所以nginx的不同版本都存放在同一个仓库中,这个仓库名称就是应用程序名称:nginx。 

    nginx仓库中会存放nginx不同版本:nginx1.10、nginx1.12等,如何标记不同版本的镜像呢?是通过为每一个镜像额外添加一个组件:标签。

    所以用  仓库名 + 标签  才能唯一标识一个镜像。如果访问镜像时只给了仓库名,而没有标签,默认是最新标签。

    对于程序而言,奇数是开发板,而偶数是稳定版。 

    Docker容器是如何工作的

    一个Docker容器包含了一个操作系统、用户添加的文件和元数据(meta-data)。我们可以看到,每个容器都是从镜像建立的。镜像告诉Docker容器内包含了什么,当容器启动时运行什么程序,还有许多配置数据。Docker镜像是只读的。当Docker运行一个从镜像建立的容器,它会在镜像顶部添加一个可读写的层,应用程序可以在这里运行。

    当你运行docker容器时发生了什么

    不论你使用docker命令或者是RESTful API,Docker客户端都会告诉Docker守护进程运行一个容器。

    $ sudo docker run -i -t ubuntu /bin/bash
    

    让我们来分析这个命令。Docker客户端使用docker命令来运行,run参数表明客户端要运行一个新的容器。Docker客户端要运行一个容器需要告诉Docker守护进程的最小参数信息是:

    • 这个容器从哪个镜像创建,这里是ubuntu,基础的Ubuntu镜像。
    • 在容器中要运行的命令,这里是/bin/bash,在容器中运行Bash shell。

    那么运行这个命令之后在底层发生了什么?

    按照顺序,Docker做了这些事情:

    • 拉取ubuntu镜像: Docker检查ubuntu镜像是否存在,如果在本地没有该镜像,Docker会从Docker Hub下载。如果镜像已经存在,Docker会使用它来创建新的容器。
    • 创建新的容器: 当Docker有了这个镜像之后,Docker会用它来创建一个新的容器。
    • 分配文件系统并且挂载一个可读写的层: 容器会在这个文件系统中创建,并且一个可读写的层被添加到镜像中。
    • 分配网络/桥接接口: 创建一个允许容器与本地主机通信的网络接口。
    • 设置一个IP地址: 从池中寻找一个可用的IP地址并且添加到容器上。
    • 运行你指定的程序: 运行指定的程序。
    • 捕获并且提供应用输出: 连接并且记录标准输出、输入和错误让你可以看到你的程序是如何运行的。

    你现在拥有了一个运行着的容器!从这里开始你可以管理你的容器,与应用交互,应用完成之后,可以停止或者删除你的容器。

    安装及使用docker

    镜像:https://mirrors.tuna.tsinghua.edu.cn/

    docker软件包 https://mirrors.tuna.tsinghua.edu.cn/centos/7/extras/x86_64/Packages/   但是版本比较老

    清华大学的docker的repo文件:https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/

    此版本比较新:https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/7/x86_64/stable/Packages/

    # cd /etc/yum.repos.d/

    # wget https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo  下载repo文件

    # vim docker-ce.repo   //由于此文件中指向的docker版本比较老,所以对此文件进行修改

    :%a@https://download.docker.com/@https://mirrors.tuna.tsinghua.edu.cn/docker-ce/@

    yum.repos.d]# yum repolist

    # yum install docker-ce   //如果用老版本的话就是yum install docker

    docker程序环境:

    环境配置文件:
       /etc/sysconfig/docker-network
       /etc/sysconfig/docker-storage
       /etc/sysconfig/docker
    Unit File:
       /usr/lib/systemd/system/docker.service
    Docker Registry 配置文件:
       /etc/containers/registries.conf
    docker-ce:
       配置文件:/etc/docker/daemon.json   //这个文件默认是不存在的,需要自己创建

    Docker镜像加速:为了下载镜像速度较快,需要定义一个镜像加速器

    Docker 中国官方镜像加速  https://www.docker-cn.com/registry-mirror   较慢

    阿里云加速器

    把下面这段话加进到/etc/docker/daemon.json文件中去

    {  
    "registry-mirrors": ["https://registry.docker-cn.com"]   
    }

    //上述是json函数的数组,key是registry-mirrors,是https://registry.docker-cn.com,值可以有多个,用","隔开

    # mkdir /etc/docker

    # vim /etc/docker/daemon.json //添加此段话

    {
    "registry-mirrors": ["https://registry.docker-cn.com"]
    }

    # systemctl start docker.service

    # docker version  //查看docker版本

    Client:
    Version: 18.09.2
    API version: 1.39
    Go version: go1.10.6
    Git commit: 6247962
    Built: Sun Feb 10 04:13:27 2019
    OS/Arch: linux/amd64
    Experimental: false

    Server: Docker Engine - Community
    Engine:
    Version: 18.09.2
    API version: 1.39 (minimum version 1.12)
    Go version: go1.10.6
    Git commit: 6247962
    Built: Sun Feb 10 03:47:25 2019
    OS/Arch: linux/amd64
    Experimental: false

    # docker info   //查看更为详细的docker信息

    Containers: 0
     Running: 0
     Paused: 0
     Stopped: 0
    Images: 0
    Server Version: 18.09.2
    Storage Driver: overlay2
     Backing Filesystem: xfs
     Supports d_type: true
     Native Overlay Diff: true
    Logging Driver: json-file
    Cgroup Driver: cgroupfs
    Plugins:
     Volume: local
     Network: bridge host macvlan null overlay
     Log: awslogs fluentd gcplogs gelf journald json-file local logentries splunk syslog
    Swarm: inactive
    Runtimes: runc
    Default Runtime: runc
    Init Binary: docker-init
    containerd version: 9754871865f7fe2f4e74d43e2fc7ccd237edcbce
    runc version: 09c8266bf2fcf9519a651b04ae54c967b9ab86ec
    init version: fec3683
    Security Options:
     seccomp
      Profile: default
    Kernel Version: 3.10.0-957.el7.x86_64
    Operating System: CentOS Linux 7 (Core)
    OSType: linux
    Architecture: x86_64
    CPUs: 6
    Total Memory: 3.692GiB
    Name: node1
    ID: LFHI:LTRE:6TA4:CJHP:HHPO:AAIH:I54H:NMPR:CJ4I:SKAI:CAQV:7GRP
    Docker Root Dir: /var/lib/docker
    Debug Mode (client): false
    Debug Mode (server): false
    Registry: https://index.docker.io/v1/
    Labels:
    Experimental: false
    Insecure Registries:
     127.0.0.0/8
    Registry Mirrors:
     https://registry.docker-cn.com/
    Live Restore Enabled: false
    Product License: Community Engine

    # docker  //可以查看docker的子命令

    # docker container --help   //现在单独管理

    Docker命令: http://dockone.io/article/102    http://www.runoob.com/docker/docker-command-manual.html

    Alpine简介   https://yeasy.gitbooks.io/docker_practice/cases/os/alpine.html

    下载镜像

    # docker image pull nginx:1.14-alpine   //下载nginx的alpine镜像

    # docker image ls    //显示镜像

    # docker pull busybox

    # docker image ls --help

    启动容器

    # docker container --help   //容器命令

    # docker container ls

    CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

       容器ID     基于哪个镜像启动的容器    在容器中运行的命令                                               容器映射的端口

    COMMAND:容器中运行的命令,docker容器是为了运行单个程序的,当基于一个镜像启动一个程序的时候运行哪个程序呢?每个镜像都有定义默认运行的程序。但是也可以修改默认程序。

    # docker run --help  http://www.runoob.com/docker/docker-run-command.html

    Usage: docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

    # docker network ls

    NETWORK ID          NAME                DRIVER              SCOPE
    5ebae7e509fa        bridge              bridge              local   如果不指定,则默认此
    b255b50dc21e        host                host                local
    db26f5263d07        none                null                local

    Docker network 

    https://www.ibm.com/developerworks/cn/linux/l-docker-network/index.html    

    https://docs.docker.com/network/

    启动的容器会自动拥有inet 172.17.0.1网络中的地址,并且是nat桥,即可以进行地址转换,通过inet 192.168.128.131与外界通信,可以请求出去,但无法进来。

    # ifconfig  

    docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
            inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
            RX packets 0  bytes 0 (0.0 B)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 0  bytes 0 (0.0 B)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
    
    ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
            inet 192.168.128.131  netmask 255.255.255.0  broadcast 192.168.128.255
            inet6 fe80::f528:9792:1744:13a7  prefixlen 64  scopeid 0x20<link>
            ether 00:0c:29:ee:53:1e  txqueuelen 1000  (Ethernet)
            RX packets 109521  bytes 75247038 (71.7 MiB)
            RX errors 0  dropped 0  overruns 0  frame 0
            TX packets 161663  bytes 335973137 (320.4 MiB)
            TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

    Docker run 命令

    OPTIONS说明:

    • -a stdin: 指定标准输入输出内容类型,可选 STDIN/STDOUT/STDERR 三项;

    • -d: 后台运行容器,并返回容器ID;

    • -i: 以交互模式运行容器,通常与 -t 同时使用;

    • -p: 端口映射,格式为:主机(宿主)端口:容器端口

    • -t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;

    • --name="nginx-lb": 为容器指定一个名称;

    • --dns 8.8.8.8: 指定容器使用的DNS服务器,默认和宿主一致;

    • --dns-search example.com: 指定容器DNS搜索域名,默认和宿主一致;

    • -h "mars": 指定容器的hostname;

    • -e username="ritchie": 设置环境变量;

    • --env-file=[]: 从指定文件读入环境变量;

    • --cpuset="0-2" or --cpuset="0,1,2": 绑定容器到指定CPU运行;

    • -m :设置容器使用内存最大值;

    • --net="bridge": 指定容器的网络连接类型,支持 bridge/host/none/container:<name|id> 四种类型;

    • --link=[]: 添加链接到另一个容器;

    • --expose=[]: 开放一个端口或一组端口;

    实例

    使用docker镜像nginx:latest以后台模式启动一个容器,并将容器命名为mynginx。

    docker run --name mynginx -d nginx:latest

    使用镜像nginx:latest以后台模式启动一个容器,并将容器的80端口映射到主机随机端口。

    docker run -P -d nginx:latest

    使用镜像 nginx:latest,以后台模式启动一个容器,将容器的 80 端口映射到主机的 80 端口,主机的目录 /data 映射到容器的 /data。

    docker run -p 80:80 -v /data:/data -d nginx:latest

    绑定容器的 8080 端口,并将其映射到本地主机 127.0.0.1 的 80 端口上。

    $ docker run -p 127.0.0.1:80:8080/tcp ubuntu bash

    使用镜像nginx:latest以交互模式启动一个容器,在容器内执行/bin/bash命令。

    runoob@runoob:~$ docker run -it nginx:latest /bin/bash
    root@b8573233d675:/#

    / # exit   //退出容器,再次查看时,此容器处于停滞状态

    # docker container start -ai busybox    //启动之前创建的容器

    # docker rm busybox   //容器停止之后可以删除

    # docker ps -a   //再次查看时就没有此容器了

    创建nginx容器

    # docker run --name web1 -d nginx:1.14-alpine    //即使本地没有镜像也无所谓,会自动下载镜像到本地的

    # docker ps   //nginx容器已经启动了
    CONTAINER ID        IMAGE               COMMAND                  CREATED          STATUS           PORTS     NAMES
    3ecb4f5d9a10        nginx:1.14-alpine   "nginx -g 'daemon of??   2 minutes ago    Up 2 minutes     80/tcp    web1
    nginx -g 'daemon of??  //这里创建nginx容器时,是将程序跑在后台的,所以会出现这种问题。在容器中运行任何程序都不要运行在后台,
    因为一个容器就是为了运行一个程序,如果这个程序还要在后台运行,那么这个容器就没有程序运行了,
    那么没有程序运行容器就会结束,它是唯一进程,是支撑容器的骨架

    # docker inspect web1   //查看容器web1的相关信息

    {
            "Id": "3ecb4f5d9a109c5714718c81acf592890c9cd6bcee95d0f1e50b103689af1bc0",
            "Created": "2019-02-15T08:45:44.059155956Z",
            "Path": "nginx",
            "Args": [
                "-g",
                "daemon off;"
            ],
            "State": {
                "Status": "running",
                "Running": true,
                "Paused": false,
                "Restarting": false,
                "OOMKilled": false,
                "Dead": false,
                "Pid": 35189,
                "ExitCode": 0,
                "Error": "",
                "StartedAt": "2019-02-15T08:45:44.947856586Z",
                "FinishedAt": "0001-01-01T00:00:00Z"
            },
    。。。
    "Networks": { "bridge": { "IPAMConfig": null, "Links": null, "Aliases": null, "NetworkID": "5ebae7e509fa740a57623ec16baa50026135b09c7c98485cbe9784a272e7bdda", "EndpointID": "2bd43ccab59dee023a35dd28cfdc1238dc9e0ee032b5c42daca6f5bf2351ec90", "Gateway": "172.17.0.1", "IPAddress": "172.17.0.2", "IPPrefixLen": 16, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "MacAddress": "02:42:ac:11:00:02", "DriverOpts": null } }

    # curl 172.17.0.2   //访问nginx的web页面

    # docker run --name kvstor1 -d redis:4-alpine

    Unable to find image 'redis:4-alpine' locally    //本地没有此镜象,就下载
    4-alpine: Pulling from library/redis
    6c40cc604d8e: Already exists 
    e42672a2ca6a: Pull complete 
    823e4275fef6: Pull complete 
    0c49a8a142d3: Pull complete 
    62c3ab7a67af: Pull complete 
    d8e4fee2dbc2: Pull complete 
    Digest: sha256:99c3c1e02e5e794d7309003d4f5d045cba0b94911b9b3a2659bb15e8f4261954
    Status: Downloaded newer image for redis:4-alpine
    da481ee71e4581928a9c56b975561ddc4f0c8d7e4b627fcb087acf99e60336f5
    # docker ps
    CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS               NAMES
    da481ee71e45        redis:4-alpine      "docker-entrypoint.s??   About a minute ago   Up About a minute   6379/tcp            kvstor1   //正在运行
    3ecb4f5d9a10        nginx:1.14-alpine   "nginx -g 'daemon of??   35 minutes ago       Up 34 minutes       80/tcp              web1

    # docker container exec --help    //访问redis容器,需要有redis客户端,此镜象自带客户端,所以可以绕过容器的边界登陆进去。

    Usage: docker container exec [OPTIONS] CONTAINER COMMAND [ARG...]

    # docker exec -it kvstor1 /bin/sh   //

    /data # ps
    PID   USER     TIME  COMMAND
        1 redis     0:01 redis-server
       12 root      0:00 /bin/sh
       17 root      0:00 ps
    /data # netstat -tunlp
    Active Internet connections (only servers)
    Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
    tcp        0      0 0.0.0.0:6379            0.0.0.0:*               LISTEN      -
    tcp        0      0 :::6379                 :::*                    LISTEN      -
    /data # exit

    关于容器的日志,由于一个容器只运行了单个程序,所以就直接把日志发送到了控制台上了,而不是保存在文件中

    # docker logs web1   //查看web1容器的日志
         172.17.0.1 - - [15/Feb/2019:09:10:42 +0000] "GET / HTTP/1.1" 200 612 "-" "curl/7.29.0" "-" 

    Docker容器状态的转换和相关常用命令

     

  • 相关阅读:
    CF949C Data Center Maintenance 题解
    P1438 无聊的数列 题解
    CF620E New Year Tree 题解
    结构体优先队列的定义
    CF464E The Classic Problem 题解
    CF427C Checkposts
    CF161D Distance in Tree 题解
    P4375 [USACO18OPEN]Out of Sorts G 题解
    SCI, SCIE, 和ESCI的区别
    Matlab画图中图的方法
  • 原文地址:https://www.cnblogs.com/hanshanxiaoheshang/p/10387226.html
Copyright © 2020-2023  润新知