我们学习语言第一个想法就是在环境搭建好了之后写一个Helloworld,我们学习如何在 k8s 上部署应用时,部署一个简单的 nginx,能够访问到它的配置页面。由于它五脏俱全,功能简单,无状态,可以当做 k8s 部署应用的 hello, world:
实验目的:
利用ingress-nginx暴露服务供外网访问,版本:0.30.0
实验步骤:
1,下载ingress-nginx安装配置文件
wget https://raw.githubusercontent.com/kubernetes/ingress-nginx/nginx-0.30.0/deploy/static/mandatory.yaml -O ingress-nginx.yaml
2,在ingress-nginx.yaml文件最后增加service的安装配置
---
apiVersion: v1
kind: Service
metadata:
name: ingress-nginx
namespace: ingress-nginx
labels:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
spec:
type: NodePort
ports:
- name: http
port: 80
targetPort: 80
nodePort: 30010
protocol: TCP
- name: https
port: 443
targetPort: 443
nodePort: 30011
protocol: TCP
selector:
app.kubernetes.io/name: ingress-nginx
app.kubernetes.io/part-of: ingress-nginx
3,安装ingress-nginx,安装了namespace,nginx-ingress-controller,ingress-nginx
kubectl apply -f ingress-nginx.yaml
输出:
namespace/ingress-nginx created
configmap/nginx-configuration created
configmap/tcp-services created
configmap/udp-services created
serviceaccount/nginx-ingress-serviceaccount created
Warning: rbac.authorization.k8s.io/v1beta1 ClusterRole is deprecated in v1.17+, unavailable in v1.22+; use rbac.authorization.k8s.io/v1 ClusterRole
clusterrole.rbac.authorization.k8s.io/nginx-ingress-clusterrole created
Warning: rbac.authorization.k8s.io/v1beta1 Role is deprecated in v1.17+, unavailable in v1.22+; use rbac.authorization.k8s.io/v1 Rolerole.rbac.authorization.k8s.io/nginx-ingress-role created
Warning: rbac.authorization.k8s.io/v1beta1 RoleBinding is deprecated in v1.17+, unavailable in v1.22+; use rbac.authorization.k8s.io/v1 RoleBindingrolebinding.rbac.authorization.k8s.io/nginx-ingress-role-nisa-binding created
Warning: rbac.authorization.k8s.io/v1beta1 ClusterRoleBinding is deprecated in v1.17+, unavailable in v1.22+; use rbac.authorization.k8s.io/v1 ClusterRoleBindingclusterrolebinding.rbac.authorization.k8s.io/nginx-ingress-clusterrole-nisa-binding createddeployment.apps/nginx-ingress-controller created
limitrange/ingress-nginx created
service/ingress-nginx created
4,查看安装结果:
1,namespace是k8s的命名空间,旨在对一组资源和对象创建一个抽象空间集合,比如可以用来将系统内部的对象划分为不同的项目组或用户组。常见的 pod, service, replication controller 和 deployment 等都是属于某一个 namespace 的(默认是 default);
2,pod是一组紧密关联的容器集合,Pod就是共享IPC、Network和UTS namespace,是K8S调度的基本单位。Pod 的设计理念是支持多个容器在一个 Pod 中共享网络和文件系统,可以通过进程间通信和文件共享这种简单高效的方式组合完成服务。这个容器就是ingress-nginx的控制器;
3,service是对一组提供相同功能的 Pods 的抽象,并为它们提供一个统一的入口。借助 Service,应用可以方便的实现服务发现与负载均衡,并实现应用的零宕机升级。Service 通过标签来选取服务后端,一般配合 Replication Controller 或者 Deployment 来保证后端容器的正常运行。这些匹配标签的 Pod IP 和端口列表组成 endpoints,由 kube-proxy 负责将服务 IP 负载均衡到这些 endpoints 上。Service有四种类型(ClusterIP,NodePort,LoadBalancer,ExternalName)为对外暴露的接口,说明了集群的机器均对外暴露30010和30011两个接口;
//查看namespace
kubectl get namespaces
NAME STATUS AGE
default Active 7d18h
ingress-nginx Active 22s
kube-node-lease Active 7d18h
kube-public Active 7d18h
kube-system Active 7d18h
kubernetes-dashboard Active 41h//查看pod
kubectl get pods -n ingress-nginx
NAME READY STATUS RESTARTS AGE
nginx-ingress-controller-54b86f8f7b-lghw4 1/1 Running 0 66s//查看service
kubectl get services -n ingress-nginx
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
ingress-nginx NodePort 10.1.64.186 <none> 80:30010/TCP,443:30011/TCP 75s
5,安装nginx pod并暴露80端口:
//nginx.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
# 指定 label,便于检索
labels:
app: nginx
spec:
containers:
- name: nginx
# 指定镜像
image: nginx:alpine
# 指定暴露端口
ports:
- containerPort: 80
//使用kubectl apply,部署 Pod
kubectl apply -f nginx.yaml
pod/nginx created
//校验部署状态,此时 STATUS 为 Running 表明部署成功
kubectl get pods nginx -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 43h 10.244.3.4 pcno4 <none> <none>
//获取更加详细的信息
kubectl describe pod nginx
Name: nginx
Namespace: default
Priority: 0
Node: pcno4/10.10.30.74
Start Time: Wed, 06 Jan 2021 15:16:28 +0800
Labels: app=nginx
Annotations: <none>
Status: Running
IP: 10.244.3.4
IPs:
IP: 10.244.3.4
Containers:
nginx:
Container ID: docker://fa7b8ef84d0c2cb9bc3c7bc1bab7e94912fecada7f901f762da3898a8bcf65cc
Image: nginx:alpine
Image ID: docker-pullable://nginx@sha256:c2ce58e024275728b00a554ac25628af25c54782865b3487b11c21cafb7fabda
Port: 80/TCP
Host Port: 0/TCP
State: Running
Started: Wed, 06 Jan 2021 15:16:47 +0800
Ready: True
Restart Count: 0
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from default-token-k9grl (ro)
Conditions:
Type Status
Initialized True
Ready True
ContainersReady True
PodScheduled True
Volumes:
default-token-k9grl:
Type: Secret (a volume populated by a Secret)
SecretName: default-token-k9grl
Optional: false
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations:
node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events: <none>
每个 pod 都有一个IP地址,直接访问IP地址获取内容
curl 10.244.3.4
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif;
}
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed andworking. Further configuration is required.</p>
<p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p>
<p><em>Thank you for using nginx.</em></p>
</body>
</html>
6,此时我们可以使用 kubectl exec 进入 Pod 的内部容器。如果 Pod 中有多个容器,使用 kubectl exec -c 指定容器
kubectl exec -it nginx sh
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead./ # vim /usr/share/nginx/html/index.html
//修改index.html文件改成自己希望加入的内容,然后退出重新使用curl命令查看
curl 10.244.3.4
#可以看到修改过的页面
//进入pod还可以查看网络情况,如下:
netstat -tan
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTENtcp 0 0 :::80 :::* LISTEN
wget -q -O - localhost
#可以看到页面文件内容
7,部署nginx至集群,在k8s中管理 Pod 的称作 Controller,我们可以使用 Deployment 这种 Controller 来为 Pod 进行扩容,当然它还可以滚动升级,回滚等等关于部署的事情,我们编写一个Deployment的资源配置文件
//nginxdelop.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
spec:
#定位需要管理的Pod
selector:
matchLabels:
app: nginx
#需要部署的个数
replicas: 3
#指定要部署的Pod
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:alpine
ports:
- containerPort: 80
//kubectl apply 部署生效后查看 Pod 以及 Deployment 状态
kubectl get pods -o wide -l 'app=nginx'
//nginx-deployment 部署的三个 pod 全部成功
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx 1/1 Running 0 46h 10.244.3.4 pcno4 <none> <none>
nginx-deployment-7fb7fd49b4-b6tcw 1/1 Running 0 46h 10.244.3.5 pcno4 <none> <none>
nginx-deployment-7fb7fd49b4-jxdx2 1/1 Running 0 46h 10.244.1.4 pcno5 <none> <none>
nginx-deployment-7fb7fd49b4-spxgr 1/1 Running 0 46h 10.244.1.5 pcno5 <none> <none>
//READY 3/3 表明全部部署成功
kubectl get deploy nginx-deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 3/3 3 3 46h
8,现在部署的这个nginx[pod],对应第二步里建立的ingress-nginx的service,这样就可以通过下面的渠道被访问了:
集群对外的ip(机器ip:10.10.30.76:80)--> ingress(ingress-nginx NodePort ClusterIP: 10.1.64.186:30010/30011) --> nginx-service(CluserIP:10.1.169.124:80) --> nginx-deployment(IP:10.244.1.4/1.5/3.5/
10.10.30.76:30010 --| |-> 10.244.1.4:80
[serive:NodePort:ingress-nginx] [pod:nginx-ingress-controller] [service:nginx-service]
| 10.1.64.186 | --> | 10.244.1.7:80 | --> | 10.1.169.124:80 |-> 10.244.1.5:80
10.10.30.75:30010 --| |-> 10.244.3.4:80
10.10.30.74:30010 --| |-> 10.244.3.5:80
9,最后可以通过集群外机器直接用ip访问(如果进入不同nginxpod机器修改不同的nginx主页,然后多次访问就能看出集群的负载均衡在自动调用不同的node处理)如下:
//编辑所有的pods,将内部部署的网页全部添加node和ip相关的信息
kubectl exec -it nginx sh #10.244.3.4 pcno4 根据第7步kubectl get pods -o wide -l 'app=nginx'命令的结果添加node和ip信息
kubectl exec -it nginx-deployment-7fb7fd49b4-jxdx2 sh #10.244.3.5 pcno4
kubectl exec -it nginx-deployment-7fb7fd49b4-b6tcw sh #10.244.1.4 pcno5
kubectl exec -it nginx-deployment-7fb7fd49b4-spxgr sh #10.244.1.5 pcno5//在外网访问,可以看到四个不同的node的信息
curl http://10.10.30.76(75|74):30010