docker安装和dockerfile 构建镜像

Posted yu344109534

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了docker安装和dockerfile 构建镜像相关的知识,希望对你有一定的参考价值。


1.1 Docker 概述

Docker 是一个开源的容器引擎,开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何 Linux 机器上,也可以实现虚拟化。容器是完全使用沙盒机制,相互之间不会有任何 接口(类似 iPhone 的 app)。几乎没有性能开销,可以很容易地在机器和数据中心中运行。最重 要的是,他们不依赖于任何语言、框架或操作系统。Docker 从 17.03 版本之后分为 CE(Community Edition: 社区版)和 EE(Enterprise Edition: 企业版),我们使用社区版就可以了。
官方网站:
Docker 官网:https://www.docker.com/
Docker 的 github 地址:https://github.com/moby/moby
Docker hub 官网:https://registry.hub.docker.com

1.2 安装 docker 容器并配置镜像加速器

1.2.1 实验环境准备
实验环境: CENTOS7.9 64 位
主机名: docker-100
主机 ip: 192.168.116.100
关闭 selinux
[root@localhost ~]# setenforce 0
[root@localhost ~]# sed -i s/SELINUX=enforcing/SELINUX=disabled/g /etc/selinux/config
注意:修改 selinux 配置文件之后,重启机器,selinux 才能永久生效
[root@localhost ~]# getenforce
Disabled #看到 Disabled 说明 selinux 成功关闭
配置主机名:
[root@localhost ~]# hostnamectl set-hostname docker-100 &&bash
关闭防火墙
[root@docker-100 ~]# systemctl stop firewalld && systemctl disable firewalld
#配置时间同步
[root@docker-100 ~]# yum install -y ntp ntpdate
[root@docker-100 ~]# ntpdate cn.pool.ntp.org
#编写计划任务
[root@docker-100 ~]# crontab -e
*/1 * * * /usr/sbin/ntpdate cn.pool.ntp.org
重启 crond 服务使配置生效:
[root@docker-100 ~]# systemctl restart crond
2、在线安装
安装基础软件包
[root@docker-100 ~]# yum install -y wget net-tools nfs-utils lrzsz gcc gcc-c++ make cmake libxml2-devel openssl-devel curl curl-devel unzip sudo ntp libaio-devel wget vim ncurses-devel autoconf automake zlib-devel python-devel epel-release openssh-server socat ipvsadm conntrack
配置 docker-ce 国内 yum 源(阿里云)
[root@docker-100 ~]# yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
安装 docker 环境
[root@docker-100 ~]# yum install docker-ce -y
#启动 docker 服务
[root@docker-100 ~]# systemctl start docker && systemctl enable docker
#查看 Docker 版本信息

[root@docker-100 ~]#docker info

查看 docker 状态
[root@docker-100 ~]# systemctl status docker
显示 running,说明 docker 正常起来了
1.2.2 开启包转发功能和修改内核参数
内核参数修改:br_netfilter 模块用于将桥接流量转发至 iptables 链,br_netfilter 内核参数需要开启转发。
[root@docker-100 ~]# cat > /etc/sysctl.d/docker.conf <<EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
[root@docker-100 ~]# sysctl -p /etc/sysctl.d/docker.conf


net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1

注有报错解决步骤:
sysctl: cannot stat /proc/sys/net/bridge/bridge-nf-call-ip6tables: No such file or directory
sysctl: cannot stat /proc/sys/net/bridge/bridge-nf-call-iptables: No such file or directory
解决方法:
[root@docker-100 ~]# modprobe br_netfilter
[root@docker-100 ~]# sysctl -p /etc/sysctl.d/docker.conf
重启后模块失效,下面是开机自动加载模块的脚本

