zoukankan      html  css  js  c++  java
  • docker4-nginx容器*springboot

    docker运行nginx容器

    快速安装运行

    • docker-hub文档
      https://hub.docker.com/_/nginx
    • 拉取nginx1.6.0 docker pull nginx:1.16.0
    • 快速运行 docker run --name mynginx -d -p 80:80 ae893c58d83f
    • 外部访问80端口验证

    关键文件目录挂载

    • 进入容器内部查看配置目录 docker exec -it mynginx /bin/bash
      默认的关键目录位置:
      • 主(配置)目录 /etc/nginx
      • 页面目录 /usr/share/nginx/html
      • 日志目录 /var/log/nginx
    • 新运行容器,挂载上面目录容器数据卷
      docker run --name mynginx -d -p 80:80 
      -v /usr/local/dcv/nginx/html:/usr/share/nginx/html 
      -v /usr/local/dcv/nginx/conf:/etc/nginx 
      ae893c58d83f    
      
    • 运行失败:

      本地fs有挂载目录,但是 docker ps 没有记录。
      查看容器运行日志 docker logs mynginx :
      2019/09/05 03:03:46 [emerg] 1#1: open() "/etc/nginx/nginx.conf" failed (2: No such file or directory)
      nginx: [emerg] open() "/etc/nginx/nginx.conf" failed (2: No such file or directory)
      容器内目录原有的东西被外部fs同步覆盖清空了..=_=

    • 解决:先从容器拷贝出需要的信息,然后子目录挂载
      • 先简单运行一个容器,从其中拷贝出配置文件和页面的目录文件
        //运行容器
        docker run --name mynginx -d -p 80:80 ae893c58d83f
        docker ps
        //本地fs建立相关目录
        mkdir -p /usr/local/dcv/nginx/conf
        mkdir -p /usr/local/dcv/nginx/html
        mkdir -p /usr/local/dcv/nginx/log
        //从容器内copy文件和目录到宿主机
        docker cp mynginx:/etc/nginx/nginx.conf /usr/local/dcv/nginx/conf
        docker cp mynginx:/etc/nginx/conf.d /usr/local/dcv/nginx/conf
        docker cp mynginx:/usr/share/nginx/html /usr/local/dcv/nginx
        docker cp mynginx:/var/log/nginx /usr/local/dcv/nginx/log
        //移动外部日志目录
        cp -rf $(pwd)/log/nginx/* $(pwd)/log
        rm -rf $(pwd)/log/nginx
        
      • 重新挂载运行
        docker rm -f mynginx
        //新挂载运行一个容器
        docker run --name mynginx -d -p 80:80 
        -v /usr/local/dcv/nginx/html:/usr/share/nginx/html 
        -v /usr/local/dcv/nginx/log:/var/log/nginx 
        -v /usr/local/dcv/nginx/conf/nginx.conf:/etc/nginx/nginx.conf 
        -v /usr/local/dcv/nginx/conf/conf.d:/etc/nginx/conf.d 
        ae893c58d83f
        //验证
        docker ps
        
      • 宿主机修改index.html 外部访问81验证效果

    nginx容器代理宿主机的springboot服务(即tomcat)

    简单的springboot包

    • 新建一个极简的springboot应用,只有一个/hello接口返回JSON串,其他默认
      @RestController
      public class HellowCtrller {
      	@ResponseBody
      	@RequestMapping("/hello")
      	public String hello() {
      		return "hello docker @" + LocalDateTime.now();
      	}
      }
      
    • cmd到pom.xml目录,mvn package 打jar包,上传宿主机hello.jar
    • 宿主机运行hello.jar nohup java -jar hello-0.0.1-SNAPSHOT.jar &
    • 宿主机8080访问验证 curl http://localhost:8080/hello,OK

    nginx代理配置

    • nginx容器内访问宿主机ip的问题
      • 直接在nginx容器内配置localhost:8080是访问不到外部tomcat的
      • 因为nginx容器有自己的ip,外部使用 docker inspect mynginx可以看到如下信息:
        "Gateway": "172.17.0.1",
        "GlobalIPv6Address": "",
        "GlobalIPv6PrefixLen": 0,
        "IPAddress": "172.17.0.2",
        "IPPrefixLen": 16,
        "IPv6Gateway": "",
        "MacAddress": "02:42:ac:11:00:02",
        "Networks": {
            "bridge": {
                "IPAMConfig": null,
                "Links": null,
                "Aliases": null,
                "NetworkID": "77b4c6b988b085d697f896ec4d19493294c0296dc99e20e6492b2cf79d7a6682",
                "EndpointID": "3933c9ccb7de29d19d82247bd1c0b4a5ed971e505fdce4455acb0df3d48a64b1",
                "Gateway": "172.17.0.1",
                "IPAddress": "172.17.0.2",
                "IPPrefixLen": 16,
                "IPv6Gateway": "",
                "GlobalIPv6Address": "",
                "GlobalIPv6PrefixLen": 0,
                "MacAddress": "02:42:ac:11:00:02",
                "DriverOpts": null
            }
        }
        
      • 其中的IPAddress就是容器自己的ip,Gateway则是外部docker安装是产生的虚拟网关docker0,外部使用 ip addr可以看到。
      • 通过docker0的地址(即上面Gateway地址),容器内可以访问宿主机
      • docker0网关的地址值在Linux上一般是固定的172.17.0.1,Mac系统则不同,移植时需要注意下。
    • 修改/usr/local/dcv/nginx/conf/conf.d下的 default.conf
      #后端负载集群
      upstream hello_server {
      	ip_hash; #session绑定节点
      	server 172.17.0.1:8080 weight=1;
      	#server 172.17.0.1:8081 weight=1;
      	#keepalive 100; #for长连接
      }
      server {
          listen       80;
          server_name  localhost;
      
          #charset koi8-r;
          #access_log  /var/log/nginx/host.access.log  main;
      
          location / {
              root   /usr/share/nginx/html;
              index  index.html index.htm;
          }
      
          location /api/ {
              proxy_pass http://hello_server/;
              #for 后端获取远程客户端真实ip
              proxy_set_header Host $host;
              proxy_set_header X-Real-IP $remote_addr;
              proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
              #自定义添加header
              #proxy_set_header applicationto blog;
              #proxy_http_version 1.1;
      
              #for后端返回状态拦截 >> 后端404自定义错误页面
              #proxy_intercept_errors on;
          }
          #error_page  404              /404.html;
      	# redirect server error pages to the static page /50x.html
          #
          error_page   500 502 503 504  /50x.html;
      	location = /50x.html {
              root   /usr/share/nginx/html;
          }
      }
      
    • nginx容器内验证配置+重启
      docker exec -t mynginx nginx -t
      docker exec -t mynginx nginx -s reload
      
    • 外部访问验证 curl http://localhost/api/hello

    nginx容器代理springboot容器服务

    制作springboot镜像运行

    • 简单的DockerFile文件(为方便名字就叫DockerFile)
      FROM java:8
      add hello-0.0.1-SNAPSHOT.jar app.jar
      expose 8080
      entrypoint ["java","-jar","/app.jar"]
      
    • build该文件为镜像 hello_img docker build -t hello_img .
    • 运行两个hello容器 端口分别8080和8081
      docker run -d --name hello1 -p 8080:8080 hello_img
      docker run -d --name hello2 -p 8081:8080 hello_img
      
    • 访问两个hello容器服务
      curl http://localhost:8080/hello
      curl http://localhost:8081/hello
      

    nginx配置代理访问hello容器

    • 运行nginx容器时使用 docker run 的--link参数传递hello容器ip
    • 重新运行mynginx容器
      //停掉
      docker stop mynginx
      docker rm mynginx
      //加--link运行
      docker run --name mynginx 
      --link=hello1:hello1ip --link=hello2:hello2ip 
      -v /usr/local/dcv/nginx/html:/usr/share/nginx/html 
      -v /usr/local/dcv/nginx/log:/var/log/nginx 
      -v /usr/local/dcv/nginx/conf/nginx.conf:/etc/nginx/nginx.conf 
      -v /usr/local/dcv/nginx/conf/conf.d:/etc/nginx/conf.d 
      -p 80:80 -d ae893c58d83f
      //查看
      docker ps
      
    • 修改 default.conf 中的后端负载集群配置
      upstream hello_server {
      	ip_hash; #session绑定节点
      	server hello1ip:8080 weight=1;
      	server hello2ip:8081 weight=1;
      	#keepalive 100; #for长连接
      }
      
    • 验证重启nginx
      docker exec -t mynginx nginx -t
      docker exec -t mynginx nginx -s reload
      
    • 外部访问验证 curl http://localhost/api/hello OK!

    碰到的问题

    外部访问虚拟机的springboot8080端口

    关掉防火墙:
    直接关闭防火墙: systemctl stop firewalld.service
    禁止firewall开机启动: systemctl disable firewalld.service
    重启docker(不然后面可能有问题):systemctl restart docker

    容器内无法使用ping

    apt-get update
    apt install iputils-ping #for ping
    //apt install net-tools #for ifconfig

    容器中nginx访问日志问题

    • docker logs mynginx 命令 stdout 出来的时间不对
    • 原因:原生容器系统的时区为0时期,而国内系统为东八区,相差8小时
    • 其他容器估计也会有这个问题
    • 解决,关键要使容器时区和宿主机一致
      主参考:https://blog.lqdev.cn/2018/07/15/docker/docker-time-diff/
      1. 运行容器时挂载宿主机的时区 -v /etc/localtime:/etc/localtime:ro
      2. 运行后cp宿主机的时区到容器 docker cp /etc/localtime mynginx:/etc/localtime
        执行出错=_=:具体原因还不知道,应该是容器内已经有的文件/夹不能通过docker cp覆盖。。还是使用第一种挂载吧
        Error response from daemon: Error processing tar file(exit status 1): invalid symlink "/usr/share/zoneinfo/UCT" -> "../usr/share/zoneinfo/Asia/Shanghai"
      3. 使用DockerFile,生产上,建议有一个base_image,里面直接定义好时区等信息,后面的from base_img构建官方镜像,DockerFile待有时间单独整理文章。

    感受

    • 咔咔咔一顿操作下来(DockerFile待深入),使用体验并没有预期的辣么爽。
    • 环境一层套一层,碰到问题和疑惑也就多了一个层次,在细节效果配置时难免会碰到一些壁垒(比如nginx更复杂的配置),解决下来的时间成本不小。
    • 所以,在公司或者个人开发上没有docker刚需时,不用急着整治,但是整套环境打包镜像,解决换环境又得重新安装、环境配置的烦恼还是很爽的(比如mysql)。
  • 相关阅读:
    数据库被黑后留下的数据
    cron(CronTrigger)表达式用法
    nodeJS常用的定时执行任务的插件
    css实现隐藏滚动条
    iOS
    iOS
    iOS
    iOS
    iOS
    iOS
  • 原文地址:https://www.cnblogs.com/noodlerkun/p/11477545.html
Copyright © 2011-2022 走看看