第52天-Docker-apline与网络资源限制

1.基于alpine和ubuntu镜像构建nginx镜像

1.2、安装alpine镜像

下载alpine
# docker pull alpine:3.13

进入镜像
sh    只有sh
# dr run -it --rm alpine sh

alpine 装包命令
#  apt add 

1.3、nginx镜像制作


下载alpine
# docker pull alpine:3.13

进入镜像
sh    只有sh
# dr run -it --rm alpine sh

alpine 装包命令
#  apt add 
 
 
基于官方alpine基础镜像制作自定义nginx镜像:
========================================
添加alpine配置目录
# cd /opt/dockerfile/system/ &&  mkdir  alpine  && cd alpine 
# cd /opt/dockerfile/system/alpine

构建Dockerfile文件
# vim  Dockerfile
FROM alpine
maintainer zhuzikang  "985848343@qq.com"
COPY repositories /etc/apk/repositories
RUN apk update && apk add iotop gcc libgcc libc-dev libcurl libc-utils pcre-dev zlib-dev libnfs make pcre pcre2 zip unzip net-tools pstree wget libevent libevent-dev iproute2   openssl openssl-dev
ADD nginx-1.16.1.tar.gz /opt/
RUN cd /opt/nginx-1.16.1 && ./configure --prefix=/apps/nginx && make && make install && ln -sv /apps/nginx/sbin/nginx /usr/bin/
I
RUN addgroup -g 2021 -S nginx && adduser -s /sbin/nologin -S -D -u 2021 -G nginx nginx
#COPY nginx.conf /apps/nginx/conf/nginx.conf
#ADD static.tar.gz /data/nginx/html
#RUN chown nginx.nginx /data/nginx/ /apps/nginx/ -R
EXPOSE 80 443
CMD ["nginx"]

构建build_command.sh启动文件
# vim build_command.sh
#!/bin/bash
docker build -t harbor.jackie.net/alpine-nginx:v1.18.0  .


拷出容器镜像加速文件repositories 
# dr run -it --rm alpine sh

进入容器修改:
/ # sed -i 's/dl-cdn.alpinelinux.org/mirrors.tuna.tsinghua.edu.cn/g' /et
c/apk/repositories   # 替换为清华源
/ # apk update       # 更新一下源信息

容器外拷贝:
# cd /opt/dockerfile/system/alpine
# dr cp e30bed0704c2:/etc/apk/repositories  .

测试结果
/ # cat /etc/apk/repositories
# cat repositories 
https://mirrors.tuna.tsinghua.edu.cn/alpine/v3.13/main
https://mirrors.tuna.tsinghua.edu.cn/alpine/v3.13/community
 

拷贝出并修改容器内生成的nginx.conf配置文件
# cd /opt/dockerfile/system/alpine
# dr cp 9b583644d17e:/apps/nginx/conf/nginx.conf    .
# vim nginx.conf 
user  nginx;           #修改用户
#pid        logs/nginx.pid;
daemon off;                             #关闭后台,直接在前台执行
      location / {
            root  /data/nginx/html;     #修改代码存放目录
            index  index.html index.htm;
        }


构建代码目录static
# mkdir static && cd  static &&   echo  static  page\njackie come  > index.html
# tar czvf static.tar.gz  static/  && mv static.tar.gz  ../


构建镜像
# bash    build_command.sh
测试结果
# dr  run  -it --rm harbor.jackie.net/alpine-nginx:v1.18.0  sh
# ls -l /apps/nginx/
# ls -l /apps/nginx/sbin/
# dr run -it --rm -p 80:80 harbor.jackie.net/alpine-nginx:v1.18.0  
http://172.31.7.16/1.png
http://172.31.7.16/



基于官方ubuntu基础镜像制作自定义nginx镜像:
=======================================
# cd /opt/dockerfile/system/ubuntu/
# cp ../alpine/nginx-1.18.0.tar.gz  .
# cp ../alpine/static.tar.gz  .
# cp ../alpine/nginx.conf  .
# cp ../alpine/build_command.sh  .



