Linux进阶 | 万字详解Docker镜像的制作,手把手学会!

发布时间:2023-05-02 09:00

  创作不易,来了的客官点点关注,收藏,订阅一键三连❤  

Linux进阶 | 万字详解Docker镜像的制作,手把手学会!_第1张图片


前言

运维之基础——Linux。我是一个即将毕业的大学生,超超。如果你也在学习Linux,不妨跟着萌新超超一起学习Linux,拿下Linux,一起加油,共同努力,拿到理想offer!


系列文章

Linux进阶 | Docker部署nginx的web服务,VOLUME的使用详解,实现数据持久化!

Linux进阶 | 2万字总结最详细的Docker的安装、底层隔离机制和简单使用!建议收藏,持续更新❤

Linux | 详解系统监控和常用命令(top free dstat)

Linux | 超超讲解SSH的原理与SSH的实现!建议收藏❤


概述

Docker 属于 Linux 容器的一种封装,提供简单易用的容器使用接口。它是目前最流行的 Linux 容器解决方案。本期内容为Docker第三期,通过本期内容将会掌握docker的镜像制作。


目录

前言

概述

超超Docker学习思维导图 

镜像的概念

Base镜像

Bootfs与rootfs

镜像的分层结构

镜像的制作

制作前的疑问

Dockerfile

制作步骤

以制作nginx镜像为例启动web服务

自己练习制作nginx镜像

练习

练习一:以python:3.9镜像为基础创建镜像,并以此启动容器并连接到redis

练习二:实现docker官网的镜像制作


超超Docker学习思维导图 

Linux进阶 | 万字详解Docker镜像的制作,手把手学会!_第2张图片

Docker思维导图将持续更新,欢迎大家订阅Linux栏目! 


镜像的概念

Base镜像

Base 镜像有两层含义

1. 不依赖其他镜像,从 scratch 构建。
2. 其他镜像可以之为基础进行扩展。

Base 镜像的通常都是各种 Linux 发行版的 Docker 镜像,比如 Ubuntu, Debian, CentOS 等,以 CentOS 为例学习 base 镜像包含哪些内容。

[root@docker ~]# docker images centos

REPOSITORY   TAG       IMAGE ID       CREATED        SIZE

centos       7         8652b9f0cb4c   9 months ago   204MB

使用docker pull centos下载最新版本的Centos镜像也就207M左右,而我们平时下载一个原生的centos镜像都是4G。

容器只能使用 Host kernel,并且不能修改。所有容器都共用 host kernel,在容器中没办法对 kernel 升级。如果容器对 kernel 版本有要求(比如应用只能在某个 kernel 版本下运行),则不建议用容器,这种场景虚拟机可能更合适。

Bootfs与rootfs

Bootfs:内核空间是 kernel,Linux 刚启动时会加载 bootfs 文件系统,之后 bootfs 会被卸载掉。

rootfs:容器内部的操作系统,用户空间的文件系统是 rootfs,包含我们熟悉的 /dev, /proc, /bin 等目录。

镜像的分层结构

Docker 支持通过扩展现有镜像,创建新的镜像。实际上,Docker Hub 中 99% 的镜像都是通过在 base 镜像中安装和配置需要的软件构建出来的。


镜像的制作

制作前的疑问

镜像是什么?

答案:镜像由程序代码、基础操作系统、基础软件组成。

      镜像是一个文件,里面包含了程序代码、基础操作系统、基础软件。

为什么要制作镜像,docker hub上不是有很多镜像吗?

答案:

    1.不能满足我们的需要

    2.不够安全,有安全隐患

谁去制作镜像?

答案: 一般都是开发人员去制作

        也可以是运维人员去制作、权利非常大的工作人员。

镜像里有什么?

1.base 镜像 --》基础镜像--》提供操作系统,其他软件最基本的功能

基础镜像里的操作系统:Ubuntu、debian、centos等

Dockerfile

如果你想要从一个基础镜像开始建立一个自定义镜像,可以选择一步一步进行构建,也可以选择写一个配置文件,然后一条命令(docker build)完成构建,显然配置文件的方式可以更好地应对需求的变更,这个配置文件就是Dockerfile。

