# docker
docker将应用采用打包成image镜像的方法,运行container容器类,解决跨平台应用问题。
docker的思想来源于集装箱,隔离:Docker核心思想,打包装箱,每个箱子都是相互隔离的
水果 生化武器
docker通过**隔离**机制,可以将服务器利用到极致!
## docker的历史
在美国成立一家公司 ==dotcloud== ,做云服务,做linux的容器技术。
在容器技术出来之前,都是使用虚拟机技术!笨重!但每个电脑虚拟起来和真实差不多。
Docker容器技术也是一种虚拟化技术。
```
vm: linux centos原生镜像(一个电脑!) 隔离,需要开启多个虚拟机!
docker: 隔离,镜像(最核心的环境4M +jdk + mysql)十分小巧,运行镜像就可以了 秒启动!
```
> 聊聊docker
Docker是基于Go语言开发的!开源项目!
官网:https://www.docker.com/
文档地址:https://www.docs.docker.com/ Docker 文档超级详细
dockerHub地址:https://hub.docker.com/
## Docker能干嘛?
虚拟机技术缺点:
1. 资源占用非常多
2. 冗余步骤多
3. 启动很慢
> 容器化技术
比较Docker和虚拟机技术的不同:
- 传统虚拟机,虚拟出一条硬件,运行一个完整的操作系统,然后在这个系统上安装和运行软件
- 容器内的应用直接运行在宿主机的内核,容器是自己没有内核的,也没有虚拟硬件,就轻便了。(也就是容器只包含环境,多个容器公用一个内核)
- 每个容器间是互相隔离的,每个容器内都有自己的文件系统,互不影响。(不同的程序不用为了避免冲突而取舍环境)
> DevOps(开发、运维)
**更快速的交付和部署**
传统:一堆帮助文档,安装程序
Docker:打包镜像,发布测试,一键运行
**更便捷的升级和扩缩容**
使用了Docker之后,我们部署应用就和搭积木一样!(SpringBoot 1.5 Redis 5 Tomcat 8 升级后所有的程序都要适应升级)
项目打包为一个镜像,扩展 服务器A! 服务器B(一个docker可以一键运行很多个容器,且容器之间可以交互。)
**更简单的系统运维**
在容器化之后,我们的开发,运维都是高度一致的!
**更高效的计算资源利用**
Docker是内核级别的虚拟化,可以在一个物理机上运行很多的容器实例!服务器的性能可以被压榨到极致!
## Docker安装
### Docker的基本组成
<img src="94ede938693c360ba0142cd82e75c7e31603447380039.png" alt="94ede938693c360ba0142cd82e75c7e31603447380039" style="zoom:200%;" />
**镜像(image):**
docker镜像好比是一个模板,可以通过这个模板创建容器服务====>run=====>tomcat01容器(提供服务器),通过这个镜像可以创建多个容器(最终服务运行或者项目运行就是在容器中的)。
**容器(container):**
Docker利用容器技术,独立运行一个或者一组应用,通过镜像来创建的。
基本操作:启动,停止,删除
**仓库(repostory):**
仓库就是来存放镜像的地方!
仓库分为共有仓库和私有仓库!
镜像仓库:Docker Hub 阿里云 华为云 ....... 都有容器服务 需要配置镜像加速
### 安装Docker
> 环境准备
1. Ubuntu
2. 使用git bash登录
> 环境查看
```shell
#内核是3.10以上的
uname -r
5.8.0-43-generic
#系统版本
cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.04
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="Ubuntu 20.04.2 LTS"
```
> 安装和卸载
帮助文档 有各个系统的安装介绍
已经安装好就不赘述啦!
```shell
#1.安装docker前需要安装的依赖包:
yum install -y yum-utils device-mapper-persistent-data lvm2
#2.设置镜像的仓库,使用国内的阿里云
yum-config-manager \
--add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
#3.更新yum软件包索引
yum makecache fast
#4.安装docker doc-ce社区版 doc-ee企业版
yum install docker-ce docker-ce-cli containerd.io
#5.启动docker
systemctl start docker
#6.使用docker version查看是否安装成功
docker version
Client: Docker Engine - Community
Version: 20.10.7
API version: 1.41
Go version: go1.13.15
Git commit: f0df350
Built: Wed Jun 2 11:56:38 2021
OS/Arch: linux/amd64
Context: default
Experimental: true
Server: Docker Engine - Community
Engine:
Version: 20.10.7
API version: 1.41 (minimum version 1.12)
Go version: go1.13.15
Git commit: b0f5bc3
Built: Wed Jun 2 11:54:50 2021
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.4.9
GitCommit: e25210fe30a0a703442421b0f60afac609f950a3
runc:
Version: 1.0.1
GitCommit: v1.0.1-0-g4144b63
docker-init:
Version: 0.19.0
GitCommit: de40ad0
#7.测试docker
docker run hello-world
```
了解:卸载docker
```shell
#1.卸载资源
sudo apt-get purge docker-ce docker-ce-cli containerd.io
#2.删除资源
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd
```
### 阿里云镜像加速
1. 登录阿里云 “弹性计算->容器镜像服务”
![Screenshot (4)](Screenshot (4).png)
发现是收费的,这步省略。。。。
## 底层原理
Docker是怎么工作的?
Docker是一个client-server结构的系统,Docker的守护进程运行在主机上,通过Socket从客户端访问!
每个容器都会有自己的输出端口!
## 常用命令
### 显示详细信息
```shell
#显示docker详细信息
$ docker version
# 或者
$ docker info
#帮助命令
$ docker --help
```
### 镜像image和容器container命令
```shell
#查看所有镜像image
docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
hello-world latest d1165f221234 5 months ago 13.3kB
pytorch/pytorch 1.7.0-cuda11.0-cudnn8-runtime f8a1d10ae3d7 9 months ago 4.65GB
# 删除 image 文件
docker image rm [imageName]
#运行镜像image文件
docker container run hello-world
# 列出本机正在运行的容器
docker container ls
# 列出本机所有容器,包括终止运行的容器
docker container ls --all
#终止在运行的容器
docker container kill [containID]
#删除运行后生成的容器文件
docker container rm [containerID]
#退出但不停止容器
ctrl+ P + Q
#删除所有容器
docker rm -f $(docker container ls -aq)
#解释
-f 强制删除
-a 表示列出所有容器
-q 表示只列出id
```
### 常用其他命令
```shell
#后台启动容器
docker run -d 镜像名
#查看日志
docker logs -t -f --tail 日志数 容器id
#查看docker容器内部进程
docker top 容器id
#查看容器的全部信息,元数据
docker inspect 容器id
#进入当前正在运行的容器 方式1
docker exec -it 容器id /bin/bash
#方式2
docker attach 容器id #进入的是正在运行的命令行,不是交互模式
#从容器内拷贝文件到主机上,可以在容器外执行
docker cp 容器id:/home/test.c /home
#通过commit提交镜像
docker commit -m "提交信息" -a "作者" 容器id 目标镜像名:[TAG]
```
### 搜索/下载 镜像
```shell
docker search mysql
NAME DESCRIPTION STARS(收藏) OFFICIAL AUTOMATED
mysql MySQL is a widely used, open-source relation… 11236 [OK]
mariadb MariaDB Server is a high performing open sou… 4272 [OK]
#下载镜像 docker pull 镜像名[:tag]
docker pull hello-world
Using default tag: latest#不写tag默认是latest
latest: Pulling from library/hello-world
Digest: sha256:df5f5184104426b65967e016ff2ac0bfcd44ad7899ca3bbcf8e44e4461491a9e#签名
Status: Image is up to date for hello-world:latest
docker.io/library/hello-world:latest#真实地址
```
## 制作自己的Docker容器
```shell
$ git clone https://github.com/ruanyf/koa-demos.git
$ cd koa-demos
```
### 1. 编写DockerFile文件
首先,在项目的根目录下,新建一个文本文件`.dockerignore`,写入下面的[内容](https://github.com/ruanyf/koa-demos/blob/master/.dockerignore)。
上面代码表示,这三个路径要排除,不要打包进入 image 文件。
如果你没有路径要排除,这个文件可以不新建!
```shell
.git
node_modules
npm-debug.log
```
然后,在项目的根目录下,新建一个文本文件 Dockerfile,写入下面的[内容](https://github.com/ruanyf/koa-demos/blob/master/Dockerfile)。
```shell
FROM node:8.4
COPY . /app
WORKDIR /app
RUN npm install --registry=https://registry.npm.taobao.org
EXPOSE 3000
#解释
FROM node:8.4:该 image 文件继承官方的 node image,冒号表示标签,这里标签是8.4,即8.4版本的 node。
COPY . /app:将当前目录下的所有文件(除了.dockerignore排除的路径),都拷贝进入 image 文件的/app目录。
WORKDIR /app:指定接下来的工作路径为/app。
RUN npm install:在/app目录下,运行npm install命令安装依赖。注意,安装后所有的依赖,都将打包进入 image 文件。
EXPOSE 3000:将容器 3000 端口暴露出来, 允许外部连接这个端口。
```
### 2. 创建image文件
有了 Dockerfile 文件以后,就可以使用`docker image build`命令创建 image 文件了。
```
$ docker image build -t koa-demo .
# 或者
$ docker image build -t koa-demo:0.0.1 .
```
上面代码中,`-t`参数用来指定 image 文件的名字,后面还可以用冒号指定标签。如果不指定,默认的标签就是`latest`。最后的那个点表示 Dockerfile 文件所在的路径,上例是当前路径,所以是一个点。
如果运行成功,就可以看到新生成的 image 文件`koa-demo`了。
### 3. 生成容器
```shell
$ docker container run -p 8000:3000 -it koa-demo /bin/bash
# 或者
$ docker container run -p 8000:3000 -it koa-demo:0.0.1 /bin/bash
#解释
-p参数:容器的 3000 端口映射到本机的 8000 端口。
-it参数:容器的 Shell 映射到当前的 Shell,然后你在本机窗口输入的命令,就会传入容器。
koa-demo:0.0.1:image 文件的名字(如果有标签,还需要提供标签,默认是 latest 标签)。
/bin/bash:容器启动以后,内部第一个执行的命令。这里是启动 Bash,保证用户可以使用 Shell。
```
## docker网络
> 原理
我们每启动一个docker容器,docker都会给容器分配一个ip,只要我们安装了docker,就会有一个网卡docker0,使用桥接模式,使用evth-pair技术!
```shell
#使用交互模式启动容器,在最后可以执行一条任意命令
#我们ping 172.18.0.2,是另一台docker 容器,发现可以ping通
docker exec -it tomcat02 ping 172.18.0.2
```