0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

kubernetesゼロから入門してみたので備忘録作ります

Last updated at Posted at 2023-02-20

ナニコレ

個人的な備忘録です。忘れた時に手早く探せるように...随時加筆です。間違ってるところもあるかもしれないでの、間違ったらご指摘していらだければ幸いです。

抽象的なもの

以下のものはkubernetsのチュートリアルから引用:(個人的な理解も含めるので、間違ったらご指摘していらだければ幸いです)。

ホームページにあるように、k8sの特徴の一つはPlanet Scaleです。この特徴に相応しく、k8sの設計もまるで1個1個の惑星を繋いでいくようなものでした。

k8s_01.png

  • clusterは全てのものを入れる容器のようなもの。バーチャルネットワークを作り、外部からアクセスできないようにする。
    • control planeはdeploymentを通してnodeなどを制御する中枢
      • deploymentはどのようにnodeをコントロールするかの設定ファイルのようなもの
    • nodeはk8sのwoker machine。仮想マシンでも物理マシンでも構わないようです。
      • kubeletはnodeとmasterの間の通信を担当するプロセス。podとコンテナの管理もしている。
      • podは実際にコンテナアプリを入れるもの
        • 中には複数のcontainerと共有スペース(volume)を持つことができる
        • nodeに障害が発生した場合、podはclusterないの別のnodeにスケジュールされる
    • serviceはどのようにpodを外部に公開するかを定義する抽象的概念
      • podは死んだり復活したりする(例えばnodeが死んだ時別のnodeにスケジュールする)ので、serviceはLabelSelectorを使ってpodを抽象的に特定する。

minikube / kubernets

まずはこのページへ行ってインストール

そしてkubectlに関して普通に入れていいですが、簡単なやりかたでminikube経由で入れる

minikube kubectl -- get po -A

そしてalias設定、.bashrcなどで永続化しても良さそう

alias kubectl="minikube kubectl --"

clusterを作る

minikube start

deploymentを作る

kubectl create deployment <deployment_name> --image=name:tag

local imageを使う
参考記事:https://miyazi888.hatenablog.com/entry/2022/05/22/194940

minikube image load image:tag

deploymentsの詳細を見る
何かを見る時はgo-templateを使って詳細を絞るのも良さそう。
参考記事:https://k69blog.com/posts/k8s_go_template/

kubectl describe deployments

deploymentのimageを更新

kubectl set image deployment/<deployment_name> <container_name>=image:tag

指定した revision まで rollback
参考記事:https://tech-lab.sios.jp/archives/18550

kubectl rollout undo deployment <deployment_name> --to-revision=1

gce

前提: gcloud というグーグルのcliをインストールしていること

auto pilotモードのclusterを作る

gcloud container clusters create-auto hello-cluster --region=<COMPUTE_REGION>

localからkubectlでgkeを操作できように

gcloud container clusters get-credentials gke-cloud-sql-quickstart --region us-central1

cloud buildを使ってソースコードからアプリをコンテナ化、そして出来たコンテナをArtifact Registoryなどのcloudにアップする。(すでにartifactにrepoが作成されている前提で話します)
artifactにpushするにはimage nameがかなり特徴的な書き方をしなければならない

# cloudbuild.yaml
steps: # steps で build して
  - name: "gcr.io/cloud-builders/docker"
    args:
      [
        "build",
        "-t",
        "<region>-docker.pkg.dev/<project_id>/<repo_name>/<dir_name>:tag",
        "-f",
        "./Dockerfile",
        ".",
      ]
images: "<region>-docker.pkg.dev/<project_id>/<directory>/image:tag" # images で自動 push

書き終わったら gcloud で実行

gcloud builds submit --config ./cloudbuild.yaml ./

そして、yamlを書いてdeployment、serviceを作ってapply、など、普通k8s作業に入るので割愛。ちゃんとconsoleで可視化されているので結構みやすいと見た。

別のgcpサービスと連携

主に cloud sql と Memorystore(redis) の連携

redis

まずはredis、redisは簡単で、redisのインスタンスをコンソール上で作れば直接VPCネットワーク経由で繋げられる(auto pilod限定かも、スタンダードは--enable-ip-aliasが必要らしい)
golangで例を挙げると

RDB = redis.NewClient(&redis.Options{
    Addr: rdbURI,
})

ここの rdbURI を redis instanceのプライマリ エンドポイントに置き換えれば直接つながる、とても楽。

cloud sql

cloud sqlは結構ややこしい。ここれは mysql の例を使う。
まずdocsに従ってcloud sql instanceを作る。

作り終わったらこちらのdocsを見ながら着実に進みましょう。

auto pilotなら前準備なしですが、スタンダートなら Workload Identity をまず有効にしないといけない。(しなくても別の方法で接続できますが、安全性が下がるってdocsにも書いてあった)

