Docker认知

1:安装docker

2:docker优势

  • 统一环境,标准化部署
  • 解决复杂的依赖问题:比如两个微服务的依赖相互冲突
  • 隔离应用的运行环境:比如redis获取服务器的权限的漏洞
  • 轻量级的虚拟环境,相比虚拟机而言开销速度快
  • 统一的服务管理:不同的服务有不同的管理工具和方式,例如不同的语言,不同的版本
  • dockerhub上有许多高价值的镜像可以直接使用

3:镜像和容器的介绍

  • 镜像:相当于光盘,光盘里面存储的数据是只读的,不会被更改;可以吧镜像看做一个模板,蓝图
  • 容器:容器是用镜像生成的docker实例,一个镜像可以生成多个容器,每个容器之间,容器与宿主之间都是相互隔离的;可以在功能上吧容器看做虚拟机

容器可以快速方便的运行,也可以方便的删除

4:手动启动容器

docker run -d -t -p 8000:5000 --name demo ubuntu:18.04

  • run: 表示启动一个新的docker容器
  • -d 容器在后台运行
  • -t 极少会用到,表示让一个空白的ununtu镜像在后台运行
  • -p 指定端口,表示本机访问的8000会被自动转到容器中的5000端口;前提是本机的8000端口没被占用
  • ubuntu:18.04 是启动容器使用的镜像
  • 每个容器生成后都有ID,并且每个容器的ID都是不一样的

5:启动容器的常见问题

端口占用

  • 占用3456端口: docker run -t -d -p 3456:5000 --name test ununtu:18.04
  • 运行一个使用3456端口的容器,会发现因为端口被占用而失败:docker run -t -d -p 3456:5000 --name test1 ununtu:18.04
  • 删除test容器来关闭对3456端口的占用 docker rm -f test
  • 再次运行容器发现任然失败,因为名字已经存在,test1容器虽然因为端口被占用而运行失败,但实际上容器已经生成了
  • 这时候要么改名字要么删除容器重来

docker run -t -d -p 3456:5000 --name test2
docker rm -f test1
docker run -t -d -p 3456:5000 --name test1

6:在容器中安装必备的软件

假如我们要运行一个 flask web程序;用 exec 参数在运行中的Docker 容器里面执行命令安装必要的依赖库

  • docker exec demo apt update
  • docker exec demo apt -y install python3 python3-pip
  • docker exec demo pip3 install flask

7:在demo容器中运行web程序

  • 当前目录下有个a.py文件
  • docker exec demo mkdir /code
  • docker cp a.py "demo:/code/a.py"
  • docker exec demo python3 /code/a.py
  • flask默认的启动端口是5000,之前我们已经做了8000::5000的端口转发

8:用脚本的方式配置容器

之前的一系列命令有些繁琐;更好的方式是在宿主机写脚本,然后cp 到容器中直接运行

  • 再用脚本方式运行程序之前,我们先清理刚才运行的程序
  • Ctrl c终止进程:只是到后台运行
  • docker stop 真正停止容器
写一个install.sh脚本用于安装软件:
# install.sh
apt update
apt -y install python3 python-pip
pip3 install flask
写一个run.sh脚本运行程序:
# run.sh
cd /code
cd /code
python3 a.py

9:运行脚本配置并开启新容器

我们可以先删除容器重新开始,也可以开一个新容器 demo1

  • docker run -t -d -p 7000:5000 --name demo1 ubuntu:18.04
  • docker exec demo1 mkdir /code
  • docker cp install.sh "demo1:/code/install.sh"
  • docker cp a.py "demo1:/code/a.py"
  • docker exec demo1 bash /code/install.sh
  • docker exec demo1 bash /code/run.sh
  • localhost:7000

10:容器的其他操作

  • 启动一个停止运行的容器:docker start demo
  • 查看正在运行的容器:docker ps
  • 停止容器:docker stop demo
  • 再查看正在运行的容器,已经看不到demo了:docker ps
  • 查看所有的容器,包括未运行的:docker ps -a
  • 删除被停止的容器:docker rm demo
  • 删除运行的容器:docker rm -f demo1

11:Dockerfile介绍

使用Dockerfile打包一个镜像并运行;优势解决手动执行命令;脚本的劣势,如果要启动多个容器,自制脚本每次都要重新安装配置一次

# 在Dockerfile 文件中#是注释
# FROM 用于指定构建镜像使用的基础镜像
FROM ununtu:18.04

