Docker的基础命令及镜像制作

Docker版本选择:

Docker之前没有区分版本,但是2017年推出(将docker更名为)新的项目Moby,github地址:https://github.com/moby/moby,Moby项目属于Docker项目的全新上游,Docker将是一个隶属于的Moby的子产品,而且之后的版本之后开始区分为CE版本(社区版本)和EE(企业收费版),CE社区版本和EE企业版本都是每个季度发布一个新版本,但是EE版本提供后期安全维护1年,而CE版本是4个月。

下载rpm包安装:

官方rpm包下载地址: https://download.docker.com/linux/centos/7/x86_64/stable/Packages/
阿里镜像下载地址:
https://mirrors.aliyun.com/docker-ce/linux/centos/7/x86_64/stable/Packages/

通过修改yum源安装

[root@docker-server1 ~]# wget -O /etc/yum.repos.d/docker-ce.repo https://mirrors.tuna.tsinghua.edu.cn/docker-ce/linux/centos/docker-ce.repo

[root@docker-server1 ~]# yum repolist

[root@docker-server1 ~]# yum install -y docker-ce

# 启动并验证docker服务:
[root@docker-server1 ~]# systemctl  start  docker
[root@docker-server1 ~]# systemctl  enable docker
# docker 版本
[root@localhost ~]# docker version
# docker 信息
[root@localhost ~]# docker info
#更改源地址

https://mirrors.tuna.tsinghua.edu.cn/docker-ce/

docker程序环境:

docker环境配置文件:
/etc/sysconfig/docker-network
/etc/sysconfig/docker-storage
/etc/sysconfig/docker
Unit File:
/usr/lib/systemd/system/docker.service
Docker Registry配置文件:
/etc/containers/registries.conf

docker-ce:
配置文件:/etc/docker/daemon.json

docker 镜像加速配置

获取加速地址:

浏览器打开 https://cr.console.aliyun.com/#/accelerator,注册或登录阿里云账号,点击左侧的镜像加速器,将会得到一个专属的加速地址,而且下面有使用配置说明:

image.png
?```
 中国科技大学
?```
 {
 "registry-mirrors": ["https://registry.docker-cn.com"]
 }
# 生成配置文件
[root@docker-server1 ~]# mkdir -p /etc/docker
[root@docker-server1 ~]# sudo tee /etc/docker/daemon.json <<-'EOF'
> {
>     "registry-mirrors": ["https://registry.docker-cn.com"]
> }
> EOF
# 重启docke服务
[root@docker-server1 ~]# systemctl daemon-reload
[root@docker-server1 ~]# sudo systemctl restart docker

Docker 镜像基础命令

Docker Registry

?启动容器时,docker daemon会试图从本地获取相关的镜像;本地镜像
不存在时,其将从Registry中下载该镜像并保存到本地;
?仓库是一个无状态的、高度可伸缩的服务器端应用程序,它存储并允许你分发Docker映像。

Docker Registry 分类

?Registry用于保存docker镜像,包括镜像的层次结构和元数据
?用户可自建Registry,也可使用官方的Docker Hub
?分类
? Sponsor Registry:第三方的registry,供客户和Docker社区使用
? Mirror Registry:第三方的registry,只让客户使用
?Vendor Registry:由发布Docker镜像的供应商提供的registry
? Private Registry:通过设有防火墙和额外的安全层的私有实体提供的registry

Registry(repository and index)

?Repository
?由某特定的docker镜像的所有迭代版本组成的镜像仓库
?一个 Registry中可以存在多个Repository ? Repository可分为“顶层仓库”和“用户仓库” ? 用户仓库名称格式为“用户名/仓库名” ?每个仓库可以包含多个Tag(标签) ,每个标签对应一个镜像
?Index
?维护用户帐户、镜像的校验以及公共命名空间的信息
?相当于为Registry提供了一个完成用户认证等功能的检索接口

Docker Registry

?Docker Registry中的镜像通常由开发人员制作,而后推送至“公共”或“
私有”Registry上保存,供其他人员使用,例如“部署”到生产环境;

Docker Hub