那DockerFile是什么?

Dockerfile: 用于描述镜像的生成规则(配置文件),Dockerfile中的每一条命令,都在Docker镜像中以一个独立镜像层的形式存在

DockerFile就类似与Linux的shell脚本,只不过DockerFile是用来构建镜像的

制作步骤

以制作nginx镜像为例启动web服务

1.新建一个空目录

[root@docker ~]# cd /mydocker/

[root@docker mydocker]# pwd

/mydocker

2.新建Dockerfile

[root@docker mydocker]# vim Dockerfile

[root@docker mydocker]# ls

Dockerfile

[root@docker mydocker]# cat Dockerfile

# Use an official Python runtime as a parent image  下载一个python2.7的镜像模板,已经有操作系统和安装好python2.7

FROM python:2.7-slim

 

# Set the working directory to /app   #在docker容器里的工作目录-->进入docker容器的时候,所在的目录

WORKDIR /app

 

# Copy the current directory contents into the container at /app  复制当前目录下的所有的内容到容器里的/app目录下

ADD . /app

 

VOLUME ["/data_flask"]

 

# Install any needed packages specified in requirements.txt 制作镜像的时候运行

RUN pip install --trusted-host pypi.python.org -r requirements.txt

 

# Make port 80 available to the world outside this container

EXPOSE 80

 

# Define environment variable 设置环境变量,app.py运行时可以调用

ENV NAME World

 

# Run app.py when the container launches 容器启动时运行

CMD ["python", "app.py"]

3.新建requirements.txt文件

[root@docker mydocker]# vim requirements.txt

[root@docker mydocker]# ls

Dockerfile  requirements.txt

[root@docker mydocker]# cat requirements.txt

Flask

Redis

4.新建app.py文件

[root@docker mydocker]# vim app.py

[root@docker mydocker]# ls

app.py  Dockerfile  requirements.txt

[root@docker mydocker]# cat app.py

from flask import Flask

from redis import Redis, RedisError

import os

import socket

 

# Connect to Redis

redis = Redis(host="redis", db=0, socket_connect_timeout=2, socket_timeout=2)

 

app = Flask(__name__)

 

@app.route("/")

def hello():

    try:

        visits = redis.incr("counter")

    except RedisError:

        visits = "cannot connect to Redis, counter disabled"

 

    html = "

Hello {name}!

" \            "Hostname: {hostname}
" \            "Visits: {visits}"     return html.format(name=os.getenv("NAME", "world"), hostname=socket.gethostname(), visits=visits)   if __name__ == "__main__":     app.run(host='0.0.0.0', port=80) [root@docker mydocker]#

5.生成镜像,需要一点时间,因为下载安装很多东西

[root@docker mydocker]# docker build -t hellochao .

-t 指定要创建的目标镜像名

. Dockerfile 文件所在目录,可以指定Dockerfile 的绝对路径

注:此时可能会有错误爆出,是由于网络连接问题所导致。

解决方法:重启docker服务。

Linux进阶 | 万字详解Docker镜像的制作,手把手学会!_第3张图片

6.查看生成的镜像

[root@docker mydocker]# docker images

REPOSITORY                 TAG        IMAGE ID       CREATED          SIZE

hellochao                  latest     b9cdb67a8db4   14 seconds ago   159MB

                          fbea61ffb278   32 minutes ago   148MB

ubuntu-chaochao            2.0        67596afe27b5   4 days ago       72.8MB

ubuntu                     latest     1318b700e415   3 weeks ago      72.8MB

redis                      latest     aa4d65e670d6   3 weeks ago      105MB

nginx                      latest     08b152afcfae   3 weeks ago      133MB

mysql                      5.7.35     8cf625070931   3 weeks ago      448MB

daocloud.io/nginx          latest     6084105296a9   5 months ago     133MB

hello-world                latest     d1165f221234   5 months ago     13.3kB

centos                     7          8652b9f0cb4c   9 months ago     204MB

