docker 入门
简介
Docker 是一种容器技术,他可以将应用和环境等进行打包,形成一个独立的,类似 iOS 的 APP 的应用,这个应用可以直接被分发到任意一个支持 Docker 的环境中,通过简单的命令即可启动运行。Docker 是一种最流行的容器化解决方案,Docker 可以让每个应用彼此相互隔离,在同一台机器上同时运行多个应用,不过他们彼此之间共享同一个操作系统
Docker 的功能就是将 Linux 中的代码打包,可以轻松的在服务器间进行迁移
术语
- host 宿主机
- image 镜像
- container 容器
- registry 仓库
- daemon 守护进程,用来接收命令
- client 客户端
1. Docker 基本概念
- 镜像,类似于一个完整的应用,每次重启运行都是独立的,不可以修改或者存储数据
- 容器,镜像运行时产生的实例,镜像可以多次运行产生多个容器,将容器内的操作和启动它的镜像合并就可以产生一个新的镜像
- 仓库,Docker 使用类似 git 的方式管理镜像,Docker Hub 是 Docker 提供的镜像中心,要使用一个镜像,需要先从远程的镜像注册中心拉取
2. 安装 Docker
Mac 安装
Ubuntu 下 安装
# 按照阿里云给出的文档
# step 1: 安装必要的一些系统工具
sudo apt-get update
sudo apt-get -y install apt-transport-https ca-certificates curl software-properties-common
# step 2: 安装GPG证书
curl -fsSL http://mirrors.aliyun.com/docker-ce/linux/ubuntu/gpg | sudo apt-key add -
# Step 3: 写入软件源信息
sudo add-apt-repository "deb [arch=amd64] http://mirrors.aliyun.com/docker-ce/linux/ubuntu $(lsb_release -cs) stable"
# Step 4: 更新并安装 Docker-CE
sudo apt-get -y update
sudo apt-get -y install docker-ce
Linux 下安装的 Docker 只允许 root 权限运行,一下是解法
# 修改用户组,将制定用户加入到 Docker 组中,使其获取权限不用再执行 sudo 命令
# mjz 就是要加入的用户
sudo usermod -aG docker mjz
# 重启 docker 服务
udo service docker restart
# 登入群组
newgrp - docker
3. 命令
可以查看镜像的地方 网易云镜像中心
0. 设置国内镜像源加速
国内网络环境 docker 官方资源库练级总是失败,这里使用阿里云提供的专属=镜像源
- 在阿里云’产品与服务’中找到容器镜像服务
- 选择镜像加速器,会在右侧提供一个镜像加速地址,和不同平台的配置方法
1. 拉取镜像
# NAME 就是要拉取镜像的名字
docker pull [OPTIONS] NAME[:TAG]
docker pull nginx:latest
2. 查看本机已下载镜像
# REPOSITORY 是指定的镜像的名称
docker images [OPTIONS] [REPOSITORY[:TAG]]
docker images nginx
3. 删除本机镜像
# -f 表示强制,否则会提示镜像被用过,不能删除
# f2a91732366c 是镜像 IMAGE ID 通过 docker images 查看
docker rmi -f f2a91732366c
docker rm 698b94b9ae6e # 这个命令是删除 容器记录的
4. 运行镜像生成容器(新建容器)
# 基本运行
docker run [OPTIONS] IMAGE[:TAG] [COMMAND] [ARG...]
docker run nginx
# 后台运行
docker run -d nginx # 会返回一个容器 ID 字符串
5. 查看本机正在运行的容器
# 列出正在运行的容器
docker ps
# 列出所有运行过的容器
docker ps -a
6. 在一个运行中的容器内运行命令
# CONTAINER 可以是容器名或者 容器ID
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
# 输入后会进入容器内的终端
docker exec -it 012bdff20070f204362ef4c1192ac03c13a13cfef611756a628b91533028632a bash
# 退出容器终端
exit # 直接输入 exit 即可
7. 停止容器运行
# 结束正在运行的容器
docker stop [CONTAINERID]
docker stop 012bdff20070f204362ef4c1192ac03c13a13cfef611756a628b91533028632a
# 虽然结束了运行,但是容易运行的记录还在可以通过下边命令查看
docker ps -a
# 清除某些容器运行的记录 698b94b9ae6e 就是容器ID
docker rm 698b94b9ae6e
# 清除全部容器记录
docker rm (docker ps -a -q)
8. 将已经停止运行的容器重新启动
docker run
会创建新的容器,如果希望重复使用可以使用docker start [containerID]
来重新运行已经停止的容器
# 在已经停止的容器列表中找到要重新运行的容器的ID
docker ps -al
# 重新运行容器,这个容器之前如果有更改,会显示更改后的内容
docker start c285b1f25615
8. 设置容器网络中端口对当前主机端口的映射
Docker 容器一般会被分配一个独立的网络命名空间,会虚拟出自己的网卡等网络环境,这个时候如果想在主机上访问到容器内的端口就需要 Bridge 桥接技术做一个映射,这个时候在主机上访问一个端口实际上就是访问容器中的一个端口
# -p 用来设置主机到容器的端口映射
docker run -d -p [HOSTPORT]:[CONTAINERPORT] nginx
# 访问 http://localhost:8081/ 即相当于访问 Docker 中的 nginx 服务
docker run -d -p 8081:80 nginx
9. 拷贝文件到镜像中
# 写一个简单的页面
vi index.html
# 拷贝 页面文件到指定容器的指定目录下
docker cp index.html 8a3ebf95f7cb://usr/share/nginx/html
# 更改后再次浏览器访问 http://localhost:8081/ 发现内容变成我们提交的内容了
# 再次根据同一个镜像开启一个容器
docker run -d -p 8082:80 nginx
# 访问 http://localhost:8082/ 发现上一个容器的变化,并没有影响到这里
# 终止所有容器,重新打开 8081 的 容器
docker stop 75ddf985d1ef
docker stop 3fb1949cefb7
docker run -d -p 8081:80 nginx
# 访问 http://localhost:8081/ 对某个容器的操作是暂时的不会影响到其他通过镜像创建的容器
4. 从容器中创建新镜像
镜像可以通过 Dockerfile 文件来配置创建,也可以在一个运行中的容器中创建
1. 运行镜像产生容器
# 执行完后 http://localhost:8081/ 显示的是 nginx 默认页面
docker run -d -p 8081:80 nginx
2. 对容器进行操作
# 替换 nginx 默认页,http://localhost:8081/ 会显示替换后的页面
docker cp index.html 4daa108105b9://usr/share/nginx/html
3. 从容器中创建一个新镜像
# 根据 ID 为 4daa108105b9 的容器创建 名为 nginx-test 的镜像
docker commit -m 'test' 4daa108105b9 nginx-test
docker images # 可以查看到 nginx-test 镜像
4. 新镜像测试
# 浏览器查看 http://localhost:8082/ 显示的是 替换后的默认页
docker run -d -p 8082:80 nginx-test
5. 通过 Dockerfile 制作自己的镜像
0. Dockerfile 语法
- FROM base image 基础镜像
- RUN 执行命令
- ADD 添加文件,可以是远程的
- COPY 拷贝文件
- CMD 执行命令
- EXPOSE 暴露端口
- WORKDIR 指定命令运行的路径
- MAINTAINER 镜像维护者
- ENV 为容器里边的环境设定环境变量
- ENTRYPOINT 设定容器入口
- USER 指定执行命令的用户
- VOLUME 指定容器所挂载的卷
RUN vs CMD : RUN 命令在 image 文件的构建阶段执行,执行结果会打包进入 image 文件;CMD 是在容器启动后执行,一个 Dockerfile 可以包含多个 RUN 命令,但是只能有一个 CMD 命令
1. 创建 Dockerfile 文件
vi Dockerfile
Dockerfile 内容
# 基础镜像的名字 就是下载镜像时的名字
from [基础镜像的名字]
MAINTAINER [所有者名字] [所有者邮箱]
# 将应用文件放在到镜像中
# ’拷贝到镜像中的位置‘ 不同的基础应用这个路径是不一样的,一般来讲 镜像资源中会有说明
COPY [文件] [拷贝到镜像中的位置]
# 以下是完整例子
from nginx
MAINTAINER mjz mjzhang1993@163.com
# 将 nginx 的默认页面替换为我们自定义的页面
COPY index.html /usr/share/nginx/html
2. 编写忽略文件 .dockerignore
排除要打包进 image 的文件
.git
node_modules
3. 根据 Dockerfile 生成镜像
docker build -t [镜像名]:[tag] path
docker build -t mjz-nginx:latest . # 注意最后的 path 当前目录 '.'
# docker images 查看当前镜像中就包含了刚才打包的镜像
docker images
4. 运行创建的镜像,生成容器
# 注意在这步之前要将运行在 8081 端口的应用停掉
docker run -d -p 8081:80 mjz-nginx
# 浏览器打开 http://localhost:8081/ 显示的就是我们更改后的 nginx 默认页面
6. Volume 持久化存储
提供一个独立于容器之外的持久化存储,并且容器与容器之间可以共享
1. 运行一个镜像,将他的部分挂载到一个卷
# 运行一个容器,将容器内的 /usr/share/nginx/html 目录挂载到某个卷
docker run -d -v /usr/share/nginx/html nginx
# inspect 检车这个容器 054db3b8566b 是容器 ID
docker inspect 054db3b8566b
# 在 返回的内容中 Mounts -> Source 找到挂载路径
2. 使用本地的一个指定目录挂载容器中的数据卷
# $PWD/html:/usr/share/nginx/html 就是将当前目录 $PWD 下的 html 文件夹 映射到 容器的 /usr/share/nginx/html 文件夹
docker run -p 8081:80 -d -v $PWD/html:/usr/share/nginx/html nginx
# 运行容器后发现本地多出 ./html 文件夹,在其中添加 index.html
vi html/index.html
# 浏览器访问 http://localhost:8081/ 发现现实的就是刚才更改的 index.html
这样我们只要在本地修改项目代码,就可以实现在 Docker 中查看变化
3. 创建一个用于分享的仅有数据的容器
# 创建数据文件夹
mkdir data
# 创建一个仅用于数据的容器 create 命令用于创建容器,但是不启动它
docker create -v $PWD/data:/var/mydata --name data_container ubuntu
# 运行一个新容器,将数据容器的数据卷加载到新容器中
docker run -it --volumes-from data_container ubuntu /bin/bash
# 在进入的命令行环境中进入 /var/mydata 文件夹,编辑文件后 exit 退出
touch new.txt
# 进入到本地 data 文件夹下发现已经出现 new.txt 文件
7. 镜像仓库 Registry
1. 搜索镜像
# 从仓库中搜索镜像
docker search nginx
# 从仓库中拉取镜像
docker pull nginx
# 创建自己的镜像(这里是直接 COPY 了 nginx 镜像)
docker tag nginx mjz/nginx # docker images 可以查看到 mjz/nginx 镜像
# 登录到镜像仓库
docker login
# 提交镜像到仓库
docker push mjz/nginx