我已经尝试了 Kubernetes1.10 教程201(标签、部署、服务、存活探针)

首先

Kubernetesの公式ページに、多くのチュートリアルが掲載されています。
Kubernetesの勉強の一環で、チュートリアルを消化していきます。
今回は、Kubernetes 201 が対象です。
https://kubernetes.io/docs/user-guide/walkthrough/k8s201/

另外,我们使用的是截至2018年4月的最新版本1.10的Kubernetes。

Kubernetes是一个开源的容器编排平台。

在Kubernetes101教程中,我们将学习以下内容。

    • Label

 

    • Deployments

 

    • Service

 

    Health Checking

勒贝尔

如果创建了许多Pod,就需要创建并整理Pod的分类。在Kubernetes中,可以使用标签(Label)对Pod进行分类。标签是赋予Kubernetes中每个对象的键值对。

以下のマニフェストファイルを使用することで、PodにLabelを割り当てて、Deployすることが出来ます
6-7行目の [metadata.labels] でLabel[ app=nginx] と指定しています。

cat <<'EOF' > /root/kube_yaml/201_walkthrough/pod-nginx-with-label.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80
EOF

Deployします

[root@sugi-kubernetes110-master01 201_walkthrough]# kubectl create -f /root/kube_yaml/201_walkthrough/pod-nginx-with-label.yaml
pod "nginx" created

在Pod中查看详细信息
可以确认在Labels中显示了app=nginx

[root@sugi-kubernetes110-master01 201_walkthrough]# kubectl describe pod nginx 
Name:         nginx
Namespace:    default
Node:         sugi-kubernetes110-node02.localdomain/192.168.120.224
Start Time:   Mon, 30 Apr 2018 01:21:12 +0900
Labels:       app=nginx
<略

从所有的Pod中,只列出符合标签[app=nginx]的那些。

[root@sugi-kubernetes110-master01 201_walkthrough]# kubectl get pods -l app=nginx
NAME      READY     STATUS    RESTARTS   AGE
nginx     1/1       Running   0          3m

Deleteアクション時にもLabelを指定して削除が出来ます

[root@sugi-kubernetes110-master01 201_walkthrough]# kubectl delete pod -l app=nginx
pod "nginx" deleted

部署

我学习了Pod的管理方法。在这里,当需要扩展或缩小Pod,或者发布新版本时,我们应该如何进行管理呢?
在Kubernetes中,我们可以使用Deployment来管理和更新它们。

可以使用Deployment来定义Pod创建的模板,并指定副本的数量。

当部署Pod时,我们之前使用的是指定Pod的名称,而现在使用Deployment后,会动态指定Pod的名称,需要准备以下的清单文件。

cat <<'EOF' > /root/kube_yaml/201_walkthrough/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2 # tells deployment to run 2 pods matching the template
  template: # create pods using pod definition in this template
    metadata:
      # unlike pod-nginx.yaml, the name is not included in the meta data as a unique name is
      # generated from the deployment name
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.7.9
        ports:
        - containerPort: 80
EOF

创建Deployment

[root@sugi-kubernetes110-master01 ~]# kubectl create -f /root/kube_yaml/201_walkthrough/deployment.yaml
deployment.apps "nginx-deployment" created

将部署列为清单显示。

[root@sugi-kubernetes110-master01 ~]# kubectl get deployment -o wide
NAME               DESIRED   CURRENT   UP-TO-DATE   AVAILABLE   AGE       CONTAINERS   IMAGES        SELECTOR
nginx-deployment   2         2         2            2           2m        nginx        nginx:1.7.9   app=nginx

因为按照指定的清单文件,Pod也设置了标签,所以可以进行获取。

[root@sugi-kubernetes110-master01 ~]# kubectl get pod -o wide -l app=nginx
NAME                                READY     STATUS    RESTARTS   AGE       IP           NODE
nginx-deployment-75675f5897-mfm5r   1/1       Running   0          4m        10.244.2.6   sugi-kubernetes110-node02.localdomain
nginx-deployment-75675f5897-zgv94   1/1       Running   0          4m        10.244.1.7   sugi-kubernetes110-node01.localdomain

准备以下清单文件。
这是更新之前创建的部署“nginx-deployment”。
将容器镜像从nginx:1.7.9更改为1.8版本。

cat <<'EOF' > /root/kube_yaml/201_walkthrough/deployment-update.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 2
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.8 # Update the version of nginx from 1.7.9 to 1.8
        ports:
        - containerPort: 80
EOF

如果要更新已存在的Deployment,请使用apply而不是create。
如果使用create,由于已经存在Deployment,将会发生错误。

[root@sugi-kubernetes110-master01 ~]# kubectl apply -f /root/kube_yaml/201_walkthrough/deployment-update.yaml
Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply
deployment.apps "nginx-deployment" configured

PodのContainerがローリングアップデートされています

