首页 > 其他分享 >Docker 详细

Docker 详细

时间:2022-09-08 01:33:06浏览次数:94  
标签:容器 run apt 详细 镜像 Docker docker

Prerequisite

很久之前写过 Docker 的博客,但那时也只是随意了解一下,现在打算重新学习(但我依然没有实际场景需要用到,因此以后可能还会再写一次)

参考文章:廖雪峰【一文读懂Docker原理】
参考文章:Install Docker Engine on Ubuntu
参考文章:浅析 Dockerfile 中 RUN、CMD 以及 ENTRYPOINT 指令的异同
参考文章:Docker 常用命令
参考视频:Docker技术从0到1全覆盖(对应笔记
参考报错:failed to solve with frontend dockerfile.v0: failed to create LLB definition
使用镜像源:清华大学开源软件镜像站

Docker 原理

Docker 的容器是一种对进程进行隔离的运行环境(进程是 Linux 操作系统执行任务的最小单元)
Docker 本质就是帮助我们设置好隔离环境后,启动容器中不同隔离的进程(Linux 系统本身负责隔离)

隔离的方法有三种:

  • 第一种就是进程之间看不到彼此,这是由 Linux 的 Cgroup 机制实现的。进程隔离的结果就是以隔离方式启动的进程看到的自身进程 ID 总是 1,且看不到系统的其他进程。
  • 第二种就是隔离系统真实的文件系统。Docker 利用 Linux 的 mount 机制,给每个隔离进程挂载了一个虚拟的文件系统,使得一个隔离进程只能访问这个虚拟的文件系统,无法看到系统真实的文件系统。至于这个虚拟的文件系统应该长什么样,这就是制作 Docker 镜像要考虑的问题。比如我们的 Python 程序要正常运行,需要一个 Python3 解释器,需要把用到的第三方库如 psutil 引入进来,这些复杂的工作被简化为一个 Dockerfile,再由 Docker 把这些运行时的依赖打包,就形成了 Docker 镜像。我们可以把一个 Docker 镜像看作一个 zip 包,每启动一个进程,Docker 都会自动解压 zip 包,把它变成一个虚拟的文件系统。
  • 第三种就是网络协议栈的隔离(以下面要运行 ZooKeeper 和 Kafka 举例)
# 将 zookeeper 进程的端口号映射到宿主机,从而在宿主机上访问 zookeeper
# 但这只是 zookeeper 进程的端口映射,如果需要映射多个进程,需要利用 Docker Compose
docker run -p 2181:2181 zookeeper:latest

因为 ZooKeeper 和 Kafka 都有监听的端口,但 Linux 可以为进程隔离网络,Docker 默认启动的 ZooKeeper 和 Kafka 进程拥有自己的网络名字空间,与宿主机不同。利用 Docker Compose,把 ZooKeeper 和 Kafka 运行在同一个网络名字空间里,并通过 zookeeper:2181 来访问 ZooKeeper 端口,让 Docker 自动把 zookeeper 名字解析为动态分配的 IP 地址

Docker Linux 下载

$ sudo apt-get install apt-transport-https ca-certificates curl gnupg2 software-properties-common

$ sudo mkdir -p /etc/apt/keyrings

$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

$ echo \
   "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/ubuntu \
   $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

$ sudo apt-get update

$ sudo apt-get install docker-ce docker-ce-cli containerd.io docker-compose-plugin

Docker 用法

基础命令
# 登入 Docker Hub(用户名为:courserli)
docker login -u courserli

# 从 Docker Hub 下载镜像(名字为:courserli 的 hello-docker)
docker pull courserli/hello-docker

# 分享镜像到 Docker Hub(名字为:courserli 的 hello-docker,默认 tag 为:latest)
docker push courserli/hello-docker
镜像命令
# 查看全部 docker 镜像
docker image ls

# 删除 docker 镜像
docker image rm 镜像名称

# 构建本地镜像(由当前目录下的 Dockerfile 文件构建,构建镜像名为 tuanzi/test)
docker build . -t tuanzi/test
进程命令
# 启动 docker 容器(-it 是交互式操作终端,sagemath/sagemath 是镜像名,--rm 表示在容器退出时自动清理容器内部的文件系统)
docker run -it --rm sagemath/sagemath

# 启动 docker 容器(-d 后台运行,-p 端口映射,前者为容器内部端口,后者为映射本地端口,如果镜像名在本地找不到,会自动联网 pull)
docker run -d -p 80:80 docker/getting-started

# 启动 docker 容器(-v 是挂载路径,后接挂载本地路径和容器路径)
docker run -it --rm -v 路径:/share/data tuanzi/test

# 在运行的 docker 容器中执行命令(ls 就是执行的命令)
docker exec -it nginx ls

# 查看正在运行的 docker 容器进程
docker ps

# 查看已经停止的 docker 容器进程
docker ps -a

# 停止 docker 容器进程(参数是 CONTAINER ID)
docker rm -f 042c94072180
Docker file

这里以一个实际的例子回顾,这是我的本地的目录

  • test
    • db
      • data
    • Dockerfile
    • run.sh

执行命令的路径与 Dockerfile 同级

  • Dockerfile 文件:
FROM ubuntu:16.04

COPY run.sh /run.sh

VOLUME /share/data

RUN useradd nss

RUN sed -i s@/deb.debian.org/@/mirrors.aliyun.com/@g /etc/apt/sources.list && \
    sed -i s@/security.debian.org/@/mirrors.aliyun.com/@g /etc/apt/sources.list
    
RUN ["apt-get", "update", "-y"]

WORKDIR /home/nss

RUN chmod +x /run.sh

ENV FLAG=NSSCTF{test_flag}

EXPOSE 80/tcp

CMD [ "helloworld" ]

USER nss

ENTRYPOINT [ "/run.sh" ]
  • run.sh 文件:
#! /bin/bash
echo "Run with user `whoami`"
echo "Run with directory `pwd`"
echo "Run with environment $FLAG"
echo "Run with parameter $1"
tail -f /dev/null

read v
while [ "$v" == "n" ];
do
    cat /share/data/data
    read v
done;

关于内容的具体细节可以看这篇文章,我来特别说一下:

  • 如何挂载?

一般构建的命令是 docker build . -t tuanzi/test,然后运行是 docker run -it --rm tuanzi/test;正如 Dockerfile 文件中的 VOLUME /share/data 所描述,我需要在命令行中添加挂载路径,即 docker run -it --rm -v 路径:/share/data tuanzi/test,此时容器内 data 文件的内容会随着本地 data 文件而改变

  • 如何直接进入容器中(而不是终端交互)?

去掉 Dockerfile 文件中的 RUN、CMD、ENTRYPOINT 的命令,或者执行 docker run -it --rm tuanzi/test /bin/sh 命令,用于覆盖掉 Dockerfile 文件中的 ENTRYPOINT

针对 RUN、CMD 和 ENTRYPOINT,大佬给出了总结:

  • RUN、CMD 和 ENTRYPOINT 指令都可以用来执行具体的命令
  • RUN 指令是在 Docker 镜像构建时发挥作用, 可以使用多个该命令, 且执行结果会记录到镜像中
  • CMD 和 ENTYPOINT 指令是在容器启动时自动执行, 均只有最后一个该指令有效, 且均可以在 docker run 中被覆盖
  • ENTRYPOINT 指令和 CMD 的区别在于使用 ENTRYPOINT 时 CMD 指令会被作为其默认参数, 而用户也可以在启动容器时通过覆盖 CMD 指令来输入参数; 此外, 这也意味着 ENTRYPOINT 指令的内容不易被用户命令覆盖

标签:容器,run,apt,详细,镜像,Docker,docker
From: https://www.cnblogs.com/CourserLi/p/16549995.html

相关文章

  • Docker
    Docker方式对比物理机部署部署慢、成本高、资源浪费、难扩展、难迁移、硬件兼容差虚拟机部署部署较慢、成本较高、资源较浪费容器化部署部署快,成本低,源利用......
  • Docker部署安装 windows
    Docker下载地https://www.docker.com/https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi   ......
  • docker容器 日志迁移
    起因docker安装网心云(挂载在外置硬盘上),这两天莫名其妙把我nas中的硬盘给跑满了,通过搜索后发现,这是docker容器运行时产生的日志文件,默认保存在系统/var/lib/docker目录......
  • [安装配置] Linux docker mysql 安装
    一.docker安装MySQLLinux命令:dockerpullmysql:5.7dockerimages查看所有镜像二.创建实例并启动suroot切换到Linuxroot用户dockerrun-p3306:3306--name......
  • Taurus.MVC-Java 版本打包上传到Maven中央仓库(详细过程):4、Maven项目转换与pom.xml配置
    文章目录:Taurus.MVC-Java版本打包上传到Maven中央仓库(详细过程):1、JIRA账号注册Taurus.MVC-Java版本打包上传到Maven中央仓库(详细过程):2、PGP下载安装与密钥生成发布Tau......
  • 03-安装docker及使用docker安装其他软件(手动挂载数据卷)
    中秋明月,豪门有,贫家也有,极慰人心Linux安装docker可以参考官方的安装文档centos安装docker:https://docs.docker.com/engine/install/centos/#1.卸载之前的docker......
  • docker 构建 TensorRT 指定版本 image
    docker构建TensorRT指定版本imagetensorrt——相关库的说明Tensorrt这是github上tensorrt的一个项目库。其介绍为:这个存储库包含了NVIDIATensorRT的开源软件(OSS)......
  • C++中构造函数的超详细讲解
    转:https://blog.csdn.net/guishangppy/article/details/125876729C++在C语言的基础上增加了类和对象的概念,官方对类和对象的解释是:对象是类的实例化,类是对象的抽象,其实这......
  • docker +zabbix
    基于阿里云服务器安装1、下载镜像1dockerpullmysql:8.023dockerpullzabbix/zabbix-server-mysql:centos-latest45dockerpullzabbix/zabbix-web-nginx-my......
  • [安装配置] Linux docker 安装
    官方安装文档地址:https://docs.docker.com/engine/install/centos/1.卸载旧版本dockersudoyumremovedocker\docker-client\......