[DOCKER] Démo AWS EKS ~

1. Création d'un environnement CLOUD9

1-1. Création d'un environnement CLOUD9

Tous ces travaux pratiques se dérouleront en «Virginie du Nord».

Ouvrez "Cloud 9" et créez-le avec les exigences suivantes.

Step 1 Name environment

Nom: indiquez un nom.

Step 2 Configure settings

Les bases sont les suivantes, toutes sont par défaut.

Environment type:Create a new EC2 instance for environment (direct access) Instance type:t2.micro (1 GiB RAM + 1 vCPU) Platform:Amazon Linux Réseau (VPC): spécifiez n'importe quel VPC pour spécifier le sous-réseau public.

Step 3 Review

Cliquez sur le bouton "Créer un environnement".

1-2. Créer un rôle IAM et l'attribuer à EC2

Créez un rôle IAM avec la stratégie IAM suivante et attachez-le à EC2.

AdministratorAccess

1-3. Invalidation temporaire des informations d'identification

Cloud9 a la capacité de définir automatiquement des informations d'identification temporaires pour les utilisateurs IAM, Ces informations d'identification temporaires sont limitées à certaines actions telles que IAM, donc Désactivez ces informations d'identification temporaires pour utiliser le rôle IAM attribué à l'instance EC2.

Ouvrez l'icône en forme d'engrenage dans l'angle supérieur droit, ouvrez le menu Paramètres AWS et désactivez les informations d'identification temporaires gérées par AWS. スクリーンショット 2020-10-26 21.46.57.png

1-4. Paramètres initiaux de l'AWS CLI

leomaro7:~/environment $ rm -vf ${HOME}/.aws/credentials
leomaro7:~/environment $ aws --version
aws-cli/1.18.162 Python/3.6.12 Linux/4.14.193-113.317.amzn1.x86_64 botocore/1.19.2
leomaro7:~/environment $ AWS_REGION="us-east-1"
leomaro7:~/environment $ aws configure set default.region ${AWS_REGION}
leomaro7:~/environment $ aws configure get default.region
us-east-1
leomaro7:~/environment $ aws sts get-caller-identity
{
    "UserId": "",
    "Account": "",
    "Arn": ""
}

2. Création d'un cluster

2-1. Installation d'eksctl

eksctl: commande utilisée pour créer le cluster Kubernetes lui-même

leomaro7:~/environment $ curl -L "https://github.com/weaveworks/eksctl/releases/latest/download/eksctl_$(uname -s)_amd64.tar.gz" | tar xz -C /tmp
leomaro7:~/environment $ sudo mv /tmp/eksctl /usr/local/bin
leomaro7:~/environment $ eksctl version
0.30.0

eksctl - The official CLI for Amazon EKS

2-2. Installation de kubectl

kubectl: commandes utilisées pour faire fonctionner le cluster Kubernetes créé

leomaro7:~/environment $ sudo curl -L -o /usr/local/bin/kubectl https://amazon-eks.s3.us-west-2.amazonaws.com/1.17.7/2020-07-08/bin/linux/amd64/kubectl
leomaro7:~/environment $ sudo chmod +x /usr/local/bin/kubectl
leomaro7:~/environment $ kubectl version --short --client
Client Version: v1.17.7-eks-bffbac

2-3. Création d'un cluster

AWS_REGION=$(aws configure get default.region)
eksctl create cluster \
  --name=ekshandson \
  --version 1.17 \
  --nodes=3 --managed \
  --region ${AWS_REGION} --zones ${AWS_REGION}a,${AWS_REGION}c

--En plus de la méthode de transmission de l'option de réglage en tant qu'argument, il est également possible de décrire le paramètre en YAML et de spécifier ce YAML en tant qu'argument.

2-4. Introduction d’outils pratiques et paramétrage de l’achèvement des commandes

jq et bash-completion

jq: commande pratique pour traiter les données json bash-completion: Achèvement des commandes sur le shell bash