构建Dockerfile镜像
FROM ubuntu:18.04
maintainer zhuzikang "985848343@qq.com"
COPY sources.list  /etc/apt/sources.list
RUN apt update && apt install -y iproute2 ntpdate tcpdump telnet traceroute nfs-kernel-server nfs-common lrzsz tree  openssl libssl-dev libpcre3 libpcre3-dev zlib1g-dev  ntpdate tcpdump telnet traceroute gcc openssh-server lrzsz tree openssl libssl-dev libpcre3 libpcre3-dev zlib1g-dev ntpdate tcpdump telnet traceroute  iotop unzip zip make && touch /tmp/linux.txt
ADD  nginx-1.18.0.tar.gz /usr/local/src
RUN cd /usr/local/src/nginx-1.18.0  &&  ./configure --prefix=/apps/nginx  && make && make install && ln -sv /apps/nginx/sbin/nginx  /usr/bin && rm -rf /usr/local/src/nginx-1.18.0  &&  rm -rf /usr/local/src/nginx-1.18.0.tar.gz
ADD nginx.conf  /apps/nginx/conf/nginx.conf
ADD static.tar.gz  /data/nginx/html
RUN groupadd -g 2021 nginx && useradd -g nginx -s  /usr/sbin/nologin -u 2021 nginx  && chown -R nginx.nginx /apps/nginx  /data/nginx/html
EXPOSE 80 443
CMD ["nginx"]
     

测试结果
# dr run -it --rm -p 80:80 harbor.jackie.net/ubuntu-nginx:v1.18.0
172.31.7.16/1.png
172.31.7.16/


2.Docker网络-上

2.1、创建自定义别名

4.2:容器之间的互联:
4.2.1∶通过容器名称互联:
即在同一个宿主机上的容器之间可以通过自定义的容器名称相互访问,比如一个业务前端静态页面是使用nginx,动态页面使用的是tomcat,由于容器在启动的时候其内部IP地址是DHCP随机分配的,所以如果通过内部访问的话,自定义名称是相对比较固定的,因此比较适用于此场景。
docker run -d  --name 新容器名称  --link目标容器名称:自定义的名称
-p 本地端口:容器端口 镜像名称  shell命令


此方式最少需要两个容器之间操作:


172.31.6.101
-------------
tomcat容器
先创建第一个容器,后续会使用到这个容器的名称:
[root@ubuntu ~]# docker run -it -d --name zhgedu-tomcat-app1 harbor.jackie.com/tomcat-app1:app1

2.1.1、nginx访问tomcat

容器之间通过容器名称或者自定义别名实现互联,仅仅限于单机docker主机使用,不能夸主机,使用场景比较少

172.31.6.101
------------
nginx容器
通过link实现同宿主机下的容器互相访问:
[root@ubuntu ~]# docker run -it -d -p 80:80 --link zhgedu-tomcat-app1 harbor.jackie.net/alpine-nginx:v1.18.0 

进入nginx容器中查看生成结果
[root@ubuntu ~]# docker exec -it  bd5556a72231  sh
/ # cat /etc/hosts
127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::0	ip6-localnet
ff00::0	ip6-mcastprefix
ff02::1	ip6-allnodes
ff02::2	ip6-allrouters
172.17.0.2	zhgedu-tomcat-app1 8574c8498c30       #连接的对方容器ID和容器名称
172.17.0.3	bd5556a72231

/ # ping zhgedu-tomcat-app1       测试访问tomcat容器的联通性
/ # apk add curl                  #添加curl命令
(1/1) Installing curl (7.77.0-r1)
Executing busybox-1.32.1-r6.trigger
OK: 192 MiB in 74 packages         安装成功
/ # curl http://zhgedu-tomcat-app1:8080/myapp/index.jsp     访问tomcat容器中结果
<h1> jackie tomcat app1 web1 </h1>

实现访问转发
/ # vim /apps/nginx/conf/nginx.conf
    #gzip  on;
upstream web {                 -------> 主要配置
  server zhgedu-tomcat-app1:8080;   ------> 主要配置
}                                    
    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;
        
