docker学习(3)之docker网络


内容来源为六星教育,这里仅作为学习笔记

lnrp环境构建

构建镜像

nginx的dockerfile

FROM centos:centos7 
RUN mkdir /data && mkdir /conf 
RUN groupadd -r nginx && useradd -r -g nginx nginx 
#修改时区 RUN cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && echo 'Asia/Shanghai' >/etc/timezone 
ARG PHP_VERSION=7.2 
#添加centos源(先下载wget) 
COPY ./epel-7.repo /etc/yum.repos.d/epel.repo 
#COPY 
#RUN yum install -y wget 
#RUN wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/Centos-7.repo 
RUN yum update -y \ 
	&& yum clean all \ 
	&& yum makecache \ 
	&& yum -y install gcc gcc-c++ autoconf automake make zlib zlib-devel net-tools openssl* pcre* wget \ 
	&& yum clean all && rm -rf /var/cache/yum/* 
	
#声明匿名卷 
VOLUME /data 

COPY ./nginx-1.14.1.tar.gz /data/nginx-1.14.1.tar.gz 

RUN cd /data \ 
	&& tar -zxvf nginx-1.14.1.tar.gz \ 
	&& cd nginx-1.14.1 \ 
	&& ./configure --prefix=/usr/local/nginx --user=nginx --group=nginx \ 
	&& make && make install && rm -rf /data/nginx-1.14.1.tar.gz && rm -rf /data/nginx-1.14. 

COPY ./conf/nginx.conf /conf 
#全局使用nginx,软链接 
RUN ln -s /usr/local/nginx/sbin/* /usr/local/sbin 

#进入容器时默认打开的目录 
WORKDIR /conf 

#声明端口 
EXPOSE 80 

#容器启动的时候执行,在docker run过程当中是会被其他指令替代 
#CMD ["/usr/local/nginx/sbin/nginx","-c","/conf/nginx.conf","-g","daemon off;"] 

#执行一条指 
# ENTRYPOINT ["/usr/local/nginx/sbin/nginx","-c","/conf/nginx.conf","-g","daemon off;"]

php的dockerfile

FROM php:7.3-fpm-alpine 
# Version
ENV PHPREDIS_VERSION 4.0.0 
# Libs 
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories \ 
	&& apk add \ 
		curl \ 
		vim \ 
		wget \ 
		git \ 
		openssl-dev\ 
		zip \ 
		unzip \ 
		g++ make autoconf 
# docker方式安装PDO extension 
# 安装扩展 
RUN mv "$PHP_INI_DIR/php.ini-production" "$PHP_INI_DIR/php.ini" \ 
	&& docker-php-ext-install pdo_mysql \ 
	&& docker-php-ext-install pcntl \ 
	&& docker-php-ext-install sysvmsg

# Redis extension 
RUN wget http://pecl.php.net/get/redis-${PHPREDIS_VERSION}.tgz -O /tmp/redis.tar.tgz \ 
	&& pecl install /tmp/redis.tar.tgz \ 
	&& rm -rf /tmp/redis.tar.tgz \ 
	&& docker-php-ext-enable redis 
# 修改php.ini的文件 extension=redis.so 
EXPOSE 9000 
#设置工作目录 
WORKDIR /www

redis的dockerfile

FROM centos:centos7 
RUN groupadd -r redis && useradd -r -g redis redis 
RUN mkdir data ;\ 
	yum update -y ; \ 
	yum -y install gcc automake autoconf libtool make wget epel-release gcc-c++; 
COPY ./redis-5.0.7.tar.gz redis-5.0.7.tar.gz 
RUN mkdir -p /usr/src/redis; \ 
	tar -zxvf redis-5.0.7.tar.gz -C /usr/src/redis; \ 
	rm -rf redis-5.0.7.tar.gz; \ 
	cd /usr/src/redis/redis-5.0.7 && make ; \ 
	cd /usr/src/redis/redis-5.0.7 && make install 

COPY ./conf/redis.conf /usr/src/redis/redis-5.0.7/redis.conf 
EXPOSE 6379 
ENTRYPOINT ["redis-server", "/usr/src/redis/redis-5.0.7/redis.conf"]

或者直接 docker pull redis:6.0-rc-alpine

构建镜像跳过

在这里插入图片描述

构建构建容器

保存容器的数据卷

[root@localhost /]# mkdir docker 
[root@localhost /]# mkdir docker/images 
[root@localhost /]# mkdir docker/images/data/ 
[root@localhost /]# mkdir docker/images/data/php 
[root@localhost /]# mkdir docker/images/data/nginx 
[root@localhost /]# mkdir docker/images/data/redis 
[root@localhost /]# mkdir docker/images/data/php/www 
[root@localhost /]# mkdir docker/images/data/nginx/conf

构建容器
在这里插入图片描述

配置连接测试

注意redis.conf配置文件

#bind 127.0.0.1 
protected-mode no

注意nginx.conf配置文件

user root; 
worker_processes 1; 
events { 
	worker_connections 1024; 
}
http {
	default_type application/octet-stream; 
	log_format main '$remote_addr - $remote_user [$time_local] "$request" ' 
					'$status $body_bytes_sent "$http_referer" ' 
					'"$http_user_agent" "$http_x_forwarded_for"'; 
	sendfile 	on; 
	keepalive_timeout 65; 
	server {
		listen 80; 
		access_log /usr/local/nginx/logs/$host main; 
		location / { 
			root /www; 
			default_type text/html; 
		}
		location ~ \.php/?.* { 
				default_type text/html; 
				#做php-fpm 配置,注意地址 
				root /www; 
				#php-fpm容器当中的路径,不是nginx容器路径 
				fastcgi_index index.php; 
				fastcgi_pass 172.17.0.2:9000; #php容器端口 
				#为php-fpm指定的根目录
				fastcgi_param SCRIPT_FILENAME $DOCUMENT_ROOT$fastcgi_script_name; 
				#注意是容器当中的位置 
				#定义变量 $path_info ,用于存放pathinfo信息 
				set $path_info ""; 
				if ($fastcgi_script_name ~ "^(.+?\.php)(/.+)$") { 
					#将文件地址赋值给变量 $real_script_name 
					set $real_script_name $1; 
						#将文件地址后的参数赋值给变量 $path_info 
						set $path_info $2; 
				}
				#配置fastcgi的一些参数 
				fastcgi_param SCRIPT_NAME $real_script_name; 
				fastcgi_param PATH_INFO $path_info; 
				include /usr/local/nginx/conf/fastcgi_params; 
		} 
		error_page 500 502 503 504 /50x.html; 
		location = /50x.html { 
			root html;
		} 
	} 
}

需要注意的是nginx.conf中的 fastcgi_pass 172.17.0.2:9001; #php容器端口 这行配置
中的 172.17.0.2 是宿主机ip
对应的PHP文件放置于: /docker/images/data/php/www
index.php文件内容:

<?php 
$redis = new Redis(); 
$redis->connect('192.168.169.160', 6379);//serverip port 
$redis ->set( "test" , "Hello World"); 
echo $redis ->get( "test"); 
?>

注意访问的地址是 http://192.168.169.160:81/index.php 需要带上 index.php

docker文件结构

  1. 为什么系统镜像那么小呢? 因为docker镜像在运行的时候直接使用docker宿主机器的kernel,Linux操作系统由内核空间和用户空间组成

在这里插入图片描述
内核空间是kernel,用户空间是rootfs, 不同Linux发行版的区别主要是rootfs.比如 Ubuntu 14.04 使用 upstart 管理服务,apt 管理软件包; 而 CentOS 7 使用 systemd 和 yum。这些都是用户空间上的区别,Linux kernel 差别不大。所以 Docker 可以同时支持多种 Linux 镜像, 模拟出多种操作系统环境。

  1. 镜像文件是分层存储的,我们可以通过docker history 命令查看到镜像的历史,也就是层

在这里插入图片描述
启动镜像的时候,一个新的可写层会加载到镜像的顶部。这一层通常称为“容器层”, 之下是“镜像层”。 容器层可以读写,容器所有发生文件变更写都发生在这一层。镜像层read-only,只允许读取。
在这里插入图片描述
Container最上面是一个可写的容器层,以及若干只读的镜像层组成,Container的数据就存放在这些层中,这样的分层结构最大的特性是Copy-OnWrite(写时复制):

  1. 新数据会直接存放在最上面的Container层。
  2. 修改现有的数据会先从Image层将数据复制到容器层,修改后的数据直接保存在Container层,Image层保持不变。
  1. 启动的容器会占用大量空间吗

创建镜像的时候,分层可以让docker只保存我们添加和修改的部分内容。其他内容基于base镜像,不需要存储,读取base镜像即可。如此,当我 们创建多个镜像的时候,所有的镜像共享base部分。节省了磁盘空间
docker通过一个叫做copy-on-write (CoW) 的策略来保证base镜像的安全性,以及更高的性能和空间利用率
简单的说,启动容器的时候,最上层容器层是可写层,之下的都是镜像层,只读层。

当容器需要读取文件的时候: 
	从最上层镜像开始查找,往下找,找到文件后读取并放入内存,若已经在内存中了,直接使用。(即,同一台机器上运行的docker容器共享 运行时相同的文件)。 
当容器需要添加文件的时候: 
	直接在最上面的容器层可写层添加文件,不会影响镜像层。 
当容器需要修改文件的时候: 
	从上往下层寻找文件,找到后,复制到容器可写层,然后,对容器来说,可以看到的是容器层的这个文件,看不到镜像层里的文件。容器在 容器层修改这个文件。 
当容器需要删除文件的时候: 
	从上往下层寻找文件,找到后在容器中记录删除。即,并不会真正的删除文件,而是软删除。综上,Docker镜像通过分层实现了资源共享,通过copy-on-write实现了文件隔离。

docker网络模式

docker安装后,默认会创建下面三种网络类型
在这里插入图片描述
可以通过 --network bridge 指定网络类型

bridge:桥接网络

默认情况下启动的Docker容器,都是使用 bridge,Docker安装时创建的桥接网络,每次Docker容器重启时,会按照顺序获取对应的IP地址,这个就导致重启下,Docker的IP地址就变
在这里插入图片描述
从上面的网络模型可以看出,容器从原理上是可以与宿主机乃至外界的其他机器通信的。同一宿主机上,容器之间都是连接掉docker0这个网桥上的,它可以作 为虚拟交换机使容器可以相互通信。然而, 由于宿主机的 IP地址与容器的IP地址均不在同一个网段,不足以使宿主机以外的网络主动发现容器的存在。为了使外 界可以方位容器中的进程,docker采用了端口绑定的方式,也就是通过iptables的NAT, 将宿主机上的端口端口流量 转发到容器内的端口上
在宿主机上,可以通过iptables -t nat -L -n,查到一条DNAT规则:
bridge模式的容器与外界通信时,必定会占用宿主机上的端口,从而与宿主机竞争端口资源,对宿主机端口的管理会是一个比较大的问题。同时,由于容 器与外界通信是基于三层上iptables NAT,性能和效率上的损耗是 可以预见的

none

无指定网络 使用 --network=none ,docker 容器就不会分配局域网的IP

host

主机网络 使用 --network=host,此时,Docker 容器的网络会附属在主机上,两者是互通的。 例如,在容器中运行一个Web服务,监听8080端口,则主 机的8080端口就会自动映射到容器中
在这里插入图片描述
弊端:

1)最明显的就是容器不再拥有隔离、独立的网络栈。容器会与宿主机竞争网络栈的使用,并且容器的崩溃就可能导致宿主机崩溃,在生产环境中,这种 问题可能是不被允许的。
2)容器内部将不再拥有所有的端口资源,因为一些端口已经被宿主机服务、bridge模式的容器端口绑定等其他服务占用掉了

指定自定义网络

因为默认的网络不能制定固定的地址,所以我们将创建自定义网络,并指定网段:192.168.1.0/24 并命名为mynetwork,指令如下:

~ docker network create --subnet=192.160.1.0/24 mynetwork 
~ docker run -itd --network=redis-network --ip 192.168.1.10 --name dockerName imagesName
~ docker network ls 
~ docker network rm mynetwork

注意:这个网络段不要和宿主机的网络端冲突,不然会容易对宿主机产生影响

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值