?Docker Hub是一个基于云的仓库服务,它允许你链接到代码库,构建你的镜像并测试它们,存储手动推送的镜像,以及链接到Docker Cloud,这样你就可以将镜像部署到你的主机上。
?它为整个开发流程中的容器映像发现、分发和更改管理、用户和团队协作以及工作流自动化提供了一个集中的资源。
?Docker Hub提供以下主要功能
?镜像存储库
?从社区和官方仓库中查找和提取镜像,并管理、推送和从您可以访问的私人仓库中提取镜像。
?自动构建
?更改源代码存储库时自动创建新镜像。
?webhooks
?webhooks是自动化构建的一个功能,它允许您在成功推送到存储库后触发操作。
?组织
?创建工作组以管理对镜像存储库的访问。
?GitHub和BitBucket集成
?将仓库和Docker镜像添加到当前工作流中。

# 搜索镜像
[root@docker-server1 ~]# docker search centos:7.2.1511 #带指定版本号
[root@docker-server1 ~]# docker search centos #不带版本号默认latest
# 下载镜像
[root@docker-server1 ~]# docker pull centos:7.2.1511 #带指定版本号
[root@docker-server1 ~]# docker pull centos #不带版本号默认latest

#从远程仓库获取Docker镜像(例如你自己的Docker仓库)并将它们添加到本地系统中,使用docker pull命令:
# docker pull <registry>[:<port>]/[<namespace>/]<name>:<tag>
#<registry>是在TCP<port>上提供Docker分发服务的主机(默认值:5000)
#<namespace>和<name>标识由该注册表中的<namespace>控制的特定镜像
#一些仓库还支持raw<name>;对于这些注册表,<namespace>是可选的
#但是,当包含时,<namespace>提供的额外层次结构有助于区分具有相同<name>的镜像
[root@docker-server1 ~]# docker pull registry.mirror.com:5000/nginx:1.12-alpine

# 查看本地镜像
[root@docker-server1 ~]# docker images
REPOSITORY               TAG                 IMAGE ID            CREATED             SIZE
redis                    latest              63130206b0fa        5 days ago          98.2MB
# REPOSITORY            #镜像所属的仓库名称
# TAG                   #镜像版本号(标识符),默认为latest
# IMAGE ID              #镜像唯一ID标示
# CREATED               #镜像创建时间
# VIRTUAL SIZE          #镜像的大小

Docker容器操作基础命令

命令格式:

  • docker run [选项] [镜像名] [shell命令] [参数]

  • docker run [参数选项] [镜像名称,必须在所有选项的后面] [/bin/echo 'hello wold'] #单次执行,没有自定义容器名称

  • docker run centos /bin/echo 'hello wold' #启动的容器在执行完shel命令就退出了

#容器的状态:
created:
runing:
paused:
stopped:
deleted:
# 从镜像启动一个容器:
# 会直接进入到容器,并随机生成容器ID和名称
[root@docker-server1 ~]# docker run -it docker.io/centos bash
[root@11445b3a84d3 /]#

# 退出容器不注销
ctrl+p+q
# 显示容器 -a:包括显示暂停和关闭的所有容器  -q:只显示容器Id
[root@linux-docker ~]# docker ps -a -q
# 删除运行中的容器:
# 即使容正在运行当中,也会被强制删除掉 rm -f
[root@docker-server1 ~]# docker rm -f 11445b3a84d3
# 随机映射端口:-P
[root@docker-server1 ~]# docker run -P docker.io/nginx  #前台启动并随机映射本地端口到容器的80
# 前台启动的会话窗口无法进行其他操作,除非退出,但是退出后容器也会退出
# 随机端口映射,其实是默认从32768开始


