docker基础简介

一、docker架构

img

在这里插入图片描述

二、Docker 基本命令

1、查看 Docker 版本

查看 Docker 版本包括 Docker 版本号、API 版本号、对应的 Git Commit、Containerd 和 runC的版本信息等。

# docker version
Client: Docker Engine - Community
Version: 20.10.4
API version: 1.40
Go version: go1.12.10
Git commit: 9013bf583a
Built: Fri Oct 18 15:52:22 2019
OS/Arch: linux/amd64
Experimental: false
Server: Docker Engine - Community
Engine:
 Version: 20.10.4
 API version: 1.40 (minimum version 1.12)
 Go version: go1.12.10
 Git commit: 9013bf583a
 Built: Fri Oct 18 15:50:54 2019
 OS/Arch: linux/amd64
 Experimental: false
containerd:
 Version: 1.2.6
 GitCommit: 894b81a4b802e4eb2a91d1ce216b8817763c29fb
runc:
 Version: 1.0.0-rc8
 GitCommit: 425e105d5a03fabd737a126ad93d62a9eeede87f
docker-init:
 Version: 0.18.0
 GitCommit: fec3683
  • OCI:Open Container Initiative的简称,由Linux基金会主导开发OCI规范和标准,目的是

    围绕容器格式和Runtime(运行时)制定的一个开放的工业化标准。

  • Containerd:Docker为了兼容OCI标准,将容器Runtime及其管理功能从Docker守护进程中

    剥离出来,用于不启动Docker也能直接通过Containerd来管理容器。

  • RunC:Docker按照OCF(Open Container Format)开放容器格式标准制定的一个轻量级

    工具,可以使用RunC不通过Docker引擎即可实现容器的启动、停止和资源隔离等功能。

2、查看 Docker 详细信息

# docker info
Client: # Client 端
Debug Mode: false # 是否开启 Debug 模式
Server: # Server 端
Containers: 8 # 容器个数
 Running: 4 # 正在运行的容器个数
 Paused: 0 # 暂停的容器个数
 Stopped: 4 # 停止的容器个数
Images: 8 # 镜像个数
Server Version: 20.10.4 # 当前服务器 Docker Server 的版本
Storage Driver: overlay2 # 存储驱动,一般为 overlay2,性能好速度快
 # 其他驱动 aufs、overlay、brtfs
 Backing Filesystem: xfs # 服务器文件系统
 Supports d_type: true # 目录条目类型,用来表示一个文件是文件、管道还是套接字。
 # 在格式化 xfs 文件系统时,必须指定 ftype=1
 Native Overlay Diff: true 
Logging Driver: json-file
# 日志驱动,json-file 表示存在本地
Cgroup Driver: cgroupfs # 限制和隔离的驱动,生产环境建议使用 systemd
Plugins:
 Volume: local
 Network: bridge host ipvlan macvlan null overlay
 Log: awslogs fluentd gcplogs gelf journald json-file local logentries 
splunk syslog # Docker 支持的日志驱动
Swarm: inactive # Docker 官方的容器编排工具,inactive 不开启,active 开启
...
Docker Root Dir: /var/lib/docker # Docker 根目录,生产环境建议使用 SSD 硬盘,或
者独立的磁盘,不要和系统盘用同一个磁盘。
Debug Mode: false
Registry: https://index.docker.io/v1/
Labels:
Experimental: false
Insecure Registries:
 127.0.0.0/8
Live Restore Enabled: false # Docker 热更新,生产环境建议设置为 true

3、常用命令

搜索镜像

# docker search nginx

拉取下载镜像

# docker pull nginx
# docker pull nginx:1.15

查看本地镜像

# docker images | grep nginx-v2

更改镜像 tag

# docker tag nginx-v2 dotbalo/nginx-v2:test
# 如果是推送到自己公司内部的镜像仓库,可以使用如下命令 docker tag nginx-v2 你公司的
镜像仓库地址/nginx-v2:test
# docker images | grep nginx-v2

镜像仓库登录

# docker login 
Login with your Docker ID to push and pull images from Docker Hub. If 
you don't have a Docker ID, head over to https://hub.docker.com to create 
one.
Username (dotbalo): username
Password: 输入仓库密码
Login Succeeded

推送本地镜像到远程仓库

docker push dotbalo/nginx-v2:test

启动容器

使用 run -ti 前台启动一个容器:

# docker run -ti nginx bash
root@23bc7ccabb09:/#
# 也可以使用-ti --rm 参数,表示前台启动的容器退出后即删除

如果一个镜像需要一直运行,可以使用-d 进行后台启动:

