Kubernetes-提供服务的方式

目录

一. 直接访问Pod的IP地址

二. 通过Service访问

1. ClusterIP类型

2. NodePort类型

3. Ingress类型


一. 直接访问Pod的IP地址

Kubernetes中的最小单位是Pod,所有的应用也是运行在Pod中的

每个Pod都会被分配一个唯一的IP地址

创建一个Pod

cat nginx-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  labels:
    k8s-app: nginx-pod
  name: nginx-pod
spec:
  containers:
  - image: 172.16.2.100:30050/library/nginx:latest
    imagePullPolicy: Always
    name: nginx
    ports:
    - containerPort: 80
      name: nginx
      protocol: TCP

kubectl create -f nginx-pod.yaml

查看Pod的详细信息

[root@k8s-node1 example]# kubectl get pod -owide
NAME        READY   STATUS    RESTARTS   AGE   IP             NODE        NOMINATED NODE   READINESS GATES
nginx-pod   1/1     Running   0          26s   172.17.76.14   k8s-node2   <none>           <none>

可以看到该Pod分配一个IP地址,在另一个容器中可以正常访问该地址

[root@k8s-node1 ~]# kubectl --namespace=admin exec -it lnbkobka-session-jzqnd bash
[root@lnbkobka-session-jzqnd ~]# curl 172.17.76.14
<p>Hello Nginx</p>

(这种方式基本上不使用)

Pod的IP地址是一个随机分配的内网地址,只能在容器内部访问

并且正常场景下为了保证服务的可用性会通过deployment(statefulset)等来创建Pod,保证Pod的数量,而不会单独创建Pod

二. 通过Service访问

应为Pod是最小的单元如果在Pod中容器出现异常终止了是不会重启,在实际使用场景下基本不会直接使用Pod而是使用Deployment部署自己的应用

Deployment是对一组Pod集群的管理,可以保证环境中一直存在指定数量的Pod(比如当pod所在的node节点关机,则deployment会在其他节点重新启动Pod)

创建deployment

[root@k8s-node1 example]# cat nginx-dp.yaml
apiVersion: extensions/v1beta1
kind: Deployment
metadata:
  labels:
    k8s-app: nginx-dp
  name: nginx-dp
spec:
  replicas: 2  // 表示当前deployment有2个副本
  selector:
    matchLabels:
      k8s-app: nginx-dp
  template:
    metadata:
      labels:
        k8s-app: nginx-dp
    spec:
      containers:
      - image: nginx:latest
        name: nginx
        ports:
        - containerPort: 80
          name: nginx
          protocol: TCP

查看deployment

[root@k8s-node1 example]# kubectl get deployments
NAME       READY   UP-TO-DATE   AVAILABLE   AGE
nginx-dp   2/2     2            2           8s

// 查看Pod信息
[root@k8s-node1 example]# kubectl get pod -owide
NAME                        READY   STATUS    RESTARTS   AGE   IP             NODE        NOMINATED NODE   READINESS GATES
nginx-dp-78c4f884c8-qwh8m   1/1     Running   0          20s   172.17.86.12   k8s-node1   <none>           <none>
nginx-dp-78c4f884c8-sbvzz   1/1     Running   0          20s   172.17.76.14   k8s-node2   <none>           <none>

可以看到该Deployment下有2个Pod分别运行在两个Node节点上

手动删除一个Pod

[root@k8s-node1 example]# kubectl delete pod nginx-dp-78c4f884c8-qwh8m
pod "nginx-dp-78c4f884c8-qwh8m" deleted

[root@k8s-node1 example]# kubectl get pod -owide
NAME                        READY   STATUS    RESTARTS   AGE   IP             NODE        NOMINATED NODE   READINESS GATES
nginx-dp-78c4f884c8-n4czv   1/1     Running   0          14s   172.17.86.12   k8s-node1   <none>           <none>
nginx-dp-78c4f884c8-sbvzz   1/1     Running   0          96s   172.17.76.14   k8s-node2   <none>           <none>

可以看到删除Pod后又自动创建了一个Pod(对于Deployment管理还可以进行Pod扩容,升级等操作)

从上面可以看到deployment只负责Pod的管理,本身并没有IP地址,但是deployment下会存在多个Pod,每个Pod的地址都不一样,如果存在扩容等操作后,扩容的Pod的地址也是随机生成的,不可能记住所有的Pod的地址

