镜像/容器相关操作

 

通过容器创建镜像
我们可以通过以下两种方式对镜像进行更改。
1. 从已经创建的容器中更新镜像,并且提交这个镜像
2. 使用 Dockerfile 指令来创建一个新的镜像
 
下面通过已存在的容器创建一个新的镜像
docker commit -m="First Docker" -a="wcjiang" a6b0a6cfdacf wcjiang/nginx:v1.2.1
上面命令参数说明:
* -m 提交的描述信息
* -a 指定镜像作者
* a6b0a6cfdacf 记住这个是容器id,不是镜像id
* wcjiang/nginx:v1.2.1 创建的目标镜像名
 
 
进入容器
创建一个守护状态的Docker容器
docker run -itd my-nginx /bin/bash
 
使用docker ps查看到该容器信息
docker ps
# CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES
# 6bd0496da64f        nginx               "/bin/bash"         20 seconds ago      Up 18 seconds       80/tcp              high_shirley
 
使用docker exec命令进入一个已经在运行的容器
# 连接关闭的容器
# 连接关闭但运行的容器
[ ~]#  ps -q
7b5f30fe77c0
[ ~]# docker attach 7b5f
[ /]#
 
# 连接关闭且未运行的容器
docker ps -a -qf status=exited
7968b44369
[ ~]# docker start 7968b44369
7968b44369
[ ~]# docker attach 7968b44369            # 会附加该容器的标准输出到当前命令行
 
# 启动状态的容器,执行任务
# 通过exec命令可以创建两种任务:后台型任务和交互型任务
# 后台型任务:docker exec -it test /bin/bash
# 交互型任务:docker attach 7968
 
文件拷贝
从主机复制到容器 docker cp host_path containerID:container_path 
从容器复制到主机 docker cp containerID:container_path host_path
 
# 从正在运行的 Docker 容器里面,将文件拷贝到本机,注意后面有个【点】拷贝到当前目录
docker container cp [containID]:[/path/to/file] .
# 例: 一个centos7容器里面有一个hello.go文件,我们需要将它copy到宿主机的/tmp下
# [ ~]# docker container cp 61d2b:/hello.go /tmp/
# [roo ~]# ls /tmp/hello.go
# /tmp/hello.go
 
 
通过Dockerfile部署CentOS7容器应用
# 生产生活中经常会涉及到使用基础镜像制作自己的镜像,经常使用的就是系统镜像,但是centos7镜像默认使用systemctl 命令是无法启动服务的。
 
# 镜像中的包管理问题
    # 默认情况下,为了减小镜像的尺寸,在构建CentOS镜像时用了yum的nodocs选项,如果你安装一个包发现文件缺失,请在/etc/yum.conf中注释掉tsflogs=nodocs之后重新安装。
 
# systemd管理服务问题
    # 在centos7之前使用init管理各种服务,centos7开始使用system管理系统中所有的服务,但因为systemd要求capsysadmin权限才能读取到宿主机cgroup(资源限制的能力);另CentOS7中用fakesystemd代替了systemd来解决依赖问题,但如果使用fakesystem无法使用应用,故需要修改回systemd,
# 无法启动服务也就无法远程连接
[ .ssh]# systemctl restart sshd.service
Failed to get D-Bus connection: Operation not permitted
 