# docker run -tid nginx bash
1bcf5154d5c3a57d92a6796f526eac2cefd962aaca9cf4098689bfe830bb9e5e
# 也可以使用--restart=always,如果容器异常自动重启

端口映射

# docker run -ti -p 1111:80 nginx bash 
root@cd676d572188:/#

查看日志

# docker logs -f 容器 ID/容器名称 --tail 1 
W0805 09:58:41.745799 8 controller.go:1130] SSL certificate for 
server "xxx" is about to expire (2020-06-19 03:44:03 +0000 UTC)

数据持久化

# docker run -ti -p 1111:80 -v /etc/hosts:/etc/hosts nginx bash 
root@cd676d572188:/#

查看当前正在运行的容器

# docker ps

查看所有容器,包括已经退出的:

# docker ps -a

查看正在运行的容器(即显示出容器的 ID):

# docker ps -q
...
0d1a98b3c402
c1fd8ff1f7f2
86b1c069024b
...

查看所有容器的 ID,包括已经退出的:

# docker ps -aq
...
17019738d93d
b3bb2a592dfb
e0637b76afe3
0b74e028d0ae
65a1b5e1e501
...

进入容器

进入到一个后台运行的容器(即之前用-d 命令参数来指定后台运行方式的容器):

# docker ps | tail -1
86b1c069024b nginx:latest "nginx -g 'daemon ..." 4 days ago 
Up 21 hours 80/tcp, 0.0.0.0:16443->16443/tcp nginx-lb
# docker exec -ti 86b1c069024b bash
root@nginx-lb:/#

文件拷贝

将本机的文件拷贝到容器,拷贝支持双向拷贝,也支持将容器的内部文件拷贝到宿主机:

# docker cp README.md 92aceec0dcdd327a709bf0ec83:/tmp
#exec 也可直接执行容器命令
# docker exec 92aceec0dcdd327a709bf0ec83 ls /tmp/
README.md

删除容器和镜像

删除已经退出的容器:

# docker ps -a |grep Exited | tail -3
600e5da5c196 3cab8e1b9802 
"etcd --advertise-..." 4 days ago Exited (137) 21 hours ago 
k8s_etcd_etcd-k8s-master01_kube-system_c94bb8ceba1b924e6e3175228b168fe0_0
5a1848d923a1 registry.cnhangzhou.aliyuncs.com/google_containers/pause-amd64:3.1 "/pause" 
4 days ago Exited (0) 21 hours ago 
k8s_POD_kube-scheduler-k8s-master01_kubesystem_9c27268d8e3e5c14fa0160192a2c7988_0
280fc86494f1 registry.cnhangzhou.aliyuncs.com/google_containers/pause-amd64:3.1 "/pause" 
4 days ago Exited (0) 21 hours ago 
k8s_POD_etcd-k8s-master01_kube-system_c94bb8ceba1b924e6e3175228b168fe0_0
# docker rm 600e5da5c196 5a1848d923a1 280fc86494f1
600e5da5c196
5a1848d923a1
280fc86494f1
# docker ps -a |grep Exited | grep -E 
"600e5da5c196|5a1848d923a1|280fc86494f1"

删除本机镜像,比如删除 REPOSITORY 或 TAG 为 none 的镜像:

# docker images | grep none
<none><none> 7ad745acca31 2 days ago 
5.83MB
dotbalo/canary <none> 00f40cc9b7f6 2 days ago 
5.83MB
dotbalo/canary <none> 9b0f2f308931 2 days ago 
5.83MB
<none><none> c3d2357e9cbd 2 days ago 
4.41MB
dotbalo/nginx <none> 97c97cee03f9 3 days ago 
109MB
# docker rmi 7ad745acca31 00f40cc9b7f6 9b0f2f308931 c3d2357e9cbd 
97c97cee03f9
Deleted: 
sha256:7ad745acca31e3f753a3d50e45b7868e9a1aa177369757a9724bccf0654abcb2
Deleted: 
sha256:0546dcf8a97e167875d6563ef7f02ddd8ad3fc0d5f5c064b41e1ce67369b7e06
Untagged: 
dotbalo/canary@sha256:cdd99e578cb2cb8e84eaf2e077c2195a40948c9621d32004a9b5f4
e82a408f4d
...
Deleted: 
sha256:697f26740b36e9a5aee72a4ca01cc6f644b59092d49ae043de9857e09ca9637e

区分镜像的版本可以使用 tag 命令给镜像打标签:

# docker images | grep nginx | tail -1
nginx 1.7.9 84581e99d807 3 years ago 
91.7MB
#不加 URL 为默认镜像仓库
# docker tag nginx dotbalo/nginx:v1
#加 URL 指定为其他镜像仓库
# docker tag nginx harbor.xxx.net/stage/nginx:v1

构建镜像

使用 docker build 通过 Dockerfile 制作镜像。注意最后的一个点( . ),表示使用当前目录

进行构建镜像:

# docker build -t image_name:image_tag .

查看容器运行信息

# docker inspect 1de2ef08945f | grep Port
 "PortBindings": {
 "HostPort": "13306"
 "PublishAllPorts": false,
 "ExposedPorts": {
 "Ports": {
 "HostPort": "13306"

查看镜像构建信息

[root@k8s-master02 ~]# docker history 0e55626662ef
IMAGE CREATED CREATED BY SIZE 
COMMENT
...
<missing> 21 months ago /bin/sh -c #(nop) CMD ["mysqld"] 
0B 
<missing> 21 months ago /bin/sh -c #(nop) EXPOSE 3306/tcp 33060/tcp 
0B
...

清理不用的镜像

docker image prune -a

三、Dockerfile 的编写

Dockerfile 的常用命令如下:

  • FROM:继承基础镜像
  • MAINTAINER:镜像制作作者的信息,已弃用,使用LABEL替代
  • LABEL:k=v形式,将一些元数据添加至镜像
  • RUN:用来执行shell命令
  • EXPOSE:暴露端口号
  • CMD:启动容器默认执行的命令,会被覆盖
  • ENTRYPOINT:启动容器真正执行的命令,不会被覆盖
  • ENV:配置环境变量
  • ADD:复制文件到容器,一般拷贝文件,压缩包自动解压
  • COPY:复制文件到容器,一般拷贝目录
  • WORKDIR:设置容器的工作目录
  • USER:容器使用的用户
  • ARG:设置编译镜像时传入的参数

1、创建用户

# cat Dockerfile 
# base image
FROM centos:7
MAINTAINER dot
RUN useradd dot
# 执行构建
# docker build -t centos:user .

2、添加环境变量

# cat Dockerfile 
# base image
FROM centos:7
MAINTAINER dot
RUN useradd dot
RUN mkdir dot
ENV envir=test version=1.0
CMD echo "envir:$envir version:$version"

执行构建并启动测试:

# 执行构建
# docker build -t centos:env-cmd .
# 启动镜像验证 ENV 和 CMD
# docker run centos:env-cmd
envir:test version:1.0

3、ENTRYPOINT

# cat Dockerfile 
# base image
FROM centos:7
MAINTAINER dot
RUN useradd dot
RUN mkdir dot
ENV envir=test version=1.0
#CMD echo "envir:$envir version:$version"
ENTRYPOINT echo "envir:$envir version:$version"

执行构建并测试:

# docker build -t centos:entrypoint .
# docker run --rm centos:entrypoint
envir:test version:1.0

4、CMD ENTRYPOINT 区别

CMD 可以被覆盖:

# docker run --rm centos:env-cmd echo "cover..."
cover...

ENTRYPOINT 指定的不能被直接覆盖:

# docker run --rm centos:entrypoint cannot cover...
envir:test version:1.0

ENTRYPOINT 指定–entrypoint 参数,比如指定 entrypoint 为 ls,后置命令为/tmp,就相当于

ENTRYPOINT 是 ls,CMD 是/tmp

# docker run --rm --entrypoint=ls centos:entrypoint /tmp
anaconda-post.log
yum.log

5、ADD COPY

使用 ADD 添加一个压缩包,使用 WORKDIR 改变工作目录:

# base image
FROM nginx
MAINTAINER dot
ADD ./index.tar.gz /usr/share/nginx/html/
WORKDIR /usr/share/nginx/html

使用 COPY 拷贝指定目录下的所有文件到容器,不包括本级目录。

此时只会拷贝 webroot 下的所有文件,不会将 webroot 文件夹拷贝过去:

# base image
FROM nginx
MAINTAINER dot
ADD ./index.tar.gz /usr/share/nginx/html/
WORKDIR /usr/share/nginx/html
COPY webroot/ .

6、更改启动用户

# base image
FROM centos:7
MAINTAINER dot
ADD ./index.tar.gz /usr/share/nginx/html/
WORKDIR /usr/share/nginx/html
COPY webroot/ .
RUN useradd -m tomcat -u 1001
USER 1001

LABEL 和 MAINTAINER

Dockerfile使用MAINTAINER定义作者信息,但是这个参数将来会被弃用,可以使用LABEL

进行替换:

# base image
FROM centos:7
# MAINTAINER dot # 即将废弃
LABEL maintainer="dot" version="demo"
LABEL multiple="true"

制作镜像并查看镜像信息:

# docker build -t test:label .
# docker inspect test:label | grep Labels -A 10
 "Labels": {
 "maintainer": "dot",
 "multiple": "true",
 "org.label-schema.build-date": "20181006",
 "org.label-schema.license": "GPLv2",
 "org.label-schema.name": "CentOS Base Image",
 "org.label-schema.schema-version": "1.0",
 "org.label-schema.vendor": "CentOS",
 "version": "demo"
 }
 },
...

7、Dockerfile 传参

使用 ARG 和 build-arg 传入动态变量:

# base image
FROM centos:7
# MAINTAINER dot # deprecated
LABEL maintainer="dot" version="demo"
LABEL multiple="true"
ARG USERNAME
ARG DIR="defaultValue"
RUN useradd -m $USERNAME -u 1001 && mkdir $DIR
# docker build --build-arg USERNAME="test_arg" -t test:arg .
# docker run -ti --rm test:arg bash
[root@fe7a40927736 /]# ls
bin dev home lib64 media opt root selinux sys usr
defaultValue etc lib lost+found mnt proc sbin srv tmp var
[root@fe7a40927736 /]# tail -1 /etc/passwd
test_arg:x:1001:1001::/home/test_arg:/bin/bash

四、镜像大小优化

基础镜像体积:

# docker images | grep user
centos user 9457226f9505 7 minutes ago 
194MB

那这 194MB 是怎么来的呢?首先看一下创建用户的 Dockerfile:

# cat Dockerfile 
# base image
FROM centos:7
MAINTAINER dot
RUN useradd dot

再来看一下执行 docker build 生成镜像时控制台的日志:

# docker build --no-cache -t centos:user .
Sending build context to Docker daemon 2.048kB
Step 1/3 : FROM centos:7
---> d0957ffdf8a2
Step 2/3 : MAINTAINER dot
---> Running in ad0f527d2872
Removing intermediate container ad0f527d2872
---> 422cd518454d
Step 3/3 : RUN useradd dot
---> Running in a50a324f8776
Removing intermediate container a50a324f8776
---> 949582cb3192
Successfully built 949582cb3192
Successfully tagged centos:user

可以使用 docker history 看一下每个层的大小:

# docker history 949582cb3192
IMAGE CREATED CREATED BY 
SIZE 
949582cb3192 About an hour ago /bin/sh -c useradd dot 
150kB
422cd518454d About an hour ago /bin/sh -c #(nop) MAINTAINER dot 
0B 
d0957ffdf8a2 17 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 
0B 
<missing> 17 months ago /bin/sh -c #(nop) LABEL org.labelschema.sc... 0B 
<missing> 17 months ago /bin/sh -c #(nop) ADD 
file:0065316a41144e95b... 194MB
<missing> 22 months ago /bin/sh -c #(nop) MAINTAINER 
https://github... 0B

1、使用 Alpine 作为基础镜像

将之前创建用户的 Dockerfile 改为 Alpine 镜像

# cat Dockerfile 
# base image
# FROM centos:7
FROM alpine:3.12
MAINTAINER dot
RUN adduser -D dot

Alpine 镜像创建用户的命令为 adduser,-D 表示不设置密码

执行构建并查看镜像大小:

# docker build -t alpine:user .
...
Successfully built 262f8225d7ec
...
# docker images | grep 262f8225d7ec
alpine user 262f8225d7ec 4 minutes ago 
5.57MB

2、多阶段构建

创建 Go 语言 Hello World 程序:

# cat hw.go 
package main
import "fmt"
func main() {
 fmt.Println("Hello World!")
}

单阶段构建:

# build step
FROM golang:1.14.4-alpine
WORKDIR /opt
COPY hw.go /opt
RUN go build /opt/hw.go 
CMD "./hw"

执行构建并运行测试:

# docker build -t hw:one .
Successfully built e036098fbb2e
Successfully tagged hw:one
# docker run --rm hw:one
Hello World!

查看此时由一个阶段构建的镜像大小:

# docker images | grep e036098fbb2e
hw one e036098fbb2e 5 minutes ago 
372MB

可以看到此时镜像大小为 372MB,但是上述的代码我们只需要构建步骤产生的二进制文件

hw 即可,这个文件大小可以进入到容器内部看一下:

# docker run --rm hw:one du -sh ./hw
2.0M ./hw

多阶段 Dockerfile 构建:

# cat Dockerfile 
# 构建过程
FROM golang:1.14.4-alpine as builder
WORKDIR /opt
COPY hw.go /opt
RUN go build /opt/hw.go 

# 生成应用镜像过程
FROM alpine:3.12
COPY --from=builder /opt/hw .
CMD [ "./hw" ]

再次构建后查看此时的镜像大小和运行镜像的效果:

# docker build -t hw:multi .
# docker images |grep multi
hw multi a3bba8204f75 6 minutes ago 2.07MB 
# docker run --rm hw:multi
Hello World!

五、Docker 容器退出码

查看:

$ docker ps --filter "status=exited"
$ docker inspect <container-id> --format='{{.State.ExitCode}}'

1、常见退出码

Exit Code 0

  • 退出代码0表示特定容器没有附加前台进程。
  • 该退出代码是所有其他后续退出代码的例外。
  • 这不一定意味着发生了不好的事情。如果开发人员想要在容器完成其工作后自动停止其容器,则使用此退出代码。

Exit Code 1

  • 程序错误,或者 Dockerfile 中引用不存在的文件,如 entrypoint 中引用了错误的包
  • 程序错误可以很简单,例如 “除以0”,也可以很复杂,比如空引用或者其他程序 crash

Exit Code 137

  • 表明容器收到了 SIGKILL 信号,进程被杀掉,对应 kill -9
  • 引发 SIGKILL 的是 Docker Kill。这可以由用户或由 Docker 守护程序来发起,手动执行:docker kill
  • 137 比较常见,如果 pod 中的 limit 资源设置较小,会运行内存不足导致 OOMKilled,此时 state 中的 “OOMKilled” 值为 true,你可以在系统的 dmesg 中看到 oom 日志

Exit Code 139

  • 表明容器收到了 SIGSEGV 信号,无效的内存引用,对应 kill -11
  • 一般是代码有问题,或者 docker 的基础镜像有问题

Exit Code 143

  • 表明容器收到了 SIGTERM 信号,终端关闭,对应 kill -15
  • 一般对应 docker stop 命令
  • 有时 docker stop 也会导致 Exit Code 137。发生在与代码无法处理 SIGTERM 的情况下,docker 进程等待十秒钟然后发出 SIGKILL 强制退出。

不常用的一些 Exit Code

  • Exit Code 126: 权限问题或命令不可执行
  • Exit Code 127: Shell 脚本中可能出现错字且字符无法识别的情况
  • Exit Code 1 或 255:因为很多程序员写异常退出时习惯用 exit(1) 或 exit(-1),-1 会根据转换规则转成 255。这个一般是自定义 code,要看具体逻辑。

退出状态码的区间

  • 必须在 0-255 之间,0 表示正常退出
  • 外界将程序中断退出,状态码在 129-255
  • 程序自身异常退出,状态码一般在 1-128
  • 假如写代码指定的退出状态码时不在 0-255 之间,例如: exit(-1),这时会自动做一个转换,最终呈现的状态码还是会在 0-255 之间。我们把状态码记为 code,当指定的退出时状态码为负数,那么转换公式如下:256 – (|code| % 256)

六、Docker容器的状态

docker下查看所有容器状态:

docker ps -a

在这里插入图片描述

返回的内容中,有一个字段是STATUS。

STATUS: 容器状态,有7种:

created(已创建)
restarting(重启中)
running(运行中)
removing(迁移中)
paused(暂停)
exited(停止)
dead(死亡)

这些状态中,最重要和常见的是除了restarting(重启中)和removing(迁移中)之外的五个状态,下面基本上网络上大部分的容器生命周期图都只包含五个状态:created(已创建),running(运行中),paused(暂停),exited(停止),dead(死亡)。

七、容器的生命周期

可以谷歌 container lifecycle去看看相关的内容,主要搜图,可以看到有很多图,就像进程的生命周期一样。

主要反映了created(已创建),running(运行中),paused(暂停),exited(停止),dead(死亡)这五个状态的一个变化关系。

下面这个图的started就约等于running。

在这里插入图片描述

下面这个图的stopped就约等于exited

在这里插入图片描述

源自: Docker Container Lifecycle Management: Create, Run, Pause, Stop And Delete

在这里插入图片描述

源自:docker基本命令

在这里插入图片描述

源自:docker命令图谱

在这里插入图片描述

源自:Docker系列03—Docker 基础入门

其实上面这个图最初应该是来自:

在这里插入图片描述

源自:Docker Internals-A Deep pe Into Docker For Engineers Interested In The Gritty Details.

参考:

https://www.php.cn/docker/491808.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值