# RUN 用于在构建镜像的时候在镜像中执行命令
RUN apt update
RUN apt -y install python3 python3-pip
RUN pip3 install flask

# COPY 相当于命令的 docker cp
# 把本机当前的目录下的app.py 文件拷贝到镜像中
# 不同的是可以自动创建不存在的目录

# WORKDIR 用于指定从镜像启动的容器内的工作目录
WORKDIR /code

# CMD 用于指定容器运行后要执行的命令和参数列表
CMD ["python3", "app.py"]

# ENTRYPOINT 参数用于指定容器运行后的入口程序,但是现在的这个参数意义已经很小了

12:使用Dockerfile构建镜像

本文件夹下有2个文件app.py和Dockerfile

  • docker build -t webimage .

命令中参数 -t webimage 指定了镜像的名字为webimage,这个名字可以用于在之后从镜像启动容器,最后的. 用于指定构建镜像时候的工作目录为本机当前目录

  • docker image 用于查看本机的镜像,包括下载的和构建的
  • docker run -p 8001:5000 --name demo2 webimage

13:服务器安装Docker

把安装的脚本和程序文件都放在本机的app 目录下,一共有如下3个文件: install-docker.sh=> 在ubuntu服务器安装docker的脚本;Dockerfile,上面的Dockerfile;app.py 上面的web程序; 我们可以用scp命令把app目录拷贝到服务器中,windows用户必须用cmder软件才有scp 这个命令;或者用 其他上传程序也可以,下面的用户名和IP换成你购买的服务器的用户名和IP

  • 拷贝:scp -r app your-ununtu@your-ip:/tmp
  • 登录:ssh your-ubuntu@your-ip
  • 安装docker:sh /tmp/app/install-docker.sh
  • 打包(提权):sudo docker build -t webimage .
  • 运行:sudo run -d -p 8000:5000 --name serverdemo webimage

14:数据卷介绍

我们可以在概念上把docker看做虚拟机,当容器被删除的时候,容器里的所有数据都会被删除,两个不同的容器之间无法互通,所有推出了数据卷 volume 功能
可以把数据卷理解为虚拟机的虚拟磁盘,独立于容器的文件,在容器中它被挂载为一个目录的形式,对于容器的应用来说,数据卷是透明的,无法感知它的存在,就是一个普通的文件夹,独立于容器存在,因此删除容器的时候数据卷不会受到影响

  • 优点:多容器可以通过挂载同一个数据卷来共享数据,数据卷可以方便地备份,存储数据

15:数据卷的使用

  • 创建一个volume:docker volume create testvolume
  • 列出所有数据卷:docker volume ls
  • 删除一个数据卷:docker volume rm testvolume
  • 查看一下:docker volume ls
  • 先创建一个volume:docker volume create web
  • 在运行容器的时候,使用参数 --mount:docker run -d --name demovolume --mount source=web,target=/volume webimage
  • --mount source=web,target=/volume,
    就是把数据卷挂载到容器的 /volume上

16:数据卷的特性演示

没有保存在数据卷上的文件会在容器被删除后丢失

  • 执行命令在容器的 /b.txt 写入时间内容并查看
docker exec demovolume sh -c 'date > /b.txt'
docker exec demovolume sh -c 'cat /b.txt'
  • 删除容器后重新启动同名容器再查看,之前容器的内容已经没有了
docker rm -f demovolume
docker run -d --name demovolume --mount source=web,target=/volume webimage
docker exec demovolume sh -c 'cat /b.txt'
  • 保存在数据卷上的内容即使容器被删除了仍然存在
docker exec demovolume sh -c 'date > /volume/b.txt'
docker rm -f demovolume
docker run -d --name demovolume --mount source=web,target=/volume webimage
docker exec demovolume sh -c 'cat /volume/b.txt'
  • 多容器之间可以通过数据卷共享文件
docker run -d --name demovolume2 --mount source=web,target=/v2 webimage 
docker exec demovolume2 sh -c 'cat /v2/b.txt'

17:共享目录

除了挂载数据卷外,docker 还可以挂载共享目录(这一点和虚拟机一样);优势:使用方便,易于理解
下面会从nginx 镜像运行一个nginx1的容器。并且设置了8080:80的端口映射;--mount参数的 type=bind 表明要挂载共享目录
把宿主机的当前目录映射为容器的 /usr/share/nginx/html;这样在宿主机中访问 localhost:8080 会自动访问宿主机当前目录下的 index.html 文件

  • docker run -p 8080:80 --name nginx1 --mount type=bind,source="${PWD}",target=/usr/share/nginx/html/ nginx
