LoginSignup
3
2

More than 1 year has passed since last update.

AWS IngressのAnnotationであるalb.ingress.kubernetes.io/group.nameを使ってALB1つにクラスタ上のサービスを相乗りさせてALB代を節約する

Last updated at Posted at 2022-05-16

説明

  • alb.ingress.kubernetes.io/group.nameはAWS Load Balancer Controlerから使うことができるIngressリソースのAnnotation
  • https://kubernetes-sigs.github.io/aws-load-balancer-controller/v2.2/guide/ingress/annotations/#group.name
  • 特徴
    • 今まで、1Ingressに1ALBという1対1の関係でデプロイされていたが、これをn対1にすることができる
    • そうすることで、単純にコストを押させることができる
    • 1つに集約するため、その分可用性は失われるので、本番環境では一考したほうがいいかもしれない

検証

namspaceを2つ作成し、別々のアプリをデプロイし、それぞれにルーティングされるかを見たい

それぞれのアプリの準備

mkdir yellow/ green/

Yellowアプリ

echo '<html style="background-color: green;"></html>' > green/index.html
cat <<EOF > green/Dockerfile
FROM public.ecr.aws/nginx/nginx:1.20-alpine
RUN mkdir -p /usr/share/nginx/html/green
COPY ./index.html /usr/share/nginx/html/green/index.html
EXPOSE 80
EOF

# ECRリポジトリを作る
aws ecr create-repository --repository-name green

Greenアプリ

echo '<html style="background-color: green;"></html>' > green/index.html
cat <<EOF > green/Dockerfile
FROM public.ecr.aws/nginx/nginx:1.20-alpine
RUN mkdir -p /usr/share/nginx/html/green
COPY ./index.html /usr/share/nginx/html/green/index.html
EXPOSE 80
EOF

# ECRリポジトリを作る
aws ecr create-repository --repository-name green

ECRへログイン