构建包含httpd应用的容器
1、使用dockerfile创建镜像
[ ~]# mkdir centos7
[ ~]# cd centos7/
[ centos7]# vim Dockerfile
FROM centos:7.7.1908
MAINTAINER "youmen"
ENV container docker
RUN yum -y install swap -- remove fakesystemd -- install system systemd-libs \
rm -f /lib/systemd/system/multi-user.target.wants/*;\
rm -f /etc/systemd/system/*.wants/*;\
rm -f /lib/systemd/system/local-fs.target.wants/*; \
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
rm -f /lib/systemd/system/basic.target.wants/*;\
rm -f /lib/systemd/system/anaconda.target.wants/*;
VOLUME [ "/sys/fs/cgroup" ]
CMD ["/usr/sbin/init"]
 
# 删除fakesystemd并安装systemd,然后再构建基础镜像
[ centos7]# docker build --rm -t local/c7-systemd .
 
# 构建包含httpd应用的容器
# 1、使用构建之后的基础镜像再去构建包含systemd应用的镜像
[ centos7]# mv Dockerfile  Dockerfile.bak
[ centos7]# vim Dockerfile
[ centos7]# cat Dockerfile
FROM local/c7-systemd
RUN yum -y install httpd; yum clean all; systemctl enable httpd.service
EXPOSE 80
CMD ["/usr/sbin/init"]
 
[ centos7]# docker build --rm -t local/c7-systemd-httpd .
 
# 2、运行包含systemd的httpd的应用容器
# 需要使用--privileged选项,并且挂载主机的 cgroups 文件夹。
[ centos7]# docker run --privileged -ti -v /sys/fs/cgroup/:/sys/fs/cgroup:ro -p 80:80 local/c7-systemd-httpd
#     [使用该参数,container内的root拥有真正的root权限。
       否则,container内的root只是外部的一个普通用户权限。
       privileged启动的容器,可以看到很多host上的设备,并且可以执行mount。
       甚至允许你在docker容器中启动docker容器。]
# 注意:不能添加/bin/bash,添加了会导致服务不可用,而且有些服务可能会发现之前提到的权限不够的问题,但是如果不加会运行在前台(没有用-d),可以用ctrl+p+q放到后台去
 
# 3、访问测试  -p 80:88   IP:88
 
 
构建包含openssh-server应用的容器
[ centos7]# cat Dockerfile
FROM local/c7-systemd
RUN yum -y install openssh-server; yum clean all; systemctl enable sshd.service
RUN echo 1 | passwd --stdin root
EXPOSE 22
CMD ["/usr/sbin/init"]
 
[ centos7]# docker build --rm -t local/c7-systemd-sshd .
 
[ centos7]# docker run --privileged -ti -v /sys/fs/cgroup:/sys/fs/cgroup:ro -p 2222:22 local/c7-systemd-sshd
 
[ ~]# ssh 39.108.140.0 -p 2222
 
CentOS7的docker容器一个bug
centos7镜像创建的容器里面安装服务后,不能用systemctl/service启动服务,centos6的容器里没有这个坑!
原因是:dbus-daemon没能启动
 
[ .ssh]# systemctl restart sshd.service
Failed to get D-Bus connection: Operation not permitted
 
治标不治本的解决方案如下:
将CMD设置为/usr/sbin/init即可。这样就会自动将dbus等服务启动起来,即采用 /usr/sbin/init自动启动dbus daemon。在启动容器时,加上参数--privileged和/sbin/init即可
[ ~]#  docker run --privileged -i -t library/centos /sbin/init     
上面的容器启动后,会一直在卡着的状态中,先不用管,打开另一个终端窗口,查看容器。这里注意,宿主机可能会出现注销当前登陆账户的情况
[ ~]# docker ps
然后按照容器的ID进去,这个时候再根据/bin/bash进入容器(前面加exec -it参数),接着重启ssh服务就ok了
[ ~]# docker exec -it af40bd07fa0f /bin/bash
[ /]# systemctl restart sshd.service
 
这个解决方案有很大的坑:
1、卡住不动的问题
2、打开图形就会先把图形重启
 
http://www.dockone.io/article/1264
 
 
 
镜像打包
方案一: export
    利用export把正在运行的容器直接导出为tar包的镜像文件,可以用-o或>
docker run --name my-nginx -d -p 8080:80 some-centent-nginx:1.2
docker export my-nginx > youmen_nginx.tar  &&  docker export -o youmen_nginx.tar my-nginx
scp youmen_nginx.tar 120.77.248.31:
docker import youmen_nginx.tar
docker tag 121d8 mynginx:1                            # 设置镜像名字
docker import youmen_nginx.tar mynginx:1.1            # 导入时即设置镜像名字
 
方案二: 利用save直接把镜像打包出来
docker save -o suibian.tar library/centos:latest
scp suibian.tar 192.168.135.161:
docker load < suibian.tar                # 导入之后使用原名
 
------------------------------------区别介绍-------------------------------------
* docker save:将一个镜像导出为文件,保存的是该镜像的所有历史记录;
* docker export:将一个容器导出为文件,保存的是容器当时的状态,即容器快照;
* docker load:将镜像存储文件导入到本地镜像库;
* docker import:导入一个容器快照到本地镜像库;
 
docker save和docker export之间的区别:
    1)docker save是将镜像保存为tar包,且会保存该镜像的父层、标签、所有历史等信息;docker export是将容器文件系统保存为tar包,保存的是容器当时的状态(快照);
    2) docker save可以同时指定多个镜像名称;docker export只能指定一个容器名称;
    3)docker save保存的镜像文件tar包使用docker load命令加载还原;docker export保存的容器快照tar包使用docker import命令导入还原;
    4)docker save保存的tar包文件通常比docker export导出的文件要大;
 
docker load和docker import之间的区别:
    1)docker load将镜像存储文件导入到本地镜像库;docker import将容器快照文件导入到本地镜像库;
    2)docker load不能指定url;而docker import可以指定url来进行导入;
 
 
 
发布自己的镜像
1. 在Docker 注册账户,发布的镜像都在这个页面里展示
 
2. 将上面做的镜像nginx,起个新的名字nginx-test
docker tag wcjiang/nginx:v1.2.1 wcjiang/nginx-test:lastest
 
3.登录docker
docker login
 
4.上传nginx-test镜像
docker push wcjiang/nginx-test:lastest
# The push refers to a repository [docker.io/wcjiang/nginx-test]
# 2f5c6a3c22e3: Mounted from wcjiang/nginx
# cf516324493c: Mounted from wcjiang/nginx
# lastest: digest: sha256:73ae804b2c60327d1269aa387cf782f664bc91da3180d10dbd49027d7adaa789 size: 736
 
 

相关推荐