部署nginx服务
使用kubectl命令
kubectl run nginx-deployment --image=nginx:1.7.9 --replicas=2
使用配置文件
创建nginx.yaml
1 | apiVersion: apps/v1 |
kubectl apply -f nginx-deployment.yaml
配置文件中添加nginx服务配置
上面的配置文件,nginx的配置、html页面、日志在容器里,不方便修改和查看,下面设置挂载路径,将上述文件挂载到宿主机
1 | apiVersion: apps/v1 |
说明:
- 挂载的目录或文件需要先在宿主机上创建,其中nginx.conf从nginx容器中拷贝出来:
docker cp {container-name}:{container-path} {host-path}
(待补充)
更新nginx应用:kubectl apply -f nginx.yaml
创建Service
1 | apiVersion: v1 |
说明:
将Service的9000端口映射到Pod的80端口
nginx-svc被分配的cluster-ip 192.168.31.22 可通过该IP访问后端nginx Pod
kubectl describe service nginx-svc
查看nginx-svc与pod的关系Endpoints列举了两个Pod的IP和端口
进入Pod
docker exec -it {container_id} /bin/bash
,查看ip地址ip addr
Service的Cluster IP 是怎么映射到Pod IP 的?
通过iptables的转发规则,将流量转发到Pod上,Cluster的每个节点都配置了相同的iptables规则
iptables-save | grep nginx
其中,红框中两条规则:
- 如果Cluster内的Pod要访问nginx-svc,则允许;
- 其他源地址访问nginx-svc,跳转到规则KUBE-SVC-HL5LMXD5JFHQZ6LN
KUBE-SVC-HL5LMXD5JFHQZ6LN规则为:
0.5的概率跳转到KUBE-SEP-RSXKIBUPEFSC7MO6
否则跳转到KUBE-SEP-NHHTLNEICZVNVOWJ
下面是KUBE-SEP-RSXKIBUPEFSC7MO6与KUBE-SEP-NHHTLNEICZVNVOWJ的转发规则,即转发到后端Pod
综上:iptables将访问Service的流量转发到后端Pod,并使用类似轮询的负载均衡策略
只有集群内部的节点可以访问Service Cluster IP,比如在集群中,有服务A与B,A需要访问B,可以通过A的Service Cluster IP,但是这个IP是随机分配的,如果Service A销毁重建,B需要更改配置,很不方便
集群内访问nginx服务
通过Service的Cluster IP
通过DNS访问
当有新的Service创建,coredns会添加该Service的DNS记录,Cluster中的Pod可以通过{serviceName}.{namespace}访问Service
如:在一个临时的Pod中通过DNS访问nginx Service
kubectl run busybox --rm -it --image=busybox /bin/sh
wget {serviceName}.{namespace}:{servicePort}
由于namespace为default,故可以省略;其他namespace不可省略
nginx-svc.default.svc.cluster.local为完整域名
这样,服务B访问A,通过A的serviceName就可以了,即使重新创建A的Service,也不需要修改B的配置
集群外部访问nginx服务
外部用户如何访问nginx?
NodePort
Service绑定Cluster节点的静态端口对外提供服务,Cluster外部通过{NodeIP}:{NodePort}
,如master:31090
,node1:31090
如何将{NodeIP}:{NodePort}映射到Pod的?
使用iptabels,上面两条规则:当访问31090端口的请求转发到规则KUBE-SVC-HL5LMXD5JFHQZ6LN
KUBE-SVC-HL5LMXD5JFHQZ6LN 对Pod进行负载均衡
相关指令
动作 | 指令 |
---|---|
查看nginx的pods | kubectl get pods -n namespace |
查看发布的deployment详情 | kubectl describe deployment nginx -n namespace |
查看pod详情 | kubectl describe pod {pod_name} -n namespace |
删除pod | kubectl delete -n default pod nginx-deployment |
查询服务列表 | kubectl get services -n namespace |
查询服务详情 | kubectl describe service {deployment-name} -n namespace |
删除一个service服务 | kubectl delete services {deployment-name} -n namespace |
存在问题
- 挂载的路径和文件需要提前创建在宿主机,集群下无法确定在哪台机器上部署,不方便提前创建,如何解决?
- 访问集群中的任意节点都按照相同的iptables进行转发到某个Pod,即访问每个节点都有负载均衡的效果,那外部域名应该绑定哪个节点ip呢?还是通过一个nginx对Cluster中的节点做分发(防止节点挂机,不是做负载均衡)