harukin721

主に学習記録 🔗 wantedly.com/id/harukin721

ひとり「トラブルシューティングから学ぶk8s勉強会」Part3

これの続き。Part3

Network編

トラブル1 (Serviceで公開したアプリケーションにアクセスできない)

デプロイされたPodではNginxコンテナが動作しており、Serviceリソースを使ってクラスター内部向けにサービスを公開しようとしている想定。

# Runnnigになっている
$ k get po ch03-trouble1
NAME            READY   STATUS    RESTARTS   AGE
ch03-trouble1   1/1     Running   0          78m

# ch03-trouble1-svcを介してPodにアクセスできない
# ポート転送
$ k port-forward service/ch03-trouble1-svc 8080:80

# Serviceにアクセスを試みる
$ curl -m 10 localhost:8080
curl: (7) Failed to connect to localhost port 8080 after 9 ms: Connection refusedMessageを見ると、

Podにポートフォワードして、PodとServiceのどちらに問題があるか切り分ける。

# ポート転送
$ k port-forward pod/ch03-trouble1 8080:80
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80

# 別ターミナル
$ curl localhost:8080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
--- snip ---

Podは正常にアクセスできている。Serviceに問題がありそう。

# Serviceを確認
$ k describe svc ch03-trouble1-svc
Name:              ch03-trouble1-svc
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          svc=nignx
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.43.250.73
IPs:               10.43.250.73
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         <none> # 空。本来ならClusterIPが入っている。
Session Affinity:  None
Events:            <none>

PodとServiceはSelectorによって関係付けされているので、Selectorの間違いを疑う。Podのラベルを確認すると `app=nginx` とあるべきだが `svc=nginx` となっているので修正する。

# 修正後
$ k describe svc ch03-trouble1-svc
Name:              ch03-trouble1-svc
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=nginx
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.43.250.73
IPs:               10.43.250.73
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         172.17.0.5:80 # PodのClusterIPが追加された
Session Affinity:  None
Events:            <none>

$ k get po ch03-trouble1 -o wide
NAME            READY   STATUS    RESTARTS   AGE    IP           NODE     NOMINATED NODE   READINESS GATES
ch03-trouble1   1/1     Running   0          117m   172.17.0.5   colima   <none>           <none>

再度、Serviceへのポートフォワードを試すと成功した!

# ポート転送
$ k port-forward service/ch03-trouble1-svc 8080:80
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80

# 別ターミナル
$ curl -m 10 localhost:8080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
--- snip ---

トラブル2 (Serviceで公開したアプリケーションにアクセスできない その2)

デプロイされたPodではhttpdコンテナが動作しており、Serviceリソースを使ってクラスター内部向けに8080番ポートでサービスを公開している想定。トラブル1と同じく`ch03-trouble2-svc` を介してPodにアクセスできないようです。

# Runnnigになっている
$ k get po ch03-trouble2
NAME            READY   STATUS    RESTARTS   AGE
ch03-trouble2   1/1     Running   0          3m57s

# ch03-trouble1-svcを介してPodにアクセスできない
# ポート転送
$ k port-forward service/ch03-trouble2-svc 8080

# Serviceにアクセスを試みる
$ curl -m 10 localhost:8080
curl: (52) Empty reply from server

Serviceを確認しよう

# Serviceを確認
$ k describe svc ch03-trouble2-svc
Name:              ch03-trouble2-svc
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=web
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.43.126.193
IPs:               10.43.126.193
Port:              <unset>  8080/TCP
TargetPort:        8080/TCP
Endpoints:         172.17.0.6:8080 # PodのClusterIPが入っている
Session Affinity:  None
Events:            <none>

$ k get po ch03-trouble2 -o wide
NAME            READY   STATUS    RESTARTS   AGE     IP           NODE     NOMINATED NODE   READINESS GATES
ch03-trouble2   1/1     Running   0          7m12s   172.17.0.6   colima   <none>           <none>

ServiceのEndpointsにIPアドレスが記載されている。こういった時に疑わしいのはPodのラベルが無計画に付けられて意図しないPodにトラフィックが転送されているケースが考えられるが、今回は意図したPodのClusterIP(172.17.0.6)が入っているので問題無さそう。

他に、Podが正常に動作しておらず指定したポート番号のトラフィックを受け付けることができないケースも考えられるのでServicemp定義を確認すると `TargetPort` でPodの8080番ポートに転送するような設定がある。

`ch03-trouble2` Podの8080番ポートにポートフォワードして確認してみる

# ポート転送
$ k port-forward pod/ch03-trouble2 8080
Forwarding from 127.0.0.1:8080 -> 8080
Forwarding from [::1]:8080 -> 8080

# 別ターミナル
$ curl -m 10 localhost:8080
curl: (52) Empty reply from server

アクセスに失敗してしまう。次の原因を探っていく。

Podのmanifestを確認すると、80番ポートをチェックするLiveness Proveが設定されていることがわかった。Probeも失敗していないので80番ポートが正しいポートである可能性が高い。ServiceのTarget Port設定を8080番から80番に修正する。

再度、Serviceへのポートフォワードを試すと成功した!

$ k describe svc ch03-trouble2-svc
Name:              ch03-trouble2-svc
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=web
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.43.126.193
IPs:               10.43.126.193
Port:              <unset>  8080/TCP
TargetPort:        80/TCP
Endpoints:         172.17.0.6:80
Session Affinity:  None
Events:            <none>

# ポート転送
$ k port-forward service/ch03-trouble1-svc 8080:80
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80

