9月底k8s发行了1.4版,在此版中增加了kubeadm似乎是在向swarm致敬,但是极大方便了k8s的集群搭建。本系列教程将从搭建一个3个节点的k8s的集群开始,用一些简单的动手实例来学习一下k8s相关的基本概念以及k8s的核心用法。
由来
本教程受Kubernetes官方最新更新的文档所触发,之所以没有做单纯的翻译是因为如下几个原因:
- Kubernetes官方此教程基于minikube,个人对minikube可能有偏见,觉得像玩具。
- Minikube更新较慢,不久前试的仍然只是能模拟kubernetes1.3,kubeadm也出来了,只是用于教程的话完全可以取代。
- google的此教程提供了一个交互式的体验窗口,但是本来就不复杂的东西,就不想用它们的交互式的界面,感觉不真实,同时自己搭建可以先看什么就看什么,另外google目前提供的版本仍不是最新的。
- Kubernetes入门虽然不复杂,但是一般使用者第一个hello world的时间成本从接触到可用可能还是以天为计算单位,太浪费。但是确实作为对Kubernetes基本概念的理解的入门教程很不错,自己再重新看的时候也能温故而知新。从中糅出这几篇文章分享给大家,希望有所帮助。
Kubernetes基础
此系列教程中会着重于围绕Kubernetes集群编排相关的基本概念展开,同时通过容器化的应用如何在Kubernetes中部署/扩展/更新为主线而展开。我们将会学到:
- 将容器化的应用部署到集群上
- 扩展应用部署
- 更新容器化的应用程序版本
- 调试容器化的应用程序
Kubernetes是什么
Kubernetes是在整个计算机集群中对应用容器进行编排和执行的一个可以用于生产环境级别的开源平台。(了解更多内容 https://www.kubernetes.org.cn/kubernetes是什么)
Kubernetes能做什么
对于现代的web service,用于期待它应该是24×7的高可用,而开发者则期待能够每天都能对这些应用程序发布几个版本(虽然我没有这么想过)。容器化则能帮助打包应用程序完成这些目标,使得应用程序能够无宕机地平稳快速发布。Kubernetes则能够帮助做到剩下的事情。打完包的容器化应用运行在集群上需要做什么呢:
- 在哪个节点上执行
- 什么时候执行
- 使用那些resouce
- 如何在这个集群中调整这些resource
- ……
这些问题都需要进行考虑的,而现在kubernetes的编排和执行功能则为能为你排忧解难。而且Kubernetes不但是可以用于生产级别,而且还积累了google的多年容器化运行的经验,有前人踏坑的可用软件自然是大家竞相追逐的。
基本内容
本系列教程将以容器化的应用如何在Kubernetes集群上进行部署/更新/扩展按照如下六个步骤按序展开。
- Step 1. Create a Kubernetes cluster
- Step 2. Deploy an app
- Step 3. Explore your app
- Step 4. Expose your app publicly
- Step 5. Scale up your app
- Step 6. Update your app
组成要素
Kubernetes集群包含如下两种类型的资源:
类型 | 作用 |
---|---|
Master | 协调和操控集群 |
Node | 实际用于运行应用容器的”worker” |
集群构成
构成说明
Master的主要职责在于管理集群,协调集群上的所有活动,比如:
- 编排应用
- 维护应用状态
- 扩展应用
- 更新应用等
Node
Node就是一台在kubernetes集群中担任worker的VM或者物理机。在每个Node上都有一个kubelet,而Kubelet就是一个用于管理node和Master之间的沟通的agent。在node上需要安装docker,或者说用于管理容器操作的工具,因为kubernetes并不绑定docker,我们以前介绍过的rkt在kubernetes中也是支持的。而且明眼人都能看出来,rkt纯粹是google用于制衡docker的,rkt和kubernetes深度融合,但是是否能得到市场的认可这并不是一个纯粹技术的问题。
一个在生产环境中能够大体使用的kubernetes集群至少要有3个node。本来就是node的协调和编排,你就一个node,也非要用kubernetes,虽然可以任性,但是屠龙宝刀只用来裁墙纸多少会有大材小用的唏嘘。
Master
Master则用来管理集群。当你在kubernetes集群上部署应用的时候,你可能会需要Master启动某个应用容器。 Master在集群中协调用于启动此容器的node,而node使用kubernetes API和master进行通信(当然,用户也可以直接使用kubernetes API和集群进行交互)。
Kubernetes集群创建
Kubernetes集群可以被部署到物理机或者虚拟机上。可以使用minikube,但是本文将使用kubeadm方式创建一个3 node + 1 Master的集群。
构成
项番 | 类别 | host名 | IP |
---|---|---|---|
No.1 | Master | host31 | 192.168.32.31 |
No.2 | Node | host32 | 192.168.32.32 |
No.3 | Node | host33 | 192.168.32.33 |
No.4 | Node | host34 | 192.168.32.34 |
easypack_kubernetes.sh
K8S在1.4出来的时候向全世界宣布2条命令创建集群,在VPN的环境下,的确是这样,因为这些依赖关系1.4会根据需要自动的去pull,但是pull不到google_container的就这样被无比简单的一件事情堵在外面。本着利己利人的出发点,写了个脚本,放到了github上(https://github.com/liumiaocn/easypack/tree/master/k8s),脚本的使用基本上是sh easypack_kubernetes.sh MASTER来创建Master,sh easypack_kubernetes.sh NODE token MASTERIP来join,其他的诸如docker和kubelet/kubectl/kubeadm等的安装,container的事前下载都写进去了,版本全部目前统一为1.4.1的版本,脚本及其简单,无非将google的步骤放到一起而已,可以自行按自己需要进行修改。
创建Master
创建master在kubernetes1.4的版本只需要一条命令,kubeadm init, 但是其前提是能够联上网络,kubeadm会自动地按照需求去pull相应的image的版本,所以省去了翻来覆去的确认各个image等的版本,但是安装过程会慢一些,如果你查看linux的系统日志你就会发现/var/log/messages中只有在安装的时候在本地找不到正确版本的image的时候才回去pull,所以事前把所需要的内容都pull下来是一个很好的主意。
命令:
git clone https://github.com/liumiaocn/easypack
cd easypack/k8s
sh easypack_kubernetes.sh MASTER
>实际执行的时候不需要一定设定本地git,将上面github上面的脚本easypack_kubernetes.sh的内容copy下来在本地vi生成一个即可
安装耗时:10分钟(基本上都是在pull google_container的镜像)
输出参照:
[root@host31 ~]# git clone https://github.com/liumiaocn/easypack
Cloning into "easypack"...
remote: Counting objects: 67, done.
remote: Compressing objects: 100% (52/52), done.
remote: Total 67 (delta 11), reused 0 (delta 0), pack-reused 15
Unpacking objects: 100% (67/67), done.
[root@host31 ~]# cd easypack/k8s
[root@host31 k8s]# sh easypack_kubernetes.sh MASTER
Wed Nov 9 05:05:53 EST 2016
##INSTALL LOG : /tmp/k8s_install.1456.log
##Step 1: Stop firewall ...
Wed Nov 9 05:05:53 EST 2016
##Step 2: set repository and install kubeadm etc...
install kubectl in Master...
#######Set docker proxy when needed. If ready, press any to continue...
注意:此处需要回车一下才能继续,因为需要给安装完docker还要设定docker的代理的提供一个手动处理的方式,不通过代理的直接回车即可
Wed Nov 9 05:07:04 EST 2016
##Step 3: pull google containers...
Now begin to pull images from liumiaocn
No.1 : kube-proxy-amd64:v1.4.1 pull begins ...
No.1 : kube-proxy-amd64:v1.4.1 pull ends ...
No.1 : kube-proxy-amd64:v1.4.1 rename ...
No.1 : kube-proxy-amd64:v1.4.1 untag ...
No.2 : kube-discovery-amd64:1.0 pull begins ...
No.2 : kube-discovery-amd64:1.0 pull ends ...
No.2 : kube-discovery-amd64:1.0 rename ...
No.2 : kube-discovery-amd64:1.0 untag ...
No.3 : kube-scheduler-amd64:v1.4.1 pull begins ...
No.3 : kube-scheduler-amd64:v1.4.1 pull ends ...
No.3 : kube-scheduler-amd64:v1.4.1 rename ...
No.3 : kube-scheduler-amd64:v1.4.1 untag ...
No.4 : kube-controller-manager-amd64:v1.4.1 pull begins ...
No.4 : kube-controller-manager-amd64:v1.4.1 pull ends ...
No.4 : kube-controller-manager-amd64:v1.4.1 rename ...
No.4 : kube-controller-manager-amd64:v1.4.1 untag ...
No.5 : kube-apiserver-amd64:v1.4.1 pull begins ...
No.5 : kube-apiserver-amd64:v1.4.1 pull ends ...
No.5 : kube-apiserver-amd64:v1.4.1 rename ...
No.5 : kube-apiserver-amd64:v1.4.1 untag ...
No.6 : pause-amd64:3.0 pull begins ...
No.6 : pause-amd64:3.0 pull ends ...
No.6 : pause-amd64:3.0 rename ...
No.6 : pause-amd64:3.0 untag ...
No.7 : etcd-amd64:2.2.5 pull begins ...
No.7 : etcd-amd64:2.2.5 pull ends ...
No.7 : etcd-amd64:2.2.5 rename ...
No.7 : etcd-amd64:2.2.5 untag ...
No.8 : kubedns-amd64:1.7 pull begins ...
No.8 : kubedns-amd64:1.7 pull ends ...
No.8 : kubedns-amd64:1.7 rename ...
No.8 : kubedns-amd64:1.7 untag ...
No.9 : kube-dnsmasq-amd64:1.3 pull begins ...
No.9 : kube-dnsmasq-amd64:1.3 pull ends ...
No.9 : kube-dnsmasq-amd64:1.3 rename ...
No.9 : kube-dnsmasq-amd64:1.3 untag ...
No.10 : exechealthz-amd64:1.1 pull begins ...
No.10 : exechealthz-amd64:1.1 pull ends ...
No.10 : exechealthz-amd64:1.1 rename ...
No.10 : exechealthz-amd64:1.1 untag ...
No.11 : kubernetes-dashboard-amd64:v1.4.1 pull begins ...
No.11 : kubernetes-dashboard-amd64:v1.4.1 pull ends ...
No.11 : kubernetes-dashboard-amd64:v1.4.1 rename ...
No.11 : kubernetes-dashboard-amd64:v1.4.1 untag ...
All images have been pulled to local as following
gcr.io/google_containers/kube-controller-manager-amd64 v1.4.1 ad7b34f5ecb8 11 days ago 142.4 MB
gcr.io/google_containers/kube-apiserver-amd64 v1.4.1 4a76dd338dfe 4 weeks ago 152.1 MB
gcr.io/google_containers/kube-scheduler-amd64 v1.4.1 f9641959ec72 4 weeks ago 81.67 MB
gcr.io/google_containers/kube-proxy-amd64 v1.4.1 b47199222245 4 weeks ago 202.7 MB
gcr.io/google_containers/kubernetes-dashboard-amd64 v1.4.1 1dda73f463b2 4 weeks ago 86.76 MB
gcr.io/google_containers/kube-discovery-amd64 1.0 c5e0c9a457fc 6 weeks ago 134.2 MB
gcr.io/google_containers/kubedns-amd64 1.7 bec33bc01f03 10 weeks ago 55.06 MB
gcr.io/google_containers/kube-dnsmasq-amd64 1.3 9a15e39d0db8 4 months ago 5.126 MB
gcr.io/google_containers/pause-amd64 3.0 99e59f495ffa 6 months ago 746.9 kB
Wed Nov 9 05:14:18 EST 2016
Wed Nov 9 05:14:18 EST 2016
##Step 4: kubeadm init
Running pre-flight checks
注意:此处被卡的原因在于不符合安装要求,基本上将提示的问题对应即可,一般是/etc/kubernetes下面事前已经有内容了,一些端口已经被占用了等等。
<master/tokens> generated token: "77eddc.77edc19a7ade45d6"
<master/pki> generated Certificate Authority key and certificate:
Issuer: CN=kubernetes | Subject: CN=kubernetes | CA: true
Not before: 2016-11-09 10:14:19 +0000 UTC Not After: 2026-11-07 10:14:19 +0000 UTC
Public: /etc/kubernetes/pki/ca-pub.pem
Private: /etc/kubernetes/pki/ca-key.pem
Cert: /etc/kubernetes/pki/ca.pem
<master/pki> generated API Server key and certificate:
Issuer: CN=kubernetes | Subject: CN=kube-apiserver | CA: false
Not before: 2016-11-09 10:14:19 +0000 UTC Not After: 2017-11-09 10:14:19 +0000 UTC
Alternate Names: [192.168.32.31 10.0.0.1 kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local]
Public: /etc/kubernetes/pki/apiserver-pub.pem
Private: /etc/kubernetes/pki/apiserver-key.pem
Cert: /etc/kubernetes/pki/apiserver.pem
<master/pki> generated Service Account Signing keys:
Public: /etc/kubernetes/pki/sa-pub.pem
Private: /etc/kubernetes/pki/sa-key.pem
<master/pki> created keys and certificates in "/etc/kubernetes/pki"
<util/kubeconfig> created "/etc/kubernetes/kubelet.conf"
<util/kubeconfig> created "/etc/kubernetes/admin.conf"
<master/apiclient> created API client configuration
<master/apiclient> created API client, waiting for the control plane to become ready
注意:此处是容易被卡住的最多的地方,从这里开始基本上是google_container没有下载下来或者是没有下载到正确版本,详细可以参看另外一篇单独讲解使用kubeadm进行安装的文章。
<master/apiclient> all control plane components are healthy after 17.439551 seconds
<master/apiclient> waiting for at least one node to register and become ready
<master/apiclient> first node is ready after 4.004373 seconds
<master/apiclient> attempting a test deployment
<master/apiclient> test deployment succeeded
<master/discovery> created essential addon: kube-discovery, waiting for it to become ready
<master/discovery> kube-discovery is ready after 2.001892 seconds
<master/addons> created essential addon: kube-proxy
<master/addons> created essential addon: kube-dns
Kubernetes master initialised successfully!
You can now join any number of machines by running the following on each node:
kubeadm join --token=77eddc.77edc19a7ade45d6 192.168.32.31
注意:这个一定要注意,token是别的node用来join的时候必须的
Wed Nov 9 05:14:46 EST 2016
##Step 5: taint nodes...
node "host31" tainted
NAME STATUS AGE
host31 Ready 5s
注意:Master一般不是作为node来用的使用这种方法,这样可以折衷。
Wed Nov 9 05:14:46 EST 2016
##Step 6: confirm version...
Client Version: version.Info{Major:"1", Minor:"4", GitVersion:"v1.4.1", GitCommit:"33cf7b9acbb2cb7c9c72a10d6636321fb180b159", GitTreeState:"clean", BuildDate:"2016-10-10T18:19:49Z", GoVersion:"go1.6.3", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"4", GitVersion:"v1.4.1", GitCommit:"33cf7b9acbb2cb7c9c72a10d6636321fb180b159", GitTreeState:"clean", BuildDate:"2016-10-10T18:13:36Z", GoVersion:"go1.6.3", Compiler:"gc", Platform:"linux/amd64"}
kubeadm version: version.Info{Major:"1", Minor:"5+", GitVersion:"v1.5.0-alpha.1.409+714f816a349e79", GitCommit:"714f816a349e7978bc93b35c67ce7b9851e53a6f", GitTreeState:"clean", BuildDate:"2016-10-17T13:01:29Z", GoVersion:"go1.6.3", Compiler:"gc", Platform:"linux/amd64"}
Wed Nov 9 05:14:47 EST 2016
##Step 7: set weave-kube ...
daemonset "weave-net" created
[root@host31 k8s]#
添加节点
创建完MASTER之后,就可以向这个集群添加节点了,首先添加host32。
命令:sh easypack_kubernetes.sh NODE 77eddc.77edc19a7ade45d6 192.168.32.31
安装耗时:10分钟左右(基本上也是docker pull的时间,但是同时取决于你的网速和dockhub的状况)
安装参照:
[root@host32 k8s]# sh easypack_kubernetes.sh NODE 77eddc.77edc19a7ade45d6 192.168.32.31
Wed Nov 9 05:43:10 EST 2016
##INSTALL LOG : /tmp/k8s_install.10517.log
##Step 1: Stop firewall ...
Wed Nov 9 05:43:10 EST 2016
##Step 2: set repository and install kubeadm etc...
#######Set docker proxy when needed. If ready, press any to continue...
Created symlink from /etc/systemd/system/multi-user.target.wants/kubelet.service to /etc/systemd/system/kubelet.service.
Wed Nov 9 05:44:04 EST 2016
##Step 3: pull google containers...
Now begin to pull images from liumiaocn
No.1 : kube-proxy-amd64:v1.4.1 pull begins ...
No.1 : kube-proxy-amd64:v1.4.1 pull ends ...
No.1 : kube-proxy-amd64:v1.4.1 rename ...
No.1 : kube-proxy-amd64:v1.4.1 untag ...
No.2 : kube-discovery-amd64:1.0 pull begins ...
No.2 : kube-discovery-amd64:1.0 pull ends ...
No.2 : kube-discovery-amd64:1.0 rename ...
No.2 : kube-discovery-amd64:1.0 untag ...
No.3 : kube-scheduler-amd64:v1.4.1 pull begins ...
No.3 : kube-scheduler-amd64:v1.4.1 pull ends ...
No.3 : kube-scheduler-amd64:v1.4.1 rename ...
No.3 : kube-scheduler-amd64:v1.4.1 untag ...
No.4 : kube-controller-manager-amd64:v1.4.1 pull begins ...
No.4 : kube-controller-manager-amd64:v1.4.1 pull ends ...
No.4 : kube-controller-manager-amd64:v1.4.1 rename ...
No.4 : kube-controller-manager-amd64:v1.4.1 untag ...
No.5 : kube-apiserver-amd64:v1.4.1 pull begins ...
No.5 : kube-apiserver-amd64:v1.4.1 pull ends ...
No.5 : kube-apiserver-amd64:v1.4.1 rename ...
No.5 : kube-apiserver-amd64:v1.4.1 untag ...
No.6 : pause-amd64:3.0 pull begins ...
No.6 : pause-amd64:3.0 pull ends ...
No.6 : pause-amd64:3.0 rename ...
No.6 : pause-amd64:3.0 untag ...
No.7 : etcd-amd64:2.2.5 pull begins ...
No.7 : etcd-amd64:2.2.5 pull ends ...
No.7 : etcd-amd64:2.2.5 rename ...
No.7 : etcd-amd64:2.2.5 untag ...
No.8 : kubedns-amd64:1.7 pull begins ...
No.8 : kubedns-amd64:1.7 pull ends ...
No.8 : kubedns-amd64:1.7 rename ...
No.8 : kubedns-amd64:1.7 untag ...
No.9 : kube-dnsmasq-amd64:1.3 pull begins ...
No.9 : kube-dnsmasq-amd64:1.3 pull ends ...
No.9 : kube-dnsmasq-amd64:1.3 rename ...
No.9 : kube-dnsmasq-amd64:1.3 untag ...
No.10 : exechealthz-amd64:1.1 pull begins ...
No.10 : exechealthz-amd64:1.1 pull ends ...
No.10 : exechealthz-amd64:1.1 rename ...
No.10 : exechealthz-amd64:1.1 untag ...
No.11 : kubernetes-dashboard-amd64:v1.4.1 pull begins ...
No.11 : kubernetes-dashboard-amd64:v1.4.1 pull ends ...
No.11 : kubernetes-dashboard-amd64:v1.4.1 rename ...
No.11 : kubernetes-dashboard-amd64:v1.4.1 untag ...
All images have been pulled to local as following
gcr.io/google_containers/kube-controller-manager-amd64 v1.4.1 ad7b34f5ecb8 11 days ago 142.4 MB
gcr.io/google_containers/pause-amd64 latest 19047b725e84 3 weeks ago 746.9 kB
gcr.io/google_containers/kube-apiserver-amd64 v1.4.1 4a76dd338dfe 4 weeks ago 152.1 MB
gcr.io/google_containers/kube-scheduler-amd64 v1.4.1 f9641959ec72 4 weeks ago 81.67 MB
gcr.io/google_containers/kube-proxy-amd64 v1.4.1 b47199222245 4 weeks ago 202.7 MB
gcr.io/google_containers/kubernetes-dashboard-amd64 v1.4.1 1dda73f463b2 4 weeks ago 86.76 MB
gcr.io/google_containers/kube-proxy-amd64 v1.4.0 1f6aa6a8c3dc 6 weeks ago 202.8 MB
gcr.io/google_containers/kube-apiserver-amd64 v1.4.0 828dcf2a8776 6 weeks ago 152.3 MB
gcr.io/google_containers/kube-controller-manager-amd64 v1.4.0 b77714f7dc16 6 weeks ago 142.2 MB
gcr.io/google_containers/kube-scheduler-amd64 v1.4.0 9ed70b516ca8 6 weeks ago 81.8 MB
gcr.io/google_containers/kube-discovery-amd64 1.0 c5e0c9a457fc 6 weeks ago 134.2 MB
gcr.io/google_containers/kubedns-amd64 1.7 bec33bc01f03 10 weeks ago 55.06 MB
gcr.io/google_containers/kube-dnsmasq-amd64 1.3 9a15e39d0db8 4 months ago 5.126 MB
gcr.io/google_containers/pause-amd64 3.0 99e59f495ffa 6 months ago 746.9 kB
Wed Nov 9 05:52:49 EST 2016
Wed Nov 9 05:52:49 EST 2016
##Step 4: kubeadm join
Running pre-flight checks
<util/tokens> validating provided token
<node/discovery> created cluster info discovery client, requesting info from "http://192.168.32.31:9898/cluster-info/v1/?token-id=77eddc"
<node/discovery> cluster info object received, verifying signature using given token
<node/discovery> cluster info signature and contents are valid, will use API endpoints [https://192.168.32.31:6443]
注意:此处有可能被卡,比如此host的时间日期和Master都不一致等会导致被卡,其他被卡被坑的情况可以参照Master或者另外一片文章的整理。
<node/bootstrap> trying to connect to endpoint https://192.168.32.31:6443
<node/bootstrap> detected server version v1.4.1
<node/bootstrap> successfully established connection with endpoint https://192.168.32.31:6443
<node/csr> created API client to obtain unique certificate for this node, generating keys and certificate signing request
<node/csr> received signed certificate from the API server:
Issuer: CN=kubernetes | Subject: CN=system:node:host32 | CA: false
Not before: 2016-11-09 10:49:00 +0000 UTC Not After: 2017-11-09 10:49:00 +0000 UTC
<node/csr> generating kubelet configuration
<util/kubeconfig> created "/etc/kubernetes/kubelet.conf"
Node join complete:
* Certificate signing request sent to master and response
received.
* Kubelet informed of new secure connection details.
Run "kubectl get nodes" on the master to see this machine join.
Wed Nov 9 05:52:55 EST 2016
##Step 5: confirm version...
kubeadm version: version.Info{Major:"1", Minor:"5+", GitVersion:"v1.5.0-alpha.1.409+714f816a349e79", GitCommit:"714f816a349e7978bc93b35c67ce7b9851e53a6f", GitTreeState:"clean", BuildDate:"2016-10-17T13:01:29Z", GoVersion:"go1.6.3", Compiler:"gc", Platform:"linux/amd64"}[root@host32 k8s]#
结果确认
使用kubectl get nodes在Master上即可查看出集群的构成
[root@host31 k8s]# kubectl get nodes
NAME STATUS AGE
host31 Ready 42m
host32 Ready 17m
host33 Ready 3m
host34 Ready 5m
[root@host31 k8s]#
什么是Deployment
在Kubernetes中,Deployment是用来负责创建和更新应用程序实例的
为什么要容器化
在Kubernetes中,为了能够被部署,应用程序需要被打包成为其所支持的容器格式(docker/rkt)
Kubernetes Deployment
我们创建了一个具有3个node的kubernetes集群.
有了这个集群,接下来我们就可以把容器化了的应用部署到其中了。
首先,我们要创建一个kubernetes的Deployment。这个Deployment是用来负责创建和更新我们应用程序实例的。
而一旦这个应用创建好了之后,Kubernetes的Master会协调在集群的哪个node上俩创建应用实例。
而一旦应用实例被创建之后,Kubernetes的Deployment Controller就会持续的监视这些应用实例。
一旦发生机器故障或者其他不可预知的情况导致应用实例停止时,一直在监视的Deployment Controller就立即知道这一情况,然后它就会重新生成新的应用实例
Kubernetes提供了这种在故障发生时的自愈机制,这个机制也是使用Kubernetes提案的时候反复被背书的能力。
创建Deployment
可以使用Kubernetes的命令行接口kubectl,kubectl只安装在Master上,通过使用kubernetes的API与集群进行交互。
确认版本
命令:kubectl version。 其实我们在安装完成的时候如果你还有印象的话就会记得已经用过这条命令了,其结果显示如下,client和Server均为1.4.1版本
[root@host31 ~]# kubectl version
Client Version: version.Info{Major:"1", Minor:"4", GitVersion:"v1.4.1", GitCommit:"33cf7b9acbb2cb7c9c72a10d6636321fb180b159", GitTreeState:"clean", BuildDate:"2016-10-10T18:19:49Z", GoVersion:"go1.6.3", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"4", GitVersion:"v1.4.1", GitCommit:"33cf7b9acbb2cb7c9c72a10d6636321fb180b159", GitTreeState:"clean", BuildDate:"2016-10-10T18:13:36Z", GoVersion:"go1.6.3", Compiler:"gc", Platform:"linux/amd64"}
[root@host31 ~]#
确认构成
命令:kubectl get nodes。 通过这条命令我们可以确认到此集群的构成以及各组成node的状态是否都是ready
[root@host31 ~]# kubectl get nodes
NAME STATUS AGE
host31 Ready 2h
host32 Ready 1h
host33 Ready 1h
host34 Ready 1h
[root@host31 ~]#
创建Deployment
事前准备
可以使用kubectl run的方式创建也可以使用yaml文件+kubectl create的方式进行创建。本次我们采用后者。首先下载一下kubernetes-dashboard.yaml。而这个文件和easypack_kubernetes.sh在同级目录,上篇文章中在git clone取得的时候已经在本地了。
[root@host31 k8s]# pwd
/root/easypack/k8s
[root@host31 k8s]# ls
easypack_kubernetes.sh kubernetes-dashboard.yaml README.md
[root@host31 k8s]#
此文件根官方最新文件的不同点仅在于其版本号我们使用的是前面下载下来的1.4.1,现在最新应该已经是1.4.2了。另外还有一点就是imagePullPolicy我们从Always修改成IfNotPresent了。不然,无论如何它都回去pull这个镜像,网络有不允许,基本上kubernetes1.4的安装和使用就只有和这点相关的有些小坑,体验真心不错。
创建
命令: kubectl create -f kubernetes-dashboard.yaml
[root@host31 k8s]# kubectl create -f kubernetes-dashboard.yaml
deployment "kubernetes-dashboard" created
service "kubernetes-dashboard" created
[root@host31 k8s]#
可以看到「deployment “kubernetes-dashboard” created」的提示信息,这表明已经成功创建了一个Deployment,同时还有一个service也被创建出来了,至于service在Kubernetes中扮演什么角色, 后续的文章中会专门讲解,此处不再赘述。
确认Deployment
get deployments
使用kubectl get deployments可以列出当前的Deployment及其他信息
[root@host31 k8s]# kubectl get deployments --namespace=kube-system
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
kube-discovery 1 1 1 1 2h
kube-dns 1 1 1 1 2h
kubernetes-dashboard 1 1 1 1 3m
[root@host31 k8s]#
确认Dashboard
命令:kubectl describe svc kubernetes-dashboard –namespace=kube-system
使用此条命令可以确认出该service对外暴露出的可以访问的端口,通过此端口我们可以访问Kubernetes的Dashboard UI界面
[root@host31 k8s]# kubectl describe svc kubernetes-dashboard --namespace=kube-system
Name: kubernetes-dashboard
Namespace: kube-system
Labels: app=kubernetes-dashboard
Selector: app=kubernetes-dashboard
Type: NodePort
IP: 10.4.41.47
Port: <unset> 80/TCP
NodePort: <unset> 31276/TCP
Endpoints: 10.36.0.1:9090
Session Affinity: None
No events.[root@host31 k8s]#
注解:NodePort 31276 为此服务对外暴露的端口号,通过它和IP即可访问Kubernetes1.4的Dashboard了
访问URL:http://192.168.32.31:31276
namespace和node信息,可以清楚地看到其是由4台机器构成的kubernetes集群。
当然号称可以完成cli的90%功能的dashbaord不仅仅限于查看一下构成而已。详细使用方法可以自行探索,此处不再废话。
Pod
我们在前面讲到过node,node就是作为整个集群中的worker,它是和Master这个节点向比较的。而pod是什么呢,我们在上一篇文章中创建了一个dashboard的Deployment,这就是一个容器化了的应用被部署的实例。而Pod是kubernetes的一组应用容器的抽象,为什么要做这层抽象呢,容器间资源的共享。比如容器的Volume,在比如容器的port,如何在多个容器之间共享,docker-compose就是基于这个目的对docker机能的扩展和延伸。pod里面可以是单独的一个container也可以是多个。pod将一组耦合度很高的容器紧密地结合在一起作为一个整体的方式。比如我们在DevOps的Automation的时候很多项目都倒入了Sonarqube,sonarqube使用一个内部缺省的DB的话一个容器就解决问题,但是如果我们希望把数据能单独进行管理比如使用mysql或者mariadb等的话,我们至少可能需要2个容器,这个时候就可以使用一个pod把这两个都塞进去就可以了。
比如上图中的Pod4,我们就可以理解为有多个被容器化了的应用程序的组合,这些应用程序共享一个集群内部的IP10.10.10.4,共享内部的Volume。
Node
了解完pod之后,在来审视一下塞了pod的node吧。pod作为kubernetes上的最小单位,当我们创建一个kubernetes的Deployment的时候,Deployment其实也自然会使用所需的容器创建pod。通过kubernetes的分配,pod会与node建立联系。我们过去通过使用小机作双机双活等技巧在kubernetes面前显得非常无力,无论是从规模还是控制等,在这里死掉一个pod希望其自动恢复之需要调整它的重启策略,node发生故障的时候也可以在其他的node上自动启动该pod,而这些都可以调整。多年之前给客户做的Tuxedo+MC/SG等作的负载均衡和高可用的架构骄傲过几天,而从去年看到象kubernetes这样的神器的出现感到极其的悲伤和无力,又有很多技能和知识变成废纸了。在这里,所有需要做的已经没有什么了,调节一下参数的程度。
使用kubectl故障排查
我们已经使用过kubectl做过好多事情,在接下来的内容中我们将会进一步的使用kubectl来探寻我们已经部署到kubernetes上的应用,而这些将会是在使用kubernetes进行工作的时候故障排查和确认所会使用的最常用的命令。
命令 | 说明 |
---|---|
kubectl get | 诸如kubectl get nodes等等列出资源一览 |
kubectl describe | 对kubectl取到的信息进一步对某一resource进行更深入的确认 |
kubectl logs | 确认pod的某个container的log信息 |
kubectl exec | 类似于docker exec,可以在某个container中执行命令等 |
确认应用配置信息
我们在前面提到过创建Deployment会创建pod,接下来我们会使用kubectl get pods来进行确认
[root@host31 ~]# kubectl get pods --namespace=kube-system
NAME READY STATUS RESTARTS AGE
dummy-2088944543-rp84q 1/1 Running 0 6h
etcd-host31 1/1 Running 0 6h
kube-apiserver-host31 1/1 Running 0 6h
kube-controller-manager-host31 1/1 Running 0 6h
kube-discovery-982812725-t71i9 1/1 Running 0 6h
kube-dns-2247936740-eez6o 3/3 Running 0 6h
kube-proxy-amd64-4jxh6 1/1 Running 0 5h
kube-proxy-amd64-5ahum 1/1 Running 0 6h
kube-proxy-amd64-6wql2 1/1 Running 0 5h
kube-proxy-amd64-qu4bs 1/1 Running 0 5h
kube-scheduler-host31 1/1 Running 0 6h
kubernetes-dashboard-3000474083-y1htc 1/1 Running 0 3h
weave-net-7tvvm 2/2 Running 0 5h
weave-net-q17ey 2/2 Running 0 5h
weave-net-uktxs 2/2 Running 0 6h
weave-net-y8zpe 2/2 Running 0 5h
[root@host31 ~]#
我们清楚地看到kubernetes-dashboard-3000474083-y1htc作为其中一个pod果然被生成了,接下来想进一步察看这个pod的话需要使用kubectl describe pods来进行了。
[root@host31 ~]# kubectl describe pods kubernetes-dashboard-3000474083-y1htc --namespace=kube-system
Name: kubernetes-dashboard-3000474083-y1htc
Namespace: kube-system
Node: host34/192.168.32.34
Start Time: Wed, 09 Nov 2016 07:37:22 -0500
Labels: app=kubernetes-dashboard
pod-template-hash=3000474083
Status: Running
IP: 10.36.0.1
Controllers: ReplicaSet/kubernetes-dashboard-3000474083
Containers:
kubernetes-dashboard:
Container ID: docker://f97b36f8de62d911356b20f3e8840c14b7ed11a35443a865ae78d79d439a7667
Image: gcr.io/google_containers/kubernetes-dashboard-amd64:v1.4.1
Image ID: docker://sha256:1dda73f463b239955d4cf94a9cd525ab5306bee0eb53c17534d3282bc50ae7aa
Port: 9090/TCP
State: Running
Started: Wed, 09 Nov 2016 07:37:24 -0500
Ready: True
Restart Count: 0
Liveness: http-get http://:9090/ delay=30s timeout=30s period=10s #success=1 #failure=3
Volume Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-852jy (ro)
Environment Variables: <none>
Conditions:
Type Status
Initialized True
Ready True
PodScheduled True
Volumes:
default-token-852jy:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-852jy
QoS Class: BestEffort
Tolerations: dedicated=master:Equal:NoSchedule
No events.[root@host31 ~]#
在这里我们看到了很多信息:Port/状态/ContainerID/Namespace等更细的信息。
关于其他kubectl相关的命令我们会在别的文章中展开,此处不再赘述。
Kubernetes Services
Pod在整个集群中有他们自己的惟一IP,但是这些IP是不对Kubernetes外部暴露的,换句话说,外部是无法直接访问它们的.
而且我们还需要考虑在使用的过程中,这些pod有可能会发生很多变化,被停止,被删除,被其他pod替换等,比如被删除之后IP就不存在了,如何访问呢?加之总体的pod的量可能会非常之大,因此我们需要一种方式让pod和应用能够自动的发现彼此.Kubernetes使用service的概念将pod分组,service是一个逻辑上的抽象层,然后在此基础上进行对外提供访问的接口同时使得负载均衡和服务发现变得可能.
了解Services:https://www.kubernetes.org.cn/kubernetes-services
Kubernetes支持如下LoadBalancer和NodePort两种方式对外提供服务访问
类型 | 说明 |
---|---|
LoadBalancer | 此种应用场景一般在于当部署kubernetes到云上得时候为最多。一般云服务商会提?
小编推荐
快速导航更多>>
|