docker学习总结

## 什么是docker

### 定义

官网:https://www.docker.com/

> Docker is an open platform for developing, shipping, and running applications. Docker enables you to separate your applications from your infrastructure so you can deliver software quickly

image-20220503203848393.png

### 它是基于什么实现



### 什么是image与container

image可以理解为部署模板(对应为Java的class文件)、container可以理解为一个个运行实例对象(Java对象)。**一个image可以生成多个对象**。

Image的构成图如下所示、本质是一层层的Layer叠加而成

layer.png

image构成.png

在服务端内,如果image存在会变换成为Containers,若不存在则会去远程仓库获取。

运作流程如下图所示:

img

## 如何安装docker

**Docker依赖于系统的一些必要工具 ** 

```bash
$ yum install -y yum-utils device-mapper-persistent-data lvm2
```

Device Mapper 是 Linux2.6 内核中支持逻辑卷管理的通用设备映射机制,

device-mapperpersistent-data 和 lvm2 是Device Mapper存储驱动程序必须要的工具

* device-mapper-persistent-data : 存储驱动管理
* lvm2: 逻辑卷管理  

**设置Docker安装的yum源 **

```bash
$ yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
```

**安装Docker**

```bash
$ yum clean all
# 更新 yum 缓存
$ yum makecache fast 
# 安装docker-ce
$ yum -y install docker-ce 
```

**启动Docker**(systemctl与service的区别)

```bash
$ systemctl start docker
## 设置为开机启动
$ systemctl start docker.service
$ systemctl enable docker.service
```

## Docker常用命令

```bash
## 帮助命令
$ docker --help
$ docker run --help

## 查看已安装的镜像
$ docker images 

## 搜索存在的镜像服务
$ docker search hadoop

## 删除本地镜像,如果ID相同,则用第二种方式通过名字:targ的方式进行删除
$ docker rmi [IMAGE ID]
$ docker rmi [REPOSITORY:TAG]
## 删除本地镜像为的。
$ docker images|grep none|awk '{print $3}'|xargs docker rmi
## 删除所有处于Exited状态的容器。
$ docker rm `docker ps -a|grep Exited|awk '{print $1}'`

## 启动镜像registry.cn-chengdu.aliyuncs.com/zvan/qionglai/data_center/web:dev,并命名为helloword
## docker run相当于执行了两步操作:
## 将镜像放入容器中(docker create)
## 将容器启动,使之变成运行时容器(docker start)
## docker run [OPTIONS] IMAGE名称
$ docker run -d --name=helloword registry.cn-chengdu.aliyuncs.com/zvan/qionglai/data_center/web:dev
## jdkx86v8是images的名称 jdk是容器名称
$ docker run -d -it --name jdk jdkx86v8
$ docker run -d -it --name rtsp-server rtsp-server
## 若此前该进行已经执行过run命令、则可以通过start、restart、stop进行相应的操作
$ docker start/restart/stop #{containerid}

## 查看当前容器列表
$ docker ps

## 查看容器(运行起来的镜像)、docker container ls 是新的方法 旧方法-》docker ps
$ docker container ls

## 查案所有容器的情况
$ docker container ls -a

## 查看某个容器的详细信息。
$ docker container inspect #{containerid}
$ docker inspect #{containerid}

## 查看容器的执行日志
$ docker logs -f #{containerid}

## 根据上一步查到的容器ID,进入到容器内部
## docker exec -it #{containerid} /bin/bash ,若想退出输入exit即可。
## -i :即使没有附加也保持STDIN 打开
## -t :分配一个伪终端
$ docker exec -it 525a40d2797f /bin/bash
## 针对基础系统为alpine的情况使用
$ docker exec -it #{containerid} /bin/sh
## 查看文件
$ docker exec  b7cac2fff72d more /etc/nginx/conf.d/default.conf

## 关闭容器
## docker kill #{containerid}
$ docker kill b7cac2fff72d

## 暂时关闭 表示60秒后自动恢复
$ docker stop -t=60 容器ID或容器名

## 删除容器
## docker rm #{containerid}
$ docker rm b7cac2fff72d

## 从容器内将文件复制出来
$ docker cp aivs-supervisor:/app/filename.dump ./

## 针对镜像的导入导出(docker load/docker save)
## 需要注意如果用这种方式,将导致load的时候,显示信息全为
$ sudo docker save --output=algorithm.tar 04d829060404
## 推荐方式
$ sudo docker save --output=algorithm.tar #{imagename}:#{version}
## 导入:
$ docker load --input=algorithm.tar
# 重命名
$ docker tag #{imageId} algorithm

## 将容器导出成文(docker import/docker export)
$ docker export -o #{containerid} > xxxx.tar
$ docker import 
```

## 如何创建一个自己的镜像并发布到云仓库

通过:https://github.com/docker-library,可以查看到官方镜像是如何构建。

注意:Docker的内部的网络地址一般推荐使用0.0.0.0

构建镜像的方式有两种

1. 基于DockerFile
2. 基于已有容器,完成调整后通过docker commit #{容器名称} #{新镜像名称} 生成新镜像

### DockerFile语法说明

