0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ingressを理解する

Posted at

目的

  • ingress を理解する

手段

killercodaで手を動かす

環境

killercoda

securityContext とは

Kubernetesの**Ingress(イングレス)**とは、外部からのHTTPおよびHTTPSリクエストをクラスタ内のサービスにルーティングするためのAPIリソースです。簡単に言うと、**Kubernetesクラスタの「入り口」**のような役割を果たします。

つまり、pod/deployment に対して service リソースを作成して kubernetes クラスター内で公開し、kubernetes クラスターの外部への公開は ingress リソースを作成する必要があるということですね。

代表的な設定は?

ingressingressClass の二つが存在します。

  • ingress : 実際のトラフィックを kubernetes クラスター内部の service へ処理する
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
spec:
  rules:
  - host: example.com
    http:
      paths:
      - path: /web
        pathType: Prefix
        backend:
          service:
            name: web-service
            port:
              number: 80
# 実際の ingress 設定は ingressClass や annotation(rewrite)等が必要になる
# あくまで ingress 設定自身の説明サンプル
  • ingressClass : Kubernetesの IngressClass(イングレスクラス) は、どのIngress Controllerが特定のIngressリソースを処理するかを指定するための仕組みです。
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
  name: nginx
spec:
  controller: k8s.io/ingress-nginx
# この IngressClass は Ingress Controller に ingress-nginx を利用すると宣言
# Ingress Controller は複数(例: NGINX, Traefik, HAProxy)存在するため

次に、deployment 作成 → Pod をクラスター内に公開 → ingress で外部に公開する手順を確認します。
まずは deployment を作成します。

controlplane:~$ k create namespace deployment
# namespace 作成

controlplane:~$ k -n deployment  create deployment nginx --image=nginx --replicas=2 
# deployment 作成

controlplane:~$ k get -n deployment deployments.apps 
NAME    READY   UP-TO-DATE   AVAILABLE   AGE
nginx   2/2     2            2           66s
# status 確認

続いて、expose コマンドで kubernetes クラスター内に公開します。

controlplane:~$ k -n deployment expose deployment nginx --port=80 --dry-run=client -oyaml
apiVersion: v1
kind: Service
metadata:
  creationTimestamp: null
  labels:
    app: nginx
  name: nginx
  namespace: deployment
spec:
  ports:
  - port: 80
    protocol: TCP
    targetPort: 80
  selector:
    app: nginx
status:
  loadBalancer: {}
# nginx という ClusterIP を作成します。

controlplane:~$ k describe -n deployment svc nginx 
Name:                     nginx
Namespace:                deployment
Labels:                   app=nginx
Annotations:              <none>
Selector:                 app=nginx
Type:                     ClusterIP
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.97.179.26
IPs:                      10.97.179.26
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
Endpoints:                192.168.0.13:80,192.168.0.14:80 # deployment の EP が二つアサイン
Session Affinity:         None
Internal Traffic Policy:  Cluster
Events:                   <none>
controlplane:~$ k get -n deployment svc
NAME    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
nginx   ClusterIP   10.97.179.26   <none>        80/TCP    18s

作成した ClusterIP に kubernetes クラスター内部からアクセスします。

controlplane:~$ curl http://10.97.179.26 --head
HTTP/1.1 200 OK
Server: nginx/1.29.1
# controlplane(kubernetes クラスター内部)からアクセスできました。

最後に ingress 設定を作成します。

controlplane:~$ k create ingress -n deployment nginx --rule="example.com/=nginx:80" --dry-run=client -oyaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  creationTimestamp: null
  name: nginx
  namespace: deployment
spec:
  rules:
  - host: world.universe.mine
    http:
      paths:
      - backend:
          service:
            name: nginx
            port:
              number: 80
        path: /
        pathType: Exact
status:
  loadBalancer: {}
# --dry-run=client オプションで ingress の yaml を作成します

必要なカラムを追加してきます。

controlplane:~$ cat nginx.yaml 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  creationTimestamp: null
  name: nginx
  namespace: deployment
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: / # path(ex: /web)にマッチしたアクセスを / に書き換え
spec:
  ingressClassName: nginx # どの ingress controller を利用するか指定
  rules:
  - host: example.com
    http:
      paths:
      - backend:
          service:
            name: nginx
            port:
              number: 80
        path: /
        pathType: Prefix # Prefix に変更
status:
  loadBalancer: {}

この yaml を適用します。

controlplane:~$ k apply -f nginx.yaml

ホスト名でアクセスできるか確認します。

