[Kubernetes] Nginx HTTPs 서버 구성하기
✔️ Nginx HTTPs 서버 구성
nginx 관련 파일은 다음과 같다.
vagrant@k8s-node1 ~/configure/nginx-https kubectl run nginx --image nginx
pod/nginx created
vagrant@k8s-node1 ~/configure/nginx-https kubectl exec -it nginx -- bash
root@nginx:/# cd /usr/share/nginx/html/
root@nginx:/usr/share/nginx/html# ls
50x.html index.html
root@nginx:/usr/share/nginx/html# cd /etc/nginx
root@nginx:/etc/nginx# ls
conf.d fastcgi_params mime.types modules nginx.conf scgi_params uwsgi_params
- Documentation Root :
/usr/share/nginx/html/
- Configuration File :
/etc/nginx/conf.d
vagrant@k8s-node1 ~/configure/nginx-https ls
conf x509
conf
에는 https를 사용하기 위한 설정이 들어가며 x509
에는 인증서가 있어야 한다.
vagrant@k8s-node1 ~/configure/nginx-https cat conf/nginx-tls.conf
server {
listen 80;
listen 443 ssl; # ssl 기능을 킨다.
server_name myapp.example.com;
ssl_certificate /etc/nginx/ssl/tls.crt; # 인증서의 위치
ssl_certificate_key /etc/nginx/ssl/tls.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
root /usr/share/nginx/html; # Documentation Root
index index.html;
}
}
해당 파일을 configMap
으로 만들어 파드에 제공하면 된다.
인증서를 만들어줘야 하는데 인증서는 비용이 들고 현재 테스트 환경이므로 SSC(Self Signed Certificate)
: 자체 서명 인증서를 사용한다.
✔️ 인증서 생성 과정
vagrant@k8s-node1 ~/configure/nginx-https/x509 openssl genrsa -out nginx-tls.key 2048
Generating RSA private key, 2048 bit long modulus (2 primes)
.....................................+++++
.................................................................+++++
e is 65537 (0x010001)
openssl
을 사용하여 private key를 만들어준다.
vagrant@k8s-node1 ~/configure/nginx-https/x509 openssl rsa -in nginx-tls.key -pubout -out nginx-tls
writing RSA key
private key 파일을 넣어서 public key를 만들어준다.
vagrant@k8s-node1 ~/configure/nginx-https/x509 openssl req -new -key nginx-tls.key -out nginx-tls.csr
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [AU]:KR
State or Province Name (full name) [Some-State]:Seoul
Locality Name (eg, city) []:Seoul
Organization Name (eg, company) [Internet Widgits Pty Ltd]:Sohui Inc.
Organizational Unit Name (eg, section) []:IT
Common Name (e.g. server FQDN or YOUR name) []:www.sohui.com
Email Address []:skysohe@naver.com
Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
vagrant@k8s-node1 ~/configure/nginx-https/x509 ls
nginx-tls nginx-tls.csr nginx-tls.key
CSR (Certificate Signing Request)
: 인증서 서명 요청 파일을 Let's encrypt로 보내거나 또는 서명할 수 있는 기관에 보낸다.
인증서에 LDAP Distinguished Name
을 표시해서 인증서가 누구의 것인지 표시한다.
vagrant@k8s-node1 ~/configure/nginx-https/x509 openssl req -x509 -days 3650 -key nginx-tls.key -in nginx-tls.csr -out nginx-tls.crt
vagrant@k8s-node1 ~/configure/nginx-https/x509 ls
nginx-tls nginx-tls.crt nginx-tls.csr nginx-tls.key
자체 서명을 한다. nginx-tls.crt
인증서는 자체 서명을 했으므로 보안상 문제가 있다.
이제 설정 파일을 configMap
으로 만들고 서명 인증서는 secret
으로 등록해야 한다.
- nginx-tls.conf
- nginx-tls.key
- nginx-tls.crt
kubernetes.io/tls
시크릿 타입을 사용해야 한다.kubernetes.io/tls
: TLS 클라이언트나 서버를 위한 데이터
apiVersion: v1
kind: Secret
metadata:
name: secret-tls
type: kubernetes.io/tls
data:
# 본 예시를 위해 축약된 데이터임
tls.crt: |
MIIC2DCCAcCgAwIBAgIBATANBgkqh ...
tls.key: |
MIIEpgIBAAKCAQEA7yn3bRHQ5FHMQ ...
YAML 파일 구조는 다음과 같을 것이다.
✔️ 리소스 생성
configMap
생성nginx-tls-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
name: nginx-tls-config
data:
nginx-tls.conf: |
server {
listen 80;
listen 443 ssl;
server_name myapp.example.com;
ssl_certificate /etc/nginx/ssl/tls.crt;
ssl_certificate_key /etc/nginx/ssl/tls.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
root /usr/share/nginx/html;
index index.html;
}
}
secret
생성nginx-tls-secret.yaml
apiVersion: v1
kind: Secret
metadata:
name: nginx-tls-secret
type: kubernetes.io/tls
data:
# base64 x509/nginx-tls.crt -w 0 # 파일 인코딩
tls.crt: |
LS0tLS1C...
# base64 x509/nginx-tls.key -w 0
tls.key: |
LS0tLS1C...
base64
로 인코딩한 값을 넣어준다.
파드 생성nginx-https-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx-https-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: nginx-config
mountPath: /etc/nginx/conf.d
- name: nginx-certs
mountPath: /etc/nginx/ssl
volumes:
- name: nginx-config
configMap:
name: nginx-tls-config
- name: nginx-certs
secret:
secretName: nginx-tls-secret
nginx-config
설정 파일을 가져가서 /etc/nginx/conf.d
에 마운팅 시킨다.nginx-certs
는 /etc/nginx/ssl
에 마운팅 시킨다.
서비스 생성nginx-svc-lb.yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-svc-lb
spec:
type: LoadBalancer
selector:
app: nginx
ports:
- name: http
port: 80
targetPort: 80
- name: https
port: 443
targetPort: 443
vagrant@k8s-node1 ~/configure/nginx-https kubectl get cm
NAME DATA AGE
kube-root-ca.crt 1 9d
mymessage 1 30h
nginx-tls-config 1 14s
vagrant@k8s-node1 ~/configure/nginx-https kubectl describe cm nginx-tls-config
Name: nginx-tls-config
Namespace: default
Labels: <none>
Annotations: <none>
Data
====
nginx-tls.conf:
----
server {
listen 80;
listen 443 ssl;
server_name myapp.example.com;
ssl_certificate /etc/nginx/ssl/tls.crt;
ssl_certificate_key /etc/nginx/ssl/tls.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
location / {
root /usr/share/nginx/html;
index index.html;
}
}
BinaryData
====
Events: <none>
vagrant@k8s-node1 ~/configure/nginx-https kubectl get secret
NAME TYPE DATA AGE
default-token-h87sc kubernetes.io/service-account-token 3 9d
mydata Opaque 2 29h
nfs-client-provisioner-token-xzr7h kubernetes.io/service-account-token 3 31h
nginx-tls-secret kubernetes.io/tls 2 69s
vagrant@k8s-node1 ~/configure/nginx-https kubectl describe secret nginx-tls-secret
Name: nginx-tls-secret
Namespace: default
Labels: <none>
Annotations: <none>
Type: kubernetes.io/tls
Data
====
tls.crt: 1432 bytes
tls.key: 1679 bytes
vagrant@k8s-node1 ~/configure/nginx-https kubectl get pod
NAME READY STATUS RESTARTS AGE
nfs-client-provisioner-758f8cd4d6-wpjbt 1/1 Running 0 31h
nginx-https-pod 0/1 ContainerCreating 0 2s
모든 리소스가 정상적으로 생성됐음을 확인한다.
vagrant@k8s-node1 ~/configure/nginx-https curl -k https://192.168.100.241
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
자체 서명 인증서를 사용했으므로 curl
로 테스트하기 위해서는 -k
옵션을 붙여서 요청한다.
nginx의 기본 페이지를 응답하는 것을 확인할 수 있다.
인증서의 LDAP DN을 확인할 수 있다.