# 指定端口映射:-p
# 方式1:本地端口81映射到容器80端口:
[root@docker-server1 ~]# docker run  -p 81:80 --name nginx-test-port1 nginx
# 方式2:本地IP:本地端口:容器端口
[root@docker-server1 ~]# docker run  -p 192.168.10.205:82:80 --name nginx-test-port2 docker.io/nginx
# 方式3:本地IP:本地随机端口:容器端口
[root@docker-server1 ~]# docker run  -p 192.168.10.205::80 --name nginx-test-port3 docker.io/nginx
# 方式4:本机ip:本地端口:容器端口/协议,默认为tcp协议
[root@docker-server1 ~]# docker run  -p 192.168.10.205:83:80/udp  --name nginx-test-port4 docker.io/nginx
# 方式5:一次性映射多个端口+协议:
[root@docker-server1 ~]# docker run  -p 86:80/tcp  -p 443:443/tcp -p 53:53/udp --name  nginx-test-port5 docker.io/nginx
#查看Nginx 容器访问日志:logs 
[root@docker-server1 ~]# docker logs  nginx-test-port3  #一次查看
[root@docker-server1 ~]# docker logs -f nginx-test-port3  #持续查看
# 查看容器已经映射的端口:port
[root@docker-server1 ~]# docker port nginx-test-port5


# 自定义容器名称:--name
[root@docker-server1 ~]# docker run -it --name nginx-test nginx


# 后台启动容器:-d
[root@docker-server1 ~]# docker run  -d -P  --name nginx-test1   docker.io/nginx

# 创建并进入容器:-it
# -i: 以交互模式运行容器,通常与 -t 同时使用;
# -t: 为容器重新分配一个伪输入终端,通常与 -i 同时使用;
[root@docker-server1 ~]# docker run -t -i  --name test-centos2  docker.io/centos /bin/bash
[root@a8fb69e71c73 /]#  #创建容器后直接进入,执行exit退出后容器关闭
[root@docker-server1 ~]# docker run -d    --name  centos-test1 docker.io/centos

# 单次运行:
# 容器退出后自动删除:--rm
[root@linux-docker opt]# docker run -it --rm --name nginx-delete-test  docker.io/nginx

# 容器的关闭:
[root@docker-server1 ~]# docker stop f821d0cd5a99
[root@docker-server1 ~]# docker kill f821d0cd5a99
# 容器启动和重启
[root@docker-server1 ~]# docker start f821d0cd5a99
[root@docker-server1 ~]# docker restart f821d0cd5a99
# 容器暂停和恢复
[root@docker-server1 ~]# docker pause f821d0cd5a99
[root@docker-server1 ~]# docker unpause f821d0cd5a99
# 过滤器条件显示
#--filter, -f:过滤器条件显示
#name=
#status={stopped|running|paused}
[root@localhost ~]# docker ps -f  name=mynginx -f status=running
#stats:动态方式显示容器的资源占用状态:
[root@docker-server1 ~]# docker stats
#top:查看容器资源情况
[root@docker-server1 ~]# docker top mynginx
# 批量关闭正在运行的容器:
[root@docker-server1 ~]# docker stop  $(docker ps -a -q)  #正常关闭所有运行中的容器
# 批量强制关闭正在运行的容器:
[root@docker-server1 ~]# docker kill  $(docker ps -a -q)  #强制关闭所有运行中的容器
# 批量删除已退出容器:
[root@docker-server1 ~]# docker rm -f  `docker ps -aq -f status=exited`
# 批量删除所有容器:
[root@docker-server1 ~]# docker rm -f  $(docker ps -a -q)
#指定容器DNS:
#Dns服务,默认采用宿主机的dns 地址
#一是将dns地址配置在宿主机
#二是将参数配置在docker 启动脚本里面 –dns=1.1.1.1
[root@docker-server1 ~]# docker run -it --rm --dns 223.6.6.6 centos bash
[root@afeb628bf074 /]# cat /etc/resolv.conf 
nameserver 223.6.6.6

传递运行命令:

容器需要有一个前台运行的进程才能保持容器的运行,通过传递运行参数是一种方式,另外也可以在构建镜像的时候指定容器启动时运行的前台命令。

[root@docker-server1 ~]# docker run  -d   centos   /usr/bin/tail -f '/etc/hosts'
image.png

**使用 ** attach 命令:

  • 使用方式为docker attach 容器名,attach 类似于vnc,操作会在各个容器界面显示,所有使用此方式进入容器的操作都是同步显示的且exit后容器将被关闭,且使用exit退出后容器关闭,不推荐使用。

使用exec命令:

