---
apiVersion: v1
kind: ConfigMap
metadata:
  name: q5
  labels:
    question.kontest.amsy.dev: "5"
data:
  question: |-
    次のServiceとDeploymentを作成後、Deploymentのイメージを変更した際にServiceリソース経由のリクエストで断が発生しました。
    これは、「Serviceの転送先リストから該当のPodを外すタイミング」と「Pod（コンテナ）を停止するタイミング」がほぼ同時に行われるために生じます。
    この問題に対応するために、コンテナの停止前に3秒待ってから停止するようにしてください（実行コマンドは"sleep 3"としてください）。
    
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: sample-deployment
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: sample-app
      template:
        metadata:
          labels:
            app: sample-app
        spec:
          containers:
          - name: nginx-container
            image: amsy810/echo-nginx:v2.0

    apiVersion: v1
    kind: Service
    metadata:
      name: sample-clusterip
    spec:
      type: ClusterIP
      ports:
      - name: "http-port"
        protocol: "TCP"
        port: 8080
        targetPort: 80
      selector:
        app: sample-app
  hint: |-
    https://qiita.com/superbrothers/items/3ac78daba3560ea406b2
  base_content.yaml: |-
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: sample-deployment
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: sample-app
      template:
        metadata:
          labels:
            app: sample-app
        spec:
          containers:
          - name: nginx-container
            image: amsy810/echo-nginx:v2.0
  answer.yaml: |-
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: sample-deployment
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: sample-app
      template:
        metadata:
          labels:
            app: sample-app
        spec:
          containers:
          - name: nginx-container
            image: amsy810/echo-nginx:v2.0
            lifecycle:
              preStop:
                exec:
                  command: ["sleep", "3"]
  comment: |-
    【解説 by カサレアル】
    kubectl delete などでPodの削除が開始されると、
    (1) 該当PodをServiceの転送先リストから除外する
    (2) 該当Podの停止（preStop処理 -> SIGTERM処理 -> SIGKILL処理）
    が非同期に行われます。
    もし(1)がまだ終了していない段階で(2)が先に終了してしまうと、リクエストを受けたにも関わらずPodがもう存在しないので処理できない、という状況に陥ります。
    これを防ぐには、SIGTERM処理が行われる前のpreStop処理で、時間を稼ぐ必要があります。
    preStop処理は spec.template.spec.containers[].lifecycle.preStop に指定します。preStop処理には exec / httpGet / tcpSocket の3種類が指定可能です。今回は sleep 3 コマンドを実行したいため exec.command に ["sleep", "3"] を指定します。
  author: |-
    Masaya Aoyama (@amsy810)
