分享程序网
首页
  • java
微服务
微前端
环境搭建
数据库
设计模式
算法
软件
解决问题
链接
首页
  • java
微服务
微前端
环境搭建
数据库
设计模式
算法
软件
解决问题
链接
  • 编程环境

    • JDK
    • maven
  • 常用服务

    • HFS
    • Tomcat
    • Nginx
    • MinIO
  • 容器

    • Docker

Docker

Docker基本概念

镜像(image):Docker 镜像(Image),就相当于是一个 root 文件系统。比如官方镜像 ubuntu:16.04 就包含了完整的一套 Ubuntu16.04 最小系统的 root 文件系统。

容器(container):镜像(Image)和容器(Container)的关系,就像是面向对象程序设计中的类和实例一样,镜像是静态的定义,容器是镜像运行时的实体。容器可以被创建、启动、停止、删除、暂停等。

仓库(Repository):仓库可看成一个代码控制中心,用来保存镜像,可以类比于Maven仓库。

我的阿里云镜像加速器地址

https://2i5funqv.mirror.aliyuncs.com

Linux安装docker

如果之前安装过旧版本的Docker,可以使用下面命令卸载:

yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-selinux \
                  docker-engine-selinux \
                  docker-engine \
                  docker-ce

添加阿里云仓库

yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

安装gcc相关

 yum -y install gcc
 yum -y install gcc-c++

安装yum工具

yum install -y yum-utils 

更新yum缓存

yum makecache

安装docker CE

yum install docker-ce docker-ce-cli containerd.io -y

查看docker版本

docker version

查看docker运行状态

systemctl status docker

启动docker

systemctl start docker

停止docker

systemctl stop docker

docker自动启动

# docker 服务开机自启动命令
systemctl enable docker.service
# 关闭docker 服务开机自启动命令
systemctl disable docker.service

常用命令

镜像常用命令

列出本地镜

docker images

搜索仓库MySQL镜像

docker search mysql

下载Redis官方最新镜像

相当于:docker pull redis:latest

docker pull redis

单个镜像删除

相当于:docker rmi redis:latest

docker rmi redis

删除本地全部镜像

docker rmi -f $(docker images -q)

删除镜像有时候输入docker images -a有很多为none的镜像,可能为空悬镜像,删除命令如下:

docker image prune
docker rmi $(docker images -f "dangling=true" -q)

可能删除不掉,显示unable to delete 镜像Id (cannot be forced) - image has dependent child images

docker image inspect --format='{{.RepoTags}} {{.Id}} {{.Parent}}' $(docker image ls -q --filter since=镜像Id)

然后从上到下依次删除

删除未运行的容器

docker rm $(docker ps --all -q -f status=exited)

docker查看日志

显示最后一百行日志

docker logs -f --tail=100 [CONTAILER_ID]

进入容器

使用run运行进入,可以使用ctrl+d退出,直接退出终端

docker run -it [CONTAILER_ID] /bin/bash

已经运行的docker进入

docker exec -it [CONTAILER_ID]  /bin/bash

上传文件至容器

docker cp 本地路径 [CONTAILER_ID]:容器路径

导出所有镜像

#!/bin/bash
docker save $(docker images --format '{{.Repository}}:{{.Tag}}') -o allinone.tar

导出单个镜像

docker save [IMAGE_ID]>docker.tar

导出单个容器

docker export [CONTAINER_ID] docker.tar

导入单个镜像

docker load < docker.tar

导入容器

docker load -i allinone.tar

导出脚本

#!/bin/bash

# 读取本地 "image:tag" 名称
IMG_NAME=`docker images | grep -v TAG | awk '{print $1":"$2}'`
# echo $IMG_NAME | awk '{gsub(/ /,"\n",$0)} {print $0}'
# 定义镜像存放目录
DIR="/data/docker/image_tar"
if [ ! -d "$DIR" ]; then
  echo -e "${DIR} 不存在"
  mkdir -p "$DIR"
  echo -e "${DIR} 已创建"
else
  echo -e "${DIR} 已存在"
