一. docker是什么
docker是一个运行在操作系统上的软件,这个软件上面可以运行多个相互隔离的容器,容器可以用image生成,一个image可以生成多个container。
像集装箱,把应用封装起来,可轻易创建,启动和销毁。
与虚拟机不同的是,虚拟机是一种操作系统里面运行另一种操作系统,而docker是对进程进行隔离,是对Linux 容器(Linux Containers,缩写为 LXC)的封装,省去了Guest OS层。共享OS层,提高了共享资源利用率。
二. docker的主要用途
- 可以保证开发交付运行环境不变,还可保证数据库每次初始状态都是一样的。
- 提供一次性环境,可为集成测试提供环境。
- 提供可扩展服务。可以根据实际情况打开需要数量的docker容器,动态提供满足数量的服务。
- 适用微服务搭建。可在一台机器上运行多台服务器,搭建微服务架构。
- 提供很大灵活性。方便服务从一台机器转移到另一台机器。
三. docker的下载安装
官网安所需操作系统的软件,登陆。
docker version 验证安装成功。
四. image文件
image是二进制文件,很小。而且可以拷贝到不同地方运行。
往往是基于一个image,进行安装运行文件等操作,制作一个新的image文件。image像一个模版,可以实例化多个container。而且多个container可以共享base image存储,节省了很大空间。
镜像文件,查看本机images:$docker images
删除image:$docker images rm
(id不一定要写全,只写到有区别就行)
Dockerfile可build image(见下文)
五. 镜像仓库
目前 Docker 官方维护了一个公共仓库 Docker Hub
可以通过 docker search 命令来查找官方仓库中的镜像,并利用 docker pull 命令来将它下载到本地。
docker push 命令来将自己的镜像推送到 Docker Hub:
$ docker push username/ubuntu:18.04
也可以上传到私有的docker registry
创建自己的私有仓库:
1. search image
$docker search registry
2. pull image
$docker pull registry
3. run image
$docker run -d -p 5000:5000 registry
启动备选项:将镜像文件存放在本地的指定路径,自动重启
$docker run -d \
-p 5000:5000 \
-v /opt/data/registry:/var/lib/registry \
--restart=always \
--name myregistry \
registry
4. tag with ip
$docker tag helloworld:latest :5000/helloworld:latest
5. 加入daemon.json:
{
"insecure-registries": [":5000"]
}
6. push image
$docker push :5000/helloworld
$curl http://
{"repositories":["helloworld"]}
六. container
查看container
$docker ps -a
或者 $docker container ls --all
生成container
image可生成container:$docker run
如果本地没有image镜像,docker会自动去仓库pull这个image。
$docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
1b930d010525: Pull complete
Digest: sha256:451ce787d12369c5df2a32c85e5a03d52cbcef6eb3586dd03075f3034f10adcd
Status: Downloaded newer image for hello-world:latest
...
$docker run -d -p 8000:8000 -p 30000-30099:30000-30099 --name
-d 是守护进程
-p是docker端口号对应的系统端口号<本机端口>:
--name是给这个生成的container起一个名字,下次生成新的container可以用不一样的名字。
运行container
停止运行的容器可以从上次停止状态继续运行,而不会产生新的container
$docker container start
mount文件
docker run --name mynginxweb -p 1080:80
--mount type=bind,source=/home/vagrant/docker,target=/usr/share/nginx/html nginx
停止container
$docker container stop
或 $docker container kill
删除container
删除指定的container:$docker container rm
也可在生成container时就指定运行结束后删除:$docker run --rm
一次性删除所有:$ docker container prune
七. Dockerfile
创建Dockerfile
- 用来制作生成image文件,文件名就叫Dockerfile。
- Dockerfile 中每一个指令都会建立一层image,下一个指令会基于前一个image做修改。因此镜像构建时,要尽量减少层数,一定要确保每一层只添加真正需要添加的东西,任何无关的东西都应该清理掉。
FROM ubuntu
CMD echo "Hello world!"
FROM python:3-alpine //从一个base image开始
WORKDIR /usr/src/app //工作路径
EXPOSE 8000 //开放端口
COPY requirements.txt .
RUN pip install -qr requirements.txt
COPY server.py .
CMD ["python3", "./server.py"]
FROM python:3-alpine:该 image 文件继承官方的 python image,冒号表示标签,即3-alpine版本的 python。
WORKDIR /usr/src/app:指定接下来的工作路径为/usr/src/app。
EXPOSE 8000:将容器 8000 端口暴露出来, 允许外部连接这个端口。
COPY server.py:将server.py拷贝进入 image 文件的/usr/src/app目录。
RUN pip install -qr requirements.txt 在/usr/src/app目录下运行 pip install安装requirements.txt中的包。
CMD ["python3", "./server.py"] 容器启动后,执行脚本server.py
FROM
在 Docker Hub 上有非常多的高质量的官方镜像,有可以直接拿来使用的服务类的镜像,如 nginx
、redis
、mongo
、mysql
、httpd
、php
、tomcat
等;也有一些方便开发、构建、运行各种语言应用的镜像,如 node
、openjdk
、python
、ruby
、golang
等。可以在其中寻找一个最符合我们最终目标的镜像为基础镜像进行定制。
如果没有找到对应服务的镜像,官方镜像中还提供了一些更为基础的操作系统镜像,如 ubuntu
、debian
、centos
、fedora
、alpine
等,这些操作系统的软件库为我们提供了更广阔的扩展空间。
除了选择现有镜像为基础镜像外,Docker 还存在一个特殊的镜像,名为 scratch
。这个镜像是虚拟的概念,并不实际存在,它表示一个空白的镜像。对于 Linux 下静态编译的程序来说,并不需要有操作系统提供运行时支持,所需的一切库都已经在可执行文件里了,因此直接 FROM scratch
会让镜像体积更加小巧。使用 Go 语言 开发的应用很多会使用这种方式来制作镜像,这也是为什么有人认为 Go 是特别适合容器微服务架构的语言的原因之一。
RUN
RUN 指令是用来执行命令行命令的。
shell 格式:RUN <命令>,就像直接在命令行中输入的命令一样。
exec 格式:RUN ["可执行文件", "参数1", "参数2"],更推荐这种写法。
RUN buildDeps='gcc libc6-dev make wget' \
&& apt-get install -y $buildDeps \
&& make -C /usr/src/redis install \
&& rm -r /usr/src/redis
(没必要多个RUN的就写到一起,用&&
连接,用\
换行)
CMD
- CMD 指令的格式和 RUN 相似,也是两种格式:
shell 格式:CMD <命令>
exec 格式:CMD ["可执行文件", "参数1", "参数2"...]
参数列表格式:CMD ["参数1", "参数2"...]。在指定了 ENTRYPOINT 指令后,用 CMD 指定具体的参数。
- 更多高级指令见:https://yeasy.gitbooks.io/docker_practice/image/dockerfile/
build image
build Dockerfile就会生成image:$docker build -t
docker是S/C架构,我们文件在本地Client系统。docker build 命令得知这个路径后,会将路径下的所有内容打包,然后上传给 Docker 引擎。
可以用 .dockerignore剔除不需要作为上下文传递给 Docker 引擎的。
实际上 Dockerfile 的文件名并不要求必须为 Dockerfile,而且并不要求必须位于上下文目录中,比如可以用 -f ../Dockerfile.php 参数指定某个文件作为 Dockerfile。
当然,一般大家习惯性的会使用默认的文件名 Dockerfile,以及会将其置于镜像构建上下文目录中。
也可用url, 例如git repo构建:$ docker build https://github.com/twang2218/gitlab-ce-zh.git#:11.1
或者压缩包:$ docker build http://server/context.tar.gz
八. 其他image创建方法
container可导出,导入为image
$ docker export 7691a814370e > ubuntu.tar
$ cat ubuntu.tar | docker import - test/ubuntu:v1.0
九. Docker Compose 项目
Docker Compose 是 Docker 官方编排项目之一,负责实现对 Docker 容器集群的快速编排。
适用于需要多个容器相互配合来完成某项任务的情况
它允许用户通过一个单独的 docker-compose.yml 模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。
Compose 中有两个重要的概念:
服务 (service):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。
项目 (project):由一组关联的应用容器组成的一个完整业务单元,在 docker-compose.yml 文件中定义。
Compose 的默认管理对象是项目,通过子命令对项目中的一组容器进行便捷地生命周期管理。
参考:https://yeasy.gitbooks.io/docker_practice/
http://www.ruanyifeng.com/blog/2018/02/docker-tutorial.html