はじめに
OKE(Container Engine for Kubernetes)のクラスタにサーバーレスのVirtual Nodeがリリースされましたので、試してみます。
IAMポリシーの設定
マニュアルの通りにIAMポリシーを設定します。
特にルートコンパートメントにポリシーを設定しないと、クラスタは作成できますが、Podが起動できない状態になります。
クラスタの作成
OKEのコンソールからクラスタを作成します。
ノードタイプの項目で「仮想」を選択します。「管理対象」は従来からあるコンピュートインスタンスをWorker Nodeとして使用します。
ノード数は1にしておきます。
クラスタの確認
プロビジョニングされたクラスタを確認します。
$ kubectl get node
NAME STATUS ROLES AGE VERSION
10.0.10.73 Ready <none> 43h v1.25.4-0.2.129-230309195324
詳細を確認します。
$ kubectl describe nodes 10.0.10.73
Name: 10.0.10.73
Roles: <none>
Labels: beta.kubernetes.io/os=linux
failure-domain.beta.kubernetes.io/zone=CA-TORONTO-1-AD-1
kubernetes.io/os=linux
name=cluster1-20230324
node.kubernetes.io/exclude-from-external-load-balancers=true
oci.oraclecloud.com/fault-domain=FAULT-DOMAIN-3
topology.kubernetes.io/zone=CA-TORONTO-1-AD-1
Annotations: node.alpha.kubernetes.io/ttl: 0
oci.oraclecloud.com/virtual-node-pool-id:
ocid1.virtualnodepool.oc1.ca-toronto-1.amaaaaaassl65iqab4x345nos56orv4msst6es6i4rp2trg45fdnncymrlqq
virtual-kubelet.io/last-applied-node-status:
{"capacity":{"cpu":"2k","memory":"8000Gi","pods":"500"},"allocatable":{"cpu":"2k","memory":"8000Gi","pods":"500"},"phase":"Running","condi...
virtual-kubelet.io/last-applied-object-meta:
{"name":"10.0.10.73","uid":"8bcb349d-e99a-48c6-b55c-a185232d221a","creationTimestamp":null,"labels":{"kubernetes.io/os":"linux","name":"cl...
CreationTimestamp: Fri, 24 Mar 2023 08:43:16 +0000
Taints: <none>
Unschedulable: false
Lease:
HolderIdentity: 10.0.10.73
AcquireTime: <unset>
RenewTime: Sun, 26 Mar 2023 04:27:16 +0000
Conditions:
Type Status LastHeartbeatTime LastTransitionTime Reason Message
---- ------ ----------------- ------------------ ------ -------
Ready True Sun, 26 Mar 2023 04:27:08 +0000 Fri, 24 Mar 2023 08:43:16 +0000 KubeletReady Kubelet is ready
OutOfDisk False Sun, 26 Mar 2023 04:27:08 +0000 Fri, 24 Mar 2023 08:43:16 +0000 KubeletHasSufficientDisk kubelet has sufficient disk space available
MemoryPressure False Sun, 26 Mar 2023 04:27:08 +0000 Fri, 24 Mar 2023 08:43:16 +0000 KubeletHasSufficientMemory kubelet has sufficient memory available
DiskPressure False Sun, 26 Mar 2023 04:27:08 +0000 Fri, 24 Mar 2023 08:43:16 +0000 KubeletHasNoDiskPressure kubelet has no disk pressure
NetworkUnavailable False Sun, 26 Mar 2023 04:27:08 +0000 Fri, 24 Mar 2023 08:43:16 +0000 RouteCreated RouteController created a route
Addresses:
InternalIP: 10.0.10.73
Capacity:
cpu: 2k
memory: 8000Gi
pods: 500
Allocatable:
cpu: 2k
memory: 8000Gi
pods: 500
System Info:
Machine ID:
System UUID:
Boot ID:
Kernel Version:
OS Image:
Operating System: Linux
Architecture: amd64
Container Runtime Version:
Kubelet Version: v1.25.4-0.2.129-230309195324
Kube-Proxy Version:
ProviderID: ocid1.virtualnode.oc1.ca-toronto-1.amaaaaaassl65iqadqmsl7wfv54ghnjzehciceq5lk5gdh3dkafwff54sfwa
Non-terminated Pods: (5 in total)
Namespace Name CPU Requests CPU Limits Memory Requests Memory Limits Age
--------- ---- ------------ ---------- --------------- ------------- ---
kube-system coredns-854ddf66ff-28n2l 100m (0%) 0 (0%) 70Mi (0%) 170Mi (0%) 43h
kube-system csi-oci-node-28w5t 30m (0%) 500m (0%) 70Mi (0%) 300Mi (0%) 43h
kube-system kube-dns-autoscaler-7c97dc6dc4-wg7vg 20m (0%) 0 (0%) 10Mi (0%) 0 (0%) 43h
kube-system kube-proxy-4tsjj 0 (0%) 0 (0%) 0 (0%) 0 (0%) 43h
kube-system kube-proxy-dq29j 0 (0%) 0 (0%) 0 (0%) 0 (0%) 32h
Allocated resources:
(Total limits may be over 100 percent, i.e., overcommitted.)
Resource Requests Limits
-------- -------- ------
cpu 150m (0%) 500m (0%)
memory 150Mi (0%) 470Mi (0%)
ephemeral-storage 0 (0%) 0 (0%)
Events: <none>
細かく見ていくと、リソースの上限は以下のようになっています。kubeletのデフォルトかな?
AWSのFargateと比べると1ノードあたりのCPU/メモリが大きいですね。
PodもFargateは1ノード/1Podですが、Virtual Nodeは1ノード/複数Podのようです。
Allocatable:
cpu: 2k
memory: 8000Gi
pods: 500
OSはおそらくOracle Linuxだと思いますが、Linux
となっています。
OS Image:
Operating System: Linux
Container Runtimeは不明です。
Container Runtime Version:
kubelet version
Kubelet Version: v1.25.4-0.2.129-230309195324
Nodeのスケール
Nodeをスケールさせてみます。
ノードプールのコンソールからスケール
→ノード数
3に増やします。
しばらく待って確認します。
$ kubectl get node
NAME STATUS ROLES AGE VERSION
10.0.10.204 Ready <none> 72s v1.25.4-0.2.129-230309195324
10.0.10.231 Ready <none> 81s v1.25.4-0.2.129-230309195324
10.0.10.73 Ready <none> 44h v1.25.4-0.2.129-230309195324
hostPath
hostPathでコンテナからVirtual Nodeのrootディレクトリをマウントしてみます。
apiVersion: v1
kind: Pod
metadata:
name: hostpath
spec:
containers:
- image: nginx
name: hostpath
volumeMounts:
- mountPath: /test
name: test-volume
volumes:
- name: test-volume
hostPath:
path: /
type: Directory
$ kubectl apply -f hostpath.yaml
pod/hostpath created
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
hostpath 0/1 Waiting 0 28s
$ kubectl describe pod hostpath
Name: hostpath
Namespace: default
・・・
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal Scheduled 45s default-scheduler Successfully assigned default/hostpath to 10.0.10.73
Normal ProviderCreateSuccess 45s 10.0.10.73/kubelet Create pod in provider successfully
Warning Failed 45s 10.0.10.73/kubelet Error creating pod: [unsupported Volume: test-volume]
hostPathはサポートしてないですね。
サポートしているボリュームは、マニュアルでは以下となっています。
- emptyDir
- ConfigMap
- Secret
- 次のタイプのProjectedVolume
- ServiceAccount
- ConfigMap
- Secret
Pod
デフォルトのPod
kube-systemに起動しているPodを確認します。
$ kubectl get pod -n kube-system -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
coredns-854ddf66ff-28n2l 1/1 Running 0 44h 10.0.10.206 10.0.10.73 <none> <none>
coredns-854ddf66ff-lgqv6 1/1 Running 0 9m23s 10.0.10.51 10.0.10.73 <none> <none>
coredns-854ddf66ff-wzpg9 1/1 Running 0 9m23s 10.0.10.4 10.0.10.73 <none> <none>
csi-oci-node-28w5t 0/1 Pending 0 44h <none> 10.0.10.73 <none> <none>
csi-oci-node-hjghm 0/1 Pending 0 9m24s <none> 10.0.10.204 <none> <none>
csi-oci-node-vcx4q 0/1 Pending 0 9m33s <none> 10.0.10.231 <none> <none>
kube-dns-autoscaler-7c97dc6dc4-wg7vg 1/1 Running 0 44h 10.0.10.159 10.0.10.73 <none> <none>
kube-proxy-dq29j 0/1 Pending 0 32h <none> 10.0.10.73 <none> <none>
kube-proxy-tlj27 0/1 Pending 0 9m33s <none> 10.0.10.231 <none> <none>
kube-proxy-z2h74 0/1 Pending 0 9m24s <none> 10.0.10.204 <none> <none>
csi-oci-node
とkube-proxy
がPendingになっています。これはVirtual NodeはDaemonsetが未サポートだからのようです。
$ kubectl -n kube-system get daemonsets.apps
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE SELECTOR AGE
csi-oci-node 3 3 0 3 0 <none> 44h
kube-proxy 3 3 0 3 0 beta.kubernetes.io/os=linux 32h
node-termination-handler 0 0 0 0 0 oci.oraclecloud.com/oke-is-preemptible=true 44h
nvidia-gpu-device-plugin 0 0 0 0 0 <none> 44h
proxymux-client 0 0 0 0 0 node.info.ds_proxymux_client=true 44h
vcn-native-ip-cni 0 0 0 0 0 <none> 44h
使えないなら、最初からデプロイしないでほしいですね。
作成、削除、ログイン
普通にPodを作成します。
$ k run nginx --image nginx
pod/nginx created
$ k get pod
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 2m35s
ログインします。
$ kubectl exec -it nginx -- sh
$
ログインできずにプロンプトが返ってきました。-c でコンテナ名を指定してログインしてみましたが、同様でした。
マニュアルには、サポートしていないと書かれています。
ログは確認できます。
$ kubectl logs nginx
2023-03-26T05:17:48.370146022Z stdout F /docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
2023-03-26T05:17:48.370166942Z stdout F /docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
2023-03-26T05:17:48.371551298Z stdout F /docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
2023-03-26T05:17:48.385396551Z stdout F 10-listen-on-ipv6-by-default.sh: info: Getting the checksum of /etc/nginx/conf.d/default.conf
2023-03-26T05:17:48.396026804Z stdout F 10-listen-on-ipv6-by-default.sh: info: Enabled listen on IPv6 in /etc/nginx/conf.d/default.conf
2023-03-26T05:17:48.408288933Z stdout F /docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
2023-03-26T05:17:48.436906488Z stdout F /docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
2023-03-26T05:17:48.440753522Z stdout F /docker-entrypoint.sh: Configuration complete; ready for start up
2023-03-26T05:17:48.44171872Z stderr F 2023/03/26 05:17:48 [notice] 1#1: using the "epoll" event method
2023-03-26T05:17:48.441727187Z stderr F 2023/03/26 05:17:48 [notice] 1#1: nginx/1.23.3
2023-03-26T05:17:48.441730101Z stderr F 2023/03/26 05:17:48 [notice] 1#1: built by gcc 10.2.1 20210110 (Debian 10.2.1-6)
2023-03-26T05:17:48.441731885Z stderr F 2023/03/26 05:17:48 [notice] 1#1: OS: Linux 5.4.17-2136.309.5.1.el8.container
2023-03-26T05:17:48.441733518Z stderr F 2023/03/26 05:17:48 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2023-03-26T05:17:48.441800666Z stderr F 2023/03/26 05:17:48 [notice] 1#1: start worker processes
2023-03-26T05:17:48.442342478Z stderr F 2023/03/26 05:17:48 [notice] 1#1: start worker process 29
2023-03-26T05:17:48.44234881Z stderr F 2023/03/26 05:17:48 [notice] 1#1: start worker process 30
ただ、kubectl logs -f
は使えず、-f オプションをつけてもつけてないと同じように表示されます。
削除します。
$ kubectl delete pod nginx
pod "nginx" deleted
Podの作成、削除は通常のKubernetesやOKEと比べて時間がかかる印象です。
また、EKS on FargateだとPodに合わせてNodeが増減しますが、OKE on Virtual NodeだとNode数は一定です。
namespace
Namespaceを作成して、Podを作成します。
$ kubectl create ns red
namespace/red created
$ kubectl run nginx-red --image nginx -n red
pod/nginx-red created
$ k -n red get pod
NAME READY STATUS RESTARTS AGE
nginx-red 1/1 Running 0 73s
追加設定なくできました。
Deployment
Deploymentを作成します。
$ kubectl create deployment nginx-dep --image nginx --replicas 10
deployment.apps/nginx-dep created
3つのNodeにPodがデプロイされています。
$ k get pod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-dep-5d749f9f67-48xrc 1/1 Running 0 34m 10.0.10.102 10.0.10.204 <none> <none>
nginx-dep-5d749f9f67-4c5sq 1/1 Running 0 34m 10.0.10.132 10.0.10.73 <none> <none>
nginx-dep-5d749f9f67-bxspw 1/1 Running 0 34m 10.0.10.191 10.0.10.204 <none> <none>
nginx-dep-5d749f9f67-jls47 1/1 Running 0 25m 10.0.10.201 10.0.10.73 <none> <none>
nginx-dep-5d749f9f67-k2z5b 1/1 Running 0 25m 10.0.10.177 10.0.10.231 <none> <none>
nginx-dep-5d749f9f67-k9jn5 1/1 Running 0 34m 10.0.10.229 10.0.10.204 <none> <none>
nginx-dep-5d749f9f67-krct4 1/1 Running 0 34m 10.0.10.50 10.0.10.204 <none> <none>
nginx-dep-5d749f9f67-mvb25 1/1 Running 0 34m 10.0.10.115 10.0.10.73 <none> <none>
nginx-dep-5d749f9f67-tvj2j 1/1 Running 0 34m 10.0.10.53 10.0.10.231 <none> <none>
nginx-dep-5d749f9f67-xk52d 1/1 Running 0 34m 10.0.10.43 10.0.10.231 <none> <none>
LoadBalancer
上記のDeployment(のPod)に対してLoadBalancerを作成します。
apiVersion: v1
kind: Service
metadata:
name: flex-nginx-lb
labels:
app: nginx-dep
annotations:
service.beta.kubernetes.io/oci-load-balancer-shape: "flexible"
service.beta.kubernetes.io/oci-load-balancer-shape-flex-min: "10"
service.beta.kubernetes.io/oci-load-balancer-shape-flex-max: "50"
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 80
selector:
app: nginx-dep
$ kubectl apply -f lb.yaml
service/flex-nginx-lb created
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
flex-nginx-lb LoadBalancer 10.96.212.65 150.230.25.196 80:31096/TCP 100s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP,12250/TCP 2d4h
しばらくするとLoadBalancerがデプロイされて、EXTERNAL-IPにIPアドレスが表示されますが、OCIのコンソールで確認すると、ヘルスチェックがクリティカルになっています。
マニュアルに以下の記載がありますので、セキュリティリストを設定します。
ロード・バランシング:ロード・バランシングは、ワーカー・ノード間ではなくポッド間です(管理対象ノードの場合と同様)。仮想ノードを含むクラスタでは、ロード・バランサ・セキュリティ・リスト管理が有効になっていないため、常にセキュリティ・ルールを手動で構成する必要があります。
LoadBalancerがデプロイされているサブネットに、ノードがデプロイされているサブネットへの以下2つのポートのEgressルールを追加します。
- LoadBalancerのポート番号(ここでは31096)
- kube-proxyのポート番号(10256)
同様にノードがデプロイされているサブネットに、LoadBalancerからのIngressルールを同様に追加します。
Egress, Ingressルールを追加すると、LoadBalancerのヘルスチェックがOKになります。
LoadBalancerのEXTERNAL-IPに対して、外部から疎通を確認します。
$ curl 150.230.25.196
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
その他制限事項
制限事項、未サポート機能としてここに書かれています。
個人的に以下をサポートしてないのは気になりました。
- init container
- kubectl logの -f オプション
- Security Context
- Container.Resources.Requests
- kubectl exec
- daemonset
- PVC
- NetworkPolicy