[root@sugi-kubernetes110-master01 ~]# kubectl get pod -o wide
NAME                                READY     STATUS              RESTARTS   AGE       IP           NODE
nginx-deployment-6ddf4c5bf7-zcpzh   0/1       ContainerCreating   0          1m        <none>       sugi-kubernetes110-node01.localdomain
nginx-deployment-75675f5897-mfm5r   1/1       Running             0          9m        10.244.2.6   sugi-kubernetes110-node02.localdomain
nginx-deployment-75675f5897-zgv94   1/1       Running             0          9m        10.244.1.7   sugi-kubernetes110-node01.localdomain

ローリングアップデートが完了しています

[root@sugi-kubernetes110-master01 ~]# kubectl get pod -o wide
NAME                                READY     STATUS    RESTARTS   AGE       IP           NODE
nginx-deployment-6ddf4c5bf7-rn5wp   1/1       Running   0          2m        10.244.2.7   sugi-kubernetes110-node02.localdomain
nginx-deployment-6ddf4c5bf7-zcpzh   1/1       Running   0          3m        10.244.1.8   sugi-kubernetes110-node01.localdomain

使用しているImageが1.8を使用していることがわかります

[root@sugi-kubernetes110-master01 ~]# kubectl describe pod -l app=nginx | grep Image
    Image:          nginx:1.8
    Image ID:       docker-pullable://docker.io/nginx@sha256:c97ee70c4048fe79765f7c2ec0931957c2898f47400128f4f3640d0ae5d60d10
    Image:          nginx:1.8
    Image ID:       docker-pullable://docker.io/nginx@sha256:c97ee70c4048fe79765f7c2ec0931957c2898f47400128f4f3640d0ae5d60d10

Services

Podを外部に公開するものがServicesです。
例えば、Podのスケールや再配置応じて、Podを外部公開する必要があります。
Kubernetesでは、Servicesでこれを実現しています。

我会准备以下的清单文件。

端口:指定访问Service时的端口号。
目标端口:指定Service访问的Pod的端口号。
选择器:指定Service访问的Pod所附带的标签。

cat <<'EOF' > /root/kube_yaml/201_walkthrough/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  ports:
  - port: 8000 # the port that this service should serve on
    # the container on each pod to connect to, can be a name
    # (e.g. 'www') or a number (e.g. 80)
    targetPort: 80
    protocol: TCP
  # just like the selector in the deployment,
  # but this time it identifies the set of pods to load balance
  # traffic to.
  selector:
    app: nginx
EOF

创建Service

[root@sugi-kubernetes110-master01 ~]# kubectl create -f /root/kube_yaml/201_walkthrough/service.yaml
service "nginx-service" created

我会查看服务列表
[nginx-service]是我这次创建的服务

[root@sugi-kubernetes110-master01 ~]# kubectl get service -o wide
NAME            TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)    AGE       SELECTOR
kubernetes      ClusterIP   10.96.0.1      <none>        443/TCP    1d        <none>
nginx-service   ClusterIP   10.98.70.219   <none>        8000/TCP   46s       app=nginx

BusyBoxを使用して、Pod内からClusterIPにアクセス可能確認します

export SERVICE_IP=$(kubectl get service nginx-service -o go-template='{{.spec.clusterIP}}')
export SERVICE_PORT=$(kubectl get service nginx-service -o go-template='{{(index .spec.ports 0).port}}')
echo "$SERVICE_IP:$SERVICE_PORT"
→ 10.98.70.219:8000

通过使用传递给BusyBox容器的环境变量,我们可以确认可以访问nginx服务。

kubectl run busybox  --generator=run-pod/v1 --image=busybox --restart=Never --tty -i --env "SERVICE_IP=$SERVICE_IP" --env "SERVICE_PORT=$SERVICE_PORT"
/ # wget -qO- http://$SERVICE_IP:$SERVICE_PORT # Run in the busybox container
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
    body {
        width: 35em;
        margin: 0 auto;
        font-family: Tahoma, Verdana, Arial, sans-serif;
    }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p>

<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>

<p><em>Thank you for using nginx.</em></p>
</body>
</html>
/ # 
/ # 
u@busybox$ exit # Exit the busybox container
$ kubectl delete pod busybox # Clean up the pod we created with "kubectl run"

我将删除该服务。

kubectl delete service nginx-service

健康检查

写一个没有bug的应用程序是不可能的。相反,当出现bug并导致崩溃时,在整个系统中定期进行检查,并自动修复是个好方法。
定期执行健康检查是很重要的,从应用程序的外部进行。
如果在应用程序内部执行,可能无法检测到应用程序故障的发生。

在Kubernetes中,内置了监控应用程序的功能。这是由运行在每个节点上的Kubelet代理执行的。

健康检查流程

最简单的健康检查是在进程级别进行的健康检查。 Kubelet代理会不断检查DockerDaemon上的容器进程是否正在运行。 如果容器进程未运行,则会重新启动容器进程。 在我们之前的教程中创建的Pod已经自动启用了进程健康检查。 它在Kubernetes中运行的所有容器中都生效。

健康检查应用程序

