在更改ConfigMap后重新启动Kubernetes部署

12
我有一个部署,其中包括configMap、persistentVolumeClaim和service。我已更改了configMap并重新应用了部署到我的集群。我知道这个更改不会自动重启部署中的pod: configmap更改不会自动反映在相应的pod上 更新了configMap.yaml但没有应用于Kubernetes pod 我知道我可以使用kubectl delete -f wiki.yaml && kubectl apply -f wiki.yaml。但这将破坏持久卷中的数据,而我希望这些数据在重启后仍然存在。如何以保留现有卷的方式重新启动pod?
这是wiki.yaml的样子:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: dot-wiki
spec:
  accessModes:
    - ReadWriteOnce
  volumeMode: Filesystem
  resources:
    requests:
      storage: 4Gi
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: wiki-config
data:
  config.json: |
    {
      "farm": true,
      "security_type": "friends",
      "secure_cookie": false,
      "allowed": "*"
    }
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: wiki-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      app: wiki
  template:
    metadata:
      labels:
        app: wiki
    spec:
      securityContext:
        runAsUser: 1000
        runAsGroup: 1000
        fsGroup: 1000
      initContainers:
      - name: wiki-config
        image: dobbs/farm:restrict-new-wiki
        securityContext:
          runAsUser: 0
          runAsGroup: 0
          allowPrivilegeEscalation: false
        volumeMounts:
          - name: dot-wiki
            mountPath: /home/node/.wiki
        command: ["chown", "-R", "1000:1000", "/home/node/.wiki"]
      containers:
      - name: farm
        image: dobbs/farm:restrict-new-wiki
        command: [
          "wiki", "--config", "/etc/config/config.json",
          "--admin", "bad password but memorable",
          "--cookieSecret", "any-random-string-will-do-the-trick"]
        ports:
        - containerPort: 3000
        volumeMounts:
          - name: dot-wiki
            mountPath: /home/node/.wiki
          - name: config-templates
            mountPath: /etc/config
      volumes:
      - name: dot-wiki
        persistentVolumeClaim:
          claimName: dot-wiki
      - name: config-templates
        configMap:
          name: wiki-config
---
apiVersion: v1
kind: Service
metadata:
  name: wiki-service
spec:
  ports:
  - name: http
    targetPort: 3000
    port: 80
  selector:
    app: wiki
3个回答

11
除了使用kubectl rollout restart deployment,还有一些其他方法来完成这个操作: 1. 重启Pods
kubectl delete pods -l app=wiki

这会导致您的Deployment的Pod被重启,这时它们会读取更新后的ConfigMap。
2. 对ConfigMap进行版本控制
不要将您的ConfigMap命名为,而是将其命名为。然后,当您更新配置时,只需创建一个名为的新ConfigMap。
现在,编辑您的Deployment规范以引用 ConfigMap,而不是。
apiVersion: apps/v1
kind: Deployment
# ...
      volumes:
      - name: config-templates
        configMap:
          name: wiki-config-v2

然后,重新应用部署:

kubectl apply -f wiki.yaml

由于部署清单中的Pod模板已更改,重新应用部署将重新创建所有Pod。新的Pod将使用新版本的ConfigMap。

此方法的另一个优点是,如果保留旧的ConfigMap(wiki-config-v1)而不删除它,则可以通过再次编辑部署清单来随时恢复到先前的配置。

这种方法在Kubernetes最佳实践(O'Reilly,2019年)第1章中有描述。


kubectl delete pods 看起来非常符合 k8s 的惯用方式,也感谢有关配置映射版本控制的建议。感谢这些建议。我仍然觉得 kubectl rollout restart 更接近我想要的东西。 - Eric Dobbs
感谢您在回答中提到“rollout restart deployment”。由于这个变化,我已经将我的接受答案切换为您的答案,特别是因为您清晰地解释了每个选项的优点。非常好的答案。 - Eric Dobbs

6

针对配置更改后重新启动容器的具体问题,在 kubectl v1.15 中可以执行以下操作:

# apply the config changes
kubectl apply -f wiki.yaml

# restart the containers in the deployment
kubectl rollout restart deployment wiki-deployment

0
你只需要更改你的ConfigMap,然后等待更改生效即可。你发布的链接中的答案是错误的。在更改ConfigMap之后,更改不会立即生效,可能需要一些时间,例如5分钟左右。
如果这种情况没有发生,请报告关于该版本k8s的特定bug。

2
这将导致容器中可见的文件发生更改,但许多进程在启动时只读取其配置一次,从不重新加载它们。您需要以某种方式重新启动Pod以使其重新读取配置文件。 - David Maze
如果你有一个包含nginx配置的ConfigMap,那么你需要重启nginx来传递新的配置,但是配置本身将在容器中可用。你可以简单地重启nginx,无需重新创建pod。 - suren
我喜欢在容器内构建应用程序的方法,以便在其配置发生更改时进行通知。那是很好的建议。但是我在这里要求的是重新启动容器的Kubernetes命令,即使它没有以那种方式构建。 - Eric Dobbs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接