I have a local Kubernetes cluster on a single machine, and I successfully deployed a flask web app using apache server, so there shouldn't be any problem with the cluster setup. However, I need to upgrade the website to https, so I used letsencrypt
to generate ssl certificates and volume mapped them into the container. I also successfully deployed the app without docker, i.e. directly start the apache server using sudo /usr/sbin/apache2ctl -D FOREGROUND
. I can visit my website at https://XXX.XXX.XXX.edu
without problem.
However, when I started putting everything into Docker and Kubernetes, and visited https://XXX.XXX.XXX.edu:30001
, the browser gave me this error:
This site can’t be reached
XXX.XXX.XXX.edu took too long to respond
Here is how I deployed:
I first started the service kubectl create -f web-service.yaml
:
apiVersion: v1
kind: Service
metadata:
name: web
labels:
name: web
role: "ssl-proxy"
spec:
type: NodePort
ports:
- nodePort: 30001
name: "https"
port: 443
targetPort: 443
protocol: "TCP"
- nodePort: 30000
name: "http"
port: 80
targetPort: 80
protocol: "TCP"
selector:
name: web
role: "ssl-proxy"
Then I started the pod kubectl create -f web-controller.yaml
:
apiVersion: v1
kind: ReplicationController
metadata:
labels:
name: web
name: web-controller
spec:
replicas: 1
selector:
name: web
template:
metadata:
labels:
name: web
spec:
containers:
- image: XXX/web_app
command: ['/bin/sh', '-c']
args: ['sudo a2enmod ssl && service apache2 restart && sudo /usr/sbin/apache2ctl -D FOREGROUND && python fake.py']
name: web
ports:
- containerPort: 443
name: http-server
volumeMounts:
- mountPath: /etc/letsencrypt/live/host
name: test-volume
readOnly: false
volumes:
- hostPath:
path: /etc/letsencrypt/archive/XXX.XXX.XXX.edu
name: test-volume
The log of the pod looks like:
root@XXX:~# kubectl logs web-controller-ontne
Considering dependency setenvif for ssl:
Module setenvif already enabled
Considering dependency mime for ssl:
Module mime already enabled
Considering dependency socache_shmcb for ssl:
Module socache_shmcb already enabled
Module ssl already enabled
* Restarting web server apache2
[Mon Jun 27 14:34:48.753153 2016] [so:warn] [pid 30:tid 140046645868416] AH01574: module ssl_module is already loaded, skipping
...done.
[Mon Jun 27 14:34:49.820047 2016] [so:warn] [pid 119:tid 139909591328640] AH01574: module ssl_module is already loaded, skipping
httpd (pid 33) already running
root@XXX:~#
The pod is running, but I got the following apache error log:
[Mon Jun 27 17:13:50.912683 2016] [ssl:warn] [pid 33:tid 140513871427456] AH01909: RSA certificate configured for 0.0.0.0i:443 does NOT include an ID which matches the server name
I think the problem is that, I am using NodePort and exposing port 30001, so I have to visit https://XXX.XXX.XXX.edu:30001
which does not match XXX.XXX.XXX.edu
(just the domain name without the arbitrary port number 30001).
This is my /etc/apache2/sites-available/000-default.conf
in the docker container:
<VirtualHost _default_:30001>
DocumentRoot /usr/local/my_app
LoadModule ssl_module /usr/lib64/apache2-prefork/mod_ssl.so
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/host/cert1.pem
SSLCertificateKeyFile /etc/letsencrypt/live/host/privkey1.pem
SSLCertificateChainFile /etc/letsencrypt/live/host/chain1.pem
WSGIDaemonProcess python-app user=www-data group=www-data threads=15 maximum-requests=10000 python-path=/usr/local/lib/python2.7/dist-p
ackages
WSGIScriptAlias / /usr/local/my_app/apache/apache.wsgi
WSGIProcessGroup python-app
CustomLog "|/usr/bin/rotatelogs /usr/local/my_app/apache/logs/access.log.%Y%m%d-%H%M%S 5M" combined
ErrorLog "|/usr/bin/rotatelogs /usr/local/my_app/apache/logs/error.log.%Y%m%d-%H%M%S 5M"
LogLevel warn
<Directory /usr/local/my_app>
Order deny,allow
Allow from all
Require all granted
</Directory>
</VirtualHost>
How to modify it so that apache serves https requests at port 30001 rather than 443? Thank you very much!
I just run into this issue this morning.
I expose the employment using --type=NodePort
I can access it from either
http://<pod ip>:<target port>
http://<cluster IP>: <port>
But I can not access it from
http://<Node IP>:< NodePort>
The Chrome say: .... took too long to respond
I check pod's status. It is ready and running
Later I fixed it by: delete the deployment and service.
--type=NodePort
I find now the pod is running on another node. I check
http://<new Node IP>:< new NodePort>
It works
I do not know what is the reason. Just guess:
I found the answer myself. 2 causes: (1) There is an environment variable specific to my web app that I forgot to set in apache.wsgi
; (2) There are several small errors in the original apache configuration file. I post the working /etc/apache2/sites-available/000-default.conf
here:
ServerName 0.0.0.0
<VirtualHost _default_:443>
DocumentRoot /usr/local/my_app
LoadModule ssl_module /usr/lib64/apache2-prefork/mod_ssl.so
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/host/cert1.pem
SSLCertificateKeyFile /etc/letsencrypt/live/host/privkey1.pem
SSLCertificateChainFile /etc/letsencrypt/live/host/chain1.pem
WSGIDaemonProcess python-app user=www-data group=www-data threads=15 maximum-requests=10000 python-path=/usr/local/lib/python2.7/dist-packages
WSGIScriptAlias / /usr/local/my_app/apache/apache.wsgi
WSGIProcessGroup python-app
CustomLog "|/usr/bin/rotatelogs /usr/local/my_app/apache/logs/access.log.%Y%m%d-%H%M%S 5M" combined
ErrorLog "|/usr/bin/rotatelogs /usr/local/my_app/apache/logs/error.log.%Y%m%d-%H%M%S 5M"
LogLevel warn
<Directory /usr/local/my_app>
Order deny,allow
Allow from all
Require all granted
</Directory>
</VirtualHost>
Start the pod with commands sudo a2enmod ssl && sudo /usr/sbin/apache2ctl -D FOREGROUND
, and containerPort
should be 443. The Kubernetes script for the service is as simple as follows:
apiVersion: v1
kind: Service
metadata:
name: web
labels:
name: web
spec:
type: NodePort
ports:
- nodePort: 30001
port: 443
targetPort: 443
protocol: TCP
selector:
name: web
Now I can visit my web site at https://XXX.XXX.XXX.XXX:30001
.
Special thanks to the owner of this github repo and NorbertvanNobelen. Hope this helps!