용찬호. 「 시작하세요! 도커/쿠버네티스」. 위키북스 를 읽으며, 학습한 내용을 정리하는 글입니다.
→ 본문의 내용은 모두 책의 내용에 대한 직/간접적 인용임을 밝힙니다.
포드, 레플리카셋, 디플로이먼트, 서비스 등과 같은 쿠버네티스 리소스들이 묶여 있는 하나의 가상공간, 또는 그룹
kubectl get namespaces
→ --namespace
옵션을 명시하지 않으면 기본적으로 default
네임스페이스를 사용!
→ kube-system
네임스페이스는 쿠버네티스 클러스터 구성에 필수적인 컴포넌트, 설정값 등이 존재하는 네임스페이스.
** 각 네임스페이스의 리소스들은 논리적으로만 구분된 것일 뿐, 물리적으로 격리된 것은 아님!
apiVersion: v1
kind: Namespace
metadata:
name: production
kubectl apply -f production-namespace.yaml
kubectl create namespace production
으로도 생성 가능!apiVersion: apps/v1
kind: Deployment
metadata:
name: hostname-deployment-ns
namespace: production
spec:
...
--- # 하나의 YAML 파일에 ---로 여러 리소스 정의 가능. 여기선 디플로이먼트와 서비스
apiVersion: v1
kind: Service
metadata:
name: hostname-svc-clusterip-ns
namespace: production
spec:
→ 모든 리소스가 네임스페이스에 의해 구분되지는 않는다.
namespaced=true
kubectl create configmap
해당 명령어로 컨피그맵 생성 가능
--from-literal
옵션을 사용하여 여러 개의 키-값을 사용하도록 설정할 수 있다.kubectl create configmap start-k8s --from-literal k8s=kubernetes \ --from-literal container=docker
[ 컨피그맵을 포드에서 사용하는 방법 ]
1. 컨피그맵의 값을 컨테이너의 환경 변수로 사용
nginx.conf
등의 파일을 통해 설정값을 읽어 들일 때 권장< 컨피그맵의 데이터를 컨테이너의 환경 변수로 가져오기 >
apiVersion: 1
kind: Pod
metadata:
name: container-env-example
spec:
containers:
- name: my-cluster
image: busybox
args: ['tail', '-f', '/dev/null']
envFrom:
- configMapRef:
name: log-level-configmap
- configMapRef:
name: start-k8s
valueFrom
과 configMapKeyRef
를 사용하여 특정 데이터만을 선택해 환경 변수로 가져올 수도 있음. env:
- name: ENV_KEYNAME_1
valueFrom:
configMapKeyRef:
name: log-level-configmap
key: LOG_LEVEL
< 컨피그맵의 내용을 파일로 포드 내부에 마운트하기 >
apiVersion: v1
kind: Pod
metadata:
name: configmap-volume-pod
spec:
containers:
- name: my-container
image: busybox
args: ["tail", "-f", "/dev/null" ]
volumeMounts:
- name: configmap-volume. # volumes에서 정의한 컨피그맵 볼륨 이름
mountPath: /etc/config #컨피그맵의 데이터가 위치할 경로
volumes:
- name: configmap-volume. # 컨피그맵 볼륨 이름
configMap:
name: start-k8s. # 키-값 쌍을 가져온 컨피그맵 이름
< 파일로부터 컨피그맵 생성하기 >
--from-env-file
옵션으로, 여러 개의 키-값 형태의 내용으로 구성된 설정 파일을 한꺼번에 컨피그맵으로 가져올 수 있음!
kubectl create configmap from-envfile --from-env-file multiple-keyvalue.env
nginx.conf
와 같이 정적 파일을 포드에 제공한다면, --from-file
옵션을 쓰는 게 편리할 수도!kubectl create secret generic \ my-password --from-lieteral password=1q2w3e4r
→ my-password라는 이름의 시크릿 생성, password=1q2w3e3r 키-값을 생성
kubectl get secret my-password -o yaml
→ password: MXEydzNlNHI=
→ 시크릿에 값을 저장할 때, 쿠버네티스가 기본적으로 base64로 값을 인코딩
→ 시크릿을 포드의 환경 변수나 볼륨 파일로서 가져오면, base64로 디코딩된 원래의 값을 사용하게 된다.
apiVersion: v1
kind: Pod
metadata:
name: secret-env-example
spec:
containers:
- name: my-container
image: busybox
args: ['tail', '-f', '/dev/null']
envFrom:
- secretRef:
name: my-password
volumeMounts:
- name: secret-volume # volumes에서 정의한 시크릿 볼륨 이름
mountPath: /etc/secret # 시크릿의 데이터가 위치할 경로
volumes:
- name: secret-volume # 시크릿 볼륨 이름
secret:
secretName: our-password # 키-값 쌍을 가져올 시크릿 이름!
[ 좀 더 쉽게 컨피그맵과 시크릿 시소스 배포하기 ]
secretGenerator: # 시크릿을 생성하기 위한 지시문 cf. configMapGenerator
- name: kustomize-secret
type: kubernetes.io/tls. # tls 타입의 시크릿을 생성
files:
- tls.crt=cert.crt # tls.crt라는 키에 cert.crt 파일의 내용을 저장
- tls.key=cert.key. # tls.key라는 키에 cert.key 파일의 내용을 저장
→ kubectl apply -k ./
로 해당 파일을 통해 시크릿 생성!
--- 3부. 쿠버네티스 고급 기능 활용 ---
만약 애플리케이션이 3개의 디플로이먼트로 생성되어 있다면, NodePort 또는 LoadBalancer 타입의 서비스를 그에 맞게 3개를 생성해야 한다.
이는 서비스마다 세부적인 설정을 할 때 추가적인 복잡성이 발생한다는 한계가 있음.
인그레스를 사용한다면, 3개의 서비스에 대해 3개의 URL이 각각 존재하지 않고, 인그레스에 접근하기 위한 단 하나의 URL만 존재한다.
→ 라우팅 정의, 보안 연결과 같은 세부 설정이 인그레스에 의해 처리!
→ 즉, 외부 요청에 대한 처리 규칙을 쿠버네티스 자체 기능으로 편리하게 관리 가능!
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: ingress-example
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: alicek106.example.com
http:
paths:
- path: /echo-hostname
backend:
serviceName: hostname-service
servicePort: 80
host
: 해당 도메인 이름으로 접근하는 요청에 대해 처리 규칙을 적용path
: 해당 경로에 들어온 요청을 어느 서비스로 전달할 것인지 정의serviceName
, servicePort
: path로 들어온 요청이 전달될 서비스와 포트kubectl apply -f ingress-example.yaml
[ Nginx 인그레스 컨트롤러 ]
kubectl apply -f \
https://raw.githubusercontent......
→ Nginx 인그레스 컨트롤러 설치
kind: Service
apiVersion: v1
metadata:
name: ingress-nginx
namespace: ingress-nginx
spec:
type: LoadBalancer
selector:
app.kubernetes.io/name: ingress-nginx
app.kuernetes.io/part-of: ingress-nginx
ports:
- name: http
port: 80
targetPort: http
- name: https:
port: 443
targetPort: https
이상으로 서비스를 생성
Nginx 인그레스 컨트롤러의 포드에 기본적으로 설정된 라벨을 selector에 명시
여기까지, 인그레스, Nginx 인그레스 컨트롤러 및 Nginx 포드에 접근하기 위한 서비스의 준비 완료-!
[ cf. ...elb.amazonaws.com/echo-hostname 접근 시의 에러 ]
→ 404 NOT_FOUND가 반환된다.
[ 인그레스 컨트롤러의 동작 원리 이해 ]
1. 공식 깃허브에서 제공되는 YAML 파일로 Nginx 인그레스 컨트롤러를 생성
2. Nginx 인그레스 컨트롤러를 외부로 노출하기 위한 서비스 생성
3. 요청 처리 규칙을 정의하는 인그레스 오브젝트를 생성
→ Nginx 인그레스 컨트롤러로 들어온 요청은 인그레스 규칙에 따라 적절한 서비스로 전달된다.
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: ingress-example
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
kubernetes.io/ingress.class: "nginx"
kubernetes.io/ingress.class
nginx.ingress.kubernetes.io/rewrite-target
nginx.ingress.kubernetes.io/rewrite-target: / # 2
paths:
- path: /echo-hostname # 1
→ /echo-hostname 경로로 들어온 요청은
→ hostname-service의 /로 전달한다.