如果我们想要让软件运行起来,首先要保证操作系统的设置,其次还需要依赖各种组件和库的正确安装。那么虚拟机就是一种带环境安装的一种解决方案,它可以实现在一种操作系统里面运行另外一种操作系统,但是虚拟机的缺点也是十分明显的,资源占用多、冗余步骤多、启动速度慢。由于虚拟机存在的这些令人诟病的缺点。Linux发展出了另一种虚拟化技术,Linux Containers,即Linux容器,缩写为LXC。
Linux容器并没有虚拟一个完整的操作系统,而是对进程进行隔离。或者说,在正常进程的外面套了一层保护层。对于容器里面的进程来说,它接触到的各种资源都是虚拟的,从而实现与底层系统的隔离。Linux的容器也十分明显,体积小、启动快、资源占用也是极少的。
Docker属于Linux容器的一种封装,提供简单易用的容器使用接口。它是目前最流行的Linux容器解决方案。Docker将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器。程序在这个虚拟容器里面运行,就好像在真实的物理机上运行一样。
同时Docker的应用场景也十分广泛,比如:单项目打包、整套项目打包、新开源技术、环境一致性、持续集成、微服务、弹性伸缩等。
下面我们来看一张图,来学习下Docker体系的结构:
我们看上图哦,Docker通过Docker Client的客户端发送指令,驱动Docker Engine引擎来启动容器,然后通过Containerd来管理对应容器的内容,然后,shim只用来管理每个独立的容器,通过runC这个轻量级的工具来启动容器。在启动容器的时候,可能会去Image Repository镜像仓库中去取对应的依赖。
Docker提供了一些内部的组件,我们也需要了解一下:
首先docker的版本类型上,分为企业版和社区版,咱们用社区版就可以了,企业版是付费的。它的安装文档地址在:https://docs.docker.com/engine/install/centos/。
我们通过下面的命令来安装下docker:
先安装docker的一些依赖:
yum install -y yum-utils device-mapper-persistent-data lvm2
再安装docker的安装源:
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
最后安装docker:
yum install docker-ce docker-ce-cli containerd.io -y
这样,我们的docker就安装好了。然后我们看下常用的一些命令:
# 启动docker
systemctl start docker
# 查看docker信息
docker version
docker info
# 卸载docker
yum remove docker
# 删除docker相关的文件夹
rm -rf /var/lib/docker
我们也可以把相关的软件依赖改成阿里云的镜像地址,这样下载的时候会快一些,我就不多说了,因为我没改:
# 创建一个文件
sudo mkdir -p /etc/docker
# 写入一些配置
sudo tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://fwvjnv59.mirror.aliyuncs.com"]
}
EOF
# 重载所有修改过的配置文件
# daemon-reload: 重新加载某个服务的配置文件
sudo systemctl daemon-reload
sudo systemctl restart docker
Docker把应用程序及其依赖,打包再image镜像文件里面,只有通过这个文件,才能生成Docker容器。image镜像文件可以看作是容器的模板。Docker根据image镜像文件生成容器的实例。同一个image镜像文件,可以生成多个同时运行的image实例。镜像文件不是一个单一的文件,而是有多层次的结构。容器其实就是在image镜像的最上面一层加了一层读写层。在运行容器里做的任何文件改动,都会写到这个读写层里。如果容器删除了,最上面的读写层也就删除了,改动也就丢失了。
我们可以通过docker history [id/name] 查看镜像中各层级的内容及大小,每层对应着dockerfile中的一条指令。
下面我们来学习下一些基本的命令:
然后,我们学习了一些相关的命令,下面我们来拿这些命令做一些实践:
首先,我们查找一下centos镜像:
docker search centos
然后,我们把centos的镜像拉取到本地,如果你这里下载很慢的话,请回头安装阿里源,嘻嘻:
docker pull centos
然后,我们可以使用fs命令,查看下现在有哪些镜像:
docker image ls
下一步我们从远程镜像仓库拉取一个docker官方的例子镜像到本地的镜像仓库:
docker pull docker.io/hello-world
然后,可以通过rmi命令,删除本地镜像:
docker rmi hello-world
首先,我们来学习下一些有关于容器的基本概念。docker run 命令会从image镜像文件中生成一个正在运行的容器实例。该命令具有自动抓取image镜像文件的功能,如果发现本地没有指定的image文件,就会从仓库自动抓取。输出提示后,实例就会停止运行,容器自动终止,当然,并不是所有的容器都会自动终止。同过image镜像文件生成的生成的容器实例,本身也是一个文件,成为容器文件。生成了容器后,就会同时存在两个文件,image镜像文件和容器文件。关闭容器并不会删除容器文件,只是停止容器的运行。
下面,我们来学习一下容器有关的命令:
kill -9
,强行终止;stop的话,首先给容器发送一个TERM
信号,让容器做一些退出前必须的保护性、安全性操作,然后让容器自动停止运行,如果在一段时间内,容器还是没有停止,再进行kill -9,强行终止。
docker run -d -p 8080:80 nginx
docker container port containerID
下面,我们把上面学习的命令来实践一下:
刚才我们在学习run命令的时候已经启动了一个容器并打印出了命令,那个是最基础的方法,那下面,我们来查看下我们的容器都有哪些:
docker ps -a
哈,只有一个,就是我们刚才执行的那个。下面我们来试一下启动一个交互式的容器:
docker run -i -t ubuntu /bin/bash
我们就进入了交互式容器的伪终端里,可以进行命令交互。然后我们执行下面的命令:
docker run centos ping www.baidu.com
执行了这个命令后,就会一直ping www.baidu.com,别的事就干不了了,只能看着:
此时,我们就需要--detach参数,进入后台运行:
docker run --detach centos ping www.baidu.com
然后,这个容器就会在后台运行:
那,我想要查看这个容器里面的日志怎么办呢,通过下面的命令就可以查看对应容器里的日志了:
docker logs --follow [id/name]
当然,我们也可以通过attach,重新进入这个容器。
docker attach [id]
然后,可以通过stop命令,停止某个正在运行中的容器:
docker stop [containerId]
docker stop是否能停止,是由容器内部指定的,需要运行完一些必要的容器才会停止。如果你希望可以立即杀死该容器,直接强行终止,就使用kill命令。停止了以后,我们可以通过docker start来重新启动。
然后,我们可以通过rm命令,删除已有的容器:
docker ps -a
先通过ps命令看下目前容器的id,然后通过rm删除:
docker rm [id]
这样一个一个删除太慢了,我们可以通过下面的命令批量删除:
docker rm $(docker ps -a -q)
很简单吧。
1、其它命令实践:
下面我们来练习下其他命令,我们先启动个hello-world的容器:
docker run hello-world
然后我们把这个容器导出:
docker export -o hello-world.tar [cantainerId]
然后我们看下这个文件:
删除这个容器:
docker rm [containerId]
然后镜像文件也删除掉:
docker rmi hello-world
然后,我们可以通过import命令,把刚才导出的tar包,再导入回来:
docker import hello-world.tar
就是这个了。
save命令可以把指定镜像打包成tar文件:
docker save -o redis.tar redis:latest
然后删除你刚才打包成tar的镜像,怎么删除我就不说了啊。删除了之后,我们可以通过load命令,把刚才的tar包下载回来。
docker load -i redis.tar
用户既可以使用 docker load
来导入镜像存储文件到本地镜像库,也可以使用 docker import
来导入一个容器快照到本地镜像库。这两者的区别在于容器(import)快照文件将丢弃所有的历史记录和元数据信息(即仅保存容器当时的快照状态),而镜像(load)存储文件将保存完整记录,体积也要大。此外,从容器(import)快照文件导入时可以重新指定标签等元数据信息。
2、下面我们来实践一些容器相关的:
我们先后台跑起来前面的那个ping命令:
docker run --detach centos ping www.baidu.com
然后,我们来用stats看下它的状态:
docker stats [containerId]
然后可以通过top命令,查看一个运行中容器的进程:
docker top [containerId]
我们还可以使用update命令更新一个或多个容器的配置,看stats那个图,LIMIT是1.7G左右,我们来通过update命令,限制一下它的内存:
docker update -m 500m [containerId]
可惜报错了,他跟你说还要同时设置memoryswap,设置一下呗:
然后LIMIT就变成了500M,简单吧。
3、下面我们来实践下如何映射指定容器的端口:
先使用下面的命令,启动一个docker容器中的nginx:
docker run -d -P nginx
这样会自动指定与宿主机的端口映射。
图中红框的部分就是自动指定的与宿主机的映射,我们也可以手动设置:
docker run -d -p 8080:80
这个意思就是说宿主机的ip是8080端口映射到docker容器的nginx的80端口。
4、学习下如何commit命令制作个性化镜像:
我们先停止并删除之前所有的容器:
docker stop $(docker ps -a -q)
docker rm $(docker ps -a -q)
然后像之前的例子一样,启动一个nginx容器。
通过下面的命令进入到容器的伪终端中:
docker exec -it [containerId]/bin/bash
然后,我们进入到容器的nginx存储html文件的目录,/usr/share/nginx/html:
cd /usr/share/nginx/html
创建一个html文件:
echo hello > hello.html
然后我们再打开一个命令行,访问一下刚才的nginx服务,要注意查看端口号哦:
这样就成功了。下面看下如何基于这个容器,建一个新的镜像:
docker commit -m'zakings nginx' -a'zaking' 0a90e57ca86b zaking/zakingnginx
这段代码是什么意思呢,docker commit -m'描述信息' -a'作者信息' [containerId] [包名]。
我们可以查看下:
多了我们刚才生成的镜像。下面我们清空下容器,使用我们自己创建的镜像创建容器:
不多说了,实践好多遍了。
然后呢,实际上就是跟之前的方式一样,创建nginx容器,并自动设置端口号就好了:
docker run -d -P [你自己刚才生成的镜像名字]
然后,在另一个终端访问下:
直接就出来了,不需要我们再重新创建了。当然,如果要发布到远程仓库,需要注册账号。这个我就不多说了,大家有兴趣可以自己试一下。
好啦,关于容器和镜像的部分。就先到这里了。