快速创建一个可访问的服务

快速创建一个可访问的服务

1 创建一个 k8s 集群

安装 Docker Desktop,并在设置中开启Kubernetes 功能 Pasted image 20241014143603.png

这时,你会得到一个单节点的 k8s 集群

通过 kubectl get nodes 查看,会输出以下内容:

➜  qsk-book git:(main) ✗ kubectl get nodes
NAME             STATUS   ROLES           AGE   VERSION
docker-desktop   Ready    control-plane   14h   v1.30.2

现在启动了一个名为 docker-desktopcontrol-plane (控制面) 节点

2 将应用部署到 k8s

下载示例文件(示例文件是《Kubernetes 快速入门》一书的附带内容):

git clone https://github.com/nigelpoulton/qsk-book.git
cd qsk-book
ls -l 

# 输出内容
total 24
drwxr-xr-x 7 wudanyang 224 10 13 15:50 App
drwxr-xr-x 8 wudanyang 256 10 13 15:50 Appv1.1
-rw-r--r-- 1 wudanyang 509 10 14 13:04 deploy.yml
-rw-r--r-- 1 wudanyang 225 10 13 15:50 pod.yml
-rw-r--r-- 1 wudanyang 929 10 13 15:50 readme.md
-rw-r--r-- 1 wudanyang 509 10 13 15:50 rolling-update.yml
-rw-r--r-- 1 wudanyang 178 10 13 15:50 svc-cloud.yml
-rw-r--r-- 1 wudanyang 217 10 13 15:50 svc-local.yml

部署 Pod:

kubectl apply -f pod.yml
➜  qsk-book git:(main) ✗ kubectl get pods
NAME                          READY   STATUS    RESTARTS   AGE
first-pod                     1/1     Running   0          6s

查看部署的 Pod

kubectl describe pod first-pod

可以看到,现在 Pod 是运行中了,端口号监听的是 8080

Name:             first-pod
Namespace:        default
Priority:         0
Service Account:  default
Node:             docker-desktop/192.168.65.3
Start Time:       Mon, 14 Oct 2024 14:49:56 +0800
Labels:           project=qsk-book
Annotations:      <none>
Status:           Running
IP:               10.1.0.27
IPs:
  IP:  10.1.0.27
Containers:
  web-ctr:
    Container ID:   docker://d06da3abd9e749933edc798a99571e3540bf8a16059823a78e4483530157e323
    Image:          nigelpoulton/qsk-book:latest
    Image ID:       docker-pullable://nigelpoulton/qsk-book@sha256:ea4422925917a5d957aab20603bbd2521e811088dc68ca3f5703458966733d72
    Port:           8080/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Mon, 14 Oct 2024 14:50:00 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-j8kn6 (ro)
Conditions:
  Type                        Status
  PodReadyToStartContainers   True
  Initialized                 True
  Ready                       True
  ContainersReady             True
  PodScheduled                True
Volumes:
  kube-api-access-j8kn6:
    Type:                    Projected (a volume that contains injected data from multiple sources)
    TokenExpirationSeconds:  3607
    ConfigMapName:           kube-root-ca.crt
    ConfigMapOptional:       <nil>
    DownwardAPI:             true
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:
  Type    Reason     Age   From               Message
  ----    ------     ----  ----               -------
  Normal  Scheduled  16m   default-scheduler  Successfully assigned default/first-pod to docker-desktop
  Normal  Pulling    16m   kubelet            Pulling image "nigelpoulton/qsk-book:latest"
  Normal  Pulled     16m   kubelet            Successfully pulled image "nigelpoulton/qsk-book:latest" in 3.231s (3.231s including waiting). Image size: 193578060 bytes.
  Normal  Created    16m   kubelet            Created container web-ctr
  Normal  Started    16m   kubelet            Started container web-ctr

3 连接到应用

如果只是部署了一个应用,那么在外部是不能访问到这个应用的,因为它的网络只工作在 k8s 的内部

要想在外部访问应用,还得使用 Service 才行

使用 svc-local.yml 文件部署一个 Service 对象

➜  qsk-book git:(main) ✗ kubectl apply -f svc-local.yml
service/svc-local created
# 2022 version
apiVersion: v1
kind: Service
metadata:
  name: svc-local
spec:
  type: NodePort
  ports:
  - port: 8080
    protocol: TCP
    targetPort: 8080
    nodePort: 31111
  selector:
    project: qsk-book

配置文件的内容大概意思就是将 label 为 project: qsk-book 的应用的8080 端口映射到节点的 31111 端口,细节再去看书

➜  qsk-book git:(main) ✗ kubectl get svc
NAME         TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)          AGE
kubernetes   ClusterIP   10.96.0.1       <none>        443/TCP          15h
svc-local    NodePort    10.101.54.180   <none>        8080:31111/TCP   2m34s

访问 http://localhost:31111/

