kubernetes 서비스
29 Apr 2019
- 동일한 서비스를 제공하는 포드 그룹에 다일 진입점을 만들기 위해 생성하는 리소스입니다.
service yaml 파일 생성
# kubia-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: kubia
spec:
sessionAffinity: ClientIP # 특정 클라이언트에서 생성된 모든 요청을 매번 같은 포드로 리디레션할 때 사용(default: NONE)
ports:
- port: 80 # 서비스가 사용할 포트
targetPort: 8080 # 서비스가 포워드할 컨테이너 포트
selector:
app: kubia # 라벨이 app=kubia인 모든 포드는 이 서비스에 속한다.
다중 포트 설정
- 다중 포트를 갖는 서비스를 생성할 때 각 포트에 이름을 꼭 지정해야 합니다.
- 서로 다른 포드의 세트에 개별적으로 라벨 셀렉터를 지정하고 싶다면 두 개의 서비스를 만들어야 합니다.
apiVersion: v1
kind: Service
metadata:
name: kubia
spec:
ports:
- name: http
port: 80
targetPort: 8080
- name: https
port: 443
targetPort: 8443
selector:
app: kubia
이름이 지정된 포트 사용
kind: Pod
spec:
containers:
- name: kubia
ports:
- name: http # 컨테이너 포트 8080을 http 이름으로 설정
containerPort: 8080
- name: https # 컨테이너 포트 8443을 https 이름으로 설정
containerPort: 8443
apiVersion: v1
kind: Service
metadata:
name: kubia
spec:
ports:
- name: http # 포트 80은 http라 불리는 컨테이너 Port에 매핑
port: 80
targetPort: http
- name: https # 포트 443은 https라 불리는 컨테이너 Port에 매핑
port: 443
targetPort: https
selector:
app: kubia
환경 변수를 이용한 서비스 검색
kubectl exec kubia-3inlr env # 컨테이너 안의 환경변수 목록을 조회
# response
PATH=...
...
HOSTNAME=kubia-3inlr
KUBIA_SERVICE_HOST=10.100.88.242 # 서비스 IP
KUBIA_SERVICE_PORT=80 # 서비스가 사용 가능한 포트
...
서비스 엔드포인트
- 엔드포인트라 불리는 리소스가 포드와 서비스 사이에 위치합니다.
- 엔드포인트 리소스는 서비스에 의해 노출되는 IP주소와 포트의 목록입니다.
- 포드 셀렉터가 서비스 스펙에 정의돼 있더라도 들어오는 연결을 리다이렉트할 때 직접 사용하진 않습니다. 대신 셀렉터는 IP와 포트의 목록을 만드는 데 사용되고 엔드포인트 리소스에 저장됩니다.
kubectl get endpoints kubia
수동으로 서비스 엔드포인트 설정
포드 셀렉터 없이 서비스를 만들었다면 쿠버네티스는 엔드포인트 리소스를 만들지 못 합니다.
# external-service.yaml
apiVersion: v1
kind: Service
metadata:
name: external-service
spec:
# type: ExternalName
# externalName: api.company.com # 도메인 주소
ports:
- port: 80
# external-service-endpoints.yaml
apiVersion: v1
kind: Endpoints
metadata:
name: external-service # 엔드포인트 객체 이름은 서비스의 이름과 매칭돼야 합니다.
subsets:
- addresses: # 서비스가 연결을 포워딩할 엔드포인트의 IP
- ip: 11.11.11.11
- ip: 22.22.22.22
ports:
- port: 80
- 엔드포인트 오브젝트는 서비스와 동일한 이름이어야 하고 서비스를 위한 IP와 포트 정보를 담고 있습니다.
외부 클라이언트로 서비스 노출
서비스가 외부에서 액세스 가능하게 하는 방법
1. NodePort 서비스 타입으로 설정하기
-
NodePort 서비스를 생성해 쿠버네티스가 모든 노드를 대상으로 포트를 예약합니다.
-
모든 노드에 동일한 포트 번호를 사용하게 됩니다.
apiVersion: v1
kind: Service
metadata:
name: kubia-nodeport
spec:
type: NodePort # 서비스 타입을 NodePort로 설정
ports:
- port: 80 # ClusterIP port
targetPort: 8080 # 이 서비스에 연결되는 포트의 대상 포트
nodePort: 30123 # 노드의 port
selector:
app: kubia
2. LoadBalancer 서비스 타입으로 설정하기
- 쿠버네티스 클러스터는 클라우드 인프라스트럭처로부터 로드 밸런서를 자동으로 프로비전하는 기능을 지원합니다.
- LoadBalancer 서비스는 NodePort 서비스의 확장이기 때문에 서비스는 NodePort 서비스처럼 동작합니다.
- 특정 노드를 위한 포트를 설정하지 않습니다. 쿠버네티스에서 알아서 선택합니다.
# kubia-svc-loadbalancer.yaml
apiVersion: v1
kind: Service
metadata:
name: kubia-loadbalanver
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 8080
selector:
app: kubia
3. 인그레스 리소스 생성하기
- 수십 가지 서비스에 액세스를 제공할 수 있습니다.
- 인그레스 리소스를 작동시키려면 클러스터에서 인그레스 컨트롤러를 실행해야 합니다.
apiVersion: extentions/v1
kind: Ingress
metadata:
name: kubia
spec:
rules:
- host: kubia.example.com # kubia.example.com 도메인 이름을 서비스로 매핑
http:
paths:
- path: /
backend:
serviceName: kubia-nodeport
serviceProt: 80
yaml 설정
-
동일한 호스트 다른 서비스
... - host: kubia.example.com http: paths: - path: /kubia backend: serviceName: kubia servicePort: 80 - path: /bar backend: seviceName: bar servicePort: 80
-
다른 호스트 다른 서비스
... spec: rules: - host: foo.example.com http: paths: - path: / backend: serviceName: foo serviceProt: 80 - host: bar.example.com http: paths: - path: / backend: serviceName: bar servicePort: 80
TLS 트래픽을 처리하기 위한 인그레스 설정
TLS의 인증서는 secret이라는 쿠버네티스 리소스에 저장됩니다.
kubectl create secret tls tls-secret --cert=<path/인증서.cert> --key=<path/키.key> # kubernetes secret 리소스 생성
apiVersion: extentions/v1
kind: Ingress
metadata:
name: kubia
spec:
tls:
- secretName: tls-secret
hosts:
- kubia.example.com
rules:
- host: kubia.example.com # kubia.example.com 도메인 이름을 서비스로 매핑
http:
paths:
- path: /
backend:
serviceName: kubia-nodeport
serviceProt: 80
-
aws certificate manager 사용하기
kind: Ingress metadata: name: test-app annotations: zalando.org/aws-load-balancer-ssl-cert: <certificate ARN> ...
https://kubernetes-on-aws.readthedocs.io/en/latest/user-guide/ingress.html