一键安装docker
curl -sSL https://get.daocloud.io/docker | sh
然后是docker镜像加速,必须加速,阿里云镜像获取地址:https://cr.console.aliyun.com/cn-hangzhou/instances/mirrors,登陆后,左侧菜单选中镜像加速器就可以看到你的专属地址了
在 /etc/docker/daemon.json 中写入如下内容(如果文件不存在请新建该文件):
{"registry-mirrors":["https://reg-mirror.qiniu.com/"]}
之后重新启动服务:
$ sudo systemctl daemon-reload
$ sudo systemctl restart docker
在命令行执行 docker info,如果从结果中看到了如下内容,说明配置成功。
$ sudo docker info
Registry Mirrors:
https://reg-mirror.qiniu.com
可以先实验一下
sudo docker run ubuntu:15.10 /bin/echo "Hello world"
以上命令完整的意思可以解释为:Docker 以 ubuntu15.10 镜像创建一个新容器,然后在容器里执行 bin/echo "Hello world",然后输出结果。
我们如何进入容器呢?
runoob@runoob:~$ docker run -i -t ubuntu:15.10 /bin/bash
root@0123ce188bd8:/#
各个参数解析:
- -t: 在新容器内指定一个伪终端或终端。
- -i: 允许你对容器内的标准输入 (STDIN) 进行交互。或者-it,就理解为进去就行了。每run一次,就会有一个新容器。
- 加了 -d 参数(-itd)默认不会进入容器,想要进入容器需要使用指令 docker exec
我们可以通过运行 exit 命令或者使用 CTRL+D 来退出容器。
使用以下命令创建一个以进程方式(后台方式)运行的容器
runoob@runoob:~$ sudo docker run -d ubuntu:15.10 /bin/sh -c "while true; do echo hello world; sleep 1; done"
2b1b7a428627c51ab8810d541d759f072b4fc75487eed05812646b8534a2fe63
这个长字符串叫做容器 ID,对每个容器来说都是唯一的,我们可以通过容器 ID (一般不用写全)来查看对应的容器发生了什么。
首先,我们需要确认容器有在运行,可以通过sudo docker ps -a来查看,如果仅仅一个ps,只是看正在运行的容器。
CONTAINER ID: 容器 ID。
IMAGE: 使用的镜像。
COMMAND: 启动容器时运行的命令。
CREATED: 容器的创建时间。
STATUS: 容器状态。
状态有7种:
- created(已创建)
- restarting(重启中)
- running 或 Up(运行中)
- removing(迁移中)
- paused(暂停)
- exited(停止)
- dead(死亡)
PORTS: 容器的端口信息和使用的连接类型(tcp\udp)。
NAMES: 自动分配的容器名称。当我们创建一个容器的时候,docker 会自动对它进行命名。另外,我们也可以使用 --name 标识来命名容器.
在宿主主机内使用 docker logs 命令,查看容器内的标准输出,docker logs [ID或者名字] 可以查看容器内部的标准输出。
sudo docker logs 2b1b7a428627 也可以用名字
使用 docker stop 命令来停止容器,id或名字都可以。使用 docker start 启动一个已停止的容器,或者restart,正在运行的容器,我们可以使用 docker restart 命令来重启。删除容器使用 docker rm 命令。-f: 让 docker logs 像使用 tail -f 一样来输出容器内部的标准输出。可以一直增长的那种。
现在举一个例子,生成一个网络应用:
sudo docker pull training/webapp # 载入镜像,有没有都没关系
sudo docker run -d -P training/webapp python app.py
-P:将容器内部使用的网络端口随机映射到我们使用的主机上。
PORTS
0.0.0.0:32769->5000/tcp
Docker 开放了 5000 端口(默认 Python Flask 端口)映射到主机端口 32769 上。说明前面是主机端口。
我们也可以通过 -p 参数来设置不一样的端口:
sudo docker run -d -p 80:5000 training/webapp python app.py
使用 docker images 来列出本地主机上的镜像。
- REPOSITORY:表示镜像的仓库源
- TAG:镜像的标签
- IMAGE ID:镜像ID
- CREATED:镜像创建时间
- SIZE:镜像大小
镜像标签一般是镜像的版本号。我们使用 REPOSITORY:TAG 来定义不同的镜像。如果你不指定一个镜像的版本标签,例如你只使用 ubuntu,docker 将默认使用 ubuntu:latest 镜像。所以,我们如果要使用版本为15.10的ubuntu系统镜像来运行容器时,命令如下:
runoob@runoob:~$ docker run -t -i ubuntu:15.10 /bin/bash
镜像删除使用 docker rmi 命令,id,名字都可以。
如何根据容器生成镜像呢?
runoob@runoob:~$ docker commit -m="has update" -a="runoob" e218edb10161 runoob/ubuntu:v2
sha256:70bf1840fd7c0d2d8ef0a42a817eb29f854c1af8f7c59fc03ac7bdee9545aff8
各个参数说明:
- -m: 提交的描述信息
- -a: 指定镜像作者
- e218edb10161:容器 ID
- runoob/ubuntu:v2: 指定要创建的目标镜像名
可以制作自己的镜像仓库,实际上我们可以用Dockerfile代替。
FROM centos:6.7
MAINTAINER Fisher "fisher@sudops.com"
RUN /bin/echo 'root:123456' |chpasswd
RUN useradd runoob
RUN /bin/echo 'runoob:123456' |chpasswd
RUN /bin/echo -e "LANG=\"en_US.UTF-8\"" >/etc/default/local
EXPOSE 22
EXPOSE 80
CMD /usr/sbin/sshd -D
第一条FROM,指定使用哪个镜像源
RUN 指令告诉docker 在镜像内执行命令。
每一个指令都会在镜像上创建一个新的层,每一个指令的前缀都必须是大写的。
然后,我们使用 Dockerfile 文件,通过 docker build 命令来构建一个镜像。
docker build -t runoob/centos:6.7 ./
- -t :指定要创建的目标镜像名,注意我们只是在构建镜像。
- ./ :Dockerfile 文件所在目录,可以指定Dockerfile 的绝对路径,上下文路径,是指 docker 在构建镜像,有时候想要使用到本机的文件(比如复制),docker build 命令得知这个路径后,会将路径下的所有内容打包。这个时候无法用到我们本机的文件。这就需要把我们本机的指定目录下的文件一起打包提供给 docker 引擎使用。就好像挂载。
我们可以使用新的镜像来创建容器
sudo docker run -t -i runoob/centos:6.7 /bin/bash
下面先创建一个新的 Docker 网络。实际上这个网络是一个什么意思呢?就是一个局域网的关系。
sudo docker network create -d bridge test-net
-d:参数指定 Docker 网络类型,有 bridge、overlay。其中 overlay 网络类型用于 Swarm mode,在本小节中你可以忽略它。
这样查看 sudo docker network ls
运行一个容器并连接到新建的 test-net 网络:
sudo docker run -itd --name test1 --network test-net ubuntu /bin/bash
再运行一个容器并加入到 test-net 网络:
sudo docker run -itd --name test2 --network test-net ubuntu /bin/bash
实际上这个网络是一个什么意思呢?就是一个局域网的关系。这里这两个容器就可以相互ping了。直接ping 容器名
基本上就讲完了,下面说说dockerfile
最简单的:
FROM nginx
RUN echo '这是一个本地构建的nginx镜像' > /usr/share/nginx/html/index.html
以 && 符号连接命令,这样执行后,只会创建 1 层镜像。
RUN yum install wget \
&& wget -O redis.tar.gz "http://download.redis.io/releases/redis-5.0.3.tar.gz" \
&& tar -xvf redis.tar.gz
COPY
复制指令,从上下文目录中复制文件或者目录到容器里指定路径。
格式:[--chown=<user>:<group>]:可选参数,用户改变复制到容器内文件的拥有者和属组。
COPY [--chown=<user>:<group>] <源路径1>... <目标路径> 该路径不用事先建好,路径不存在的话,会自动创建。
CMD
为启动的容器指定默认要运行的程序,程序运行结束,容器也就结束。CMD 指令指定的程序可被 docker run 命令行参数中指定要运行的程序所覆盖。
注意:如果 Dockerfile 中如果存在多个 CMD 指令,仅最后一个生效。所以一般只是在最后放这个。其他用RUN
ENV
设置环境变量,定义了环境变量,那么在后续的指令中,就可以使用这个环境变量。以下示例设置 NODE_VERSION = 7.2.0 , 在后续的指令中可以通过 $NODE_VERSION 引用,在容器中也照样有用:
ENV NODE_VERSION 7.2.0
RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \
&& curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt.asc"
ARG
构建参数,与 ENV 作用一至。不过作用域不一样。ARG 设置的环境变量仅对 Dockerfile 内有效,也就是说只有 docker build 的过程中有效,构建好的镜像内不存在此环境变量。
VOLUME
定义匿名数据卷。在启动容器时忘记挂载数据卷,会自动挂载到匿名卷。或者说,是默认卷,因此这是很重要的。在启动容器 docker run 的时候,我们可以通过 -v 参数修改挂载点。
VOLUME ["<路径1>", "<路径2>"...]
VOLUME <路径>
EXPOSE
仅仅只是声明端口。
EXPOSE <端口1> [<端口2>...]
WORKDIR
指定工作目录。用 WORKDIR 指定的工作目录,会在构建镜像的每一层中都存在。(WORKDIR 指定的工作目录,必须是提前创建好的)。
docker build 构建镜像过程中的,每一个 RUN 命令都是新建的一层。只有通过 WORKDIR 创建的目录才会一直存在。或者说,就是镜像中的home。
格式:
WORKDIR <工作目录路径>
Docker Compose
这个东西说白了就是针对容器。dockerfile是针对镜像的。使用 docker-compose.yml 定义构成应用程序的服务,这样它们可以在隔离环境中一起运行。最后,执行 docker-compose up 命令来启动并运行整个应用程序。
运行以下命令以下载 Docker Compose 的当前稳定版本:
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
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
docker-compose --version
# yaml 配置
version: '3'
services:
web:
build: .
ports:
- "5000:5000"
redis:
image: "redis:alpine"
该 Compose 文件定义了两个服务:web 和 redis。或者说,两个容器。
- web:该 web 服务使用从 Dockerfile 当前目录中构建的镜像。然后,它将容器和主机绑定到暴露的端口 5000。此示例服务使用 Flask Web 服务器的默认端口 5000 。说明一个文件夹只能有一个dockerfile,除非你多设定几个文件夹。
- redis:该 redis 服务使用 Docker Hub 的公共 Redis 映像。
build:
context: ./dir
dockerfile: Dockerfile-alternate
这样的话,就可以设置多个dockerfile在一个文件夹了。
执行以下命令来启动应用程序:
docker-compose up
如果你想在后台执行该服务可以加上 -d 参数:
docker-compose up -d
command
覆盖容器启动的默认命令。
command: ["bundle", "exec", "thin", "-p", "3000"]
这个还是在dockerfile弄好就行了。或者说用image的时候。
container_name
指定自定义容器名称,而不是生成的默认名称。
container_name: my-web-container
depends_on
设置依赖关系。
- docker-compose up :以依赖性顺序启动服务。在以下示例中,先启动 db 和 redis ,才会启动 web。
- docker-compose up SERVICE :自动包含 SERVICE 的依赖项。在以下示例中,docker-compose up web 还将创建并启动 db 和 redis。
- docker-compose stop :按依赖关系顺序停止服务。在以下示例中,web 在 db 和 redis 之前停止。
version: "3.7"
services:
web:
build: .
depends_on:
- db
- redis
redis:
image: redis
db:
image: postgres
注意:web 服务不会等待 redis db 完全启动 之后才启动。
expose
暴露端口,但不映射到宿主机,只被连接的服务访问。
仅可以指定内部端口为参数:
expose:
- "3000"
- "8000"
image
指定容器运行的镜像。以下格式都可以:
image: redis
image: ubuntu:14.04
image: tutum/influxdb
image: example-registry.com:4000/postgresql
image: a4bc65fd # 镜像id
volumes
将主机的数据卷或着文件挂载到容器里。
version: "3.7"
services:
db:
image: postgres:latest
volumes:
- "/localhost/postgres.sock:/var/run/postgres/postgres.sock"
- "/localhost/data:/var/lib/postgresql/data"
这个实用啊。接下来是怎么用呢?执行 docker-compose up
如果你想在后台执行该服务可以加上 -d 参数:
docker-compose up -d
docker-compose down
理解成删除所有容器
docker-compose build
理解成在线更新