【Scala】Scala ~ 可変長引数のメソッドでネストした際の注意点 ~

◾️はじめに

久しぶりにコードを書く仕事にありつけた、、、

https://dk521123.hatenablog.com/entry/2024/07/30/155036

で、Scalaの可変長引数をやったが、
Javaのように使ったら単体試験でエラーになって大分ハマったので
メモしておく

目次

【1】Scalaで可変長引数のメソッドでネストした場合
【2】対応案
 1)修正例
【3】サンプル

【1】Scalaで可変長引数のメソッドでネストした場合

http://naoki-k.blogspot.com/2011/10/blog-post.html

に記載されている通り、
WrappedArray という型(ScalaのバージョンによってはArraySeq??)で
渡っているため意図した結果にならない

1)現象発生例

val result = getMessage("Hello")
println(result)

def getMessage(values: String*): String = {
  "%s".format(values)
}

https://scastie.scala-lang.org

で実行したら「ArraySeq(Hello)」

【2】対応案

* 可変長引数のメソッドでネストする場合、
 「_*」シンボルを指定する必要がある

1)修正例

val result = getMessage("Hello")
println(result)

def getMessage(values: String*): String = {
  // ★ここに注目(「values: _*」)
  "%s".format(values: _*)
}

https://scastie.scala-lang.org

で実行したら「Hello」(OK動作!)

【3】サンプル

object Hello {
  def main(args: Array[String]): Unit = {
    // toList
    val result1s = toList("Hello", "world", "")
    println(result1s.get.mkString(","))

    println("Done")
  }

  def toList(values: String*): Option[List[String]] = {
    // ★(values: _*)部分★
    if (values.isEmpty) None else toListWithFilter(values: _*)
  }

  def toListWithFilter(values: String*): Option[List[String]] = {
    if (values.isEmpty)
      None
    else {
      val list = values.filter(x => x.nonEmpty).map(x => x).toList
      if (list.isEmpty) None else Some(list)
    }
  }
}

参考文献

https://jumble-note.blogspot.com/2013/06/scala.html
http://naoki-k.blogspot.com/2011/10/blog-post.html

関連記事

Scala ~ 環境構築編 ~
https://dk521123.hatenablog.com/entry/2023/03/10/193805
Scala ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2023/03/12/184331
Scala ~ 可変長引数 ~
https://dk521123.hatenablog.com/entry/2024/07/30/155036
Scala ~ 基本編 / Option型 ~
https://dk521123.hatenablog.com/entry/2023/03/09/000000
Scala ~ 基本編 / ジェネリック
https://dk521123.hatenablog.com/entry/2023/03/21/003817
Scala ~ 基本編 / コレクション ~
https://dk521123.hatenablog.com/entry/2023/03/13/000345
Scala ~ コレクションで使えるメソッド ~
https://dk521123.hatenablog.com/entry/2023/09/07/223422
Scala ~ mutable collection ~
https://dk521123.hatenablog.com/entry/2024/07/09/223730
Scala ~ 基本編 / メソッド ~
https://dk521123.hatenablog.com/entry/2023/03/03/000000
Scala ~ 基本編 / 繰り返し ~
https://dk521123.hatenablog.com/entry/2023/01/24/000000
Scala ~ 基本編 / トレイト ~
https://dk521123.hatenablog.com/entry/2023/09/10/204016
Scala ~ 基本編 / パターンマッチング ~
https://dk521123.hatenablog.com/entry/2023/06/06/233614
Scala ~ 基本編 / 例外処理 ~
https://dk521123.hatenablog.com/entry/2023/10/05/000135
ScalaEnum
https://dk521123.hatenablog.com/entry/2023/01/05/000000
Scala ~ asInstanceOf / isInstanceOf ~
https://dk521123.hatenablog.com/entry/2024/07/26/225713
Scala ~ implicit ~
https://dk521123.hatenablog.com/entry/2024/07/24/120726
Scala ~ 代数的データ型 / ADT ~
https://dk521123.hatenablog.com/entry/2024/07/23/193246
Scala ~ Joda-Time ~
https://dk521123.hatenablog.com/entry/2024/07/10/001348
ScalaTest ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2023/03/27/001306
ScalaTest ~ 基本編 ~
https://dk521123.hatenablog.com/entry/2023/03/28/003906
ScalaTest ~ あれこれ編 ~
https://dk521123.hatenablog.com/entry/2024/06/11/232020

【k8s】Kubernetes ~ Kind ~

◾️はじめに

以下の「つくって、壊して、直して学ぶ Kubernetes入門」を借りて
読んでいるのだが、その中では「Minikube」ではなく「kind」を使っていたので
ちょっとまとめてみた

