前回のエントリー
はじめに
やはり、人は強欲らしいのでコンテナを使っているのに必要な時必要な分だけのリソースを起動させてほしいという願いを常に持っている。Kubernetes の場合はKnativeなどを利用すれば達成できる。sablierはリバースプロキシを利用してアクセスがない時は自動的にシャットダウンしてアクセスがあれば指定のコンテナを起動することができるツールです。 前回はdocker 上での動作確認を行った。引き続き今回はKubernetes 環境でのsablierの検証を行いました。今回はsablierやTraefik 、各種ミドルウェアの設定ファイルに関しては言及してません。気合があれば後編として書いていきます。
sablier/hourglass.png at main · acouvreur/sablier · GitHub より
- 前回のエントリー
- はじめに
- やってみる
- k3s を用いて Kubernetes Cluster を作成する
- Helmを用いたTraefikの作成
- Sablier を作成していく
- アプリケーション本体のデプロイ
- Sablier PluginによるTraefik経由でのIngressの設定を行う
- さいごに
やってみる
公式サイトにはサンプルコード「Sablier Guide: Code-Server + Traefik + Kubernetes Ingress」としてKubernetes 上で Cloud Native なアプリケーションプロキシーのTraefikとKubernetes Ingressを用いたものが紹介されている。
k3s を用いて Kubernetes Cluster を作成する
以下の内容をdocker-compose.yml
というファイルにコピーして、docker compose up -d
を実行します。
version: '3' services: server: image: "rancher/k3s:v1.24.8-k3s1" command: server --no-deploy traefik tmpfs: - /run - /var/run ulimits: nproc: 65535 nofile: soft: 65535 hard: 65535 privileged: true restart: always environment: - K3S_KUBECONFIG_OUTPUT=/output/kubeconfig.yaml - K3S_KUBECONFIG_MODE=666 volumes: # This is just so that we get the kubeconfig file out - .:/output ports: - 6443:6443 # Kubernetes API Server - 8080:80 # Ingress controller port 80
docker compose up -d
を実行します。
$ docker compose up -d [+] Running 3/3 ⠿ server Pulled ⠿ 73c47571f4bd Pull complete ⠿ 210e8c1c5e29 Pull complete [+] Running 2/2 ⠿ Network sablier-code-server-traefik-kubernetes_default Created ⠿ Container sablier-code-server-traefik-kubernetes-server-1 Started
set -x KUBECONFIG ./kubeconfig.yaml:/Users/nwiizo/.kube/config
のような設定が環境変数として入っているのでカレントディレクトリにあるkubeconfig.yaml
がKUBECONFIG
として優先的に実行される。そこでkubectl get node
を実行するとCluster が準備できていることが分かる。
$ kubectl get node NAME STATUS ROLES AGE VERSION 58160ffa6e9b Ready control-plane,master 3m56s v1.24.8+k3s1
Helmを用いたTraefikの作成
helm のインストールに関しては各自「helm install」とかで調べてほしい。とりあえず、traefikのHelmリポジトリを追加します。
$ helm repo add traefik https://helm.traefik.io/traefik $ helm repo update
helm でデプロイするリソースは事前に確認しておいたほうがよいので確認しておきます。
$ helm show all traefik/traefik
デプロイをするのですが既存のHelm templateに自分が利用したい値を渡してデプロイします。templateに値を渡す方法は主に二つあります。
- values.yamlを利用者が用意する
- chartの利用者が helm install コマンド時に値を渡す(values.yamlの上書き可能)
今回はvalues.yaml
を以下のように作成してデプロイを行う
image: tag: "2.9.1" experimental: plugins: enabled: true additionalArguments: - "--experimental.plugins.sablier.moduleName=github.com/acouvreur/sablier" - "--experimental.plugins.sablier.version=v1.1.1" providers: kubernetesIngress: enabled: true allowEmptyServices: true
traefikチャートをvalues.yamlファイルとともにインストールします。また、kube-system
というシステムコンポーネントやアドオンとして位置づけられているものをデプロイするためのNamespaceを用います。
$ helm install traefik traefik/traefik -f values.yaml --namespace kube-system NAME: traefik LAST DEPLOYED: Wed Nov 30 07:58:21 2022 NAMESPACE: kube-system STATUS: deployed REVISION: 1 TEST SUITE: None NOTES: Traefik Proxy v2.9.5 has been deployed successfully on kube-system namespace !
Sablier を作成していく
再三の説明になるのですがsablier はアプリケーションをシャットダウンさせたりしているアプリです。それ故に強い権限が必要になります。そのため、Sablier 用のサービスアカウント作成して、 Sablier のデプロイを行います。
sablier-sa.yaml
というファイルで権限周りを一つにした。
--- apiVersion: v1 kind: ServiceAccount metadata: name: sablier namespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: sablier namespace: kube-system rules: - apiGroups: - apps - "" resources: - deployments - deployments/scale - statefulsets - statefulsets/scale verbs: - patch # Scale up and down - get # Retrieve info about specific deployment or statefulset - update # Scale up and down - list # Events - watch # Events --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: sablier namespace: kube-system roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: sablier subjects: - kind: ServiceAccount name: sablier namespace: kube-system
こちらをデプロイ
$ kubectl apply -f sablier-sa.yaml
serviceaccount/sablier created
clusterrole.rbac.authorization.k8s.io/sablier created
clusterrolebinding.rbac.authorization.k8s.io/sablier created
sablier-deploy.yaml
というファイルでリソース周りを一つにした。
apiVersion: apps/v1 kind: Deployment metadata: name: sablier-deployment namespace: kube-system labels: app: sablier spec: replicas: 1 selector: matchLabels: app: sablier template: metadata: labels: app: sablier spec: serviceAccountName: sablier serviceAccount: sablier containers: - name: sablier image: acouvreur/sablier:1.1.1 args: - "start" - "--provider.name=kubernetes" ports: - containerPort: 10000 --- apiVersion: v1 kind: Service metadata: name: sablier namespace: kube-system spec: selector: app: sablier ports: - protocol: TCP port: 10000 targetPort: 10000
こちらもデプロイ
$ kubectl apply -f sablier-deploy.yaml
deployment.apps/sablier-deployment created
service/sablier created
きちんとデプロイされているか確認する。また、kubectl -n kube-system logs -l=app=sablier
でログを確認するのも良いと思う
$ kubectl -n kube-system get deployments -l=app=sablier NAME READY UP-TO-DATE AVAILABLE AGE sablier-deployment 1/1 1 1 6m9s
アプリケーション本体のデプロイ
app-deployment.yaml
でアプリケーションのリソースをデプロイします。
apiVersion: apps/v1 kind: Deployment metadata: name: code-server-deployment namespace: default labels: app: code-server spec: replicas: 1 selector: matchLabels: app: code-server template: metadata: labels: app: code-server spec: containers: - name: code-server image: codercom/code-server:4.8.3 ports: - containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: code-server-service namespace: default spec: selector: app: code-server ports: - protocol: TCP port: 8080 targetPort: 8080
kubectl
にk
というalias を貼っている。手癖でこうなったのでブログでも記載しておく。リソースの確認をk get pod
したらさっさと次に行く
$ k apply -f app-deployment.yaml
deployment.apps/code-server-deployment created
service/code-server-service created
Sablier PluginによるTraefik経由でのIngressの設定を行う
app-ingress.yaml
でデプロイする
apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: code-server-ingress namespace: default annotations: kubernetes.io/ingress.class: traefik spec: rules: - host: localhost http: paths: - path: / pathType: Prefix backend: service: name: code-server-service port: number: 8080
http://localhost:8080 にアクセスできたと思います。 その後、アプリケーションのレプリカセットを0にします。がこれは削除ではないです。
$ k scale deployment code-server-deployment --replicas=0 deployment.apps/code-server-deployment scaled # 削除されたわけではないので確認できる $ k get deployments/code-server-deployment NAME READY UP-TO-DATE AVAILABLE AGE code-server-deployment 0/0 0 0 12m
app-sablier-middleware.yaml をデプロイする。sessionDuration: 2m
に設定をしたので2分後には落ちるはずです。
apiVersion: traefik.containo.us/v1alpha1 kind: Middleware metadata: name: code-server-sablier namespace: default spec: plugin: sablier: names: deployment_default_code-server-deployment_1 sablierUrl: 'http://sablier:10000' sessionDuration: 2m dynamic: displayName: 'Code Server Demo' showDetails: true theme: hacker-terminal refreshFrequency: 5s
$ k apply -f app-sablier-middleware.yaml
$ k get middleware
NAME AGE
code-server-sablier 2m5s
その後にapp-ingress-patch.yaml
を作成し、kubectl patch ingress code-server-ingress --patch-file app-ingress-patch.yaml
でIngressにパッチを当てます。
metadata: annotations: traefik.ingress.kubernetes.io/router.middlewares: default-code-server-sablier@kubernetescrd
パッチを当てた直後はアクセスがないのでpod 数は0です。
$ k get pod
No resources found in default namespace.
しかし、traefik 及びsablier の動作によってhttp://localhost:8080 に何もせずにアクセスできました。 この時に関連している各種ログを確認すると動作していることがわかります。
$ k get pod NAME READY STATUS RESTARTS AGE code-server-deployment-7f56554786-j4b69 1/1 Running 0 2m44s
そして、2分後にはシャットダウンされていると思います。
# -w で継続的にウォッチする $ k get po -w NAME READY STATUS RESTARTS AGE code-server-deployment-7f56554786-t5j8x 1/1 Running 0 36s code-server-deployment-7f56554786-t5j8x 1/1 Terminating 0 2m17s code-server-deployment-7f56554786-t5j8x 0/1 Terminating 0 2m18s code-server-deployment-7f56554786-t5j8x 0/1 Terminating 0 2m18s code-server-deployment-7f56554786-t5j8x 0/1 Terminating 0 2m18s
さいごに
本来やりたかった。Kubernetes 環境での動作確認までできました。此処から先は皆さんの環境に合うようにいくつかの設定ファイルを見ていく会を本来やれれば良かったですが眠いのでおやすみです。