新着記事

Viewing posts for the category Kubernetes

Ubuntu22 に MicroK8s で Kubernetes 環境を構築し、その中で Rancher を起動する

今まで(2021年頃まで) は、社内サーバの Kubernetes 環境を作る際は、 Rancher を Docker で起動し、その中の RKE で Kubernetes クラスタを構築していました。

ところが、それだと OS のアップデートがあったりした時など、年一回ぐらいのペースでトラブルがあり、環境が再構築不能になってしまっていました。

Rancher + RKE で Kubernetes 環境を作っている場合、トラブルの原因を追うのが非常に難しくて、原因まで解明して解決できたことはありません。

今回は、 Kubernetes 環境は Ubuntu の MicroK8s で起動し、その K8s の中で、 Deployment として Rancher を起動するようにしました。

試してみた所、なかなか快適だったため、今後もこのパターンは使っていこうと思います。

OS は Ubutntu 22.04 で、ノードはシングルノード構成です。やはり OS が Ubutnu の場合は MicroK8s が簡単で安定しており、Ingress なども一発で有効化できるため、セットアップは楽でした。

1. MicroK8s の セットアップ

1-1. インストール

sudo snap install microk8s --classic

1-2. ユーザーに権限を付与する

sudo usermod -a -G microk8s ubuntu
sudo chown -f -R ubuntu ~/.kube
newgrp microk8s

1-3. DNS, Ingress の有効化

microk8s enable dns ingress

1-4. ダッシュボードを使う場合

Rancher が起動したらダッシュボードは不要だと思いますが、Rancher 起動前の確認用として重宝します。

microk8s enable dashboard

Kubernetes のノード上で

microk8s kubectl port-forward -n kube-system service/kubernetes-dashboard --address 0.0.0.0 31443:443

してから、https://<your-host>:31443/ を見る

2. kubeconfig の取得

microk8s config

コピペして、 Mac の .kube/config-<Config名> にコピーしておく

3. namespace の作成

※ Macで実行

#!/usr/bin/env zsh

export KUBECONFIG=${HOME}/.kube/config-<Config名>

kubectl create namespace <ネームスペース>

4. secrets の作成

SSL証明書 (wildcard.example.com.key, wildcard.example.com.crt) を mac のディレクトリに用意して、

※ Macで実行

#!/usr/bin/env zsh

export KUBECONFIG=${HOME}/.kube/config-<Config名>

kubectl -n <ネームスペース> create secret tls tls-certificate \
--key <wildcard.example.com.key> \
--cert <wildcard.example.com.crt>

5. Rancher のインストール

サーバに /data/rancher ディレクトリを作っておく

deployment.yml

apiVersion: apps/v1
kind: Deployment
metadata:
name: my-awesome-rancher-deployment
namespace: <ネームスペース>
spec:
replicas: 1
selector:
matchLabels:
app: my-awesome-rancher
template:
metadata:
labels:
app: my-awesome-rancher
spec:
containers:
- name: my-awesome-rancher
image: rancher/rancher:v2.6-head
imagePullPolicy: Always
ports:
- containerPort: 80

volumeMounts:
- name: data-rancher
mountPath: /var/lib/rancher

imagePullSecrets:
- name: ecr-credeintial

volumes:
- name: data-rancher
hostPath:
path: /data/rancher

service.yml

apiVersion: v1
kind: Service
metadata:
  name: my-awesome-rancher-service
namespace: <ネームスペース>
spec:
type: NodePort
ports:
- port: 80
protocol: TCP
targetPort: 80
name: my-awesome-rancher-http
selector:
app: my-awesome-rancher

ingress.yml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: my-awesome-rancher-ingress
namespace: <ネームスペース>
spec:
tls:
- hosts:
- my-awesome-rancher.example.com
secretName: tls-certificate
rules:
- host: my-awesome-rancher.example.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: my-awesome-rancher-service
port:
number: 80

※ mac で実行

#!/usr/bin/env zsh

export KUBECONFIG=${HOME}/.kube/config-<Config名>

kubectl apply -f deployment.yml
kubectl apply -f service.yml
kubectl apply -f ingress.yml

6. Rancher の ブートストラップパスワードの取得

Rancher を起動すると、「ブートストラップパスワード」が発行され、ログに表示されます。

今回は Kubernetes の Pod として起動しているため、Pod のログを grep します。

 ※ Macで実行

#!/usr/bin/env zsh

export KUBECONFIG=${HOME}/.kube/config-<Config名>

pods=( $(kubectl get pod -n <ネームスペース> | egrep -o "my-awesome-rancher-deployment-[a-zA-Z0-9-]+") )

for pod in "${pods[@]}" ; do
kubectl logs -n <ネームスペース> ${pod} | grep "Bootstrap Password:"
done

7. ブラウザから Rancher へのログイン

my-awesome-rancher.example.com (仮のドメインです) というドメインで Rancher が起動しているはずなので、DNS を設定してからブラウザでアクセスします。

Bootstrap Password の入力を求められるので、先程取得したものを入力します。

ローカルで起動している MicroK8s のシングルノードクラスタを自動的に認識し、管理できるようになります。

付録

kubernetes の secret へ、AWS の EKS のログイントークンを登録する Python スクリプト

当社は、Docker イメージリポジトリは AWS ECR を使っています。
ローカルPCの ~/.aws/credentials の認証情報を元に、 Kubernetes の Secret を作るスクリプトを紹介します。

#!/usr/bin/env python3

import subprocess
import re
import sys

namespace = '<ネームスペース>'
secret_name = 'ecr-credeintial'
aws_region = 'ap-northeast-1'
docker_server = 'https://<AWS-ID>.dkr.ecr.ap-northeast-1.amazonaws.com'


def main():
output = subprocess.check_output([
'/usr/bin/aws', 'ecr', 'get-login',
'--no-include-email', '--region', aws_region,
]).decode()
words = output.split()
username = words[words.index('-u') + 1]
password = words[words.index('-p') + 1]

// 既に作成済みの secret を消す
command = [
// kubectl の実行環境に合わせて調整してください
'microk8s', 'kubectl', '-n', namespace, 'delete', 'secret', secret_name]
subprocess.run(command)

// secret を再登録する
command = [
'microk8s', 'kubectl', '-n', namespace, 'create', 'secret',
'docker-registry', secret_name,
f'--docker-username={username}',
f'--docker-password={password}',
f'--docker-server={docker_server}'
]
subprocess.run(command)


if __name__ == '__main__':
main()
Search