쿠버네티스(애플리케이션 사용자화)
7.1 컨테이너 애플리케이션 사용자화
컨테이너에 있는 애플리케이션을 몇 가지 기능을 통해 사용자화 할 수 있다.
1) 이미지 사용자화
토거 이미지 작성 시 Dockerfile의 엔드포인트 및 CMD 지시어를 지정해 애플리케이션을 어떻게 동작할 것인지 지정할 수 있다
2) 환경 변수 사용자화
쉘 환경 변수를 전달해 사용자화 할 수 있다.
3) 컨피그 맵을 이용한 사용자화
키/값 저장소를 제공하며 컨테이너에 환경 변수나 사용자화 된 설정 파일kubectl create secret tls ingress-tls-secret --key=ingress-tls/ingress-tls.key --cert=ingress-tls/ingress-tls.crt
을 볼륨의 형태로 제공할 수 있다.
4) 시크릿을 이용한 사용자화
컨피그 맵과 같은 기능을 제공하지만, 패스워드나 암호화 키, 토큰 등 평문으로 제공되면 안 되는 민감정보를 저장하고, 환경변수나 볼륨형태로 안전하게 제공할 수 있다.
7.2 이미지 사용자화
2) 쿠버네티스에서 인수변경
Dokerfile에서 지정한 ENTRYPOINT 속성은, 쿠버네티스에서 컨테이너 정의시 command 속성으로 대체할 수 있고, CMD 속성은 쿠버네티스에서 arg 속성으로 대체할 수 있다.
다음은 인수를 변경해 서비스 포트를 변경하는 파드 오브젝트이다.
vim myapp-pod-arg.yaml

파드를 생성해보자
kubectl create -f myapp-pod-arg.yaml
메시지 변경을 확인하기 위해 포트 포워드를 설정한다.
kubectl port-forward myapp-pods-arg 8080:8088

호스트의 포트는 8080 포트이며, 컨테이너의 포트는 8088이다.
새 터미널을 실행시켜 웹 컨텐츠를 확인한다
curl http://localhost:8080
포트포워딩 되었으므로 변경된 포트로 접근할 수 있다

3) 리소스 삭제
kubectl delete -f myapp-pod-arg.yaml
7.3 환경 변수를 이용한 사용자화
쿠버네티스에서 환경 변수를 정의하려면 env 필드를 정의한다
1) 쿠버네티스 정의에서 환경 변수 설정
vim myapp-pod-env.yaml

파드를 생성
kubectl create -f myapp-pod-env.yaml
파드의 상세정보를 확인하면, Environment 필드에 설정된 환경 변수를 확인할 수 있다.
kubectl describe pod myapp-pod-env

확인을 위해 포트포워딩을 구성!! 포트는 호스트의 8080에서 컨테이너의 8080응로 포워딩 !!!!
kubectl port-forward myapp-pod-env 8080:8080
curl http://localhost:8080

변경된 메시지 확인 가능
2) 리소스 삭제
kubectl delete -f myapp-pod-env.yaml
7.4 컨피그 맵을 이용한 사용자화
간단한 설정, 변수, 설정 파일의 값을 키/값 쌍 형태로 저장하고 사용할 수 있는 쿠버네티스 저장소다.
설정값을 앞서본 환경변수나 명령의 인수로 제공할 수도 있고, 설정파일 및 간단한 파일을 저장했다가 볼륨으로 제공할 수도 있다.
1) 컨피그 맵 생성 및 확인
파드에게 제공할 포트 정보와 메시지 정보를 담은 파일을 생성한다.
mkdir configmap >>> configmap 디렉터리를 생성
configmap 디렉터리에 nodeport 파일과 message 파일을 생성한다.
echo "Hello World by ConfigMap" > configmap/message
해당 파일을 이용해 컨피그 맵을 생성해보자
kubectl create configmap myapp-message --from-file-configmap/message
디렉터리를 지정하면 하나의 컨피그 맵에 여러 키를 저장할 수 있다.
생성한 myapp-message 컨피그 맵을 확인해보자
kubectl get configmaps myapp-message
컨피그 맵에 등록된 키/값을 확인한다.
kubectl describe configmap myapp-message

3) 컨피그 맵을 참조하는 파드 생성
myapp-pod-options 컨피그 맵을 참조하는 파드 오브젝트 정의 파일이다.
vim myapp-pod-cm.yaml

