初识Docker

目的

熟悉Docker的基本使用、基于cgroups的资源限制和内容信任机制;

步骤

  1. 安装Docker

    1
    sudo apt install docker.io

  2. 从Docker Hub拉取Ubuntu基础镜像ubuntu:18.04,创建并运行容器;

    1
    2
    3
    4
    docker pull ubuntu:18.04
    docker images
    docker run ubuntu:18.04
    docker ps -a

  3. 运行并进入容器,观察容器内部和外部主机在主机名、用户和运行中进程上的不同;

    输入如下命令运行进入容器:

    1
    docker run --name=ubuntu -it ubuntu:18.04

    • 主机名

      • 外部:ubuntu
      • 内部:942d3efe3838

    • 用户

      • 外部:root
      • 内部:root

    • 进程

      • 未运行docker容器时的进程

      • 运行docker容器时的进程

      • 进入docker容器时的进程

  4. 编写Dockerfile,基于ubuntu:18.04镜像构建stress镜像;

    1. 创建Dockerfile文件

      1
      2
      3
      mkdir ubuntu-18.04-stress
      cd ubuntu-18.04-stress/
      vim Dockerfile
    2. 编写Dockerfile内容如下

      1
      2
      3
      4
      5
      # Dockerfile
      From ubuntu:18.04
      RUN apt-get update && apt-get install -y stress
      ENTRYPOINT ["/usr/bin/stress"]
      CMD []
    3. 生成镜像

      1
      docker build -t ubuntu-18.04-stress ./ubuntu-18.04-stress/

      其中-t表示标签,./ubuntu-18.04-stress/表示在目录/ubuntu-18.04-stress/下执行Dockerfile

      查看成功生成镜像

  5. 从stress镜像启动容器,用docker run--memory--memory-swap参数限制容器能够使用的内存容量,在容器中用stress分配内存验证限制的效果

    输入如下命令

    1
    docker run --memory 100M --memory-swap 200M e73e92924e16 --vm 1 --vm-bytes 500M --verbose

    以id为e73e92924e16的镜像创建容器,使用--memory限定该容器分配内存为100M,--memory-swap限定容器最大可分配总内存为200M;设置处理malloc()内存分配函数的进程数量为1,使用--vm-bytes分配内存500M,--verbose表示debug模式。

    因为使用--memory-swap限定容器最大可分配总内存为200M,当stress需要分配500M内存时明显不能满足,容器退出,证明--memory--memory-swap起了作用;

  6. 从stress镜像同时启动多个容器,用docker run--cpu-shares参数限制容器能够使用的CPU资源,在容器中用stress验证限制的效果

    分别打开两个窗口启动两个容器

    1
    2
    docker run --name=test2 e73e92924e16 -c 1024 --cpu 2	#窗口1
    docker run --name=test2 e73e92924e16 -c 512 --cpu 1 #窗口2

    其中窗口1设置--cpu-shares相对值为1024,cpu数量为2

    窗口1设置--cpu-shares相对值为512,cpu数量为1

    查看CPU占用率,test1的两个CPU各使用约50%,test2的CPU使用约100%,这是由于CPU权重约为2:1(1024:512),以及CPU数量为2:1导致的

  7. 在Docker Hub上创建账号;

    Docker账号已创建,ID为leeyuxun;

  8. 将stress镜像推送到Docker Hub

    1. 登录docker

      输入如下命令后输入用户名和密码登录

      1
      docker login

    2. 由于本地仓库名与Docker Hub上不对应,输入如下命令进行更改

      1
      docker tag 2338a41b1ae5 lililizhilin/stress:v1

      或删除原镜像,重新生成镜像

      1
      docker build -t leeyuxun/stress:v1 ./ubuntu-18.04-stress/
    3. 将镜像上传到docker hub的仓库

      1
      docker push leeyuxun/stress:v1

    4. 上传完成后,在仓库中查看上传成功

    5. 输入如下命令删除本地的镜像

      1
      docker rmi leeyuxun/stress:v1
  9. 通过设置DOCKER_CONTENT_TRUST环境变量启用docker内容信任

    命令行输入如下内容启用docker内容信任

    1
    export DOCKER_CONTENT_TRUST=1

    后续的 docker push 命令会在推送镜像时自动对镜像进行签名。因此,所有的 pull、 build 和 run 命令只会对已签名的镜像起作用。

  10. 将带签名的stress镜像推送到Docker Hub(用不同的tag区分未签名和签名版本)

    1. 输入如下命令新建带签名的stress镜像标签为DCT

      1
      docker build -t leeyuxun/stress:DCT ./ubuntu-18.04-stress/

    2. 将带签名的stress镜像推送到Docker Hub

      1
      docker push leeyuxun/stress:DCT

      由于开启 DCT ,该镜像会在推送时自动被签名,在签名时会创建两个密钥:

      • 根密钥(Root key)
      • 库密钥(Repository key)

      默认情况下,两个密钥被保存在家目录下的隐藏目录 ~/.docker/trust下;

      根密钥是主密钥,它用于创建和签名新的库密钥,这意味着,用户需要使用强密码予以保护,并且在不使用它的时候对其离线保存。正常情况下,每个用户应该仅有一个密钥,甚至一个团队或组织仅有一个密钥。并且通常情况下仅用它来创建新的库密钥。

      库密钥也被称为标签密钥,用于对需要推送到指定镜像库的打标签的镜像进行签名。因此,每个镜像库配备一个库密钥。如果密钥遗失,相对来说容易恢复,但是仍然应该使用强密码进行保护,并妥善保存。

      在Docker Hub中显示上传成功

    3. 删除本地镜像

      1
      docker rmi leeyuxun/stress:DCT
  11. 分别尝试拉取未签名版和签名版stress镜像,观察结果

    1. 拉去未签名版的stress镜像

      1
      docker pull leeyuxun/stress:v1

      显示错误如下,v1版本没有信任数据

      输入如下命令,可以跳过签名拉取镜像

      1
      docker pull --disable-content-trust leeyuxun/stress:v1

      输入如下命令,运行该镜像

      1
      docker container run -d --rm leeyuxun/stress:v1

      仍然v1版本没有信任数据

    2. 拉取签名版的stress镜像

      1
      docker pull leeyuxun/stress:DCT

      通过本地保存到库密钥可以正确拉去签名版的stress镜像

      输入如下命令可以正确运行该镜像

      1
      docker container run leeyuxun/stress:DCT  --vm 1 --vm-bytes 100M --verbose

      成功创建并运行容器