K8S==springboot项目生成image部署到K8S

IDEA springboot新建helloword项目

http://localhost:30000/hello

1
2
3
4
5
6
7
8
9
10
11
12
package com.example.demohelloword.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {
    @RequestMapping("/hello")
    public String get() {
        return "hello world K8S============================================";
    }
}
1
2
server:
  port: 30000

打包成jar包

编写Dockerfile

1
2
3
4
FROM java:8-alpine
    COPY ./demo-helloword-0.0.1-SNAPSHOT.jar /tmp/app.jar
    EXPOSE 30000
    ENTRYPOINT java -jar /tmp/app.jar

将jar包和Dockerfile上传到自己用的linux,我这是阿里云的ECS,已经安装了DOCKER

上传完成后,

在jar包所在的目录下执行,镜像名字为 javaweb:1.0

1
docker build -t javaweb:1.0 .

根据镜像生成容器,并绑定端口

1
docker run --name demo -p 8847:30000 -d javaweb:1.0

防火墙和安全组开放端口8847

访问

http://118.31.120.118:8847/hello

1641216056724

将image推送到我的dockerhub仓库

先在我的linux上用dockerhub账号密码登录

docker login

1
2
3
4
5
6
7
8
9
[root@cenos812 ~]# docker login
Login with your Docker ID to push and pull images from Docker Hub. If you don't have a Docker ID, head over to https://hub.docker.com to create one.
Username: ldj1994
Password:
WARNING! Your password will be stored unencrypted in /root/.docker/config.json.
Configure a credential helper to remove this warning. See
https://docs.docker.com/engine/reference/commandline/login/#credentials-store

Login Succeeded

推送镜像的规范是:
docker push 注册docker用户名/REPOSITORY:TAG

先要打上dockerhub开头的用户名的tag,再push

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@cenos812 ~]# docker tag javaweb:1.0 ldj1994/javaweb:1.0
[root@cenos812 ~]# docker images;
REPOSITORY        TAG        IMAGE ID       CREATED          SIZE
ldj1994/javaweb   1.0        1aee65304364   10 minutes ago   163MB
javaweb           1.0        1aee65304364   10 minutes ago   163MB
java              8-alpine   3fd9dd82815c   4 years ago      145MB
[root@cenos812 ~]# docker push ldj1994/javaweb:1.0
The push refers to repository [docker.io/ldj1994/javaweb]
c63ed3f246c0: Pushed
a1e7033f082e: Pushed
78075328e0da: Pushed
9f8566ee5135: Pushed
1.0: digest: sha256:3b0e77dba1c727873bfdf2209d2aa3140342e884a418e304bec58ce90edba44e size: 1159

完成,能看到我的dockerhub仓库中已经有了镜像了。然后从k8s中调用这个镜像生成POD和service

1641217124532

=========================

使用上述镜像在K8S master中新建一个pod

kubectl create deployment javaweb --image=ldj1994/javaweb:1.0

kubectl expose deployment javaweb --port=30000 --type=NodePort

kubectl get pod,svc

kubectl describe pod javaweb-c9f868ff6-zpd5b

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
[root@master ~]# kubectl get pod,svc
NAME                          READY   STATUS              RESTARTS   AGE
pod/javaweb-c9f868ff6-zpd5b   0/1     ContainerCreating   0          3m57s
pod/nginx-86c57db685-hfws6    1/1     Running             0          6h25m

NAME                 TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)           AGE
service/javaweb      NodePort    10.105.115.0   <none>        30000:31669/TCP   3m20s
service/kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP           7h13m
service/nginx        NodePort    10.102.75.10   <none>        80:31519/TCP      6h25m
[root@master ~]# kubectl describe pod javaweb-c9f868ff6-zpd5b
Name:           javaweb-c9f868ff6-zpd5b
Namespace:      default
Priority:       0
Node:           node2/192.168.136.102
Start Time:     Mon, 03 Jan 2022 21:40:33 +0800
Labels:         app=javaweb
                pod-template-hash=c9f868ff6
Annotations:    cni.projectcalico.org/containerID: 65b9bc2149fa7878044d9df83fe909e50d218f55aab268d8d27cf29817090cf7
                cni.projectcalico.org/podIP: 10.244.104.3/32
                cni.projectcalico.org/podIPs: 10.244.104.3/32
