Docker简介及常用命令

Docker简介及常用命令

 

Docker是一种容器技术,现在,它已经成了Linux相关的软件开发和部署事实上的标准。Docker是个开源项目,它彻底释放了计算虚拟化的威力,极大提高了应用的维护效率,降低了云计算应用开发的成本。通过使用Docker,不仅可以让应用的部署、测试和分发都变得前所未有的高效和轻松,而且,当你在实验结束后,可以一键删除所有镜像和临时文件,而不会在你的操作系统上的各种目录中留下垃圾(当然,Docker本身还是需要占用一些存储空间)。当然,如果你的硬盘空间足够大,是否占用存储空间也不算是主要矛盾,更重要的是,通过使用Docker,可以把环境隔离开来,避免与其它环境产生冲突。比如笔者在开发过程中,经常用到Kamailio以及FreeSWITCH的不同版本,它们又分别依赖于很多不同的第三方软件库,不同的库又有很多不同的版本……,使用Docker容器就可以很好地避免它们之间的冲突。

Docker简介

如果你还不熟悉Docker,那至少应该听说过虚拟机。虚拟机是在真正的物理机上虚拟出来的“电脑”,有虚拟的CPU、内存、硬盘、网卡等。而Docker技术在虚拟机的基础上更进一步,通过Linux内核和内核功能(例如Cgroup和Namespace)来分隔进程,以便各进程相对独立运行,但还能共享宿主机的内核和网络资源等。

为了理解Docker,我们先来理解一下虚拟机。大家都知道,计算机有CPU、内存、硬盘、网卡等最基本的硬件,而为了有效的使用这些硬件,需要一个操作系统来管理和维护它们,典型的操作系统有Windows、Linux、macOS等(手机其实也是一台计算机,有Android和iOS等操作系统)。一般来说一台计算机上只能运行一个操作系统,为了能同时运行多个操作系统,人们发明了虚拟机。虚拟机就是使用软件模拟CPU、内存、硬盘和网卡等,这样就是在操作系统中套操作系统。相对于虚拟机,运行原来的操作系统的主机就称为宿主机。常见的虚拟机软件有VMWare和Virtual Box、以及Xen、KVM等。

但完全的虚拟各种硬件有些慢,有些重。在Linux内核中,有一个轻量级的东西叫control groups(即Cgroups),它可以做资源控制、进程控制和隔离。使用Cgroups做出来的虚拟化技术叫LXC(Linux Container),由于LXC只是使用了资源隔离,而不需要像虚拟机那样将虚拟机里全部的CPU指令“翻译”成宿主机的指令,因而更轻量级。

但是LXC用起来还比较麻烦,因而出现了很多年其实没有流行起来,直到Docker出现。

Docker其实并不是什么虚拟化技术,它只是提供了一组工具,可以方便的生成和管理镜像,启动虚拟化的容器等。所以,这些的虚拟化也不再叫虚拟机,而叫容器。就是说,在一个Linux操作系统上,可以跑很多不同的容器,不同的容器之间的资源(如CPU、进程、内存、网络、硬盘空间等)都是隔离的,不同容器里的内容可以使用不同的内容,不同版本的应用序、或依赖库等,彼此独立运行,很方便,但它们实际上是共用内核,因而只适用于Linux。也就是说,宿主机和服务器必须都是Linux。

在Linux宿主上运行Docker开销很小,也理所当然。但人们还想在macOS上及Windows上运行Docker。最早都是以虚拟机的方式实现的,如基于Virtual Box的实现。但后来,macOS上有了性能更好的Hypervisor.Framework(xhyve是它的具体实现),Windows上也出现了WSL2[^wsl2],支持更好的虚拟化。

[^wsl2]: 值得一提的是微软最初把开源和Linux视为“毒瘤、癌症”,但后来他们表示拥抱开源,现在有了WSL及WSL2(Windows Subsystem for Linux)以及WSA(Windows Subsystem for Android),相当于直接把Linux内核做进了Windows里,直接在Windows中就可以运行Linux和Android程序。

还有一个比较有用的工具叫Docker Compose,它使用一组YAML格式的编排文件,可以更方便地管理很多容器。最初该工具是单独提供的,不过在最新的Docker版本里,已经把该工具整合进了Docker。

Docker安装

如果你使用Ubuntu或者Debian Linux操作系统,可以使用如下命令一键安装(通过--mirror参数使用阿里云的镜像速度会快一些):

curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun

或使用DaoCloud提供的一键安装方式:

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

在其它Linux系统上(如CentOS、RHEL等)以及macOS和Windows上的安装方法也有所不同,篇幅原因我们就不一一介绍了,以下链接上列出了各操作系统上Docker的安装方法:

下面几个链接上也有中文的安装说明,供参考:

基本概念

这里我们简单介绍一下Docker相关的一些基本概念。

  • 镜像

即Docker Image。里面是一些文件,相当于一个硬盘。镜像是分层的,便于传输和分享。如果日后镜像有更新,可以只下载更新过的层,而没动过的层不需要重新下载。

  • Tag

镜像有一个Tag属性,相当于给镜像打个记号。Tag是可选的,它就是一个字符串,如果没有Tag,默认为latest。Tag通常用于标志镜像的版本。

  • 容器

通过一个镜像可以启动一个容器,它是一个隔离的运行环境(可以认为是个轻量级的虚拟机),可以进入一个容器的内部执行命令。

