本文参考b站free-coder的视频,以及网络上的一些其他资料,加入了我自己的一些思考。在此向up主和原作者表示感谢!

docker简介

docker可以理解成一个虚拟机管理器(这不过这里我们把里面的虚拟机叫做容器),相比于虚拟机而言更轻量化。我们可以从官方仓库中下载到一系列别人已经帮我们做好的镜像,这些镜像可以让我们免于自己配置环境而直接能够跑起来一些服务。

关于docker中的一些概念和转化关系可以参考下图:

docker

可以看到,镜像就是docker的中心。另外由于每一个镜像想要运行起来,都需要有个容器来作为它的环境,所以容器是docker的核心。之后的docker基本命令都会围绕这个模型来讲解。

安装docker

官方网站上有关于docker的安装说明,此处也稍作整理。

首先如果之前有安装过docker,需要先干净地卸载掉。

然后需要切换到root用户,对yum的安装仓库进行一下简单配置,添加阿里云镜像:

yum-config-manager --add-repo https://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo

之后执行安装命令

 yum install -y docker-ce docker-ce-cli containerd.io

并且通过以下命令来启动、停止和重启docker服务:

systemctl start docker # 启动
systemctl stop docker # 关闭
systemctl restart docker # 重启

可选操作:添加当前用户到docker用户组:sudo usermod -aG docker $USER (需注销),newgrp docker (立即生效)

配置阿里云加速镜像

当然也可以直接使用国内的其他镜像站,但是个人推荐还是使用阿里云的加速镜像更快,而且本质上阿里云还是会连接docker的主仓库,所以不用考虑仓库更新的问题。

先来到阿里云容器镜像服务网站,然后找到如下图的位置,复制加速镜像地址。

阿里云加速镜像

然后参考下面的操作文档进行操作即可,这里稍作整理:

进入/etc/docker/目录下,修改daemon.json文件(如果没有则直接创建一个),在里面添加如下内容:

{
    "registry-mirrors":["https://8eemjwlo.mirror.aliyuncs.com"]
}

这里的镜像地址换成你自己的加速镜像地址即可。

之后使用systemctl restart docker 重启docker即可。然后输入docker info 可以确认一下,发现输出的信息中有刚才设置的镜像,说明设置成功了。

docker基本命令

pull

将镜像用远程仓库下载到本地。

docker pull hello-world: 如果之前没有问题就可以看到docker的欢迎语了!

如果在镜像后面写上:然后加上版本号还可以指定pull的版本,不写则默认是:latest

run

docker run 【-d】(后台运行不阻塞shell) 【-p 80:80】(指定容器端口映射,宿主机端口:容器端口) nginx

docker run -d -p 8080:80 nginx 是将容器中nginx默认的80端口映射到宿主机的8080端口,也就是可以通过访问8080端口看到nginx的页面了!如果想从外网访问别忘了开8080的防火墙。

然后可以看到输出了一串字符,这个就是这次创建出来的容器ID了,后面我们可以拿这个ID来指定对应的容器(一般用前两位就够了,能区分出来是哪个容器就行)。

docker跑起来的服务只要开放了防火墙(和服务商的安全组),那么外网是可以直接访问的!

-v 数据卷挂载

  • 指定目录挂载:-v /宿主机目录:容器目录,宿主机目录可以写作’pwd’表示当前目录。比如-v /home/learnLinux/dockerfile/html:/usr/share/nginx/html
  • 具名挂载:-v 卷名:容器目录,会在/var/lib/docker/volumes/下产生一个指定卷名的新目录,用来映射到容器的指定目录。具体挂载内容还在里面的_data/目录中。
  • 匿名挂在:-v 容器目录,在/var/lib/docker/volumes/下产生一个新目录,只不过名字是hash值,其他和具名挂载一样。

–volumes-from挂载容器:后面跟一个已经存在的容器,可以复制这个容器的挂载状态做挂载,并且挂载到外部同一个卷,实现多个容器之间共享数据。

另外如果在容器目录后面再追加:ro表示只读,容器不能从内部改变这个目录中的内容(没有权限),但是可以从外面更改。加:rw表示读写,容器可以从内部修改挂载的目录中的内容。

-i 可以直接以交互式的方式启动容器,比如docker run -it alpine 就可以直接进入alpine的终端

--restart=always 选项可以指定容器退出时自动重新启动。如果忘记在run的时候设置,也可以使用docker update --restart=always <容器id> 来重新设置。

commit

docker commit 容器ID 镜像名

可以将现在正在运行的一个容器保存成一个镜像,保留其目前的所有状态,镜像名是自己取的

docker commit a1 jingxiang1

build

可以参照一个Dockerfile中的配置信息建立一个镜像。

docker build -t 镜像名 -f Dockerfile的路径

