-
[Kubernetes] EKS 구축kubernetes 2022. 10. 23. 23:34반응형
❗️ AWS에서 제공하는 가이드 문서 예제로 진행한다.
💡 Requires
1. Terraform
2. Helm
3. aws-cli
4. aws-iam-authenticator
5. aws 계정 설정💡 EKS란 ?
Amazon EKS는 AWS에서 만든 관리형 쿠버네티스 서비스 이다. EKS는 Elastic Kubernetes Service의 약자다.
EKS를 사용하면 쿠버네티스 마스터노드구성을 하지 않아도 AWS에서 관리해주기 때문에 되기 때문에 쉽고 빠르게
쿠버네티스를 이용할 수 있다. EKS는 구축하기 위해서 EKS클러스터생성과 노드그룹을 생성해야 한다.
❗️ 자세한 설명은 아래 링크 참조
https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/what-is-eks.htmlTerraform을 이용해 AWS EKS를 구성하고 Helm을 이용해서 ingress와 application을 EKS 위에 띄워본다.
💡 AWS IAM Authenticator 란?
aws-iam-authenticator는 쿠버네티스의 RBAC 권한을 AWS IAM을 통해 제어할 수 있도록 해주는 도구이다. 기존에 이미 AWS 상에서 개발자의 권한 관리를 하고 있었다면 이를 그대로 API 서버로 가져와 쿠버네티스에서의 Role을 엮어줄 수 있다고 생각하면 된다. 예를 들어 DevOps 팀의 IAM Role은 kubernetes-admin 권한을 부여하되, 개발팀의 IAM Role에는 개발용 네임스페이스에만 접근 권한을 부여할 수도 있다. EKS에서는 자동으로 내장되어 있다.💡 인그레스(Ingress) 란?
클러스터 내의 서비스에 대한 외부 접근을 관리하는 API 오브젝트이며, HTTP와 HTTPS 경로를 노출한다. 트래픽 라우팅은 인그레스 리소스에 정의된 규칙에 의해 컨트롤된다.
인그레스는 부하 분산, SSL 종료, 명칭 기반의 가상 호스팅을 제공할 수 있다.인그레스는 임의의 포트 또는 프로토콜을 노출시키지 않는다. HTTP와 HTTPS 이외의 서비스를 인터넷에 노출하려면 보통 Service.Type=NodePort 또는 Service.Type=LoadBalancer 유형의 서비스를 사용한다.
인그레스 컨트롤러가 있어야 인그레스를 충족할 수 있다. 인그레스 리소스만 생성한다면 효과가 없다.
ingress-nginx와 같은 인그레스 컨트롤러를 배포해야 할 수도 있다. 여러 인그레스 컨트롤러 중에서 선택할 수도 있다.출처: https://kubernetes.io/ko/docs/concepts/services-networking/ingress/
📌 시작하기
Helm / Kubectl / Terraform / aws-cli / aws-iam-authenticator 설치
$ brew install helm kubectl terraform awscli aws-iam-authenticator
1. IAM 사용자 생성 및 권한 부여
- IAM을 사용하여 Amazon EKS에 대한 액세스를 관리하기 위해 IAM 사용자를 생성하고 권한을 부여한다.
- 사용자 생성 후 Access Key, Secret Key는 별도로 저장해둔다.
IAM 사용자 생성 링크
https://docs.aws.amazon.com/ko_kr/IAM/latest/UserGuide/id_users_create.html#id_users_create_cliwpsapi권한 부여 * 편의상 EC2FullAccess, AdministratorAccess 권한을 추가하지만, 운영 환경에서는 고려 해야 한다.
2. 샘플 Terraform 스크립트 생성
$ cd ~ $ git clone https://github.com/terraform-providers/terraform-provider-aws.git $ cd terraform-provider-aws/example/eks-getting-started
파일을 확인해보면 .tf 확장자가 붙어있다. 이 파일들은 샘플 EKS 클러스터를 구성하도록 되어있다.
$ ll eks-cluster.tf eks-worker-nodes.tf outputs.tf providers.tf README.md variables.tf vpc.tf workstation-external-ip.tf
variables.tf 파일의 aws_region default 값이 us-west-2로 되어있다. 원하는 region으로 변경하면 된다. 이 글에서는 서울 리전(ap-northeast-2)으로 변경하여 진행한다.
variable "aws_region" { default = "ap-northeast-2" } variable "cluster-name" { default = "terraform-eks-demo" type = string }
❗️ EKS Node Group Default 값은 [t3.medium]이다. 비교적 비싼 요금제이기 때문에, [t3.small] type으로 변경하여 진행한다.
-> eks-worker-nodes.tf 파일을 보면, node group의 정보가 적혀있다. 이 부분에 Instance type을 설정해준다.resource "aws_eks_node_group" "demo" { cluster_name = aws_eks_cluster.demo.name node_group_name = "demo" node_role_arn = aws_iam_role.demo-node.arn subnet_ids = aws_subnet.demo[*].id instance_types = ["t3.small"] // 배열형태로 t3.small 값을 설정해준다. scaling_config { desired_size = 1 max_size = 1 min_size = 1 } depends_on = [ aws_iam_role_policy_attachment.demo-node-AmazonEKSWorkerNodePolicy, aws_iam_role_policy_attachment.demo-node-AmazonEKS_CNI_Policy, aws_iam_role_policy_attachment.demo-node-AmazonEC2ContainerRegistryReadOnly, ] }
3. AWS Cli Authentication
aws default profile을 설정하여 aws 인증정보를 입력한다.$ aws configure // **설정이 안되어 있으면 None 으로 설정되어 있다.** AWS Access Key ID [None]: AWS Secret Access Key [None]: Default region name [None]: Default output format [None]:
위에서 저장해둔 IAM User의 Access Key와 Secret Key를 입력한다.
region과 output format은 각각 “ap-northeast-2”, “json” 으로 입력한다.
$ aws configure AWS Access Key ID [None]: ****************NG6K AWS Secret Access Key [None]: ****************WSQh Default region name [None]: ap-northeast-2 Default output format [None]: json
설정이 완료 됐으면 Default Profile로 설정한다. (IAM User Nickname)
$ export AWS_DEFAULT_PROFILE=honggildong
4. EKS 생성
Terraform Initialization- Terraform을 사용하기 위해 초기화를 하는 작업이다.
$ terraform init
Terraform plan
- .tf 파일의 내용을 실제로 적용 가능한지 확인하는 작업이며 추가, 삭제 되는 내용을 출력해준다.
$ terraform plan
Terraform apply
- .tf 파일의 리소스를 생성, 수정, 삭제하는 작업이다. 현재는 최초로 실행하기 때문에 리소스를 생성만 한다.
$ terraform apply
- apply 실행 전에 아래와 같이 진행여부를 물어보는 Enter a value 문구가 뜨면 yes 라고 입력한다.
5. Kubectl 설정
- kubectl을 통해 접근하기 위해, aws 인증 정보를 output.tf 을 통해 생성한다.
$ terraform output -raw kubeconfig > ~/.kube/config $ kubectl get namespaces # kubectl로 접근이 가능한지 test # Kubenetes Master 노드의 ConfigMap에 대해 EKS 클러스터가 접근할 수 있도록 설정 $ terraform output -raw config_map_aws_auth > configmap.yml $ kubectl apply -f configmap.yml # output.tf 파일 변경시 $ terraform refresh
6. Install Nginx-Ingress
- Helm을 이용해 nginx-stable 레포지토리를 추가하고 stable chart를 설치한다.
$ helm repo add nginx-stable https://helm.nginx.com/stable $ helm repo update $ helm install nginx nginx-stable/nginx-ingress --set rbac.create=true
- 아래와 같이 ingress가 running 중인 것을 확인한다.
$ kubectl get pod NAME READY STATUS RESTARTS AGE nginx-nginx-ingress-68d844db84-hchc9 1/1 Running 0 42s
7. 샘플 Deployment, Service, Ingress yaml 생성
- 편의상 한번에 Directory Path로 apply를 하기 위해서 mgmt/ingress Directory 하위의 yaml 파일에
Deployment, Service, Ingress 정의
>apiVersion: v1 kind: Namespace metadata: name: web --- apiVersion: apps/v1 kind: Deployment metadata: name: web-server namespace: web spec: selector: matchLabels: app: web template: metadata: labels: app: web spec: containers: - name: httpd image: httpd:2.4.48-alpine3.14 ports: - containerPort: 80 --- apiVersion: v1 kind: Service metadata: name: web-server-service namespace: web spec: selector: app: web ports: - protocol: TCP port: 5000 targetPort: 80 --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: web-server-ingress namespace: web spec: ingressClassName: nginx rules: - host: web.example.com http: paths: - path: / pathType: Prefix backend: service: name: web-server-service port: number: 80
7-1. Deployment, Service, Ingress yaml 실행
$ kubectl apply -f ./mgmt/ingress/single-load-balancer-app.yaml
7-2. Deployment, Service, Ingress 확인
- web namespace 확인
$ kubectl get namespace
- nginx-ingress controller 확인
$ kubectl get svc kubernetes ClusterIP 172.20.0.1 <none> 443/TCP 5h nginx-nginx-ingress LoadBalancer 172.20.77.13 a17c46026a89c46769b6ac5dd21b5a87-878311181.ap-northeast-2.elb.amazonaws.com 80:31128/TCP,443:32175/TCP 144m
- pod, service, deployment, ingress 확인
$ kubectl get pods,services,deployment,ingress --namespace=web NAME READY STATUS RESTARTS AGE pod/web-server-74cbbc97fc-v48rx 1/1 Running 0 17m NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE service/web-server-service ClusterIP 172.20.93.124 <none> 5000/TCP 17m NAME READY UP-TO-DATE AVAILABLE AGE deployment.apps/web-server 1/1 1 1 17m NAME CLASS HOSTS ADDRESS PORTS AGE ingress.networking.k8s.io/web-server-ingress nginx web.example.com a17c46026a89c46769b6ac5dd21b5a87-878311181.ap-northeast-2.elb.amazonaws.com 80 17m
- 정의한 Ingress 파일 코드 중에 ingressClassName: nginx는 nginx-ingress 사용 의미
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: web-server-ingress namespace: web spec: ingressClassName: nginx ......
- nginx-ingress name 확인
$ kubectl edit service nginx-nginx-ingress apiVersion: v1 kind: Service metadata: annotations: meta.helm.sh/release-name: nginx meta.helm.sh/release-namespace: default creationTimestamp: "2022-06-07T03:09:35Z" finalizers: - service.kubernetes.io/load-balancer-cleanup labels: app.kubernetes.io/instance: nginx app.kubernetes.io/managed-by: Helm app.kubernetes.io/name: nginx-nginx-ingress helm.sh/chart: nginx-ingress-0.13.1 name: nginx-nginx-ingress .......
7-3. Access 확인
curl a17c46026a89c46769b6ac5dd21b5a87-878311181.ap-northeast-2.elb.amazonaws.com -H "Host: web.example.com" # curl 결과 확인 <html><body><h1>It works!</h1></body></html>
EKS 예제 구축 끝 🥊
References
반응형'kubernetes' 카테고리의 다른 글
[Kubernetes] Object (0) 2022.10.23 [Kubernetes] Component (0) 2022.10.23 [Kubernetes] Basic concepts (0) 2022.10.23