Docker学习笔记

Docker安装

安装方式

手动安装

  参照Docker官方的教程。(暂时不做记录)

脚本安装

  推荐使用脚本安装,以下是官方的脚本安装命令:

# 可以使用--mirror命令来指定源
curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun

  也可以使用国内daocloud的一键安装命令,如下所示:

curl -sSL https://get.daocloud.io/docker | sh

  就个人体验而言,国内daocloud的一键安装命令好用些。

启动Docker

  使用以下命令启动Docker:

sudo systemctl enable docker
sudo systemctl start docker

添加用户权限

  我们需要将使用Docker的用户加入到docker用户组中:

sudo usermod -aG docker 用户名

配置国内镜像源

  1.编辑配置文件/etc/docker/daemon.json

{
    "registry-mirrors":["https://docker.mirrors.ustc.edu.cn"]
}

  国内可用的镜像源有以下几个:

# Docker国内官方镜像源
https://registry.docker-cn.com
# 中国科技大学镜像源
https://docker.mirrors.ustc.edu.cn
# 网易镜像源
https://hub-mirror.c.163.com/

  2.重启Docker
  使用以下命令重启Docker服务:

systemctl restart docker.service

启动hello-world

  就像学习一门编程语言一样,我们可以通过运行Docker已经准备好的镜像hello-world来验证我们的环境是否安装成功:

docker run hello-world

  因为我们本地没有hello-world这个镜像,所以docker会自动在镜像源中拉取hello-world镜像然后启动一个容器。如果一切顺利,我们会看到以下输出:

Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
2db29710123e: Pull complete 
Digest: sha256:2498fce14358aa50ead0cc6c19990fc6ff866ce72aeb5546e1d59caac3d0d60f
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (amd64)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/

Docker的基本命令

# 查看docker的版本信息
docker version

# 查看docker的系统信息
docker info

# docker的帮助命令 [COMMAND]表示具体的命令,比如run
docker [COMMAND] --help

Docker镜像

Docker镜像的基本概念

  简单记录一下自己的理解。如果做一个简单的类比,把我们的操作系统比作docker服务,那么每一个镜像就像是我们的可执行程序,我们可以通过多次启动可执行程序创建多个进程,同样的我们可以通过启动镜像创建多个容器来提供服务。但是Docker的原理远比这个类比复杂,这里暂不详细记录,先从学习基础操作开始。

Docker镜像的基本命令

  使用docker的帮助命令可以查看到镜像的基本命令及其说明,以下是与镜像相关的常用命令:
  1.查看镜像docker images

Usage:  docker images [OPTIONS] [REPOSITORY[:TAG]]

List images             显示镜像

Options:
  -a, --all             显示所有镜像(默认隐藏中间镜像)
      --digests         显示镜像的摘要信息
  -f, --filter filter   根据提供的条件过滤显示
      --format string   格式化显示镜像信息
      --no-trunc        不截断输出
  -q, --quiet           只显示镜像的ID号

  2.搜索镜像docker search

Usage:  docker search [OPTIONS] TERM

Search the Docker Hub for images