fi
echo ""
for IMAGE in $IMG_NAME
do
  echo -e "正在保存 ${IMAGE}"
  SAVE_NAME=`echo $IMAGE | awk -F: '{print $1"_"$2}' | sed 's/\//_/g'`
  docker save $IMAGE -o ${DIR}/${SAVE_NAME}.tar
  echo -e "已保存到 ${DIR}/${SAVE_NAME}.tar"
  echo ""
done

导入脚本

#!/bin/bash

# 在此处填写镜像文件的保存目录
IMAGE_DIR="/data/docker/image_tar"

for IMAGE in `ls $IMAGE_DIR`
do
  echo -e "正在导入镜像 $IMAGE"
  docker load -i ${IMAGE_DIR}/${IMAGE}
  echo -e "已成功导入镜像 $IMAGE"
  echo ""
done

容器相关命令

https://www.cnblogs.com/eden-libinglin/p/13803729.html

新建并启动容器

  • -i 以交互模式运行容器;
  • -t 为容器重新分配一个伪输入终端;
  • –name 为容器指定一个名称;
  • -p 宿主机的端口映射到容器的端口;
  • -v 容器数据卷(作用:数据持久化)的使用,将容器上的指定目录挂载到宿主机的目录,从而可以实现数据的同步(删除容器并不会删除其挂载的数据卷)
docker run -i -t --name mycentos -p 9090:8080 -v /home:/usr/local
  • -d 已守护方式启动容器
docker run -d mycentos #后台启动容器
docker ps # 列出正在运行的容器
docker ps -a #列出所有容器(包括未运行的)
docker start redis # 启动已经被停止的容器redis
docker restart redis # 重启容器redis
docker top redis # 列出redis容器中运行进程
docker logs rabbitmq #查看redis容器日志,默认参数
docker run -it centos /bin/bash #使用run方式在创建时进入
exit #关闭容器并退出
docker attach centos #直接进入centos容器启动命令的终端,不会启动新进程
docker exec -it centos /bin/bash #在centos容器中打开新的交互模式终端,可以启动新进程
docker inspect redis #获取镜像redis的元信息
docker stop redis #停止一个运行中的容器
docker kill redis #杀掉一个运行中的容器
docker rm -f redis #删除一个容器
docker cp rabbitmq:/[container_path] [local_path] #将rabbitmq容器中的文件copy至本地路径

容器数据卷

docker有一个问题,就是将容器删除的话,数据就会丢失。但我们需要数据的持久化,要将数据存储到本地。容器之间可以有一个数据共享的技术,Docker容器中产生的数据,同步到本地。这就是卷技术,目录的挂载,将我们容器内的目录,挂载到Linux上面。

使用如上:docker run 后面加 -v aaa:bbb 表示指定卷挂载的目录,aaa表示宿主机目录,bbb表示容器目录,这种方式为指定路径挂载。当然还有如下两种挂载方式:

具名挂载和匿名挂载

三种挂载: 匿名挂载、具名挂载、指定路径挂载

  • -v 容器内路径 #匿名挂载

  • -v 卷名:容器内路径 #具名挂载

  • -v /宿主机路径:容器内路径 #指定路径挂载 docker volume ls 是查看不到的

    通过 docker volume ls 命令可以查看所有卷名。所有的docker容器内的卷,没有指定目录的情况下都是在宿主机 /var/lib/docker/volumes/xxxx/_data 目录下。

Dockerfile的编写

构建步骤:

  1. 编写一个dockerfile文件
  2. docker build 构建一个镜像
  3. docker run 运行镜像
  4. docker push 发布镜像(DockerHub、阿里云从仓库等)

Dockerfile 基础知识

1、每个指令都必须是大写字母;

2、执行顺序从上到下;

3、#表示注释;

4、每一个指令都会提交一个新的镜像层,并提交。

DockerFile常用指令

