動かざることバグの如し

近づきたいよ 君の理想に

ReactでContext-apiを使うサンプルコード

環境

  • React v18

問題点

ReactにはProps機能があり、それを使うとコンポーネント間でデータのやり取りが出来る。

が孫とかまでやりとりしようとすると一気に面倒になる

import type { NextPage } from 'next';
import { useState } from 'react';

const Home: NextPage = () => {
  const [user, setUser] = useState('長門有希');
  return (
    <>
      <h1>{user}</h1>
      <Component1 user={user} />
    </>
  );
};

const Component1 = (props: any) => {
  return (
    <>
      <h1>Component1</h1>
      <Component2 user={props.user} />
    </>
  );
};

const Component2 = (props: any) => {
  return (
    <>
      <h1>Component2 {props.user}</h1>
    </>
  );
};

export default Home;

KubernetesでSecretsをファイルから作成する方法

環境

シークレットが当たり前過ぎて全然記事がなかったのでまとめ

追加方法

まずは秘匿情報が書かれたキーとバリューの組み合わせが書かれたファイルを用意する

NAME=taro
PASSWORD=12345

kubectl create secret generic 構文でシークレットを登録する。my-secretの部分は任意の名前

kubectl create secret generic my-secret --from-env-file=.env

確認

$ kubectlubectl get secret                 
NAME                                         TYPE                 DATA   AGE
my-secret                                    Opaque               2      19s

個別のを確認してみる。値はBase64で格納されている。

$ kubectl get secrets my-secret -o yaml

apiVersion: v1
data:
  NAME: dGFybw==
  PASSWORD: MTIzNDU=
kind: Secret
metadata:
  creationTimestamp: "2022-08-30T14:19:42Z"
  name: my-secret
  namespace: default
  resourceVersion: "6839359"
  uid: 63868e12-b4a3-4a28-a5ed-7a2ec1314b86
type: Opaque

kubectlから値の確認方法

別に暗号化されている訳ではないのでコマンドを駆使すれば値を得られる

$ kubectl get secrets my-secret -o json | jq -r '.data.NAME' | base64 --decode
taro
$ kubectl get secrets my-secret -o json | jq -r '.data.PASSWORD' | base64 --decode
12345

Podからの値の確認方法

PodからはSecret名を指定して起動すると、環境変数として取得することが出来る

例えば適当に以下のような環境変数を出力するだけのPodを作成する。「my-secret」が最初作ったSecret名になっている。

apiVersion: v1
kind: Pod
metadata:
  name: secret-test-pod
spec:
  containers:
    - name: test-container
      image: k8s.gcr.io/busybox
      resources: {}
      command: [ "/bin/sh", "-c", "env" ]
      envFrom:
      - secretRef:
          name: my-secret
  restartPolicy: Never
kubectl apply -f deployment.yml

でログを確認してみる おk

$ kubectl logs secret-test-pod

KUBERNETES_PORT=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT=443
HOSTNAME=secret-test-pod
SHLVL=1
HOME=/root
NAME=taro
KUBERNETES_PORT_443_TCP_ADDR=10.96.0.1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
KUBERNETES_PORT_443_TCP_PORT=443
KUBERNETES_PORT_443_TCP_PROTO=tcp
KUBERNETES_PORT_443_TCP=tcp://10.96.0.1:443
KUBERNETES_SERVICE_PORT_HTTPS=443
PWD=/
KUBERNETES_SERVICE_HOST=10.96.0.1
PASSWORD=12345

シークレットを更新する

実はSecretsまたはConfigMapのアップデートはkubectlコマンド自体には用意されていない。

そこで新たにそれ用のYAMLを生成し kubectl apply でパッチする

kubectl create secret generic my-secret --from-env-file=.env --dry-run=client -o yaml | kubectl apply -f -

参考リンク

TypeScriptでElement implicitly has an 'any' type because expression of type 'string'エラー

環境

  • TypeScript 4

問題

例えば以下のようなサンプルコードがあったとする

function receivedStringValue() : string {
  return 'apple';
}

const fruits = {
  apple: 'りんご',
  banana: 'バナナ',
  melon: 'メロン'
};

const key: string = receivedStringValue();
const value = fruits[key];

が、実はコレだといかのようなエラーになる

Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{ apple: string; banana: string; melon: string; }'.
No index signature with a parameter of type 'string' was found on type '{ apple: string; banana: string; melon: string; }'.ts(7053)

fruits[key] のkeyの型がわからん、といった感じだろうか

解決方法1

明示的にinterface FruitsKey を作成する。そうすることでfruitsのキーのいずれか来るということがわかりエラーにならなくなる

-const fruits = {
+interface FruitsKey {
+  [key: string]: any;
+}
+
+const fruits: FruitsKey = {
   apple: 'りんご',
   banana: 'バナナ',
   melon: 'メロン'
 };
 
 const key: string = receivedStringValue();
 const value = fruits[key];

解決方法2

keyを key as keyof typeof Foo の形にする。

const fruits = {
   apple: 'りんご',
   banana: 'バナナ',
   melon: 'メロン'
 };

-const value = fruits[key];
+const value = fruits[key as keyof typeof fruits];

解決方法2のほうが簡単だが1の方がfruitのValue側の方も決めれるのでより厳密な定義ができそう?

参考リンク

Kubernetesでコントロールプレーンを増やす方法

環境

やりたいこと

kubeadmでKubernetesクラスタを生成すると1台目のノードがマスターノードとなる。つまりcontrol-planeは1台構成

一般的には2台以上が推奨なのでもう1台増やしてみる

手順

まずはkubeadmコマンドでcontrol-plane証明書を更新する

# kubeadm init phase upload-certs --upload-certs
[upload-certs] Storing the certificates in Secret "kubeadm-certs" in the "kube-system" Namespace
[upload-certs] Using certificate key:
22e1b256080eb4233afb5a1f49fe5d2c85532daa114986a2a29d50e6d7806023

次にクラスタに追加する用のコマンドを生成する

# kubeadm token create --print-join-command
kubeadm join control-plane.minikube.internal:8443 --token nl6a49.h007qqkw7h12lelf --discovery-token-ca-cert-hash sha256:7e0a541aa19430dfaddd77206ac1514488270cbac740c5ab0e3cf5e19e223df2

最後に新品のkubeadmインストール済みのサーバーで以下を実行 kubeadm token create で表示されたコマンドに--certificate-keyを追加するのがポイント

kubeadm join control-plane.minikube.internal:8443 --token nl6a49.h007qqkw7h12lelf --discovery-token-ca-cert-hash sha256:7e0a541aa19430dfaddd77206ac1514488270cbac740c5ab0e3cf5e19e223df2 --control-plane --certificate-key 22e1b256080eb4233afb5a1f49fe5d2c85532daa114986a2a29d50e6d7806023

参考リンク