[Ubuntu, k3s] Kubernetesの基本のキをしていく

Minikubeをインストールしつつ、できればCI/CDの環境を整える。
買ってきてなんにも入れてないUbuntu Server22.04での作業

※試した順に書いているけど、Minukubeじゃなくてk3sにしました。(5からk3s)

※IngressとArgo CDはそれぞれ掘り下げたいのでここではインストールと動作確認のみです。

注意:作業と並行して更新しているので未完です

1. Dockerのインストール

# add GPG key
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg

# add repository
$ echo "deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# install dependencies
$ sudo apt-get install apt-transport-https ca-certificates curl gnupg lsb-release -y

# install docker
$ sudo apt-get update
$ sudo apt-get install docker-ce docker-ce-cli containerd.io -y

# add user to docker group
$ sudo usermod -aG docker $USER

# run docker
$ docker version
$ docker pull hello-world

2. Kubectlのインストール

# install dependencies
$ sudo apt install -y apt-transport-https gnupg2

# add GPG key
$ curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -

# add repository
$ echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee /etc/apt/sources.list.d/kubernetes.list

# install kubectl
$ sudo apt update
$ sudo apt install -y kubectl

# check
$ kubectl version --client --output=json

3. Minikubeのインストール

# install minikube
$ curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
$ sudo install minikube-linux-amd64 /usr/local/bin/minikube

# run minikube
$ minikube start

# 最初に公式じゃないとこの手順でインストールしたら、下記入れろって怒られた。
# 不要かもしれない
$ sudo wget https://github.com/Mirantis/cri-dockerd/releases/download/v0.3.10/cri-dockerd-0.3.10.amd64.tgz -C /usr/local/bin

4. Minikubeをサービス登録

毎回起動面倒なのとローカルネットワークなので、サービス登録しちゃう。
参考リンクそのまま

# create service file
$ sudo vi /etc/systemd/system/minikube.service
[Unit]
Description=Minikube Cluster
After=containerd.service docker.service

[Service]
Type=oneshot
ExecStart=/usr/local/bin/minikube start
RemainAfterExit=true
ExecStop=/usr/local/bin/minikube stop
StandardOutput=journal
User=username
Group=docker

[Install]
WantedBy=multi-user.target
$ sudo systemctl daemon-reload
$ sudo systemctl enable minikube.service
$ sudo restart

5. Minikubeのアンインストール

本当ごめんなさい。ここまでやって、サービスとかデプロイとか作ってみたんだけど
Minikubeは動作がもっさりしていること、ネットワーク設定が若干面倒なことから
(NodePortにLAN内の他ホストから直接アクセスできない。多分設定頑張れば出来るけど無知すぎる)

k3sに乗り換えることにしました。

こちらの手順も参考リンク通り

$ minikube stop
$ minikube delete
$ sudo rm -rf /usr/local/bin/minikube
$ rm -rf ~/.minikube
$ rm -rf ~/.kube

# 参考リンクではOptionalだったけど、違うk8sいれるなら消したほうがいいです
$ sudo rm -rf /usr/local/bin/kubectl

How to Uninstall Minikube on Ubuntu

6. k3sのインストール

シングルノード(1PCで全部)でやりたいならコマンド一発

$ curl -sfL https://get.k3s.io | sh -

# 確認
$ systemctl status k3s
$ sudo kubectl get all -n kube-system

# kubectlの実行にsudoいらないように
$ sudo chmod 644 /etc/rancher/k3s/k3s.yaml

これだけでさっきまで作ったMinikubeの環境に追いつきます。
(サービスの登録とか、kubectlのインストールとかもやってくれる。dockerも不要。)

しかもNodePortへのアクセスもLAN内の他ホストからできるようになる。
MinikubeはVM上に構築するので、多分もう一段階設定が必要だったんだと思う
(分かってないので必要に応じて後で調べます。)