Docker容器在运行期间会保存一个临时的镜像,用于存储变动过的文件。容器重启临时镜像的内容还会保留,至到容器被彻底删除。

  • 网络

网络最典型的使用方法是使用NAT模式,在Linux宿主机上也可以使用host模式,但后者实际上是破坏了网络隔离。

  • Docker Hub

类似Github是众所周知的代码仓库聚集地,Docker hub就是Docker镜象的聚集地。除Docker Hub外,其他云厂商也提供镜像服务,如附录2中的xswitch-free镜象就存储在腾讯云上。

常用命令

以下命令经常用到。

启动一个容器。如:

docker run hello-world

Hello from Docker!

在首次需要一个镜象时,Docker会自行从Docker Hub(或指定的其他镜象服务器)上下载。其中Hello from Docker是镜像启动后打印的内容,打印后即退出,容器也会退出。如果想让镜像启动后不退出,则可以运行一个永远不退出的程序,如以下命令运行alpine(它是一个小的Linux发行版,非常小)镜像的Shell:

docker run -it alpine sh

其中,-it参数表示开启交互式终端。进入Shell环境后就可以在容器内部执行一些命令了。在宿主机上换一个终端容器,可以使用docker ps命令列出所有正在运行的镜象,如:

# docker ps
CONTAINER ID   IMAGE   COMMAND            CREATED  STATUS  PORTS     NAMES
873ea4a68dc0   alpine  "sh"    About a minute ago  Up

有了,Container ID,就可以在宿主机上可以进入这个容器:

docker exec -it 873ea4a68dc0 sh

当然,Container ID是自动生成的,在启动Docker镜象时可以指定一个好记的名字,如

docker run --name alpine-test --rm alpine sh

其中,--name指定一个名字(alpine-test),--rm表示容器停止运行后,自动删除相关资源(如果在镜象运行期间创建了一个文件,则如果没有--rm的话,重启镜象后文件内容还在)。

有了名字,以后进入容器就可以把Container ID换成名字,如:

docker exec -it alpine-test sh

在容器中可以使用exit退出Shell,如果是最初启动的那个Shell退出,那么容器就自动退出。

其他常用的参数是使用-p做NAT端口映射和-e设置环境变量等。

在宿主机上可以查看标准输出(STDOUT)的日志:

docker logs alpine-test

-f参数可以进入Follow模式,即跟踪日志输出永不退出:

docker logs -f alpine-test

停止容器:

docker stop alpine-test

彻底删除:

docker rm alpine-test

在Docker运行期间,会产生大量缓存,如自动下载的镜象,没有使用--rm自动删除容器产生的缓存等,时间长了会占用大量硬盘空间。可以使用如下命令删除(注意这个命令会删除东西,在使用前确保知道你自己在做什么,如果不确定的话最好多看看Docker手册或找个同事帮助你一块看着):

docker system prune -a

Docker Compose

此处的Docker Compose文件为例(docker/uuam.yml):

version: "3.3"                # 配置文件的版本号

services:                     # 服务,可以有多个
  kb-kam:                     # 定义一个Kamailio服务,名字任意
    container_name: kb-kam    # 启动后,容器的名字,类似于`docker run --name 名字`
    image: kamailio/kamailio-ci:5.5.2-alpine  # 使用的镜像,来自Docker Hub
    # restart: always         # 崩溃后是否自动重启,在生产环境中经常使用
    env_file: .env            # 从该文件中自动导入一些环境变量
    stdin_open: true          # 是否启用标准输入
    tty: true                 # 是否启用控制台,这个和stdin_open都开启可以在控制台输入
    # command: ["/bin/sh"]# 容器启动后执行的命令,如果没有则执行构建时Dockerfile中指定的命令
    privileged: true          # 特权模式,如是否可以在容器中运行tcpdump抓包或gdb调试
    entrypoint:               # 启动后自动执行的命令
      - /bin/sh
      # - /start-kam.sh
    volumes:                  # 挂载宿主机上的目录或文件,这些文件在容器停止后不会消失
      - ../etc:/usr/local/etc/kamailio:cached
      - ../etc:/etc/kamailio:cached
      - ../start-kam.sh:/start-kam.sh
    networks:                 # 指定网络,这里我们指定了一个外部网络,方便跟其他容器共享
      - kamailio-example
    ports:                    # 映射端口,这里引用了环境变量,在.env中设置
      - "${KAM_SIP_PORT}:${KAM_SIP_PORT}"
      - "${KAM_SIP_PORT}:${KAM_SIP_PORT}/udp"

networks:
  kamailio-example:
    external: true

其中,外部网络使用docker network create kamailio-example命令创建,这样,可以将Kamailio容器与FreeSWITCH容器启动到同一个网络上(使用相同的网络地址段)。

可以通过以下命令启动容器:

docker-compose -f docker/db.yml up      # 启动到前台,可以在当前Shell中看日志输入命令等
docker-compose -f docker/db.yml up -d   # 启动,进入后台模式,不占用当前Shell

上述命令中,如果把up换成down则可以停止服务。从上面可以看出,有了这个YAML编排文件,可以比原始的docker少输入很多命令行参数。另外也可以将多个服务写到同一个YAML文件中同时启停多个服务、管理他们的依赖关系等。

其他

本文只是简单介绍了Docker和Docker Compose,可以带大家快速上手安装和使用Docker,更多的Docker使用方法还需要读者自行去找相关资料学习。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值