在/etc/新建 rc.sysinit 文件
cat /etc/rc.sysinit
#!/bin/bash
for file in /etc/sysconfig/modules/*.modules ; do
[ -x $file ] && $file
done
在/etc/sysconfig/modules/目录下新建文件如下
cat /etc/sysconfig/modules/br_netfilter.modules
modprobe br_netfilter
增加权限
chmod 755 br_netfilter.modules
重启机器模块也会自动加载
[root@localhost ~]# lsmod |grep br_netfilter
br_netfilter 22209 0
bridge 136173 1 br_netfilter

注:
Docker 安装后出现:WARNING: bridge-nf-call-iptables is disabled 的解决办法:
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1: 将 Linux 系统作为路由或者 VPN 服务就必须要开启 IP 转发功能。当 linux 主机有多个网卡时一个
网卡收到的信息是否能够传递给其他的网卡 如果设置成 1 的话 可以进行数据包转发 可以实现VxLAN 等功能。不开启会导致 docker 部署应用无法访问。
#重启 docker
[root@docker-100 ~]# systemctl restart docker
搜索镜像
[root@docker-100 ~]# docker search centos #默认从 Docker Hub 中搜索镜像。
下载镜像
方法 1:从 docker hub 上下载镜像
[root@docker-100 ~]# docker pull centos
Using default tag: latest
Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: TLS
handshake timeout
#报错了,因为网络的问题。 无法连接到 dockerhub 下载镜像。 如果你的网络没有问题,你可以下载。
解决:可以换种方法下载镜像
方法 2:配置镜像加速器
tee /etc/docker/daemon.json << EOF

"registry-mirrors":["https://rsbud4vc.mirror.aliyuncs.com","https://registry.docker-cn.com","https://docker.mirrors.ustc.edu.cn","https://dockerhub.azk8s.cn","http://hub-mirror.c.163.com","http://qtid6917.mirror.aliyuncs.com","https://rncxm540.mirror.aliyuncs.com","https://e9yneuy4.mirror.aliyuncs.com"]

EOF
重启 docker 服务使配置生效
[root@docker-100 ~]# systemctl daemon-reload && systemctl restart docker

[root@docker-100 ~]# docker pull centos
docker.io/library/centos:latest
[root@docker-100 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 5d0da3dc9764 6 months ago 231MB

方法3:把之前下载好的镜像通过 docker load -i 解压出来

[root@docker-100 ~]# docker load -i centos-7.tar.gz 
174f56854903: Loading layer [==================================================>] 211.7MB/211.7MB
Loaded image: centos:7
[root@docker-100 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 5d0da3dc9764 6 months ago 231MB
centos 7 8652b9f0cb4c 17 months ago 204MB

注意:把镜像打成离线包
[root@docker-100 ~]# docker save -o centos_7_2022.tar.gz centos:latest
查看镜像列表
#列出本地所有镜像。
[root@docker-100 ~]# docker image
删除镜像

[root@docker-100 ~]# docker rmi -f 5d0da3dc9764
[root@docker-100 ~]# docker load -i centos_7_2022.tar.gz
74ddd0ec08fa: Loading layer [==================================================>] 238.6MB/238.6MB
Loaded image: centos:latest
You have new mail in /var/spool/mail/root
[root@docker-100 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
centos latest 5d0da3dc9764 6 months ago 231MB
centos 7 8652b9f0cb4c 17 months ago 204MB

镜像打标签:
[root@docker-100 ~]# docker tag centos:latest centos:v1

1.3 通过 docker 部署应用

1.3.1 基于镜像启动容器
[root@docker-100 ~]# docker run -d -p 80:80 nginx
注:
-d 在后台运行 ;
-i 以交互模式运行容器,通常与 -t 同时使用;
-t 为容器重新分配一个伪输入终端,通常与 -i 同时使用;
-p 物理机的 80 端口:容器实例的 80 端口 ,把容器中的 80 端口映射到物理机上的80 端口在物理机上查看容器状态:

[root@docker-100 ~]# docker ps

CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2dc383edf47b nginx "/docker-entrypoint.…" 4 seconds ago Up 2 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp zealous_cartwright

停掉 docker 容器
[root@docker-100 ~]# docker stop 2dc383edf47b
查看所有,包括停止的容器
[root@docker-100 ~]# docker ps -a
1.3.2 访问正在运行的容器
语法: docker exec -it <container id | name> /bin/bash
查看正在运行的容器 ID:

[root@docker-100 ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
2dc383edf47b nginx "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 0.0.0.0:80->80/tcp, :::80->80/tcp zealous_cartwright

#进入容器
[root@docker-100 ~]# docker exec -it 2dc383edf47b /bin/bash
1.3.3 查看物理机和容器的网络
查看容器的 IP:
root@2dc383edf47b:~# apt update
root@2dc383edf47b:~# apt install net-tools -y
root@2dc383edf47b:~# ifconfig

root@2dc383edf47b:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.17.0.2 netmask 255.255.0.0 broadcast 172.17.255.255

物理机的 IP:
[root@docker-100 ~]# ip ad

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
inet 192.168.116.100/24 brd 192.168.116.255 scope global noprefixroute eth0
3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue
inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0

注:相当于虚拟机的 NAT 网络模式
测试物理机能否访问 docker 运行的容器:
[root@docker-100 ~]# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.4: icmp_seq=1 ttl=64 time=0.414 ms
停止容器
[root@docker-100 ~]# docker stop 2dc383edf47b
扩展:Docker 网络:
Docker 有四种网络模式
(1)bridge:这是 Docker 默认的网络驱动,此模式会为每一个容器分配 Network Namespace和设置 IP 等,并将容器连接到一个虚拟网桥上。如果未指定网络驱动,这默认使用此驱动
(2)host:此网络驱动直接使用宿主机的网络。
(3)none:此驱动不构造网络环境。采用了 none 网络驱动,那么就只能使用 loopback 网络设
备,容器只能使用 127.0.0.1 的本机网络。
(4)container:这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信。
在默认情况,Docker 使用 bridge 网络模式,bridge 网络驱动的示意图如下,此文以 bridge 模式对 Docker 的网络进行说明
1、bridge 网络的构建过程如下
1)安装 Docker 时,创建一个名为 docke0 的虚拟网桥,虚拟网桥使用“10.0.0.0 -
10.255.255.255 “、”172.16.0.0-172.31.255.255″和“192.168.0.0-192.168.255.255”这三个私有网络的地址范围。
通过 ifconfig 命令可以查看 docker0 网桥的信息:
通过 docker network inspect bridge 可以查看网桥的子网网络范围和网关:
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
2)运行容器时,在宿主机上创建虚拟网卡 veth pair 设备,veth pair 设备是成对出现的,从而组成一个数据通道,数据从一个设备进入,就会从另一个设备出来。将 veth pair 设备的一端放在新创建的容器中,命名为 eth0;另一端放在宿主机的 docker0 中,以 veth 为前缀的名字命名。通过 brctl show 命令查看放在 docker0 中的 veth pair 设备
#安装 brctl
[root@docker-100 ~]# yum install bridge-utils -y
[root@docker-100 ~]# ifconfig
[root@docker-100 ~]# brctl show
2、 外部访问
bridge 的 docker0 是虚拟出来的网桥,因此无法被外部的网络访问。因此需要在运行容器时通过- p 和-P 参数对将容器的端口映射到宿主机的端口。实际上 Docker 是采用 NAT 的 方式,将容器内部的服务监听端口与宿主机的某一个端口 port 进行绑定,使得宿主机外部可以将网络报文发送至容器。
1)通过-P 参数,将容器的端口映射到宿主机的随机端口:
[root@docker-100 ~]# docker run -P images
2)通过-p 参数,将容器的端口映射到宿主机的制定端口:
[root@docker-100 ~]# docker run -p hostPort:containerPort images
#docker 运行的时候指定网络模式
--net

1.4 基于 dockerfile 构建镜像

1.4.1编写 dockerfile
[root@docker-100 ~]# mkdir dockerfile
[root@docker-100 ~]# cd dockerfile/
[root@docker-100 dockerfile]# vim dockerfile

FROM centos:centos7.9.2009  #如果不指定版本号默认下载的是centos8
MAINTAINER yy
RUN yum install wget -y
#需要下载Nginx的源,否则yum install nginx会报错
RUN rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
RUN yum install nginx -y
COPY index.html /usr/share/nginx/html/
EXPOSE 80
ENTRYPOINT ["/usr/sbin/nginx","-g","daemon off;"]

[root@docker-100 dockerfile]# vim index.html
#写入如下内容

<html>

<head>
<title>page added to dockerfile</title>
</head>

<body>

<h1>welcome to docker dockerfile </h1>

</body>
</html>

#基于上面的 dockerfile 构建镜像
[root@docker-100 dockerfile]# docker build -t="docker/nginx:v2" .
[root@docker-100 dockerfile]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
docker/nginx v2 234e859a999a 7 seconds ago 567MB

注:--name html 给容器起个名字,-p 80 容器端口,33333物理机端口

[root@xuegod62 dockerfile]# docker run -d -p 33333:80 --name html docker/nginx:v2
44aef4d001ca84ef06e0f04ab4d7e785de19326cf38a43929d9e6a738ab82866
[root@xuegod62 dockerfile]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
44aef4d001ca docker/nginx:v2 "/usr/sbin/nginx -g …" 2 seconds ago Up 2 seconds 0.0.0.0:33333->80/tcp, :::33333->80/tcp html
[root@xuegod62 dockerfile]# curl 192.168.116.100:33333


<h1>welcome to docker dockerfile </h1>


以上是关于docker安装和dockerfile 构建镜像的主要内容,如果未能解决你的问题,请参考以下文章

docker----安装初步使用构建镜像Dockerfile编写通过Dockerfile文件封装nginx镜像并优化

004Docker学习__Dockerfile_build命令构建docker镜像

Docker安装部署(镜像构建)-执行Dockerfile

使用dockerfile构建docker镜像

07-docker系列-使用dockerfile构建pythonjenkins镜像

Docker教程-9-构建镜像并上传到DockerHub仓库