Docker容器学习(一)

前言:

废话就不说了,抓紧时间学习。docker yyds!

一、Docker 概述:

1、Docker 简介:

请添加图片描述
Docker 是一个开源的应用容器引擎,可以将你的开发环境、代码、配置文件等一并打包到这个容器中,并发布和应用到任意平台。比如,你在本地用 Python 开发网站后台,开发测试完成后,就可以将 Python3 及其依赖包、Flask 及其各种插件、Mysql、Nginx 等打包到一个容器中,然后部署到任意你想部署到的环境。

Docker 的思想来自于集装箱,集装箱解决了什么问题?在一艘大船上,可以把货物规整的摆放起来。并且各种各样的货物被集装箱标准化了,集装箱和集装箱之间不会互相影响。那么就不需要专门运送水果的船和专门运送化学品的船了。

Docker基于Go语言开发的!开源项目!

2、对比传统虚拟机:

在容器技术出来之前,我们都是使用虚拟机技术,虚拟机相较于 docker 容器很笨重。

二、基本概念:

Docker 包括三个基本概念:

  • 镜像(Image)

  • 容器(Container)

  • 仓库(Repository)

理解了这三个概念,就理解了 Docker 的整个生命周期。

1、镜像(image):

类似于虚拟机中的镜像,是一个包含有文件系统的面向 docker 引擎的只读模板。任何应用程序运行都需要环境,而镜像就是用来提供这种运行环境的。例如一个 Ubuntu 镜像就是一个包含 Ubuntu 操作系统环境的模板。

2、容器(container):

镜像和容器的关系,就像是面向对象程序设计中的 “类” 和 “实例” 一样,镜像是静态的定义,容器是镜像运行时的实体。可以将其看作一个简易的Linux系统 以及运行在其中的应用程序。Docker利用容器来运行、隔离各个应用。容器是镜像创建的应用实例,可以创建、启动、停止、删除容器,各个容器之间是是相互隔离的,互不影响。

3、仓库(repository)

仓库就是用来集中存放镜像文件的地方。类似于代码仓库,这里是镜像仓库,分为公有仓库和私有仓库。注意与注册服务器(Registry)的区别:注册服务器是存放仓库的地方,一般会有多个仓库;而仓库是存放镜像的地方,一般每个仓库存放一类镜像,每个镜像利用 tag 进行区分,比如 Ubuntu 仓库存放有多个版本(12.04、14.04等)的 Ubuntu 镜像。

目前最用的 Registry 是官方的 Docker Hub,这也是默认的 Registry,拥有大量的高质量的官方镜像 。除此以外,还有 Red Hat 的 Quay.io ;Google 的 Google Container RegistryKubernetes (K8s) 的镜像使用的就是这个服务;以及代码托管平台 GitHub 推出的 ghcr.io

三、Docker 安装

Docker 可以安装在 Windows、Linux、Mac 等各个平台上。具体可以查看文档 Install Docker

环境准备: Linux要求内核3.0以上

查询内核版本命令:

 uname -r


这里使用的OS是Ubuntu,可以看到 版本是符合要求的。

准备好环境之后,接下来按着官方文档来一步一步安装。

这里使用官方推荐的第一种方法安装。

第一步:卸载旧版本
 sudo apt-get remove docker docker-engine docker.io containerd runc

如果有的话就卸,没有则省略。

第二步:更新apt包索引和安装包,以允许apt使用http存储库:
 sudo apt-get update

 sudo apt-get install \
    apt-transport-http \
    ca-certificates \
    curl \
    gnupg \
    lsb-release
第三步:添加Docker官方的GPG密钥
curl -fsSL http://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
第四步:设置镜像的仓库
echo \
  "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] http://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null


这里默认是从国外的,不推荐,推荐使用国内的。

echo \
  "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg]  http://mirrors.aliyun.com/docker-ce/linux/ubuntu\
   $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
第五步:更新apt包索引
sudo apt-get update
第六步:安装最新版本的Docker Engine和containerd
sudo apt-get install docker-ce docker-ce-cli containerd.io # docker-ce 社区版 而ee是企业版

🆗,至此安装完成!如果 Docker 没启动的话,先启动一下。

sudo systemctl start docker
第七步:使用docker version查看是否安装成功
sudo docker version


出现这个页面就是成功安装了!

第九步:测试 hello-world
sudo docker run hello-world


hello-world 第一次需要先下载。

最后:查看下载的镜像
docker images


🆗,都没什么问题!  

补充:

1、卸载 Docker:

#1.卸载 Docker Engine、CLI 和 Containerd 包:
sudo apt-get purge docker-ce docker-ce-cli containerd.io