そして実際に手を動かす前に、少し手順のおさらいをしましょう。

大雑把に行くと、gkeとcloud sqlの連携はサービスアカウント(Service Account)というものによって結び付けられている(binding)。

このサービスアカウント(以下グーグルの習慣に乗ってSAと呼ぶ)というのは、どのアプリがどのgcpのapiを使えるかを制御するもの(セキュリティ)。

そして中にはGSA(google service account)というプロジェクト規模なものとKSA(kubernetes service account)というgke規模なものがある。なので、gkeからcloud sqlをアクセスするには、まず

  1. cloud sqlをアクセスできるGSAを作る
  2. sql操作する予定のKSAを作る
  3. GSAKSAを結びつける(bind)
  4. cloud-sql-proxyを使って接続

では参ろう(初見で結構苦戦した私でござる

まずGSAを作る

# まずアカウント作る
gcloud iam service-accounts create <GSA_account_name> --display-name="gsa account display name"

# cloud sqlの権限を付与
gcloud projects add-iam-policy-binding <YOUR_PROJECT_ID> \
  --member="serviceAccount:<GSA_account_name>@<YOUR_PROJECT_ID>.iam.gserviceaccount.com" \
  --role="roles/cloudsql.client"

# logging書き込み権限付与
gcloud projects add-iam-policy-binding <YOUR_PROJECT_ID> \
  --member="serviceAccount:<GSA_account_name>@<YOUR_PROJECT_ID>.iam.gserviceaccount.com" \
  --role="roles/logging.logWriter"

続いてyamlを書いてKSAを作る

# service-account.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: <YOUR-KSA-NAME>

書いたらcmdで実行

kubectl apply -f service-account.yaml

GSA と KSA の binding です

gcloud iam service-accounts add-iam-policy-binding \
    --role="roles/iam.workloadIdentityUser" \
    --member="serviceAccount:<YOUR_PROJECT_ID>.svc.id.goog[<YOUR-K8S-NAMESPACE>/<YOUR-KSA-NAME>]" \
    <GSA_account_name>@<YOUR_PROJECT_ID>.iam.gserviceaccount.com

まだ終わってません、KSA側でもアノテーションをつけてバインドを完了させます

kubectl annotate serviceaccount \
    <YOUR-KSA-NAME> \
    iam.gke.io/gcp-service-account=<GSA_account_name>@<YOUR_PROJECT_ID>.iam.gserviceaccount.com

これで cli の作業は完了、これからは deployment の作業に入る
実際に繋ぐコードはgolangのgormを予想して書きます

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: <deployment-name>
spec:
  selector:
    matchLabels:
      app: <app-lable>
  template:
    metadata:
      labels:
        app: <app-lable>
    spec:
      serviceAccountName: <YOUR-KSA-NAME>
      containers:
      - name: <your-container-name>
        image: <your-image-url>
        ports:
          - containerPort: <expose-port>
        env:
          - name: PORT
            value: "<expose-port>" # env の中は必ず文字列でなければいけない
          - name: DB_URI # 実際に gorm で繋ぐためのものをかく、注意が必要なのは、cloud-sql-proxy使っているので直接localhostに繋ぎまず
            value: "<username>:<password>@tcp(127.0.0.1:3306)/<db_name>?charset=utf8mb4&parseTime=true"
      - name: cloud-sql-proxy # 重要: アプリのコンテナ以外、cloud-sql-proxyのコンテナが必要
        image: gcr.io/cloudsql-docker/gce-proxy:latest # image は gce-proxy を使う、公式チュートリアルでは gcr.io/cloud-sql-connectors/cloud-sql-proxy:latest を使う文章もあったが、こっちの方がいいです
        command:
          - "/cloud_sql_proxy"
          - "--log_debug_stdout=true"
          # - "-enable_iam_login" # この行は普通使わない、自動IAMログインが必要のときだけつける、必要のない時につけちゃうと繋がらないので注意
          - "-instances=<INSTANCE_CONNECTION_NAME>=tcp:3306"
        securityContext:
          runAsNonRoot: true

実際に繋ぐところのコードも見てみましょう。
公式は kubectl secretを使って環境変数に値を付与しているが、別に直接書いても繋がるので、安全面を考慮しながら好みでいいと思う。

dbURI := os.Getenv("DB_URI")

db, err := gorm.Open(mysql.New(mysql.Config{
    DSN:                     dbURI,
    DontSupportRenameIndex:  true,
    DontSupportRenameColumn: true,
}), &gorm.Config{
    DisableForeignKeyConstraintWhenMigrating: true,
    CreateBatchSize:                          1000,
})

これでkubectl apply -f deployment.yamlすれば動くはずです。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?