(アホなので)各用途でリソースが何だったかわからなくなる…のでまとめた。
Deployment/Daemonset/Staticpodリソース
Deployment
ReplicaSetを管理してローリングアップデートやロールバックを実現する。
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-deployment
spec:
selector:
matchLabels: #templateセクションの設定が自動設定
app: my-nginx
strategy:
type: RollingUpdate #1podずつ更新する
replicas: 3 #pod数
template: #podの仕様
metadata:
labels: #ここに設定したラベルがselectorにも適用されることでグループ化
app: my-nginx
spec:
containers:
- name: nginx-container
image: nginx
ports:
- containerPort: 80
たとえば"httpd-frontend"という名前のdeploymentをデプロイすると、
"httpd-frontend-5f494775df"という名前のreplicasetが作られ、
"httpd-frontend-5f494775df-random1"
"httpd-frontend-5f494775df-random2" というように-で枝分かれしたpodが作られる
deploymentのreplicasの数をeditで変えるとreplicasetの数も同時に変更される。※逆は不可
マニフェストの内容としてはkind以外はreplicasetと同じ
strategyはRollingUpdate
で1podずつ更新。Recreate
は全pod一気に削除→再作成
一般的なユーザーリソースの他、
k8sのデフォルトのリソースとしてはCoreDNS
などで使用されている。
Daemonset
apiVersion: apps/v1
kind: DaemonSet
metadata:
labels:
app: elasticsearch
name: elasticsearch
namespace: kube-system
spec:
selector:
matchLabels:
app: elasticsearch #templateのラベルと一致させる
template:
metadata:
labels:
app: elasticsearch
spec:
containers:
- image: registry.k8s.io/fluentd-elasticsearch:1.20
name: fluentd-elasticsearch
数関係なくWorkerNodeに1ずつたてるpod
ワーカーノードを管理するデーモンをpodで動作させたい場合に使用
システムリソースのモニタリングツールやログ収集(fluentd)など。ノードが消えるとpodもそのまま消える。
KubernetesクラスタでデフォルトでDaemonSetとしてデプロイされる代表的なものには、以下のようなコンポーネントがある
1. Node Exporter(Prometheus用)
Prometheusによって各ノードのメトリクスを収集するために使用されるエージェント。システムのリソース使用状況(CPU、メモリ、ディスクなど)をモニタリングする
2. Fluentd(またはその他のログ収集エージェント)
ログデータを集約し、中央のログ集約システム(例:Elasticsearch、Splunk)に送信するためのエージェント。ノード上のすべてのコンテナのログを収集できる
3. Node Problem Detector
ノードの健康状態を監視するためのコンポーネント。ノードのハードウェアやオペレーティングシステムレベルの問題を検出できる
4. Kube-proxy
Kubernetesのネットワークプロキシで、サービスのエンドポイント間の通信を管理する。主要な役割は、ネットワークトラフィックを適切なサービスエンドポイントにルーティングすること
5. CNIプラグイン(例えば、Cilium、Weave Net、Calico)
CNI(Container Network Interface)プラグインは、コンテナ間のネットワークを管理するために使用されるネットワークプラグイン。pod間の通信を制御・管理
6. ログ収集ユーティリティ(例:fluent-bit, logdna-agent)
これらのエージェントは、各ノードからログデータを収集し、集中管理するために使用される。
7. システムメトリクスコレクター(例:metrics-server)
metrics-serverは、クラスタ内の各ノードからシステムメトリクスを収集し、Kubernetes APIサーバに提供するエージェント
Staticpod
通常の方法でDeploymentやReplicaSetなどkube-apiserverを介して各コントローラーで処理されるのではなく、コントロールプレーンの影響を受けずに特定のノードのkubeletプロセスによってのみ直接管理・処理されるpod
そのため、
・そもそもコントロールプレーンのコンポーネントをデプロイするのに使用されている
・両者ともkube-schedulerからは無視される
#コマンドでのデプロイ
kubectl run --restart=Never --image=busybox:1.28.4 static-busybox --dry-run=client -o yaml --command -- sleep 1000 > /etc/kubernetes/manifests/static-busybox.yaml
Static Podの名前には末尾に"-node名"が付く。
kubeletが監視している特定のディレクトリ(デフォルトでは /etc/kubernetes/manifests
)に配置される
※定義ファイルの場所は各ノードのkubelet設定ファイル /var/lib/kubelet/config.yml
の staticPodPath:
で確認できる
#デフォルトでデプロイされているstaticpod群(例)↓:
/etc/kubernetes/manifests/kube-apiserver.yaml
/etc/kubernetes/manifests/kube-controller-manager.yaml
/etc/kubernetes/manifests/kube-scheduler.yaml
/etc/kubernetes/manifests/etcd.yaml
これらのStatic Podマニフェストファイルを編集することで、直接これらのコンポーネントの設定を変更することができる。Kubeletはこのディレクトリを監視しており、ファイルの変更を検知すると対応するPodを再作成し、ファイルが削除されるとpodを終了させる。
Networkリソース
ClusterIP
デフォルトのサービスタイプで、クラスタ内の内部トラフィックのみが対象
・クラスタ内部トラフィック用の仮想IPを提供
・外部からのアクセスはできない
・クラスター内部の通信に使用される
Serviceリソースに振られるNWは
/etc/kubernetes/manifests/kube-apiserver.yaml
の - --service-cluster-ip-range=10.96.0.0/12
で確認できる。
apiVersion: v1
kind: Service
metadata:
name: webapp-service
spec:
type: ClusterIP
ports:
- port: 8080 #serviceが受け付けるport
targetPort: 8080 #podがリッスンしているport
selector: #ServiceがトラフィックをどのPodにルーティングするかを決定
app: webapp
podのmetadata.labels: にapp: webapp
と設定されているものだけが対象になる。
対象になったpodのアドレスがEndpointとして表示される
コマンドで設定したい場合は以下
#podを指定してデプロイ(svcが受け付けるportを6379で指定)
kubectl expose pod redis --port=6379 --name redis-service
#podデプロイ+ClusterIP(podと同じ名前のsvcが一緒にデプロイされる)
kubectl run httpd --image=httpd:alpine --port=80 --expose
クラスタ内部からアクセスできる
http://<ClusterIP>:8080
NodePort
各クラスタノードの特定のポートを開放し、そのポート番号を通じて外部トラフィックをノードにルーティング
・クラスタ外部からアクセスできる
・ノードのIPアドレス上の指定ポートにアクセス
デプロイすると自動的にClusterIPも払い出される
apiVersion: v1
kind: Service
metadata:
name: webapp-service
spec:
type: NodePort
ports:
- port: 8080 #Serviceのport
targetPort: 8080 #Podが受け付けるport
nodePort: 30080 #外部アクセス用のport
selector:
app: webapp
アクセス(クラスタ外部から)
http://<NodeIP>:30080
get出力例
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
webapp-service NodePort 10.43.80.67 <none> 8080:30080/TCP 10m
CLUSTER-IP
: 10.43.80.67 は自動的に割り当てられたClusterIP
PORT(S)
: 8080:30080/TCP は、ClusterIPのポート(8080)と、各ノードのNodePort(30080)を示す
LoadBalancer
外部ロードバランサーを利用し、外部トラフィックをKubernetesクラスタ内のサービスにルーティング
・クラウドプロバイダー(AWSなど)が外部ロードバランサーをプロビジョニングし、設定を管理
・自動的に負荷分散IPが割り当てられる
apiVersion: v1
kind: Service
metadata:
name: webapp-service
spec:
type: LoadBalancer
ports:
- port: 8080
targetPort: 8080
selector:
app: webapp
アクセス方法(クラウドプロバイダーによる外部IP)
# クラウドプロバイダーが割り当てた外部IPアドレスでアクセス
http://<LoadBalancerIP>:8080
ExternalIP
特定の外部IPから直接アクセスを受ける必要がある場合、特定のノードIPを外部トラフィックのエントリーポイントとして使用する
・外部のIPアドレスをノードに直接マッピングして、外部トラフィックを特定のサービスにルーティング
・ClusterIPと連携して外部からアクセスを提供
apiVersion: v1
kind: Service
metadata:
name: webapp-service
spec:
type: ClusterIP #NodePort,LoadBalancerも指定できる
externalIPs:
- 192.168.1.100 #外部IPアドレス
ports:
- port: 8080
targetPort: 8080
selector:
app: webapp
アクセス方法(外部から指定されたExternalIP)
http://192.168.1.100:8080
Ingress
複数のHTTPおよびHTTPSルータを定義し、クラスタ内の異なるサービスにトラフィックをルーティング
・ドメイン名やパスを基にしたルーティング
・SSL/TLS終端を管理できる
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: / #リクエストパスを指定したターゲットにリライトする。例えば、リクエストが/wear/somethingの場合、このリクエストは/somethingにリライトされてwear-serviceに送られる。
nginx.ingress.kubernetes.io/ssl-redirect: "false" #HTTPリクエストをHTTPSにリダイレクトするが、falseに設定されていると無効になる
name: ingress-wear-watch
namespace: app-space
spec:
rules:
- http:
paths:
- backend:
service:
name: wear-service #アプリケーションのserviceを指定
port:
number: 8080 #serviceが受け付けるport
path: /wear #URLにつけるpath
pathType: Prefix #例えば、path: /wearと指定した場合、/wear, /wear/, /wear/somethingのようなパスにマッチする。
- backend:
service:
name: video-service
port:
number: 8080
path: /watch
pathType: Prefix
アプリ例
apiVersion: v1
kind: Service
metadata:
name: wear-service
namespace: app-space
spec:
ports:
- port: 8080
protocol: TCP
targetPort: 8080
selector:
app: webapp-wear
type: ClusterIP
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp-wear
namespace: app-space
spec:
replicas: 1
selector:
matchLabels:
app: webapp-wear
strategy:
type: RollingUpdate
template:
metadata:
labels:
app: webapp-wear
spec:
containers:
- image: kodekloud/ecommerce:apparels
name: simple-webapp
ports:
- containerPort: 8080
protocol: TCP
アクセス(DNSが設定された場合)
http://webapp.example.com/wear
http://webapp.example.com/watch
Ingress Controller
Ingressリソースは単なるルールの定義なので、実際のトラフィックルーティングを行うにはそれらのルールを実行するためのコンポーネント(Ingressコントローラ)が必要
#有名なIngressコントローラには以下のようなものがあり、URLから引っ張ってきてデプロイする
・NGINX Ingress コントローラ
・Traefik
・HAProxy
・Envoy
・Istio(サイドカープロキシとIngressゲートウェイとして)
Deployment/service例
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.1.2
helm.sh/chart: ingress-nginx-4.0.18
name: ingress-nginx-controller
namespace: ingress-nginx
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
strategy:
type: RollingUpdate
template:
metadata:
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
spec:
containers:
- args:
- /nginx-ingress-controller
- --publish-service=$(POD_NAMESPACE)/ingress-nginx-controller
- --election-id=ingress-controller-leader
- --watch-ingress-without-class=true
- --default-backend-service=app-space/default-backend-service
- --controller-class=k8s.io/ingress-nginx
- --ingress-class=nginx
- --configmap=$(POD_NAMESPACE)/ingress-nginx-controller
- --validating-webhook=:8443
- --validating-webhook-certificate=/usr/local/certificates/cert
- --validating-webhook-key=/usr/local/certificates/key
env:
- name: POD_NAME
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.name
- name: POD_NAMESPACE
valueFrom:
fieldRef:
apiVersion: v1
fieldPath: metadata.namespace
- name: LD_PRELOAD
value: /usr/local/lib/libmimalloc.so
image: registry.k8s.io/ingress-nginx/controller:v1.1.2@sha256:28b11ce69e57843de44e3db6413e98d09de0f6688e33d4bd384002a44f78405c
imagePullPolicy: IfNotPresent
lifecycle:
preStop:
exec:
command:
- /wait-shutdown
livenessProbe:
failureThreshold: 5
httpGet:
path: /healthz
port: 10254
scheme: HTTP
initialDelaySeconds: 10
periodSeconds: 10
successThreshold: 1
timeoutSeconds: 1
name: controller
ports:
- containerPort: 80
name: http
protocol: TCP
- containerPort: 443
name: https
protocol: TCP
- containerPort: 8443
name: webhook
protocol: TCP
readinessProbe:
failureThreshold: 3
httpGet:
path: /healthz
port: 10254
scheme: HTTP
resources:
requests:
cpu: 100m
memory: 90Mi
securityContext:
allowPrivilegeEscalation: true
capabilities:
add:
- NET_BIND_SERVICE
drop:
- ALL
runAsUser: 101
volumeMounts:
- mountPath: /usr/local/certificates/
name: webhook-cert
readOnly: true
dnsPolicy: ClusterFirst
nodeSelector:
kubernetes.io/os: linux
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
serviceAccount: ingress-nginx
serviceAccountName: ingress-nginx
terminationGracePeriodSeconds: 300
volumes:
- name: webhook-cert
secret:
defaultMode: 420
secretName: ingress-nginx-admission
Service
k get svc -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx-controller NodePort 172.20.43.138 <none> 80:30080/TCP,443:32103/TCP 9m48s
ingress-nginx-controller-admission ClusterIP 172.20.165.224 <none> 443/TCP 9m48s
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx-controller
namespace: ingress-nginx
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.1.2
helm.sh/chart: ingress-nginx-4.0.18
spec:
externalTrafficPolicy: Local
internalTrafficPolicy: Cluster
ports:
- appProtocol: http
name: http
nodePort: 30080
port: 80
protocol: TCP
targetPort: http
- appProtocol: https
name: https
nodePort: 32103
port: 443
protocol: TCP
targetPort: https
selector:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
type: NodePort
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx-controller-admission
namespace: ingress-nginx
labels:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/managed-by: Helm
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
app.kubernetes.io/version: 1.1.2
helm.sh/chart: ingress-nginx-4.0.18
spec:
internalTrafficPolicy: Cluster
ports:
- appProtocol: https
name: https-webhook
port: 443
protocol: TCP
targetPort: webhook
selector:
app.kubernetes.io/component: controller
app.kubernetes.io/instance: ingress-nginx
app.kubernetes.io/name: ingress-nginx
sessionAffinity: None
type: ClusterIP
coredns
kube-dns
というserviceとcoredns
というdeploymentで構成されており、クラスタ内のリソースを名前解決してくれる。同namespaceであればPod名 or Service名で通信できる。
別のnamespaceへはPod名 or Service名.NameSpace名(.svc or .svc.デフォルトドメイン)
で通信できる。
適用されているconfigmapでdns設定を確認できる。
Storageリソース
PV作成(static)
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-log
#labels:
#type: log-storage #PVCで直接このPVを指定したい場合、ラベル付与
spec:
persistentVolumeReclaimPolicy: Retain #PVCが削除された後、PVがどのように扱われるかを制御するポリシー(Retain=そのまま残る,Delete=ボリュームもボリューム内のデータも削除)
accessModes:
- ReadWriteMany #ボリュームは複数ノードで読み書き可。ReadWriteOnce=単一ノードによって読み書き可、ReadOnlyMany=複数ノードで読み取り専用
capacity:
storage: 100Mi
hostPath: #node上の領域を使用する
path: /pv/log #node上の/pv/logを使う
# kubectl get pv -o wide
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE VOLUMEMODE
pv-log 100Mi RWX Retain Bound default/claim-log-1 <unset> 16m Filesystem
PV作成(自動)
StorageClassを作成する。
PVCに伴って自動でPVが作成される。動的プロビジョニング
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: volume-sc
provisioner: kubernetes.io/portworx-volume #プロビジョナー(kubernetes.io/no-provisioner = local手動管理で動的プロビジョニングをサポートしていない)。外部ストレージなら/aws-ebsや/azure-diskなど
allowVolumeExpansion: true #ボリュームの拡張を許可
volumeBindingMode: WaitForFirstConsumer #PVとPVCのバインディングの振る舞いを制御.PVC作成→PV作成ではなく、PVCを使用するPodが作成されるのを待機。(Immediate = PVC作成→すぐPV作成)
PVC作成
作成されると、クラスタ上で要件(accsessmodeや容量)に一致するPVを探し、自動的にバインドする。(複数PVが一致する場合は、容量の大きいものから使われる)
StorageClassを指定した場合はBindingModeに応じてPVが作成される
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: claim-log-1
spec:
accessModes:
- ReadWriteMany
resources:
requests:
storage: 50Mi
#selector:
#matchLabels:
#type: log-storage #ラベル付きのPVを直接指定する場合
#volumeName: pv-log #直接PV名を指定でも可
storageClassName: volume-sc #StorageClassを指定する場合.SCのbindingmodeにより即時またはPVC呼び出し時にPV作成
# kubectl get pvc -o wide
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE VOLUMEMODE
claim-log-1 Bound pv-log 100Mi RWX <unset> 11m Filesystem
PVがない場合、STATUSはPendingになる
Podで利用
apiVersion: v1
kind: Pod
metadata:
name: webapp
spec:
containers:
- name: event-simulator
image: kodekloud/event-simulator
env:
- name: LOG_HANDLERS
value: file
volumeMounts:
- mountPath: /log
name: log-volume
volumes:
- name: log-volume
persistentVolumeClaim:
claimName: claim-log-1
#hostpath: #nodeの領域を使う.シングルノードや一時利用専用
# path: /data #node上の/dataを使う
# type: directory #/dataはディレクトリで存在する必要がある
PVCを削除した場合
ReclaimPolicyがRetain
の場合、PVCを削除すると...
# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
pv-log 100Mi RWX Retain Bound default/claim-log-1 <unset> 17m
#
# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
claim-log-1 Bound pv-log 100Mi RWX <unset> 3m9s
#
# kubectl delete pvc claim-log-1
persistentvolumeclaim "claim-log-1" deleted
#
# kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
claim-log-1 Terminating pv-log 100Mi RWX <unset> 6m59s
#
# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
pv-log 100Mi RWX Retain Bound default/claim-log-1 <unset> 21m
podがpvcを呼び出しているため、terminatingになる.PVは残るが、使用できない
podを削除↓
# kubectl delete pod webapp
pod "webapp" deleted
#
# kubectl get pvc
No resources found in default namespace.
#
# kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
pv-log 100Mi RWX Retain Released default/claim-log-1 <unset> 25m
pvcを呼び出しているpodが消えるとpvcも削除される。pvは残っており、STATUSはReleased
になっている
スケジューリングを制御するリソース
drain/cordon
ノード再起動や一時的なメンテナンス用
drain = 指定したノードからpodを退避する
cordon = 指定したノードへのスケジューリングを無効にする
kubectl drain host03 --ignore-daemonsets --delete-local-data --force
--ignore-daemonsets
: DaemonSet で管理されている Pod は退避の対象外
--delete-local-data
: ノード上のローカルストレージを使用している Pod を強制的に削除
--force
: 静的 Pod を強制的に削除
drainすると自動でcordonも設定される
#設定
kubectl cordon host03
#解除
kubectl uncordon host03
ノードにSchedulingDisabled
というステータスがつく
ノード上の既存のPodはそのまま継続して実行されるが、それ以上新しいPodがスケジュールされることはない
taint/toleration
ノードの役割管理、特定の用途に対するノードの使用制限用途
特定のノードには特定のポッドしかスケジュールしないようにしたい場合(高性能ノードを特定のワークロード専用にする等)
taint = ノードにカスタムラベルを付与し、特定の条件を満たさない場合にPodのスケジュールを制限
toleration = Pod に toleration を設定することで選択的にそのノードにスケジュールする
ノードにtaint付与
#設定
kubectl taint nodes host03 key=value:NoSchedule
#解除
kubectl taint nodes host03 key-
NoSchedule
: このtaintを持つノードにPodをスケジュールできない
PreferNoSchedule
: なるべくこのノードにPodをスケジュールしないようにする
NoExecute
: すでにノード上で動作しているPodも追い出し、再配置
apiVersion: v1
kind: Pod
metadata:
name: mypod
spec:
containers:
- name: mycontainer
image: nginx
tolerations:
- key: "key"
operator: "Equal"
value: "value"
effect: "NoSchedule"
後述のAffinity設定との差異としては、ノードに対して直接設定されるため、全てのpodに対して適用される
Affinity
こちらはノードにラベルを付与して指定する方法
同じ種類のpodを異なるノードに分散して配置する等で、単一のノード障害時の影響を最小化する場合
Podに適用され、どのノードにスケジュールされるかを制御
affinity設定に基づき、スケジューラーはpodを特定のlabelを持つノードに優先的に配置する
ノードにラベル付与
#ラベル付与
kubectl label node node01 color=blue
#確認
kubectl get node --show-labels
nodeSelectorまたはnodeAffinityでlabelのついたnodeにのみデプロイされるようにする
spec:
containers:
- image: nginx
name: nginx
nodeSelector:
color: blue
apiVersion: apps/v1
kind: Deployment
metadata:
name: blue
labels:
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: color
operator: In
values:
- blue
operatorは
"Exists"
: keyに対する値が存在する場合に一致する(value値はなくてもよい)
"In"
: keyに対する値が指定したvaluesの一部と一致する場合に一致する。(valueが必須)
Securityリソース
NetworkPolicy
リソース単体でACLをかけたい場合
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: internal-policy
namespace: default
spec:
podSelector:
matchLabels:
name: internal
policyTypes:
- Egress
- Ingress
ingress:
- {}
egress:
- to:
- podSelector:
matchLabels:
name: mysql
ports:
- protocol: TCP
port: 3306
- to:
- podSelector:
matchLabels:
name: payroll
ports:
- protocol: TCP
port: 8080
- ports:
- port: 53
protocol: UDP
- port: 53
protocol: TCP
Role
特定の名前空間内でアクセス制御を定義
リソースへのアクセス権限(例えば、読み取り、書き込み、削除など)が含まれる。
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: mynamespace
name: pod-reader
rules:
- apiGroups: [""] #コアAPIグループ(v1)の範囲。kubectl api-resources で確認
resources: ["pods"]
verbs: ["get", "watch", "list"]
RoleBinding
特定のnamespace内で、Role または ClusterRole をユーザー、グループ、またはサービスアカウントに関連付ける。
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: mynamespace
subjects:
- kind: User #Group や ServiceAccount も指定できる
name: jane #kubectl get pod --as=jane でなりすまして実行できる
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader #roleリソース名を指定
apiGroup: rbac.authorization.k8s.io
ClusterRole
クラスタ全体でアクセス制御を定義。namespaceに限定されないため、クラスター全体のリソースに対するアクセス権限を付与できる。
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: cluster-admin
rules:
- apiGroups: ["*"] #すべてのAPIグループ
resources: ["*"] #すべてのリソース
verbs: ["*"] #すべての動作。つまりこれはフルアクセスになる
ClusterRoleBinding
クラスタ全体で、ClusterRole をユーザー、グループ、またはサービスアカウントに関連付ける。
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: cluster-admin-binding
subjects:
- kind: User
name: jane
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: cluster-admin
apiGroup: rbac.authorization.k8s.io
ServiceAccount
podからの通信に使用するアカウント。podをdescribeすると使用されているアカウントを確認できる。
アカウント作成
# kubectl create sa testsa
role、rolebindingで権限付与し、deploymentで指定
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
namespace: default
spec:
selector:
matchLabels:
name: web-app
strategy:
type: RollingUpdate
template:
metadata:
labels:
name: web-app
spec:
serviceAccountName: testsa
containers:
...
情報を別出しするリソース
マニフェストファイルが似ており、どちらも用途としては同じ。
Configmap
apiVersion: v1
data:
APP_COLOR: darkblue # 格納する KEY: VALUE
APP_OTHER: disregard
kind: ConfigMap
metadata:
name: webapp-config-map # ConfigMap名。適用時に使用する
namespace: default
podに適用(環境変数)
apiVersion: v1
kind: Pod
metadata:
labels:
name: webapp-color
name: webapp-color
namespace: default
spec:
containers:
- env:
- name: APP_COLOR
valueFrom:
configMapKeyRef:
name: webapp-config-map # この値を取得するConfigMap名
key: APP_COLOR # 取得するKEY
image: webapp
imagePullPolicy: Always
name: webapp-color
podに適用(ボリュームマウント)
apiVersion: v1
kind: Pod
metadata:
labels:
name: webapp-color
name: webapp-color
namespace: default
spec:
containers:
- name: webapp-color
image: webapp
imagePullPolicy: Always
volumeMounts:
- mountPath: /etc/config # マウントするパスを指定
name: config-volume
volumes:
- name: config-volume
configMap:
name: webapp-config-map # このConfigMapからデータを取得
Podが起動すると、ConfigMapの各キーは指定されたディレクトリ内にファイルとして表示される。
/etc/config/
├── APP_COLOR #ファイルの内容は darkblue
└── APP_OTHER #ファイルの内容は disregard
Secret
機密情報(パスワード、OAuthトークン、SSHキーなど)を保存するためのリソース
Pod内のコンテナにマウントされ、アプリケーションが機密情報に安全にアクセスできるようにする。
マニフェストの場合、値ベタ書きだとダメ。base64エンコードが必要
# echo -n "XXX" |base64
apiVersion: v1
kind: Secret
metadata:
name: db-secret
type: Opaque
data: # stringDataというフィールドにすればエンコード不要。作成後に自動でエンコードされた値が入る
DB_Host: c3FsMDE= # base64エンコードされた値を入れる.sql01
DB_User: cm9vdA== # root
DB_Password: cGFzc3dvcmQxMjM= # password123
以下でも作成できる。--from-literalでOpaque形式。エンコードは不要
# kubectl create secret generic --from-literal=DB_Host=sql01 --from-literal=DB_User=root --from-literal=DB_Password=password123
pod適用(環境変数利用)
apiVersion: v1
kind: Pod
metadata:
name: db-pod
spec:
containers:
- name: app-container
image: mysql
env:
- name: DB_HOST
valueFrom:
secretKeyRef:
name: db-secret
key: DB_Host
- name: DB_USER
valueFrom:
secretKeyRef:
name: db-secret
key: DB_User
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-secret
key: DB_Password
pod適用(ボリュームマウント)
apiVersion: v1
kind: Pod
metadata:
name: db-pod
spec:
containers:
- name: app-container
image: mysql
command:
- sleep
- "4800"
volumeMounts:
- name: secret-volume # ボリュームの名前
mountPath: /etc/db-secret # マウントするパス
readOnly: true # 読み取り専用
volumes:
- name: secret-volume # ボリュームの定義
secret:
secretName: db-secret # 使用するSecretの名前
Podが起動すると、ConfigMapの各キーは指定されたディレクトリ内にファイルとして表示される。
内容はデコード済みの値(DB_Hostならsql01)
/etc/db-secret/
├── DB_Host
├── DB_User
└── DB_Password
おまけ
忘れがちなやつリスト
・namespace固定
# kubectl config set-context --current -namespace=NAMESPACE
・APIリソース確認
# kubectl api-resources
・コンテナのシェルへログイン。(-c なしでpodへログイン)
# kubectl exec -it my-pod -c my-container -- /bin/bash
・json整形(出力を抜き出して表示)
# kubectl get pod -o=jsonpath='{.items[*].metadata.name}'
nginx redis
・出力を抜き出して任意のカラムを追加して表示.名前でソート
# kubectl get deployment -n admin -o custom-columns="DEPLOYMENT:metadata.name,CONTAINER_IMAGE:spec.template.spec.containers[].image,REPLICAS:status.replicas,NAMESPACE:metadata.namespace" --sort-by=.metadata.name
DEPLOYMENT CONTAINER_IMAGE REPLICAS NAMESPACE
deploy1 nginx 1 admin
deploy2 nginx:alpine 1 admin
deploy3 nginx:1.16 1 admin
deploy4 nginx:1.17 1 admin
deploy5 nginx:latest 1 admin2
・Pod作成
# kubectl run 名 --restart=Never nginx --image=nginx:alpine
--restartで挙動を設定できる
Always: デプロイコントローラで起動、要求を待ち続け終了せず、異常終了したら再起動する(デフォ)
Never: podを直接起動、podが停止したときにリスタートしない
OnFailure: jobの制御下で起動、起動失敗した時に所定の回数に達するまでポッドの起動を再試行
・Pod/Serviceをまとめて作成
# kubectl expose pod redis --port=6379 --name redis-service
# kubectl run httpd --image=httpd:alpine --port=80 --expose
→podと同じ名前のsvcになる
・Deployment作成
kubectl create deployment redis-deploy --image=redis --replicas=2 -n dev-ns