.spec.containers.env : 환경변수
.spec.containers.env.valueFrom.configMapKeyRef : 컨피그 맵 리소스에서 키를 참조하여 매핑
- name : 컨피그 맵 리소스의 이름
- key : 키 이름
.spec.containers.args 필드
- 인수를 지정하는 필드
- $(MESSAGE)로 환경 변수를 참조하고 있다.
파드를 생성해보자
kubectl create -f myapp-pod-cm.yaml
확인을 위해 포트 포워딩 한다,
kubectl port-forward myapp-pod-cm 8080:8080

새로운 터미널에서 확인해보자
curl http://localhost:8080

MESSAGE 환경 변수에 의해 변경된 메시지를 확인할 수 있다!!
4) 컨피그 맵의 볼륨 사용
컨피그 맵에 설정 파일을 저장하고, 이를 볼륨으로 제공할 수 있다
1) 컨피그 맵서 사용할 설정파일
mkdir conf
conf/nginx-gzip.conf

Nginx 설정 파일로 기본 설정에 gzip 압출 기능을 활성화 했다
설정파일을 컨피그 맵으로 생성하자
kubectl create configmap nginx-gzip-config --from-file=conf/nginx-gzip.conf
컨피그 맵 내용 확인!! 파일명이 키가 된다!!

(2) 컨피그 맵을 볼륨으로 사용하는 파드 생성
vim nginx-pod-compress.yaml

nginx-gzip-config 컨피그 맵을 볼륨으로 선언하고 /etc/nginx/conf.d 디렉터리에 마운트!!!
/etc/nginx.conf : 기본 설정 파일
/etc/nginx/conf.d : 추가 설정 디렉터리
컨피그 맵을 볼륨으로 사용하는 파드를 생성하자
kubectl create -f nginx-pod-compress.yaml
파드의 상세정보를 확인해보자
kubectl desribe pod nginx-pod-compress

볼륨이 마운트 된것을 확인, 볼륨은 nginx-compress-config 컨피그 맵에 의해 제공된 것을 확인할 수 있다.
마지막으로 확인을 위해 포트포워딩 해보자
kubectl port-forward nginx-pod-compress 8080:80
curl -l http://localhost:8080apiVersion : networking.k8s.io/v1

5) 리소스 삭제
kubectl delete -f myapp-pod-cm.yaml -f nginx-pod-compress.yaml
7.5 시크릿을 이용한 사용자화
시크릿은 컨피그 맵과 같은 키/값 저장소!!!
차이점은 시크릿은 패스워드, 암호화 키/인증서, 토큰 등 소량의 민감 데이터를 저장하고 안전하게 제공될 수 있도록 만들어졌음
컨피그맵 : 단순데이터, 민감하지 않은 데이터 저장
시크릿 : 민감데이터, 데이터를 안전하게 저장하고 안전하게 참조할 수 있다는 차이
1) 시크릿 정의 및 확인
(1) 시크릿 저장 데이터 종류
직접 시크릿에 저장할 수 있는 주요 데이터 종류는 다음과 같다
- generic : 임의 데이터(기본)
- docker-registry : 도커 저장소 인증 정보
- tls : TLS 키 및 인증서
직접 시크릿에 사용 가능하지 않으느 시크릿 저장 데이터 종류
- service-account-token : 서비스 계정 토큰
kubectl get secrets에 표시되는 데이터 종류
- Opaque( = generic)
- kubernetes.io/dockerconfigjson
- kubernetes.io/tls
- kubernetes.io/service-account-token
(3) Base64 인코딩 및 디코딩
평문 데이터를 Base64로 인코딩 하여 데이터를 저장해보자
echo "sy0218" | base64 >>> sy0218텍스트를 Base64로 인코딩

echo "c3kwMjE4Cg==" | base64 --decode >>> base64로 인코딩된 데이터를 디코딩 해보기

(4) 시크릿 생성
시크릿에 저장할 파일을 생성해보자
id.txt, pwd.txt 파일을 secret 디렉터리에 생성
echo -n "sy0218" > id.txt
echo -n "cocooco" > pwd.txt
시크릿 생성( 데이터 종류는 일반(generic) 종류이다.)
kubectl create secret generic my-secret --from-file=id.txt --from-file=pwd.txt
(5) 시크릿 확인
생성된 my-secret 시크릿 리소스를 확인해보자
kubectl get secret my-secret