Options:
  -f, --filter filter   根据条件进行过滤
      --format string   格式化显示镜像信息
      --limit int       搜索结果的显示数量(默认25)
      --no-trunc        不截断输出

  更多命令的解释说明可以查看(官方索引)[https://docs.docker.com/reference/]。
  3.拉取镜像或者仓库docker pull

Usage:  docker pull [OPTIONS] NAME[:TAG|@DIGEST]

Pull an image or a repository from a registry

Options:
  -a, --all-tags                下载仓库中所有标签的镜像
      --disable-content-trust   跳过镜像验证(默认为真)
      --platform string         指定拉取镜像的仓库
  -q, --quiet                   不输出拉取镜像的详细信息

  4.删除镜像docker rmi

Usage:  docker rmi [OPTIONS] IMAGE [IMAGE...]

Remove one or more images

Options:
  -f, --force      强制删除镜像
      --no-prune   不删除没有打上标签的父镜像

Docker容器

Docker容器的基本概念

  Docker的容器类似于虚拟机,可以将应用程序执行的环境彼此隔离,但是依然共享底层的OS内核,有着比虚拟机更少的开销,提供了一种高效和高粒度的虚拟机制。

Docker容器的基本命令

  1.使用镜像创建并运行一个容器docker run

sage:  docker run [OPTIONS] IMAGE [COMMAND] [ARG...]

Run a command in a new container

Options:
  -d, --detach                         在后台运行容器并打印容器的ID
      --entrypoint string              覆盖默认的的ENTRYPOINT命令
  -e, --env list                       设置环境变量
      --expose list                    暴露端口
  -i, --interactive                    保持标准输入STDIN打开
      --ip string                      指定IPV4地址(e.g., 172.30.100.104)
      --ip6 string                     指定IPV6地址(e.g., 2001:db8::33)
  -m, --mac-address string             指定MAC地址(e.g.,92:d0:c6:0a:29:33)
      --mount mount                    将文件系统挂在到容器
      --name string                    给容器指定名字
      --rm                             停止后自动删除容器
  -p, --publish list                   映射端口到宿主机(宿主机端口:容器端口)
  -P, --publish-all                    将暴露的端口随机映射到宿主机
  -t, --tty                            为容器重新分配一个伪输入终端,通常与 -i 同时使用
  -u, --user string                    指定容器运行时的用户名和用户ID(格式为:<name|uid>[:<group|gid>])
  -v, --volume list                    绑定挂载卷
  -w, --workdir string                 指定容器的工作目录

  2.查询容器docker ps

Usage:  docker ps [OPTIONS]

List containers

Options:
  -a, --all             显示所有的容器(默认只显示正在运行的)
  -f, --filter filter   根据过滤条件过滤显示容器
      --format string   格式化输出容器信息
  -n, --last int        显示最近n个创建的容器 (包含所有状态) (默认 -1)
  -l, --latest          显示最近创建的容器 (包含所有状态)
      --no-trunc        不截断输出
  -q, --quiet           只显示容器的ID
  -s, --size            显示总的文件大小

  2.退出容器

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

  3.删除容器docker rm

Usage:  docker rm [OPTIONS] CONTAINER [CONTAINER...]

Remove one or more containers

Options:
  -f, --force     强制删除正在运行的容器
  -l, --link      删除指定的链接
  -v, --volumes   删除和容器相关联的匿名卷

  可以通过参数传递的方式删除所有容器:

docker rm -f $(docker ps -aq)       # 删除所有容器

  4.启动、进入、停止容器的命令

docker start 容器ID
docker restart 容器ID
docker stop 容器ID

dockerfile

  dockerfile是用于构建自定义镜像的一种文本文件,这种文件由特定的语法构成并通过build命令构建出镜像。dockerfile有利于我们根据自己的需求定制镜像,并且通过简洁的方式描述了镜像的构建层级。

dockerfile语法

  dockerfile主要由两种语句,一种是#起始的注释语句,另一种是由特定命令关键词组成的构建指令,其中每个指令都会创建一个新的层。如下所示:

# 这是一句注释

# 下面是一句指令
FROM ubuntu

dockerfile的指令类型

  dockerfile的指令类型汇总如下:

指令 功能简介
FROM 指定构建新image时使用的基础image,通常必须是Dockerfile的第一个有效指令,但其前面也可以出现ARG指令
LABEL 附加到image之上的元数据,使用键值对格式
ENV 以键值对格式设定环境变量,可被其后的指令所调用,且基于新生成的image运行的容器中也会存在这些变量
RUN 以FROM中定义的image为基础运行环境运行指定命令,生成结果将作为新image的一个镜像层,并可由后续指令使用
CMD 基于该dockerfile生成的image运行容器时,CMD能够指定程序中默认运行的程序,因此之应该定义一次
ENTRYPOINT 类似于CMD指令的功能,但不能被命令行指定要运行的应用程序覆盖,且与CMD共存时,CMD的内容将作为该指令中定义的程序的参数
WORKDIR 为RUN、CMD、ENTYPOINT、COPY和ADD等指令设定工作目录
COPY 复制主机上或者前一阶段构建结果中(需要使用--from选项)文件或者目录生成新的镜像层
ADD 与COPY指令的功能相似,但ADD额外支持使用URL指定的资源作为源文件
VOLUME 指定基于新生成的image运行容器时期望作为volume使用的目录
EXPOSE 指定基于新生成的image运行容器时期望暴露的端口,但实际暴露与否取决于"docker run"命令的选项,支持TCP和UDP协议
USER 作为dockerfile中该指令后面的RUN、CMD和ENTRYPOINT指令中要运行的应用程序指定运行者身份UID,以及一个可选的GID
ARG 定义用于build过程中的变量,但仅对该指令之后的调用生效,其值可以由命令行选项"--build -arg"进行传递
ONBUILD 触发器,生效于由该dockerfile构建出的新image被用于另一个dockerfile的FROM指令作为基础镜像时
STOPSIGNAL 用于通知容器终止的系统调用信号
HEALTHCHECK 定义检测容器应用健康状态的具体方法
SHELL 为容器定义运行时使用的默认shell程序,linux程序默认使用["/bin/sh","-c"],windows默认使用["cmd","/S',"/C"]

编写自己的dockerfile

  为了方便自己的使用,我编写了自己的dockerfile用于创建一个基础ubuntu镜像,包括更换源、安装常用的工具、开启ssh等基本功能,方便将来的学习使用。dockerfile的内容如下所示:

FROM ubuntu
LABEL author="songjiahao" email="994628768@qq.com"

# 设置root密码为root,  格式如下 root:密码
RUN echo "root:root" | chpasswd

# 更换源
RUN sed -i s@/archive.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list      \
 && sed -i s@/security.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list     \
 && apt clean                                                                       \
 && apt-get update -y

# 安装常用的工具
RUN apt-get -y -q install build-essential python3 git gdb cmake tree vim zip net-tools openssh-client openssh-server 

# 创建python3的软链接
RUN ln -s /usr/bin/python3 /usr/bin/python

# 允许ssh root连接, 
RUN echo "Port 22\nPermitRootLogin yes" >> /etc/ssh/sshd_config
RUN mkdir /var/run/sshd

# 运行容器时启动sshd
CMD ["/usr/sbin/sshd","-D"]

build镜像并运行

  使用build命令由dockerfile创建镜像,命令格式如下所示:

# -f 指定dockerfile文件路径  -t指定生成的镜像名称和版本
# 最后的 . 不要漏掉
docker build -f ./ubuntu-base -t ubuntu-base:1.0 .

  build执行之后的结果如下所示(因为我已经构建过了,所以直接使用了原来构建的缓存,第一次构建的输出可能不同,但是构建成功会在终端中输出提示):

Sending build context to Docker daemon  3.584kB
Step 1/9 : FROM ubuntu
 ---> 27941809078c
Step 2/9 : LABEL author="songjiahao" email="994628768@qq.com"
 ---> Using cache
 ---> a9eafc0d2bc9
Step 3/9 : RUN echo "root:root" | chpasswd
 ---> Using cache
 ---> aa2381d26f49
Step 4/9 : RUN sed -i s@/archive.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list       && sed -i s@/security.ubuntu.com/@/mirrors.aliyun.com/@g /etc/apt/sources.list      && apt clean                                                                        && apt-get update -y
 ---> Using cache
 ---> 2017f2eaff09
Step 5/9 : RUN apt-get -y -q install build-essential python3 git gdb cmake tree vim zip net-tools openssh-client openssh-server
 ---> Using cache
 ---> fa96d338ec44
Step 6/9 : RUN ln -s /usr/bin/python3 /usr/bin/python
 ---> Using cache
 ---> 49357f7383da
Step 7/9 : RUN echo "Port 22\nPermitRootLogin yes" >> /etc/ssh/sshd_config
 ---> Using cache
 ---> 410c91af03c3
Step 8/9 : RUN mkdir /var/run/sshd
 ---> Using cache
 ---> 05100b210303
Step 9/9 : CMD ["/usr/sbin/sshd","-D"]
 ---> Using cache
 ---> 2af9c0293a70
Successfully built 2af9c0293a70
Successfully tagged ubuntu-base:1.0

使用run命令运行一个容器

  使用run命令运行一个程序,如下所示:

# 使用交互模式运行,--name用于指定容器的名称
docker run -it --name ubuntu-base-1.0 ubuntu-base

# 运行后使用ctrl+P+Q让容器运行在后台,然后开启控制台进入容器
docker exec -it ubuntu-base-1.0 /bin/bash

  如果需要使用ssh工具连接容器,请在启动容器时映射对应的端口,容器内部端口为22。


当珍惜每一片时光~