#2. 删除所有镜像、容器和卷 //主机上的映像、容器、卷或自定义配置文件不会自动删除。
sudo rm -rf /var/lib/docker # /var/lib/docker 是docker的默认工作路径!
sudo rm -rf /var/lib/containerd

2、阿里云镜像加速:

因为默认的 docker 仓库是国外的,所以这里把仓库改为aliyun的。

依次执行下面命令:

sudo mkdir -p /etc/docker

sudo tee /etc/docker/daemon.json <<-'EOF'
{
  "registry-mirrors": ["http://j5l0vyp9.mirror.aliyuncs.com"]
}
EOF

sudo systemctl daemon-reload

sudo systemctl restart docker

四、Docker运行原理:

1、回顾 HelloWorld 流程:


run的流程图:

2、Docker是怎么工作的?

Docker是一个 C/S 结构的系统,Docker的守护进程运行在主机上。通过 Socket 从客户端访问。

Docker-Server 接收到 Docker-Client 的指令,就会执行这个命令。

3、Docker 为什么比 VM 快?

1、Docker 有着比虚拟机更少的抽象层。由于 docker 不需要 Hypervisor 实现硬件资源虚拟化,运行在 docker 容器上的程序直接使用的都是实际物理机的硬件资源。因此在CPU、内存利用率上docker将会在效率上有明显优势。

2、docker 利用的是宿主机的内核,vm 需要 Guest OS。

  • GuestOS: VM(虚拟机)里的的系统(OS)

  • HostOS:物理机里的系统(OS)


因此,当新建一个容器时,docker 不需要和虚拟机一样重新加载一个操作系统内核。虚拟机加载 GuestOS,是分钟级别的。而 docker 直接利用宿主机的操作系统,省略了这个复杂的过程,因此新建一个 docker 容器只需要几秒钟。

五、Docker的常用命令:

1、帮助命令:
docker version #显示docker的版本信息。

docker info #显示docker的系统信息,包括镜像和容器的数量

docker 命令 --help #帮助命令

帮助文档

2、镜像命令:
docker images #查看所有本地主机上的镜像 可以使用 docker image ls代替

docker search #搜索镜像

docker pull #下载镜像 = docker image pull

docker rmi  #删除镜像 = docker image rm

docker images 查看所有本地主机上的镜像:

#可选项
-a,--all    #列出所有镜像
-q,--quiet  #只显示镜像的id

docker search 搜索镜像

#可选项,通过收藏来过滤
-f/--filter=STARS=3000 #搜索出来的镜像就是STARS大于3000的

docker pull 下载镜像

#下载镜像 docker pull 镜像名
smk@ubuntu:~$ sudo docker pull mysql
Using default tag: latest #如果不写tag,默认就是latest
latest: Pulling from library/mysql 
33847f680f63: Pull complete #分层下载: docker image 的核心 联合文件系统
5cb67864e624: Pull complete 
1a2b594783f5: Pull complete 
b30e406dd925: Pull complete 
48901e306e4c: Pull complete 
603d2b7147fd: Pull complete 
802aa684c1c4: Pull complete 
715d3c143a06: Pull complete 
6978e1b7a511: Pull complete 
f0d78b0ac1be: Pull complete 
35a94d251ed1: Pull complete 
36f75719b1a9: Pull complete 
Digest: sha256:8b928a5117cf5c2238c7a09cd28c2e801ac98f91c3f8203a8938ae51f14700fd #签名 防伪
Status: Downloaded newer image for mysql:latest 
docker.io/library/mysql:latest #真实地址

#二者等价
docker pull mysql
docker pull docker.io/library/mysql:latest

指定版本下载:

docker rmi 删除镜像

docker rmi -f 镜像id #删除指定的镜像
docker rmi -f 镜像id 镜像id 镜像id 镜像id #删除指定的镜像
docker rmi -f $(docker images -aq) #删除全部的镜像


注意这里不是root用户,需要加 sudo

3、容器命令:

说明:有了镜像才可以创建容器;先下载一个 centos 镜像来测试:

docker pull centos

新建容器并启动(注意和 start 的区别,start 只能启动):

docker run [可选参数] 镜像名 
#参数说明
--name="Name" 容器名字 tomcat01 tomcat02 用来区分容器
-d 后台方式运行
-it 使用交互方式运行(就是进入容器内)
-p 指定容器的端口 -p 8080(宿主机):8080(容器)
     #一共有四种用法:
    -p ip:主机端口:容器端口
    -p 主机端口:容器端口(常用)
    -p 容器端口
    容器端口
-P(大写) 随机指定端口

启动并进入容器:

/bin/bash:即启动 bash类型的shell。

退出容器

exit       #容器停止并退出
ctrl +P +Q #容器不停止退出


列出所有运行的容器

docker ps [可选参数] #列出当前正在运行的容器
#参数说明
-a #列出当前正在运行的容器 + 带出历史运行过的容器
-n=? #显示最近创建的容器
-q #只显示容器的编号