在大多数情况下,仅通过进程级别的检查是不足够的。
例如,如果发生了死锁,从Docker的角度来看,进程似乎正常运行。
然而,从应用程序的角度来看,却因死锁而停止,无法返回响应。

为了应对这个问题,Kubernetes 带有执行应用程序健康检查的功能。
应用程序健康检查是由 Kubelet 代理执行的,可以确认应用程序的正常运行。

以下是三种应用程序健康检测功能的特点。

    • HTTP Health Checks : KubeletがWebHoolを呼び出します。HTTPの response code が 200~399 の間は正常と判断されます。それ以外の response code の場合、異常と判断されます。

 

    • Container Exec : Kubeletがコンテナーの内側でコマンドを実行します。Return Code が 0 の場合は正常と判断されます。それ以外の場合、異常と判断されます。

 

    TCP Socket : KubeletがコンテナへTCP Socket を open することを試みます。接続が成功した場合、正常と判断されます。それ以外の場合、異常と判断されます。

在所有的情况下,如果被判断为异常,容器将会自动重新启动。

在Container中定义了健康检查的LivenessProbe部分。

我将准备以下的清单文件。

cat <<'EOF' > /root/kube_yaml/201_walkthrough/pod-with-http-healthcheck.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-with-http-healthcheck
spec:
  containers:
  - name: nginx
    image: nginx
    # defines the health checking
    livenessProbe:
      # an http probe
      httpGet:
        path: /_status/healthz
        port: 80
      # length of time to wait for a pod to initialize
      # after pod startup, before applying health checking
      initialDelaySeconds: 30
      timeoutSeconds: 1
    ports:
    - containerPort: 80
EOF

部署

[root@sugi-kubernetes110-master01 ~]# kubectl create -f /root/kube_yaml/201_walkthrough/pod-with-http-healthcheck.yaml
pod "pod-with-http-healthcheck" created

可以看出,在使用的nginx映像中,由于缺少livenessProbe的路径,导致容器定期重新启动的事件发生。

[root@sugi-kubernetes110-master01 ~]# kubectl describe pod pod-with-http-healthcheck 
Name:         pod-with-http-healthcheck
Namespace:    default
Node:         sugi-kubernetes110-node02.localdomain/192.168.120.224
Start Time:   Mon, 30 Apr 2018 13:58:17 +0900
Labels:       <none>
Annotations:  <none>
Status:       Running
IP:           10.244.2.10
Containers:
  nginx:
    Container ID:   docker://27c7a66726be6476bc6f7ec383bc9c2823ed38766598cf28b57d48912421c34b
    Image:          nginx
    Image ID:       docker-pullable://docker.io/nginx@sha256:80e2f223b2a53cfcf3fd491521e5fb9b4004d42dfc391c76011bcdd9565643df
    Port:           80/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Mon, 30 Apr 2018 14:01:56 +0900
    Last State:     Terminated
      Reason:       Completed
      Exit Code:    0
      Started:      Mon, 30 Apr 2018 14:01:06 +0900
      Finished:     Mon, 30 Apr 2018 14:01:52 +0900
    Ready:          True
    Restart Count:  4
    Liveness:       http-get http://:80/_status/healthz delay=30s timeout=1s period=10s #success=1 #failure=3
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-q65hj (ro)
Conditions:
  Type           Status
  Initialized    True 
  Ready          True 
  PodScheduled   True 
Volumes:
  default-token-q65hj:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-q65hj
    Optional:    false
QoS Class:       BestEffort
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              4m               default-scheduler                               Successfully assigned pod-with-http-healthcheck to sugi-kubernetes110-node02.localdomain
  Normal   SuccessfulMountVolume  4m               kubelet, sugi-kubernetes110-node02.localdomain  MountVolume.SetUp succeeded for volume "default-token-q65hj"
  Normal   Created                2m (x3 over 3m)  kubelet, sugi-kubernetes110-node02.localdomain  Created container
  Normal   Started                2m (x3 over 3m)  kubelet, sugi-kubernetes110-node02.localdomain  Started container
  Normal   Pulling                1m (x4 over 4m)  kubelet, sugi-kubernetes110-node02.localdomain  pulling image "nginx"
  Warning  Unhealthy              1m (x7 over 3m)  kubelet, sugi-kubernetes110-node02.localdomain  Liveness probe failed: HTTP probe failed with statuscode: 404
  Normal   Killing                1m (x3 over 2m)  kubelet, sugi-kubernetes110-node02.localdomain  Killing container with id docker://nginx:Container failed liveness probe.. Container will be killed and recreated.
  Normal   Pulled                 1m (x4 over 3m)  kubelet, sugi-kubernetes110-node02.localdomain  Successfully pulled image "nginx"

请提供一个参考网址

Kubernetes 201 公式教程页面
https://kubernetes.io/docs/user-guide/walkthrough/k8s201/

文档概览
https://kubernetes.io/docs/home/?path=users&persona=app-developer&level=foundational

bannerAds