gcloud
が便利なので設定しておく。
参考: https://cloud.google.com/pubsub/docs/quickstart-cli
kubernetesのversionを確認して起動
gcloud container get-server-config --zone asia-northeast1-a # versionのリストを確認
gcloud container clusters create k8s --cluster-version 1.13.7-gke.8 --zone asia-northeast1-a --num-nodes 3
-
--cluster-version 1.10.5-gke.3
ValidMasterVersionsにあるVersionを入力 -
--zone asia-northeast1-a
Kubernetesを設置するRegion -
--num-nodes 3
ノード数。 -
--project
プロジェクトID
kubernetesのCredentialを~/.kube/config
に保存
gcloud container clusters get-credentials k8s --zone asia-northeast1-a
以降kubectl
で管理ができるように
Kubectl Command一覧
kubectl get [リソースの種別] [リソース名] # podの一覧取得
kubectl describe [リソースの種別] [リソース名] # 詳細を確認
kubectl top [リソースの種別] # リソース使用量を確認
kubectl -n kube-system top [リソースの種別] # kube-system namespaceで起動しているものの使用量を確認
kubectl exec -it sample-pod /bin/sh # Resource内のコンテナでコマンドを実行
kubectl logs sample-pod # sample-podでの標準出力をログとして出力
kubectl cp sample-pod:/etc/hostname . # Containerのファイルをローカルにコピー
kuberctl port-forward pod-A 12345:8080 # localhost-port:container-portという書式。
各種コマンドも他にオプションが色々確認あるので複雑なことをやろうと思ったら確認してみる。
リソースの更新, 作成, 削除
kubectl apply -f sample-pod.yaml --prune --all # update, create, or delete
-
--record
アップデートの更新を記録する
削除の際にerror: error pruning nonNamespaced object /v1, Kind=Namespace: namespaces "kube-system" is forbidden: this namespace may not be deleted
というエラーが出る模様。削除は出来ているが気になる...
参考: https://github.com/kubernetes/kubernetes/issues/66430
Pod
sample-pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: sample-pod
annotations:
annotation1: val1 # Annotation 各種設定がこれを通して行われたりする。
annotation2: val2 # Annotation
spec:
containers:
- name: nginx-container
image: nginx:1.12
command: ["/bin/sleep"] # dockerfileのCMDの上書き
args: ["3600"] # dockerfileのCMDの上書き
ports:
- containerPort: 80 # Containerのポート番号を指定
env: # 環境変数を設定
- name: MAX_CONNECTION
value: "100"
kubectl exec -it sample-pod env # 環境変数を確認
ReplicaSet
apiVersion: apps/v1
kind: ReplicaSet # 複製する場合
metadata:
name: sample-rs
spec:
replicas: 3 # 複製の個数
selector:
matchLabels:
app: sample-app # ラベルで複製するものを選ぶ
template:
metadata:
labels:
app: sample-app # 複製識別ラベル。一致していないと作成できない。
spec:
containers:
- name: nginx-container
image: nginx:1.13
ports:
- containerPort: 80
kubectl describe rs sample-rs # Podの増減の履歴確認Command
Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-deployment
spec:
strategy:
type: Recreate # RollingUpdateがDefault。ここら辺は設定できるパラメーターも多い。minReadySecond, etc...
replicas: 3
selector:
matchLabels:
app: sample-app
template:
metadata:
labels:
app: sample-app
spec:
containers:
- name: nginx-container
image: nginx:1.12
ports:
- containerPort: 80
kubectl get replicasets # -o yaml 生成されたReplicasets/Deploymentを確認
kubectl get deployments # -o yaml 生成されたReplicasets/Deploymentを確認
kubectl rollout status deployment sample-deployment # アップデートの状況
kubectl rollout history deployment sample-deployment # --revision [番号] 詳細表示
kubectl rollout undo deployment sample-deployment # --to-revision [番号] ロールバック先を指定
kubectl rollout pause deployment sample-deployment # 更新の適用を一時停止
kubectl rollout resume deployment sample-deployment # 更新の適用の一時停止を解除
DaemonSet
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: sample-ds-ondelete
spec:
updateStrategy:
type: OnDelete # 削除された時に新しく作成する RollingUpdateとかもある。
selector:
matchLabels:
app: sample-app
template:
metadata:
labels:
app: sample-app
spec:
containers:
- name: nginx-container
image: nginx:1.12
kubectl delete pod [podリソース名] # 削除された時のセルフヒーリングで更新を行う。
StatefulSet
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: sample-stateful-set
spec:
podManagementPolicy: Parallel # Podを並列的に作成。Defaultは一つずつ
updateStrategy:
type: OnDelete # RollingUpdateもある。
serviceName: sample-statefulset
replicas: 3
selector:
matchLabels:
app: sample-app
template:
metadata:
labels:
app: sample-app
spec:
containers:
- name: nginx-container
image: nginx:1.12
ports:
- containerPort: 80
volumeMounts:
- name: www
mountPath: /usr/share/nginx/html
volumeClaimTemplates:
- metadata:
name: www
spec:
accessModes: ["ReadWriteOnce"]
resources:
requests:
storage: 1G
kubectl get persistentvolumeclaims # 確保した永続化領域の確認
kubectl delete persistentvolumeclaims [リソース名] # podを削除するだけでは永続化領域までは削除されないので気をつける。
Job
apiVersion: batch/v1
kind: Job
metadata:
name: sample-job
spec:
completions: 5 # タスク実行回数。指定しないこともできる。タスクを実行し続けるワークキューになる。
parallelism: 2 # 並列実行度
backoffLimit: 10 # 失敗を許容する回数。Defaultは6
template:
spec:
containers:
- name: sleep-container
image: centos:6
command: ["sleep"]
args: ["60"]
restartPolicy: Never # OnFailure -> 失敗時に新規Podを作成 Never -> 失敗時に同一のPodで実行
kubectl get jobs # 状況を確認
CronJob
---
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: sample-cronjob
spec:
schedule: "*/1 * * * *"
concurrencyPolicy: Allow # Forbid 前のジョブが終了していない場合に次のジョブを実行しない
# Replace 前のジョブを削除して次のジョブを実行する
startingDeadlineSeconds: 30
successfulJobsHistoryLimit: 5 # 成功したジョブを保存する数
failedJobsHistoryLimit: 3 # 失敗したジョブを保存する数
suspend: false # 停止する時はここを変更する
jobTemplate:
spec:
completions: 10
parallelism: 2
backoffLimit: 10
template:
spec:
containers:
- name: sleep-container
image: centos:6
command: ["sh", "-c"]
args: ["sleep 40; data + '%N' | cut -c 9 | egrep '[1|3|5|7|9]'"]
restartPolicy: Never
kubectl get cronjobs
kubectl get jobs
kubectl delete jobs --all #削除
Service
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-deployment
spec:
# strategy:
# type: Recreate # RollingUpdateがDefault。ここら辺は設定できるパラメーターも多い。minReadySecond, etc...
replicas: 3
selector:
matchLabels:
app: sample-app
template:
metadata:
labels:
app: sample-app
spec:
containers:
- name: nginx-container
image: nginx:1.12
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: sample-clusterip
spec:
type: ClusterIP
# clusterIP: 10.11.253.81 静的に指定することも可能。
# externalIPs: externalIPsも設定できる。利用可能なものは`kubectl get nodes -o custom-columns="NAME:{metadata.name},IP:{status.addresses[].address}"`とかで確認可能
# - 10.240.0.7 Exnternal IPsを設定することでGKEのkubernetesネットワークの外側からもアクセスできるようになる。
# - 10.240.0.8
ports:
- name: "http-port"
protocol: "TCP"
port: 8080
targetPort: 80
selector:
app: sample-app
kubectl get pods -l app=sample-app -o custom-columns="NAME:{metadata.name},IP:{status.podIP}"
kubectl get services sample-clusterip
kubectl describe svc sample-clusterip
NodePort
apiVersion: v1
kind: Service
metadata:
name: sample-nodeport
spec:
type: NodePort
externalTrafficPolicy: Local # defaultがClusterでNode到達後にもNodeを飛び越えてPodにロードバランシングを行う。
ports:
- name: "http-port"
protocol: "TCP"
port: 8080 # ClusterのPort
targetPort: 80 # PodのPort
nodePort: 30080 # 全NodeでLisetenするPort。30000~32767の間で設定できる。指定しなかったら自動的に選択。
selector:
app: sample-app
Load Balancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-deployment
spec:
replicas: 3
selector:
matchLabels:
app: sample-app
template:
metadata:
labels:
app: sample-app
spec:
containers:
- name: nginx-container
image: nginx:1.12
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: sample-load-balancer
spec:
type: LoadBalancer
externalTrafficPolicy: Local # defaultがClusterでNode到達後にもNodeを飛び越えてPodにロードバランシングを行う。
loadBalancerIP: XXX.XXX.XXX.XXX # 静的に指定することも可能
ports:
- name: "http-port"
protocol: "TCP"
port: 8080
targetPort: 80
nodePort: 30082
selector:
app: sample-app
loadBalancerSourceRanges:
- 10.0.0.0/8 # LoadBalancerのアクセス制限。Defaultは0.0.0.0/0
kubectl get services # External IPを確認 [ExternalIP] + [NodePort]で接続
GCPでは自分が所有していないアドレスはloadBalancerIPとして指定できない。[VPCネットワーク] - [外部IPアドレス]から事前に予約するべし。
ExternalName Service
apiVersion: v1
kind: Service
metadata:
name: sample-external-name-service
namespace: default
spec:
type: ExternalName
externalName: external.example.com # 外部サービスのCNAME。Clusterから外部サービスへのアクセスの切り替えがKubenetesで切り替えられるようになる。
Ingress
動かない。なぜだろう...?
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: sample-deployment
spec:
replicas: 1
selector:
matchLabels:
app: sample-app
template:
metadata:
labels:
app: sample-app
spec:
containers:
- name: nginx-container
image: nginx:1.12
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: sample-nodeport
spec:
type: NodePort
ports:
- name: "http-port"
protocol: "TCP"
port: 8080
targetPort: 80
selector:
app: sample-app
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: sample-ingress
spec:
rules:
- host: sample.example.com
http:
paths:
- path: /path1/*
backend:
serviceName: sample-nodeport
servicePort: 8080
- path: /path2/*
backend:
serviceName: sample-nodeport
servicePort: 8080
backend:
serviceName: sample-nodeport
servicePort: 8080
# tls:
# - hosts:
# - sample.example.com
# secretName: tls-sample
kubectl get ingresses sample-ingress # 払い出されたIDアドレスの確認
Secret
apiVersion: v1
kind: Pod
metadata:
name: sample-pull-secret
spec:
containers:
- name: sample-pull-secret
image: REGISTRY_NAME/secret-image:latest
envFrom: # SecretのKeyを全て環境変数として設定
- secretRef:
name: sample-db-auth
env:
- name: DB_USERNAME
valueFrom: # Secretから環境変数を作成
secretKeyRef:
name: sample-db-auth
key: username
imagePullSecrets: # ここで指定してPullできるように
- name: sample-registry-auth
kubectl create secret generic --save-config sample-db-auth --from-env-file .env # envファイルからSecretを作成
kubectl create secret generic --save-config docker-registry sample-registry-auth --docker-server=REGISTRY_SERVER --docker-username=REGISTRY_USERNAME --docker-password=DOCKER_PASSWORD --docker-email=REGISTRY_USER_EMAIL # PrivateImageをPullするためのSecretを作成
.env
username=keijun
userbirthday=12345678
ConfigMap
apiVersion: v1
kind: Pod
metadata:
name: sample-pull-secret
spec:
containers:
- name: sample-pull-secret
image: REGISTRY_NAME/secret-image:latest
envFrom: # ConfigMapのKeyを全て環境変数として設定
- configMapRef:
name: sample-db-auth
env:
- name: DB_USERNAME
valueFrom: # ConfigMapから環境変数を作成
configMapKeyRef:
name: sample-db-auth
key: connection.max
kubectl create configmap --save-config sample-configmap --from-file=./nginx.conf
kubectl get configmaps sample-configmap -o json | jq .data
EmptyDir
apiVersion: v1
kind: Pod
metadata:
name: sample-emptydir
spec:
containers:
- image: nginx:1.12
name: nginx-container
volumeMounts:
- mountPath: /cache
name: cache-volume
volumes:
- name: cache-volume
emptyDir: {}
HostPath
apiVersion: v1
kind: Pod
metadata:
name: sample-hostpath
spec:
containers:
- image: nginx:1.12
name: nginx-container
volumeMounts:
- mountPath: /etc
name: cache-volume
volumes:
- name: cache-volume
hostPath:
path: /etc
type: DirectoryOrCreate
DownwardAPI
apiVersion: v1
kind: Pod
metadata:
name: sample-downward-api
spec:
containers:
- image: nginx:1.12
name: nginx-container
volumeMounts:
- mountPath: /srv
name: downward-api-volume
volumes:
- name: downward-api-volume
downwardAPI:
items:
- path: "podname"
fieldRef:
fieldPath: metadata.name
- path: "cpu-request"
resourceFieldRef:
containerName: "nginx-container"
resource: requests.cpu
kubectl exec -it sample-downward-api ls /srv # 確認
Projected
apiVersion: v1
kind: Pod
metadata:
name: sample-projected
spec:
containers:
- image: nginx:1.12
name: nginx-container
volumeMounts:
- name: projected-volume
mountPath: /srv
volumes:
- name: projected-volume
projected:
sources:
- secret:
name: sample-db-auth
items:
- key: username
path: secret/username.txt
- configMap:
name: sample-cnofigmap
items:
- key: nginx.conf
path: configmap/nginx.conf
- downwardAPI:
items:
- path: "podname"
fieldRef:
fieldPath: metadata.name
kubectl exec -it sample-projected ls /srv # 確認
PersistVolume
apiVersion: v1
kind: PersistentVolume
metadata:
name: sample-pv
labels:
type: gce-pv
environment: stg
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce # ReadWriteManyとかもある
persistentVolumeReclaimPolicy: Retain # Claimの方で利用されなくなった時の挙動とか。Delete、Recycleとかがある。
storageClassName: manual
gcePersistentDisk:
pdName: sample-gce-pv
fsType: ext4
gcloud compute disks create --size=10GB sample-gce-pv --zone asia-northeast1-a
kubectl get persistentvolumes
PersistentVolumeClaim
---
apiVersion: v1
kind: Pod
metadata:
name: sample-projected
spec:
containers:
- image: nginx:1.12
name: nginx-container
volumeMounts:
- name: sample-pvc
mountPath: /srv
volumes:
- name: projected-volume
persistentVolumeClaim:
claimName: sample-pvc
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: sample-pv
labels:
type: gce-pv
environment: stg
spec:
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
storageClassName: manual
gcePersistentDisk:
pdName: sample-gce-pv
fsType: ext4
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: sample-pvc
spec:
selector:
matchLabels:
type: gce-pv
matchExpressions:
- {key: environment, operator: In, values: [stg]}
resources:
requests:
storage: 4Gi
accessModes:
- ReadWriteOnce
storageClassName: manual
kubectl get persistentvolumeclaims
kubectl describe pvc sample-pvc
StorageClass
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: sample-pvc-provisioner
annotations:
volume.beta.kubernetes.io/storage-class: sample-storageclass
spec:
resources:
requests:
storage: 3Gi
accessModes:
- ReadWriteOnce
---
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: sample-strageclass
parameters:
type: pd-ssd
provisioner: kubernetes.io/gce-pd
reclaimPolicy: Delete
自動でPersistentColumeが作成されない....
StatefulSet
使うと簡単にPersistentVolumeClaimが設定できそうである。