任何一门新技术,新语言,或者新工具的出现 必然会有其解决的问题或者痛点
docker 是什么?
一款产品从开发到上线,从操作系统,到运行环境,再到应用配置。作为开发+运维之间的协作我们需要关心很多东西,这也是很多互联网公司都不得不面对的问题,特别是各种版本的迭代之后,不同版本环境的兼容,对运维人员都是考验 Docker之所以发展如此迅速,也是因为它对此给出了一个标准化的解决方案 环境配置如此麻烦,换一台机器,就要重新来一次,费力费时,很多人想到,能不能从根本上解决问题,软件可以带环境安装吗?
也就是说,安装的时候把原始环境一模一样的复制过来,开发人员利用Docker可以消除编码时"在我的机器上可以正常工作"的问题
- 这只鲸鱼就是Docker
- 鲸鱼背上的集装箱就是一个个的容器,每一个容器里面安装的一个软件,比如 nginx,mysql等 这也就是多个集装箱("软件")
docker未出现时存在哪些问题?
相信大家总是听到的一句话: "在我电脑上运行的好好的啊!!!!"
java开发者写完程序后交给运维工程师进行部署,但是部署时总是出现这样那样的问题,导致运维人员总是去问java开发者是不是代码写的有问题,java开发者就说"在我本机运行的好好的啊"! 环境不一样,程序无法正常运行
现在基本都是分布式集群环境了,那么服务器也不止一台,10台起步吧,那么运维人员部署完第一台服务器后,继续做同样的操作部署第二台,一直到第十台,机器固定还好说,咬咬牙就坚持过去了,但是说不定哪天搞活动,要搞弹性云扩容,再添加20台服务器,那么运维就疯了;同样的操作重复几十遍;
docker 核心理念
一次构建,到处运行
三大要素
- 镜像
- 容器
- 仓库
镜像
镜像(Image)是一个只读的模板,镜像可以用来创建Docker容器,一个镜像可以创建很多容器
容器
根据个Person(镜像)创建多个Person实例(容器)
- 1
- 2
- 3
Person p1 = new Person();
Person p1 = new Person();
Person p1 = new Person();
Person类就是一个模板,每次new都是一个实例(容器);
Docker利用容器独立运行的一个或一组应用,容器是用镜像创建的运行实例
它可以被启动,开始,停止,删除,每个容器都是相互隔离的,保证安全的平台;
可以把容器看做一个简单的Linux环境(包括root用户权限,进程空间,用户空间和网络空间等)和运行在其中的应用程序
仓库
仓库是一个集中存放镜像文件的场所,你可以把它理解成github。
DockerHub 是docker的中央仓库,开发人员可以将程序发布到dockerHub然后告诉运维人员下载即可获得与开发一模一样的运行环境
Docker 的用途
提供一次性的环境。比如,本地测试他人的软件、持续集成的时候提供单元测试和构建的环境。
提供弹性的云服务。因为 Docker 容器可以随开随关,很适合动态扩容和缩容。
组建微服务架构。通过多个容器,一台机器可以跑多个服务,因此在本机就可以模拟出微服务架构。
基本概念
run 和start区别
docker run : 只在第一次运行时使用,将镜像放到容器中,以后再次启动这个容器时,只需要使用命令docker start 即可, docker run相当于执行了两步操作:将镜像放入容器中(docker create),然后将容器启动,使之变成运行时容器(docker start)。
docker start:重新启动已存在的镜像。也就是说,如果使用这个命令,我们必须事先知道这个容器的ID,或者这个容器的名字,我们可以使用docker ps找到这个容器的信息。
上手docker
搞懂了docker基本概念,现在我们直接上手操作
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
// 1. yum设置为阿里源
wget -O CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo & wget -O epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
yum clean all & yum makecache
// 2. 第一次安装 设置存储库
// 安装所需的包
yum install -y yum-utils device-mapper-persistent-data lvm2
// 设置稳定存储库
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
// 3. 安装 docker-ce
yum install docker-ce
// 4. 更新yum软件包
yum makecache fast
// 5. 启动
systemctl start docker
5. 验证
docker -v
docker run hello-world:latest :latest (最新) 不写的话默认是最新,可以自己定义
Docker命令
帮助命令
命令 | 描述 |
---|---|
docker version | 版本 |
docker info | 列出docker的详细信息 |
docker --help | 帮助命令 |
镜像命令
命令 | 描述 |
---|---|
docker images | 列出本地所有镜像 |
docker search | 搜索镜像,相当于网站上的搜索 |
docker pull 镜像的名字 | 将镜像下拉到本地上 |
docker rmi 镜像的名字 | 删除镜像 |
容器命令
命令 | 描述 |
---|---|
docker run 镜像名字 | 第一次启动使用run,后面使用start |
docker ps | 列出容器 |
docker start 容器id或名字 | 启动容器 |
docker stop 容器id或名字 | 停止容器 |
docker kill 容器id或名字 | 强制停止容器 |
docker run -it -p tomcat | -it交互模式,-p指定端口 |
docker run -it -P tomcat | 大写P随机端口 |
docker run --rm | 容器停止时删除 容器内部的文件系统仍然被保留,也就是docker ps -a 查不到了 |
常用的基本命令
命令 | 描述 |
---|---|
docker logs 容器名称 | 查看服务日志 |
docker restart 容器id或名字 | 重启容器 |
docker rm 容器id或名字 | 删除容器 |
docker rm -f $(docker ps -a | grep "模糊搜索的服务名称*" | awk '{print $1}') | 按照名称批量删除容器 |
docker stop $(docker ps -a | grep "模糊搜索的服务名称*" | awk '{print $1}') | 按照名称批量停止容器 |
docker exec -it 容器id或名字 bash | 进入容器内部 |
- 交互式启动
例子: docker run -it -p 8888:8080 tomcat
8888是docker访问tomcat的端口,tomcat自己端口还是8080,相当于是映射
- 后台启动
docker run -d -p 8888:8080 tomcat
- 将容器制作成镜像
docker commit -m="提交的信息描述" -a="作者" 容器id 要创建的镜像名称:标签名
docker commit -a="lgg" -m="666" d928634aac1d testmytomcat:1.2
推送到远程仓库
- 1
- 2
- 3
docker login --username=dockerhub用户名 --password 密码
docker tag 镜像名称 dockerhub用户名/镜像名称
docker push dockerhub用户名/镜像名称:版本
Docker加速
vim /etc/docker/daemon.json
- 1
- 2
- 3
- 4
- 5
- 6
- 7
{
"registry-mirrors":["https://almtd3fa.mirror.aliyuncs.com"]
}
service docker restart
Dockerfile
dockerfile
WORKDIR : 是指定工作目录,在宿主机看不到这个目录,一般是在第一行FROM这个容器里,比如先这个,WORKDIR指定app在node这个
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
FROM node:10.15.3 MAINTAINER GuoGuang ENV NODE_ENV=production ENV HOST 0.0.0.0 RUN mkdir -p /app COPY . /app WORKDIR /app EXPOSE 3000 RUN npm install RUN npm run build CMD ["npm", "start"]
CMD : 类似于 RUN 指令,用于运行程序,但二者运行的时间点不同:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
// COPY 宿主机文件路径 容器路径
COPY overrides /opt/overrides
// 列出数据卷 https://www.cnblogs.com/51kata/p/5266626.html
docker volume ls
volume 和 run命令里的 -v 区别是 volume不能指定宿主机的目录,是自动生成的,volume存在云Dockerfile中,所有通过此文件创建的容器都有次挂载点
docker 容器数据卷
docker容器产生的数据,如果不通过docker commit 生成新的镜像将数据保存下来的话,那么当容器删除后,数据也就没了;
为了能保存数据,我们使用数据卷保存,类似redis 的持久化
DockerCompose
Docker一般搭配微服务使用,一个docker实例对应一个服务,但是当我们的服务多了的时候,需要编写多个dockerfile文件,非常麻烦,使用DockerCompose即可解决这个问题,先来看一下官方定义:
Compose 是用于定义和运行多容器 Docker 应用程序的工具。通过 Compose,您可以使用 YML 文件来配置应用程序需要的所有服务。然后,使用一个命令,就可以从 YML 文件配置中创建并启动所有服务。
模板如下:
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
version: '自定义版本'
# 指定启动的服务
services:
redis: # 服务名称
image: redis:4.0.6 # 镜像
command: redis-server --requirepass "qwWDRRR5..D" --appendonly yes # 扩展命令
volumes: # 绑定的物理卷
- '/root/xxx/redis:/data'
networks:
- easy-mock
restart: always
三大概念
安装Docker-compose
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
sudo curl -L "https://github.com/docker/compose/releases/download/1.24.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
// 修改文件权限为可执行文件
sudo chmod +x /usr/local/bin/docker-compose
docker-compose version
// 启动,docker-compose默认执行当前目录下的docker-compose.yml文件,如果没有需要使用 -f 指定
docker-compose up -d
如果你在阅读过程中有自己的见解或观点,烦请不吝指教,谢谢。