Status:         Pending
IP:            
IPs:            <none>
Controlled By:  ReplicaSet/javaweb-c9f868ff6
Containers:
  javaweb:
    Container ID:  
    Image:          ldj1994/javaweb:1.0
    Image ID:      
    Port:           <none>
    Host Port:      <none>
    State:          Waiting
      Reason:       ContainerCreating
    Ready:          False
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-6kxt8 (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             False
  ContainersReady   False
  PodScheduled      True
Volumes:
  default-token-6kxt8:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-6kxt8
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  4m21s  default-scheduler  Successfully assigned default/javaweb-c9f868ff6-zpd5b to node2
  Normal  Pulling    4m20s  kubelet, node2     Pulling image "ldj1994/javaweb:1.0"
[root@master ~]#

可以看到K8S这个POD放在了node2上,所以在node2上能够看到镜像 ldj1994/javaweb 1.0

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@node2 ~]# docker images
REPOSITORY                                           TAG                 IMAGE ID            CREATED             SIZE
ldj1994/javaweb                                      1.0                 1aee65304364        30 minutes ago      163MB
nginx                                                latest              605c77e624dd        4 days ago          141MB
calico/node                                          v3.20.3             6570786a0fd3        5 weeks ago         183MB
calico/pod2daemon-flexvol                            v3.20.3             0631af1a04ae        5 weeks ago         21.7MB
calico/cni                                           v3.20.3             e9a8982d9e89        5 weeks ago         146MB
kubernetesui/dashboard                               v2.0.0              8b32422733b3        20 months ago       222MB
k8s.gcr.io/kube-proxy                                v1.17.4             6dec7cfde1e5        22 months ago       116MB
registry.aliyuncs.com/google_containers/kube-proxy   v1.17.4             6dec7cfde1e5        22 months ago       116MB
k8s.gcr.io/kube-controller-manager                   v1.17.4             7f997fcf3e94        22 months ago       161MB
k8s.gcr.io/kube-apiserver                            v1.17.4             2e1ba57fe95a        22 months ago       171MB
k8s.gcr.io/kube-scheduler                            v1.17.4             5db16c1c7aff        22 months ago       94.4MB
k8s.gcr.io/coredns                                   1.6.5               70f311871ae1        2 years ago         41.6MB
k8s.gcr.io/etcd                                      3.4.3-0             303ce5db0e90        2 years ago         288MB
quay.io/coreos/flannel                               v0.11.0-amd64       ff281650a721        2 years ago         52.6MB
k8s.gcr.io/pause                                     3.1                 da86e6ba6ca1        4 years ago         742kB
registry.aliyuncs.com/google_containers/pause        3.1                 da86e6ba6ca1        4 years ago         742kB
[root@node2 ~]#

等到master上看到service和pod启动完成后,如下,

1
2
3
4
5
6
7
8
9
10
[root@master ~]# kubectl get pod,svc
NAME                          READY   STATUS    RESTARTS   AGE
pod/javaweb-c9f868ff6-zpd5b   1/1     Running   0          7m13s
pod/nginx-86c57db685-hfws6    1/1     Running   0          6h28m

NAME                 TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)           AGE
service/javaweb      NodePort    10.105.115.0   <none>        30000:31669/TCP   6m36s
service/kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP           7h16m
service/nginx        NodePort    10.102.75.10   <none>        80:31519/TCP      6h28m
[root@master ~]#

访问查看结果 master/node1/node2的 IP+service端口31669

http://192.168.136.100:31669/hello

http://192.168.136.101:31669/hello

http://192.168.136.102:31669/hello

1641218202782

重启电脑,之前设置了kubectl自动启动,它管理的pod也会启动,直接访问就行了。

=============================================================================

删除service和pod,用yaml重新拉取镜像并启动pod,然后根据pod生成service管理pod,pod和service都在名称空间dev下.

先确认之前没有创建过

kubectl get pods,svc,deploy -n dev

有的话都delete

kubectl delete XXX -n dev

kubectl delete ns dev

创建名称空间

kubectl create ns dev

运行yaml创建pod和service,从MD拷贝YAML可能会少些东西,要注意核对

vim service-mypod.yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
---
apiVersion: apps/v1
kind: Deployment   #创建pod使用Deployment控制器
metadata:
  name: my-pod   #POD的名字叫做这个,service可以通过名字来调用
  namespace: dev  #所属的名称空间,之前已经创建了
spec:
  selector:
    matchLabels:  # Labels匹配规则,这里未指定具体规则 ,但是名字必须要和template中一样
      app: my-pod
  replicas: 1
  template:  # 模板,当副本数量不足时,会根据下面的模板创建pod副本
    metadata:
      labels:
        app: my-pod
    spec:
      containers:
      - name: my-pod
        image: ldj1994/javaweb:1.0   #基础镜像,就是之前用push到dockerhub的
        ports:
        - containerPort: 30000   #一般不写,防止端口冲突,一旦开启同一个主机只能启动镜像的一个容器,除非都改端口错开
---
apiVersion: v1
kind: Service
metadata:
  name: my-service
  namespace: dev
spec:
  ports:
  - port: 8999   # service端口
    nodePort: 32767 # 集群对外暴露该服务的端口,30000-32767,可以通过集群任意IP+nodeport访问到pod
    targetPort: 30000  # pod端口
  selector:
    app: my-pod
  type: NodePort
1
2
3
4
5
6
7
8
9
10
11
12
[root@master ~]# kubectl create -f service-mypod.yaml
deployment.apps/my-pod created
service/my-service created
[root@master ~]# kubectl get pods,svc,deploy -n dev
NAME                          READY   STATUS    RESTARTS   AGE
pod/my-pod-75ff4985b6-dzhwh   1/1     Running   0          69s

NAME                 TYPE       CLUSTER-IP       EXTERNAL-IP   PORT(S)          AGE
service/my-service   NodePort   10.110.132.205   <none>        8999:32767/TCP   69s

NAME                     READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/my-pod   1/1     1            1           69s

因为yaml中指定了集群暴露service时给分配的端口为32767,所以随便输入个IP+32767

http://192.168.136.101:32767/hello

成功

查看下该POD的详情

kubectl describe pod my-pod-75ff4985b6-dzhwh -n dev

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
[root@master ~]# kubectl describe pod my-pod-75ff4985b6-dzhwh -n dev
Name:         my-pod-75ff4985b6-dzhwh
Namespace:    dev
Priority:     0
Node:         node2/192.168.136.102
Start Time:   Tue, 04 Jan 2022 09:43:20 +0800
Labels:       app=my-pod
              pod-template-hash=75ff4985b6
Annotations:  cni.projectcalico.org/containerID: 96ff37be877356d6f30cb314b2e3ea54454f3dabbe4ad4f5f3876f895dd37837
              cni.projectcalico.org/podIP: 10.244.104.8/32
              cni.projectcalico.org/podIPs: 10.244.104.8/32
Status:       Running
IP:           10.244.104.8
IPs:
  IP:           10.244.104.8
Controlled By:  ReplicaSet/my-pod-75ff4985b6
Containers:
  my-pod:
    Container ID:   docker://933809cb3f7850d8c639d1dc82dca2aa1694c212f400638364299ff5190bb433
    Image:          ldj1994/javaweb:1.0
    Image ID:       docker-pullable://ldj1994/javaweb@sha256:3b0e77dba1c727873bfdf2209d2aa3140342e884a418e304bec58ce90edba44e
    Port:           30000/TCP
    Host Port:      0/TCP
    State:          Running
      Started:      Tue, 04 Jan 2022 09:43:22 +0800
    Ready:          True
    Restart Count:  0
    Environment:    <none>
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-w7dt9 (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  default-token-w7dt9:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-w7dt9
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type    Reason     Age        From               Message
  ----    ------     ----       ----               -------
  Normal  Scheduled  <unknown>  default-scheduler  Successfully assigned dev/my-pod-75ff4985b6-dzhwh to node2
  Normal  Pulled     18m        kubelet, node2     Container image "ldj1994/javaweb:1.0" already present on machine
  Normal  Created    18m        kubelet, node2     Created container my-pod
  Normal  Started    18m        kubelet, node2     Started container my-pod

 default-scheduler  Successfully assigned dev/my-pod-75ff4985b6-dzhwh to node2
  Normal  Pulled     18m        kubelet, node2     Container image "ldj1994/javaweb:1.0" already present on machine
  Normal  Created    18m        kubelet, node2     Created container my-pod
  Normal  Started    18m        kubelet, node2     Started container my-pod