目次

【0】ローカルクラスタ
【1】kind
 1)特徴
【2】環境設定
 0)前提条件
 1)kubectlのインストール
 2)kindのインストール
【3】クラスタの立ち上げ方法
 1)クラスタの構築
 2)動作確認
 3)後片付け
【4】Hello world - Pod起動 -
 0)前提条件
 1)定義ファイル (マニフェストファイル) 作成
 2)Podを作成
 3)Pod の作成確認
 4)後片付け

【0】ローカルクラスタ

1)Minikube
2)Kind << ★今回のテーマ
3)k3s

【1】kind

* kind = Kubernetes IN Docker

1)特徴

* マルチノードクラスタを作成できる
 => Docker in Docker(Dockerの中にDockerを立ち上げる)
 => なので、Dockerは必須

【2】環境設定

0)前提条件

* Docker がインストールされていること
* Linuxの場合、Go v1.16以上がインストールされていること

1)kubectlのインストール

* 以下の公式ドキュメントに従い、インストールする

https://kubernetes.io/ja/docs/tasks/tools/

Macの場合
https://kubernetes.io/ja/docs/tasks/tools/install-kubectl-macos/#install-with-homebrew-on-macos

# Case1: brew が使える場合
brew install kubectl

# 確認
kubectl version --client

2)kindのインストール

# Case1: brew が使える場合
brew install kind

# Case2: Goがインストールされている場合
go install sigs.k8s.io/kind@v0.26.0

# 確認
kind version

【3】クラスタの立ち上げ方法

1)クラスタの構築

kind create cluster --image=kindest/node:v1.29.12

# kind create cluster

https://hub.docker.com/r/kindest/node/

2)動作確認

# Step1: kubectlコマンドで確認
$ kubectl cluster-info --context kind-kind
Kubernetes control plane is running at https://127.0.0.1:49896
CoreDNS is running at https://127.0.0.1:49896/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

# Step2: 設定ファイルを表示
$ more ~/.kube/config
apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: L...
    server: https://127.0.0.1:49896
  name: kind-kind
contexts:
- context:
    cluster: kind-kind
    user: kind-kind
  name: kind-kind
current-context: kind-kind
kind: Config
preferences: {}
users:
- name: kind-kind
  user:
    client-certificate-data: L...
    client-key-data: L...

3)後片付け

# クラスタの削除
$ kind delete cluster

# 確認
$ kubectl cluster-info --context kind-kind
error: context "kind-kind" does not exist

【4】Hello world - Pod起動 -

0)前提条件

# クラスタを立ち上げておくこと
kind create cluster --image=kindest/node:v1.29.12

1)定義ファイル (マニフェストファイル) 作成

hello-world.yaml

apiVersion: v1
kind: Pod
metadata:
  name: hello-world-demo
  labels:
    app: hello-world-demo
spec:
  containers:
    - name: demo-server
      image: nginx:1.25.3
      ports:
      - containerPort: 18080

2)Podを作成

# YAMLファイルに基づいてPodを作成
$ kubectl apply -f hello-world.yaml --namespace default
pod/hello-world-demo created

3)Pod の作成確認

# Podの一覧表示
$ kubectl get pod --namespace default
NAME               READY   STATUS    RESTARTS   AGE
hello-world-demo   1/1     Running   0          3m1s

# Podに関する情報を表示
$ kubectl describe pod hello-world-demo --namespace default
Name:             hello-world-demo
Namespace:        default
Priority:         0
Service Account:  default
Node:             kind-control-plane/172.xxx.xxx.xxx
Start Time:       Mon, 20 Jan 2025 23:47:28 +0900
Labels:           app=hello-world-demo
Annotations:      <none>
Status:           Running
IP:               10.xxx.xxx.xxx
IPs:
  IP:  10.244.0.5
Containers:
  demo-server:
    Container ID:   containerd://xxxx
    Image:          nginx:1.25.3
    Image ID:       docker.io/library/nginx@sha256:xxxxxx
    Port:           18080/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Mon, 20 Jan 2025 23:47:42 +0900
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-z87gn (ro)
Conditions:
  Type                        Status
  PodReadyToStartContainers   True 
  Initialized                 True 
  Ready                       True 
  ContainersReady             True 
  PodScheduled                True 
Volumes:
  kube-api-access-z87gn:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