sudo yum -y install jq bash-completion

docker, docker-compose et achèvement de la commande

sudo curl -L -o /etc/bash_completion.d/docker https://raw.githubusercontent.com/docker/cli/master/contrib/completion/bash/docker
sudo curl -L -o /usr/local/bin/docker-compose "https://github.com/docker/compose/releases/download/1.26.2/docker-compose-$(uname -s)-$(uname -m)"
sudo chmod +x /usr/local/bin/docker-compose
sudo curl -L -o /etc/bash_completion.d/docker-compose https://raw.githubusercontent.com/docker/compose/1.26.2/contrib/completion/bash/docker-compose

Achèvement de la commande kubectl

kubectl completion bash > kubectl_completion
sudo mv kubectl_completion /etc/bash_completion.d/kubectl

Achèvement de la commande eksctl

eksctl completion bash > eksctl_completion
sudo mv eksctl_completion /etc/bash_completion.d/eksctl

k (alias)

cat <<"EOT" >> ${HOME}/.bash_profile

alias k="kubectl"
complete -o default -F __start_kubectl k
EOT

kube-ps1###

kube-ps1: invite le contexte kubectl actuel et l'espace de noms.

git clone https://github.com/jonmosco/kube-ps1.git ~/.kube-ps1
cat <<"EOT" >> ~/.bash_profile

source ~/.kube-ps1/kube-ps1.sh
function get_cluster_short() {
  echo "$1" | cut -d . -f1
}
KUBE_PS1_CLUSTER_FUNCTION=get_cluster_short
KUBE_PS1_SUFFIX=') '
PS1='$(kube_ps1)'$PS1
EOT

kubectx / kubens###

kubectx et kubens: kubectx et kubens Cela facilite le changement de contexte et d'espace de noms de kubectl.

git clone https://github.com/ahmetb/kubectx.git ~/.kubectx
sudo ln -sf ~/.kubectx/completion/kubens.bash /etc/bash_completion.d/kubens
sudo ln -sf ~/.kubectx/completion/kubectx.bash /etc/bash_completion.d/kubectx
cat <<"EOT" >> ~/.bash_profile

export PATH=~/.kubectx:$PATH
EOT

stern###

stern: Vérifiez le journal du conteneur

sudo curl -L -o /usr/local/bin/stern https://github.com/wercker/stern/releases/download/1.11.0/stern_linux_amd64
sudo chmod +x /usr/local/bin/stern

Fermez l'onglet dans le terminal actuel et ouvrez l'onglet dans le nouveau terminal pour que les paramètres ajoutés à ~ / .bash_profile prennent effet.

3. Vérifiez le cluster

3-1. Vérification du cluster

Affiche le cluster actuel et des informations de base sur le cluster.

leomaro7:~/environment $ eksctl get cluster
NAME            REGION
ekshandson      us-east-1

leomaro7:~/environment $ kubectl cluster-info
Kubernetes master is running at https://25FF2316ECD9ED0E8D621ED7DCFD6263.gr7.us-east-1.eks.amazonaws.com
CoreDNS is running at https://25FF2316ECD9ED0E8D621ED7DCFD6263.gr7.us-east-1.eks.amazonaws.com/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

3-2. Confirmation du nœud

Vérifiez les nœuds qui appartiennent au cluster, la capacité des nœuds et les pods en cours d'exécution.

leomaro7:~/environment $ kubectl get node
NAME                            STATUS   ROLES    AGE   VERSION
ip-192-168-4-184.ec2.internal   Ready    <none>   13m   v1.17.11-eks-cfdc40
ip-192-168-56-48.ec2.internal   Ready    <none>   13m   v1.17.11-eks-cfdc40
ip-192-168-6-63.ec2.internal    Ready    <none>   13m   v1.17.11-eks-cfdc40

leomaro7:~/environment $ kubectl describe node ip-192-168-4-184.ec2.internal

3-3. Confirmation de NAME SPACE

