k8s ハンズオンをなぞってみる

KubernetesのわかりやすいハンズオンがQiitaにあったので試してみた。

数時間で完全理解!わりとゴツいKubernetesハンズオン!! https://qiita.com/Kta-M/items/ce475c0063d3d3f36d5d

手順上、以下でエラーとなるため、変更して作業する必要あり

Docker for Desktop での「下準備」は以下の手順で対応:

kustomizationのBASEファイルが削除されているため、記載されている手順ではエラーとなる。 https://github.com/kubernetes/ingress-nginx/issues/5164

以下の手順で動作確認

kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-0.32.0/deploy/static/provider/cloud/deploy.yaml

ハンズオン結果1

以下、「サンプルアプリをデプロイ」から「Ingress」確認までの履歴

$ kubectl apply -f examples/guestbook/
$ kubectl apply -f guestbook-ingress.yaml

$ kubectl get ingress
NAME                HOSTS   ADDRESS   PORTS   AGE
guestbook-ingress   *                 80      16s
$ kubectl get ingress
NAME                HOSTS   ADDRESS     PORTS   AGE
guestbook-ingress   *       localhost   80      26s

$ curl http://localhost
<html ng-app="redis">
  <head>
    <title>Guestbook</title>
    <link rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.12/angular.min.js"></script>
    <script src="controllers.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.13.0/ui-bootstrap-tpls.js"></script>
  </head>
  <body ng-controller="RedisCtrl">
    <div style="width: 50%; margin-left: 20px">
      <h2>Guestbook</h2>
    <form>
    <fieldset>
    <input ng-model="msg" placeholder="Messages" class="form-control" type="text" name="input"><br>
    <button type="button" class="btn btn-primary" ng-click="controller.onRedis()">Submit</button>
    </fieldset>
    </form>
    <div>
      <div ng-repeat="msg in messages track by $index">
        {{msg}}
      </div>
    </div>
    </div>
  </body>
</html>

$ kubectl get all
NAME                                READY   STATUS    RESTARTS   AGE
pod/frontend-6cb7f8bd65-fxc6b       1/1     Running   0          7m38s
pod/redis-master-7db7f6579f-7cmgr   1/1     Running   0          7m38s
pod/redis-slave-5bdcfd74c7-hbdmp    1/1     Running   0          7m38s

NAME                   TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
service/frontend       NodePort    10.111.147.241   <none>        80:30228/TCP   7m38s
service/kubernetes     ClusterIP   10.96.0.1        <none>        443/TCP        21d
service/redis-master   ClusterIP   10.111.102.221   <none>        6379/TCP       7m38s
service/redis-slave    ClusterIP   10.102.8.228     <none>        6379/TCP       7m38s

NAME                           READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/frontend       1/1     1            1           7m38s
deployment.apps/redis-master   1/1     1            1           7m38s
deployment.apps/redis-slave    1/1     1            1           7m38s

NAME                                      DESIRED   CURRENT   READY   AGE
replicaset.apps/frontend-6cb7f8bd65       1         1         1       7m38s
replicaset.apps/redis-master-7db7f6579f   1         1         1       7m38s
replicaset.apps/redis-slave-5bdcfd74c7    1         1         1       7m38s

$ kubectl get deploy -o wide
NAME           READY   UP-TO-DATE   AVAILABLE   AGE   CONTAINERS   IMAGES                                   SELECTOR
frontend       1/1     1            1           35m   php-redis    gcr.io/google-samples/gb-frontend:v4     app=guestbook,tier=frontend
redis-master   1/1     1            1           35m   master       k8s.gcr.io/redis:e2e                     app=redis,role=master,tier=backend
redis-slave    1/1     1            1           35m   slave        gcr.io/google_samples/gb-redisslave:v1   app=redis,role=slave,tier=backend


