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