QoS Class:                   BestEffort
Node-Selectors:              <none>
Tolerations:                 node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
                             node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  4m39s  default-scheduler  Successfully assigned default/hello-world-demo to kind-control-plane
  Normal  Pulling    4m38s  kubelet            Pulling image "nginx:1.25.3"
  Normal  Pulled     4m25s  kubelet            Successfully pulled image "nginx:1.25.3" in 13.235s (13.235s including waiting)
  Normal  Created    4m25s  kubelet            Created container demo-server
  Normal  Started    4m25s  kubelet            Started container demo-server

4)後片付け

# クラスタの削除
$ kind delete cluster

# 確認
$ kubectl cluster-info --context kind-kind
error: context "kind-kind" does not exist

関連記事

KubernetesWindows / 環境構築編 ~
https://dk521123.hatenablog.com/entry/2020/05/01/000000
KubernetesLinux / 環境構築編 ~
https://dk521123.hatenablog.com/entry/2024/01/02/005053
Kubernetes ~ MicroK8s / 環境構築編 ~
https://dk521123.hatenablog.com/entry/2024/03/10/230329
Kubernetes ~ 基礎知識編 ~
https://dk521123.hatenablog.com/entry/2020/04/27/224624
Kubernetes ~ 入門編 ~
https://dk521123.hatenablog.com/entry/2020/05/04/013529
KubernetesKubernetes Dashboard
https://dk521123.hatenablog.com/entry/2023/05/27/144144
Kubernetes ~ 基本編 / Pod ~
https://dk521123.hatenablog.com/entry/2024/03/16/111336
Kubernetes ~ 基本編 / minikube ~
https://dk521123.hatenablog.com/entry/2023/05/07/214515
Kubernetes ~ 基本編 / kubectlコマンド ~
https://dk521123.hatenablog.com/entry/2022/01/12/110555
Kubernetes ~ 基本編 / kubeconfigファイル ~
https://dk521123.hatenablog.com/entry/2023/05/24/211803
Kubernetes ~ 基本編 / Helm ~
https://dk521123.hatenablog.com/entry/2023/05/11/000840
Amazon EKS ~ 基礎知識編 ~
https://dk521123.hatenablog.com/entry/2023/02/23/000000
Kubernetes / minikube に関するトラブル
https://dk521123.hatenablog.com/entry/2024/10/24/210338

【k8s】Kubernetes ~ kubelet ~

◾️はじめに

kubelet について、徐々にまとめていく。

目次

【1】kubelet
【2】環境設定

【0】

                   Control Plane              Worker Node
          +------------------------------+ +-------------+
          |         +----------+         | |         +----------+         |
          |         |   etcd   |         | |           |         |   kubelet   |         |
          |         +----------+         | |         +----------+
          |               ↓              |  
kubectl   |         +-----------+        |
------------------->| kube-     |        |
          |         | apiserver |        |
          |         +-----------+        |
          |               ↑              |  
          |        |           |         | 
          | +----------+  +------------+ |
          | | kube-    |  | kube-      | |
          | | scheduler|  | controller-| |
          | |          |  | manager    | |
          | +----------+  +------------+ | 
          +------------------------------+

【1】kubelet

* クラスタ内の各ノードで実行されるエージェント
* Podやコンテナの起動などを行う

【2】環境設定

* 以下に詳しく記載されている

https://qiita.com/Yoyo-kikuchi/items/e4092805f9ce9ac6175c

1)手順

公式ドキュメント
https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/
[1] スワップを無効にする

# Swapがオフであること。
# kubeletが正常に動作するためにはswapは必ずオフでなければなりません。

# スワップの使用状況をデバイスごとに表示する
$ swapon -s
# スワップを無効にする
$ swapoff -a

[2] インストールする

# 公式ドキュメントより抜粋

# [1] Set SELinux to permissive mode
# (SELinuxをpermissiveモードに設定する(効果的に無効化する))
sudo setenforce 0
sudo sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config

# [2] This overwrites any existing configuration in /etc/yum.repos.d/kubernetes.repo
$ cat <<EOF | sudo tee /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/v1.30/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/v1.30/rpm/repodata/repomd.xml.key
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
EOF

# [3] Install kubelet, kubeadm and kubectl
$ sudo dnf install -y kubelet kubeadm kubectl --disableexcludes=kubernetes

# [4] (Optional) Enable the kubelet service before running kubeadm
$ sudo systemctl enable --now kubelet

関連記事

Kubernetes ~ 基礎知識編 ~
https://dk521123.hatenablog.com/entry/2020/04/27/224624
KubernetesLinux / 環境構築編 ~
https://dk521123.hatenablog.com/entry/2024/01/02/005053
SELinux
https://dk521123.hatenablog.com/entry/2017/12/10/222000