É um pedido de ajuda? (Em caso afirmativo, você deve usar nosso guia de solução de problemas e canais de suporte da comunidade, consulte http://kubernetes.io/docs/trou troubleshooting/.): Não
Quais palavras-chave você pesquisou nos problemas do Kubernetes antes de preencher este? (Se você encontrou alguma duplicata, você deve responder lá.): Command not found configmap kubernetes
Este é um RELATÓRIO DE BUGS ou PEDIDO DE RECURSO? (escolha um): BUG
Versão do Kubernetes (use kubectl version
):
Versão do cliente: v1.6.1 GitCommit: "b0b7a323cc5a4a2019b2e9520c21c7830b7f708e"
Versão do servidor: v1.6.0 GitCommit: "fff5156092b56e6bd60fff75aad4dc9de6b6ef37
Meio Ambiente :
uname -a
): o host é Linux dev1 4.4.0-72-generic # 93-Ubuntu SMP Sex. 31 de março 14:07:41 UTC 2017 x86_64 x86_64 x86_64 GNU / LinuxO que aconteceu :
Quando tento criar uma implantação com um arquivo configmap montado no mesmo diretório do ponto de entrada, o contêiner falha ao iniciar com o seguinte erro
"Resposta de erro do daemon: Comando do recipiente '/app/app.sh' não encontrado ou não existe."
A especificação do pod inclui um configmap que é montado no mesmo diretório que o ponto de entrada
Parece que o script do ponto de entrada foi perdido após montar o volume para o mapa de configuração no mesmo diretório
Se eu montar o arquivo configmap em um subdiretório, tudo funcionará conforme o esperado
O que você esperava que acontecesse :
Eu esperava que o arquivo de mapa de configuração fosse criado no diretório sem afetar o conteúdo do diretório existente, que neste caso contém um script de ponto de entrada
Como reproduzi-lo (o mais mínimo e precisamente possível):
Arquivo Docker - observe o ponto de entrada
FROM busybox:latest
RUN mkdir /app
COPY app.sh /app
ENTRYPOINT ["/app/app.sh"]
Script de ponto de entrada - loop infinito
#!/bin/sh
seq=1
while [[ true ]]; do
echo "${seq} $(date) working"
sleep .5s
let seq=$((seq + 1))
done
k8s configmap e arquivo de implantação
apiVersion: v1
kind: ConfigMap
metadata:
labels:
product: k8s-demo
name: demo
data:
settings.json: |
{
"store": {
"type": "InMemory",
}
---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
labels:
product: k8s-demo
name: demo
spec:
replicas: 1
template:
metadata:
labels:
app: demo
product: k8s-demo
spec:
containers:
- name: demo
image: pmcgrath/shellloop:1
imagePullPolicy: Always
volumeMounts:
- name: demo-config
mountPath: /app
volumes:
- name: demo-config
configMap:
name: demo
items:
- key: settings.json
path: settings.json
Quando executo o kubectl apply -d k8s.yaml e vejo o pod, vejo o seguinte erro
erro rpc: code = 2 desc = falhou ao iniciar o contêiner "f9e0112c80ebba568d4b508f99ffb053bf1ae5a4f095ce7f45bff5f38900b617": Resposta de erro do daemon: Comando do contêiner '/app/app.sh' não encontrado ou não existe.
Mais alguma coisa que precisamos saber :
Se eu mudar o mountPath do volume para qualquer outro diretório, ele funcionará conforme o esperado
Eu testei isso diretamente com docker no meu host (17.03.0-ce) e funcionou conforme o esperado
touch settings.json
docker container run -ti -v $(pwd)/settings.json:/app/settings.json pmcgrath/shellloop:1
@pmcgrath
Verifique aqui .
parece que entendo seu problema. Eu tenho a mesma pergunta antes, mas há uma resposta na sua situação.
Para resumir seu caso, você tem um configmap ( settings.json: blahblah
) e deseja montar em uma pasta /app
. Então, abaixo está o que você precisa saber:
mountPath
, portanto, no seu caso, a pasta /app
conterá apenas settings.json
.mountPath: /app/settings.json
, só assim, o conteúdo original nas pastas /app
não será afetado.Isso é algo que você obterá eventualmente:
containers:
- volumeMounts:
- name: demo-config
mountPath: /app/settings.json
subPath: settings.json
volumes:
- name: demo-config
configMap:
name: demo
@ zhouhaibing089
Obrigado pela resposta, funciona com base na sua sugestão, agradeço a explicação
Estou feliz por encerrar este problema
Pat
Para referência, a menção original desta solução parece estar aqui: https://github.com/kubernetes/kubernetes/issues/23748#issuecomment -230390309
Parece que a documentação para isso está faltando, o que torna este caso bastante confuso / enganoso, e os documentos de projeção também parecem torná-lo mais enganoso - não tenho certeza se está faltando porque as atualizações automáticas aparentemente não funcionam para esse problema
O requisito para que o nome do arquivo seja especificado em mountPath
e subPath
é contra-intuitivo.
A solução fornecida por @ zhouhaibing089 funciona, mas o conteúdo do arquivo montado em subPath
não atualiza se o editarmos no ConfigMap semelhante.
IMO, isso não está _realmente_ resolvido. Deve haver uma opção para anexar cada chave em vez de sobrescrever.
Algo como:
kind: ConfigMap
apiVersion: v1
metadata:
name: nginx-conf
data:
example1.conf: |
server {
server_name example1.com;
# config here...
}
example2.conf: |
server {
server_name example2.com;
# config here...
}
De modo a...
- name: nginx-conf
mountPath: /etc/nginx/conf.d
append: true
... mantém o default.conf
e quaisquer outros artefatos da imagem Docker, mas aumenta com example*.conf
Repetir a mesma informação no subPath é apenas _icky_.
+1 na opção append: true
@leebenson .
De acordo com a resposta de @leebenson : alguém pode explicar de onde vem append: true
option ??
não funciona para mim, eu tenho:
error: error validating "hdfs/21-namenode-statefulset.yaml": error validating data: ValidationError(StatefulSet.spec.template.spec.containers[1].volumeMounts[1]): unknown field "append" in io.k8s.api.core.v1.VolumeMount; if you choose to ignore these errors, turn validation off with --validate=false
Além disso, não está presente na documentação da API para montagem de volume:
https://k8smeetup.github.io/docs/api-reference/v1.9/#volumemount -v1-core
De acordo com a resposta de @leebenson : alguém pode explicar de onde vem
append: true
option ??não funciona para mim, eu tenho:
error: error validating "hdfs/21-namenode-statefulset.yaml": error validating data: ValidationError(StatefulSet.spec.template.spec.containers[1].volumeMounts[1]): unknown field "append" in io.k8s.api.core.v1.VolumeMount; if you choose to ignore these errors, turn validation off with --validate=false
Além disso, não está presente na documentação da API para montagem de volume:
https://k8smeetup.github.io/docs/api-reference/v1.9/#volumemount -v1-core
não existe, é uma sugestão. um bom para o caso de uso.
Tentei usar este método, mas recebi um erro de sistema de arquivos somente leitura, quando apliquei o statefulset. Alguém sabe como consertar aquilo?
(Estou substituindo um arquivo existente, que contém configurações para elasticsearch, mensagem de erro real -> /usr/share/elasticsearch/bin/run.sh: line 28: ./config/elasticsearch.yml: Read-only file system
)
Comentários muito úteis
@pmcgrath
Verifique aqui .
parece que entendo seu problema. Eu tenho a mesma pergunta antes, mas há uma resposta na sua situação.
Para resumir seu caso, você tem um configmap (
settings.json: blahblah
) e deseja montar em uma pasta/app
. Então, abaixo está o que você precisa saber:mountPath
, portanto, no seu caso, a pasta/app
conterá apenassettings.json
.mountPath: /app/settings.json
, só assim, o conteúdo original nas pastas/app
não será afetado.Isso é algo que você obterá eventualmente: