Docker学习之路系列(1)

144 阅读6分钟

软件部署的问题

Linux容器: 不是模拟一个完整的操作系统,而是对进程进行隔离。或者说,在正常进程外面套了一个保护层。对于容器里面的进程来说,他接触到的各种资源都是虚拟的,从而与底层系统隔离。

- 启动快
- 资源占用少
- 体积小

Docker是什么

Docker属于Linux容器的一种封装, 提供简单易用的容器使用接口,它是目前最流行的Linux解决方案。

Docker将应用程序与该程序的依赖,打包在一个文件里面。运行这个文件,就会生成一个虚拟容器,程序在这个虚拟容器里运行,就好像在真实的物理机上一样。Docker和KVM 启动时间 :Docker秒级启动,KVM分钟启动 轻量级: 容器镜像通常以M为单位,虚拟机以G为单位,容器资源占用小,要比虚拟要部署更快速。

- 容器共享主机内核,系统级虚拟化,占用资源少,容器性能基本接近物理机
- 虚拟机需要虚拟化一些设备,具有完整的OS,虚拟机开销大,因而降低性能,没有容器性能好
- 安全性: 由于共享宿主内核,只是进程隔离,因此隔离性和稳定性不如虚拟机,容器具有一定权限访问宿主内核,存在安全隐患
-  使用要求
	- KVM基于硬件的完全虚拟化,需要硬件CPU虚拟化技术支持
	- 容器共享宿主内核,可运行在主机的Linux的发行版,不用考虑CPU是否支持虚拟化技术

docker应用场景

- 节省项目环境部署时间
- 单项目打包
- 整套项目打包
- 新开源技术
- 环境一致性  jenkins  ci cd
- 持续集成
- 微服务
- 弹性伸缩

docker run --rm -it ubuntu /bin/bash

What is a container ? Simply put, a container is simply another process on you machine that has been isolated from all other processes on the host machine.The isolation leverages kernel namespaces and cgroups, features that has been in Linux for a long time.Docker has worked to make these capalities approachable and easy to use. What is a container image? When running a container, it uses an isolated filesystem. This custom filesystem is provided by a container image.Since the image contains the contain's filesystem, it must contain everything needed to run an application - all dependencies, configuration, scripts,binaries,etc.The image alse contains other configuration for the container, suce as environment variavbles, a default command to run , and other metadata

应用实例

创建容器镜像(以node小项目距离)

1、 在根目录创建一个名为Dockerfile的文件,输入一下内容

FROM node:12-alpine
WORKDIR /app
COPY . .
RUN yarn install --production
CMD ["node", "src/index.js"]

请检查Dockerfile没有像.txt一样的后缀,有些编辑器会自动添加后缀导致接下来步骤的错误

2、 接下来使用docker build命令创建镜像

docker build  -t gettting-started .

这个命令使用Dockerfile来创建新的容器镜像。你可能已经注意到许多“layers”层被下载下来了。这是因为我们指定了构建生成器从node:12-alpine镜像开始构建。但是,在我们机器上没有这个环境,因而这个Image需要被下载。

在镜像被下载之后, 在应用中完成拷贝,并且使用yarn来安装我们应用的依赖 。这个CMD指令描述了从这个镜像起一个容器时执行的命令

最后,-t标识了我们的镜像,它为我们最后的镜像起了一个起了个可读的名字。当我们要起这个容器的时候,我们可以通过getting-started名字来查找

最后结尾的.命令告诉容器应该在当前目录中查找DockerFile

起一个应用容器(Starting an App Container)

现在我们已经有了一个镜像,让我们运行起来吧。为了完成这个操作,我们使用docker run指令

1、 使用docker run命令并且指定我们刚才创建镜像后的命名来启动我们的容器 docker run -dp 3000:3000 getting-started 还记得-d 和 -p标识吗?我们在新容器的后端开启了独立模式,并且创建了一个从主机3000端口到容器3000端口的映射。没有端口映射,我们无法访问到这个应用。

2、几秒钟之后,我们可以在localhost:3000的网址上看到我们的应用。而在下面的容器图上可以看到已经运行的容器

更新我们的App

1、 在应用中做些许修改

2、 让我们使用之前相同的指令来更新镜像 docker build -t getting-started .

3、如果直接用docker run -dp 3000:3000 getting-started 会报错。在旧的容器还在运行的时候,新的容器不能启动。因为,旧的容器还在使用者主机3000的端口,并且在主机上只有一个进程可以监听特定的端口号。为了修正它,我们需要移除老的容器。

替代我们的老容器

1、 通过docker ps命令来获取容器的id号 docker ps

2、 使用docker stop命令来停止容器 docker stop <the-container-id>

3、一旦容器停止,我们可以通过docker rm指令来移除它 docker rm <the-container-id>

在GUI界面,以上操作更简单

分享我们的应用

创建一个仓库

要上传一个镜像,我们首先在Docker Hub上创建一个仓库 1、 登录Docker Hub 2、 点击创建仓库按钮 3、使用gettting-started名称,确保Visibility是Public 4、点击创建按钮

1、在命令行,尝试运行上图你看见的命令。需要注意的是,在命令行使用你的命名空间,而不是"docker"

$ docker push docker/getting-started
The push refers to repository [docker.io/docker/getting-started]
An image does not exist locally with the tag: docker/getting-started

为什么会失败?Push命令会查找docker/getting-started的镜像,但肯定找不到。如果你运行docker image ls,你讲找不到

2、使用docker login -u YOUR-USER-NAME指令登录Docker Hub

3、使用docker tag命令来给getting-started镜像一个新名字。注意记得将YOUR-USER-NAME替换成你的Docker ID docker tag getting-started YOUR-USER-NAME/getting-started

4、现在再次尝试push命令。 docker push YOUR-USER-NAME/getting-started

在新的实例上运行我们的应用

1、 在浏览器打开Play with Docker

2、 登录Docker Hub账号

3、登录之后,点击“ ADD NEW INSTANCE”,然后在命令行输入

docker run -dp 3000:3000 YOUR-USER-NAME/getting-started

使用我们的DB

我们注意到,我们的todo列表在每次我们打开容器的时候会被清空。让我们继续深入容器的运作

实践

在下面的动作中,我们开启两个容器,在每个容器中创建一个文件。你会发现,这个文件在另一个容器中接触不到

1、开启一个ubuntu容器,然后创建一个带有0到1000随机数的/data.txt文件 docker run -d ubuntu bash -c "shuf -i 1-10000 -n 1 -o /data.txt && tail -f /dev/null"

我们开启了一个bash的shell脚本并且激活了两个命令,第一个获取一个随机数写入文件,第二名了仅仅检测一个文件保持容器运行

2、