FROM # 基础镜像,一切从这里开始构建 
MAINTAINER # 镜像是谁写的, 姓名+邮箱 
RUN # 镜像构建的时候需要运行的命令 
ADD # 拷贝文件(支持正则表达式)到镜像,并自动解压(如果是压缩包) 
WORKDIR # 镜像的工作目录 
VOLUME # 挂载的目录 
EXPOSE # 保留端口配置 
CMD # 指定这个容器启动的时候要运行的命令,只有最后一个会生效,可被替代。 
ENTRYPOINT # 指定这个容器启动的时候要运行的命令,可以追加命令 
COPY # 类似ADD,将我们文件拷贝到镜像中 
ENV # 构建的时候设置环境变量!

例如:springboot的dockerFile例子

FROM java:8
EXPOSE 8081
MAINTAINER chengli/931209494@qq.com

VOLUME /tmp
ARG JAR_FILE
COPY target/${JAR_FILE} /app.jar
ENTRYPOINT ["./run.sh", "restart"]

docker-compose.yml运行docker

docker-compose.yml文件内容

version: "3"
services:
  manager:
    build:
      context: .
      dockerfile: Dockerfile
    # 镜像名称
    image: manager-ui
    ports:
      - 3334:80
    restart: always
    # 容器名称
    container_name: "manager-ui"

复制相关的文件,如果是前端,则拷贝

  • default.conf(nginx配置文件)
  • docker-compose.yml
  • Dockerfile(docker文件)
  • build(文件夹,npm run build的产物)

执行命令

docker-compose up --force-recreate --build -d

MAVEN推送Docker

先停用docker

docker stop [CONTAINER_ID]

删除停止运行的 docker

docker rm [CONTAINER_ID]

删除镜像

docker rmi [IMAGE_ID]
<plugin>
    <groupId>com.spotify</groupId>
    <artifactId>dockerfile-maven-plugin</artifactId>
    <version>1.4.13</version>
    <configuration>
        <repository>${project.artifactId}</repository>
        <tag>${project.version}</tag>
        <buildArgs>
            <JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
        </buildArgs>
    </configuration>
</plugin>
<!--使用docker-maven-plugin插件-->
<plugin>
    <groupId>com.spotify</groupId>
    <artifactId>docker-maven-plugin</artifactId>
    <version>1.2.0</version>
    <!--将插件绑定在某个phase执行-->
    <executions>
        <execution>
            <id>build-image</id>
            <!--用户只需执行mvn package ,就会自动执行mvn docker:build-->
            <phase>package</phase>
            <goals>
                <goal>build</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <!--覆盖相同标签镜像-->
        <forceTags>true</forceTags>
        <!--指定生成的镜像名-->
        <imageName>${project.artifactId}</imageName>

        <!-- 容器启动执行的命令,相当于dockerFile的ENTRYPOINT -->
        <baseImage>openjdk:8</baseImage>
        <entryPoint>["java","-jar","/${project.build.finalName}.jar"]</entryPoint>
        <exposes>
            <expose>8081</expose>
        </exposes>
        <maintainer>chengli/931209494@qq.com</maintainer>
        <volumes>
            <volume>/tmp</volume>
        </volumes>

        <!-- 指定 Dockerfile 路径-->
        <!--<dockerDirectory>${project.basedir}</dockerDirectory>-->
        <!--指定远程 docker api地址-->
        <dockerHost>http://192.168.124.12:2375</dockerHost>
        <buildArgs>
            <JAR_FILE>${project.build.finalName}.jar</JAR_FILE>
        </buildArgs>
        <!-- 这里是复制 jar 包到 docker 容器指定目录配置 -->
        <resources>
            <resource>
                <targetPath>/</targetPath>
                <!--jar 包所在的路径  此处配置的 即对应 target 目录-->
                <directory>${project.build.directory}</directory>
                <!-- 需要包含的 jar包 ,这里对应的是 Dockerfile中添加的文件名 -->
                <include>${project.build.finalName}.jar</include>
            </resource>
        </resources>
    </configuration>
</plugin>

package之后再去docker环境中执行

docker run -d -p 8081:8081 --name [取得别名] --restart always [IMAGE_ID]
Last Updated:
Contributors: chengli