You can use the following expression to create the points along the line every n distance (here 5000 considering the layer use meters)
collect_geometries(array_foreach(
generate_series(0, length($geometry),step:=5000),
make_point_m(
x(line_interpolate_point($geometry, @element)),
y(line_interpolate_point($geometry, @element)),
@element)
))
Alternative if you need to deal with layer projection (needed if your layer is not using meters in particular) considering EPSG:4326
is your layer projection and your local projection is EPSG:25831
collect_geometries(array_foreach(
generate_series(0, length(transform($geometry,'EPSG:4326', 'EPSG:25831')),step:=5000),
transform(make_point_m(
x(line_interpolate_point(transform($geometry,'EPSG:4326', 'EPSG:25831'),
@element)),
y(line_interpolate_point(transform($geometry, 'EPSG:4326', 'EPSG:25831'), @element)),
@element
), 'EPSG:25831', 'EPSG:4326')
))
Although it works for a part and I set the distance value in the M part of the geometry, I don't really see how I can then reuse the M in the labels part as you want in the second part of your requirements. Using Font marker can be another way e.g https://gis.stackexchange.com/a/314789/638
with expression to_string((@geometry_part_num - 1) * 5) || ' Km'
Edit note: comment from @RBenet made me change the second part of the answer