仮想化通信

日本仮想化技術株式会社の公式エンジニアブログ

microk8sでKubernetes Ingressをもう少し触ってみた

以前、こんな記事を書いていました。

tech.virtualtech.jp

今回はmicrok8sでKubernetesを動かしてIngressでURLを発行してみたいと思います。

microk8sはこれまでお伝えしているようにアドオンがいくつかあり、必要なサービスをコマンド一つで有効化できます。KnativeとかIstioとか、Prometheusもあります。最近Metallbが追加されました。

microk8sのセットアップ

本題に入る前に、microk8sをセットアップしておきましょう。今回は1台のサーバーで動かすのでこれだけです。

% sudo snap install microk8s --classic --channel=1.22/stable

インストール後、今回はIngressを使いたいので次のようなコマンドを実行します。実行するとセットアップが始まります。

% sudo microk8s.enable ingress

これで終わりです。 なお、microk8sについては過去記事もご覧ください。

Ingressを使ったアプリの展開

[4/27/2022 update] Ingress APIバージョンを最新に更新。公式ドキュメントのIngressの例を参考にしました。

Ingressを使って、外部に公開してみます。 今回は「hello-world.example.com」と言うドメインでアプリケーションを公開してみます。 事前にDNSでFQDNで引けるようにするか、クライアントのhostsファイルなどで名前解決できるようにしておく必要があります。

まず、次のようなアプリケーションデプロイ用のYAMLを作成します。

$ cat deploy.yaml 
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginxapp1
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginxapp1
  template:
    metadata:
      labels:
        app: nginxapp1
    spec:
      containers:
      - name: nginxapp1
        image: docker.io/library/nginx:alpine
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: nginxapp1-service
  labels:
    app: nginxapp1
spec:
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: nginxapp1

次でアプリのIngressを定義します。

$ cat ingress.yaml 
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
  rules:
    - host: hello-world.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: nginxapp1-service
                port:
                  number: 80

注記

ここで利用しているドメイン example.com は自分が所有するドメインに書き換えます。 当然ながらサブドメイン含めたドメインを、DNSサーバーに設定する必要があります。 テストしたいだけなら、ここに書いたドメインをクライアントの /etc/hosts に書いて実行します。

アプリをデプロイします。

$ microk8s.kubectl create -f deploy.yaml
$ microk8s.kubectl create -f ingress.yaml

curlやブラウザーなどでアプリにアクセスできることを確認します。

$ curl http://hello-world.example.com/
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
...

ワイルドカードDNSサービスを使ったアプリの展開

次のようなYAMLを作成して、アプリケーションをデプロイしましょう。 nginx.172.17.28.74.nip.io のIPアドレスの部分はmicrok8sサーバーのIPアドレスを指定してください。

YAML例はこちらです。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: app1
  template:
    metadata:
      name: app1
      labels:
        app: app1
    spec:
      containers:
      - name: app1
        image: nginx:alpine
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: svc1
  labels:
    app: app1
spec:
  type: NodePort
  ports:
  - port: 80
    targetPort: 80
  selector:
    app: app1
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: svc1
spec:
  rules:
  - host: nginx.172.17.28.74.nip.io
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
              service:
                name: svc1
                port:
                  number: 80

しばらくすると、 http://nginx.172.17.28.74.nip.io でアクセスできるようになります。 ちなみにIngressはデプロイしてからアクセスできるようになるまで1〜2分程度の時間がかかります。

アクセスできない場合は dig nginx.172.17.28.74.nip.ionip.io に指定しているIPアドレスが返ってくるか確認してください。それが返ってくるまでアクセスできません。

複数のサービスの展開

次のようなYAMLを書くと http://fruits.172.17.28.74.nip.io/applehttp://fruits.172.17.28.74.nip.io/banana で、それぞれ別々のコンテナーアプリケーションにアクセスできるようになります。ちなみにxip.ioのようなサービスは自分で建てることができるようです。まだ試してはいませんが、そのうちやってみたいと思います。

少々短めですが、本日のネタは以上です。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: banana
spec:
  replicas: 1
  selector:
    matchLabels:
      app: banana
  template:
    metadata:
      name: banana
      labels:
        app: banana
    spec:
      containers:
      - name: banana
        image: hashicorp/http-echo
        args:
        - "-text=banana"
        ports:
        - containerPort: 5678
---
apiVersion: v1
kind: Service
metadata:
  name: banana
  labels:
    app: banana
spec:
  ports:
  - port: 5678
    targetPort: 5678
  selector:
    app: banana
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: apple
spec:
  replicas: 1
  selector:
    matchLabels:
      app: apple
  template:
    metadata:
      name: apple
      labels:
        app: apple
    spec:
      containers:
      - name: apple
        image: hashicorp/http-echo
        args:
        - "-text=apple"
        ports:
        - containerPort: 5678
---
apiVersion: v1
kind: Service
metadata:
  name: apple
  labels:
    app: apple
spec:
  ports:
  - port: 5678
    targetPort: 5678
  selector:
    app: apple
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: simple-fanout-example
spec:
  rules:
  - host: www4.tooyama.org
    http:
      paths:
      - path: /banana
        pathType: Prefix
        backend:
          service:
            name: banana
            port:
              number: 5678
      - path: /apple
        pathType: Prefix
        backend:
          service:
            name: apple
            port:
              number: 5678

アクセスしてみましょう。

~$ curl http://fruits.172.17.28.74.nip.io/banana
banana
~$ curl http://fruits.172.17.28.74.nip.io/apple
apple

【追記】 次のサイトの情報が非常にわかりやすかったです。

matthewpalmer.net