出现下面的情况,就代表访问通了

Pasted image 20241014152010.png

4 清理应用

kubectl delete pod first-pod

5 应用自我修复

自我修复需要一个新的对象:Deployment

kubectl apply -f deploy.yml
# 2022 version
apiVersion: apps/v1
kind: Deployment
metadata:
  name: qsk-deploy
spec:
  replicas: 5
  selector:
    matchLabels:
      project: qsk-book
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    metadata:
      labels:
        project: qsk-book
    spec:
      containers:
      - name: qsk-pod
        imagePullPolicy: Always
        ports:
        - containerPort: 8080
        image: nigelpoulton/qsk-book:1.1
➜  qsk-book git:(main) ✗ kubectl get deploy
NAME         READY   UP-TO-DATE   AVAILABLE   AGE
qsk-deploy   5/5     5            5           4h5m
➜  qsk-book git:(main) ✗ kubectl get pods
NAME                          READY   STATUS    RESTARTS   AGE
qsk-deploy-668c8bdb95-6cw5d   1/1     Running   0          141m
qsk-deploy-668c8bdb95-dgtx5   1/1     Running   0          140m
qsk-deploy-668c8bdb95-f97mk   1/1     Running   0          140m
qsk-deploy-668c8bdb95-qhzl4   1/1     Running   0          141m
qsk-deploy-668c8bdb95-xssrf   1/1     Running   0          141m

5.1 Pod 故障重新拉起

使用命令删除掉一个 pod,模拟有一个 pod 故障了

kubectl delete pod qsk-deploy-668c8bdb95-6cw5d

可以看到立刻有一个 pod 被创建

➜  qsk-book git:(main) ✗ kubectl get pods
NAME                          READY   STATUS              RESTARTS   AGE
qsk-deploy-668c8bdb95-6cw5d   1/1     Terminating         0          143m
qsk-deploy-668c8bdb95-dgtx5   1/1     Running             0          141m
qsk-deploy-668c8bdb95-f97mk   1/1     Running             0          141m
qsk-deploy-668c8bdb95-qbhtg   0/1     ContainerCreating   0          3s
qsk-deploy-668c8bdb95-qhzl4   1/1     Running             0          142m
qsk-deploy-668c8bdb95-xssrf   1/1     Running             0          142m

5.2 工作节点故障重新部署

本地没有多节点环境,所以无法模拟

具体现象是,如果故障节点上面有 2 个 pod,那么这 2 个 pod 会被部署到仍存在的节点上

如果节点机器提供者也有故障恢复,那么故障的节点会重新加入到 k8s 集群中,但是已经被迁移走的 pod 不会重新回来

6 应用扩缩容

修改 deploy.yml 将 replicas 修改成你想要的数量

重新执行: kubectl apply -f deploy.yml

扩容时,会重新创建新 pod

➜  qsk-book git:(main) ✗ kubectl get pods
NAME                          READY   STATUS              RESTARTS   AGE
qsk-deploy-668c8bdb95-dgtx5   1/1     Running             0          148m
qsk-deploy-668c8bdb95-f97mk   1/1     Running             0          149m
qsk-deploy-668c8bdb95-fxh4n   0/1     ContainerCreating   0          4s
qsk-deploy-668c8bdb95-hn5bq   0/1     ContainerCreating   0          4s
qsk-deploy-668c8bdb95-qbhtg   1/1     Running             0          7m8s
qsk-deploy-668c8bdb95-qhzl4   1/1     Running             0          149m
qsk-deploy-668c8bdb95-tj4wv   0/1     ContainerCreating   0          4s
qsk-deploy-668c8bdb95-xssrf   1/1     Running             0          149m

缩容时,会将多余的 pod 删掉(我发现都是删除的运行时间比较短的 pod)

➜  qsk-book git:(main) ✗ kubectl get pods
NAME                          READY   STATUS        RESTARTS   AGE
qsk-deploy-668c8bdb95-dgtx5   1/1     Running       0          149m
qsk-deploy-668c8bdb95-f97mk   1/1     Terminating   0          149m
qsk-deploy-668c8bdb95-fxh4n   1/1     Terminating   0          48s
qsk-deploy-668c8bdb95-hn5bq   1/1     Terminating   0          48s
qsk-deploy-668c8bdb95-qbhtg   1/1     Terminating   0          7m52s
qsk-deploy-668c8bdb95-qhzl4   1/1     Running       0          150m
qsk-deploy-668c8bdb95-tj4wv   1/1     Terminating   0          48s
qsk-deploy-668c8bdb95-xssrf   1/1     Running       0          150m

7 应用滚动更新

kubectl apply -f rolling-update.yml

rolling-update.yml 和 原来的配置的区别:

Pasted image 20241014154350.png

执行之后,会新创建一个新的 Pod,将老的 pod 删掉


本文总阅读量