发布时间:2023-05-02 09:00
创作不易,来了的客官点点关注,收藏,订阅一键三连❤
运维之基础——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栏目!
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:内核空间是 kernel,Linux 刚启动时会加载 bootfs 文件系统,之后 bootfs 会被卸载掉。
rootfs:容器内部的操作系统,用户空间的文件系统是 rootfs,包含我们熟悉的 /dev, /proc, /bin 等目录。
Docker 支持通过扩展现有镜像,创建新的镜像。实际上,Docker Hub 中 99% 的镜像都是通过在 base 镜像中安装和配置需要的软件构建出来的。
镜像是什么?
答案:镜像由程序代码、基础操作系统、基础软件组成。
镜像是一个文件,里面包含了程序代码、基础操作系统、基础软件。
为什么要制作镜像,docker hub上不是有很多镜像吗?
答案:
1.不能满足我们的需要
2.不够安全,有安全隐患
谁去制作镜像?
答案: 一般都是开发人员去制作
也可以是运维人员去制作、权利非常大的工作人员。
镜像里有什么?
1.base 镜像 --》基础镜像--》提供操作系统,其他软件最基本的功能
基础镜像里的操作系统:Ubuntu、debian、centos等
如果你想要从一个基础镜像开始建立一个自定义镜像,可以选择一步一步进行构建,也可以选择写一个配置文件,然后一条命令(docker build)完成构建,显然配置文件的方式可以更好地应对需求的变更,这个配置文件就是Dockerfile。
那DockerFile是什么?
Dockerfile: 用于描述镜像的生成规则(配置文件),Dockerfile中的每一条命令,都在Docker镜像中以一个独立镜像层的形式存在
DockerFile就类似与Linux的shell脚本,只不过DockerFile是用来构建镜像的
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服务。
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+端口号
访问方式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服务,效果如下:
方式一:用浏览器
方式二:curl
[root@docker ~]# curl 192.168.232.132:8014
Hello World!
Hostname: 1967d1eae722
Visits: 3[root@docker ~]#
Dockerfile里面的RUN和CMD是什么时候运行的?
RUN:构建镜像时候运行的,在临时启动的中间测试的容器里运行,会产生中间的镜像层
CMD:镜像制作好后,容器启动的时候运行
ADD和COPY
Dockerfile中的COPY指令和ADD指令都可以将主机上的资源复制或加入到容器镜像中,都是在构建镜像的过程中完成的。
COPY指令和ADD指令的唯一区别在于是否支持从远程URL获取资源。
COPY指令只能从执行docker build所在的主机上读取资源并复制到镜像中。
而ADD指令还支持通过URL从远程服务器读取资源并复制到镜像中。(推荐)
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.
[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]#
方法二:使用卷
[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
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]#
实现 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]#
创作不易,客官点个赞,评论一下吧!超超和你一起加油❤