内容简介:docker 实战 + 各种操作小抄。数据卷的本质其实依然是宿主操作系统上的一个目录,只不过这个目录存放在 Docker 内部,接受 Docker 的管理。通常我们不会从零开始搭建一个镜像,而是会选择一个已经存在的镜像作为我们新镜像的基础。
docker 实战 + 各种操作小抄。
开始
名词解释
-
Image(镜像)
docker commit ContainerID TAG
-
Container(容器)
- 镜像类比为类的话,容器就是类的实例
-
Volume(数据卷)
- Volume 是专门存放数据的文件夹,启动 Image 时可以挂在一个或者多个 Volume,Volume 中的数据独立于 Image,重启不会丢失
-
Network(网络)
-
在 Container 中运行服务监听
127.0.0.1:8080
,在自己的机器访问127.0.0.1:8080
是无法访问的 -
Container 的 IP 通常是
192.168.99.100
,只能被宿主机访问。但只关联了 IP,要想访问端口需要手动配置端口映射,把 Container 内部端口映射到 IP 上
-
在 Container 中运行服务监听
安装 docker
# Mac https://docs.docker.com/docker-for-mac/install/ # CentOS https://docs.docker.com/install/linux/docker-ce/centos/ sudo yum install yum-utils device-mapper-persistent-data lvm2 sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo yum install docker-ce sudo systemctl enable docker sudo systemctl start docker
portainer
# 安装 https://portainer.readthedocs.io/en/stable/deployment.html#quick-start # 文档 https://portainer.readthedocs.io/en/stable/
使用
镜像
常用命令
# 列出本机的所有 image 文件。 # username/repository:tag docker image ls # 删除 image 文件 docker image rm [IMAGE ID] # 删除所有 image 文件 docker system prune -a
从仓库获得镜像
# 搜索镜像 docker search ubuntu # 拉取镜像 docker pull ubuntu
容器
生命周期
- Created:容器已经被创建,容器所需的相关资源已经准备就绪,但容器中的程序还未处于运行状态
- Running:容器正在运行,也就是容器中的应用正在运行
- Paused:容器已暂停,表示容器中的所有程序都处于暂停 ( 不是停止 ) 状态
- Stopped:容器处于停止状态,占用的资源和沙盒环境都依然存在,只是容器中的应用程序均已停止
- Deleted:容器已删除,相关占用的资源及存储在 Docker 中的管理信息也都已释放和移除
启动容器
# 拉取镜像 docker pull nginx:1.12 # 创建容器 docker create --name nginx nginx:1.12 # 启动容器 docker start nginx # run 同时创建和启动,-d 是在后台运行 # docker run --name nginx -d nginx:1.12
管理容器
# 查看所有容器 docker container ls -a # 删除容器 docker container rm -f [CONTAINER ID] # 查看容器状态 docker inspect [NAME]
进入容器
docker exec -it nginx bash
容器互联
# 通过 docker create 或 docker run 时通过 --link 选项进行配置 docker run -d --name mysql -e MYSQL_RANDOM_ROOT_PASSWORD=yes mysql docker run -d --name webapp --link mysql webapp:latest # 连接方式 String url = "jdbc:mysql://mysql:3306/webapp";
暴露端口
# 在容器创建时使用 --expose 进行定义,不暴露的端口不能访问 docker run -d --name mysql -e MYSQL_RANDOM_ROOT_PASSWORD=yes --expose 13306 --expose 23306 mysql:5.7
端口映射
# 在创建容器时使用 -p 创建端口映射 docker run -d -p 80:80 -p 443:443 nginx
数据管理
- 沙盒文件系统是跟随容器生命周期所创建和移除的,数据无法直接被持久化存储
- 由于容器隔离,我们很难从容器外部获得或操作容器内部文件中的数据
挂载宿主文件
# -v <host-path>:<container-path> 读写挂载 docker run --name nginx -d -p 80:80 -v ~/static/:/usr/share/nginx/html nginx # -v <host-path>:<container-path>:ro 以只读挂载 docker run --name nginx -d -p 80:80 -v ~/static/:/usr/share/nginx/html:ro nginx
Volume
数据卷的本质其实依然是宿主操作系统上的一个目录,只不过这个目录存放在 Docker 内部,接受 Docker 的管理。
使用数据卷
# 创建数据卷 docker volume create appdata # 使用数据卷 docker run -d --name webapp -v appdata webapp:latest docker run -d --name nginx -v appdata nginx # 删除没有被容器引用的数据卷 docker volume prune -f
备份与迁移
# 可以在 /backup 下找到数据卷的备份文件,也就是 backup.tar docker run --rm --volumes-from appdata -v /backup:/backup ubuntu tar cvf /backup/backup.tar /webapp/storage # 恢复备份 docker run --rm --volumes-from appdata -v /backup:/backup ubuntu tar xvf /backup/backup.tar -C /webapp/storage --strip
保存和共享镜像
# 将容器修改的内容保存为新的镜像 docker commit -m 'costom config' nginx # 为新的镜像命名 docker tag [IMAGE ID] nginx_new # 导出新的镜像 docker save -o ./nginx_new.tar nginx_new # 导入镜像 docker load < nginx_new.tar # 批量导出 # docker save -o ./images.tar webapp:1.0 nginx:1.12 mysql:5.7
Dockerfile
例子
# 该 image 文件继承官方的 node image,冒号表示标签,这里标签是 8.4,即 8.4 版本的 node。 FROM node:8.4 # 将当前目录下的所有文件(除了.dockerignore排除的路径),都拷贝进入 image 文件的/app目录。 COPY . /app # 指定接下来的工作路径为/app。 WORKDIR /app # 在/app目录下,运行npm install命令安装依赖。注意,安装后所有的依赖,都将打包进入 image 文件。 RUN npm install --registry=https://registry.npm.taobao.org # 将容器 3000 端口暴露出来, 允许外部连接这个端口。 EXPOSE 3000
常用指令
FROM
通常我们不会从零开始搭建一个镜像,而是会选择一个已经存在的镜像作为我们新镜像的基础。
FROM <image> [AS <name>] FROM <image>[:<tag>] [AS <name>] FROM <image>[@<digest>] [AS <name>]
RUN
RUN 命令在 image 文件的构建阶段执行,执行结果都会打包进入 image 文件
RUN <command> RUN ["executable", "param1", "param2"]
ENTRYPOINT 和 CMD
基于镜像启动的容器,在容器启动时会根据镜像所定义的一条命令来启动容器中进程号为 1 的进程。而这个命令的定义,就是通过 Dockerfile 中的 ENTRYPOINT 和 CMD 实现的。
ENTRYPOINT ["executable", "param1", "param2"] ENTRYPOINT command param1 param2 CMD ["executable","param1","param2"] CMD ["param1","param2"] CMD command param1 param2
EXPOSE
通过 EXPOSE 指令为镜像指定要暴露的端口
EXPOSE <port> [<port>/<protocol>...]
VOLUME
制作镜像的人是最清楚镜像中程序工作的各项流程的,所以它来定义数据卷也是最合适的。所以在 Dockerfile 里,提供了 VOLUME 指令来定义基于此镜像的容器所自动建立的数据卷。
在 VOLUME 指令中定义的目录,在基于新镜像创建容器时,会自动建立为数据卷,不需要我们再单独使用 -v 选项来配置了。
VOLUME ["/data"]
COPY 和 ADD
使用 COPY 或 ADD 指令能够帮助我们直接从宿主机的文件系统里拷贝内容到镜像里的文件系统中。
COPY [--chown=<user>:<group>] <src>... <dest> ADD [--chown=<user>:<group>] <src>... <dest> COPY [--chown=<user>:<group>] ["<src>",... "<dest>"] ADD [--chown=<user>:<group>] ["<src>",... "<dest>"]
COPY 与 ADD 指令的定义方式完全一样,需要注意的仅是当我们的目录中存在空格时,可以使用后两种格式避免空格产生歧义。
对比 COPY 与 ADD,两者的区别主要在于 ADD 能够支持使用网络端的 URL 地址作为 src 源,并且在源文件被识别为压缩包时,自动进行解压,而 COPY 没有这两个能力。
虽然看上去 COPY 能力稍弱,但对于那些不希望源文件被解压或没有网络请求的场景,COPY 指令是个不错的选择。
构建镜像
docker build 可以接收一个参数,需要特别注意的是,这个参数为一个目录路径 ( 本地路径或 URL 路径 ),而并非 Dockerfile 文件的路径。在 docker build 里,这个我们给出的目录会作为构建的环境目录,我们很多的操作都是基于这个目录进行的。例如,在我们使用 COPY 或是 ADD 拷贝文件到构建的新镜像时,会以这个目录作为基础目录。
在默认情况下,docker build 也会从这个目录下寻找名为 Dockerfile 的文件,将它作为 Dockerfile 内容的来源。
在构建时我们最好总是携带上 -t 选项,用它来指定新生成镜像的名称。
docker build -t webapp:latest ./webapp
实用技巧
构建时变量
# --build-arg 制定参数 docker build --build-arg TOMCAT_MAJOR=8 --build-arg TOMCAT_VERSION=8.0.53 -t tomcat:8.0 ./tomcat
FROM debian:stretch-slim # 声明参数 ARG TOMCAT_MAJOR ARG TOMCAT_VERSION # 使用参数 RUN wget -O tomcat.tar.gz "https://www.apache.org/dyn/closer.cgi?action=download&filename=tomcat/tomcat-$TOMCAT_MAJOR/v$TOMCAT_VERSION/bin/apache-tomcat-$TOMCAT_VERSION.tar.gz"
环境变量
FROM debian:stretch-slim # 环境变量设置的实质,其实就是定义操作系统环境变量 # 在运行的容器里,一样拥有这些变量,而容器中运行的程序也能够得到这些变量的值 ENV TOMCAT_MAJOR 8 ENV TOMCAT_VERSION 8.0.53 RUN wget -O tomcat.tar.gz "https://www.apache.org/dyn/closer.cgi?action=download&filename=tomcat/tomcat-$TOMCAT_MAJOR/v$TOMCAT_VERSION/bin/apache-tomcat-$TOMCAT_VERSION.tar.gz"
构建缓存
# 默认开启缓存,可以通过 --no-cache 禁用 docker build --no-cache ./webapp
.dockerignore
.git node_modules npm-debug.log
上面代码表示,这三个路径要排除,不要打包进入 image 文件。
Docker Compose
Dockerfile 是将容器内运行环境的搭建固化下来,Docker Compose 可以理解为将多个容器运行的方式和配置固化下来。
安装
# 下载 sudo curl -L "https://github.com/docker/compose/releases/download/1.22.0/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose # 增加可执行权限 sudo chmod +x /usr/local/bin/docker-compose # 检查是否安装成功 sudo docker-compose version # 也可以通过 pip 安装 # sudo pip install docker-compose
编写配置
docker-compose.yml
version: '3' # 制定 docker compose 版本 services: # service 作为配置最小单元 webapp: build: ./image/webapp ports: - "5000:5000" volumes: - ./code:/code - logvolume:/var/log links: - mysql - redis redis: image: redis:3.2 mysql: image: mysql:5.7 environment: - MYSQL_ROOT_PASSWORD=my-secret-pw volumes: logvolume: {}
启动停止
# 启动,和 run 一样,默认在前台运行,需要加 -d docker-compose up -d # 停止,停止所有的容器,并将它们删除,同时消除网络等配置内容 docker-compose down
常用配置
制定镜像
# 通过 image 制定镜像 redis: image: redis:3.2 # 通过 Dockerfile 构建镜像 webapp: build: context: ./webapp dockerfile: webapp-dockerfile args: - JAVA_VERSION=1.6
依赖声明
如果我们的服务间有非常强的依赖关系,我们就必须告知 Docker Compose 容器的先后启动顺序。只有当被依赖的容器完全启动后,Docker Compose 才会创建和启动这个容器。
webapp: depends_on: - redis - database
文件挂载
nginx: image: nginx:1.12 volumes: - ./nginx/nginx.conf:/etc/nginx/nginx.conf:ro - ./nginx/conf.d:/etc/nginx/conf.d:ro - ./webapp/html:/webapp/html
使用数据卷
想把属于 Docker Compose 项目以外的数据卷引入进来直接使用,我们可以将数据卷定义为外部引入,通过 external 这个配置就能完成这个定义。
volumes: mysql-data: external: true
配置网络
webapp: build: ./webapp networks: - frontend - backend nginx: image: nginx:1.12 networks: - frontend
端口映射
nginx: ports: - "80:80" - "443:443"
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Apache源代码全景分析第1卷
2009-5 / 88.00元
《Apache源代码全景分析第1卷:体系结构与核心模块》是“Apache源代码全景分析”的第1卷。书中详细介绍了Apache的基础体系结构和核心模块的实现机制,包括配置文件、模块化结构、多任务并发,以及网络连接和请求读取,其中多任务并发体系结构是《Apache源代码全景分析第1卷:体系结构与核心模块》分析的重点,讨论了Prefork、Worker及WinNT三种MPM。《Apache源代码全景分析......一起来看看 《Apache源代码全景分析第1卷》 这本书的介绍吧!