표시되는 종류는 Opaque이며 generic 형식을 의미한다.
저장된 리소스를 YAML 형식으로 확인!!
kubectl get secret my-secret -o yaml

평문 데이터가 Base64 인코딩 되어 저장된 것을 확인할수 있음
한번 직접 디코딩을 해보자
echo "c3kwMjE4" | base64 --decode
echo "Y29jb29jbw==" | base64 --decode

시크릿 리소스를 자세히 확인
kubectl describe secret my-secret

kubectl describe 명령에서는 데이터가 직접 표시되지 않고 크기만 표시된다!!!
(6) 오브젝트 파일을 이용한 시크릿 정의
yaml 형식의 오브젝트를 이용해 시크릿 정의 ㄱㄱㄱ
yaml 파일을 이용해 데이터를 저장시 직접 base64로 인코딩된 데이터를 정의해야됨 만약 평문으로 정의해서 시크릿 리소스를 생성하는 경우 base64로 인코딩 되지 않은 데이터가 있다고 오류를 보고함!!!(중요)
2) 기본 토큰 시크릿
쿠버네티스에서 모든 파드에는 기본적으로 토큰 시크릿이 적용되어 있음
시크릿 목록을 확인해보자
kubectl get secrets
3) 시크릿을 이용한 Nginx HTTPS 웹 서비스 제공
시크릿에 TLS 키 및 인증서를 저장하고 이를 파드에 제공해 Https를 제공하는 웹 서비스를 구성하자
(1) TLS 키 및 인증서 생성
키를 저장하기 위해 nginx-tls 디렉터리 생성
mkdir nginx-tls
HTTPS를 위한 TLS 키를 생성
openssl genrsa -out nginx-tls/nginx-tls.key 2048

생성된 것을 확인할 수 있다.
TLS 키를 이용하여 TLS 인증서를 생성한다.
openssl req -new -x509 -key nginx-tls/nginx-tls.key -out nginx-tls/nginx-tls.crt -days 365 -subj /CN=myapp.example.com
(2) 시크릿 생성
TLS 인증서와 키를 저장하기 위한 시크릿 생성하자
kubectl create secret tls nginx-tls-secret --cert=nginx-tls/nginx-tls.crt --key=nginx-tls/nginx-tls.key
시크릿 리소스의 자세한 정보를 확인해보자
kubectl describe secrets nginx-tls-secret

키 이름은 tls.crt, tls.key로 저장된 것을 확인!!!
(3) TLS설정을 위한 Nginx 설정 파일 및 컨피그 맵 생성
TLS 설정을 위한 Nginx 설정 파일을 생성해보자
mkdir conf >>> 설정 파일을 저장하기 위해 conf디렉터리를 생성하자
TLS 적용을 위한 Nginx 설정 파일은 다음과 같다
conf/nginx-tls.conf

TLS가 설정된 Nginx 설정 파일을 컨피그 맵으로 생성하자.
kubectl create configmap nginx-tls-config --from-file=conf/nginx-tls.conf
생성한 컨피그 맵의 자세한 정보를 한번 확인해보자

(4) 시크릿 및 컨피그 맵을 사용하는 파드 생성 ㄱㄱㄱㄱ
TLS가 적용된 Nginx 파드를 실행하기 위한 파드 오브젝트다.
vim nginx-pod-https.yaml

nginx-tls-config 컨피그 맵 = nginx-tls-config 볼륨
nginx-tls-secret 시크릿 = https-cert 볼륨
nginx-tls-config 볼륨 = /etc/nginx/conf.d 디렉터리에 마운트
https-cert 볼륨 = /etc/nginx/ssl 디렉터리에 마운트(읽기 전용)
파드를 생성해보자
kubectl create -f nginx-pod-https.yaml
파드의 자세한 정보를 확인해보자
kubectl describe pod nginx-pod-https

(5) HTTPS 웹 서비스 확인
Nginx 파드에 HTTPS가 잘 적용되었는지 확인!!
호스트의 8443 포트를 파드의 443 포트로 포워딩 ㄱㄱ
kubectl port-forward nginx-pod-https 8443:443

마지막으로 https://localhost:8443 포트로 요청하여 TLS 연결이 되는지 확인한다. 자체 서명 인증서 이기에 -K 옵션 사용 ㄱㄱㄱ
curl https://localhost:8443 -k -v