Kubernete Service 是一个定义了一组Pod的策略的抽象,我们也有时候叫做宏观服务。这些被服务标记的Pod都是(一般)通过label Selector决定的,举个例子,我们假设有一个tomcat的应用,通过deployment部署,有三个副本。对于需要调用tomcat服务的应用(比如nginx)来说,不需要关注这个tomcat有几个pod,而是通过一个固定的地址访问,当tomcat的pod发生变化时,nginx不需要关注,使用固定的地址仍然可用继续访问

Service根据使用方式有几种类型

1. ClusterIP类型

创建一个service

[root@k8s-node1 example]# cat nginx-svc.yaml 
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc
spec:
  ports:
  - name: nginx
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    k8s-app: nginx-dp
  type: ClusterIP


[root@k8s-node1 example]# kubectl create -f nginx-svc.yaml 
service/nginx-svc created

查看Service信息,可用看到service分配了一个cluster-ip

[root@k8s-node1 example]# kubectl get service nginx-svc 
NAME        TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
nginx-svc   ClusterIP   10.10.207.26   <none>        80/TCP    10s

在其他容器中访问clusterIP

[root@k8s-node1 ~]# kubectl --namespace=admin exec -it lnbkobka-session-jzqnd bash
[root@lnbkobka-session-jzqnd ~]# curl 10.10.207.26
<p>Hello Nginx</p>

可用看到通过clusterip访问也可以正常访问,但是clusterip仍然是内网IP,只能通过容器内部访问(也可以直接通过service-name访问,k8s内部会自动进行域名解析)

这种方式一般适用于不需要对外的服务,比如mysql,redis等

 

2. NodePort类型

nodeport类型的service和clusterip相比多了一个nodeport属性,会在所有的node节点开放nodeport端口,通过访问物理机的端口达到访问容器的效果

创建nodeport类型的service(service yaml中可以手动定义nodeport,范围在30000-32767,不过这种方式容易冲突,不定义的话kubernetes会自动生成一个)

[root@k8s-node1 example]# cat nginx-svc-nodeport.yaml 
apiVersion: v1
kind: Service
metadata:
  name: nginx-svc-nodeport
spec:
  ports:
  - name: nginx
    port: 80
    protocol: TCP
    targetPort: 80
  selector:
    k8s-app: nginx-dp
  type: NodePort

[root@k8s-node1 example]# kubectl create -f nginx-svc-nodeport.yaml 
service/nginx-svc-nodeport created

[root@k8s-node1 example]# kubectl get service nginx-svc-nodeport 
NAME                 TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
nginx-svc-nodeport   NodePort   10.10.133.76   <none>        80:32117/TCP   14s

查看service可以看到多了一个32117的端口,在物理机上查看该端口的状态,可以看到在监听中

[root@k8s-node1 example]# lsof -i:32117
COMMAND     PID USER   FD   TYPE    DEVICE SIZE/OFF NODE NAME
kube-prox 27278 root   33u  IPv6 120151742      0t0  TCP *:32117 (LISTEN)

在物理机上访问物理机IP:NodePort,可以看到在物理机上通过nodeport已经可以访问到容器的服务

[root@k8s-node1 example]# curl 127.0.0.1:32117
<p>Hello Nginx</p>

由于nodeport会在每个节点上进行监听,所以任意一个nodeip+nodeport都可以访问

在实际环境中,我们一般会使用keepalived对node节点做vip,通过vip访问,或者单独搭建一个nginx,通过nginx进行负载均衡

3. Ingress类型

