一.基本概念
容器概念:享同一个操作系统的内核,将应用程序与系统其它部分隔离开。
虚拟化:虚拟化使得多个操作系统可同时运行在单个系统上。
docker和openstack的区别:
docker:简单,秒级,和物理系统几乎一致,镜像是MB级别,管理简单,隔离性高,单进程(不建议使用SSH),网络连接比较弱。
openstack:组件多,部署复杂,分钟级,vm会占用一些资源,虚拟机镜像是GB级别,组件相互依赖,管理复杂,彻底隔离,完整的系统管理。
docker应用场景:web自动化打包和发布,自动化测试和持续集成、发布,在服务型环境中部署和调整数据库或其他后台应用。
docker架构:架构十分重要,Docker的大部分操作都围绕着它的三大核心概念——镜像、容器和仓库而展开。
架构:c/s架构
容器3大组件:镜像,容器,仓库;
1.镜像: 2.容器 3.仓库
1.docker优点
1.它是不可变的:操作系统,库版本,配置,文件夹和应用都是一样的。
2.它是轻量级的-容器的内存占用非常小。
3.它很快速-启动一个容器与启动一个单进程一样快。
二.Docker基本命令
1.Docker常用命令整合:
docker images //查询本地仓库镜像 dockers search docker_name(nginx) //网上查询所需要的镜像 docker pull docker_name(nginx) //下载镜像到本地仓库 docker push docker_name(nginx) //上传镜像到其他仓库 docker save docker.io/busybox:latext -o busybox.tar //备份镜像(导出镜像) docker load -i busybox.tar //导入镜像 docker history docker.io/nginx:insest //查看镜像制作历史 docker inspect docker.io/nginx:insest //查看镜像底层信息 docker rmi //删除本地镜像 docker tag (image ID或者名称+标签) //新名称+标签,修改镜像名称和标签 docker run -it docker.io/centos:latest /bin/bsh //前台运行容器(关闭会清除数据) docker run -itd docker.io/centos:latest /bin/bsh //后台运行容器 docker ps -a //查看容器列表 -a(显示关闭的列表) docker stop //关闭容器(+id) docker start //启动容器(+id) docker restart //重启容器(+id) docker attach / (exec -it) +id /bin/bash //进入容器(前:退出关闭,后:退出不关闭) docker inspect docker.io/centos //查看容器底层信息 docker top //查看容器进程列表(+id) docker rm //删除容器(+id) docker commit 旧ID容器 新容器名 //使用启动容器,在该容器基础上修改,另存为一个新镜像。 docker cp /etc/yum.repos.d/*.repo 容器ID:/root/ //复制主机yum文件到容器/root目录下 。
2.查看Docker版本
查看 Docker 版本包括 Docker 版本号、API版本号、对应的 Git Commit、Containerd 和 runC的版本信息等。
[root@k8s-master01 ~]# docker version Client: Docker Engine - Community Version: 20.10.12 API version: 1.40 Go version: go1.16.12 Git commit: e91ed57 Built: Mon Dec 13 11:45:41 2021 OS/Arch: linux/amd64 Context: default Experimental: true Server: Docker Engine - Community Engine: Version: 19.03.15 API version: 1.40 (minimum version 1.12) Go version: go1.13.15 Git commit: 99e3ed8919 Built: Sat Jan 30 03:16:33 2021 OS/Arch: linux/amd64 Experimental: false containerd: Version: 1.4.12 GitCommit: 7b11cfaabd73bb80907dd23182b9347b4245eb5d runc: Version: 1.0.2 GitCommit: v1.0.2-0-g52b36a2 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引擎即可实现容器的启动、停止和资源隔离等功能。
3.查看 Docker 详细信息
[root@k8s-master01 ~]# docker info Client: Context: default Debug Mode: false Plugins: app: Docker App (Docker Inc., v0.9.1-beta3) buildx: Docker Buildx (Docker Inc., v0.7.1-docker) scan: Docker Scan (Docker Inc., v0.12.0) Server: Containers: 14 # 容器个数 Running: 12 # 正在运行的容器个数 Paused: 0 # 暂停的容器个数 Stopped: 2 # 停止的容器个数 Images: 16 # 镜像个数 Server Version: 19.03.15 # 当前服务器 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: systemd # 限制和隔离的驱动,生产环境建议使用 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 开启 Runtimes: runc Default Runtime: runc ... ... 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 Registry Mirrors: https://registry.docker-cn.com/ http://hub-mirror.c.163.com/ https://docker.mirrors.ustc.edu.cn/ Live Restore Enabled: true # Docker 热更新,生产环境建议设置为 true
4.搜索镜像
[root@k8s-master01 ~]# docker search nginx NAME DESCRIPTION STARS OFFICIAL AUTOMATED nginx Official build of Nginx. 17696 [OK] linuxserver/nginx An Nginx container, brought to you by LinuxS… 180 bitnami/nginx Bitnami nginx Docker Image 142 [OK] .....
5.拉取/下载镜像
拉取公网上的 Nginx 镜像:
[root@k8s-master01 ~]# docker pull nginx Using default tag: latest latest: Pulling from library/nginx a603fa5e3b41: Pull complete .... 9802a2cfdb8d: Pull complete Digest: sha256:e209ac2f37c70c1e0e9873a5f7231e91dcd83fdf1178d8ed36c2ec09974210ba Status: Downloaded newer image for nginx:latest docker.io/library/nginx:latest 拉去指定版本: [root@k8s-master01 ~]# docker pull nginx:1.15 1.15: Pulling from library/nginx Digest: sha256:23b4dcdf0d34d4a129755fc6f52e1c6e23bb34ea011b315d87e193033bcd1b68 Status: Downloaded newer image for nginx:1.15 docker.io/library/nginx:1.15
6.查看本地镜像
[root@k8s-master01 ~]# docker images | grep nginx nginx latest 88736fe82739 3 days ago 142MB nginx 12766a6745ee 7 months ago 142MB registry.cn-beijing.aliyuncs.com/dotbalo/nginx phone af38d1dd89b1 15 months ago 109MB registry.cn-beijing.aliyuncs.com/dotbalo/nginx backend-api a45bff32dbc4 15 months ago 109MB k8s.gcr.io/ingress-nginx/kube-webhook-certgen 17e55ec30f20 15 months ago 46.7MB nginx 1.20.0 7ab27dbbfbdf 18 months ago 133MB nginx 1.15 53f3fd8007f7 3 years ago 109MB
7.更改镜像tag
[root@k8s-master01 ~]# docker tag nginx:1.15 nginx:1.15test [root@k8s-master01 ~]# docker images | grep 1.15 nginx 1.15 53f3fd8007f7 3 years ago 109MB nginx 1.15test 53f3fd8007f7 3 years ago 109MB
8.镜像仓库登录
默认是https://hub.docker.com的远程仓库
[root@k8s-master01 ~]# 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: Password: 输入仓库密码 Login Succeeded
9.推送本地镜像到远程仓库
# 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: 136
10.启动容器
使用 run -ti 前台启动一个容器: # docker run -ti nginx bash root@23bc7ccabb09:/# # 也可以使用-ti --rm 参数,表示前台启动的容器退出后即删除 如果一个镜像需要一直运行,可以使用-d 进行后台启动: # docker run -tid nginx bash 1bcf5154d5c3a57d92a6796f526eac2cefd962aaca9cf4098689bfe830bb9e5e # 也可以使用--restart=always,如果容器异常自动重启
11.端口映射
# docker run -ti -p 1111:80 nginx bash root@cd676d572188:/#
12.查看日志
# 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)
13.数据持久化
# docker run -ti -p 1111:80 -v /etc/hosts:/etc/hosts nginx bash root@cd676d572188:/#
14.查看当前正在运行的容器
# docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 862e82066496 94ec7e53edfc "nginx -g 'daemon ..." 21 hours ago Up 21 hours k8s_nginx_nginx-deployment-57895845b8-vb7bs_default_d0d254f8-1fb3-11e9-a9f2- 000c293ad492_1 10bf838e18d0 registry.cnhangzhou.aliyuncs.com/google_containers/pause-amd64:3.1 "/pause" 21 hours ago Up 21 hours k8s_POD_nginx-deployment-57895845b8-vb7bs_default_d0d254f8-1fb3-11e9-a9f2- 000c293ad492_1
查看所有容器,包括已经退出的:
# docker ps -a
查看正在运行的容器(即显示出容器的 ID):
# docker ps -q ... 0d1a98b3c402 c1fd8ff1f7f2 86b1c069024b ...
15.进入容器
进入到一个后台运行的容器(即之前用-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:/#
16.文件拷贝
将本机的文件拷贝到容器,拷贝支持双向拷贝,也支持将容器的内部文件拷贝到宿主机:
# docker cp README.md 92aceec0dcdd327a709bf0ec83:/tmp #exec 也可直接执行容器命令 # docker exec 92aceec0dcdd327a709bf0ec83 ls /tmp/ README.md
17.删除容器和镜像
删除已经退出的容器:
# 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 7ad745acca31 2 days ago 5.83MB dotbalo/canary 00f40cc9b7f6 2 days ago 5.83MB dotbalo/canary 9b0f2f308931 2 days ago 5.83MB c3d2357e9cbd 2 days ago 4.41MB dotbalo/nginx 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
18.构建镜像
使用 docker build 通过 Dockerfile 制作镜像。注意最后的一个点( . ),表示使用当前目录进行构建镜像: # docker build -t image_name:image_tag .
19.查看容器运行信息
[root@k8s-master01 ~]# docker inspect e1a61
20.查看镜像构建信息
[root@k8s-master01 ~]# docker history 88736fe82739 IMAGE CREATED CREATED BY SIZE COMMENT 88736fe82739 3 days ago /bin/sh -c #(nop) CMD ["nginx" "-g" "daemon… 0B 3 days ago /bin/sh -c #(nop) STOPSIGNAL SIGQUIT 0B 3 days ago /bin/sh -c #(nop) EXPOSE 80 0B 3 days ago /bin/sh -c #(nop) ENTRYPOINT ["/docker-entr… 0B 3 days ago /bin/sh -c #(nop) COPY file:e57eef017a414ca7… 4.62kB 3 days ago /bin/sh -c #(nop) COPY file:abbcbf84dc17ee44… 1.27kB 3 days ago /bin/sh -c #(nop) COPY file:5c18272734349488… 2.12kB 3 days ago /bin/sh -c #(nop) COPY file:7b307b62e82255f0… 1.62kB 3 days ago /bin/sh -c set -x && addgroup --system -… 61.2MB 3 days ago /bin/sh -c #(nop) ENV PKG_RELEASE=1~bullseye 0B 3 days ago /bin/sh -c #(nop) ENV NJS_VERSION=0.7.7 0B 3 days ago /bin/sh -c #(nop) ENV NGINX_VERSION=1.23.2 0B 3 days ago /bin/sh -c #(nop) LABEL maintainer=NGINX Do… 0B 4 days ago /bin/sh -c #(nop) CMD ["bash"] 0B 4 days ago /bin/sh -c #(nop) ADD file:d08e242792caa7f84… 80.5MB
三.Dockerfile的编写
Dockerfile 的常用命令如下:
⚫ FROM:继承基础镜像
⚫ MAINTAINER:镜像制作作者的信息,已弃用,使用LABEL替代
⚫ LABEL:k=v形式,将一些元数据添加至镜像
⚫ RUN:用来执行shell命令
⚫ EXPOSE:暴露端口号
⚫ CMD:启动容器默认执行的命令,会被覆盖
⚫ ENTRYPOINT:启动容器真正执行的命令,不会被覆盖
⚫ ENV:配置环境变量
⚫ ADD:复制文件到容器,一般拷贝文件,压缩包自动解压
⚫ COPY:复制文件到容器,一般拷贝目录
⚫ WORKDIR:设置容器的工作目录
⚫ USER:容器使用的用户
⚫ ARG:设置编译镜像时传入的参数
1.创建用户
FROM centos:7 MAINTAINER dot RUN useradd dot #执行构建 [root@k8s-master01 image] 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
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.CMD 和 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" ] # docker build -t centos:entrypoint1 . CMD 可以被覆盖: # docker run --rm centos:env 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:entrypoint1 /tmp anaconda-post.log yum.log
6.ADD 和 COPY
使用 ADD 添加一个压缩包,使用 WORKDIR 改变工作目录:
使用 COPY 拷贝指定目录下的所有文件到容器,不包括本级目录。
此时只会拷贝 webroot 下的所有文件,不会将 webroot 文件夹拷贝过去:
FROM nginx ADD ./text.tar.gz /usr/share/nginx/html WORKDIR /usr/share/nginx/html COPY webroot/ . #只会拷贝 webroot 下的所有文件 # docker build -t centos:add_copy . # docker run -it --rm centos:add_copy bash root@7d9c9dd1b3f3:/usr/share/nginx/html# ls 50x.html index.html text.txt text1.txt text2.txt text3.txt text5.txt text6.txt text7.txt root@7d9c9dd1b3f3:/usr/share/nginx/html# pwd /usr/share/nginx/html
7.Dockerfile传参
使用 ARG 和 build-arg 传入动态变量:
# cat Dockerfile # base image FROM centos:7 ARG USERNAME ARG DIR="defaultValue" RUN useradd -m $USERNAME -u 1001 && mkdir $DIR # docker build -t centos:ARG --build-arg USERNAME="test_arg" . #传入动态变量USERNAME # docker run -ti --rm centos:ARG bash [root@b488f1b4ea54 /]# ls anaconda-post.log bin defaultValue dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var [root@b488f1b4ea54 /]# tail -1 /etc/passwd test_arg:x:1001:1001::/home/test_arg:/bin/bash
四.镜像大小优化
docker history 看一下每个层的大小:
# docker history centos:7 IMAGE CREATED CREATED BY SIZE COMMENT eeb6ee3f44bd 14 months ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B 14 months ago /bin/sh -c #(nop) LABEL org.label-schema.sc… 0B 14 months ago /bin/sh -c #(nop) ADD file:b3ebbe8bd304723d4… 204MB
1.使用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.多阶段构建
单阶段构建:把编译和运行等操作全在一个阶段构建,构建镜像会很大:可以看到以下构建的镜像为:372MB
例如:
cat Dockerfile_dan FROM golang:1.14.4-alpine WORKDIR /opt COPY hw.go /opt RUN go build /opt/hw.go CMD "./hw" # docker build -t hw:dan . -f Dockerfile_dan # # docker run --rm hw:dan Hello World! # docker images | grep hw hw dan 5dbd198045bd 47 seconds ago 372MB
多阶段构建:把编译镜像和运行的镜像分开:
编译的镜像只需要构建步骤产生的二进制文件hw复制到运行的镜像中即可,以下可见构建的镜像大小为:7.66MB
例如:
cat Dockerfile_duo 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 #把编译容器产生的可执行文件/opt/hw复制到运行到alpine的默认目录 COPY --from=builder /opt/hw . CMD [ "./hw" ] # docker build -t sw:duo . -f Dockerfile_duo # docker run --rm sw:duo Hello World! [root@k8s-master01 go]# docker images | grep sw sw duo acf93c900ed8 About a minute ago 7.66MB