1
votes

Summary

I have a flask application deployed to Kubernetes with python 2.7.12, Flask 0.12.2 and using requests library. I'm getting a SSLError while using requests.session to send a POST Request inside the container. When using requests sessions to connect to a https url , requests throws a SSLError

Some background

  • I have not added any certificates
  • The project works when I run a docker image locally but after deployment to kubernetes, from inside the container - the post request is not being sent to the url verify=false does not work either

System Info - What I am using: Python 2.7.12, Flask==0.12.2, Kubernetes, python-requests-2.18.4

Expected Result

Get HTTP Response code 200 after sending a POST request

Error Logs

r = adapter.send(request, **kwargs)
File "/usr/local/lib/python2.7/site-packages/requests/adapters.py", line 511, in send
raise SSLError(e, request=request)
SSLError: HTTPSConnectionPool(host='dev.domain.nl', port=443): Max retries exceeded with url: /ingestion?LrnDevEui=0059AC0000152A03&LrnFPort=1&LrnInfos=TWA_100006356.873.AS-1-135680630&AS_ID=testserver&Time=2018-06-22T11%3A41%3A08.163%2B02%3A00&Token=1765b08354dfdec (Caused by SSLError(SSLEOFError(8, u'EOF occurred in violation of protocol (_ssl.c:661)'),))

/usr/local/lib/python2.7/site-packages/urllib3/connectionpool.py:858: InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised. See: https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings InsecureRequestWarning)

Reproduction Steps

import requests
from flask import Flask, request, jsonify
from requests import Request, Session

sess = requests.Session()
adapter = requests.adapters.HTTPAdapter(max_retries = 200)
sess.mount('http://', adapter)
sess.mount('https://', adapter)
sess.cert ='/usr/local/lib/python2.7/site-packages/certifi/cacert.pem'


def test_post():
    url = 'https://dev.domain.nl/ingestion/?'
    header = {'Content-Type': 'application/json', 'Accept': 'application/json'}
    response = sess.post(url, headers= header, params= somepara, data= json.dumps(data),verify=True)
    print response.status_code
    return response.status_code

def main():
    threading.Timer(10.0, main).start()
    test_post()

if __name__ == '__main__':
    main()
    app.run(host="0.0.0.0", debug=True, port=5001, threaded=True)

Docker File

FROM python:2.7-alpine
COPY ./web /web
WORKDIR /web
RUN pip install -r requirements.txt

ENV FLASK_APP app.py

EXPOSE 5001
EXPOSE 443

CMD ["python", "app.py"]
1
When you say that project works locally do you mean you run code from your workstation or you build Docker container and run this Docker container from workstation? - lexsys
Could you please publish the Dockerfile you use to build the container image? - lexsys
"EOF occurred in violation of protocol" - looks like the server has closed the connection for unknown reason which means the client can not continue. Maybe you'll find the reason if you look more closely at the server side (error logs etc) instead of only at the client. - Steffen Ullrich
@lexsys Included the docker file above. Yes, the project runs on a local flask setup on localhost:5001/flask - StarJedi
@CloudJedi try to reproduce problem running Docker container locally. I guess the problem is in the Alpine image that has no CA certificates installed not in k8s itself - lexsys

1 Answers

0
votes

The problem may be in the Alpine Docker image that lacks CA certificates. On your laptop code works as it uses CA certs from you local workstation. I would think that running Docker image locally will fail too - so the problem is not k8s.

Try to add the following line to the Dockerfile:

RUN apk update && apk add ca-certificates && rm -rf /var/cache/apk/*

It will install CA certs inside the container.