Espace de noms: un regroupement de ressources Kubernetes telles que des pods et des services.

Vérifier l'espace de noms

leomaro7:~/environment $ kubectl get namespace
NAME              STATUS   AGE
default           Active   24m
kube-node-lease   Active   24m
kube-public       Active   24m
kube-system       Active   24m

Pod: la plus petite unité de déploiement dans Kubernetes, avec un ou plusieurs conteneurs s'exécutant dans un pod.

↓ est le pod du contenu de l'espace de noms: par défaut (bien sûr pas encore)

leomaro7:~/environment $ kubectl get pod -n default
No resources found in default namespace.

Changement de l'espace de noms par défaut en kube-system à l'aide de kubens.

leomaro7:~/environment $ kubens kube-system
Context "[email protected]" modified.
Active namespace is "kube-system".

Dans kube-system, des pods comme ↓ sont en cours d'exécution.

leomaro7:~/environment $ kubectl get pod -n kube-system
NAME                       READY   STATUS    RESTARTS   AGE
aws-node-2p7s2             1/1     Running   0          26m
aws-node-cmmkc             1/1     Running   0          26m
aws-node-vbp6f             1/1     Running   0          26m
coredns-75b44cb5b4-cktx9   1/1     Running   0          31m
coredns-75b44cb5b4-lq58q   1/1     Running   0          31m
kube-proxy-c6td9           1/1     Running   0          26m
kube-proxy-jxwc6           1/1     Running   0          26m

Utilisez l'option -A pour obtenir des informations sur tous les espaces de noms.

leomaro7:~/environment $ kubectl get pod -A
NAMESPACE     NAME                       READY   STATUS    RESTARTS   AGE
kube-system   aws-node-2p7s2             1/1     Running   0          27m
kube-system   aws-node-cmmkc             1/1     Running   0          27m
kube-system   aws-node-vbp6f             1/1     Running   0          27m
kube-system   coredns-75b44cb5b4-cktx9   1/1     Running   0          32m
kube-system   coredns-75b44cb5b4-lq58q   1/1     Running   0          32m
kube-system   kube-proxy-c6td9           1/1     Running   0          27m
kube-system   kube-proxy-jxwc6           1/1     Running   0          27m
kube-system   kube-proxy-z454c           1/1     Running   0          27m

4. Déployez l'exemple d'application

4-1. Création d'une table DynamoDB

aws dynamodb create-table --table-name 'messages' \
  --attribute-definitions '[{"AttributeName":"uuid","AttributeType": "S"}]' \
  --key-schema '[{"AttributeName":"uuid","KeyType": "HASH"}]' \
  --provisioned-throughput '{"ReadCapacityUnits": 1,"WriteCapacityUnits": 1}'

4-2. Création d'une image Docker

Si vous avez déplacé le répertoire, replacez-le dans le répertoire ~ / environment /.

cd ~/environment/

DL l'exemple d'application et décompressez-le.

wget https://eks-for-aws-summit-online.workshop.aws/sample-app.zip
unzip sample-app.zip

Construisez avec docker-compose.

cd sample-app
docker-compose build

Confirmez qu'il a été construit.

docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
backend             latest              412ec271d5e7        11 seconds ago      107MB
frontend            latest              fa4eba7cd29c        20 seconds ago      57.7MB
python              3-alpine            dc68588b1801        6 days ago          44.3MB

4-3. Enregistrement de l'image dans ECR

Créez un référentiel ECR.

aws ecr create-repository --repository-name frontend
aws ecr create-repository --repository-name backend

Obtenez l'URL du référentiel et stockez-la dans une variable.

frontend_repo=$(aws ecr describe-repositories --repository-names frontend --query 'repositories[0].repositoryUri' --output text)
backend_repo=$(aws ecr describe-repositories --repository-names backend --query 'repositories[0].repositoryUri' --output text)

Alias l'image que vous venez de créer avec le nom d'URL du référentiel ECR.

