ingress
는 외부에서 쿠버네티스 클러스터에 접근하기 위한 오브젝트를 가리키며 NGINX
Traefik
등의 구현이 있습니다. k3s
는 Traefik
을 번들로 제공하고 있습니다.
Traefik ingress (helm)
helm repo add traefik https://traefik.github.io/charts
Code language: JavaScript (javascript)
helm install traefik traefik/traefik
테스트 애플리케이션 – 에코서버 배포
테스트응 위해 도커 애플리케이션 이미지를 만들기 번거로우니 적절히 에코서버 이미지를 가져와서 deployment를 사용하여 배포합니다.
mkdir ~/k3s
cd ~/k3s
vi echo-server.yaml
Code language: PHP (php)
# echo-sever.yml
# 서비스
---
apiVersion: v1
kind: Service
metadata:
name: echo-server
labels:
app: echo-server
spec:
ports:
- protocol: TCP
port: 80
targetPort: 80
selector:
app: echo-server
# 디플로이먼트
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: echo-server
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
selector:
matchLabels:
app: echo-server
template:
metadata:
labels:
app: echo-server
spec:
containers:
- name: echo-server
image: ealen/echo-server:0.5.2
imagePullPolicy: Always
ports:
- containerPort: 80
resources:
limits:
cpu: "0.5"
memory: "1Gi"
Code language: PHP (php)
kubectl apply -f echo-server.yaml # 서비스와 디플로이먼트를 적용합니다.
Code language: PHP (php)
kubectl get pods # 포드 목록을 나열합니다.
Code language: JavaScript (javascript)
Traefik을 사용해 외부로 서비스 노출하기
파드는 서비스의 형태로 배포되었지만, 호스트에서 해당 파드로 직접 접근할 수는 없습니다.Ingress
를 사용하여 ingress Controller
에게 생성한 서비스를 연결해 주어야 외부에서 80 포트로 접근이 가능합니다.
cd ~/k3s
vi traefik.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: traefik-routers
annotations:
kubernetes.io/ingress.class: traefik
spec:
rules:
- host: [YOUR_DOMAIN]
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: echo-server
port:
number: 80
k3s traefik cert-manager로 인증서 관리하기
cert-manager와 let’s encrypt로 TLS 구현하기
이번에는 cert-manager
와 letsencrypt
를 사용하여 TLS 인증서를 적용
Helm – cert-manager Documentation helm
을 이용하여 cert-manager
를 설치합니다.
helm repo add jetstack https://charts.jetstack.io
Code language: JavaScript (javascript)
helm repo update
curl -L -o cert-manager.yml https://github.com/cert-manager/cert-manager/releases/download/v1.12.0/cert-manager.crds.yaml
Code language: JavaScript (javascript)
버전이 바뀔수있으니 Helm – cert-manager Documentation 3-install-customresourcedefinitions참고하기
kubectl apply -f cert-manager.yml
Code language: CSS (css)
helm install cert-manager jetstack/cert-manager --version v1.12.0
kubectl get pods --namespace=cert-manager
===
NAME READY STATUS RESTARTS AGE
cert-manager-cainjector-5c55bb7cb4-schmh 1/1 Running 0 5m16s
cert-manager-76578c9687-jgqmp 1/1 Running 0 5m16s
cert-manager-webhook-556f979d7f-7l99s 1/1 Running 0 5m16s
cert-manager-startupapicheck-xt556 0/1 Completed 0 5m15s
Code language: JavaScript (javascript)
issuer 등록
인증서를 만들기 전, 발급자를 등록해 주어야 합니다. letsencrypt
에 대한 tls-issuer.yaml
를 작성합니다.
# tls-issuer.yml
---
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: tls-issuer # 마음대로 지정합니다
namespace: default
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: [YOUR_EMAIL]
privateKeySecretRef:
name: tls-key # 마음대로 지정합니다
solvers:
- selector: {}
http01:
ingress:
class: traefik
tls-issuer.yaml
를 등록하고 상태를 확인합니다. Ready: True
상태로 변경되기 까지 시간이 조금 걸릴 수 있습니다.
kubectl create -f tls-issuer.yml
Code language: CSS (css)
kubectl get issuer -o wide
===
NAME READY STATUS AGE
tls-issuer True The ACME account was registered with the ACME server 4m31s
Code language: JavaScript (javascript)
certificate 생성
인증서를 만듭니다.
# tls-cert.yml
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: tls-cert
namespace: default
spec:
secretName: tls-secret # 마음대로 작성
issuerRef:
name: tls-issuer # 위에서 지정한 이름
commonName: [YOUR_DOMAIN]
dnsNames:
- [YOUR_DOMAIN]
# 서브도메인 등록 가능
# - sub.example.com
이제 인증서를 발급합니다.
- 더미 인증서 제작
- acme 핸드쉐이크
- 실제 인증서 발급 및 적용
- 더미 인증서 파기
해당 과정을 자동으로 처리해줍니다.
kubectl create -f tls-cert.yml
Code language: CSS (css)
kubectl get certificate -o wide
===
NAME READY SECRET ISSUER STATUS AGE
tls-cert True tls-secret tls-issuer Certificate is up to date and has not expired 6s
Code language: JavaScript (javascript)
마찬가지로 Ready: True
상태가 되기까지 시간이 조금 걸릴 수 있습니다.
Ingress Controller에 인증서 정보 전달하기
인증서 발급이 성공적으로 처리되었으니 이제 traefik.yaml
에서 인증서와 비밀 키 정보를전달하면 TLS를 사용할 수 있습니다.
# traefik.yml
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: traefik-routers
annotations:
kubernetes.io/ingress.class: traefik
spec:
rules:
- host: [YOUR_DOMAIN]
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: echo-server
port:
number: 80
tls:
- secretName: tls-secret # tls-cert 에서 지정한 키 이름
hosts:
- [YOUR_DOMAIN]
cert-manager
플러그인이 인증서 파기 1개월 전에 자동갱신 처리해 주니 신경 쓸 필요가 없습니다. describe
명령어를 통해 인증서 만료일과 갱신 예정일을 확인해 볼 수 있습니다.
kubectl describe certificate tls-cert
Name: tls-cert
Namespace: default
Labels: <none>
Annotations: <none>
API Version: cert-manager.io/v1
Kind: Certificate
Metadata:
Creation Timestamp: 2023-01-18T14:30:56Z
Generation: 1
Managed Fields:
API Version: cert-manager.io/v1
Fields Type: FieldsV1
fieldsV1:
f:spec:
.:
f:commonName:
f:dnsNames:
f:issuerRef:
.:
f:name:
f:secretName:
Manager: kubectl-create
Operation: Update
Time: 2023-01-18T14:30:56Z
API Version: cert-manager.io/v1
Fields Type: FieldsV1
fieldsV1:
f:status:
f:revision:
Manager: cert-manager-certificates-issuing
Operation: Update
Subresource: status
Time: 2023-01-18T14:31:22Z
API Version: cert-manager.io/v1
Fields Type: FieldsV1
fieldsV1:
f:status:
.:
f:conditions:
.:
k:{"type":"Ready"}:
.:
f:lastTransitionTime:
f:message:
f:observedGeneration:
f:reason:
f:status:
f:type:
f:notAfter:
f:notBefore:
f:renewalTime:
Manager: cert-manager-certificates-readiness
Operation: Update
Subresource: status
Time: 2023-01-18T14:31:22Z
Resource Version: 23295
UID: 24262cb8-631f-4506-ade0-2abba2023f61
Spec:
Common Name: 4t.gg
Dns Names:
4t.gg
Issuer Ref:
Name: tls-issuer
Secret Name: tls-secret
Status:
Conditions:
Last Transition Time: 2023-01-18T14:31:22Z
Message: Certificate is up to date and has not expired
Observed Generation: 1
Reason: Ready
Status: True
Type: Ready
Not After: 2023-04-18T13:31:20Z
Not Before: 2023-01-18T13:31:21Z
Renewal Time: 2023-03-19T13:31:20Z
Revision: 1
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Issuing 7m1s cert-manager-certificates-trigger Issuing certificate as Secret does not exist
Normal Generated 7m1s cert-manager-certificates-key-manager Stored new private key in temporary Secret resource "tls-cert-sb27z"
Normal Requested 7m1s cert-manager-certificates-request-manager Created new CertificateRequest resource "tls-cert-twd5d"
Normal Issuing 6m35s cert-manager-certificates-issuing The certificate has been successfully issued
Code language: HTML, XML (xml)
인증서를 받아와서 설정된 것을 알수 있도 해당 도메인으로 들어가면 SSL 인증이 받아진 것을 확인할 수 있다.
traefik ingress를 이용하면서 설정해야할 것도 많고 관리하는 것도 만만치 않았다.
나의 사용 스타일에서는 아직 cert-menager까지는 필요 없는 것같다. [[post/traefik ingress cert-manger 조합에서 traefik만 사용하는 방법으로 변경]]