FROM
指定基础镜像,比如FROM ubuntu:14.04


RUN
在镜像内部执行一些命令,比如安装软件,配置环境等,换行可以使用""

```dockerfile
RUN groupadd -r mysql && useradd -r -g mysql mysql
```


ENV
设置变量的值,可以通过docker run --e key=value修改,后面可以直接使用${MYSQL_MA_JOR}

```dockerfile
ENV MYSQL_MA_JOR 5.7
```


LABEL

```dockerfile
LABEL email="[email protected]"
LABEL name="itcrazy2016"
```


VOLUME
指定容器数据挂在宿主的哪个目录、例如:VOLUME /var/lib/mysql

```bash
# 挂载多个
VOLUME ["/dataVolumeContainer001","/dataVolumeContainer002","/dataVolumeContainer003"]

# 挂载某个
VOLUME /var/lib/mysql
```


COPY
将主机的文件复制到镜像内,如果目录不存在,会自动创建所需要的目录,注意只是复制,不会提取和
解压。COPY docker-entrypoint.sh /usr/local/bin/


ADD
将主机的文件复制到镜像内,和COPY类似,只是ADD会对压缩文件提取和解压

ADD application.yml /etc/itcrazy2016/


WORKDIR
指定镜像的工作目录,之后的命令都是基于此目录工作,若不存在则创建

```dockerfile
WORKDIR /usr/local
WORKDIR tomcat
RUN touch test.txt
WORKDIR /root
ADD app.yml test/
```


CMD
容器启动的时候默认会执行的命令,若有多个CMD命令,则最后一个生效

CMD ["mysqld"] 或 CMD mysqld 


ENTRYPOINT
和CMD的使用类似,示例:ENTRYPOINT ["docker-entrypoint.sh"],和CMD的不同
docker run执行时,会覆盖CMD的命令,而ENTRYPOINT不会 

EXPOSE 
指定镜像要暴露的端口,启动镜像时,可以使用-p将该端口映射给宿主机

```dockerfile
EXPOSE 3306 
```

### 建Image的步骤

#### 编写Dockerfile

```plain
FROM registry.cn-chengdu.aliyuncs.com/zvan/java8-jre:latest

RUN mkdir /app

RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai  /etc/localtime
## 需要注意 dataCenter.jar的路径是相对路径,是从DockerFile的所在位置来计算。不能写绝对的。
COPY dataCenter.jar /app/dataCenter.jar

CMD ["java","-Xms256m","-Xmx2048m","-Dspring.profiles.active=dev","-Duser.timezone=GMT+08","-jar","/app/dataCenter.jar"]

ENV LANG C.UTF-8
FROM nginx
RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai  /etc/localtime
ADD  dist /app/datacenter/web
COPY Docker/nginx-docker-dev.conf  /etc/nginx/conf.d/default.conf
```

#### 开始构建

如下所示:

```bash
## 默认使用当前路径下的Dockerfile进行构建镜像
docker build -t data_center:v1.0 .

## 如果出现如下报错需要将 DockerFile重命名为Dockerfile
$ docker build -t test:v1.0 .
unable to prepare context: unable to evaluate symlinks in Dockerfile path: lstat /home/dockerImage/Dockerfile: no such file or directory

## 出现这个报错的时候,采用docker build -t data_center:v1.0 ..试试
COPY failed: file not found in build context or excluded by .dockerignore: stat entrypoint.sh: file does not exist
```

注意:

- 构建的镜像在运行起来以后,将形成容器
- build的文件名称均需要为小写。

### 本地编译镜像并推送到远程仓库示例

```bash
# 重命名
$ docker tag #{镜像名称} #{镜像别名}
示例:docker tag test ruby/test:v1.0
#!/bin/bash
#docker仓库地址
REGISTRY_HOST="registry.cn-chengdu.aliyuncs.com"
#命名空间_攀西项目
NAME_SPACE="zvan"
PROJECT_NAME="data_center"
CI_COMMIT_REF_NAME="dev"
#系统镜像,阿里云的进行是仓库地址+命名空间+镜像地址组成。
#名称不满足规则时,需要通过tag重命名
SERVER_IMAGE=$REGISTRY_HOST/$NAME_SPACE/$PROJECT_NAME/server:$CI_COMMIT_REF_NAME
WEB_IMAGE=$REGISTRY_HOST/$NAME_SPACE/$PROJECT_NAME/web:$CI_COMMIT_REF_NAME

echo $REGISTRY_HOST

echo '构建Docker容器'

# 以用户名密码的方式登录阿里云,主要是应对公司的私有云配置。
# --password可以用--password-stdin进行替换,相对更加安全。
# 如果不输入密码的话一般是默认登录到官方仓库(hub.docker)
docker login --username=cdzvan --password=docker123456 $REGISTRY_HOST


echo '构建前端Docker'
docker build  -t $WEB_IMAGE -f WebDockerFile .

echo '构建后端Docker'
docker build  -t $SERVER_IMAGE -f DockerFileDev .

echo '推送镜像'

docker push $SERVER_IMAGE
docker push $WEB_IMAGE
```

## 问题收集

你可能感兴趣的:(docker,学习,java)