/ # /apps/nginx/sbin/nginx -s reload

2.1.2、修改自定义别名

创建tomcat容器别名
# docker run -it -d --name zhgedu-tomcat-app1-m43 harbor.jackie.com/tomcat-app1:app1

创建nginx容器别名
# docker run -it -d -p 80:80 --link zhgedu-tomcat-app1-m43:zhgedu-tomcat-app1-m43  harbor.jackie.net/alpine-nginx:v1.18.0

[root@ubuntu ~]# docker exec -it a375b54cf4e7 sh
/ # vi /apps/nginx/conf/nginx.conf
    #gzip  on;
upstream web {                 -------> 主要配置
  server zhgedu-tomcat-app1:8080;   ------> 主要配置
}                                    
    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;
        
/ #  /apps/nginx/sbin/nginx -s reload

2.2、docker网络

2.2.0、docker网络基本配置

[root@ubuntu ~]# docker network --help
Docker 的网络使用docker network ls命令看到有三种类型,下面将介绍每一种类型的具体工作方式:
Bridge模式,使用参数 -net=bridge指定,不指定默认就是bridge模式。
#查看当前docke的网卡信息:

查看当前docker的网卡信息
# docker network list
NETWORK ID          NAME                DRIVER              SCOPE
a72e99d7fabe        bridge              bridge              local
75bfa55942fc        host                host                local
7d10eac7ecec        none                null                local

系统优化
[root@ubuntu ~]# vim /etc/sysctl.conf 
[root@ubuntu ~]# sysctl -p
net.ipv4.ip_forward = 1

查看docker0的详细信息
[root@ubuntu ~]# apt-get install bridge-utils

2.2.1、指定桥接网络类型

默认docker创建网络模式

指定网络类型
[root@ubuntu ~]# dr run -it --net=bridge  harbor.jackie.net/alpine-nginx:v1.18.0 sh 可以不用加,是默认的模式

桥接网络分配地址
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> 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
20: eth0@if21: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:04 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.4/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever

2.2.2、指定host网络类型

容器不会创建网络堆栈信息,而是直接使用宿主机的网络堆栈进行通信,
优势: 是不需要docker0网桥进行报文转发所以性能比较强,通常用于对网络性能要求比较高的业务,比如mysql/kafka/redis/大数据业务。
缺点: 就是会在宿主机直接监听端口,可能出现端口冲突等问题。

指定host网络类型
[root@ubuntu ~]# docker run -it --rm  --net=host -p 80:80 harbor.jackie.net/alpine-nginx:v1.18.0 sh

容器共用宿主机地址
/ # ip a
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:0c:29:cf:db:f2 brd ff:ff:ff:ff:ff:ff
    inet 172.31.6.101/21 brd 172.31.7.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fecf:dbf2/64 scope link 
       valid_lft forever preferred_lft forever

2.2.3、指定none模式网络类型

[root@docker-server1 ~]# docker run -it  --net=none  harbor.jackie.net/alpine-nginx:v1.18.0 sh

指定在容器本身通信
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> 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

3.Docker网络-中

3.1.1、指定container网络

Container模式,使用参数-net=container:名称或ID指定。
使用此模式创建的容器需指定和一个已经存在的容器共享一个网络,
而不是和宿主机共享网,新创建的容器不会创建自己的网卡也不会配置自己的IP,而是和一个已经存在的被指定的容器东西IP和端口范围,因此这个容器的端口不能和被指定的端口冲突,除了网络之外的文件系统、进程信息等仍然保持相互隔离,
两个容器的进程可以通过lo网卡及容器IP进行通信。

创建一个以存在的网络
[root@docker-server1 ~]# dr run -it -d harbor.jackie.net/alpine-nginx:v1.18.0 
[root@docker-server1 ~]# dr exec -it b5c3dc28a85c sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> 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
22: eth0@if23: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:04 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.4/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever


与容器使用相同的数据信息
[root@ubuntu ~]# dr run -it --net=container:b5c3dc28a85c php:5.6.34 sh
# ip a
1: lo: <LOOPBACK,UP,LOWER_UP> 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
22: eth0@if23: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:04 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.4/16 brd 172.17.255.255 scope global eth0    ---->和上面nginx容器使用相同的ip信息
       valid_lft forever preferred_lft forever

4.Docker网络-下

4.1、创建自定义docker网络

docker network create -d  bridge  --subnet 172.28.0.0/24  --gateway 172.28.0.1 zhgedu-net-m43

创建自定义docker网络
[root@docker-server1 ~]# docker network list
NETWORK ID          NAME                DRIVER              SCOPE
261189b92c70        bridge              bridge              local
75bfa55942fc        host                host                local
7d10eac7ecec        none                null                local
98962faa4884        zhgedu-net-m43      bridge              local

4.1.1、删除自定义网络

# docker network rm 98962faa4884  

4.1.2、查资源详情

# dr inspect 6d5edc9b273a

4.2、创建自定义网络的容器

docker run -it  --rm  --net=zhgedu-net-m43  harbor.jackie.net/alpine-nginx:v1.18.0  sh

查看自定义网络
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> 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
6: eth0@if7: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:1c:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.28.0.2/24 brd 172.28.0.255 scope global eth0     ----->自定义网络
       valid_lft forever preferred_lft forever

查看网路走向
/ # traceroute 223.6.6.6
traceroute to 223.6.6.6 (223.6.6.6), 30 hops max, 46 byte packets
 1  172.28.0.1 (172.28.0.1)  0.007 ms  0.010 ms  0.006 ms
 2  172.31.7.254 (172.31.7.254)  0.010 ms  0.159 ms  0.010 ms
 
 查看网桥名称
 [root@docker-server1 ~]# brctl show
bridge name	bridge id		STP enabled	interfaces
br-6d5edc9b273a		8000.0242bec7df9f	no		veth8f45b36
docker0		8000.0242602c1203	no	

指定一个桥接网络
docker run -it --rm --net=bridge  harbor.jackie.net/alpine-nginx:v1.18.0 sh

4.2.1、查看iptable规则