需要注意的是 source 参数必须使用绝对路径,所以这里使用 “${PWD}” 
的方式来在 Mac/Linux/Windows 中获取当前目录路径;这是一个可以在多平台通用的获取当前目录路径的方法(win下必须使用PowerShell),加引号是因为路径中可能含有空格等特殊符号,如果路径有空格而未加引号,会产生错误

18其他挂载模式

  • 单文件挂载,单文件挂载一定要保证宿主机文件存在,否则这个路径会被认为是一个目录挂载
docker run -p 8081:80 --name nginx2 --mount type=bind,source="${PWD}/index.html",target=/usr/share/nginx/html/test.html nginx
这时候我们访问 http://localhost:8081 返回的是 nginx 的默认首页,而访问 http://localhost:8081/test.html
  • 多文件挂载
docker run -p 80812:80 --name nginx3 --mount type=bind,source="${PWD}/index.html",target=/usr/share/nginx/html/test.html 
--mount type=bind,source="${PWD}/test.html",target=/usr/share/nginx/html/test2.html
nginx

19:compose的介绍

解决多容器互相配合,协同工作;虽然可以手动配置多容器之间的虚拟网络,文件互访等功能来实现容器互相访问,但docker官方推出了composer 程序用于配置,管理多容器的运行;Compose通过单独的docker-compose.yml配置文件来管理一组容器

20:安装Compose

在Docker for mac,Docker for Windows中 docker-compose 是自带的;只有在linux服务器上,才需要单独安装

sudo su
curl -L
https://github.com/docker/compose/releases/download/版本号/docker-compose
chmod +x /usr/local/bin/docker-compose

使用国内的地址来安装
sudo su
curl -L https://get.daocloud.io/docker/compose/releases/download/版本号/docker-compose
chmod +x /usr/local/bin/docker-compose

官方安装指南:
https://doc.docker.com/compose/install/

21:compose使用

compose 把一组容器作为一个项目来进行管理,并且会设置好容器之间的内部网络,每个容器在compose中被称为服务;composer使用docker-compose.yml文件来描述compose项目的构建;如同docker使用dockerfile来描述一个镜像的构建一样;

  • 命令启动:docker-compose up(Ctrl c 终止项目的运行)
  • 后台运行:docker-compose up -d
  • 暂停运行:docker-compose stop
  • 关闭并删除所有容器:docker-compose down

22:加速换源安装

23:可选的镜像

基于Alpine linux的alpine镜像,alpine已经是官方推荐的打包基础镜像

  • 使用专有镜像,而不是在Ubuntu镜像上安装软件
  • 使用基于alpine打包的镜像

24:镜像的分层构建和缓存

docker会对dockerfile中执行的结果生成缓存,再次构建镜像时,如果没有改动会复用缓存结果,因此指令的顺序很重要,前面的指令有改变,后面会全部重新build,所以应该把最不易更改的指令放在前面

25:compose使用技巧

  • 端口绑定;8000:3000形式实际上是 0.0.0.0:8000:3000;表示任意机器都能访问本机的8000端口;很多时候我们不能希望暴露服务端口,希望只有本机能访问,这时候我们应该写成:127.0.0.1:8000:3000
  • 查看日志:在项目中,使用 docker-compose logs 可以查看一个compose项目的日志;使用 docker-compose logs pyweb 的形式可以只查看某个特定服务的
  • compose的多文件和覆盖配置:当我们使用docker-compose up启动compose项目的时候,实际上相当于 docker-compose -f docker-compose.yml up
我们可以用多个不同的compose配置文件来实现不同的启动方式;可以用init.yml
用于初始化,可以用debug.yml用于启动调试模式
docker-compose -f docker-compose.yml -f debug.yml up

26:开发部署

项目的开发和部署需要不同的设置,我们通常会使用不同的环境变量来配置环境

27:docker 其它用法

  • 用docker来发布C C++或者其它平台相关的软件,可以让mac win用户都可以使用Linux软件
  • 同时使用多个软件的不同版本
  • 用于快速,方便安装一些服务,例如gogs:
docker run -p 3000:3000 gogs/gogs:latest

实战docker持续集成和部署

标签: docker

仅有一条评论

  1. 很棒a

添加新评论