Docker入门1.Docker简介1.1 题外话--运输业货运方式1.2 什么是Docker2. 开始2.1 基本概念2.2 安装Docker2.3 镜像(Image)操作2.4 容器(Container)操作2.4.1 基本操作2.4.2 端口映射3.创建/发布镜像3.1 基于容器创建3.2 使用Dockfile创建3.3 发布到仓库3.4 镜像导入与导出4. Docker与CI/CD1.Docker简介1.1 题外话–运输业货运方式集装箱▼集装箱被发明之前▼两种货运方式的对比–散货运输集装箱运输货物装载时间几天到一个星期分拣、合并、装卸过程繁琐几个小时货物装卸时间占整个运输过程的比例 50% 10%所需劳动力大量码头工人少数码头工人和起重机操作员自动化程度低高安全性低高总体运输时间货物装卸时间实际运输时间在总距离和运输工具的运输速度不变的前提下可以节约一半以上的时间1.2 什么是DockerDocker[dɑkɚ]: 码头工人Docker 是一种容器(Container)技术它可以将应用和环境等进行打包形成一个独立的类似于 iOS/Android 的 APP 形式的「应用」这个应用可以直接被分发到任意一个支持 Docker 的环境中通过简单的命令即可启动运行。Docker 是一种最流行的容器化实现方案。和虚拟化技术类似它极大的方便了应用服务的部署又与虚拟化技术不同它以一种更轻量的方式实现了应用服务的打包。使用 Docker 可以让每个应用彼此相互隔离在同一台机器上同时运行多个应用不过他们彼此之间共享同一个操作系统。Docker 的优势在于它可以在更细的粒度上进行资源的管理也比虚拟化技术更加节约资源。Docker和虚拟化技术的对比▲结合前面的集装箱技术可以更好的理解docker:资源独立、隔离Docker Engine限制了硬件资源与软件运行环境与宿主机上的其他应用实现了隔离做到了互不影响。不同应用或服务以「集装箱」container为单位装「船」或卸「船」「集装箱船」运行 container 的宿主机或集群上数千数万个「集装箱」排列整齐不同公司、不同种类的「货物」运行应用所需的程序、组件、运行环境、依赖保持独立。环境的一致性开发工程师完成应用开发后 build 一个 Docker image基于这个 image 创建的 container 像是一个集装箱里面打包了各种「散件货物」运行应用所需的程序、组件、运行环境、依赖。无论这个集装箱在哪里——开发环境、测试环境、生产环境都可以确保集装箱里面的「货物」种类与个数完全相同软件包不会在测试环境缺失环境变量不会在生产环境忘记配置开发环境与生产环境不会因为安装了不同版本的依赖导致应用运行异常。这样的一致性得益于「发货」build Docker image时已经密封到「集装箱」中而每一个环节都是在运输这个完整的、不需要拆分合并的「集装箱」。轻量化相比传统的虚拟化技术VM使用 Docker 在 CPU、Memory、Disk I/O、Network I/O 上的性能损耗都有同样水平甚至更优的表现。Container 的快速创建、启动、销毁受到很多赞誉Build Once, Run Everywhere「货物」应用在「汽车」、「火车」、「轮船」私有云、公有云等服务之间迁移交换时只需要迁移符合标准规格和装卸方式的「集装箱」Docker container削减了耗时费力的人工「装卸」上线、下线应用带来的是巨大的时间人力成本节约。这使未来仅有少数几个运维人员运维超大规模装载线上应用的容器集群成本可能2. 开始2.1 基本概念镜像(Image):可以理解为一个预配置的系统光盘这个光盘插入电脑后就可以启动一个操作系统。当然由于是光盘所以你无法修改它或者保存数据每次重启都是一个原样全新的系统.容器(Container):同样一个镜像我们可以同时启动运行多个运行期间的产生的这个实例就是容器。把容器内的操作和启动它的镜像进行合并就可以产生一个新的镜像。2.2 安装Docker以Ubuntu系统为例:使用官方命令安装:wget -qO- https://get.docker.com/ | sh使用国内镜像安装curl -sSL https://get.daocloud.io/docker | sh安装镜像加速器:curl -sSL https://get.daocloud.io/daotools/set_mirror.sh | sh -s http://f1361db2.m.daocloud.io2.3 镜像(Image)操作搜索镜像docker search image_name如:docker search ubuntu拉取(下载)镜像docker pull user_name:image_name:tag如docker pull name/ubuntudocker pull name/ubuntu:18.04查看已拉取的镜像docker images删除镜像(需先删除对应的Container)docker rmi image_id2.4 容器(Container)操作2.4.1 基本操作操作命令说明启动(创建)一个容器docker run -it image_id/image_name /bin/bash-i表示: 表示这是一个交互容器会把当前标准输入重定向到容器的标准输入中.-t表示:为这个容器分配一个终端。也可以仅仅启动容器不需要交互(前提是你的镜像中要有可执行的前台程序否则就会立即退出。如果使用我们自己编译好的dotnet项目镜像因为已经包含有ENTRYPOINT或CMD就不会自动退出启动(创建)一个容器2docker run -d -p 9200:9200 -p 9300:9300 -e keyvalue -e key2value2 image_id/image_name-p:进行端口映射。-e:设置环境变量。-d:后台启动查看所有容器docker ps -a(docker ps查看正在运行的容器)查看容器详细信息docker inspect container_id停止\启动\重启容器docker start/stop/restart container_id开机自启动容器docker update --restart always container_id除了aways还可以设置为no默认不自动重启always总是自动重启包括开机后unless-stopped类似always但手动stop后重启机器后不会自动启动on-failure仅在非正常退出时重启连接到容器docker attach --sig-proxyfalse container_id能够连接的前提是容器正在start–sig-proxyfalse确保CTRL-D或CTRL-C不会关闭容器连接到容器2docker exec -it container_id /bin/bashattach命令无法给容器传入参数进行交互如果有交互需求可以使用exec命令替代获取容器的日志docker logs container_id1. 查看实时日志docker logs -f container_id2. 查看最近N行日志docker logs --tail N container_id3.查看某日志后的日志docker logs --since YYY-MM-DDTHH:MM:SS container_id列出指定的容器的端口映射docker port container_id删除容器docker rm container_iddocker rm $(docker ps -a -f statusexited -q)删除所有exit状态的容器2.4.2 端口映射容器启动之前可以通过以下命令进行映射dockerrun-P80-itubuntu /bin/bash(将容器的80端口映射到主机的任意端口上dockerrun-P192.168.0.100::80-itubuntu /bin/bash 将容器的80端口和192.168.0.100IP映射到主机的任意端口上dockerrun-p8000:80-itubuntu /bin/bash 将容器的80端口映射到主机的8000端口上dockerrun-p192.168.0.100:8000:80-itubuntu /bin/bash 将容器的80端口和192.168.0.100IP映射到主机的8000端口上注意P和p区别就是是否要映射到注意的任意端口容器启动之后可以通过以下命令进行映射iptables-tnat-ADOCKERTEST-ptcp-mtcp--dport8000-jDNAT --to-destination192.168.42.2:6379(将主机的8000端口映射到192.168.42.2容器的6379端口上注意此方式映射之后无法通过 docker port命令查看映射的端口可以使用iptables -t nat -nvL | grep 192.168.42.2 来查看3.创建/发布镜像要创建一个新的 Docker 镜像通常基于一个已有的 Docker 镜像来创建。Docker 提供了两种方式来创建镜像把容器创建为一个新的镜像、使用 Dockerfile 创建镜像。下面以创建一个包含.netcore sdk的镜像为例, 来演示两种不同的创建方式:3.1 基于容器创建dockerrun-itubuntu /bin/bashwget-qhttps://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.debsudodpkg-ipackages-microsoft-prod.debsudoapt-getinstallapt-transport-httpssudoapt-getupdatesudoapt-getinstalldotnet-sdk-2.1然后输入以下命令进行创建docker commit container_id user_name/image_name如: docker commit 51f guyiming/firstimage 注意用户名里不能有特殊符号用户名非必选3.2 使用Dockfile创建使用命令行的方式创建 Docker 镜像通常难以自动化操作。更多的是使用Dockerfile 来创建 Docker 镜像。Dockerfile 是一个纯文本文件它记载了从一个镜像创建另一个新镜像的步骤。撰写好 Dockerfile 文件之后我们就可以轻而易举的使用 docker build 命令来创建镜像了。Dockerfile常见命令:命令参数说明#-注释FROM image[: tag]从一个已有镜像创建例如ubuntu:latestMAINTAINERAuthor some-oneexample.com镜像作者名字如Max Liu some-oneexample.comRUN cmd或者[‘cmd1’, ‘cmd2’…]在镜像创建用的临时容器里执行单行命令ADD src dest将本地的 src添加到镜像容器中的 dest位置RUN cmd或者[‘cmd1’, ‘cmd2’…]在镜像创建用的临时容器里执行单行命令VOLUME path或者[‘/var’, ‘home’]将指定的路径挂载为数据卷EXPOSE port [ port…]将指定的端口暴露给主机ENV key value 或者 key value指定环境变量值CMD[“executable”,“param1”,“param2”]容器启动时默认执行的命令。注意一个Dockerfile中只有最后一个CMD生效ENTRYPOINT[“executable”, “param1”, “param2”]容器的入口点CMD 和 ENTRYPOINT 需要特殊说明一下:CMD 用来指定 Docker 容器启动时默认的命令例如我们上面例子提到的docker run -it ubuntu /bin/bash。其中/bin/bash就是通过手工指定传入的 CMD覆盖容器内原有的CMD命令进行执行。如果我们不加这个参数那么容器将会默认使用 CMD 指定的命令启动如果构建容器时没有设置CMD则不会启动。ENTRYPOINT 从字面看是入口点。构建dockerfile时ENTRYPOINT 用来指定特定的可执行文件、Shell 脚本并把启动参数或 CMD 指定的默认值作为附加参数传递给 ENTRYPOINT即对容器所有的操作只能在这个范围内。docker run -it ubuntu xxx时xxx将被作为参数传给ENTRYPOINT。论docker中 CMD 与 ENTRYPOINT 的区别安装.netcore sdk的Dockfile:FROM ubuntu:18.04 RUN apt-get update RUN apt-get install wget -y RUN wget -q https://packages.microsoft.com/config/ubuntu/18.04/packages-microsoft-prod.deb RUN dpkg -i packages-microsoft-prod.deb RUN apt-get install apt-transport-https -y RUN apt-get update RUN apt-get install dotnet-sdk-2.1 -y然后输入一下命令进行创建注意最后的小数点dockerbuild-tuser_name/image_name.3.3 发布到仓库创建完成之后使用push命令进行发布.在发布之前, 需要先登录到dockerhub:docker login -u user_name或者登陆到私有仓库docker login www.xxx.com -u username -p password如果是push到私有仓库需要先对构建之后的镜像打tag如docker tag imageid www.xxx.com/seatest_base/dotnetsdk:3.1网址就是私有仓库的地址中间的seatest_base是你私有仓库里项目的名称最后的dotnetsdk:3.1就是镜像名称和镜像tag了。tag打好之后push到仓库docker push www.xxx.com/seatest_base/dotnetsdk:3.13.4 镜像导入与导出docker 镜像导入导出有两种方法使用 save 和 load 命令保存的是一个镜像而非容器。不能对load的镜像重命名。docker save -o test.tar imageiddocker load -i test.tar使用 export 和 import 命令导出的是一个容器的快照, 不是镜像本身, 也就是说没有 layer。你的 dockerfile 里的 workdir, entrypoint 之类的所有东西都会丢失commit 过的话也会丢失。可以为镜像指定新名称。docker export -o test.tar containeriddocker import test.tar newgroup/newname:1需要注意两种方法不可混用。4. Docker与CI/CD以daocloud为例tbd