首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >重学Docker

重学Docker

作者头像
晚上没宵夜
发布2021-07-19 14:49:26
发布2021-07-19 14:49:26
59500
代码可运行
举报
运行总次数:0
代码可运行

转了云方向,代码都少写了

1. 为什么出现Docker

以前开发项目有开发的环境、测试的环境、还有生产的环境,每经过一阶段就要迁移项目。不同的环境有不同的配置,可能导致不可预估的错误,运维要经常性的改动

世界陷入了混乱,于是上帝说,让Docker来吧,于是一切光明。Dokcer 把初始的环境一模一样地复制过来,那么就消除了协作编码时,我的机器能运行,而其他机器不能运行的困境

Docker是基于Go语言的开源项目,Docker可实现应用层的隔离,共享宿主机内核、而虚拟机是隔离系统,连内核,硬件都是各自模拟的

2. Docker的结构

Docker_Host (宿主机):安装了Docker程序的主机,形式为一个守护进程

Client (客户端):连接docker主机进行操作(与守护进程通信)

Registry (仓库):保存各种打包好的镜像(类似Github)

Images (镜像):软件打包好的镜像,放进仓库中(笔者理解为类,可以派生对象)

Containers (容器):镜像启动后的实例成为容器(笔者理解按照类创建的对象)

3. 卸载、安装

3.1 卸载

代码语言:javascript
代码运行次数:0
运行
复制
# 卸载旧版本
$  sudo yum remove docker \
                  docker-client \
                  docker-client-latest \
                  docker-common \
                  docker-latest \
                  docker-latest-logrotate \
                  docker-logrotate \
                  docker-engin
                  
# 卸载新版本
$ sudo rm -rf /var/lib/docker
$ sudo rm -rf /var/lib/containerd
$ yum remove docker-ce docker-ce-cli containerd.io

主机上的镜像、容器、卷、自定义配置是不会自动删除的需要手动

3.2 配置Docker库

代码语言:javascript
代码运行次数:0
运行
复制
$ yum install -y yum-utils
$ yum-config-manager \ 
	--add-repo \ 
	https://download.docker.com/linux/centos/docker-ce.repo

安装yum工具包,里面包含yum-config-manager,用来设置yum配置 首次安装Docker需在yum中设置的Docker存储库,之后就可从Docker存储库中安装和更新

3.3 安装

代码语言:javascript
代码运行次数:0
运行
复制
$ yum install docker-ce docker-ce-cli containerd.io

docker-ce引擎(社区免费版)、cli(可远程连接守护进程)、containerd(提供容器管理服务)

3.4 启动

代码语言:javascript
代码运行次数:0
运行
复制
$ systemctl start docker
$ systemctl enable docker
$ docker version	# 查看版本

3.5 设置镜像加速

代码语言:javascript
代码运行次数:0
运行
复制
$ vim /etc/docker/daemon.json

# 去阿里云开发平台查看自己的仓库地址
{
  "registry-mirrors": ["https://XXXXXXXX.mirror.aliyuncs.com"]
}

$ systemctl daemon-reload
$ systemctl restart docker

梯子加速你懂的 —_—

4. 启动案例

下面举几个例子,现在看不懂没关系,看看使用Docker有多快速

4.1 Hello-World

代码语言:javascript
代码运行次数:0
运行
复制
# 输入命令并执行
$ docker run hello-world

阅读运行之后的说明,里面有步骤与相关信息,对理解其原理有很大的帮助

4.2 启动Tomcat

以前运行Tomcat,要安装设置启动jdk、tomcat,期间还需到weget、tar等命令

现在使用了Docker,只需几个命令

代码语言:javascript
代码运行次数:0
运行
复制
# 拉取镜像,不加后面的标签默认拉取最新版
$ docker pull tomcat

# 启动容器
$ docker run -d -p 8080:8080 --name mytomcat -v /root/aria2-downloads:/usr/local/tomcat/webapps tomcat

