Typha 설치하기
Typha는 Kubernetes API 서버와 각 노드 데몬 사이에서 데이터스토어 읽기를 분산해 주는 컴포넌트예요. 이 문서는 Calico 설치 난이도 높은 방식(hard way) 시리즈의 일부로, Typha를 직접 설치하는 절차를 안내해요. CA 인증서 생성부터 RBAC 구성, Deployment와 Service 배포, TLS 동작 확인까지 차근차근 따라 해 보세요.
출처: 문서
본문
Typha는 Kubernetes API 서버와 calico/node에서 실행되는 Felix, confd 같은 노드별 데몬 사이에 위치해요. Typha는 이 데몬들이 사용하는 Kubernetes 리소스와 Calico 커스텀 리소스를 감시(watch)하고, 리소스가 바뀔 때마다 변경 사항을 데몬들에게 전파해요. 덕분에 Kubernetes API 서버가 처리해야 하는 watch 수가 줄고 클러스터 확장성이 좋아져요.
인증서 준비하기
calico/node와 Typha가 안전하게 통신하도록 상호 인증 TLS를 사용할 거예요. 이 섹션에서는 인증 기관(CA)을 생성하고, 이 CA로 Typha 인증서에 서명해요.
CA 인증서와 키 만들기
openssl req -x509 -newkey rsa:4096 \
-keyout typhaca.key \
-nodes \
-out typhaca.crt \
-subj "/CN=Calico Typha CA" \
-days 365
CA 인증서를 Typha와 calico/node가 접근할 ConfigMap에 저장해요.
kubectl create configmap -n kube-system calico-typha-ca --from-file=typhaca.crt
Typha 키와 인증서 서명 요청(CSR) 만들기
openssl req -newkey rsa:4096 \
-keyout typha.key \
-nodes \
-out typha.csr \
-subj "/CN=calico-typha"
이 인증서는 Common Name(CN)으로 calico-typha를 제시해요. calico/node는 이 이름을 검증하도록 구성될 거예요.
CA로 Typha 인증서 서명하기
openssl x509 -req -in typha.csr \
-CA typhaca.crt \
-CAkey typhaca.key \
-CAcreateserial \
-out typha.crt \
-days 365
Typha 키와 인증서를 Typha가 접근할 시크릿에 저장해요.
kubectl create secret generic -n kube-system calico-typha-certs --from-file=typha.key --from-file=typha.crt
RBAC 준비하기
Typha 실행에 사용할 ServiceAccount를 만들어요.
kubectl create serviceaccount -n kube-system calico-typha
Calico 데이터스토어 객체를 watch할 수 있는 권한을 가진 Typha용 클러스터 롤을 정의해요.
kubectl apply -f - <<EOF
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: calico-typha
rules:
- apiGroups: [""]
resources:
- pods
- namespaces
- serviceaccounts
- endpoints
- services
- nodes
verbs:
- watch
- list
- get
- apiGroups: ["networking.k8s.io"]
resources:
- networkpolicies
verbs:
- watch
- list
- apiGroups: ["crd.projectcalico.org"]
resources:
- globalfelixconfigs
- felixconfigurations
- bgppeers
- globalbgpconfigs
- bgpconfigurations
- ippools
- ipamblocks
- globalnetworkpolicies
- globalnetworksets
- networkpolicies
- clusterinformations
- hostendpoints
- blockaffinities
- networksets
verbs:
- get
- list
- watch
- apiGroups: ["crd.projectcalico.org"]
resources:
#- ippools
#- felixconfigurations
- clusterinformations
verbs:
- get
- create
- update
EOF
클러스터 롤을 calico-typha ServiceAccount에 바인딩해요.
kubectl create clusterrolebinding calico-typha --clusterrole=calico-typha --serviceaccount=kube-system:calico-typha
Deployment 설치하기
Typha는 calico/node가 필요로 하고, calico/node는 파드 네트워크를 구성하므로, 닭과 달걀 문제를 피하려고 Typha를 호스트 네트워크 파드로 실행해요. 롤링 업데이트 중에도 단일 장애로 Typha를 사용할 수 없게 되지 않도록 레플리카 3개로 실행해요.
kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: calico-typha
namespace: kube-system
labels:
k8s-app: calico-typha
spec:
replicas: 3
revisionHistoryLimit: 2
selector:
matchLabels:
k8s-app: calico-typha
template:
metadata:
labels:
k8s-app: calico-typha
annotations:
cluster-autoscaler.kubernetes.io/safe-to-evict: 'true'
spec:
hostNetwork: true
tolerations:
# Mark the pod as a critical add-on for rescheduling.
- key: CriticalAddonsOnly
operator: Exists
serviceAccountName: calico-typha
priorityClassName: system-cluster-critical
containers:
- image: calico/typha:v3.8.0
name: calico-typha
ports:
- containerPort: 5473
name: calico-typha
protocol: TCP
env:
# Disable logging to file and syslog since those don't make sense in Kubernetes.
- name: TYPHA_LOGFILEPATH
value: "none"
- name: TYPHA_LOGSEVERITYSYS
value: "none"
# Monitor the Kubernetes API to find the number of running instances and rebalance
# connections.
- name: TYPHA_CONNECTIONREBALANCINGMODE
value: "kubernetes"
- name: TYPHA_DATASTORETYPE
value: "kubernetes"
- name: TYPHA_HEALTHENABLED
value: "true"
# Location of the CA bundle Typha uses to authenticate calico/node; volume mount
- name: TYPHA_CAFILE
value: /calico-typha-ca/typhaca.crt
# Common name on the calico/node certificate
- name: TYPHA_CLIENTCN
value: calico-node
# Location of the server certificate for Typha; volume mount
- name: TYPHA_SERVERCERTFILE
value: /calico-typha-certs/typha.crt
# Location of the server certificate key for Typha; volume mount
- name: TYPHA_SERVERKEYFILE
value: /calico-typha-certs/typha.key
livenessProbe:
httpGet:
path: /liveness
port: 9098
host: localhost
periodSeconds: 30
initialDelaySeconds: 30
readinessProbe:
httpGet:
path: /readiness
port: 9098
host: localhost
periodSeconds: 10
volumeMounts:
- name: calico-typha-ca
mountPath: "/calico-typha-ca"
readOnly: true
- name: calico-typha-certs
mountPath: "/calico-typha-certs"
readOnly: true
volumes:
- name: calico-typha-ca
configMap:
name: calico-typha-ca
- name: calico-typha-certs
secret:
secretName: calico-typha-certs
EOF
TYPHA_CLIENTCN을 calico-node로 설정했는데, 이는 다음 실습에서 calico/node가 사용할 인증서에 넣을 common name이에요.
Typha가 인스턴스 세 개로 잘 떠 있는지 확인해요.
kubectl get pods -l k8s-app=calico-typha -n kube-system
결과:
NAME READY STATUS RESTARTS AGE
calico-typha-66498ddfbd-2pzsr 1/1 Running 0 69s
calico-typha-66498ddfbd-lrtzw 1/1 Running 0 50s
calico-typha-66498ddfbd-scckd 1/1 Running 0 62s
Service 설치하기
calico/node는 Kubernetes Service를 사용해 로드 밸런싱된 Typha 접근을 얻어요.
kubectl apply -f - <<EOF
apiVersion: v1
kind: Service
metadata:
name: calico-typha
namespace: kube-system
labels:
k8s-app: calico-typha
spec:
ports:
- port: 5473
protocol: TCP
targetPort: calico-typha
name: calico-typha
selector:
k8s-app: calico-typha
EOF
Typha가 TLS를 사용하는지 검증해요.
TYPHA_CLUSTERIP=$(kubectl get svc -n kube-system calico-typha -o jsonpath='{.spec.clusterIP}')
curl https://$TYPHA_CLUSTERIP:5473 -v --cacert typhaca.crt
결과
* Rebuilt URL to: https://10.103.120.116:5473/
* Trying 10.103.120.116...
* TCP_NODELAY set
* Connected to 10.103.120.116 (10.103.120.116) port 5473 (#0)
* ALPN, offering h2
* ALPN, offering http/1.1
* successfully set certificate verify locations:
* CAfile: typhaca.crt
CApath: /etc/ssl/certs
* (304) (OUT), TLS handshake, Client hello (1):
* (304) (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS handshake, Certificate (11):
* TLSv1.2 (IN), TLS handshake, Server key exchange (12):
* TLSv1.2 (IN), TLS handshake, Request CERT (13):
* TLSv1.2 (IN), TLS handshake, Server finished (14):
* TLSv1.2 (OUT), TLS handshake, Certificate (11):
* TLSv1.2 (OUT), TLS handshake, Client key exchange (16):
* TLSv1.2 (OUT), TLS change cipher, Client hello (1):
* TLSv1.2 (OUT), TLS handshake, Finished (20):
* TLSv1.2 (IN), TLS alert, Server hello (2):
* error:14094412:SSL routines:ssl3_read_bytes:sslv3 alert bad certificate
* stopped the pause stream!
* Closing connection 0
curl: (35) error:14094412:SSL routines:ssl3_read_bytes:sslv3 alert bad certificate
이 결과는 Typha가 TLS 인증서를 제시하고 있고, 우리 쪽에서 인증서를 제시하지 않았기 때문에 연결을 거부했다는 뜻이에요. 다음 실습에서 calico/node를 Typha가 받아들이는 인증서와 함께 배포할 거예요.
다음
더 알아보기 (Learn more)
Typha는 API 서버의 watch 부담을 덜어 주는 확장성 컴포넌트예요. TLS 검증 단계에서 인증서 없이 연결이 거부되는 것은 정상 동작이니, 실패로 오해하지 않도록 주의하세요.