docker学习

docker镜像常见操作:
    作为容器使用者,最好自己编辑镜像,满足自己的需求。
    docker image --help 查看镜像
    
    docker search 搜索镜像:
    docker pull 下载镜像
    docker images 查看本地镜像
    docker rmi    删除镜像
    可与替换成:
    docker image search
    docker image pull
    docker image list
    docker image rm
        
docker容器常见操作:
    docker container --help
    docker run 
        -i:以交互式模式运行容器,通常与-t同时使用
        -t:为容器重新分配一个伪输入终端,通常与-i同时使用
        -p:映射容器端口号
        -v:绑定挂载卷
        -h/--hostname:指定容器主机名字
        --rm:退出后删除容器
        --dns:指定DNS服务器地址
        --name:指定容器名字
        --network:指定网络类型
        --dns-search:指定dns搜索域
        --add-host:直接注入hosts文件内的解析 例:--add-host www.baidu.com:192.168.1.1
        
    docker inspect test/busyhttpd:v0.1-1 查看容器具体信息

镜像制作方式:
    1.dockerfile
    2.基于容器制作
        例如:做一个带index.html的busybox
            # docker run --name b1 -it busybox:latest
            # cat /data/html/index.html 
                <h1> Busybox httpd server test</h1>
            要将改变的结果保存,不能关闭容器,处于运动状态的容器做镜像
            # docker commit -p b1 (-p 暂停容器,b1基于哪个容器制作镜像)
            sha256:83a40fda5529ec14c......
            # docker tag 83a40fda5529 test/busyhttpd:v0.1-1 (第一次要基于IMAGE ID打标签)
            # docker tag test/busyhttpd:v0.1-1 test/busyhttpd:latest(一个镜像可打多个标签)
            # docker image rm test/busyhttpd:latest  (删除标签)
        
        基于新的busybox容器改变默认的启动运行命令(非 sh)。制作完镜像直接取名
            [root@zklf-server01 ~]# docker commit -a "jiuya@qq.com" -c 'CMD ["/bin/httpd","-f","-h","/data/html"]' -p busybox001 test/bushttpd:v0.2
            ha256:f330ada6d1dc55fcbfff1e882272d5e5f044f9ba755046ea6b65b3bcd7eac9de
                -a:author string 指定作者
                -c:change list 修改启动列表
                -p:pause 暂停容器
                        
    3.Docker Hub automated builds


个人阿里云docker镜像仓库:
    命名空间:
    仓库:
        busybox
    登陆:
        docker login --username=酒亚春123 registry.cn-beijing.aliyuncs.com
    标签:
        docker tag f330ada6d1dc registry.cn-beijing.aliyuncs.com/jiuyachun-hub/busybox:v1
    推送:
        docker push registry.cn-beijing.aliyuncs.com/jiuyachun-hub/busybox:v1
    拉去:
        docker pull registry.cn-beijing.aliyuncs.com/jiuyachun-hub/busybox:v1

镜像的导入和导出
    导出:
        docker save -o /root/busyboxhttpd.gz test/bushttpd:v0.2 
        -o 输出,保存路径以及文件名
    导入:
        docker load -i /root/busyboxhttpd.gz

Linux内核支持6种内核空间
    UTS(主机名和域名),User用户,mount文件系统,IPC进程间通信,Pid进程号,Net网络
    名称空间配置物理网卡对外通信,如果名称空间超过物理网卡,则通过软件模拟网卡

docker网络:
    docker提供三种网络,bridge,host,none
    bridge:NAT桥接式网络,docker0,可交换机或者网卡,启动一个容器创建一对网卡,类似于网线连接两个设备,一个在容器一个在宿主机docker0
    通过bridge-utils工具查看桥接网卡关联
    # yum install bridge-utils
    # brctl show
    bridge name    bridge id        STP enabled    interfaces
    docker0        8000.0242fd3aa28c    no        veth1ad09f4
                                                veth4eb16e2

    创建集中不同得网络容器:
        创建桥接,默认或者指定bridge都会拥有网络172.17.0网段网络   
            # docker run --name t1 -it --network bridge --rm busybox 
            # docker run --name t1 -it --rm busybox
            # cat /etc/resolv.conf  容器主机的DNS会指向物理机的或者虚拟机的网关或者DNS
                nameserver 10.0.0.2
                nameserver 19.141.136.10

        创建none网络,封闭容器没有网络设备
            # docker run --name t1 -it --network none --rm busybox

    对外暴露网络端口:
        # docker run --name myweb --rm -p 80 test/bushttpd:v0.2
    查看容器端口映射:
        # docker port myweb
        80/tcp -> 0.0.0.0:32768
    此处的-p参数使用方法:
        -p <containerPort>:将指定的容器端口映射至主机所有地址的一个动态端口
        -p <hostPort>:<containerPort>:将容器端口<containerPort>映射至指定的主机端口<hostPort>
            # docker run --name myweb --rm -p 80:80 test/bushttpd:v0.2
        -p <ip>::<containerPort>:指定的容器端口<containerPort>映射至主机指定的<ip>的动态端口
            # docker run --name myweb --rm -p 10.0.0.10::80 test/bushttpd:v0.2
        -p <ip>:<hostPort>:<containerPort>:将指定的容器端口<containerPort>映射至主机指定<ip>的端口<hostPort>
            # docker run --name myweb --rm -p 10.0.0.10:80:80 test/bushttpd:v0.2
        
