1、Docker和虚拟机的区别
两者的区别
虚拟化环境下每个 VM 是一台完整的计算机,在虚拟化硬件之上运行所有组件,包括其自己的操作系统。
容器之间可以共享操作系统,比起 VM 被认为是更轻量级.且与 VM 类似,每个容器都具有自己的文件系统、CPU、内存、进程空间.
由于容器启动和运行过程中是直接使用了宿主机的内核,不会直接调用物理硬件,所以也不会涉及到硬
件驱动,因此也无需容器内拥有自已的内核和驱动。而如果使用虚拟机技术,对应每个虚拟机都有自已
独立的内核。
容器与虚拟化比有以下优点:
- 敏捷应用程序的创建和部署:与使用 VM 镜像相比,提高了容器镜像创建的简便性和效率。
- 持续开发、集成和部署:通过快速简单的回滚(由于镜像不可变性), 提供可靠且频繁的容器镜像构建和部署。
- 关注开发与运维的分离:在构建、发布时创建应用程序容器镜像,而不是在部署时, 从而将应用程序与基础架构分离。
- 可观察性:不仅可以显示 OS 级别的信息和指标,还可以显示应用程序的运行状况和其他指标信号。
- 跨开发、测试和生产的环境一致性:在笔记本计算机上也可以和在云中运行一样的应用程序。
- 跨云和操作系统发行版本的可移植性:可在 Ubuntu、RHEL、CoreOS、本地、 Google Kubernetes Engine 和其他任何地方运行。
- 以应用程序为中心的管理:提高抽象级别,从在虚拟硬件上运行 OS 到使用逻辑资源在 OS 上运行应用程序。
- 松散耦合、分布式、弹性、解放的微服务:应用程序被分解成较小的独立部分, 并且可以动态部署和管理 - 而不是在一台大型单机上整体运行。
- 资源隔离:可预测的应用程序性能。
- 资源利用:高效率和高密度
简述K8s和Docker关系
Docker包括3个部分
-
image Docker通过Dockerfile将应用程序,参数,程序代码和相关依赖打包到一个镜像中,从而实现可移植性的特性.
-
container:docker镜像可以用docker run命令以单机方式运行.
-
repository docker用来存放docker镜像,常见的可以分为公有仓库和私有仓库.一个Docker Repository中可以包含多个仓库,仓库与仓库以名字进行区分,仓库中的镜像以Tag进行区别.
K8s对多个主机上的容器进行关联与编排.更合理的利用资源和保障服务的可用性. k8s中最小单位是Pod,一个Pod中可以有1至多个容器.
2、docker容器的常用命令
docker info #查看容器的信息
docker search $image #搜索镜像
docker pull #下载镜像
docker push #上传镜像
#配置镜像加速器
mkdir -p /etc/docker
tee /etc/docker/daemon.json <<-'EOF'
{
"registry-mirrors": ["https://uxlgig3a.mirror.aliyuncs.com"]
}
EOF
systemctl daemon-reload
systemctl restart docker
docker images #查看镜像
docker image inspect centos #查看镜像的信息
docker save $image > /$PATH/IMAGE_NAME.tar #把容器的镜像导出到宿主机
docker load < $IMAGE_NAME.tar #把宿主机的镜像导入到容器
docker rmi -f $IMAGE #删除镜像
(-f #强制删除镜像,也会删除对应的容器)
docker tag $IMAGE $IMAGE:TAG #给镜像打标签
docker container #查看容器的命令
docker run $image #运行容器
#指定运行容器的名称
docker run --name=$container_name $image
docker run --name=centos7 centos:2009
#以交互式启动容器并进入(运行并进入到容器里,exit退出时容器随之停止)
docker run -it --name=centos7 centos:2009 /bin/bash
#一次性运行容器,退出后立即删除容器,仅用于测试
docker run --rm $image
#一次运行容器,退出后立即删除镜像,仅用于测试
docker run --rmi $Container_name $image
docker ps #显示正在运行的容器
docker ps -a #显示所有的容器
#查看容器内的进程
docker top $container_name
#查看指定容器的资源使用情况
docker stats $container_name
#删除容器
docker rm #删除容器
#开启容器
docker start $containerID
#停止容器
docker stop $containerID
#后台运行容器
docker run -d --name=$container_name $image
(Docker容器如果希望启动后能持续运行,就必须有一个能前台持续运行的进程,如果在容器中启动传统的
服务,如:httpd,php-fpm等均为后台进程模式运行,就导致 docker 在前台没有运行的应用,这样的容器启
动后会立即退出。所以一般会将服务程序以前台方式运行,对于有一些可能不知道怎么实现前台运行的
程序,只需要在你启动的该程序之后添加类似于 tail ,top 这种可以前台运行的程序即可. 比较常用的方
法)
#运行并进入容器
docker run --name=$container_name $image /bin/bash
#给容器发送信号,默认是9信号
docker kill $container_name
#进入容器,此方法退出容器也不会终止容器
docker exec -it $containID bash/sh
#容器端口映射(多个容器映射到宿主机的端口不能冲突,但容器内使用的端口可以相同)
docker run -d -it -p 宿主机端口:容器端口 --name=$contain_name $image
实例1:把容器里nginx的80端口映射给宿主机81
docker run -d -it -p 81:80 --name=nginx-test nginx
实例2:一次性映射多个端口加协议
docker run -d -it -p 81:80/tcp -p 88:443/udp --name=nginx-test nginx
#查看容器的日志
docker logs $containID
docker logs --tail $number $containID
docker logs -f
#将宿主机的文件拷贝到容器
docker cp $PATH $containID:$PATH
#将容器里的文件拷贝到宿主机
docker cp $containID:$PATH 宿主机的指定目录
#传剃环境变量
-e <参数> #传递参数
--env-file <参数文件>
3、dockerfile
FROM #指定运行的基础镜像,必须位于Dockerfile的第一行
RUN #用来运行构建镜像阶段需要的shell命令
ENV #定义环境变量
ARG #定义临时环境变量,和ENV不同的是,容器运行时不会存在这些环境变量
COPY #复制本地宿主机的文件到容器中,本地文件必须和Dockerfile在同一级目录
ADD #把本地压缩包文件拷贝到容器并且自动解压,但是以tar命名的压缩包文件是不会自动解压的
EXPOSE #指定服务端的容器需要对外暴露的端口号,已实现容器与外部通信
(EXPOSE 仅仅是声明容器打算使用什么端口而已,并不会真正暴露端口,即不会自动在宿主进行端口映射,故暴露端口还是要通过-p选项)
WORKDIR #指定工作目录(当前目录)
USER #指定运行容器的用户名或UID
#以Dockerfil构建镜像
docker build -t 镜像名:标签 .
CMD:容器启动命令
一个容器中需要持续运行的进程一般只有一个,CMD 用来指定启动容器时默认执行的一个命令,且其运
行结束后,容器也会停止,所以一般CMD 指定的命令为持续运行且为前台命令.
- 如果docker run没有指定任何的执行命令或者dockerfile里面也没有ENTRYPOINT命令,那么开启
容器时就会使用执行CMD指定的默认的命令 - 每个 Dockerfile 只能有一条 CMD 命令。如指定了多条,只有最后一条被执行
- 如果用户启动容器时用 docker run xxx 指定运行的命令,则会覆盖 CMD 指定的命令
ENDPOINT
- ENTRYPOINT 不能被 docker run 提供的参数覆盖,而是追加,即如果docker run 命令有参数,那
么参数全部都会作为ENTRYPOINT的参数 - 如果docker run 后面没有额外参数,但是dockerfile中有CMD命令(即上面CMD的第三种用
法),即Dockerfile中即有CMD也有ENTRYPOINT,那么CMD的全部内容会作为ENTRYPOINT的参
数 - 如果docker run 后面有额外参数,同时Dockerfile中即有CMD也有ENTRYPOINT,那么docker run
后面的参数覆盖掉CMD参数内容,最终作为ENTRYPOINT的参数 - 可以通过docker run --entrypoint string 参数在运行时替换,注意string不要加空格
使用CMD要在运行时重新写命令本身,然后在后面才能追加运行参数,ENTRYPOINT则可以运行时
无需重写命令就可以直接接受新参数 - 每个 Dockerfile 中只能有一个 ENTRYPOINT,当指定多个时,只有最后一个生效
- 通常会利用ENTRYPOINT指令配合脚本,可以为CMD指令提供环境配置
CMD和ENDPOINT的区别
- CMD的指令可以被docker run 指定的参数覆盖,而ENDPOINT的指令不会被docker run 指定的参数覆盖,并将docker run的参数作为ENDPOINT指定的参数使用
- ENDPOINT和CMD同时存在时,CMD的指令会被ENDPOINT当做指定的参数,当多个ENDPOINT的指令存在时只运行最后一个ENDPOINT的指令
由于是复习,这里就只整理常用的内容,其实docker单独拿来用已经很少,一般都是和k8s连用,掌握常用命令和Dockerfile的编写就可以。