#azure #kubernetes #azure-devops #azure-pipelines #azure-aks
#azure #kubernetes #azure-devops #azure-конвейеры #azure-aks
Вопрос:
Я новичок в операциях разработки. Я настраиваю конвейер CD в VSTS. Я использовал задачу Deploy to Kubernetes для развертывания приложения, которое работает нормально.
После развертывания в задаче Kubernetes я добавил еще одну задачу развертывания в Kubernetes, и я хочу выполнить приведенную ниже команду
kubectl describe pods <podname>
Приведенная выше команда описывает модуль.
Я вижу, что в задаче развертывания в Kubernetes (в конвейере VSTS) нет такой команды для описания.
Доступны только следующие команды get, apply, set, exec, login, logout, create, delete, expose, run and top
.
Выполняя вышеуказанные команды, я хочу убедиться, что все модули запущены.
Как я могу выполнить команду описания в конвейере VSTS CD?
Альтернативным вариантом является любая другая команда, которая вернет тот же результат, что и describe pods <podname>
команда.
Комментарии:
1. какие данные вам нужны из kubectl для описания?
2.
kubectl get po name
возвращает состояние, поэтому оно предоставляет то, что вы запрашиваете3. @Amityo: В основном мне нужны следующие условия состояния: Тип Status Инициализирован True Ready True ContainersReady True PodScheduled True
4. @4c74356b41: команда не работает.
5. что значит не работает? лол
Ответ №1:
вы можете использовать метки, чтобы найти интересующий вас модуль:
$ kg po --show-labels
NAME READY STATUS RESTARTS AGE LABELS
frontend-76dc7bfc6d-7zcb8 1/1 Running 0 9h app=Frontend,branch=develop,pod-template-hash=76dc7bfc6d
identityserverapp-f9684fc77-z9wtb 1/1 Running 0 9h app=IdentityServerApp,branch=develop,pod-template-hash=f9684fc77
$ kg po --selector=app=Frontend
NAME READY STATUS RESTARTS AGE
frontend-76dc7bfc6d-7zcb8 1/1 Running 0 9h
ps. kg
= псевдоним для kubectl get
Ответ №2:
Вот как вы могли бы это сделать из jupyter….
#find all pods containing foobar in namepods_per_node = !kubectl get pod -o=custom-columns=NAMESPACE:metadata.namespace,NAME:.metadata.name,STATUS:.status.phase,NODE:.spec.nodeName --all-namespaces
# print ('n'.join(pods_per_node))
print (pods_per_node[0])
pods_per_node_filtered = [ln for ln in pods_per_node if ln.find('foobar')!=-1]
print ('n'.join(pods_per_node_filtered))
Результат:
NAMESPACE NAME STATUS NODE
datalabs foobar-deployment-5dbf985bdb-mllwp Running xxxxxxx.online-server.cloud
misc foobar-second-deployment-85c5bd757f-fpm9z Running xxxxxxx.online-server.cloud
Затем используйте get, чтобы получить сведения в формате json и упорядочить по имени модуля:
#full node state:
pod_descriptions_txt = !kubectl get pods -o json --all-namespaces
pod_descriptions = json.loads(''.join(pod_descriptions_txt))
pod_descriptions = pod_descriptions['items']
pod_descriptions_by_name = {pod_desc['metadata']['name']:pod_desc for pod_desc in pod_descriptions}
Затем распечатайте узлы с подключенными томами:
for ln in pods_per_node_filtered:
pod_namespace, pod_name, pod_status, pod_node = ln.split()
print(pod_name)
# no machine readable format:
# pod_desc = !kubectl describe pods {pod_name} --namespace {pod_namespace}
pod_desc = pod_descriptions_by_name[pod_name]
pod_volumes = pod_desc['spec']['volumes']
for volume in pod_volumes:
if 'persistentVolumeClaim' in volume:
print (f"[{volume['name']:>34}]---> persistant[{volume['persistentVolumeClaim']['claimName']}]")
assert len(volume)==2
elif 'configMap' in volume:
assert len(volume)==2
print (f"[{volume['name']:>34}]---> configMap: {volume['configMap']}")
elif 'secret' in volume:
assert len(volume)==2
print (f"[{volume['name']:>34}]---> secret: {volume['secret']}")
elif 'hostPath' in volume:
assert len(volume)==2
print (f"[{volume['name']:>34}]---> hostPath: {volume['hostPath']}")
else:
print()
print()
print(volume)
raise Exception('Todo')
Результаты для:
foobar-deployment-5dbf985bdb-mllwp
[ some-pv]---> persistant[foobar-claim]
[ default-token-xxxxx]---> secret: {'defaultMode': 420, 'secretName': 'default-token-xxxxx'}
foobar-second-deployment-85c5bd757f-fpm9z
[ someother-pv]---> hostPath: {'path': '/nfs/someother-pv', 'type': 'Directory'}
[ default-token-xxxxx]---> secret: {'defaultMode': 420, 'secretName': 'default-token-xxxxx'}
Могут быть объединены в функцию вместе с дополнительной информацией о томах:
def describe_pods(filter_str='foobar'):
pods_per_node = !kubectl get pod -o=custom-columns=NAMESPACE:metadata.namespace,NAME:.metadata.name,STATUS:.status.phase,NODE:.spec.nodeName --all-namespaces
# print ('n'.join(pods_per_node))
print (pods_per_node[0])
pods_per_node_filtered = [ln for ln in pods_per_node if ln.find(filter_str)!=-1]
#full node state:
pod_descriptions_txt = !kubectl get pods -o json --all-namespaces
pod_descriptions = json.loads(''.join(pod_descriptions_txt))
pod_descriptions = pod_descriptions['items']
# pod_desc['metadata']['name'] is the pod's name...
pod_descriptions_by_name = {pod_desc['metadata']['name']:pod_desc for pod_desc in pod_descriptions}
for ln in pods_per_node_filtered:
pod_namespace, pod_name, pod_status, pod_node = ln.split()
pod_node_ip_txt = !kubectl describe node {pod_node}|grep InternalIP
assert len(pod_node_ip_txt)==1
pod_node_ip = pod_node_ip_txt[0].split()[1]
print(f"POD [{pod_name:>45}] on node [{pod_node}]({pod_node_ip}), namespace {pod_namespace}")
# no machine readable format:
# pod_desc = !kubectl describe pods {pod_name} --namespace {pod_namespace}
pod_desc = pod_descriptions_by_name[pod_name]
pod_volumes = pod_desc['spec']['volumes']
for volume in pod_volumes:
if 'persistentVolumeClaim' in volume:
claimName = volume['persistentVolumeClaim']['claimName']
print (f" - [{volume['name']:>30}]---> persistant[{claimName}]")
pvc = !kubectl get pvc {claimName} --namespace {pod_namespace}
print (" " "n ".join(pvc))
assert len(pvc)==2
pv= pvc[1].split()[2]
pv_descr = !kubectl describe pv {pv}
print (" " "n ".join(pv_descr))
assert len(volume)==2
elif 'configMap' in volume:
assert len(volume)==2
print (f" - [{volume['name']:>30}]---> configMap: {volume['configMap']}")
elif 'secret' in volume:
assert len(volume)==2
print (f" - [{volume['name']:>30}]---> secret: {volume['secret']}")
elif 'hostPath' in volume:
assert len(volume)==2
print (f" - [{volume['name']:>30}]---> hostPath: {volume['hostPath']}")
else:
print()
print()
print(volume)
raise Exception('Todo')
print('====================================================================================================')
print()
(имена узлов и т.д. Изменены по соображениям конфиденциальности)