python                     2.7-slim   eeb27ee6b893   16 months ago    148MB

centos/python-35-centos7   latest     2db34dda8fd8   2 years ago      645MB

7.以刚刚创建的镜像为基础创建容器

[root@docker mydocker]# docker run -d --name hello-chao-1 -p 8013:80 hellochao

b571dc07bf393737fe820cf5a7b6c5c61359b9979054d3484aeb1d573a788d71

[root@docker mydocker]# docker ps

CONTAINER ID   IMAGE       COMMAND           CREATED         STATUS         PORTS                                   NAMES

b571dc07bf39   hellochao   "python app.py"   2 minutes ago   Up 2 minutes   0.0.0.0:8013->80/tcp, :::8013->80/tcp   hello-chao-1

访问方式1:

用浏览器访问:网站-->宿主机IP+端口号

Linux进阶 | 万字详解Docker镜像的制作,手把手学会!_第4张图片

访问方式2:curl IP地址:端口号

Hello World!

Hostname: f4aeb5d5305a

 Visits: cannot connect to Redis, counter disabled

因为redis数据库容器没有启动,flask web服务不能连接到redis数据库

8.启动redis容器

[root@docker mydocker]# docker run -d -p 6379:6379 --name hello-redis-1 redis

4ae649e2c9cf52e19e5cab4e4a6136d493390ff2e089838a4d65221e8e5b534a

9.再次启动一个自己制作镜像的容器,连接到redis容器

[root@docker mydocker]# docker run -d --name hello-chao-2 -p 8014:80 --link hello-redis-1:redis hellochao
1967d1eae722bd34e01f5bc575127e041a6caea15f48bd5f3f137ae1f2c744a9

10.访问web服务,效果如下:

方式一:用浏览器

Linux进阶 | 万字详解Docker镜像的制作,手把手学会!_第5张图片

 方式二:curl

[root@docker ~]# curl 192.168.232.132:8014

Hello World!

Hostname: 1967d1eae722
Visits: 3[root@docker ~]#

Dockerfile里面的RUNCMD是什么时候运行的?

RUN构建镜像时候运行的,在临时启动的中间测试的容器里运行,会产生中间的镜像层

CMD镜像制作好后,容器启动的时候运行

ADDCOPY

Dockerfile中的COPY指令和ADD指令都可以将主机上的资源复制或加入到容器镜像中,都是在构建镜像的过程中完成的

COPY指令和ADD指令的唯一区别在于是否支持从远程URL获取资源

COPY指令只能从执行docker build所在的主机上读取资源并复制到镜像中。

而ADD指令还支持通过URL从远程服务器读取资源并复制到镜像中。(推荐)


自己练习制作nginx镜像

1.部署环境

[root@docker ~]# mkdir/mydocker/nginx

2.创建Dockerfile

[root@docker nginx]# ls

Dockerfile  install_nginx.sh  nginx-1.21.1.tar.gz

[root@docker nginx]# vim Dockerfile

[root@docker nginx]# cat Dockerfile

FROM centos:7

ENV NGINX_VERSION 1.21.1

ENV AUTHOR ChaoChao

LABEL maintainer="lzc<2569138892@qq.com>"

RUN mkdir /nginx

WORKDIR /nginx

COPY . /nginx

RUN set -ex;\

    bash install_nginx.sh ; \

    yum install vim iputils net-tools iproute -y

EXPOSE 80

ENV PATH=/usr/local/nginx1/sbin:$PATH

 

STOPSIGNAL SIGQUIT

CMD ["nginx","-g","daemon off;"]

 

[root@docker nginx]#

3.构建nginx镜像

[root@docker nginx]#docker build -t chao-ngixn-1 .

[root@docker nginx]# docker images

REPOSITORY                 TAG         IMAGE ID       CREATED         SIZE

chao-nginx-1               latest      f668613a9de5   6 seconds ago   543MB

getting-started-1          latest      78bc6143bbce   7 hours ago     383MB

getting-started            latest      8224b1c2dc86   19 hours ago    374MB

hello-chao-3               latest      a9c7a3290464   20 hours ago    923MB