export AWS_REGION=$(aws ec2 describe-availability-zones --output text --query 'AvailabilityZones[0].[RegionName]')
export AWS_REGISTRY_ID=$(aws ecr describe-registry --query registryId --output text)
export AWS_ECR_REPO=${AWS_REGISTRY_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com

aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin $AWS_ECR_REPO

Yellowアプリのビルド&Push

cd yellow/
docker build . -t yellow
docker tag yellow:latest $AWS_ECR_REPO/yellow:latest
docker push $AWS_ECR_REPO/yellow:latest
cd ..

Greenアプリのビルド&Push

export AWS_REGION=$(aws ec2 describe-availability-zones --output text --query 'AvailabilityZones[0].[RegionName]')
export AWS_REGISTRY_ID=$(aws ecr describe-registry --query registryId --output text)
export AWS_ECR_REPO=${AWS_REGISTRY_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com

aws ecr get-login-password --region $AWS_REGION | docker login --username AWS --password-stdin $AWS_ECR_REPO

マニフェストファイル

Yellowアプリ用

color-app-deployment-1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: yellow-app
  namespace: color-app-1
  labels:
    app: yellow-app
spec:
  selector:
    matchLabels:
      app: yellow-app
  replicas: 2
  template:
    metadata:
      labels:
        app: yellow-app
    spec:
      containers:
      - name: yellow-container
        image: 697333814333.dkr.ecr.ap-northeast-1.amazonaws.com/yellow:latest
        ports:
            - containerPort: 80
        resources:
          limits:
            memory: "100Mi"
            cpu: "200m"
color-app-service-1.yaml
apiVersion: v1
kind: Service
metadata:
  namespace: color-app-1
  name: yellow-service
  labels:
    app: yellow-app
  annotations:
    alb.ingress.kubernetes.io/healthcheck-path: /yellow/index.html
spec:
  type: NodePort
  selector:
    app: yellow-app
  ports:
    - port: 80
      targetPort: 80
color-app-ingress-1.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: color-app-ingress
  namespace: color-app-1
  labels:
    app: color-app
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/healthcheck-protocol: HTTP
    alb.ingress.kubernetes.io/healthcheck-port: traffic-port
    alb.ingress.kubernetes.io/healthcheck-interval-seconds: '15'
    alb.ingress.kubernetes.io/healthcheck-timeout-seconds: '5'
    alb.ingress.kubernetes.io/success-codes: '200'
    alb.ingress.kubernetes.io/healthy-threshold-count: '2'
    alb.ingress.kubernetes.io/unhealthy-threshold-count: '2'
    alb.ingress.kubernetes.io/group.name: color-group
    external-dns.alpha.kubernetes.io/hostname: color-app-1.vamdemic.xyz
spec:
  rules:
    - host: "color-app-1.vamdemic.xyz"
      http:
        paths:
          - path: /yellow
            pathType: Prefix
            backend:
              service:
                name: yellow-service
                port:
                  number: 80

Greenアプリ用

color-app-deployment-1.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: yellow-app
  namespace: color-app-1
  labels:
    app: yellow-app
spec:
  selector:
    matchLabels:
      app: yellow-app
  replicas: 2
  template:
    metadata:
      labels:
        app: yellow-app
    spec:
      containers:
      - name: yellow-container
        image: 697333814333.dkr.ecr.ap-northeast-1.amazonaws.com/yellow:latest
        ports:
            - containerPort: 80
        resources:
          limits:
            memory: "100Mi"
            cpu: "200m"
color-app-service-1.yaml
apiVersion: v1
kind: Service
metadata:
  namespace: color-app-1
  name: yellow-service
  labels:
    app: yellow-app
  annotations:
    alb.ingress.kubernetes.io/healthcheck-path: /yellow/index.html
spec:
  type: NodePort
  selector:
    app: yellow-app
  ports:
    - port: 80
      targetPort: 80
color-app-ingress-2.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: color-app-ingress
  namespace: color-app-2
  labels:
    app: color-app
  annotations:
    kubernetes.io/ingress.class: alb
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: ip
    alb.ingress.kubernetes.io/healthcheck-protocol: HTTP
    alb.ingress.kubernetes.io/healthcheck-port: traffic-port
    alb.ingress.kubernetes.io/healthcheck-interval-seconds: '15'
    alb.ingress.kubernetes.io/healthcheck-timeout-seconds: '5'
    alb.ingress.kubernetes.io/success-codes: '200'
    alb.ingress.kubernetes.io/healthy-threshold-count: '2'
    alb.ingress.kubernetes.io/unhealthy-threshold-count: '2'
    alb.ingress.kubernetes.io/group.name: color-group
    external-dns.alpha.kubernetes.io/hostname: color-app-2.vamdemic.xyz
spec:
  rules:
    - host: "color-app-2.vamdemic.xyz"
      http:
        paths:
          - path: /green
            pathType: Prefix
            backend:
              service:
                name: green-service
                port:
                  number: 80

デプロイ

Yellowアプリ

kubectl create namespace color-app-1
kubectl apply -f color-app-deployment-1.yaml
kubectl apply -f color-app-service-1.yaml
kubectl apply -f color-app-ingress-1.yaml

Greenアプリ

kubectl create namespace color-app-2
kubectl apply -f color-app-deployment-2.yaml
kubectl apply -f color-app-service-2.yaml
kubectl apply -f color-app-ingress-2.yaml

テスト

Yellowアプリ
image.png

Greenアプリ
image.png

各NamespaceごとにIngressを作成したとしても、alb.ingress.kubernetes.io/group.nameはnamespaceをまたぐものであるので共有ができる

注意点

  • ingressの設定
    • 2.4.1で検証しました
    • externalDNSを設定してもいけます
      • その場合は、hostを付ける必要がたぶんあって、つけない場合、メッシュ状に接続できてしまうのでその時点で想定されていないエンドポイントを公開してしまうことになると思うから

参考

https://aws.amazon.com/jp/blogs/news/how-to-expose-multiple-applications-on-amazon-eks-using-a-single-application-load-balancer/
https://developers.freee.co.jp/entry/2020/12/14/130003

3
2
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2