docker_0">为什么有docker
假设有这么一个场景,作为新时代的全栈工程师,某一天你接手一个项目,搭建好项目以后,还需要一台服务器,在它上面安装mysql、redis等项目中常用的中间件,于是你网上搜索Linux如何安装mysql、redis,照着网上的资料进行复制粘贴,结果发现老是运行不成功,好像不适配你的操作系统,甚至都无法区分当前系统是ubuntu还是centos或者debian,此时你多么希望有一门技术,能够一行命令就能安装这些软件,而且无视平台,docker 就是这么一门技术,它可以跨平台快速运行应用,只需要一行命令,终于在你的努力下,安装成功了,项目也开发完了,接下来你要把整个项目交付给客户,让客户也要能部署成功,所以你专门为整个项目,写了一个详细的文档,客户一看很不满意,他们觉得平时玩游戏啥的都是一键下载安装就好了,你这玩意,还得下载安装java、下载一堆软件安装,这时候你有希望有一门技术,能帮我们快速把整个项目一键打包,让客户拿到我们的软件包直接运行,docker就能解决这个问题,它可以帮我们把软件打成一个软件包,实现快速构建应用的目的,那终于你用docker把软件打成软件包,准备把这个软件包发给客户,你准备用u盘,网盘,或者软件传输助手传给用户,后面你就会发现,客户经常让你把网盘连接再发一次,之前的找不到了,此时你又希望有一门技术,能像手机应用商店那么方便,我把软件上传到应用商店,别人可以随时下载使用,docker就可以做到,它可以快速把你的软件快速分享到dockerhub,别人就可以去dockerhub下载软件了。把软件包发布到dockerhub以后,把这个软件称为镜像。下面是docker官网总结的什么是docker:
docker_6">docker架构与容器化
想要使用docker完成应用的构建、分享和运行,首先我们需要准备一台机器,在它上边安装docker环境,安装了docker环境的机器,我们称为docker主机,只要安装了docker,docker的后台进程docker daemon就会一直运行,于此同时,docker还提供了一个客户端,用来操作docker主机的后台进程,同时docker还有一个应用市场,将所有的应用都集中到应用市场里面,我们把应用市场里面的软件称为镜像。以启动一个redis为例,我们想要在docker主机上面运行redis,首先用docker命令行程序发送一个:
docker pull redis
这个命令发给docker 后台进程后,它就会连向docker的应用市场,下载这个redis镜像,把这个镜像下载到本机,本机就会有redis镜像,接下来我们用这个镜像启动应用,我们需要再发送一个命令:
docker run redis
这里的redis就是镜像名,这个命令发给docker daemon后,它就会在本机找redis镜像,当然如果找不到它也会自动下载,拿到镜像后,就会用镜像来启动redis的应用,我们把用镜像启动的这个应用称为容器,我们可以启动非常多的容器,每个容器都代表运行中的一个应用,这个是我们从镜像市场中下载的镜像来启动的,如果我们想要自己做一个软件的镜像,发给镜像市场,我们可以使用:
docker build xxx(软件名)
当这个命令发送给docker daemon后,docker daemon就会帮你制作这个软件的镜像,假设我们做了一个镜像叫openjdk,如果你想把这个镜像发给应用市场,让docker保存,那需要再用一个命令:
docker push xxx(软件名)
当把这个命令发给docker daemon后,docker daemon就会找到这个镜像,推送给软件市场,这样张三构建的这个镜像,只要推给应用市场,李四王五就可以从应用市场下载。
总结起来,想使用docker构建自己的软件包,只需要熟练掌握docker build命令就行,想要用docker分享你的应用,需要掌握docker push,把应用推送到docker市场,第二个是docker pull从应用市场下载镜像,想要运行应用需要掌握docker run命令。我们后面会详细探究这些命令的细节。
在这个架构里面有两个核心概念,镜像和容器。镜像好理解,其实就是软件包,而容器就是这软件包启动起来的应用,每一个运行中的应用我们称为容器,解析来我们进一步理解什么是容器。
如果用传统方式,直接在操作系统上部署一个个应用,那假设某个应用挂了,比如发生内存泄漏,这样就会挤压其他应用的内存空间,一个应用挂了,可能导致其他应用都挂了,这种方式带来一个严重问题叫,应用之间不隔离,为了隔离,我们可以进阶到虚拟化的部署,操作系统上,利用虚拟化技术,开上几个虚拟机,每个应用部署在自己的虚拟机内部,这样某个应用炸了,只能影响到虚拟机级别,不会影响别的虚拟机中的应用,这样就有了隔离机制,但虚拟机有个严重问题,每个虚拟机都有完整的操作系统,就会导致虚拟机非常笨重,基于这个问题,就可以进阶到容器化部署,在操作系统上,我们不用虚拟化技术创建虚拟机了,而且安装容器的运行时环境,然后利用容器的技术,启动一个个应用,每个应用运行在自己的容器内部,这个应用的容器其实就包含了运行这个应用完整的环境,而且容器之间互相隔离,某个应用炸了,只影响自己的容器,容器就类似于一个集装箱,把这个应用直接封装起来,这样容器和容器直接就互相隔离,看起来就是应用与应用直接互相隔离。
所以容器的优点就是即拥有了隔离特性,每个容器也没有操作系统,所以容器就类似于轻量级的虚拟机。它是共享操作系统的内核。
docker_40">docker安装
接下来我们安装docker,安装docker会分为两步,第一步先开通云服务器,然后在这个服务器上安装docker,测试完后可以删了就行,我们可以去各大云厂商,按量付费开通就行,我自己购买的华为云,只因为当时最便宜。
一定要记得在配置安全组中配置要开的相关端口:
接下来我们开始安装docker:
- 移除旧版本docker
docker">sudo yum remove docker \docker-client \docker-client-latest \docker-common \docker-latest \docker-latest-logrotate \docker-logrotate \docker-engine
- 配置docker yum源。
docker">sudo yum install -y yum-utils
sudo yum-config-manager \
--add-repo \
http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
- 安装 最新 docker
- docker-ce: docker引擎
- docker-ce-cli:docker引擎的命令行
- containerd.io:docker运行环境
- docker-buildx-plugin:docker构建镜像的插件
- docker-compose-plugin:docker做批量的插件
docker">sudo yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
- 启动& 开机启动docker; enable + start 二合一
docker">systemctl enable docker --now
- 配置加速
docker">sudo mkdir -p /etc/docker
sudo tee /etc/docker/daemon.json <<-'EOF'
{"registry-mirrors": ["https://mirror.ccs.tencentyun.com","https://docker.m.daocloud.io"]
}
EOF
sudo systemctl daemon-reload
sudo systemctl restart docker
docker_107">docker常见命令
- 我们先把docker最常用的命令进行总结:
docker">#查看运行中的容器
docker ps
#查看所有容器
docker ps -a
#搜索镜像
docker search nginx
#下载镜像
docker pull nginx
#下载指定版本镜像
docker pull nginx:1.26.0
#查看所有镜像
docker images
#删除指定id的镜像
docker rmi e784f4560448#运行一个新容器
docker run nginx
#停止容器
docker stop keen_blackwell
#启动容器
docker start 592
#重启容器
docker restart 592
#查看容器资源占用情况
docker stats 592
#查看容器日志
docker logs 592
#删除指定容器
docker rm 592
#强制删除指定容器
docker rm -f 592
# 后台启动容器
docker run -d --name mynginx nginx
# 后台启动并暴露端口
docker run -d --name mynginx -p 80:80 nginx
# 进入容器内部
docker exec -it mynginx /bin/bash# 提交容器变化打成一个新的镜像
docker commit -m "update index.html" mynginx mynginx:v1.0
# 保存镜像为指定文件
docker save -o mynginx.tar mynginx:v1.0
# 删除多个镜像
docker rmi bde7d154a67f 94543a6c1aef e784f4560448
# 加载镜像
docker load -i mynginx.tar # 登录 docker hub
docker login
# 重新给镜像打标签
docker tag mynginx:v1.0 leifengyang/mynginx:v1.0
# 推送镜像
docker push leifengyang/mynginx:v1.0
- 接下来我们用案例来讲解各个命令
要完成上面的实验,需要这么几个步骤:
下载镜像
(1)先看看市场有没有nginx镜像
docker">docker search nginx
(2)下载nginx镜像
docker">docker pull nginx
(3)下载完成后,查看镜像
docker">docker images
当前默认下载的就是nginx最新版,这里需要注意一个问题,就是一个镜像的完整名称的格式其实是:
docker">镜像名:标签(也就是版本)
我们刚才下载nginx命令的完整写法:
docker">docker pull nginx:latest
如果我要下载指定版本就不推荐用docker search搜索镜像了,而是去dockerhub自己搜索镜像,里面有镜像完整的版本列表,比如:
我们下载一下这个版本,直接复制官网的下载命令:
docker">docker pull nginx:1.26
docker image ls的缩写就是docker images:
如果我们想要删除某个镜像可以使用下面命令:
docker">docker rmi 唯一id
或者
docker rmi nginx:latest
rmi就是remove image
上面就是常见的镜像相关操作。总结如下图:
启动容器
(1)当我们已经有了nginx镜像以后,想要启动这个应用,我们要做的第一步,就是docker run启动一个应用。我们先看看这个命令改怎么用,可以执行:
docker">docker run --help
options是可选的,COMMAND和ARG是命令和参数,也是可选的,一般都不用写,因为每个镜像都有自己的启动命令和参数,这是镜像里面默认带好的,除非我们要改动镜像的默认启动行为,否则都不用管。那就简单了,其实只要用:
现在就启动了,只不过它阻塞了控制台,我们不能把它停了,否则应用也就停了,我们重新打开一个连接,看看运行中的应用:
docker ps是查询正在运行的容器,docker ps -a是查询所有容器,包括已经停止的,比如我们把当前容器停止后查看:
退出的容器,如果我们再想启动,可以用:
docker">docker start 容器id或者容器的id
这里容器id也可以只写前面几位,能和其他区分就行
启动的应用如果想停掉可以用:
docker">docker stop 应用id或应用名
</