Open7

k8s

hanpenmanhanpenman

replicaset

podの複数
同一仕様のpodのレプリカ数を管理するもの

deployment

replicasetを管理するもの

apiVersion: apps/v1
kind: Deployment
metadata:
  name: echo
  labels:
    app: echo
spec:
  replicas: 3
  selector:
    # NOTE: どのPodをDeploymentの対象とするかのラベルセレクター
    # LINK: https://christina04.hatenablog.com/entry/kubernetes-labels
    matchLabels:
      app: echo
  template:
    metadata:
      labels:
        app: echo
    spec:
      containers:
        - name: nginx
          image: ghcr.io/gihyodocker/simple-nginx-proxy:v0.1.0
          env:
            - name: NGINX_PORT
              value: "80"
            - name: SERVER_NAME
              value: "localhost"
            - name: BACKEND_HOST
              value: "localhost:8080"
            - name: BACKEND_MAX_FAILS
              value: "3"
            - name: BACKEND_FAIL_TIMEOUT
              value: "10s"
          ports:
            - containerPort: 80
        - name: echo
          image: ghcr.io/gihyodocker/echo:v0.1.0-patch
          ports:
            - containerPort: 8080

labelの用途

  • Deploymentのmetadata.labels: Deployment自体を識別するためのラベル。他のリソースとの関連付けやセレクションに使用。
  • Deploymentのselector.matchLabels: このDeploymentによって管理されるPod.どのpodをdeploymentの対象にするかの指定
  • Podのtemplate.metadata.labels: Deploymentによって作成されるPodに割り当てられるラベル。deploymentの対象にさせるためのlabel指定
hanpenmanhanpenman

色々コマンド

kubectl create namespace taskapp #namespace作成
kubectl config set-context --current --namespace=  #namcespaceのswitch
kubectl get pod,replicaset,deployment #色々みれる
kubectl get pods -n my-namespace #my-namespaceのpodをみれる
kubectl get pod --selector app=echo #deploymentで管理されているpodを確認できる

kubectl create secret generic test-secret --from-literal=password=aa_password #secret作成. test-secretという名前でpasswordがkey, aa_passwordがvalueとなる
kubectl get secret/test-secret -o yaml # secretを確認できる
kubectl -n taskapp describe secrets/api-config  #より詳細な情報



hanpenmanhanpenman

service

内部のloadbalancer的なやつ。ipアドレス振ってくれる。いくつか種類があるみたい

ingress

パスベースでも振り分けることができる。

ingressでパスベースのルーティングが可能となり、serviceにてpodにloadbalanceできるという役割。

 kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/cloud/deploy.yaml  #ローカルでingressを立てるにはingress controllerというのが必要。

kubectl get ingressClass #ingressClassを確認できる。
ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: echo
  labels:
    app: echo
spec:
  ingressClassName: nginx
  rules:
    - host: ch05.gihyo.local
      http:
        paths:
          - pathType: Prefix
            path: /  #全てのpathが指定されている。ここで/api と指定すれば https://example.com/api のようなurlが一致する
            backend:
              service:
                name: echo
                port:
                  number: 80
hanpenmanhanpenman

stateful

replicasetの意味を含めつつ、ストレージをマウントする。mysqlのようなデータを永続的に保存したいような時に利用する。podが連番となる。

apiVersion: apps/v1
kind: StatefulSet #Replicasetの意味も含めている。
metadata:
  name: mysql
  labels:
    app: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  serviceName: "mysql"
  replicas: 1
  template:
    metadata:
      labels:
        app: mysql
    spec:
      terminationGracePeriodSeconds: 10
      containers:
        - name: mysql
          image: ghcr.io/gihyodocker/taskapp-mysql:v0.1.0
          env:
            - name: MYSQL_ROOT_PASSWORD_FILE
              value: /var/run/secrets/mysql/root_password
            - name: MYSQL_DATABASE
              value: taskapp
            - name: MYSQL_USER
              value: taskapp_user
            - name: MYSQL_PASSWORD_FILE
              value: /var/run/secrets/mysql/user_password
          ports:
            - containerPort: 3306
              name: mysql
          volumeMounts:
            - name: mysql-data
              mountPath: /var/lib/mysql
            - name: mysql-secret
              mountPath: "/var/run/secrets/mysql"
              readOnly: true
      volumes:
        - name: mysql-secret
          secret:
            secretName: mysql
  volumeClaimTemplates: #PVCの作成。永続化できる
    - metadata:
        name: mysql-data
      spec:
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 1Gi

---
apiVersion: v1
kind: Service
metadata:
  name: mysql
  labels:
    app: mysql
spec:
  ports:
    - protocol: TCP
      port: 3306
      targetPort: 3306
  selector:
    app: mysql
  clusterIP: None

kubectl -n taskapp get pod,statefulset,pvc,service -l app=mysql                                                                     (git)-[main]
NAME          READY   STATUS    RESTARTS   AGE
pod/mysql-0   1/1     Running   0          7m51s