hellochao                  latest      b9cdb67a8db4   24 hours ago    159MB

                           fbea61ffb278   24 hours ago    148MB

python                     3.9         4c7220cee541   31 hours ago    912MB

node                       12-alpine   dc1848067319   5 days ago      88.9MB

ubuntu-chaochao            2.0         67596afe27b5   5 days ago      72.8MB

ubuntu                     latest      1318b700e415   3 weeks ago     72.8MB

redis                      latest      aa4d65e670d6   3 weeks ago     105MB

nginx                      latest      08b152afcfae   3 weeks ago     133MB

mysql                      5.7.35      8cf625070931   3 weeks ago     448MB

daocloud.io/nginx          latest      6084105296a9   5 months ago    133MB

hello-world                latest      d1165f221234   5 months ago    13.3kB

centos                     7           8652b9f0cb4c   9 months ago    204MB

python                     2.7-slim    eeb27ee6b893   16 months ago   148MB

centos/python-35-centos7   latest      2db34dda8fd8   2 years ago     645MB

4.创建以新建镜像为基础的容器并测试是否实现功能

[root@docker nginx]# docker run -d --name chaochao-nginx-1 -p 8018:80 chao-nginx-1

fad41f8b6ee1da4034c8fd89a1a56c3588a28100850e7c5a9cfdb8f089eeef4f

[root@docker nginx]# curl 192.168.232.132:8018







Welcome to nginx!







Welcome to nginx!

If you see this page, the nginx web server is successfully installed and working. Further configuration is required.

 

For online documentation and support please refer to nginx.org.
Commercial support is available at nginx.com.

 

Thank you for using nginx.

Linux进阶 | 万字详解Docker镜像的制作,手把手学会!_第6张图片

[root@docker nginx]# docker exec -it chaochao-nginx-1 /bin/bash

[root@fad41f8b6ee1 nginx]# ls

Dockerfile  install_nginx.sh  nginx-1.21.1  nginx-1.21.1.tar.gz

[root@fad41f8b6ee1 nginx]# vim chaochao.txt

[root@fad41f8b6ee1 nginx]# cat chaochao.txt

echo I am chaochao!

[root@fad41f8b6ee1 nginx]# ip a

1: lo:  mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000

    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

    inet 127.0.0.1/8 scope host lo

       valid_lft forever preferred_lft forever

135: eth0@if136:  mtu 1500 qdisc noqueue state UP group default

    link/ether 02:42:ac:11:00:0a brd ff:ff:ff:ff:ff:ff link-netnsid 0

    inet 172.17.0.10/16 brd 172.17.255.255 scope global eth0

       valid_lft forever preferred_lft forever

[root@fad41f8b6ee1 nginx]# exit

exit

[root@docker nginx]# ls

Dockerfile  install_nginx.sh  nginx-1.21.1.tar.gz

5.更改index.html

方法一:利用挂载实现

[root@docker nginx]# docker run -dp 8019:80 -v /web:/usr/local/nginx1/html --name chaochao-nginx-2 chao-nginx-1

6e3f9a849ce179ad184e2c314651c86a4db8c3c7ab5f264f0af27baa6aa1a047

[root@docker nginx]#

Linux进阶 | 万字详解Docker镜像的制作,手把手学会!_第7张图片

方法二:使用卷

[root@docker nginx]# docker volume create chao-nginx-volume-1

chao-nginx-volume-1

[root@docker nginx]# docker volume inspect chao-nginx-volume-1

[

    {

        "CreatedAt": "2021-08-18T17:20:27+08:00",

        "Driver": "local",

        "Labels": {},

        "Mountpoint": "/var/lib/docker/volumes/chao-nginx-volume-1/_data",

        "Name": "chao-nginx-volume-1",

        "Options": {},

        "Scope": "local"

    }

]

[root@docker nginx]# cd /var/lib/docker/volumes/chao-nginx-volume-1/_data

[root@docker _data]# cp /web/* .

[root@docker _data]# ls

1.jpg  index.html  rep.html

