LoginSignup
0
1

More than 3 years have passed since last update.

Kubernetes + GCP 技術調査 まとめ

Last updated at Posted at 2019-07-25

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が設定できそうである。

0
1
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
1