目录

  1. Image and Container
    1. 一、 深入探讨Image
      1. 官方镜像
      2. Dockerfile认识
      3. 基于Dockerfile实战Spring项目
      4. 将镜像推送至官网
      5. 使用阿里云Docker hub
      6. 搭建自己的Docker Harbor
      7. Image常见操作
    2. 深入探讨Container
      1. container到image
      2. container资源限制
        1. 内存限制
        2. CPU限制
        3. 图形化资源监控
      3. container常见操作
    3. 底层技术支持

Image and Container

一、 深入探讨Image

官方镜像

1
通过docker的环境搭建,我们知道可以通过docker run [name] 去拉取一个镜像,但这些image是在官方网站,一个是速度可能比较慢,第二是谁去创建的image放在官方网站的呢?我们自己可以不可以创建一个image呢?

官方镜像地址仓库

Mysql-Image

从上面的地址中,我们可以发现一个叫Dockerfile的文件,这类文件主要就是为了制作image的,我们可以将我们的自己的一整套环境进行镜像的制作,后续就可以直接利用制作好的镜像进行快速部署和落地。

Dockerfile认识

不妨我们也来制作一个自己的image的镜像,顺便学习一下Dockerfile文件的常见语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
FORM:指定基础镜像,比如FORM ubuntu:14:04
FORM ubuntu:14:04
RUN:在镜像内部执行一些命令,比如安装软件,配置环境等,换行可以使用“\”
RUN groupad -r mysql && useradd -r -g mysql mysql
ENV:设置变量的值,ENV MYSQL_MAJOR 5.7,可以通过docker run --e key=value修改,后面可以直接使用${MYSQL_MAJOR}
ENV MYSQL_MAJOR 5.7
LABEL:设置镜像标签
LABEL email="274027703@.com"
LABEL name="wangli"
VOLUME:指定数据的挂载目录
VOLUME /var/lib/mysql
COPY:将主机的文件复制到镜像内,如果目录不存在,会自动创建所需要的目录,注意只是复制,不会提取和解压
COPY docker-entryporint.sh /usr/local/bin/
ADD: 将主机的文件复制到镜像内,和COPY类似,只是ADD会对压缩文件提取和解压
ADD application.yml /etc/wangli/
WORKDIR:指定镜像的工作目录,之后的命令都是基于此目录工作,若不存在则创建
WORKDIR /usr/local
WORKDIR tomcat
RUN touch test.txt
// 会在/usr/local/tomcat下创建test.txt文件
WORKDIR /root
ADD app.yml test/
// 会在/root/test下多出一个app.yml文件
CMD:容器启动的时候默认会执行的命令,若有多个CMD命令,则最后一个生效
CMD ["mysqld"] 或者 CMD mysqld
ENTRYPOINT: 和CMD的使用类似,不同的是,docker run执行时,会覆盖CMD的命令,而ENTRYPOINT不会
ENTRYPOINT [“docker-entrypoint.sh”]
EXPOSE: 指定镜像要暴露的端口,启动镜像时,可以使用-p将该端口映射给宿主机
EXPOSE 3306

基于Dockerfile实战Spring项目

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
创建一个Spring Boot项目
写一个Controller,包含一个公共的GetMapping("/dockerfile")
mvn clean package 打成一个jar包
在docker环境中新建一个目录“first-dockerfile”
上传“dockerfile-demo-0.0.1-SNAPSHOT.jar"到该目录下,并且在此目录创建Dockerfile
创建Dockerfile文件,并编写内容
FROM openjdk:8
MAINTAINER wangli
LABEL name="dockerfile-demo" version="v1.0" author="wangli"
COPY dockerfile-demo-0.0.1-SNAPSHOT.jar dockerfile-image.jar
CMD ["java", "-jar","dockerfile-image.jar"]
基于Dockerfile构建镜像
docker build -t wangli-docker-image .
基于image创建container
docker run -d --name user01 -p 9090:8080 wangli-docker-image
查看启动日志
docker logs user01
宿主机上访问
curl lcoalhost:9090/dockerfile
还可以再次启动一个
docker run -d --name user01 -p 8081:8080 wangli-docker-image

将镜像推送至官网

1
2
3
4
5
6
7
8
9
10
11
12
首先需要在hub.docker.com注册自己的账户
在docker机器上登录
docker login
输入用户名和密码
docker push 用户名/wangli-docker-image[注意镜像名称要和docker id一直,不然push不成功]
给image重命名,并删除掉原来的
docker tag wangli-docker-image 用户名/wangli-docker-image
docker rmi -f wangli-docker-image
再次推送,刷新hub.docker.com后台,发现成功
别人下载,并且运行
docker pull 用户名/wangli-docker-image
docker run -d --name user01 -p 8081:8080 用户名/wangli-docker-image

使用阿里云Docker hub

阿里云docker仓库

参考手册