docker tag frontend:latest ${frontend_repo}:latest
docker tag backend:latest ${backend_repo}:latest

Vérifiez l'image avec un autre nom.

docker images
REPOSITORY                                              TAG                 IMAGE ID            CREATED             SIZE
4.dkr.ecr.us-east-1.amazonaws.com/backend    latest              412ec271d5e7        2 minutes ago       107MB
4.dkr.ecr.us-east-1.amazonaws.com/frontend   latest              fa4eba7cd29c        2 minutes ago       57.7MB

Connectez-vous à ECR.

ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
AWS_REGION=$(aws configure get default.region)
aws ecr get-login-password | docker login --username AWS --password-stdin https://${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com

Poussez l'image vers ECR.

docker push ${frontend_repo}:latest
docker push ${backend_repo}:latest

4. Déployez l'application

Créer un répertoire de travail.

mkdir -p ~/environment/manifests/
cd ~/environment/manifests/

Créer un espace de noms pour l'application 1. Également changé l'espace de noms par défaut.

kubectl create namespace frontend
kubens frontend

Créer un déploiement

python


frontend_repo=$(aws ecr describe-repositories --repository-names frontend --query 'repositories[0].repositoryUri' --output text)
cat <<EOF > frontend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: frontend
spec:
  selector:
    matchLabels:
      app: frontend
  replicas: 2
  template:
    metadata:
      labels:
        app: frontend
    spec:
      containers:
      - name: frontend
        image: ${frontend_repo}:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 5000
        env:
        - name: BACKEND_URL
          value: http://backend.backend:5000/messages
EOF
kubectl apply -f frontend-deployment.yaml -n frontend

Vérifiez le déploiement créé.

kubectl get deployment -n frontend
NAME       READY   UP-TO-DATE   AVAILABLE   AGE
frontend   2/2     2            2           13s

Vérifiez le pod.

kubectl get pod -n frontend
NAME                        READY   STATUS    RESTARTS   AGE
frontend-84ccd456fb-l6kjl   1/1     Running   0          53s
frontend-84ccd456fb-wdhwr   1/1     Running   0          53s

Créer un service.

Service: fournit des capacités de résolution de noms et d'équilibrage de charge pour accéder aux pods lancés par le déploiement.

python


cat <<EOF > frontend-service-lb.yaml
apiVersion: v1
kind: Service
metadata:
  name: frontend
spec:
  type: LoadBalancer
  selector:
    app: frontend
  ports:
  - protocol: TCP
    port: 80
    targetPort: 5000
EOF
kubectl apply -f frontend-service-lb.yaml -n frontend

Vérifiez le service créé.

kubectl get service -n frontend
NAME       TYPE           CLUSTER-IP       EXTERNAL-IP                                                               PORT(S)        AGE
frontend   LoadBalancer   10.100.219.241   dd7c90ab25e44a939b065e566aa5432-1872056256.us-east-1.elb.amazonaws.com   80:30374/TCP   10s

Accédez à EXTERNAL-IP et vérifiez s'il est affiché. (Cela prend quelques minutes pour résoudre le nom)

Créer un espace de noms pour l'application 2. Également changé l'espace de noms par défaut.

kubectl create namespace backend
kubens backend

Créer un déploiement.

AWS_REGION=$(aws configure get default.region)
backend_repo=$(aws ecr describe-repositories --repository-names backend --query 'repositories[0].repositoryUri' --output text)
cat <<EOF > backend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: backend
spec:
  selector:
    matchLabels:
      app: backend
  replicas: 2
  template:
    metadata:
      labels:
        app: backend
    spec:
      containers:
      - name: backend
        image: ${backend_repo}:latest
        imagePullPolicy: Always
        ports:
        - containerPort: 5000
        env:
        - name: AWS_DEFAULT_REGION
          value: ${AWS_REGION}
        - name: DYNAMODB_TABLE_NAME
          value: messages
EOF
kubectl apply -f backend-deployment.yaml -n backend