联盟式容器:第四种网络模型
    两个容器使用独立的User,Mount,Pid。共享UTS,Net,IPC
        # docker run --name myweb2 --network -it --rm busybox
        # docker run --name myweb2 --network container:myweb1 -it --rm busybox
        用ifconfig命令可以查看到,两个容器的IP地址是一样的。创建文件夹可以验证文件系统隔离
    以上可以看到两个容器可以联盟,想到容器和宿主机也可以联盟
        # docker run --name myweb3 --network host -it --rm busybox
    
自定义docker0桥的网络信息:/etc/docker/daemon.json
    只要定义bip和dns即可,其他会自动获取;若只定义bip,dns会获取到宿主机的
    
    {
        "bip":"192.168.1.1/24",
        "fixed-cidr":"10.20.0.0/16",
        "mtu":1500,
        "default-gateway":"10.20.1.1",
        "default-gateway-v6":"2001:db8:abcd::89",
        "dns":["10.20.1.1","10.20.1.3"]
    }
docker远程连接宿主机
    dockerd守护进程的C/S,其默认监听Unix Socket格式的地址。/var/run/docker.sock,如果使用TCP套接字
    /etc/docker/danmon.json:
        "hosts":["tcp://0.0.0.0:2375","unxi:///var/run/docker.sock"]
    开启端口后即可远程连接宿主机并执行命令:
        # docker -H 10.0.0.10:2375 image ls

docker创建自定义网络:
    # docker network create --help
    # docker network create -d bridge --subnet "172.16.0.0/16" --gateway "172.16.0.1" mybr0
    # 07e12f7f25d70
    修改网卡名:
        # ip link set br-9e94971c51ca name docker1  ”RTNETLINK answers: Device or resource busy:
        # ip link set br-9e94971c51ca down
        # ip link set br-9e94971c51ca name docker1
        # ip link set docker1 up 
    
docker存储卷:
    docker镜像由多个只读层叠加而成,启动容器时,docker会加载只读镜像并在镜像栈顶部添加一个读写层
    如果运行中的容器修改了现有的一个已经存在的文件,那该文件将会从读写层下面的只读层复制到读写层。该文件只读版本仍然存在,读写层副本被隐藏,称为“写时复制(COW)机制”
    “卷” 是容器上的一个或多个目录,
    
    docker两种类型的卷:
        绑定挂在卷:宿主机和容器创建两个目录,相关联
        docker管理卷:容器指定挂载卷,宿主机的目录由docker自行管理    (作为临时存储较为方便)
    
    绑定挂载卷:
        # docker run --name myweb4 -it -v /data/volume:/data/test busybox
        先指定宿主机挂载卷,再指定容器挂载卷
        # docker inspect myweb4
        "Mounts": [
            {
                "Type": "bind",
                "Source": "/data/volume",
                "Destination": "/data/test",
                "Mode": "",
                "RW": true,
                "Propagation": "rprivate"
            }
        ],

    docker管理的卷:
        # docker run --name myweb5 -it -v /test busybox
        可以看到在根目录下有一个test目录,用docker inspect可以看到源宿主机目录以及关联的容器目录。
        # docker inspect myweb5
        "Mounts": [
            {
                "Type": "volume",
                "Name": "965f4ef7eeff79a7263952f877f536ec652ac83f1dda61c2e223fa67bbb98999",
                "Source": "/var/lib/docker/volumes/965f4ef7eeff79a7263952f877f536ec652ac83f1dda61c2e223fa67bbb98999/_data",
                "Destination": "/test",
                "Driver": "local",
                "Mode": "",
                "RW": true,
                "Propagation": ""
            }
        ],

    docker inspect获取某个字段:
        docker是用Go语言开发的
        docker inspect获取信息,最外层称为根,用“.”代替,每下一层都用.连接
        # docker inspect -f {{.Config.Env}} myweb6 
        [PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin]
    
    docker两个或多个容器挂载同一个目录,可以实现文件共享,网络共享等
    以此思想,我们可以做基于单个容器一组基础架构:类似于lnmp: 
        # docker run --name infracon -it -v /data/infracon/volume/:/data/web/html busybox
        # docker run --name nginx --network container:infracon --volume-from infracon -it busybox
        基于一个文件夹,做nginx静态文件,php动态文件,mysql的数据文件
    