controlplane:~$ curl --head example.com -v
* Host example.com:80 was resolved.
* IPv6: (none)
* IPv4: 10.104.72.18
*   Trying 10.104.72.18:80...
* Connected to example.com (10.104.72.18) port 80
> HEAD / HTTP/1.1
> Host: example.com
> User-Agent: curl/8.5.0
> Accept: */*
> 
< HTTP/1.1 200 OK
HTTP/1.1 200 OK
# 10.104.72.18 は ClusterIP かどうか確認します

controlplane:~$ k get svc -n deployment 
NAME    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
nginx   ClusterIP   10.104.72.18   <none>        80/TCP    7m53s
# ClusterIP に接続できていることが確認できました

ここからは ingress に https を追加します。必要な手順は以下の通りです。

  1. サーバ証明書を作成
  2. サーバ証明書を基に secret リソース作成
  3. ingress 設定 yaml に secret 等の設定を追加

それぞれ順番に実施していきます。

  1. サーバ証明書を作成
controlplane:~$ openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout cert.key -out cert.crt -subj="/CN=world.universe.mine/O=world.universe.mine"
.........+..+.........+....+..+.......+.....+...+...+.+...+......+...........+...+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*........................+..+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*......+....+........+.............+.........+...+...+..+......+......+...............+.........+.+.....+.............+.....+.......+........+.+..+..........+...+..+.........................+..+...+....+.....+..........+...+..+.............+..+...+...+......................+...+...+..+.........+....+......+........+.+.....+......+......+...+............+...+.........+...+...............+...+.+........+.+............+...+.....+......+.+........+....+............+...+...........+.......+..+.......+........+...+...+............+...+....+...+..+......+.+..............+.+........+................+...........+......+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
.+...+...+.........+.........+....+..+.+...+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*...+..+....+...........+......+..........+..+.+......+........+.+.....+......+.+..+......+.........+...+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++*....+..+...+.............+.....+.......+..+.+...........+....+....................+.+.....+....+..............+.+.........+..+......+..........+...+.....+....+.....+..................+...+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
-----
controlplane:~$ 

ingress の https 実装前にどのような証明書が提示されるか確認します。

controlplane:~$ curl -kv https://world.universe.mine:30443/europe
* Host world.universe.mine:30443 was resolved.
* IPv6: (none)
--- snip ---
* ALPN: server accepted h2
* Server certificate:
*  subject: O=Acme Co; CN=Kubernetes Ingress Controller Fake Certificate
# `Kubernetes Ingress Controller Fake Certificate` が利用されています

2 .サーバ証明書を基に secret リソース作成

controlplane:~$ k create -n world  secret tls world-secret --cert=cert.crt --key=cert.key 
secret/world-secret created
controlplane:~$ k get -n world secrets world-secret 
NAME           TYPE                DATA   AGE
world-secret   kubernetes.io/tls   2      11s
controlplane:~$ k describe -n world secrets world-secret 
Name:         world-secret
Namespace:    world
Labels:       <none>
Annotations:  <none>

Type:  kubernetes.io/tls

Data
====
tls.key:  1704 bytes
tls.crt:  1220 bytes
controlplane:~$ 

3 .ingress 設定 yaml に secret 等の設定を追加

controlplane:~$ k get -n world ingress world -oyaml > world.yaml
controlplane:~$ vi world.yaml 
controlplane:~$ cat world.yaml
--- snip ---

spec:
  ingressClassName: nginx
  tls:
  - hosts:
      - world.universe.mine
    secretName: world-secret
# spec 配下に tls を追加。hosts と証明書の CN は一致させる。secretName は作成した secret を指定

controlplane:~$ k replace -f world.yaml --force
ingress.networking.k8s.io "world" deleted
ingress.networking.k8s.io/world replaced

アクセス確認してみます。

controlplane:~$ curl -kv https://world.universe.mine:30443/asia 
--- snip ---
*  SSL certificate verify result: self-signed certificate (18), continuing anyway.
*   Certificate level 0: Public key type RSA (2048/112 Bits/secBits), signed using sha256WithRSAEncryption
# 作成した tls 証明書が提示されています。Okですね

最後の pathType を確認します。

  • Prefix : /内の要素マッチング。例えば /app/ であれば app が対象
  • Exact : 完全一致
  • ImplementationSpecific : 利用する ingress controller の実装に依存する
  rules:
  - host: world.universe.mine
    http:
      paths:
      - backend:
          service:
            name: europe
            port:
              number: 80
        path: /europe
        pathType: Prefix
      - backend:
          service:
            name: asia
            port:
              number: 80
        path: /asia
        pathType: Prefix

あとがき

Kubernetes は奥が深い...

ソース

0
0
0

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?