[root@linux-docker opt]# docker exec -it nginx /bin/bash  # 有时最后需要用sh

使用 nsenter 命令:

推荐使用此方式,nsenter命令需要通过PID进入到容器内部,不过可以使用docker inspect获取到容器的PID:

[root@docker-server1 ~]# yum install util-linux #安装nsenter命令
# 查看容器91fc190cb538的ip地址
[root@docker-server1 ~]# docker inspect -f "{{.NetworkSettings.IPAddress}}" 91fc190cb538
172.17.0.2
[root@docker-server1 ~]# docker inspect -f "{{.State.Pid}}" mydocker  #获取到某个docker容器的PID,可以通过PID进入到容器内

[root@docker-server1 ~]#  docker inspect -f "{{.State.Pid}}" centos-test3
5892
[root@docker-server1 ~]#  nsenter -t 5892  -m -u -i -n -p
[root@66f511bb15af /]# ls

# 脚本方式:
# 将nsenter命令写入到脚本进行调用,如下:
[root@docker-server1 ~]# cat docker-in.sh 
#!/bin/bash
docker_in(){
  NAME_ID=$1
  PID=$(docker inspect -f "{{.State.Pid}}" ${NAME_ID})
  nsenter -t ${PID} -m -u -i -n -p
}
docker_in $1
#测试脚本是否可以正常进入到容器且退出后仍然正常运行:
[root@docker-server1 ~]# chmod  a+x docker-in.sh 
[root@docker-server1 ~]# ./docker-in.sh  centos-test3
[root@66f511bb15af /]# pwd
/
[root@66f511bb15af /]# exit
logout
[root@docker-server1 ~]# ./docker-in.sh  centos-test3
[root@66f511bb15af /]# exit
Logout
# 查看容器内部的hosts文件:
[root@docker-server1 ~]# docker run -i -t  --name test-centos3  docker.io/centos /bin/bash
[root@056bb4928b64 /]# cat /etc/hosts    
127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.4  056bb4928b64 #
#容器默认会将实例的ID 添加到自己的hosts文件

Docker 镜像与制作

Docker 镜像有没有内核?
  • 从镜像大小上面来说,一个比较小的镜像只有十几MB,而内核文件需要一百多兆, 因此镜像里面是没有内核的,镜像在被启动为容器后将直接使用宿主机的内核,而镜像本身则只提供相应的rootfs,即系统正常运行所必须的用户空间的文件系统,比如/dev/,/proc,/bin,/etc等目录,所以容器当中基本是没有/boot目录的,而/boot当中保存的就是与内核相关的文件和目录。
image.png
  • 由于容器启动和运行过程中是直接使用了宿主机的内核,所以没有直接调用过物理硬件,所以也不会涉及到硬件驱动,因此也用不上内核和驱动,另外有内核的那是虚拟机。
手动制作镜像
  • Docker制作类似于虚拟机的镜像制作,即按照公司的实际业务务求将需要安装的软件、相关配置等基础环境配置完成,然后将其做成镜像,最后再批量从镜像批量生产实例,这样可以极大的简化相同环境的部署工作。基于基础镜像去做,一个镜像尽量只做一件事。
镜像导出
  • 可以将镜像从本地导出问为一个压缩文件,然后复制到其他服务器进行导入使用。