1
2
3
4
5
6
7
8
9
10
11
登录到阿里云docker仓库
sudo docker login --username=274027703@qq.com registry.cn-hangzhou.aliyuncs.com
输入密码
创建命名空间,比如wangli
给image打tag
sudo docker tag [ImageId] registry.cn-hangzhou.aliyuncs.com/wangli/wangli-docker-image:v1.0
推送镜像到docker阿里云仓库
sudo docker push registry.cn-hangzhou.aliyuncs.com/wangli/wangli-docker-image:v1.0
别人下载,并且运行
docker pull registry.cn-hangzhou.aliyuncs.com/wangli/wangli-docker-image:v1.0
docker run -d --name user01 -p 8081:8080 registry.cn-hangzhou.aliyuncs.com/wangli/wangli-docker-image:v1.0

搭建自己的Docker Harbor

可以认为是私有的image仓库,类似maven的nexus。

1
2
3
4
5
6
7
8
9
10
11
12
访问github上的harbor项目
https://github.com/goharbor/harbor
下载版本,比如1.7.1
https://github.com/goharbor/harbor/releases
找一台安装了docker-compose,上传并解压
tar -zxvf xxx.tar.gz
进入到harbor目录
修改harbor.cfg文件,主要是ip地址修改成当前机器的ip地址
同时也可以看到Harbor的面,默认是Harbor12345
安装harbor,需要一些时间
sh install.sh
浏览器访问,比如39.100.39.63,输入用户名和密码即可

Image常见操作

1
2
3
4
5
6
7
8
9
10
11
12
13
查看本地image列表
docker images
docker image ls
获取远端镜像
docker pull
删除镜像[注意此镜像如果正在使用,或者有关联的镜像,则需要先处理完]
docker image rm [imageid]
docker rmi -f [imageid]
docker rmi -f $(docker image ls) 删除所有镜像
运行镜像
docker run image
发布镜像
docker push

深入探讨Container

既然container是有image运行起来的,那么是否可以劣迹为container和image有某种关系?

image-20191104204218889

1
理解:其实可以理解为container只是基于image之后的layer而已,也就是可以通过docker run image创建出一个container出来。

container到image

既然container是基于image之上的,想想是否能够由一个container反推出image呢?

肯定是可以的,比如通过docker run运行起一个container出来,这时候对container对一些修改,然后再生成一个新的image,这时候image的由来就不仅仅只能通过Dockerfile咯。

实验

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
拉取一个centos image
docker pull centos
根据centos镜像创建出一个container
docker run -d -it --name my-centos centos
进入my-centos容器中
docker exec -it my-centos bash
输入vim命令
bash:vim:command not found
我们要做的是
对该container进行修改,也就是安装一些vim命令,然后将其生成一个新的centos
在centos的container中安装vim
yum install -y vim
退出容器,将其生成一个新的centos,名称为“vim-centos-image”
docker commit my-centos vim-centos-image
查看镜像列表,并且基于"vim-centos-image"创建新的容器
docker run -d -it --name my-vim-centos vim-centos-image
进入到my-vim-centos容器中,检查vim命令是否存在
docker exec -it my-vim-centos bash
vim

结论

1
可以通过docker commit命令基于一个container重新生成一个image,但是一般得到image的方式不建议这么做,不然image怎么来的就全然不知了。

container资源限制

如果不对container的资源做限制,它就会无限制地使用物理机的资源,这样显然是不合适的。

查看资源情况: docker stats

内存限制

1
2
3
--memory   Memory limit
如果不设置 --memory-swap,其大小和memory一样
docker run -d --memory 100M --name tomcat1 tomcat

CPU限制

1
2
cpu-shares    权重
docker run -d --cpu-shares 10 --name tomcat2 tomat

图形化资源监控

参考官方git

1
2
3
4
5
6
7
8
sudo curl -L git.io/scope -o /usr/local/bin/scope
sudo chmod a+x /usr/local/bin/scope
scope launch 39.100.39.63

`# 停止scope`
scope stop
`# 同时监控两台机器,在两台机器中分别执行如下命令`
scope launch ip1 ip2

container常见操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
根据镜像创建容器
docker run -d --name -p 9090:8080 my-tomcat tomcat
查看运行中的container
docker ps
查看所有的container[包含退出的]
docker ps -a
删除container
docker rm [containerid]
docker rm -f $(docker ps -a) 删除所有container
进入到一个container中
docker exec -it container bash
根据container生成image
docker commit
查看某个container的日志
docker stats
查看容器详细信息
docker inspect container
停止/启动容器
docker stop/start container

底层技术支持

Container是一种轻量级的虚拟化技术,不用模拟硬件创建虚拟机。

Docker是基于Linux kernel的Namespace、CGroups、UnionFIleSystem等技术封装成的一种自定义容器格式,从而提供一套虚拟运行环境。

1
2
3
>Namespace:用来做隔离的,比如pid[进程]、net[网络]、mnt[挂载点]
>CGroups:Contrller Groups用来做资源限制,比如内存和CPU等
>Union file Systems:用来做image和container分层