# 访问
# 访问结果是404,因为镜像的webapps空的,意思是没有html页面给我们访问
# 其实最新的镜像将wepapps改名为webapps.dist,那么我们只需复制内容过去就可
# 不怕有解决方法,还是按着下面步骤输入:
$ docker exec -it  mytomcat  /bin/bash
$ cp -r webapps.dist/* webapps
$ exit

# 再次访问即可

4.3 启动MySQL

去Docker官网搜索MySQL,跟着其步骤走 MySQL的Docker地址,下面的密码设置官网也都有详细介绍

因为使用Navicat连接时会发生身份验证器错误,所以我们得进去容器修改验证器插件

代码语言:javascript
代码运行次数:0
运行
复制
# 启动并设置密码
$ docker run -d -p 3306:3306 --name howlmysql -e MYSQL_ROOT_PASSWORD=123456 mysql

# 进入容器内部
docker exec -it containerId /bin/bash

# 登录容器内的MySQL
mysql -uroot -p 123456

# 修改身份验证插件
ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '123456';

# 刷新权限
flush privileges;

4.4 启动Aria2

一个基于命令行的下载工具

代码语言:javascript
代码运行次数:0
运行
复制
# Aria2本体
$ docker run -d \
  --name aria2-pro \
  --restart unless-stopped \
  --log-opt max-size=1m \
  -e PUID=$UID \
  -e PGID=$GID \
  -e UMASK_SET=022 \
  -e RPC_SECRET=<secret> \
  -e RPC_PORT=6800 \
  -p 6800:6800 \
  -e LISTEN_PORT=6888 \
  -p 6888:6888 \
  -p 6888:6888/udp \
  -v $PWD/aria2-config:/config \
  -v $PWD/aria2-downloads:/downloads \
  p3terx/aria2-pro
  
  
# Web界面
$ docker run -d \
  --name ariang \
  --log-opt max-size=1m \
  --restart unless-stopped \
  -p 6880:6880 \
  p3terx/ariang

5. 常用命令

5.1 帮助命令

代码语言:javascript
代码运行次数:0
运行
复制
$ docker version
$ docker info			 # 更详细信息,客户端,服务器运行状况
$ docker [命令] --help    # 帮助命令

5.2 镜像命令

代码语言:javascript
代码运行次数:0
运行
复制
$ docker pull name[:tag]     # 拉镜像
$ docker rmi name|id		 # 删镜像
$ docker images  			 # 列出本地镜像
$ docker search  			 # 官网查找镜像

5.3 容器命令

代码语言:javascript
代码运行次数:0
运行
复制
# 新建并启动容器
$ docker run [可选参数] image
    --name 				# 重命名
    -d					# 守护容器后台
    -p					# 端口映射
    -v					# 文件挂载
    -i					# 交互模式
    -t					# 分配一个伪终端,后面跟分配的终端 /bin/bash
    -e					# 环境配置
    --rm				# 用完就删包括卷,测试用(docker run --rm -it -p 80:80 nginx)
    --restart=always	# docker重启,容器也会跟着启动


# 列出正在运行的容器
$ docker ps [可选参数]
    -a 					# 显示包括未运行的
    -l 					# 显示最近创建的容器
    -n					# 显示最近创建的n个容器
	-q					# 只显示id


# 生命周期命令
$ docker start name|id
$ docker restart
$ docker stop
$ docker kill
$ docker rm [-f]		# 强制删除运行中的容器


# 容器交互命令
$ docker exec 			# 在运行的容器里执行命令
$ docker exec -it id /bin/bash # 进入容器开一个新的终端,exit后不会停止容器运行
$ docker attach id 		# 进入正在执行的终端
$ ctrl + P + Q			# 交互中容器不停止退出
$ docker exit 			# 交互中停止容器并退出


# 快捷操作
$ docker container prune  删除所有容器
$ docker rmi $(docker images -q) 删除所有镜像
$ docker rm $(docker ps -aq)

5.4 其他命令

代码语言:javascript
代码运行次数:0
运行
复制
$ docker logs id		# 查看容器的日志
$ docker top id		 	# 查看容器里运行的进程
$ docker inspect id 	# 查看镜像详细信息(层、挂载目录)
$ docker cp id:容器路径 宿主机路径			# 拷贝容器文件到宿主机
$ docker cp 宿主机路径 id:容器路径			# 拷贝宿主机文件到容器
$ docker volume	create|inspect|ls|prue|rm # 数据卷操作
$ docker build	 id		# 由dockerfile生成镜像
$ docker history id		# 查看镜像如何构建
$ docker save id		# 备份镜像成.tar文件
$ docker load id		# 加载备份镜像.tar文件,建议上传仓库

6. Dockers和虚拟机的区别

6.1 虚拟机

模拟出完整的计算机系统(Guest OS),模拟的系统都是完全隔离的,且运行在监视器(Hypervisor)中,这个监视器是软件、硬件或固件

Infrastructure (基础设施):是硬件设施,理解为主机,即笔记本,云服务器

Host Operating System (主机操作系统):是主机的物理操作系统,即日常说的操作系统,Linxu、Windows

Hypervisor (虚拟机监视器):是运行在基础物理服务器和虚拟操作系统间的中间软件层,各应用和虚拟系统可共享硬件

Guest OS (宿主系统):虚拟的操作系统,虚拟机内部运行的操作系统,有完整的硬件和内核(Docker是共享)

Bins/Libs (命令/资源):二进制命令和资源库

APP (应用程序):用户安装的程序

缺点:要运行几个隔离的应用,就要监视器启动几个宿主系统,也就是几个虚拟机。虚拟机模拟了多个隔离的系统,占用了很多的硬盘、CPU、内存,所以启动也很缓慢。

6.2 Docker

Docker是运行容器的引擎,我们将 操作系统的基础库文件、应用程序、所需的依赖等打包到镜像中,然后通过镜像创建容器(类和对象),而容器就在Docker中运行

Docker Daemon (守护进程):守护进程取代Hypervisor,是个进程,负责管理Docker容器

守护进程与宿主机通信,为容器分配资源 使用宿主机的硬件资源,无需虚拟化硬件资源,所以容器无需加载内核,因此是秒级 Docker使用了cgroup + namespace,前者限制资源集,后者限制可访问权限 Docker是Client-Server结构,守护进程在宿主机上,客户端socket连接进程管理运行在主机上的容器

6.3 对比

虚拟机:彻底隔离整个运行环境,每个运行的虚拟系统都是完全隔离的

Docker:隔离不同的应用程序,比如数据库,后端,前端等

比对项

Container(容器)

VM(虚拟机)

启动速度

秒级

分钟级

运行性能

接近原生

有所损失

磁盘占用

MB

GB

数量

成百上千

一般几十台

隔离性

进程级别

系统级别

操作系统

只支持Linux

几乎所有

封装程度

只打包项目代码和依赖关系,共享宿主机内核

完整的操作系统

7. 图形化界面

笔者了解到的图形化管理工具是Portainer,也是在Docker上运行的程序,建议跟着仓库文档走

代码语言:javascript
代码运行次数:0
运行
复制
# 必须挂载
$ docker run -d -p 9000:9000 --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce

具体各位去摸索一下把~

8. 镜像 image

镜像一种轻量级、可执行的独立软件包,用来打包软件的运行环境和基于运行环境开发的技术。它包含运行某个软件需要的所有内容(包括代码、运行库、环境变量和配置文件)

8.1 联合文件系统

联合文件系统(UnionFS):是一个分层的、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层叠加(类似Git),同时可以将不同目录挂载到同一虚拟文件系统下(-v 文件挂载)

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

一次同时加载多个文件系统,但从外面看只能看到一个文件系统,联合加载会把各层文件系统叠加起来,这样最终的文件系统会包含所有的底层文件和目录

8.2 镜像加载原理

Docker使用UnionFS进行分层,底层是bootfs文件系统(bootloader加载最基础的内核、kernvel)

bootfs的上一层是rootfs,也就是 /dev,/bin,/etc等标准目录和文件

不同的镜像中有相同的分层,那宿主机只需在磁盘、内存中保存一份,这些镜像共享这些分层

8.3 镜像层的叠加

假如我们在Docker上安装tomcat,首先底层是bootfs层,然后在上面安装centos (rootfs),意思是修改了文件系统,那就会叠加一层文件系统、依次类推,还有jdk8层、tomcat层。最终打包成tomcat这个镜像,对外则是一个整体

镜像都是只读的,当容器启动时,一个新的可写层被加载到镜像的顶部(容器层,之下叫镜像层) 若我们在容器层删除了文件,那么会生成一个wihteout文件,将对应的下层文件隐藏掉

8.4 提交生成镜像

上面tomcat的案例我们已经修改过webapps的内容,因修改了联合文件系统,所以可作为一次提交来层层叠加

代码语言:javascript
代码运行次数:0
运行
复制
# 提交到本地仓库,没有add行为了
# name[:tag] 是 自己命名的 镜像名[tag] 作为镜像名
$ docker commit -m "提交信息" -a "作者" id name[:tag]
# eg:
$ docker commit -m "add webapps files" -a "Howl" 9c8524bxxxx  mytomcat:1.0


# 然后就可看到自己打包的镜像了
$ docker images

9. 数据卷

数据卷(volume)是由docker挂载到容器(不属于UFS)存在于一个或多个容器中的目录或文件,因此能绕过UFS一些用于持续存储或共享数据的特性

卷的出现是为了数据的持久化和同步操作,其完全独立于容器的生存周期,因此在删除容器时其挂载的数据卷不会被删除。简单来说:使容器和宿主机共享独立于docker生命周期的数据、亦或者:独立于docker生命周期的目录挂载

特点:

  • 数据卷可以容器之间共享或重用
  • 卷中的更改直接生效
  • 卷中的更改不会包含在镜像的更新中
  • 数据卷的生命周期持续到没有容器使用为止

9.1 具名、匿名挂载

数据卷的默认地址 /var/lib/docker/volumes/xxx

代码语言:javascript
代码运行次数:0
运行
复制
$ docker run -v /宿主机绝对路径:/容器内目录 name[tag]	# 具名挂载(不加"/",在默认地址下起个名字而已)
$ docker run -v /容器内目录	name[tag]				 # 匿名挂载,宿主机用默认地址(会生成唯一的32位id)

# 还有只读,读写权限
$ docker run -v /宿主机绝对路径:/容器内目录:ro|rw name[tag]


# 还有先创建数据卷,后面再挂载
$ docker volume create mysql_data
$ docker run -d -p 3306:3360 -v mysql_data:/root/mysql_data

9.2 Dockerfile挂载

这里说明有这种挂载方式,什么是dockerfile下面会讲

代码语言:javascript
代码运行次数:0
运行
复制
$ FROM centos

# 没有"/",是匿名挂载,宿主机的默认地址
# 容器内直接在根目录下
$ VOLUME ["volume01","volume02"]

$ CMD echo "----Howl write dockerfile----"

$ CMD /bin/bash

9.3 容器数据卷

容器数据卷是用于容器间的数据共享,操作方式还是命令行: --volume-from

代码语言:javascript
代码运行次数:0
运行
复制
# centos01就叫数据卷容器
$ docker run -d --name centos01 howl/centos:1.0

$ docker run -d --name centos02 --volume-from centos01 howl/centos:1.0

这是数据卷,不和容器同生命周期,所以哪怕父容器删了,其余容器也能访问同步

10. Dockerfile

Dockerfile是有一系列命令和参数的脚本,通过这个脚本我们可以构建一个镜像

10.1 Dockerfile指令

指令必须都是大写,从上往下执行,且每个指令都会创建一层(可用&&将命令连起来只生成一层)

命令

语法

解释

FROM

FROM image[:tag]

指定基础镜像,必须第一条。FROM scratch表示不以任何镜像为基础

MAINTAINER

维护者信息

RUN

镜像构建时需要执行的命令

ADD

复制本地压缩文件,会自动解压

WORKDIR

镜像工作目录

VOLUME

设置容器卷

EXPOSE

指定堆外端口

CMD

指定容器运行中的命令,会被覆盖

ENTRYPOINT

指定容器启动时运行的命令,可以追加命令

ONBUILD

当构建一个被继承Dockerfile时会运行该指令

COPY

COPY 宿主文件地址 容器文件地址

将文件拷贝到镜像中

ENV

构建时设置环境变量

10.1 编写Dockerfile

举例做个tomcat镜像,需要准备tomcat压缩包、jdk压缩包、readme文件

代码语言:javascript
代码运行次数:0
运行
复制
$ FROM centos
$ MAINTAINER howl

$ COPY readme.txt /usr/local/readme.txt
$ ADD jdk-8u291-linux-x64.tar.gz /usr/local
$ ADD apache-tomcat-8.5.68.tar.gz /usr/local

$ RUN yum -y install vim

$ ENV MYPATH /usr/local
$ WORKDIR $MYPATH

# JAVA_HOME 目录安装之后才知道
$ ENV JAVA_HOME /usr/local/jdk1.8.0_291
$ ENV CLASSPATH $JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
$ ENV CATALINA_HOME /usr/local/apache-tomcat-8.5.68
$ ENV CATALINA_BASH /usr/local/apache-tomcat-8.5.68
$ ENV PATH $PATH:$JAVA_HOME/bin:$CATALINA_HOME/lib

$ EXPOSE 8080

$ CMD /usr/local/apache-tomcat-8.5.68/bin/startup.sh && tail -F /usr/local/apache-tomcat-8.5.68/bin/logs/catalina.out

每条指令都会创建一个新的镜像层,并对镜像进行提交 若构建名为Dockerfile那么就会自动查找,不用-f去指定了 Docker运行得有前台应用在运行,不然会自动结束,tail就是为了前台运行,比如top等命令 注意:根据linux位数,arm,aarch64来安装jdk,笔者安装错了,走了很多弯路

10.2 Build制作镜像

代码语言:javascript
代码运行次数:0
运行
复制
# -f 指定dockerfile的路径
# -t 生成的镜像名字[:tag] 生成镜像的地址
# . 表示当前目录
$ docker build -t howl/tomcat .

10.3 运行制作的镜像

代码语言:javascript
代码运行次数:0
运行
复制
$ docker run -d -p 8080:8080 howl/tomcat

有个注意的地方,webapps下要新建目录才能访问的,不能放入已有文件夹内,也不能直接放入webapps里面

10.4 发布镜像

镜像的发布有两种途径,分别是:

  • DockerHub
代码语言:javascript
代码运行次数:0
运行
复制
# 首先需要登录
$ docker login -u loadingkiller
$ Password: "输入密码"

# 推送名字得是自己DockerHub上的账号名,所以得先改标签
# 本来 howl/centos 改成 loadingkiller/tomcat
$ docker tag howl/tomcat:latest loadingkiller/tomcat:1.0

# 推送,速度慢等吧
$ docker push loadingkiller/centos:1.0
  • 阿里云镜像仓库

进入阿里云镜像管理可以创建镜像仓库,然后跟着里面的提示走

代码语言:javascript
代码运行次数:0
运行
复制
# 登录
docker login -u=XXX registry.cn-hongkong.aliyuncs.com

# 选择分支对应关系
docker tag [ImageId] registry.cn-hongkong.aliyuncs.com/howlet/mytomcat:[镜像版本号]

# 推送上去
docker push registry.cn-hongkong.aliyuncs.com/howlet/mytomcat:[镜像版本号]

# 拉取
docker pull registry.cn-hongkong.aliyuncs.com/howlet/mytomcat:[镜像版本号]
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-07-14 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 为什么出现Docker
  • 2. Docker的结构
  • 3. 卸载、安装
    • 3.1 卸载
    • 3.2 配置Docker库
    • 3.3 安装
    • 3.4 启动
    • 3.5 设置镜像加速
  • 4. 启动案例
    • 4.1 Hello-World
    • 4.2 启动Tomcat
    • 4.3 启动MySQL
    • 4.4 启动Aria2
  • 5. 常用命令
    • 5.1 帮助命令
    • 5.2 镜像命令
    • 5.3 容器命令
    • 5.4 其他命令
  • 6. Dockers和虚拟机的区别
    • 6.1 虚拟机
    • 6.2 Docker
    • 6.3 对比
  • 7. 图形化界面
  • 8. 镜像 image
    • 8.1 联合文件系统
    • 8.2 镜像加载原理
    • 8.3 镜像层的叠加
    • 8.4 提交生成镜像
  • 9. 数据卷
    • 9.1 具名、匿名挂载
    • 9.2 Dockerfile挂载
    • 9.3 容器数据卷
  • 10. Dockerfile
    • 10.1 Dockerfile指令
    • 10.1 编写Dockerfile
    • 10.2 Build制作镜像
    • 10.3 运行制作的镜像
    • 10.4 发布镜像
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档