删除容器

docker rm 容器id #删除指定的容器,不能删除正在运行的容器,如果要强制删除 rm -f
docker rm -f $(docker ps -aq) #强制删除所有的容器
docker ps -a -q|xargs docker rm #删除所有的容器

启动和停止容器

docker start 容器id #启动容器
docker restart 容器id #重启容器
docker stop 容器id #停止当前正在运行的容器
docker kill 容器id #强制停止当前容器

4、常用其他命令:

后台启动

docker run -d 镜像名


一个小坑:

docker ps 发现 centos 停止了

原因是:docker容器使用后台运行,就必须要有要一个前台进程,docker 没有发现前台进程,就会自动停止。

常见:nginx,容器启动后,发现自己没有提供服务,就会立刻停止,就是没有程序了

查看容器中进程信息

docker top 容器id


注:必须是运行的容器。

进入当前正在运行的容器

# 我们通常容器都是使用后台方式运行的,需要进入容器,修改一些配置
# 命令:
docker exec -it 容器id bashshell

# 方式二
docker attach 容器id

#区别
docker exec #进入当前容器后开启一个新的终端,可以在里面操作。(常用)
docker attach # 进入容器正在执行的终端

从容器内拷贝到主机上:

docker cp 容器id:容器内路径 主机目的路径

例:

5、Docker可视化:

portainer 是 docker 图形化界面管理工具!提供一个后台面板供我们操作!(不建议使用)

#官网查找安装命令
docker run -d -p 8000:8000 -p 9000:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce

访问:

进来之后就是这样。

可以看到一些本地docker的配置

六、Docker镜像讲解:

1、Docker镜像加载原理:
  • docker 的镜像实际上由一层一层的文件系统组成,这种层级的文件系统 UnionFS(下载的时候看到一层层的下载就是这个) 。

UnionFs (联合文件系统):

UnionFs 是Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。

  • bootfs(boot file system):主要包含 bootloader 和 Kernel(内核),bootloader 主要是引导加载 kernel,Linux 刚启动时会加 bootfs 文件系统,在 Docker 镜像的最底层是 bootfs。这一层与我们典型的 Linux/Unix 系统是一样的,包含 boot加载器和内核。当 boot 加载完成之后整个内核就都在内存中了,此时内存的使用权已由 bootfs 转交给内核,此时系统也会卸载 bootfs。

  • rootfs(root file system),在 bootfs 之上。包含的就是典型 Linux 系统中的 /dev,/proc,/bin,/etc 等标准目录和文件。 rootfs 就是各种不同的操作系统发行版,比如 Ubuntu,Centos 等等。

平时安装的虚拟机的 CentOS 都是好几个G,为什么 Docker 这里才200M?

  • 对于个精简的OS,rootfs 可以很小,只需要包含最基本的命令,工具和程序库就可以了,因为底层直接用 Host(主机) 的 kernel,自己只需要提供 rootfs 就可以了。由此可见对于不同的 Linux 发行版, bootfs 基本是一致的, rootfs 会有差別,因此不同的发行版可以公用 bootfs.

    2、分层理解:


    思考:为什么Docker镜像要采用这种分层的结构呢?

  • 最大的好处:资源共享,比如有多个镜像都从相同的 Base镜像构建而来,那么宿主机只需在磁盘上保留一份base镜像,同时内存中也只需要加载一份base镜像,这样就可以为所有的容器服务了,而且镜像的每一层都可以被共享。

例如:当系统中已经有了 CentOS 镜像,那么后面再有用到 CentOS 镜像的就不用再下载一次了。

查看镜像分层的方式可以通过docker image inspect 命令:

3、Commit 镜像:

Docker 镜像都是只读的,当容器启动时,一个新的可写层加载到镜像的顶部。

这一层就是我们通常说的容器层,容器之下的都叫镜像层!

如果想要保存当前容器的状态,就可以通过 commit 来提交,获得一个镜像,就好比使用虚拟机的快照。

命令:

docker commit -m="描述信息" -a="作者" 容器id 目标镜像名:[TAG]

实战测试

1、启动一个tomcat

docker run -d -p 8080:8080 tomcat:9.0

2、发现这个默认的 tomcat 是没有 webapps 应用

docker exec -it 容器id

3、自己拷贝文件进去

cp -r webapps.dist/* webapps

4、将操作过的容器通过 commit 提交为一个镜像

docker commit -a="smk" -m="add webapps" 容器id tomcat02:1.0


这样以后就可以使用我们修改过的镜像了,这就是我们自己的一个修改的镜像。


🆗,至此 docker入门成功!
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 2058751973@qq.com

×

喜欢就点赞,疼爱就打赏