--- tags: Study --- # EKS Fargate and Kubeless --- # EKS Fargate Demonstrate the setup of EKS Fargate including 1. Create cluster 2. Deploy an app ## Installation 1. auto install: `eksctl` 2. manual install: AWS mgmt console ### Install by eksctl [reference link](https://docs.aws.amazon.com/eks/latest/userguide/getting-started-eksctl.html) Prerequirement: 1. AWS CLI 2. [eksctl](https://docs.aws.amazon.com/eks/latest/userguide/getting-started-eksctl.html#install-eksctl) - `curl --silent --location "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp` - `sudo mv /tmp/eksctl /usr/local/bin` - `eksctl version` 4. [kubectl](https://docs.aws.amazon.com/eks/latest/userguide/getting-started-eksctl.html#eksctl-gs-install-kubectl) - `curl -o kubectl https://amazon-eks.s3.us-west-2.amazonaws.com/1.18.9/2020-11-02/bin/linux/amd64/kubectl` - `chmod +x ./kubectl` - `sudo mv ./kubectl /usr/local/bin` - `kubectl version --short --client` Install: `eksctl create cluster --name k800s --version 1.18 --region us-east-1 --fargate` If you encounter an error like: > Cannot create cluster 'k800s' because us-east-1e, the targeted availability zone, does not currently have sufficient capacity to support the cluster you can add an option: `--zones=us-east-1a,us-east-1b` ### Create a `kubeconfig` for Amazon EKS [reference link](https://docs.aws.amazon.com/eks/latest/userguide/create-kubeconfig.html) If EKS is installed by `eksctl`, the `kubeconfig` would be installed as well > kubectl get nodes > kubectl get svc ### Config fargate profile to enable computing [reference link](https://docs.aws.amazon.com/eks/latest/userguide/fargate-getting-started.html#fargate-gs-create-profile) `eksctl create fargateprofile --cluster k800s --name fp-my-namespace --namespace my-namespace` ### Grant portal users [reference link](https://docs.aws.amazon.com/eks/latest/userguide/add-user-role.html) 1. `kubectl edit -n kube-system configmap/aws-auth` 2. Add user role into `aws-auth`, ex. line 9-12 ```yaml= apiVersion: v1 data: mapRoles: | - rolearn: arn:aws:iam::account-id:role/eksctl-k800s-cluster-FargatePodExecutionRole-12S280531CHV9 username: system:node:{{EC2PrivateDNSName}} groups: - system:bootstrappers - system:nodes - rolearn: arn:aws:iam::account-id:role/ADFS-ADMIN username: admin groups: - system:masters ``` ### Enable ALB Ingress [reference link](https://docs.aws.amazon.com/zh_tw/eks/latest/userguide/alb-ingress.html) 1. Create IAM OIDC ```bash= eksctl utils associate-iam-oidc-provider \ --region <region-code> \ --cluster <my-cluster> \ --approve ``` 2. Download [iam-policy.json](https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/main/docs/install/iam_policy.json) 3. Create iam policy ```bash= aws iam create-policy \ --policy-name <AWSLoadBalancerControllerIAMPolicy> \ --policy-document file://iam-policy.json ``` 4. Create service account ```bash= eksctl create iamserviceaccount \ --cluster=<my-cluster> \ --namespace=kube-system \ --name=aws-load-balancer-controller \ --attach-policy-arn=arn:aws:iam::<AWS_ACCOUNT_ID>:policy/<AWSLoadBalancerControllerIAMPolicy> \ --override-existing-serviceaccounts \ --approve ``` 5. Install ALB controller by `helm` - `kubectl apply -k "github.com/aws/eks-charts/stable/aws-load-balancer-controller//crds?ref=master"` - `helm repo add eks https://aws.github.io/eks-charts` - helm upgrade ```bash= helm upgrade -i aws-load-balancer-controller eks/aws-load-balancer-controller \ --set clusterName=k800s \ --set serviceAccount.create=false \ --set serviceAccount.name=aws-load-balancer-controller \ --set region=us-east-1 \ --set vpcId=<vpc> \ -n kube-system ``` > region and vpcId are important in order to avoid "failed to introspect region from EC2Metadata, specify --aws-region instead if EC2Metadata is unavailable" ## Deploy apps [reference link](https://docs.aws.amazon.com/eks/latest/userguide/sample-deployment.html) 1. `kubectl create namespace my-namespace` 2. Perpare a sample config ```yaml= apiVersion: v1 kind: Service metadata: name: my-service namespace: my-namespace labels: app: my-app spec: selector: app: my-app ports: - protocol: TCP port: 80 targetPort: 80 --- apiVersion: apps/v1 kind: Deployment metadata: name: my-deployment namespace: my-namespace labels: app: my-app spec: replicas: 3 selector: matchLabels: app: my-app template: metadata: labels: app: my-app spec: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: beta.kubernetes.io/arch operator: In values: - amd64 - arm64 containers: - name: nginx image: public.ecr.aws/z9d2n7e1/nginx:1.19.5 ports: - containerPort: 80 ``` 3. Deploy service - `kubectl apply -f sample-service.yaml` 5. Verify pods - `kubectl get all -n my-namespace` 5. View pods - `kubectl -n my-namespace describe pod my-deployment-5cbcfc6d74-bc562` - `kubectl exec -it my-deployment-5cbcfc6d74-bc562 -n my-namespace -- /bin/bash` ### Deploy App using ALB 1. `eksctl create fargateprofile --cluster <my-cluster> --region <region-code> --name <alb-sample-app> --namespace game-2048` 2. `kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/aws-load-balancer-controller/main/docs/examples/2048/2048_full.yaml` 3. Verify: `kubectl get ingress/ingress-2048 -n game-2048` > annotations: `kubernetes.io/ingress.class` and `alb.ingress.kubernetes.io/target-type` ```yaml= apiVersion: extensions/v1beta1 kind: Ingress metadata: namespace: game-2048 name: ingress-2048 annotations: kubernetes.io/ingress.class: alb alb.ingress.kubernetes.io/scheme: internet-facing alb.ingress.kubernetes.io/target-type: ip spec: rules: - http: paths: - path: /* backend: serviceName: service-2048 servicePort: 80 ``` --- # Kubeless [reference link](https://kubeless.io/docs/quick-start/) 1. Create Farget profile - `eksctl create fargateprofile --cluster k800s --name fp-kubeless --namespace kubeless` 2. Create kubeless controller ```bash= export RELEASE=$(curl -s https://api.github.com/repos/kubeless/kubeless/releases/latest | grep tag_name | cut -d '"' -f 4) kubectl create ns kubeless kubectl create -f https://github.com/kubeless/kubeless/releases/download/$RELEASE/kubeless-$RELEASE.yaml kubectl get pods -n kubeless ``` 3. Install `kubeless` ```bash= export OS=$(uname -s| tr '\[:upper:\]' '\[:lower:\]') curl -OL https://github.com/kubeless/kubeless/releases/download/$RELEASE/kubeless_$OS-amd64.zip unzip kubeless_$OS-amd64.zip sudo mv bundles/kubeless_$OS-amd64/kubeless /usr/local/bin/ ``` 4. Prepare a sample function - `test.py` ```python= def hello(event, context): print event return event['data'] ``` 5. Deploy sample - `kubeless function deploy hello --runtime python2.7 --from-file test.py --handler test.hello` - Verify: `kubeless function ls` 6. Invoke sample - `kubeless function call hello --data 'Hello world!'` ## More Complex Example How to use `requirements.txt` to pack dependencies? ```bash= git clone https://github.com/kubeless/kubeless.git cd kubeless/examples/ make get-python-deps kubeless function ls get-python-deps ``` View in details ```bash= cd python && zip hellowithdeps.zip hellowithdeps.py hellowithdepshelper.py && cd .. kubeless function deploy get-python-deps --runtime python3.7 --handler hellowithdeps.foo --from-file python/hellowithdeps.zip --dependencies python/requirements.txt kubeless function call get-python-deps |egrep Google ``` ## Troubleshooting [reference link](https://kubeless.io/docs/debug-functions/) - Get pods - `kubectl get pods -l function=get-python-deps` ## Kinesis Trigger Controller [reference link](https://aws.amazon.com/tw/blogs/opensource/data-processing-pipeline-kinesis-kubeless/) ## Serverless ``` - "serverless-kubeless": "^0.7.0" + "serverless-kubeless": "^0.11.0" ``` > v0.7.x encounter an [issue](https://github.com/serverless/serverless-kubeless/issues/140) > v0.11.x passed --- # Reference 1. [Troubleshoot deployment](https://learnk8s.io/troubleshooting-deployments) 2. [Deep dive into kubeless](https://www.alibabacloud.com/blog/kubeless-a-deep-dive-into-serverless-kubernetes-frameworks-1_594901)