深入浅出docker

时间:2022-05-02 22:40:30

笔者在海外工作多年,所以文中多用英文单词,有些时候是为了更精准的描述,请见谅。希望这篇随笔能帮大家入门docker。由于在海外连博客园有些慢,所以我图片用的比较少,以后再考虑一下如何更好的解决图片上传问题。

docker 已经是比较成熟的技术了,尤其是现在搭配kubernetes,swarm 让企业级部署更加轻松。以前主要是虚拟机技术,在host os上通过hypervisor连多个guest os,比较heavy。Docker则是在host os上直接联通多个container(相关联的container共享bin/library),属于更轻量级的架构。

深入浅出docker

Docker 架构

docker client, docker daemon, docker.io registry

docker daemon(dockerd)是一个用来管理container的守护进程,它支持unix, tcp, fd几种联通方式,通常情况下相同机器CLI访问用的是unix domain socket(/var/run/docker.sock),记得要把用户名添加到docker group中,否则在不用sudo的情况下,会没有权限访问/var/run/docker.sock,接下来我会再提一下。

docker.io registry,平时用git会有github,docker也会有docker hub, docker.io registry就是常用的docker image存放的地点.

写:你自己可以通过docker build/docker commit创建image, 然后通过docker login/docker tag/docker push 上传image

读:可以通过docker search 找到想要的image,比如 docker search nginx, 注意search结果里面标明OFFICIAL 【OK】是官方维护的稳定版本,剩下的基本都是个人项目。docker pull用来把image pull/extract到本地,你会发现pull的时候,是多个layer并发pull/extract, 如果是企业级应用,可以用企业内部的registry, 然后caching hot pull path,这样pull 几个或者几十G的image速度会更快。当然很多layer是共享的,所以只是第一次pull会慢一些,以后就是用本地的cache了。

Docker 安装

follow 官方文档就可以了,我主要在Mac和Linux上装过,唯一要注意的就是:sudo usermod -a -G docker $your_username,可以通过cat /etc/group | grep docker来确认是否已经把用户添加到docker group里面. 还有一点 docker 默认安装路径是/var/lib/docker, 可以通过在/etc/default/docker添加 DOCKER_OPTS="-g $otherpath" 来更改路径,通常适用于默认分区空间不够需要使用更大分区的情况。注意如果你已经运行了一段时间,然后更改docker路径之后,会发现之前的image和container都不见了,那是因为它们还在旧的路径中。

Docker 命令

docker images 显示repository和tag,image ID, 创建事件,大小。repository:tag 这个格式相当于docker image的uri。tag 主要是控制版本, 比如常用的latest

docker ps 显示正在运行的container 和它们的状态, “-a" 显示所有运行过的container(包括已退出的)

这里要简单描述一下image和container的区别,image是静态的snapshot,而container是运行了这个snapshot,可以实时通信,同时可以docker commit成新的image保留下来。

docker rename 重命名,docker run 会随机给生成的container默认的名字(这个太有趣了),你会想要重命名为你能记住的名字

docker run, 这就是最重要的生成container的命令了,如果你想要进行交互,那么需要用docker run -it $uri /bin/bash, 这样你就可以直接用bash进行交互,如果是运行像nginx这种服务器,就直接-d 让它们在背景运行就可以了。

docker attach, 这个通常不会怎么用到,因为它的弊端在于一旦退出,attached进程也跟着结束了,这可能往往不是你想看到的 :)

docker exec, 这个更常用,因为它解决了上面提到的问题 docker exec -it $uri /bin/bash

注意如果你用多个docker run,那么会生成多个container,你可能只是想docker run一次,接下来以后就用docker exec访问就可以了,初学者容易犯错误。

docker rmi 删除image,注意如果你有正在运行的container,它会报错,除非你强制删除。注意就算你强制删除,你会发现依赖的container仍然可以正常使用(设计的好!)即使关闭,重启啥的依然能用(牛逼!),只是不能生成新的container了。

docker rm 删除container

docker inspect 查看image内容

Docker image

这就属于进阶题目了,下面举个简单的例子:

FROM debian:stable
MAINTAINER huashao1985 <huashao1985@lalala.com> RUN apt-get update
RUN apt-get upgrade

你会发现每一行代码都会生成一个docker layer,这4行docker layer就组成了一个docker image。如果想要减少layer的数量,可以用比如 RUN apt-get udpate && apt-get upgrade的方式。

Docker 容器生命周期

下面聊聊容器的生命周期,docker run会启动一个新容器,然后容器可以被docker stop,也可以被docker start,docker ps可以看到当前容器的状态。

Docker port

最后聊聊docker port,比如你在docker里面启动了nginx(准备以后专门找机会聊聊nginx),它的映射可能是0.0.0.0:32678->80/tcp, 0.0.0.0:32679->443/tcp,可以通过 docker port $image $CONTAINERPORT查看。那么如果我想把nginx绑定到我想指定的端口该怎么办呢?可以这样: docker run -d -p 8080:80 --name=$CONTAINER_NAME $IMAGE

好了,这次大概就聊这些,happy docker!