# 別ターミナル
$ curl -m 10 localhost:8080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
--- snip ---

トラブル3 (Serviceで公開したアプリケーションにアクセスできない その3)

デプロイされたPodではpodinfoコンテナが9898番ポートで動作しており、Serviceリソースを使ってクラスター内部向けに8080番ポートでサービスを公開している想定。`ch03-trouble3-svc` を介してPodにアクセスできないようです。

今回はポートフォワードを使わずに、クラスタ内から動作確認するぞ!!!

# curlのイメージでdebugという名前のPodを作成して`sh`を実行
$ k run -it --rm --restart=Never debug --image=curlimages/curl sh
If you don't see a command prompt, try pressing enter.
# debug Pod内のcurlコンテナ内での操作
/ $ curl ch03-trouble3-svc:8080
curl: (7) Failed to connect to ch03-trouble3-svc port 8080 after 75001 ms: Couldn't connect to server
/ $
# EndpointsにIPアドレスが定義されていない。
$ k describe svc ch03-trouble3-svc
Name:              ch03-trouble3-svc
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=podinfo
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.43.241.31
IPs:               10.43.241.31
Port:              <unset>  8080/TCP
TargetPort:        9898/TCP
Endpoints:
Session Affinity:  None
Events:            <none>

Selectorの設定ミスではないかを確認する。

# `app=podinfo` が付いているPodを確認
$ k get po -l app=podinfo
NAME                            READY   STATUS    RESTARTS   AGE
ch03-trouble3-d6b64b7f5-pcbl2   0/1     Running   0          14m

Selectorに一致するPodは存在したのでSelectorの設定ミスではなかった。

しかし、PodのREADYは 0/1 になっている。( PodがReady状態でないと、ServiceのEndpointsには追加されない。)

# Podを確認
$ k describe po -l app=podinfo
Name:             ch03-trouble3-d6b64b7f5-pcbl2
Namespace:        default
Priority:         0
Service Account:  default
Node:             colima/192.168.5.15
Start Time:       Mon, 24 Apr 2023 23:16:46 +0900
Labels:           app=podinfo
                  pod-template-hash=d6b64b7f5
Annotations:      <none>
Status:           Running
IP:               172.17.0.7
IPs:
  IP:           172.17.0.7
Controlled By:  ReplicaSet/ch03-trouble3-d6b64b7f5
Containers:
  podinfo:
    Container ID:   docker://21727a3a4db9b5f33ee7e39127dea859cc99dff4c126d8ead09e31b0ecf1dab8
    Image:          ghcr.io/stefanprodan/podinfo
    Image ID:       docker-pullable://ghcr.io/stefanprodan/podinfo@sha256:b68bfced7e4dbf9961c33bab7a36c5b80364dbd3390a496e9801411987ca296a
    Port:           9898/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Mon, 24 Apr 2023 23:16:53 +0900
    Ready:          False
    Restart Count:  0
    Readiness:      http-get http://:9898/readyzz delay=0s timeout=1s period=3s #success=1 #failure=1
    Environment:    <none>

--- snip ---

Events:
  Type     Reason     Age                    From               Message
  ----     ------     ----                   ----               -------
  Normal   Scheduled  17m                    default-scheduler  Successfully assigned default/ch03-trouble3-d6b64b7f5-pcbl2 to colima
  Normal   Pulling    17m                    kubelet            Pulling image "ghcr.io/stefanprodan/podinfo"
  Normal   Pulled     17m                    kubelet            Successfully pulled image "ghcr.io/stefanprodan/podinfo" in 6.421729962s
  Normal   Created    17m                    kubelet            Created container podinfo
  Normal   Started    17m                    kubelet            Started container podinfo
  Warning  Unhealthy  2m49s (x313 over 17m)  kubelet            Readiness probe failed: HTTP probe failed with statuscode: 404

--- snip ---

PodのEventを見ると、`Readiness probe failed: HTTP probe failed with statuscode: 404` とあり、Readiness probeの検査に失敗しているためReady状態になっていないとわかる。

podinfoを適用したmanifestsを確認するとRediness Probeのパスが間違っており、正しくは `/readyz` のようなので修正する。

# 修正後のRediness Probeのパスを確認
$ k get po -l app=podinfo -o jsonpath='{.items[0].spec.containers[0].readinessProbe.httpGet.path}'
/readyz

# Podを確認
$ k get po -l app=podinfo
NAME                             READY   STATUS    RESTARTS   AGE
ch03-trouble3-774fcd44c7-k8v72   1/1     Running   0          48s

正常にアクセスできた!

# debug用のPodを立ち上げてcurlを実行
$ k run -it --rm --restart=Never debug --image=curlimages/curl curl ch03-trouble3-svc:8080
{
  "hostname": "ch03-trouble3-774fcd44c7-k8v72",
  "version": "6.3.5",
  "revision": "67e2c98a60dc92283531412a9e604dd4bae005a9",
  "color": "#34577c",
  "logo": "https://raw.githubusercontent.com/stefanprodan/podinfo/gh-pages/cuddle_clap.gif",
  "message": "greetings from podinfo v6.3.5",
  "goos": "linux",
  "goarch": "arm64",
  "runtime": "go1.20.2",
  "num_goroutine": "6",
  "num_cpu": "4"
}pod "debug" deleted
# ポート転送
$ k port-forward service/ch03-trouble3-svc 8080:8080
Forwarding from 127.0.0.1:8080 -> 9898
Forwarding from [::1]:8080 -> 9898

ブラウザからも動作確認してみたら、挨拶してくれた。

おわり

akichanさん ありがとうございました!