NAME                     READY   AGE
statefulset.apps/mysql   1/1     7m51s

NAME                                       STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS   AGE
persistentvolumeclaim/mysql-data-mysql-0   Bound    pvc-a6445c8f-cf72-4bca-855b-023fb793e756   1Gi        RWO            hostpath       7m51s

NAME            TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
service/mysql   ClusterIP   None         <none>        3306/TCP   7m51s

job

処理の完了後に常駐せずに終了するコンテナのこと

hanpenmanhanpenman

ingress, service, deploymentmを書く

同じファイルで書くことができる。podの中にはnginx,webと2つ用意。nginxはログ、静的ファイルの役割がある。この時のnginxはサイドカーと呼ばれる。
initContainersにて静的ファイルはコピーしておき、containersにてマウントを行いnginxのサーバに配置させる。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
  labels:
    app: web
spec:
  replicas: 1
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      initContainers: #initContainersでassetをvolumeMountにコピーして静的ファイルはnginxから参照させる。
        - name: init
          image: ghcr.io/gihyodocker/taskapp-web:v0.1.0
          command:
            - "sh"
            - "-c"
            - "cp -r /go/src/github.com/gihyodocker/taskapp/assets/* /var/www/assets"
          volumeMounts:
            - name: assets-volume
              mountPath: "/var/www/assets"
      containers:
        - name: nginx-web
          image: ghcr.io/gihyodocker/taskapp-nginx-web:v0.1.0
          env:
            - name: NGINX_PORT
              value: "80"
            - name: SERVER_NAME
              value: "localhost"
            - name: ASSETS_DIR
              value: "/var/www/assets"
            - name: BACKEND_HOST
              value: "localhost:8280"
            - name: BACKEND_MAX_FAILS
              value: "3"
            - name: BACKEND_FAIL_TIMEOUT
              value: "10s"
          volumeMounts:
            - name: assets-volume
              mountPath: "/var/www/assets"
              readOnly: true
        - name: web
          image: ghcr.io/gihyodocker/taskapp-web:v0.1.0
          ports:
            - containerPort: 8280
          args:
            - "server"
            - "--api-address=http://api:80"# urlのapiは同じnamespaceにservice名apiがある場合、そこにアクセスする。api.defaultと記載する場合は違うnamespaceの時このように書く。
      volumes:
        - name: assets-volume
          emptyDir: {}

---
apiVersion: v1
kind: Service
metadata:
  name: web
  labels:
    app: web
spec:
  ports:
    - protocol: TCP
      port: 80
      targetPort: 80
  selector:
    app: web

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web
  labels:
    app: web
spec:
  ingressClassName: nginx
  rules:
    - host: localhost
      http:
        paths:
          - pathType: Prefix
            path: /
            backend:
              service:
                name: web
                port:
                  number: 80

hanpenmanhanpenman

ヘルスチェック

  • livenessProve

    • ファイルチェックを行ってヘルスチェック
  • readinessProbe

    • L7レイヤーでのリクエストチェック

    cronjob

cronjob

apiVersion: batch/v1
kind: CronJob
metadata:
name: ping
labels:
  app: ping
spec:
schedule: "*/1 * * * *" #スケジュール
jobTemplate:
  spec:
    template:
      metadata:
        labels:
          app: ping
      spec:
        containers:
          - name: ping
            image: ubuntu
            command:
              - "sh"
              - "-c"
              - |
                echo [`date`] ping
                sleep 10
                echo [`date`] pong
        restartPolicy: OnFailure

kubectl apply -f k8s/cronjob/cronjob.yamlで実行すればnamespaceの場所にcronjobを仕込むことができる。cronjobを一度だけ実行する。 kubectl create job onetime-ping --from=cronjob/ping

hanpenmanhanpenman

helm

helmのrepoを追加
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo list

以下で例えばmysqlを配置することができる。

helm install mysql bitnami/mysql \ 
...................................................................... --namespace helm-mysql \ 
...................................................................... --create-namespace \ 
...................................................................... --version 9.12.5 \ 
...................................................................... --values mysql.yaml

以下コマンドで配置されたmysqlの環境を確認できる。

helm ls --namespace helm-mysql
kubectl get pod,service,statefulset,secret -n helm-mysql

kubernetsのclusterにdebugできる
kubectl run -i --rm --tty debug --image=ghcr.io/gihyodocker/debug:v0.1.0 --restart=Never -- bash

独自のChartを置くことができる

helm create echo

.
├── Chart.yaml
├── charts
├── templates
│   ├── NOTES.txt
│   ├── _helpers.tpl
│   ├── deployment.yaml
│   ├── hpa.yaml
│   ├── ingress.yaml
│   ├── service.yaml
│   ├── serviceaccount.yaml
│   └── tests
│       └── test-connection.yaml
└── values.yaml