系统学习Docker 践行DevOps理念 笔记(七)|容器编排Kubernetes
容器编排Kubernetes,是课程第九章的内容
1.Kubenetes简介
1.1为什么简写是k8s
因为kubernetes,k和s之间一共有8个字母
2.Minikube快速搭建K8S单节点环境
2.1配置K8S环境
- https://github.com/kelseyhightower/kubernetes-the-hard-way 这个是k8s的从头开始安装的方法
- https://github.com/kubernetes/minikube 这个是在本地跑一个最简单的k8s,只有一个节点。类似vagrant,是要借助virtual box这种的
2.2安装kubetcl
https://kubernetes.io/docs/tasks/tools/install-kubectl/
2.3minikube
minikube相关命令:
- minikube start,启动minikube节点
- minikube ssh,连接到minikube内部
- minikube stop
2.4kubectl
kubectl context:
里面存着一个kubernetes集群的信息,比如集群的host。kubectl下可能有多个context,我们可以通过context去管理多个k8s集群
相关命令:
- kubectl config view
- kubectl config get-contexts,得到现在是用的哪个context
- kubectl cluster-info,得到集群信息
- kubectl version
3.K8S最小调度单位Pod
k8s不对容器进行操作,因为最小单位是pod。同一个pod里面的容器,是在一个namespace下的,这里的namespace包括所有的namespace(如network namespace)
相关命令:
- kubectl create -f pod_nginx.yml,创建pod
- kubectl delete -f pod_nginx.yml,删除pod
- kubectl get pods,查看pods的情况
- kubectl get pods -o wide,加了wide参数之后,会显示更多信息
- 上面的命令,可以看到pod里面的容器具体是在哪个机器上的,要进入这个容器,我们先ssh到这个机器上,然后docker exec -it container_name sh,
- kubectl describe pods nginx,查看pods的具体信息
- kubectl port-forward nginx 8080:80,映射本地的8080端口和pod的80端口,nginx是pod name,但是要注意的是,这个命令一旦ctrl+c退出,映射就结束了。8080端口是运行了kubectl的机器的端口,不是pod所在的容器的端口。
pod_nginx.yml:
|
|
NOTICE
kubectl create之后,可能pod会一直不启动,这个时候可以通过minikube logs查看错误日志。我遇到的问题的是不能拉取镜像,是要翻墙的网址。 解决这个问题可以在启动minikube的时候,指定代理:
|
|
参考资料:https://github.com/kubernetes/minikube/blob/master/docs/http_proxy.md
4.ReplicaSet和ReplicationController
ReplicaSet是新一代的ReplicationController。这里的replica就是我们之前docker里面遇到的是一样的。也是多个,这里就是多个pod。下面简称rc或者rs
相关命令:
- kubectl create -f rc_nginx.yml,创建replicationController,rc_nginx.yml见docker_labs
- kubectl get rc,可以查看rc的情况
- kubectl get pods,查看pod的情况
- kubectl delete pods nginx-6cznp,删除这个一个pod
- kubectl scale rc nginx –replicas=2,修改rc的pod数量
- kubectl delete rc nginx,删除replicationController -kubectl create -f rs_nginx.yml,创建replicaSet,ns_nginx.yml见docker-labs
- kubectl get rs,查看rs的情况
- kubectl scale rs nginx –replicas=2,对rs进行scale
rc_nginx.yml:
|
|
rs_nginx.yml:
|
|
NOTICE
要是我们在rc或者rs下创建pod,然后我们去强制删除这个pod,删除之后,rc和rs会自动再去创建一个pod。rc和rs会保持pod的数量,所以就算只创建一个pod,也推荐使用rc或者rs。因为这会保持pod的数量。
5.Deployment
Deployment描述了一种希望的状态,是对pods和replicaset的希望达到的一个状态。比如我希望这个replicaset是有3个replica的,pods的image是nginx。之后我们要修改的话,只要把希望的状态改变,deployment就会自动帮我们完成。 需要注意的是,我们通过deployment创建的replicaset和pod,创建了之后,我们就不能独立的对replicaset和pod进行删除了,我们一定要对deployment进行操作
相关命令:
- kubectl create -f deployment_nginx.yml,创建deployment,详见docker-lab
- kubectl get deployment,得到deployment的情况
- kubectl get deployment -o wide,得到详细情况
- kubectl set image deployment nginx-deployment nginx=nginx:1.13,更新镜像,nginx-deployment是deployment的name,nginx:1.13是新的镜像
- kubectl rollout history deployment nginx-deployment,查看deployment的历史版本
- kubectl rollout undo deployment nginx-deployment,撤销之前的操作,比如我们先更新了一个镜像,然后我们使用undo,就会变回原来的镜像了
- kubectl get node -o wide,查看k8s node的情况
- kubectl expose deployment nginx-deployment –type=NodePort,会暴露到node的一个随机端口上,是暴露到最终运行pod的机器上,不是运行kubectl的机器上,具体可以看9-8
- kubectl get services,查看services的情况,因为我们用了8的命令,所以service会随机一个端口绑定到容器的80端口。是绑定到最终运行pod的node上的,不是运行kubectl的机器
- kubectl delete service nginx-deployment,删除service
deployment_nginx.yml:
|
|
NOTICE
deployment下的replicaset和pods的name,replicaset的前缀是deployment的name,pods的name的前缀是replicaset的name
6.使用Tectonic在本地搭建多节点K8S集群
tectonic的脚本详见docker-lab,要注意的是,vagrant up的时候用的脚本,访问的基本都是被墙的网址,在脚本里面设置代理很麻烦,我最后是直接在路由器上安装了代理,才安装好。
相关命令:
- kubectl config get-contexts,查看kubectl的context
- kubectl config use-context tectonic,切换到tectonic这个context
NOTICE
我一开始用kubectl_1.11的版本使用命令kubectl get nodes的时候,会返回错误,然后我就用了kubectl的1.8这个版本,就正确了。
参考资料:https://github.com/kubernetes/kubernetes/issues/65575
7.k8s基础网络Cluster Network
这个flannel其实是一个k8s的网络插件,也可以不用flannel,可以用的别的网络插件。
k8s的网络插件,要符合最基本的3个规则,详见:
https://kubernetes.io/docs/concepts/cluster-administration/networking/
8.Service简介和演示
8.1不要直接使用和管理Pods
这里创建新的pods倒是没问题,但是最关键的是,新创建的pod可能ip会变。我们现在打个比方,我有两个pod,一个是nginx,还有一个是db,现在我db的pod被terminated然后创建了一个新的。这个时候要是db的ip变了,nginx是没办法修改的。所以我们需要用到service来解决这个问题,service就会给一个不变的ip和pod的ip相当于映射住,service的ip是不变的。那我们访问service的ip就可以了。然后我们要是用deployment这种,replica设成多个,我们可以在deployment上创建service,那么这个service会自动帮我们在多个replica之间做负载均衡。
8.2Service
本节课说的是ClusterIP的,这种service是在cluster内部,任何一台机器都可以访问的,但是也仅限于cluster内部
相关命令:
- kubectl expose pods nginx-pod,创建service,默认是ClusterIP
- kubectl get svc/services,svc是简写
- kubectl expose deployment service-test,在deployment上创建一个service,会为deployment里面的pods自动做负载均衡
- kubectl edit deployment service-test,这样可以更新service-test这个deployment的配置,然后k8s会帮我们自己更新
9.NodePort类型Service以及Label的简单实用
9.1NodePort类型Service
创建NodePort的service,有两种方式,一种用命令创建,一种是用yml文件来创建。 NodePort是可以给外网访问的,而且是集群内,所有node的ip加上这个service的port都可以访问。NodePort的端口是有范围的,是从30000-32767
用命令创建:
- kubectl create -f pod_nginx.yml,创建pod_nginx,yml见docker-lab
- kubectl expose pods nginx-pod –type=NodePort,创建NodePort的service
- kubectl get svc,查看创建的sevice,注意,在service我们会看到NodePort类型的service,会随机一个端口映射到pod的端口。这个时候所有node的ip+这个端口,就可以访问pod
用文件创建:
pod_nginx.yml:
|
|
service_nginx.yml
|
|
- targetPort后面要跟pod的yml文件里面的ports下的name
- selector后面的值是label的key和value,通过这个值去选择有这个label的pod去创建这个service
9.2Label
k8s里面,几乎所有的resource,如pod,deployment等等,我们都可以设置标签。比如我们可以指定nodeSelector,那么我们在创建pod的时候,就可以指定我们这个pod是要创建在哪个node上。
相关命令:
- kubectl label node w1.tectonicsandbox.com hardware=good,这个就是给w1这个node添加了一个label
- kubectl get node –show-labels,可以查看label
NOTICE
- 在生产环境里面,ClusterIP因为只能在cluster内部访问,外部是不能访问的,所以不会用。NodePort的端口又是有限的,所以一般也不会使用,但是是可以使用的。
- NodePort的端口是有范围的,是从30000-32767
10.准备工作——使用kops在亚马逊AWS上搭建k8s集群
kops: https://github.com/kubernetes/kops
11.使用kops在亚马逊AWS上搭建k8s集群
使用kops,在AWS创建k8s集群
12.LoadBlancer类型Service以及AWS的DNS服务配置
service里面还有一个类型是,loadblancer,这个类型是需要云服务商的支持的,本地是没法测试的。这个service会给出一个url,然后加上给出的端口就可以访问了。因为这个url会很长,所以我们还可以使用dns来添加ANAME来映射到一个短的sub domain
13.在亚马逊k8s集群上部署wordpress
略