🫙

memo "Kubernetes in Docker" 🫙

2023/04/26に公開

こんにちは。Enabling team の山本です。

今回は、Kubernetes in Dockerkind )についてです。

3年ぶりに kind をやり直す動機は、研修のためです。

研修で kind の実習を行うため、手順を再確認します。

TL;DR

  • Install 手順は、変わっていない。
  • Artifact Registry の認証さえ通れば、GKE と同じ。

構築

Compute Instance の作成

  • machinie の spec に意味はありません。最適なものを選びます。
gcloud compute instances create kind-danny --machine-type=e2-standard-2 --zone=asia-northeast1-a

Install

# docker
sudo apt-get update
sudo apt-get remove docker docker-engine docker.io containerd runc
sudo apt-get update
sudo apt-get install \
    ca-certificates \
    curl \
    gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg
echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
sudo docker run hello-world
sudo apt-get install -y wget

# Go
cd /usr/local/
sudo wget https://go.dev/dl/go1.20.3.linux-amd64.tar.gz
sudo tar -C /usr/local -xzf go1.20.3.linux-amd64.tar.gz
export PATH=$PATH:/usr/local/go/bin

# kind
sudo curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.18.0/kind-linux-amd64
sudo chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind

# kubectl
cd /usr/local/
sudo curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

kind cluster 作成

# root の password を変更
sudo passwd root
# root に switch
su -
# cluster 作成
kind create cluster --name hoge
# cluster の作成を確認
kind get clusters
# cluster への接続情報を作成
kubectl cluster-info --context kind-hoge

テスト

Pod、Deployment の動作を確認

# Node の状態を確認
kubectl get node
# Nginx の Pod を作成
kubectl run nginx --image=nginx --restart=Never
# command を別名登録
alias k=kubectl
# Pod の状態を確認
k get po
# deployment を作成
cat << EOF  | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx
spec:
  selector:
    matchLabels:
      run: my-nginx
  replicas: 2
  template:
    metadata:
      labels:
        run: my-nginx
    spec:
      containers:
      - name: my-nginx
        image: nginx
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: my-nginx
  labels:
    run: my-nginx
spec:
  ports:
  - port: 80
    protocol: TCP
  selector:
    run: my-nginx
EOF
# Pod 間通信を確認するため、2つ目の deployment を作成
cat << EOF  | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx-b
spec:
  selector:
    matchLabels:
      run: my-nginx-b
  replicas: 2
  template:
    metadata:
      labels:
        run: my-nginx-b
    spec:
      containers:
      - name: my-nginx-b
        image: nginx
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: my-nginx-b
  labels:
    run: my-nginx-b
spec:
  ports:
  - port: 80
    protocol: TCP
  selector:
    run: my-nginx-b
EOF
  • どちらかの Pod に入る
  • DNS に curl を送信して「Welcome Nginx」が表示されることを確認します。
# nslookup を install
apt-get install dnsutils
# service の DNS を確認
nslookup my-nginx-b
nslookup my-nginx
  • config の mount を確認します。
  • index.html を変更します。
cat << EOF  | kubectl apply -f -
apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-index
data:
  index.html: |-
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to hoge!</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>
EOF
cat << EOF  | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-nginx-b
spec:
  selector:
    matchLabels:
      run: my-nginx-b
  replicas: 2
  template:
    metadata:
      labels:
        run: my-nginx-b
    spec:
      containers:
      - name: my-nginx-b
        image: nginx
        ports:
        - containerPort: 80
        volumeMounts:
        - name: index
          mountPath: /usr/share/nginx/html/
      volumes:
        - name: index
          configMap:
            name: nginx-index
EOF

Image を Private Image リポジトリに push、pull

  • DockerHub の Image を Private Image リポジトリに push します。
  • Cloud Shell で実行します。
# pull
docker pull nginx:1.24.0
# auth
gcloud auth configure-docker asia-northeast1-docker.pkg.dev
docker images
# tag 付け
docker tag nginx:latest asia-northeast1-docker.pkg.dev/junior-engineers-gym-2023/danny/nginx:1.24.0
# push
docker push asia-northeast1-docker.pkg.dev/junior-engineers-gym-2023/danny/nginx:1.24.0
  • console で作成した credentials.json を key.json として保存します。
vi key.json
  • Private Image リポジトリを認証します。
cat key.json | docker login -u _json_key --password-stdin asia-northeast1-docker.pkg.dev
  • secret を作成します。
kubectl create secret docker-registry my-secret-b   --docker-server=https://asia-northeast1-docker.pkg.dev   --docker-username=_json_key   --docker-email=kind-test@junior-engineers-gym-2023.iam.gserviceaccount.com   --docker-password="$(cat key.json)"
  • Private Image で Pod を apply します。
    • imagePullSecrets に secret を指定します。
cat << EOF  | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
  - name: my-container
    image: asia-northeast1-docker.pkg.dev/hoge/danny/nginx:1.24.0
  imagePullSecrets:
  - name: my-secret-b
EOF

まとめ

kind について書きました。
managed service を使用していると、「この option 何だっけ?」というのは、高頻度であります。そこが面倒に感じます。特に、managed service は、機能追加が継続的に行われるため。
一方、kind は、自分の client で手軽に動かせるメリットはあると思います。

参考

Discussion