4) 인그레스를 이용한 TLS 종료 프록시 구현
앞선 실습은 파드에 직업 TLS 구성을 통해 클아이언트와 서버 사이 End-to-End 암호화가 이루어졌다. 그러나 TLS가 구성된 웹서버가 많아지면 우쨰될까요??? 관리적 부담 늘어남 ㅠㅠㅠ, 부하가 더 많이 걸릴 수 있음 ㅠㅠㅠ
TLS 종료 프록시(Termination Proxy)는 파드에 직접 TLS 구성하지 않고, 클라이언트와 프록시 사이에서만 TLS로 암호화하고, 내부 네티워크의 TLS 종료 프록시와 파드 사이는 일반 HTTP로 통신하는 방식을 구성!!!
TLS 종료 프록시 사용시 장점
- 파드가 직접 암/복호화 처리하지 않기에 부하를 줄일 수 있다!!
- 보안 솔류션이 악의적인 공격을 탐지해 보안을 향상할 수 있다.
쿠버네티스 클러스테에서 인그레스 컨트롤러를 이용해 TLS 종료 프록시 기능을 구성할 수 있다!!!
(2) TLS 종료 프록시를 위한 레플리카셋, 서비스 생성
인그레스 컨트롤러를 통해 서비스할 레플리카셋 컨트롤러와, 노드 포트 서비스를 생성
kubectl create -f myapp-rs-exp.yaml -f myapp-svc-np.yaml
(3) TLS 종료 프록시를 위한 TLS 인증서 생성
TLS 종료 프록시의 인증서/키를 저장할 디렉터리를 생성한다.
mkdir ingress-tls
인그레이스 컨트롤러를 위해 TLS키, TLS인증서를 생성
openssl genrsa -out ingress-tls/ingress-tls.key 2048

openssl req -new -x509 -key ingress-tls/ingress-tls.key -out ingress-tls/ingress-tls.crt -days 365 -subj /CN=myapp.example.com >>> TLS 인증서를 생성
(4) TLS 키 및 인증서를 위한 시크릿 생성
인그레스 컨트롤러를 위한 인증서와 키를 시크릿에 저장!!
kubectl create secret tls ingress-tls-secret --key=ingress-tls/ingress-tls.key --cert=ingress-tls/ingress-tls.crt
인증서와 키가 시크릿에 저장되었는지 확인
kubectl describe secret ingress-tls-secret

kubectl delete replicasets.apps,services,ingresses.networking.k8s.io --all
(5) TLS 종료 프록시를 위한 인그레스 컨트롤러 생성
vim myapp-ing-tls-term.yaml

ingress.spec.tls : TLS 구성
ingress.spec.tls.hosts : 사용할 호스트의 FQDN 지정
ingress.spec.tls.secretName : tls 인증서 및 키가 저장된 시크릿 지정
TLS 종료 프록시 기능의 인그레스 컨트롤러를 생성
kubectl create -f myapp-ing-tls-term.yaml
(6) 인그레스 컨트롤러 확인
kubectl get ingresses.networking.k8s.io

curl 명령을 통해 자체 서명 인증서를 사용하는 인그레스 컨트롤러에 접속 시도!!! 인그레스 컨트롤러는 FQDN 기반으로 리다이렉션 하기에 --resolv 옵션을 사용, 자체 서명 인증서 떄문에 insecure 옵션인 -k 옵션을 사용했다. 마지막으로 TLS 핸드 세이크 정보를 확인하기 위해 -v 옵션사용!!!!
curl --resolve myapp.example.com:443:192.168.56.21 -k -v https://myapp.example.com

결과는 당연히 이상없이 TLS 종료 프록시 통한 웹서비스 구축!!
5) 혹시나 시크릿 환경 변수로 참조하는 방법도 알고가즈아
볼륨이 아닌 환경 변수로 참조하는 YAML 오브젝트예제
env :
- name : f00_secret
valueFrom :
secretKeyRef : ??? (시크릿 변수 참조)
name : sercret-name (시크릿 이름)
key : key-name (시크릿의 키)
6) 리소스 삭제
리소스 한번에 삭제 ㄱㄱㄱ
kubectl delete replicasets.apps,services,ingresses.networking.k8s.io --all