https://www.digitalocean.com/community/tutorials/how-to-setup-k3s-kubernetes-cluster-on-ubuntu

後学のため、後からノード増やしたいとかなったらこれでいいらしい。
もう一台のサーバーはパルワールドが専有しているので閉じたらやってみる。
https://docs.k3s.io/quick-start

curl -sfL https://get.k3s.io | K3S_URL=https://myserver:6443 K3S_TOKEN=mynodetoken sh -

7. まずミニマムなサービスを動かしてみる。

定義内容はk8sの入門書にあったものを少しいじったもの。

# apache_dep.yaml
apiVersion:  apps/v1
kind: Deployment
metadata:
  name: apa000dep
spec:
  selector:
    matchLabels:
      app: apa000kube
  replicas: 3
  template:
    metadata:
      labels:
        app: apa000kube
    spec:
      containers:
        - name: apa000ex91
          image: httpd
          ports:
            - containerPort: 80
---
# apache_ser.yaml
apiVersion: v1
kind: Service
metadata:
  name: apa000ser
spec:
  type: NodePort
  ports:
    - port: 8099
      targetPort: 80
      protocol: TCP
      nodePort: 30080
  selector:
    app: apa000kube
$ kubectl apply -f apache_dep.yaml
$ kubectl apply -f apache_ser.yaml

これで, http://[server local ip]:30080でapacheのホームが表示される。
簡単すぎるだろ!!!!

スクリーンショット 2024-02-27 023949

後学のために自分用メモ。Portがとくかくややこしい。

  • pod: apacheのコンテナ。port 80
  • replica: 3台構成
  • NodePort: 30080で外部からアクセスできるようにする
  • ServiceのPort: 8099
    • NodePort(30080) => ServicePort(8099)負荷分散的な => ContainerPort(80)
    • こんな感じで転送される。
    • ここから下は勉強のための想像
    • (合ってるかわからないが現状イメージや予想) 一般的なWebサービスを例とするなら
      • ※ポート番号は適当
      • DBサーバー: NodePort 13306
        • ServicePort 13336
          • ContainerPort3306で待ち受けるDBクラスタ
      • APIサーバー: NodePort 18080
        • ServicePort 8080
          • ContainerPort80で待ち受けるAPIサーバー複数
      • フロントサーバー: NodePort 28080 (これだけ公開したい)
        • ServicePort 8080
          • ContainerPort80で待ち受けるフロントサーバー複数
      • そのうえでこういうサービスが複数運用されていたら、Ingressとかでルーティング?(後学
        • このk3sのクラスタに1グローバルIPがあるとして、複数種類のドメインからアクセスされたケースを想定
        • A.comでアクセスされたらフロントサーバーに、B.comでアクセスされたらほかのサーバーにみたいなこと
        • chatgptに聴いたらこんな感じのことを言ってた気がするのでメモった。

kubernetes-dashboardを動かしてみる

ちょっと調べた感じ、公式と2種類でてきた。

公式
Portainer

どっちがいい、とかは現状自分の知識じゃ判断できないけどインストールして、そのまま外部からアクセスできるようになっていたのがPortainerだったのでそっちを使ってみている。

# StorageClassの名前を確認
$ kubectl get sc

# 出てきたものをデフォルトに設定
$ kubectl patch storageclass <storage-class-name> -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'

# install portainer
$ kubectl apply -n portainer -f https://downloads.portainer.io/ce2-19/portainer.yaml

# ポート確認
$ kubectl get svc -n portainer
NAME                       TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)                                         AGE
portainer                  NodePort       10.43.111.203   <none>          9000:30777/TCP,9443:30779/TCP,30776:30776/TCP   13h
portainer-agent-headless   ClusterIP      None            <none>          <none>                                          13h
portainer-agent            LoadBalancer   10.43.227.155   192.168.0.222   9001:32643/TCP                                  13h

この状態でhttp://[server local ip]:30777にアクセスすると、Portainerのログイン画面が表示される。