# iptables -t nat -vnL
Chain PREROUTING (policy ACCEPT 42 packets, 2912 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    6   368 DOCKER     all  --  *      *       0.0.0.0/0            0.0.0.0/0            ADDRTYPE match dst-type LOCAL

Chain INPUT (policy ACCEPT 9 packets, 956 bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 16 packets, 1244 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DOCKER     all  --  *      *       0.0.0.0/0           !127.0.0.0/8          ADDRTYPE match dst-type LOCAL

Chain POSTROUTING (policy ACCEPT 17 packets, 1328 bytes)
 pkts bytes target     prot opt in     out     source               destination         
   25  1398 MASQUERADE  all  --  *      !br-6d5edc9b273a  172.28.0.0/24        0.0.0.0/0           
    0     0 MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0           

Chain DOCKER (2 references)
 pkts bytes target     prot opt in     out     source               destination         
    1    84 RETURN     all  --  br-6d5edc9b273a *       0.0.0.0/0            0.0.0.0/0           
    0     0 RETURN     all  --  docker0 *       0.0.0.0/0            0.0.0.0/0           

4.2.2、导出iptables规则

[root@docker-server1 ~]# iptables-save >  1.txt

[root@docker-server1 ~]# vim   1.txt
#-A DOCKER-ISOLATION-STAGE-2 -o br-6d5edc9b273a -j DROP     ----->注释iptables规则
#-A DOCKER-ISOLATION-STAGE-2 -o docker0 -j DROP             ----->注释iptables规则

4.2.3、导入iptables规则

[root@docker-server1 ~]# iptables-restore < 1.txt 

4.3、Overlay介绍

overlay网络:叠加网络或者覆盖网络,在物理网络的基础之上叠加实现新的虚拟网络,
即可使网络的中的容器可以相互通信:
VxLAN: VxLAN全称是Visual extensible Local Area Network(虚拟扩展本地局域网),主要有Cisco推出,vxlan是一个VLAN 的扩展协议,使用MAC in UDP的方法对报文进行重新封装。
VxLAN 本质上是一种overlay的隧道封装技术,它将L2的以太网帧封装成L4的UDP数据报,然后在L3的网络中传输,效果就像L2的以太网模在一个广播域中传输一样,

在容器的mac地址与源地址,在容器的上一层在封装一层宿主机的mac地址与源地址

5.Docker资源限制-上

5.1、解决不支持swap限制警告

[root@docker-server1 ~]# vim /etc/default/grub
GRUB_DEFAULT=0
GRUB_TIMEOUT_STYLE=hidden
GRUB_TIMEOUT=2
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT=""
GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0 cgroup_enable=memory swapaccount=1"   ---->主要配置

[root@docker-server1 ~]# update-grub
[root@docker-server1 ~]# reboot

5.2、解决java程序内存溢出问题

OOM (Out of Memory Exception,内存溢出、内存泄漏、内存异常),随后系统会开始杀死进程以释放内存,凡是运行在宿主机的进程都有可能被kill,包括Dockerd和其它的应用程序,如果重要的系统进程被Kill,会导致和该进程相关的服务全部宕机。
产生OOM异常时,Dockerd尝试通过调整Docker守护程序上的OOM优先级来减轻这些风险,以便它比系统上的其他进程更不可能被杀死,但是容器的OOM优先级未调整,这使得单个容器被杀死的可能性比 Docker守护程序或其他系统进程被杀死的可能性更大,不推荐通过在守护程序或容器上手动设置--oom-score-adj为极端负数,或通过在容器上设置--oom-kill-disable来绕过这些安全措施。

ooM优先级机制:
linux会为每个进程算一个分数,最终他会将分数最高的进程kill。
/proc/PID/oom_score_adj #范围为-1000到1000,值越高越容易被宿主机kill掉,如果将该值设置为-1000,则进程永远不会被宿主机 kernel kill。

/proc/PID/oom_adj   #范围为-17到+15,取值越高越容易被干掉,如果是-17,则表示不能被kill,该设置参数的存在是为了和旧版本的 Linux内核兼容。

/proc/PID/oom_score #这个值是系统综合进程的内存消耗量、CPU时间(utime + stime)、存活时间(uptime - start time)和 oom_adj计算出的进程得分,消耗内存越多得分越高,越容易被宿主机 kernel强制杀死。

[root@docker-server1 ~]# dr run -it -d -p 80:80 harbor.jackie.net/alpine-nginx:v1.18.0 

[root@docker-server1 ~]# ps -ef | grep nginx
root       1396   1379  0 10:50 pts/0    00:00:00 nginx: master processnginx
2021       1441   1396  0 10:50 pts/0    00:00:00 nginx: worker process
root       1444   1298  0 10:50 pts/0    00:00:00 grep --color=auto nginx

默认此进程值为0
[root@docker-server1 ~]# cat /proc/1396/oom_adj                旧版本
[root@docker-server1 ~]# cat /proc/1396/oom_score_adj          新版本
0

5.3、内存限制参数

内存限制参数:
-m or --memory   #容器可以使用的最大内存量,如果设置此选项,则允许的最小存值为4m(4兆字节)。
 
--memory-swap    #容器可以使用的交换分区大小,必须要在设置了物理内存限制的前提才能设置交换分区的限制

--memory-swappiness #设置容器使用交换分区的倾向性,值越高表示越倾向干使用swaD 分区。范围为0-100.0为能不用就不用.100为能用就用。

--oom-kill-disable  #对某个容器关闭oom机制。

设置内存限制
[root@docker-server1 ~]# docker run -it --rm -m 4m  harbor.jackie.net/alpine-nginx:v1.18.0 

5.3.1、设置交换分区限制

隐藏算法:
真正的交换分区:  612 - 512  = 100 
[root@docker-server1 ~]# docker run -it --rm -m 512m --memory-swap 612m harbor.jackie.net/alpine-nginx:v1.18.0
posted @ 2024-03-08 11:32  Jackiezhu  阅读(110)  评论(0)    收藏  举报