比如docker build -t jingxiang2 ./test/ 可以读取./test/目录下的名为Dockerfile的文件内容并依照其中的配置建立一个名为jingxiang2的镜像。如果不指定-f则只会找名为Dockerfile的文件,可以通过-f指定一个文件作为Dockerfile进行构建。

下面是一个Dockerfile的实例,可以基于nginx镜像,并将宿主机的./test/目录下的内容拷贝到容器的/usr/share/nginx/html/目录下。

FROM nginx
ADD ./test/ /usr/share/nginx/html/

save

可以将一个镜像保存成易于分享复制的tar文件

docker save 镜像名 > tar文件名

比如docker save jingxiang1 > mytar

load

将一个tar文件载入成一个镜像

docker load < tar文件名

比如docker load < mytar

start

可以将一个停止的容器重新跑起来。

docker ps -a可以查看所有容器,包括没在运行中的。

比如通过docker start -i a1可以将一个有alpine的容器退出后重新跑起来。

exec

docker exec -it 容器id bash

这里id写可以区分的前缀即可。

比如docker exec -it a1 bash 就进入了容器a1中,并且新打开一个终端以供操作。也可以用-u root 指定以root用户登录。

attach

进入容器,不会新开一个终端。attach 容器ID即可。

退出容器

如果使用exit或者ctrl+D退出,可以退出容器,但是会使得没有服务的容器停止。

可以使用Ctrl+p+q实现不停止退出,下次依旧可以通过attach进入同一个终端。

查看状态

docker ps 查看当前正在运行的容器

docker images 查看本地的镜像

docker logs a1 可以查看ID前缀为a1的容器的日志

docker inspect a1 可以查看容器挂载的状态等

docker stats 可以进入docker容器的任务管理器,实时查看容器消耗CPU和内存等资源。

docker volumes ls可以查看所有具名挂载卷和匿名挂载卷,不包括指定路径挂载卷。

rm和rmi

docker rm -f a1 表示强制删除a1开头id的容器

docker rmi jingxiang1 删除指定名字的镜像,前提是这个镜像没有在任何一个容器中运行

tag

创建一个镜像的硬链接

docker tag test1 test2 表示创建一个名为test2的test1的硬链接。注意这时删掉其中一个镜像并不会导致另一个被删除。用这种方法可以实现镜像重命名。

cp

将容器内文件拷贝到宿主机:docker cp 容器ID:容器内路径 本机路径

将宿主机内文件拷贝到容器:docker cp 本机路径 容器ID:容器内路径

history

通过docker history <镜像id>可以查看一个镜像的构建过程历史。

Dockfile

FROM docker.io/jeanblanchard/alpine-glibc

MAINTAINER claws<123@qq.com>

RUN mkdir /usr/local/java/
ADD jdk-8u251-linux-x64.tar.gz /usr/local/java/

ENV JAVA_HOME=/usr/local/java/jdk1.8.0_251
ENV CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
ENV PATH=$JAVA_HOME/bin:$PATH

CMD ["java","-version"]
CMD /bin/sh

以上是我在构建自己的以alpine为基础的jdk环境镜像的时候使用的Dockerfile,以此为例说明一下语法。

Dockerfile中常见的命令有:

  • FROM 指明基础镜像
  • RUN 在构建镜像时运行的命令
  • ADD 将外部内容加入(如果是压缩包会自动解压,如果是url会自动下载)
  • ENV 添加环境变量
  • CMD 在镜像实例化成容器时运行的命令,可以被run的时候新的命令参数覆盖。
  • MAINTAINER 作者信息

docker compose

docker compose工具可以一次启动多个协同的docker容器,方便了容器部署管理。

通过包管理器安装docker的时候一般都会附带安装docker compose。

docker compose 会自动寻找当前目录下的配置文件并启动镜像。

docker-compose up 前台启动docker容器组,可以看到运行状态和日志。

docker-compose up -d 后台启动docker容器组。

docker-compose down 关闭容器组。

docker-compose up -f 指定配置文件启动容器组。

docker私有仓库操作

以我的gitea仓库为例。

login

docker login gitea.claws.top,会提示输入用户名和密码,这里也可以输入api_token。如果输错密码的话可能是不会有提示的,会在push的时候显示缺失凭证。

之后docker会将登录信息存储到~/.docker/config.json中。

logout

docker logout gitea.claws.top 实际上就是讲config.json中的登录凭证删除掉。

push操作

一个镜像的名称被分为四个部分:[repository/][user/]image-name[:tag] 只不过方括号的三个部分经常省略。如果需要push到自己的仓库而不是中央仓库,一定要将repository、user设置正确。这里可以使用docker tag命令:docker tag test-image:1.0 gitea.claws.top/jingjiecb/test-image:1.0来修改镜像的tag。

之后,再直接使用docker push <image>命令即可,不需要再加什么其他参数了。例如:docker push gitea.claws.top/jingjiecb/test-image:1.0 注意,如果之前的用户名和密码(或者token)没有配置正确的话push这步才会报错说没有授权。