执行 `kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.5.0/aio/deploy/recommended.yaml` 命令后输出信息的含义如下: ```plaintext namespace/kubernetes-dashboard created serviceaccount/kubernetes-dashboard created service/kubernetes-dashboard created secret/kubernetes-dashboard-certs created secret/kubernetes-dashboard-csrf created secret/kubernetes-dashboard-key-holder created configmap/kubernetes-dashboard-settings created role.rbac.authorization.k8s.io/kubernetes-dashboard created clusterrole.rbac.authorization.k8s.io/kubernetes-dashboard created rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created clusterrolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created deployment.apps/kubernetes-dashboard created service/dashboard-metrics-scraper created deployment.apps/dashboard-metrics-scraper created ``` - `namespace/kubernetes-dashboard created`:创建了一个名为 `kubernetes-dashboard` 的命名空间,用于隔离 Kubernetes Dashboard 相关的资源。 - `serviceaccount/kubernetes-dashboard created`:在 `kubernetes-dashboard` 命名空间中创建了一个名为 `kubernetes-dashboard` 的服务账户,用于 Kubernetes Dashboard 与集群进行交互。 - `service/kubernetes-dashboard created`:创建了一个名为 `kubernetes-dashboard` 的服务,用于暴露 Kubernetes Dashboard 的应用。 - `secret/kubernetes-dashboard-certs created`:创建了一个名为 `kubernetes-dashboard-certs` 的密钥,用于存储 Kubernetes Dashboard 的证书。 - `secret/kubernetes-dashboard-csrf created`:创建了一个名为 `kubernetes-dashboard-csrf` 的密钥,用于防止跨站请求伪造(CSRF)攻击。 - `secret/kubernetes-dashboard-key-holder created`:创建了一个名为 `kubernetes-dashboard-key-holder` 的密钥,用于存储一些关键信息。 - `configmap/kubernetes-dashboard-settings created`:创建了一个名为 `kubernetes-dashboard-settings` 的配置映射,用于存储 Kubernetes Dashboard 的配置信息。 - `role.rbac.authorization.k8s.io/kubernetes-dashboard created`:在 `kubernetes-dashboard` 命名空间中创建了一个名为 `kubernetes-dashboard` 的角色,用于定义对命名空间内资源的访问权限。 - `clusterrole.rbac.authorization.k8s.io/kubernetes-dashboard created`:创建了一个名为 `kubernetes-dashboard` 的集群角色,用于定义对整个集群资源的访问权限。 - `rolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created`:在 `kubernetes-dashboard` 命名空间中创建了一个名为 `kubernetes-dashboard` 的角色绑定,将服务账户与角色进行绑定。 - `clusterrolebinding.rbac.authorization.k8s.io/kubernetes-dashboard created`:创建了一个名为 `kubernetes-dashboard` 的集群角色绑定,将服务账户与集群角色进行绑定。 - `deployment.apps/kubernetes-dashboard created`:创建了一个名为 `kubernetes-dashboard` 的部署,用于管理 Kubernetes Dashboard 的 Pod。 - `service/dashboard-metrics-scraper created`:创建了一个名为 `dashboard-metrics-scraper` 的服务,用于暴露指标收集器的应用。 - `deployment.apps/dashboard-metrics-scraper created`:创建了一个名为 `dashboard-metrics-scraper` 的部署,用于管理指标收集器的 Pod。 ### 后续操作 #### 1. 检查资源状态 使用以下命令检查创建的资源状态: ```bash kubectl get all -n kubernetes-dashboard ``` 确保所有的 Pod 都处于 `Running` 状态。 #### 2. 配置访问方式 可以通过 NodePort 类型的 Service 从外部访问 Kubernetes Dashboard。编辑 `recommended.yaml` 文件,添加 `nodePort` 和 `type: NodePort` 配置: ```yaml --- kind: Service apiVersion: v1 metadata: labels: k8s-app: kubernetes-dashboard name: kubernetes-dashboard namespace: kubernetes-dashboard spec: ports: - port: 443 targetPort: 8443 nodePort: 30002 type: NodePort selector: k8s-app: kubernetes-dashboard ``` 保存修改后,再次应用配置文件: ```bash kubectl apply -f https://raw.githubusercontent.com/kubernetes/dashboard/v2.5.0/aio/deploy/recommended.yaml ``` #### 3. 创建访问令牌 为了登录 Kubernetes Dashboard,需要创建一个 Service Account 和对应的令牌。以下是创建 Service Account 和令牌的示例命令: ```bash kubectl create serviceaccount admin-user -n kubernetes-dashboard kubectl create clusterrolebinding admin-user-binding --clusterrole=cluster-admin --serviceaccount=kubernetes-dashboard:admin-user kubectl -n kubernetes-dashboard create token admin-user ``` 复制获取到的令牌,用于登录 Dashboard。 #### 4. 访问 Kubernetes Dashboard 在浏览器中输入 `https://<节点 IP>:30002`(30002 为之前配置的 `nodePort`),打开 Kubernetes Dashboard 登录页面。选择 `Token` 登录方式,粘贴之前获取的令牌,点击 `Sign in` 登录。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值