docker练习---部署一个docker容器
1 docker原理
1.1 docker采用c/s架构, 使用cli与docker engine进行通信.
1.2 docker engine通过dockerfile构建容器,每个容器就是一些依赖包的安装.
tip: 个人理解(仅供参考)
实际docker engine做的事情就是, 1.执行一些命令; 2.设置一些全局变量; 3.构建虚拟文件系统. ------> 这里构建的就是一个image ------> docker build
当执行app时, 通过关联的WORKDIR, 将app打包到容器中, 组成container. ------> 这里构建的是一个container ------> docker run -it 新建并启动容器
dockerfile模板
FROM python:3.8 WORKDIR /app COPY requirements.txt ./ RUN pip install --no-cache-dir -r requirements.txt ENV PYTHONPATH="/app"
2. Docker实操
2.1 运行一个redis container
2.1.1. 搜索别人已经打包好的redis image
docker search redis
# 可以从搜索结果中找出redis的image叫什么名字.
2.2.2. 运行搜索到的redis
docker run -d redis
# 1. -d 表明是后台运行redis, 不会占用当前cli
# 2. 这里的redis是search结果里里image的Name
# 3. docker默认会使用image的最新版本,如果需要之前的版本,使用如下语法:
docker run -d redis:3.2
3. 查看在运行的容器
方法-1:
docker ps
方法-2:
docker inspect <friendly-name|container-id> # 查看详细的执行状态
方法-3:
docker logs <friendly-name|container-id> # 查看执行日志
4. 给container起名并绑定端口
docker run -d --name redisHostPort -p 6379:6379 redis:latest # -p <host-port>:<container-port>
docker run -d --name redisDynamic -p 6379 redis:latest # 绑定host的6379端口
docker port redisDynamic 6379 # 查看host的6379端口
5. 数据持久化
正常情况下删除或重启container,会导致数据丢失.
可以再run的时候, 通过-v参数( -v <host-dir>:<container-dir>), 把容器地址映射到host物理地址,从而持久化数据.
docker run -d --name redisMapped -v /opt/docker/data/redis:/data redis
6. 与container交互
一般是bash等shell程序
docker run ubuntu ps # 不支持交互的命令
docker run -it ubuntu bash # 支持交互的命令
2 部署静态页面
2.1. 创建Dockerfile
docker image都是基于一个base image创建的. 这个base image包含app的平台依赖.
docker image都是根据Dockerfile创建的, 而Dockerfile描述的是如何部署app的步骤.
FROM nginx:alpine # 定义base image COPY . /usr/share/nginx/html # 复制当前文件夹到container中的特定文件夹中
2.2. 建立docker image
2.2.1 使用docker CLI 执行Dockerfile中的每个命令
docker build -t <build-directory> .
docker build -t webserver-image:v1 # -t repository:tag
docker images # 查看当前host中的所有image
2.3 使用onbuild优化Dockerfile
ONBUILD描述的指令, 只有在当前image作为base image的情况下(即这个image作为FROM 写入其他Dockerfile中), 才能被执行.
FROM node:7 RUN mkdir -p /usr/src/app WORKDIR /usr/src/app ONBUILD COPY package.json /usr/src/app/ ONBUILD RUN npm install ONBUILD COPY . /usr/src/app CMD [ "npm", "start" ]
2.4 添加.dockerignore
Dockerfile会将某些工作目录复制到container中.
echo passwords.txt >> .dockerignore
2.5 数据容器data container
数据容器就是一个单独的容器,用来保存数据,常用的image是busybox.
docker create -v /config --name dataContainer busybox # -v选项表示这个container提供的文件位置供其他container使用
复制host的文件到container中
docker cp config.conf dataContainer:/config/
使用其他已登录的container访问这个data container
docker run --volumes-from dataContainer ubuntu ls /config # --volumes-from 会将数据容器 -v指定的路径 挂载到当前容器
导入/导出container
docker export dataContainer > dataContainer.tar # 导出为tar文件
docker import dataContainer.tar # 导入tar文件
2.6 不同container之间通信 --- 使用链接
2.6.1 新建一个redis container
docker run -d --name redis-server redis
2.6.2 创建上一个container的link
docker run --link redis-server:redis alpine env # --link container-name:alias # env 是输出所有环境变量
2.6.3 验证连接
docker run --link redis-server:redis alpine env
2.6.4 使用app连接上述redis
docker run -d -p 3000:3000 --link redis-server:redis katacoda/redis-node-docker-example
2.6.5 连接redis命令行
docker run -it --link redis-server:redis redis redis-cli -h redis
2.7 不同container之间通信 --- 使用网络
2.7.1 创建一个网络, 所有其他container可以使用这个网络通信
docker network create backend-network
2.7.2 运行container时, 指出使用哪个网络
docker run -d --name=redis --net=backend-network redis
2.7.3 与链接的区别
docker run --net=backend-network alpine env # 不会更新环境变量
docker run --net=backend-network alpine cat /etc/hosts # 不会更改container的hosts文件
2.7.4 DNS服务
docker中会有一个DNS服务, 所有container都是用这个DNS服务, 这个服务的IP为127.0.0.11, 并保存在 resolv.conf file
docker run --net=backend-network alpine cat /etc/resolv.conf
'''
nameserver 127.0.0.11
options ndots:0
'''
2.7.5 实操举例
docker network create frontend-network # 创建一个网络
docker network connect frontend-network redis # 将已存在的container链接到这个网络
docker run -d -p 3000:3000 --net=frontend-network katacoda/redis-node-docker-example # 执行其他container
2.7.6 关闭链接
docker network ls
docker network inspect frontend-network
docker network disconnect frontend-network redis # 关闭redis容器的network
上述第二个命令文本如下
[ { "Name": "frontend-network", "Id": "7cfb531f75e68ecd43bdc5da3762cab53036238607f15cdb7ca72158a70e0eaf", "Created": "2020-05-22T09:23:15.614138336Z", "Scope": "local", "Driver": "bridge", "EnableIPv6": false, "IPAM": { "Driver": "default", "Options": {}, "Config": [ { "Subnet": "172.20.0.0/16", "Gateway": "172.20.0.1" } ] }, "Internal": false, "Attachable": false, "Ingress": false, "ConfigFrom": { "Network": "" }, "ConfigOnly": false, "Containers": { "b94e2642f4e6110ad096be50c44b6fff50e02ba82a238accaefdf864fb2e3a32": { "Name": "sleepy_beaver", "EndpointID": "dc4f4dc6a65ae1ad9c8f8e39db38293c1b8fe1723ff1245cb61786578f574b1c", "MacAddress": "02:42:ac:14:00:03", "IPv4Address": "172.20.0.3/16", "IPv6Address": "" } }, "Options": {}, "Labels": {} } ]