k8s部署nginx,了解Pod,ReplicationController,Service,Deployment等方式部署nginx
环境说明:
k8s:1.5.2
docker:1.13.1
nginx:1.15.4
上一篇博客专门讲了如何通过yum方式搭建k8s集群传送门
虽然现在yum方式搭建k8s集群有点过时了,但是yum方式搭建的k8s集群用来学习是完全足够的,后面有时间我会用kubeadmin方式重新搭建一套。
通过Pod方式部署nginx
编辑nginx-pod.yaml
#创建并且切换到工作目录,
vi nginx-pod.yaml
#---内容如下
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.15.4
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
hostPort: 80
#apiVersion跟k8s版本绑定,1.5.2用v1就完了
#kind是部署方式,先采用最简单的Pod
#指定了nginx镜像版本,以及镜像拉取策略——如果存在就不重新拉取
#指定了容器端口号以及映射主机的端口号
#然后通过kubectl命令创建pod运行nginx
kubectl create -f nginx-pod.yaml
kubectl get pods -o wide
#一直返回No resources found
解决执行kubectl get pods返回No resources found问题
vi /etc/kubernetes/apiserver
#找到”KUBE_ADMISSION_CONTROL="--admission_control=NamespaceLifecycle,NamespaceExists,LimitRanger,SecurityContextDeny,ServiceAccount,ResourceQuota"这一行去掉ServiceAccount,保存退出
# 重启此服务
systemctl restart kube-apiserver
删除旧的pod,然后重新运行pod
kubectl delete -f nginx-pod.yaml
kubectl create -f nginx-pod.yaml
kubectl get pods -o wide
#这个时候能返回pod信息了,但是状态一直是ContainerCreating
kubectl describe pod nginx
#能看到有报错信息,failed for registry.access.redhat.com/rhel7/pod-infrastructure:latest
解决pod无法运行,报failed for registry.access.redhat.com/rhel7/pod-infrastructure:latest问题
#证书问题,从网上下载并复制到对应目录即可
yum install python-rhsm-certificates
wget http://mirror.centos.org/centos/7/os/x86_64/Packages/python-rhsm-certificates-1.19.10-1.el7_4.x86_64.rpm
rpm2cpio python-rhsm-certificates-1.19.10-1.el7_4.x86_64.rpm | cpio -iv --to-stdout ./etc/rhsm/ca/redhat-uep.pem | tee /etc/rhsm/ca/redhat-uep.pem
还是老套路,删除旧的pod,然后重新运行pod
kubectl delete -f nginx-pod.yaml
kubectl create -f nginx-pod.yaml
kubectl get pods -o wide
#能看到如下信息,状态是Running,而且pod分配到了node02节点
[root@master working]# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
nginx 1/1 Running 0 32m 172.16.71.2 node02
#那么已知node02节点的ip是10.0.0.22,而且主机80端口映射到容器的80端口,就可以在浏览器输入http://10.0.0.22访问nginx了。
#也可以通过命令查看pod的ip地址,kubectl describe pod nginx
至此,通过Pod方式部署nginx已经完成了,但是k8s动态伸缩,回滚升级等等高级功能还需要用ReplicationController完成
通过ReplicationController方式部署nginx
编辑nginx-rc.yaml
vi nginx-rc.yaml
apiVersion: v1
kind: ReplicationController
metadata:
name: myweb
labels:
app: myweb
spec:
replicas: 2 #'//指定副本数为2'
selector:
app: myweb
template:
metadata:
labels:
app: myweb
spec:
containers:
- name: myweb
image: nginx:1.15.4
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
hostPort: 50080
#kind选择ReplicationController
#指定pod名称myweb,以及标签app:myweb
#spec.replicas指定创建2个pod
#spec.selector指定通过app:myweb这个标签判断副本在k8s中的数量,如果数量不够指定的2,那么就继续创建pod,如果多于指定的2,那么就会删除多余的,删除时优先删除最晚创建的
#指定模板
#指定主机的50080端口映射容器的80端口
#每个字段什么意思以及怎么赋值都可以通过k8s提供的命令查看
#查看explain命令提示
kubectl explain -h
#查看rc有哪些配置
kubectl explain rc
kubectl explain rc.spec
kubectl explain rc.spec.selector
kubectl explain rc.spec.template
kubectl explain rc.spec.template.spec
kubectl explain rc.spec.template.metadata
kubectl explain rc.spec.template.metadata.labels
动态伸缩
vi nginx-rc.yaml
#找到replicas,修改replicas的值,比如修改为3,保存退出
spec:
replicas: 3
kubectl apply -f nginx-rc.yaml
kubectl get pods -o wide
#可以看到如下信息,第三个myweb的pod已经在Running了
NAME READY STATUS RESTARTS AGE IP NODE
myweb-pc957 1/1 Running 0 18h 172.16.7.3 master
myweb-vqz83 1/1 Running 0 18h 172.16.13.2 node01
myweb-w71hq 1/1 Running 0 3m 172.16.71.3 node02
#把replicas值再改回2,重新执行apply命令,就又缩容到2了
kubectl apply -f nginx-rc.yaml
kubectl get pods -o wide
滚动升级和回滚
cp nginx-rc.yaml nginx-rc2.yaml
vi nginx-rc2.yaml
#修改为如下内容,name还有标签改成myweb2,nginx版本改成1.18.0,主机端口55080映射容器80端口
apiVersion: v1
kind: ReplicationController
metadata:
name: myweb2
labels:
app: myweb2
spec:
replicas: 3
selector:
app: myweb2
template:
metadata:
labels:
app: myweb2
spec:
containers:
- name: myweb2
image: nginx:1.18.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
hostPort: 55080
#升级
kubectl rolling-update myweb -f nginx-rc2.yaml --update-period=30s
#回滚
kubectl rolling-update myweb2 -f nginx-rc.yaml --update-period=1s
#升级过程中回滚
kubectl rolling-update myweb myweb2 --update-period=10s --rollback
myweb到myweb2的升级过程如下(副本数还是3):
- 先创建第一个myweb2的pod
- 第一个myweb2的pod运行成功且到30s了,关闭第一个myweb的pod,创建第二个myweb2的pod
- 第二个myweb2的pod运行成功且到30s后,依此类推
- 最后k8s集群中就只剩3个myweb2的pod
通过Service方式部署nginx
前提:通过ReplicationController部署的nginx已经存在于k8s集群中
编辑nginx-svc.yaml
apiVersion: v1
kind: Service
metadata:
name: myweb
spec:
type: NodePort
ports:
- port: 80
nodePort: 30000
targetPort: 80
selector:
app: myweb
#port指的是虚拟ip的端口,是kubeproxy访问端口
#nodePort指的是node节点的端口,可以提供外部访问,比如通过浏览器访问
#targetPort指的是pod容器的端口
#type选了NodePort,就是在任意节点都可以通过节点ip+nodePort访问,实际就是通过kubeproxy轮询对应pod
kubectl create -f nginx-svc.yaml
# k8s的3种ip地址
#node IP:节点的ip
#cluster IP:默认是10.254.0/16,固定的,提供负载均衡的功能,rr轮询,cluster IP是虚拟IP,仅供k8s内部访问,不能外部访问,自动关联pod ip
#pod IP:pod的容器ip地址
service的服务自动发现
kubectl scale rc myweb --replicas=4
#增加myweb的pod副本数量后,在svc会自动把新增的pod添加进去
通过Deployment部署nginx
rc控制pod的高可用,svc控制pod的外部访问,但是rc在做滚动升级的时候,由于标签的改动会导致svc短时间无法访问pod。此时就需要通过Deployment部署nginx。
编辑nginx-deployment.yaml
vim nginx-deployment.yaml
apiVersion: extensions/v1beta1
#通过yum安装的k8s版本较低,apiVersion只能用这个,后续考虑通过kubeadmin安装最新版本的k8s集群
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.15.4
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
#启动deployment
kubectl create -f nginx-deployment.yaml
#暴露端口
kubectl expose deployment nginx-deployment --port=80 --type=NodePort
#升级,直接编辑配置即可
kubectl edit deployment nginx-deployment
#回滚
kubectl rollout undo deployment nginx-deployment
#升级和回滚都是通过rs控制,ReplicationSet,升级时会多一条rs记录,回滚时恢复到原来的rs记录
#查看历史版本,但之前通过edit和rollout方式升级和回滚导致历史版本信息较少
kubectl rollout history deployment nginx-deployment
#先delete掉nginx deployment
kubectl delete deployment nginx-deployment
#重新运行nginx-deployment,加--record参数
kubectl run nginx-deployment --image=nginx:1.15.4 --replicas=3 --record
#升级版本
kubectl set image deploy nginx-deployment nginx-deployment=nginx:1.18.0
#查看历史版本
kubectl rollout history deployment nginx-deployment
#回滚指定版本
kubectl rollout undo deployment nginx-deployment --to-revision=1
deployment的优势,可以不依赖配置文件完成rc所有功能,而且支持pod升级过程中仍然高可用。