Docker初识
Docker介绍
官网:www.docker.com,github:https://github.com/docker/docker.github.io;开源的容器引擎,可以让开发者打包应用以及依赖的库,然后发布到任何流行的linux发行版上,移植很方便;由go语言编写,基于apache2.0协议发布,基于linux kernel,要想在win下运行需要借助一个vm(虚拟机)来实现;自2013年开始,近些年发展迅猛,docker从1.13x开始,版本分为社区版ce和企业版ee,并且基于年月的时间线形式,当前最新稳定版为18.03。
Docker和传统的虚拟化比较
Docker的优势
1. 启动非常快,秒级实现 2. 资源利用率高,一台高配置服务器可以跑上千个docker容器 3. 更快的交付和部署,一次创建和配置后,可以在任意地方运行 4. 内核级别的虚拟化,不需要额外的hypervisor支持,会有更高的性能和效率 5. 易迁移,平台依赖性不强
核心概念
镜像:是一个只读的模板,类似于安装系统用到的那个iso文件,我们通过镜像来完成各种应用的部署。
容器:镜像类似于操作系统,而容器类似于虚拟机本身。它可以被启动、开始、停止、删除等操作,每个容器都是相互隔离的。
仓库:存放镜像的一个场所,仓库分为公开仓库和私有仓库。 最大的公开仓库是Docker hub(hub.docker.com)。
Docker的安装
官方yum源安装
curl https://download.docker.com/linux/centos/docker-ce.repo -o /etc/yum.repos.d/docker.repo
yum install -y docker-ce
RPM安装
wget https://download.docker.com/linux/centos/7/x86_64/stable/Packages/ yum install -y docker-ce-xxxx.rpm systemctl start docker # 启动docker
除此之外,也可利用国内yum源进行安装:
参考:https://blog.csdn.net/luojingcsdn/article/details/79191277
Docker镜像管理
下载镜像
docker pull centos
默认从dockerhub下载,速度慢
上传镜像
docker push centos
查看本地镜像
docker images
搜索镜像
docker search xxx # xxx是关键词
打标签
docker tag centos my_tag
删除镜像
docker rmi centos
保存镜像到镜像文件包
docker save -o centos_7.tar centos:7
镜像文件包恢复为镜像
docker load --input centos_7.tar # 或 docker load < centos_7.tar
配置镜像加速器
vi /etc/docker/daemon.json # 加入如下内容 { "registry-mirrors": ["https://registry.docker-cn.com"] } systemctl restart docker
加速地址也可以是阿里云等镜像仓库地址
Docker容器管理
创建容器
docker run -it centos bash
这样进入了一个虚拟终端里面,我们可以运行一些命令,使用命令exit或者ctrl+d 退出该bash,当退出后这个容器也会停止。
启动,停止,重启容器
docker start | stop | restart container_id | container_name
查看容器
docker ps
默认只输出正在运行的容器,要查看所有容器需要增加-a参数
运行容器常用参数(docker run)
-d: 后台运行容器,并返回容器ID; -i: 以交互模式运行容器,通常与 -t 同时使用; -t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用; --name nginx-lb : 为容器指定一个名称; --dns 8.8.8.8: 指定容器使用的DNS服务器,默认和宿主一致; -h "mars": 指定容器的hostname; -e username="ritchie": 设置环境变量; --cpuset="0-2" or --cpuset="0,1,2": 绑定容器到指定CPU运行; -m :设置容器使用内存最大值; --link : 添加链接到另一个容器; -p: 映射容器端口到宿主机 -v : 挂载本地目录到容器内部 --restart : 标志会检查容器的退出代码,并据此来决定是否要重启容器,默认是不会重启 - always:无论容器的退出代码是什么,Docker都会自动重启该容器 - on-failure:只有当容器的退出代码为非0值的时候才会自动重启。另外,该参数还接受一个可选的重启次数参数,`--restart=on-fialure:5`表示当容器退出代码为非0时,Docker会尝试自动重启该容器,最多5次。
容器查看日志
docker logs container_id docker logs -f container_id # 持续打印 docker logs -f --tail 10 container_id # 持续打印最后10行
进入容器
docker attach container_id
但是attach命令不算好用,比如我们想要退出终端,就得exit了,这样容器也就退出了
打开虚拟终端进入容器
docker exec -it container_id bash
与attach不同的是退出后容器依然运行。
删除容器
docker rm container_id
默认运行着的容器不会删除,要删除运行着的容器需要加-f参数
导出容器到容器文件包
docker export container_id > file.tar
从容器文件包导入
cat file.tar |docker import - bin_test
这样会生成bin_test的镜像
扩展:
docker save 和docker export的区别
- docker save保存的是镜像(image),docker export保存的是容器(container);
- docker load用来载入镜像包,docker import用来载入容器包,但两者都会恢复为镜像;
- docker load不能对载入的镜像重命名,而docker import可以为镜像指定新名称。
镜像创建
镜像创建一般分为两种方式:
- 通过容器创建镜像
- 通过Dockerfile创建镜像
Docker通过容器创建镜像
启动容器并做一些变更后:
docker commit -m "change somth" -a "somebody info" container_id new_image_name
container_id通过docker ps -a获取,后面的new_image_name为新镜像名字,这个命令有点像svn的提交,-m 加一些改动信息,-a 指定作者相关信息。
Dockerfile创建镜像---Dockerfile格式
1. FROM 指定基于哪个基础镜像
格式 FROM <image> 或者 FROM <image>:<tag>, 比如
FROM centos
FROM centos:latest
2. MAINTAINER 指定作者信息
格式 MAINTAIN <name> ,比如
MAINTAINER houxingbin houxingbin@sunlands.com
3. RUN 镜像操作指令
格式为 RUN <command> 或者 RUN [“executable”, “param1”, “param2”],比如
RUN yum install httpd RUN ["/bin/bash", "-c", "echo hello"]
4. EXPOSE 容器要暴露的端口
格式为 EXPOSE <port> [<port>...] , 比如
EXPOSE 22 80 8443
这个用来指定要映射出去的端口,比如容器内部我们启动了sshd和nginx,所以我们需要把22和80端口暴漏出去。这个需要配合-P(大写)来工作,也就是说在启动容器时,需要加上-P,让它自动分配。如果想指定具体的端口,也可以使用-p(小写)来指定。
5. ENV 指定环境变量
格式 ENV <key> <value>, 比如
ENV PATH /usr/local/mysql/bin:$PATH
它主要是为后续的RUN指令提供一个环境变量,我们也可以定义一些自定义的变量,如
ENV MYSQL_version 5.6
6. COPY 将本地的一个文件或目录拷贝到容器的某个目录里,其中src为Dockerfile所在目录的相对路径
格式 COPY <src> <dest>,比如
COPY <conf/vhosts> </usr/local/nginx/conf>
7. ADD 将本地的一个文件或目录拷贝到容器的某个目录里,其中src为Dockerfile所在目录的相对路径
格式 同COPY,比如
ADD <conf/vhosts> </usr/local/nginx/conf>
与COPY不同的是,ADD支持URL。
8. CMD 容器启动命令,三种格式:
CMD ["executable", "param1", "param2"] CMD command param1 param2 CMD ["param1", "param2"]
RUN和CMD看起来挺像,但是CMD用来指定容器启动时用到的命令,只能有一条。比如
CMD ["/bin/bash", "/usr/local/nginx/sbin/nginx", "-c", "/usr/local/nginx/conf/nginx.conf"]
9. ENTRYPOINT 格式类似CMD
同CMD相比:
- 相同点:都是容器启动时要执行的命令,如果写多个只有最后一条有效。
- 不同点:CMD 是可以被 docker run 指令覆盖的,而ENTRYPOINT不能覆盖。
10. VOLUME 创建一个可以从本地主机或其他容器挂载的挂载点
格式 VOLUME ["dir"],如
VOLUME ["/data"]
11. USER 指定运行容器的用户
格式 USER user,如
USER daemon
12. WORKDIR 为后续的RUN、CMD或者ENTRYPOINT指定工作目录
格式 WORKDIR dir,如
WORKDIR /opt
利用Dockerfile创建镜像
docker build -t image:test . # 或 docker build -t image:test /dockerfile_dir/
Docker仓库
Docker最大的仓库为dockerhub,上边存着各种官方以及个人上传的docker镜像。当然我们还可以用国内的镜像仓库,如阿里云的镜像仓库服务。除此之外,我们还可以搭建私有仓库,目前常用的有Harbor。
Docker仓库的使用:
docker pull 和docker push来下载和上传docker镜像。
Docker Volume
想要了解Docker Volume,首先我们需要知道Docker的文件系统是如何工作的。Docker镜像是由多个文件系统(只读层)叠加而成。当我们启动一个容器的时候,Docker会加载只读镜像层并在其上(译者注:镜像栈顶部)添加一个读写层。如果运行中的容器修改了现有的一个已经存在的文件,那该文件将会从读写层下面的只读层复制到读写层,该文件的只读版本仍然存在,只是已经被读写层中该文件的副本所隐藏。当删除Docker容器,并通过该镜像重新启动时,之前的更改将会丢失。在Docker中,只读层及在顶部的读写层的组合被称为Union File System(联合文件系统)。
为了能够保存(持久化)数据以及共享容器间的数据,Docker提出了Volume的概念。简单来说,Volume就是目录或者文件,它可以绕过默认的联合文件系统,而以正常的文件或者目录的形式存在于宿主机上。
Docker Volume实现的几种方式:
1. 数据卷(-v)
docker run -tid -v /data/:/data centos bash
docker run –tid –v /data centos bash
-v用来指定挂载目录,:前面的/data/为宿主机本地目录,:后面的/data/为容器里的目录,会在容器中自动创建。
如果使用第二种方式,将会把宿主机/var/lib/docker/volumes/container_id/_data目录挂载到容器中。
2. 使用 data container (—volumes-from)
定义数据卷容器
有时候,我们需要多个容器之间相互共享数据,类似于linux里面的NFS,所以就可以搭建一个专门的数据卷容器,然后其他容器直接挂载该数据卷。
首先建立数据卷容器
docker run -itd -v /data/ --name testvol centos bash
注意:这里的/data/是容器的/data目录,并非本地的/data/目录。然后让其他容器挂载该数据卷然后让其他容器挂载该数据卷。
docker run -itd --volumes-from testvol test123 bash
3. 使用 docker volume 命令
创建一个volume
[root@kube-node1 ~]# docker volume create vol1 vol1 [root@kube-node1 ~]# docker volume inspect vol1 [ { "CreatedAt": "2018-07-03T14:17:44+08:00", "Driver": "local", "Labels": {}, "Mountpoint": "/var/lib/docker/volumes/vol1/_data", "Name": "vol1", "Options": {}, "Scope": "local" } ]
使用volume
docker run -itd -v vol1:/data centos:7 bash
Docker网络模式
bridge
使用--net=bridge指定。默认模式,不用指定默认就是这种网络模式。这种模式会为每个容器分配一个独立的NetworkNamespace。类似于vmware的nat网络模式。同一个宿主机上的所有容器会在同一个网段下,相互之间是可以通信的。
host
使用--net=host指定。docker使用的网络实际上和宿主机一样,在容器内看到的网卡ip是宿主机ip。
container
使用--net=container:container_id/container_name指定。多个容器使用共同的网络,看到的ip是一样的。
none
使用--net=none指定。这种模式下,不会配置任何网络。