k8s는 물리적인 인프라 위에 자체적인 네트워크 레이어를 구현하여 통신을 구현한다. 이를 통해서 외부와 Pod간 통신이나 Pod와 Pod간 통신이 이루어지게 된다.
이 네트워크 레이어를 활용하여 통신을 하는 컴포넌트들이 Service와 Ingress이다.
Ingress는 클러스터 외부와 클러스터를 통신하기 위한 컴포넌트이고, 리버스 프록시 역할을 하고, Service는 역할 별로 다양한 종류들이 있는데 아래와 같은 것들이 있다.

클러스터 IP는 위에서도 이야기했듯이 Pod와 Pod 간 통신에 사용된다.
그림처럼 Frontend 애플리케이션이 돌고 있는 Pod에서 Backend 애플리케이션이 돌고 있는 Pod와 통신하고자하는 경우가 그 예시가 될 수 있다.
이 때 필요한 Service 유형이 바로 ClusterIP 유형이다.
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
type: ClusterIP # (default)
selector:
app: my-backend
ports:
- protocol: TCP
port: 8080
위와 같이 Backend 애플리케이션이 돌고 있는 Pod를 가리키도록 ClusterIP Service를 만들 수 있다.
http://my-service:8080
http://my-service.default.svc.cluster.local:8080
Frontend Pod에서 이 서비스를 호출하기 위해서는 위와 같이 서비스 명을 통해서 호출 할 수 있다. (순서대로, 축약형과 원본)

클러스터 외부에 존재하는 DB 또는 API 서버와 같은 것을 호출할 때는 ExternalName Service를 사용할 수 있다.
apiVersion: v1
kind: Service
metadata:
name: my-external-service
spec:
type: ExternalName
externalName: mysql.database.com
ExternalName Service는 위와 같이 yml을 작성하여 만들 수 있다.
http://my-external-service:3306
ExternalName Service는 위와 같이 호출할 수 있다.
물론, ExternalName을 사용하지 않아도 외부 Url을 호출할 수는 있지만, ExternalName을 사용하여, 외부 호출을 추상화해서 사용하는 장점을 갖는다고 볼 수 있다.

NodePort 서비스는 서비스를 특정 Port에 노출시키는 기능을 수행하는 서비스이다.
apiVersion: v1
kind: Service
metadata:
name: my-nodeport-service
spec:
type: NodePort
selector:
app: my-frontend
ports:
- port: 8080
targetPort: 8080
nodePort: 30007
위와 같이 yml을 작성하여 NodePort 서비스를 생성할 수 있다. 이렇게 생성하면, 클터스터 내부에서는 이 서비스를 http://my-nodeport-service:8080과 같이 8080포트로 호출할 수 있고, 외부에서는 30007 포트로 노출되게 된다.

LoadBalancer 서비스는 자체적으로 뭔가를 처리한다기보다 외부에 존재하는 LoadBalancer에 라우팅을 위임한 형태라고 볼 수 있다.
apiVersion: v1
kind: Service
metadata:
name: my-loadbalancer-service
spec:
type: LoadBalancer
selector:
app: my-frontend
ports:
- protocol: TCP
port: 8080
targetPort: 8080
위와 같이 yml을 작성하여 LoadBalancer 서비스를 생성할 수 있고, LoadBalancer 역할을 하는 것은 AWS 또는 Azure와 같은 클라우드에서 제공하는 로드 밸런서가 되거나, LoadBalancer 역할을 하는 k8s 플러그인이 될 수 있다.
Ingress는 NGinX나 AWS의 ALB와 같이 애플리케이션 레벨에서 트래픽을 처리해주는 리버스 프록시 역할을 하는 컴포넌트이다.
위에서 살펴봤던, Service들과 달리 Ingress가 바라보는 대상은 Pod가 아니라 Service가 되고, HTTP 또는 HTTPS 통신만 사용할 수 있다.
Ingress는 동작을 정의하기 위한 "리소스"와 이를 처리하기 위한 "컨트롤러"로 구분된다.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-ingress
spec:
tls:
- hosts:
- myapp.example.com
secretName: myapp-tls
rules:
- host: myapp.exampple.com
http:
paths:
- path: /user
pathType: Prefix
backend:
service:
name: user-service
port:
number: 8080
- path: /product
pathType: Prefix
backend:
servivce:
name: product-service
port:
number: 8080
Ingress는 위와 같은 형태로 yml을 작성하여 생성할 수 있고, tls 옵션을 통해서 SSL 인증서를 붙일 수 있고, rules에 라우팅 규칙을 작성하여 리버스 프록시로써의 역할도 정의할 수 있다.