环境说明
kubenetes:阿里云服务,版本v1.10.4
,三个master,一个node,我也不知道为啥阿里云设定master最少是3个,而node最少可以是1个…
服务器:阿里云Centos 7.4
部署服务
首先,我们先部署一个以dockhub最新nginx镜像为底的nginx。命令如下:kubectl run nginx-test --image=nginx:latest --port=80
。同理,再部署一个最新版redis的话,就是找葫芦画瓢:kubectl run redis-test --image=redis:latest --port=6379
。
两个命令敲完,这就给k8s下达了一个deployment(部署任务),可用kubectl get deployments
和kubectl get pods
命令查看:
可以看到现在已经生成了对应的pod,而pod里就是容器了,容器里就是对应的服务。如果想爬进这个容器看一下里面的文件等情况,命令是:kubectl exec -it nginx-test-bb95c4645-7qpbj bash
。
这里插播一下kubectl get deployment
里各参数的含义:
1
2
3
4DESIRED:对应.spec.replicas,用户设定的期望副本数
CURRENT:对应.status.replicas,目前运行的副本数
UP-TO-DATE:对应.status.updatedReplicas,包含最新的pod template的副本数
AVAILABLE:对应.status.availableReplicas,进入正常状态的副本数
但是现在这个服务是外网无法访问的,因为宿主机还没有一个端口与这个nginx容器的80端口相对应。所以要暴露一个端口给外部用于访问。命令是:kubectl expose deployment/kubernetes-bootcamp --type="NodePort" --port 80
,然后用kubectl get services
查看一下效果:
然后在对应的master和node里就看到宿主机随机分配的那个30497端口已经启动了,如图:
在浏览器上访问一下30497端口,果然可以访问到nginx服务:
扩容服务
服务嘛,总有高峰低谷。比如微博,突然爆出来哪个娱乐明星的新闻,肯定就会有大量的流量涌入,此时就需要扩容,那么k8s的扩容很简单,就是pod的复制,如果要把上面那个nginx-test的部署任务进行扩展,命令就是kubectl scale deployments/nginx-test --replicas=4
,如图:
可见nginx-test又生成了三个pod,与原来的组成了4个pod,而另一个redis的部署任务是没有变化的。
用kubectl get pods -o wide
可见,每一个pod分配到了不同的虚拟IP上,而且node都是阿里云的那台node服务器。
在阿里云控制台也能看到里面的情况:
此时进入到node节点,docker ps -a
就会看到新的nginx景象生成,同时也生成了三个/pause
的容器:
kubernetes中的pause容器主要为每个业务容器提供以下功能:
- 在pod中担任Linux命名空间共享的基础;
- 启用pid命名空间,开启init进程。
注意!目前kubernetes似乎仅仅支持共享网络,还不支持进程体系、文件系统之间的共享。如果此时在访问,就会看到访问会相对均匀的落到这四个pod中的每一个,起到一个负载均衡的作用。如果高峰期过了,不需要那么多pod了,就kubectl scale deployments/nginx-test --replicas=1
,pod就会恢复成1个,据我几次试验,每次都是保留最老的那一个pod。
yaml文件创建一个pod
K8s的yaml文件的文法和规矩,官方社区就有教程:https://www.kubernetes.org.cn/1414.html 。但是如果要搭配阿里云的私有镜像,需要先参考一下阿里云文档:https://help.aliyun.com/document_detail/86562.html 。注意,这个方法不能在命令行里使用,只能在yaml或者json里用。这里先写一个简单的nginx配置文件pod-nginx.yaml
做例子,全文如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20---
apiVersion: v1
kind: Pod
metadata:
name: aliyun-nginx
labels:
app: web
spec:
restartPolicy: Always #表明该容器一直运行,默认k8s的策略,在此容器退出后,会立即创建一个相同的容器
nodeSelector:
zone: node1 #节点选择
containers:
- name: aliyun-test-nginx
image: registry-vpc.cn-hangzhou.aliyuncs.com/lechangetest/chentest:1.1
imagePullPolicy: IfNotPresent #可选择Always、Never、IfNotPresent,即每次启动时检查和更新images的策略,IfNotPresent是节点上没有此nginx镜像时才执行pull操作
ports:
- containerPort: 80 #容器开发对外的端口
hostPort: 33664 #映射到主机的端口/对外映射的端口(一般可以不写)
imagePullSecrets:
- name: regsecret #这句话为了通过阿里云似有仓库的鉴权
保存退出,再kubectl create -f pod-redis.yaml
把这个文件执行一下。然后kubectl get pod
看一下效果:
发现我们创建那个redis-pod状态是Pending
(等待中),那就是不成功啊。于是就kubectl describe pod/pod-redis
查看一下原因,反馈如下:
这个错误的意思是“如果指定的label在所有node上都无法匹配,则创建Pod失败”。原来是我没有配置kubectl label nodes
,那先把pod-redis
删除,再把nodeSelector
那一段去掉,改成nodeName: cn-hangzhou.i-bp1978gmunq3oalfcqlx
,去掉再重新create一下。kubectl get pod
检查:
然后就是给这个pod增加一个对外的端口。kubectl expose pod/aliyun-nginx --type="NodePort" --port 80
,效果如下:
再去浏览器里,输入node的外网网址:31829
看看效果:
配置成功,当然这整个过程也可以在阿里云的控制台操作,更简单更直观,而且阿里云还会自动把对外端口配置到SLB里,具体步骤可以看阿里云的官方文档。
升级与回滚
假设我们把nginx-test
这个deployment的镜像升级成阿里云私有仓库的1.1版本,那么命令是:
1
kubectl set image deployments/nginx-test nginx-test=registry.cn-hangzhou.aliyuncs.com/lechangetest/chentest:1.1
升级之后,kubectl get pod
发现有几个节点不正常,如图:
那么这种情况下需要紧急回滚,回滚命令:
1
kubectl rollout undo deployment/nginx-test
一会就看到回滚成功了。如图:
参考资料
https://jimmysong.io/posts/what-is-a-pause-container/
https://blog.csdn.net/mailjoin/article/details/79686937
http://pipul.org/2016/05/why-we-need-the-pod-and-service-of-kubernetes/
https://www.imooc.com/article/30473