쿠버네티스는 허브 앤 스포크 API 패턴을 가지고 있다. 노드의 모든 API 사용은 API 서버에서 종료된다. 다른 컨트롤 플레인 컴포넌트 중 어느 것도 원격 서비스를 노출하도록 설계되지 않았다. API서버는 하나 이상의 클라이언트 인증 형식이 활성화된 보안 HTTPS 포트에서 원격 연결을 수신하도록 구성딘다.
API 서버에서 kubelect으로의 연결은 다음의 용도로 사용된다.
-파드에 대한 로그를 가져온다.
-실행 중인 파드에 (kubectl을 통해) 연결한다.
-kubelet의 포트-포워딩 기능을 제공한다.
--kubelet-certificate-authority플래그를 사용하여 API서버에 kubelet의 서빙 인증서를 확인하는 데 사용할 루트 인증서 번들을 제공한다. 하지만 이 방법은 신뢰할 수 없는 네트워크 및, 공용 네트워크에서 실행되기에 안전하지않다.
API서버에서 노드 파드 또는 서비스로의 연결은 기본적으로 일반 HTTP연결로 연결되므로 인증하거나 암호화되지 않는다. API URL 에서 노드, 파드, 서비스 이름을 접두어 https로 사용하여 보안 https 연결을 통해 실행될 수 있지만, HTTPS 엔드포인트가 제공한 인증서의 유효성을 검증하지 않거나 클라이언트 자격 증명을 제공하지 않느다 그래서 연결이 암호화 되는 동안 무결성을 보장하지않는다. 고로 현재는 안전하지 않다.
쿠버네티스는 SSH터널을 지원하여 컨트롤 플레인에서 노드로의 통신 경로를 보호한다. 익 ㅜ성에서 API서버는 클러스터의 각 노드에 SSH 터널을 시작하고 터널을 통해 kublet, 노드, 파드, 서비스로 향하는 모든 트래픽을 전달한다. 이 터널은 트래픽이 노드가 실행중인 네트워크 외부에 노출되지 않도록 한다.
SSH 터널을 대체하는 konnectivity 서비스는 컨트롤 플레인에서 클러스터 통신에 TCP 레벨 프록시를 제공한다 konnectivity 서비스는 컨트롤 플레인 네트워크의 konnectivity 서버와 노드 네트워크의 konnectivity 에이전트 두 개로 구성된다. konnectivity 에이전트는 konnectivity 서버에 대한 연결을 시작하고 네트워크 연결을 유지한다. konnectivity 서비스를 활성화 한 후, 모든 컨트롤 플레인에서 노드로의 트래픽은 이 연결을 통과한다.
konnectivity 서비스를 사용하고 네트워크 트래픽을 클러스터 노드로 보내도록 api 서버 구성
--service-account-issuer=api
--service-account-signing-key-file=/etc/kubernetes/pki/sa.key
--api-audiences=system:konnectivity-server
openssl 명령을 통해 클러스터 CA인증서를 사용하여 X.509인증서를 발급
openssl req -subj "/CN=system:konnectivity-server" -new -newkey rsa:2048 -nodes -out konnectivity.csr -keyout konnectivity.key -out konnectivity.csr
openssl x509 -req -in konnectivity.csr -CA /etc/kubernetes/pki/ca.crt -CAkey /etc/kubernetes/pki/ca.key -CAcreateserial -out konnectivity.crt -days 375 -sha256
SERVER=$(kubectl config view -o jsonpath='{.clusters..server}')
kubectl --kubeconfig /etc/kubernetes/konnectivity-server.conf config set-credentials system:konnectivity-server --client-certificate konnectivity.crt --client-key konnectivity.key --embed-certs=true
kubectl --kubeconfig /etc/kubernetes/konnectivity-server.conf config set-cluster kubernetes --server "$SERVER" --certificate-authority /etc/kubernetes/pki/ca.crt --embed-certs=true
kubectl --kubeconfig /etc/kubernetes/konnectivity-server.conf config set-context system:konnectivity-server@kubernetes --cluster kubernetes --user system:konnectivity-server
kubectl --kubeconfig /etc/kubernetes/konnectivity-server.conf config use-context system:konnectivity-server@kubernetes
rm -f konnectivity.crt konnectivity.key konnectivity.csr
컨트롤 플레인 노드에 konnectivity 서버를 배포
apiVersion: v1
kind: Pod
metadata:
name: konnectivity-server
namespace: kube-system
spec:
priorityClassName: system-cluster-critical
hostNetwork: true
containers:
- name: konnectivity-server-container
image: us.gcr.io/k8s-artifacts-prod/kas-network-proxy/proxy-server:v0.0.16
command: ["/proxy-server"]
args: [
"--logtostderr=true",
# This needs to be consistent with the value set in egressSelectorConfiguration.
"--uds-name=/etc/kubernetes/konnectivity-server/konnectivity-server.socket",
# The following two lines assume the Konnectivity server is
# deployed on the same machine as the apiserver, and the certs and
# key of the API Server are at the specified location.
"--cluster-cert=/etc/kubernetes/pki/apiserver.crt",
"--cluster-key=/etc/kubernetes/pki/apiserver.key",
# This needs to be consistent with the value set in egressSelectorConfiguration.
"--mode=grpc",
"--server-port=0",
"--agent-port=8132",
"--admin-port=8133",
"--health-port=8134",
"--agent-namespace=kube-system",
"--agent-service-account=konnectivity-agent",
"--kubeconfig=/etc/kubernetes/konnectivity-server.conf",
"--authentication-audience=system:konnectivity-server"
]
livenessProbe:
httpGet:
scheme: HTTP
host: 127.0.0.1
port: 8134
path: /healthz
initialDelaySeconds: 30
timeoutSeconds: 60
ports:
- name: agentport
containerPort: 8132
hostPort: 8132
- name: adminport
containerPort: 8133
hostPort: 8133
- name: healthport
containerPort: 8134
hostPort: 8134
volumeMounts:
- name: k8s-certs
mountPath: /etc/kubernetes/pki
readOnly: true
- name: kubeconfig
mountPath: /etc/kubernetes/konnectivity-server.conf
readOnly: true
- name: konnectivity-uds
mountPath: /etc/kubernetes/konnectivity-server
readOnly: false
volumes:
- name: k8s-certs
hostPath:
path: /etc/kubernetes/pki
- name: kubeconfig
hostPath:
path: /etc/kubernetes/konnectivity-server.conf
type: FileOrCreate
- name: konnectivity-uds
hostPath:
path: /etc/kubernetes/konnectivity-server
type: DirectoryOrCreate
클러스터에 연결 에이전트를 배포
apiVersion: apps/v1
# Alternatively, you can deploy the agents as Deployments. It is not necessary
# to have an agent on each node.
kind: DaemonSet
metadata:
labels:
addonmanager.kubernetes.io/mode: Reconcile
k8s-app: konnectivity-agent
namespace: kube-system
name: konnectivity-agent
spec:
selector:
matchLabels:
k8s-app: konnectivity-agent
template:
metadata:
labels:
k8s-app: konnectivity-agent
spec:
priorityClassName: system-cluster-critical
tolerations:
- key: "CriticalAddonsOnly"
operator: "Exists"
containers:
- image: us.gcr.io/k8s-artifacts-prod/kas-network-proxy/proxy-agent:v0.0.16
name: konnectivity-agent
command: ["/proxy-agent"]
args: [
"--logtostderr=true",
"--ca-cert=/var/run/secrets/kubernetes.io/serviceaccount/ca.crt",
# Since the konnectivity server runs with hostNetwork=true,
# this is the IP address of the master machine.
"--proxy-server-host=35.225.206.7",
"--proxy-server-port=8132",
"--admin-server-port=8133",
"--health-server-port=8134",
"--service-account-token-path=/var/run/secrets/tokens/konnectivity-agent-token"
]
volumeMounts:
- mountPath: /var/run/secrets/tokens
name: konnectivity-agent-token
livenessProbe:
httpGet:
port: 8134
path: /healthz
initialDelaySeconds: 15
timeoutSeconds: 15
serviceAccountName: konnectivity-agent
volumes:
- name: konnectivity-agent-token
projected:
sources:
- serviceAccountToken:
path: konnectivity-agent-token
audience: system:konnectivity-server
마지막으로 클러스터에서 RBAC가 활성화된 경우 관련 RBAC 규칙을 생성
여기서 RBAC란 Role 기반으로 쿠버네티스 시스템의 권한을 관리하는 것을 뜻함.
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: system:konnectivity-server
labels:
kubernetes.io/cluster-service: "true"
addonmanager.kubernetes.io/mode: Reconcile
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: system:auth-delegator
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: system:konnectivity-server
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: konnectivity-agent
namespace: kube-system
labels:
kubernetes.io/cluster-service: "true"
addonmanager.kubernetes.io/mode: Reconcile
'INFRA > DevOps' 카테고리의 다른 글
Jenkins Pipeline (1) (0) | 2022.05.17 |
---|---|
AWS DevOps CI/CD 환경 구축 2편(CodeCommit, CodeBuild, CodeDeploy, Codepipeline) (0) | 2022.05.13 |
yaml 문법 (0) | 2022.05.12 |
AWS CI/CD 환경 구축 1편(CodeCommit, CodeBuild, CodeDeploy, Codepipeline) (0) | 2022.05.06 |
ReplicaSet (0) | 2022.05.02 |
댓글