dockerfile制作
    # mkdir docker_img
    # vim /docker_img/Dockerfile
        第一阶段:注释行和FROM    
            # Description:test image
            FROM busybox:latest    或者 FROM busy@哈希码
        第二阶段:MAINTANIER在较新版本换成LABLE(制作者信息,名字+联系方式)
            MAINTAINER "jiu <897860358@qq.com>" 或者 LABEL maintainer="jiu <897860358@qq.com>"
        第三阶段:COPY,Docker主机复制文件到创建的新映像文件
            COPY <src>..<dest>,dest最好使用绝对路径且要以/结尾表示目录,src下的文件需要放在docker工作目录,会被递归复制,但是其自身目录不会被复制。
    制作镜像:
        # docker build -t thinyhttpd:v0.1-1 ./
    验证镜像文件是否存在:(命令结束容器停止)
        # docker run --name web07 --rm thinyhttpd:v0.1-1 cat /data/web/html/index.html
        <h1> Test Dockerfile Image </h1>
        
        第四阶段:ADD,类似于COPY    ADD <src>..<dest>
            如果<src>为URL且<dest>不以/结尾,则<src>将被下载并保存为<dest>.若<dest>以/结尾,则文件名将被下载到此目录
            如果<src>是一个本地系统上的压缩格式的tar文件,将被展开为一个目录。但是通过URL获取的tar文件则不会被展开
        第五阶段:VOLUME,用于在image中创建一个挂载点目录
            用 VOLUME 命令只能创建一个docker管理的卷,在docker run 命令以后会自动挂载
        第六阶段:EXPOSE,为容器打开指定要监听的端口实现外部通信
            EXPOSE <port> 只能指定自己要暴露的端口,动态绑定在宿主机上的随机端口,默认tcp
            EXPOSE 80/tcp 80/udp
            指定暴露端口并未真正暴露。运行容器时 -P 即可暴露
        第七阶段:ENV,用于为镜像定义所需的环境变量,并可被Dockerfile文件中位于其后的其他指令(ENV,ADD,COPY等)调用
            调用格式:$variable_name ${variable_name}
            ENV key=value 
                key2=value2
        第八阶段:CMD 改变容器启动以后的默认执行命令    
            CMD /bin/httpd -f -h /data/web/html
            可用json数组格式:CMD ["/bin/httpd","-f","-h /data/web/html"]
            可以定义多个CMD,但是只有最后一个生效
        第九阶段:ENTRYPOINT,类似于CMD指令的功能,用于为容器指定默认运行程序,使得容器像一个单独的可执行程序。
            与CMD不同的是,ENTRYPOINT启动的程序不会被docker run命令行指定的参数覆盖,会被当参数传递进去
            也可定义多个ENTRYPOINT,最后一个生效
            
            CMD["<PARAM1>","<PARAM2>"],为ENTRYPOINT指令提供默认参数
            
        第十阶段:USER,指定运行用户的
        第十一阶段:HEALTHCHECK 健康状态检测
        第十二阶段:SHELL
            镜像默认的执行程序:"/bin/sh -c",一般不改,除非是windows之类的
            
Docker Registry 镜像仓库
    1.私有registry:
        在yum源中就有docker-registry 0.9.1版本。安装时是docker-distribution-2.6.2的新版本,有点诡异
        这个服务器即可作为私有镜像仓库,配置文件:/etc/docker-distribution/registry/config.yml
        此处开一台docker2的服务器作为私有仓库
        
        #打标签:docker tag myweb:v0.3-1 docker2:5000/myweb:0.3-1
        #推镜像:docker push docker2:5000/myweb:0.3-1 (这里提醒我们必须得用https)
    修改docker镜像仓库为http协议
        在/etc/docker/daemon.json中加入 "insecure-registries":["docker2:5000"],重启服务。此处注意防火墙的问题
    其他局域网主机拉取镜像:
        # docker pull docker2:5000/myweb:0.3-1
        
    2.私有仓库管理工具,harbor
        
原文地址:https://www.cnblogs.com/jiuyachun/p/11133909.html