エージェントの入れ方とか、設定とかは割愛
公式に複数の方法で説明があります。

自分の場合なんかデフォルトのままで現状ほしい情報は載ってたので一旦そのまま

スクリーンショット 2024-02-28 034733

Ingressを導入して、経由してアクセスしてみる

参考:Qiita k3sでアプリケーションをデプロイし、外部からアクセスしてみた

Namespaceの作成

自作アプリケーションをデプロイするためのNamespaceを作成。

# create namespace
$ kubectl apply -f tamago_namespace.yml
# tamago_namespace.yml
apiVersion: v1
kind: Namespace
metadata:
  name: tamago
  labels:
    name: tamago

Deploymentの作成

$ kube apply -f tamago_deployment.yml
# tamago_deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-app
  namespace: tamago
  labels:
    app: tamago
spec:
  replicas: 1
  selector:
    matchLabels:
      app: sample-app
  template:
    metadata:
      labels:
        app: sample-app
    spec:
      containers:
        - image: containous/whoami:v1.5.0
          name: whoami

Serviceの作成

サービス2つ作ってみる

$ kubectl apply -f tamago_service1.yml
$ kubectl apply -f tamago_service2.yml
# tamago_service1.yml
apiVersion: v1
kind: Service
metadata:
  name: sample-app1
  namespace: tamago
  labels:
    app: sample-app1
spec:
  ports:
    - name: "whoami"
      port: 18080
      protocol: TCP
      targetPort: 80
  selector:
    app: sample-app
  type: ClusterIP
# tamago_service2.yml
apiVersion: v1
kind: Service
metadata:
  name: sample-app2
  namespace: tamago
  labels:
    app: sample-app2
spec:
  ports:
    - name: "whoami"
      port: 18081
      protocol: TCP
      targetPort: 80
  selector:
    app: sample-app
  type: ClusterIP

各サービスはClusterIPで作成しているので、外部からアクセスできない。

Ingressの作成

$ kubectl apply -f tamago_ingress.yml
# tamago_ingress.yml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: sample-ingress
  namespace: tamago
spec:
  rules:
    - host: sample-app1.local
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: sample-app1
                port:
                  number: 18080
    - host: sample-app2.local
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: sample-app2
                port:
                  number: 18081
  • [ ] TODO: これでホストに応じてアクセスを分けられているかチェック
  • [ ] TODO: 勝手に80で待ち受けされるけど、設定可能か、問題ないのか
  • [ ] TODO: 複数のIngressを作成した場合、どうなるか

ArgoCDを導入してみる

参考:ArgoCDのインストール

基本的には公式の手順のままで動く。が1点追加

# install argocd
kubectl create namespace argocd
kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/install.**yaml**

# install argocd cli
curl -sSL -o argocd-linux-amd64 https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
sudo install -m 555 argocd-linux-amd64 /usr/local/bin/argocd
rm argocd-linux-amd64

# 外部からアクセスできるようにロードバランサーに変更
kubectl patch svc argocd-server -n argocd -p '{"spec": {"type": "LoadBalancer"}}'

# ここが公式にない。k3sだとKUBECONFIGが環境変数に設定されていないっぽいので自分で設定
echo "export KUBECONFIG=/etc/rancher/k3s/k3s.yaml" >> ~/.bashrc

# 初期パスワードの表示(あとで変えてね
argocd admin initial-password -n argocd

# ログイン(IPとポートは自分の環境に応じて変更してね ex: kubecctl get svc -n argocd)
argocd login 127.0.0.1:30696

# ログイン後、パスワードを入力
argocd account update-password

ここまでやってブラウザにアクセスして、設定したパスワードでログインできたらOK(ユーザ名はadmin)
スクリーンショット 2024-03-01 003226

2024-03-10追記:自宅のネットワーク工事が延期やら、やり直しでサーバーを落ち着いたネットワークで稼働できないので、環境落ち着き次第追記します。

上部へスクロール