[root@docker _data]# docker run -dp 8020:80 --name chao-nginx-3 --mount source=chao-nginx-volume-1,target=/usr/local/nginx1/html/ chao-nginx-1

e0f8f8b0bfc40b8ad6d2e74a536b6e831dde444fbb8c536b37ead81e31c5d64c

Linux进阶 | 万字详解Docker镜像的制作,手把手学会!_第8张图片

练习

练习一:以python:3.9镜像为基础创建镜像,并以此启动容器并连接到redis

1.升级 hello-chao-1的镜像里的基础镜像为python:3.9,并将自己的镜像更名

2.启动容器和redis容器,测试访问

[root@docker ~]# cd mydocker2/

[root@docker mydocker2]# ls

[root@docker mydocker2]# cp /mydocker/* .

[root@docker mydocker2]# ls

app.py  Dockerfile  requirements.txt

[root@docker mydocker2]# vim Dockerfile

[root@docker mydocker2]# docker pull python:3.9

[root@docker mydocker2]# docker build -t hello-chao-3 .

[root@docker mydocker2]# curl 192.168.232.132:8015

Hello,I am Lizhichao!

Hostname: 232af106a331
Visits: cannot connect to Redis, counter disabled[root@docker mydocker2]# [root@docker mydocker2]# docker run -d --name hello-redis-2 -p 8011:6379 redis 181d9b51863a6ad888e7e53ac27070343396fab16c911851dfa2c4e7579b7f22 [root@docker mydocker2]# docker run -d --name hello-chao-5 -p 8016:80 --link hello-redis-2:redis hello-chao-3 080bdc9dcd9304597c27db1afd6e266fd6d8c37ae78fcf02bedf81809a085470 [root@docker mydocker2]# curl 192.168.232.132:8016

Hello,I am Lizhichao!

Hostname: 080bdc9dcd93
Visits: 1[root@docker mydocker2]# curl 192.168.232.132:8016

Hello,I am Lizhichao!

Hostname: 080bdc9dcd93
Visits: 2[root@docker mydocker2]#

练习二:实现docker官网的镜像制作

实现 https://docs.docker.com/get-started/02_our_app/ 官网的镜像制作

[root@docker ~]# ls

anaconda-ks.cfg  getting-started-master.zip  mydocker2  ubuntu-chao2.tar  ubuntu-chao.tar

[root@docker ~]# unzip getting-started-master.zip

[root@docker ~]# ls

anaconda-ks.cfg  getting-started-master  getting-started-master.zip  mydocker2  ubuntu-chao2.tar  ubuntu-chao.tar

[root@docker ~]# cd getting-started-master

[root@docker getting-started-master]# ls

app       docker-compose.yml  docs         LICENSE     README.md         yarn.lock

build.sh  Dockerfile          Jenkinsfile  mkdocs.yml  requirements.txt

[root@docker getting-started-master]# cd app

[root@docker app]#

[root@docker app]# ls

package.json  spec  src  yarn.lock

[root@docker app]# vim Dockerfile

[root@docker app]# ls

Dockerfile  package.json  spec  src  yarn.lock

[root@docker app]# cat Dockerfile

#syntax=docker/dockerfile:1

FROM node:12-alpine

RUN apk add --no-cache python g++ make

WORKDIR /app

COPY . .

RUN yarn install --production

CMD ["node", "src/index.js"]

[root@docker app]#

[root@docker app]# docker run -dp 3000:3000 getting-started-1

588fd20a79b9d8082507dc209e73fa8a51a1e6abb56bc019256afc0df43ac73a

[root@docker app]#

[root@docker app]# docker run -dp 3001:3000 --name chao-node-2 getting-started-1

b5c8d74e7be4426fb22e1c524e26bead8b160cd938ae6bebe2433a52c65ab33a

[root@docker app]#

Linux进阶 | 万字详解Docker镜像的制作,手把手学会!_第9张图片

Linux进阶 | 万字详解Docker镜像的制作,手把手学会!_第10张图片

创作不易,客官点个赞,评论一下吧!超超和你一起加油❤

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号