docker基础用法
1. docker基本命令
1.1 查看docker版本
查看docker版本号,包括docker版本号,API版本号,对应的git commit,tontainerd和runC的版本信息等
[root@k8s-node02 ~]# docker version
Client: Docker Engine - Community
Version: 20.10.24
API version: 1.41
Go version: go1.19.7
Git commit: 297e128
Built: Tue Apr 4 18:22:57 2023
OS/Arch: linux/amd64
Context: default
Experimental: true
Server: Docker Engine - Community
Engine:
Version: 20.10.24
API version: 1.41 (minimum version 1.12)
Go version: go1.19.7
Git commit: 5d6db84
Built: Tue Apr 4 18:21:02 2023
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: 1.6.31
GitCommit: e377cd56a71523140ca6ae87e30244719194a521
runc:
Version: 1.1.12
GitCommit: v1.1.12-0-g51d5e94
docker-init:
Version: 0.19.0
GitCommit: de40ad0
- OCI: Open Container Initiative的简称,有linux基金会主导开发OCI规范和标准,目的是围绕容器格式和Runtime(运行时)指定的一个开放的工业化标准
- Containerd:Docker为了兼容OCI标准,将容器Runtime 及其管理功能从docker守护进程中剥离出来,用于不启动docker也能直接通过containerd来管理容器。
- RunC:docker按照OCF(Open Container Format)开放容器格式标准制定的一个轻量级工具,可以使用RunC不通过Docker引擎即可实现容器的启动,停止和资源隔离等功能。
1.2查看docker详细信息
[root@k8s-node02 ~]# docker info
Client: # Client端
Context: default
Debug Mode: false #是否开启debug模式
Plugins:
app: Docker App (Docker Inc., v0.9.1-beta3)
buildx: Docker Buildx (Docker Inc., v0.10.4-docker)
Server: #Server端
Containers: 0 #容器个数
Running: 0 #正在运行的容器个数
Paused: 0 # 暂停的容器个数
Stopped: 0# 停止的容器个数
Images: 0 #镜像个数
Server Version: 20.10.24 #当前服务器 docker server 的版本
Storage Driver: overlay2 #存储驱动,一般为overlay2性能好速度快
#其他驱动 aufs,overlay,brtfs
Backing Filesystem: xfs #服务器文件系统
Supports d_type: true #目录条目类型,用来表示一个文件是文件,管道,还是套接字。
#在格式化xfs文件系统时,必须制定fytpe=1
Native Overlay Diff: true
userxattr: false
Logging Driver: json-file #日志驱动,json-file 表示存在本地
Cgroup Driver: cgroupfs #限制和隔离的驱动,生产环境兼用使用systemd
Cgroup Version: 1
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官方的容器编排工具,incative不开启,active开启
Runtimes: io.containerd.runc.v2 io.containerd.runtime.v1.linux runc
Default Runtime: runc
Init Binary: docker-init
containerd version: e377cd56a71523140ca6ae87e30244719194a521
runc version: v1.1.12-0-g51d5e94
init version: de40ad0
Security Options:
seccomp
Profile: default
Kernel Version: 4.19.12-1.el7.elrepo.x86_64
Operating System: CentOS Linux 7 (Core)
OSType: linux
Architecture: x86_64
CPUs: 4
Total Memory: 7.79GiB
Name: k8s-node02
ID: E4HI:BOOU:6L34:4VLQ:RWTT:3SXU:JAGT:OTM6:M5SZ:LMJI:BQND:CQPS
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
1.3 搜索镜像
[root@k8s-node02 ~]# docker search nginx
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
nginx Official build of Nginx. 19768 [OK]
1.4 拉取/下载镜像
docker pull harbor.xxx.net/frontend:v1
拉取公网上的nginx镜像:
#把公网上的镜像拉取到本地服务器,不指定版本号为latest
[root@k8s-master1 ~]# docker pull nginx
Using default tag: latest
latest: Pulling from library/nginx
22d97f6a5d13: Pull complete
21f638c63a61: Pull complete
986afc5da157: Pull complete
6a5cdb238fe4: Pull complete
b3678f371bdd: Pull complete
b4b06232e7eb: Pull complete
68b681650ba3: Pull complete
Digest: sha256:ed6d2c43c8fbcd3eaa44c9dab6d94cb346234476230dc1681227aa72d07181ee
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
#拉取指定版本
[root@k8s-master1 ~]# docker pull nginx:1.15
1.15: Pulling from library/nginx
29b80961214d: Pull complete
07b8ab2ff324: Pull complete
ba4f63a9ae5b: Pull complete
Digest: sha256:23b4dcdf0d34d4a129755fc6f52e1c6e23bb34ea011b315d87e193033bcd1b68
Status: Downloaded newer image for nginx:1.15
docker.io/library/nginx:1.15
1.5 查看本地镜像
[root@k8s-master1 ~]# docker images | grep nginx
nginx latest 786a14303c96 9 days ago 193MB
nginx 1.15 f6d22dec9931 4 years ago 103MB
1.6 更改镜像tag
# docker tag nginx-v2 dotbalo/nginx-v2:test
# 如果是推送到自己公司内部的镜像仓库,可以使用如下命令 docker tag nginx-v2 你公司的
镜像仓库地址/nginx-v2:test
# docker images | grep nginx-v2
dotbalo/nginx-v2 test 3d9c6e44d3db 3 hours ago
109MB
nginx-v2 latest 3d9c6e44d3db 3 hours ago
109MB
1.7 镜像仓库登录
# 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): dotbalo
Password: 输入仓库密码
Login Succeeded
1.8 推送本地镜像到远程仓库
# docker push dotbalo/nginx-v2:test
The push refers to a repository [docker.io/dotbalo/nginx-v2]
2eaa7b5717a2: Mounted from dotbalo/nginx
a674e06ede38: Mounted from dotbalo/nginx
b7efe781401d: Mounted from dotbalo/nginx
c9c2a3696080: Mounted from dotbalo/nginx
7b4e562e58dc: Mounted from dotbalo/nginx
test: digest: sha256:
5d749d2b10150426b510d2c3a05a99cf547c2ca1be382e1dbb2f90b68b6bea96 size: 1362
1.9 启动容器
使用 run -ti 前台启动一个容器:
[root@k8s-master1 ~]# docker run -ti nginx bash
root@a95935c4e80b:/#
# 也可以使用-ti --rm 参数,表示前台启动的容器退出后即删除
如果一个镜像需要一直运行,可以使用-d进行后台启动
[root@k8s-master1 ~]# docker run -tid nginx bash
84f5ae0378373031de29f8488fb8e2df1fdefe90d84b5cc4c1666f7c627cc874
# 也可以使用--restart=always,如果容器异常自动重启
1.10 端口映射
[root@k8s-master1 ~]# docker run -ti -p 1111:80 nginx bash
root@406725f8762f:/#
1.11查看日志
# docker logs -f 容器ID/容器名称 --tail 1
[root@k8s-master1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
84f5ae037837 nginx "/docker-entrypoint.…" About a minute ago Up About a minute 80/tcp clever_kepler
[root@k8s-master1 ~]# docker logs -f 84f5ae037837 --tail 1
1.12 数据持久化
[root@k8s-master1 ~]# docker run -ti -p 1111:80 -v /etc/hosts:/etc/hosts nginx bash
root@26af380a01b1:/#
1.13 查看当前正在运行的容器
[root@k8s-master1 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
84f5ae037837 nginx "/docker-entrypoint.…" 6 minutes ago Up 6 minutes 80/tcp clever_kepler
查看所有容器,包括已经退出的
docker ps -a
查看正在运行的容器,(即显示出容器的id)
[root@k8s-master1 ~]# docker ps -q
84f5ae037837
查看所有容器的ID,包括已经退出的
[root@k8s-master1 ~]# docker ps -qa
ca1409545073
1c7f5eaa3431
d2443de8d2f4
26af380a01b1
406725f8762f
84f5ae037837
a95935c4e80b
1.14 进入容器
进入到一个后台运行的容器(即之前用-d命令参数来指定后台运行方式的容器)
[root@k8s-master1 ~]# docker exec -ti 84f5ae037837 bash
root@84f5ae037837:/#
1.15 文件拷贝
将本机的文件拷贝到容器,拷贝支持双向拷贝,也支持将容器内部文件拷贝到宿主机
[root@k8s-master1 ~]# docker cp initial-setup-ks.cfg 84f5ae037837:/tmp
Successfully copied 3.58kB to 84f5ae037837:/tmp
#exec 也可以直接执行容器命令
[root@k8s-master1 ~]# docker exec 84f5ae037837 ls /tmp
initial-setup-ks.cfg
1.16 删除容器和镜像
[root@k8s-master1 ~]# docker rm 3ff1f4aec37a 1f30f4d5d403 26af380a01b1
#容器id
删除本机镜像,比如删除 REPOSITORY 或 TAG 为 none 的镜像:
# docker images | grep none
<none><none> 7ad745acca31 2 days ago
5.83MB
# docker rmi 7ad745acca31
区分镜像的版本可以使用 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
1.17 构建镜像
使用 docker build 通过 Dockerfile 制作镜像。注意最后的一个点( . ),表示使用当前目录
进行构建镜像:
# docker build -t image_name:image_tag .
1.18 查看容器运行信息
[root@k8s-master1 ~]# docker inspect 84f5ae037837 |grep Port
"PortBindings": {},
"PublishAllPorts": false,
"ExposedPorts": {
"Ports": {
1.19 查看镜像构建信息
[root@k8s-master1 ~]# docker history 786a14303c96
IMAGE CREATED CREATED BY SIZE COMMENT
786a14303c96 9 days ago CMD ["nginx" "-g" "daemon off;"] 0B buildkit.dockerfile.v0
<missing> 9 days ago STOPSIGNAL SIGQUIT 0B buildkit.dockerfile.v0
<missing> 9 days ago EXPOSE map[80/tcp:{}] 0B buildkit.dockerfile.v
2. Dockerfile 的编写
Dockerfile 的常用命令如下:
- FROM:集成基础镜像
- MAINTAINER:镜像制作坐车的信息,已启用,使用LABEL替代
- LABEL:k=v形式,将一些元数据添加至镜像
- RUN:用来执行shell命令
- EXPOSE:暴漏端口号
- CMD启动容器默认执行的命令,会被覆盖
- ENTRYPOINT:启动容器真正的执行命令,不会被覆盖
- ENV:配置环境变量
- ADD:复制文件到容器,一般拷贝文件,压缩包自动解压
- COPY:复制 文件到容器,一般拷贝目录
- WORKDIR:设置容器的工作目录
- USER:容器使用的用户
- ARG:设置编译镜像时传入的参数
2.1 创建用户
[root@k8s-master1 dockerfile]# cat dockerfilee
# base image
FROM centos:7
MAINTAINER dot
RUN useradd dot
# 执行构建
[root@k8s-master1 dockerfile]# docker build -t centos:user .
2.2 添加环境变量
[root@k8s-master1 dockerfile]# 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"
#执行构建
[root@k8s-master1 dockerfile]# docker build -t centos:env-cmd .
#启动镜像验证ENV和CMD
[root@k8s-master1 dockerfile]# docker run centos:env-cmd
envir:test version:1.0
2.3 ENTRYPOINT
[root@k8s-master1 dockerfile]# 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
2.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
2.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/ .
2.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
LAABEL和MAINTAINER
Docker使用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"
}
},
...
2.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
3,镜像大小优化
基础镜像体积:
# 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
3.1 使用AIpine作为基础镜像
将之前创建用户的 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
3.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
# CMD "./hw"
# 生成应用镜像过程
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!