$ kubectl describe deploy frontend
Name:                   frontend
Namespace:              default
CreationTimestamp:      Sat, 06 Jun 2020 17:40:37 +0900
Labels:                 <none>
Annotations:            deployment.kubernetes.io/revision: 1
                        kubectl.kubernetes.io/last-applied-configuration:
                          {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{},"name":"frontend","namespace":"default"},"spec":{"replicas":1,"se...
Selector:               app=guestbook,tier=frontend
Replicas:               1 desired | 1 updated | 1 total | 1 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=guestbook
           tier=frontend
  Containers:
   php-redis:
    Image:      gcr.io/google-samples/gb-frontend:v4
    Port:       80/TCP
    Host Port:  0/TCP
    Requests:
      cpu:     100m
      memory:  100Mi
    Environment:
      GET_HOSTS_FROM:  dns
    Mounts:            <none>
  Volumes:             <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  <none>
NewReplicaSet:   frontend-6cb7f8bd65 (1/1 replicas created)
Events:
  Type    Reason             Age   From                   Message
  ----    ------             ----  ----                   -------
  Normal  ScalingReplicaSet  36m   deployment-controller  Scaled up replica set frontend-6cb7f8bd65 to 1

$ kubectl get rs -o wide
NAME                      DESIRED   CURRENT   READY   AGE   CONTAINERS   IMAGES                                   SELECTOR
frontend-6cb7f8bd65       1         1         1       38m   php-redis    gcr.io/google-samples/gb-frontend:v4     app=guestbook,pod-template-hash=6cb7f8bd65,tier=frontend
redis-master-7db7f6579f   1         1         1       38m   master       k8s.gcr.io/redis:e2e                     app=redis,pod-template-hash=7db7f6579f,role=master,tier=backend
redis-slave-5bdcfd74c7    1         1         1       38m   slave        gcr.io/google_samples/gb-redisslave:v1   app=redis,pod-template-hash=5bdcfd74c7,role=slave,tier=backend

$ kubectl describe rs frontend-6cb7f8bd65
Name:           frontend-6cb7f8bd65
Namespace:      default
Selector:       app=guestbook,pod-template-hash=6cb7f8bd65,tier=frontend
Labels:         app=guestbook
                pod-template-hash=6cb7f8bd65
                tier=frontend
Annotations:    deployment.kubernetes.io/desired-replicas: 1
                deployment.kubernetes.io/max-replicas: 2
                deployment.kubernetes.io/revision: 1
Controlled By:  Deployment/frontend
Replicas:       1 current / 1 desired
Pods Status:    1 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  app=guestbook
           pod-template-hash=6cb7f8bd65
           tier=frontend
  Containers:
   php-redis:
    Image:      gcr.io/google-samples/gb-frontend:v4
    Port:       80/TCP
    Host Port:  0/TCP
    Requests:
      cpu:     100m
      memory:  100Mi
    Environment:
      GET_HOSTS_FROM:  dns
    Mounts:            <none>
  Volumes:             <none>
Events:
  Type    Reason            Age   From                   Message
  ----    ------            ----  ----                   -------
  Normal  SuccessfulCreate  38m   replicaset-controller  Created pod: frontend-6cb7f8bd65-fxc6b

$ kubectl get pod -o wide
NAME                            READY   STATUS    RESTARTS   AGE   IP          NODE             NOMINATED NODE   READINESS GATES
frontend-6cb7f8bd65-fxc6b       1/1     Running   0          40m   10.1.0.26   docker-desktop   <none>           <none>
redis-master-7db7f6579f-7cmgr   1/1     Running   0          40m   10.1.0.25   docker-desktop   <none>           <none>
redis-slave-5bdcfd74c7-hbdmp    1/1     Running   0          40m   10.1.0.27   docker-desktop   <none>           <none>

$ kubectl describe pod frontend-6cb7f8bd65-fxc6b
Name:         frontend-6cb7f8bd65-fxc6b
Namespace:    default
Priority:     0
Node:         docker-desktop/192.168.65.3
Start Time:   Sat, 06 Jun 2020 17:40:37 +0900
Labels:       app=guestbook
              pod-template-hash=6cb7f8bd65
              tier=frontend
Annotations:  <none>
Status:       Running
IP:           10.1.0.26
IPs:
  IP:           10.1.0.26
Controlled By:  ReplicaSet/frontend-6cb7f8bd65
Containers:
  php-redis:
    Container ID:   docker://78eb908cd313b23b1ccaa425d9c1966701ddccf643197a9ae2d232342910923c
    Image:          gcr.io/google-samples/gb-frontend:v4
    Image ID:       docker-pullable://gcr.io/google-samples/gb-frontend@sha256:d44e7d7491a537f822e7fe8615437e4a8a08f3a7a1d7d4cb9066b92f7556ba6d
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Sat, 06 Jun 2020 17:46:36 +0900
    Ready:          True
    Restart Count:  0
    Requests:
      cpu:     100m
      memory:  100Mi
    Environment:
      GET_HOSTS_FROM:  dns
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-q8xgg (ro)
Conditions:
  Type              Status
  Initialized       True 
  Ready             True 
  ContainersReady   True 
  PodScheduled      True 
Volumes:
  default-token-q8xgg:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-q8xgg
    Optional:    false
QoS Class:       Burstable
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type    Reason     Age   From                     Message
  ----    ------     ----  ----                     -------
  Normal  Scheduled  40m   default-scheduler        Successfully assigned default/frontend-6cb7f8bd65-fxc6b to docker-desktop
  Normal  Pulling    40m   kubelet, docker-desktop  Pulling image "gcr.io/google-samples/gb-frontend:v4"
  Normal  Pulled     34m   kubelet, docker-desktop  Successfully pulled image "gcr.io/google-samples/gb-frontend:v4"
  Normal  Created    34m   kubelet, docker-desktop  Created container php-redis
  Normal  Started    34m   kubelet, docker-desktop  Started container php-redis

$ kubectl logs frontend-6cb7f8bd65-fxc6b
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 10.1.0.26. Set the 'ServerName' directive globally to suppress this message
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 10.1.0.26. Set the 'ServerName' directive globally to suppress this message
[Sat Jun 06 08:46:36.740260 2020] [mpm_prefork:notice] [pid 1] AH00163: Apache/2.4.10 (Debian) PHP/5.6.20 configured -- resuming normal operations
[Sat Jun 06 08:46:36.740298 2020] [core:notice] [pid 1] AH00094: Command line: 'apache2 -D FOREGROUND'
10.1.0.24 - - [06/Jun/2020:08:48:21 +0000] "GET / HTTP/1.1" 200 770 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Safari/605.1.15"
10.1.0.24 - - [06/Jun/2020:08:48:21 +0000] "GET /controllers.js HTTP/1.1" 200 704 "http://localhost/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Safari/605.1.15"
10.1.0.24 - - [06/Jun/2020:08:48:21 +0000] "GET /guestbook.php?cmd=get&key=messages HTTP/1.1" 200 189 "http://localhost/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Safari/605.1.15"

$ kubectl get svc -o wide
NAME           TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE   SELECTOR
frontend       NodePort    10.111.147.241   <none>        80:30228/TCP   42m   app=guestbook,tier=frontend
kubernetes     ClusterIP   10.96.0.1        <none>        443/TCP        21d   <none>
redis-master   ClusterIP   10.111.102.221   <none>        6379/TCP       42m   app=redis,role=master,tier=backend
redis-slave    ClusterIP   10.102.8.228     <none>        6379/TCP       42m   app=redis,role=slave,tier=backend

$ kubectl describe svc frontend
Name:                     frontend
Namespace:                default
Labels:                   app=guestbook
                          tier=frontend
Annotations:              kubectl.kubernetes.io/last-applied-configuration:
                            {"apiVersion":"v1","kind":"Service","metadata":{"annotations":{},"labels":{"app":"guestbook","tier":"frontend"},"name":"frontend","namespa...
Selector:                 app=guestbook,tier=frontend
Type:                     NodePort
IP:                       10.111.147.241
LoadBalancer Ingress:     localhost
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  30228/TCP
Endpoints:                10.1.0.26:80
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>


$ kubectl get ing
NAME                HOSTS   ADDRESS     PORTS   AGE
guestbook-ingress   *       localhost   80      42m

$ kubectl describe ing guestbook-ingress
Name:             guestbook-ingress
Namespace:        default
Address:          localhost
Default backend:  default-http-backend:80 (<none>)
Rules:
  Host  Path  Backends
  ----  ----  --------
  *     
        /   frontend:80 (10.1.0.26:80)
Annotations:
  kubectl.kubernetes.io/last-applied-configuration:  {"apiVersion":"extensions/v1beta1","kind":"Ingress","metadata":{"annotations":{},"name":"guestbook-ingress","namespace":"default"},"spec":{"rules":[{"http":{"paths":[{"backend":{"serviceName":"frontend","servicePort":80},"path":"/"}]}}]}}

Events:
  Type    Reason  Age   From                      Message
  ----    ------  ----  ----                      -------
  Normal  CREATE  42m   nginx-ingress-controller  Ingress default/guestbook-ingress
  Normal  UPDATE  42m   nginx-ingress-controller  Ingress default/guestbook-ingress

ハンズオン結果2

「スケールさせてみよう」から「お片付け」まで

$ kubectl apply -f k8s-examples/guestbook/frontend-deployment.yaml 
deployment.apps/frontend configured

$ kubectl get pod
NAME                            READY   STATUS    RESTARTS   AGE
frontend-6cb7f8bd65-fxc6b       1/1     Running   0          146m
frontend-6cb7f8bd65-w4hcb       1/1     Running   0          31s
redis-master-7db7f6579f-7cmgr   1/1     Running   0          146m
redis-slave-5bdcfd74c7-hbdmp    1/1     Running   0          146m

$ kubectl delete pod frontend-6cb7f8bd65-w4hcb
pod "frontend-6cb7f8bd65-w4hcb" deleted

$ kubectl get pod
NAME                            READY   STATUS    RESTARTS   AGE
frontend-6cb7f8bd65-4klft       1/1     Running   0          9s
frontend-6cb7f8bd65-fxc6b       1/1     Running   0          147m
redis-master-7db7f6579f-7cmgr   1/1     Running   0          147m
redis-slave-5bdcfd74c7-hbdmp    1/1     Running   0          147m

$ kubectl apply -f k8s-examples/guestbook/frontend-deployment.yaml 
deployment.apps/frontend configured
$ kubectl get pod
NAME                            READY   STATUS              RESTARTS   AGE
frontend-6cb7f8bd65-4klft       1/1     Running             0          105s
frontend-6cb7f8bd65-fxc6b       1/1     Running             0          149m
frontend-769bc557fc-fnjvv       0/1     ContainerCreating   0          2s
redis-master-7db7f6579f-7cmgr   1/1     Running             0          149m
redis-slave-5bdcfd74c7-hbdmp    1/1     Running             0          149m
$ kubectl get pod
NAME                            READY   STATUS              RESTARTS   AGE
frontend-6cb7f8bd65-4klft       0/1     Terminating         0          107s
frontend-6cb7f8bd65-fxc6b       1/1     Running             0          149m
frontend-769bc557fc-fnjvv       1/1     Running             0          4s
frontend-769bc557fc-wt86j       0/1     ContainerCreating   0          2s
redis-master-7db7f6579f-7cmgr   1/1     Running             0          149m
redis-slave-5bdcfd74c7-hbdmp    1/1     Running             0          149m
$ kubectl get pod
NAME                            READY   STATUS    RESTARTS   AGE
frontend-769bc557fc-fnjvv       1/1     Running   0          6s
frontend-769bc557fc-wt86j       1/1     Running   0          4s
redis-master-7db7f6579f-7cmgr   1/1     Running   0          149m
redis-slave-5bdcfd74c7-hbdmp    1/1     Running   0          149m

$ kubectl rollout history deployments frontend
deployment.apps/frontend 
REVISION  CHANGE-CAUSE
1         <none>
2         <none>

$ kubectl rollout history deployments frontend --revision=2
deployment.apps/frontend with revision #2
Pod Template:
  Labels:   app=guestbook
    pod-template-hash=769bc557fc
    tier=frontend
  Containers:
   php-redis:
    Image:  gcr.io/google-samples/gb-frontend:v4
    Port:   80/TCP
    Host Port:  0/TCP
    Requests:
      cpu:  100m
      memory:   120Mi
    Environment:
      GET_HOSTS_FROM:   dns
    Mounts: <none>
  Volumes:  <none>

$ kubectl rollout undo deployments frontend --to-revision=1
deployment.apps/frontend rolled back

$ kubectl rollout history deployments frontend
deployment.apps/frontend 
REVISION  CHANGE-CAUSE
2         <none>
3         <none>

$ kubectl get pods --namespace=kube-system
NAME                                     READY   STATUS    RESTARTS   AGE
coredns-5644d7b6d9-857g6                 1/1     Running   0          21d
coredns-5644d7b6d9-hvjc5                 1/1     Running   0          21d
etcd-docker-desktop                      1/1     Running   0          21d
kube-apiserver-docker-desktop            1/1     Running   0          21d
kube-controller-manager-docker-desktop   1/1     Running   0          21d
kube-proxy-2kqkm                         1/1     Running   0          21d
kube-scheduler-docker-desktop            1/1     Running   0          21d
storage-provisioner                      1/1     Running   1          21d
vpnkit-controller                        1/1     Running   0          21d

$ kubectl delete -f k8s-examples/guestbook/
deployment.apps "frontend" deleted
service "frontend" deleted
deployment.apps "redis-master" deleted
service "redis-master" deleted
deployment.apps "redis-slave" deleted
service "redis-slave" deleted

$ kubectl delete -f guestbook-ingress.yaml 
ingress.extensions "guestbook-ingress" deleted

$ kubectl get namespace
NAME              STATUS   AGE
default           Active   21d
docker            Active   21d
ingress-nginx     Active   3h42m
kube-node-lease   Active   21d
kube-public       Active   21d
kube-system       Active   21d

$ kubectl delete namespace ingress-nginx
namespace "ingress-nginx" deleted