zoukankan      html  css  js  c++  java
  • 【Azure 应用服务】由Web App“无法连接数据库”而逐步分析到解析内网地址的办法(SQL和Redis开启private endpoint,只能通过内网访问,无法从公网访问的情况下)

    问题描述

    在Azure上创建的数据库,单独通过SQL的连接工具是可以访问,但在Web App却无法访问,错误信息为: 

    {
        "timestamp": "2021-05-20T05:21:04.672+0000",
        "status": 500,
        "error": "Internal Server Error",
        "message": "nested exception is org.apache.ibatis.exceptions.PersistenceException: 
    ### Error querying database.  
    Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection;
    nested exception is com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 60000, active 0, maxActive 100, creating 0
    ### The error may exist in com/digital/dao/SumOrderMapper.java (best guess)
    ### The error may involve com.digital.dao.SumOrderMapper.selectOne
    ### The error occurred while executing a query
    ### Cause: org.springframework.jdbc.CannotGetJdbcConnectionException: Failed to obtain JDBC Connection;
    nested exception is com.alibaba.druid.pool.GetConnectionTimeoutException: wait millis 60000, active 0, maxActive 100, creating 0", "path": "/ba/getGapAndOffset" }

    问题分析&解决

    一:分析从Web App到数据库的网络是否相通:使用 PsPing & PaPing 进行 TCP 端口连通性测试

    PsPing 是微软 PSTools 工具套件中的其中一个命令。除了ICMP ping 测试,它主要用来测试 TCP 端口的连通性,还可以测试 TCP/UDP 网络时延和带宽。下载地址为:https://technet.microsoft.com/zh-cn/sysinternals/jj729731.aspx

    PsPing 进行 TCP 连接测试时所支持的参数说明:

    -t 类似于 ICMP 的长 ping 测试,直到按下 Ctrl+C 停止测试,并显示统计结果;
    -n 指定测试次数。还可以指定测试的时间长度,以秒为单位,使用时在数字后加上 s,例如“10s”;
    -i 每次测试的间隔,默认为 1 秒。还可以指定为 0 来进行快速 ping 测试;
    -w 热身次数,默认为 1 次;
    -q 测试过程中不输出结果,结束后显示统计结果;
    -h 将时延结果统计为直方图打印(默认打印 20行),也可以指定结果行数,比如 -h 10,指定 10 行;另一种使用方法是统计自定义时延,比如 -h "65,70",结果将统计时延分别为 65 和 70 毫秒的次数;
    -4 强制使用 IPv4;
    -6 强制使用 IPv6;

    如果在 Linux 中发起 TCP 端口连通性和网路时延的测试,可以使用 PaPing 。PaPing 是一个跨平台的开源工具。它的功能相对 PsPing 而言更简单,只支持 TCP 端口的相关测试,不支持 UDP 端口的测试。下载地址为:https://code.google.com/archive/p/paping/downloads

    安装方式(Linux):

    #cd ~
    #wget https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/paping/paping_1.5.5_x86-64_linux.tar.gz
    #tar zxvf paping_1.5.5_x86-64_linux.tar.gz

    测试结果, 在App Service(Web App)上去paping数据库可以连通的,由此可见网络层面应该是可以通的。

    二:在网络层是连通的情况下,进一步就需要查看应用的异常信息

    在App Service(Web App)的应用日志中,发现了 “ ssl connection is required ” 的错误消息,这是因为数据库(PostgreSQL) 配置SSL的连接要求,而应用程序时运行在Linux环境Docker中,也是需要开启SSL的。而在Linux中为容器开启SSL,需要以下几步:

    注:SSH 实现容器和客户端之间的安全通信。 为了使自定义容器支持 SSH,必须将其添加到 Docker 映像本身。

    第一步:将 sshd_config 文件添加到项目文件中,示例内容如下
    Port            2222
    ListenAddress       0.0.0.0
    LoginGraceTime      180
    X11Forwarding       yes
    Ciphers aes128-cbc,3des-cbc,aes256-cbc,aes128-ctr,aes192-ctr,aes256-ctr
    MACs hmac-sha1,hmac-sha1-96
    StrictModes         yes
    SyslogFacility      DAEMON
    PasswordAuthentication  yes
    PermitEmptyPasswords    no
    PermitRootLogin     yes
    Subsystem sftp internal-sftp

    此文件配置 OpenSSH 并且必须包括以下项:

    • Port 必须设置为 2222。
    • Ciphers 必须至少包含此列表中的一项:aes128-cbc,3des-cbc,aes256-cbc
    • MACs 必须至少包含此列表中的一项:hmac-sha1,hmac-sha1-96
     
    第二步:在 Dockerfile 中,添加以下命令
    # Install OpenSSH and set the password for root to "Docker!". In this example, "apk add" is the install instruction for an Alpine Linux-based image.
    RUN apk add openssh 
         && echo "root:Docker!" | chpasswd 
    
    # Copy the sshd_config file to the /etc/ssh/ directory
    COPY sshd_config /etc/ssh/
    
    # Open port 2222 for SSH access
    EXPOSE 80 2222

    此配置不允许从外部建立到容器的连接。 容器的端口 2222 只能在专用虚拟网络的桥网络中访问,Internet 上的攻击者无法访问该端口。

     
    第三步:在容器的启动脚本中启动 SSH 服务器
     
    /usr/sbin/sshd

    三:App Service(Web App)如何能够解析内网中资源的Endpoint呢?

    由于在App Service(Web App)中无法解析Redis的Private Endpoint IP,所以无法连接Redis,由于Redis在开启Private Endpoint时也有创建Azure Private DNS Zone,所以需要在App Service配置使用Azure Private DNS Zone用于解析Redis Private E你的point。

    在App Service的配置中添加两项应用程序设置:

    WEBSITE_DNS_SERVER= 168.63.129.16 #Azure Private DNS Server IP Address

    WEBSITE_VNET_ROUTE_ALL=1 

    这些设置会将所有出站调用从应用发送到 VNet,还允许应用访问 Azure DNS 专用区域。配置使用Azure Private DNS Zone的官方文档:https://docs.azure.cn/zh-cn/app-service/web-sites-integrate-with-vnet#azure-dns-private-zones

     

    参考资料

    配置使用Azure Private DNS Zone: https://docs.azure.cn/zh-cn/app-service/web-sites-integrate-with-vnet#azure-dns-private-zones

    App service启用应用程序日志: https://docs.microsoft.com/zh-cn/azure/app-service/troubleshoot-diagnostic-logs#enable-application-logging-linuxcontainer

    PostgreSQL配置ssl: https://docs.azure.cn/zh-cn/postgresql/concepts-ssl-connection-security

    Paping测试连通性: https://docs.azure.cn/zh-cn/articles/azure-operations-guide/virtual-network/aog-virtual-network-tcp-psping-paping-connectivity#%E4%B8%8B%E8%BD%BD%E5%92%8C%E5%AE%89%E8%A3%85-1

    【完】

    当在复杂的环境中面临问题,格物之道需:浊而静之徐清,安以动之徐生。 云中,恰是如此!

  • 相关阅读:
    链堆栈的实现
    关于HyperLink的NavigateUrl属性的链接地址参数设置
    //yield return用于无缝实现迭代模式。
    NUnit的使用
    非常不错的数据访问架构
    Dictionary应用
    针对数据分析没态度的几句牢骚
    微软算法面试题(4)
    程序员面试题精选100题(60)判断二叉树是不是平衡的
    C++设计模式单件
  • 原文地址:https://www.cnblogs.com/lulight/p/14860033.html
Copyright © 2011-2022 走看看