Vérifiez le pod.

kubectl get pod -n backend
NAME                       READY   STATUS    RESTARTS   AGE
backend-7544ddcd98-7lxcx   1/1     Running   0          12s
backend-7544ddcd98-bn5jq   1/1     Running   0          12s

Créer un service.

cat <<EOF > backend-service.yaml
apiVersion: v1
kind: Service
metadata:
  name: backend
spec:
  type: ClusterIP
  selector:
    app: backend
  ports:
  - protocol: TCP
    port: 5000
    targetPort: 5000
EOF
kubectl apply -f backend-service.yaml -n backend

Vérifiez le service créé.

kubectl get service -n backend
NAME      TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)    AGE
backend   ClusterIP   10.100.60.141   <none>        5000/TCP   13s

Essayez à nouveau d'accéder à EXTERNAL-IP.

5.IAM ROLES FOR SERVICE ACCOUNTS#

Utilisez une fonctionnalité EKS appelée Rôles IAM pour les comptes de service pour accorder des rôles IAM aux pods d'application 2 afin d'autoriser l'accès à DynamoDB.

Créez un fournisseur d'identité OIDC et associez-le à votre cluster.

eksctl utils associate-iam-oidc-provider \
    --cluster ekshandson \
    --approve

Créez une stratégie IAM qui autorise un accès complet à la table des messages DynamoDB.

cat <<EOF > dynamodb-messages-fullaccess-policy.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "ListAndDescribe",
            "Effect": "Allow",
            "Action": [
                "dynamodb:List*",
                "dynamodb:DescribeReservedCapacity*",
                "dynamodb:DescribeLimits",
                "dynamodb:DescribeTimeToLive"
            ],
            "Resource": "*"
        },
        {
            "Sid": "SpecificTable",
            "Effect": "Allow",
            "Action": [
                "dynamodb:BatchGet*",
                "dynamodb:DescribeStream",
                "dynamodb:DescribeTable",
                "dynamodb:Get*",
                "dynamodb:Query",
                "dynamodb:Scan",
                "dynamodb:BatchWrite*",
                "dynamodb:CreateTable",
                "dynamodb:Delete*",
                "dynamodb:Update*",
                "dynamodb:PutItem"
            ],
            "Resource": "arn:aws:dynamodb:*:*:table/messages"
        }
    ]
}
EOF
aws iam create-policy \
    --policy-name dynamodb-messages-fullaccess \
    --policy-document file://dynamodb-messages-fullaccess-policy.json

Créez et associez un rôle IAM au ServiceAccount utilisé pour exécuter l'application 2.

ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
eksctl create iamserviceaccount \
    --name dynamodb-messages-fullaccess \
    --namespace backend \
    --cluster ekshandson \
    --attach-policy-arn arn:aws:iam::${ACCOUNT_ID}:policy/dynamodb-messages-fullaccess \
    --override-existing-serviceaccounts \
    --approve

Vérifiez le ServiceAccount créé.

kubectl get serviceaccount -n backend
default                        1         24m
dynamodb-messages-fullaccess   1         35s

Modifiez la définition de déploiement dans l'application 2 pour exécuter le pod sur le ServiceAccount que vous avez créé.

Ouvrez backend-deployment.yaml dans Cloud9 en double-cliquant, ajoutez la spécification serviceAccountName comme suit et enregistrez.

    spec:
+     serviceAccountName: dynamodb-messages-fullaccess
      containers:
kubectl apply -f backend-deployment.yaml -n backend

Un nouveau pod sera lancé automatiquement, alors vérifiez-le.

kubectl get pod -n backend
NAME                       READY   STATUS    RESTARTS   AGE
backend-647595dd78-jjmml   1/1     Running   0          70s
backend-647595dd78-w7f6t   1/1     Running   0          72s

Si vous essayez à nouveau d'accéder à EXTERNAL-IP, il devrait s'afficher correctement.

Recommended Posts

Démo AWS EKS ~
Mémo AWS