#导出方法1:
# docker image save IMAGE-ID ... -o /PATH/TO/SOMEFILE.tar
[root@docker-server1 ~]# docker save -o /opt/centos.tar.gz centos
[root@docker-server1 ~]# ll /opt/centos.tar.gz 
-rw------- 1 root root 205225472 Nov  1 03:52 /opt/centos.tar.gz
#导出方法2:
[root@docker-server1 ~]# docker save centos > /opt/centos-1.tar.gz
[root@docker-server1 ~]# ll /opt/centos-1.tar.gz 
-rw-r--r-- 1 root root 205225472 Nov  1 03:52 /opt/centos-1.tar.gz
#查看镜像内容:
[root@docker-server1 ~]# cd /opt/
[root@docker-server1 opt]# tar xvf centos.tar.gz
[root@docker-server1 opt]# cat manifest.json  #包含了镜像的相关配置,配置文件、分层
[{"Config":"196e0ce0c9fbb31da595b893dd39bc9fd4aa78a474bbdc21459a3ebe855b7768.json","RepoTags":["docker.io/centos:latest"],"Layers":["892ebb5d1299cbf459f67aa070f29fdc6d83f40
25c58c090e9a69bd4f7af436b/layer.tar"]}]

#分层为了方便文件的共用,即相同的文件可以共用
[{"Config":"配置文件.json","RepoTags":["docker.io/nginx:latest"],"Layers":["分层1/layer.tar","分层2 /layer.tar","分层3 /layer.tar"]}]
# 镜像导入
[root@docker-server1 ~]# scp /opt/centos.tar.gz  192.168.10.206:/opt/
# scp
#docker image load -i /PATH/TO/SOMEFILE.tar
[root@docker-server2 ~]# docker load < /opt/centos.tar.gz
# 删除镜像
[root@docker-server1 opt]# docker rmi centos
#获取运行参数帮助
[root@linux-docker opt]# docker daemon –help

命令总结:

  • docker load -i centos-latest.tar.xz #导入本地镜像
  • docker save -o /opt/centos.tar #centos #导出镜像
  • docker rmi 镜像ID/镜像名称 #删除指定ID的镜像,通过镜像启动容器的时候镜像不能被删除,除非将容器全部关闭
  • docker rm 容器ID/容器名称 #删除容器
  • docker rm 容器ID/容器名-f #强制删除正在运行的容器
# 提交为镜像:
# 基于容器制作镜像

# 修改原有基础镜像启动要运行的命令
# docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]
#Options:
#  -a, --author string    Author (e.g., "John Hannibal Smith <hannibal@a-team.com>")
#  -c, --change list      Apply Dockerfile instruction to the created image
#  -m, --message string   Commit message
#  -p, --pause            Pause container during commit (default true)

[root@docker-server1 ~]# docker commit -a "wsl" -c 'CMD ["/bin/httpd","-f","-h","/data/html"]' -p b1 myhub/httpd:v0.1-2
# 提交镜像,修改默认运行的命令
[root@docker-server1 ~]# docker commit --change='CMD ["httpd", "-h /data/httpd/htdocs“, “-f”]' -c "EXPOSE 80" bbox1 myhub/busybox/httpd:v0.1
# 提交的时候标记tag号:
# 标记tag号,生产当中比较长用,后期可以根据tag标记启动不同版本启动image启动
[root@docker-server1 ~]# docker commit -m "nginx image" f5f8c13d0f9f jack/centos-nginx:v1
sha256:ab9759679eb586f06e315971d28b88f0cd3e0895d2e162524ee21786b98b24e8
# 从自己镜像启动容器:
[root@docker-server1 ~]# docker run -d -p 80:80  --name my-centos-nginx jack/centos-nginx /usr/sbin/nginx
ce4ee8732a0c4c6a10b85f5463396b27ba3ed120b27f2f19670fdff3bf5cdb62

将镜像push到Docker Hub

?docker push
? Push images to Docker Cloud or private registry
?推送镜像到Docker Hub的前提是于Docker Hub有用户账号,且镜像标签格式为“$DOCKER_USER_ID/IMAGE”
?使用docker login命令登录成功后,即可使用docker push命令进行推送
?示例
? ~]# docker push mageedu/busybox/httpd:version0.1

默认情况下Docker的存放位置为:/var/lib/docker

可以通过下面命令查看具体位置:

sudo docker info | grep "Docker Root Dir"

如果docker是1.12或以上的版本,可以修改(或新建)daemon.json文件。修改后会立即生效,不需重启docker服务。

vim /etc/docker/daemon.json 
{"graph": "/new-path/docker"}
最后编辑于
?著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,029评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,238评论 3 388
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事?!?“怎么了?”我有些...
    开封第一讲书人阅读 159,576评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,214评论 1 287
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,324评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,392评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,416评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,196评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,631评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,919评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,090评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,767评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,410评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,090评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,328评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,952评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,979评论 2 351

推荐阅读更多精彩内容