Scaleway 베어메탈 ARM 및 x86-64에서 Kubernetes를 설정하는 방법에 대한 단계별 가이드입니다. 제가 이 프로젝트를 진행한 주된 이유는 OpenFaaS 및 Weave Net on ARM을 위한 테스트 환경 생성을 자동화하고 싶었기 때문입니다. 저는 통합 테스트를 실행할 저렴한 솔루션을 찾고 있었고 여러 클라우드 제공업체를 시도한 후 Scaleway에 정착했습니다. Scaleway는 저렴한 가격에 베어메탈 ARM 및 x86-64 서버를 제공하는 프랑스 클라우드 제공업체입니다. kubeadm과 함께 Terraform Scaleway 공급자를 사용하면 10분 안에 완벽하게 작동하는 Kubernetes 클러스터를 가질 수 있습니다. 초기 설정 저장소를 복제하고 종속 항목을 설치합니다. $ git 클론 httpsgithub.com/stefanprodan/k8s-scw-baremetal.git $ cd k8s-scw-baremetal $ terraform 초기화 이 프로젝트를 실행하려면 Terraform v0.10 이상이 필요합니다. 프로젝트를 실행하기 전에 Scaleway API에 연결할 Terraform용 액세스 토큰을 생성해야 합니다. 토큰과 액세스 키를 사용하여 두 개의 환경 변수를 만듭니다. $ 수출 SCALEWAY_ORGANIZATIONACCESS-KEY>"$ 수출 SCALEWAY_TOKENACCESS-TOKEN>"용법 하나의 마스터와 두 개의 노드가 있는 ARMv7 베어메탈 Kubernetes 클러스터를 만듭니다. $ terraform 작업 공간 새 arm $ terraform 적용 \ -var region=par1 \ -var arch=arm \ -var server_type=C1 \ -var nodes=2 \ -var weave_passwd=ChangeMe \ -var k8s_version=stable-1.9 \ -var docker_version =17.03.0~ce-0~ubuntu-xenial 이렇게 하면 다음이 수행됩니다. - 각 서버에 대해 공용 IP를 예약합니다. - Ubuntu 16.04.1 LTS로 베어메탈 서버 3개 프로비저닝 - SSH를 통해 마스터 서버에 연결하고 Docker CE 및 kubeadm armhf apt 패키지를 설치합니다. - 마스터 서버에서 kubeadm init 실행 및 kubectl 구성 - 로컬 컴퓨터에 kubectl 관리 구성 파일을 다운로드하고 사설 IP를 공용 IP로 바꿉니다. - Weave Net 비밀번호로 Kubernetes 시크릿 생성 - 암호화된 오버레이로 Weave Net 설치 - 클러스터 애드온 설치(Kubernetes 대시보드, 메트릭 서버 및 Heapster) - 작업자 노드를 병렬로 시작하고 Docker CE 및 kubeadm을 설치합니다. - 마스터에서 얻은 kubeadm 토큰을 사용하여 클러스터의 작업자 노드를 조인합니다. 노드 수를 늘려 수직 확장: $ terraform 적용 -var 노드=3 다음을 사용하여 전체 인프라를 해체합니다. 테라포밍 하나의 마스터와 노드가 있는 AMD64 베어메탈 Kubernetes 클러스터를 생성합니다. $ terraform 작업 공간 새 amd64 $ terraform 적용 \ -var region=par1 \ -var arch=x86_64 \ -var server_type=C2S \ -var nodes=1 \ -var weave_passwd=ChangeMe \ -var k8s_version=stable-1.9 \ -var docker_version =17.03.0~ce-0~ubuntu-xenial 리모콘 Terraform 계획을 적용하면 마스터 공용 IP, kubeadmn 조인 명령 및 현재 작업 공간 관리자 구성과 같은 여러 출력 변수가 표시됩니다. 실행하려면 Scaleway 클러스터에 대한 kubectl 명령을 사용할 수 있습니다. kubectl_config 출력 변수: Heapster가 작동하는지 확인하십시오. $ kubectl --kubeconfig terraform 출력 kubectl_config) 최상위 노드 이름 CPU(코어) CPU% MEMORY(바이트) MEMORY% arm-master-1 655m 16% 873Mi 45% arm-node-1 147m 3% 618Mi 32% arm-node- 2 101m 2% 584Mi 30% 그만큼 kubectl 구성 파일 형식은 .conf as in arm.conf or amd64.conf In order to access the dashboard you’ll need to find its cluster IP: $ kubectl --kubeconfig terraform output kubectl_config) \ -n kube-system get svc --selector=k8s-app=kubernetes-dashboard NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes-dashboard ClusterIP 10.107.37.220 80/TCP 6m Open a SSH tunnel: ssh -L 8888::80 [email protected] Now you can access the dashboard on your computer at httplocalhost:8888 Expose services outside the cluster Since we’re running on bare-metal and Scaleway doesn’t offer a load balancer, the easiest way to expose applications outside of Kubernetes is using a NodePort service Let’s deploy the podinfo app in the default namespace. Podinfo has a multi-arch Docker image and it will work on arm, arm64 or amd64 Create the podinfo nodeport service: $ kubectl --kubeconfig terraform output kubectl_config) \ apply -f httpsraw.githubusercontent.com/stefanprodan/k8s-podinfo/master/deploy/auto-scaling/podinfo-svc-nodeport.yaml service "podinfo-nodeport" created Create the podinfo deployment: $ kubectl --kubeconfig terraform output kubectl_config) \ apply -f httpsraw.githubusercontent.com/stefanprodan/k8s-podinfo/master/deploy/auto-scaling/podinfo-dep.yaml deployment "podinfo" created Inspect the podinfo service to obtain the port number: $ kubectl --kubeconfig terraform output kubectl_config) \ get svc --selector=app=podinfo NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE podinfo-nodeport NodePort 10.104.132.14 9898:31190/TCP 3m You can access podinfo at httpMASTER_PUBLIC_IP>:31190 or using curl: $ curl httpterraform output k8s_master_public_ip):31190 runtime: arch: arm max_procs: "4" num_cpu: "4" num_goroutine: "12" os: linux version: go1.9.2 labels: app: podinfo pod-template-hash: "1847780700" annotations: kubernetes.io/config.seen: 2018-01-08T00:39:45.580597397Z kubernetes.io/config.source: api environment: HOME: /root HOSTNAME: podinfo-5d8ccd4c44-zrczc KUBERNETES_PORT: tcp10.96.0.1:443 KUBERNETES_PORT_443_TCP: tcp10.96.0.1:443 KUBERNETES_PORT_443_TCP_ADDR: 10.96.0.1 KUBERNETES_PORT_443_TCP_PORT: "443" KUBERNETES_PORT_443_TCP_PROTO: tcp KUBERNETES_SERVICE_HOST: 10.96.0.1 KUBERNETES_SERVICE_PORT: "443" KUBERNETES_SERVICE_PORT_HTTPS: "443" PATH: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin externalIP: IPv4: 163.172.139.112 OpenFaaS You can deploy OpenFaaS on Kubernetes with Helm or by using the YAML files form the faas-netes repository Clone the faas-netes repo: git clone httpsgithub.com/openfaas/faas-netes cd faas-netes Deploy OpenFaaS for ARM: $ kubectl --kubeconfig terraform output kubectl_config) \ apply -f ./namespaces.ymlyaml_armhf Deploy OpenFaaS for AMD64: $ kubectl --kubeconfig terraform output kubectl_config) \ apply -f ./namespaces.ymlyaml You can access the OpenFaaS gateway at httpMASTER_PUBLIC_IP>:31112 Horizontal Pod Autoscaling Starting from Kubernetes 1.9 kube-controller-manager is configured by default with horizontal-pod-autoscaler-use-rest-clients In order to use HPA we need to install the metrics server to enable the new metrics API used by HPA v2 Both Heapster and the metrics server have been deployed from Terraform when the master node was provisioned The metric server collects resource usage data from each node using Kubelet Summary API. Check if the metrics server is running: $ kubectl --kubeconfig terraform output kubectl_config) \ get --raw "/apis/metrics.k8s.io/v1beta1/nodes" | jq { "kind": "NodeMetricsList", "apiVersion": "metrics.k8s.io/v1beta1", "metadata": { "selfLink": "/apis/metrics.k8s.io/v1beta1/nodes" }, "items": [ { "metadata": { "name": "arm-master-1", "selfLink": "/apis/metrics.k8s.io/v1beta1/nodes/arm-master-1", "creationTimestamp": "2018-01-08T15:17:09Z" }, "timestamp": "2018-01-08T15:17:00Z", "window": "1m0s", "usage": { "cpu": "384m", "memory": "935792Ki" } }, { "metadata": { "name": "arm-node-1", "selfLink": "/apis/metrics.k8s.io/v1beta1/nodes/arm-node-1", "creationTimestamp": "2018-01-08T15:17:09Z" }, "timestamp": "2018-01-08T15:17:00Z", "window": "1m0s", "usage": { "cpu": "130m", "memory": "649020Ki" } }, { "metadata": { "name": "arm-node-2", "selfLink": "/apis/metrics.k8s.io/v1beta1/nodes/arm-node-2", "creationTimestamp": "2018-01-08T15:17:09Z" }, "timestamp": "2018-01-08T15:17:00Z", "window": "1m0s", "usage": { "cpu": "120m", "memory": "614180Ki" } } ] } Let’s define a HPA that will maintain a minimum of two replicas and will scale up to ten if the CPU average is over 80% or if the memory goes over 200Mi apiVersion: autoscaling/v2beta1 kind: HorizontalPodAutoscaler metadata: name: podinfo spec: scaleTargetRef: apiVersion: apps/v1beta1 kind: Deployment name: podinfo minReplicas: 2 maxReplicas: 10 metrics: - type: Resource resource: name: cpu targetAverageUtilization: 80 - type: Resource resource: name: memory targetAverageValue: 200Mi Apply the podinfo HPA: $ kubectl --kubeconfig terraform output kubectl_config) \ apply -f httpsraw.githubusercontent.com/stefanprodan/k8s-podinfo/master/deploy/auto-scaling/podinfo-hpa.yaml horizontalpodautoscaler "podinfo" created After a couple of seconds the HPA controller will contact the metrics server and will fetch the CPU and memory usage: $ kubectl --kubeconfig terraform output kubectl_config) get hpa NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE podinfo Deployment/podinfo 2826240 / 200Mi, 15% / 80% 2 10 2 5m In order to increase the CPU usage we could run a load test with hey: #install hey go get -u github.com/rakyll/hey #do 10K requests rate limited at 20 QPS hey -n 10000 -q 10 -c 5 httpterraform output k8s_master_public_ip):31190 You can monitor the autoscaler events with: $ kubectl --kubeconfig terraform output kubectl_config) describe hpa Events: Type Reason Age From MessageNormal SuccessfulRescale 7m horizontal-pod-autoscaler New size: 4; reason: cpu resource utilization (percentage of request) above target Normal SuccessfulRescale 3m horizontal-pod-autoscaler New size: 8; reason: cpu resource utilization (percentage of request) above target After the load tests finishes the autoscaler will remove replicas until the deployment reaches the initial replica count: Events: Type Reason Age From MessageNormal SuccessfulRescale 20m horizontal-pod-autoscaler New size: 4; reason: cpu resource utilization (percentage of request) above target Normal SuccessfulRescale 16m horizontal-pod-autoscaler New size: 8; reason: cpu resource utilization (percentage of request) above target Normal SuccessfulRescale 12m horizontal-pod-autoscaler New size: 10; reason: cpu resource utilization (percentage of request) above target Normal SuccessfulRescale 6m horizontal-pod-autoscaler New size: 2; reason: All metrics below target Conclusions Thanks to kubeadm and Terraform, bootstrapping a Kubernetes cluster on bare-metal can be done with a single command and it takes just ten minutes to have a fully functional setup. If you have any suggestion on improving this guide please submit an issue or PR on GitHub at stefanprodan/k8s-scw-baremetal. Contributions are more than welcome!