如何让 pod 创建 运行 一个应用程序(命令和参数),同时有一个部署和服务引用它?

How to have the pod created run an application (command and args) and at the same time have a deployment and service referring to it?

上下文:
技术:Java,Docker 工具箱,Minikube。
我有一个 java 网络应用程序(已经打包为 web-tool.jar),我想要 运行 同时拥有 kubernetes 的所有好处。
为了指示 kubernetes 在本地拍摄图像 我使用图像标签:

docker build -t despot/web-tool:1.0 .

然后通过以下方式使其可用于 minikube:

docker save despot/web-tool:1.0 | (eval $(minikube docker-env) && docker load)

docker 文件 是:

FROM openjdk:11-jre
ADD target/web-tool-1.0-SNAPSHOT.jar app.jar
EXPOSE 1111
EXPOSE 2222

1.我怎样才能创建 pod,运行 java 应用程序,同时有一个部署和服务引用它?

1.1。我可以创建一个部署来在创建 pod 时传播命令和参数吗? (最适合我,因为我确保在创建 pod 之前创建部署和服务)
1.2.如果 1.1。不可行,我可以 kubectl 将一些带有命令和参数的 pod 配置应用到已经创建的 deployment/pod/service 吗? (更糟糕的解决方案是额外的手动步骤)
1.3.如果 1.2。不可行,是否可以创建一个 deployment/service 并将其附加到已经 运行ning 的 pod(以 "kubectl run ... java -jar app.jar reg" 开始)?

我试过的是:
a) 创建部署(自动启动 pod)并公开部署(创建服务):

kubectl create deployment reggo --image=despot/web-tool:1.0

有了这个,创建了一个具有 CrashLoopBackoff 状态的 pod,因为它还没有前台进程 运行ning。

b) 尝试了以下操作,希望部署接受将传播到 pod 创建 (1.1.) 的命令和参数:

kubectl create deployment reggo --image=despot/web-tool:1.0 -- java -jar app.jar reg

pod 的结果相同,因为部署不接受命令和参数。

c) 尝试在部署创建 pod 后使用命令和 args 应用 pod 配置,所以我 运行 来自 a) 的命令,找到了 pod 的 id (reggo-858ccdcddd-mswzs) with (kubectl get pods) 然后我执行了:

kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: reggo-858ccdcddd-mswzs
spec:
  containers:
  - name: reggo-858ccdcddd-mswzs
    command: ["java"]
    args: ["-jar", "app.jar", "reg"]
EOF

但我得到了:

Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply The Pod
"reggo-858ccdcddd-mswzs" is invalid:
* spec.containers[0].image: Required value
* spec.containers: Forbidden: pod updates may not add or remove containers

这让我觉得我无法通过应用 command/args 配置来执行命令。

解决方案(使用

kubectl apply -f - <<EOF
apiVersion: apps/v1
kind: Deployment
metadata:
  name: reggo
spec:
  selector:
    matchLabels:
      app: reggo-label
  template:
    metadata:
      labels:
        app: reggo-label
    spec:
     containers:
     - name: reggo
       image: "despot/web-tool:1.0"
       command: ["java"]
       args: ["-jar", "app.jar", "reg"]
       ports:
       - containerPort: 1111
EOF

并执行:

kubectl expose deployment reggo  --type=NodePort --port=1111

您可以在 docker 文件本身中将 java -jar 命令作为 ENTRYPOINT,它告诉 Docker 到 运行 java 应用程序.

FROM openjdk:11-jre
ADD target/web-tool-1.0-SNAPSHOT.jar app.jar
EXPOSE 1111
EXPOSE 2222
ENTRYPOINT ["java", "-jar", "app.jar", "reg"]

或者,可以通过 kubernetes yaml

中的 commandargs 部分实现相同的目的
containers:
- name: myapp
  image: myregistry.azurecr.io/myapp:0.1.7
  command: ["java"]
  args: ["-jar", "app.jar", "reg"]

现在到了 Forbidden: pod updates may not add or remove containers 错误的地步,它发生的原因是因为您正在尝试修改不允许的现有 pod 对象的 containers 部分。您可以获取整个部署 yaml 并在编辑器中打开并编辑它以添加命令部分,然后删除现有部署,最后将修改后的部署 yaml 应用到集群,而不是这样做。

  1. kubectl get deploy reggo -o yaml --export > deployment.yaml
  2. 通过kubectl delete deploy reggo
  3. 删除现有部署
  4. 编辑deployment.yaml以添加正确的命令
  5. 将 yaml 应用到集群 kubectl apply -f deployment.yaml

如前所述,推荐的方法是在您的 Dockerfile 中添加 ENTRYPOINT 以及您愿意使用的命令。

但是,如果您想使用 kubectl 命令创建部署,您可以 运行

kubectl run $DEPLOYMENT_NAME --image=despot/web-tool:1.0 --command -- java -jar app.jar reg

此外,如果您想使用相同的命令公开部署,您可以通过:

--expose=true 参数将创建 ClusterIP

类型的服务

--port=$PORT_NUMBER 选择要公开的端口。

要将端口类型更改为 NodePort,您必须 运行:

kubectl run $DEPLOYMENT_NAME --image=despot/web-tool:1.0 --expose=true --service-overrides='{ "spec": { "type": "NodePort" } }' --port=$PORT_NUMBER --command -- java -jar app.jar reg