我已经尝试了 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